diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000000000..b706e527d77c0 --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,12 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + 'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'deps', 'chore']], + 'header-max-length': [2, 'always', 80], + 'subject-case': [0], + 'body-max-line-length': [0], + 'footer-max-line-length': [0], + }, +} diff --git a/.eslintrc.js b/.eslintrc.js index 1718f033c4122..58e76436686f4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,3 +1,7 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +'use strict' + const { readdirSync: readdir } = require('fs') const localConfigs = readdir(__dirname) @@ -6,6 +10,16 @@ const localConfigs = readdir(__dirname) module.exports = { root: true, + ignorePatterns: [ + 'tap-testdir*/', + '/node_modules/.bin/', + '/node_modules/.cache/', + 'docs/**', + 'smoke-tests/**', + 'mock-globals/**', + 'mock-registry/**', + 'workspaces/**', + ], extends: [ '@npmcli', ...localConfigs, diff --git a/.eslintrc.local.js b/.eslintrc.local.js new file mode 100644 index 0000000000000..2dce9d2badc08 --- /dev/null +++ b/.eslintrc.local.js @@ -0,0 +1,37 @@ +const { resolve, relative } = require('path') + +// Create an override to lockdown a file to es6 syntax only +// and only allow it to require an allowlist of files +const rel = (p) => relative(__dirname, resolve(__dirname, p)) +const braces = (a) => a.length > 1 ? `{${a.map(rel).join(',')}}` : a[0] + +const es6Files = (e) => Object.entries(e).map(([file, allow]) => ({ + files: `./${rel(file)}`, + parserOptions: { + ecmaVersion: 6, + }, + rules: Array.isArray(allow) ? { + 'node/no-restricted-require': ['error', [{ + name: ['/**', `!${__dirname}/${braces(allow)}`], + message: `This file can only require: ${allow.join(',')}`, + }]], + } : {}, +})) + +module.exports = { + rules: { + 'no-console': 'error', + }, + overrides: es6Files({ + 'index.js': ['lib/cli.js'], + 'bin/npm-cli.js': ['lib/cli.js'], + 'lib/cli.js': ['lib/cli/validate-engines.js'], + 'lib/cli/validate-engines.js': ['package.json'], + // TODO: This file should also have its requires restricted as well since it + // is an entry point but it currently pulls in config definitions which have + // a large require graph, so that is not currently feasible. A future config + // refactor should keep that in mind and see if only config definitions can + // be exported in a way that is compatible with ES6. + 'bin/npx-cli.js': null, + }), +} diff --git a/.eslintrc.local.json b/.eslintrc.local.json deleted file mode 100644 index beb4581f41d82..0000000000000 --- a/.eslintrc.local.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "ignorePatterns": [ - "docs/", - "workspaces/*" - ], - "rules": { - "no-shadow": "off", - "no-console": "error" - }, - "overrides": [{ - "files": [ - "scripts/**", - "bin/**", - "test/**" - ], - "rules": { - "no-console": "off" - } - }] -} diff --git a/.gitattributes b/.gitattributes index ef4b94f9e45f9..c70f4d0bcee0a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,28 @@ -/node_modules/** linguist-generated=false -/package-lock.json linguist-generated=false +# normalize all line endings by default +* text=auto + +# our shell/bin scripts always need to be LF +/bin/* text eol=lf +/workspaces/arborist/bin/index.js text eol=lf +/configure text eol=lf + +# our cmd scripts always need to be CRLF +/bin/**/*.cmd text eol=crlf + +# ignore all line endings in node_modules since we dont control that +/node_modules/** -text + +# the files we write should be LF so they can be generated cross platform +/node_modules/.gitignore text eol=lf +/workspaces/arborist/test/fixtures/.gitignore text eol=lf +/DEPENDENCIES.md text eol=lf +/DEPENDENCIES.json text eol=lf +/AUTHORS text eol=lf + +# fixture tarballs should be treated as binary +/workspaces/*/test/fixtures/**/*.tgz binary + +# these hint to GitHub to show these files as not generated so they default to +# showing the full diff in pull requests +/node_modules/** linguist-generated=false +/package-lock.json linguist-generated=false diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ef8743136d8a1..2c54b0d250372 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,3 @@ -* @npm/cli-team +# This file is automatically added by @npmcli/template-oss. Do not edit. + +* @npm/cli-team diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000000000..f285bcce4c81e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,63 @@ +name: 🐞 Bug +description: File a bug/issue against the latest version of npm +title: "[BUG] " +labels: [Bug, Needs Triage] +body: +- type: checkboxes + attributes: + label: Is there an existing issue for this? + description: Please [search here](https://github.com/npm/cli/issues) to see if an issue already exists for your problem. + options: + - label: I have searched the existing issues + required: true +- type: checkboxes + attributes: + label: This issue exists in the latest npm version + description: Please make sure you have installed the latest npm and verified it is still an issue. + options: + - label: I am using the latest npm + required: true +- type: textarea + attributes: + label: Current Behavior + description: A clear & concise description of what you're experiencing. + validations: + required: false +- type: textarea + attributes: + label: Expected Behavior + description: A clear & concise description of what you expected to happen. + validations: + required: false +- type: textarea + attributes: + label: Steps To Reproduce + description: Steps to reproduce the behavior. + value: | + 1. In this environment... + 2. With this config... + 3. Run '...' + 4. See error... + validations: + required: false +- type: textarea + attributes: + label: Environment + description: | + examples: + - **`npm -v`**: **npm**: 10.0.0 + - **`node -v`**: **Node.js**: 18.0.0 + - **OS Name**: Ubuntu 20.04 + - **System Model Name**: Macbook Pro + - **`npm config ls`**: `; "user" config from ...` + value: | + - npm: + - Node.js: + - OS Name: + - System Model Name: + - npm config: + ```ini + ; copy and paste output from `npm config ls` here + ``` + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/bug_8.yml b/.github/ISSUE_TEMPLATE/bug_8.yml deleted file mode 100644 index f6855c4deba48..0000000000000 --- a/.github/ISSUE_TEMPLATE/bug_8.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: 🐞 Bug v8 -description: File a bug/issue against v8.x -title: "[BUG] <title>" -labels: [Bug, Needs Triage, Release 8.x] -body: -- type: checkboxes - attributes: - label: Is there an existing issue for this? - description: Please [search here](https://github.com/npm/cli/issues) to see if an issue already exists for your problem. - options: - - label: I have searched the existing issues - required: true -- type: checkboxes - attributes: - label: This issue exists in the latest npm version - description: Please make sure you have installed the latest npm and verified it is still an issue. - options: - - label: I am using the latest npm - required: true -- type: textarea - attributes: - label: Current Behavior - description: A clear & concise description of what you're experiencing. - validations: - required: false -- type: textarea - attributes: - label: Expected Behavior - description: A clear & concise description of what you expected to happen. - validations: - required: false -- type: textarea - attributes: - label: Steps To Reproduce - description: Steps to reproduce the behavior. - value: | - 1. In this environment... - 2. With this config... - 3. Run '...' - 4. See error... - validations: - required: false -- type: textarea - attributes: - label: Environment - description: | - examples: - - **`npm -v`**: **npm**: 7.6.3 - - **`node -v`**: **Node.js**: 13.14.0 - - **OS Name**: Ubuntu 20.04 - - **System Model Name**: Macbook Pro - - **`npm config ls`**: `; "user" config from ...` - value: | - - npm: - - Node.js: - - OS Name: - - System Model Name: - - npm config: - ```ini - ; copy and paste output from `npm config ls` here - ``` - validations: - required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 07e3b979df202..8bcac1c6dfdd9 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -4,7 +4,7 @@ contact_links: url: https://github.community/c/software-development/47 about: Find/file tickets with the community - name: ⭐️ Feature Request - url: https://github.com/npm/feedback + url: https://github.com/orgs/community/discussions/categories/npm about: Add your request or discuss the project w/ the community - name: 📃 RFC url: https://github.com/npm/rfcs diff --git a/.github/actions/create-check/action.yml b/.github/actions/create-check/action.yml new file mode 100644 index 0000000000000..d1220c90cfb11 --- /dev/null +++ b/.github/actions/create-check/action.yml @@ -0,0 +1,52 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: 'Create Check' +inputs: + name: + required: true + token: + required: true + sha: + required: true + check-name: + default: '' +outputs: + check-id: + value: ${{ steps.create-check.outputs.check_id }} +runs: + using: "composite" + steps: + - name: Get Workflow Job + uses: actions/github-script@v7 + id: workflow + env: + JOB_NAME: "${{ inputs.name }}" + SHA: "${{ inputs.sha }}" + with: + result-encoding: string + script: | + const { repo: { owner, repo}, runId, serverUrl } = context + const { JOB_NAME, SHA } = process.env + + const job = await github.rest.actions.listJobsForWorkflowRun({ + owner, + repo, + run_id: runId, + per_page: 100 + }).then(r => r.data.jobs.find(j => j.name.endsWith(JOB_NAME))) + + return [ + `This check is assosciated with ${serverUrl}/${owner}/${repo}/commit/${SHA}.`, + 'Run logs:', + job?.html_url || `could not be found for a job ending with: "${JOB_NAME}"`, + ].join(' ') + - name: Create Check + uses: LouisBrunner/checks-action@v1.6.0 + id: create-check + with: + token: ${{ inputs.token }} + sha: ${{ inputs.sha }} + status: in_progress + name: ${{ inputs.check-name || inputs.name }} + output: | + {"summary":"${{ steps.workflow.outputs.result }}"} diff --git a/.github/actions/install-latest-npm/action.yml b/.github/actions/install-latest-npm/action.yml new file mode 100644 index 0000000000000..580603dd40c92 --- /dev/null +++ b/.github/actions/install-latest-npm/action.yml @@ -0,0 +1,58 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: 'Install Latest npm' +description: 'Install the latest version of npm compatible with the Node version' +inputs: + node: + description: 'Current Node version' + required: true +runs: + using: "composite" + steps: + # node 10/12/14 ship with npm@6, which is known to fail when updating itself in windows + - name: Update Windows npm + if: | + runner.os == 'Windows' && ( + startsWith(inputs.node, 'v10.') || + startsWith(inputs.node, 'v12.') || + startsWith(inputs.node, 'v14.') + ) + shell: cmd + run: | + curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz + tar xf npm-7.5.4.tgz + cd package + node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz + cd .. + rmdir /s /q package + - name: Install Latest npm + shell: bash + env: + NODE_VERSION: ${{ inputs.node }} + working-directory: ${{ runner.temp }} + run: | + MATCH="" + SPECS=("latest" "next-10" "next-9" "next-8" "next-7" "next-6") + + echo "node@$NODE_VERSION" + + for SPEC in ${SPECS[@]}; do + ENGINES=$(npm view npm@$SPEC --json | jq -r '.engines.node') + echo "Checking if node@$NODE_VERSION satisfies npm@$SPEC ($ENGINES)" + + if npx semver -r "$ENGINES" "$NODE_VERSION" > /dev/null; then + MATCH=$SPEC + echo "Found compatible version: npm@$MATCH" + break + fi + done + + if [ -z $MATCH ]; then + echo "Could not find a compatible version of npm for node@$NODE_VERSION" + exit 1 + fi + + npm i --prefer-online --no-fund --no-audit -g npm@$MATCH + - name: npm Version + shell: bash + run: npm -v diff --git a/.github/matchers/tap.json b/.github/matchers/tap.json new file mode 100644 index 0000000000000..2c81ea9803fbc --- /dev/null +++ b/.github/matchers/tap.json @@ -0,0 +1,32 @@ +{ + "//@npmcli/template-oss": "This file is automatically added by @npmcli/template-oss. Do not edit.", + "problemMatcher": [ + { + "owner": "tap", + "pattern": [ + { + "regexp": "^\\s*not ok \\d+ - (.*)", + "message": 1 + }, + { + "regexp": "^\\s*---" + }, + { + "regexp": "^\\s*at:" + }, + { + "regexp": "^\\s*line:\\s*(\\d+)", + "line": 1 + }, + { + "regexp": "^\\s*column:\\s*(\\d+)", + "column": 1 + }, + { + "regexp": "^\\s*file:\\s*(.*)", + "file": 1 + } + ] + } + ] +} diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml new file mode 100644 index 0000000000000..91596c57f814f --- /dev/null +++ b/.github/workflows/audit.yml @@ -0,0 +1,43 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Audit + +on: + workflow_dispatch: + schedule: + # "At 08:00 UTC (01:00 PT) on Monday" https://crontab.guru/#0_8_*_*_1 + - cron: "0 8 * * 1" + +permissions: + contents: read + +jobs: + audit: + name: Audit Dependencies + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js --package-lock + - name: Run Production Audit + run: node . audit --omit=dev + - name: Run Full Audit + run: node . audit --audit-level=none diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml deleted file mode 100644 index 018eeae7e4974..0000000000000 --- a/.github/workflows/benchmark.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: Benchmark - CLI - -on: - pull_request: - branches: - - '*' - paths: - - lib/** - issue_comment: - types: - - created - - edited - -jobs: - trigger-benchmark: - runs-on: ubuntu-latest - steps: - - name: Incoming Pull Request - if: | - github.event_name == 'pull_request' || ( - github.event_name == 'issue_comment' && - github.event.issue.pull_request && - github.event.issue.state == 'open' && - startsWith(github.event.comment.body, '@npm-cli-bot benchmark this') - ) - env: - # gh cli uses these env vars for owner/repo/token - GH_REPO: "npm/benchmarks" - GITHUB_TOKEN: ${{ secrets.BENCHMARK_DISPATCH_TOKEN }} - run: | - EVENT_NAME="${{ github.event_name }}" - OWNER="${{ github.event.repository.owner.login }}" - REPO="${{ github.event.repository.name }}" - PR="" - - if [[ "$EVENT_NAME" == "pull_request" ]]; then - if [[ "$GITHUB_TOKEN" == "" ]]; then - echo "No auth - from fork pull request, exiting" - exit 0 - fi - PR="${{ github.event.pull_request.number }}" - else - PR="${{ github.event.issue.number }}" - SENDER="${{ github.event.comment.user.login }}" - ROLE=$(gh api repos/${OWNER}/${REPO}/collaborators/${SENDER}/permission -q '.permission') - - if [[ "$ROLE" != "admin" ]]; then - echo "${SENDER} is ${ROLE}, not an admin, exiting" - exit 0 - fi - - # add emoji to comment if user is an admin to signal - # benchmark is running - COMMENT_NODE_ID="${{ github.event.comment.node_id }}" - QUERY='mutation ($inputData:AddReactionInput!) { - addReaction (input:$inputData) { - reaction { content } - } - }' - echo '{ - "query": "'${QUERY}'", - "variables": { - "inputData": { - "subjectId": "'"${COMMENT_NODE_ID}"'", - "content": "ROCKET" - } - } - }' | gh api graphql --input - - fi - - EVENT="${EVENT_NAME} ${OWNER}/${REPO}#${PR}" - echo '{ - "event_type": "'"$EVENT"'", - "client_payload": { - "pr_id": "'"$PR"'", - "repo": "'"$REPO"'", - "owner": "'"$OWNER"'" - } - }' | gh api repos/{owner}/{repo}/dispatches --input - diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml deleted file mode 100644 index f5543605a9d9f..0000000000000 --- a/.github/workflows/ci-docs.yml +++ /dev/null @@ -1,85 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: CI - docs - -on: - workflow_dispatch: - pull_request: - branches: - - '*' - paths: - - docs/** - push: - branches: - - main - - latest - paths: - - docs/** - schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16 - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w docs - - test: - strategy: - fail-fast: false - matrix: - node-version: - - 16 - platform: - - os: ubuntu-latest - shell: bash - - os: macos-latest - shell: bash - - os: windows-latest - shell: cmd - runs-on: ${{ matrix.platform.os }} - defaults: - run: - shell: ${{ matrix.platform.shell }} - steps: - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w docs diff --git a/.github/workflows/ci-libnpmaccess.yml b/.github/workflows/ci-libnpmaccess.yml index eda4741583bb9..0fc976d1eb1fb 100644 --- a/.github/workflows/ci-libnpmaccess.yml +++ b/.github/workflows/ci-libnpmaccess.yml @@ -5,86 +5,118 @@ name: CI - libnpmaccess on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmaccess/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmaccess/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmaccess + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmaccess + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmaccess test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmaccess + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmaccess + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmdiff.yml b/.github/workflows/ci-libnpmdiff.yml index e2347877d0243..7e9353f67caa2 100644 --- a/.github/workflows/ci-libnpmdiff.yml +++ b/.github/workflows/ci-libnpmdiff.yml @@ -5,86 +5,118 @@ name: CI - libnpmdiff on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmdiff/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmdiff/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmdiff + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmdiff + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmdiff test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmdiff + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmdiff + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmexec.yml b/.github/workflows/ci-libnpmexec.yml index 645eada5c0618..65a92a65f5df6 100644 --- a/.github/workflows/ci-libnpmexec.yml +++ b/.github/workflows/ci-libnpmexec.yml @@ -5,86 +5,118 @@ name: CI - libnpmexec on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmexec/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmexec/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmexec + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmexec + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmexec test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmexec + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmexec + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmfund.yml b/.github/workflows/ci-libnpmfund.yml index 3ec70cf103584..4b8ed23432de7 100644 --- a/.github/workflows/ci-libnpmfund.yml +++ b/.github/workflows/ci-libnpmfund.yml @@ -5,86 +5,118 @@ name: CI - libnpmfund on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmfund/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmfund/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmfund + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmfund + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmfund test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmfund + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmfund + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmhook.yml b/.github/workflows/ci-libnpmhook.yml deleted file mode 100644 index 1e29eb84d7688..0000000000000 --- a/.github/workflows/ci-libnpmhook.yml +++ /dev/null @@ -1,90 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: CI - libnpmhook - -on: - workflow_dispatch: - pull_request: - branches: - - '*' - paths: - - workspaces/libnpmhook/** - push: - branches: - - main - - latest - paths: - - workspaces/libnpmhook/** - schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmhook - - test: - strategy: - fail-fast: false - matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x - platform: - - os: ubuntu-latest - shell: bash - - os: macos-latest - shell: bash - - os: windows-latest - shell: cmd - runs-on: ${{ matrix.platform.os }} - defaults: - run: - shell: ${{ matrix.platform.shell }} - steps: - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmhook diff --git a/.github/workflows/ci-libnpmorg.yml b/.github/workflows/ci-libnpmorg.yml index 48fc1e794eb17..4dcf220e12bf3 100644 --- a/.github/workflows/ci-libnpmorg.yml +++ b/.github/workflows/ci-libnpmorg.yml @@ -5,86 +5,118 @@ name: CI - libnpmorg on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmorg/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmorg/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmorg + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmorg + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmorg test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmorg + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmorg + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmpack.yml b/.github/workflows/ci-libnpmpack.yml index 765e1eb472ca5..aea7ea825a059 100644 --- a/.github/workflows/ci-libnpmpack.yml +++ b/.github/workflows/ci-libnpmpack.yml @@ -5,86 +5,118 @@ name: CI - libnpmpack on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmpack/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmpack/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmpack + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmpack + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmpack test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmpack + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmpack + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmpublish.yml b/.github/workflows/ci-libnpmpublish.yml index 4aaba116e5b51..2209e32d3bc95 100644 --- a/.github/workflows/ci-libnpmpublish.yml +++ b/.github/workflows/ci-libnpmpublish.yml @@ -5,86 +5,118 @@ name: CI - libnpmpublish on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmpublish/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmpublish/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmpublish + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmpublish + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmpublish test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmpublish + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmpublish + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmsearch.yml b/.github/workflows/ci-libnpmsearch.yml index 5d6ac4e798396..231614b2e6278 100644 --- a/.github/workflows/ci-libnpmsearch.yml +++ b/.github/workflows/ci-libnpmsearch.yml @@ -5,86 +5,118 @@ name: CI - libnpmsearch on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmsearch/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmsearch/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmsearch + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmsearch + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmsearch test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmsearch + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmsearch + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmteam.yml b/.github/workflows/ci-libnpmteam.yml index 4e2636d936060..4e6f22bdc615f 100644 --- a/.github/workflows/ci-libnpmteam.yml +++ b/.github/workflows/ci-libnpmteam.yml @@ -5,86 +5,118 @@ name: CI - libnpmteam on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmteam/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmteam/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmteam + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmteam + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmteam test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmteam + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmteam + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-libnpmversion.yml b/.github/workflows/ci-libnpmversion.yml index 2a86e6b825e0e..a2bf0f4c6f9cf 100644 --- a/.github/workflows/ci-libnpmversion.yml +++ b/.github/workflows/ci-libnpmversion.yml @@ -5,86 +5,118 @@ name: CI - libnpmversion on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/libnpmversion/** push: branches: - - main - latest + - release/v* paths: - workspaces/libnpmversion/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w libnpmversion + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace libnpmversion + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace libnpmversion test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w libnpmversion + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace libnpmversion + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-npmcli-arborist.yml b/.github/workflows/ci-npmcli-arborist.yml index 1dbe0184a0f01..2c6ad5c283876 100644 --- a/.github/workflows/ci-npmcli-arborist.yml +++ b/.github/workflows/ci-npmcli-arborist.yml @@ -5,86 +5,118 @@ name: CI - @npmcli/arborist on: workflow_dispatch: pull_request: - branches: - - '*' paths: - workspaces/arborist/** push: branches: - - main - latest + - release/v* paths: - workspaces/arborist/** schedule: - # "At 02:00 on Monday" https://crontab.guru/#0_2_*_*_1 - - cron: "0 2 * * 1" + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm run lint -w @npmcli/arborist + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace @npmcli/arborist + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace @npmcli/arborist test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' strategy: fail-fast: false matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x platform: - - os: ubuntu-latest + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest shell: bash - - os: macos-latest + - name: macOS + os: macos-13 shell: bash - - os: windows-latest + - name: Windows + os: windows-latest shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x runs-on: ${{ matrix.platform.os }} defaults: run: shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User run: | git config --global user.email "npm-cli+bot@github.com" git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: node-version: ${{ matrix.node-version }} - - name: Update to workable npm (windows) - # node 12 and 14 ship with npm@6, which is known to fail when updating itself in windows - if: matrix.platform.os == 'windows-latest' && (startsWith(matrix.node-version, '12.') || startsWith(matrix.node-version, '14.')) - run: | - curl -sO https://registry.npmjs.org/npm/-/npm-7.5.4.tgz - tar xf npm-7.5.4.tgz - cd package - node lib/npm.js install --no-fund --no-audit -g ..\npm-7.5.4.tgz - cd .. - rmdir /s /q package - - name: Update npm to 7 - # If we do test on npm 10 it needs npm7 - if: startsWith(matrix.node-version, '10.') - run: npm i --prefer-online --no-fund --no-audit -g npm@7 - - name: Update npm to latest - if: ${{ !startsWith(matrix.node-version, '10.') }} - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - run: npm i --ignore-scripts --no-audit --no-fund - - run: npm test --ignore-scripts -w @npmcli/arborist + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace @npmcli/arborist + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-npmcli-config.yml b/.github/workflows/ci-npmcli-config.yml new file mode 100644 index 0000000000000..79f1f6797e526 --- /dev/null +++ b/.github/workflows/ci-npmcli-config.yml @@ -0,0 +1,122 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - @npmcli/config + +on: + workflow_dispatch: + pull_request: + paths: + - workspaces/config/** + push: + branches: + - latest + - release/v* + paths: + - workspaces/config/** + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read + +jobs: + lint: + name: Lint + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace @npmcli/config + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace @npmcli/config + + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace @npmcli/config + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-npmcli-docs.yml b/.github/workflows/ci-npmcli-docs.yml new file mode 100644 index 0000000000000..f6540de9298f0 --- /dev/null +++ b/.github/workflows/ci-npmcli-docs.yml @@ -0,0 +1,163 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - @npmcli/docs + +on: + workflow_dispatch: + pull_request: + paths: + - docs/** + push: + branches: + - latest + - release/v* + paths: + - docs/** + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read + +jobs: + lint: + name: Lint + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace @npmcli/docs + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace @npmcli/docs + + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace @npmcli/docs + - name: Check Git Status + run: node scripts/git-dirty.js + + compare-docs: + name: Compare Docs + if: github.repository_owner == 'npm' && github.event_name == 'pull_request' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Build Docs + run: | + node . run build -w docs + mv man/ man-update/ + mv docs/output/ docs/output-update/ + mv docs/content/ docs/content-update/ + - name: Get Current Docs + run: | + git clean -fd + git checkout ${{ github.event.pull_request.base.ref }} + node scripts/resetdeps.js + node . run build -w docs + - name: Diff Man + run: diff -r --color=always man/ man-update/ || true + - name: Diff HTML + run: diff -r --color=always docs/output/ docs/output-update/ || true + - name: Diff Markdown + run: diff -r --color=always docs/content/ docs/content-update/ || true diff --git a/.github/workflows/ci-npmcli-mock-globals.yml b/.github/workflows/ci-npmcli-mock-globals.yml new file mode 100644 index 0000000000000..d8788376a2416 --- /dev/null +++ b/.github/workflows/ci-npmcli-mock-globals.yml @@ -0,0 +1,122 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - @npmcli/mock-globals + +on: + workflow_dispatch: + pull_request: + paths: + - mock-globals/** + push: + branches: + - latest + - release/v* + paths: + - mock-globals/** + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read + +jobs: + lint: + name: Lint + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace @npmcli/mock-globals + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace @npmcli/mock-globals + + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace @npmcli/mock-globals + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-npmcli-mock-registry.yml b/.github/workflows/ci-npmcli-mock-registry.yml new file mode 100644 index 0000000000000..8a71330f47fd8 --- /dev/null +++ b/.github/workflows/ci-npmcli-mock-registry.yml @@ -0,0 +1,122 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - @npmcli/mock-registry + +on: + workflow_dispatch: + pull_request: + paths: + - mock-registry/** + push: + branches: + - latest + - release/v* + paths: + - mock-registry/** + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read + +jobs: + lint: + name: Lint + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace @npmcli/mock-registry + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace @npmcli/mock-registry + + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace @npmcli/mock-registry + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-npmcli-smoke-tests.yml b/.github/workflows/ci-npmcli-smoke-tests.yml new file mode 100644 index 0000000000000..bdbf6575cb7fd --- /dev/null +++ b/.github/workflows/ci-npmcli-smoke-tests.yml @@ -0,0 +1,122 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - @npmcli/smoke-tests + +on: + workflow_dispatch: + pull_request: + paths: + - smoke-tests/** + push: + branches: + - latest + - release/v* + paths: + - smoke-tests/** + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read + +jobs: + lint: + name: Lint + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: npm run lint --ignore-scripts --workspace @npmcli/smoke-tests + - name: Post Lint + run: npm run postlint --ignore-scripts --workspace @npmcli/smoke-tests + + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Install Latest npm + uses: ./.github/actions/install-latest-npm + with: + node: ${{ steps.node.outputs.node-version }} + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: npm test --ignore-scripts --workspace @npmcli/smoke-tests + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml new file mode 100644 index 0000000000000..7268747be60f1 --- /dev/null +++ b/.github/workflows/ci-release.yml @@ -0,0 +1,272 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI - Release + +on: + workflow_dispatch: + inputs: + ref: + required: true + type: string + default: latest + workflow_call: + inputs: + ref: + required: true + type: string + check-sha: + required: true + type: string + +permissions: + contents: read + checks: write + +jobs: + lint-all: + name: Lint All + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Create Check + id: create-check + if: ${{ inputs.check-sha }} + uses: ./.github/actions/create-check + with: + name: "Lint All" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ inputs.check-sha }} + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: node . run lint --ignore-scripts --workspaces --include-workspace-root --if-present + - name: Post Lint + run: node . run postlint --ignore-scripts --workspaces --include-workspace-root --if-present + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.create-check.outputs.check-id }} + + test-all: + name: Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Create Check + id: create-check + if: ${{ inputs.check-sha }} + uses: ./.github/actions/create-check + with: + name: "Test All - ${{ matrix.platform.name }} - ${{ matrix.node-version }}" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ inputs.check-sha }} + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: node . test --ignore-scripts --workspaces --include-workspace-root --if-present + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.create-check.outputs.check-id }} + + smoke-tests: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + name: Smoke Tests - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Create Check + id: create-check + if: ${{ inputs.check-sha }} + uses: ./.github/actions/create-check + with: + name: "Smoke Tests - ${{ matrix.platform.name }} - ${{ matrix.node-version }}" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ inputs.check-sha }} + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Smoke Tests + run: ./scripts/smoke-tests.sh + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.create-check.outputs.check-id }} + + publish-dryrun: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + name: Publish Dry-Run - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Create Check + id: create-check + if: ${{ inputs.check-sha }} + uses: ./.github/actions/create-check + with: + name: "Publish Dry-Run - ${{ matrix.platform.name }} - ${{ matrix.node-version }}" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ inputs.check-sha }} + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Publish Dry-Run + run: node ./scripts/publish.js --pack-destination=$RUNNER_TEMP --smoke-publish=true + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.create-check.outputs.check-id }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67dcfb4d1d69a..04d0e03d884a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,97 +1,285 @@ -name: CI - cli +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CI on: workflow_dispatch: pull_request: - branches: - - '*' + paths-ignore: + - docs/** + - smoke-tests/** + - mock-globals/** + - mock-registry/** + - workspaces/** push: branches: - latest + - release/v* + paths-ignore: + - docs/** + - smoke-tests/** + - mock-globals/** + - mock-registry/** + - workspaces/** + schedule: + # "At 09:00 UTC (02:00 PT) on Monday" https://crontab.guru/#0_9_*_*_1 + - cron: "0 9 * * 1" + +permissions: + contents: read jobs: lint: + name: Lint + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: - node-version: 16.x + node-version: 22.x + check-latest: contains('22.x', '.x') cache: npm - - run: node bin/npm-cli.js run resetdeps - - run: node bin/npm-cli.js run lint + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Lint + run: node . run lint --ignore-scripts + - name: Post Lint + run: node . run postlint --ignore-scripts - check_docs: - runs-on: ubuntu-latest + test: + name: Test - ${{ matrix.platform.name }} - ${{ matrix.node-version }} + if: github.repository_owner == 'npm' + strategy: + fail-fast: false + matrix: + platform: + - name: Linux + os: ubuntu-latest + shell: bash + - name: macOS + os: macos-latest + shell: bash + - name: macOS + os: macos-13 + shell: bash + - name: Windows + os: windows-latest + shell: cmd + node-version: + - 20.17.0 + - 20.x + - 22.9.0 + - 22.x + exclude: + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.17.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.x + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: - node-version: 16.x + node-version: ${{ matrix.node-version }} + check-latest: contains(matrix.node-version, '.x') cache: npm - - run: make freshdocs - - run: node scripts/git-dirty.js + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Add Problem Matcher + run: echo "::add-matcher::.github/matchers/tap.json" + - name: Test + run: node . test --ignore-scripts + - name: Check Git Status + run: node scripts/git-dirty.js licenses: + name: Check Licenses + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: - node-version: 16.x + node-version: 22.x + check-latest: contains('22.x', '.x') cache: npm - - run: node bin/npm-cli.js run resetdeps - - run: node bin/npm-cli.js run licenses - + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Check Licenses + run: node . run licenses + smoke-tests: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + name: Smoke Tests + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Create Check + id: create-check + if: ${{ inputs.check-sha }} + uses: ./.github/actions/create-check with: - node-version: 16.x + name: "Smoke Tests" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ inputs.check-sha }} + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') cache: npm - - run: node bin/npm-cli.js run resetdeps - - run: node bin/npm-cli.js test -w smoke-tests --ignore-scripts - - name: git status - if: matrix.platform.os != 'windows-latest' + - name: Check Git Status run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Smoke Tests + run: ./scripts/smoke-tests.sh + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.create-check.outputs.check-id }} - test: - strategy: - fail-fast: false - matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x - platform: - - os: ubuntu-latest - shell: bash - - os: macos-latest - shell: bash - - os: windows-latest - shell: cmd - runs-on: ${{ matrix.platform.os }} + publish-dryrun: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + name: Publish Dry-Run + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest defaults: run: - shell: ${{ matrix.platform.shell }} + shell: bash steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: npm - - run: node bin/npm-cli.js run resetdeps - - run: node bin/npm-cli.js run test --ignore-scripts - - name: git status - if: matrix.platform.os != 'windows-latest' - run: node scripts/git-dirty.js + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Create Check + id: create-check + if: ${{ inputs.check-sha }} + uses: ./.github/actions/create-check + with: + name: "Publish Dry-Run" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ inputs.check-sha }} + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Publish Dry-Run + run: node ./scripts/publish.js --pack-destination=$RUNNER_TEMP --smoke-publish=true + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ steps.create-check.outputs.check-id }} + + windows-shims: + name: Windows Shims Tests + runs-on: windows-latest + defaults: + run: + shell: cmd + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Setup WSL + uses: Vampire/setup-wsl@v2.0.1 + - name: Setup Cygwin + uses: egor-tensin/setup-cygwin@v4.0.1 + with: + install-dir: C:\cygwin64 + - name: Run Windows Shims Tests + run: node . test --ignore-scripts -- test/bin/windows-shims.js --no-coverage + env: + WINDOWS_SHIMS_TEST: true + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000000000..03163a4da7721 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,41 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: CodeQL + +on: + push: + branches: + - latest + - release/v* + pull_request: + branches: + - latest + - release/v* + schedule: + # "At 10:00 UTC (03:00 PT) on Monday" https://crontab.guru/#0_10_*_*_1 + - cron: "0 10 * * 1" + +permissions: + contents: read + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: javascript + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/create-cli-deps-pr.yml b/.github/workflows/create-cli-deps-pr.yml deleted file mode 100644 index e0fd97fa206b3..0000000000000 --- a/.github/workflows/create-cli-deps-pr.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: "Create CLI Deps PR" - -on: - workflow_dispatch: - inputs: - npmVersion: - description: "6.x.x or latest" - required: true - default: 'latest' - dryRun: - description: "Do a dry run?" - default: '' - -jobs: - create-pull-request: - runs-on: ubuntu-latest - steps: - - name: Checkout npm/node - uses: actions/checkout@v3 - with: - fetch-depth: 0 - ref: main - repository: npm/node - token: ${{ secrets.NODE_PULL_REQUEST_TOKEN }} - - name: Setup git user - run: | - git config --global user.email "npm CLI robot" - git config --global user.name "npm-cli+bot@github.com" - - name: Sync upstream changes - uses: aormsby/Fork-Sync-With-Upstream-action@v3.2 - with: - target_sync_branch: main - target_repo_token: ${{ secrets.NODE_PULL_REQUEST_TOKEN }} - upstream_sync_branch: main - upstream_sync_repo: nodejs/node - upstream_pull_args: --ff-only - - name: Run dependency updates and create PR - env: - GITHUB_TOKEN: ${{ secrets.NODE_PULL_REQUEST_TOKEN }} - run: | - base_dir="$( pwd )"/ - dry_run="${{ github.event.inputs.dryRun }}" - npm_version="${{ github.event.inputs.npmVersion }}" - npm_tag="" - base_branch="" - - if [ "$npm_version" == "latest" ]; then - npm_tag=`npm view npm@latest version` - base_branch="main" - else - npm_tag="$npm_version" - base_branch="v14.x-staging" - fi - - npm_vtag="v$npm_tag" - npm_branch="npm-$npm_tag" - message="deps: upgrade npm to $npm_tag" - - git checkout -b "$npm_branch" - - echo "Cloning CLI repo" - gh repo clone npm/cli - - echo "Prepping CLI repo for release" - cd cli - git checkout "$npm_vtag" - make - make release - - echo "Removing old npm" - deps_dir="$base_dir"deps/ - cd "$deps_dir" - rm -rf npm/ - - echo "Copying new npm" - tar zxf "$base_dir"cli/release/"$npm_branch".tgz - - echo "Removing CLI workspace" - cd "$base_dir" - rm -rf cli - - git add -A deps/npm - git commit -m "$message" - git rebase --whitespace=fix main - - if [[ "$dry_run" == "true" ]]; then - git status - git show --summary - echo $message - echo $npm_branch - echo $base_branch - echo $npm_vtag - else - git push origin "$npm_branch" - gh release view "$npm_vtag" -R npm/cli --json body -q ".body" | \ - gh pr create -R nodejs/node -B "$base_branch" -H "npm:$npm_branch" -t "$message" -F - - fi diff --git a/.github/workflows/create-node-pr.yml b/.github/workflows/create-node-pr.yml new file mode 100644 index 0000000000000..3444c8c16fc30 --- /dev/null +++ b/.github/workflows/create-node-pr.yml @@ -0,0 +1,62 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: "Create Node PR" + +on: + workflow_dispatch: + inputs: + spec: + description: "The npm spec to create the PR from" + required: true + default: 'latest' + branch: + description: "The major node version to serve as the base of the PR. Should be `main` or a number like `18`, `19`, etc." + required: true + default: 'main' + dryRun: + description: "Setting this to anything will run all the steps except opening the PR" + +permissions: + contents: write + +jobs: + create-pull-request: + name: Create Node PR + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Checkout Node + uses: actions/checkout@v3 + with: + token: ${{ secrets.NODE_PULL_REQUEST_TOKEN }} + repository: nodejs/node + fetch-depth: 0 + path: node + - name: Create Node Pull Request + env: + GITHUB_TOKEN: ${{ secrets.NODE_PULL_REQUEST_TOKEN }} + run: | + DRY_RUN=$([ -z "${{ inputs.dryRun }}" ] && echo "" || echo "--dry-run") + node scripts/create-node-pr.js ${{ inputs.spec }} ${{ inputs.branch }} "$DRY_RUN" diff --git a/.github/workflows/node-integration.yml b/.github/workflows/node-integration.yml new file mode 100644 index 0000000000000..054b7f1b657a7 --- /dev/null +++ b/.github/workflows/node-integration.yml @@ -0,0 +1,495 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: nodejs integration + +on: + workflow_call: + inputs: + nodeVersion: + description: 'nodejs version' + required: true + type: string + default: nightly + npmVersion: + description: 'npm version' + required: true + type: string + default: git + installFlags: + description: 'extra flags to pass to npm install' + required: false + type: string + default: '' + + workflow_dispatch: + inputs: + nodeVersion: + description: 'nodejs version' + required: true + type: string + default: nightly + npmVersion: + description: 'npm version' + required: true + type: string + default: git + installFlags: + description: 'extra flags to pass to npm install' + required: false + type: string + default: '' + +jobs: + build-nodejs: + name: build nodejs@${{ inputs.nodeVersion }} npm@${{ inputs.npmVersion }} + runs-on: ubuntu-latest + outputs: + nodeVersion: ${{ steps.build-nodejs.outputs.nodeVersion }} + steps: + - name: setup ccache + uses: Chocobo1/setup-ccache-action@v1 + with: + override_cache_key: nodejs-${{ inputs.nodeVersion }} + - name: build nodejs + id: build-nodejs + run: | + echo "::group::setup" + set -eo pipefail + npmDir="${RUNNER_TEMP}/npm" + sourceDir="${RUNNER_TEMP}/src" + targetDir="${RUNNER_TEMP}/build" + npmFile="${RUNNER_TEMP}/npm.tgz" + sourceFile="${RUNNER_TEMP}/source.tgz" + targetFile="${RUNNER_TEMP}/build.tgz" + echo "::endgroup::" + + echo "::group::finding nodejs version matching ${{ inputs.nodeVersion }}" + if [[ "${{ inputs.nodeVersion }}" == "nightly" ]]; then + nodeVersion=$(curl -sSL https://nodejs.org/download/nightly/index.json | jq -r .[0].version) + nodeUrl="https://nodejs.org/download/nightly/${nodeVersion}/node-${nodeVersion}.tar.gz" + else + nodeVersion=$(curl -sSL https://nodejs.org/download/release/index.json | jq -r 'map(select(.version | test("^v${{ inputs.nodeVersion }}"))) | .[0].version') + if [[ -z "$nodeVersion" ]]; then + echo "::error ::unable to find released nodejs version matching: ${{ inputs.nodeVersion }}" + exit 1 + fi + nodeUrl="https://nodejs.org/download/release/${nodeVersion}/node-${nodeVersion}.tar.gz" + fi + echo "nodeVersion=${nodeVersion}" >> $GITHUB_OUTPUT + echo "::endgroup::" + + echo "::group::extracting source from $nodeUrl" + mkdir -p "$sourceDir" + curl -sSL "$nodeUrl" | tar xz -C "$sourceDir" --strip=1 + echo "::endgroup::" + + echo "::group::cloning npm" + mkdir -p "$npmDir" + git clone https://github.com/npm/cli.git "$npmDir" + npmVersion=$(cat "${npmDir}/package.json" | jq -r '"\(.version)-git"') + echo "::endgroup::" + + if [[ "${{ inputs.npmVersion }}" != "git" ]]; then + npmVersion="${{ inputs.npmVersion }}" + npmVersion="${npmVersion#v}" + echo "::group::checking out npm@${npmVersion}" + pushd "$npmDir" >/dev/null + taggedSha=$(git show-ref --tags "v${npmVersion}" | cut -d' ' -f1) + git reset --hard "$taggedSha" + publishedSha=$(curl -sSL https://registry.npmjs.org/npm | jq -r --arg ver "$npmVersion" '.versions[$ver].gitHead') + if [[ "$taggedSha" != "$publishedSha" ]]; then + echo "::warning ::git tag ($taggedSha) differs from published tag ($publishedSha)" + fi + popd >/dev/null + echo "::endgroup::" + fi + + echo "::group::packing npm release $npmVersion" + pushd "$npmDir" >/dev/null + node scripts/resetdeps.js + npmtarball="$(node . pack --loglevel=silent --json | jq -r .[0].filename)" + tar czf "$npmFile" -C "$npmDir" . + popd >/dev/null + echo "npm=$npmFile" >> $GITHUB_OUTPUT + echo "::endgroup::" + + echo "::group::updating nodejs bundled npm" + rm -rf "${sourceDir}/deps/npm" + mkdir -p "${sourceDir}/deps/npm" + tar xfz "${npmDir}/${npmtarball}" -C "${sourceDir}/deps/npm" --strip=1 + echo "::endgroup::" + + echo "::group::packing nodejs source" + tar cfz "$sourceFile" -C "$sourceDir" . + echo "source=$sourceFile" >> $GITHUB_OUTPUT + echo "::endgroup::" + + echo "::group::building nodejs" + mkdir -p "$targetDir" + pushd "$sourceDir" >/dev/null + ./configure --prefix="$targetDir" + make -j4 install + popd >/dev/null + echo "::endgroup::" + + echo "::group::packing nodejs build" + tar cfz "$targetFile" -C "$targetDir" . + echo "build=$targetFile" >> $GITHUB_OUTPUT + echo "::endgroup::" + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: nodejs-${{ steps.build-nodejs.outputs.nodeVersion }} + path: | + ${{ steps.build-nodejs.outputs.source }} + ${{ steps.build-nodejs.outputs.build }} + ${{ steps.build-nodejs.outputs.npm }} + + test-nodejs: + name: test nodejs + runs-on: ubuntu-latest + needs: + - build-nodejs + steps: + - name: setup ccache + uses: Chocobo1/setup-ccache-action@v1 + with: + override_cache_key: nodejs-${{ inputs.nodeVersion }} + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: nodejs-${{ needs.build-nodejs.outputs.nodeVersion }} + - name: test nodejs + run: | + set -e + tar xf source.tgz + ./configure + make -j4 test-only + + test-npm: + name: test npm + runs-on: ubuntu-latest + needs: + - build-nodejs + steps: + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: nodejs-${{ needs.build-nodejs.outputs.nodeVersion }} + path: ${{ runner.temp }} + - name: install nodejs ${{ needs.build-nodejs.outputs.nodeVersion }} + id: install + run: | + set -e + mkdir -p "${RUNNER_TEMP}/node" + tar xf "${RUNNER_TEMP}/build.tgz" -C "${RUNNER_TEMP}/node" + + mkdir -p "${RUNNER_TEMP}/npm" + tar xf "${RUNNER_TEMP}/npm.tgz" -C "${RUNNER_TEMP}/npm" + + echo "${RUNNER_TEMP}/node/bin" >> $GITHUB_PATH + echo "cache=$(npm config get cache)" >> $GITHUB_OUTPUT + - name: setup npm cache + uses: actions/cache@v3 + with: + path: ${{ steps.install.outputs.cache }} + key: npm-tests + - run: node --version + - run: npm --version + - name: test npm + run: | + echo "::group::setup" + set -e + cd "${RUNNER_TEMP}/npm" + echo "::endgroup::" + + echo "::group::npm run resetdeps" + node scripts/resetdeps.js + echo "::endgroup::" + + echo "::group::npm link" + node . link + echo "::endgroup::" + + STEPEXIT=0 + FINALEXIT=0 + + set +e + echo "::group::npm test" + node . test --ignore-scripts + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + echo "::warning ::npm test failed, exit: $STEPEXIT" + FINALEXIT=STEPEXIT + fi + echo "::endgroup::" + + for workspace in $(npm query .workspace | jq -r .[].name); do + echo "::group::npm test -w $workspace" + node . test -w $workspace --if-present --ignore-scripts + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + echo "::warning ::npm test -w $workspace failed, exit: $STEPEXIT" + FINALEXIT=STEPEXIT + fi + echo "::endgroup::" + done + + exit $FINALEXIT + + generate-matrix: + name: generate matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.generate-matrix.outputs.matrix }} + steps: + - name: install dependencies + run: | + npm install --no-save --no-audit --no-fund citgm npm-package-arg + - name: generate matrix + id: generate-matrix + uses: actions/github-script@v6 + env: + NODE_VERSION: "${{ inputs.nodeVersion }}" + INSTALL_FLAGS: "${{ inputs.installFlags }}" + with: + script: | + const { NODE_VERSION, INSTALL_FLAGS } = process.env + + const { execSync } = require('child_process') + const npa = require('npm-package-arg') + + const lookup = require('./node_modules/citgm/lib/lookup.json') + + const matchesKeyword = (value) => { + const keywords = ['ubuntu', 'debian', 'linux', 'x86', '>=11', '>=12', '>=16', '>=17'] + if (value === true || + (typeof value === 'string' && keywords.includes(value)) || + (Array.isArray(value) && keywords.some((keyword) => value.includes(keyword) || value.includes(true)))) { + return true + } + + return false + } + + // this is a manually updated list of packages that we know currently fail + const knownFailures = [ + 'body-parser', // json parsing error difference + 'clinic', // unknown, lots of failures + 'ember-cli', // timeout in nodejs ci, one failing test for us that timed out + 'express', // body-parser is what actually fails, it's used in a test + 'https-proxy-agent', // looks ssl related + 'node-gyp', // one test consistently times out + 'resolve', // compares results to require.resolve and fails, also missing inspector/promises + 'uuid', // tests that crypto.getRandomValues throws but it doesn't + 'weak', // doesn't seem to build in node >12 + 'mkdirp', // failing actions in own repo + 'undici', // test failure in node >=18, unable to root cause + ] + + if (NODE_VERSION === '18') { + knownFailures.push('multer') + } else if (NODE_VERSION === '19') { + // empty block + } else if (NODE_VERSION === 'nightly') { + // fails in node 20, looks like a streams issue + knownFailures.push('fastify') + // esbuild barfs on node 20.0.0-pre + knownFailures.push('serialport') + } + + // this is a manually updated list of packages that are flaky + const supplementalFlaky = [ + 'pino', // flaky test test/transport/core.test.js:401 + 'tough-cookie', // race condition test/node_util_fallback_test.js:87 + ] + + const matrix = [] + for (const package in lookup) { + const meta = lookup[package] + + // we omit npm from the matrix because its tests are run as their own job + if (matchesKeyword(meta.skip) || meta.yarn === true || package === 'npm') { + continue + } + + const install_flags = ['--no-audit', '--no-fund'] + if (meta.install) { + install_flags.push(meta.install.slice(1)) + } + if (INSTALL_FLAGS) { + install_flags.push(INSTALL_FLAGS) + } + const context = JSON.parse(execSync(`npm show ${package} --json`)) + const test = meta.scripts ? meta.scripts.map((script) => `npm run ${script}`) : ['npm test'] + + const repo = npa(meta.repo || context.repository.url).hosted + const details = {} + if (meta.useGitClone) { + details.repo = repo.https() + } else { + if (meta.ignoreGitHead) { + details.url = repo.tarball() + } else { + details.url = repo.tarball({ committish: context.gitHead }) + } + } + + const env = { ...meta.envVar, NODE_VERSION } + matrix.push({ + package, + version: context.version, + env, + install_flags: install_flags.join(' '), + commands: [...test], + flaky: matchesKeyword(meta.flaky) || supplementalFlaky.includes(package), + knownFailure: knownFailures.includes(package), + ...details, + }) + } + core.setOutput('matrix', matrix) + + citgm: + name: citgm - ${{ matrix.package }}@${{ matrix.version }} ${{ matrix.flaky && '(flaky)' || '' }} ${{ matrix.knownFailure && '(known failure)' || '' }} + runs-on: ubuntu-latest + needs: + - build-nodejs + - generate-matrix + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + steps: + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: nodejs-${{ needs.build-nodejs.outputs.nodeVersion }} + path: ${{ runner.temp }} + - name: install nodejs ${{ needs.build-nodejs.outputs.nodeVersion }} + id: install + run: | + set -e + mkdir -p "${RUNNER_TEMP}/node" + tar xf "${RUNNER_TEMP}/build.tgz" -C "${RUNNER_TEMP}/node" + echo "nodedir=${RUNNER_TEMP}/node" >> $GITHUB_OUTPUT + + echo "${RUNNER_TEMP}/node/bin" >> $GITHUB_PATH + echo "cache=$(npm config get cache)" >> $GITHUB_OUTPUT + - name: setup npm cache + uses: actions/cache@v3 + with: + path: ${{ steps.install.outputs.cache }} + key: npm-${{ matrix.package }} + - run: node --version + - run: npm --version + - name: download source + id: download + run: | + set -eo pipefail + TARGET_DIR="${RUNNER_TEMP}/${{ matrix.package }}" + mkdir -p "$TARGET_DIR" + echo "target=$TARGET_DIR" >> $GITHUB_OUTPUT + + if [[ -n "${{ matrix.repo }}" ]]; then + export GIT_TERMINAL_PROMPT=0 + export GIT_SSH_COMMAND="ssh -oBatchMode=yes" + git clone --recurse-submodules "${{ matrix.repo }}" "$TARGET_DIR" + elif [[ -n "${{ matrix.url }}" ]]; then + curl -sSL "${{ matrix.url }}" | tar xz -C "$TARGET_DIR" --strip=1 + fi + + if [[ -f "${TARGET_DIR}/package-lock.json" ]]; then + lockfileVersion=$(cat "${TARGET_DIR}/package-lock.json" | jq .lockfileVersion) + echo "lockfileVersion=$lockfileVersion" >> $GITHUB_OUTPUT + fi + - name: npm install ${{ matrix.install_flags }} + id: npm-install + working-directory: ${{ steps.download.outputs.target }} + run: | + set +e + npm install --nodedir="${{steps.install.outputs.nodedir }}" ${{ matrix.install_flags }} + exitcode=$? + if [[ $exitcode -ne 0 && "${{ matrix.knownFailure }}" == "true" ]]; then + echo "::warning ::npm install failed, exit $exitcode" + echo "failed=true" >> $GITHUB_OUTPUT + exit 0 + fi + exit $exitcode + - name: verify lockfileVersion unchanged + working-directory: ${{ steps.download.outputs.target }} + if: ${{ steps.download.outputs.lockfileVersion && steps.npm-install.outputs.failed != 'true' }} + run: | + if [[ -f "package-lock.json" ]]; then + newLockfileVersion=$(cat "package-lock.json" | jq .lockfileVersion) + if [[ "$newLockfileVersion" -ne "${{ steps.download.outputs.lockfileVersion }}" ]]; then + if [[ "${{ steps.download.outputs.lockfileVersion }}" -ne 1 ]]; then + echo "::error ::lockfileVersion changed from ${{ steps.download.outputs.lockfileVersion }} to $newLockfileVersion" + exit 1 + fi + fi + fi + - name: npm ls + working-directory: ${{ steps.download.outputs.target }} + if: ${{ steps.npm-install.outputs.failed != 'true' }} + run: | + npm ls + - name: ${{ join(matrix.commands, ' && ') }} + id: command + continue-on-error: true + timeout-minutes: 10 + env: ${{ matrix.env }} + working-directory: ${{ steps.download.outputs.target }} + if: ${{ steps.npm-install.outputs.failed != 'true' }} + run: | + set +e + FINALEXIT=0 + STEPEXIT=0 + + export npm_config_nodedir="${{ steps.install.outputs.nodedir }}" + + # inlining some patches to make tests run + if [[ "${{ matrix.package }}" == "undici" ]]; then + sed -i.bak 's/--experimental-wasm-simd //' package.json + rm -f package.json.bak + sed -i.bak 's/--experimental-wasm-simd//' .taprc + rm -f .taprc.bak + fi + + for row in $(echo '${{ toJSON(matrix.commands) }}' | jq -r '.[] | @base64'); do + FAILCOUNT=0 + COMMAND=$(echo "$row" | base64 --decode) + echo "::group::$COMMAND" + $COMMAND + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + FAILCOUNT=1 + if [[ "${{ matrix.knownFailure }}" == "true" || "$NODE_VERSION" == "nightly" ]]; then + echo "::warning ::$COMMAND failed, exit: $STEPEXIT" + elif [[ "${{ matrix.flaky }}" ]]; then + while [[ $STEPEXIT -ne 0 && $FAILCOUNT -lt 3 ]]; do + $COMMAND + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + ((FAILCOUNT=FAILCOUNT+1)) + fi + done + + if [[ $STEPEXIT -ne 0 ]]; then + echo "::warning ::$COMMAND still failing after $FAILCOUNT attempts, exit: $STEPEXIT" + fi + else + FINALEXIT=$STEPEXIT + echo "::error ::$COMMAND failed, exit: $STEPEXIT" + fi + fi + echo "::endgroup::" + done + exit $FINALEXIT + - name: Set conclusion + env: ${{ matrix.env }} + run: | + EXIT=1 + if [[ "${{ steps.command.outcome }}" == "success" || "${{ matrix.flaky }}" == "true" || "${{ matrix.knownFailure }}" == "true" || $NODE_VERSION == "nightly" ]]; then + EXIT=0 + fi + exit $EXIT diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000000000..d16202c1c0745 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,52 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Pull Request + +on: + pull_request: + types: + - opened + - reopened + - edited + - synchronize + +permissions: + contents: read + +jobs: + commitlint: + name: Lint Commits + if: github.repository_owner == 'npm' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node + with: + node-version: 22.x + check-latest: contains('22.x', '.x') + cache: npm + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Run Commitlint on Commits + id: commit + continue-on-error: true + run: npx --offline commitlint -V --from 'origin/${{ github.base_ref }}' --to ${{ github.event.pull_request.head.sha }} + - name: Run Commitlint on PR Title + if: steps.commit.outcome == 'failure' + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: echo "$PR_TITLE" | npx --offline commitlint -V diff --git a/.github/workflows/release-integration.yml b/.github/workflows/release-integration.yml new file mode 100644 index 0000000000000..5b49491731731 --- /dev/null +++ b/.github/workflows/release-integration.yml @@ -0,0 +1,34 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Release Integration + +on: + workflow_dispatch: + inputs: + releases: + required: true + type: string + description: 'A json array of releases. Required fields: publish: tagName, publishTag. publish check: pkgName, version' + workflow_call: + inputs: + releases: + required: true + type: string + description: 'A json array of releases. Required fields: publish: tagName, publishTag. publish check: pkgName, version' + +permissions: + contents: read + +jobs: + publish: + strategy: + fail-fast: false + matrix: + nodeVersion: + - 22 + - 23 + - nightly + uses: ./.github/workflows/node-integration.yml + with: + nodeVersion: ${{ matrix.nodeVersion }} + npmVersion: ${{ fromJSON(inputs.releases)[0].version }} diff --git a/.github/workflows/release-please-libnpmaccess.yml b/.github/workflows/release-please-libnpmaccess.yml deleted file mode 100644 index ce479107923ff..0000000000000 --- a/.github/workflows/release-please-libnpmaccess.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmaccess - -on: - push: - paths: - - workspaces/libnpmaccess/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmaccess - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmaccess" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmaccess@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmdiff.yml b/.github/workflows/release-please-libnpmdiff.yml deleted file mode 100644 index e2913fc56c251..0000000000000 --- a/.github/workflows/release-please-libnpmdiff.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmdiff - -on: - push: - paths: - - workspaces/libnpmdiff/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmdiff - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmdiff" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmdiff@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmexec.yml b/.github/workflows/release-please-libnpmexec.yml deleted file mode 100644 index 2b264d6ae8425..0000000000000 --- a/.github/workflows/release-please-libnpmexec.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmexec - -on: - push: - paths: - - workspaces/libnpmexec/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmexec - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmexec" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmexec@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmfund.yml b/.github/workflows/release-please-libnpmfund.yml deleted file mode 100644 index 5e9fe6d4fcbf9..0000000000000 --- a/.github/workflows/release-please-libnpmfund.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmfund - -on: - push: - paths: - - workspaces/libnpmfund/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmfund - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmfund" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmfund@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmhook.yml b/.github/workflows/release-please-libnpmhook.yml deleted file mode 100644 index 6325c37ff5404..0000000000000 --- a/.github/workflows/release-please-libnpmhook.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmhook - -on: - push: - paths: - - workspaces/libnpmhook/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmhook - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmhook" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmhook@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmorg.yml b/.github/workflows/release-please-libnpmorg.yml deleted file mode 100644 index a3ba63ca1b21e..0000000000000 --- a/.github/workflows/release-please-libnpmorg.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmorg - -on: - push: - paths: - - workspaces/libnpmorg/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmorg - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmorg" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmorg@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmpack.yml b/.github/workflows/release-please-libnpmpack.yml deleted file mode 100644 index 3bfaf8d413118..0000000000000 --- a/.github/workflows/release-please-libnpmpack.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmpack - -on: - push: - paths: - - workspaces/libnpmpack/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmpack - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmpack" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmpack@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmpublish.yml b/.github/workflows/release-please-libnpmpublish.yml deleted file mode 100644 index 78cd2b77e4211..0000000000000 --- a/.github/workflows/release-please-libnpmpublish.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmpublish - -on: - push: - paths: - - workspaces/libnpmpublish/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmpublish - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmpublish" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmpublish@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmsearch.yml b/.github/workflows/release-please-libnpmsearch.yml deleted file mode 100644 index a093f3ffcd537..0000000000000 --- a/.github/workflows/release-please-libnpmsearch.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmsearch - -on: - push: - paths: - - workspaces/libnpmsearch/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmsearch - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmsearch" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmsearch@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmteam.yml b/.github/workflows/release-please-libnpmteam.yml deleted file mode 100644 index 14158e253ed4a..0000000000000 --- a/.github/workflows/release-please-libnpmteam.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmteam - -on: - push: - paths: - - workspaces/libnpmteam/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmteam - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmteam" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmteam@${title##* }" - git push diff --git a/.github/workflows/release-please-libnpmversion.yml b/.github/workflows/release-please-libnpmversion.yml deleted file mode 100644 index 6a67bccbc46ec..0000000000000 --- a/.github/workflows/release-please-libnpmversion.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - libnpmversion - -on: - push: - paths: - - workspaces/libnpmversion/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/libnpmversion - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "libnpmversion" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: libnpmversion@${title##* }" - git push diff --git a/.github/workflows/release-please-npmcli-arborist.yml b/.github/workflows/release-please-npmcli-arborist.yml deleted file mode 100644 index 9e6886695f9e3..0000000000000 --- a/.github/workflows/release-please-npmcli-arborist.yml +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically added by @npmcli/template-oss. Do not edit. - -name: Release Please - @npmcli/arborist - -on: - push: - paths: - - workspaces/arborist/** - branches: - - main - - latest - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: google-github-actions/release-please-action@v3 - id: release - with: - release-type: node - monorepo-tags: true - path: workspaces/arborist - # name can be removed after this is merged - # https://github.com/google-github-actions/release-please-action/pull/459 - package-name: "@npmcli/arborist" - changelog-types: > - [ - {"type":"feat","section":"Features","hidden":false}, - {"type":"fix","section":"Bug Fixes","hidden":false}, - {"type":"docs","section":"Documentation","hidden":false}, - {"type":"deps","section":"Dependencies","hidden":false}, - {"type":"chore","hidden":true} - ] - - uses: actions/checkout@v3 - - name: Setup git user - run: | - git config --global user.email "npm-cli+bot@github.com" - git config --global user.name "npm CLI robot" - - uses: actions/setup-node@v3 - with: - node-version: 16.x - - name: Update npm to latest - run: npm i --prefer-online --no-fund --no-audit -g npm@latest - - run: npm -v - - name: Update package-lock.json and commit - if: steps.release.outputs.pr - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh pr checkout ${{ fromJSON(steps.release.outputs.pr).number }} - npm run resetdeps - title="${{ fromJSON(steps.release.outputs.pr).title }}" - # get the version from the pr title - # get everything after the last space - git commit -am "deps: @npmcli/arborist@${title##* }" - git push diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84c40e7745106..ee0e7f5bd9275 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,118 +1,302 @@ -name: Release - cli +# This file is automatically added by @npmcli/template-oss. Do not edit. + +name: Release on: - workflow_dispatch: - pull_request: - schedule: - # 08:00am UTC everyday: https://crontab.guru/#0_8_*_*_* - # https://dateful.com/convert/utc?t=8am - - cron: "0 8 * * *" + push: + branches: + - latest + - release/v* + +permissions: + contents: write + pull-requests: write + checks: write jobs: - lint-all: - if: | - github.event_name == 'schedule' || - github.event_name == 'workflow_dispatch' || - startsWith(github.head_ref, 'release/') + release: + outputs: + pr: ${{ steps.release.outputs.pr }} + pr-branch: ${{ steps.release.outputs.pr-branch }} + pr-number: ${{ steps.release.outputs.pr-number }} + pr-sha: ${{ steps.release.outputs.pr-sha }} + releases: ${{ steps.release.outputs.releases }} + comment-id: ${{ steps.create-comment.outputs.comment-id || steps.update-comment.outputs.comment-id }} + check-id: ${{ steps.create-check.outputs.check-id }} + name: Release + if: github.repository_owner == 'npm' runs-on: ubuntu-latest + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v3 - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Git User + run: | + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: - node-version: 16.x + node-version: 22.x + check-latest: contains('22.x', '.x') cache: npm - - run: node bin/npm-cli.js run resetdeps - - run: node bin/npm-cli.js run lint-all --ignore-scripts + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Release Please + id: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx --offline template-oss-release-please --branch="${{ github.ref_name }}" --backport="" --defaultTag="latest" + - name: Create Release Manager Comment Text + if: steps.release.outputs.pr-number + uses: actions/github-script@v7 + id: comment-text + with: + result-encoding: string + script: | + const { runId, repo: { owner, repo } } = context + const { data: workflow } = await github.rest.actions.getWorkflowRun({ owner, repo, run_id: runId }) + return['## Release Manager', `Release workflow run: ${workflow.html_url}`].join('\n\n') + - name: Find Release Manager Comment + uses: peter-evans/find-comment@v2 + if: steps.release.outputs.pr-number + id: found-comment + with: + issue-number: ${{ steps.release.outputs.pr-number }} + comment-author: 'github-actions[bot]' + body-includes: '## Release Manager' + - name: Create Release Manager Comment + id: create-comment + if: steps.release.outputs.pr-number && !steps.found-comment.outputs.comment-id + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ steps.release.outputs.pr-number }} + body: ${{ steps.comment-text.outputs.result }} + - name: Update Release Manager Comment + id: update-comment + if: steps.release.outputs.pr-number && steps.found-comment.outputs.comment-id + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.found-comment.outputs.comment-id }} + body: ${{ steps.comment-text.outputs.result }} + edit-mode: 'replace' + - name: Create Check + id: create-check + uses: ./.github/actions/create-check + if: steps.release.outputs.pr-sha + with: + name: "Release" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ steps.release.outputs.pr-sha }} - smoke-publish: - if: | - github.event_name == 'schedule' || - github.event_name == 'workflow_dispatch' || - startsWith(github.head_ref, 'release/') - strategy: - fail-fast: false - matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x - platform: - - os: ubuntu-latest - shell: bash - - os: macos-latest - shell: bash - # XXX: this should be possible in windows also - # but resetdeps cant be a bash script - runs-on: ${{ matrix.platform.os }} + update: + needs: release + outputs: + sha: ${{ steps.commit.outputs.sha }} + check-id: ${{ steps.create-check.outputs.check-id }} + name: Update - Release + if: github.repository_owner == 'npm' && needs.release.outputs.pr + runs-on: ubuntu-latest defaults: run: - shell: ${{ matrix.platform.shell }} + shell: bash steps: - - uses: actions/checkout@v3 - - name: Setup git user + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ needs.release.outputs.pr-branch }} + - name: Setup Git User run: | - git config --global user.email "ops+npm-cli@npmjs.com" - git config --global user.name "npm cli ops bot" - - name: Use Node.js 16.x - uses: actions/setup-node@v3 + git config --global user.email "npm-cli+bot@github.com" + git config --global user.name "npm CLI robot" + - name: Setup Node + uses: actions/setup-node@v4 + id: node with: - node-version: 16.x + node-version: 22.x + check-latest: contains('22.x', '.x') cache: npm - - name: Pack + - name: Check Git Status + run: node scripts/git-dirty.js + - name: Reset Deps + run: node scripts/resetdeps.js + - name: Create Release Manager Checklist Text + id: comment-text + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node . exec --offline -- template-oss-release-manager --pr="${{ needs.release.outputs.pr-number }}" --backport="" --defaultTag="latest" --lockfile + - name: Append Release Manager Comment + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ needs.release.outputs.comment-id }} + body: ${{ steps.comment-text.outputs.result }} + edit-mode: 'append' + - name: Run Post Pull Request Actions + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: node . run rp-pull-request --ignore-scripts --workspaces --include-workspace-root --if-present -- --pr="${{ needs.release.outputs.pr-number }}" --commentId="${{ needs.release.outputs.comment-id }}" + - name: Commit + id: commit + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git commit --all --amend --no-edit || true + git push --force-with-lease + echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT + - name: Create Check + id: create-check + uses: ./.github/actions/create-check + with: + name: "Update - Release" + check-name: "Release" + token: ${{ secrets.GITHUB_TOKEN }} + sha: ${{ steps.commit.outputs.sha }} + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ job.status }} + check_id: ${{ needs.release.outputs.check-id }} + + ci: + name: CI - Release + needs: [ release, update ] + if: needs.release.outputs.pr + uses: ./.github/workflows/ci-release.yml + with: + ref: ${{ needs.release.outputs.pr-branch }} + check-sha: ${{ needs.update.outputs.sha }} + + post-ci: + needs: [ release, update, ci ] + name: Post CI - Release + if: github.repository_owner == 'npm' && needs.release.outputs.pr && always() + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Get CI Conclusion + id: conclusion run: | - NPM_VERSION="$(node bin/npm-cli.js --version)-$GITHUB_SHA.0" - node bin/npm-cli.js version $NPM_VERSION --ignore-scripts - node bin/npm-cli.js run resetdeps - git clean -fd - node bin/npm-cli.js ls --production >/dev/null - node bin/npm-cli.js prune --production --no-save --no-audit --no-fund - node scripts/git-dirty.js - node bin/npm-cli.js pack --pack-destination=$RUNNER_TEMP - node bin/npm-cli.js install -g $RUNNER_TEMP/npm-$NPM_VERSION.tgz - node bin/npm-cli.js install -w smoke-tests --ignore-scripts --no-audit --no-fund - rm -rf {lib,bin,index.js} - SMOKE_PUBLISH_NPM=1 npm test -w smoke-tests --ignore-scripts - - test-all: - if: | - github.event_name == 'schedule' || - github.event_name == 'workflow_dispatch' || - startsWith(github.head_ref, 'release/') - strategy: - fail-fast: false - matrix: - node-version: - - 12.13.0 - - 12.x - - 14.15.0 - - 14.x - - 16.0.0 - - 16.x - platform: - - os: ubuntu-latest - shell: bash - - os: macos-latest - shell: bash - - os: windows-latest - shell: cmd - runs-on: ${{ matrix.platform.os }} + result="" + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then + result="failure" + elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then + result="cancelled" + else + result="success" + fi + echo "result=$result" >> $GITHUB_OUTPUT + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + conclusion: ${{ steps.conclusion.outputs.result }} + check_id: ${{ needs.update.outputs.check-id }} + + post-release: + needs: release + outputs: + comment-id: ${{ steps.create-comment.outputs.comment-id }} + name: Post Release - Release + if: github.repository_owner == 'npm' && needs.release.outputs.releases + runs-on: ubuntu-latest defaults: run: - shell: ${{ matrix.platform.shell }} + shell: bash steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: npm - - run: node bin/npm-cli.js run resetdeps - - run: node bin/npm-cli.js link -f --ignore-scripts - - run: node bin/npm-cli.js run test-all --ignore-scripts - - name: git status - if: matrix.platform.os != 'windows-latest' - run: node scripts/git-dirty.js + - name: Create Release PR Comment Text + id: comment-text + uses: actions/github-script@v7 + env: + RELEASES: ${{ needs.release.outputs.releases }} + with: + result-encoding: string + script: | + const releases = JSON.parse(process.env.RELEASES) + const { runId, repo: { owner, repo } } = context + const issue_number = releases[0].prNumber + const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${runId}` + + return [ + '## Release Workflow\n', + ...releases.map(r => `- \`${r.pkgName}@${r.version}\` ${r.url}`), + `- Workflow run: :arrows_counterclockwise: ${runUrl}`, + ].join('\n') + - name: Create Release PR Comment + id: create-comment + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ fromJSON(needs.release.outputs.releases)[0].prNumber }} + body: ${{ steps.comment-text.outputs.result }} + + release-integration: + needs: release + name: Release Integration + if: needs.release.outputs.releases + uses: ./.github/workflows/release-integration.yml + with: + releases: ${{ needs.release.outputs.releases }} + + post-release-integration: + needs: [ release, release-integration, post-release ] + name: Post Release Integration - Release + if: github.repository_owner == 'npm' && needs.release.outputs.releases && always() + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - name: Get Post Release Conclusion + id: conclusion + run: | + if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then + result="x" + elif [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then + result="heavy_multiplication_x" + else + result="white_check_mark" + fi + echo "result=$result" >> $GITHUB_OUTPUT + - name: Find Release PR Comment + uses: peter-evans/find-comment@v2 + id: found-comment + with: + issue-number: ${{ fromJSON(needs.release.outputs.releases)[0].prNumber }} + comment-author: 'github-actions[bot]' + body-includes: '## Release Workflow' + - name: Create Release PR Comment Text + id: comment-text + if: steps.found-comment.outputs.comment-id + uses: actions/github-script@v7 + env: + RESULT: ${{ steps.conclusion.outputs.result }} + BODY: ${{ steps.found-comment.outputs.comment-body }} + with: + result-encoding: string + script: | + const { RESULT, BODY } = process.env + const body = [BODY.replace(/(Workflow run: :)[a-z_]+(:)/, `$1${RESULT}$2`)] + if (RESULT !== 'white_check_mark') { + body.push(':rotating_light::rotating_light::rotating_light:') + body.push([ + '@npm/cli-team: The post-release workflow failed for this release.', + 'Manual steps may need to be taken after examining the workflow output.' + ].join(' ')) + body.push(':rotating_light::rotating_light::rotating_light:') + } + return body.join('\n\n').trim() + - name: Update Release PR Comment + if: steps.comment-text.outputs.result + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.found-comment.outputs.comment-id }} + body: ${{ steps.comment-text.outputs.result }} + edit-mode: 'replace' diff --git a/.gitignore b/.gitignore index 8f054d246da48..93b77383ab9a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,64 @@ -/* +# This file is automatically added by @npmcli/template-oss. Do not edit. -!/.github/ -!/bin/ -!/changelogs/ -!/docs/ -!/lib/ -!/node_modules/ -/node_modules/.bin/ -/node_modules/.cache/ -!/scripts/ -!/smoke-tests/ -!/tap-snapshots/ -!/test/ -!/workspaces/ +# ignore everything in the root +/* +!**/.gitignore +!/.commitlintrc.js +!/.eslint.config.js !/.eslintrc.js -!/.eslintrc.local.json +!/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitattributes +!/.github/ !/.gitignore !/.licensee.json !/.mailmap !/.npmrc +!/.prettierignore +!/.prettierrc.js +!/.release-please-manifest.json !/AUTHORS -!/CHANGELOG.md +!/bin/ +!/CHANGELOG* +!/CODE_OF_CONDUCT.md !/configure !/CONTRIBUTING.md +!/DEPENDENCIES.json +!/DEPENDENCIES.md +!/docs/ !/index.js -!/LICENSE -!/make.bat -!/Makefile +!/lib/ +!/LICENSE* +!/map.js +!/node_modules/ +/node_modules/.bin/ +/node_modules/.cache/ !/package-lock.json !/package.json -!/README.md +!/README* +!/release-please-config.json +!/scripts/ !/SECURITY.md -!/DEPENDENCIES.md +!/tap-snapshots/ +!/test/ +!/tsconfig.json +tap-testdir*/ +!/docs/ +!/smoke-tests/ +!/mock-globals/ +!/mock-registry/ +!/workspaces/ +/workspaces/* +!/workspaces/arborist/ +!/workspaces/config/ +!/workspaces/libnpmaccess/ +!/workspaces/libnpmdiff/ +!/workspaces/libnpmexec/ +!/workspaces/libnpmfund/ +!/workspaces/libnpmorg/ +!/workspaces/libnpmpack/ +!/workspaces/libnpmpublish/ +!/workspaces/libnpmsearch/ +!/workspaces/libnpmteam/ +!/workspaces/libnpmversion/ diff --git a/.npmrc b/.npmrc index e69de29bb2d1d..63cd3a3b11d06 100644 --- a/.npmrc +++ b/.npmrc @@ -0,0 +1,3 @@ +; This file is automatically added by @npmcli/template-oss. Do not edit. + +package-lock=true diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000000000..b8222e3ae26db --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,15 @@ +{ + ".": "11.9.0", + "workspaces/arborist": "9.2.0", + "workspaces/libnpmaccess": "10.0.3", + "workspaces/libnpmdiff": "8.1.0", + "workspaces/libnpmexec": "10.2.0", + "workspaces/libnpmfund": "7.0.14", + "workspaces/libnpmorg": "8.0.1", + "workspaces/libnpmpack": "9.1.0", + "workspaces/libnpmpublish": "11.1.3", + "workspaces/libnpmsearch": "9.0.1", + "workspaces/libnpmteam": "8.0.2", + "workspaces/libnpmversion": "8.0.3", + "workspaces/config": "10.6.0" +} diff --git a/AUTHORS b/AUTHORS index 29a062c7f6b64..0e28b6a2751b3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -846,3 +846,146 @@ MapleCCC <littlelittlemaple@gmail.com> Patryk Ludwikowski <psychoxivi@gmail.com> Takuya N <takninnovationresearch@gmail.com> Neel Dani <neeldani@github.com> +Anton Rieder <1301152+aried3r@users.noreply.github.com> +William Marlow <linuxdragon@gmail.com> +KevinBrother <1301239018@qq.com> +Kyle West <kyle-west@users.noreply.github.com> +Nathan Hughes <nathan@endor.ai> +Sandeep Meduru <73886592+sandeepmeduru@users.noreply.github.com> +Kid <44045911+kidonng@users.noreply.github.com> +Hugh Lilly <hughlilly@users.noreply.github.com> +Hafizur046 <hafijurrahman046@gmail.com> +Michael Rienstra <mrienstra@gmail.com> +Juan Heyns <juanheyns@gmail.com> +Michał Kurowski <michalkurowskix@gmail.com> +giovanniPepi <gtpepi@proton.me> +Winter <winter@winter.cafe> +shalvah <diakon.ng@gmail.com> +Albert 理斯特 <shuaizhexu@gmail.com> +Gennadiy Gashev <63790536+gennadiygashev@users.noreply.github.com> +Andrew Dawes <andrewsdawes@gmail.com> +sosoba <slawomir.osoba@coig.pl> +Aron <aron@master.co> +HenryNguyen5 <6404866+HenryNguyen5@users.noreply.github.com> +Eric Mutta <eric.mutta@gmail.com> +Peally <102741826+Peallyz@users.noreply.github.com> +James Shaw <jamesshaw1987@googlemail.com> +Brian DeHamer <bdehamer@github.com> +Santosh Heigrujam <heisantosh@github.com> +Rohan Mukherjee <roerohan@gmail.com> +Andreas Deininger <andreas@deininger.net> +Tuukka Hastrup <Tuukka.Hastrup@iki.fi> +David Tanner <darthtanner@gmail.com> +Jeff Mealo <jeffreymealo@gmail.com> +Kevin Rouchut <kevin.rouchut@gmail.com> +Stafford Williams <staff0rd@users.noreply.github.com> +CharlieWONG <charlie-wong@outlook.com> +James Henry <james@henry.sc> +Kashyap Kaki <30841403+kashyapkaki@users.noreply.github.com> +Darryl Tec <darryl.t@getjobber.com> +Michaël Bitard <bitard.michael@gmail.com> +may <63159454+m4rch3n1ng@users.noreply.github.com> +Rayyan Ul Haq <31252332+Rayyan98@users.noreply.github.com> +DaviDevMod <98312056+DaviDevMod@users.noreply.github.com> +Mike Ribbons <mribbons@gmail.com> +Rahul <122141535+rahulio96@users.noreply.github.com> +AaronHamilton965 <91709196+AaronHamilton965@users.noreply.github.com> +Emmanuel Ferdman <emmanuelferdman@gmail.com> +P-Chan <hello@0x50.io> +Rahul <rahulgithub96@gmail.com> +Francesco Sardone <francesco@airscript.it> +joaootavios <joaootaviostivi2@gmail.com> +Saquib <saquibkhan@github.com> +Dan Rose <danoftheroses@gmail.com> +Yuku Kotani <poyo0315@gmail.com> +Vlad-Ștefan Harbuz <291640+vladh@users.noreply.github.com> +siemhesda <143130929+siemhesda@users.noreply.github.com> +Carl <carl@carlfoster.io> +jpg619 <141764922+jpg619@users.noreply.github.com> +Frazer Smith <frazer.dev@outlook.com> +Aaron <2738518+NeonArray@users.noreply.github.com> +Wes Todd <wes@wesleytodd.com> +Mike McCready <66998419+MikeMcC399@users.noreply.github.com> +Piotr Kmieć <103869106+Gekuro@users.noreply.github.com> +Santoshraj2 <143222321+Santoshraj2@users.noreply.github.com> +Jamie Tanna <github@jamietanna.co.uk> +三咲智子 Kevin Deng <sxzz@sxzz.moe> +Manuel Spigolon <behemoth89@gmail.com> +Robin <robin.knipe@gmail.com> +Juan Julián Merelo Guervós <jjmerelo@gmail.com> +Le Michel <95184938+Ptitet@users.noreply.github.com> +Zearin <Zearin@users.noreply.github.com> +Jan T. Sott <git@idleberg.com> +Daniel Kaplan <tieTYT@gmail.com> +Andrii Romasiun <35810911+Blaumaus@users.noreply.github.com> +Rita Aktay <ritaaktay@gmail.com> +GoodDaisy <90915921+GoodDaisy@users.noreply.github.com> +Aleks Sobieraj <contact@aleks.tech> +Roberto Basile <robertobasile84@users.noreply.github.com> +rveerd <rutgervaneerd@hotmail.com> +Jason Ho <jasonho353@gmail.com> +Christian Oliff <christianoliff@pm.me> +Jamie King <hello@jamieking.me> +David LJ <mail@davidlj95.com> +Uiolee <22849383+uiolee@users.noreply.github.com> +Vinicius Lourenço <12551007+H4ad@users.noreply.github.com> +roni-berlin <72336831+roni-berlin@users.noreply.github.com> +Marc Bernard <59966492+mbtools@users.noreply.github.com> +Erik Williamson <me@erik.tw> +Hong Xu <hong@topbug.net> +Thomas Reggi <reggi@github.com> +Mottle <sgt_ah@163.com> +klm-turing <litaaba.a@turing.com> +klm <litaaba.a@turing.com> +Avinal Kumar <avinal@redhat.com> +milaninfy <111582375+milaninfy@users.noreply.github.com> +Reggi <reggi@github.com> +Norman Perrin <hey@nperrin.io> +Leo Balter <301201+leobalter@users.noreply.github.com> +drew4237 <57016082+drew4237@users.noreply.github.com> +AmirHossein Sakhravi <amirhosseinpr184@gmail.com> +Hiroo Ono <49257691+oikumene@users.noreply.github.com> +Sonny <47546413+sonsurim@users.noreply.github.com> +Alessandro Diez <demedos@users.noreply.github.com> +Rhys Evans <wheresrhys@gmail.com> +reggi <reggi@github.com> +btea <2356281422@qq.com> +Sander Aalbers <31731300+Sanderovich@users.noreply.github.com> +Chris Sidi <hashtagchris@github.com> +Maksim Koryukov <maxkoryukov@users.noreply.github.com> +Trevor Burnham <trevorburnham@gmail.com> +Michael Smith <owlstronaut@github.com> +terrainvidia <fixitic@gmail.com> +Tyler Albee <tyleralbee25@gmail.com> +William Briggs <37094383+billy-briggs-dev@users.noreply.github.com> +Gabriel Bouyssou <contact@stoneleaf.dev> +Carl Gay <carlgay@gmail.com> +liang.chen <liang.chen@ichef.com.tw> +Milan Meva <milaninfy@github.com> +Spencer Faith <45831293+13sfaith@users.noreply.github.com> +David Glasser <glasser@apollographql.com> +Alex Schwartz <alexschwartz01@gmail.com> +xaos7991 <44319098+xaos7991@users.noreply.github.com> +Tom Mrazauskas <tom@mrazauskas.de> +sam crochet <shmam@github.com> +tarekwfa0110 <109884541+tarekwfa0110@users.noreply.github.com> +Marc Bernard <marc@marcbernardtools.com> +Gareth Jones <3151613+G-Rath@users.noreply.github.com> +Aaron Jensen <atj@me.com> +Jeepsboucher <42554351+Jeepsboucher@users.noreply.github.com> +Arkadiusz Czekajski <aczekajski@gmail.com> +Liam Mitchell <git@liam.geek.nz> +Jon Jensen <jonj@netflix.com> +Josh Soref <2119212+jsoref@users.noreply.github.com> +Tejas Mahajan <59790915+Tejas242@users.noreply.github.com> +Max Black <husivm@gmail.com> +PiotrD <morph03lone@icloud.com> +khanhkhanhlele <namkhanh20xx@gmail.com> +Artur Signell <artur@vaadin.com> +Julian Flögel <flj2mu@bosch.com> +Max Black <husivm@google.com> +Yashwant Bezawada <yashwant_b@me.com> +Keegan Carruthers-Smith <keegan.csmith@gmail.com> +Saksham Malhotra <saksh.m.malhotra@gmail.com> +Kai <2644614+Schweinepriester@users.noreply.github.com> +Mateusz Burzyński <mateuszburzynski@gmail.com> diff --git a/CHANGELOG.md b/CHANGELOG.md index c6de53a087785..2760b0d1adc70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,1281 +1,716 @@ # Changelog -## v8.16.0 (2022-08-03) - +## [11.9.0](https://github.com/npm/cli/compare/v11.8.0...v11.9.0) (2026-02-04) ### Features - - * [`3c024ac`](https://github.com/npm/cli/commit/3c024ace60904c69e61da00e1fb56c0c1735804a) [#5000](https://github.com/npm/cli/pull/5000) feat: add npm query cmd ([@ruyadorno](https://github.com/ruyadorno)) ([@wraithgar](https://github.com/wraithgar)) - * [`703dbbf`](https://github.com/npm/cli/commit/703dbbf2a8149dff72c848d60600889a76779828) [#4860](https://github.com/npm/cli/pull/4860) feat: add --replace-registry-host=<npmjs|always|never> ([@fritzy](https://github.com/fritzy)) - +* [`f5f6cf7`](https://github.com/npm/cli/commit/f5f6cf7c9fc9315b96eb29c5c7d5ab63ad3a9122) [#8943](https://github.com/npm/cli/pull/8943) config: add --allow-git (@wraithgar) ### Bug Fixes - - * [`eac1bf2`](https://github.com/npm/cli/commit/eac1bf26f28e9e8fc07e1350c3d7b14a94005ebf) [#5164](https://github.com/npm/cli/pull/5164) fix(ls): when filtering workspaces, make sure the edge has a to before checking if its a workspace ([@nlf](https://github.com/nlf)) - * [`47cc95d`](https://github.com/npm/cli/commit/47cc95d9ffb37fc8ff62a1d5554eab16d303aa43) [#5227](https://github.com/npm/cli/pull/5227) fix(arborist): use the sourceReference root rather than the node root for overrides ([@nlf](https://github.com/nlf)) - * [`050284d`](https://github.com/npm/cli/commit/050284d2abb6aa91a0f9ffad5b0c4f074e5dbf6d) [#5233](https://github.com/npm/cli/pull/5233) fix(arborist): pass the edge to fromPath in order to determine correct path ([@nlf](https://github.com/nlf)) - * [`d315ead`](https://github.com/npm/cli/commit/d315ead7a7f6d531eb57cfa4350bb08949c60997) [#5243](https://github.com/npm/cli/pull/5243) fix: gracefully exit login and publish commands on Ctrl+C (SIGINT) in the new webAuthn flow ([@neeldani](https://github.com/neeldani)) - * [`ea44995`](https://github.com/npm/cli/commit/ea449954844f21abbf984e09e421f0e03485a535) [#5244](https://github.com/npm/cli/pull/5244) fix: properly find locally/globally/npxCache packages ([@wraithgar](https://github.com/wraithgar)) - * [`19f1497`](https://github.com/npm/cli/commit/19f1497322411f1566885bd53e63dc39f0df27ea) [#5244](https://github.com/npm/cli/pull/5244) fix: use binPaths ([@wraithgar](https://github.com/wraithgar)) - * [`3b30af2`](https://github.com/npm/cli/commit/3b30af25e93665f5aa21897910a65d7f26bbd066) [#5244](https://github.com/npm/cli/pull/5244) fix: fix exec tests and clean up workspace-location-msg ([@wraithgar](https://github.com/wraithgar)) - * [`8233fca`](https://github.com/npm/cli/commit/8233fca44321186c485964d26aa3c7c43eafff3d) [#5248](https://github.com/npm/cli/pull/5248) fix(arborist): fix bare attribute queries ([@darcyclarke](https://github.com/darcyclarke)) - * [`19a8346`](https://github.com/npm/cli/commit/19a834610d154f36748536b27aed13bfdb5ee748) [#5250](https://github.com/npm/cli/pull/5250) fix: properly find and run global scoped packages ([@wraithgar](https://github.com/wraithgar)) - -### Documentation - - * [`a6153cf`](https://github.com/npm/cli/commit/a6153cfd2b0764e69d103b33af6b42978b0403f4) [#5240](https://github.com/npm/cli/pull/5240) docs: Use the full proper name of Travis CI ([@tnir](https://github.com/tnir)) - +* [`2242f25`](https://github.com/npm/cli/commit/2242f2515826474a4fb8664fc679f1919ecaf458) [#8952](https://github.com/npm/cli/pull/8952) webauth: improve error messages around webauth in non-TTY (#8952) (@Andarist) ### Dependencies - - * [`fd030c8`](https://github.com/npm/cli/commit/fd030c86b1e01b7df1b9d73fda07496742a4737f) [#5245](https://github.com/npm/cli/pull/5245) deps: `npm-profile@6.2.1` - * [`c18dbc4`](https://github.com/npm/cli/commit/c18dbc4393491e02532d698351747307848d2e20) [#5244](https://github.com/npm/cli/pull/5244) deps: add `@npmcli/fs@2.1.1` - * [`cd6bafd`](https://github.com/npm/cli/commit/cd6bafdfbbd7a054709c11850b58f7dbc26eb8da) [#5244](https://github.com/npm/cli/pull/5244) deps: add `semver@7.3.7` - * [`d0be9a2`](https://github.com/npm/cli/commit/d0be9a2bb53e74b30e13751afd1f6924990c8422) [#5244](https://github.com/npm/cli/pull/5244) deps: `@npmcli/run-script@4.2.0` - * [`d55007d`](https://github.com/npm/cli/commit/d55007d9c535b17612a07a7a58cb6be94eedf77a) [#5247](https://github.com/npm/cli/pull/5247) deps: `@npmcli/query@1.1.1` - * [`c650a29`](https://github.com/npm/cli/commit/c650a29a664aa303d8b8761dcf50236baf4bb4ca) [#5241](https://github.com/npm/cli/pull/5241) deps: `@npmcli/arborist@5.4.0` - * [`4b7b48b`](https://github.com/npm/cli/commit/4b7b48befdca90e0114f4c64eac1d96fea1cc191) [#5246](https://github.com/npm/cli/pull/5246) deps: `libnpmexec@4.0.9` - -## v8.15.1 (2022-07-27) - -### Bug Fixes - - * [`9905d0e`](https://github.com/npm/cli/commit/9905d0e24c162c3f6cc006fa86b4c9d0205a4c6f) [#5197](https://github.com/npm/cli/pull/5197) fix: don't fail immediately if cache dir is not accessible ([@lukekarrys](https://github.com/lukekarrys)) - * [`0e3660e`](https://github.com/npm/cli/commit/0e3660eb39bd12a25517d745701bf841811b4623) [#5206](https://github.com/npm/cli/pull/5206) fix(init): allow for spec on scope-only arg ([@wraithgar](https://github.com/wraithgar)) - * [`62b95a0`](https://github.com/npm/cli/commit/62b95a04337661e3fa17093708b57000054442d9) [#5122](https://github.com/npm/cli/pull/5122) fix: allow hash character in paths ([@AgainPsychoX](https://github.com/AgainPsychoX)) - -### Documentation - - * [`f9abee7`](https://github.com/npm/cli/commit/f9abee79abe541226a249f50bdeec41317dd5712) [#5205](https://github.com/npm/cli/pull/5205) docs: update commit-ish default branch ([@dijonkitchen](https://github.com/dijonkitchen)) - * [`77bf2e1`](https://github.com/npm/cli/commit/77bf2e10236b72613101ac21d151f5974240f3aa) [#5218](https://github.com/npm/cli/pull/5218) docs: update npm-ls.md ([@MapleCCC](https://github.com/MapleCCC)) - * [`de40c31`](https://github.com/npm/cli/commit/de40c31d1fe7521ffbc4e22fd233b18eca149afe) [#5207](https://github.com/npm/cli/pull/5207) docs: sync ci params with install ([@wraithgar](https://github.com/wraithgar)) - * [`4d1d8a9`](https://github.com/npm/cli/commit/4d1d8a9561000064fe765ba31a3ad21832721c59) [#5221](https://github.com/npm/cli/pull/5221) docs: describe implicit workspace and prefix configuration ([@fritzy](https://github.com/fritzy)) ([@lukekarrys](https://github.com/lukekarrys)) ([@wraithgar](https://github.com/wraithgar)) - -### Dependencies - - * [`3bbb293`](https://github.com/npm/cli/commit/3bbb2931d09df66186108760353b2992171b057f) [#5223](https://github.com/npm/cli/pull/5223) deps: `@npmcli/arborist@5.3.1` - -## v8.15.0 (2022-07-20) - +* [`332c9f3`](https://github.com/npm/cli/commit/332c9f355ff7c9a9a9e624100a84130a9b7c4162) [#8960](https://github.com/npm/cli/pull/8960) `glob@13.0.1` +* [`eca02c7`](https://github.com/npm/cli/commit/eca02c78c993af969f837c55068239468794932a) [#8960](https://github.com/npm/cli/pull/8960) `minimatch@10.1.2` `@isaacs/brace-expansion@5.0.1` +* [`b3f8475`](https://github.com/npm/cli/commit/b3f847568bcc95e1466668476cf3dcf1a4993ac3) [#8951](https://github.com/npm/cli/pull/8951) `minipass-fetch@5.0.1` +* [`924171b`](https://github.com/npm/cli/commit/924171bf5794f16f688b8544912a6205ec1d1fb5) [#8951](https://github.com/npm/cli/pull/8951) `is-cidr@6.0.2` +* [`4404002`](https://github.com/npm/cli/commit/4404002a16502e710625c7668cbc9b3a932d6fe8) [#8951](https://github.com/npm/cli/pull/8951) `ci-info@4.4.0` +* [`b65af73`](https://github.com/npm/cli/commit/b65af737d8b05b1fec4540dfefeda4edd84e4aea) [#8951](https://github.com/npm/cli/pull/8951) `lru-cache@11.2.5` +* [`164c355`](https://github.com/npm/cli/commit/164c35580ba9dd26461d9bcdf0c993b7a0eee5a6) [#8951](https://github.com/npm/cli/pull/8951) `tar@7.5.7` +* [`a74a19c`](https://github.com/npm/cli/commit/a74a19ce52501e63af19db5a542b793c8ad2477b) [#8951](https://github.com/npm/cli/pull/8951) `node-gyp@12.2.0` +* [`e0bc212`](https://github.com/npm/cli/commit/e0bc2129c9ba0ba5ac61c07e07aefd99adff5fb6) [#8943](https://github.com/npm/cli/pull/8943) `pacote@21.1.0` +### Chores +* [`4a82a8f`](https://github.com/npm/cli/commit/4a82a8f2e8873853ce3ef2f91c459ec9fd5aebde) [#8951](https://github.com/npm/cli/pull/8951) dev dependency updates (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.2.0): `@npmcli/arborist@9.2.0` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.6.0): `@npmcli/config@10.6.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.1.0): `libnpmdiff@8.1.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.2.0): `libnpmexec@10.2.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.14): `libnpmfund@7.0.14` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.1.0): `libnpmpack@9.1.0` + +## [11.8.0](https://github.com/npm/cli/compare/v11.7.0...v11.8.0) (2026-01-21) ### Features - - * [`5ef53ee`](https://github.com/npm/cli/commit/5ef53eedad2871a32611f47001e1c9ca9b813c07) [#5160](https://github.com/npm/cli/pull/5160) feat: accept registry-scoped certfile and keyfile as credentials ([@jenseng](https://github.com/jenseng)) - * [`c8bdb4a`](https://github.com/npm/cli/commit/c8bdb4a2517cf69cccf9bfe5bd5375a5e3d4b5b1) feat: Support pure web authentication for commands ([@jumoel](https://github.com/jumoel)) ([@ljharb](https://github.com/ljharb)) ([@hfaulds](https://github.com/hfaulds)) ([@sandeepmeduru](https://github.com/sandeepmeduru)) - +* [`545e861`](https://github.com/npm/cli/commit/545e86154cc847766ceb356c3b1229d0573314c0) [#8828](https://github.com/npm/cli/pull/8828) show proxy environment variables in npm config list (Max Black) ### Bug Fixes - - * [`9c590fa`](https://github.com/npm/cli/commit/9c590fac8b9b649b3ab7203c48a0abce89e6f3e9) [#5172](https://github.com/npm/cli/pull/5172) fix: disable progress bar on publish ([@wraithgar](https://github.com/wraithgar)) - * [`2fa3271`](https://github.com/npm/cli/commit/2fa3271ba37a58767307cf0105424b3c0b4ba7fe) [#5196](https://github.com/npm/cli/pull/5196) fix: add missing ` in adduser warning ([@MylesBorins](https://github.com/MylesBorins)) - +* [`c2f784d`](https://github.com/npm/cli/commit/c2f784dbb5a83106558ff6ee7cc60bfc088ee9ed) [#8859](https://github.com/npm/cli/pull/8859) preserve serialNumber UUID in CycloneDX SBOM output #8837 (#8859) (@saksham-malhotra-27) +* [`f2c3af7`](https://github.com/npm/cli/commit/f2c3af7de1906b0517bba1e7e5b9247d57960d99) [#8840](https://github.com/npm/cli/pull/8840) more intuitive byte formatting boundaries for rounding (#8840) (@watilde) ### Documentation - - * [`7efad06`](https://github.com/npm/cli/commit/7efad065ed4e7bc56e14e94cdcb21f71d547dd9e) [#5168](https://github.com/npm/cli/pull/5168) docs: Update audit signatures cmd ([@feelepxyz](https://github.com/feelepxyz)) - * [`8ab5fca`](https://github.com/npm/cli/commit/8ab5fcabbf9317df096bc727c49a98cf87dda560) [#5171](https://github.com/npm/cli/pull/5171) docs: correct bundledDependencies -> bundleDependencies ([@nlf](https://github.com/nlf)) - +* [`3474ec3`](https://github.com/npm/cli/commit/3474ec35fb579873d20a4b6747983ca369d61592) [#8866](https://github.com/npm/cli/pull/8866) fix typo/logic error in npm-dedupe docs (#8866) (@Schweinepriester) +* [`5552e46`](https://github.com/npm/cli/commit/5552e465125c72e5d591fb6dff76c450e78c7c70) [#8797](https://github.com/npm/cli/pull/8797) npm-install: explain package-lock.json behavior (#8797) (@MaxBlack-dev, Max Black) ### Dependencies - - * [`64fe64b`](https://github.com/npm/cli/commit/64fe64b74bc66635771ae65003ccc67be5853929) [#5187](https://github.com/npm/cli/pull/5187) deps: `@npmcli/config@4.2.0` - * [`51b12a0`](https://github.com/npm/cli/commit/51b12a085e087609c99befccfd6a98ef8a9919d0) [#5187](https://github.com/npm/cli/pull/5187) deps: `npm-registry-fetch@13.3.0` - * [`3ae1b81`](https://github.com/npm/cli/commit/3ae1b814aa557ccb5b639a57715f67119754ea76) [#5190](https://github.com/npm/cli/pull/5190) deps: `make-fetch-happen@10.2.0` - -## v8.14.0 (2022-07-13) - +* [`f478ca0`](https://github.com/npm/cli/commit/f478ca0efb6e3dd7b32a3d7b51c896fdd5f5cd90) [#8919](https://github.com/npm/cli/pull/8919) `postcss-selector-parser@7.1.1` +* [`2b6a71f`](https://github.com/npm/cli/commit/2b6a71fae386e76e142dbab8e1bbc368d5ef0487) [#8919](https://github.com/npm/cli/pull/8919) `path-scurry@2.0.1` +* [`19096f2`](https://github.com/npm/cli/commit/19096f28883706a96a5146d4ec313dffbcc148f7) [#8919](https://github.com/npm/cli/pull/8919) `sigstore@4.1.0` +* [`e7f5d1e`](https://github.com/npm/cli/commit/e7f5d1e445f599c60791a849484c4c0167392d10) [#8919](https://github.com/npm/cli/pull/8919) `lru-cache@11.2.4` +* [`9e756ae`](https://github.com/npm/cli/commit/9e756ae2b51b8ae6b4661ab47a1401690b82ce31) [#8919](https://github.com/npm/cli/pull/8919) `ip-address@10.1.0` +* [`f951820`](https://github.com/npm/cli/commit/f95182001771ad5d52dfc57934d7ce1b97055b70) [#8919](https://github.com/npm/cli/pull/8919) `common-ancestor-path@2.0.0` +* [`7a949ad`](https://github.com/npm/cli/commit/7a949ad8967c93c6b38ed9d4ee469703d269eea5) [#8919](https://github.com/npm/cli/pull/8919) `@sigstore/verify@3.1.0` +* [`6979ce1`](https://github.com/npm/cli/commit/6979ce1e0455042038d953d1631eaf8ed5cbb90a) [#8919](https://github.com/npm/cli/pull/8919) `@sigstore/sign@4.1.0` +* [`b4a6a41`](https://github.com/npm/cli/commit/b4a6a41bcc17694047c85fd71b3155ab0cb29302) [#8919](https://github.com/npm/cli/pull/8919) `@sigstore/core@3.1.0` +* [`dc8a8e8`](https://github.com/npm/cli/commit/dc8a8e8090deffc244f836fde2328d6444fc8ffc) [#8919](https://github.com/npm/cli/pull/8919) `@sigstore/tuf@4.0.1` +* [`be221ea`](https://github.com/npm/cli/commit/be221eae2974a04fadb1c80fc423eb949e4df723) [#8919](https://github.com/npm/cli/pull/8919) `validate-npm-package-name@7.0.2` +* [`149823d`](https://github.com/npm/cli/commit/149823de9a920e8ea25ed11399d79d3758f592ef) [#8919](https://github.com/npm/cli/pull/8919) `diff@8.0.3` +* [`32b2001`](https://github.com/npm/cli/commit/32b2001f552078eac8f4ec863d704fc91346efe3) [#8919](https://github.com/npm/cli/pull/8919) `tar@7.5.4` +### Chores +* [`8f599df`](https://github.com/npm/cli/commit/8f599df6a3888fd9a06a5c17748657cbb45076c3) [#8919](https://github.com/npm/cli/pull/8919) pin jsdom to 27.0.0 (@wraithgar) +* [`f4f1161`](https://github.com/npm/cli/commit/f4f1161520e6c2b4b9038d4bd723ccef235e4273) [#8919](https://github.com/npm/cli/pull/8919) dev dependency updates (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.10): `@npmcli/arborist@9.1.10` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.5.0): `@npmcli/config@10.5.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.13): `libnpmdiff@8.0.13` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.12): `libnpmexec@10.1.12` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.13): `libnpmfund@7.0.13` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.13): `libnpmpack@9.0.13` + +## [11.7.0](https://github.com/npm/cli/compare/v11.6.4...v11.7.0) (2025-12-09) ### Features - - * [`f032e1c`](https://github.com/npm/cli/commit/f032e1c0ada062e2139c8f057b24abb1ce2e4a33) [#4827](https://github.com/npm/cli/pull/4827) feat: add npm audit signatures ([@feelepxyz](https://github.com/feelepxyz)) - * [`e8102c1`](https://github.com/npm/cli/commit/e8102c1aae65a18e41253fbcdffe2eff0bedae53) [#5076](https://github.com/npm/cli/pull/5076) feat: Add `web` auth type ([@jumoel](https://github.com/jumoel)) - * [`e9b4214`](https://github.com/npm/cli/commit/e9b4214e1ddb1ad79fe6826cf2ce7ba385f0c274) [#5094](https://github.com/npm/cli/pull/5094) feat(arborist): add support for dependencies script ([@nlf](https://github.com/nlf)) - * [`c6c4ba3`](https://github.com/npm/cli/commit/c6c4ba3b62e2a0896a48329f4c7e13d9e44a2f80) [#5149](https://github.com/npm/cli/pull/5149) feat: notify on adduser of upcoming cmds, login and register ([@fritzy](https://github.com/fritzy)) - * [`e58f02f`](https://github.com/npm/cli/commit/e58f02f5e8263bf86ae1f07a863098d445e6d0cd) [#5149](https://github.com/npm/cli/pull/5149) feat: warn on config --auth-type=sso/saml/oauth, undeprecate --auth-type ([@fritzy](https://github.com/fritzy)) - +* [`b380d15`](https://github.com/npm/cli/commit/b380d155050be21a9ee5ce08d50e184c06a13f36) [#8697](https://github.com/npm/cli/pull/8697) add deduping to notices unless in verbose+ mode (@owlstronaut) ### Bug Fixes - - * [`52ec5ec`](https://github.com/npm/cli/commit/52ec5ec61fd3b266efd7a9c5712dd6a769a2d365) [#5154](https://github.com/npm/cli/pull/5154) fix: properly open package arg repo inside workspace ([@wraithgar](https://github.com/wraithgar)) - +* [`4ebb831`](https://github.com/npm/cli/commit/4ebb831d93f13cc0b980754bf36abb2982b131f7) [#8839](https://github.com/npm/cli/pull/8839) updates hints to use cli paradigm (@owlstronaut) +* [`7896e51`](https://github.com/npm/cli/commit/7896e51812d6b3d7f204f32a92a6721affd257a5) [#8838](https://github.com/npm/cli/pull/8838) update the token list text (@owlstronaut) +* [`8ab8668`](https://github.com/npm/cli/commit/8ab86685baee32ef9428ab202f60b8b631e40ca9) [#8836](https://github.com/npm/cli/pull/8836) query: support package-lock-only in workspaces (@watilde) +* [`35e8d38`](https://github.com/npm/cli/commit/35e8d38ef880239b5dd2c61a8112f6aa11d10eab) [#8322](https://github.com/npm/cli/pull/8322) properly handle newlines with input when using the spinner (#8322) (@mbtools) +* [`0c0faae`](https://github.com/npm/cli/commit/0c0faae91d47fe1303de77aae7c6b38709972d2f) [#8780](https://github.com/npm/cli/pull/8780) adduser: improve email prompt (#8780) (@mbtools) ### Documentation +* [`7f2ab9d`](https://github.com/npm/cli/commit/7f2ab9dac62b56343204e13194f8f53421c19f3b) [#8810](https://github.com/npm/cli/pull/8810) scripts: replace deprecated prepublish and install examples with prepare (Max Black) +* [`91ebab7`](https://github.com/npm/cli/commit/91ebab777e5bfac6f34537e58c228209f7cc961a) [#8847](https://github.com/npm/cli/pull/8847) remove note about token create being disabled (@owlstronaut) +* [`2030250`](https://github.com/npm/cli/commit/2030250fbce3ac99ab116b6aee7e4d06f395134b) [#8822](https://github.com/npm/cli/pull/8822) scripts: clarify prepare script runs with --production (Max Black) +* [`33a50d7`](https://github.com/npm/cli/commit/33a50d7981492e71f533448d93fc586429e603fd) [#8821](https://github.com/npm/cli/pull/8821) scripts: update npm_package_* environment variables documentation (Max Black) +* [`50508f9`](https://github.com/npm/cli/commit/50508f9b18051761ec466de85cf0ecbee3130165) [#8793](https://github.com/npm/cli/pull/8793) package-json: add documentation for type field (#8793) (@MaxBlack-dev, Max Black) +* [`aa1dd7e`](https://github.com/npm/cli/commit/aa1dd7e974176225973bd1aa1683ef4ae3c418eb) [#8823](https://github.com/npm/cli/pull/8823) scripts: document that prepare scripts run concurrently in workspaces (Max Black) +* [`3f48487`](https://github.com/npm/cli/commit/3f48487aa343003bce0e55e1dfcd5fc8a9b3e198) [#8820](https://github.com/npm/cli/pull/8820) package-spec: fix alias syntax in examples (Max Black) +* [`dd104da`](https://github.com/npm/cli/commit/dd104da7d7c2ddd00731df716a082595df4a89b0) [#8812](https://github.com/npm/cli/pull/8812) version: add note about git version requirements (Max Black) +* [`58afdcc`](https://github.com/npm/cli/commit/58afdcc2094bd245c9916a02a62640a76ace8e72) [#8792](https://github.com/npm/cli/pull/8792) install: clarify prerelease version range behavior (Max Black) +* [`9f818e8`](https://github.com/npm/cli/commit/9f818e8cdfb4f10e36c7659e9aa86ddc4633e503) [#8795](https://github.com/npm/cli/pull/8795) npm-view: clarify object property access syntax and provide examples (Max Black) +* [`39c2f2e`](https://github.com/npm/cli/commit/39c2f2ef890b3af97aad85f71fbcb148f8965259) [#8791](https://github.com/npm/cli/pull/8791) add examples for command line flags including --prefix (Max Black) +* [`1298530`](https://github.com/npm/cli/commit/1298530af04f6982b7ba8b2cb677f23090fb806f) [#8790](https://github.com/npm/cli/pull/8790) clarify version field can be omitted in package-lock (Max Black) +* [`090b6ca`](https://github.com/npm/cli/commit/090b6cacb8228b2050e0e3746655441d2739a2ab) [#8794](https://github.com/npm/cli/pull/8794) npx: clarify that arguments are passed to executed command (Max Black) +* [`a864f80`](https://github.com/npm/cli/commit/a864f80799b407ee90f6482d5eb966dd66d13b56) [#8787](https://github.com/npm/cli/pull/8787) document gypfile field in package.json (Max Black) +* [`2fc689d`](https://github.com/npm/cli/commit/2fc689dfa0a69d66d7599997b4fa51a64111a619) [#8788](https://github.com/npm/cli/pull/8788) add field access patterns to npm view (Max Black) +* [`4850639`](https://github.com/npm/cli/commit/48506391c6248837cfd357aec28f5a3beb3cf184) [#8796](https://github.com/npm/cli/pull/8796) package-json: add examples for replacing dependencies with forks in overrides (Max Black) +* [`4864dd4`](https://github.com/npm/cli/commit/4864dd4289272e310065ccd43b254e1d3232d07f) [#8798](https://github.com/npm/cli/pull/8798) npm-install: document engines field priority when installing packages (Max Black) +* [`95d25cd`](https://github.com/npm/cli/commit/95d25cd97d88baa3ae11c69d5e69a1e850c39701) [#8799](https://github.com/npm/cli/pull/8799) package-json: clarify repository field normalization during publish (Max Black) +* [`a367f9b`](https://github.com/npm/cli/commit/a367f9bdac86f34769acfc427200e11f21e0c3ce) [#8800](https://github.com/npm/cli/pull/8800) package-lock-json: clarify that version field may be omitted for certain dependencies (Max Black) +* [`ffc9b71`](https://github.com/npm/cli/commit/ffc9b713b6a4ef762d6231ade70b008e9f296cb7) [#8801](https://github.com/npm/cli/pull/8801) npm-install: clarify --tag does not override package.json (#8801) (@MaxBlack-dev, Max Black) +* [`73688ca`](https://github.com/npm/cli/commit/73688ca5eb984d0027abcc72980cc287a892e5c8) [#8735](https://github.com/npm/cli/pull/8735) clarify npm version behavior with prerelease versions (#8735) (@yashwantbezawada) +* [`4a32606`](https://github.com/npm/cli/commit/4a32606ff50c71309455a0e3324d5ca90c1bbecc) [#8785](https://github.com/npm/cli/pull/8785) updates the token create documentation (#8785) (@owlstronaut, @wraithgar) +### Chores +* [`54929ce`](https://github.com/npm/cli/commit/54929cef8e26a4698234e5d2499a43b746569b12) [#8836](https://github.com/npm/cli/pull/8836) update baseline-browser-mapping (@watilde) - * [`9697f16`](https://github.com/npm/cli/commit/9697f16952b1bf02bb5455c36a1995277cbc0c97) [#5118](https://github.com/npm/cli/pull/5118) docs: typo in npm command ([@crisanmm](https://github.com/crisanmm)) - * [`da5a4ba`](https://github.com/npm/cli/commit/da5a4ba2c83af9a7e5e0fe38c32136adf396f557) [#5079](https://github.com/npm/cli/pull/5079) docs: update reference to deprecated spdx package ([@kachick](https://github.com/kachick)) - * [`25b3058`](https://github.com/npm/cli/commit/25b305830be0892bbbf0245aee2eebdb76ee2ce3) [#5043](https://github.com/npm/cli/pull/5043) docs: naming of files in example code should be consistent ([@xc1427](https://github.com/xc1427)) - * [`ac56fc4`](https://github.com/npm/cli/commit/ac56fc41bc2f91f51c8438f98893121e7a92ee46) [#5095](https://github.com/npm/cli/pull/5095) docs: document `dependencies` script ([@nlf](https://github.com/nlf)) ### Dependencies - * [`cb0db7c`](https://github.com/npm/cli/commit/cb0db7c3fd1d0a4c30db9f44e9ea9e69ec327fe8) [#5147](https://github.com/npm/cli/pull/5147) deps: `@npmcli/arborist@5.3.0` - * [`b8c0580`](https://github.com/npm/cli/commit/b8c0580e5df93aa519b3ec240bb85d59eee5ee37) [#5156](https://github.com/npm/cli/pull/5156) deps: `minipass@3.3.4` - * [`ad72611`](https://github.com/npm/cli/commit/ad726118755ef577cc0755499d35a5d3c74d54a6) [#5156](https://github.com/npm/cli/pull/5156) deps: `lru-cache@7.12.0` - * [`c94919d`](https://github.com/npm/cli/commit/c94919dd4874196d3a84eff4fab450a17dcd4867) [#5156](https://github.com/npm/cli/pull/5156) deps: `just-diff@5.0.3` - * [`18ddc57`](https://github.com/npm/cli/commit/18ddc57c7a54165d55c81b413ef9de981c790148) [#5156](https://github.com/npm/cli/pull/5156) deps: `just-diff-apply@5.3.1` - * [`a2d700b`](https://github.com/npm/cli/commit/a2d700b3cc7cebca2d1b0c16224af41da3689aaf) [#5156](https://github.com/npm/cli/pull/5156) deps: `npm-package-arg@9.1.0` - * [`99dc697`](https://github.com/npm/cli/commit/99dc697409e1eb42caaf0c0e38fa41635d89a871) [#5156](https://github.com/npm/cli/pull/5156) deps: `@npmcli/run-script@4.1.7` - * [`4a9f2dc`](https://github.com/npm/cli/commit/4a9f2dc9169fd330c4dcf2bad7890aaf4765bafa) [#5157](https://github.com/npm/cli/pull/5157) deps: `npm-registry-fetch@13.2.0` - * [`45a9bde`](https://github.com/npm/cli/commit/45a9bdee604073a3c5b4d3c6d90e22bf6672d6bf) [#5158](https://github.com/npm/cli/pull/5158) deps: `npm-profile@6.2.0` - -## v8.13.2 (2022-06-29) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.9): `@npmcli/arborist@9.1.9` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.4.5): `@npmcli/config@10.4.5` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.12): `libnpmdiff@8.0.12` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.11): `libnpmexec@10.1.11` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.12): `libnpmfund@7.0.12` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.12): `libnpmpack@9.0.12` +## [11.6.4](https://github.com/npm/cli/compare/v11.6.3...v11.6.4) (2025-11-25) ### Documentation - - * [`5be7d6e`](https://github.com/npm/cli/commit/5be7d6ea555bc25acaae1bfd309d64ce6693b084) [#5087](https://github.com/npm/cli/pull/5087) docs: add foreground-scripts to run-script page ([@ruyadorno](https://github.com/ruyadorno)) - -### Dependencies - - * [`dd62328`](https://github.com/npm/cli/commit/dd6232817d8c86afa4eb27ec1f62278893443163) [#5086](https://github.com/npm/cli/pull/5086) deps: `@npmcli/run-script@4.1.4` - * [`5546906`](https://github.com/npm/cli/commit/5546906977bae55c61a3874e2cbf10e28f2df4ea) [#5086](https://github.com/npm/cli/pull/5086) deps: `@npmcli/run-script@4.1.5` - * [`c7d5a69`](https://github.com/npm/cli/commit/c7d5a69080b5de6ed0f1cdde77e7d7a3c6b05158) [#5102](https://github.com/npm/cli/pull/5102) deps: `@npmcli/metavuln-calculator@3.1.1` - * [`7ce66b0`](https://github.com/npm/cli/commit/7ce66b017a611458b4ce385c13c446d89c23d777) [#5103](https://github.com/npm/cli/pull/5103) deps: `npm-packlist@5.1.1` - -## v8.13.1 (2022-06-23) - +* [`dfb83c7`](https://github.com/npm/cli/commit/dfb83c7887810abd555a2ab62a681858aabe2430) [#8749](https://github.com/npm/cli/pull/8749) add example for keywords field (#8749) (@MaxBlack-dev, Max Black) +* [`1b1e227`](https://github.com/npm/cli/commit/1b1e227d234dc6132832e1a65141260d3601838b) [#8750](https://github.com/npm/cli/pull/8750) remove outdated roadmap link (#8750) (@MaxBlack-dev, Max Black) +* [`1333d57`](https://github.com/npm/cli/commit/1333d576448c3868a29a65cf9cfb0d07ccfccd93) [#8752](https://github.com/npm/cli/pull/8752) clarify .npmrc naming convention for environment variable overrides (#8752) (@MaxBlack-dev) +* [`22cddb8`](https://github.com/npm/cli/commit/22cddb83f884c179258dabe6f20954246074c623) [#8755](https://github.com/npm/cli/pull/8755) add workspace dependencies example to workspaces (Max Black) +* [`17e154c`](https://github.com/npm/cli/commit/17e154cac7394b1baa3987c5b9b168762d9ba4ad) [#8756](https://github.com/npm/cli/pull/8756) standardize env vars to uppercase convention (Max Black) +* [`1e51a25`](https://github.com/npm/cli/commit/1e51a25d02508fbfa1d5d53602d35669115e55ff) [#8754](https://github.com/npm/cli/pull/8754) fix lifecycle event order for prepare script (Max Black) +* [`8d72bc9`](https://github.com/npm/cli/commit/8d72bc99dc705e04e25f24b05cac0f72934608b4) [#8753](https://github.com/npm/cli/pull/8753) add os, cpu, and funding fields to package-lock.json (Max Black) ### Dependencies - - * [`f59a114`](https://github.com/npm/cli/commit/f59a114ffe3d1f86ccb2e52a4432292ab76852cc) [#5064](https://github.com/npm/cli/pull/5064) deps: `@npmcli/run-script@4.1.3` - * fix: improves escaping of arguments for run-script, exec and npx ([@nlf](https://github.com/nlf)) - * [`236b4a2`](https://github.com/npm/cli/commit/236b4a21046c4cb43a1aaa8bde09f4cec2aa1fb6) [#5069](https://github.com/npm/cli/pull/5069) deps: `libnpmpack@4.1.2` - * [`0a6664d`](https://github.com/npm/cli/commit/0a6664d285b300f26764efaa2798a5b6045b95a1) [#5070](https://github.com/npm/cli/pull/5070) deps: `@npmcli/arborist@5.2.3` - * [`9f94049`](https://github.com/npm/cli/commit/9f94049f058687b916da726ea625b5fa68d0829d) [#5071](https://github.com/npm/cli/pull/5071) deps: `libnpmexec@4.0.8` - * [`8212363`](https://github.com/npm/cli/commit/8212363280f02c10f38e22c2dcd7e2abdf8bec35) [#5072](https://github.com/npm/cli/pull/5072) deps: `libnpmversion@3.0.6` - -## v8.13.0 (2022-06-22) - -### Features - - * [`06fd788`](https://github.com/npm/cli/commit/06fd788f79e16da04d6e96aa56416cd2698f057a) [#4960](https://github.com/npm/cli/pull/4960) feat: prompt before opening web-login URL when performing `login`/`adduser` ([@jumoel](https://github.com/jumoel)) - +* [`f56bb13`](https://github.com/npm/cli/commit/f56bb133bbd07f92b32f776f310bcd2aa26cbdfc) [#8779](https://github.com/npm/cli/pull/8779) `proc-log@6.1.0` (#8779) +* [`f963223`](https://github.com/npm/cli/commit/f96322350e497f90a54c8a1cfd952b3329f00492) [#8770](https://github.com/npm/cli/pull/8770) `proggy@4.0.0` +* [`f51e4aa`](https://github.com/npm/cli/commit/f51e4aaf06ac6703abe053a95fe25b8efca3c527) [#8770](https://github.com/npm/cli/pull/8770) `nopt@9.0.0` +* [`2d15040`](https://github.com/npm/cli/commit/2d15040390697cd78c9a9db3f0dbafab51a6e3e9) [#8770](https://github.com/npm/cli/pull/8770) `@npmcli/query@5.0.0` +* [`9d77b84`](https://github.com/npm/cli/commit/9d77b84ce961a28941af8b1a597a03e308828cd4) [#8770](https://github.com/npm/cli/pull/8770) `@npmcli/installed-package-contents@4.0.0` +* [`e2ac092`](https://github.com/npm/cli/commit/e2ac092fdab0ccbf3b20abbac7ff1ebb7cda9a88) [#8770](https://github.com/npm/cli/pull/8770) `read@5.0.1` +* [`6e5bfd9`](https://github.com/npm/cli/commit/6e5bfd93f5423ab0b89fd81493969af108438066) [#8770](https://github.com/npm/cli/pull/8770) `init-package-json@8.2.4` +* [`7f8e237`](https://github.com/npm/cli/commit/7f8e2376e289fc46410f68b7c686d3868ad837c0) [#8770](https://github.com/npm/cli/pull/8770) `p-map@7.0.4` +* [`a4aa218`](https://github.com/npm/cli/commit/a4aa218fa0a3cc5fc65bc516bc4c83fd4bac7fd8) [#8770](https://github.com/npm/cli/pull/8770) `npm-user-validate@4.0.0` +* [`6430446`](https://github.com/npm/cli/commit/643044690be9554366e0cbd5bc42afa77c4acc45) [#8770](https://github.com/npm/cli/pull/8770) `npm-audit-report@7.0.0` +* [`58650dc`](https://github.com/npm/cli/commit/58650dc089c74d090c51d1cb2f269f2d605dcca0) [#8770](https://github.com/npm/cli/pull/8770) `@npmcli/fs@5.0.0` +* [`4a11146`](https://github.com/npm/cli/commit/4a11146aa7e3d06c42793ef5daf3c19b37bdc7ce) [#8770](https://github.com/npm/cli/pull/8770) `glob@13.0.0` +* [`00511d4`](https://github.com/npm/cli/commit/00511d426a7f8d761700b315a0f660854a782353) [#8770](https://github.com/npm/cli/pull/8770) `@npmcli/cacache@20.0.3` +* [`224afa2`](https://github.com/npm/cli/commit/224afa27174f43695ac308de9f849529419a59b2) [#8770](https://github.com/npm/cli/pull/8770) `@npmcli/map-workspaces@5.0.3` +* [`664ac34`](https://github.com/npm/cli/commit/664ac341efef746ac47d08fcd8cc4cc105f1445b) [#8770](https://github.com/npm/cli/pull/8770) `@npmcli/package-json@7.0.4` +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.8): `@npmcli/arborist@9.1.8` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.4.4): `@npmcli/config@10.4.4` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.11): `libnpmdiff@8.0.11` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.10): `libnpmexec@10.1.10` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.11): `libnpmfund@7.0.11` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.11): `libnpmpack@9.0.11` + +## [11.6.3](https://github.com/npm/cli/compare/v11.6.2...v11.6.3) (2025-11-19) ### Bug Fixes - - * [`e03009f`](https://github.com/npm/cli/commit/e03009f4b423e85e498f1b1851fae785de91a73d) [#5042](https://github.com/npm/cli/pull/5042) fix: Add space to SemVer log message ([@dnicolson](https://github.com/dnicolson)) - * [`2953983`](https://github.com/npm/cli/commit/2953983ad5c5e830a5844be5d6d0a2b49863c05d) [#5035](https://github.com/npm/cli/pull/5035) fix(view): error on missing version ([@wraithgar](https://github.com/wraithgar)) - +* [`c6242d9`](https://github.com/npm/cli/commit/c6242d92e5227e0a772d9cfe474ea57776af79e0) [#8706](https://github.com/npm/cli/pull/8706) change npm profile to create tokens with GAT support (#8706) (@owlstronaut, @wraithgar) +* [`cbc6fa9`](https://github.com/npm/cli/commit/cbc6fa9cd7c582053be77a56677191313c7e8d98) [#8731](https://github.com/npm/cli/pull/8731) order of version information in error message (#8731) (@piotrd, @pd-be) +* [`11dbd7e`](https://github.com/npm/cli/commit/11dbd7e36287695801f02a43e53b24fc2d72a545) [#8709](https://github.com/npm/cli/pull/8709) display full token when creating authentication tokens (#8709) (@MaxBlack-dev, Max Black) +* [`49a4eef`](https://github.com/npm/cli/commit/49a4eefd613dbb60bcff3dac39129f70586d3cff) [#8676](https://github.com/npm/cli/pull/8676) use look behind regex for trailing slash stripping (#8676) (@wraithgar) +* [`b1aee62`](https://github.com/npm/cli/commit/b1aee62082d7b25ec07f64e906afd76840907fbd) [#8645](https://github.com/npm/cli/pull/8645) dep flag calculation (#8645) (@liamcmitchell) ### Documentation - - * [`69b5a96`](https://github.com/npm/cli/commit/69b5a9674e8c03219c3da088b35b8ec6dea69770) [#5048](https://github.com/npm/cli/pull/5048) docs: consolidate docs and help for package spec ([@wraithgar](https://github.com/wraithgar)) - * [`facba42`](https://github.com/npm/cli/commit/facba42bcd2a10722788f44de13ea46cde6c8e71) [#5030](https://github.com/npm/cli/pull/5030) docs: fix typo ([@westy92](https://github.com/westy92)) - -### Dependencies - - * [`2e50cb8`](https://github.com/npm/cli/commit/2e50cb83e84cf25fee93ba0ca5a0343fbdb33c41) [#5049](https://github.com/npm/cli/pull/5049) deps: `pacote@13.6.1` - * [`2c06cee`](https://github.com/npm/cli/commit/2c06ceee82dd813c0ae84cc0b09e6941cfc5533e) [#5049](https://github.com/npm/cli/pull/5049) deps: `@npmcli/run-script@4.1.0` - * [`61112f7`](https://github.com/npm/cli/commit/61112f718efd1dd31e56c98321b721692e19f032) [#5044](https://github.com/npm/cli/pull/5044) deps: `make-fetch-happen@10.1.8` - * [`01eef03`](https://github.com/npm/cli/commit/01eef035cf3c14136fc68da09b05b2ff9d73f2e1) [#5034](https://github.com/npm/cli/pull/5034) deps: `npm-profile@6.1.0` - * [`afa10c7`](https://github.com/npm/cli/commit/afa10c747e44bc6fa12cfeb3ece7a8e25ac4beae) [#5063](https://github.com/npm/cli/pull/5063) deps: `libnpmdiff@4.0.4` - * [`a5be4d6`](https://github.com/npm/cli/commit/a5be4d612ff1ce2b31e2246cf17308652e804ce1) [#5062](https://github.com/npm/cli/pull/5062) deps: `libnpmversion@3.0.5` - * [`3ea332b`](https://github.com/npm/cli/commit/3ea332b1cbc24c82c1ee7523b4fb37d295d47243) [#5061](https://github.com/npm/cli/pull/5061) deps: `libnpmpack@4.1.1` - * [`14a08d6`](https://github.com/npm/cli/commit/14a08d6ceb57130a2e4bdbad74ebf4944c92890e) [#5060](https://github.com/npm/cli/pull/5060) deps: `libnpmexec@4.0.7` - * [`1ab9776`](https://github.com/npm/cli/commit/1ab9776b5db12d2fd14bf379ce0ae715a49a68fa) [#5059](https://github.com/npm/cli/pull/5059) deps: `@npmcli/arborist@5.2.2` - -## v8.12.2 (2022-06-15) - -### Dependencies - - * [`053dffe`](https://github.com/npm/cli/commit/053dffe2adf4bc5cc33e98de63f9331f47be23ea) [#4986](https://github.com/npm/cli/pull/4986) deps: `make-fetch-happen@10.1.7` - * [`d404c8c`](https://github.com/npm/cli/commit/d404c8c9d3f86e7491070210a763e701582830e0) [#4985](https://github.com/npm/cli/pull/4985) deps: `cacache@16.1.1` - -## v8.12.1 (2022-06-02) - -### Bug Fixes - - * [`40c823c`](https://github.com/npm/cli/commit/40c823cc7d33d22f659a1ccceed440baacaaff1d) [#4982](https://github.com/npm/cli/pull/4982) fix: undeprecate and remove warnings for --global, -g, --local ([@fritzy](https://github.com/fritzy)) - -## v8.12.0 (2022-06-01) - -### Features - - * [`aee6fc8`](https://github.com/npm/cli/commit/aee6fc857458ac660bf90ecd0af94212c7269fd7) [#4892](https://github.com/npm/cli/pull/4892) feat(init): reify on init new workspace ([@ruyadorno](https://github.com/ruyadorno)) - * [`a8ae177`](https://github.com/npm/cli/commit/a8ae17775a24ccbaf4570530d7433e0d290b3793) [#4931](https://github.com/npm/cli/pull/4931) feat: Add `--auth-type=webauthn` flag ([@jumoel](https://github.com/jumoel)) - -### Bug Fixes - - * [`646b6b5`](https://github.com/npm/cli/commit/646b6b5d05de937beb8202e5fd8b8daf3e58e902) [#4963](https://github.com/npm/cli/pull/4963) fix(arborist): use rawSpec for bundled and shrinkwrapped deps ([@nlf](https://github.com/nlf)) - * [`fcc72dd`](https://github.com/npm/cli/commit/fcc72dd8791187f4b3d8705fb23c2744c83ef943) [#4929](https://github.com/npm/cli/pull/4929) fix(libnpmexec): fix bug not install latest pkg ([@jihunleekr](https://github.com/jihunleekr)) - +* [`ca53c21`](https://github.com/npm/cli/commit/ca53c21e8a0f0e659e891415735e184443b8f48b) [#8745](https://github.com/npm/cli/pull/8745) add workspace usage examples (#8745) (@MaxBlack-dev, Max Black) +* [`e71ca0e`](https://github.com/npm/cli/commit/e71ca0e1934b805c97485b39501653655a54c919) [#8746](https://github.com/npm/cli/pull/8746) add --save flag to documentation (#8746) (@MaxBlack-dev, Max Black) +* [`06510a8`](https://github.com/npm/cli/commit/06510a8720fa180e9ef9093d9caee2e85bbc5165) [#8683](https://github.com/npm/cli/pull/8683) add ignore-scripts option to npm version help and docs (#8683) (@Tejas242) ### Dependencies - - * [`a6b62b2`](https://github.com/npm/cli/commit/a6b62b2b0a3a22c4039b41b527ebdf8d06b0e1f1) [#4949](https://github.com/npm/cli/pull/4949) deps: `make-fetch-happen@10.1.6` - * [`fb4cc24`](https://github.com/npm/cli/commit/fb4cc249a413af1ecfe6b2be14b1d376f787a03d) [#4969](https://github.com/npm/cli/pull/4969) deps: `pacote@13.6.0` - * [`5b9688c`](https://github.com/npm/cli/commit/5b9688cfd832ae72071a89ee7a7c3a939df91c58) [#4971](https://github.com/npm/cli/pull/4971) deps: `glob@8.0.3` - * [`a8bfdd8`](https://github.com/npm/cli/commit/a8bfdd8e8f3939f9be1d61567ee19ed4834e64be) [#4972](https://github.com/npm/cli/pull/4972) deps: `minimatch@5.1.0` - * [`66981ec`](https://github.com/npm/cli/commit/66981ecf08b888fde9188c162cc928fff7d6d9d6) [#4973](https://github.com/npm/cli/pull/4973) deps: `tap@16.2.0` - * [`180a7e4`](https://github.com/npm/cli/commit/180a7e4647ded3d3bca5cd9a2fa8d264b7d2104a) [#4975](https://github.com/npm/cli/pull/4975) deps: `@npmcli/arborist@5.2.1` - * [`0886f7f`](https://github.com/npm/cli/commit/0886f7fa5ac641137052782698407ada230c611c) [#4976](https://github.com/npm/cli/pull/4976) deps: `libnpmexec@4.0.6` - -## v8.11.0 (2022-05-25) - -### Features - - * [`8898710`](https://github.com/npm/cli/commit/8898710220a3d84b0a9ea2a6d9cf880e50b94c9e) [#4879](https://github.com/npm/cli/pull/4879) feat: deprecated set-script, birthday, --global, and --local ([@fritzy](https://github.com/fritzy)) - * [`7307c8d`](https://github.com/npm/cli/commit/7307c8de388cd14c96c42d70b7e567ec343ad084) [#4940](https://github.com/npm/cli/pull/4940) feat(libnpmpack): bump pacote for better workspace awareness ([@nlf](https://github.com/nlf)) - +* [`7f72238`](https://github.com/npm/cli/commit/7f7223833b9f655ea82039cf389ed8d03fb3b212) [#8723](https://github.com/npm/cli/pull/8723) `cacache@20.0.2` +* [`7ac9db8`](https://github.com/npm/cli/commit/7ac9db8564312ffd57a8f622634d6f3de080c472) [#8723](https://github.com/npm/cli/pull/8723) `init-package-json@8.2.3` +* [`41e97c6`](https://github.com/npm/cli/commit/41e97c65d1d9d0bf7fa80d4b018ff4c051b1487b) [#8723](https://github.com/npm/cli/pull/8723) `validate-npm-package-name@7.0.0` +* [`6b1fbe1`](https://github.com/npm/cli/commit/6b1fbe1ef3db7f5782809abdcdf6c53ff7542330) [#8723](https://github.com/npm/cli/pull/8723) `npm-package-arg@13.0.2` +* [`aa1d486`](https://github.com/npm/cli/commit/aa1d486a4e4a82de16d4c63154a1b1a89ad09e6d) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/promise-spawn@9.0.1` +* [`599c819`](https://github.com/npm/cli/commit/599c819e525f235bab08c9395e7f357d4d2454a6) [#8723](https://github.com/npm/cli/pull/8723) `which@6.0.0` +* [`e49286e`](https://github.com/npm/cli/commit/e49286e2189dfe1604d957ccc415038957a64d19) [#8723](https://github.com/npm/cli/pull/8723) `ini@5.0.0` +* [`b7c9f96`](https://github.com/npm/cli/commit/b7c9f960063da93c8476739d1d6a717746255f93) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/promise-spawn@9.0.0` +* [`8cc9f70`](https://github.com/npm/cli/commit/8cc9f70c2769f068ea0ef77a602162cdd949998e) [#8723](https://github.com/npm/cli/pull/8723) `ssri@13.0.0` +* [`0b7274f`](https://github.com/npm/cli/commit/0b7274fa39edacc7103eacf2a72c074d01451284) [#8723](https://github.com/npm/cli/pull/8723) `pacote@21.0.4` +* [`59b3c6a`](https://github.com/npm/cli/commit/59b3c6adf5fb7e5c8e0f990ade7417677270057a) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/redact@4.0.0` +* [`578abad`](https://github.com/npm/cli/commit/578abad64d57dee1db460f1013c8514099e08136) [#8723](https://github.com/npm/cli/pull/8723) `node-gyp@12.1.0` +* [`89c4151`](https://github.com/npm/cli/commit/89c4151a9182ddb77eff1beaeaaa2c0279578a2e) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/git@7.0.1` +* [`c6d109d`](https://github.com/npm/cli/commit/c6d109d7ad59b0be87225917e6393bcc9838f64d) [#8723](https://github.com/npm/cli/pull/8723) `make-fetch-happen@15.0.3` +* [`34d8599`](https://github.com/npm/cli/commit/34d8599987bdd4335391394fc00f80b395fb3a7c) [#8723](https://github.com/npm/cli/pull/8723) `npm-registry-fetch@19.1.1` +* [`4811a86`](https://github.com/npm/cli/commit/4811a86a563d4361b15dd33415857410785a8e81) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/run-script@10.0.3` +* [`6cb77df`](https://github.com/npm/cli/commit/6cb77df37989cb7c165cb2c35c735fb12dc1385a) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/installed-package-contents@4.0.0` +* [`05ac7a7`](https://github.com/npm/cli/commit/05ac7a7ea2a4d258658537a19ba350e07df34fda) [#8723](https://github.com/npm/cli/pull/8723) `proc-log@6.0.0` +* [`0a74f6d`](https://github.com/npm/cli/commit/0a74f6d1d8643f3a089f6e63502df77e6e3038ff) [#8723](https://github.com/npm/cli/pull/8723) `bin-links@6.0.0` +* [`c02ce5c`](https://github.com/npm/cli/commit/c02ce5c132ea6e2b3d1941520228b10a10ad50f1) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/package-json@7.0.2` +* [`9c0cefa`](https://github.com/npm/cli/commit/9c0cefa8417d9e14ee19dd5e833019f0f99ce837) [#8723](https://github.com/npm/cli/pull/8723) `json-parse-even-better-errors@5.0.0` +* [`041b9b2`](https://github.com/npm/cli/commit/041b9b29b30c539c5bf8b8cd26ea2202f94862b3) [#8723](https://github.com/npm/cli/pull/8723) `parse-conflict-json@5.0.1` +* [`a1b0fea`](https://github.com/npm/cli/commit/a1b0feac64ff681b2aec6938eb5136f5e177a07a) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/name-from-folder@4.0.0` +* [`a085745`](https://github.com/npm/cli/commit/a085745da65662f5ce02933b99109f77542fc3bb) [#8723](https://github.com/npm/cli/pull/8723) `abbrev@4.0.0` +* [`00d9c7d`](https://github.com/npm/cli/commit/00d9c7da4173cd48c4295d32d4d8b47d3c8d8701) [#8723](https://github.com/npm/cli/pull/8723) `nopt@9.0.0` +* [`3404dca`](https://github.com/npm/cli/commit/3404dca3d986d1bf0de3e74cf8b61856778711c6) [#8723](https://github.com/npm/cli/pull/8723) `npm-install-checks@8.0.0` +* [`542fcf3`](https://github.com/npm/cli/commit/542fcf3eee92cc41e86838c97c4036a97d749155) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/node-gyp@5.0.0` +* [`89e14d3`](https://github.com/npm/cli/commit/89e14d376fa4d0dc3bb15fefcd932e3f949dbbaa) [#8723](https://github.com/npm/cli/pull/8723) `tar@7.5.2` +* [`5383f3a`](https://github.com/npm/cli/commit/5383f3aa680a028bc6f66ce76383d0259cc5a80d) [#8723](https://github.com/npm/cli/pull/8723) `npm-registry-fetch@19.1.0` +* [`1bb9a7d`](https://github.com/npm/cli/commit/1bb9a7d4ce779cca184d665c7ee4a4d3c9494168) [#8723](https://github.com/npm/cli/pull/8723) `npm-profile@12.0.1` +* [`de619a4`](https://github.com/npm/cli/commit/de619a40eccaa34eafb68b026bd6790ec38d2249) [#8723](https://github.com/npm/cli/pull/8723) `npm-pick-manifest@11.0.3` +* [`0e042ec`](https://github.com/npm/cli/commit/0e042ec4ed6eab646c645506378d409746b324bc) [#8723](https://github.com/npm/cli/pull/8723) `npm-packlist@10.0.3` +* [`2a3c338`](https://github.com/npm/cli/commit/2a3c33871471f327444a0e477199b3c1885683ed) [#8723](https://github.com/npm/cli/pull/8723) `node-gyp@11.5.0` +* [`b96e86c`](https://github.com/npm/cli/commit/b96e86cca5b0c63d98f3cfb92883f9a26882a1dd) [#8723](https://github.com/npm/cli/pull/8723) `minimatch@10.1.1` +* [`d347329`](https://github.com/npm/cli/commit/d347329513229ed2ba5954b996c322e9fd3d807d) [#8723](https://github.com/npm/cli/pull/8723) `exponential-backoff@3.1.3` +* [`d6830f4`](https://github.com/npm/cli/commit/d6830f4fac3b03090d97dce4cac26d5ff0b903d7) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/run-script@10.0.2` +* [`bcc7ec8`](https://github.com/npm/cli/commit/bcc7ec83ad69b2a80d98cfced94553d7f6e8c943) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/metavuln-calculator@9.0.3` +* [`7a419df`](https://github.com/npm/cli/commit/7a419df651b3d8d6fbf9571b80d2f4009e7a5e37) [#8723](https://github.com/npm/cli/pull/8723) `@npmcli/map-workspaces@5.0.1` +### Chores +* [`32bdd83`](https://github.com/npm/cli/commit/32bdd833f83cf2a939ed56eba1972d5d729c677c) [#8723](https://github.com/npm/cli/pull/8723) fix package-lock (@wraithgar) +* [`4bff14b`](https://github.com/npm/cli/commit/4bff14b536f70b998b38ca984cbcab94a6c65bf9) [#8670](https://github.com/npm/cli/pull/8670) write tarball to testDir (#8670) (@wraithgar) +* [`679486b`](https://github.com/npm/cli/commit/679486b095f262d478daa21629d01f68f0240c9b) [#8672](https://github.com/npm/cli/pull/8672) fix lockfile (#8672) (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.7): `@npmcli/arborist@9.1.7` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.4.3): `@npmcli/config@10.4.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.10): `libnpmdiff@8.0.10` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.9): `libnpmexec@10.1.9` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.10): `libnpmfund@7.0.10` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.10): `libnpmpack@9.0.10` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.1.3): `libnpmpublish@11.1.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmversion-v8.0.3): `libnpmversion@8.0.3` + +## [11.6.2](https://github.com/npm/cli/compare/v11.6.1...v11.6.2) (2025-10-08) ### Bug Fixes - - * [`400c80f`](https://github.com/npm/cli/commit/400c80f570228a2c0ffe09d6564cc88dc2f356c3) [#4913](https://github.com/npm/cli/pull/4913) fix(ci): remove node_modules post-validation ([@wraithgar](https://github.com/wraithgar)) - * [`124df81`](https://github.com/npm/cli/commit/124df81391ea5810b29d2af9500ed597f076d597) [#4910](https://github.com/npm/cli/pull/4910) fix: clean up npm cache tests ([@wraithgar](https://github.com/wraithgar)) - * [`ee3308a`](https://github.com/npm/cli/commit/ee3308a7a08799ec7e86237165ebaf278d9a4f9f) fix: remove dead code from get-identity ([@wraithgar](https://github.com/wraithgar)) - * [`357b0af`](https://github.com/npm/cli/commit/357b0af2af2b07a58d2d837043d1d77c9495d8b5) [#4917](https://github.com/npm/cli/pull/4917) fix: pass prefix and workspaces to libnpmpack ([@nlf](https://github.com/nlf)) - * [`0f89e07`](https://github.com/npm/cli/commit/0f89e0750f2ac9b5b4794b5718d047b5286283c8) [#4935](https://github.com/npm/cli/pull/4935) fix: add global getter to npm class ([@nlf](https://github.com/nlf)) - +* [`c54d1e9`](https://github.com/npm/cli/commit/c54d1e96f37e7fd4bf2645c4905535c9b3d93e3b) [#8633](https://github.com/npm/cli/pull/8633) progress bar code cleanup (#8633) (@wraithgar) +* [`d352e27`](https://github.com/npm/cli/commit/d352e27a679b1b7f4417ff5f7e3ac73fe13b403a) [#8629](https://github.com/npm/cli/pull/8629) do not redact notice logs going to stdout (#8629) (@wraithgar) +* [`5ac3678`](https://github.com/npm/cli/commit/5ac3678feabbb28b1d0d8a78838bf8da79f63c1b) [#8617](https://github.com/npm/cli/pull/8617) spelling in ./lib and ./test/lib (#8617) (@jsoref) +* [`9197995`](https://github.com/npm/cli/commit/9197995ef0b760738454f2d255c0683d0731b24c) [#8619](https://github.com/npm/cli/pull/8619) spelling (#8619) (@jsoref) +* [`dd884e3`](https://github.com/npm/cli/commit/dd884e371c1fba7e2b7c1540baec405dd30ac3e7) [#8618](https://github.com/npm/cli/pull/8618) spelling (#8618) (@jsoref) +* [`f6028e6`](https://github.com/npm/cli/commit/f6028e67aa1b2696e60e115d870182a026bae07f) [#8614](https://github.com/npm/cli/pull/8614) skip redacting urls meant for opening by the user (#8614) (@wraithgar, @jolyndenning) +* [`54fd27f`](https://github.com/npm/cli/commit/54fd27f9f6af54ca9fd11165aafbc8a13a38f39e) [#8602](https://github.com/npm/cli/pull/8602) refactor node.ideallyInert to node.inert (#8602) (@liamcmitchell) +* [`79e3c1e`](https://github.com/npm/cli/commit/79e3c1eff776ed7bbc76c1aa53b02cfdea40a6e7) [#8593](https://github.com/npm/cli/pull/8593) use @npmcli/package-json to normalize package data (@wraithgar) ### Documentation - - * [`83ed8d0`](https://github.com/npm/cli/commit/83ed8d0d4fb51716fa58608fa3c1ee8eb0a93571) [#4922](https://github.com/npm/cli/pull/4922) docs: update roadmap link in readme ([@OmriBarZik](https://github.com/OmriBarZik)) - * [`ed054d4`](https://github.com/npm/cli/commit/ed054d477093be3da96968d217c244cf2efd3ef1) [#4933](https://github.com/npm/cli/pull/4933) docs: fix broken link in changelog ([@yonran](https://github.com/yonran)) - -### Dependencies - - * [`632ce87`](https://github.com/npm/cli/commit/632ce87bbd23707cba2c49b95d5db755b3d68638) [#4915](https://github.com/npm/cli/pull/4915) deps: `cacache@16.1.0` - * [`7b2b77a`](https://github.com/npm/cli/commit/7b2b77adca730e516c1b187092374a01de7f0f56) [#4915](https://github.com/npm/cli/pull/4915) deps: `make-fetch-happen@10.1.5` - * [`f3b0a24`](https://github.com/npm/cli/commit/f3b0a2407c7e213b1660ef7024c861dcb0eacb50) [#4915](https://github.com/npm/cli/pull/4915) deps: `pacote@13.4.1` - * [`0df3011`](https://github.com/npm/cli/commit/0df3011ec59ba76c12fb8fbfb29ff4d601cc4bdb) [#4915](https://github.com/npm/cli/pull/4915) deps: `ssri@9.0.1` - * [`dc38ab9`](https://github.com/npm/cli/commit/dc38ab96fca99069449e6c5e492062b94a1264b6) [#4919](https://github.com/npm/cli/pull/4919) deps: `npm-packlist@5.0.4` - * [`353e2f9`](https://github.com/npm/cli/commit/353e2f9dc60a5d319d4105822a9e0b2ddbf82bc0) [#4940](https://github.com/npm/cli/pull/4940) deps: `pacote@13.5.0 npm-packlist@5.1.0` - * [`f4d4126`](https://github.com/npm/cli/commit/f4d41265931c3c2eee433e27f4535c7a209e69fa) [#4941](https://github.com/npm/cli/pull/4941) deps: `libnpmpack@4.1.0` - -## v8.10.0 (2022-05-11) - -### Features - - * [`911f55d`](https://github.com/npm/cli/commit/911f55dc6ac3672f48740d0675f67c934c01aaf4) [#4864](https://github.com/npm/cli/pull/4864) feat: add --iwr alias for --include-workspace-root ([@fritzy](https://github.com/fritzy)) - * [`bfb8bcc`](https://github.com/npm/cli/commit/bfb8bccbe83753e527b43c8a3889696087dbe8f1) [#4874](https://github.com/npm/cli/pull/4874) feat: add flag --omit-lockfile-registry-resolved ([@fritzy](https://github.com/fritzy)) ([Caleb ツ Everett](mailto:calebev@amazon.com)) - -### Bug Fixes - - * [`48d2db6`](https://github.com/npm/cli/commit/48d2db6037487fd782f67bbcd2cf12e009ece17b) [#4862](https://github.com/npm/cli/pull/4862) fix: remove test coverage map ([@wraithgar](https://github.com/wraithgar)) - * [`38cf29a`](https://github.com/npm/cli/commit/38cf29a0054544c575b6bce953f1d433dbb6a3b5) [#4868](https://github.com/npm/cli/pull/4868) fix: cleanup star/unstar ([@wraithgar](https://github.com/wraithgar)) - * [`5baa4a7`](https://github.com/npm/cli/commit/5baa4a7c64319485604982f9060702a7cee8a85c) [#4857](https://github.com/npm/cli/pull/4857) fix: consolidate bugs, docs, repo command logic ([@wraithgar](https://github.com/wraithgar)) - * [`5a50762`](https://github.com/npm/cli/commit/5a50762faa37ae5964ae6f12595b20b367056c0a) [#4875](https://github.com/npm/cli/pull/4875) fix(arborist): link deps lifecycle scripts ([@ruyadorno](https://github.com/ruyadorno)) - +* [`0469c5e`](https://github.com/npm/cli/commit/0469c5ebec7d4998f957d7c69702796af6797c57) [#8639](https://github.com/npm/cli/pull/8639) rewrap markdown (#8639) (@jsoref) +* [`9ceb9c1`](https://github.com/npm/cli/commit/9ceb9c1d18d2c52a5c3328b4939e979baca7edea) [#8636](https://github.com/npm/cli/pull/8636) rewrap markdown (#8636) (@jsoref) +* [`6324370`](https://github.com/npm/cli/commit/63243709429ab7d95f360caebce6c31946d41857) [#8616](https://github.com/npm/cli/pull/8616) fix spelling (#8616) (@jsoref) +* [`1b0429a`](https://github.com/npm/cli/commit/1b0429af3b837e12fc5063d153393641435a856d) [#8607](https://github.com/npm/cli/pull/8607) Fix spelling (#8607) (@jsoref) +* [`7fbe07a`](https://github.com/npm/cli/commit/7fbe07a6ad9eff81a41776fb6068fce9e7b557d1) [#8603](https://github.com/npm/cli/pull/8603) clean up deprecated `npm access` commands (#8603) (@jsoref) ### Dependencies - - * [`d58bf40`](https://github.com/npm/cli/commit/d58bf40abf7c3ff8ae400f50e5e5a19c33138707) [#4856](https://github.com/npm/cli/pull/4856) deps: `npm-packlist@5.0.3` - * [`86f443e`](https://github.com/npm/cli/commit/86f443e97aa58c1a06b8eb6f523656274234bb71) [#4872](https://github.com/npm/cli/pull/4872) deps: `make-fetch-happen@10.1.3` - * [`f9984e6`](https://github.com/npm/cli/commit/f9984e64e714937fa69f14850a1d3ed7ccfc934c) [#4880](https://github.com/npm/cli/pull/4880) deps: `@npmcli/arborist@5.2.0` - * [`ba59915`](https://github.com/npm/cli/commit/ba599154dc8ea9f424410fb7dc382d5829215920) [#4881](https://github.com/npm/cli/pull/4881) deps: `socks-proxy-agent@6.2.0` - * [`c0806ba`](https://github.com/npm/cli/commit/c0806ba2b325456199069b245446c8a86e7feae2) [#4881](https://github.com/npm/cli/pull/4881) deps: `http-proxy-agent@5.0.1` - * [`cc7be6b`](https://github.com/npm/cli/commit/cc7be6b8b63a7314066e8763589a57e5a6e77d30) [#4881](https://github.com/npm/cli/pull/4881) deps: `is-core-module@2.9.0` - * [`0432c7d`](https://github.com/npm/cli/commit/0432c7d8a22ddbfdf238c2b22dd3c7bd263e2d6c) [#4881](https://github.com/npm/cli/pull/4881) deps: `lru-cache@7.9.0` - * [`5778820`](https://github.com/npm/cli/commit/57788204646a6aa5a384630a5640bf00efa25ce0) [#4881](https://github.com/npm/cli/pull/4881) deps: `just-diff@5.0.2` - * [`893dd00`](https://github.com/npm/cli/commit/893dd0066e2315f0d9937fe05879957e1446b755) [#4881](https://github.com/npm/cli/pull/4881) deps: `ip@1.1.8` - * [`6ab85bd`](https://github.com/npm/cli/commit/6ab85bd5df88ade023f7e4895d07a39228d23a33) [#4881](https://github.com/npm/cli/pull/4881) deps: `builtins@5.0.1` - -## v8.9.0 (2022-05-04) - -### Features - - * [`62af3a1`](https://github.com/npm/cli/commit/62af3a1dc003cf23c563d18437be81f61e65cb49) [#4835](https://github.com/npm/cli/pull/4835) feat: make npm owner workspace aware ([@wraithgar](https://github.com/wraithgar)) - +* [`fa7cc6f`](https://github.com/npm/cli/commit/fa7cc6f9338e6d9c0be1dbe7002d683fd389794a) [#8662](https://github.com/npm/cli/pull/8662) `ci-info@4.3.1` (#8662) +* [`b05461b`](https://github.com/npm/cli/commit/b05461b6b16f262179efdea45fccf388f88ddc51) [#8663](https://github.com/npm/cli/pull/8663) `@sigstore/sign@4.0.1` (#8663) +* [`c31de22`](https://github.com/npm/cli/commit/c31de22970930bedf43c1f92ff771bccf435271b) [#8661](https://github.com/npm/cli/pull/8661) downgrade ci-info to 4.3.0 (#8661) (@wraithgar) +* [`c5191b5`](https://github.com/npm/cli/commit/c5191b542a9a49edf121be7127110e2958309df0) [#8659](https://github.com/npm/cli/pull/8659) `ci-info@4.3.1` +* [`f255c92`](https://github.com/npm/cli/commit/f255c92abf6281af7b7f148b9683194ad09d9ba9) [#8659](https://github.com/npm/cli/pull/8659) `hosted-git-info@9.0.2` +* [`bdaf323`](https://github.com/npm/cli/commit/bdaf323a160e47862ca228fa82e90555dcb567a8) [#8659](https://github.com/npm/cli/pull/8659) `is-cidr@6.0.1` +* [`a33f106`](https://github.com/npm/cli/commit/a33f1062c3cacd889cea0d989de77a704931f54c) [#8659](https://github.com/npm/cli/pull/8659) `lru-cache@11.2.2` +* [`8044e07`](https://github.com/npm/cli/commit/8044e07000c2b00e7db33693b1f7fb8e96978e02) [#8659](https://github.com/npm/cli/pull/8659) `npm-package-arg@13.0.1` +* [`f577504`](https://github.com/npm/cli/commit/f5775043e7d2739256db20937ae072a1b1b3fb57) [#8659](https://github.com/npm/cli/pull/8659) `npm-packlist@10.0.2` +* [`9aa4fa6`](https://github.com/npm/cli/commit/9aa4fa6687ee85a5c0085b3c3c96330eb9a9c7df) [#8659](https://github.com/npm/cli/pull/8659) `semver@7.7.3` +* [`fe9484a`](https://github.com/npm/cli/commit/fe9484a17707f5a6bc16cdc91f29f848a4b54d31) [#8593](https://github.com/npm/cli/pull/8593) remove normalize-package-data +### Chores +* [`b3409f4`](https://github.com/npm/cli/commit/b3409f480fef2b9885fd071c951ad8313de2754e) [#8659](https://github.com/npm/cli/pull/8659) dev dependency updates (@wraithgar) +* [`e8de81b`](https://github.com/npm/cli/commit/e8de81bc8202cfe1253676fd3f9785508e9051a6) [#8643](https://github.com/npm/cli/pull/8643) Add automatically generated annotation to dependencies.md (#8643) (@jsoref) +* [`67cfaf3`](https://github.com/npm/cli/commit/67cfaf35295fa2f5d7aa01d37c423c60ad7afeca) [#8627](https://github.com/npm/cli/pull/8627) fix spelling: different (#8627) (@jsoref) +* [`17ddc0d`](https://github.com/npm/cli/commit/17ddc0d6af1b56c4670b36b2c2705d31bdfa7749) [#8622](https://github.com/npm/cli/pull/8622) fix spelling (#8622) (@jsoref) +* [`c3e1790`](https://github.com/npm/cli/commit/c3e1790c98d5c7fabc92bcfb1a5fa170f4c7fc1d) [#8605](https://github.com/npm/cli/pull/8605) Remove reference to nonexistent calendar (#8605) (@jsoref) +* [`ac9143e`](https://github.com/npm/cli/commit/ac9143eafd46a89f707f525381b0ddb109b3beb6) [#8604](https://github.com/npm/cli/pull/8604) Improve link accessibility for screen reader users (#8604) (@jsoref) +* [`62d73e7`](https://github.com/npm/cli/commit/62d73e763fa2deffa629a4451a80b7e58032b8e0) [#8601](https://github.com/npm/cli/pull/8601) remove references to benchmarks workflow (#8601) (@jsoref) +* [`bb4b739`](https://github.com/npm/cli/commit/bb4b73953ada43285aa43dad626f48dafc53fea2) [#8598](https://github.com/npm/cli/pull/8598) remove stale comment (#8598) (@jsoref) +* [`f73e65d`](https://github.com/npm/cli/commit/f73e65d86d425bcf6b1693553e981bd05d2daeaf) [#8592](https://github.com/npm/cli/pull/8592) fix build url code for remark-github@12 (#8592) (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.6): `@npmcli/arborist@9.1.6` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.4.2): `@npmcli/config@10.4.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmaccess-v10.0.3): `libnpmaccess@10.0.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.9): `libnpmdiff@8.0.9` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.8): `libnpmexec@10.1.8` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.9): `libnpmfund@7.0.9` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.9): `libnpmpack@9.0.9` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.1.2): `libnpmpublish@11.1.2` + +## [11.6.1](https://github.com/npm/cli/compare/v11.6.0...v11.6.1) (2025-09-23) ### Bug Fixes - - * [`d654e7e`](https://github.com/npm/cli/commit/d654e7e9146f123a9806cfd9a17150eb1f6075a4) [#4781](https://github.com/npm/cli/pull/4781) fix: start consolidating color output ([@wraithgar](https://github.com/wraithgar)) - * [`b9a966c`](https://github.com/npm/cli/commit/b9a966cf33cfa9b1e5f16c16219f63633bbe19d6) [#4843](https://github.com/npm/cli/pull/4843) fix(exec): ignore packageLockOnly flag ([@nlf](https://github.com/nlf)) - +* [`d389614`](https://github.com/npm/cli/commit/d3896147c61b06d6d39a55bbb609f878548e0107) [#8579](https://github.com/npm/cli/pull/8579) corrects peer dependency flag propagation (@owlstronaut) +* [`5db81c3`](https://github.com/npm/cli/commit/5db81c350654dbbe2e1442d623efada9a24e04f1) [#8512](https://github.com/npm/cli/pull/8512) allow concurrent non-local npx calls (#8512) (@jenseng, @wraithgar) ### Documentation - - * [`8fd7eec`](https://github.com/npm/cli/commit/8fd7eec8ef76224dd8a9874a1044a0cc8f5e1c49) [#4845](https://github.com/npm/cli/pull/4845) docs: remove incorrect v6 auto prune info ([@wraithgar](https://github.com/wraithgar)) - * [`5f59f80`](https://github.com/npm/cli/commit/5f59f803d1c6cdc690d4d7016990ca0e20c6706f) [#4847](https://github.com/npm/cli/pull/4847) docs: show complex object interactions in npm pkg ([@wraithgar](https://github.com/wraithgar)) - +* [`7a09902`](https://github.com/npm/cli/commit/7a099029dbeeeab821498b9b462abce1269461f4) [#8582](https://github.com/npm/cli/pull/8582) bring back certfile (#8582) (@jenseng) ### Dependencies - - * [`62faf8a`](https://github.com/npm/cli/commit/62faf8adba19d6ef26238887a453d013fe58ae75) [#4837](https://github.com/npm/cli/pull/4837) deps: `pacote@13.2.0` - * [`4ff7d3d`](https://github.com/npm/cli/commit/4ff7d3d993533d6407fa69c5e6dd00f95090a280) [#4816](https://github.com/npm/cli/pull/4816) deps: `cacache@16.0.7` - * [`e2e9c81`](https://github.com/npm/cli/commit/e2e9c8152e2d2adcb7e2dfc90f61353d50e433ba) [#4852](https://github.com/npm/cli/pull/4852) deps: `pacote@13.3.0` - -## v8.8.0 (2022-04-27) - +* [`849dcb6`](https://github.com/npm/cli/commit/849dcb6dc22a16f01869ba9c6bf9146143000b25) [#8589](https://github.com/npm/cli/pull/8589) `tar@7.5.1` (#8589) +* [`ea15731`](https://github.com/npm/cli/commit/ea15731e3246ca698ad3f63fadd696479a906633) [#8576](https://github.com/npm/cli/pull/8576) `binary-extensions@3.1.0` +* [`0f41bac`](https://github.com/npm/cli/commit/0f41bace5677d0d624c67ff3fac5e2caeebcb399) [#8576](https://github.com/npm/cli/pull/8576) `tiny-relative-date@2.0.2` +* [`07bf540`](https://github.com/npm/cli/commit/07bf5402fbec900f1d69c05b7cb73a987d963d2c) [#8576](https://github.com/npm/cli/pull/8576) `is-cidr@6.0.0` +* [`ef87ec6`](https://github.com/npm/cli/commit/ef87ec6612fe5924d3466967aa7e104f3f98bf15) [#8576](https://github.com/npm/cli/pull/8576) `diff@8.0.2` +* [`48285e0`](https://github.com/npm/cli/commit/48285e04fd0a89b34d0c214295d5e76f68413f91) [#8576](https://github.com/npm/cli/pull/8576) add fdir, isexe, and picomatch to node_modules +* [`099238a`](https://github.com/npm/cli/commit/099238ac13ba535c99ff51bde348fcd9f6b86542) [#8576](https://github.com/npm/cli/pull/8576) `fdir@6.5.0` +* [`6e4d673`](https://github.com/npm/cli/commit/6e4d673138ee4026081e72bea1f6cdfc14516a98) [#8576](https://github.com/npm/cli/pull/8576) `isexe@3.1.1` +* [`09a7494`](https://github.com/npm/cli/commit/09a7494b59a89faa1f550864ce9f68b0c86179f1) [#8576](https://github.com/npm/cli/pull/8576) `supports-color@10.2.2` +* [`c5157c9`](https://github.com/npm/cli/commit/c5157c978fc235dea3a70235b6d08902473058f4) [#8576](https://github.com/npm/cli/pull/8576) `chalk@5.6.2` +* [`46035db`](https://github.com/npm/cli/commit/46035dbf4d87dad76051410c6b1b2536a874d9ed) [#8576](https://github.com/npm/cli/pull/8576) `debug@4.4.3` +* [`5f6664b`](https://github.com/npm/cli/commit/5f6664b7a8f622cfdd356d776e97dc8bae7e0ada) [#8576](https://github.com/npm/cli/pull/8576) `spdx-license-ids@3.0.22` +* [`5516583`](https://github.com/npm/cli/commit/5516583de7982f4b8d5142510429b809654d8f75) [#8576](https://github.com/npm/cli/pull/8576) `socks@2.8.7` +* [`6a392f3`](https://github.com/npm/cli/commit/6a392f36312b71cc4b0e71c25b4c95f47d1eeaf8) [#8576](https://github.com/npm/cli/pull/8576) `tinyglobby@0.2.15` +* [`9519f18`](https://github.com/npm/cli/commit/9519f189a427eb0a56c846379fdd92ff95078a5b) [#8576](https://github.com/npm/cli/pull/8576) `npm-install-checks@7.1.2` +* [`34bafd1`](https://github.com/npm/cli/commit/34bafd153f20954b5f8efdbf068fe1ec384ab489) [#8576](https://github.com/npm/cli/pull/8576) `node-gyp@11.4.2` +* [`dfd034e`](https://github.com/npm/cli/commit/dfd034eaf9c8fac8c40276aab42c65e2736158c8) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/promise-spawn@8.0.3` +* [`d4eef14`](https://github.com/npm/cli/commit/d4eef14dcdc30ef3a09e88180168b649ea82d72e) [#8576](https://github.com/npm/cli/pull/8576) `rimraf@6.0.1` +* [`566f1b7`](https://github.com/npm/cli/commit/566f1b7b487ad80604c61162ddde769d5ac2b241) [#8576](https://github.com/npm/cli/pull/8576) `minimatch@10.0.3` +* [`ac33497`](https://github.com/npm/cli/commit/ac334979ab94a52085b81a276c64788fa688e735) [#8576](https://github.com/npm/cli/pull/8576) `mkdirp@3.0.1` +* [`1676626`](https://github.com/npm/cli/commit/167662683d7ebbb34b1d65cf1cb74d69db12c871) [#8576](https://github.com/npm/cli/pull/8576) `glob@11.0.3` +* [`817f0b1`](https://github.com/npm/cli/commit/817f0b1eb57b9b0e5893beac11f053e3a7d3f765) [#8576](https://github.com/npm/cli/pull/8576) `ignore-walk@8.0.0` +* [`79a4e67`](https://github.com/npm/cli/commit/79a4e67c358b491f0456162fa9307e0f5a99167b) [#8576](https://github.com/npm/cli/pull/8576) `minizlib@3.0.2` +* [`38fa2c2`](https://github.com/npm/cli/commit/38fa2c2e67bed4c6e69d894cdbed0175d30ad085) [#8576](https://github.com/npm/cli/pull/8576) `negotiator@1.0.0` +* [`24252a1`](https://github.com/npm/cli/commit/24252a16fc45bfa6a4c1112269016568484006e1) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/agent@4.0.0` +* [`ea7ca5f`](https://github.com/npm/cli/commit/ea7ca5f49d6cab81e9ce3d412963c48acd87b7c0) [#8576](https://github.com/npm/cli/pull/8576) `lru-cache@11.2.1` +* [`521823b`](https://github.com/npm/cli/commit/521823bc398de0eb85135a3ef09e217db93ed1ce) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/git@7.0.0` +* [`bf6b686`](https://github.com/npm/cli/commit/bf6b6862731e03002cc6fa3b86b6f090df46b009) [#8576](https://github.com/npm/cli/pull/8576) `npm-package-arg@13.0.0` +* [`9392488`](https://github.com/npm/cli/commit/9392488d6036dfc9696e29cc8d463335517974ca) [#8576](https://github.com/npm/cli/pull/8576) `npm-package-manifest@11.0.1` +* [`0082083`](https://github.com/npm/cli/commit/0082083fe4f52d3ef40241e9d8b991f7ed4a60dc) [#8576](https://github.com/npm/cli/pull/8576) `normalize-package-data@8.0.0` +* [`633c4ed`](https://github.com/npm/cli/commit/633c4ed76ea13b8dfb5837a397e984e44cccb820) [#8576](https://github.com/npm/cli/pull/8576) `hosted-git-info@9.0.0` +* [`66f64eb`](https://github.com/npm/cli/commit/66f64eb1426beaad314321c22b5debff64b2357a) [#8576](https://github.com/npm/cli/pull/8576) `make-fetch-happen@15.0.2` +* [`1f85f94`](https://github.com/npm/cli/commit/1f85f94ec2e5dcf295c68c02b21d0b830b2082c2) [#8576](https://github.com/npm/cli/pull/8576) `@sigstore/tuf@4.0.0` +* [`a2bdecc`](https://github.com/npm/cli/commit/a2bdecc6677abcd58ed3037ab0edafb419ea86fa) [#8576](https://github.com/npm/cli/pull/8576) `sigstore@4.0.0` +* [`1149971`](https://github.com/npm/cli/commit/11499711e4c10e4ddb97bf3e1ef1652d151894fb) [#8576](https://github.com/npm/cli/pull/8576) `npm-registry-fetch@19.0.0` +* [`b5bd5e3`](https://github.com/npm/cli/commit/b5bd5e351061b46d6417210cd73c0f64c39e6819) [#8576](https://github.com/npm/cli/pull/8576) `npm-profile@12.0.0` +* [`6221e27`](https://github.com/npm/cli/commit/6221e277b4b841df09225b4d72f9eda70db1f15a) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/metavuln-calculator@9.0.2` +* [`da81a37`](https://github.com/npm/cli/commit/da81a3702fdf7ea2dc7223fc6ece4c7a19e32ad1) [#8576](https://github.com/npm/cli/pull/8576) `cacache@20.0.1` +* [`6b4c5f9`](https://github.com/npm/cli/commit/6b4c5f92865230ed9a260cd3e8486bf3991120eb) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/run-script@10.0.0` +* [`cb36a8a`](https://github.com/npm/cli/commit/cb36a8ad38df37579f59cf794d6c23ed7274fba9) [#8576](https://github.com/npm/cli/pull/8576) `init-package-json@8.2.2` +* [`b6bb9ae`](https://github.com/npm/cli/commit/b6bb9aea4134c47f0593c111a734eda12ec3c20d) [#8576](https://github.com/npm/cli/pull/8576) `pacote@21.0.3` +* [`1b4433f`](https://github.com/npm/cli/commit/1b4433fdb85623e019a6194cb01ff85c7f64ccad) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/map-workspaces@5.0.0` +* [`ceae674`](https://github.com/npm/cli/commit/ceae674c32a080b81e62d79003c2d537d7ca93d2) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/package-json@7.0.1` +* [`4f37534`](https://github.com/npm/cli/commit/4f37534300553e9ddfbc413c14d1ef15b02b46f2) [#8576](https://github.com/npm/cli/pull/8576) remove read-package-json-fast +### Chores +* [`7eb5c09`](https://github.com/npm/cli/commit/7eb5c09eb4c9d20095fd285a32275743f10cf80b) [#8576](https://github.com/npm/cli/pull/8576) update package-lock with peer flag fixes (@wraithgar) +* [`0d00fd8`](https://github.com/npm/cli/commit/0d00fd862c75d743a38ed4c5336636696129cf3b) [#8576](https://github.com/npm/cli/pull/8576) `jsdom@27.0.0` (@wraithgar) +* [`420a569`](https://github.com/npm/cli/commit/420a569762e65b50d18338706420a85f24e3e0ee) [#8576](https://github.com/npm/cli/pull/8576) `unified@11.0.5` (@wraithgar) +* [`064deb3`](https://github.com/npm/cli/commit/064deb3b329a953d86c3cbaee26805987ff82d0d) [#8576](https://github.com/npm/cli/pull/8576) `remark-rehype@11.1.2` (@wraithgar) +* [`30fe3ba`](https://github.com/npm/cli/commit/30fe3ba2455caa66e0aaf7d1e9343ed9872faba0) [#8576](https://github.com/npm/cli/pull/8576) `remark-man@9.0.0` (@wraithgar) +* [`1c6bb4c`](https://github.com/npm/cli/commit/1c6bb4c54f515fdb7ead06cb05d24e0b9d403f8b) [#8576](https://github.com/npm/cli/pull/8576) `rehype-stringify@10.0.1` (@wraithgar) +* [`208cb93`](https://github.com/npm/cli/commit/208cb93fabae2b11993497382ceb48dacc41e490) [#8576](https://github.com/npm/cli/pull/8576) `remark-gfm@4.0.1` (@wraithgar) +* [`4a46b5a`](https://github.com/npm/cli/commit/4a46b5aaaeaa68ce718d4d4a95a74b9e49da8129) [#8576](https://github.com/npm/cli/pull/8576) `remark-github@12.0.0` (@wraithgar) +* [`93d190b`](https://github.com/npm/cli/commit/93d190bcb02342ce4d159168f12b86f071d6fca7) [#8576](https://github.com/npm/cli/pull/8576) `remark-parse@11.0.0` (@wraithgar) +* [`05301a4`](https://github.com/npm/cli/commit/05301a49fb3feed88736722c8b511dde3a1117e6) [#8576](https://github.com/npm/cli/pull/8576) `remark@15.0.1` (@wraithgar) +* [`6afdda9`](https://github.com/npm/cli/commit/6afdda99ed20c7e1fb95ed379fcc9665ef4f340d) [#8576](https://github.com/npm/cli/pull/8576) `ajv-formats@3.0.1` (@wraithgar) +* [`402a0ab`](https://github.com/npm/cli/commit/402a0ab1b4e5d1a8414dd063d0cbde0c0bc5a192) [#8576](https://github.com/npm/cli/pull/8576) `@npmcli/template-oss@4.25.1` (@wraithgar) +* [`3b43bf7`](https://github.com/npm/cli/commit/3b43bf79d36a04ee65f562528c7ac54ebafaf79b) [#8576](https://github.com/npm/cli/pull/8576) dev dependency updates (@wraithgar) +* [`9f9146f`](https://github.com/npm/cli/commit/9f9146f99c638361aed606a67156854c7cf2c2cf) [#8576](https://github.com/npm/cli/pull/8576) `@tufjs/repo-mock@4.0.0` (@wraithgar) +* [`eed8a10`](https://github.com/npm/cli/commit/eed8a10f09831cc01bdc7d07c4fae5c27dcf966c) [#8576](https://github.com/npm/cli/pull/8576) use latest/local arborist in mock-registry (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.5): `@npmcli/arborist@9.1.5` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.4.1): `@npmcli/config@10.4.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmaccess-v10.0.2): `libnpmaccess@10.0.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.8): `libnpmdiff@8.0.8` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.7): `libnpmexec@10.1.7` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.8): `libnpmfund@7.0.8` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmorg-v8.0.1): `libnpmorg@8.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.8): `libnpmpack@9.0.8` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.1.1): `libnpmpublish@11.1.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmsearch-v9.0.1): `libnpmsearch@9.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmteam-v8.0.2): `libnpmteam@8.0.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmversion-v8.0.2): `libnpmversion@8.0.2` + +## [11.6.0](https://github.com/npm/cli/compare/v11.5.2...v11.6.0) (2025-09-03) ### Features - - * [`bedd8a1`](https://github.com/npm/cli/commit/bedd8a1f5844b5b379af5a756baa70821d78c610) [#4745](https://github.com/npm/cli/pull/4745) feat: add install-links config definition ([@nlf](https://github.com/nlf)) - +* [`bdcc10d`](https://github.com/npm/cli/commit/bdcc10d9f848940987b3d326ccd4673fab2bcfef) [#8359](https://github.com/npm/cli/pull/8359) add support for optional env var replacements in .npmrc (#8359) (@aczekajski, @owlstronaut) ### Bug Fixes +* [`dd4cee9`](https://github.com/npm/cli/commit/dd4cee9026c8e2dd5e4c28fd45ac8bceae74fb89) [#8539](https://github.com/npm/cli/pull/8539) powershell: improve argument parsing (#8539) (@alexsch01) +* [`5f18557`](https://github.com/npm/cli/commit/5f1855778b5e376c5f1389e0ee5f204dc86c4d32) [#8532](https://github.com/npm/cli/pull/8532) powershell: fix issue with modified InvocationName (#8532) (@alexsch01) +* [`9e5abf1`](https://github.com/npm/cli/commit/9e5abf19b93359881b2035bc371e09794a1dad01) [#8529](https://github.com/npm/cli/pull/8529) add redaction to log format egress (#8529) (@wraithgar) +* [`75ce64a`](https://github.com/npm/cli/commit/75ce64a5b21b806be203b97f35a48497b4afcb56) [#8524](https://github.com/npm/cli/pull/8524) revert handle signal exits gracefully (#8524) (@owlstronaut) +* [`5d82d0b`](https://github.com/npm/cli/commit/5d82d0b4a4bd1424031fb68b4df740c1bbe5b172) [#8469](https://github.com/npm/cli/pull/8469) ps1 scripts in powershell 5.1 (#8469) (@splatteredbits) - * [`6253d19`](https://github.com/npm/cli/commit/6253d1968d8390ea6b16604ff3abb5e6509349c9) [#4643](https://github.com/npm/cli/pull/4643) fix(exec): workspaces support ([@ruyadorno](https://github.com/ruyadorno)) - * [`e9163b4`](https://github.com/npm/cli/commit/e9163b48d8e46a80d2a4cc98c492b94dfa152cb8) [#4657](https://github.com/npm/cli/pull/4657) fix(libnpmpublish): unpublish from custom registry ([@ruyadorno](https://github.com/ruyadorno)) - * [`a677f49`](https://github.com/npm/cli/commit/a677f49e29ee9d472c8c9aa1c9eb3d5d8b4ee4a9) [#4778](https://github.com/npm/cli/pull/4778) fix: Use node in and fallback to PATH if not found ([@elibus](https://github.com/elibus)) - * [`b10462e`](https://github.com/npm/cli/commit/b10462ed156ada4d4ad90e6cf613e292a9361a87) [#4752](https://github.com/npm/cli/pull/4752) fix: completion for `deprecate` cmd ([@wraithgar](https://github.com/wraithgar)) - * [`ced0acf`](https://github.com/npm/cli/commit/ced0acfe5998a5be9313815f76f5c1439a09db78) [#4775](https://github.com/npm/cli/pull/4775) fix: consolidate registryConfig application logic ([@wraithgar](https://github.com/wraithgar)) - * [`b06e89f`](https://github.com/npm/cli/commit/b06e89f434fe8f104e71d4d8b5c98f1e866efdfa) [#4679](https://github.com/npm/cli/pull/4679) fix(install): do not install invalid package name ([@ruyadorno](https://github.com/ruyadorno)) - * [`9ea2603`](https://github.com/npm/cli/commit/9ea26038ad4d3dc971d442cba2bb02a35755c07a) [#4786](https://github.com/npm/cli/pull/4786) fix: normalize win32 paths before globbing ([@lukekarrys](https://github.com/lukekarrys)) - * [`8da28b4`](https://github.com/npm/cli/commit/8da28b403f32d2e99c842893bdc40429b8ffa9a7) [#4757](https://github.com/npm/cli/pull/4757) fix: remove `lib/utils/read-package-name.js` ([@wraithgar](https://github.com/wraithgar)) - -### Documentation - - * [`a6ea884`](https://github.com/npm/cli/commit/a6ea8843a9761d4392b3344400eb56e07691a91d) [#4745](https://github.com/npm/cli/pull/4745) docs: add some more docs for --install-links ([@nlf](https://github.com/nlf)) - * [`6cd6831`](https://github.com/npm/cli/commit/6cd6831eaa9e1681e07f6646e6f13cce344e1250) [#4782](https://github.com/npm/cli/pull/4782) docs: explain that _auth only goes to npm registry ([@wraithgar](https://github.com/wraithgar)) - * [`fa3d829`](https://github.com/npm/cli/commit/fa3d82989df7071cfe500c5f9cc09c597bcc17ee) [#4772](https://github.com/npm/cli/pull/4772) docs: include org instructions in scoped publish ([@bnb](https://github.com/bnb)) ### Dependencies - * [`36899d1`](https://github.com/npm/cli/commit/36899d193b8e8ee6019b04aa5e6a3a9a641a3172) [#4807](https://github.com/npm/cli/pull/4807) deps: `@npmcli/arborist@5.1.1` - * [`0ebadf5`](https://github.com/npm/cli/commit/0ebadf5b603368557e9e837a46ea5c59c2677a81) [#4745](https://github.com/npm/cli/pull/4745) add support for installLinks ([@nlf](https://github.com/nlf)) - * [`3d96494`](https://github.com/npm/cli/commit/3d964940f410052918e37a9b05818fe9dc4cd86a) [#4745](https://github.com/npm/cli/pull/4745) when replacing a Link with a Node, make sure to remove the Link target from the root ([@nlf](https://github.com/nlf)) - * [`3f2b24a`](https://github.com/npm/cli/commit/3f2b24afe205547dbbadf5a6313e95f6b565fb49) [#4786](https://github.com/npm/cli/pull/4786) deps: `@npmcli/map-workspaces@2.0.3` - * [`b1b6948`](https://github.com/npm/cli/commit/b1b69487637ce99192dc930257eebae9eed4fe7f) [#4808](https://github.com/npm/cli/pull/4808) deps: `libnpmexec@4.0.5` - * [`4a46a27`](https://github.com/npm/cli/commit/4a46a27f2b968e2f8c1f4821508f93013738c482) [#4777](https://github.com/npm/cli/pull/4777) fix read mixed local/registry pkg ([@ruyadorno](https://github.com/ruyadorno)) - * [`9f57404`](https://github.com/npm/cli/commit/9f57404dc148835d7393b5fe617c8c5e2c958061) [#4743](https://github.com/npm/cli/pull/4743) deps: `npm-registry-fetch@13.1.1` - * [`532883f`](https://github.com/npm/cli/commit/532883ffc35fc1cc9aec09f03bf5ee0f256b94a4) [#4786](https://github.com/npm/cli/pull/4786) deps: `cacache@16.0.6` - * [`4d1398e`](https://github.com/npm/cli/commit/4d1398e347ed56464d7afd8ef0b3a3bc82b2f19f) [#4786](https://github.com/npm/cli/pull/4786) deps: `npm-profile@6.0.3` - * [`5e31322`](https://github.com/npm/cli/commit/5e313223100db1207818d756b081eaba3468b273) [#4786](https://github.com/npm/cli/pull/4786) deps: `npmlog@6.0.2` - * [`4eb2ccb`](https://github.com/npm/cli/commit/4eb2ccbacbd2ca55f2a41a104ee20578542fc52f) [#4786](https://github.com/npm/cli/pull/4786) deps: `read-package-json@5.0.1` - * [`aeb54e4`](https://github.com/npm/cli/commit/aeb54e41b613f4a98d1f02d255b3a564c43270d8) [#4786](https://github.com/npm/cli/pull/4786) deps: `glob@8.0.1` - * [`252b2b1`](https://github.com/npm/cli/commit/252b2b1e8caaf1c26e5ab6836a83ec430d2a699a) [#4786](https://github.com/npm/cli/pull/4786) deps: `npm-packlist@5.0.2` - * [`c51e553`](https://github.com/npm/cli/commit/c51e553a32315e4f1b703ca9030eb7ade91d1a85) [#4786](https://github.com/npm/cli/pull/4786) deps: `semver@7.3.7` - * [`13299ee`](https://github.com/npm/cli/commit/13299eed80db9a05f0b0a063b8936c0148ec3037) [#4786](https://github.com/npm/cli/pull/4786) deps: `lru-cache@7.8.1` - * [`0f2da5d`](https://github.com/npm/cli/commit/0f2da5dca54862707a00d2254bf4c0b4c2e0be60) [#4786](https://github.com/npm/cli/pull/4786) deps: `cli-table3@0.6.2` - * [`0ee57f1`](https://github.com/npm/cli/commit/0ee57f1492893da84686f4340feeb0469fb751f8) [#4805](https://github.com/npm/cli/pull/4805) deps: `libnpmpublish@6.0.4` - * [`8a633a4`](https://github.com/npm/cli/commit/8a633a436cf37dad293af3aaf8ea9a0b5badf314) [#4806](https://github.com/npm/cli/pull/4806) deps: `libnpmversion@3.0.4` - -## v8.7.0 (2022-04-13) - -### Features - - * [`6611e91`](https://github.com/npm/cli/commit/6611e9147f1726ab4537a7fe3b9e3beb6728f700) [#4723](https://github.com/npm/cli/pull/4723) feat(config): add more npm/node information to config ls ([@lukekarrys](https://github.com/lukekarrys)) - * [`c057b90`](https://github.com/npm/cli/commit/c057b90d0954ff5b6f2973748ae5d41885b99213) [#4740](https://github.com/npm/cli/pull/4740) feat(config): warn on deprecated configs ([@lukekarrys](https://github.com/lukekarrys)) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.4): `@npmcli/arborist@9.1.4` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.4.0): `@npmcli/config@10.4.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.7): `libnpmdiff@8.0.7` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.6): `libnpmexec@10.1.6` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.7): `libnpmfund@7.0.7` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.7): `libnpmpack@9.0.7` +## [11.5.2](https://github.com/npm/cli/compare/v11.5.1...v11.5.2) (2025-07-30) ### Bug Fixes - - * [`2829cb2`](https://github.com/npm/cli/commit/2829cb28a432b5ff7beeeb3bf3e7e2e174c1121d) [#4658](https://github.com/npm/cli/pull/4658) fix: update readme badges ([@lukekarrys](https://github.com/lukekarrys)) - * [`e3da5df`](https://github.com/npm/cli/commit/e3da5df4152fbe547f7871547165328e1bf06262) [#4667](https://github.com/npm/cli/pull/4667) fix: replace deprecated String.prototype.substr() ([@CommanderRoot](https://github.com/CommanderRoot)) - * [`2a26e5e`](https://github.com/npm/cli/commit/2a26e5e21af788f025a5731d88f15f6dc88b4c0c) [#4645](https://github.com/npm/cli/pull/4645) fix: remove dedupe --save ([@wraithgar](https://github.com/wraithgar)) - * [`47438ff`](https://github.com/npm/cli/commit/47438ff19f4b6e84a0325ed73b97999ce34bc789) [#4645](https://github.com/npm/cli/pull/4645) fix: do not export npm_config_include_workspace_root ([@wraithgar](https://github.com/wraithgar)) - * [`840c338`](https://github.com/npm/cli/commit/840c338aa6aba7dc39d9d3afba075701e3979362) [#4678](https://github.com/npm/cli/pull/4678) fix(run-script): don't cascade if-present config ([@ruyadorno](https://github.com/ruyadorno)) - * [`4d676e3`](https://github.com/npm/cli/commit/4d676e31a68f081b8553eff4e79db1f29acf47e1) [#4709](https://github.com/npm/cli/pull/4709) fix(arborist): when reloading an edge, also refresh overrides ([@nlf](https://github.com/nlf)) - * [`3f7fe17`](https://github.com/npm/cli/commit/3f7fe17d1ea743b3ce1f27b9156e9fa0e358a7df) [#4659](https://github.com/npm/cli/pull/4659) fix: skip update notifier file if not requested ([@lukekarrys](https://github.com/lukekarrys)) - * [`5ba7f0c`](https://github.com/npm/cli/commit/5ba7f0cef753d4af0bc02ca7d6dd0ac1bdd11ffe) [#4726](https://github.com/npm/cli/pull/4726) fix: show more information during publish dry-run ([@lukekarrys](https://github.com/lukekarrys)) - * [`aa4a4da`](https://github.com/npm/cli/commit/aa4a4da336a6ec1963394fdbd06acb173c842d26) [#4735](https://github.com/npm/cli/pull/4735) fix(arborist): dont skip adding advisories to audit based on name/range ([@lukekarrys](https://github.com/lukekarrys)) - * [`0cd852f`](https://github.com/npm/cli/commit/0cd852f62e1453e647a2551e98c78ce7e0c8ea03) [#4741](https://github.com/npm/cli/pull/4741) fix: mitigate doctor test race condition ([@wraithgar](https://github.com/wraithgar)) - * [`ba8b2a7`](https://github.com/npm/cli/commit/ba8b2a753d63c8a8c7a44a48c2e13626b12025fe) [#4744](https://github.com/npm/cli/pull/4744) fix(ls): make `--omit` filter `npm ls` ([@lukekarrys](https://github.com/lukekarrys)) - +* [`7d900c4`](https://github.com/npm/cli/commit/7d900c4656cfffc8cca93240c6cda4b441fbbfaa) [#8467](https://github.com/npm/cli/pull/8467) oidc visibility check for provenance (#8467) (@reggi, @wraithgar) ### Documentation +* [`d4e56b2`](https://github.com/npm/cli/commit/d4e56b2976ef1d2af273a6750d10b217adf4bf8e) [#8459](https://github.com/npm/cli/pull/8459) update snapshot generation command (#8459) (@MikeMcC399) - * [`85b3c48`](https://github.com/npm/cli/commit/85b3c48d2c9bc4199aed699cc4c00ac96c5feebd) [#4666](https://github.com/npm/cli/pull/4666) docs(ci): add note that configuration must be consistent between install and ci ([@nlf](https://github.com/nlf)) - * [`44108f7`](https://github.com/npm/cli/commit/44108f7be5e1e928d8aa3eda3c5c177bcd216c99) [#4670](https://github.com/npm/cli/pull/4670) docs: fix npm-uninstall typo ([@JSKitty](https://github.com/JSKitty)) - -### Dependencies - - * [`aaf86f6`](https://github.com/npm/cli/commit/aaf86f61836c45b254794785f0a2e8f43dc38800) [#4674](https://github.com/npm/cli/pull/4674) deps: `@npmcli/metavuln-calculator@3.1.0` - * [`4a9a705`](https://github.com/npm/cli/commit/4a9a705de6992a3e9eefecc6c0cf8da45a527c7a) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/package-json@2.0.0` - * [`1a90b9e`](https://github.com/npm/cli/commit/1a90b9e9ebe98cce83591e11312aaf41c830f835) [#4691](https://github.com/npm/cli/pull/4691) deps: `treeverse@2.0.0` - * [`f86f1af`](https://github.com/npm/cli/commit/f86f1af636f39d7d30a97873bbb6652416f68013) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/disparity-colors@2.0.0` - * [`3a76dff`](https://github.com/npm/cli/commit/3a76dff3f49af9688a44a508d956f2091363b66d) [#4691](https://github.com/npm/cli/pull/4691) deps: `make-fetch-happen@10.1.2` - * [`0230428`](https://github.com/npm/cli/commit/02304284ddd147e604835a000d3a28a2deb65702) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/config@4.0.2` - * [`82dc75f`](https://github.com/npm/cli/commit/82dc75fe62466714ea59accf245a6f9d6d111e17) [#4691](https://github.com/npm/cli/pull/4691) deps: `npm-pick-manifest@7.0.1` - * [`ad99360`](https://github.com/npm/cli/commit/ad9936063f20829eb9d5358d056593883f17a57b) [#4691](https://github.com/npm/cli/pull/4691) deps: `npm-install-checks@5.0.0` - * [`79fc706`](https://github.com/npm/cli/commit/79fc706f9c389a17ba50dd8835223160b8b0c3fb) [#4691](https://github.com/npm/cli/pull/4691) deps: `bin-links@3.0.1` - * [`1f2fb1e`](https://github.com/npm/cli/commit/1f2fb1e07b752ee34867c271a0fd1f186397d8ec) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/git@3.0.1` - * [`0f23c33`](https://github.com/npm/cli/commit/0f23c3378c991b2a482463ce7f700829a3752940) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/run-script@3.0.2` - * [`485753d`](https://github.com/npm/cli/commit/485753df44e66921dcb593e1bcbb39de79c6dc11) [#4691](https://github.com/npm/cli/pull/4691) deps: `cacache@16.0.4` - * [`e9b25cd`](https://github.com/npm/cli/commit/e9b25cd66bef17e807a84e7b10384f5f4d0064b7) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/move-file@2.0.0` - * [`0e87cac`](https://github.com/npm/cli/commit/0e87cac8b6f09692f6bd1bf086aadbe323d127b5) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/node-gyp@2.0.0` - * [`b632746`](https://github.com/npm/cli/commit/b632746b99121b5a271c75b985a849dfd75b6c57) [#4691](https://github.com/npm/cli/pull/4691) deps: `@npmcli/promise-spawn@3.0.0` - * [`b1863bf`](https://github.com/npm/cli/commit/b1863bf87adeb6deec83869f0f7bb1df4a5731ef) [#4691](https://github.com/npm/cli/pull/4691) deps: `pacote@13.1.1` - * [`a2781a3`](https://github.com/npm/cli/commit/a2781a367d62328d7f870de878f1b63d66593f4f) [#4691](https://github.com/npm/cli/pull/4691) deps: `ssri@9.0.0` - * [`5172e03`](https://github.com/npm/cli/commit/5172e03a572c99159568861049e4c2a536922f50) [#4691](https://github.com/npm/cli/pull/4691) deps: `ini@3.0.0` - * [`71296d5`](https://github.com/npm/cli/commit/71296d5ca4ace5805e1061c1a58878939c1c32f3) [#4691](https://github.com/npm/cli/pull/4691) deps: `npm-package-arg@9.0.2` - * [`69d8343`](https://github.com/npm/cli/commit/69d834319a9d668bd451600ab6e124a8819b284d) [#4691](https://github.com/npm/cli/pull/4691) deps: `graceful-fs@4.2.10` - * [`c44c2b0`](https://github.com/npm/cli/commit/c44c2b02920854897ba7a663ef705b9b474c2250) [#4691](https://github.com/npm/cli/pull/4691) deps: `lru-cache@7.7.3` - * [`38029ed`](https://github.com/npm/cli/commit/38029edea846ffe81768d7073d4ec09a4b129c24) [#4691](https://github.com/npm/cli/pull/4691) deps: `dezalgo@1.0.4` - * [`e57353c`](https://github.com/npm/cli/commit/e57353c78e798afbd3eb4390a42da5d5076be45d) [#4691](https://github.com/npm/cli/pull/4691) deps: `semver@7.3.6` - * [`1b30c72`](https://github.com/npm/cli/commit/1b30c725ecd0f03f55e3c0576962972748eec238) [#4691](https://github.com/npm/cli/pull/4691) deps: `minimatch@5.0.1` - * [`c70232c`](https://github.com/npm/cli/commit/c70232cc12fd9b3b024c2c759edd708af2367b8d) [#4706](https://github.com/npm/cli/pull/4706) deps: `@npmcli/arborist@5.0.5` - * [`baff482`](https://github.com/npm/cli/commit/baff4828f733efee0a569e00f87d25f06f2b384b) [#4705](https://github.com/npm/cli/pull/4705) deps: `libnpmdiff@4.0.3` - * [`dda8a97`](https://github.com/npm/cli/commit/dda8a976a9dd696cf2b2e2be5b55b2048e768768) [#4704](https://github.com/npm/cli/pull/4704) deps: `libnpmorg@4.0.3` - * [`8914864`](https://github.com/npm/cli/commit/891486451f1c34a2e7649b0a76c6c0d611ce3d39) [#4703](https://github.com/npm/cli/pull/4703) deps: `libnpmaccess@6.0.3` - * [`3516f61`](https://github.com/npm/cli/commit/3516f61e415d9ce6e9b00378c45791e33bb99fc9) [#4702](https://github.com/npm/cli/pull/4702) deps: `libnpmfund@3.0.2` - * [`ecd22b0`](https://github.com/npm/cli/commit/ecd22b07af515d86b77248e6a4cc2dec57bafd50) [#4701](https://github.com/npm/cli/pull/4701) deps: `libnpmversion@3.0.2` - * [`7ed9faf`](https://github.com/npm/cli/commit/7ed9fafaa951071a7988a3ec4ca3a5e01756b11d) [#4700](https://github.com/npm/cli/pull/4700) deps: `libnpmhook@8.0.3` - * [`df92e23`](https://github.com/npm/cli/commit/df92e23af63ca07bb4c261abd7365530529d3fd2) [#4699](https://github.com/npm/cli/pull/4699) deps: `libnpmexec@4.0.3` - * [`5074adc`](https://github.com/npm/cli/commit/5074adc5e17d1b0ec753cde3b7efd96c2fc7c4a3) [#4698](https://github.com/npm/cli/pull/4698) deps: `libnpmsearch@5.0.3` - * [`35e5100`](https://github.com/npm/cli/commit/35e5100e287925d19df4aab98de96cf70a6ff5a6) [#4697](https://github.com/npm/cli/pull/4697) deps: `libnpmteam@4.0.3` - * [`86f5b27`](https://github.com/npm/cli/commit/86f5b273fc57118b8b1a5e53ec3ca49d94d81601) [#4696](https://github.com/npm/cli/pull/4696) deps: `libnpmpack@4.0.3` - * [`1617bce`](https://github.com/npm/cli/commit/1617bce61663a743435d162b003d3b99376d426f) [#4695](https://github.com/npm/cli/pull/4695) deps: `libnpmpublish@6.0.3` - * [`e33aa0f`](https://github.com/npm/cli/commit/e33aa0f94f87ae4f9d2a73781e84832ef61d1855) [#4714](https://github.com/npm/cli/pull/4714) deps: remove stringify-package - * [`98377d1`](https://github.com/npm/cli/commit/98377d159f72a5b6073f07235b057984eb09a85c) [#4740](https://github.com/npm/cli/pull/4740) deps: `@npmcli/config@4.1.0` - * [`605ccef`](https://github.com/npm/cli/commit/605ccef6916c170f6d0c53775614f8a02682262a) [#4728](https://github.com/npm/cli/pull/4728) deps: remove ansistyles - * [`c22fb1e`](https://github.com/npm/cli/commit/c22fb1e756d43b54fefd826f2c3f459d4f1204b5) [#4728](https://github.com/npm/cli/pull/4728) deps: remove ansicolors - * [`970244c`](https://github.com/npm/cli/commit/970244c415da91b98ca3b200d88c1206ba81d774) [#4734](https://github.com/npm/cli/pull/4734) deps: `libnpmversion@3.0.3` - * [`42dc0b0`](https://github.com/npm/cli/commit/42dc0b03d60dc27602dab26a2f8cbfc17bf4ab40) [#4733](https://github.com/npm/cli/pull/4733) deps: `@npmcli/arborist@5.0.6` - -## v8.6.0 (2022-03-31) - -### Features - - * [`723a0918a`](https://github.com/npm/cli/commit/723a0918a5a9d9f795584f85d04506fafda9ca42) [#4588](https://github.com/npm/cli/pull/4588) feat(version): reify on workspace version change ([@ruyadorno](https://github.com/ruyadorno)) - * [`cc6c09431`](https://github.com/npm/cli/commit/cc6c09431d7fe2db8ac1dc7a707f2dab7a7a1f83) [#4594](https://github.com/npm/cli/pull/4594) feat: add logs-dir config to set custom logging location ([@lukekarrys](https://github.com/lukekarrys)) - +## [11.5.1](https://github.com/npm/cli/compare/v11.5.0...v11.5.1) (2025-07-24) ### Bug Fixes +* [`476bf17`](https://github.com/npm/cli/commit/476bf174c1c9874fa2a92df7257c3d445e3e16d3) [#8457](https://github.com/npm/cli/pull/8457) provenance should only default for oidc (@reggi) - * [`98bfd9a8c`](https://github.com/npm/cli/commit/98bfd9a8cc23930e6becd15fffabadd1c269b0a2) fix: remove always true condition (#4590) ([@XhmikosR](https://github.com/XhmikosR)) - * [`81afa5a88`](https://github.com/npm/cli/commit/81afa5a8838c71a3a5037e2c8b4ae196e19fe0d7) [#4601](https://github.com/npm/cli/pull/4601) fix(unpublish): properly apply publishConfig ([@wraithgar](https://github.com/wraithgar)) - * [`716a07fde`](https://github.com/npm/cli/commit/716a07fde7905bb69e4c6f1991bb7289589a6669) [#4607](https://github.com/npm/cli/pull/4607) fix: 100% coverage in tests ([@wraithgar](https://github.com/wraithgar)) - * [`6f9cb490e`](https://github.com/npm/cli/commit/6f9cb490e7299976c43c6a118036c130671fe188) [#4614](https://github.com/npm/cli/pull/4614) fix(arborist): handle link nodes in old lockfiles correctly ([@nlf](https://github.com/nlf)) - * [`18b8b9435`](https://github.com/npm/cli/commit/18b8b94357d8f57301fbaa0f1e5dc2cf1128bf3e) [#4617](https://github.com/npm/cli/pull/4617) fix(arborist): make sure resolveParent exists before checking props ([@nlf](https://github.com/nlf)) - * [`bd96ae407`](https://github.com/npm/cli/commit/bd96ae4071f9cc8a65e741f414db12e98537971d) [#4599](https://github.com/npm/cli/pull/4599) fix(arborist): identify and repair invalid nodes in the virtual tree ([@nlf](https://github.com/nlf)) - * [`99d884542`](https://github.com/npm/cli/commit/99d88454248f950b82652b592fe2b4d019c1060b) [#4599](https://github.com/npm/cli/pull/4599) fix: make sure we loadOverrides on the root node in loadVirtual() ([@nlf](https://github.com/nlf)) - * [`45dd8b861`](https://github.com/npm/cli/commit/45dd8b8615bb1d7a93e1733746581049a1f399e6) [#4609](https://github.com/npm/cli/pull/4609) fix: move shellout logic into commands ([@wraithgar](https://github.com/wraithgar)) - * [`a64acc0bf`](https://github.com/npm/cli/commit/a64acc0bf01e4bc68b26ead5b2d5c6db47ef16c2) [#4609](https://github.com/npm/cli/pull/4609) fix: really load all commands in tests, add description to birthday ([@wraithgar](https://github.com/wraithgar)) - * [`d8dcc02cf`](https://github.com/npm/cli/commit/d8dcc02cfd354c1314c45d6530ec926cd138210c) [#4609](https://github.com/npm/cli/pull/4609) fix: consolidate command alias code ([@wraithgar](https://github.com/wraithgar)) - * [`f76d4f2f6`](https://github.com/npm/cli/commit/f76d4f2f661bcc2534f541ee0e7d683155372baf) [#4609](https://github.com/npm/cli/pull/4609) fix: consolidate is-windows code ([@wraithgar](https://github.com/wraithgar)) - * [`57d8f75eb`](https://github.com/npm/cli/commit/57d8f75eb864486f6aa17bb3dd2f213b5c148073) [#4609](https://github.com/npm/cli/pull/4609) fix: consolidate node version support logic ([@wraithgar](https://github.com/wraithgar)) - * [`0a957f5e2`](https://github.com/npm/cli/commit/0a957f5e2fbcce51c407d22b19e38004d09c51af) [#4609](https://github.com/npm/cli/pull/4609) fix: consolidate path delimiter logic ([@wraithgar](https://github.com/wraithgar)) - * [`738a40445`](https://github.com/npm/cli/commit/738a404454677b78b25ce82a8d2e4c1f46d57ffa) [#4609](https://github.com/npm/cli/pull/4609) fix: bump knownBroken to <12.5.0 ([@wraithgar](https://github.com/wraithgar)) - * [`8b65bfd5d`](https://github.com/npm/cli/commit/8b65bfd5d610a70e1a860936be1a47f3a3df7f32) [#4629](https://github.com/npm/cli/pull/4629) fix: return otplease fn results ([@wraithgar](https://github.com/wraithgar)) - * [`d8d374d23`](https://github.com/npm/cli/commit/d8d374d23d34c17e22b52afc1cfb5247cc7c3e1d) [#4632](https://github.com/npm/cli/pull/4632) fix: consolidate split-package-names ([@wraithgar](https://github.com/wraithgar)) - * [`cc0a2ec99`](https://github.com/npm/cli/commit/cc0a2ec9999b956ea654deaf68fd49ae4bf1a1c0) [#4611](https://github.com/npm/cli/pull/4611) fix: work better with system manpages (#4610) ([@d0sboots](https://github.com/d0sboots)) - * [`668ec7f33`](https://github.com/npm/cli/commit/668ec7f33b7a76f5e86a59f7e5a6c0e068a242b1) [#4644](https://github.com/npm/cli/pull/4644) fix: only call npmlog progress methods if explicitly requested ([@lukekarrys](https://github.com/lukekarrys)) - -### Documentation - - * [`ff1367f01`](https://github.com/npm/cli/commit/ff1367f01b9dd924d039b5a6b58399101cac99ca) [#4641](https://github.com/npm/cli/pull/4641) docs: recommend prepare over prepublish ([@verhovsky](https://github.com/verhovsky)) - -### Dependencies - - * [`6df061ec2`](https://github.com/npm/cli/commit/6df061ec2a52882693ed86a3524ac6af0f88acd8) [#4594](https://github.com/npm/cli/pull/4594) deps: `npm-registry-fetch@13.1.0` - * [`6dd1139c9`](https://github.com/npm/cli/commit/6dd1139c9f302ac71f47a75e70bbe9cdf2e64960) [#4594](https://github.com/npm/cli/pull/4594) deps: `cacache@16.0.3` - * [`feb4446d5`](https://github.com/npm/cli/commit/feb4446d50a7b6a61e44a92b78e1e1af2d89a725) [#4616](https://github.com/npm/cli/pull/4616) deps: `make-fetch-happen@10.1.0` - * [`c33b53311`](https://github.com/npm/cli/commit/c33b5331120d8304e0f090ceda55e19cc6f451f4) [#4613](https://github.com/npm/cli/pull/4613) deps: `minipass-fetch@2.1.0` - * [`6a4c8ff89`](https://github.com/npm/cli/commit/6a4c8ff89acc98409060f5aa55b2f1a795a6b66c) [#4606](https://github.com/npm/cli/pull/4606) deps: `npm-audit-report@3.0.0` - * [`6e0a131d2`](https://github.com/npm/cli/commit/6e0a131d2ff3143856f388bb42c6568d5312c451) [#4627](https://github.com/npm/cli/pull/4627) deps: `debug@4.3.4` - * [`0f1cd60a1`](https://github.com/npm/cli/commit/0f1cd60a1cdb643782ae86a5a7fce84e357dbf10) [#4627](https://github.com/npm/cli/pull/4627) deps: `proc-log@2.0.1` - * [`da377eed5`](https://github.com/npm/cli/commit/da377eed5cba72185b90f5fc32ef288331c856ef) [#4627](https://github.com/npm/cli/pull/4627) deps: `parse-conflict-json@2.0.2` - * [`726a8a07a`](https://github.com/npm/cli/commit/726a8a07afeb3bd24979307679ce7e63c73b178e) [#4627](https://github.com/npm/cli/pull/4627) deps: `gauge@4.0.4` - * [`aac01b89c`](https://github.com/npm/cli/commit/aac01b89caf6336a2eb34d696296303cdadd5c08) [#4628](https://github.com/npm/cli/pull/4628) deps: `@npmcli/template-oss@3.2.1` - * [`52dfaf239`](https://github.com/npm/cli/commit/52dfaf239a3f66a05ee9d6148bc41a46b5adffd6) [#4630](https://github.com/npm/cli/pull/4630) deps: `make-fetch-happen@10.1.1` - * [`9778a5387`](https://github.com/npm/cli/commit/9778a5387771256fc81e3587922c12ec47f750ea) [#4635](https://github.com/npm/cli/pull/4635) deps: `init-package-json@3.0.2` - * [`86eff5dcc`](https://github.com/npm/cli/commit/86eff5dccb9bce2eb8d80706e8dea855faf753b3) [#4635](https://github.com/npm/cli/pull/4635) deps: `npm-package-arg@9.0.2` - * [`5b4cbb217`](https://github.com/npm/cli/commit/5b4cbb2175bfa35e347fe94e21d49a05ea64ead1) [#4635](https://github.com/npm/cli/pull/4635) deps: `validate-npm-package-name@4.0.0` - * [`a59fd2cb8`](https://github.com/npm/cli/commit/a59fd2cb863245fce56f96c90ac854e62c5c4d6f) [#4639](https://github.com/npm/cli/pull/4639) deps: `@npmcli/template-oss@3.2.2` - * [`679e569d5`](https://github.com/npm/cli/commit/679e569d5778aef312b37c1ba3bda0171366c9fb) [#4655](https://github.com/npm/cli/pull/4655) deps: `@npmcli/arborist@5.0.4` - -## v8.5.5 (2022-03-17) - +## [11.5.0](https://github.com/npm/cli/compare/v11.4.2...v11.5.0) (2025-07-24) +### Features +* [`1cce318`](https://github.com/npm/cli/commit/1cce31810eb5ff1e0f7c8ee4516e7c73cedb38a1) [#8336](https://github.com/npm/cli/pull/8336) adds support for oidc publish (#8336) (@reggi) ### Bug Fixes - - * [`0e7511d14`](https://github.com/npm/cli/commit/0e7511d144bdb6624e4c0fdfb31b4b42ed2954c9) [#4261](https://github.com/npm/cli/pull/4261) fix(arborist): _findMissingEdges missing dependency due to inconsistent path separators ([@salvadorj](https://github.com/salvadorj)) - * [`c83069436`](https://github.com/npm/cli/commit/c83069436ef4af75eaef071bc181ba1ab49729e9) [#4547](https://github.com/npm/cli/pull/4547) fix: omit bots from authors ([@wraithgar](https://github.com/wraithgar)) - * [`f66da2ed8`](https://github.com/npm/cli/commit/f66da2ed8948fbfa919dd5debe52eafe2018735c) [#4565](https://github.com/npm/cli/pull/4565) fix(owner): bypass cache when fetching packument ([@wraithgar](https://github.com/wraithgar)) - * [`f0c6e86ca`](https://github.com/npm/cli/commit/f0c6e86ca5920baa85355af3ea50ed13f7429a10) [#4572](https://github.com/npm/cli/pull/4572) fix: remove name from unpublished message ([@wraithgar](https://github.com/wraithgar)) - * [`f7e58fa74`](https://github.com/npm/cli/commit/f7e58fa74d9008731b86c82f75251ca295056cf1) [#4572](https://github.com/npm/cli/pull/4572) fix: remove "bug the author" message from package 404 ([@wraithgar](https://github.com/wraithgar)) - * [`5471ff5fe`](https://github.com/npm/cli/commit/5471ff5fe8f74f46cdc2bb056ba9b496c7dd1a78) [#4573](https://github.com/npm/cli/pull/4573) fix: add isntall alias to install ([@wraithgar](https://github.com/wraithgar)) - * [`84d19210e`](https://github.com/npm/cli/commit/84d19210e5604775a3a413aa32cbba2c103933f2) [#4576](https://github.com/npm/cli/pull/4576) fix: properly show `npm view ./directory` ([@wraithgar](https://github.com/wraithgar)) - * [`e9a2981f5`](https://github.com/npm/cli/commit/e9a2981f55f84ff521ef597883a4e732d08ce1c1) [#4578](https://github.com/npm/cli/pull/4578) fix(arborist): save workspace version ([@ruyadorno](https://github.com/ruyadorno)) - +* [`7f66f0a`](https://github.com/npm/cli/commit/7f66f0ae8fb84f567fe83a9a5738d06c7fe8fb54) [#8447](https://github.com/npm/cli/pull/8447) add better hint for `before` and clean up description (@wraithgar) +* [`280817a`](https://github.com/npm/cli/commit/280817a0a5b4e2aebd4b2f39c79ac9af58165edf) [#8447](https://github.com/npm/cli/pull/8447) add --before param to command help output (@wraithgar) +* [`6e47325`](https://github.com/npm/cli/commit/6e47325e59f19e4e563b5f9308cff165739088a2) [#8441](https://github.com/npm/cli/pull/8441) Makes 404 errors less scary without revealing existence (#8441) (@owlstronaut) +* [`0a97ffd`](https://github.com/npm/cli/commit/0a97ffdf8b2df40a5f24b710415eb0c9aaa82f5d) [#8429](https://github.com/npm/cli/pull/8429) handle signal exits gracefully (@owlstronaut) +* [`5b858c6`](https://github.com/npm/cli/commit/5b858c6b2c275f0e670e09c52de5b931936d6e07) [#8411](https://github.com/npm/cli/pull/8411) ensure progress bars display consistently across all environments (#8411) (@owlstronaut) ### Documentation - - * [`a30405258`](https://github.com/npm/cli/commit/a304052580c070a1f8c1c0cf8cbeec615c46af02) [#4580](https://github.com/npm/cli/pull/4580) docs: add foreground-scripts and ignore-scripts to commands ([@wraithgar](https://github.com/wraithgar)) - * [`2361a68e1`](https://github.com/npm/cli/commit/2361a68e14f893e97dad53d66fde32082e23521a) [#4582](https://github.com/npm/cli/pull/4582) docs: add isntall alias to install command ([@wraithgar](https://github.com/wraithgar)) - * [`8ff1dfaae`](https://github.com/npm/cli/commit/8ff1dfaaeeb32e88c879b96a786835fe13526a88) [#4575](https://github.com/npm/cli/pull/4575) docs: explain that linked deps need `npm install` ran in them ([@wraithgar](https://github.com/wraithgar)) - * [`ddbb505ec`](https://github.com/npm/cli/commit/ddbb505ec6077576e0a9d00a14b43d32d69e4f9e) [#4574](https://github.com/npm/cli/pull/4574) docs: explain that git-tag-version=false does not commit ([@wraithgar](https://github.com/wraithgar)) - * [`7c878b978`](https://github.com/npm/cli/commit/7c878b9781be2e2151f41bd29d46c33e421aeb10) [#4584](https://github.com/npm/cli/pull/4584) docs: fix unpublish docs to auto generate usage ([@wraithgar](https://github.com/wraithgar)) - +* [`ef3529e`](https://github.com/npm/cli/commit/ef3529ec4b45901c95182850e8e9da8dae833227) [#8435](https://github.com/npm/cli/pull/8435) add test snapshot (#8435) (@reggi, @wraithgar) +* [`b7758d7`](https://github.com/npm/cli/commit/b7758d73d6b715a62e6d0c48e11b87017ce2b71c) [#8418](https://github.com/npm/cli/pull/8418) remove reference to Node.js download less common os (#8418) (@MikeMcC399) +* [`746ac5d`](https://github.com/npm/cli/commit/746ac5d95dc19a74c519a8e3f3e1eed029957921) [#8380](https://github.com/npm/cli/pull/8380) remove duplicate info (#8380) (@alexsch01) +* [`4673e9c`](https://github.com/npm/cli/commit/4673e9c165b39563e16409f3b1ca06fdc32e7d44) [#8371](https://github.com/npm/cli/pull/8371) rebrand OS X references to macOS (@MikeMcC399) ### Dependencies - - * [`fcc6acfa8`](https://github.com/npm/cli/commit/fcc6acfa808aa556748544edf4e9b73262f77608) [#4562](https://github.com/npm/cli/pull/4562) deps: `@npmcli/metavuln-calculator@3.0.1` - * [`6d3145014`](https://github.com/npm/cli/commit/6d3145014861b4198c16d7772d809fd037ece289) [#4562](https://github.com/npm/cli/pull/4562) deps: `pacote@13.0.4` - * [`f6b771aab`](https://github.com/npm/cli/commit/f6b771aabece09dca2231426d4f681d3578e5ab7) [#4562](https://github.com/npm/cli/pull/4562) deps: `make-fetch-happen@10.0.6` - * [`e26548fb1`](https://github.com/npm/cli/commit/e26548fb12a3bb23fbe32a336f1305e083aa51c0) [#4562](https://github.com/npm/cli/pull/4562) deps: `cacache@16.0.0` - * [`915dda7ab`](https://github.com/npm/cli/commit/915dda7abeedf79cfe0dde1bd55d80115e2a795d) [#4562](https://github.com/npm/cli/pull/4562) deps: `init-package-json@3.0.1` - * [`f2ec2ef1f`](https://github.com/npm/cli/commit/f2ec2ef1f7a639ea292d6ab442d588ed72198857) [#4562](https://github.com/npm/cli/pull/4562) deps: `read-package-json@5.0.0` - * [`340fa51f4`](https://github.com/npm/cli/commit/340fa51f423a518a96c8015a67d8f6144a2e8051) [#4562](https://github.com/npm/cli/pull/4562) deps: `pacote@13.0.5` - * [`9555a5f1d`](https://github.com/npm/cli/commit/9555a5f1d135aa1b8f7374273403efe41e99ee26) [#4562](https://github.com/npm/cli/pull/4562) deps: `npm-package-arg@9.0.1` - * [`b2a494283`](https://github.com/npm/cli/commit/b2a494283f45a25d1b87bc40bf2d68812871e89c) [#4562](https://github.com/npm/cli/pull/4562) deps: `normalize-package-data@4.0.0` - * [`1cb88f4b3`](https://github.com/npm/cli/commit/1cb88f4b31019af9cb8eac8a46433b44bba9d061) [#4562](https://github.com/npm/cli/pull/4562) deps: `hosted-git-info@5.0.0` - * [`f95396a03`](https://github.com/npm/cli/commit/f95396a033b75e2a3e9aa83f0b06c527641027a4) [#4562](https://github.com/npm/cli/pull/4562) deps: `cacache@16.0.1` - * [`aec2bfecc`](https://github.com/npm/cli/commit/aec2bfecca4ad3ee7db4481cf068add9c42e7160) [#4585](https://github.com/npm/cli/pull/4585) deps: `cacache@16.0.2` - * [`ed8ab63e4`](https://github.com/npm/cli/commit/ed8ab63e4a2c8e6527bf7d49736d1bbb6f0aead2) deps: `libnpmpack@4.0.2` - * [`0b73bfa82`](https://github.com/npm/cli/commit/0b73bfa82d4eb826ec0dbda4cc457c94580e0d64) deps: `libnpmteam@4.0.2` - * [`475d59b36`](https://github.com/npm/cli/commit/475d59b361ef9e260e21d39361baf92f2272f1d7) deps: `libnpmaccess@6.0.2` - * [`7201c7395`](https://github.com/npm/cli/commit/7201c7395f66d3faf24b361e69555490d606ed91) deps: `libnpmsearch@5.0.2` - * [`f5df358c3`](https://github.com/npm/cli/commit/f5df358c3af2c23e7818105608bcceabdd8b62fa) deps: `libnpmorg@4.0.2` - * [`472e7dd7a`](https://github.com/npm/cli/commit/472e7dd7aa6935cb6b89ec78cbce45f75f3f0044) deps: `libnpmhook@8.0.2` - * [`c901d7290`](https://github.com/npm/cli/commit/c901d7290ed09aefe3ba6e8c09cb3126f0d92f95) deps: `libnpmpublish@6.0.2` - * [`aad53327f`](https://github.com/npm/cli/commit/aad53327f23b123d0e017338a9a1b65d40f21efe) deps: `@npmcli/arborist@5.0.3` - * [`b40136bca`](https://github.com/npm/cli/commit/b40136bcaf32232e4cacdb517ce40f61871da159) deps: `libnpmdiff@4.0.2` - * [`5d91201d1`](https://github.com/npm/cli/commit/5d91201d1c69e3c095a4eedf0f1d702f35b0d8c1) deps: `libnpmexec@4.0.2` - -## v8.5.4 (2022-03-10) - +* [`398fed4`](https://github.com/npm/cli/commit/398fed45af63a8f7e3f5da8fc882674befd39216) [#8450](https://github.com/npm/cli/pull/8450) `normalize-package-data@7.0.1` +* [`5b242c9`](https://github.com/npm/cli/commit/5b242c9302e9ae1405b5ecbc76eb290c0f72634d) [#8450](https://github.com/npm/cli/pull/8450) `validate-npm-package-name@6.0.2` +* [`d4e8a8a`](https://github.com/npm/cli/commit/d4e8a8aba42f146a5feb20da262f92d0c3100986) [#8450](https://github.com/npm/cli/pull/8450) `tuf-js@3.1.0` +* [`e1b37b2`](https://github.com/npm/cli/commit/e1b37b2c84346eba3451369753756381658214b5) [#8450](https://github.com/npm/cli/pull/8450) `picomatch@4.0.3` +* [`3cb5884`](https://github.com/npm/cli/commit/3cb58842ff65a9ca2b31306e0e71ccf9ee5702e5) [#8450](https://github.com/npm/cli/pull/8450) `socks@2.8.6` +* [`daea981`](https://github.com/npm/cli/commit/daea98168b636b89ced80ab6d895ba7d9c5c8e20) [#8450](https://github.com/npm/cli/pull/8450) `ci-info@4.3.0` +* [`39ad47d`](https://github.com/npm/cli/commit/39ad47dd46dd69bcf16eb7dd5b6d8efec0d5d1c2) [#8450](https://github.com/npm/cli/pull/8450) `aproba@2.1.0` +* [`a789f33`](https://github.com/npm/cli/commit/a789f334757b691db02fcc182781d02b41e8bb5c) [#8450](https://github.com/npm/cli/pull/8450) `agent-base@7.1.4` +* [`1c0d257`](https://github.com/npm/cli/commit/1c0d257aa015297b703d0f413928bff661ed1430) [#8450](https://github.com/npm/cli/pull/8450) `@npmcli/metavuln-calculator@9.0.1` +### Chores +* [`804a964`](https://github.com/npm/cli/commit/804a9646e41d3aaa11ed084aa0c9997b7375882f) [#8450](https://github.com/npm/cli/pull/8450) update devDependencies in lockfile (@wraithgar) +* [`643ae71`](https://github.com/npm/cli/commit/643ae7104e5246a8ea10bfbd4f98540945c8430d) [#8450](https://github.com/npm/cli/pull/8450) update mock-registry to use local arborist (@wraithgar) +* [`cf023d7`](https://github.com/npm/cli/commit/cf023d71135427f2fdb290162432802e8a1514da) [#8421](https://github.com/npm/cli/pull/8421) contributing: prepare easier copy-paste contributing commands (#8421) (@MikeMcC399) +* [`3f60b5f`](https://github.com/npm/cli/commit/3f60b5f9621b43ae0b8796d3a7160a603748f756) [#8383](https://github.com/npm/cli/pull/8383) `@npmcli/template-oss@4.24.4` (#8383) (@wraithgar) +* [`01f8cc6`](https://github.com/npm/cli/commit/01f8cc6f001e3211135fa0563f7129aed09dc46c) [#8381](https://github.com/npm/cli/pull/8381) `@npmcli/template-oss@4.24.3` (#8381) (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.3): `@npmcli/arborist@9.1.3` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.3.1): `@npmcli/config@10.3.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.6): `libnpmdiff@8.0.6` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.5): `libnpmexec@10.1.5` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.6): `libnpmfund@7.0.6` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.6): `libnpmpack@9.0.6` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.1.0): `libnpmpublish@11.1.0` + +## [11.4.2](https://github.com/npm/cli/compare/v11.4.1...v11.4.2) (2025-06-11) ### Bug Fixes - -* [`fbdb43138`](https://github.com/npm/cli/commit/fbdb43138ab8e682efb7668767465e7066d43b9f) - [#4529](https://github.com/npm/cli/pull/4529) - fix(rebuild): don't run lifecycle scripts twice on linked deps - ([@wraithgar](https://github.com/wraithgar)) -* [`1c182e11d`](https://github.com/npm/cli/commit/1c182e11d524294d85348a3c2566f266bd281c00) - [#4495](https://github.com/npm/cli/pull/4495) - fix(doctor): don't retry ping - ([@wraithgar](https://github.com/wraithgar)) -* [`55ab38c53`](https://github.com/npm/cli/commit/55ab38c5337de76b739c4f0cdfb8932dc5420ce4) - [#4495](https://github.com/npm/cli/pull/4495) - fix(doctor): allow for missing local bin and `node_modules` - ([@wraithgar](https://github.com/wraithgar)) -* [`5c06a33e6`](https://github.com/npm/cli/commit/5c06a33e641594c5617a0606c338fc54c64d623b) - [#4528](https://github.com/npm/cli/pull/4528) - fix: clean up owner command and otplease - ([@wraithgar](https://github.com/wraithgar)) - +* [`f2d6947`](https://github.com/npm/cli/commit/f2d69478923b919c77bbb8bdb70c30ddeb59ffe7) [#8345](https://github.com/npm/cli/pull/8345) move warning to new line when `npm init` is canceled (@mbtools) +* [`e758dd7`](https://github.com/npm/cli/commit/e758dd7bec58efed2cc865a6d360b0432ccc9f57) [#8318](https://github.com/npm/cli/pull/8318) powershell: multiple Invoke-Expression fixes (#8318) (@alexsch01) ### Documentation - -* [`2485064da`](https://github.com/npm/cli/commit/2485064da590ef787e94a952e0bbdcd9f4880703) - [#4524](https://github.com/npm/cli/pull/4524) - docs: fix typo in configuring-npm/package-json.md - ([@dlcmh](https://github.com/dlcmh)) -* [`91f03ee61`](https://github.com/npm/cli/commit/91f03ee618bc635f9cfbded735fe98bbfa9d643f) - [#4510](https://github.com/npm/cli/pull/4510) - docs: standardize changelog heading - ([@wraithgar](https://github.com/wraithgar)) - +* [`7233cb3`](https://github.com/npm/cli/commit/7233cb3a159872236338b97bcb9d3797864abb33) [#8355](https://github.com/npm/cli/pull/8355) remove deprecated section related temp files (#8355) (@milaninfy) +* [`fb7a498`](https://github.com/npm/cli/commit/fb7a498d557abdd0c1a6945522d47878cf930a27) [#8351](https://github.com/npm/cli/pull/8351) clarify shell used for script (#8351) (@milaninfy) +* [`8b55d38`](https://github.com/npm/cli/commit/8b55d38cd2815a9503aed664c85eb678203dc4d4) [#8329](https://github.com/npm/cli/pull/8329) Rename "command" to "script" (#8329) (@DanKaplanSES) ### Dependencies - -* [`377f55e0e`](https://github.com/npm/cli/commit/377f55e0e786ac6c26d64848a89ce720c5d478eb) - [#4530](https://github.com/npm/cli/pull/4530) - deps: `make-fetch-happen@10.0.5` - * add code property to unsupported proxy url error -* [`40b7fbf67`](https://github.com/npm/cli/commit/40b7fbf670c8ba064b3a771981fa0510d63fb6ef) - [#4531](https://github.com/npm/cli/pull/4531) - deps: `read-package-json@4.1.2` - * don't throw exception on invalid main attr -* [`d9dc70ce4`](https://github.com/npm/cli/commit/d9dc70ce4d632b8b0401c41e9a015b8083e87db1) - [#4545](https://github.com/npm/cli/pull/4545) - deps: `map-workspaces@2.0.2` - * evaluate all patterns before throwing `EDUPLICATEWORKSPACE` -* [`70fcfb46b`](https://github.com/npm/cli/commit/70fcfb46bebc777e0ef6b36a47d9620807488acd) - deps: `libnpmfund@3.0.1` -* [`621cd033f`](https://github.com/npm/cli/commit/621cd033f64f101084af83ff8a797f5415a3b70d) - deps: `@npmcli/arborist@5.0.2` -* [`087fdc4cb`](https://github.com/npm/cli/commit/087fdc4cb4d6582b2b628087f866e8ca8bc00934) - deps: `libnpmpublish@6.0.1` -* [`d24c6d288`](https://github.com/npm/cli/commit/d24c6d288b1cfe6dd893a8ffedb15cbe6837d545) - deps: `libnpmhook@8.0.1` -* [`fa59830fc`](https://github.com/npm/cli/commit/fa59830fc429d354179853e8f9b9a32ef3444067) - deps: `libnpmsearch@5.0.1` -* [`6d5f22b86`](https://github.com/npm/cli/commit/6d5f22b86006e7c563161837f56e47079e0fde4a) - deps: `libnpmexec@4.0.1` -* [`69ea54350`](https://github.com/npm/cli/commit/69ea5435016a9d1c454af7253a80204dc9941380) - deps: `libnpmaccess@6.0.1` -* [`4742d7cf3`](https://github.com/npm/cli/commit/4742d7cf3ad15f5263fd5fefd15c04f9871c58af) - deps: `libnpmteam@4.0.1` -* [`fdd255ae9`](https://github.com/npm/cli/commit/fdd255ae9ebf41147085e74cec5c9f65eb5ff1de) - deps: `libnpmorg@4.0.1` -* [`ed41bc101`](https://github.com/npm/cli/commit/ed41bc10182ffd1db66181c20db6c348dba6783e) - deps: `libnpmdiff@4.0.1` -* [`21e241025`](https://github.com/npm/cli/commit/21e24102564e2f3c795312d256fade4228e67776) - deps: `libnpmversion@3.0.1` -* [`ec7f36ff9`](https://github.com/npm/cli/commit/ec7f36ff9e6c973ae5d5998a783bcff16027c282) - deps: `libnpmpack@4.0.1` -* [`ad4b56414`](https://github.com/npm/cli/commit/ad4b564148eaa6fdfe68e5b68f910e41e4e8ee14) - deps: `gauge@4.0.3` - -## v8.5.3 (2022-03-03) - -### Bug Fixes - -* [`defe79ad6`](https://github.com/npm/cli/commit/defe79ad6f2f4216bf5e0188256c77b49164eb94) - [#4480](https://github.com/npm/cli/pull/4480) - fix: publish of tarballs includes README in packument - ([@fritzy](https://github.com/fritzy)) -* [`45fc297f1`](https://github.com/npm/cli/commit/45fc297f12e63c026715945a186ba0ec4efbdedb) - [#4479](https://github.com/npm/cli/pull/4479) - fix: ignore implict workspace for some commands - ([@fritzy](https://github.com/fritzy)) -* [`a0900bdf1`](https://github.com/npm/cli/commit/a0900bdf1ab7a68988984735f1f3885d02ffb67f) - [#4481](https://github.com/npm/cli/pull/4481) - fix(ls): respect `--include-workspace-root` - ([@fritzy](https://github.com/fritzy)) -* [`0cfc155db`](https://github.com/npm/cli/commit/0cfc155db5f11ce23419e440111d99a63bf39754) - [#4476](https://github.com/npm/cli/pull/4476) - fix: set proper workspace repo urls in package.json - ([@ljharb](https://github.com/ljharb)) -* [`9e43de8a5`](https://github.com/npm/cli/commit/9e43de8a59e5bf354a9595ed8a79fedcec085aaa) - [#4493](https://github.com/npm/cli/pull/4493) - fix: ignore implicit workspace for whoami - ([@nlf](https://github.com/nlf)) - -### Dependencies - -* [`d13f067d9`](https://github.com/npm/cli/commit/d13f067d91283e1dec94780a3c007883de9edc46) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `@npmcli/run-script@3.0.1` - ([@wraithgar](https://github.com/wraithgar)) -* [`ce9a6eac0`](https://github.com/npm/cli/commit/ce9a6eac0c8329871664167c37f4982c5e443a2a) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `node-gyp@9.0.0` - ([@wraithgar](https://github.com/wraithgar)) -* [`bd660f5f1`](https://github.com/npm/cli/commit/bd660f5f1ccc1d9fa88085b168ea05b6dcf5826a) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `@npmcli/config@4.0.1` -* [`3c17b6965`](https://github.com/npm/cli/commit/3c17b6965f0c5fffd5ac908388568a307466a73f) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `make-fetch-happen@10.0.4` -* [`e9b69c4c5`](https://github.com/npm/cli/commit/e9b69c4c5454cc8b7d6cf2cbf1f09313f0d20afc) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `npm-registry-fetch@13.0.1` -* [`cf27ca888`](https://github.com/npm/cli/commit/cf27ca8884387f2b82f8f6900a29e4e41693e774) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `write-file-atomic@4.0.1` -* [`f3421921a`](https://github.com/npm/cli/commit/f3421921aa72ef570105474cdb2e48cec80de796) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `gauge@4.0.2` -* [`1dd2f7ee1`](https://github.com/npm/cli/commit/1dd2f7ee16a61024e520b3efa54f8cdba5458a16) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `socks@2.6.2` -* [`236e3b403`](https://github.com/npm/cli/commit/236e3b4030dd91397713eb02cdf2737dcc988fd7) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `minimatch@3.1.2` - ([@wraithgar](https://github.com/wraithgar)) -* [`10e1326d2`](https://github.com/npm/cli/commit/10e1326d2eb7ff2c70ee19907991b369476ccdd0) - [#4490](https://github.com/npm/cli/pull/4490) - deps: `lru-cache@7.4.0` - -## v8.5.2 (2022-02-24) - -### Bug Fixes - -* [`9bdd1ace8`](https://github.com/npm/cli/commit/9bdd1ace86300a8ee562027bbc5cb57d62dc7ba8) - [#4300](https://github.com/npm/cli/pull/4300) - fix(arborist): use full location as tracker key when inflating - ([@lukekarrys](https://github.com/lukekarrys)) ([@kirtangajjar](https://github.com/kirtangajjar)) -* [`c9ff797e8`](https://github.com/npm/cli/commit/c9ff797e8b5e5a7b39ced04b1d3f8a0006993a1f) - [#4457](https://github.com/npm/cli/pull/4457) - fix: remove html comments from man entries - ([@wraithgar](https://github.com/wraithgar)) -* [`f4c5f0e52`](https://github.com/npm/cli/commit/f4c5f0e52679b1aa42db833fc23dc07d96cc904e) - fix(arborist): fix unescaped periods (#4462) - ([@lukekarrys](https://github.com/lukekarrys)) -* [`c608512ed`](https://github.com/npm/cli/commit/c608512ed03ccf87dc989cec2849d14bf034513a) - [#4468](https://github.com/npm/cli/pull/4468) - fix: ignore integrity values for git dependencies - ([@lukekarrys](https://github.com/lukekarrys)) - +* [`7b05420`](https://github.com/npm/cli/commit/7b0542028f9c3cc326c26a1986c34cec7eb04931) [#8358](https://github.com/npm/cli/pull/8358) `fdir@6.4.6` +* [`e1a3b23`](https://github.com/npm/cli/commit/e1a3b23ebca0cb9b42c62a8c7b506ae9c2cc1a03) [#8358](https://github.com/npm/cli/pull/8358) `tinyglobby@0.2.14` +* [`522efa2`](https://github.com/npm/cli/commit/522efa2641780e1703d3578baeb94d3e57bcc8af) [#8358](https://github.com/npm/cli/pull/8358) `socks@2.8.5` +* [`7a0723f`](https://github.com/npm/cli/commit/7a0723f142b29065efec602e9e7d6585175e87a1) [#8358](https://github.com/npm/cli/pull/8358) `debug@4.4.1` +* [`9a342a4`](https://github.com/npm/cli/commit/9a342a4afb40d0668ab6a2c3820be7cacb4b79f7) [#8358](https://github.com/npm/cli/pull/8358) `brace-expansion@2.0.2` +* [`e691ba0`](https://github.com/npm/cli/commit/e691ba0918ea8526be9655f4c4c51e0887f7c623) [#8358](https://github.com/npm/cli/pull/8358) `@sigstore/protobuf-specs@0.4.3` +* [`42ef765`](https://github.com/npm/cli/commit/42ef765008ed76e5cc2521a92ba2d329933524b7) [#8358](https://github.com/npm/cli/pull/8358) `validate-npm-package-name@6.0.1` +* [`774c0b1`](https://github.com/npm/cli/commit/774c0b1e9c5704ffa24196fdcc44ba9575b04ca0) [#8358](https://github.com/npm/cli/pull/8358) `@npmcli/redact@3.2.2` +* [`dda6f87`](https://github.com/npm/cli/commit/dda6f871331280eeb37493a4ccc57361a27949eb) [#8317](https://github.com/npm/cli/pull/8317) `@npmcli/package-json@6.2.0` +* [`bc08ac7`](https://github.com/npm/cli/commit/bc08ac7a82f047485885d9c41a8b6fc48e8981b0) [#8317](https://github.com/npm/cli/pull/8317) remove normalize-package-data +### Chores +* [`0ad1444`](https://github.com/npm/cli/commit/0ad1444d76b0b68e4a4d48d7f22ebd4cd0d0e850) [#8358](https://github.com/npm/cli/pull/8358) dev dependency updates (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.2): `@npmcli/arborist@9.1.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.5): `libnpmdiff@8.0.5` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.4): `libnpmexec@10.1.4` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.5): `libnpmfund@7.0.5` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.5): `libnpmpack@9.0.5` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.0.1): `libnpmpublish@11.0.1` + +## [11.4.1](https://github.com/npm/cli/compare/v11.4.0...v11.4.1) (2025-05-21) ### Documentation +* [`3ed764a`](https://github.com/npm/cli/commit/3ed764aa08f2087fa1d1bd7391a646ba47565294) [#8308](https://github.com/npm/cli/pull/8308) Clarify script working directory behavior (fixes #8305) (#8308) (@tarekwfa0110, @owlstronaut) +### Chores +* [`2f30251`](https://github.com/npm/cli/commit/2f302516401928239593dd2eebc171729df60537) [#8314](https://github.com/npm/cli/pull/8314) remove references to skimdb.npmjs.com (#8314) (@shmam) +* [`9cb9d50`](https://github.com/npm/cli/commit/9cb9d5030b1fdb83e3ffa45b7c8d2de80a657768) [#8298](https://github.com/npm/cli/pull/8298) add contributor to changelog entry (#8298) (@wraithgar) -* [`e83e5c9ba`](https://github.com/npm/cli/commit/e83e5c9bad93e598969088ae780149dbe34c6b5c) - [#4435](https://github.com/npm/cli/pull/4435) - docs: clarify npm init @latest behavior - ([@wraithgar](https://github.com/wraithgar)) -* [`d8fa9fa5e`](https://github.com/npm/cli/commit/d8fa9fa5e44d91e1c0170628d4839f7802c65a7f) - [#4436](https://github.com/npm/cli/pull/4436) - docs: explain $INIT_CWD on using scripts page - ([@wraithgar](https://github.com/wraithgar)) -* [`6b68c1aaa`](https://github.com/npm/cli/commit/6b68c1aaa282205eb4d47dbc81909c11851f7e06) - [#4450](https://github.com/npm/cli/pull/4450) - docs: auto-generate npm usage for each command - ([@manekinekko](https://github.com/manekinekko)) - -### Dependencies - -* [`d58e4442b`](https://github.com/npm/cli/commit/d58e4442b0a16c84219d5f80ab88ef68ad209918) - deps `@npmcli/arborist@5.0.0` -* [`77399cb98`](https://github.com/npm/cli/commit/77399cb988d984133bfc2885a6407ffc56b9152d) - deps: `libnpmaccess@6.0.0` -* [`9633752cd`](https://github.com/npm/cli/commit/9633752cd5c4a0d240adcb24f0ae7e3fafd122ba) - deps: `libnpmdiff@4.0.0` -* [`938750581`](https://github.com/npm/cli/commit/9387505819f0e7e4b3d76dd3e2bd8636a1bb6306) - deps: `libnpmexec@4.0.0` -* [`2c86feaf1`](https://github.com/npm/cli/commit/2c86feaf1f974ee510563c7d93c0dd26f6355b15) - deps: `libnpmfund@3.0.0` -* [`1dab29805`](https://github.com/npm/cli/commit/1dab29805c820f82e4bae18123e911fec6948dfd) - deps: `libnpmhook@8.0.0` -* [`cf273f1cf`](https://github.com/npm/cli/commit/cf273f1cf31775c8a73cc67b654faf87b44f7f79) - deps: `libnpmorg@4.0.0` -* [`8b1d9636a`](https://github.com/npm/cli/commit/8b1d9636ad2374254263d154f2b4ca8ea6416f4c) - deps: `libnpmpack@4.0.0` -* [`67aed0542`](https://github.com/npm/cli/commit/67aed05429163fc120e05e6fb15f8f3cd9c6ef22) - deps: `libnpmpublish@6.0.0` -* [`8b26a6db1`](https://github.com/npm/cli/commit/8b26a6db13c37a6f0df86c54ca859ad2f9627825) - deps: `libnpmsearch@5.0.0` -* [`0b2fa7fed`](https://github.com/npm/cli/commit/0b2fa7feda4643fe16c9a492497908f94d310dbd) - deps: `libnpmteam@4.0.0` -* [`2646d199f`](https://github.com/npm/cli/commit/2646d199f26f77c4197ec0bcf30c3e452844c1ab) - deps: `libnpmversion@3.0.0` -* [`5b29666e5`](https://github.com/npm/cli/commit/5b29666e566c09dc685108daaa20163dd58ade2b) - [#4459](https://github.com/npm/cli/pull/4459) - deps: `columnify@1.6.0 and dedupe vulnerable deps` - -## v8.5.1 (2022-02-17) ### Dependencies -* [`54cda9697`](https://github.com/npm/cli/commit/54cda9697b776fae807966097315c7b836623743) - [#4410](https://github.com/npm/cli/pull/4410) - fix(arborist): do not audit in offline mode - ([@mohd-akram](https://github.com/mohd-akram)) -* [`fb13bdaf1`](https://github.com/npm/cli/commit/fb13bdaf12dde3ef5685a77354e51a9cfa579879) - [#4403](https://github.com/npm/cli/pull/4403) - deps: `@npmcli/ci-detect@2.0.0` -* [`702801002`](https://github.com/npm/cli/commit/702801002e99bf02dd4d6d1e447a5ab332d56c79) - [#4415](https://github.com/npm/cli/pull/4415) - deps: `make-fetch-happen@10.0.3` -* [`88bab3540`](https://github.com/npm/cli/commit/88bab354097023c96c49e78d7ee54159f495bf73) - [#4416](https://github.com/npm/cli/pull/4416) - deps: `gauge@4.0.1` - -### Documentation - -* [`20378c67c`](https://github.com/npm/cli/commit/20378c67cd533db514dd2aec7828c6d119e9d6c7) - [#4423](https://github.com/npm/cli/pull/4423) - docs: update documentation for ping - ([@fhinkel](https://github.com/fhinkel)) -* [`408d2fc15`](https://github.com/npm/cli/commit/408d2fc150185ef66125f7d6bdb1c25edb71bba3) - [#4426](https://github.com/npm/cli/pull/4426) - docs: update workspaces guide for consistency - ([@bnb](https://github.com/bnb)) -* [`9275856eb`](https://github.com/npm/cli/commit/9275856eb75e7c394a3c7617c2b495aba35ee2de) - [#4424](https://github.com/npm/cli/pull/4424) - docs: update usage example for npm pkg - ([@manekinekko](https://github.com/manekinekko)) -* [`20c83fae7`](https://github.com/npm/cli/commit/20c83fae76ff4a051e4f6542a328f1c00cf071bb) - [#4428](https://github.com/npm/cli/pull/4428) - docs: update docs for npm install <folder> - ([@manekinekko](https://github.com/manekinekko)) - -## v8.5.0 (2022-02-10) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.1): `@npmcli/arborist@9.1.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.4): `libnpmdiff@8.0.4` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.3): `libnpmexec@10.1.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.4): `libnpmfund@7.0.4` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.4): `libnpmpack@9.0.4` +## [11.4.0](https://github.com/npm/cli/compare/v11.3.0...v11.4.0) (2025-05-15) ### Features - -* [`0cc9d4c51`](https://github.com/npm/cli/commit/0cc9d4c51a337af0edd2e20c6fadb26807e5d09f) - [#4372](https://github.com/npm/cli/pull/4372) - feat(deps): `@npmcli/config@3.0.0 - introduce automatic workspace roots` - ([@nlf](https://github.com/nlf)) - +* [`a0e60fb`](https://github.com/npm/cli/commit/a0e60fb1893ac77a78380d9a9faaaaa54da1fe85) [#8246](https://github.com/npm/cli/pull/8246) added init-private option (@owlstronaut) +* [`57aa89f`](https://github.com/npm/cli/commit/57aa89ff70e0c6186a43888b944b5799b25c7bc8) [#8265](https://github.com/npm/cli/pull/8265) use run by default and run-script as the alias (#8265) (@owlstronaut) +* [`0d4c023`](https://github.com/npm/cli/commit/0d4c023914f835927540bd0110c1ca5716b84056) [#8234](https://github.com/npm/cli/pull/8234) install: add package info to json output (#8234) (@wraithgar) ### Bug Fixes - -* [`fb6e2ddf9`](https://github.com/npm/cli/commit/fb6e2ddf942bacf5ae745d16c2d57f3836dce75a) - [#4386](https://github.com/npm/cli/pull/4386) - fix(log): pass in logger to more external modules - ([@wraithgar](https://github.com/wraithgar)) -* [`0e231d4a4`](https://github.com/npm/cli/commit/0e231d4a40526608411aca0a6e7cf27c750f2409) - [#4389](https://github.com/npm/cli/pull/4389) - fix(pack): let libnpmpack take care of file writes - ([@nlf](https://github.com/nlf)) -* [`e2f1f7b04`](https://github.com/npm/cli/commit/e2f1f7b045a3ae9840f431cb4266ba046831247b) - [#4389](https://github.com/npm/cli/pull/4389) - fix(publish): pass dryRun: true to libnpmpack so it doesnt write a tarball - ([@nlf](https://github.com/nlf)) -* [`2937b43d4`](https://github.com/npm/cli/commit/2937b43d4629225d83b6c71833df00743209f5ff) - [#4389](https://github.com/npm/cli/pull/4389) - fix(config): add pack-destination flattener - ([@nlf](https://github.com/nlf)) - +* [`8794fd9`](https://github.com/npm/cli/commit/8794fd9161c29fea3f51ae8581f54172011d4069) [#8297](https://github.com/npm/cli/pull/8297) powershell: support pipeline input with Invoke-Expression (#8297) (@alexsch01) +* [`b5173d1`](https://github.com/npm/cli/commit/b5173d13c182efa5434ef4ca413e62ce1437f47a) [#8293](https://github.com/npm/cli/pull/8293) docs: corrected github_path (#8293) (@xaos7991) +* [`2210d7a`](https://github.com/npm/cli/commit/2210d7a670ac3522ceee8856a3399e8f44e77bbe) [#8278](https://github.com/npm/cli/pull/8278) powershell: use Invoke-Expression to pass args (#8278) (@alexsch01, @mbtools) +* [`8669d09`](https://github.com/npm/cli/commit/8669d0931abd0ae4b655cf9e5a024065054a8bb4) [#8228](https://github.com/npm/cli/pull/8228) add otplease for enable-2fa, disable-2fa, access (#8228) (@reggi, @wraithgar) +* [`78b5a6f`](https://github.com/npm/cli/commit/78b5a6fa9cd103bb80a25957ddfcb5832bc1f937) [#8269](https://github.com/npm/cli/pull/8269) correctly handle scenario where prefix is the cwd (#8269) (@owlstronaut, @ficocelliguy) +* [`fdc3413`](https://github.com/npm/cli/commit/fdc3413019c2f34f1fde35449e5f3a6b0fb51ba2) [#8221](https://github.com/npm/cli/pull/8221) exec: Fails to Execute Binaries Named After Shell Keywords (#8221) (@13sfaith) +* [`4b08e2e`](https://github.com/npm/cli/commit/4b08e2ed252a18f85a360b76c7273a7aa7a994ca) [#8245](https://github.com/npm/cli/pull/8245) docs: prepare script runs for local package links (@milaninfy) +* [`1622ac4`](https://github.com/npm/cli/commit/1622ac456f07403e6afe02352b8f95db14dcf9eb) [#8241](https://github.com/npm/cli/pull/8241) handle missing `time` in packument to prevent crash on `npm view` (@owlstronaut) +* [`db8f5da`](https://github.com/npm/cli/commit/db8f5da886326ae40d44a8cceedb99e2e6a00855) [#8110](https://github.com/npm/cli/pull/8110) outdated: add dependent location in long output (#8110) (@milaninfy, @wraithgar) ### Documentation - -* [`b836d596f`](https://github.com/npm/cli/commit/b836d596f9d98cd7849882000cad11ad2a0b9a26) - [#4384](https://github.com/npm/cli/pull/4384) - docs: add cross-references between npx and npm exec - ([@Delapouite](https://github.com/Delapouite)) -* [`f3fbeea5a`](https://github.com/npm/cli/commit/f3fbeea5a173902ca7455c6c94a9e677591b0410) - [#4388](https://github.com/npm/cli/pull/4388) - docs: add --save-bundle to --save usage output - ([@wraithgar](https://github.com/wraithgar)) - +* [`d2498df`](https://github.com/npm/cli/commit/d2498df8efa558c3048f71324be0ef189c14bd49) [#8295](https://github.com/npm/cli/pull/8295) Remove `CHANGELOG` from never-ignored list (#8295) (@mrazauskas) +* [`4d5c3c1`](https://github.com/npm/cli/commit/4d5c3c1d8d99e352b1b4906c2607752ee3051a75) [#8283](https://github.com/npm/cli/pull/8283) fix `overrides` example in package-json.md (#8283) (@glasser) +* [`96cc4f9`](https://github.com/npm/cli/commit/96cc4f9a87a231abf4c9584a277765368ba6663d) [#8226](https://github.com/npm/cli/pull/8226) format publish as code to highlight it (@LiangYingC) +* [`4990ea0`](https://github.com/npm/cli/commit/4990ea0f0c017e4702cf2da2fbd99dad61c77015) [#8226](https://github.com/npm/cli/pull/8226) clarify legacy token creation in npm login and adduser commands (@LiangYingC) ### Dependencies - -* [`8732f393e`](https://github.com/npm/cli/commit/8732f393ee547e2eada4317613599517c1d8ec0a) - deps: `@npmcli/arborist@4.3.1` - * [`2ba09cc0d`](https://github.com/npm/cli/commit/2ba09cc0d7d56a064aa67bbb1881d381e6504888) - [#4371](https://github.com/npm/cli/pull/4371) - fix(arborist): check if a spec is a workspace before fetching a manifest, closes #3637 - ([@nlf](https://github.com/nlf)) - * [`e631faf7b`](https://github.com/npm/cli/commit/e631faf7b5f414c233d723ee11413264532b37de) - [#4387](https://github.com/npm/cli/pull/4387) - fix(arborist): save bundleDependencies to package.json when reifying - ([@wraithgar](https://github.com/wraithgar)) -* [`d3a7c15e1`](https://github.com/npm/cli/commit/d3a7c15e1e3d305a0bf781493406dfb1fdbaca35) - deps: `libnpmpack@3.1.0` - * [`4884821f6`](https://github.com/npm/cli/commit/4884821f637ca1992b494fbdbd94d000e4428a40) - [#4389](https://github.com/npm/cli/pull/4389) - feat(libnpmpack): write tarball file when dryRun === false - ([@nlf](https://github.com/nlf)) -* [`ab926995e`](https://github.com/npm/cli/commit/ab926995e43ccdd048a6e1164b436fea1940f932) - [#4393](https://github.com/npm/cli/pull/4393) - deps: `npm-registry-fetch@12.0.2` -* [`1c0d0699c`](https://github.com/npm/cli/commit/1c0d0699c13e1cb36a69f2ac4acdb78ea205aa3e) - [#4394](https://github.com/npm/cli/pull/4394) - deps: `npmlog@6.0.1` - * changed notice color from blue to cyan for improved readability -* [`3c33a5842`](https://github.com/npm/cli/commit/3c33a584213e4f2230f3b912fad2c2f5786906fb) - [#4400](https://github.com/npm/cli/pull/4400) - deps: `make-fetch-happen@10.0.2` - -## v8.4.1 (2022-02-03) - +* [`c97ef8a`](https://github.com/npm/cli/commit/c97ef8ae62187b5330c82887e9f566a4d2466cc4) [#8246](https://github.com/npm/cli/pull/8246) `init-package-json@8.2.1` +* [`f48613d`](https://github.com/npm/cli/commit/f48613d0403a5267a7a55cbaa9d1e814d2033fe4) [#8292](https://github.com/npm/cli/pull/8292) `@sigstore/verify@2.1.1` +* [`a4c5e74`](https://github.com/npm/cli/commit/a4c5e7455b621a4dffa893fef0ebf8ffa2307b1f) [#8292](https://github.com/npm/cli/pull/8292) `tinyglobby@0.2.13` +* [`b9156d2`](https://github.com/npm/cli/commit/b9156d2144ca387edd13178547c0ec276450f118) [#8292](https://github.com/npm/cli/pull/8292) `http-cache-semantics@4.2.0` +* [`472a685`](https://github.com/npm/cli/commit/472a685a8fe4d120a86ea6c7ee50e304bc8e7e94) [#8292](https://github.com/npm/cli/pull/8292) `binary-extensions@3.1.0` +* [`988696e`](https://github.com/npm/cli/commit/988696eb93548e703ae04496d0e361a6015cb0d3) [#8292](https://github.com/npm/cli/pull/8292) `@sigstore/tuf@3.1.1` +* [`569ac84`](https://github.com/npm/cli/commit/569ac84537f05450260e05d006361cdfe586359b) [#8292](https://github.com/npm/cli/pull/8292) `semver@7.7.2` +* [`2521c9b`](https://github.com/npm/cli/commit/2521c9ba18172c2ade525cbe9a675d293a0484d9) [#8233](https://github.com/npm/cli/pull/8233) `@sigstore/protobuf-specs@0.4.1` +* [`3274d68`](https://github.com/npm/cli/commit/3274d68b13595415586b41445838cc258543173a) [#8233](https://github.com/npm/cli/pull/8233) `@npmcli/query@4.0.1` +* [`c263626`](https://github.com/npm/cli/commit/c2636268e83b8049789534e78f4c15913e047c89) [#8233](https://github.com/npm/cli/pull/8233) `abbrev@3.0.1` +* [`78df711`](https://github.com/npm/cli/commit/78df711a60aaf8538b9fcaf13f2f9d50ce62b7b8) [#8233](https://github.com/npm/cli/pull/8233) `hosted-git-info@8.1.0` +### Chores +* [`e80e38e`](https://github.com/npm/cli/commit/e80e38eb961865de4006dc0e2ea991aebb1a3bdf) [#8292](https://github.com/npm/cli/pull/8292) dev dependency updates (@wraithgar) +* [`3231ee9`](https://github.com/npm/cli/commit/3231ee9afefcadce2b17a143fd51d365de4d6dea) [#8244](https://github.com/npm/cli/pull/8244) update snapshots (@owlstronaut) +* [`c561a33`](https://github.com/npm/cli/commit/c561a3307b18f9c208eb7305db0f2a51db61277d) [#8233](https://github.com/npm/cli/pull/8233) dev dependency updates (@owlstronaut) +* [`7eca19c`](https://github.com/npm/cli/commit/7eca19cb5ddc32688a8e331d5468d58f14684bff) [#8215](https://github.com/npm/cli/pull/8215) update workflow permissions for updating Node PR (@owlstronaut) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.1.0): `@npmcli/arborist@9.1.0` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.3.0): `@npmcli/config@10.3.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmaccess-v10.0.1): `libnpmaccess@10.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.3): `libnpmdiff@8.0.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.2): `libnpmexec@10.1.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.3): `libnpmfund@7.0.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.3): `libnpmpack@9.0.3` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmteam-v8.0.1): `libnpmteam@8.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmversion-v8.0.1): `libnpmversion@8.0.1` + +## [11.3.0](https://github.com/npm/cli/compare/v11.2.0...v11.3.0) (2025-04-08) +### Features +* [`b306d25`](https://github.com/npm/cli/commit/b306d25df2f2e6ae75fd4f6657e0858b6dd71c43) [#8129](https://github.com/npm/cli/pull/8129) add `node-gyp` as actual config (@wraithgar) ### Bug Fixes - -* [`1b9338554`](https://github.com/npm/cli/commit/1b9338554fc006954fae54c25c33e64e26ae997e) - [#4359](https://github.com/npm/cli/pull/4359) - fix(log): pass in logger to external modules - ([@wraithgar](https://github.com/wraithgar)) -* [`457e0ae61`](https://github.com/npm/cli/commit/457e0ae61bbc55846f5af44afa4066921923490f) - [#4363](https://github.com/npm/cli/pull/4363) - fix(ci): lock file validation - ([@ruyadorno](https://github.com/ruyadorno)) -* [`c0519edc1`](https://github.com/npm/cli/commit/c0519edc16f66370b2153430342247b4ec5cb496) - [#4364](https://github.com/npm/cli/pull/4364) - fix(ci): should not use package-lock config - ([@ruyadorno](https://github.com/ruyadorno)) -* [`ebb428375`](https://github.com/npm/cli/commit/ebb428375cd417c096d5a648df92620dc4215a3d) - [#4365](https://github.com/npm/cli/pull/4365) - fix(outdated): parse aliased modules - ([@ruyadorno](https://github.com/ruyadorno)) - +* [`2f5392a`](https://github.com/npm/cli/commit/2f5392ae1f87fd3df3d7e521e0e69222fb9899e5) [#8135](https://github.com/npm/cli/pull/8135) make `npm run` autocomplete work with workspaces (#8135) (@terrainvidia) ### Documentation - -* [`0b0a7cc76`](https://github.com/npm/cli/commit/0b0a7cc767947ea738da50caa832d8a922e20ac6) - [#4361](https://github.com/npm/cli/pull/4361) - docs: bundleDependencies can be a boolean. - ([@forty](https://github.com/forty)) - +* [`26b6454`](https://github.com/npm/cli/commit/26b64543ebb27e421c05643eb996f6765c13444c) fix grammar in local path note (@cgay) +* [`1c0e83d`](https://github.com/npm/cli/commit/1c0e83d6c165a714c7c37c0887e350042e53cf34) [#7886](https://github.com/npm/cli/pull/7886) fix typo in package-json.md (#7886) (@stoneLeaf) +* [`14efa57`](https://github.com/npm/cli/commit/14efa57f13b2bbbf10b0b217b981f919556789cd) [#8178](https://github.com/npm/cli/pull/8178) fix example package name in `overrides` explainer (#8178) (@G-Rath) +* [`4183cba`](https://github.com/npm/cli/commit/4183cba3e13bcfea83fa3ef2b6c5b0c9685f79bc) [#8162](https://github.com/npm/cli/pull/8162) logging: replace proceeding with preceding in loglevels details (#8162) (@tyleralbee) ### Dependencies - -* [`3d41447b9`](https://github.com/npm/cli/commit/3d41447b961a72f1ce541fea252d0cd462399c76) - [#4353](https://github.com/npm/cli/pull/4353) - deps: `wide-align@1.1.5` -* [`dc1a0573a`](https://github.com/npm/cli/commit/dc1a0573ace328d985a741af76d03752b1dbf1ff) - [#4353](https://github.com/npm/cli/pull/4353) - deps: `socks-proxy-agent@6.1.1` -* [`adcefef6b`](https://github.com/npm/cli/commit/adcefef6b953e0804f4a2de3a1912321f44c4a7e) - [#4353](https://github.com/npm/cli/pull/4353) - deps: `spdx-license-ids@3.0.11` -* [`d7e2499e0`](https://github.com/npm/cli/commit/d7e2499e073301a62607266d3ab8f9b63d630fb5) - [#4353](https://github.com/npm/cli/pull/4353) - deps: `debug@4.3.3` -* [`f0f307140`](https://github.com/npm/cli/commit/f0f30714002db979a2707d85c65bb92ae0ff76fe) - [#4353](https://github.com/npm/cli/pull/4353) - deps: `@npmcli/fs@1.1.0` -* [`1cb107d33`](https://github.com/npm/cli/commit/1cb107d33d7e1499d92c3405fa0694142bdee8df) - [#4353](https://github.com/npm/cli/pull/4353) - deps: `is-core-module@2.8.1` -* [`e198ac0d1`](https://github.com/npm/cli/commit/e198ac0d1c1e536db57e84af6e7f40089b4c1bfc) - [#4354](https://github.com/npm/cli/pull/4354) - deps: `cli-table3@0.6.1` -* [`5a84e6515`](https://github.com/npm/cli/commit/5a84e6515a0331be20395ce2a6b1e892ecea20f8) - [#4355](https://github.com/npm/cli/pull/4355) - deps: `graceful-fs@4.2.9` - -## v8.4.0 (2022-01-27) - +* [`e57f112`](https://github.com/npm/cli/commit/e57f1126e496aa88e7164bf3102147b95d96c9c8) [#8207](https://github.com/npm/cli/pull/8207) `minipass-fetch@4.0.1` +* [`3daabb1`](https://github.com/npm/cli/commit/3daabb1a0cd048db303a9246ab6855f2a0550c96) [#8207](https://github.com/npm/cli/pull/8207) `minizlib@3.0.2` +* [`c7a7527`](https://github.com/npm/cli/commit/c7a752709509baffe674ca6d49e480835ff4a2df) [#8207](https://github.com/npm/cli/pull/8207) `ci-info@4.2.0` +* [`20b09b6`](https://github.com/npm/cli/commit/20b09b67bedca8d2d49404d32d031bf1d875bf81) [#8207](https://github.com/npm/cli/pull/8207) `node-gyp@11.2.0` +* [`679bc4a`](https://github.com/npm/cli/commit/679bc4a71614bffedfbea3058af13c7deb69fcd4) [#8129](https://github.com/npm/cli/pull/8129) `@npmcli/run-script@9.1.0` +### Chores +* [`3fbed84`](https://github.com/npm/cli/commit/3fbed848c1f909cf1321ad0916f938bae116219f) [#8207](https://github.com/npm/cli/pull/8207) install rimraf as a devdependency for smoke tests (@owlstronaut) +* [`43f0b41`](https://github.com/npm/cli/commit/43f0b41a17b32997e7de9369c485acc8aa661c0a) [#8207](https://github.com/npm/cli/pull/8207) dev dependency updates (@wraithgar) +* [`26803bc`](https://github.com/npm/cli/commit/26803bc46cf85e400b66644c975ee99f6fd0575e) [#8147](https://github.com/npm/cli/pull/8147) release integration node 23 yml (#8147) (@reggi) +* [`d679a1a`](https://github.com/npm/cli/commit/d679a1ae9e22eb01663d3390b9522b1b5380db32) [#8146](https://github.com/npm/cli/pull/8146) release integration node 23 (#8146) (@reggi) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.0.2): `@npmcli/arborist@9.0.2` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.2.0): `@npmcli/config@10.2.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.2): `libnpmdiff@8.0.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.1): `libnpmexec@10.1.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.2): `libnpmfund@7.0.2` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.2): `libnpmpack@9.0.2` + +## [11.2.0](https://github.com/npm/cli/compare/v11.1.0...v11.2.0) (2025-03-05) ### Features - -* [`fbe48a840`](https://github.com/npm/cli/commit/fbe48a84047e0c5de31bdaa84707f0f8fdcef71d) - [#4307](https://github.com/npm/cli/pull/4307) - feat(arborist): add named updates validation - ([@ruyadorno](https://github.com/ruyadorno)) - +* [`247ee1d`](https://github.com/npm/cli/commit/247ee1d95a12983e181c3c3f2f1fdb790dd21794) [#8100](https://github.com/npm/cli/pull/8100) cache: add npx commands (@wraithgar) +* [`3a80a7b`](https://github.com/npm/cli/commit/3a80a7b7d168c23b5e297cba7b47ba5b9875934d) [#8081](https://github.com/npm/cli/pull/8081) add --init-type flag (#8081) (@reggi) +* [`2a1e11f`](https://github.com/npm/cli/commit/2a1e11f1f6e4a4c948b8ac52b9cda8f370d8674b) [#8071](https://github.com/npm/cli/pull/8071) move nerfDart list into @npmcli/config (@wraithgar) ### Bug Fixes - -* [`1f853f8bf`](https://github.com/npm/cli/commit/1f853f8bf7cecd1222703dde676a4b664526141d) - [#4306](https://github.com/npm/cli/pull/4306) - fix(arborist): load actual tree on named updates - ([@ruyadorno](https://github.com/ruyadorno)) -* [`90c384ccc`](https://github.com/npm/cli/commit/90c384ccccac32c80c481a04c438cbcbea82539c) - [#4326](https://github.com/npm/cli/pull/4326) - fix(logout): require proper auth.js from npm-registry-fetch - ([@wraithgar](https://github.com/wraithgar)) -* [`fabcf431a`](https://github.com/npm/cli/commit/fabcf431a63ecf93b56ae5d9a05ad4e7ef280c2a) - [#4327](https://github.com/npm/cli/pull/4327) - fix(arborist): correctly load overrides on workspace edges, closes #4205 - ([@nlf](https://github.com/nlf)) -* [`8c3b143ca`](https://github.com/npm/cli/commit/8c3b143ca20d0da56c0ce2764e288a4c203b9f93) - [#4258](https://github.com/npm/cli/pull/4258) - fix(arborist): shrinkwrap throws when trying to read a folder without permissions - ([@Linkgoron](https://github.com/Linkgoron)) -* [`b51b29c56`](https://github.com/npm/cli/commit/b51b29c563fa97aa4fbf38250d1f04e879a8d961) - [#4334](https://github.com/npm/cli/pull/4334) - fix(arborist): update save exact - ([@ruyadorno](https://github.com/ruyadorno)) - +* [`8461186`](https://github.com/npm/cli/commit/846118686849f821b084775f7891038013f7ba97) [#8100](https://github.com/npm/cli/pull/8100) update npx cache if possible when spec is a range (@wraithgar) +* [`e345cc5`](https://github.com/npm/cli/commit/e345cc58ecad0e1e18eefc00638d7fa32966c2b7) [#8050](https://github.com/npm/cli/pull/8050) don't suggest npm update outside of valid engine range (#8050) (@milaninfy) +* [`811ca29`](https://github.com/npm/cli/commit/811ca2927eed733c8fabf308bf9d467e7c959163) [#8115](https://github.com/npm/cli/pull/8115) stop working around bug fixed in `npm-package-arg@12.0.2` (@TrevorBurnham) +* [`879303c`](https://github.com/npm/cli/commit/879303cd7c529a04d855f47d14dce433118ac626) [#8078](https://github.com/npm/cli/pull/8078) warn on invalid publishConfig (#8078) (@wraithgar) +* [`41417de`](https://github.com/npm/cli/commit/41417de9f493969a5826d05d7024fdd1da8d88da) [#8080](https://github.com/npm/cli/pull/8080) warn when TUF fetching of keys fails (#8080) (@wraithgar) +* [`593c849`](https://github.com/npm/cli/commit/593c84921b0df963cef2ca7b13e44acc20cbd558) [#8076](https://github.com/npm/cli/pull/8076) warn on invalid single-hyphen cli flags (#8076) (@wraithgar) ### Dependencies - -* [`8558527c7`](https://github.com/npm/cli/commit/8558527c7158b2c1c353f8ab9c31de2a66ab470e) - [#4333](https://github.com/npm/cli/pull/4333) - deps: `make-fetch-happen@10.0.0` - * compress option and accept/content encoding header edge cases - * strip cookie header on redirect across hostnames -* [`1bfc507f2`](https://github.com/npm/cli/commit/1bfc507f2a5afa02f04d4dea2fc6d151d4fef3ac) - [#4326](https://github.com/npm/cli/pull/4326) - deps: `npm-registry-fetch@12.0.1` -* [`52c9608e7`](https://github.com/npm/cli/commit/52c9608e7bb1cda396b2cef3fc1b48dbaa2b7de3) - [#4326](https://github.com/npm/cli/pull/4326) - deps: `pacote@12.0.3` -* [`2bbeedfeb`](https://github.com/npm/cli/commit/2bbeedfebb3aea082d612deb5e4d9de9e550c529) - [#4326](https://github.com/npm/cli/pull/4326) - deps: `npm-profile@6.0.0` -* [`9652d685b`](https://github.com/npm/cli/commit/9652d685b1e4bd21cec107a611c2e307387623d6) - chore(release): `@npmcli/arborist@4.3.0` - ([@wraithgar](https://github.com/wraithgar)) -* [`0ee4927d2`](https://github.com/npm/cli/commit/0ee4927d2e8206dd24fa7eea5e1c10ea649ecc49) - chore(release): `libnpmaccess@5.0.1` - ([@wraithgar](https://github.com/wraithgar)) -* [`6c0dc1ffb`](https://github.com/npm/cli/commit/6c0dc1ffb70858be1e9ca9afdb6950e39609a367) - chore(release): `libnpmexec@3.0.3` - ([@wraithgar](https://github.com/wraithgar)) -* [`41b8f7b6f`](https://github.com/npm/cli/commit/41b8f7b6ff62f0e738865eb8e98df8650f5467bd) - chore(release): `libnpmorg@3.0.1` - ([@wraithgar](https://github.com/wraithgar)) -* [`433e6aafb`](https://github.com/npm/cli/commit/433e6aafbbf56efcf71e991767a6f00afe4aba7c) - chore(release): `libnpmpublish@5.0.1` - ([@wraithgar](https://github.com/wraithgar)) -* [`6654b6efe`](https://github.com/npm/cli/commit/6654b6efe02666bdb9864f4608e477ba132fd215) - chore(release): `libnpmsearch@4.0.1` - ([@wraithgar](https://github.com/wraithgar)) -* [`3423a9804`](https://github.com/npm/cli/commit/3423a980436492b7f0ee9e002517387a801f4f4a) - chore(release): `libnpmteam@3.0.1` - ([@wraithgar](https://github.com/wraithgar)) -* [`fb03e485d`](https://github.com/npm/cli/commit/fb03e485d9b1f09eb1cbcce00ee8e3e5c012097f) - chore(release): `libnpmhook@7.0.1` - ([@wraithgar](https://github.com/wraithgar)) - -## v8.3.2 (2022-01-20) - +* [`3d8b257`](https://github.com/npm/cli/commit/3d8b257bd667e76e74236c756aaa2dceaa6d6e5e) [#8100](https://github.com/npm/cli/pull/8100) `@npmcli/package-json@6.1.1` +* [`ab17523`](https://github.com/npm/cli/commit/ab175238dd885e2aa6cf2be21796055c629ec1e5) [#8134](https://github.com/npm/cli/pull/8134) `supports-color@10.0.0` +* [`3cbe21a`](https://github.com/npm/cli/commit/3cbe21ae64d5c1276c9aa6b53876fe86c165867d) [#8134](https://github.com/npm/cli/pull/8134) `foreground-child@3.3.1` +* [`ee5e1aa`](https://github.com/npm/cli/commit/ee5e1aa43e69e89da5ce210969a2f4cc1e3e08b0) [#8118](https://github.com/npm/cli/pull/8118) `@npmcli/redact@3.1.1` +* [`5df69b4`](https://github.com/npm/cli/commit/5df69b42be4e16b770d4452520a37f9456c26b66) [#8118](https://github.com/npm/cli/pull/8118) `exponential-backoff@3.1.2` +* [`80c3273`](https://github.com/npm/cli/commit/80c3273901e9878ec5492e8d99cca5ef14324a60) [#8118](https://github.com/npm/cli/pull/8118) `read@4.1.0` +* [`7fd70fa`](https://github.com/npm/cli/commit/7fd70fa2660c549cb564f956db0f5d0d2363db98) [#8118](https://github.com/npm/cli/pull/8118) `node-gyp@11.1.0` +* [`7aeffff`](https://github.com/npm/cli/commit/7aeffff2a39446b28319cbac5dbbd949d1965412) [#8118](https://github.com/npm/cli/pull/8118) `cidr-regex@4.1.3` +* [`b0c0490`](https://github.com/npm/cli/commit/b0c04908d413e71704cf8f5c6f469ab005c7385b) [#8118](https://github.com/npm/cli/pull/8118) `is-cidr@5.1.1` +* [`ef49d6b`](https://github.com/npm/cli/commit/ef49d6bcc8130f3e25f92b123bc46abe8a64e773) [#8118](https://github.com/npm/cli/pull/8118) `sigstore@3.1.0` +* [`1399bfb`](https://github.com/npm/cli/commit/1399bfb24ac04fcdc3d7464488dc4e8cd191b9da) [#8118](https://github.com/npm/cli/pull/8118) `socks@2.8.4` +* [`6b72107`](https://github.com/npm/cli/commit/6b72107063757bfd4b061dde01029a8a75c5e8b4) [#8118](https://github.com/npm/cli/pull/8118) `semver@7.7.1` +* [`c9ad0c4`](https://github.com/npm/cli/commit/c9ad0c4bbee2ee13a1521e10268edbbb3b794e8e) [#8118](https://github.com/npm/cli/pull/8118) `@npmcli/git@6.0.3` +* [`b153927`](https://github.com/npm/cli/commit/b153927feca3717598440b82a705281d652b4bf0) [#8115](https://github.com/npm/cli/pull/8115) `npm-package-arg@12.0.2` +* [`f0f6265`](https://github.com/npm/cli/commit/f0f626526b86bb54862bb4c0e3c24adfc0f1c8ce) [#8071](https://github.com/npm/cli/pull/8071) `nopt@8.1.0` +### Chores +* [`cc72b89`](https://github.com/npm/cli/commit/cc72b89cc07993a0fa3a7fb55ab91ac2798de7a2) [#8143](https://github.com/npm/cli/pull/8143) fix smoke tests to account for new release versions within a workspace (#8143) (@reggi) +* [`c3810bc`](https://github.com/npm/cli/commit/c3810bc8735336e6983fefb811f8e08279f7cddf) [#8134](https://github.com/npm/cli/pull/8134) dev dependency updates (@wraithgar) +* [`9dc40e6`](https://github.com/npm/cli/commit/9dc40e6c96c2c019c95fdc745bc1756da08bcc28) [#8118](https://github.com/npm/cli/pull/8118) dev dependency updates (@wraithgar) +* [`7ec0831`](https://github.com/npm/cli/commit/7ec0831b22eb65b69c0f0908139e582ff5b5af15) [#8118](https://github.com/npm/cli/pull/8118) update jsonpath-plus (@wraithgar) +* [`ed85b01`](https://github.com/npm/cli/commit/ed85b014bfb050ae4ae04827133d49b0f78c5df0) [#8071](https://github.com/npm/cli/pull/8071) tests for config warnings/changes (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.0.1): `@npmcli/arborist@9.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.1.0): `@npmcli/config@10.1.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.1): `libnpmdiff@8.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.1.0): `libnpmexec@10.1.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.1): `libnpmfund@7.0.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.1): `libnpmpack@9.0.1` + +## [11.1.0](https://github.com/npm/cli/compare/v11.0.0...v11.1.0) (2025-01-29) +### Features +* [`7f6c997`](https://github.com/npm/cli/commit/7f6c9973dc9a4dfebd76e52e060a9d8496b8bd98) [#8009](https://github.com/npm/cli/pull/8009) add dry-run to deprecate/undeprecate commands (@wraithgar) +* [`1764a37`](https://github.com/npm/cli/commit/1764a37f1913b6a0811a85d89e029fc1dc79da54) [#8009](https://github.com/npm/cli/pull/8009) add npm undeprecate command (@wraithgar) ### Bug Fixes - -* [`cfd59b8c8`](https://github.com/npm/cli/commit/cfd59b8c81078f842328b13a23a234150842cd58) - [#4223](https://github.com/npm/cli/pull/4223) - fix: npm update --save - ([@ruyadorno](https://github.com/ruyadorno)) -* [`510f0ecbc`](https://github.com/npm/cli/commit/510f0ecbc9970ed8c8993107cc03cf27b7b996dc) - [#4218](https://github.com/npm/cli/pull/4218) - fix(arborist): ensure indentation is preserved - ([@ljharb](https://github.com/ljharb)) -* [`c99c2151a`](https://github.com/npm/cli/commit/c99c2151a868672c017f64ff0ecb12149a2fb095) - [#4230](https://github.com/npm/cli/pull/4230) - fix(arborist): prioritize valid workspace nodes - ([@nlf](https://github.com/nlf)) -* [`14a3d9500`](https://github.com/npm/cli/commit/14a3d95000f1cba937f3309d198a363ae65cf01f) - [#4265](https://github.com/npm/cli/pull/4265) - fix: resolve workspace paths from cwd when possible - ([@nlf](https://github.com/nlf)) - +* [`31455b2`](https://github.com/npm/cli/commit/31455b2e177b721292f3382726e3f5f3f2963b1d) [#8054](https://github.com/npm/cli/pull/8054) publish: honor force for no dist tag and registry version check (#8054) (@reggi) +* [`dc31c1b`](https://github.com/npm/cli/commit/dc31c1bdc6658ab69554adcf2988ee99a615c409) [#8038](https://github.com/npm/cli/pull/8038) remove max-len linting bypasses (@wraithgar) +* [`8a911ff`](https://github.com/npm/cli/commit/8a911ff895967678aa786595db3418fc28e6966a) [#8038](https://github.com/npm/cli/pull/8038) publish: disregard deprecated versions when calculating highest version (@wraithgar) +* [`7f72944`](https://github.com/npm/cli/commit/7f72944e43f009cf4d55ff4fe24c459e07f588fd) [#8038](https://github.com/npm/cli/pull/8038) publish: accept publishConfig.tag to override highest semver check (@wraithgar) +* [`ab9ddc0`](https://github.com/npm/cli/commit/ab9ddc0413374fbf4879da535f82e03bc4e62cf3) [#7992](https://github.com/npm/cli/pull/7992) sbom: deduplicate sbom dependencies (#7992) (@bdehamer) +* [`f7da341`](https://github.com/npm/cli/commit/f7da341322c2f860156e8144b208583596504479) [#7980](https://github.com/npm/cli/pull/7980) search: properly display multiple search terms (#7980) (@wraithgar) +### Documentation +* [`3644e79`](https://github.com/npm/cli/commit/3644e79a73e511bc54d857bc2026b071fe18a6fe) [#8055](https://github.com/npm/cli/pull/8055) update readme for Node.js versions, remove badges (#8055) (@wraithgar) +* [`f1af61f`](https://github.com/npm/cli/commit/f1af61f917e58a0a45d2b15d1e5600988b2c824f) [#8041](https://github.com/npm/cli/pull/8041) fix typos in "package-json" (#8041) (@maxkoryukov) +* [`e90c6fe`](https://github.com/npm/cli/commit/e90c6feeacdf9ad010d4d73b65d7dd7d3b86efe2) [#8051](https://github.com/npm/cli/pull/8051) depth flag default value (#8051) (@milaninfy) +* [`866b5ee`](https://github.com/npm/cli/commit/866b5ee3ae5ed508ecbe832d01f5ebd6b00f6789) [#8030](https://github.com/npm/cli/pull/8030) safer documentation urls, repos, packages (#8030) (@reggi) ### Dependencies - -* [`2ef9f9847`](https://github.com/npm/cli/commit/2ef9f9847c11fe8c0c0494558fe77c15ac4dbc80) - [#4254](https://github.com/npm/cli/pull/4254) - deps: `bin-links@3.0.0 write-file-atomic@4.0.0` - -## v8.3.1 (2022-01-13) - -### Bug Fixes - -* [`2ac540b0c`](https://github.com/npm/cli/commit/2ac540b0ccd016a14676ad891758e8d9e903a12c) - fix(unpublish): Show warning on unpublish command when last version (#4191) - ([@ebsaral](https://github.com/ebsaral)) - +* [`7ddfbad`](https://github.com/npm/cli/commit/7ddfbadd1d51d07e68afbe1b91a36106d98c7bea) [#8053](https://github.com/npm/cli/pull/8053) `@npmcli/package-json@6.1.1` +* [`9473a86`](https://github.com/npm/cli/commit/9473a8638257297c420136009de567c131d2f299) [#8053](https://github.com/npm/cli/pull/8053) `spdx-license-ids@3.0.21` +* [`a65e5ce`](https://github.com/npm/cli/commit/a65e5ceb15c4aad6bde1ffdbee7da6f685caf81e) [#8053](https://github.com/npm/cli/pull/8053) `@sigstore/protobuf-specs@0.3.3` +* [`215ebe4`](https://github.com/npm/cli/commit/215ebe4d8f6c7f30d4b6a68fa11a3372c132929e) [#8053](https://github.com/npm/cli/pull/8053) `chalk@5.4.1` +### Chores +* [`61f00e3`](https://github.com/npm/cli/commit/61f00e3c23211d37c7980ebd6d1cf8d1dac49f18) [#8069](https://github.com/npm/cli/pull/8069) splits out smoke-tests from publish-dryrun tests (#8069) (@reggi) +* [`6d0f46e`](https://github.com/npm/cli/commit/6d0f46e67e9673e8a2dc6edb92144a73f853950c) [#8058](https://github.com/npm/cli/pull/8058) stop publish smoke from check git clean (#8058) (@reggi) +* [`9281ebf`](https://github.com/npm/cli/commit/9281ebf8e428d40450ad75ba61bc6f040b3bf896) [#8057](https://github.com/npm/cli/pull/8057) fix smoke tests prerelease needs separate string args (#8057) (@reggi) +* [`aa202e9`](https://github.com/npm/cli/commit/aa202e9dac2f927bedcaaed4db0eef7b3415fc68) [#8056](https://github.com/npm/cli/pull/8056) smoke tests using a preid (#8056) (@reggi) +* [`18e0449`](https://github.com/npm/cli/commit/18e0449ae41703a7980cee73bae69521db6fa53e) [#8053](https://github.com/npm/cli/pull/8053) dev dependency updates (@wraithgar) +* [`859a71c`](https://github.com/npm/cli/commit/859a71c59ea5f91f21a8410db46585a2fc0a8126) [#8052](https://github.com/npm/cli/pull/8052) update node versions for release integration tests (#8052) (@wraithgar) +* [`7e7961d`](https://github.com/npm/cli/commit/7e7961d8936e277f3dbc8e44f9e7b07daaeb36ca) [#8038](https://github.com/npm/cli/pull/8038) bump @npmcli/eslint-config to 5.1.0 (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.0.1): `@npmcli/config@10.0.1` + +## [11.0.0](https://github.com/npm/cli/compare/v11.0.0-pre.1...v11.0.0) (2024-12-16) +### Documentation +* [`8a911da`](https://github.com/npm/cli/commit/8a911da452b9785bcd051778570beeb2d8b27421) [#7963](https://github.com/npm/cli/pull/7963) ls: removed design change pending section note (#7963) (@milaninfy) ### Dependencies - -* [`da80d579d`](https://github.com/npm/cli/commit/da80d579d1f1db61894c54f7b9b3623394882c16) - [#4211](https://github.com/npm/cli/pull/4211) - deps: `hosted-git-info@4.1.0` - * feat: Support Sourcehut -* [`5a87d190f`](https://github.com/npm/cli/commit/5a87d190f38af9f2f98084d9b476184dbcaf1429) - [#4228](https://github.com/npm/cli/pull/4228) - deps: `@npmcli/config@2.4.0` -* [`1f0d1370f`](https://github.com/npm/cli/commit/1f0d1370ff6bf2ca978ef0d7d32640314c62204e) - chore(release): `@npmcli/arborist@4.2.0` - * [`3cfae3840`](https://github.com/npm/cli/commit/3cfae384011a8b291cc82cc02b56bc114557a9e5) - [#4181](https://github.com/npm/cli/pull/4181) - feat(arborist) add `toJSON`/`toString` methods to get shrinkwrap contents without saving - ([@ljharb](https://github.com/ljharb)) - +* [`5319e48`](https://github.com/npm/cli/commit/5319e48a5a91768dccdfe728392dc2040e7ce27e) [#7973](https://github.com/npm/cli/pull/7973) remove unnecessary sprintf-js files in node_modules (#7973) +* [`d369c77`](https://github.com/npm/cli/commit/d369c7716d753580da708723a2a4f8b3be767cb1) [#7976](https://github.com/npm/cli/pull/7976) `socks-proxy-agent@8.0.5` +* [`3b2951a`](https://github.com/npm/cli/commit/3b2951a3ba1521b9866d9b33960aa3307d4f31dd) [#7976](https://github.com/npm/cli/pull/7976) `https-proxy-agent@7.0.6` +* [`a598b7b`](https://github.com/npm/cli/commit/a598b7bd3de2b02bd14a3fa2f49c14a5ca50a43e) [#7976](https://github.com/npm/cli/pull/7976) `agent-base@7.1.3` +* [`52bcaf6`](https://github.com/npm/cli/commit/52bcaf6464f44b30137ee3d3fe79322c1b1646ef) [#7976](https://github.com/npm/cli/pull/7976) `debug@4.4.0` +* [`aabf345`](https://github.com/npm/cli/commit/aabf345a524f8aba7e0f45c0d4b8c86d5160d0cc) [#7976](https://github.com/npm/cli/pull/7976) `p-map@7.0.3` +* [`28e8761`](https://github.com/npm/cli/commit/28e876135411cd9a93dbdd74906869c54286d7bc) [#7976](https://github.com/npm/cli/pull/7976) `npm-package-arg@12.0.1` ### Chores - -* [`d72650457`](https://github.com/npm/cli/commit/d7265045730555c03b3142c004c7438e9577028c) - chore: Bring in all libnpm modules + arborist as workspaces (#4166) - ([@fritzy](https://github.com/fritzy)) - - -## v8.3.0 (2021-12-09) - +* [`ecd7190`](https://github.com/npm/cli/commit/ecd719026860d464557223b212acec4347477128) [#7976](https://github.com/npm/cli/pull/7976) dev dependency updates (@wraithgar) +* [`a07f4e0`](https://github.com/npm/cli/commit/a07f4e0d921f640be6aa87736debd550ec478f89) [#7976](https://github.com/npm/cli/pull/7976) `@npmcli/template-oss@4.23.6` (@wraithgar) +* [`687ab12`](https://github.com/npm/cli/commit/687ab12eb5ea0ee1017101f3a83d42fd76299627) [#7970](https://github.com/npm/cli/pull/7970) remove pre-release mode from npm 11 and workspaces (#7970) (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.0.0): `@npmcli/arborist@9.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.0.0): `@npmcli/config@10.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmaccess-v10.0.0): `libnpmaccess@10.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.0): `libnpmdiff@8.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.0.0): `libnpmexec@10.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.0): `libnpmfund@7.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmorg-v8.0.0): `libnpmorg@8.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.0): `libnpmpack@9.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.0.0): `libnpmpublish@11.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmsearch-v9.0.0): `libnpmsearch@9.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmteam-v8.0.0): `libnpmteam@8.0.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmversion-v8.0.0): `libnpmversion@8.0.0` + +## [11.0.0-pre.1](https://github.com/npm/cli/compare/v11.0.0-pre.0...v11.0.0-pre.1) (2024-12-06) +### ⚠️ BREAKING CHANGES +* Upon publishing, in order to apply a default "latest" dist tag, the command now retrieves all prior versions of the package. It will require that the version you're trying to publish is above the latest semver version in the registry, not including pre-release tags. +* `npm init` now has a `type` prompt, and sorts the entries in created packages differently +* `bun.lockb` files are now included in the strict ignore list during packing ### Features - -* [`4b0c29a7c`](https://github.com/npm/cli/commit/4b0c29a7c5860410c7b453bec389c54cb21dbde3) - [#4116](https://github.com/npm/cli/issues/4116) - feat: `@npmcli/arborist@4.1.0` - * introduces overrides - ([@nlf](https://github.com/nlf)) -* [`166d9e144`](https://github.com/npm/cli/commit/166d9e144b38087ee5e7d8aaf6ec7d602cf2957c) - [npm/statusboard#416](https://github.com/npm/statusboard/issues/416) - [#4143](https://github.com/npm/cli/issues/4143) - feat: output configured registry during publish - ([@lukekarrys](https://github.com/lukekarrys)) -* [`71777be17`](https://github.com/npm/cli/commit/71777be17e57179d203cb9162664ecd0c36ca633) - [npm/statusboard#417](https://github.com/npm/statusboard/issues/417) - [#4146](https://github.com/npm/cli/issues/4146) - feat: display `publishConfig` during `config list` - ([@lukekarrys](https://github.com/lukekarrys)) - +* [`f3ac7b7`](https://github.com/npm/cli/commit/f3ac7b7460e1d9e1f9d3d8056317e36bb9813d5d) [#7939](https://github.com/npm/cli/pull/7939) no implicit latest tag on publish when latest > version (#7939) (@reggi, @ljharb) ### Bug Fixes - -* [`08c663931`](https://github.com/npm/cli/commit/08c663931ec1f56d777ffdb38f94926b9eac13ef) - [#4128](https://github.com/npm/cli/issues/4128) - [#4134](https://github.com/npm/cli/issues/4134) - fix: dont warn on error cleaning individual log files - ([@lukekarrys](https://github.com/lukekarrys)) -* [`e605b128c`](https://github.com/npm/cli/commit/e605b128c87620aae843cdbd8f35cc614da3f8a2) - [#4142](https://github.com/npm/cli/issues/4142) - fix: redact all private keys from config output - ([@lukekarrys](https://github.com/lukekarrys)) - +* [`e362c6d`](https://github.com/npm/cli/commit/e362c6d3a6c8bc0221b8c8a6c3dd623da9e6ae04) [#7944](https://github.com/npm/cli/pull/7944) prefix: remove duplicate -g from usage output (#7944) (@wraithgar) ### Documentation - -* [`db1885d7f`](https://github.com/npm/cli/commit/db1885d7fec012f018093c76dec5a9c01a0ca2b0) - [#4092](https://github.com/npm/cli/issues/4092) - chore(docs): document overrides - ([@nlf](https://github.com/nlf)) - +* [`2af31dd`](https://github.com/npm/cli/commit/2af31dd30f4c226f43ce7295cd0b5fbb3f3cb2a6) [#7947](https://github.com/npm/cli/pull/7947) change certfile to cafile (#7947) (@wraithgar) +* [`1be8e95`](https://github.com/npm/cli/commit/1be8e9500826e7aef041976fd908658f473caf23) [#7945](https://github.com/npm/cli/pull/7945) update ignore rules (@wraithgar) ### Dependencies - -* [`e1da1fa4b`](https://github.com/npm/cli/commit/e1da1fa4ba7d95616928d2192b5b9db09b3120bc) - [#4141](https://github.com/npm/cli/issues/4141) - deps: `@npmcli/arborist@4.1.1`: `parse-conflict-json@2.0.1` - * Fixes object property assignment bug in resolving package-locks with - conflicts -* [`1d8bec566`](https://github.com/npm/cli/commit/1d8bec566cb08ff5ff220f53083323fa8c3fb72e) - [#4144](https://github.com/npm/cli/issues/4144) - [#3884](https://github.com/npm/cli/issues/3884) - deps: `minipass@3.1.6` - * fixes some TAR_ENTRY_INVALID and Z_DATA_ERROR errors - -## v8.2.0 (2021-12-02) - +* [`bc9b14d`](https://github.com/npm/cli/commit/bc9b14dc35378262c36ef5f59f96455b21a430cc) [#7955](https://github.com/npm/cli/pull/7955) `@npmcli/run-script@9.0.2` +* [`fecfcf4`](https://github.com/npm/cli/commit/fecfcf4987e30cc5ed04b0b77ccc9eb30c2b5c8f) [#7955](https://github.com/npm/cli/pull/7955) `node-gyp@11.0.0` +* [`8905037`](https://github.com/npm/cli/commit/890503767c733a1eacfdd562b01eb37ac253906c) [#7955](https://github.com/npm/cli/pull/7955) `p-map@7.0.2` +* [`ac8eb39`](https://github.com/npm/cli/commit/ac8eb390b0e0a21346fcdc5476ee0b884278b3a9) [#7955](https://github.com/npm/cli/pull/7955) `diff@7.0.0` +* [`c0bcc2a`](https://github.com/npm/cli/commit/c0bcc2a860fec5c86234dec44f5474364c25aefc) [#7955](https://github.com/npm/cli/pull/7955) `walk-up-path@4.0.0` +* [`d463a6f`](https://github.com/npm/cli/commit/d463a6f071da79b7a2151eeeea8a6f6cceea182f) [#7955](https://github.com/npm/cli/pull/7955) `init-package-json@8.0.0` +* [`b87ba24`](https://github.com/npm/cli/commit/b87ba2402ab86532d54b7b4e09b38582c0f11a5e) [#7945](https://github.com/npm/cli/pull/7945) `@npmcli/package-json@6.1.0` +* [`4bf1901`](https://github.com/npm/cli/commit/4bf1901f6dc57748d851ebe82262e9bef85a4ba7) [#7945](https://github.com/npm/cli/pull/7945) `@npmcli/metavuln-calculator@9.0.0` +* [`ca84b22`](https://github.com/npm/cli/commit/ca84b22a18806495c37ef6ee2aecd42a1c7bb7f6) [#7945](https://github.com/npm/cli/pull/7945) `pacote@21.0.0` +* [`4906f3d`](https://github.com/npm/cli/commit/4906f3ddf05c97f6e9832617a22c7ae228b46985) [#7945](https://github.com/npm/cli/pull/7945) `npm-packlist@10.0.0` +### Chores +* [`cfdf214`](https://github.com/npm/cli/commit/cfdf2147b5bfd80c7478486d07cb085de6fb8c4c) [#7943](https://github.com/npm/cli/pull/7943) fork changelog (#7943) (@wraithgar) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.0.0-pre.1): `@npmcli/arborist@9.0.0-pre.1` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.0.0-pre.1): `@npmcli/config@10.0.0-pre.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.0-pre.1): `libnpmdiff@8.0.0-pre.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.0.0-pre.1): `libnpmexec@10.0.0-pre.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.0-pre.1): `libnpmfund@7.0.0-pre.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmorg-v8.0.0-pre.1): `libnpmorg@8.0.0-pre.1` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.0-pre.1): `libnpmpack@9.0.0-pre.1` + +## [11.0.0-pre.0](https://github.com/npm/cli/compare/v10.9.0...v11.0.0-pre.0) (2024-11-26) +### ⚠️ BREAKING CHANGES +* When publishing a package with a pre-release version, you must explicitly specify a tag. +* `--ignore-scripts` now applies to all lifecycle scripts, include `prepare` +* npm will no longer fall back to the old audit endpoint if the bulk advisory request fails. +* npm will no longer switch to global mode if aliased to "npmg" or "npm-g" etc. +* The `npm hook` command has been removed +* Attestations made by this package will no longer validate in npm versions prior to 10.6.0 +* npm now supports node `^20.17.0 || >=22.9.0` +* @npmcli/docs now supports node `^20.17.0 || >=22.9.0` ### Features - -* [`6734ba36d`](https://github.com/npm/cli/commit/6734ba36dd6e07a859ab4d6eb4f264d2c0022276) - [#4062](https://github.com/npm/cli/issues/4062) - feat: streaming debug logfile - ([@lukekarrys](https://github.com/lukekarrys)) - +* [`6995303`](https://github.com/npm/cli/commit/6995303687ab59541b727bf611f73624d1829b6c) [#7850](https://github.com/npm/cli/pull/7850) adds `--ignore-scripts` flag to `pack` (@reggi) ### Bug Fixes - -* [`5f4040aa0`](https://github.com/npm/cli/commit/5f4040aa0e30a3b74caab64958770c682e4d0031) - chore: remove get-project-scope utils - ([@Yucel Okcu](https://github.com/Yucel Okcu)) -* [`c5c6d1603`](https://github.com/npm/cli/commit/c5c6d1603b06df4c10b503047aeed34d6e0c36c2) - [#4060](https://github.com/npm/cli/issues/4060) - fix: add missing scope on flat options - ([@yuqu](https://github.com/yuqu)) -* [`47828b766`](https://github.com/npm/cli/commit/47828b766a4a7b50c1245c8f01b99ffbeffd014f) - chore: update one-time password prompt - ([@Darcy Clarke](https://github.com/Darcy Clarke)) - +* [`16b7367`](https://github.com/npm/cli/commit/16b7367245a0ea7228a27a43555eefb3c6b16870) [#7910](https://github.com/npm/cli/pull/7910) publishing prerelease requires explicit tag (#7910) (@reggi) +* [`e19bff0`](https://github.com/npm/cli/commit/e19bff0ece79b189497720f076c0b324cb641061) [#7901](https://github.com/npm/cli/pull/7901) perf: enable compile cache if present (#7901) (@H4ad) +* [`080a0f2`](https://github.com/npm/cli/commit/080a0f2d3f09a81f0a5b2992431e0bc7feb8d701) [#7911](https://github.com/npm/cli/pull/7911) remove old audit fallback request (@wraithgar) +* [`780afc5`](https://github.com/npm/cli/commit/780afc50e3a345feb1871a28e33fa48235bc3bd5) [#7855](https://github.com/npm/cli/pull/7855) pkg: display if any of multiple attributes exist (#7855) (@Sanderovich) +* [`ecd2d23`](https://github.com/npm/cli/commit/ecd2d23d429b2fee833e534e679cce97e4190b1b) [#7842](https://github.com/npm/cli/pull/7842) don't go into global mode if aliased to npmg (#7842) (@wraithgar) +* [`62c71e5`](https://github.com/npm/cli/commit/62c71e5128a01283f97bd62da30ddc673bddda0b) [#7835](https://github.com/npm/cli/pull/7835) removes `npm hook` command (@reggi) +* [`7f541e8`](https://github.com/npm/cli/commit/7f541e82a0b2908cc0cfef9a36b714eeab40c029) [#7815](https://github.com/npm/cli/pull/7815) make pack and exec work with git hash refs (#7815) (@milaninfy) +* [`3162620`](https://github.com/npm/cli/commit/316262004747e04dfdcf2628abbc45cd366c86b8) [#7831](https://github.com/npm/cli/pull/7831) sets node engine range to `^20.17.0 || >=22.9.0` (@reggi) +* [`4c8ba0a`](https://github.com/npm/cli/commit/4c8ba0aa678b532146200e4cc082f151983b0d82) [#7831](https://github.com/npm/cli/pull/7831) for @npmcli/docs sets node engine range to `^20.17.0 || >=22.9.0` (@reggi) +* [`70cd88d`](https://github.com/npm/cli/commit/70cd88d95aa06ac96154c14ee262076704af807f) [#7808](https://github.com/npm/cli/pull/7808) view: sort and truncate dist-tags (#7808) (@wraithgar) +* [`534ad77`](https://github.com/npm/cli/commit/534ad7789e5c61f579f44d782bdd18ea3ff1ee20) [#7795](https://github.com/npm/cli/pull/7795) remove unused parameters catch statements (#7795) (@btea) ### Documentation - -* [`fc46a7926`](https://github.com/npm/cli/commit/fc46a792621c89354eddc0e1ee2d4f5c26efe5a5) - [#4072](https://github.com/npm/cli/issues/4072) - docs: fix typo in `save-peer` description - ([@chalkygames123](https://github.com/chalkygames123)) -* [`2fbf1576f`](https://github.com/npm/cli/commit/2fbf1576f5427babab2bdf314b1760adc5f9a575) - [#4081](https://github.com/npm/cli/issues/4081) - docs: Fix typo - ([@idleberg](https://github.com/idleberg)) -* [`a8bc95f11`](https://github.com/npm/cli/commit/a8bc95f11c9d21319581d7b09baf9f864bea21ac) - [#4089](https://github.com/npm/cli/issues/4089) - docs(workspaces): Fix typo - ([@yotamselementor](https://github.com/yotamselementor)) -* [`31b098ee2`](https://github.com/npm/cli/commit/31b098ee26ed17facb132278bb3205e80e2a760d) - [#4113](https://github.com/npm/cli/issues/4113) - docs: add logging docs - ([@darcyclarke](https://github.com/darcyclarke)) -* [`cbae0fb71`](https://github.com/npm/cli/commit/cbae0fb71cea55004f7066c0dfc870137b53ee8b) - [#4114](https://github.com/npm/cli/issues/4114) - docs: update description about where/when debug log is written - ([@lukekarrys](https://github.com/lukekarrys)) - - +* [`feb54f7`](https://github.com/npm/cli/commit/feb54f7e9a39bd52519221bae4fafc8bc70f235e) [#7822](https://github.com/npm/cli/pull/7822) package.json: add libc field (#7822) (@wraithgar) ### Dependencies - -* [`037f2cc8c`](https://github.com/npm/cli/commit/037f2cc8c8ed9d9a092475a5a07f2a3a88915633) - [#4078](https://github.com/npm/cli/issues/4078) - `node-gyp@8.4.1` -* [`0e63df612`](https://github.com/npm/cli/commit/0e63df61283a2f7ace991f72e4577c6f23ffc5df) - [#4102](https://github.com/npm/cli/issues/4102) - `@npmcli/config@2.3.2`: - * fix: always load localPrefix - -## v8.1.4 (2021-11-18) - -### BUG FIXES - -* [`7887fb3d7`](https://github.com/npm/cli/commit/7887fb3d7ba7f05abeb49dd92b76d90422cb38ca) - [#4025](https://github.com/npm/cli/issues/4025) - fix: don't try to open file:/// urls - ([@wraithgar](https://github.com/wraithgar)) -* [`cd6d3a90d`](https://github.com/npm/cli/commit/cd6d3a90d4bbf3793834830b4c77fc8eb0846596) - [#4026](https://github.com/npm/cli/issues/4026) - fix: explicitly allow `npm help` to open file:/// man pages - ([@wraithgar](https://github.com/wraithgar)) -* [`72ca4a4e3`](https://github.com/npm/cli/commit/72ca4a4e39a1d4de03d6423480aa2ee82b021060) - [#4020](https://github.com/npm/cli/issues/4020) - [#4032](https://github.com/npm/cli/issues/4032) - fix: command completion - ([@wraithgar](https://github.com/wraithgar)) -* [`b78949134`](https://github.com/npm/cli/commit/b789491345aa6fbe345aa3c96fe9f415296ec418) - [#4023](https://github.com/npm/cli/issues/4023) - fix(install): command completion with single match - ([@wraithgar](https://github.com/wraithgar)) -* [`44bfa3787`](https://github.com/npm/cli/commit/44bfa378723554195fccf8cf4ca2d895ddbd8f8c) - [#4065](https://github.com/npm/cli/issues/4065) - @npmcli/arborist 4.0.5 - * fix: accurate filtering of workspaces `--no-workspaces` - ([@fritzy](https://github.com/fritzy)) - -### DEPENDENCIES - -* [`225645420`](https://github.com/npm/cli/commit/225645420cf3d13bc0b0d591f7f7bf21a9c24e47) - [#3995](https://github.com/npm/cli/issues/3995) - update to latest eslint and linting rules - ([@wraithgar](https://github.com/wraithgar)) -* [`203fedf5b`](https://github.com/npm/cli/commit/203fedf5b1eba78b76ebacbda88f215caabea6ca) - [#4016](https://github.com/npm/cli/issues/4016) - `eslint@8.0.0`: `@npmcli/eslint-config@2.0.0` - * Update to eslint@8 and and `@npmcli/eslint-config@2.0.0` - * Remove eslint-plugin-node. - Also remove an unused script that was failing linting. We don't use the - update-dist-tags script anymore as part of our release process. - ([@wraithgar](https://github.com/wraithgar)) -* [`7b4aa59b6`](https://github.com/npm/cli/commit/7b4aa59b6630831f25d19c0c15a65acaf3a83327) - `signal-exit@3.0.6`:, `tap@15.1.2` - ([@isaacs](https://github.com/isaacs)) -* [`08015859c`](https://github.com/npm/cli/commit/08015859ca0abe47845d2970212cd344cdfc56e6) - [#4049](https://github.com/npm/cli/issues/4049) - `npmlog@6.0.0` -* [`088c11694`](https://github.com/npm/cli/commit/088c11694a9f575e5c0fe10ab9efb55d14019be7) - [#4045](https://github.com/npm/cli/issues/4045) - `node-gyp@8.4.0`: - * feat: support vs2022 - * feat: build with config.gypi from node headers - -## v8.1.3 (2021-11-04) - -### BUG FIXES - -* [`8ffeb71df`](https://github.com/npm/cli/commit/8ffeb71dfb248b4a76744bd06cd4d6100f17c8ae) - [#3959](https://github.com/npm/cli/issues/3959) - fix: refactor commands - ([@wraithgar](https://github.com/wraithgar)) -* [`e5bfdaca4`](https://github.com/npm/cli/commit/e5bfdaca455e294109ba026f4d8b5cc80d3dfd20) - [#3978](https://github.com/npm/cli/issues/3978) - fix: shrinkwrap setting incorrect lockfileVersion - ([@lukekarrys](https://github.com/lukekarrys)) -* [`32ccd3c27`](https://github.com/npm/cli/commit/32ccd3c2767a14198a1803f04e747ef848f7c938) - [#3988](https://github.com/npm/cli/issues/3988) - fix: remove usage of unnecessary util.promisify - ([@lukekarrys](https://github.com/lukekarrys)) -* [`1e9c31c4e`](https://github.com/npm/cli/commit/1e9c31c4e3929483580a0a554d7515095b5418ca) - [#3994](https://github.com/npm/cli/issues/3994) - fix: npm help on windows - ([@wraithgar](https://github.com/wraithgar)) -* [`22230ef3d`](https://github.com/npm/cli/commit/22230ef3dd590def31c274b3412106b4cfbd212f) - [#3987](https://github.com/npm/cli/issues/3987) - fix: make prefixed usage errors more consistent - ([@lukekarrys](https://github.com/lukekarrys)) - -### DEPENDENCIES - -* [`ac2fabb86`](https://github.com/npm/cli/commit/ac2fabb8604db0dac852913d61c8415ae7464485) - [#3990](https://github.com/npm/cli/issues/3990) - `@npmcli/arborist@4.0.4` - * fix: don't compare spec for local dep vs existing - * fix: stop pruning peerSets when entryEdge is from a workspace -* [`a0d35ff20`](https://github.com/npm/cli/commit/a0d35ff20aed6aab8508123eb540bc9c61fb127d) - [#3996](https://github.com/npm/cli/issues/3996) - `@npmcli/config@2.3.1`: - * fix: dont load project configs in global mode - -## v8.1.2 (2021-10-28) - -### BUG FIXES - -* [`cb9f43551`](https://github.com/npm/cli/commit/cb9f43551f46bf27095cd7bd6c1885a441004cd2) - [#3949](https://github.com/npm/cli/issues/3949) - allow `--lockfile-version` config to be string and coerce to number ([@lukekarrys](https://github.com/lukekarrys)) -* [`070901d7a`](https://github.com/npm/cli/commit/070901d7a6e3110a04ef41d8fcf14ffbfcce1496) - [#3943](https://github.com/npm/cli/issues/3943) - fix(publish): clean args before logging - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`8af94726b`](https://github.com/npm/cli/commit/8af94726b098031c7c0cae7ed50cc4e2e3499181) - [#3953](https://github.com/npm/cli/issues/3953) - `arborist@4.0.3` - * [`38cee94`](https://github.com/npm/arborist/commit/38cee94afa53d578830cc282348a803a8a6eefad) - [#340](https://github.com/npm/arborist/pull/340) - fix: set lockfileVersion from file during reset - * [`d310bd3`](https://github.com/npm/arborist/commit/d310bd3290c3a81e8285ceeb6eda9c9b5aa867d7) - [#339](https://github.com/npm/arborist/pull/339) - fix: always set originalLockfileVersion when doing shrinkwrap reset - -## v8.1.1 (2021-10-21) - -### DEPENDENCIES - -* [`51fb83ce9`](https://github.com/npm/cli/commit/51fb83ce93fdd7e289da7b2aabc95b0518f0aa31) - [#3921](https://github.com/npm/cli/issues/3921) - `@npmcli/arborist@4.0.2`: - * fix: skip peer conflict check if there is a current node -* [`1d07f2187`](https://github.com/npm/cli/commit/1d07f21876994c6d4d69559203cfdac6022536b6) - [#3913](https://github.com/npm/cli/issues/3913) - `node-gyp@8.3.0`: - * feat(gyp): update gyp to v0.10.0 - -## v8.1.0 (2021-10-14) - -### FEATURES - -* [`24273a862`](https://github.com/npm/cli/commit/24273a862e54abfd022df9fc4b8c250bfe77817c) - [#3890](https://github.com/npm/cli/issues/3890) - feat(workspaces): add --include-workspace-root and explicit --no-workspaces - ([@fritzy](https://github.com/fritzy)) -* [`d559d6da8`](https://github.com/npm/cli/commit/d559d6da84c2dae960c6b7c89c6012fb31bcfa37) - [#3880](https://github.com/npm/cli/issues/3880) - feat(config): Add --lockfile-version config option - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`ae4bf013d`](https://github.com/npm/cli/commit/ae4bf013d06d84b8600937a28cc7b4c4034f571c) - [#3883](https://github.com/npm/cli/issues/3883) - `pacote@12.0.2`: - * fix: preserve git+ssh url for non-hosted repos - * deps: update `npm-packlist@3.0.0` - * fix: no longer include ignored bundled link deps -* [`fbc5a3d08`](https://github.com/npm/cli/commit/fbc5a3d08231176b9d8a7b9dd3371fb40ba6abc9) - [#3889](https://github.com/npm/cli/issues/3889) - `@npmcli/ci-detect@1.4.0` -* [`b6bc279e5`](https://github.com/npm/cli/commit/b6bc279e55aa65afff09d9258f9df7168a7dbadb) - `@npmcli/arborist@4.0.1` -* [`0f69d295b`](https://github.com/npm/cli/commit/0f69d295bd5516f496af75ef29e7ae6304fa2ba5) - [#3893](https://github.com/npm/cli/issues/3893) - `@npmcli/map-workspaces@2.0.0` - -### DOCUMENTATION - -* [`f77932ca1`](https://github.com/npm/cli/commit/f77932ca1eafbece16fc249a7470f760d652bd94) - [#3861](https://github.com/npm/cli/issues/3861) - fix(docs): Update Node support in README - ([@gfyoung](https://github.com/gfyoung)) -* [`a190f422a`](https://github.com/npm/cli/commit/a190f422a2587a0e56afa5032175e57e55123ea2) - [#3878](https://github.com/npm/cli/issues/3878) - fix(docs): grammar fix - ([@XhmikosR](https://github.com/XhmikosR)) - -## v8.0.0 (2021-10-07) - -The purpose of this release is to drop support for old node versions and -to remove support for `require('npm')`. There are no other breaking -changes. - -### BREAKING CHANGES - -* Drop support for node 10 and 11 -* Raise support ceiling in node 12 and 14 to LTS (^12.13.0/^14.15.0) -* Drop support to `require('npm')` -* Update subdependencies that also dropped node10 support - -### DEPENDENCIES - -* The following dependencies were updated to drop node10 support and - update to the latest node-gyp - * libnpmversion@2.0.1 - * pacote@12.0.0 - * libnpmpack@3.0.0 - * @npmcli/arborist@3.0.0 - * libnpmfund@2.0.0 - * libnpmexec@3.0.0 - * node-gyp@8.2.0 -* [`8bd85cdae`](https://github.com/npm/cli/commit/8bd85cdae5eead60d5e92d6f1be27e88b480b1cb) - [#3813](https://github.com/npm/cli/issues/3813) - `cli-columns@4.0.0` +* [`78293ad`](https://github.com/npm/cli/commit/78293ad9b58b30b373dd69d15ea4e5735e720f55) [#7937](https://github.com/npm/cli/pull/7937) `spdx-license-ids@3.0.20` +* [`33cf580`](https://github.com/npm/cli/commit/33cf5801308b4b0b2a055e842a340135367f8a8d) [#7937](https://github.com/npm/cli/pull/7937) `promise-call-limit@3.0.2` +* [`ef1c368`](https://github.com/npm/cli/commit/ef1c3687b35295993258127ad7a5b0fd323fba8b) [#7937](https://github.com/npm/cli/pull/7937) `package-json-from-dist@1.0.1` +* [`92e6f07`](https://github.com/npm/cli/commit/92e6f076789b3bc39377308b84ee834b98855258) [#7937](https://github.com/npm/cli/pull/7937) `npm-registry-fetch@18.0.2` +* [`e32284a`](https://github.com/npm/cli/commit/e32284a8ebb679e41a2e8f0c8c63cc704296810c) [#7937](https://github.com/npm/cli/pull/7937) `npm-install-checks@7.1.1` +* [`5dffd11`](https://github.com/npm/cli/commit/5dffd112ba85864582b9af688ffc0b6d1a6a0166) [#7937](https://github.com/npm/cli/pull/7937) `negotiator@0.6.4` +* [`69d9f01`](https://github.com/npm/cli/commit/69d9f01ab11cb79bede2bde00423b9511d048c56) [#7937](https://github.com/npm/cli/pull/7937) `make-fetch-happen@14.0.3` +* [`884bbde`](https://github.com/npm/cli/commit/884bbde5a2865722fae0eb4de386f4d55ebdba93) [#7937](https://github.com/npm/cli/pull/7937) `hosted-git-info@8.0.2` +* [`3c74ec0`](https://github.com/npm/cli/commit/3c74ec00e1244178226b88331f703aded3c9d1e2) [#7937](https://github.com/npm/cli/pull/7937) `debug@4.3.7` +* [`f00359f`](https://github.com/npm/cli/commit/f00359f422d00ea6d209d624e2885e072b0a8f60) [#7937](https://github.com/npm/cli/pull/7937) `cross-spawn@7.0.6` +* [`534bbe8`](https://github.com/npm/cli/commit/534bbe8482f04f65c96c34fdd8734be91b29b18a) [#7937](https://github.com/npm/cli/pull/7937) `ci-info@4.1.0` +* [`8cbf1a7`](https://github.com/npm/cli/commit/8cbf1a75e12c586cdf77f03f7494ecb17b7030df) [#7937](https://github.com/npm/cli/pull/7937) `@npmcli/promise-spawn@8.0.2` +* [`1bd39e7`](https://github.com/npm/cli/commit/1bd39e7f766373021cc137fecc3cc3076967b444) [#7937](https://github.com/npm/cli/pull/7937) `@npmcli/map-workspaces@4.0.2` +* [`eb6498d`](https://github.com/npm/cli/commit/eb6498dc543fa117ba4d4bc87c7bc77423e2b72a) [#7937](https://github.com/npm/cli/pull/7937) `ansi-regex@6.1.0` +* [`66fc8c9`](https://github.com/npm/cli/commit/66fc8c997a37b0e28d35cb537fc68f6ed5466a73) [#7850](https://github.com/npm/cli/pull/7850) `@npmcli/metavuln-calculator@8.0.1` +* [`7dbef6f`](https://github.com/npm/cli/commit/7dbef6f3a3ead089b1b8b9fe6b2fa25e24309000) [#7850](https://github.com/npm/cli/pull/7850) `pacote@20.0.0` +* [`75a3f12`](https://github.com/npm/cli/commit/75a3f1228865f426d8790be27f1258e501f2c450) [#7859](https://github.com/npm/cli/pull/7859) remove unused deps (#7859) +* [`f36dc59`](https://github.com/npm/cli/commit/f36dc593ecbfe77439a1d0e31afb5a45de3b8d14) [#7833](https://github.com/npm/cli/pull/7833) `pacote@19.0.1` +* [`7ee15bb`](https://github.com/npm/cli/commit/7ee15bbdc1da0ed85297f47952b66089f29ed3fd) [#7833](https://github.com/npm/cli/pull/7833) bump sigstore from 2.x to 3.0.0 (@bdehamer) +### Chores +* [`2d530a5`](https://github.com/npm/cli/commit/2d530a5db705e72569d4beec02d86a2939b212f3) [#7941](https://github.com/npm/cli/pull/7941) tests: account for when npm is a prerelease (#7941) (@wraithgar) +* [`2c1b369`](https://github.com/npm/cli/commit/2c1b36951b1af9b798ece9392d778d4f9eff2268) [#7937](https://github.com/npm/cli/pull/7937) dev dependency updates (@wraithgar) +* [`6edfe2f`](https://github.com/npm/cli/commit/6edfe2f3a45169b6d194ccd8d366bb8d0e09b4a5) [#7937](https://github.com/npm/cli/pull/7937) `@npmcli/template-oss@4.23.5` (@wraithgar) +* [`475285b`](https://github.com/npm/cli/commit/475285b81e8db441ccadca1273b2bae9d83fc941) [#7920](https://github.com/npm/cli/pull/7920) clean up dependency graph repos (#7920) (@hashtagchris) +* [`ec57f5f`](https://github.com/npm/cli/commit/ec57f5f0831e6e82b87b9ed9ebdfa9fc3d5ba1ee) [#7911](https://github.com/npm/cli/pull/7911) fix dependencies script for circular workspace deps (@wraithgar) +* [`ccd8420`](https://github.com/npm/cli/commit/ccd84201e4e369992289842a5117cb3b531a7a36) [#7911](https://github.com/npm/cli/pull/7911) fix cli tests for audit fallback removal (@wraithgar) +* [`720b4d8`](https://github.com/npm/cli/commit/720b4d807bd2e214a045a9ffa9c56435823a7a05) [#7833](https://github.com/npm/cli/pull/7833) bump @npmcli/arborist to 8.0.0 (@wraithgar) +* [`286739c`](https://github.com/npm/cli/commit/286739c0224bad88c4a38927bafd61973f71098c) [#7824](https://github.com/npm/cli/pull/7824) add creation of a DEPENDENCIES.json file (#7824) (@reggi) +* [`852dd8b`](https://github.com/npm/cli/commit/852dd8bdcb958439d343bcd9fb27fb4f07e95991) [#7831](https://github.com/npm/cli/pull/7831) sets npm 11 to prerelease (@reggi) +* [`95d009e`](https://github.com/npm/cli/commit/95d009e606b187b9e148f4f1119b8a19e5beb7f0) [#7831](https://github.com/npm/cli/pull/7831) update engine `^20.17.0 || >=22.9.0` in actions (@reggi) +* [`5a74478`](https://github.com/npm/cli/commit/5a744782af53d6655669e49d911468934ea5e027) [#7831](https://github.com/npm/cli/pull/7831) update engines `^20.17.0 || >=22.9.0` in package template (@reggi) +* [workspace](https://github.com/npm/cli/releases/tag/arborist-v9.0.0-pre.0): `@npmcli/arborist@9.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/config-v10.0.0-pre.0): `@npmcli/config@10.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmaccess-v10.0.0-pre.0): `libnpmaccess@10.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmdiff-v8.0.0-pre.0): `libnpmdiff@8.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmexec-v10.0.0-pre.0): `libnpmexec@10.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmfund-v7.0.0-pre.0): `libnpmfund@7.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmorg-v8.0.0-pre.0): `libnpmorg@8.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpack-v9.0.0-pre.0): `libnpmpack@9.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmpublish-v11.0.0-pre.0): `libnpmpublish@11.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmsearch-v9.0.0-pre.0): `libnpmsearch@9.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmteam-v8.0.0-pre.0): `libnpmteam@8.0.0-pre.0` +* [workspace](https://github.com/npm/cli/releases/tag/libnpmversion-v8.0.0-pre.0): `libnpmversion@8.0.0-pre.0` diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000..167043c29d41d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,7 @@ +<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> + +All interactions in this repo are covered by the [npm Code of +Conduct](https://docs.npmjs.com/policies/conduct) + +The npm cli team may, at its own discretion, moderate, remove, or edit +any interactions such as pull requests, issues, and comments. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e12e300210841..a6cbabb062eb4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,13 +13,13 @@ When submitting a new bug report, please first [search](https://github.com/npm/c **1. Clone this repository...** ```bash -$ git clone git@github.com:npm/cli.git npm +git clone git@github.com:npm/cli.git npm ``` **2. Navigate into project & install development-specific dependencies...** ```bash -$ cd ./npm && node . install +cd ./npm && node ./scripts/resetdeps.js ``` **3. Write some code &/or add some tests...** @@ -30,7 +30,7 @@ $ cd ./npm && node . install **4. Run tests & ensure they pass...** ``` -$ node . run test +node . run test ``` **5. Open a [Pull Request](https://github.com/npm/cli/pulls) for your work & become the newest contributor to `npm`! 🎉** @@ -48,15 +48,30 @@ We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). We use [`tap`](https://node-tap.org/) for testing & expect that every new feature or bug fix comes with corresponding tests that validate the solutions. Tap also reports on code coverage and it will fail if that drops below 100%. -## Performance & Benchmarks +To run your repository's version of the npm cli on your local machine use the following commands: -We've set up an automated [benchmark](https://github.com/npm/benchmarks) integration that will run against all Pull Requests; Posting back a comment with the results of the run. - -**Example:** +**npm commands:** +```bash +node . <command> +``` -![image](https://user-images.githubusercontent.com/2818462/72312698-e2e57f80-3656-11ea-9fcf-4a8f6b97b0d1.png) +**npx commands:** +```bash +node . exec +``` -You can learn more about this tool, including how to run & configure it manually, [here](https://github.com/npm/benchmarks) +For example instead of: +```bash +npm exec -- <package> +``` +Use: +```bash +node . exec -- <package> +``` +To update the snapshots run: +```bash +TAP_SNAPSHOT=1 node . run test +``` ## What _not_ to contribute? diff --git a/DEPENDENCIES.json b/DEPENDENCIES.json new file mode 100644 index 0000000000000..feac637159e40 --- /dev/null +++ b/DEPENDENCIES.json @@ -0,0 +1,94 @@ +[ + [ + "npm" + ], + [ + "@npmcli/mock-registry", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmpack" + ], + [ + "@npmcli/arborist" + ], + [ + "@npmcli/metavuln-calculator" + ], + [ + "pacote", + "@npmcli/config", + "libnpmversion" + ], + [ + "@npmcli/map-workspaces", + "@npmcli/run-script", + "libnpmaccess", + "libnpmorg", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "init-package-json", + "npm-profile" + ], + [ + "@npmcli/package-json", + "npm-registry-fetch" + ], + [ + "@npmcli/git", + "make-fetch-happen" + ], + [ + "@npmcli/smoke-tests", + "@npmcli/installed-package-contents", + "npm-pick-manifest", + "cacache", + "promzard" + ], + [ + "@npmcli/docs", + "@npmcli/fs", + "npm-bundled", + "@npmcli/promise-spawn", + "npm-install-checks", + "npm-package-arg", + "unique-filename", + "npm-packlist", + "bin-links", + "nopt", + "parse-conflict-json", + "@npmcli/mock-globals", + "read" + ], + [ + "@npmcli/eslint-config", + "@npmcli/template-oss", + "ignore-walk", + "semver", + "npm-normalize-package-bin", + "@npmcli/name-from-folder", + "which", + "ini", + "hosted-git-info", + "proc-log", + "validate-npm-package-name", + "json-parse-even-better-errors", + "ssri", + "unique-slug", + "@npmcli/node-gyp", + "@npmcli/redact", + "@npmcli/agent", + "minipass-fetch", + "@npmcli/query", + "cmd-shim", + "read-cmd-shim", + "write-file-atomic", + "abbrev", + "proggy", + "minify-registry-metadata", + "mute-stream", + "npm-audit-report", + "npm-user-validate" + ] +] diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 92b0b85846804..843eedaf8486f 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -1,3 +1,5 @@ +<!-- This file is automatically added by `scripts/dependency-graph.js`. Do not edit. --> + # npm dependencies ## `github.com/npm/` only @@ -5,27 +7,25 @@ graph LR; bin-links-->cmd-shim; bin-links-->npm-normalize-package-bin; + bin-links-->proc-log; bin-links-->read-cmd-shim; bin-links-->write-file-atomic; - cacache-->fs-minipass; - cacache-->infer-owner; cacache-->npmcli-fs["@npmcli/fs"]; - cacache-->npmcli-move-file["@npmcli/move-file"]; cacache-->ssri; cacache-->unique-filename; - dezalgo-->wrappy; init-package-json-->npm-package-arg; + init-package-json-->npmcli-package-json["@npmcli/package-json"]; init-package-json-->promzard; - init-package-json-->read-package-json; init-package-json-->read; init-package-json-->semver; init-package-json-->validate-npm-package-name; libnpmaccess-->npm-package-arg; libnpmaccess-->npm-registry-fetch; libnpmaccess-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmaccess-->npmcli-mock-registry["@npmcli/mock-registry"]; libnpmaccess-->npmcli-template-oss["@npmcli/template-oss"]; libnpmdiff-->npm-package-arg; - libnpmdiff-->npmcli-disparity-colors["@npmcli/disparity-colors"]; + libnpmdiff-->npmcli-arborist["@npmcli/arborist"]; libnpmdiff-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmdiff-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; libnpmdiff-->npmcli-template-oss["@npmcli/template-oss"]; @@ -33,37 +33,35 @@ graph LR; libnpmexec-->bin-links; libnpmexec-->npm-package-arg; libnpmexec-->npmcli-arborist["@npmcli/arborist"]; - libnpmexec-->npmcli-ci-detect["@npmcli/ci-detect"]; libnpmexec-->npmcli-eslint-config["@npmcli/eslint-config"]; - libnpmexec-->npmcli-fs["@npmcli/fs"]; + libnpmexec-->npmcli-mock-registry["@npmcli/mock-registry"]; + libnpmexec-->npmcli-package-json["@npmcli/package-json"]; libnpmexec-->npmcli-run-script["@npmcli/run-script"]; libnpmexec-->npmcli-template-oss["@npmcli/template-oss"]; - libnpmexec-->npmlog; libnpmexec-->pacote; libnpmexec-->proc-log; - libnpmexec-->read-package-json-fast; libnpmexec-->read; libnpmexec-->semver; libnpmfund-->npmcli-arborist["@npmcli/arborist"]; libnpmfund-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmfund-->npmcli-template-oss["@npmcli/template-oss"]; - libnpmhook-->npm-registry-fetch; - libnpmhook-->npmcli-eslint-config["@npmcli/eslint-config"]; - libnpmhook-->npmcli-template-oss["@npmcli/template-oss"]; libnpmorg-->npm-registry-fetch; libnpmorg-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmorg-->npmcli-template-oss["@npmcli/template-oss"]; libnpmpack-->npm-package-arg; + libnpmpack-->npmcli-arborist["@npmcli/arborist"]; libnpmpack-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmpack-->npmcli-run-script["@npmcli/run-script"]; libnpmpack-->npmcli-template-oss["@npmcli/template-oss"]; libnpmpack-->pacote; - libnpmpublish-->libnpmpack; - libnpmpublish-->normalize-package-data; libnpmpublish-->npm-package-arg; libnpmpublish-->npm-registry-fetch; libnpmpublish-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmpublish-->npmcli-mock-globals["@npmcli/mock-globals"]; + libnpmpublish-->npmcli-mock-registry["@npmcli/mock-registry"]; + libnpmpublish-->npmcli-package-json["@npmcli/package-json"]; libnpmpublish-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpublish-->proc-log; libnpmpublish-->semver; libnpmpublish-->ssri; libnpmsearch-->npm-registry-fetch; @@ -72,6 +70,7 @@ graph LR; libnpmteam-->npm-registry-fetch; libnpmteam-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmteam-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmversion-->json-parse-even-better-errors; libnpmversion-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmversion-->npmcli-git["@npmcli/git"]; libnpmversion-->npmcli-run-script["@npmcli/run-script"]; @@ -80,20 +79,20 @@ graph LR; libnpmversion-->semver; make-fetch-happen-->cacache; make-fetch-happen-->minipass-fetch; + make-fetch-happen-->npmcli-agent["@npmcli/agent"]; + make-fetch-happen-->proc-log; make-fetch-happen-->ssri; nopt-->abbrev; - normalize-package-data-->hosted-git-info; - normalize-package-data-->semver; npm-->abbrev; npm-->cacache; npm-->hosted-git-info; npm-->ini; npm-->init-package-json; + npm-->json-parse-even-better-errors; npm-->libnpmaccess; npm-->libnpmdiff; npm-->libnpmexec; npm-->libnpmfund; - npm-->libnpmhook; npm-->libnpmorg; npm-->libnpmpack; npm-->libnpmpublish; @@ -105,31 +104,35 @@ graph LR; npm-->npm-audit-report; npm-->npm-install-checks; npm-->npm-package-arg; + npm-->npm-packlist; + npm-->npm-pick-manifest; npm-->npm-profile; npm-->npm-registry-fetch; npm-->npm-user-validate; npm-->npmcli-arborist["@npmcli/arborist"]; - npm-->npmcli-ci-detect["@npmcli/ci-detect"]; npm-->npmcli-config["@npmcli/config"]; + npm-->npmcli-docs["@npmcli/docs"]; npm-->npmcli-eslint-config["@npmcli/eslint-config"]; npm-->npmcli-fs["@npmcli/fs"]; + npm-->npmcli-git["@npmcli/git"]; npm-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npm-->npmcli-metavuln-calculator["@npmcli/metavuln-calculator"]; + npm-->npmcli-mock-globals["@npmcli/mock-globals"]; + npm-->npmcli-mock-registry["@npmcli/mock-registry"]; npm-->npmcli-package-json["@npmcli/package-json"]; + npm-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npm-->npmcli-redact["@npmcli/redact"]; npm-->npmcli-run-script["@npmcli/run-script"]; + npm-->npmcli-smoke-tests["@npmcli/smoke-tests"]; npm-->npmcli-template-oss["@npmcli/template-oss"]; - npm-->npmlog; npm-->pacote; npm-->parse-conflict-json; npm-->proc-log; - npm-->read-package-json-fast; - npm-->read-package-json; npm-->read; - npm-->readdir-scoped-modules; npm-->semver; npm-->ssri; - npm-->treeverse; npm-->validate-npm-package-name; - npm-->write-file-atomic; + npm-->which; npm-bundled-->npm-normalize-package-bin; npm-install-checks-->semver; npm-package-arg-->hosted-git-info; @@ -137,203 +140,173 @@ graph LR; npm-package-arg-->semver; npm-package-arg-->validate-npm-package-name; npm-packlist-->ignore-walk; - npm-packlist-->npm-bundled; - npm-packlist-->npm-normalize-package-bin; + npm-packlist-->proc-log; + npm-pick-manifest-->npm-install-checks; + npm-pick-manifest-->npm-normalize-package-bin; + npm-pick-manifest-->npm-package-arg; + npm-pick-manifest-->semver; npm-profile-->npm-registry-fetch; npm-profile-->proc-log; npm-registry-fetch-->make-fetch-happen; npm-registry-fetch-->minipass-fetch; npm-registry-fetch-->npm-package-arg; + npm-registry-fetch-->npmcli-redact["@npmcli/redact"]; npm-registry-fetch-->proc-log; npmcli-arborist-->bin-links; npmcli-arborist-->cacache; + npmcli-arborist-->hosted-git-info; + npmcli-arborist-->minify-registry-metadata; npmcli-arborist-->nopt; npmcli-arborist-->npm-install-checks; npmcli-arborist-->npm-package-arg; + npmcli-arborist-->npm-pick-manifest; npmcli-arborist-->npm-registry-fetch; npmcli-arborist-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-arborist-->npmcli-fs["@npmcli/fs"]; npmcli-arborist-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; npmcli-arborist-->npmcli-map-workspaces["@npmcli/map-workspaces"]; npmcli-arborist-->npmcli-metavuln-calculator["@npmcli/metavuln-calculator"]; - npmcli-arborist-->npmcli-move-file["@npmcli/move-file"]; + npmcli-arborist-->npmcli-mock-registry["@npmcli/mock-registry"]; npmcli-arborist-->npmcli-name-from-folder["@npmcli/name-from-folder"]; npmcli-arborist-->npmcli-node-gyp["@npmcli/node-gyp"]; npmcli-arborist-->npmcli-package-json["@npmcli/package-json"]; npmcli-arborist-->npmcli-query["@npmcli/query"]; + npmcli-arborist-->npmcli-redact["@npmcli/redact"]; npmcli-arborist-->npmcli-run-script["@npmcli/run-script"]; npmcli-arborist-->npmcli-template-oss["@npmcli/template-oss"]; - npmcli-arborist-->npmlog; npmcli-arborist-->pacote; npmcli-arborist-->parse-conflict-json; npmcli-arborist-->proc-log; - npmcli-arborist-->read-package-json-fast; - npmcli-arborist-->readdir-scoped-modules; + npmcli-arborist-->proggy; npmcli-arborist-->semver; npmcli-arborist-->ssri; - npmcli-arborist-->treeverse; npmcli-config-->ini; npmcli-config-->nopt; + npmcli-config-->npmcli-eslint-config["@npmcli/eslint-config"]; npmcli-config-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npmcli-config-->npmcli-mock-globals["@npmcli/mock-globals"]; + npmcli-config-->npmcli-package-json["@npmcli/package-json"]; + npmcli-config-->npmcli-template-oss["@npmcli/template-oss"]; npmcli-config-->proc-log; - npmcli-config-->read-package-json-fast; npmcli-config-->semver; + npmcli-docs-->ignore-walk; + npmcli-docs-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-docs-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-docs-->semver; npmcli-fs-->semver; + npmcli-git-->ini; + npmcli-git-->npm-pick-manifest; npmcli-git-->npmcli-promise-spawn["@npmcli/promise-spawn"]; npmcli-git-->proc-log; npmcli-git-->semver; + npmcli-git-->which; npmcli-installed-package-contents-->npm-bundled; npmcli-installed-package-contents-->npm-normalize-package-bin; npmcli-map-workspaces-->npmcli-name-from-folder["@npmcli/name-from-folder"]; - npmcli-map-workspaces-->read-package-json-fast; + npmcli-map-workspaces-->npmcli-package-json["@npmcli/package-json"]; npmcli-metavuln-calculator-->cacache; + npmcli-metavuln-calculator-->json-parse-even-better-errors; npmcli-metavuln-calculator-->pacote; + npmcli-metavuln-calculator-->proc-log; npmcli-metavuln-calculator-->semver; - npmcli-promise-spawn-->infer-owner; - npmcli-query-->npm-package-arg; - npmcli-query-->semver; + npmcli-mock-globals-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-mock-globals-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-mock-registry-->npm-package-arg; + npmcli-mock-registry-->npmcli-arborist["@npmcli/arborist"]; + npmcli-mock-registry-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-mock-registry-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-mock-registry-->pacote; + npmcli-package-json-->hosted-git-info; + npmcli-package-json-->json-parse-even-better-errors; + npmcli-package-json-->npmcli-git["@npmcli/git"]; + npmcli-package-json-->proc-log; + npmcli-package-json-->semver; + npmcli-promise-spawn-->which; npmcli-run-script-->npmcli-node-gyp["@npmcli/node-gyp"]; + npmcli-run-script-->npmcli-package-json["@npmcli/package-json"]; npmcli-run-script-->npmcli-promise-spawn["@npmcli/promise-spawn"]; - npmcli-run-script-->read-package-json-fast; - npmlog-->are-we-there-yet; - npmlog-->gauge; + npmcli-run-script-->proc-log; + npmcli-run-script-->which; + npmcli-smoke-tests-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-smoke-tests-->npmcli-mock-registry["@npmcli/mock-registry"]; + npmcli-smoke-tests-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-smoke-tests-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-smoke-tests-->which; pacote-->cacache; - pacote-->fs-minipass; - pacote-->infer-owner; pacote-->npm-package-arg; pacote-->npm-packlist; + pacote-->npm-pick-manifest; pacote-->npm-registry-fetch; pacote-->npmcli-git["@npmcli/git"]; pacote-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + pacote-->npmcli-package-json["@npmcli/package-json"]; pacote-->npmcli-promise-spawn["@npmcli/promise-spawn"]; pacote-->npmcli-run-script["@npmcli/run-script"]; pacote-->proc-log; - pacote-->read-package-json-fast; - pacote-->read-package-json; pacote-->ssri; + parse-conflict-json-->json-parse-even-better-errors; promzard-->read; read-->mute-stream; - read-package-json-->normalize-package-data; - read-package-json-->npm-normalize-package-bin; - read-package-json-fast-->npm-normalize-package-bin; - readdir-scoped-modules-->dezalgo; unique-filename-->unique-slug; ``` ## all dependencies ```mermaid graph LR; - agent-base-->debug; - agentkeepalive-->debug; - agentkeepalive-->depd; - agentkeepalive-->humanize-ms; - aggregate-error-->clean-stack; - aggregate-error-->indent-string; - ansi-styles-->color-convert; - are-we-there-yet-->delegates; - are-we-there-yet-->readable-stream; bin-links-->cmd-shim; - bin-links-->mkdirp-infer-owner; bin-links-->npm-normalize-package-bin; + bin-links-->proc-log; bin-links-->read-cmd-shim; - bin-links-->rimraf; bin-links-->write-file-atomic; - brace-expansion-->balanced-match; - brace-expansion-->concat-map; - builtins-->semver; - cacache-->chownr; cacache-->fs-minipass; cacache-->glob; - cacache-->infer-owner; cacache-->lru-cache; cacache-->minipass-collect; cacache-->minipass-flush; cacache-->minipass-pipeline; cacache-->minipass; - cacache-->mkdirp; cacache-->npmcli-fs["@npmcli/fs"]; - cacache-->npmcli-move-file["@npmcli/move-file"]; cacache-->p-map; - cacache-->promise-inflight; - cacache-->rimraf; cacache-->ssri; - cacache-->tar; cacache-->unique-filename; - chalk-->ansi-styles; - chalk-->supports-color; cidr-regex-->ip-regex; cli-columns-->string-width; cli-columns-->strip-ansi; - cli-table3-->colors-colors["@colors/colors"]; - cli-table3-->string-width; - cmd-shim-->mkdirp-infer-owner; - color-convert-->color-name; - columnify-->strip-ansi; - columnify-->wcwidth; debug-->ms; - defaults-->clone; - dezalgo-->asap; - dezalgo-->wrappy; - docs-->cmark-gfm; - docs-->jsdom; - docs-->marked-man; - docs-->mdx-js-mdx["@mdx-js/mdx"]; - docs-->npmcli-eslint-config["@npmcli/eslint-config"]; - docs-->npmcli-fs["@npmcli/fs"]; - docs-->npmcli-promise-spawn["@npmcli/promise-spawn"]; - docs-->npmcli-template-oss["@npmcli/template-oss"]; - docs-->tap; - docs-->which; - docs-->yaml; encoding-->iconv-lite; + fdir-->picomatch; fs-minipass-->minipass; - gauge-->aproba; - gauge-->color-support; - gauge-->console-control-strings; - gauge-->has-unicode; - gauge-->signal-exit; - gauge-->string-width; - gauge-->strip-ansi; - gauge-->wide-align; - glob-->fs.realpath; - glob-->inflight; - glob-->inherits; glob-->minimatch; - glob-->once; - glob-->path-is-absolute; - has-->function-bind; + glob-->minipass; + glob-->path-scurry; hosted-git-info-->lru-cache; http-proxy-agent-->agent-base; http-proxy-agent-->debug; - http-proxy-agent-->tootallnate-once["@tootallnate/once"]; https-proxy-agent-->agent-base; https-proxy-agent-->debug; - humanize-ms-->ms; iconv-lite-->safer-buffer; ignore-walk-->minimatch; - inflight-->once; - inflight-->wrappy; init-package-json-->npm-package-arg; + init-package-json-->npmcli-package-json["@npmcli/package-json"]; init-package-json-->promzard; - init-package-json-->read-package-json; init-package-json-->read; init-package-json-->semver; init-package-json-->validate-npm-package-license; init-package-json-->validate-npm-package-name; is-cidr-->cidr-regex; - is-core-module-->has; - libnpmaccess-->aproba; - libnpmaccess-->minipass; - libnpmaccess-->nock; + isaacs-brace-expansion-->isaacs-balanced-match["@isaacs/balanced-match"]; + isaacs-fs-minipass-->minipass; libnpmaccess-->npm-package-arg; libnpmaccess-->npm-registry-fetch; libnpmaccess-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmaccess-->npmcli-mock-registry["@npmcli/mock-registry"]; libnpmaccess-->npmcli-template-oss["@npmcli/template-oss"]; libnpmaccess-->tap; libnpmdiff-->binary-extensions; libnpmdiff-->diff; libnpmdiff-->minimatch; libnpmdiff-->npm-package-arg; - libnpmdiff-->npmcli-disparity-colors["@npmcli/disparity-colors"]; + libnpmdiff-->npmcli-arborist["@npmcli/arborist"]; libnpmdiff-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmdiff-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; libnpmdiff-->npmcli-template-oss["@npmcli/template-oss"]; @@ -342,32 +315,28 @@ graph LR; libnpmdiff-->tar; libnpmexec-->bin-links; libnpmexec-->chalk; - libnpmexec-->mkdirp-infer-owner; + libnpmexec-->ci-info; + libnpmexec-->just-extend; + libnpmexec-->just-safe-set; libnpmexec-->npm-package-arg; libnpmexec-->npmcli-arborist["@npmcli/arborist"]; - libnpmexec-->npmcli-ci-detect["@npmcli/ci-detect"]; libnpmexec-->npmcli-eslint-config["@npmcli/eslint-config"]; - libnpmexec-->npmcli-fs["@npmcli/fs"]; + libnpmexec-->npmcli-mock-registry["@npmcli/mock-registry"]; + libnpmexec-->npmcli-package-json["@npmcli/package-json"]; libnpmexec-->npmcli-run-script["@npmcli/run-script"]; libnpmexec-->npmcli-template-oss["@npmcli/template-oss"]; - libnpmexec-->npmlog; libnpmexec-->pacote; libnpmexec-->proc-log; - libnpmexec-->read-package-json-fast; + libnpmexec-->promise-retry; libnpmexec-->read; libnpmexec-->semver; + libnpmexec-->signal-exit; libnpmexec-->tap; libnpmexec-->walk-up-path; libnpmfund-->npmcli-arborist["@npmcli/arborist"]; libnpmfund-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmfund-->npmcli-template-oss["@npmcli/template-oss"]; libnpmfund-->tap; - libnpmhook-->aproba; - libnpmhook-->nock; - libnpmhook-->npm-registry-fetch; - libnpmhook-->npmcli-eslint-config["@npmcli/eslint-config"]; - libnpmhook-->npmcli-template-oss["@npmcli/template-oss"]; - libnpmhook-->tap; libnpmorg-->aproba; libnpmorg-->minipass; libnpmorg-->nock; @@ -377,20 +346,24 @@ graph LR; libnpmorg-->tap; libnpmpack-->nock; libnpmpack-->npm-package-arg; + libnpmpack-->npmcli-arborist["@npmcli/arborist"]; libnpmpack-->npmcli-eslint-config["@npmcli/eslint-config"]; libnpmpack-->npmcli-run-script["@npmcli/run-script"]; libnpmpack-->npmcli-template-oss["@npmcli/template-oss"]; libnpmpack-->pacote; + libnpmpack-->spawk; libnpmpack-->tap; - libnpmpublish-->libnpmpack; - libnpmpublish-->lodash.clonedeep; - libnpmpublish-->nock; - libnpmpublish-->normalize-package-data; + libnpmpublish-->ci-info; libnpmpublish-->npm-package-arg; libnpmpublish-->npm-registry-fetch; libnpmpublish-->npmcli-eslint-config["@npmcli/eslint-config"]; + libnpmpublish-->npmcli-mock-globals["@npmcli/mock-globals"]; + libnpmpublish-->npmcli-mock-registry["@npmcli/mock-registry"]; + libnpmpublish-->npmcli-package-json["@npmcli/package-json"]; libnpmpublish-->npmcli-template-oss["@npmcli/template-oss"]; + libnpmpublish-->proc-log; libnpmpublish-->semver; + libnpmpublish-->sigstore; libnpmpublish-->ssri; libnpmpublish-->tap; libnpmsearch-->nock; @@ -413,24 +386,18 @@ graph LR; libnpmversion-->require-inject; libnpmversion-->semver; libnpmversion-->tap; - lru-cache-->yallist; - make-fetch-happen-->agentkeepalive; make-fetch-happen-->cacache; make-fetch-happen-->http-cache-semantics; - make-fetch-happen-->http-proxy-agent; - make-fetch-happen-->https-proxy-agent; - make-fetch-happen-->is-lambda; - make-fetch-happen-->lru-cache; - make-fetch-happen-->minipass-collect; make-fetch-happen-->minipass-fetch; make-fetch-happen-->minipass-flush; make-fetch-happen-->minipass-pipeline; make-fetch-happen-->minipass; make-fetch-happen-->negotiator; + make-fetch-happen-->npmcli-agent["@npmcli/agent"]; + make-fetch-happen-->proc-log; make-fetch-happen-->promise-retry; - make-fetch-happen-->socks-proxy-agent; make-fetch-happen-->ssri; - minimatch-->brace-expansion; + minimatch-->isaacs-brace-expansion["@isaacs/brace-expansion"]; minipass-->yallist; minipass-collect-->minipass; minipass-fetch-->encoding; @@ -438,40 +405,33 @@ graph LR; minipass-fetch-->minipass; minipass-fetch-->minizlib; minipass-flush-->minipass; - minipass-json-stream-->jsonparse; - minipass-json-stream-->minipass; minipass-pipeline-->minipass; minipass-sized-->minipass; minizlib-->minipass; - minizlib-->yallist; - mkdirp-infer-owner-->chownr; - mkdirp-infer-owner-->infer-owner; - mkdirp-infer-owner-->mkdirp; node-gyp-->env-paths; - node-gyp-->glob; + node-gyp-->exponential-backoff; node-gyp-->graceful-fs; node-gyp-->make-fetch-happen; node-gyp-->nopt; - node-gyp-->npmlog; - node-gyp-->rimraf; + node-gyp-->proc-log; node-gyp-->semver; node-gyp-->tar; + node-gyp-->tinyglobby; node-gyp-->which; nopt-->abbrev; - normalize-package-data-->hosted-git-info; - normalize-package-data-->is-core-module; - normalize-package-data-->semver; - normalize-package-data-->validate-npm-package-license; npm-->abbrev; + npm-->ajv-formats-draft2019; + npm-->ajv-formats; + npm-->ajv; npm-->archy; npm-->cacache; npm-->chalk; - npm-->chownr; + npm-->ci-info; npm-->cli-columns; npm-->cli-table3; - npm-->columnify; - npm-->docs; + npm-->diff; npm-->fastest-levenshtein; + npm-->fs-minipass; npm-->glob; npm-->graceful-fs; npm-->hosted-git-info; @@ -484,19 +444,16 @@ graph LR; npm-->libnpmdiff; npm-->libnpmexec; npm-->libnpmfund; - npm-->libnpmhook; npm-->libnpmorg; npm-->libnpmpack; npm-->libnpmpublish; npm-->libnpmsearch; npm-->libnpmteam; npm-->libnpmversion; - npm-->licensee; npm-->make-fetch-happen; + npm-->minimatch; npm-->minipass-pipeline; npm-->minipass; - npm-->mkdirp-infer-owner; - npm-->mkdirp; npm-->ms; npm-->nock; npm-->node-gyp; @@ -504,79 +461,88 @@ graph LR; npm-->npm-audit-report; npm-->npm-install-checks; npm-->npm-package-arg; + npm-->npm-packlist; npm-->npm-pick-manifest; npm-->npm-profile; npm-->npm-registry-fetch; npm-->npm-user-validate; npm-->npmcli-arborist["@npmcli/arborist"]; - npm-->npmcli-ci-detect["@npmcli/ci-detect"]; npm-->npmcli-config["@npmcli/config"]; + npm-->npmcli-docs["@npmcli/docs"]; npm-->npmcli-eslint-config["@npmcli/eslint-config"]; npm-->npmcli-fs["@npmcli/fs"]; + npm-->npmcli-git["@npmcli/git"]; npm-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npm-->npmcli-metavuln-calculator["@npmcli/metavuln-calculator"]; + npm-->npmcli-mock-globals["@npmcli/mock-globals"]; + npm-->npmcli-mock-registry["@npmcli/mock-registry"]; npm-->npmcli-package-json["@npmcli/package-json"]; + npm-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npm-->npmcli-redact["@npmcli/redact"]; npm-->npmcli-run-script["@npmcli/run-script"]; + npm-->npmcli-smoke-tests["@npmcli/smoke-tests"]; npm-->npmcli-template-oss["@npmcli/template-oss"]; - npm-->npmlog; - npm-->opener; npm-->p-map; npm-->pacote; npm-->parse-conflict-json; npm-->proc-log; npm-->qrcode-terminal; - npm-->read-package-json-fast; - npm-->read-package-json; npm-->read; - npm-->readdir-scoped-modules; + npm-->remark-gfm; + npm-->remark-github; + npm-->remark; npm-->rimraf; npm-->semver; - npm-->smoke-tests; + npm-->sigstore-tuf["@sigstore/tuf"]; npm-->spawk; + npm-->spdx-expression-parse; npm-->ssri; + npm-->supports-color; npm-->tap; npm-->tar; npm-->text-table; npm-->tiny-relative-date; npm-->treeverse; + npm-->tufjs-repo-mock["@tufjs/repo-mock"]; npm-->validate-npm-package-name; npm-->which; - npm-->write-file-atomic; - npm-audit-report-->chalk; npm-bundled-->npm-normalize-package-bin; npm-install-checks-->semver; npm-package-arg-->hosted-git-info; npm-package-arg-->proc-log; npm-package-arg-->semver; npm-package-arg-->validate-npm-package-name; - npm-packlist-->glob; npm-packlist-->ignore-walk; - npm-packlist-->npm-bundled; - npm-packlist-->npm-normalize-package-bin; + npm-packlist-->proc-log; npm-pick-manifest-->npm-install-checks; npm-pick-manifest-->npm-normalize-package-bin; npm-pick-manifest-->npm-package-arg; npm-pick-manifest-->semver; npm-profile-->npm-registry-fetch; npm-profile-->proc-log; + npm-registry-fetch-->jsonparse; npm-registry-fetch-->make-fetch-happen; npm-registry-fetch-->minipass-fetch; - npm-registry-fetch-->minipass-json-stream; npm-registry-fetch-->minipass; npm-registry-fetch-->minizlib; npm-registry-fetch-->npm-package-arg; + npm-registry-fetch-->npmcli-redact["@npmcli/redact"]; npm-registry-fetch-->proc-log; + npmcli-agent-->agent-base; + npmcli-agent-->http-proxy-agent; + npmcli-agent-->https-proxy-agent; + npmcli-agent-->lru-cache; + npmcli-agent-->socks-proxy-agent; npmcli-arborist-->benchmark; npmcli-arborist-->bin-links; npmcli-arborist-->cacache; - npmcli-arborist-->chalk; npmcli-arborist-->common-ancestor-path; + npmcli-arborist-->hosted-git-info; npmcli-arborist-->isaacs-string-locale-compare["@isaacs/string-locale-compare"]; - npmcli-arborist-->json-parse-even-better-errors; npmcli-arborist-->json-stringify-nice; + npmcli-arborist-->lru-cache; npmcli-arborist-->minify-registry-metadata; npmcli-arborist-->minimatch; - npmcli-arborist-->mkdirp-infer-owner; - npmcli-arborist-->mkdirp; npmcli-arborist-->nock; npmcli-arborist-->nopt; npmcli-arborist-->npm-install-checks; @@ -584,48 +550,64 @@ graph LR; npmcli-arborist-->npm-pick-manifest; npmcli-arborist-->npm-registry-fetch; npmcli-arborist-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-arborist-->npmcli-fs["@npmcli/fs"]; npmcli-arborist-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; npmcli-arborist-->npmcli-map-workspaces["@npmcli/map-workspaces"]; npmcli-arborist-->npmcli-metavuln-calculator["@npmcli/metavuln-calculator"]; - npmcli-arborist-->npmcli-move-file["@npmcli/move-file"]; + npmcli-arborist-->npmcli-mock-registry["@npmcli/mock-registry"]; npmcli-arborist-->npmcli-name-from-folder["@npmcli/name-from-folder"]; npmcli-arborist-->npmcli-node-gyp["@npmcli/node-gyp"]; npmcli-arborist-->npmcli-package-json["@npmcli/package-json"]; npmcli-arborist-->npmcli-query["@npmcli/query"]; + npmcli-arborist-->npmcli-redact["@npmcli/redact"]; npmcli-arborist-->npmcli-run-script["@npmcli/run-script"]; npmcli-arborist-->npmcli-template-oss["@npmcli/template-oss"]; - npmcli-arborist-->npmlog; npmcli-arborist-->pacote; npmcli-arborist-->parse-conflict-json; npmcli-arborist-->proc-log; + npmcli-arborist-->proggy; npmcli-arborist-->promise-all-reject-late; npmcli-arborist-->promise-call-limit; - npmcli-arborist-->read-package-json-fast; - npmcli-arborist-->readdir-scoped-modules; - npmcli-arborist-->rimraf; npmcli-arborist-->semver; npmcli-arborist-->ssri; npmcli-arborist-->tap; + npmcli-arborist-->tar-stream; npmcli-arborist-->tcompare; npmcli-arborist-->treeverse; npmcli-arborist-->walk-up-path; + npmcli-config-->ci-info; npmcli-config-->ini; - npmcli-config-->mkdirp-infer-owner; npmcli-config-->nopt; + npmcli-config-->npmcli-eslint-config["@npmcli/eslint-config"]; npmcli-config-->npmcli-map-workspaces["@npmcli/map-workspaces"]; + npmcli-config-->npmcli-mock-globals["@npmcli/mock-globals"]; + npmcli-config-->npmcli-package-json["@npmcli/package-json"]; + npmcli-config-->npmcli-template-oss["@npmcli/template-oss"]; npmcli-config-->proc-log; - npmcli-config-->read-package-json-fast; npmcli-config-->semver; + npmcli-config-->tap; npmcli-config-->walk-up-path; - npmcli-disparity-colors-->ansi-styles; - npmcli-fs-->gar-promisify["@gar/promisify"]; + npmcli-docs-->front-matter; + npmcli-docs-->ignore-walk; + npmcli-docs-->isaacs-string-locale-compare["@isaacs/string-locale-compare"]; + npmcli-docs-->jsdom; + npmcli-docs-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-docs-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-docs-->rehype-stringify; + npmcli-docs-->remark-gfm; + npmcli-docs-->remark-man; + npmcli-docs-->remark-parse; + npmcli-docs-->remark-rehype; + npmcli-docs-->semver; + npmcli-docs-->tap; + npmcli-docs-->unified; + npmcli-docs-->yaml; npmcli-fs-->semver; + npmcli-git-->ini; npmcli-git-->lru-cache; - npmcli-git-->mkdirp; npmcli-git-->npm-pick-manifest; npmcli-git-->npmcli-promise-spawn["@npmcli/promise-spawn"]; npmcli-git-->proc-log; - npmcli-git-->promise-inflight; npmcli-git-->promise-retry; npmcli-git-->semver; npmcli-git-->which; @@ -634,82 +616,93 @@ graph LR; npmcli-map-workspaces-->glob; npmcli-map-workspaces-->minimatch; npmcli-map-workspaces-->npmcli-name-from-folder["@npmcli/name-from-folder"]; - npmcli-map-workspaces-->read-package-json-fast; + npmcli-map-workspaces-->npmcli-package-json["@npmcli/package-json"]; npmcli-metavuln-calculator-->cacache; npmcli-metavuln-calculator-->json-parse-even-better-errors; npmcli-metavuln-calculator-->pacote; + npmcli-metavuln-calculator-->proc-log; npmcli-metavuln-calculator-->semver; - npmcli-move-file-->mkdirp; - npmcli-move-file-->rimraf; + npmcli-mock-globals-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-mock-globals-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-mock-globals-->tap; + npmcli-mock-registry-->json-stringify-safe; + npmcli-mock-registry-->nock; + npmcli-mock-registry-->npm-package-arg; + npmcli-mock-registry-->npmcli-arborist["@npmcli/arborist"]; + npmcli-mock-registry-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-mock-registry-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-mock-registry-->pacote; + npmcli-mock-registry-->tap; + npmcli-package-json-->glob; + npmcli-package-json-->hosted-git-info; npmcli-package-json-->json-parse-even-better-errors; - npmcli-promise-spawn-->infer-owner; - npmcli-query-->npm-package-arg; + npmcli-package-json-->npmcli-git["@npmcli/git"]; + npmcli-package-json-->proc-log; + npmcli-package-json-->semver; + npmcli-package-json-->validate-npm-package-license; + npmcli-promise-spawn-->which; npmcli-query-->postcss-selector-parser; - npmcli-query-->semver; npmcli-run-script-->node-gyp; npmcli-run-script-->npmcli-node-gyp["@npmcli/node-gyp"]; + npmcli-run-script-->npmcli-package-json["@npmcli/package-json"]; npmcli-run-script-->npmcli-promise-spawn["@npmcli/promise-spawn"]; - npmcli-run-script-->read-package-json-fast; + npmcli-run-script-->proc-log; npmcli-run-script-->which; - npmlog-->are-we-there-yet; - npmlog-->console-control-strings; - npmlog-->gauge; - npmlog-->set-blocking; - once-->wrappy; - p-map-->aggregate-error; + npmcli-smoke-tests-->npmcli-eslint-config["@npmcli/eslint-config"]; + npmcli-smoke-tests-->npmcli-mock-registry["@npmcli/mock-registry"]; + npmcli-smoke-tests-->npmcli-promise-spawn["@npmcli/promise-spawn"]; + npmcli-smoke-tests-->npmcli-template-oss["@npmcli/template-oss"]; + npmcli-smoke-tests-->proxy; + npmcli-smoke-tests-->rimraf; + npmcli-smoke-tests-->tap; + npmcli-smoke-tests-->which; pacote-->cacache; - pacote-->chownr; pacote-->fs-minipass; - pacote-->infer-owner; pacote-->minipass; - pacote-->mkdirp; pacote-->npm-package-arg; pacote-->npm-packlist; pacote-->npm-pick-manifest; pacote-->npm-registry-fetch; pacote-->npmcli-git["@npmcli/git"]; pacote-->npmcli-installed-package-contents["@npmcli/installed-package-contents"]; + pacote-->npmcli-package-json["@npmcli/package-json"]; pacote-->npmcli-promise-spawn["@npmcli/promise-spawn"]; pacote-->npmcli-run-script["@npmcli/run-script"]; pacote-->proc-log; pacote-->promise-retry; - pacote-->read-package-json-fast; - pacote-->read-package-json; - pacote-->rimraf; + pacote-->sigstore; pacote-->ssri; pacote-->tar; parse-conflict-json-->json-parse-even-better-errors; parse-conflict-json-->just-diff-apply; parse-conflict-json-->just-diff; + path-scurry-->lru-cache; + path-scurry-->minipass; postcss-selector-parser-->cssesc; postcss-selector-parser-->util-deprecate; promise-retry-->err-code; promise-retry-->retry; promzard-->read; read-->mute-stream; - read-package-json-->glob; - read-package-json-->json-parse-even-better-errors; - read-package-json-->normalize-package-data; - read-package-json-->npm-normalize-package-bin; - read-package-json-fast-->json-parse-even-better-errors; - read-package-json-fast-->npm-normalize-package-bin; - readable-stream-->inherits; - readable-stream-->string_decoder; - readable-stream-->util-deprecate; - readdir-scoped-modules-->debuglog; - readdir-scoped-modules-->dezalgo; - readdir-scoped-modules-->graceful-fs; - readdir-scoped-modules-->once; - rimraf-->glob; - semver-->lru-cache; - smoke-tests-->minify-registry-metadata; - smoke-tests-->npmcli-eslint-config["@npmcli/eslint-config"]; - smoke-tests-->npmcli-promise-spawn["@npmcli/promise-spawn"]; - smoke-tests-->npmcli-template-oss["@npmcli/template-oss"]; - smoke-tests-->rimraf; - smoke-tests-->tap; - smoke-tests-->which; - socks-->ip; + sigstore-->sigstore-bundle["@sigstore/bundle"]; + sigstore-->sigstore-core["@sigstore/core"]; + sigstore-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; + sigstore-->sigstore-sign["@sigstore/sign"]; + sigstore-->sigstore-tuf["@sigstore/tuf"]; + sigstore-->sigstore-verify["@sigstore/verify"]; + sigstore-bundle-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; + sigstore-sign-->make-fetch-happen; + sigstore-sign-->proc-log; + sigstore-sign-->promise-retry; + sigstore-sign-->sigstore-bundle["@sigstore/bundle"]; + sigstore-sign-->sigstore-core["@sigstore/core"]; + sigstore-sign-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; + sigstore-tuf-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; + sigstore-tuf-->tuf-js; + sigstore-verify-->sigstore-bundle["@sigstore/bundle"]; + sigstore-verify-->sigstore-core["@sigstore/core"]; + sigstore-verify-->sigstore-protobuf-specs["@sigstore/protobuf-specs"]; + socks-->ip-address; socks-->smart-buffer; socks-proxy-agent-->agent-base; socks-proxy-agent-->debug; @@ -722,40 +715,42 @@ graph LR; string-width-->emoji-regex; string-width-->is-fullwidth-code-point; string-width-->strip-ansi; - string_decoder-->safe-buffer; strip-ansi-->ansi-regex; - supports-color-->has-flag; tar-->chownr; - tar-->fs-minipass; + tar-->isaacs-fs-minipass["@isaacs/fs-minipass"]; tar-->minipass; tar-->minizlib; - tar-->mkdirp; tar-->yallist; + tinyglobby-->fdir; + tinyglobby-->picomatch; + tuf-js-->debug; + tuf-js-->make-fetch-happen; + tuf-js-->tufjs-models["@tufjs/models"]; + tufjs-models-->minimatch; + tufjs-models-->tufjs-canonical-json["@tufjs/canonical-json"]; unique-filename-->unique-slug; unique-slug-->imurmurhash; validate-npm-package-license-->spdx-correct; validate-npm-package-license-->spdx-expression-parse; - validate-npm-package-name-->builtins; - wcwidth-->defaults; which-->isexe; - wide-align-->string-width; write-file-atomic-->imurmurhash; write-file-atomic-->signal-exit; ``` -## npm dependency heirarchy +## npm dependency hierarchy These are the groups of dependencies in npm that depend on each other. Each group depends on packages lower down the chain, nothing depends on packages higher up the chain. - npm - - libnpmexec, libnpmfund - - @npmcli/arborist, libnpmpublish - - @npmcli/metavuln-calculator, libnpmdiff, libnpmpack - - pacote, libnpmaccess, libnpmhook, libnpmorg, libnpmsearch, libnpmteam, npm-profile - - npm-registry-fetch - - make-fetch-happen, libnpmversion, @npmcli/config, init-package-json - - @npmcli/installed-package-contents, @npmcli/map-workspaces, cacache, @npmcli/git, @npmcli/run-script, npm-packlist, read-package-json, @npmcli/query, readdir-scoped-modules, promzard - - npm-bundled, read-package-json-fast, @npmcli/fs, unique-filename, @npmcli/promise-spawn, npm-package-arg, normalize-package-data, bin-links, nopt, npm-install-checks, npmlog, dezalgo, read - - npm-normalize-package-bin, @npmcli/name-from-folder, semver, @npmcli/move-file, fs-minipass, infer-owner, ssri, unique-slug, proc-log, @npmcli/node-gyp, hosted-git-info, validate-npm-package-name, ignore-walk, minipass-fetch, @npmcli/package-json, cmd-shim, read-cmd-shim, write-file-atomic, abbrev, are-we-there-yet, gauge, parse-conflict-json, wrappy, treeverse, @npmcli/eslint-config, @npmcli/template-oss, @npmcli/disparity-colors, @npmcli/ci-detect, mute-stream, ini, npm-audit-report, npm-user-validate \ No newline at end of file + - @npmcli/mock-registry, libnpmdiff, libnpmexec, libnpmfund, libnpmpack + - @npmcli/arborist + - @npmcli/metavuln-calculator + - pacote, @npmcli/config, libnpmversion + - @npmcli/map-workspaces, @npmcli/run-script, libnpmaccess, libnpmorg, libnpmpublish, libnpmsearch, libnpmteam, init-package-json, npm-profile + - @npmcli/package-json, npm-registry-fetch + - @npmcli/git, make-fetch-happen + - @npmcli/smoke-tests, @npmcli/installed-package-contents, npm-pick-manifest, cacache, promzard + - @npmcli/docs, @npmcli/fs, npm-bundled, @npmcli/promise-spawn, npm-install-checks, npm-package-arg, unique-filename, npm-packlist, bin-links, nopt, parse-conflict-json, @npmcli/mock-globals, read + - @npmcli/eslint-config, @npmcli/template-oss, ignore-walk, semver, npm-normalize-package-bin, @npmcli/name-from-folder, which, ini, hosted-git-info, proc-log, validate-npm-package-name, json-parse-even-better-errors, ssri, unique-slug, @npmcli/node-gyp, @npmcli/redact, @npmcli/agent, minipass-fetch, @npmcli/query, cmd-shim, read-cmd-shim, write-file-atomic, abbrev, proggy, minify-registry-metadata, mute-stream, npm-audit-report, npm-user-validate diff --git a/Makefile b/Makefile deleted file mode 100644 index 72b285359e776..0000000000000 --- a/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -# vim: set softtabstop=2 shiftwidth=2: -SHELL = bash - -PUBLISHTAG = $(shell node scripts/publish-tag.js) -BRANCH = $(shell git rev-parse --abbrev-ref HEAD) - -# these docs have the @VERSION@ tag in them, so they have to be rebuilt -# whenever the package.json is touched, in case the version changed. -version_mandocs = $(shell grep -rl '@VERSION@' docs/content \ - |sed 's|.md|.1|g' \ - |sed 's|docs/content/commands/|man/man1/|g' ) - -cli_mandocs = $(shell find docs/content/commands -name '*.md' \ - |sed 's|.md|.1|g' \ - |sed 's|docs/content/commands/|man/man1/|g' ) - -files_mandocs = $(shell find docs/content/configuring-npm -name '*.md' \ - |sed 's|.md|.5|g' \ - |sed 's|docs/content/configuring-npm/|man/man5/|g' ) - -misc_mandocs = $(shell find docs/content/using-npm -name '*.md' \ - |sed 's|.md|.7|g' \ - |sed 's|docs/content/using-npm/|man/man7/|g' ) - -mandocs = $(cli_mandocs) $(files_mandocs) $(misc_mandocs) - -markdown_docs = $(shell for file in $(find lib/commands -name '*.js'); do echo docs/content/commands/npm-$(basename $file .js).md; done) - -all: docs - -docs: mandocs htmldocs $(markdown_docs) - -# don't regenerate the snapshot if we're generating -# snapshots, since presumably we just did that. -mandocs: deps $(mandocs) - @ ! [ "$${npm_lifecycle_event}" = "snap" ] && \ - ! [ "$${npm_lifecycle_event}" = "postsnap" ] && \ - TAP_SNAPSHOT=1 node test/lib/utils/config/definitions.js || true - -$(version_mandocs): package.json - -htmldocs: deps - node bin/npm-cli.js rebuild cmark-gfm - node docs/bin/dockhand.js - -clean: docsclean gitclean - -docsclean: - rm -rf man - -deps: - node bin/npm-cli.js run resetdeps - -## targets for man files, these are encouraged to be only built by running `make docs` or `make mandocs` -man/man1/%.1: docs/content/commands/%.md docs/bin/docs-build.js - @[ -d man/man1 ] || mkdir -p man/man1 - node docs/bin/docs-build.js $< $@ - -man/man5/npm-json.5: man/man5/package.json.5 - cp $< $@ - -man/man5/npm-global.5: man/man5/folders.5 - cp $< $@ - -man/man5/%.5: docs/content/configuring-npm/%.md docs/bin/docs-build.js - @[ -d man/man5 ] || mkdir -p man/man5 - node docs/bin/docs-build.js $< $@ - -man/man7/%.7: docs/content/using-npm/%.md docs/bin/docs-build.js - @[ -d man/man7 ] || mkdir -p man/man7 - node docs/bin/docs-build.js $< $@ - -# Any time the config definitions description changes, automatically -# update the documentation to account for it -docs/content/using-npm/config.md: docs/bin/config-doc.js lib/utils/config/*.js - node docs/bin/config-doc.js - -mddocs: docs/bin/config-doc-command.js lib/utils/config/*.js lib/utils/cmd-list.js - @for file in $(shell find docs/content/commands -name 'npm-*.md'); do \ - cmdname=$$(basename $$file .md) ;\ - cmdname=$${cmdname##npm-} ;\ - echo node docs/bin/config-doc-command.js $${file} lib/commands/$${cmdname}.js ;\ - node docs/bin/config-doc-command.js $${file} lib/commands/$${cmdname}.js ;\ - done - -docs/content/commands/npm-%.md: lib/commands/%.js - node docs/bin/config-doc-command.js $@ $< - -freshdocs: - touch lib/utils/config/definitions.js - touch docs/bin/*.js - make docs - make mddocs - -test-all: deps - node bin/npm-cli.js run test-all - -ls-ok: - node bin/npm-cli.js ls --omit=dev >/dev/null - -gitclean: - git clean -fd - -uninstall: - node bin/npm-cli.js rm -g -f npm - -link: uninstall - node bin/npm-cli.js link -f --ignore-scripts - -prune: deps - node bin/npm-cli.js prune --omit=dev --no-save --no-audit --no-fund - node scripts/git-dirty.js - -publish: gitclean ls-ok link test-all docs prune - git push origin $(BRANCH) &&\ - git push origin --tags &&\ - node bin/npm-cli.js publish --tag=$(PUBLISHTAG) - -release: gitclean ls-ok docs prune - @bash scripts/release.sh - -.PHONY: all latest install dev link docs mddocs clean uninstall test-all man docsclean release ls-ok deps prune freshdocs diff --git a/README.md b/README.md index 7e4a5f38a7607..d31017ec771b1 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,8 @@ # npm - a JavaScript package manager -[![npm version](https://img.shields.io/npm/v/npm.svg)](https://npm.im/npm) -[![license](https://img.shields.io/npm/l/npm.svg)](https://npm.im/npm) -[![CI - cli](https://github.com/npm/cli/actions/workflows/ci.yml/badge.svg)](https://github.com/npm/cli/actions/workflows/ci.yml) -[![Benchmark Suite](https://github.com/npm/cli/actions/workflows/benchmark.yml/badge.svg)](https://github.com/npm/cli/actions/workflows/benchmark.yml) - ### Requirements -One of the following versions of [Node.js](https://nodejs.org/en/download/) must be installed to run **`npm`**: - -* `12.x.x` >= `12.13.0` -* `14.x.x` >= `14.15.0` -* `16.0.0` or higher +You should be running a currently supported version of [Node.js](https://nodejs.org/en/download/) to run **`npm`**. For a list of which versions of Node.js are currently supported, please see the [Node.js releases](https://nodejs.org/en/about/previous-releases) page. ### Installation @@ -27,17 +18,7 @@ curl -qL https://www.npmjs.com/install.sh | sh #### Node Version Managers -If you're looking to manage multiple versions of **`node`** &/or **`npm`**, consider using a "Node Version Manager" such as: - -* [**`nvm`**](https://github.com/nvm-sh/nvm) -* [**`nvs`**](https://github.com/jasongin/nvs) -* [**`nave`**](https://github.com/isaacs/nave) -* [**`n`**](https://github.com/tj/n) -* [**`volta`**](https://github.com/volta-cli/volta) -* [**`nodenv`**](https://github.com/nodenv/nodenv) -* [**`asdf-nodejs`**](https://github.com/asdf-vm/asdf-nodejs) -* [**`nvm-windows`**](https://github.com/coreybutler/nvm-windows) -* [**`fnm`**](https://github.com/Schniz/fnm) +If you're looking to manage multiple versions of **`Node.js`** &/or **`npm`**, consider using a [node version manager](https://github.com/search?q=node+version+manager+archived%3Afalse&type=repositories&ref=advsearch) ### Usage @@ -50,18 +31,16 @@ npm <command> * [**Documentation**](https://docs.npmjs.com/) - Official docs & how-tos for all things **npm** * Note: you can also search docs locally with `npm help-search <query>` * [**Bug Tracker**](https://github.com/npm/cli/issues) - Search or submit bugs against the CLI -* [**Roadmap**](https://github.com/orgs/github/projects/4247/views/1?filterQuery=npm) - Track & follow along with our public roadmap -* [**Feedback**](https://github.com/npm/feedback) - Contribute ideas & discussion around the npm registry, website & CLI +* [**Community Feedback and Discussions**](https://github.com/orgs/community/discussions/categories/npm) - Contribute ideas & discussion around the npm registry, website & CLI * [**RFCs**](https://github.com/npm/rfcs) - Contribute ideas & specifications for the API/design of the npm CLI * [**Service Status**](https://status.npmjs.org/) - Monitor the current status & see incident reports for the website & registry * [**Project Status**](https://npm.github.io/statusboard/) - See the health of all our maintained OSS projects in one view -* [**Events Calendar**](https://calendar.google.com/calendar/u/0/embed?src=npmjs.com_oonluqt8oftrt0vmgrfbg6q6go@group.calendar.google.com) - Keep track of our Open RFC calls, releases, meetups, conferences & more -* [**Support**](https://www.npmjs.com/support) - Experiencing problems with the **npm** [website](https://npmjs.com) or [registry](https://registry.npmjs.org)? File a ticket [here](https://www.npmjs.com/support) +* [**Support**](https://www.npmjs.com/support) - Experiencing problems with the **npm** [website](https://npmjs.com) or [registry](https://registry.npmjs.org)? [File a ticket](https://www.npmjs.com/support) ### Acknowledgments * `npm` is configured to use the **npm Public Registry** at [https://registry.npmjs.org](https://registry.npmjs.org) by default; Usage of this registry is subject to **Terms of Use** available at [https://npmjs.com/policies/terms](https://npmjs.com/policies/terms) -* You can configure `npm` to use any other compatible registry you prefer. You can read more about configuring third-party registries [here](https://docs.npmjs.com/cli/v7/using-npm/registry) +* You can configure `npm` to use any other compatible registry you prefer. You can read more about [configuring third-party registries](https://docs.npmjs.com/cli/v7/using-npm/registry) ### FAQ on Branding diff --git a/SECURITY.md b/SECURITY.md index 41b76c24663ed..4fe06a2a32c77 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1 +1,13 @@ -Please send vulnerability reports through [hackerone](https://hackerone.com/github). +<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> + +GitHub takes the security of our software products and services seriously, including the open source code repositories managed through our GitHub organizations, such as [GitHub](https://github.com/GitHub). + +If you believe you have found a security vulnerability in this GitHub-owned open source repository, you can report it to us in one of two ways. + +If the vulnerability you have found is *not* [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) or if you do not wish to be considered for a bounty reward, please report the issue to us directly through [opensource-security@github.com](mailto:opensource-security@github.com). + +If the vulnerability you have found is [in scope for the GitHub Bug Bounty Program](https://bounty.github.com/#scope) and you would like for your finding to be considered for a bounty reward, please submit the vulnerability to us through [HackerOne](https://hackerone.com/github) in order to be eligible to receive a bounty award. + +**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.** + +Thanks for helping make GitHub safe for everyone. diff --git a/bin/node-gyp-bin/node-gyp.cmd b/bin/node-gyp-bin/node-gyp.cmd index 1ef2ae0c68fc4..083c9c58a502a 100755 --- a/bin/node-gyp-bin/node-gyp.cmd +++ b/bin/node-gyp-bin/node-gyp.cmd @@ -1,5 +1,5 @@ -if not defined npm_config_node_gyp ( - node "%~dp0\..\..\node_modules\node-gyp\bin\node-gyp.js" %* -) else ( +if not defined npm_config_node_gyp ( + node "%~dp0\..\..\node_modules\node-gyp\bin\node-gyp.js" %* +) else ( node "%npm_config_node_gyp%" %* -) +) diff --git a/bin/npm b/bin/npm index a131a53543404..027dc9d128d22 100755 --- a/bin/npm +++ b/bin/npm @@ -1,4 +1,8 @@ #!/usr/bin/env bash + +# This is used by the Node.js installer, which expects the cygwin/mingw +# shell script to already be present in the npm dependency folder. + (set -o igncr) 2>/dev/null && set -o igncr; # cygwin encoding fix basedir=`dirname "$0"` @@ -7,6 +11,16 @@ case `uname` in *CYGWIN*) basedir=`cygpath -w "$basedir"`;; esac +if [ `uname` = 'Linux' ] && type wslpath &>/dev/null ; then + IS_WSL="true" +fi + +function no_node_dir { + # if this didn't work, then everything else below will fail + echo "Could not determine Node.js install directory" >&2 + exit 1 +} + NODE_EXE="$basedir/node.exe" if ! [ -x "$NODE_EXE" ]; then NODE_EXE="$basedir/node" @@ -17,14 +31,21 @@ fi # this path is passed to node.exe, so it needs to match whatever # kind of paths Node.js thinks it's using, typically win32 paths. -CLI_BASEDIR="$("$NODE_EXE" -p 'require("path").dirname(process.execPath)')" +CLI_BASEDIR="$("$NODE_EXE" -p 'require("path").dirname(process.execPath)' 2> /dev/null)" +if [ $? -ne 0 ]; then + # this fails under WSL 1 so add an additional message. we also suppress stderr above + # because the actual error raised is not helpful. in WSL 1 node.exe cannot handle + # output redirection properly. See https://github.com/microsoft/WSL/issues/2370 + if [ "$IS_WSL" == "true" ]; then + echo "WSL 1 is not supported. Please upgrade to WSL 2 or above." >&2 + fi + no_node_dir +fi +NPM_PREFIX_JS="$CLI_BASEDIR/node_modules/npm/bin/npm-prefix.js" NPM_CLI_JS="$CLI_BASEDIR/node_modules/npm/bin/npm-cli.js" - -NPM_PREFIX=`"$NODE_EXE" "$NPM_CLI_JS" prefix -g` +NPM_PREFIX=`"$NODE_EXE" "$NPM_PREFIX_JS"` if [ $? -ne 0 ]; then - # if this didn't work, then everything else below will fail - echo "Could not determine Node.js install directory" >&2 - exit 1 + no_node_dir fi NPM_PREFIX_NPM_CLI_JS="$NPM_PREFIX/node_modules/npm/bin/npm-cli.js" @@ -34,7 +55,7 @@ NPM_WSL_PATH="/.." # WSL can run Windows binaries, so we have to give it the win32 path # however, WSL bash tests against posix paths, so we need to construct that # to know if npm is installed globally. -if [ `uname` = 'Linux' ] && type wslpath &>/dev/null ; then +if [ "$IS_WSL" == "true" ]; then NPM_WSL_PATH=`wslpath "$NPM_PREFIX_NPM_CLI_JS"` fi if [ -f "$NPM_PREFIX_NPM_CLI_JS" ] || [ -f "$NPM_WSL_PATH" ]; then diff --git a/bin/npm-prefix.js b/bin/npm-prefix.js new file mode 100755 index 0000000000000..b0b0ace6a92ab --- /dev/null +++ b/bin/npm-prefix.js @@ -0,0 +1,30 @@ +#!/usr/bin/env node +// This is a single-use bin to help windows discover the proper prefix for npm +// without having to load all of npm first +// It does not accept argv params + +const path = require('node:path') +const Config = require('@npmcli/config') +const { definitions, flatten, shorthands } = require('@npmcli/config/lib/definitions') +const config = new Config({ + npmPath: path.dirname(__dirname), + // argv is explicitly not looked at since prefix is not something that can be changed via argv + argv: [], + definitions, + flatten, + shorthands, + excludeNpmCwd: false, +}) + +async function main () { + try { + await config.load() + // eslint-disable-next-line no-console + console.log(config.globalPrefix) + } catch (err) { + // eslint-disable-next-line no-console + console.error(err) + process.exit(1) + } +} +main() diff --git a/bin/npm.cmd b/bin/npm.cmd index f111c59d1efb6..68af4b0fca09f 100755 --- a/bin/npm.cmd +++ b/bin/npm.cmd @@ -1,19 +1,20 @@ -:: Created by npm, please don't edit manually. -@ECHO OFF - -SETLOCAL - -SET "NODE_EXE=%~dp0\node.exe" -IF NOT EXIST "%NODE_EXE%" ( - SET "NODE_EXE=node" -) - -SET "NPM_CLI_JS=%~dp0\node_modules\npm\bin\npm-cli.js" -FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO ( - SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js" -) -IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" ( - SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%" -) - -"%NODE_EXE%" "%NPM_CLI_JS%" %* +:: Created by npm, please don't edit manually. +@ECHO OFF + +SETLOCAL + +SET "NODE_EXE=%~dp0\node.exe" +IF NOT EXIST "%NODE_EXE%" ( + SET "NODE_EXE=node" +) + +SET "NPM_PREFIX_JS=%~dp0\node_modules\npm\bin\npm-prefix.js" +SET "NPM_CLI_JS=%~dp0\node_modules\npm\bin\npm-cli.js" +FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_PREFIX_JS%"') DO ( + SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js" +) +IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" ( + SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%" +) + +"%NODE_EXE%" "%NPM_CLI_JS%" %* diff --git a/bin/npm.ps1 b/bin/npm.ps1 new file mode 100644 index 0000000000000..efed03fe5655e --- /dev/null +++ b/bin/npm.ps1 @@ -0,0 +1,50 @@ +#!/usr/bin/env pwsh + +Set-StrictMode -Version 'Latest' + +$NODE_EXE="$PSScriptRoot/node.exe" +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="$PSScriptRoot/node" +} +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="node" +} + +$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 +} + +$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 +} + +if ($MyInvocation.ExpectingInput) { # takes pipeline input + $input | & $NODE_EXE $NPM_CLI_JS $args +} elseif (-not $MyInvocation.Line) { # used "-File" argument + & $NODE_EXE $NPM_CLI_JS $args +} else { # used "-Command" argument + if (($MyInvocation | Get-Member -Name 'Statement') -and $MyInvocation.Statement) { + $NPM_ORIGINAL_COMMAND = $MyInvocation.Statement + } else { + $NPM_ORIGINAL_COMMAND = ( + [Management.Automation.InvocationInfo].GetProperty('ScriptPosition', [Reflection.BindingFlags] 'Instance, NonPublic') + ).GetValue($MyInvocation).Text + } + + $NODE_EXE = $NODE_EXE.Replace("``", "````") + $NPM_CLI_JS = $NPM_CLI_JS.Replace("``", "````") + + $NPM_COMMAND_ARRAY = [Management.Automation.Language.Parser]::ParseInput($NPM_ORIGINAL_COMMAND, [ref] $null, [ref] $null). + EndBlock.Statements.PipelineElements.CommandElements.Extent.Text + $NPM_ARGS = ($NPM_COMMAND_ARRAY | Select-Object -Skip 1) -join ' ' + + Invoke-Expression "& `"$NODE_EXE`" `"$NPM_CLI_JS`" $NPM_ARGS" +} + +exit $LASTEXITCODE diff --git a/bin/npx b/bin/npx index a34e3459b5a70..b8619ee9c5e37 100755 --- a/bin/npx +++ b/bin/npx @@ -11,6 +11,16 @@ case `uname` in *CYGWIN*) basedir=`cygpath -w "$basedir"`;; esac +if [ `uname` = 'Linux' ] && type wslpath &>/dev/null ; then + IS_WSL="true" +fi + +function no_node_dir { + # if this didn't work, then everything else below will fail + echo "Could not determine Node.js install directory" >&2 + exit 1 +} + NODE_EXE="$basedir/node.exe" if ! [ -x "$NODE_EXE" ]; then NODE_EXE="$basedir/node" @@ -19,17 +29,24 @@ if ! [ -x "$NODE_EXE" ]; then NODE_EXE=node fi -# these paths are passed to node.exe, so they need to match whatever +# this path is passed to node.exe, so it needs to match whatever # kind of paths Node.js thinks it's using, typically win32 paths. -CLI_BASEDIR="$("$NODE_EXE" -p 'require("path").dirname(process.execPath)')" +CLI_BASEDIR="$("$NODE_EXE" -p 'require("path").dirname(process.execPath)' 2> /dev/null)" if [ $? -ne 0 ]; then - # if this didn't work, then everything else below will fail - echo "Could not determine Node.js install directory" >&2 - exit 1 + # this fails under WSL 1 so add an additional message. we also suppress stderr above + # because the actual error raised is not helpful. in WSL 1 node.exe cannot handle + # output redirection properly. See https://github.com/microsoft/WSL/issues/2370 + if [ "$IS_WSL" == "true" ]; then + echo "WSL 1 is not supported. Please upgrade to WSL 2 or above." >&2 + fi + no_node_dir fi -NPM_CLI_JS="$CLI_BASEDIR/node_modules/npm/bin/npm-cli.js" +NPM_PREFIX_JS="$CLI_BASEDIR/node_modules/npm/bin/npm-prefix.js" NPX_CLI_JS="$CLI_BASEDIR/node_modules/npm/bin/npx-cli.js" -NPM_PREFIX=`"$NODE_EXE" "$NPM_CLI_JS" prefix -g` +NPM_PREFIX=`"$NODE_EXE" "$NPM_PREFIX_JS"` +if [ $? -ne 0 ]; then + no_node_dir +fi NPM_PREFIX_NPX_CLI_JS="$NPM_PREFIX/node_modules/npm/bin/npx-cli.js" # a path that will fail -f test on any posix bash @@ -38,7 +55,7 @@ NPX_WSL_PATH="/.." # WSL can run Windows binaries, so we have to give it the win32 path # however, WSL bash tests against posix paths, so we need to construct that # to know if npm is installed globally. -if [ `uname` = 'Linux' ] && type wslpath &>/dev/null ; then +if [ "$IS_WSL" == "true" ]; then NPX_WSL_PATH=`wslpath "$NPM_PREFIX_NPX_CLI_JS"` fi if [ -f "$NPM_PREFIX_NPX_CLI_JS" ] || [ -f "$NPX_WSL_PATH" ]; then diff --git a/bin/npx-cli.js b/bin/npx-cli.js index cb05e1cb706c6..e2e1b87906abe 100755 --- a/bin/npx-cli.js +++ b/bin/npx-cli.js @@ -24,9 +24,9 @@ const removed = new Set([ ...removedOpts, ]) -const { definitions, shorthands } = require('../lib/utils/config/index.js') +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) @@ -98,6 +98,7 @@ for (i = 3; i < process.argv.length; i++) { } if (removed.has(key)) { + // eslint-disable-next-line no-console console.error(`npx: the --${key} argument has been removed.`) sawRemovedFlags = true process.argv.splice(i, 1) @@ -122,6 +123,7 @@ for (i = 3; i < process.argv.length; i++) { } if (sawRemovedFlags) { + // eslint-disable-next-line no-console console.error('See `npm help exec` for more information') } diff --git a/bin/npx.cmd b/bin/npx.cmd index b79518ec50540..ab991abfc2562 100755 --- a/bin/npx.cmd +++ b/bin/npx.cmd @@ -1,20 +1,20 @@ -:: Created by npm, please don't edit manually. -@ECHO OFF - -SETLOCAL - -SET "NODE_EXE=%~dp0\node.exe" -IF NOT EXIST "%NODE_EXE%" ( - SET "NODE_EXE=node" -) - -SET "NPM_CLI_JS=%~dp0\node_modules\npm\bin\npm-cli.js" -SET "NPX_CLI_JS=%~dp0\node_modules\npm\bin\npx-cli.js" -FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO ( - SET "NPM_PREFIX_NPX_CLI_JS=%%F\node_modules\npm\bin\npx-cli.js" -) -IF EXIST "%NPM_PREFIX_NPX_CLI_JS%" ( - SET "NPX_CLI_JS=%NPM_PREFIX_NPX_CLI_JS%" -) - -"%NODE_EXE%" "%NPX_CLI_JS%" %* +:: Created by npm, please don't edit manually. +@ECHO OFF + +SETLOCAL + +SET "NODE_EXE=%~dp0\node.exe" +IF NOT EXIST "%NODE_EXE%" ( + SET "NODE_EXE=node" +) + +SET "NPM_PREFIX_JS=%~dp0\node_modules\npm\bin\npm-prefix.js" +SET "NPX_CLI_JS=%~dp0\node_modules\npm\bin\npx-cli.js" +FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_PREFIX_JS%"') DO ( + SET "NPM_PREFIX_NPX_CLI_JS=%%F\node_modules\npm\bin\npx-cli.js" +) +IF EXIST "%NPM_PREFIX_NPX_CLI_JS%" ( + SET "NPX_CLI_JS=%NPM_PREFIX_NPX_CLI_JS%" +) + +"%NODE_EXE%" "%NPX_CLI_JS%" %* diff --git a/bin/npx.ps1 b/bin/npx.ps1 new file mode 100644 index 0000000000000..3fe7b5435763a --- /dev/null +++ b/bin/npx.ps1 @@ -0,0 +1,50 @@ +#!/usr/bin/env pwsh + +Set-StrictMode -Version 'Latest' + +$NODE_EXE="$PSScriptRoot/node.exe" +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="$PSScriptRoot/node" +} +if (-not (Test-Path $NODE_EXE)) { + $NODE_EXE="node" +} + +$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 +} + +$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 +} + +if ($MyInvocation.ExpectingInput) { # takes pipeline input + $input | & $NODE_EXE $NPX_CLI_JS $args +} elseif (-not $MyInvocation.Line) { # used "-File" argument + & $NODE_EXE $NPX_CLI_JS $args +} else { # used "-Command" argument + if (($MyInvocation | Get-Member -Name 'Statement') -and $MyInvocation.Statement) { + $NPX_ORIGINAL_COMMAND = $MyInvocation.Statement + } else { + $NPX_ORIGINAL_COMMAND = ( + [Management.Automation.InvocationInfo].GetProperty('ScriptPosition', [Reflection.BindingFlags] 'Instance, NonPublic') + ).GetValue($MyInvocation).Text + } + + $NODE_EXE = $NODE_EXE.Replace("``", "````") + $NPX_CLI_JS = $NPX_CLI_JS.Replace("``", "````") + + $NPX_COMMAND_ARRAY = [Management.Automation.Language.Parser]::ParseInput($NPX_ORIGINAL_COMMAND, [ref] $null, [ref] $null). + EndBlock.Statements.PipelineElements.CommandElements.Extent.Text + $NPX_ARGS = ($NPX_COMMAND_ARRAY | Select-Object -Skip 1) -join ' ' + + Invoke-Expression "& `"$NODE_EXE`" `"$NPX_CLI_JS`" $NPX_ARGS" +} + +exit $LASTEXITCODE diff --git a/changelogs/CHANGELOG-1.md b/changelogs/CHANGELOG-1.md deleted file mode 100644 index ea409c3d998b7..0000000000000 --- a/changelogs/CHANGELOG-1.md +++ /dev/null @@ -1,743 +0,0 @@ -### v1.4.29 (2015-10-29): - -#### THINGS ARE HAPPENING IN LTS LAND - -In a special one-off release as part of the [strategy to get a version of npm -into Node LTS that works with the current -registry](https://github.com/nodejs/LTS/issues/37), modify npm to print out -this deprecation banner literally every time npm is invoked to do anything: - -``` -npm WARN deprecated This version of npm lacks support for important features, -npm WARN deprecated such as scoped packages, offered by the primary npm -npm WARN deprecated registry. Consider upgrading to at least npm@2, if not the -npm WARN deprecated latest stable version. To upgrade to npm@2, run: -npm WARN deprecated -npm WARN deprecated npm -g install npm@latest-2 -npm WARN deprecated -npm WARN deprecated To upgrade to the latest stable version, run: -npm WARN deprecated -npm WARN deprecated npm -g install npm@latest -npm WARN deprecated -npm WARN deprecated (Depending on how Node.js was installed on your system, you -npm WARN deprecated may need to prefix the preceding commands with `sudo`, or if -npm WARN deprecated on Windows, run them from an Administrator prompt.) -npm WARN deprecated -npm WARN deprecated If you're running the version of npm bundled with -npm WARN deprecated Node.js 0.10 LTS, be aware that the next version of 0.10 LTS -npm WARN deprecated will be bundled with a version of npm@2, which has some small -npm WARN deprecated backwards-incompatible changes made to `npm run-script` and -npm WARN deprecated semver behavior. -``` - -The message basically tells the tale: Node 0.10 will finally be getting -`npm@2`, so those of you who haven't upgraded your build systems to deal with -its (relatively small) breaking changes should do so now. - -Also, this version doesn't even pretend that it can deal with scoped packages, -which, given the confusing behavior of older versions of `npm@1.4`, where it -would sometimes try to install packages from GitHub, is a distinct improvement. - -There is no good reason for you as an end user to upgrade to this version of -npm yourself. - -* [`709e9b4`](https://github.com/npm/npm/commit/709e9b44f5df9817a1c4babfbf26a2329bd265fb) - Print 20-line deprecation banner on all command invocations. - ([@othiym23](https://github.com/othiym23)) -* [`0c29d09`](https://github.com/npm/npm/commit/0c29d0906608e8e174bd30a7a245e19795326051) - Crash out immediately with an exhortation to upgrade on attempts to use - scoped packages. ([@othiym23](https://github.com/othiym23)) - -### v1.5.0-alpha-4 (2014-07-18): - -* fall back to `_auth` config as default auth when using default registry - ([@isaacs](https://github.com/isaacs)) -* support for 'init.version' for those who don't want to deal with semver 0.0.x - oddities ([@rvagg](https://github.com/rvagg)) -* [`be06213`](https://github.com/npm/npm/commit/be06213415f2d51a50d2c792b4cd0d3412a9a7b1) - remove residual support for `win` log level - ([@aterris](https://github.com/aterris)) - -### v1.5.0-alpha-3 (2014-07-17): - -* [`a3a85dd`](https://github.com/npm/npm/commit/a3a85dd004c9245a71ad2f0213bd1a9a90d64cd6) - `--save` scoped packages correctly ([@othiym23](https://github.com/othiym23)) -* [`18a3385`](https://github.com/npm/npm/commit/18a3385bcf8bfb8312239216afbffb7eec759150) - `npm-registry-client@3.0.2` ([@othiym23](https://github.com/othiym23)) -* [`375988b`](https://github.com/npm/npm/commit/375988b9bf5aa5170f06a790d624d31b1eb32c6d) - invalid package names are an early error for optional deps - ([@othiym23](https://github.com/othiym23)) -* consistently use `node-package-arg` instead of arbitrary package spec - splitting ([@othiym23](https://github.com/othiym23)) - -### v1.5.0-alpha-2 (2014-07-01): - -* [`54cf625`](https://github.com/npm/npm/commit/54cf62534e3331e3f454e609e44f0b944e819283) - fix handling for 301s in `npm-registry-client@3.0.1` - ([@Raynos](https://github.com/Raynos)) -* [`e410861`](https://github.com/npm/npm/commit/e410861c69a3799c1874614cb5b87af8124ff98d) - don't crash if no username set on `whoami` - ([@isaacs](https://github.com/isaacs)) -* [`0353dde`](https://github.com/npm/npm/commit/0353ddeaca8171aa7dbdd8102b7e2eb581a86406) - respect `--json` for output ([@isaacs](https://github.com/isaacs)) -* [`b3d112a`](https://github.com/npm/npm/commit/b3d112ae190b984cc1779b9e6de92218f22380c6) - outdated: Don't show headings if there's nothing to output - ([@isaacs](https://github.com/isaacs)) -* [`bb4b90c`](https://github.com/npm/npm/commit/bb4b90c80dbf906a1cb26d85bc0625dc2758acc3) - outdated: Default to `latest` rather than `*` for unspecified deps - ([@isaacs](https://github.com/isaacs)) - -### v1.5.0-alpha-1 (2014-07-01): - -* [`eef4884`](https://github.com/npm/npm/commit/eef4884d6487ee029813e60a5f9c54e67925d9fa) - use the correct piece of the spec for GitHub shortcuts - ([@othiym23](https://github.com/othiym23)) - -### v1.5.0-alpha-0 (2014-07-01): - -* [`7f55057`](https://github.com/npm/npm/commit/7f55057807cfdd9ceaf6331968e666424f48116c) - install scoped packages ([#5239](https://github.com/npm/npm/issues/5239)) - ([@othiym23](https://github.com/othiym23)) -* [`0df7e16`](https://github.com/npm/npm/commit/0df7e16c0232d8f4d036ebf4ec3563215517caac) - publish scoped packages ([#5239](https://github.com/npm/npm/issues/5239)) - ([@othiym23](https://github.com/othiym23)) -* [`0689ba2`](https://github.com/npm/npm/commit/0689ba249b92b4c6279a26804c96af6f92b3a501) - support (and save) --scope=@s config - ([@othiym23](https://github.com/othiym23)) -* [`f34878f`](https://github.com/npm/npm/commit/f34878fc4cee29901e4daf7bace94be01e25cad7) - scope credentials to registry ([@othiym23](https://github.com/othiym23)) -* [`0ac7ca2`](https://github.com/npm/npm/commit/0ac7ca233f7a69751fe4386af6c4daa3ee9fc0da) - capture and store bearer tokens when sent by registry - ([@othiym23](https://github.com/othiym23)) -* [`63c3277`](https://github.com/npm/npm/commit/63c3277f089b2c4417e922826bdc313ac854cad6) - only delete files that are created by npm - ([@othiym23](https://github.com/othiym23)) -* [`4f54043`](https://github.com/npm/npm/commit/4f540437091d1cbca3915cd20c2da83c2a88bb8e) - `npm-package-arg@2.0.0` ([@othiym23](https://github.com/othiym23)) -* [`9e1460e`](https://github.com/npm/npm/commit/9e1460e6ac9433019758481ec031358f4af4cd44) - `read-package-json@1.2.3` ([@othiym23](https://github.com/othiym23)) -* [`719d8ad`](https://github.com/npm/npm/commit/719d8adb9082401f905ff4207ede494661f8a554) - `fs-vacuum@1.2.1` ([@othiym23](https://github.com/othiym23)) -* [`9ef8fe4`](https://github.com/npm/npm/commit/9ef8fe4d6ead3acb3e88c712000e2d3a9480ebec) - `async-some@1.0.0` ([@othiym23](https://github.com/othiym23)) -* [`a964f65`](https://github.com/npm/npm/commit/a964f65ab662107b62a4ca58535ce817e8cca331) - `npmconf@2.0.1` ([@othiym23](https://github.com/othiym23)) -* [`113765b`](https://github.com/npm/npm/commit/113765bfb7d3801917c1d9f124b8b3d942bec89a) - `npm-registry-client@3.0.0` ([@othiym23](https://github.com/othiym23)) - -### v1.4.28 (2014-09-12): - -* [`f4540b6`](https://github.com/npm/npm/commit/f4540b6537a87e653d7495a9ddcf72949fdd4d14) - [#6043](https://github.com/npm/npm/issues/6043) defer rollbacks until just - before the CLI exits ([@isaacs](https://github.com/isaacs)) -* [`1eabfd5`](https://github.com/npm/npm/commit/1eabfd5c03f33c2bd28823714ff02059eeee3899) - [#6043](https://github.com/npm/npm/issues/6043) `slide@1.1.6`: wait until all - callbacks have finished before proceeding - ([@othiym23](https://github.com/othiym23)) - -### v1.4.27 (2014-09-04): - -* [`4cf3c8f`](https://github.com/npm/npm/commit/4cf3c8fd78c9e2693a5f899f50c28f4823c88e2e) - [#6007](https://github.com/npm/npm/issues/6007) request@2.42.0: properly set - headers on proxy requests ([@isaacs](https://github.com/isaacs)) -* [`403cb52`](https://github.com/npm/npm/commit/403cb526be1472bb7545fa8e62d4976382cdbbe5) - [#6055](https://github.com/npm/npm/issues/6055) npmconf@1.1.8: restore - case-insensitivity of environmental config - ([@iarna](https://github.com/iarna)) - -### v1.4.26 (2014-08-28): - -* [`eceea95`](https://github.com/npm/npm/commit/eceea95c804fa15b18e91c52c0beb08d42a3e77d) - `github-url-from-git@1.4.0`: add support for git+https and git+ssh - ([@stefanbuck](https://github.com/stefanbuck)) -* [`e561758`](https://github.com/npm/npm/commit/e5617587e7d7ab686192391ce55357dbc7fed0a3) - `columnify@1.2.1` ([@othiym23](https://github.com/othiym23)) -* [`0c4fab3`](https://github.com/npm/npm/commit/0c4fab372ee76eab01dda83b6749429a8564902e) - `cmd-shim@2.0.0`: upgrade to graceful-fs 3 - ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`2d69e4d`](https://github.com/npm/npm/commit/2d69e4d95777671958b5e08d3b2f5844109d73e4) - `github-url-from-username-repo@1.0.0`: accept slashes in branch names - ([@robertkowalski](https://github.com/robertkowalski)) -* [`81f9b2b`](https://github.com/npm/npm/commit/81f9b2bac9d34c223ea093281ba3c495f23f10d1) - ensure lifecycle spawn errors caught properly - ([@isaacs](https://github.com/isaacs)) -* [`bfaab8c`](https://github.com/npm/npm/commit/bfaab8c6e0942382a96b250634ded22454c36b5a) - `npm-registry-client@2.0.7`: properly encode % in passwords - ([@isaacs](https://github.com/isaacs)) -* [`91cfb58`](https://github.com/npm/npm/commit/91cfb58dda851377ec604782263519f01fd96ad8) - doc: Fix 'npm help index' ([@isaacs](https://github.com/isaacs)) - -### v1.4.25 (2014-08-21): - -* [`64c0ec2`](https://github.com/npm/npm/commit/64c0ec241ef5d83761ca8de54acb3c41b079956e) - `npm-registry-client@2.0.6`: Print the notification header returned by the - registry, and make sure status codes are printed without gratuitous quotes - around them. - ([@othiym23](https://github.com/othiym23)) -* [`a8ed12b`](https://github.com/npm/npm/commit/a8ed12b) `tar@1.0.1`: - Add test for removing an extract target immediately after unpacking. - ([@isaacs](https://github.com/isaacs)) -* [`70fd11d`](https://github.com/npm/npm/commit/70fd11d) - `lockfile@1.0.0`: Fix incorrect interaction between `wait`, `stale`, - and `retries` options. Part 2 of race condition leading to `ENOENT` - errors. - ([@isaacs](https://github.com/isaacs)) -* [`0072c4d`](https://github.com/npm/npm/commit/0072c4d) - `fstream@1.0.2`: Fix a double-finish call which can result in excess - FS operations after the `close` event. Part 2 of race condition - leading to `ENOENT` errors. - ([@isaacs](https://github.com/isaacs)) - -### v1.4.24 (2014-08-14): - -* [`9344bd9`](https://github.com/npm/npm/commit/9344bd9b2929b5c399a0e0e0b34d45bce7bc24bb) - doc: add new changelog ([@othiym23](https://github.com/othiym23)) -* [`4be76fd`](https://github.com/npm/npm/commit/4be76fd65e895883c337a99f275ccc8c801adda3) - doc: update version doc to include `pre-*` increment args - ([@isaacs](https://github.com/isaacs)) -* [`e4f2620`](https://github.com/npm/npm/commit/e4f262036080a282ad60e236a9aeebd39fde9fe4) - build: add `make tag` to tag current release as `latest` - ([@isaacs](https://github.com/isaacs)) -* [`ec2596a`](https://github.com/npm/npm/commit/ec2596a7cb626772780b25b0a94a7e547a812bd5) - build: publish with `--tag=v1.4-next` ([@isaacs](https://github.com/isaacs)) -* [`9ee55f8`](https://github.com/npm/npm/commit/9ee55f892b8b473032a43c59912c5684fd1b39e6) - build: add script to output `v1.4-next` publish tag - ([@isaacs](https://github.com/isaacs)) -* [`aecb56f`](https://github.com/npm/npm/commit/aecb56f95a84687ea46920a0b98aaa587fee1568) - build: remove outdated `docpublish` make target - ([@isaacs](https://github.com/isaacs)) -* [`b57a9b7`](https://github.com/npm/npm/commit/b57a9b7ccd13e6b38831ed63595c8ea5763da247) - build: remove unpublish step from `make publish` - ([@isaacs](https://github.com/isaacs)) -* [`2c6acb9`](https://github.com/npm/npm/commit/2c6acb96c71c16106965d5cd829b67195dd673c7) - install: rename `.gitignore` when unpacking foreign tarballs - ([@isaacs](https://github.com/isaacs)) -* [`22f3681`](https://github.com/npm/npm/commit/22f3681923e993a47fc1769ba735bfa3dd138082) - cache: detect non-gzipped tar files more reliably - ([@isaacs](https://github.com/isaacs)) - -### v1.4.23 (2014-07-31): - -* [`8dd11d1`](https://github.com/npm/npm/commit/8dd11d1) update several - dependencies to avoid using `semver`s starting with 0. - -### v1.4.22 (2014-07-31): - -* [`d9a9e84`](https://github.com/npm/npm/commit/d9a9e84) `read-package-json@1.2.4` - ([@isaacs](https://github.com/isaacs)) -* [`86f0340`](https://github.com/npm/npm/commit/86f0340) - `github-url-from-git@1.2.0` ([@isaacs](https://github.com/isaacs)) -* [`a94136a`](https://github.com/npm/npm/commit/a94136a) `fstream@0.1.29` - ([@isaacs](https://github.com/isaacs)) -* [`bb82d18`](https://github.com/npm/npm/commit/bb82d18) `glob@4.0.5` - ([@isaacs](https://github.com/isaacs)) -* [`5b6bcf4`](https://github.com/npm/npm/commit/5b6bcf4) `cmd-shim@1.1.2` - ([@isaacs](https://github.com/isaacs)) -* [`c2aa8b3`](https://github.com/npm/npm/commit/c2aa8b3) license: Cleaned up - legalese with actual lawyer ([@isaacs](https://github.com/isaacs)) -* [`63fe0ee`](https://github.com/npm/npm/commit/63fe0ee) `init-package-json@1.0.0` - ([@isaacs](https://github.com/isaacs)) - -### v1.4.21 (2014-07-14): - -* [`88f51aa`](https://github.com/npm/npm/commit/88f51aa27eb9a958d1fa7ec50fee5cfdedd05110) - fix handling for 301s in `npm-registry-client@2.0.3` - ([@Raynos](https://github.com/Raynos)) - -### v1.4.20 (2014-07-02): - -* [`0353dde`](https://github.com/npm/npm/commit/0353ddeaca8171aa7dbdd8102b7e2eb581a86406) - respect `--json` for output ([@isaacs](https://github.com/isaacs)) -* [`b3d112a`](https://github.com/npm/npm/commit/b3d112ae190b984cc1779b9e6de92218f22380c6) - outdated: Don't show headings if there's nothing to output - ([@isaacs](https://github.com/isaacs)) -* [`bb4b90c`](https://github.com/npm/npm/commit/bb4b90c80dbf906a1cb26d85bc0625dc2758acc3) - outdated: Default to `latest` rather than `*` for unspecified deps - ([@isaacs](https://github.com/isaacs)) - -### v1.4.19 (2014-07-01): - -* [`f687433`](https://github.com/npm/npm/commit/f687433) relative URLS for - working non-root registry URLS ([@othiym23](https://github.com/othiym23)) -* [`bea190c`](https://github.com/npm/npm/commit/bea190c) - [#5591](https://github.com/npm/npm/issues/5591) bump nopt and npmconf - ([@isaacs](https://github.com/isaacs)) - -### v1.4.18 (2014-06-29): - -* Bump glob dependency from 4.0.2 to 4.0.3. It now uses graceful-fs when - available, increasing resilience to [various filesystem - errors](https://github.com/isaacs/node-graceful-fs#improvements-over-fs-module). - ([@isaacs](https://github.com/isaacs)) - -### v1.4.17 (2014-06-27): - -* replace escape codes with ansicolors - ([@othiym23](https://github.com/othiym23)) -* Allow to build all the docs OOTB. ([@GeJ](https://github.com/GeJ)) -* Use core.longpaths on win32 git - fixes - [#5525](https://github.com/npm/npm/issues/5525) ([@bmeck](https://github.com/bmeck)) -* `npmconf@1.1.2` ([@isaacs](https://github.com/isaacs)) -* Consolidate color sniffing in config/log loading process - ([@isaacs](https://github.com/isaacs)) -* add verbose log when project config file is ignored - ([@isaacs](https://github.com/isaacs)) -* npmconf: Float patch to remove 'scope' from config defs - ([@isaacs](https://github.com/isaacs)) -* doc: npm-explore can't handle a version - ([@robertkowalski](https://github.com/robertkowalski)) -* Add user-friendly errors for ENOSPC and EROFS. - ([@voodootikigod](https://github.com/voodootikigod)) -* bump tar and fstream deps ([@isaacs](https://github.com/isaacs)) -* Run the npm-registry-couchapp tests along with npm tests - ([@isaacs](https://github.com/isaacs)) - -### v1.2.8000 (2014-06-17): - -* Same as v1.4.16, but with the spinner disabled, and a version number that - starts with v1.2. - -### v1.4.16 (2014-06-17): - -* `npm-registry-client@2.0.2` ([@isaacs](https://github.com/isaacs)) -* `fstream@0.1.27` ([@isaacs](https://github.com/isaacs)) -* `sha@1.2.4` ([@isaacs](https://github.com/isaacs)) -* `rimraf@2.2.8` ([@isaacs](https://github.com/isaacs)) -* `npmlog@1.0.1` ([@isaacs](https://github.com/isaacs)) -* `npm-registry-client@2.0.1` ([@isaacs](https://github.com/isaacs)) -* removed redundant dependency ([@othiym23](https://github.com/othiym23)) -* `npmconf@1.0.5` ([@isaacs](https://github.com/isaacs)) -* Properly handle errors that can occur in the config-loading process - ([@isaacs](https://github.com/isaacs)) - -### v1.4.15 (2014-06-10): - -* cache: atomic de-race-ified package.json writing - ([@isaacs](https://github.com/isaacs)) -* `fstream@0.1.26` ([@isaacs](https://github.com/isaacs)) -* `graceful-fs@3.0.2` ([@isaacs](https://github.com/isaacs)) -* `osenv@0.1.0` ([@isaacs](https://github.com/isaacs)) -* Only spin the spinner when we're fetching stuff - ([@isaacs](https://github.com/isaacs)) -* Update `osenv@0.1.0` which removes ~/tmp as possible tmp-folder - ([@robertkowalski](https://github.com/robertkowalski)) -* `ini@1.2.1` ([@isaacs](https://github.com/isaacs)) -* `graceful-fs@3` ([@isaacs](https://github.com/isaacs)) -* Update glob and things depending on glob - ([@isaacs](https://github.com/isaacs)) -* github-url-from-username-repo and read-package-json updates - ([@isaacs](https://github.com/isaacs)) -* `editor@0.1.0` ([@isaacs](https://github.com/isaacs)) -* `columnify@1.1.0` ([@isaacs](https://github.com/isaacs)) -* bump ansi and associated deps ([@isaacs](https://github.com/isaacs)) - -### v1.4.14 (2014-06-05): - -* char-spinner: update to not bork windows - ([@isaacs](https://github.com/isaacs)) - -### v1.4.13 (2014-05-23): - -* Fix `npm install` on a tarball. - ([`ed3abf1`](https://github.com/npm/npm/commit/ed3abf1aa10000f0f687330e976d78d1955557f6), - [#5330](https://github.com/npm/npm/issues/5330), - [@othiym23](https://github.com/othiym23)) -* Fix an issue with the spinner on Node 0.8. - ([`9f00306`](https://github.com/npm/npm/commit/9f003067909440390198c0b8f92560d84da37762), - [@isaacs](https://github.com/isaacs)) -* Re-add `npm.commands.cache.clean` and `npm.commands.cache.read` APIs, and - document `npm.commands.cache.*` as npm-cache(3). - ([`e06799e`](https://github.com/npm/npm/commit/e06799e77e60c1fc51869619083a25e074d368b3), - [@isaacs](https://github.com/isaacs)) - -### v1.4.12 (2014-05-23): - -* remove normalize-package-data from top level, de-^-ify inflight dep - ([@isaacs](https://github.com/isaacs)) -* Always sort saved bundleDependencies ([@isaacs](https://github.com/isaacs)) -* add inflight to bundledDependencies - ([@othiym23](https://github.com/othiym23)) - -### v1.4.11 (2014-05-22): - -* fix `npm ls` labeling issue -* `node-gyp@0.13.1` -* default repository to https:// instead of git:// -* addLocalTarball: Remove extraneous unpack - ([@isaacs](https://github.com/isaacs)) -* Massive cache folder refactor ([@othiym23](https://github.com/othiym23) and - [@isaacs](https://github.com/isaacs)) -* Busy Spinner, no http noise ([@isaacs](https://github.com/isaacs)) -* Per-project .npmrc file support ([@isaacs](https://github.com/isaacs)) -* `npmconf@1.0.0`, Refactor config/uid/prefix loading process - ([@isaacs](https://github.com/isaacs)) -* Allow once-disallowed characters in passwords - ([@isaacs](https://github.com/isaacs)) -* Send npm version as 'version' header ([@isaacs](https://github.com/isaacs)) -* fix cygwin encoding issue (Karsten Tinnefeld) -* Allow non-github repositories with `npm repo` - ([@evanlucas](https://github.com/evanlucas)) -* Allow peer deps to be satisfied by grandparent -* Stop optional deps moving into deps on `update --save` - ([@timoxley](https://github.com/timoxley)) -* Ensure only matching deps update with `update --save*` - ([@timoxley](https://github.com/timoxley)) -* Add support for `prerelease`, `preminor`, `prepatch` to `npm version` - -### v1.4.10 (2014-05-05): - -* Don't set referer if already set -* fetch: Send referer and npm-session headers -* `run-script`: Support `--parseable` and `--json` -* list runnable scripts ([@evanlucas](https://github.com/evanlucas)) -* Use marked instead of ronn for html docs - -### v1.4.9 (2014-05-01): - -* Send referer header (with any potentially private stuff redacted) -* Fix critical typo bug in previous npm release - -### v1.4.8 (2014-05-01): - -* Check SHA before using files from cache -* adduser: allow change of the saved password -* Make `npm install` respect `config.unicode` -* Fix lifecycle to pass `Infinity` for config env value -* Don't return 0 exit code on invalid command -* cache: Handle 404s and other HTTP errors as errors -* Resolve ~ in path configs to env.HOME -* Include npm version in default user-agent conf -* npm init: Use ISC as default license, use save-prefix for deps -* Many test and doc fixes - -### v1.4.7 (2014-04-15): - -* Add `--save-prefix` option that can be used to override the default of `^` - when using `npm install --save` and its counterparts. - ([`64eefdf`](https://github.com/npm/npm/commit/64eefdfe26bb27db8dc90e3ab5d27a5ef18a4470), - [@thlorenz](https://github.com/thlorenz)) -* Allow `--silent` to silence the echoing of commands that occurs with `npm - run`. - ([`c95cf08`](https://github.com/npm/npm/commit/c95cf086e5b97dbb48ff95a72517b203a8f29eab), - [@Raynos](https://github.com/Raynos)) -* Some speed improvements to the cache, which should improve install times. - ([`cb94310`](https://github.com/npm/npm/commit/cb94310a6adb18cb7b881eacb8d67171eda8b744), - [`3b0870f`](https://github.com/npm/npm/commit/3b0870fb2f40358b3051abdab6be4319d196b99d), - [`120f5a9`](https://github.com/npm/npm/commit/120f5a93437bbbea9249801574a2f33e44e81c33), - [@isaacs](https://github.com/isaacs)) -* Improve ability to retry registry requests when a subset of the registry - servers are down. - ([`4a5257d`](https://github.com/npm/npm/commit/4a5257de3870ac3dafa39667379f19f6dcd6093e), - https://github.com/npm/npm-registry-client/commit/7686d02cb0b844626d6a401e58c0755ef3bc8432, - [@isaacs](https://github.com/isaacs)) -* Fix marking of peer dependencies as extraneous. - ([`779b164`](https://github.com/npm/npm/commit/779b1649764607b062c031c7e5c972151b4a1754), - https://github.com/npm/read-installed/commit/6680ba6ef235b1ca3273a00b70869798ad662ddc, - [@isaacs](https://github.com/isaacs)) -* Fix npm crashing when doing `npm shrinkwrap` in the presence of a - `package.json` with no dependencies. - ([`a9d9fa5`](https://github.com/npm/npm/commit/a9d9fa5ad3b8c925a589422b7be28d2735f320b0), - [@kislyuk](https://github.com/kislyuk)) -* Fix error when using `npm view` on packages that have no versions or have - been unpublished. - ([`94df2f5`](https://github.com/npm/npm/commit/94df2f56d684b35d1df043660180fc321b743dc8), - [@juliangruber](https://github.com/juliangruber); - [`2241a09`](https://github.com/npm/npm/commit/2241a09c843669c70633c399ce698cec3add40b3), - [@isaacs](https://github.com/isaacs)) - -### v1.4.6 (2014-03-19): - -* Fix extraneous package detection to work in more cases. - ([`f671286`](https://github.com/npm/npm/commit/f671286), npm/read-installed#20, - [@LaurentVB](https://github.com/LaurentVB)) - -### v1.4.5 (2014-03-18): - -* Sort dependencies in `package.json` when doing `npm install --save` and all - its variants. - ([`6fd6ff7`](https://github.com/npm/npm/commit/6fd6ff7e536ea6acd33037b1878d4eca1f931985), - [@domenic](https://github.com/domenic)) -* Add `--save-exact` option, usable alongside `--save` and its variants, which - will write the exact version number into `package.json` instead of the - appropriate semver-compatibility range. - ([`17f07df`](https://github.com/npm/npm/commit/17f07df8ad8e594304c2445bf7489cb53346f2c5), - [@timoxley](https://github.com/timoxley)) -* Accept gzipped content from the registry to speed up downloads and save - bandwidth. - ([`a3762de`](https://github.com/npm/npm/commit/a3762de843b842be8fa0ab57cdcd6b164f145942), - npm/npm-registry-client#40, [@fengmk2](https://github.com/fengmk2)) -* Fix `npm ls`'s `--depth` and `--log` options. - ([`1d29b17`](https://github.com/npm/npm/commit/1d29b17f5193d52a5c4faa412a95313dcf41ed91), - npm/read-installed#13, [@zertosh](https://github.com/zertosh)) -* Fix "Adding a cache directory to the cache will make the world implode" in - certain cases. - ([`9a4b2c4`](https://github.com/npm/npm/commit/9a4b2c4667c2b1e0054e3d5611ab86acb1760834), - domenic/path-is-inside#1, [@pmarques](https://github.com/pmarques)) -* Fix readmes not being uploaded in certain rare cases. - ([`527b72c`](https://github.com/npm/npm/commit/527b72cca6c55762b51e592c48a9f28cc7e2ff8b), - [@isaacs](https://github.com/isaacs)) - -### v1.4.4 (2014-02-20): - -* Add `npm t` as an alias for `npm test` (which is itself an alias for `npm run - test`, or even `npm run-script test`). We like making running your tests - easy. ([`14e650b`](https://github.com/npm/npm/commit/14e650bce0bfebba10094c961ac104a61417a5de), [@isaacs](https://github.com/isaacs)) - -### v1.4.3 (2014-02-16): - -* Add back `npm prune --production`, which was removed in 1.3.24. - ([`acc4d02`](https://github.com/npm/npm/commit/acc4d023c57d07704b20a0955e4bf10ee91bdc83), - [@davglass](https://github.com/davglass)) -* Default `npm install --save` and its counterparts to use the `^` version - specifier, instead of `~`. - ([`0a3151c`](https://github.com/npm/npm/commit/0a3151c9cbeb50c1c65895685c2eabdc7e2608dc), - [@mikolalysenko](https://github.com/mikolalysenko)) -* Make `npm shrinkwrap` output dependencies in a sorted order, so that diffs - between shrinkwrap files should be saner now. - ([`059b2bf`](https://github.com/npm/npm/commit/059b2bfd06ae775205a37257dca80142596a0113), - [@Raynos](https://github.com/Raynos)) -* Fix `npm dedupe` not correctly respecting dependency constraints. - ([`86028e9`](https://github.com/npm/npm/commit/86028e9fd8524d5e520ce01ba2ebab5a030103fc), - [@rafeca](https://github.com/rafeca)) -* Fix `npm ls` giving spurious warnings when you used `"latest"` as a version - specifier. - (https://github.com/npm/read-installed/commit/d2956400e0386931c926e0f30c334840e0938f14, - [@bajtos](https://github.com/bajtos)) -* Fixed a bug where using `npm link` on packages without a `name` value could - cause npm to delete itself. - ([`401a642`](https://github.com/npm/npm/commit/401a64286aa6665a94d1d2f13604f7014c5fce87), - [@isaacs](https://github.com/isaacs)) -* Fixed `npm install ./pkg@1.2.3` to actually install the directory at - `pkg@1.2.3`; before it would try to find version `1.2.3` of the package - `./pkg` in the npm registry. - ([`46d8768`](https://github.com/npm/npm/commit/46d876821d1dd94c050d5ebc86444bed12c56739), - [@rlidwka](https://github.com/rlidwka); see also - [`f851b79`](https://github.com/npm/npm/commit/f851b79a71d9a5f5125aa85877c94faaf91bea5f)) -* Fix `npm outdated` to respect the `color` configuration option. - ([`d4f6f3f`](https://github.com/npm/npm/commit/d4f6f3ff83bd14fb60d3ac6392cb8eb6b1c55ce1), - [@timoxley](https://github.com/timoxley)) -* Fix `npm outdated --parseable`. - ([`9575a23`](https://github.com/npm/npm/commit/9575a23f955ce3e75b509c89504ef0bd707c8cf6), - [@yhpark](https://github.com/yhpark)) -* Fix a lockfile-related errors when using certain Git URLs. - ([`164b97e`](https://github.com/npm/npm/commit/164b97e6089f64e686db7a9a24016f245effc37f), - [@nigelzor](https://github.com/nigelzor)) - -### v1.4.2 (2014-02-13): - -* Fixed an issue related to mid-publish GET requests made against the registry. - (https://github.com/npm/npm-registry-client/commit/acbec48372bc1816c67c9e7cbf814cf50437ff93, - [@isaacs](https://github.com/isaacs)) - -### v1.4.1 (2014-02-13): - -* Fix `npm shrinkwrap` forgetting to shrinkwrap dependencies that were also - development dependencies. - ([`9c575c5`](https://github.com/npm/npm/commit/9c575c56efa9b0c8b0d4a17cb9c1de3833004bcd), - [@diwu1989](https://github.com/diwu1989)) -* Fixed publishing of pre-existing packages with uppercase characters in their - name. - (https://github.com/npm/npm-registry-client/commit/9345d3b6c3d8510dd5c4418f27ee1fce59acebad, - [@isaacs](https://github.com/isaacs)) - -### v1.4.0 (2014-02-12): - -* Remove `npm publish --force`. See - https://github.com/npm/npmjs.org/issues/148. - ([@isaacs](https://github.com/isaacs), - npm/npm-registry-client@2c8dba990de6a59af6545b75cc00a6dc12777c2a) -* Other changes to the registry client related to saved configs and couch - logins. ([@isaacs](https://github.com/isaacs); - npm/npm-registry-client@25e2b019a1588155e5f87d035c27e79963b75951, - npm/npm-registry-client@9e41e9101b68036e0f078398785f618575f3cdde, - npm/npm-registry-client@2c8dba990de6a59af6545b75cc00a6dc12777c2a) -* Show an error to the user when doing `npm update` and the `package.json` - specifies a version that does not exist. - ([@evanlucas](https://github.com/evanlucas), - [`027a33a`](https://github.com/npm/npm/commit/027a33a5c594124cc1d82ddec5aee2c18bc8dc32)) -* Fix some issues with cache ownership in certain installation configurations. - ([@outcoldman](https://github.com/outcoldman), - [`a132690`](https://github.com/npm/npm/commit/a132690a2876cda5dcd1e4ca751f21dfcb11cb9e)) -* Fix issues where GitHub shorthand dependencies `user/repo` were not always - treated the same as full Git URLs. - ([@robertkowalski](https://github.com/robertkowalski), - https://github.com/meryn/normalize-package-data/commit/005d0b637aec1895117fcb4e3b49185eebf9e240) - -### v1.3.26 (2014-02-02): - -* Fixes and updates to publishing code - ([`735427a`](https://github.com/npm/npm/commit/735427a69ba4fe92aafa2d88f202aaa42920a9e2) - and - [`c0ac832`](https://github.com/npm/npm/commit/c0ac83224d49aa62e55577f8f27d53bbfd640dc5), - [@isaacs](https://github.com/isaacs)) -* Fix `npm bugs` with no arguments. - ([`b99d465`](https://github.com/npm/npm/commit/b99d465221ac03bca30976cbf4d62ca80ab34091), - [@Hoops](https://github.com/Hoops)) - -### v1.3.25 (2014-01-25): - -* Remove gubblebum blocky font from documentation headers. - ([`6940c9a`](https://github.com/npm/npm/commit/6940c9a100160056dc6be8f54a7ad7fa8ceda7e2), - [@isaacs](https://github.com/isaacs)) - -### v1.3.24 (2014-01-19): - -* Make the search output prettier, with nice truncated columns, and a `--long` - option to create wrapping columns. - ([`20439b2`](https://github.com/npm/npm/commit/20439b2) and - [`3a6942d`](https://github.com/npm/npm/commit/3a6942d), - [@timoxley](https://github.com/timoxley)) -* Support multiple packagenames in `npm docs`. - ([`823010b`](https://github.com/npm/npm/commit/823010b), - [@timoxley](https://github.com/timoxley)) -* Fix the `npm adduser` bug regarding "Error: default value must be string or - number" again. ([`b9b4248`](https://github.com/npm/npm/commit/b9b4248), - [@isaacs](https://github.com/isaacs)) -* Fix `scripts` entries containing whitespaces on Windows. - ([`80282ed`](https://github.com/npm/npm/commit/80282ed), - [@robertkowalski](https://github.com/robertkowalski)) -* Fix `npm update` for Git URLs that have credentials in them - ([`93fc364`](https://github.com/npm/npm/commit/93fc364), - [@danielsantiago](https://github.com/danielsantiago)) -* Fix `npm install` overwriting `npm link`-ed dependencies when they are tagged - Git dependencies. ([`af9bbd9`](https://github.com/npm/npm/commit/af9bbd9), - [@evanlucas](https://github.com/evanlucas)) -* Remove `npm prune --production` since it buggily removed some dependencies - that were necessary for production; see - [#4509](https://github.com/npm/npm/issues/4509). Hopefully it can make its - triumphant return, one day. - ([`1101b6a`](https://github.com/npm/npm/commit/1101b6a), - [@isaacs](https://github.com/isaacs)) - -Dependency updates: -* [`909cccf`](https://github.com/npm/npm/commit/909cccf) `read-package-json@1.1.6` -* [`a3891b6`](https://github.com/npm/npm/commit/a3891b6) `rimraf@2.2.6` -* [`ac6efbc`](https://github.com/npm/npm/commit/ac6efbc) `sha@1.2.3` -* [`dd30038`](https://github.com/npm/npm/commit/dd30038) `node-gyp@0.12.2` -* [`c8c3ebe`](https://github.com/npm/npm/commit/c8c3ebe) `npm-registry-client@0.3.3` -* [`4315286`](https://github.com/npm/npm/commit/4315286) `npmconf@0.1.12` - -### v1.3.23 (2014-01-03): - -* Properly handle installations that contained a certain class of circular - dependencies. - ([`5dc93e8`](https://github.com/npm/npm/commit/5dc93e8c82604c45b6067b1acf1c768e0bfce754), - [@substack](https://github.com/substack)) - -### v1.3.22 (2013-12-25): - -* Fix a critical bug in `npm adduser` that would manifest in the error message - "Error: default value must be string or number." - ([`fba4bd2`](https://github.com/npm/npm/commit/fba4bd24bc2ab00ccfeda2043aa53af7d75ef7ce), - [@isaacs](https://github.com/isaacs)) -* Allow `npm bugs` in the current directory to open the current package's bugs - URL. - ([`d04cf64`](https://github.com/npm/npm/commit/d04cf6483932c693452f3f778c2fa90f6153a4af), - [@evanlucas](https://github.com/evanlucas)) -* Several fixes to various error messages to include more useful or updated - information. - ([`1e6f2a7`](https://github.com/npm/npm/commit/1e6f2a72ca058335f9f5e7ca22d01e1a8bb0f9f7), - [`ff46366`](https://github.com/npm/npm/commit/ff46366bd40ff0ef33c7bac8400bc912c56201d1), - [`8b4bb48`](https://github.com/npm/npm/commit/8b4bb4815d80a3612186dc5549d698e7b988eb03); - [@rlidwka](https://github.com/rlidwka), - [@evanlucas](https://github.com/evanlucas)) - -### v1.3.21 (2013-12-17): - -* Fix a critical bug that prevented publishing due to incorrect hash - calculation. - ([`4ca4a2c`](https://github.com/npm/npm-registry-client/commit/4ca4a2c6333144299428be6b572e2691aa59852e), - [@dominictarr](https://github.com/dominictarr)) - -### v1.3.20 (2013-12-17): - -* Fixes a critical bug in v1.3.19. Thankfully, due to that bug, no one could - install npm v1.3.19 :) - -### v1.3.19 (2013-12-16): - -* Adds atomic PUTs for publishing packages, which should result in far fewer - requests and less room for replication errors on the server-side. - -### v1.3.18 (2013-12-16): - -* Added an `--ignore-scripts` option, which will prevent `package.json` scripts - from being run. Most notably, this will work on `npm install`, so e.g. `npm - install --ignore-scripts` will not run preinstall and prepublish scripts. - ([`d7e67bf`](https://github.com/npm/npm/commit/d7e67bf0d94b085652ec1c87d595afa6f650a8f6), - [@sqs](https://github.com/sqs)) -* Fixed a bug introduced in 1.3.16 that would manifest with certain cache - configurations, by causing spurious errors saying "Adding a cache directory - to the cache will make the world implode." - ([`966373f`](https://github.com/npm/npm/commit/966373fad8d741637f9744882bde9f6e94000865), - [@domenic](https://github.com/domenic)) -* Re-fixed the multiple download of URL dependencies, whose fix was reverted in - 1.3.17. - ([`a362c3f`](https://github.com/npm/npm/commit/a362c3f1919987419ed8a37c8defa19d2e6697b0), - [@spmason](https://github.com/spmason)) - -### v1.3.17 (2013-12-11): - -* This release reverts - [`644c2ff`](https://github.com/npm/npm/commit/644c2ff3e3d9c93764f7045762477f48864d64a7), - which avoided re-downloading URL and shinkwrap dependencies when doing `npm - install`. You can see the in-depth reasoning in - [`d8c907e`](https://github.com/npm/npm/commit/d8c907edc2019b75cff0f53467e34e0ffd7e5fba); - the problem was, that the patch changed the behavior of `npm install -f` to - reinstall all dependencies. -* A new version of the no-re-downloading fix has been submitted as - [#4303](https://github.com/npm/npm/issues/4303) and will hopefully be - included in the next release. - -### v1.3.16 (2013-12-11): - -* Git URL dependencies are now updated on `npm install`, fixing a two-year old - bug - ([`5829ecf`](https://github.com/npm/npm/commit/5829ecf032b392d2133bd351f53d3c644961396b), - [@robertkowalski](https://github.com/robertkowalski)). Additional progress on - reducing the resulting Git-related I/O is tracked as - [#4191](https://github.com/npm/npm/issues/4191), but for now, this will be a - big improvement. -* Added a `--json` mode to `npm outdated` to give a parseable output. - ([`0b6c9b7`](https://github.com/npm/npm/commit/0b6c9b7c8c5579f4d7d37a0c24d9b7a12ccbe5fe), - [@yyx990803](https://github.com/yyx990803)) -* Made `npm outdated` much prettier and more useful. It now outputs a - color-coded and easy-to-read table. - ([`fd3017f`](https://github.com/npm/npm/commit/fd3017fc3e9d42acf6394a5285122edb4dc16106), - [@quimcalpe](https://github.com/quimcalpe)) -* Added the `--depth` option to `npm outdated`, so that e.g. you can do `npm - outdated --depth=0` to show only top-level outdated dependencies. - ([`1d184ef`](https://github.com/npm/npm/commit/1d184ef3f4b4bc309d38e9128732e3e6fb46d49c), - [@yyx990803](https://github.com/yyx990803)) -* Added a `--no-git-tag-version` option to `npm version`, for doing the usual - job of `npm version` minus the Git tagging. This could be useful if you need - to increase the version in other related files before actually adding the - tag. - ([`59ca984`](https://github.com/npm/npm/commit/59ca9841ba4f4b2f11b8e72533f385c77ae9f8bd), - [@evanlucas](https://github.com/evanlucas)) -* Made `npm repo` and `npm docs` work without any arguments, adding them to the - list of npm commands that work on the package in the current directory when - invoked without arguments. - ([`bf9048e`](https://github.com/npm/npm/commit/bf9048e2fa16d43fbc4b328d162b0a194ca484e8), - [@robertkowalski](https://github.com/robertkowalski); - [`07600d0`](https://github.com/npm/npm/commit/07600d006c652507cb04ac0dae9780e35073dd67), - [@wilmoore](https://github.com/wilmoore)). There are a few other commands we - still want to implement this for; see - [#4204](https://github.com/npm/npm/issues/4204). -* Pass through the `GIT_SSL_NO_VERIFY` environment variable to Git, if it is - set; we currently do this with a few other environment variables, but we - missed that one. - ([`c625de9`](https://github.com/npm/npm/commit/c625de91770df24c189c77d2e4bc821f2265efa8), - [@arikon](https://github.com/arikon)) -* Fixed `npm dedupe` on Windows due to incorrect path separators being used - ([`7677de4`](https://github.com/npm/npm/commit/7677de4583100bc39407093ecc6bc13715bf8161), - [@mcolyer](https://github.com/mcolyer)). -* Fixed the `npm help` command when multiple words were searched for; it - previously gave a `ReferenceError`. - ([`6a28dd1`](https://github.com/npm/npm/commit/6a28dd147c6957a93db12b1081c6e0da44fe5e3c), - [@dereckson](https://github.com/dereckson)) -* Stopped re-downloading URL and shrinkwrap dependencies, as demonstrated in - [#3463](https://github.com/npm/npm/issues/3463) - ([`644c2ff`](https://github.com/isaacs/npm/commit/644c2ff3e3d9c93764f7045762477f48864d64a7), - [@spmason](https://github.com/spmason)). You can use the `--force` option to - force re-download and installation of all dependencies. diff --git a/changelogs/CHANGELOG-2.md b/changelogs/CHANGELOG-2.md deleted file mode 100644 index c4d2b777ebf12..0000000000000 --- a/changelogs/CHANGELOG-2.md +++ /dev/null @@ -1,5344 +0,0 @@ -### v2.15.12 (2017-03-24): - -This version brings the latest `node-gyp` to a soon to be released Node.js -4.x. The `node-gyp` update is particularly important to Windows folks due to -its addition of Visual Studio 2017 support. - -* [`cdd60e733`](https://github.com/npm/npm/commit/cdd60e733905a9994e1d6d832996bfdd12abeaee) - `node-gyp@3.6.0`: - Improvements to how Python is located. New `--devdir` flag. - Support for VS2017. - Chakracore support on ARM. - Remove path-array dependency, reducing size significantly. - ([@bnoordhuis](https://github.com/bnoordhuis)) - ([@mhart](https://github.com/mhart)) - ([@refack](https://github.com/refack)) - ([@kunalspathak](https://github.com/kunalspathak)) - -### v2.15.11 (2016-09-08): - -On we go with our monthly release cadence! This week is pretty much all -dependency updates and some documentation changes, as can be expected by now. - -Note that `npm@4` will almost certainly be released next month! It's not final -what we'll end up doing as far as LTS support goes, but the current thinking is -that, considering how small and resource-constrained our team is, support for -`npm@2` will be reduced to essentially maintenance, so we can better focus on -`npm@3` as the new LTS version (which will go into `node@6`), and `npm@4` as our -next main development version. - -#### DOCUMENTATION UPDATES - -* [`8f71038`](https://github.com/npm/npm/commit/8f71038310501ad5bc7445b2fa2ff0eaa377919a) - [#13892](https://github.com/npm/npm/pull/13892) - Update `LICENSE` file to match license on `master`. - ([@rvagg](https://github.com/rvagg)) -* [`e81b4f1`](https://github.com/npm/npm/commit/e81b4f1d18a4d79b7af8342747f2ed7dc3e84f0a) - [#12438](https://github.com/npm/npm/issues/12438) - Remind folks to use `#!/usr/bin/env node` in their `bin` scripts to make files - executable directly. - ([@mxstbr](https://github.com/mxstbr)) -* [`f89789f`](https://github.com/npm/npm/commit/f89789f43d65bfc74f64f15a99356841377e1af3) - [#13655](https://github.com/npm/npm/pull/13655) - Document line comment syntax for `.npmrc`. - ([@mdjasper](https://github.com/mdjasper)) -* [`5cd3abc`](https://github.com/npm/npm/commit/5cd3abc3511515e09b4a1b781c0520e84c267c5b) - [#13493](https://github.com/npm/npm/pull/13493) - Document that the user config file can itself be configured either through the - `$NPM_CONFIG_USERCONFIG` environment variable, or `--userconfig` command line - flag. - ([@jasonkarns](https://github.com/jasonkarns)) -* [`dd71ca0`](https://github.com/npm/npm/commit/dd71ca0efc2094b824ccc9e23af0fc915499f2e6) - [#13911](https://github.com/npm/npm/pull/13911) - Minor documentation reword and cleanup. - ([@othiym23](https://github.com/othiym23)) -* [`f7a320c`](https://github.com/npm/npm/commit/f7a320c816947d578a050c97e0fb9878954be0e8) - [#13682](https://github.com/npm/npm/pull/13682) - Minor grammar fix in documentation for `npm scripts`. - ([@Ajedi32](https://github.com/Ajedi32)) -* [`e5cb5e8`](https://github.com/npm/npm/commit/e5cb5e8fcf4642836fedf3f3421c994a8e27e19b) - [#13717](https://github.com/npm/npm/pull/13717) - Document that `npm link` will link the files specified in the `bin` field of - `package.json` to `{prefix}/bin/{name}`. - ([@legodude17](https://github.com/legodude17)) - -#### DEPENDENCY UPDATES -* [`8bef026`](https://github.com/npm/npm/commit/8bef026603b6da888edf0d41308d9e532abfcd54) - `graceful-fs@4.1.6` - ([@francescoinfante](https://github.com/francescoinfante)) -* [`9f73f4a`](https://github.com/npm/npm/commit/9f73f4aab5f56b256c5cf9e461e81abfa2844945) - `glob@7.0.6` - ([@isaacs](https://github.com/isaacs)) -* [`5391b7e`](https://github.com/npm/npm/commit/5391b7e8cd4401fbadbf54e810fdc965a3662a21) - `which@1.2.1` - ([@isaacs](https://github.com/isaacs)) -* [`43bfec8`](https://github.com/npm/npm/commit/43bfec8376dd8ded7d56a8dabd6139919544760e) - `retry@0.10.0` - ([@tim-kos](https://github.com/tim-kos)) -* [`39305f1`](https://github.com/npm/npm/commit/39305f1c76f74bf9789c769ef72a94ea9a81d119) - `readable-stream@2.1.5` - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`a5512fa`](https://github.com/npm/npm/commit/a5512fafd72e23755e77e28f1122b008bc12a733) - `once@1.4.0` - ([@zkochan](https://github.com/zkochan)) -* [`06a208b`](https://github.com/npm/npm/commit/06a208b178c1de3d0da58bc35a854d200fea8ef0) - `npm-registry-client@7.2.1`: - * [npm/npm-registry-client#142](https://github.com/npm/npm-registry-client/pull/142) Fix `EventEmitter` warning spam from error handlers on socket. ([@addaleax](https://github.com/addaleax)) - * [npm/npm-registry-client#131](https://github.com/npm/npm-registry-client/pull/131) Adds support for streaming request bodies. ([@aredridel](https://github.com/aredridel)) - * Fixes [#13656](https://github.com/npm/npm/issues/13656). - * Dependency updates. - * Documentation improvements. - ([@othiym23](https://github.com/othiym23)) -* [`4f759be`](https://github.com/npm/npm/commit/4f759be1fb5e23180b970350e58f40a513daa680) - `inherits@2.0.3` - ([@isaacs](https://github.com/isaacs)) -* [`4258b76`](https://github.com/npm/npm/commit/4258b764e2565f6294ae1e34a5653895290b62e3) - `tap@7.1.1` - ([@isaacs](https://github.com/isaacs)) - -### v2.15.10 (2016-08-11): - -Hi all, today's our first release coming out of the new monthly release -cadence. See below for details. We're all recovered from conferences now and -raring to go! For LTS we see some bug fixes, documentation improvements and -a host of dependency updates. - -The most dramatic bug fix is probably the inclusion of scoped modules in -bundled dependencies. Prior to this release and -[v3.10.7](https://github.com/npm/npm/releases/v3.10.7), npm had ignored -scoped modules found in `bundleDependencies` entirely. - -#### NEW RELEASE CADENCE - -Releasing npm has been, for the most part, a very prominent part of our -weekly process process. As part of our efforts to find the most effective -ways to allocate our team's resources, we decided last month that we would -try and slow our releases down to a monthly cadence, and see if we found -ourselves with as much extra time and attention as we expected to have. -Process experiments are useful for finding more effective ways to do our -work, and we're at least going to keep doing this for a whole quarter, and -then measure how well it worked out. It's entirely likely that we'll switch -back to a more frequent cadence, specially if we find that the value that -weekly cadence was providing the community is not worth sacrificing for a -bit of extra time. Does this affect you significantly? Let us know! - -#### WINDOWS CORNER CASES - -* [`405c404`](https://github.com/npm/npm/commit/405c4048c69c14d66e6179aba0c8a35e504e8041) - [#13023](https://github.com/npm/npm/pull/13023) - Fixed a Windows issue with the cache where callbacks could be called more than once. - ([@zkat](https://github.com/zkat)) - -* [`bf348dc`](https://github.com/npm/npm/commit/bf348dcfb944dc4b9f71b779bf172f86a2e1f474) - [#13023](https://github.com/npm/npm/pull/13023) - Fixed a Windows corner case with correct-mkdir where if SUDO_UID or - SUDO_GID were set then we would try to chown things even though that can't - work on Windows. - ([@zkat](https://github.com/zkat)) - -#### RACES IN THE CACHE - -* [`68f29f1`](https://github.com/npm/npm/commit/68f29f18f65c7a7e1c58eb6933af41d786971379) - [#12669](https://github.com/npm/npm/issues/12669) - Ignore ENOENT errors on chownr while adding packages to cache. This change - works around problems with race conditions and local packages. - ([@julianduque](https://github.com/julianduque)) - -#### BETTER GIT ENVIRONMENT WHITELISTING - -* [`5e96566`](https://github.com/npm/npm/commit/5e96566088f0d88c1ed10c5a9cbb7c0cd4aa2aee) - [#13358](https://github.com/npm/npm/pull/13358) - Add GIT_EXEC_PATH to Git environment whitelist. - ([@mhart](https://github.com/mhart)) - -#### DOCUMENTATION - -* [`363e381`](https://github.com/npm/npm/commit/363e381a4076ead89707a00cc4a447b1d59df3bc) - [#13319](https://github.com/npm/npm/pull/13319) - As Node.js 0.8 is no longer supported, remove mention of it from the README. - ([@watilde](https://github.com/watilde)) -* [`e8fafa8`](https://github.com/npm/npm/commit/e8fafa887c60eb8842c76c4b3dffe85eb49fa434) - [#10167](https://github.com/npm/npm/pull/10167) - Clarify in scope documentation that npm@2 is required for scoped packages. - ([@danpaz](https://github.com/danpaz)) - -#### DEPENDENCIES - -* [`66ef279`](https://github.com/npm/npm/commit/66ef279b7c3b3e4f9454474dddd057cc1f21873b) - [npm/fstream-npm#22](https://github.com/npm/fstream-npm/pull/22) - `fstream@1.1.1`: - Always include NOTICE files now. Fix inclusion of scoped modules as bundled dependencies. - ([@kemitchell](https://github.com/kemitchell)) - ([@forivall](https://github.com/forivall)) -* [`fe8385b`](https://github.com/npm/npm/commit/fe8385bd655502feb175eed175a6a06cafb2247a) - `glob@7.0.5`: - Update minimatch dep for security fix. See the minimatch update below for details. - ([@isaacs](https://github.com/isaacs)) -* [`51d49d2`](https://github.com/npm/npm/commit/51d49d2f79b4c69264de73a492ed54f87188d554) - [isaacs/node-graceful-fs#71](https://github.com/isaacs/node-graceful-fs/pull/71) - `graceful-fs@4.1.5`: - `graceful-fs` had a [bug fix](https://github.com/isaacs/node-graceful-fs/pull/71) which - fixes a problem ([nodejs/node#7846](https://github.com/nodejs/node/pull/7846)) exposed - by recent changes to Node.js. - ([@thefourtheye](https://github.com/thefourtheye)) -* [`5c8f39d`](https://github.com/npm/npm/commit/5c8f39d152c43e96b9006ffe865646a36a433a8a) - `minimatch@3.0.3`: - Handle extremely long and terrible patterns more gracefully. - There were some magic numbers that assumed that every extglob pattern starts - and ends with a specific number of characters in the regular expression. - Since !(||) patterns are a little bit more complicated, this led to creating - an invalid regular expression and throwing. - ([@isaacs](https://github.com/isaacs)) -* [`d681e16`](https://github.com/npm/npm/commit/d681e16a475a49d6196af9a5cedaaf88712f3a9f) - [npm/npm-user-validate#9](https://github.com/npm/npm-user-validate/pull/9) - `npm-user-validate@0.1.5`: - Use correct, lower username length limit. - ([@aredridel](https://github.com/aredridel)) -* [`f918994`](https://github.com/npm/npm/commit/f918994bd05ca965766cd573606ac35fb3032d6e) - `request@2.74.0`: - Update `request` dependency `tough-cookie` to `2.3.0` to - to address [https://nodesecurity.io/advisories/130](https://nodesecurity.io/advisories/130). - Versions 0.9.7 through 2.2.2 contain a vulnerable regular expression that, - under certain conditions involving long strings of semicolons in the - "Set-Cookie" header, causes the event loop to block for excessive amounts of - time. - ([@stash-sfdc](https://github.com/stash-sfdc)) -* [`5540cc4`](https://github.com/npm/npm/commit/5540cc4d6bde65071fb6fc2cb074e8598bd1276f) - [isaacs/rimraf#111](https://github.com/isaacs/rimraf/issues/111) - `rimraf@2.5.4`: Clarify assertions: cb is required, options are not. - ([@isaacs](https://github.com/isaacs)) -* [`6357928`](https://github.com/npm/npm/commit/6357928673be85f520dae2104fea58c35742bd65) - `spdx-license-ids@1.2.2`: - New licenses synced from spdx.org. - ([@shinnn](https://github.com/shinnn)) - -### v2.15.9 (2016-06-30): - -What's this? An LTS release? Yes, that is indeed so. Small, as usual, and as -LTSs should be, really, but a release nonetheless! - -The star of the show is an updated `node-gyp` with some goodies. The rest is -just docs and some CI stuff. - -Happy hacking! - -#### DEPENDENCY UPDATE! - -* [`f9a07cc`](https://github.com/npm/npm/commit/f9a07cc873f1915827d8df97d0c43204d1eb128c) - [#13200](https://github.com/npm/npm/pull/13200) - [`node-gyp@3.4.0`](https://github.com/nodejs/node-gyp/blob/master/CHANGELOG.md): - AIX, Visual Studio 2015, and logging improvements. Oh my~! - ([@rvagg](https://github.com/rvagg)) - -#### CI TWEAKS - -* [`bee83b8`](https://github.com/npm/npm/commit/bee83b8500c31aba65451dfcb082f9b5d1d5ce34) - Globally install `rimraf` on CI to make the LTS self-install work better. - ([@othiym23](https://github.com/othiym23)) -* [`6b8c0ab`](https://github.com/npm/npm/commit/6b8c0ab6fcbf8a37e8693acb8bbac22293b10893) - This new Travis configuration only runs coverage checks against Node.js LTS, - which speeds up all the other test runs. By, like, a lot. Also, the entire - file has been extensively commented, so the next time we need to mess with it, - we'll be able to better remember why all the weird bits are there. - ([@othiym23](https://github.com/othiym23)) - -#### DOCUMENTATION FIXES - -* [`2c7a5be`](https://github.com/npm/npm/commit/2c7a5be080276e3fdca3375ab0f8f5edffff753e) - [#13156](https://github.com/npm/npm/pull/13156) - Fix old reference to `doc/install` in a source comment. - ([@sheerun](https://github.com/sheerun)) -* [`e1cf78c`](https://github.com/npm/npm/commit/e1cf78c5b77f95383bd4a7fc6eeb8adbbe68e12e) - [#13189](https://github.com/npm/npm/pull/13189) - [#13113](https://github.com/npm/npm/issues/13113) - [#13189](https://github.com/npm/npm/pull/13189) - Fixes a link to `npm-tag(3)` that was breaking to instead point to - `npm-dist-tag(1)`, as reported by [@SimenB](https://github.com/SimenB) - ([@macdonst](https://github.com/macdonst)) - -### v2.15.8 (2016-06-17): - -There's a very important bug fix and a long-awaited (and significant!) -deprecation in this hotfix release. [Hold on.](http://butt.holdings/) - -#### *WHOA* - -When Node.js 6.0.0 was released, the CLI team noticed an alarming upsurge in -bugs related to important files (like `README.md`) not being included in -published packages. The new bugs looked much like -[#5082](https://github.com/npm/npm/issues/5082), which had been around in one -form or another since April, 2014. #5082 used to be a very rare (and obnoxious) -bug that the CLI team hadn't had much luck reproducing, and we'd basically -marked it down as a race condition that arose on machines using slow and / or -rotating-media-based hard drives. - -Under 6.0.0, the behavior was reliable enough to be nearly deterministic, and -made it very difficult for publishers using `.npmignore` files in combination -with `"files"` stanzas in `package.json` to get their packages onto the -registry without one or more files missing from the packed tarball. The entire -saga is contained within [the issue](https://github.com/npm/npm/issues/5082), -but the summary is that an improvement to the performance of -[`fs.realpath()`](https://nodejs.org/api/fs.html#fs_fs_realpath_path_options_callback) -made it much more likely that the packing code would lose the race. - -Fixing this has proven to be very difficult, in part because the code used by -npm to produce package tarballs is more complicated than, strictly speaking, it -needs to be. [**@evanlucas**](https://github.com/evanlucas) contributed [a -patch](https://github.com/npm/fstream/pull/50) that passed the tests in a -[special test suite](https://github.com/othiym23/eliminate-5082) that I -([**@othiym23**](https://github.com/othiym23)) created (with help from -[**@addaleax**](https://github.com/addaleax)), but only _after_ we'd released -the fixed version of that package did we learn that it actually made the -problem _worse_ in other situations in npm proper. Eventually, -[**@rvagg**](https://github.com/rvagg) put together a more durable fix that -appears to completely address the errant behavior under Node.js 6.0.0. That's -the patch included in this release. Everybody should chip in for redback -insurance for Rod and his family; he's done the community a huge favor. - -Does this mean the long (2+ year) saga of #5082 is now over? At this point, I'm -going to quote from my latest summary on the issue: - -> The CLI team (mostly me, with input from the rest of the team) has decided that -> the overall complexity of the interaction between `fstream`, `fstream-ignore`, -> `fstream-npm`, and `node-tar` has grown more convoluted than the team is -> comfortable (maybe even capable of) supporting. -> -> - While I believe that @rvagg's (very targeted) fix addresses _this_ issue, I -> would be shocked if there aren't other race conditions in npm's packing -> logic. I've already identified a couple other places in the code that are -> most likely race conditions, even if they're harder to trigger than the -> current one. -> - The way that dependency bundling is integrated leads to a situation in -> which a bunch of logic is duplicated between `fstream-npm` and -> `lib/utils/tar.js` in npm itself, and the way `fstream`'s extension -> mechanism works makes this difficult to clean up. This caused a nasty -> regression ([#13088](https://github.com/npm/fstream/pull/50), see below) as -> of ~`npm@3.8.7` where the dependencies of `bundledDependencies` were no -> longer being included in the built package tarballs. -> - The interaction between `.npmignore`, `.gitignore`, and `files` is hopelessly -> complicated, scattered in many places throughout the code. We've been -> discussing [making the ignores and includes logic clearer and more -> predictable](https://github.com/npm/npm/wiki/Files-and-Ignores), and the -> current code fights our efforts to clean that up. -> -> So, our intention is still to replace `fstream`, `fstream-ignore`, and -> `fstream-npm` with something much simpler and purpose-built. There's no real -> reason to have a stream abstraction here when a simple recursive-descent -> filesystem visitor and a synchronous function that can answer whether a given -> path should be included in the packed tarball would do the job adequately. -> -> What's not yet clear is whether we'll need to replace `node-tar` in the -> process. `node-tar` is a very robust implementation of tar (it handles, like, -> everything), and it also includes some very important tweaks to prevent several -> classes of security exploits involving maliciously crafted packages. However, -> its packing API involves passing in an `fstream` instance, so we'd either need -> to produce something that follows enough of `fstream`'s contract for `node-tar` -> to keep working, or swap `node-tar` out for something like `tar-stream` (and -> then ensuring that our use of `tar-stream` is secure, which could involve -> security patches for either npm or `tar-stream`). - -The testing and review of `fstream@1.0.10` that the team has done leads us to -believe that this bug is fixed, but I'm feeling more than a little paranoid -about fstream now, so it's important that people keep a close eye on their -publishes for a while and let us know immediately if they notice any -irregularities. - -* [`2c49265`](https://github.com/npm/npm/commit/2c49265c6746d29ae0cd5f3532d28c5950f9847e) - [#5082](https://github.com/npm/npm/issues/5082) `fstream@1.0.10`: Ensure that - entries are collected after a paused stream resumes. - ([@rvagg](https://github.com/rvagg)) -* [`92e4344`](https://github.com/npm/npm/commit/92e43444d9204f749f83512aeab5d5e0a2d085a7) - [#5082](https://github.com/npm/npm/issues/5082) Remove the warning introduced - in `npm@3.10.0`, because it should no longer be necessary. - ([@othiym23](https://github.com/othiym23)) - -#### GOODBYE, FAITHFUL FRIEND - -At NodeConf Adventure 2016 (RIP in peace, Mikeal Rogers's NodeConf!), the CLI -team had an opportunity to talk to representatives from some of the larger -companies that we knew were still using Node.js 0.8 in production. After asking -them whether they were still using 0.8, we got back blank stares and questions -like, "0.8? You mean, from four years ago?" After establishing that being able -to run npm in their legacy environments was no longer necessary, the CLI team -made the decision to drop support for 0.8. (Faithful observers of our [team -meetings](https://github.com/npm/npm/issues?utf8=%E2%9C%93&q=is%3Aissue+npm+cli+team+meeting+) -will have known this was the plan for NodeConf since the beginning of 2016.) - -In practice, this means only what's in the commit below: we've removed 0.8 from -our continuous integration test matrix below, and will no longer be habitually -testing changes under Node 0.8. We may also give ourselves permission to use -`setImmediate()` in test code. However, since the project still supports -Node.js 0.10 and 0.12, it's unlikely that patches that rely on ES 2015 -functionality will land anytime soon. - -Looking forward, the team's current plan is to drop support for Node.js 0.10 -when its LTS maintenance window expires in October, 2016, and 0.12 when its -maintenance / LTS window ends at the end of 2016. We will also drop support for -Node.js 5.x when Node.js 6 becomes LTS and Node.js 7 is released, also in the -October-December 2016 timeframe. - -(Confused about Node.js's LTS policy? [Don't -be!](https://github.com/nodejs/LTS) If you look at [this -diagram](https://github.com/nodejs/LTS/blob/ce364a94b0e0619eba570cd57be396573e1ef889/schedule.png), -it should make all of the preceding clear.) - -If, in practice, this doesn't work with distribution packagers or other -community stakeholders responsible for packaging and distributing Node.js and -npm, please reach out to us. Aligning the npm CLI's LTS policy with Node's -helps everybody minimize the amount of work they need to do, and since all of -our teams are small and very busy, this is somewhere between a necessity and -non-negotiable. - -* [`4a1ecc0`](https://github.com/npm/npm/commit/4a1ecc068fb2660bd9bc3e2e2372aa0176d2193b) - Remove 0.8 from the Node.js testing matrix, and reorder to match real-world - priority, with comments. ([@othiym23](https://github.com/othiym23)) - -### v2.15.7 (2016-06-16): - -It pains me greatly that we haven't been able to fix -[#5082](https://github.com/npm/npm/issues/5082) yet, but warning you away from -potentially publishing incomplete packages takes priority over feeling cheesy -about landing a warning to help keep y'all out of trouble, so here you go -(_please read this next bit_ (_please clap_)): - -#### DANGER: PUBLISHING ON NODE 6.0.0 - -Publishing and packing are buggy under Node versions greater than 6.0.0. -Please use Node.js LTS (4.4.x) to publish packages. See -[#5082](https://github.com/npm/npm/issues/5082) for details and current -status. - -* [`dff00ce`](https://github.com/npm/npm/commit/dff00cedd56b9c04370f840299a7e657a7a835c6) - [#13077](https://github.com/npm/npm/pull/13077) - Warn when using Node 6+. - ([@othiym23](https://github.com/othiym23)) - -#### PACKAGING CHANGES - -* [`1877171`](https://github.com/npm/npm/commit/1877171648e20595a82de34073b643f7e01a339f) - [#12873](https://github.com/npm/npm/issues/12873) - Ignore `.nyc_output`. This will help avoid an accidental publish or commit filled with - code coverage data. - ([@TheAlphaNerd](https://github.com/TheAlphaNerd)) - -#### DOCUMENTATION CHANGES - -* [`470ae86`](https://github.com/npm/npm/commit/470ae86e052ae2f29ebec15b7547230b6240042e) - [#12983](https://github.com/npm/npm/pull/12983) - Describe how to run the lifecycle scripts of dependencies. How you do - this changed with `npm` v2. - ([@Tapppi](https://github.com/Tapppi)) -* [`9cedf37`](https://github.com/npm/npm/commit/9cedf37e5a3e26d0ffd6351af8cac974e3e011c2) - [#12776](https://github.com/npm/npm/pull/12776) - Remove mention of `<pkg>` arg for `run-script`. - ([@fibo](https://github.com/fibo)) -* [`55b8424`](https://github.com/npm/npm/commit/55b8424d7229f2021cac55f0b03de72403e7c0ff) - [#12840](https://github.com/npm/npm/pull/12840) - Remove sexualized language from comment. - ([@geek](https://github.com/geek)) -* [`d6bf0c3`](https://github.com/npm/npm/commit/d6bf0c393788a6398bf80b41c57956f2dbcf3b39) - [#12802](https://github.com/npm/npm/pull/12802) - Small grammar fix in `doc/cli/npm.md`. - ([@andresilveira](https://github.com/andresilveira)) - -#### DEPENDENCY UPDATES - -* [`2c2c568`](https://github.com/npm/npm/commit/2c2c56857ff801d5fe1b6d3157870cd16e65891b) - `readable-stream@2.1.4`: Brought up to date with Node 6.1.0's streams implementation. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`d682e64`](https://github.com/npm/npm/commit/d682e6445845b0a2584935d5e2942409c43f6916) - [npm/npm-user-validate#8](https://github.com/npm/npm-user-validate/pull/8) - `npm-user-validate@0.1.4`: Add a maximum length limit for usernames based on - the (arbitrary) limit imposed by the primary npm registry. - ([@aredridel](https://github.com/aredridel)) -* [`448b65b`](https://github.com/npm/npm/commit/448b65b48cda3b782b714057fb4b8311cc1fa36a) - `which@1.2.10`: Remove unused dependency `is-absolute`, bug fixes. - ([@isaacs](https://github.com/isaacs)) -* [`7d15434`](https://github.com/npm/npm/commit/7d15434f0b0af8e70b119835b21968217224664f) - `require-inject@1.4.0`: Add `requireInject.withEmptyCache` and - `requireInject.installGlobally.andClearCache` to support loading modules to be - injected with an empty cache. - ([@iarna](https://github.com/iarna)) -* [`31845c0`](https://github.com/npm/npm/commit/31845c081bc6f3f8a2f3d83a3c792dccffbaa2a8) - `init-package-json@1.9.4`: - Replace use of reserved identifier `package` in, uh, the package. - ([@adius](https://github.com/adius)) -* [`d73ef3e`](https://github.com/npm/npm/commit/d73ef3e6b18d4905de668c5115bc6042905a02d9) - `glob@7.0.4`: Use userland `fs.realpath` implementation to get glob working under Node 6. - ([@isaacs](https://github.com/isaacs)) -* [`b47da85`](https://github.com/npm/npm/commit/b47da85cf83b946f2c8d29ab612c92028f31f6b0) - `inflight@1.0.5`: Correct link to package repository, add `"files"` stanza. - ([@iarna](https://github.com/iarna), [@jamestalmage](https://github.com/jamestalmage)) -* [`04815e4`](https://github.com/npm/npm/commit/04815e436035de785279fd000cdbc821cc1f3447) - [npm/npmlog#32](https://github.com/npm/npmlog/pull/32) - `npmlog@2.0.4`: Add `"files"` stanza to `package.json`. - ([@jamestalmage](https://github.com/jamestalmage)) -* [`9e29ad2`](https://github.com/npm/npm/commit/9e29ad227300bb970e7bcd21029944d4733e40db) - `wrappy@1.0.2`: Add `"files"` stanza to `package.json`. - ([@jamestalmage](https://github.com/jamestalmage)) -* [`44af4d4`](https://github.com/npm/npm/commit/44af4d475ac65bdce6d088173273ce4a4f74a49e) - `abbrev@1.0.9` ([@jorrit](https://github.com/jorrit)) -* [`6c977c0`](https://github.com/npm/npm/commit/6c977c0031d074479a26c7bec6ec83fd6c6526b2) - `npm-registry-client@7.1.2`: Add support for newer versions of `npmlog`. - ([@iarna](https://github.com/iarna)) - -### v2.15.6 (2016-05-12): - -I have a couple of doc fixes and a shrinkwrap fix for you all this week. - -#### PEER DEPENDENCIES AND SHRINKWRAPS - -* [`55c998a`](https://github.com/npm/npm/commit/55c998a098a306b90a84beef163a8890f9a616b1) - [#5135](https://github.com/npm/npm/issues/5135) - Fix a bug where peerDependencies & shrinkwraps didn't play nice together. (Where - the peerDependency resolver would end up installing its dep when it wasn't needed.) - ([@majgis](https://github.com/majgis)) - -#### NPM AND `node-gyp` DOCS IMPROVEMENTS - -* [`1826908`](https://github.com/npm/npm/commit/1826908b991510d8fbc71a0d0f2c01ff24fd83c2) - [#12636](https://github.com/npm/npm/pull/12636) - Improve `npm-scripts` documentation regarding when `node-gyp` is used. - ([@reconbot](https://github.com/reconbot)) -* [`f9ff7f3`](https://github.com/npm/npm/commit/f9ff7f36cc2c2c3fbb4f6eef91491b589d049d5f) - [#12586](https://github.com/npm/npm/pull/12586) - Correct `package.json` documentation as to when `node-gyp rebuild` called. - This now matches https://docs.npmjs.com/misc/scripts#default-values - ([@reconbot](https://github.com/reconbot)) - -### v2.15.5 (2016-05-05): - -This is a minor LTS release, bringing dependencies up to date and updating -our CI matrix to match what we support. - -Some of the dependency updates come out of our getting the development -branch's tests passing on Windows and so bring in fixes for a few Windows -related corner cases. - -#### CI UPDATES - -* [`bb6f0e5`](https://github.com/npm/npm/commit/bb6f0e5c95d4ad186768b1c962dd4c399f90ddb1) - [#12487](https://github.com/npm/npm/pull/12487) - Remove iojs from CI, add Node.js 6, prioritize 4 over 5. - ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY UPDATES - -* [`f2f8753`](https://github.com/npm/npm/commit/f2f8753c4aef2a604a4bdca2677711c940234b8f) - `which@1.2.8`: - Properly handle relative path executables. - ([@isaacs](https://github.com/isaacs)) -* [`e287ca9`](https://github.com/npm/npm/commit/e287ca99c37680d8e4cfacf4cfebe2da98884865) - `read-package-json@2.0.4`: - Fix Windows issue with ENOTDIR detection. - ([@zkat](https://github.com/zkat)) -* [`1a0ce6c`](https://github.com/npm/npm/commit/1a0ce6cff4c347bad035dc89bba2ceed9dacbf73) - `realize-package-specifier@3.0.3`: - Use npa with windows fix. - Fix relative path resolution when the local file might also be a tag. - ([@zkat](https://github.com/zkat)) - ([@iarna](https://github.com/iarna)) -* [`a475c9a`](https://github.com/npm/npm/commit/a475c9a4e4b36d00080b11f379657ce68185adc6) - `lru-cache@4.0.1`: - Use Symbol if available. - ([@isaacs](https://github.com/isaacs)) -* [`7141e08`](https://github.com/npm/npm/commit/7141e08816c620b1889d7537c30dc5b254de4d1f) - `sorted-object@2.0.0` - ([@iamstarkov](https://github.com/iamstarkov)) -* [`27c6190`](https://github.com/npm/npm/commit/27c6190216cc8a5a280f0efbabb3444581968d40) - `request@2.72.0` - ([@simov](https://github.com/simov)) -* [`ab90daf`](https://github.com/npm/npm/commit/ab90daf70ba51b51f722fb4cd74ac5267621c4b4) - `readable-stream@2.1.2` - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`b1715f8`](https://github.com/npm/npm/commit/b1715f805426403273225bcfa91d1a52d7b56eb8) - `graceful-fs@4.1.4` - ([@isaacs](https://github.com/isaacs)) -* [`ca97de6`](https://github.com/npm/npm/commit/ca97de6c18059ef420235f4706898ad8758904e6) - `block-stream@0.0.9` - ([@isaacs](https://github.com/isaacs)) - -### v2.15.4 (2016-04-21): - -Gosh, it's been a peaceful couple of weeks! - -Overall, the CLI team has been focused on the project to [get the test suite -passing on Windows](https://github.com/npm/npm/pull/11444). Our efforts should -be paying off soon -- there's only a couple of tests left! - -It's very unlikely those particular changes will make their way into our current -`npm@2` LTS release, I think, but it will help `npm@3` a lot, as well as -whatever version makes it into [`node@6`, which will eventually be the next -Node.js LTS](https://github.com/nodejs/node/pull/6155). - -As far as this week goes, we've got a couple of dep updates and doc fixes. -Always happy to see community contributions flying in. 💚 - -#### DEP UPDATE MAGIC - -* [`b178c4a`](https://github.com/npm/npm/commit/b178c4ac9ce91c0a0794526a38b553c759132d18) - `spdx-license-ids@1.2.1`: - Minor project-related tweaks -- no license changes. - ([@shinnn](https://github.com/shinnn)) -* [`1adf179`](https://github.com/npm/npm/commit/1adf179948ab8cb97dfb2f46a61e9f37d944c42a) - `normalize-git-url@3.0.2`: - Fixes `file://` URLs on Windows. Turns out stuff like `file://C:\hello` is - actually fairly weird for a URL (it's not actually a valid URL, but we're just - gonna pretend.😉) - ([@zkat](https://github.com/zkat)) -* [`9cfd56c`](https://github.com/npm/npm/commit/9cfd56cdadc040c0b2fa7654cdb5e7d22dbef7cb) - `fs-vacuum@1.2.9`: - This one goes out to our fans at Big Blue: There was an AIX-specific issue - where `fs.rmDir` was failing with `EEXIST` instead of `ENOTEMPTY` with - non-empty directories. - ([@richardlau](https://github.com/richardlau)) - -#### HOORAY DOC CONTRIBUTIONS - -No seriously, we love these. Keep 'em comin'! - -* [`2afe8bf`](https://github.com/npm/npm/commit/2afe8bf415a159baa181a8102f72c96e1d189bc9) - [#12415](https://github.com/npm/npm/pull/12415) - Clarify that the `--cert` and `--key` options are actual certs and keys, not - paths to files containing them. - ([@rvedotrc](https://github.com/rvedotrc)) -* [`3522560`](https://github.com/npm/npm/commit/3522560b0a4bb6c9717a34f9728f156fd9760cad) - [#12107](https://github.com/npm/npm/pull/12107) - Document `npm login` as an alias to `npm adduser`. People are still surprised - by this so often. - ([@gnerkus](https://github.com/gnerkus)) - -### v2.15.3 (2016-03-31): - -Hiiiiiii!~👋 - -We're really happy to be getting more and more community contributions! Keep it -up! We really appreciate folks trying to help us, and we'll do our best to help -point you in the right direction. Even things like documentation are a huge -help. And remember -- you get socks for it, too!🎁 - -This week is as quiet as usual, aside from fixing a regression to `npm -deprecate` you might want to pay attention to! Other than that, just docs and -deps, as any good LTS release train should be. 🙆 - -#### FIXME - -* [`6e0b66e`](https://github.com/npm/npm/commit/6e0b66e282aa27d1b5371e2babaa859924121730) - [#11884](https://github.com/npm/npm/pull/11884) - Include `node_modules` in the list of files and directories that npm won't - include in packages ordinarily. (Modules listed in `bundledDependencies` and - things that those modules rely on, ARE included of course.) - ([@Jameskmonger](https://github.com/Jameskmonger)) -* [`9896290`](https://github.com/npm/npm/commit/98962909b160364030705575202ad133971033c1) - [#12079](https://github.com/npm/npm/pull/12079) - Back in `npm@2.13.1` we included [a patch that made it so `npm install pkg` - was basically `npm install pkg@latest` instead of - `pkg@*`](https://github.com/npm/npm/pull/9170) This is probably what most - users expected, but it also ended up [breaking `npm - deprecate`](https://github.com/npm/npm/pull/9170) when no version was provided - for a package. In that case, we were using `*` to mean "deprecate all - versions" and relying on the `pkg` -> `pkg@*` conversion. This patch fixes - `npm deprecate pkg` to work as it used to by special casing that particular - command's behavior. - ([@polm](https://github.com/polm)) -* [`6c1628f`](https://github.com/npm/npm/commit/6c1628f62b657db6c116be13849d00933a3388cd) - [#12146](https://github.com/npm/npm/pull/12146) - Adds `make doc-clean` to `prepublish` script, to clear out previously built - docs before publishing a new npm version. - ([@watilde](https://github.com/watilde)) -* [`6d3017e`](https://github.com/npm/npm/commit/6d3017e6eed8a771b395d10130ac1f498e2d3211) - [#12146](https://github.com/npm/npm/pull/12146) - Adds `doc-clean` phony target to `make publish`. - ([@watilde](https://github.com/watilde)) - -#### DOCS - -* [`d43921c`](https://github.com/npm/npm/commit/d43921c546617cdb94bbee444d7d67ef55f38dc5) - [#12147](https://github.com/npm/npm/pull/12147) - Document that the current behavior of `engines` is just to warn if the node - platform is incompatible. - ([@reconbot](https://github.com/reconbot)) -* [`3cfe99e`](https://github.com/npm/npm/commit/3cfe99e3a757c5d8cbb1c2789410e9802563abac) - [#12093](https://github.com/npm/npm/pull/12093) - Update `bugs` url in `package.json` to use the `https` URL for Github. - ([@watilde](https://github.com/watilde)) -* [`ecf865f`](https://github.com/npm/npm/commit/ecf865f4eed1419c75442e0d52bc34ba1647de15) - [#12075](https://github.com/npm/npm/pull/12075) - Add the `--ignore-scripts` flag to the `npm install` docs. - ([@paulirish](https://github.com/paulirish)) -* [`f0e6db3`](https://github.com/npm/npm/commit/f0e6db32827d88680ef2320e60c0863754a4fbc5) - [#12063](https://github.com/npm/npm/pull/12063) - Various minor fixes to the html docs homepage. - ([@watilde](https://github.com/watilde)) - -#### DEPS - -* [`e2660de`](https://github.com/npm/npm/commit/e2660de1c08ed68a1c6fc4ee75d10376595979be) - `npmlog@2.0.3` - ([@iarna](https://github.com/iarna)) - -### v2.15.2 (2016-03-24): - -It's always nice to see new contributors. 💚 - -This week sees another small release, but we're still chugging along on our -[Windows efforts](https://github.com/npm/npm/pull/11444). - -There's also some small process changes to our LTS process relatively recently -that you might wanna know about! 💁 - -For one, the `2.x` branch was removed in favor of just `lts`. If you're making -PRs exclusively against npm's LTS, please use that name from now on. `2.x` was -deleted. - -Also, [@othiym23](https://github.com/othiym23) put some time into [writing down -our LTS process and policy](https://github.com/npm/npm/wiki/LTS). Check it out -and ping us if you have questions or comments about it! - -In general, we're trying to make sure all our policy and such for our -contributors is written down, and we hope it makes it easier in general for -y'all. Forrest is also working on a shiny new Contributor's Guide right now, but -we'll link to that in the (near?) future, when it's ready to roll out. - -#### TESTS - -* [`1d0e468`](https://github.com/npm/npm/commit/1d0e468c06c7b8e2b95b7fe874a3399a16d9db74) - [#11931](https://github.com/npm/npm/pull/11931) - Removes a bunch of old, disabled tests that have just been sitting around, - doing nothing. - ([@othiym23](https://github.com/othiym23)) -* [`7ae8aa1`](https://github.com/npm/npm/commit/7ae8aa1d9dc47761024f6756114205db3fb2c80b) - [#11987](https://github.com/npm/npm/pull/11987) - There was a failure in the `outdated-symlink` test caused by using the default - registry instead of the mock registry tests. - ([@yodeyer](https://github.com/yodeyer)) - -#### DOCS - -* [`b2649fb`](https://github.com/npm/npm/commit/b2649fb360f239aadef1ab51a580cbf4fdf29722) - [#12006](https://github.com/npm/npm/pull/12006) - Access was Team and Team was Access, but someone from the community rolled - around and corrected it for us. Thanks a bunch! - ([@yaelz](https://github.com/yaelz)) - -### v2.15.1 (2016-03-17): - -#### SECURITY ADVISORY: BEARER TOKEN DISCLOSURE - -This release includes [the fix for a -vulnerability](https://github.com/npm/npm/commit/fea8cc92cee02c720b58f95f14d315507ccad401) -that could cause the unintentional leakage of bearer tokens. - -Here are details on this vulnerability and how it affects you. - -##### DETAILS - -Since 2014, npm’s registry has used HTTP bearer tokens to authenticate requests -from the npm’s command-line interface. A design flaw meant that the CLI was -sending these bearer tokens with _every_ request made by logged-in users, -regardless of the destination of their request. (The bearers only should have -been included for requests made against a registry or registries used for the -current install.) - -An attacker could exploit this flaw by setting up an HTTP server that could -collect authentication information, then use this authentication information to -impersonate the users whose tokens they collected. This impersonation would -allow them to do anything the compromised users could do, including publishing -new versions of packages. - -With the fixes we’ve released, the CLI will only send bearer tokens with -requests made against a registry. - -##### THINK YOU'RE AT RISK? REGENERATE YOUR TOKENS - -If you believe that your bearer token may have been leaked, [invalidate your -current npm bearer tokens](https://www.npmjs.com/settings/tokens) and rerun -`npm login` to generate new tokens. Keep in mind that this may cause continuous -integration builds in services like Travis to break, in which case you’ll need -to update the tokens in your CI server’s configuration. - -##### WILL THIS BREAK MY CURRENT SETUP? - -Maybe. - -npm’s CLI team believes that the fix won’t break any existing registry setups. -Due to the large number of registry software suites out in the wild, though, -it’s possible our change will be breaking in some cases. - -If so, please [file an issue](https://github.com/npm/npm/issues/new) describing -the software you’re using and how it broke. Our team will work with you to -mitigate the breakage. - -##### CREDIT & THANKS - -Thanks to Mitar, Will White & the team at Mapbox, Max Motovilov, and James -Taylor for reporting this vulnerability to npm. - -### BACK TO YOUR REGULARLY SCHEDULED PROGRAMMING - -Aside from that, it's another one of those releases again! Docs and tests, it -turns out, have a pretty easy time getting into LTS releases, and boring is -exactly how LTS should be. 💁 - -#### DOCS - -* [`981c89c`](https://github.com/npm/npm/commit/981c89c8e398ca22ab6bf466123b25728ef6f543) - [#11820](https://github.com/npm/npm/pull/11820) - The basic explanation for how `npm link` works was a bit confusing, and - somewhat incorrect. It should be clearer now. - ([@rhgb](https://github.com/rhgb)) -* [`35b2b45`](https://github.com/npm/npm/commit/35b2b45f181dcbfb297f53b577dc1f26efcf3aba) - [#11787](https://github.com/npm/npm/pull/11787) - The `verison` alias for `npm version` no longer shows up in the command list - when you do `npm -h`. - ([@doug-wade](https://github.com/doug-wade)) -* [`1c9d00f`](https://github.com/npm/npm/commit/1c9d00f788298a81a8a7293d7dcf430f01bdd7fd) - [#11786](https://github.com/npm/npm/pull/11786) - Add a comment to the `npm-scope.md` docs about `npm@>=2` being required in - order to use scoped packaged. - ([@doug-wade](https://github.com/doug-wade)) -* [`7d64fb1`](https://github.com/npm/npm/commit/7d64fb1452d360aa736f31c85d6776ce570b2365) - [#11762](https://github.com/npm/npm/pull/11762) - Roll back patch that previously advised people to use `--depth Infinity` - instead of `--depth 9999`. Just keep using `--depth 9999`. - ([@GriffinSchneider](https://github.com/GriffinSchneider)) - -#### TESTS - -* [`98a9ee4`](https://github.com/npm/npm/commit/98a9ee4773f83994b8eb63c0ff75a9283408ba1a) - [#11912](https://github.com/npm/npm/pull/11912) - Did you know npm can install itself? `npm install -g npm` is the way to - upgrade! Turns out that one of the tests that verified this functionality got - rewritten as part of our recent push for better tests, and in the process - omitted a detail about *how* the test ran. We're testing that corner case - again, now, by moving the install folder to `/tmp`, where the original legacy - test ran. - ([@iarna](https://github.com/iarna)) - -### v2.15.0 (2016-03-10): - -#### WHY IS THIS SEMVER-MINOR I THOUGHT THIS WAS LTS - -A brief note about LTS this week! - -npm, as you may know if you're using this `2.x` branch, has an LTS process for -releases. We also try and play nice with [Node.js' own LTS release -process](https://github.com/nodejs/LTS#lts-plan). That means we generally try to -avoid things like minor version bumps on our `2.x` branch (which is also tagged -`lts` in the `dist-tag`s). - -That said, we had a minor-bump update recently for `npm@3.8.0` which added a -`maxsockets` option to allow users to configure the number of concurrent sockets -that npm would keep open at a time -- a setting that has the potential to help a -bunch for people with fussy routers or internet connections that aren't very -happy with Node.js applications' usual concurrency storm. This change was done -to `npm-registry-client`, which we don't have a parallel LTS-tracking branch -for. - -After talking it over, we ended up deciding that this was a reasonable enough -addition to LTS, even though it's *technically* a `semver-minor` bump, taking -into account both its potential for bugfixing (specially on `2.x`!) and the -general hassle it would be to maintain another branch for `npm-registry-client`. - - -* [`6dd61e7`](https://github.com/npm/npm/commit/6dd61e781c145480dc255a3e6a748729868443fd) - Expose `maxsockets` config setting from new `npm-registry-client`. - ([@misterbyrne](https://github.com/misterbyrne)) -* [`8a021c3`](https://github.com/npm/npm/commit/8a021c35184e665bd1f3f70ae2f478af812ab614) - `npm-registry-client@7.1.0`: - Adds support for configuring the max number of concurrent sockets, defaulting - to `50`. - ([@iarna](https://github.com/iarna)) - -#### DOC PATCH IS HERE TOO - -* [`0ae9f74`](https://github.com/npm/npm/commit/0ae9f740001a1bdf5920bc464cf9e284d5d139f0) - [#11748](https://github.com/npm/npm/pull/11748) - Add command aliases as a separate section in documentation for npm - subcommands. - ([@watilde](https://github.com/watilde)) - -#### DEP UPDATES - -* [`bfc3888`](https://github.com/npm/npm/commit/bfc38887f832f701c16b7ee410c4e0220a90399f) - `strip-ansi@3.0.1` - ([@jbnicolai](https://github.com/jbnicolai)) -* [`d5f4d51`](https://github.com/npm/npm/commit/d5f4d51a1b7ea78d7431c7ed4fed30200b2622f8) - `node-gyp@3.3.1`: Fixes Android generator - ([@bnoordhuis](https://github.com/bnoordhuis)) -* [`4119df8`](https://github.com/npm/npm/commit/4119df8aecd2ae57b0492ad8c9a480d900833008) - `glob@7.0.3`: Some path-related fixes for Windows. - ([@isaacs](https://github.com/isaacs)) - -### v2.14.22 (2016-03-03): - -This week is all documentation improvements. In case you hadn't noticed, we -*love* doc patches. We love them so much, we give socks away if you submit -documentation PRs! - -These folks are all getting socks if they ask for them. The socks are -super-sweet. Do you have yours yet? 👣 - -* [`3f3c7d0`](https://github.com/npm/npm/commit/3f3c7d080f052a5db91ff6091f8b1b13f26b53d6) - [#11441](https://github.com/npm/npm/pull/11441) - Add a link to the [Contribution - Guidelines](https://github.com/npm/npm/wiki/Contributing-Guidelines) to the - main npm docs. - ([@watilde](https://github.com/watilde)) -* [`9f87bb1`](https://github.com/npm/npm/commit/9f87bb1934acb33b678c17b7827165b17c071a82) - [#11441](https://github.com/npm/npm/pull/11441) - Remove Google Group email from npm docs about contributing. - ([@watilde](https://github.com/watilde)) -* [`93eaab3`](https://github.com/npm/npm/commit/93eaab3ee5ad16c7d90d1a4b38a95403fcf3f0f6) - [#11474](https://github.com/npm/npm/pull/11474) - Fix an invalid JSON error overlooked in - [#11196](https://github.com/npm/npm/pull/11196). - ([@robludwig](https://github.com/robludwig)) -* [`a407ca2`](https://github.com/npm/npm/commit/a407ca2bcf6a05117e55cf2ab69376e09094995e) - [#11483](https://github.com/npm/npm/pull/11483) - Add more details and an example to the documentation for bundledDependencies. - ([@gnerkus](https://github.com/gnerkus)) -* [`2c851a2`](https://github.com/npm/npm/commit/2c851a231afd874baa77c42ea5ba539c454ac79c) - [#11490](https://github.com/npm/npm/pull/11490) - Document the `--registry` flag for `npm search`. - ([@plumlee](https://github.com/plumlee)) - -### v2.14.21 (2016-02-25): - -Good news, everyone! There's a new LTS release with a few shinies here and there! - -#### USE THIS ONE INSTEAD - -We had some cases where the versions of npm and node used in some scripting situations were different than the ideal, or what folks actually expected. These should be particularly helpful to our Windows friends! <3 - -* [`02813c5`](https://github.com/npm/npm/commit/02813c55782a9def23f7f1e614edc38c6c88aed3) [#9253](https://github.com/npm/npm/issues/9253) Fix a bug where, when running lifecycle scripts, if the Node.js binary you ran `npm` with wasn't in your `PATH`, `npm` wouldn't use it to run your scripts. ([@segrey](https://github.com/segrey) and [@narqo](https://github.com/narqo)) -* [`a985dd5`](https://github.com/npm/npm/commit/a985dd50e06ee51ba5544577f977c7440c227ba2) [#11526](https://github.com/npm/npm/pull/11526) Prefer locally installed npm in Git Bash -- previous behavior was to use the global one. This was done previously for other shells, but not for Git Bash. ([@destroyerofbuilds](https://github.com/destroyerofbuilds)) - -#### SOCKS FOR THE SOCK GOD - -* [`f961092`](https://github.com/npm/npm/commit/f9610920079d8b88ae464b30007a92c594bd85a8) - [#11636.](https://github.com/npm/npm/issues/11636.) - Document the `--save-bundle` option for `npm install`. - ([@datyayu](https://github.com/datyayu)) -* [`7c908b6`](https://github.com/npm/npm/commit/7c908b618f7123f0a3b860c71eb779e33df35964) - [#11644](https://github.com/npm/npm/pull/11644) - Add documentation for the `test` directory for packages. - ([@lewiscowper](https://github.com/lewiscowper)) - -#### INTERNAL TEST IMPROVEMENTS - -The npm CLI team's time recently has been sunk into npm's many years of tech debt. Specifically, we've been working on improving the test suite. This isn't user visible, but in future should mean a more stable, easier to contribute to npm. Ordinarily we don't report these kinds of changes in the change log, but I thought I might share this week as this chunk is bigger than usual. - -These patches were previously released for `npm@3`, and then ported back to `npm@2` LTS. - -* [`437c537`](https://github.com/npm/npm/commit/437c537e2be5923c6d2c2753154564ba13db8fd9) [#11613](https://github.com/npm/npm/pull/11613) Fix up one of the tests after rebasing the legacy test rewrite to `npm@2`. ([@zkat](https://github.com/zkat)) -* [`55abd0c`](https://github.com/npm/npm/commit/55abd0cc20e87a144d33ce2d459f65e7506da576) [#11613](https://github.com/npm/npm/pull/11613) Test that the `package.json` `files` section and `.npmignore` do what they're supposed to. ([@zkat](https://github.com/zkat)) -* [`a2b99b6`](https://github.com/npm/npm/commit/a2b99b6273ada14b2121ebc0acb7933e630edd9d) [#11613](https://github.com/npm/npm/pull/11613) Test that npm's distribution binary is complete and can be installed and used. ([@iarna](https://github.com/iarna)) -* [`8a8c36c`](https://github.com/npm/npm/commit/8a8c36ce51166006022e5c5d4f8655bbc458d651) [#11613](https://github.com/npm/npm/pull/11613) Test that environment variables are properly passed into scripts. - ([@iarna](https://github.com/zkat)) -* [`a95b550`](https://github.com/npm/npm/commit/a95b5507616bd51e83d7eab5f2337b1aff6480b1) [#11613](https://github.com/npm/npm/pull/11613) Test that we don't leak auth info into the environment. ([@iarna](https://github.com/iarna)) -* [`a1c1c52`](https://github.com/npm/npm/commit/a1c1c52efeab24f6dba154d054f85d9efc833486) [#11613](https://github.com/npm/npm/pull/11613) Remove all the relatively cryptic legacy tests and creates new tap tests that check the same functionality. The *legacy* tests were tests that were originally a shell script that was ported to javascript early in `npm`'s history. ([@iarna](https:\\github.com/iarna) and [@zkat](https://github.com/zkat)) -* [`9d89581`](https://github.com/npm/npm/commit/9d895811d3ee70c2e672f3d8fa06574495b5b488) [#11613](https://github.com/npm/npm/pull/11613) `tacks@1.0.9`: Add a package that provides a tool to generate fixtures from folders and, relatedly, a module that an create and tear down filesystem fixtures easily. ([@iarna](https://github.com/iarna)) - -### v2.14.20 (2016-02-18): - -Hope y'all are having a nice week! As usual, it's a fairly limited release. The -most notable thing is some dependency updates that might help the Node.js CI -setup for Windows run a little better, even if we have some work to do on that -path length things, still. - -#### WHITTLING AWAY AT PATH LENGTHS - -So for all of you who don't know -- Node.js does, in fact, support long Windows -paths. Unfortunately, depending on the tool and the Windows version, a lot of -external tooling does not. This means, for example, that some (all?) versions of -Windows Explorer *can literally never delete npm from their system entirely -because of deeply-nested npm dependencies*. Which is pretty gnarly. - -Incidentally, if you run into that in particularly, you can use -[rimraf](npm.im/rimraf) to remove such files 💁. - -The latest victim of this issue was the Node.js CI setup for testing on Windows, -which uses some tooling or another that croaks on the usual path length limit -for that OS: 255 characters. - -This issue, of course, is largely not a problem as of `npm@3`, with its flat -trees, but it still occasionally and viciously bites LTS. - -We've taken another baby step towards alleviating this in this release by -updating a couple of dependencies that were preventing `npmlog` from deduping, -and then doing a dedupe on that and `gauge`. Hopefully it helps. - -* [`4199551`](https://github.com/npm/npm/commit/41995517e617674710748ab6d262670c96124393) - [#11528](https://github.com/npm/npm/pull/11528) - `npm-install-checks@1.0.7`: Just updates the version of npmlog so we can - dedupe it better. - ([@zkat](https://github.com/zkat)) -* [`14d72c7`](https://github.com/npm/npm/commit/14d72c756b89e2d167eb52c1849263dbddcb9f35) - [#11552](https://github.com/npm/npm/pull/11552) - [#11528](https://github.com/npm/npm/pull/11528) - `node-gyp@3.3.0`: AIX support, new `gyp`, update `npmlog` (for the dedupe), - adds `--cafile` command line option, and allows configuration of Node.js and - io.js mirrors. - ([@rvagg](https://github.com/rvagg)) -* [`0453cb9`](https://github.com/npm/npm/commit/0453cb94b33520eb723b7072cd2654b1d0142533) - [#11528](https://github.com/npm/npm/pull/11528) - Do a `dedupe` on `gauge` to flatten our dependencies a bit more. - ([@zkat](https://github.com/zkat)) - -#### OTHER DEP STUFF - -* [`686c0b3`](https://github.com/npm/npm/commit/686c0b37ec3a7b65f9b3849e1099805e5221c408) - `rimraf@2.5.2`: Just updates to glob@7. - ([@isaacs](https://github.com/isaacs)) - -#### @wyze, DOCUMENTATION HERO OF THE PEOPLE, GETS THEIR OWN HEADER - -* [`7232948`](https://github.com/npm/npm/commit/72329484c775376cb40d5b348f453eaaf2f0b821) - [#11416](https://github.com/npm/npm/pull/11416) - Logout docs were using a section copy-pasted from the adduser docs. - ([@wyze](https://github.com/wyze)) -* [`922b33a`](https://github.com/npm/npm/commit/922b33aba4362e1e90f42e9348f061a1cc73eafb) - [#11414](https://github.com/npm/npm/pull/11414) - Add colon for consistency. - ([@wyze](https://github.com/wyze)) - -### v2.14.19 (2016-02-11): - -Really tiny micro-release this week! The main thing to note is a dependency -update that means we no longer have `graceful-fs@3` in our dependency tree. This -has some implications for being able to run on future Node.js releases, so -better to get this out the door. 😁 - -#### DEPS - -* [`a556e0f`](https://github.com/npm/npm/commit/a556e0f9dcb5d7b44224ba9c16c9d0dc6c8d2532) - `cmd-shim@2.0.2`: Final straggler using `graceful-fs@<4`. - ([@ForbesLindesay](https://github.com/ForbesLindesay)) - -#### DOCS - -* [`69a2d59`](https://github.com/npm/npm/commit/69a2d599bf0cba674ee268483e9bd5c14333b89f) - [#11391](https://github.com/npm/npm/pull/11391) - Fixed versions of `shrinkwrap.json` in examples in documentation for `npm - shrinkwrap`, which did not quite match up. - ([@xcatliu](https://github.com/xcatliu)) - -### v2.14.18 (2016-02-04): - -Clearly our docs are perfect after all those wonderful PRs, 'cause this week's -gonna be all about dependency updates. Note: There is a small security-related -fix included here! - -#### SECURITY-RELATED DEPENDENCY UPDATE - -* [`5c095ef`](https://github.com/npm/npm/commit/5c095eff8dc006980d4d083f2007e4dacff23be3) - [#11341](https://github.com/npm/npm/pull/11341) - `request@2.69.0`: Includes security-related dependency updates involving - `hawk` and `is-my-json-valid` - ([@remy](https://github.com/remy) and [@simov](https://github.com/simov)) - -#### OTHER DEPENDENCY UPDATES - -* [`f9c2668`](https://github.com/npm/npm/commit/f9c2668ca3e6e2602d91250ce61280e5e12d0a00) - `which@1.2.4` - ([@isaacs](https://github.com/isaacs)) -* [`2907c43`](https://github.com/npm/npm/commit/2907c43ad4ef87e5f730c2576f680d6837fcbad0) - `spdx-license-ids@1.2.0` - ([@shinnn](https://github.com/shinnn)) -* [`7734069`](https://github.com/npm/npm/commit/773406960bf7f4a87b2ecb6ebf593c62d0e9f95d) - `rimraf@2.5.1` - ([@isaacs](https://github.com/isaacs)) -* [`f4b39a7`](https://github.com/npm/npm/commit/f4b39a7dd5e1335d92aa22c46d99abb33f271b8b) - `retry@0.9.0` - ([@tim-kos](https://github.com/tim-kos)) -* [`ded1e7a`](https://github.com/npm/npm/commit/ded1e7a1c9c7bec29bb7c30a8f85546670e75b56) - Nest `retry@0.8.0` inside `npm-registry-client` to prevent invalid - dependency issue until the latter gets a dependency update. - ([@zkat](https://github.com/zkat)) -* [`ab9f867`](https://github.com/npm/npm/commit/ab9f8679f9687f91ad03adaab6211a897aeebbae) - `read-package-json@2.0.3` - ([@iarna](https://github.com/iarna)) -* [`b638c41`](https://github.com/npm/npm/commit/b638c41607bb936b9eaaceba2aeeda1d34e3a9b2) - `npmlog@2.0.2` - ([@iarna](https://github.com/iarna)) -* [`49f34af`](https://github.com/npm/npm/commit/49f34af463a674359269025d8438feb6a7c69960) - `init-package-json@1.9.3` - ([@iarna](https://github.com/iarna)) -* [`2305dab`](https://github.com/npm/npm/commit/2305dab4e7bff09bb7686cec653cf1e663dbf15d) - `graceful-fs@4.1.3`: Fixed `.close()` not being patched. - ([@isaacs](https://github.com/isaacs)) -* [`18496d9`](https://github.com/npm/npm/commit/18496d9a0fff94e3652655998e8333056aa52b15) - `fs-write-stream-atomic@1.0.8` - ([@iarna](https://github.com/iarna)) -* [`6637bc7`](https://github.com/npm/npm/commit/6637bc7a0e194d82554cd7c91e1794018fef5943) - `config-chain@1.1.10` - ([@dominictarr](https://github.com/dominictarr)) -* [`4222bad`](https://github.com/npm/npm/commit/4222badffed9e9edacea6a8a96a99a164d376158) - `columnify@1.5.4` - ([@timoxley](https://github.com/timoxley)) -* [`df9016f`](https://github.com/npm/npm/commit/df9016f327a2a9ce492ebc75b882b03069438e13) - `ansi@0.3.1`: Added a license file. - ([@TooTallNate](https://github.com/TooTallNate)) - -### v2.14.17 (2016-01-28): - -Another week, another small LTS release! - -#### BETTER ERROR REPORTING YAY - -So as it turns out, when stuff goes wrong, it's actually nice to give people a -better clue rather than just say "oh well 😏". - -* [`5b8ccb9`](https://github.com/npm/npm/commit/5b8ccb91cf11b4edb463609cd4ed1dee84ed4db0) - [#11289](https://github.com/npm/npm/pull/11289) - There is an obscure feature that lets you monkey-patch npm when it starts up. - If the module being required with this feature failed, it would previous just - make npm error out– this reduces that to a warning. - ([@evanlucas](https://github.com/evanlucas)) -* [`556e42a`](https://github.com/npm/npm/commit/556e42ac6bab078722ddc1dc6cce4428d001133b) - [#11300](https://github.com/npm/npm/pull/11300) - Report symlinked packages as 'linked' in the output for `npm outdated`. - ([@halhenke](https://github.com/halhenke)) -* [`3842317`](https://github.com/npm/npm/commit/3842317583e0ea2eca78e39aa03f5bc06ba21de7) - [#11290](https://github.com/npm/npm/pull/11290) - Suppress warnings about pre-release node versions. This should get node's CI - passing on non-Windows platforms without needing to modify the node version to - get rid of the pre-release suffix. - ([@iarna](https://github.com/iarna)) - -#### EVERYONE WANTS THOSE NPM SOCKS, GEEZE - -Did you know that you can get npm socks for contributing to our docs? I bet -these people do, and now so do you! - -* [`dcde451`](https://github.com/npm/npm/commit/dcde451cb85a6ca08acc6ef45782c652f1d8fc89) - [#11232](https://github.com/npm/npm/pull/11232) - Update automatically included/excluded packages in `package.json`. - ([@jscissr](https://github.com/jscissr)) -* [`e3f8d5b`](https://github.com/npm/npm/commit/e3f8d5be5ac5ec1d72db42f7abf50cc4a8c5935c) - [#11273](https://github.com/npm/npm/pull/11273) - Add an example for `npm view <pkg> versions`. - ([@vedatmahir](https://github.com/vedatmahir)) -* [`6a06ef2`](https://github.com/npm/npm/commit/6a06ef2252748089f0013de951f2d06160b90306) - [#11272](https://github.com/npm/npm/pull/11272) - Fix a typo in `npm-update.md`. - ([@jonathanp](https://github.com/jonathanp)) -* [`2515ff1`](https://github.com/npm/npm/commit/2515ff1de28f0b261fb25c79a66bd762a65961c4) - [#11215](https://github.com/npm/npm/pull/11215) - Correct small thinko in docs for SPDX expressions. - ([@kemitchell](https://github.com/kemitchell)) -* [`70f897b`](https://github.com/npm/npm/commit/70f897b03da9a5d5d4fd34614e9ee40e6f9e9653) - [#11196](https://github.com/npm/npm/pull/11196) - Make JSON snippets valid JSON in `npm update` docs. - ([@s100](https://github.com/s100)) - -### v2.14.16 (2016-01-21): - -Good to see you all again! It's been a while since we had an LTS release, and -the team continues to work hard to both get the issue tracker under control, and -get our test suite to be awesome and reliable. - -This is also the first LTS release of this year. - -We're gonna have an interesting time -- most of our focus this year will be -around stability and maintainability of the CLI, so you might actually end up -seeing a number of updates even over here, just for the sake of making sure -we're stable, that bugs get fixed, and tests have proper coverage. - -What better way to start this effort, then, than getting Travis tests green, fix -a few things here and there, and tweak a bunch of documentation? 😁 - -#### FIX ALL THE BUGS AND TWEAK ALL THE THINGS - -* [`24b13fb`](https://github.com/npm/npm/commit/24b13fbc57d34db1d5b0a37bcca122c00deba978) - [#11158](https://github.com/npm/npm/pull/11158) - Fix custom node-gyp env var quoting on Windows. - ([@orangemocha](https://github.com/orangemocha)) -* [`e2503f2`](https://github.com/npm/npm/commit/e2503f2be40157b05a9c500ec3b5d16090ffee50) - [#11142](https://github.com/npm/npm/pull/11142) - Fix race condition with `correctMkdir` in the cache directory. - ([@Jimbly](https://github.com/Jimbly)) - -* [`5c0e4c4`](https://github.com/npm/npm/commit/5c0e4c45a29d774ab729e86044377d4e5e424252) - [#10940](https://github.com/npm/npm/pull/10940) - Ignore failures replacing `package.json`. writeFileAtomic is not atomic in - Windows, it fails if the file is being accessed concurrently. - ([@orangemocha](https://github.com/orangemocha)) -* [`2c44d8d`](https://github.com/npm/npm/commit/2c44d8dc8c267d5e054d0175ce2f4750f0986463) - [#10903](https://github.com/npm/npm/pull/10903) - Add tests for `npm adduser --scope`. - ([@ekmartin](https://github.com/ekmartin)) -* [`4cb25d0`](https://github.com/npm/npm/commit/4cb25d0fed5c7792dfd1aec891380ecc1f8a5761) - [#10903](https://github.com/npm/npm/pull/10903) - Add a message informing users when they have been successfully logged in. - ([@ekmartin](https://github.com/ekmartin)) -* [`fe3ec6d`](https://github.com/npm/npm/commit/fe3ec6d6658262054c0c19c55373c21e84ab9f17) - [#10628](https://github.com/npm/npm/pull/10628) - Tell users how to open an issue with a package that has errored. - ([@trodrigues](https://github.com/trodrigues)) - -#### DOCS DOCS DOCS - -We got a TON of lovely documentation patches, too! Thanks all for submitting! - -* [`22482a1`](https://github.com/npm/npm/commit/22482a1f22079d72c3f8ca55c2f0c153bdd024c0) - [#11188](https://github.com/npm/npm/pull/11188) - Briefly explain what's included when you publish. - ([@beaugunderson](https://github.com/beaugunderson)) -* [`fa47724`](https://github.com/npm/npm/commit/fa4772438df0c66a19309dd1c1a3ce43cbee5461) - [#11150](https://github.com/npm/npm/pull/11150) - Advise use of `--depth Infinity` instead of `--depth 9999` in `npm update`. - ([@halhenke](https://github.com/halhenke)) -* [`248ddfe`](https://github.com/npm/npm/commit/248ddfe8f7ddd3318e14bf61de41cab4a638c8a3) - [#11130](https://github.com/npm/npm/pull/11130) - Nuke "using npm programmatically" section from README. The programmatic npm - API is unsupported, and is not guaranteed not to break in non-major versions. - Removing this section so newcomers aren't encouraged to discover or use it. - ([@ljharb](https://github.com/ljharb)) -* [`ae9c452`](https://github.com/npm/npm/commit/ae9c4521222d60ab4a69c19fee5e361c62f41fae) - [#11128](https://github.com/npm/npm/pull/11128) - Add link to local paths section indocs for `package.json`. - ([@orangejulius](https://github.com/orangejulius)) -* [`663a8c6`](https://github.com/npm/npm/commit/663a8c6b4b1647f9b86c15ef32e30023edc8c060) - [#11044](https://github.com/npm/npm/pull/11044) - Update default value documentation for the color option in npm's config. - ([@scottaddie](https://github.com/scottaddie)) -* [`5c1dda0`](https://github.com/npm/npm/commit/5c1dda0d3a18b2954872dba33fbc696ff0700ffe) - [#11037](https://github.com/npm/npm/pull/11037) - Correct the name property max length constraint verbiage. - ([@scottaddie](https://github.com/scottaddie)) -* [`8288365`](https://github.com/npm/npm/commit/8288365d08e97fa3a5b0d31703c015a8be49e07f) - [#10990](https://github.com/npm/npm/pull/10990) - Update folder docs to reflect that process.installPrefix was removed as of - 0.8.x. - ([@jeffmcmahan](https://github.com/jeffmcmahan)) -* [`61d63fa`](https://github.com/npm/npm/commit/61d63fa22c4f09742180c2de460a4ffb6c32738e) - [#10790](https://github.com/npm/npm/pull/10790) - Clarify that `npm install foo` is the same as `npm install foo@latest` now. - ([@cvrebert](https://github.com/cvrebert)) -* [`442c920`](https://github.com/npm/npm/commit/442c9207f375354c91d36df8711ba2d33e1c97f3) - [#10789](https://github.com/npm/npm/pull/10789) - Link over to `npm-dist-tag(1)` in `npm install` docs when they talk about the - `pkg@<tag>` syntax. - ([@cvrebert](https://github.com/cvrebert)) -* [`dca7a5e`](https://github.com/npm/npm/commit/dca7a5e2be3bfa306a870a123707d35c732406c0) - [#10788](https://github.com/npm/npm/pull/10788) - Link to tag docs in docs for `npm publish --tag`. - ([@cvrebert](https://github.com/cvrebert)) -* [`a72904e`](https://github.com/npm/npm/commit/a72904e8d4ab1d43ae8150fbe3f6468b0cbb1efd) - [#10787](https://github.com/npm/npm/pull/10787) - Explain why the `latest` tag matters. - ([@cvrebert](https://github.com/cvrebert)) -* [`9d0697a`](https://github.com/npm/npm/commit/9d0697a534046df7efda32170014041bbc1f4e7d) - [#10785](https://github.com/npm/npm/pull/10785) - Replace some quite marks in `npm dist-tag` docs for the sake of consistency. - ([@cvrebert](https://github.com/cvrebert)) - -#### I REALLY LIKE GREEN. CAN YOU TELL? - -So Travis is all green now on `npm@2`, thanks to the removal of nock and a few -other test suite tweaks. This is a fantastic step towards making sure we can all -have confidence in our test suite! 🎉 - -* [`64995be`](https://github.com/npm/npm/commit/64995be6d874356b15c136f9867302d805dfe1e9) [`75ab216`](https://github.com/npm/npm/commit/75ab2164cf79e28ac7f7ebe714f3c5aee99c6626) [`a9f6fe9`](https://github.com/npm/npm/commit/a9f6fe9dc558f17c4a7b9eb83329ac080f7df4b7) [`649c193`](https://github.com/npm/npm/commit/649c193adadf714c2819837f9372a29d724a5ec0) [`94cb05e`](https://github.com/npm/npm/commit/94cb05eaa9e5ad6675cf15c4ac0a44fbdde05900) [`6541690`](https://github.com/npm/npm/commit/65416907008061ac5a5f66b1630a57776803b526) [`255be6f`](https://github.com/npm/npm/commit/255be6f5bca9e3d216f3a5cbdf6714c6c9fcf132) [`9e84fa4`](https://github.com/npm/npm/commit/9e84fa43c49d04cf86ca1678e2a61412f5559cb9) [`8a587b0`](https://github.com/npm/npm/commit/8a587b0c1696ae7302891fa6355fc3e8670e00d3) [`bf812a5`](https://github.com/npm/npm/commit/bf812a54e497a573493346399798aa0b9373ac24) - [#10903](https://github.com/npm/npm/pull/10903) - Get rid of nock from tests, and get Travis green. - ([@zkat](https://github.com/zkat) and [@iarna](https://github.com/iarna)) -* [`70a5310`](https://github.com/npm/npm/commit/70a5310712c6666e753ca8f3bfff4a780ec6292d) - `npm-registry-couchapp@2.6.12`: - Better 0.8 compatibility, and ability to run in travis docker stuff. This - means the test suite should run a lot faster, too! - ([@iarna](https://github.com/iarna)) -* [`28fae39`](https://github.com/npm/npm/commit/28fae399212eda5554e6c0ffd8c9591144ab7b9d) - Get rid of sudo, for Travis! - ([@zkat](https://github.com/zkat)) - -### v2.14.15 (2015-12-10): - -Did you know that Bob Ross reached the rank of master sergeant in the US Air -Force before becoming perhaps the most soothing painter of all time? - -#### TWO HAPPY LITTLE BUG FIXES - -* [`f482664`](https://github.com/npm/npm/commit/f4826645dc6b5c0f05c5f9187efb28c1a293554f) - [#10505](https://github.com/npm/npm/issues/10505) `npm ls --json --depth=0` - now respects the depth parameter, when it is zero and when it is not zero. - ([@MarkReeder](https://github.com/MarkReeder)) -* [`529fa1f`](https://github.com/npm/npm/commit/529fa1ff2c6432a773af99a1c5209c0865f7a19c) - [#9099](https://github.com/npm/npm/issues/9099) I had always thought you - could run `npm version` from subdirectories in your project, which is great, - because now you can. I guess I was just ahead of my time. - ([@ekmartin](https://github.com/ekmartin)) - -#### NOW PAINT IN SOME NICE DOCS CHANGES - -* [`1fc7f2b`](https://github.com/npm/npm/commit/1fc7f2b523ea760e08adb9b861b28e3ba450e565) - [#10546](https://github.com/npm/npm/issues/10546) Goodbye, FAQ! You were - cheeky and fun until you weren't! Don't worry: npm still loves everyone, - especially you! ([@ashleygwilliams](https://github.com/ashleygwilliams)) -* [`7fe6950`](https://github.com/npm/npm/commit/7fe6950b44d241bb4d90857a44d89d750af1e2b3) - [#10570](https://github.com/npm/npm/issues/10570) Update documentation URLs - to be HTTPS everywhere sensible. No HTTP shall be spared! - ([@rsp](https://github.com/rsp)) -* [`96ebb90`](https://github.com/npm/npm/commit/96ebb902439e4f6f37f8beffb589769146fecf24) - [#10650](https://github.com/npm/npm/issues/10650) Correctly note that there - are two lifecycle scripts run by an install phase in an example, instead of - three. ([@eymengunay](https://github.com/eymengunay)) -* [`5196893`](https://github.com/npm/npm/commit/5196893a7496f68a514b83641ff6b72f14d664dd) - [#10687](https://github.com/npm/npm/issues/10687) `npm outdated`'s output can - be a little puzzling sometimes. I've attempted to make it clearer, with some - examples, of what's going on with "wanted" and "latest" in more cases. - ([@othiym23](https://github.com/othiym23)) -* [`8e6712d`](https://github.com/npm/npm/commit/8e6712d4ee128858cab36c77723e35bddbb977ba) - [#10700](https://github.com/npm/npm/issues/10700) Hey, do you remember when - `search.npmjs.org` was a thing? I think I do? The last time I used it was in - like 2012, and it's gone now, so remove it from the docs. - ([@gagern](https://github.com/gagern)) -* [`27d2612`](https://github.com/npm/npm/commit/27d2612b3f5aa88b12c943d04e162ce4c3a350ae) - `semver@5.1.0`: Include BNF for SemVer expression grammar (which is also now - included in `npm help semver`). ([@isaacs](https://github.com/isaacs)) - -#### LAND YOUR DEPENDENCY UPGRADES IN PAIRS SO EVERYONE HAS A FRIEND - -* [`fc6c3c5`](https://github.com/npm/npm/commit/fc6c3c53a31e9e11c2616fcd378202e5b80bf286) - `request@2.67.0` ([@simov](https://github.com/simov)) -* [`07013fd`](https://github.com/npm/npm/commit/07013fd0fd55a2eb31fb9334631ee5d0dd5c41bb) - [isaacs/rimraf#89](https://github.com/isaacs/rimraf/pull/89) `rimraf@2.4.4` - ([@zerok](https://github.com/zerok)) -* [`bc149be`](https://github.com/npm/npm/commit/bc149bef871f0f00639509898cece531af3aa8b3) - [isaacs/once#7](https://github.com/isaacs/once/pull/7) `once@1.3.3` - ([@floatdrop](https://github.com/floatdrop)) -* [`ac598d3`](https://github.com/npm/npm/commit/ac598d36e1ad207bc0d8a7eadfd84b26146aec1f) - `lru-cache@3.2.0` ([@isaacs](https://github.com/isaacs)) -* [`1b915ce`](https://github.com/npm/npm/commit/1b915ce1e0787ccb6d8aa235d002d66565f2175d) - `npm-registry-client@7.0.9` ([@othiym23](https://github.com/othiym23)) -* [`df7dd78`](https://github.com/npm/npm/commit/df7dd78b8fe3cc58202996fa6c994fc55419bfa5) - `tap@2.3.1` ([@isaacs](https://github.com/isaacs)) - -### v2.14.14 (2015-12-03): - -#### FIX URL IN LICENSE - -The license incorrectly identified the registry URL as `registry.npmjs.com` and -this has been corrected to `registry.npmjs.org`. - -* [`6051a69`](https://github.com/npm/npm/commit/6051a69b1adc80f5f200077067e831643f655bd4) - [#10685](https://github.com/npm/npm/pull/10685) - Fix npm public registry URL in notices. - ([@kemitchell](https://github.com/kemitchell)) - -#### NO MORE MD5 - -We updated modules that had been using MD5 for non-security purposes. While -this is perfectly safe, if you compile Node in FIPS-compliance mode it will -explode if you try to use MD5. We've replaced MD5 with Murmur, which conveys -our intent better and is faster to boot. - -* [`30b5994`](https://github.com/npm/npm/commit/30b599496a9762482e1cef945a378e3a534fd366) - [#10629](https://github.com/npm/npm/issues/10629) - `write-file-atomic@1.1.4` - ([@othiym23](https://github.com/othiym23)) -* [`68c63ff`](https://github.com/npm/npm/commit/68c63ff1279d3d5ea7b2c970ab5562a8e0536f27) - [#10629](https://github.com/npm/npm/issues/10629) - `fs-write-stream-atomic@1.0.5` - ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY UPDATES - -* [`e48e5a9`](https://github.com/npm/npm/commit/e48e5a90b4dcf76124b7e9ea3b295c1383e7f0c8) - [nodejs/node-gyp#831](https://github.com/nodejs/node-gyp/pull/831) - `node-gyp@3.2.1`: Improved \*BSD support. - ([@bnoordhuis](https://github.com/bnoordhuis)) - -### v2.14.13 (2015-11-25): - -#### THE npm CLI !== THE npm REGISTRY !== npm, INC. - -npm-the-CLI is licensed under the terms of the [Artistic License -2.0](https://github.com/npm/npm/blob/8d79c1a39dae908f27eaa37ff6b23515d505ef29/LICENSE), -which is a liberal open-source license that allows you to take this code and do -pretty much whatever you like with it (that is, of course, not legal language, -and if you're doing anything with npm that leaves you in doubt about your legal -rights, please seek the review of qualified counsel, which is to say, not -members of the CLI team, none of whom have passed the bar, to my knowledge). At -the same time the primary registry the CLI uses when looking up and downloading -packages is a commercial service run by npm, Inc., and it has its own [Terms of -Use](https://www.npmjs.com/policies/terms). - -Aside from clarifying the terms of use (and trying to make sure they're more -widely known), the only recent changes to npm's licenses have been making the -split between the CLI and registry clearer. You are still free to do whatever -you like with the CLI's source, and you are free to view, download, and publish -packages to and from `registry.npmjs.org`, but now the existing terms under -which you can do so are more clearly documented. Aside from the two commits -below, see also [the release notes for -`npm@2.14.11`](https://github.com/npm/npm/releases/tag/v2.14.11), which is where -the split between the CLI's code and the terms of use for the registry was -first made more clear. - -* [`1f3e936`](https://github.com/npm/npm/commit/1f3e936aab6840667948ef281e0c3621df365131) - [#10532](https://github.com/npm/npm/issues/10532) Clarify that - `registry.npmjs.org` is the default, but that you're free to use the npm CLI - with whatever registry you wish. ([@kemitchell](https://github.com/kemitchell)) -* [`6733539`](https://github.com/npm/npm/commit/6733539eeb9b32a5f2d1a6aa797987e2252fa760) - [#10532](https://github.com/npm/npm/issues/10532) Having semi-duplicate - release information in `README.md` was confusing and potentially inaccurate, - so remove it. ([@kemitchell](https://github.com/kemitchell)) - -#### EASE UP ON WINDOWS BASH USERS - -It turns out that a fair number of us use bash on Windows (through MINGW or -bundled with Git, plz – Cygwin is still a bridge too far, for both npm and -Node.js). [@jakub-g](https://github.com/jakub-g) did us all a favor and relaxed -the check for npm completion to support MINGW bash. Thanks, Jakub! - -* [`460cc09`](https://github.com/npm/npm/commit/460cc0950fd6a005c4e5c4f85af807814209b2bb) - [#10156](https://github.com/npm/npm/issues/10156) completion: enable on - Windows in git bash ([@jakub-g](https://github.com/jakub-g)) - -#### MAKE NODE-GYP A LITTLE BLUER - -* [`333e118`](https://github.com/npm/npm/commit/333e1181082842c21edc62f0ce515928424dff1f) - `node-gyp@3.2.0`: Support AIX, use `which` to find Python, updated to a newer - version of `gyp`, and more! ([@bnoordhuis](https://github.com/bnoordhuis)) - -#### WE LIKE SPDX AND ALL BUT IT'S NOT ACTUALLY A DIRECT DEP, SORRY - -* [`1f4b4bb`](https://github.com/npm/npm/commit/1f4b4bbdf8758281beecb7eaf75d05a6c4a77c15) - Removed `spdx` as a direct npm dependency, since we don't actually need it at - that level, and updated subdeps for `validate-npm-package-license` - ([@othiym23](https://github.com/othiym23)) - -#### A BOUNTEOUS THANKSGIVING CORNUCOPIA OF DOC TWEAKS - -These are great! Keep them coming! Sorry for letting them pile up so deep, -everybody. Also, a belated Thanksgiving to our Canadian friends, and a happy -Thanksgiving to all our friends in the USA. - -* [`6101f44`](https://github.com/npm/npm/commit/6101f44737645d9379c3396fae81bbc4d94e1f7e) - [#10250](https://github.com/npm/npm/issues/10250) Correct order of `org:team` - in `npm team` documentation. ([@louislarry](https://github.com/louislarry)) -* [`e8769f9`](https://github.com/npm/npm/commit/e8769f9807b91582c15ef130733e2e72b6c7bda4) - [#10371](https://github.com/npm/npm/issues/10371) Remove broken / duplicate - link to tag. ([@WickyNilliams](https://github.com/WickyNilliams)) -* [`1ae2dbe`](https://github.com/npm/npm/commit/1ae2dbe759feb80d8634569221ec6ee2c6d1d1ff) - [#10419](https://github.com/npm/npm/issues/10419) Remove references to - nonexistent `npm-rm(1)` documentation. ([@KenanY](https://github.com/KenanY)) -* [`777a271`](https://github.com/npm/npm/commit/777a271830a42d4ee62540a89f764a6e7d62de19) - [#10474](https://github.com/npm/npm/issues/10474) Clarify that install finds - dependencies in `package.json`. ([@sleekweasel](https://github.com/sleekweasel)) -* [`dcf4b5c`](https://github.com/npm/npm/commit/dcf4b5cbece1b0ef55ab7665d9acacc0b6b7cd6e) - [#10497](https://github.com/npm/npm/issues/10497) Clarify what a package is - slightly. ([@aredridel](https://github.com/aredridel)) -* [`447b3d6`](https://github.com/npm/npm/commit/447b3d669b2b6c483b8203754ac0a002c67bf015) - [#10539](https://github.com/npm/npm/issues/10539) Remove an extra, spuriously - capitalized letter. ([@alexlukin-softgrad](https://github.com/alexlukin-softgrad)) - -### v2.14.12 (2015-11-19): - -#### TEEN ORCS AT THE GATES - -This week heralds the general release of the primary npm registry's [new -support for private packages for -organizations](http://blog.npmjs.org/post/133542170540/private-packages-for-organizations). -For many potential users, it's the missing piece needed to make it easy for you -to move your organization's private work onto npm. And now it's here! The -functionality to support it has been in place in the CLI for a while now, -thanks to [@zkat](https://github.com/zkat)'s hard work. - -During our final testing before the release, our ace support team member -[@snopeks](https://github.com/snopeks) noticed that there had been some drift -between the CLI team's implementation and what npm was actually preparing to -ship. In the interests of everyone having a smooth experience with this -_extremely useful_ new feature, we quickly made a few changes to square up the -CLI and the web site experiences. - -* [`0e8b15e`](https://github.com/npm/npm/commit/0e8b15e9fbc89e31bd00e573b648846beddfb835) - [#9327](https://github.com/npm/npm/issues/9327) `npm access` no longer has - problems when run in a directory that doesn't contain a `package.json`. - ([@othiym23](https://github.com/othiym23)) -* [`c4e939c`](https://github.com/npm/npm/commit/c4e939c1d493601d25dcb88e6ffcca73076fd3fd) - [npm/npm-registry-client#126](https://github.com/npm/npm-registry-client/issues/126) - `npm-registry-client@7.0.8`: Allow the CLI to grant, revoke, and list - permissions on unscoped (public) packages on the primary registry. - ([@othiym23](https://github.com/othiym23)) - -#### A BRIEF NOTE ON NPM'S BACKWARDS COMPATIBILITY - -We don't often have much to say about the changes we make to our internal -testing and tooling, but I'm going to take this opportunity to reiterate that -npm tries hard to maintain compatibility with a wide variety of Node versions. -As this change shows, we want to ensure that npm works the same across: - -* Node.js 0.8 -* Node.js 0.10 -* Node.js 0.12 -* the latest io.js release -* Node.js 4 LTS -* Node.js 5 - -Contributors who send us pull requests often notice that it's very rare that -our tests pass across all of those versions (ironically, almost entirely due to -the packages we use for testing instead of any issues within npm itself). We're -currently beginning an effort, lasting the rest of 2015, to clean up our test -suite, and not only get it passing on all of the above versions of Node.js, but -working solidly on Windows as well. This is a compounding form of technical -debt that we're finally paying down, and our hope is that cleaning up the tests -will produce a more robust CLI that's a lot easier to write patches for. - -* [`d743620`](https://github.com/npm/npm/commit/d743620a0005213a65d25de771661b4d48a09717) - [#10233](https://github.com/npm/npm/issues/10233) Update Node.js versions - that Travis uses to test npm. ([@iarna](https://github.com/iarna)) - -#### TYPOS IN THE LICENSE, OH MY - -* [`58ac241`](https://github.com/npm/npm/commit/58ac241f556b2c202a8ee33321965e2540361ca7) - [#10478](https://github.com/npm/npm/issues/10478) Correct two typos in npm's - LICENSE. ([@jorrit](https://github.com/jorrit)) - -### v2.14.11 (2015-11-12): - -#### ASK FOR NOTHING, GET LATEST - -When you run `npm install foo`, you probably expect that you'll get the -`latest` version of `foo`, whatever that is. And good news! That's what this -change makes it do. - -We _think_ this is what everyone wants, but if this causes problems for you, we -want to know! If it proves problematic for people we will consider reverting it -(preferably before this becomes `npm@latest`). - -Previously, when you ran `npm install foo` we would act as if you typed `npm -install foo@*`. Now, like any range-type specifier, in addition to matching the -range, it would also have to be `<=` the value of the `latest` dist-tag. -Further, it would exclude prerelease versions from the list of versions -considered for a match. - -This worked as expected most of the time, unless your `latest` was a prerelease -version, in which case that version wouldn't be used, to everyone's surprise. - -* [`6f0a646`](https://github.com/npm/npm/commit/6f0a646cd865b24fe3ff25365bf5421780e63e01) - [#10189](https://github.com/npm/npm/issues/10189) `npm-package-arg@4.1.0`: - Change the default version from `*` to `latest`. - ([@zkat](https://github.com/zkat)) - -#### LICENSE CLARIFICATION - -* [`54a9046`](https://github.com/npm/npm/commit/54a90461f068ea89baa5d70248cdf1581897936d) - [#10326](https://github.com/npm/npm/issues/10326) Clarify what-all is covered - by npm's license and point to the registry's terms of use. - ([@kemitchell](https://github.com/kemitchell)) - -#### CLOSER TO GREEN TRAVIS - -* [`28efd3d`](https://github.com/npm/npm/commit/28efd3d7dfb2fa3755076ae706ea4d38c6ee6900) - [#10232](https://github.com/npm/npm/issues/10232) `nock@1.9.0`: Downgrade - nock to a version that doesn't depend on streams2 in core so that more of our - tests can pass in 0.8. ([@iarna](https://github.com/iarna)) - -#### A BUG FIX - -* [`eacac8f`](https://github.com/npm/npm/commit/eacac8f05014d15217c3d8264d0b00a72eafe2d2) - [#9965](https://github.com/npm/npm/issues/9965) Fix a corrupt `package.json` - file introduced by a merge conflict in - [`022691a`](https://github.com/npm/npm/commit/022691a). - ([@waynebloss](https://github.com/waynebloss)) - -#### A DEPENDENCY UPGRADE - -* [`ea7d8e0`](https://github.com/npm/npm/commit/ea7d8e00a67a3d5877ed72c9728909c848468a9b) - [npm/nopt#51](https://github.com/npm/nopt/pull/51) `nopt@3.0.6`: Allow - types checked to be validated by passed-in name in addition to the JS name of - the type / class. ([@wbecker](https://github.com/wbecker)) - -### v2.14.10 (2015-11-05): - -There's nothing in here that that isn't in the `npm@3.4.0` release notes, but -all of the commit shasums have been adjusted to be correct. Enjoy! - -#### BUG FIXES VIA DEPENDENCY UPDATES - -* [`204c558`](https://github.com/npm/npm/commit/204c558c06637a753c0b41d0cf19f564a1ac3715) - [#8640](https://github.com/npm/npm/issues/8640) - [npm/normalize-package-data#69](https://github.com/npm/normalize-package-data/pull/69) - `normalize-package-data@2.3.5`: Fix a bug where if you didn't specify the - name of a scoped module's binary, it would install it such that it was - impossible to call it. ([@iarna](https://github.com/iarna)) -* [`bbdf4ee`](https://github.com/npm/npm/commit/bbdf4ee0a3cd12be6a2ace255b67d573a72f1f8f) - [npm/fstream-npm#14](https://github.com/npm/fstream-npm/pull/14) - `fstream-npm@1.0.7`: Only filter `config.gypi` when it's in the build - directory. ([@mscdex](https://github.com/mscdex)) -* [`d82ff81`](https://github.com/npm/npm/commit/d82ff81403e906931fac701775723626dcb443b3) - [npm/fstream-npm#15](https://github.com/npm/fstream-npm/pull/15) - `fstream-npm@1.0.6`: Stop including directories that happened to have names - matching whitelisted npm files in npm module tarballs. The most common cause - was that if you had a README directory then everything in it would be - included if wanted it or not. ([@taion](https://github.com/taion)) - -#### DOCUMENTATION FIXES - -* [`16361d1`](https://github.com/npm/npm/commit/16361d122f2ff6d1a4729c66153b7c24c698fd19) - [#10036](https://github.com/npm/npm/pull/10036) Fix typo / over-abbreviation. - ([@ifdattic](https://github.com/ifdattic)) -* [`d1343dd`](https://github.com/npm/npm/commit/d1343dda42f113dc322f95687f5a8c7d71a97c35) - [#10176](https://github.com/npm/npm/pull/10176) Fix broken link, scopes => - scope. ([@ashleygwilliams](https://github.com/ashleygwilliams)) -* [`110663d`](https://github.com/npm/npm/commit/110663d000a3908a4853393d9abae481700cf4dc) - [#9460](https://github.com/npm/npm/issue/9460) Specifying the default command - run by "npm start" and the fact that you can pass it arguments. - ([@JuanCaicedo](https://github.com/JuanCaicedo)) - -#### DEPENDENCY UPDATES FOR THEIR OWN SAKE - -* [`7476d2d`](https://github.com/npm/npm/commit/7476d2d31552a41671c425aa7fcc2844e0381008) - [npm/npmlog#19](https://github.com/npm/npmlog/pull/19) - `npmlog@2.0.0`: Make it possible to emit log messages with `error` as the - prefix. - ([@bengl](https://github.com/bengl)) -* [`6ca7888`](https://github.com/npm/npm/commit/6ca7888862cfe8bf802dc7c66632c102acd94cf5) - `read-package-json@2.0.2`: Minor cleanups. - ([@KenanY](https://github.com/KenanY)) - -### v2.14.9 (2015-10-29): - -There's still life in `npm@2`, but for now, enjoy these dependency upgrades! -Also, [@othiym23](https://github.com/othiym23) says hi! _waves_ -[@zkat](https://github.com/zkat) has her hands full, and -[@iarna](https://github.com/iarna)'s handling `npm@3`, so I'm dealing with -`npm@2` and the totally nonexistent weird bridge `npm@1.4` LTS release that may -or may not be happening this week. - -#### CAN'T STOP WON'T STOP UPDATING THOSE DEPENDENCIES - -* [`f52f0cb`](https://github.com/npm/npm/commit/f52f0cb51526314197e9d67619feebbd82a397b7) - [#10150](https://github.com/npm/npm/issues/10150) `chmodr@1.0.2`: Use - `fs.lstat()` to check if an entry is a directory, making `chmodr()` work - properly with NFS mounts on Windows. ([@sheerun](https://github.com/sheerun)) -* [`f7011d7`](https://github.com/npm/npm/commit/f7011d7b3b1d9148a6cd8f7b8359d6fe3269a912) - [#10150](https://github.com/npm/npm/issues/10150) `which@1.2.0`: Additional - command-line parameters, which is nice but not used by npm. - ([@isaacs](https://github.com/isaacs)) -* [`ebcc0d8`](https://github.com/npm/npm/commit/ebcc0d8629388da0b849bbbad590382cd7268f51) - [#10150](https://github.com/npm/npm/issues/10150) `minimatch@3.0.0`: Don't - package browser version. ([@isaacs](https://github.com/isaacs)) -* [`8c98dce`](https://github.com/npm/npm/commit/8c98dce5ffe242bafbe92b849e73e8de1803e256) - [#10150](https://github.com/npm/npm/issues/10150) `fstream-ignore@1.0.3`: - Upgrade to use `minimatch@3` (for deduping purposes). - ([@othiym23](https://github.com/othiym23)) -* [`db9ef33`](https://github.com/npm/npm/commit/db9ef337c253ecf21c921055bf8742e10d1cb3bb) - [#10150](https://github.com/npm/npm/issues/10150) `request@2.65.0`: - Dependency upgrades and a few bug fixes, mostly related to cookie handling. - ([@simov](https://github.com/simov)) - -#### DEVDEPENDENCIES TOO, I GUESS, IT'S COOL - -* [`dfbf621`](https://github.com/npm/npm/commit/dfbf621afa09c46991249b4f9a995d1823ea7ede) - [#10150](https://github.com/npm/npm/issues/10150) `tap@2.2.0`: Better - handling of test order handling (including some test fixes for npm). - ([@isaacs](https://github.com/isaacs)) -* [`cf5ad5a`](https://github.com/npm/npm/commit/cf5ad5a8c88bfd72e30ef8a8d1d3c5508e0b3c23) - [#10150](https://github.com/npm/npm/issues/10150) `nock@2.16.0`: More - expectations, documentation, and bug fixes. - ([@pgte](https://github.com/pgte)) - -### v2.14.8 (2015-10-08): - -#### SLOWLY RECOVERING FROM FEELINGS - -OS&F is definitely my favorite convention I've gone to. Y'all should check it -out next year! Rebecca and Kat are back, although Forrest is out at -[&yet conf](http://andyetconf.com/). - -This week sees another tiny LTS release with non-code-related patches -- just -CI/release things. - -Meanwhile, have you heard? `npm@3` is much faster now! Go upgrade with `npm -install -g npm@latest` and give it a whirl if you haven't already! - -#### IF YOU CHANGE CASING ON A FILE, YOU ARE NOT MY FRIEND - -Seriously. I love me some case-sensitive filesystems, but a lot of us have to -deal with `git` and its funky support for case normalizing systems. Have mercy -and just don't bother if all you're changing is casing, please? Otherwise, I -have to do this little dance to prevent horrible conflicts. - -* [`c3a7b61`](https://github.com/npm/npm/commit/c3a7b619786650a45653c8b55b8741fc7bb5cfda) - [#9804](https://github.com/npm/npm/pulls/9804) Remove the readme file with - weird casing. - ([@zkat](https://github.com/zkat)) -* [`f3f619e`](https://github.com/npm/npm/commit/f3f619e06e4be1378dbf286f897b50e9c69c9557) - [#9804](https://github.com/npm/npm/pulls/9804) Add the readme file back in, - with desired casing. - ([@zkat](https://github.com/zkat)) - -#### IDK. OUR CI DOESN'T EVEN FULLY WORK YET BUT SURE - -Either way, it's nice to make sure we're running stuff on the latest Node. `4.2` -is getting released very soon, though (this week?), and that'll be the first -official LTS release! - -* [`bd0b9ab`](https://github.com/npm/npm/commit/bd0b9ab6e60a31448794bbd88f94672572c3cb55) - [#9827](https://github.com/npm/npm/pulls/9827) Add node `4.0` and `4.1` to - TravisCI - ([@JaKXz](https://github.com/JaKXz)) - -### v2.14.7 (2015-10-01): - -#### MORE RELEASE STAGGERING?! - -Hi all, and greetings from [Open Source & Feelings](http://osfeels.com)! - -So we're switching gears a little with how we handle our weekly releases: from -now on, we're going to stagger release weeks between dependency bumps and -regular patches. So, this week, aside from a doc change, we'll be doing only -version bumps. Expect actual patches next week! - -#### TOTALLY FOLLOWING THE RULES ALREADY - -So I snuck this in, because it's our own [@snopeks](https://github.com/snopeks)' -first contribution to the main `npm` repo. She's been helping with building -support documents for Orgs, and contributed her general intro guide to the new -feature so you can read it with `npm help orgs` right in your terminal! - -* [`8324ea0`](https://github.com/npm/npm/commit/8324ea023ace4e08b6b8959ad199e2457af9f9cf) - [#9761](https://github.com/npm/npm/pull/9761) Added general user guide for - Orgs. - ([@snopeks](https://github.com/snopeks)) - -#### JUST. ONE. MORE. - -* [`9a502ca`](https://github.com/npm/npm/commit/9a502ca96e2d43ec75a8f684c9ca33af7e910f0a) - Use unique package name in tests to work around weird test-state-based - failures. - ([@iarna](https://github.com/iarna)) - -#### OKAY ACTUALLY THE THING I WAS SUPPOSED TO DO - -Anyway -- here's your version bump! :) - -* [`4aeb94c`](https://github.com/npm/npm/commit/4aeb94c9f0df3f41802cf2e0397a998f3b527c25) - `request@2.64.0`: No longer defaulting to `application/json` for `json` - requests. Also some minor doc and packaging patches. - ([@simov](https://github.com/simov)) - `minimatch@3.0.0`: No longer packaging browser modules. - ([@isaacs](https://github.com/isaacs)) -* [`a18b213`](https://github.com/npm/npm/commit/a18b213e6945a8f5faf882927829ac95f844e2aa) - `glob@5.0.15`: Upgraded `minimatch` dependency. - ([@isaacs](https://github.com/isaacs)) -* [`9eb64d4`](https://github.com/npm/npm/commit/9eb64e44509519ca9d788502edb2eba4cea5c86b) - `nock@2.13.0` - ([@pgte](https://github.com/pgte)) - -### v2.14.6 (2015-09-24): - -#### `¯\_(ツ)_/¯` - -Since `2.x` is LTS now, you can expect a slowdown in overall release sizes. On -top of that, we had our all-company-npm-internal-conf thing on Monday and -Tuesday so there wasn't really time to do much at all. - -Still, we're bringing you a couple of tiny little changes this week! - -* [`7b7da13`](https://github.com/npm/npm/commit/7b7da13c6cdf5eae53c20d5c69afc4c16e6f715d) - [#9471](https://github.com/npm/npm/pull/9471) When the port for a tarball is - different than the registry it's in, but the hostname is the same, the - protocol is now allowed to change, too. - ([@fastest963](https://github.com/fastest963)) -* [`6643ada`](https://github.com/npm/npm/commit/6643adaf9f37f08893e3ad28b797c55a36b2a152) - `request@2.63.0`: Use `application/json` as the default content type when - making `json` requests. - ([@simov](https://github.com/simov)) - -### v2.14.5 (2015-09-17): - -#### NPM IS DEAD. LONG LIVE NPM - -That's right folks. As of this week, `npm@next` is `npm@3`, which means it'll be -`npm@latest` next week! There's some really great shiny new things over there, -and you should really take a look. - -Many kudos to [@iarna](https://github.com/iarna) for her hard work on `npm@3`! - -Don't worry, we'll keep `2.x` around for a while (as LTS), but you won't see -many, if any, new features on this end. From now on, we're going to use -`latest-2` and `next-2` as the dist tags for the `npm@2` branch. - -#### OKAY THAT'S FINE CAN I DEPRECATE THINGS NOW? - -Yes! Specially if you're using scoped packages. Apparently, deprecating them -never worked, but that should be better now. :) - -* [`eca7b24`](https://github.com/npm/npm/commit/eca7b24de9a0090da02a93a69726f5e70ab80543) - [#9558](https://github.com/npm/npm/issues/9558) Add tests for npm deprecate. - ([@zkat](https://github.com/zkat)) -* [`648fe16`](https://github.com/npm/npm/commit/648fe16157ef0db22395ae056d1dd4b4c1605bf4) - [#9558](https://github.com/npm/npm/issues/9558) `npm-registry-client@7.0.7`: - Fixes `npm deprecate` so you can actually deprecate scoped modules now (it - never worked). - ([@zkat](https://github.com/zkat)) - -#### WTF IS `node-waf` - -idk. Some old thing. We don't talk about it anymore. - -* [`cf1b39f`](https://github.com/npm/npm/commit/cf1b39fc95a9ffad7fba4c2fee705c53b19d1d16) - [#9584](https://github.com/npm/npm/issues/9584) Fix ancient references to - `node-waf` in the docs to refer to the `node-gyp` version of things. - ([@KenanY](https://github.com/KenanY)) - -#### THE `graceful-fs` AND `node-gyp` SAGA CONTINUES - -Last week had some sweeping `graceful-fs` upgrades, and this takes care of one -of the stragglers, as well as bumping `node-gyp`. `node@4` users might be -excited about this, or even `node@<4` users who previously had to cherry-pick a -bunch of patches to get the latest npm working. - -* [`e07354f`](https://github.com/npm/npm/commit/e07354f3ff3a6be568fe950f1f825897f72912d8) - `sha@2.0.1`: Upgraded graceful-fs! - ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`83cb6ee`](https://github.com/npm/npm/commit/83cb6ee4045b85e565e9678ca1878877e1dc75bd) - `node-gyp@3.0.3` - ([@rvagg](https://github.com/rvagg)) - -#### DEPS! DEPS! MORE DEPS! OK STOP DEPS - -* [`0d60888`](https://github.com/npm/npm/commit/0d608889615a1cb63f5f852337e955053f201aeb) - `normalize-package-data@2.3.4`: Use an external package to check for built-in - node modules. - ([@sindresorhus](https://github.com/sindresorhus)) -* [`79b4dac`](https://github.com/npm/npm/commit/79b4dac11f1c2d8ad5489fc3104734e1c10d4793) - `retry@0.8.0` - ([@tim-kos](https://github.com/tim-kos)) -* [`c164941`](https://github.com/npm/npm/commit/c164941d3c792904d5b126a4fd36eefbe0699f52) - `request@2.62.0`: node 4 added to build targets. Option initialization issues - fixed. - ([@simov](https://github.com/simov)) -* [`0fd878a`](https://github.com/npm/npm/commit/0fd878a44d5ae303325808d1f00df4dce7549d50) - `lru-cache@2.7.0`: Cache serialization support and fixes a cache length bug. - ([@isaacs](https://github.com/isaacs)) -* [`6a7a114`](https://github.com/npm/npm/commit/6a7a114a45b4699995d6e09164fdfd0fa1274591) - `nock@2.12.0` - ([@pgte](https://github.com/pgte)) -* [`6b25e6d`](https://github.com/npm/npm/commit/6b25e6d2235c11f4444104db4545cb42a0267666) - `semver@5.0.3`: Removed uglify-js dead code. - ([@isaacs](https://github.com/isaacs)) - -### v2.14.4 (2015-09-10): - -#### THE GREAT NODEv4 SAGA - -So [Node 4 is out now](https://nodejs.org/en/blog/release/v4.0.0/) and that's -going to involve a number of things over in npm land. Most importantly, it's the -last major release that will include the `2.x` branch of npm. That also means -that `2.x` is going to go into LTS mode in the coming weeks -- once `npm@3` -becomes our official `latest` release. You can most likely expect Node 5 to -include `npm@3` by default, whenever that happens. We'll go into more detail -about LTS at that point, as well, so keep your eyes peeled for announcements! - -#### NODE IS DEAD. LONG LIVE NODE! - -Node 4 being released means that a few things that used to be floating patches -are finally making it right into npm proper. This week, we've got two such -updates, both to dependencies: - -* [`505d9e4`](https://github.com/npm/npm/commit/505d9e40c13b8b0bb3f70ee9886f7b73ba569407) - `node-gyp@3.0.1`: Support for node nightlies and compilation for both node and - io.js without extra patching - ([@rvagg](https://github.com/rvagg)) - -[@thefourtheye](https://github.com/thefourtheye) was kind enough to submit a -*bunch* of PRs to npm's dependencies updating them to `graceful-fs@4.1.2`, which -mainly makes it so we're no longer monkey-patching `fs`. The following are all -updates related to this: - -* [`10cb189`](https://github.com/npm/npm/commit/10cb189c773fef804214018d57509cc7a943184b) - `write-file-atomic@1.1.3` - ([@thefourtheye](https://github.com/thefourtheye)) -* [`edfb80b`](https://github.com/npm/npm/commit/edfb80b39f8cfce9a993f139eb98248001198e09) - `tar@2.2.1` - ([@thefourtheye](https://github.com/thefourtheye)) -* [`aa6e1ee`](https://github.com/npm/npm/commit/aa6e1eede7d71fa69d7256afdfbaa3406bc39a5b) - `read-package-json@2.0.1` - ([@thefourtheye](https://github.com/thefourtheye)) -* [`18971a3`](https://github.com/npm/npm/commit/18971a361635ed3958ecd39b63930ae1e56f8612) - `read-installed@4.0.3` - ([@thefourtheye](https://github.com/thefourtheye)) -* [`a4cba71`](https://github.com/npm/npm/commit/a4cba71bd2532236fda7385bf55e8790cafd4f0a) - `fstream@1.0.8` - ([@thefourtheye](https://github.com/thefourtheye)) -* [`70a38e2`](https://github.com/npm/npm/commit/70a38e29418951ac61ab6cf269d188074fe8ac3a) - `fs-write-stream-atomic@1.0.4` - ([@thefourtheye](https://github.com/thefourtheye)) -* [`9cbd20f`](https://github.com/npm/npm/commit/9cbd20f691e37960e4ba12d401abd1069657cb47) - `fs-vacuum@1.2.7` - ([@thefourtheye](https://github.com/thefourtheye)) - -#### OTHER PATCHES - -* [`c4dd521`](https://github.com/npm/npm/commit/c4dd5213b2f3283ea0392845e5f78cac4573529e) - [#9506](https://github.com/npm/npm/issues/9506) Make `npm link` work on - Windows when using node pre-release/RC releases. - ([@jon-hall](https://github.com/jon-hall)) -* [`b6bc29c`](https://github.com/npm/npm/commit/b6bc29c1401b3d6b570c09cbef1866bdb0436b59) - [#9544](https://github.com/npm/npm/issues/9549) `process.binding` is being - deprecated, so our only direct usage has been removed. - ([@ChALkeR](https://github.com/ChALkeR)) - -#### MORE DEPENDENCIES! - -* [`d940594`](https://github.com/npm/npm/commit/d940594e479a7f012b6dd6952e8ef985ba2a6216) - `tap@1.4.1` - ([@isaacs](https://github.com/isaacs)) -* [`ee38486`](https://github.com/npm/npm/commit/ee3848669331fd98879a3175789d963543f67ce3) - `which@1.1.2`: Added tests for Windows-related dead code that was previously - helping a silent failure happen. Travis stuff, too. - ([@isaacs](https://github.com/isaacs)) - -#### DOC UPDATES - -* [`475daf5`](https://github.com/npm/npm/commit/475daf54ad07777938d1d7ee1a3e576961e84510) - [#9492](https://github.com/npm/npm/issues/9492) Clarify how `.npmignore` and - `.gitignore` are found and used by npm. - ([@addaleax](https://github.com/addaleax)) -* [`b2c391d`](https://github.com/npm/npm/commit/b2c391d7833249626a6d7650363a83bcc778717a) - `nopt@3.0.4`: Minor clarifications to docs about how array and errors work. - ([@zkat](https://github.com/zkat)) - -### v2.14.3 (2015-09-03): - -#### TEAMS AND ORGS STILL BETA. CLI CODE STILL SOLID. - -Our closed beta for Teens and Orcs is happening! The web team is hard at work -making sure everything looks pretty and usable and such. Once we fix things -stemming from that beta, you can expect the feature to be available publicly. -Some time after that, it'll even be available for free for FOSS orgs. It'll Be -Done When It's Done™. - -#### OH GOOD, I CAN ACTUALLY UPSTREAM NOW - -Looks like last week's release foiled our own test suite when trying to upstream -it to Node! Just a friendly reminder that no, `.npmrc` is no longer included -then you pack/release a package! [@othiym23](https://github.com/othiym23) and -[@isaacs](https://github.com/isaacs) managed to suss the really strange test -failures resulting from that, and we've patched it in this release. - -* [`01a3428`](https://github.com/npm/npm/commit/01a3428534b754dca89a56fd1e49f55cb22f6f25) - [#9476](https://github.com/npm/npm/issues/9476) test: Recreate missing - `.npmrc` files when missing so downstream packagers can run tests on packed - npm. - ([@othiym23](https://github.com/othiym23)) - -#### TALKING ABOUT THE CHANGELOG IN THE CHANGELOG IS LIKE, POMO OR SOMETHING - -* [`c1e7a83`](https://github.com/npm/npm/commit/c1e7a83c0ae7aadf01aecc57cf8a0ae2009d4da8) - [#9431](https://github.com/npm/npm/issues/9431) CHANGELOG: clarify - windows-related nature of patch - ([@saper](https://github.com/saper)) - -#### devDependencies UPDATED - -No actual dep updates this week, but we're bumping a couple of devDeps: - -* [`8454835`](https://github.com/npm/npm/commit/84548351bfd63e3e305d195abbcad24c6b7c3e8e) - `tap@1.4.0`: Add `t.contains()` as alias to `t.match()` - ([@isaacs](https://github.com/isaacs)) -* [`13d2216`](https://github.com/npm/npm/commit/13d22161bcdeb6e1ed095d5ba2f77e6abfffa5eb) - `deep-equal@1.0.1`: Make `null == undefined` in non-strict mode - ([@isaacs](https://github.com/isaacs)) - -### v2.14.2 (2015-08-27): - -#### GETTING THAT PESKY `preferGlobal` WARNING RIGHT - -So apparently the `preferGlobal` option hasn't quite been warning correctly for -some time. But now it should be all better! tl;dr: if you try and install a -dependency with `preferGlobal: true`, and it's _not already_ in your -`package.json`, you'll get a warning that the author would really rather you -install it with `--global`. This should prevent Windows PowerShell from thinking -npm has failed just because of a benign warning. - -* [`bbb25f3`](https://github.com/npm/npm/commit/bbb25f30d582f8979168c79233a9f8f840974f90) - [#8841](https://github.com/npm/npm/issues/8841) - [#9409](https://github.com/npm/npm/issues/9409) The `preferGlobal` - warning shouldn't happen if the dependency being installed is listed in - `devDependencies`. ([@saper](https://github.com/saper)) -* [`222fcec`](https://github.com/npm/npm/commit/222fcec85ccd30d35899e5037079fb14625af4e2) - [#9409](https://github.com/npm/npm/issues/9409) `preferGlobal` now prints a - warning when there are no dependencies for the current package. - ([@zkat](https://github.com/zkat)) -* [`5cfed6d`](https://github.com/npm/npm/commit/5cfed6d7a1a5f2731688cfc8293b5e43a6355393) - [#9409](https://github.com/npm/npm/issues/9409) Verify that - `preferGlobal` is warning as expected (when a `preferGlobal` dependency is - installed, but isn't listed in either `dependencies` or `devDependencies`). - ([@zkat](https://github.com/zkat)) - -#### BUMP +1 - -* [`eeafce2`](https://github.com/npm/npm/commit/eeafce2d06883c0f51bf403415b6bc5f2647eba3) - `validate-npm-package-license@3.0.1`: Include additional metadata in parsed license object, - useful for license checkers. ([@kemitchell](https://github.com/kemitchell)) -* [`1502a28`](https://github.com/npm/npm/commit/1502a285f84aa548806b3eafc8889e6288e810f3) - `normalise-package-data@2.3.2`: Updated to use `validate-npm-package-license@3.0.1`. - ([@othiym23](https://github.com/othiym23)) -* [`cbde823`](https://github.com/npm/npm/commit/cbde8233436bf0ea62a4740869b4990322c20659) - `init-package-json@1.9.1`: Add a `silent` option to suppress output on writing the - generated `package.json`. Also, updated to use `validate-npm-package-license@3.0.1`. - ([@zkat](https://github.com/zkat)) -* [`08fda46`](https://github.com/npm/npm/commit/08fda465452b4d77f1ced8050ee3a35a77fc30a5) - `tar@2.2.0`: Minor improvements. ([@othiym23](https://github.com/othiym23)) -* [`dc2f20b`](https://github.com/npm/npm/commit/dc2f20b53fff77203139c863b48da0e959df2ac9) - `rimraf@2.4.3`: `EPERM` now triggers a delay / retry loop (since Windows throws - this when things still hold a handle). ([@isaacs](https://github.com/isaacs)) -* [`e8acb27`](https://github.com/npm/npm/commit/e8acb273aa67ee0394d0431650e1b2a7d09c8554) - `read@1.0.7`: Fix licensing ambiguity. ([@isaacs](https://github.com/isaacs)) - -#### OTHER STUFF THAT'S RELEVANT - -* [`73a1ee0`](https://github.com/npm/npm/commit/73a1ee0be90fa1928521b63f28bef83b8ffab61d) - [#9386](https://github.com/npm/npm/issues/9386) Include additional unignorable files in - documentation. - ([@mjhasbach](https://github.com/mjhasbach)) -* [`0313e40`](https://github.com/npm/npm/commit/0313e40ee0f757fce8861be590ad668c23d7be53) - [#9396](https://github.com/npm/npm/issues/9396) Improve the `EISDIR` error - message returned by npm's error-handling code to give users a better hint of - what's most likely going on. Usually, error reports with this error code are - about people trying to install things without a `package.json`. - ([@KenanY](https://github.com/KenanY)) -* [`2677457`](https://github.com/npm/npm/commit/26774579c739c5951351e58263cf4d6ea3d66ec8) - [#9360](https://github.com/npm/npm/issues/9360) Make it easier to run - only _some_ of npm tests with lifecycle scripts via `npm tap test/tap/testname.js`. - ([@iarna](https://github.com/iarna)) - -### v2.14.1 (2015-08-20): - -#### SECURITY FIX - -There are patches for two information leaks of moderate severity in `npm@2.14.1`: - -1. In some cases, npm was leaking sensitive credential information into the - child environment when running package and lifecycle scripts. This could - lead to packages being published with files (most notably `config.gypi`, a - file created by `node-gyp` that is a cache of environmental information - regenerated on every run) containing the bearer tokens used to authenticate - users to the registry. Users with affected packages have been notified (and - the affected tokens invalidated), and now npm has been modified to not - upload files that could contain this information, as well as scrubbing the - sensitive information out of the environment passed to child scripts. -2. Per-package `.npmrc` files are used by some maintainers as a way to scope - those packages to a specific registry and its credentials. This is a - reasonable use case, but by default `.npmrc` was packed into packages, - leaking those credentials. npm will no longer include `.npmrc` when packing - tarballs. - -If you maintain packages and believe you may be affected by either -of the above scenarios (especially if you've received a security -notification from npm recently), please upgrade to `npm@2.14.1` as -soon as possible. If you believe you may have inadvertently leaked -your credentials, upgrade to `npm@2.14.1` on the affected machine, -and run `npm logout` and then `npm login`. Your access tokens will be -invalidated, which will eliminate any risk posed by tokens inadvertently -included in published packages. We apologize for the inconvenience this -causes, as well as the oversight that led to the existence of this issue -in the first place. - -Huge thanks to [@ChALkeR](https://github.com/ChALkeR) for bringing these -issues to our attention, and for helping us identify affected packages -and maintainers. Thanks also to the Node.js security working group for -their coördination with the team in our response to this issue. We -appreciate everybody's patience and understanding tremendously. - -* [`b9474a8`](https://github.com/npm/npm/commit/b9474a843ca55b7c5fac6da33989e8eb39aff8b1) - `fstream-npm@1.0.5`: Stop publishing build cruft (`config.gypi`) and per-project - `.npmrc` files to keep local configuration out of published packages. - ([@othiym23](https://github.com/othiym23)) -* [`13c286d`](https://github.com/npm/npm/commit/13c286dbdc3fa8fec4cb79fc4d1ee505c8a41b2e) - [#9348](https://github.com/npm/npm/issues/9348) Filter "private" - (underscore-prefixed, even when scoped to a registry) configuration values - out of child environments. ([@othiym23](https://github.com/othiym23)) - -#### BETTER WINDOWS INTEGRATION, ONE STEP AT A TIME - -* [`e40e71f`](https://github.com/npm/npm/commit/e40e71f2f838a8a42392f44e3eeec04e323ab743) - [#6412](https://github.com/npm/npm/issues/6412) Improve the search strategy - used by the npm shims for Windows to prioritize your own local npm installs. - npm has really needed this tweak for a long time, so hammer on it and let us - know if you run into issues, but with luck it will Just Work. - ([@joaocgreis](https://github.com/joaocgreis)) -* [`204ebbb`](https://github.com/npm/npm/commit/204ebbb3e0cab696a429a878ceeb4a7e78ec2b94) - [#8751](https://github.com/npm/npm/issues/8751) - [#7333](https://github.com/npm/npm/issues/7333) Keep [autorun - scripts](https://technet.microsoft.com/en-us/sysinternals/bb963902.aspx) from - interfering with npm package and lifecycle script execution on Windows by - adding `/d` and `/s` when invoking `cmd.exe`. - ([@saper](https://github.com/saper)) - -#### IT SEEMED LIKE AN IDEA AT THE TIME - -* [`286f3d9`](https://github.com/npm/npm/commit/286f3d97103812f0fd84b70352addbe899e258f9) - [#9201](https://github.com/npm/npm/pull/9201) For a while npm was building - HTML partials for use on [`docs.npmjs.com`](https://docs.npmjs.com), but we - weren't actually using them. Stop building them, which makes running the full - test suite and installation process around a third faster. - ([@isaacs](https://github.com/isaacs)) - -#### A SINGLE LONELY DEPENDENCY UPGRADE - -* [`b343b95`](https://github.com/npm/npm/commit/b343b956ef777e321e4251ddc96ec6d80827d9e2) - `request@2.61.0`: Bug fixes and keep-alive tweaks. - ([@simov](https://github.com/simov)) - -### v2.14.0 (2015-08-13): - -#### IT'S HERE! KINDA! - -This release adds support for teens and orcs (err, teams and organizations) to -the npm CLI! Note that the web site and registry-side features of this are -still not ready for public consumption. - -A beta should be starting in the next couple of weeks, and the features -themselves will become public once all that's done. Keep an eye out for more -news! - -All of these changes were done under [`#9011`](https://github.com/npm/npm/pull/9011): - -* [`6424170`](https://github.com/npm/npm/commit/6424170fc17c666a6efc090370ec691e0cab1792) - Added new `npm team` command and subcommands. - ([@zkat](https://github.com/zkat)) -* [`52220d1`](https://github.com/npm/npm/commit/52220d146d474ec29b683bd99c06f75cbd46a9f4) - Added documentation for new `npm team` command. - ([@zkat](https://github.com/zkat)) -* [`4e66830`](https://github.com/npm/npm/commit/4e668304850d02df8eb27a779fda76fe5de645e7) - Updated `npm access` to support teams and organizations. - ([@zkat](https://github.com/zkat)) -* [`ea3eb87`](https://github.com/npm/npm/commit/ea3eb8733d9fa09ce34106b1b19fb1a8f95844a5) - Gussied up docs for `npm access` with new commands. - ([@zkat](https://github.com/zkat)) -* [`6e0b431`](https://github.com/npm/npm/commit/6e0b431c1de5e329c86e57d097aa88ebfedea864) - Fix up `npm whoami` to make the underlying API usable elsewhere. - ([@zkat](https://github.com/zkat)) -* [`f29c931`](https://github.com/npm/npm/commit/f29c931012ce5ccd69c29d83548f27e443bf7e62) - `npm-registry-client@7.0.1`: Upgrade `npm-registry-client` API to support - `team` and `access` calls against the registry. - ([@zkat](https://github.com/zkat)) - -#### A FEW EXTRA VERSION BUMPS - -* [`c977e12`](https://github.com/npm/npm/commit/c977e12cbfa50c2f52fc807f5cc19ba1cc1b39bf) - `init-package-json@1.8.0`: Checks for some `npm@3` metadata. - ([@iarna](https://github.com/iarna)) -* [`5c8c9e5`](https://github.com/npm/npm/commit/5c8c9e5ae177ba7d0d298cfa42f3fc7f0271e4ec) - `columnify@1.5.2`: Updated some dependencies. - ([@timoxley](https://github.com/timoxley)) -* [`5d56742`](https://github.com/npm/npm/commit/5d567425768b75aeab402c817a53d8b2bc60d8de) - `chownr@1.0.1`: Tests, docs, and minor style nits. - ([@isaacs](https://github.com/isaacs)) - -#### ALSO A DOC FIX - -* [`846fcc7`](https://github.com/npm/npm/commit/846fcc79b86984b109a97366b0422f995a45f8bf) - [`#9200`](https://github.com/npm/npm/pull/9200) Remove single quotes - around semver range, thus making it valid semver. - ([@KenanY](https://github.com/KenanY)) - -### v2.13.5 (2015-08-07): - -This is another quiet week for the `npm@2` release. -[@zkat](https://github.com/zkat) has been working hard on polishing the CLI -bits of the registry's new feature to support direct management of teams and -organizations, and [@iarna](https://github.com/iarna) continues to work through -the list of issues blocking the general release of `npm@3`, which is looking -more and more solid all the time. - -[@othiym23](https://github.com/othiym23) and [@zkat](https://github.com/zkat) -have also been at this week's Node.js / io.js [collaborator -summit](https://github.com/nodejs/summit/tree/master), both as facilitators and -participants. This is a valuable opportunity to get some face time with other -contributors and to work through a bunch of important discussions, but it does -leave us feeling kind of sleepy. Running meetings is hard! - -What does that leave for this release? A few of the more tricky bug fixes that -have been sitting around for a little while now, and a couple dependency -upgrades. Nothing too fancy, but most of these were contributed by developers -like _you_, which we think is swell. Thanks! - -#### BUG FIXES - -* [`d7271b8`](https://github.com/npm/npm/commit/d7271b8226712479cdd339bf85faf7e394923e0d) - [#4530](https://github.com/npm/npm/issues/4530) The bash completion script - for npm no longer alters global completion behavior around word breaks. - ([@whitty](https://github.com/whitty)) -* [`c9ce294`](https://github.com/npm/npm/commit/c9ce29415a0a8fc610690b6e9d91b64d6e36cfcc) - [#7198](https://github.com/npm/npm/issues/7198) When setting up dependencies - to be shared via `npm link <package>`, only run the lifecycle scripts during - the original link, not when running `npm link <package>` or `npm install - --link` against them. ([@murgatroid99](https://github.com/murgatroid99)) -* [`422da66`](https://github.com/npm/npm/commit/422da664bd3ce71313da447f170507faf5aac46a) - [#9108](https://github.com/npm/npm/issues/9108) Clear up minor confusion - around wording in `bundledDependencies` section of `package.json` docs. - ([@derekpeterson](https://github.com/derekpeterson)) -* [`6b42d99`](https://github.com/npm/npm/commit/6b42d99460885e715772d3487b1c548d2bc8a738) - [#9146](https://github.com/npm/npm/issues/9146) Include scripts that run for - `preversion`, `version`, and `postversion` in the section for lifecycle - scripts rather than the generic `npm run-script` output. - ([@othiym23](https://github.com/othiym23)) - -#### NOPE, NOT DONE WITH DEPENDENCY UPDATES - -* [`91a48bb`](https://github.com/npm/npm/commit/91a48bb5ef5a990781c86f8b69b8a32cf4fac2d9) - `chmodr@1.0.1`: Ignore symbolic links when recursively changing mode, just - like the Unix command. ([@isaacs](https://github.com/isaacs)) -* [`4bbc86e`](https://github.com/npm/npm/commit/4bbc86e3825e2eee9a8758ba26bdea0cb6a2581e) - `nock@2.10.0` ([@pgte](https://github.com/pgte)) - -### v2.13.4 (2015-07-30): - -#### JULY ENDS ON A FAIRLY QUIET NOTE - -Hey everyone! I hope you've had a great week. We're having a fairly small -release this week while we wrap up Teams and Orgs (or, as we've taken to calling -it internally, _Teens and Orcs_). - -In other exciting news, a bunch of us are gonna be at the [Node.js Collaborator -Summit](https://github.com/nodejs/summit/issues/1), and you can also find us at -[wafflejs](https://wafflejs.com/) on Wednesday. Hopefully we'll be seeing some -of you there. :) - -#### THE PATCH!!! - -So here it is. The patch. Hope it helps. (Thanks, -[@ktarplee](https://github.com/ktarplee)!) - -* [`2e58c48`](https://github.com/npm/npm/commit/2e58c4819e3cafe4ae23ab7f4a520fe09258cfd7) - [#9033](https://github.com/npm/npm/pull/9033) `npm version` now works on git - submodules - ([@ktarplee](https://github.com/ktarplee)) - -#### OH AND THERE'S A DEV DEPENDENCIES UPDATE - -Hooray. - -* [`d204683`](https://github.com/npm/npm/commit/d2046839d471322e61e3ceb0f00e78e5c481f967) - `nock@2.9.1` - ([@pgte](https://github.com/pgte)) - -### v2.13.3 (2015-07-23): - -#### I'M SAVING THE GOOD JOKES FOR MORE INTERESTING RELEASES - -It's pretty hard to outdo last week's release buuuuut~ I promise I'll have a -treat when we release our shiny new **Teams and Organizations** feature! :D -(Coming Soon™). It'll be a real *gem*. - -That means it's a pretty low-key release this week. We got some nice -documentation tweaks, a few bugfixes, and other such things, though! - -Oh, and a _bunch of version bumps_. Thanks, `semver`! - -#### IT'S THE LITTLE THINGS THAT MATTER - -* [`2fac6ae`](https://github.com/npm/npm/commit/2fac6aeffefba2934c3db395b525d931599c34d8) - [#9012](https://github.com/npm/npm/issues/9012) A convenience for releases -- - using the globally-installed npm before now was causing minor annoyances, so - we just use the exact same npm we're releasing to build the new release. - ([@zkat](https://github.com/zkat)) - -#### WHAT DOES THIS BUTTON DO? - -There's a couple of doc updates! The last one might be interesting. - -* [`4cd3205`](https://github.com/npm/npm/commit/4cd32050c0f89b7f1ae486354fa2c35eea302ba5) - [#9002](https://github.com/npm/npm/issues/9002) Updated docs to list the - various files that npm automatically includes and excludes, regardless of - settings. - ([@SimenB](https://github.com/SimenB)) -* [`cf09e75`](https://github.com/npm/npm/commit/cf09e754931739af32647d667b671e72a4c79081) - [#9022](https://github.com/npm/npm/issues/9022) Document the `"access"` field - in `"publishConfig"`. Did you know you don't need to use `--access=public` - when publishing scoped packages?! Just put it in your `package.json`! - Go refresh yourself on scopes packages by [checking our docs](https://docs.npmjs.com/getting-started/scoped-packages) on them. - ([@boennemann](https://github.com/boennemann)) -* [`bfd73da`](https://github.com/npm/npm/commit/bfd73da33349cc2afb8278953b2ae16ea95023de) - [#9013](https://github.com/npm/npm/issues/9013) fixed typo in changelog - ([@radarhere](https://github.com/radarhere)) - -#### THE SEMVER MAJOR VERSION APOCALYPSE IS UPON US - -Basically, `semver` is up to `@5`, and that meant we needed to go in an update a -bunch of our dependencies manually. `node-gyp` is still pending update, since -it's not ours, though! - -* [`9232e58`](https://github.com/npm/npm/commit/9232e58d54c032c23716ef976023d36a42bfdcc9) - [#8972](https://github.com/npm/npm/issues/8972) `init-package-json@1.7.1` - ([@othiym23](https://github.com/othiym23)) -* [`ba44f6b`](https://github.com/npm/npm/commit/ba44f6b4201a4faee025341b123e372d8f45b6d9) - [#8972](https://github.com/npm/npm/issues/8972) `normalize-package-data@2.3.1` - ([@othiym23](https://github.com/othiym23)) -* [`3901d3c`](https://github.com/npm/npm/commit/3901d3cf191880bb4420b1d6b8aedbcd8fc26cdf) - [#8972](https://github.com/npm/npm/issues/8972) `npm-install-checks@1.0.6` - ([@othiym23](https://github.com/othiym23)) -* [`ffcc7dd`](https://github.com/npm/npm/commit/ffcc7dd12f8bb94ff0f64c465c57e460b3f24a24) - [#8972](https://github.com/npm/npm/issues/8972) `npm-package-arg@4.0.2` - ([@othiym23](https://github.com/othiym23)) -* [`7128f9e`](https://github.com/npm/npm/commit/7128f9ec10c0c8482087511b716dbddb54249626) - [#8972](https://github.com/npm/npm/issues/8972) `npm-registry-client@6.5.1` - ([@othiym23](https://github.com/othiym23)) -* [`af28911`](https://github.com/npm/npm/commit/af28911ecd54a844f848c6ae41887097d6aa2f3b) - [#8972](https://github.com/npm/npm/issues/8972) `read-installed@4.0.2` - ([@othiym23](https://github.com/othiym23)) -* [`3cc817a`](https://github.com/npm/npm/commit/3cc817a0f34f698b580ff6ff02308700efc54f7c) - [#8972](https://github.com/npm/npm/issues/8972) node-gyp needs its own version - of semver - ([@othiym23](https://github.com/othiym23)) -* [`f98eccc`](https://github.com/npm/npm/commit/f98eccc6e3a6699ca0aa9ecbad93a3b995583871) - [#8972](https://github.com/npm/npm/issues/8972) `semver@5.0.1`: Stop including - browser builds. - ([@isaacs](https://github.com/isaacs)) - -#### \*BUMP\* - -And some other version bumps for good measure. - -* [`254ecfb`](https://github.com/npm/npm/commit/254ecfb04f026c2fd16427db01a53600c1892c8b) - [#8990](https://github.com/npm/npm/issues/8990) `marked-man@0.1.5`: Fixes an - issue with documentation rendering where backticks in 2nd-level headers would - break rendering (?!?!) - ([@steveklabnik](https://github.com/steveklabnik)) -* [`79efd79`](https://github.com/npm/npm/commit/79efd79ac216da8cee8636fb2ed926b0196a4eb6) - `minimatch@2.0.10`: A pattern like `'*.!(x).!(y)'` should not match a name - like `'a.xyz.yab'`. - ([@isaacs](https://github.com/isaacs)) -* [`39c7dc9`](https://github.com/npm/npm/commit/39c7dc9a4e17cd35a5ed882ba671821c9a900f9e) - `request@2.60.0`: A few bug fixes and doc updates. - ([@simov](https://github.com/simov)) -* [`72d3c3a`](https://github.com/npm/npm/commit/72d3c3a9e1e461608aa21b14c01a650333330da9) - `rimraf@2.4.2`: Minor doc and dep updates - ([@isaacs](https://github.com/isaacs)) -* [`7513035`](https://github.com/npm/npm/commit/75130356a06f5f4fbec3786aac9f9f0b36dfe010) - `nock@2.9.1` - ([@pgte](https://github.com/pgte)) -* [`3d9aa82`](https://github.com/npm/npm/commit/3d9aa82260f0643a32c13d0c1ed16f644b6fd4ab) - Fixes this thing where Kat decided to save `nock` as a regular dependency ;) - ([@othiym23](https://github.com/othiym23)) - -### v2.13.2 (2015-07-16): - -#### HOLD ON TO YOUR TENTACLES... IT'S NPM RELEASE TIME! - -Kat: Hooray! Full team again, and we've got a pretty small patch release this -week, about everyone's favorite recurring issue: git URLs! - -Rebecca: No Way! Again? - -Kat: The ride never ends! In the meantime, there's some fun, exciting work in -the background to get orgs and teams out the door. Keep an eye out for news. :) - -Rebecca: And make sure to keep an eye out for patches for the super-fresh -`npm@3`! - -#### LET'S GIT INKY - -Rebecca: So what's this about another git URL issue? - -Kat: Welp, I apparently broke backwards-compatibility on what are actually -invalid `git+https` URLs! So I'm making it work, but we're gonna deprecate URLs -that look like `git+https://user@host:path/is/here`. - -Rebecca: What should we use instead?! - -Kat: Just do me a solid and use `git+ssh://user@host:path/here` or -`git+https://user@host/absolute/https/path` instead! - -* [`769f06e`](https://github.com/npm/npm/commit/769f06e5455d7a9fc738379de2e05868df0dab6f) - Updated tests for `getResolved` so the URLs are run through - `normalize-git-url`. - ([@zkat](https://github.com/zkat)) -* [`edbae68`](https://github.com/npm/npm/commit/edbae685bf48971e878ced373d6825fc1891ee47) - [#8881](https://github.com/npm/npm/issues/8881) Added tests to verify that `git+https:` URLs are handled compatibly. - ([@zkat](https://github.com/zkat)) - -#### NEWS FLASH! DOCUMENTATION IMPROVEMENTS! - -* [`bad4e014`](https://github.com/npm/npm/commit/bad4e0143cc95754a682f1da543b2b4e196e924b) - [#8924](https://github.com/npm/npm/pull/8924) Make sure documented default - values in `lib/cache.js` properly correspond to current code. - ([@watilde](https://github.com/watilde)) -* [`e7a11fd`](https://github.com/npm/npm/commit/e7a11fdf70e333cdfe3dac94a1a30907adb76d59) - [#8036](https://github.com/npm/npm/issues/8036) Clarify the documentation for - `.npmrc` to clarify that it's not read at the project level when doing global - installs. - ([@espadrine](https://github.com/espadrine)) - -#### STAY FRESH~ - -Kat: That's it for npm core changes! - -Rebecca: Great! Let's look at the fresh new dependencies, then! - -Kat: See you all next week! - -Both: Stay Freeesh~ - -(some cat form of Forrest can be seen snoring in the corner) - -* [`bfa1f45`](https://github.com/npm/npm/bfa1f45ee760d05039557d2245b7e3df9fda8def) - `normalize-git-url@3.0.1`: Fixes url normalization such that `git+https:` - accepts scp syntax, but get converted into absolute-path `https:` URLs. Also - fixes scp syntax so you can have absolute paths after the `:` - (`git@myhost.org:/some/absolute/place.git`) - ([@zkat](https://github.com/zkat)) -* [`6f757d2`](https://github.com/npm/npm/6f757d22b53f91da0bebec6b5d16c1f4dbe130b4) - `glob@5.0.15`: Better handling of ENOTSUP - ([@isaacs](https://github.com/isaacs)) -* [`0920819`](https://github.com/npm/npm/09208197fb8b0c6d5dbf6bd7f59970cf366de989) - `node-gyp@2.0.2`: Fixes an issue with long paths on Win32 - ([@TooTallNate](https://github.com/TooTallNate)) - -### v2.13.1 (2015-07-09): - -#### KAUAI WAS NICE. I MISS IT. - -But Forrest's still kinda on vacation, and not just mentally, because he's -hanging out with the fine meatbags at CascadiaFest. Enjoy this small bug -release. - -#### MAKE OURSELVES HAPPY - -* [`40981f2`](https://github.com/npm/npm/commit/40981f2e0c9c12bb003ccf188169afd1d201f5af) - [#8862](https://github.com/npm/npm/issues/8862) Make the lifecycle's safety - check work with scoped packages. ([@tcort](https://github.com/tcort)) -* [`5125856`](https://github.com/npm/npm/commit/512585622481dbbda9a0306932468d59efaff658) - [#8855](https://github.com/npm/npm/issues/8855) Make dependency versions of - `"*"` match `"latest"` when all versions are prerelease. - ([@iarna](https://github.com/iarna)) -* [`22fdc1d`](https://github.com/npm/npm/commit/22fdc1d52602ba7098af978c75fca8f7d1060141) - Visually emphasize the correct way to write lifecycle scripts. - ([@josh-egan](https://github.com/josh-egan)) - -#### MAKE TRAVIS HAPPY - -* [`413c3ac`](https://github.com/npm/npm/commit/413c3ac2ab2437f3011c6ca0d1630109ec14e604) - Use npm's `2.x` branch for testing its `2.x` branch. - ([@iarna](https://github.com/iarna)) -* [`7602f64`](https://github.com/npm/npm/commit/7602f64826f7a465d9f3a20bd87a376d992607e6) - Don't prompt for GnuPG passphrase in version lifecycle tests. - ([@othiym23](https://github.com/othiym23)) - -#### MAKE `npm outdated` HAPPY - -* [`d338668`](https://github.com/npm/npm/commit/d338668601d1ebe5247a26237106e80ea8cd7f48) - [#8796](https://github.com/npm/npm/issues/8796) `fstream-npm@1.0.4`: When packing the - package tarball, npm no longer crashes for packages with certain combinations of - `.npmignore` entries, `.gitignore` entries, and lifecycle scripts. - ([@iarna](https://github.com/iarna)) -* [`dbe7c9c`](https://github.com/npm/npm/commit/dbe7c9c74734be870d16dd61b9e7f746123011f6) - `nock@2.7.0`: Add matching based on query strings. - ([@othiym23](https://github.com/othiym23)) - -There are new versions of `strip-ansi` and `ansi-regex`, but npm only uses them -indirectly, so we pushed them down into their dependencies where they can get -updated at their own pace. - -* [`06b6ca5`](https://github.com/npm/npm/commit/06b6ca5b5333025f10c8d901628859bd4678e027) - undeduplicate `ansi-regex` ([@othiym23](https://github.com/othiym23)) -* [`b168e33`](https://github.com/npm/npm/commit/b168e33ad46faf47020a45f72ba8cec8c644bdb9) - undeduplicate `strip-ansi` ([@othiym23](https://github.com/othiym23)) - -### v2.13.0 (2015-07-02): - -#### FORREST IS OUT! LET'S SNEAK IN ALL THE THINGS! - -Well, not _everything_. Just a couple of goodies, like the new `npm ping` -command, and the ability to add files to the commits created by `npm version` -with the new version hooks. There's also a couple of bugfixes in `npm` itself -and some of its dependencies. Here we go! - -#### YES HELLO THIS IS NPM REGISTRY SORRY NO DOG HERE - -Yes, that's right! We now have a dedicated `npm ping` command. It's super simple -and super easy. You ping. We tell you whether you pinged right by saying hello -right back. This should help out folks dealing with things like proxy issues or -other registry-access debugging issues. Give it a shot! - -This addresses [#5750](https://github.com/npm/npm/issues/5750), and will help -with the `npm doctor` stuff described in -[#6756](https://github.com/npm/npm/issues/6756). - -* [`f1f7a85`](https://github.com/npm/npm/commit/f1f7a85) - Add ping command to CLI - ([@michaelnisi](https://github.com/michaelnisi)) -* [`8cec629`](https://github.com/npm/npm/commit/8cec629) - Add ping command to npm-registry-client - ([@michaelnisi](https://github.com/michaelnisi)) -* [`0c0c92d`](https://github.com/npm/npm/0c0c92d) - Fixed ping command issues (added docs, tests, fixed minor bugs, etc) - ([@zkat](https://github.com/zkat)) - -#### I'VE WANTED THIS FOR `version` SINCE LIKE LITERALLY FOREVER AND A DAY - -Seriously! This patch lets you add files to the `version` commit before it's -made, So you can add additional metadata files, more automated changes to -`package.json`, or even generate `CHANGELOG.md` automatically pre-commit if -you're into that sort of thing. I'm so happy this is there I can't even. Do you -have other fun usecases for this? Tell -[npmbot (@npmjs)](http://twitter.com/npmjs) about it! - -* [`582f170`](https://github.com/npm/npm/commit/582f170) - [#8620](https://github.com/npm/npm/issues/8620) version: Allow scripts to add - files to the commit. - ([@jamestalmage](https://github.com/jamestalmage)) - -#### ALL YOUR FILE DESCRIPTORS ARE BELONG TO US - -We've had problems in the past with things like `EMFILE` errors popping up when -trying to install packages with a bunch of dependencies. Isaac patched up -[`graceful-fs`](https://github.com/isaacs/node-graceful-fs) to handle this case -better, so we should be seeing fewer of those. - -* [`022691a`](https://github.com/npm/npm/commit/022691a) - `graceful-fs@4.1.2`: Updated so we can monkey patch globally. - ([@isaacs](https://github.com/isaacs)) -* [`c9fb0fd`](https://github.com/npm/npm/commit/c9fb0fd) - Globally monkey-patch graceful-fs. This should fix some errors when installing - packages with lots of dependencies. - ([@isaacs](https://github.com/isaacs)) - -#### READ THE FINE DOCS. THEY'VE IMPROVED - -* [`5587d0d`](https://github.com/npm/npm/commit/5587d0d) - Nice clarification for `directories.bin` - ([@ujane](https://github.com/ujane)) -* [`20673c7`](https://github.com/npm/npm/commit/20673c7) - Hey, Windows folks! Check out - [`nvm-windows`](https://github.com/coreybutler/nvm-windows) - ([@ArtskydJ](https://github.com/ArtskydJ)) - -#### MORE NUMBERS! MORE VALUE! - -* [`5afa2d5`](https://github.com/npm/npm/commit/5afa2d5) - `validate-npm-package-name@2.2.2`: Documented package name rules in README - ([@zeusdeux](https://github.com/zeusdeux)) -* [`021f4d9`](https://github.com/npm/npm/commit/021f4d9) - `rimraf@2.4.1`: [#74](https://github.com/isaacs/rimraf/issues/74) Use async - function for bin (to better handle Window's `EBUSY`) - ([@isaacs](https://github.com/isaacs)) -* [`5223432`](https://github.com/npm/npm/commit/5223432) - `osenv@0.1.3`: Use `os.homedir()` polyfill for more reliable output. io.js - added the function and the polyfill does a better job than the prior solution. - ([@sindresorhus](https://github.com/sindresorhus)) -* [`8ebbc90`](https://github.com/npm/npm/commit/8ebbc90) - `npm-cache-filename@1.0.2`: Make sure different git references get different - cache folders. This should prevent `foo/bar#v1.0` and `foo/bar#master` from - sharing the same cache folder. - ([@tomekwi](https://github.com/tomekwi)) -* [`367b854`](https://github.com/npm/npm/commit/367b854) - `lru-cache@2.6.5`: Minor test/typo changes - ([@isaacs](https://github.com/isaacs)) -* [`9fcae61`](https://github.com/npm/npm/commit/9fcae61) - `glob@5.0.13`: Tiny doc change + stop firing 'match' events for ignored items. - ([@isaacs](https://github.com/isaacs)) - -#### OH AND ONE MORE THING - -* [`7827249`](https://github.com/npm/npm/commit/7827249) - `PeerDependencies` errors now include the package version. - ([@NickHeiner](https://github.com/NickHeiner)) - -### v2.12.1 (2015-06-25): - -#### HEY WHERE DID EVERYBODY GO - -I keep [hearing some commotion](https://github.com/npm/npm/releases/tag/v3.0.0). -Is there something going on? Like, a party or something? Anyway, here's a small -release with at least two significant bug fixes, at least one of which some of -you have been waiting for for quite a while. - -#### REMEMBER WHEN I SAID "REMEMBER WHEN I SAID THAT THING ABOUT PERMISSIONS?"? - -`npm@2.12.0` has a change that introduces a fix for a permissions problem -whereby the `_locks` directory in the cache directory can up being owned by -root. The fix in 2.12.0 takes care of that problem, but introduces a new -problem for Windows users where npm tries to call `process.getuid()`, which -doesn't exist on Windows. It was easy enough to fix (but more or less -impossible to test, thanks to all the external dependencies involved with -permissions and platforms and whatnot), but as a result, Windows users might -want to skip `npm@2.12.0` and go straight to `npm@2.12.1`. Sorry about that! - -* [`7e5da23`](https://github.com/npm/npm/commit/7e5da238ee869201fdb9027c27b79b0f76b440a8) - When using the new, "fixed" cache directory creator, be extra-careful to not - call `process.getuid()` on platforms that lack it. - ([@othiym23](https://github.com/othiym23)) - -#### WHEW! ALL DONE FIXING GIT FOREVER! - -New npm CLI team hero [@zkat](https://github.com/zkat) has finally (FINALLY) -fixed the regression somebody (hi!) introduced a couple months ago whereby git -URLs of the format `git+ssh://user@githost.com:org/repo.git` suddenly stopped -working, and also started being saved (and cached) incorrectly. I am 100% sure -there are absolutely no more bugs in the git caching code at all ever. Mm hm. -Yep. Pretty sure. Maybe. Hmm... I hope. - -*Sighs audibly.* - -[Let us know](http://github.com/npm/npm/issues/new) if we broke something else -with this fix. - -* [`94ca4a7`](https://github.com/npm/npm/commit/94ca4a711619ba8e40ce3d20bc42b13cdb7611b7) - [#8031](https://github.com/npm/npm/issues/8031) Even though - `git+ssh://user@githost.com:org/repo.git` isn't a URL, treat it like one for - the purposes of npm. ([@zkat](https://github.com/zkat)) -* [`e7f56e5`](https://github.com/npm/npm/commit/e7f56e5a97fcf1c52d5c5bee71303b0126129815) - [#8031](https://github.com/npm/npm/issues/8031) `normalize-git-url@2.0.0`: - Handle git URLs (and URL-like remote refs) in a manner consistent with npm's - docs. ([@zkat](https://github.com/zkat)) - -#### YEP, THERE ARE STILL DEPENDENCY UPGRADES - -* [`679bf47`](https://github.com/npm/npm/commit/679bf4745ac2cfbb01c9ce273e189807fd04fa33) - [#40](http://github.com/npm/read-installed/issues/40) `read-installed@4.0.1`: - Handle prerelease versions in top-level dependencies not in `package.json` - without marking those packages as invalid. - ([@benjamn](https://github.com/benjamn)) -* [`3a67410`](https://github.com/npm/npm/commit/3a6741068c9119174c920496778aeee870ebdac0) - `tap@1.3.1` ([@isaacs](https://github.com/isaacs)) -* [`151904a`](https://github.com/npm/npm/commit/151904af39dc24567f8c98529a2a64a4dbcc960a) - `nopt@3.0.3` ([@isaacs](https://github.com/isaacs)) - -### v2.12.0 (2015-06-18): - -#### REMEMBER WHEN I SAID THAT THING ABOUT PERMISSIONS? - -About [a million people](https://github.com/npm/npm/issues?utf8=%E2%9C%93&q=is%3Aissue+EACCES+_locks) -have filed issues related to having a tough time using npm after they've run -npm once or twice with sudo. "Don't worry about it!" I said. "We've fixed all -those permissions problems ages ago! Use this one weird trick and you'll never -have to deal with this again!" - -Well, uh, if you run npm with root the first time you run npm on a machine, it -turns out that the directory npm uses to store lockfiles ends up being owned by -the wrong user (almost always root), and that can, well, it can cause problems -sometimes. By which I mean every time you run npm without being root it'll barf -with `EACCES` errors. Whoops! - -This is an obnoxious regression, and to prevent it from recurring, we've made -it so that the cache, cached git remotes, and the lockfile directories are all -created and maintained using the same utilty module, which not only creates the -relevant paths with the correct permissions, but will fix the permissions on -those directories (if it can) when it notices that they're broken. An `npm -install` run as root ought to be sufficient to fix things up (and if that -doesn't work, first tell us about it, and then run `sudo chown -R $(whoami) -$HOME/.npm`) - -Also, I apologize for inadvertently gaslighting any of you by claiming this bug -wasn't actually a bug. I do think we've got this permanently dealt with now, -but I'll be paying extra-close attention to permissions issues related to the -cache for a while. - -* [`85d1a53`](https://github.com/npm/npm/commit/85d1a53d7b5e0fc04823187e522ae3711ede61fa) - Set permissions on lock directory to the owner of the process. - ([@othiym23](https://github.com/othiym23)) - -#### I WENT TO NODECONF AND ALL I GOT WAS THIS LOUSY SPDX T-SHIRT - -That's not literally true. We spent very little time discussing SPDX, -[@kemitchell](https://github.com/kemitchell) is a champ, and I had a lot of fun -playing drum & bass to a mostly empty Boogie Barn and only ended up with one -moderately severe cold for my pains. Another winner of a NodeConf! (I would -probably wear a SPDX T-shirt if somebody gave me one, though.) - -A bunch of us did have a spirited discussion of the basics of open-source -intellectual property, and the convergence of me, -[@kemitchell](https://github.com/kemitchell), and -[@jandrieu](https://github.com/jandrieu) in one place allowed us to hammmer out -a small but significant issue that had been bedeviling early adopters of the -new SPDX expression syntax in `package.json` license fields: how to deal with -packages that are left without a license on purpose. - -Refer to [the docs](https://github.com/npm/npm/blob/16a3dd545b10f8a2464e2037506ce39124739b41/doc/files/package.json.md#license) -for the specifics, but the short version is that instead of using -`LicenseRef-LICENSE` for proprietary licenses, you can now use either -`UNLICENSED` if you want to make it clear that you don't _want_ your software -to be licensed (and want npm to stop warning you about this), or `SEE LICENSE -IN <filename>` if there's a license with custom text you want to use. At some -point in the near term, we'll be updating npm to verify that the mentioned -file actually exists, but for now you're all on the honor system. - -* [`4827fc7`](https://github.com/npm/npm/commit/4827fc784117c17f35dd9b51b21d1eff6094f661) - [#8557](https://github.com/npm/npm/issues/8557) - `normalize-package-data@2.2.1`: Allow `UNLICENSED` and `SEE LICENSE IN - <filename>` in "license" field of `package.json`. - ([@kemitchell](https://github.com/kemitchell)) -* [`16a3dd5`](https://github.com/npm/npm/commit/16a3dd545b10f8a2464e2037506ce39124739b41) - [#8557](https://github.com/npm/npm/issues/8557) Document the new accepted - values for the "license" field. - ([@kemitchell](https://github.com/kemitchell)) -* [`8155311`](https://github.com/npm/npm/commit/81553119350deaf199e79e38e35b52a5c8ad206c) - [#8557](https://github.com/npm/npm/issues/8557) `init-package-json@1.7.0`: - Support new "license" field values at init time. - ([@kemitchell](https://github.com/kemitchell)) - -#### SMALLISH BUG FIXES - -* [`9d8cac9`](https://github.com/npm/npm/commit/9d8cac94a258db648a2b1069b1c8c6529c79d013) - [#8548](https://github.com/npm/npm/issues/8548) Remove extraneous newline - from `npm view` output, making it easier to use in shell scripts. - ([@eush77](https://github.com/eush77)) -* [`765fd4b`](https://github.com/npm/npm/commit/765fd4bfca8ea3e2a4a399765b17eec40a3d893d) - [#8521](https://github.com/npm/npm/issues/8521) When checking for outdated - packages, or updating packages, raise an error when the registry is - unreachable instead of silently "succeeding". - ([@ryantemple](https://github.com/ryantemple)) - -#### SMALLERISH DOCUMENTATION TWEAKS - -* [`5018335`](https://github.com/npm/npm/commit/5018335ce1754a9f771954ecbc1a93acde9b8c0a) - [#8365](https://github.com/npm/npm/issues/8365) Add details about which git - environment variables are whitelisted by npm. - ([@nmalaguti](https://github.com/nmalaguti)) -* [`bed9edd`](https://github.com/npm/npm/commit/bed9edddfdcc6d22a80feab33b53e4ef9172ec72) - [#8554](https://github.com/npm/npm/issues/8554) Fix typo in version docs. - ([@rainyday](https://github.com/rainyday)) - -#### WELL, I GUESS THERE ARE MORE DEPENDENCY UPGRADES - -* [`7ce2f06`](https://github.com/npm/npm/commit/7ce2f06f6f34d469b1d2e248084d4f3fef10c05e) - `request@2.58.0`: Refactor tunneling logic, and use `extend` instead of - abusing `util._extend`. ([@simov](https://github.com/simov)) -* [`e6c6195`](https://github.com/npm/npm/commit/e6c61954aad42e20eec49745615c7640b2026a6c) - `nock@2.6.0`: Refined interception behavior. - ([@pgte](https://github.com/pgte)) -* [`9583cc3`](https://github.com/npm/npm/commit/9583cc3cb192c2fced006927cfba7cd37b588605) - `fstream-npm@1.0.3`: Ensure that `main` entry in `package.json` is always - included in the bundled package tarball. - ([@coderhaoxin](https://github.com/coderhaoxin)) -* [`df89493`](https://github.com/npm/npm/commit/df894930f2716adac28740b29b2e863170919990) - `fstream@1.0.7` ([@isaacs](https://github.com/isaacs)) -* [`9744049`](https://github.com/npm/npm/commit/974404934758124aa8ae5b54f7d5257c3bd6b588) - `dezalgo@1.0.3`: `dezalgo` should be usable in the browser, and can be now - that `asap` has been upgraded to be browserifiable. - ([@mvayngrib](https://github.com/mvayngrib)) - -### v2.11.3 (2015-06-11): - -This was a very quiet week. This release was done by -[@iarna](https://github.com/iarna), while the rest of the team hangs out at -NodeConf Adventure! - -#### TESTS IN 0.8 FAIL LESS - -* [`5b3b3c2`](https://github.com/npm/npm/commit/5b3b3c2) - [#8491](//github.com/npm/npm/pull/8491) - Updates a test to use only 0.8 compatible features - ([@watilde](https://github.com/watilde)) - -#### THE TREADMILL OF UPDATES NEVER CEASES - -* [`9f439da`](https://github.com/npm/npm/commit/9f439da) - `spdx@0.4.1`: License range updates - ([@kemitchell](https://github.com/kemitchell)) -* [`2dd055b`](https://github.com/npm/npm/commit/2dd055b) - `normalize-package-data@2.2.1`: Fixes a crashing bug when the package.json - `scripts` property is not an object. - ([@iarna](https://github.com/iarna)) -* [`e02e85d`](https://github.com/npm/npm/commit/e02e85d) - `osenv@0.1.2`: Switches to using the `os-tmpdir` module instead of - `os.tmpdir()` for greater consistency in behavior between node versions. - ([@iarna](https://github.com/iarna)) -* [`a6f0265`](https://github.com/npm/npm/commit/a6f0265) - `ini@1.3.4` ([@isaacs](https://github.com/isaacs)) -* [`7395977`](https://github.com/npm/npm/commit/7395977) - `rimraf@2.4.0` ([@isaacs](https://github.com/isaacs)) - -### v2.11.2 (2015-06-04): - -Another small release this week, brought to you by the latest addition to the -CLI team, [@zkat](https://github.com/zkat) (Hi, all!) - -Mostly small documentation tweaks and version updates. Oh! And `npm outdated` -is actually sorted now. Rejoice! - -It's gonna be a while before we get another palindromic version number. Enjoy it -while it lasts. :3 - -#### QUALITY OF LIFE HAS NEVER BEEN BETTER - -* [`31aada4`](https://github.com/npm/npm/commit/31aada4ccc369c0903ff7f233f464955d12c6fe2) - [#8401](https://github.com/npm/npm/issues/8401) `npm outdated` output is just - that much nicer to consume now, due to sorting by name. - ([@watilde](https://github.com/watilde)) -* [`458a919`](https://github.com/npm/npm/commit/458a91925d8b20c5e672ba71a86745aad654abaf) - [#8469](https://github.com/npm/npm/pull/8469) Explicitly set `cwd` for - `preversion`, `version`, and `postversion` scripts. This makes the scripts - findable relative to the root dir. - ([@alexkwolfe](https://github.com/alexkwolfe)) -* [`55d6d71`](https://github.com/npm/npm/commit/55d6d71562e979e745c9db88861cc39f99b9f3ec) - Ensure package name and version are included in display during `npm version` - lifecycle execution. Gets rid of those little `undefined`s in the console. - ([@othiym23](https://github.com/othiym23)) - -#### WORDS HAVE NEVER BEEN QUITE THIS READABLE - -* [`3901e49`](https://github.com/npm/npm/commit/3901e4974c800e7f9fba4a5b2ff88da1126d5ef8) - [#8462](https://github.com/npm/npm/pull/8462) English apparently requires - correspondence between indefinite articles and attached nouns. - ([@Enet4](https://github.com/Enet4)) -* [`5a744e4`](https://github.com/npm/npm/commit/5a744e4b143ef7b2f50c80a1d96fdae4204d452b) - [#8421](https://github.com/npm/npm/pull/8421) The effect of `npm prune`'s - `--production` flag and how to use it have been documented a bit better. - ([@foiseworth](https://github.com/foiseworth)) -* [`eada625`](https://github.com/npm/npm/commit/eada625993485f0a2c5324b06f02bfa0a95ce4bc) - We've updated our `.mailmap` and `AUTHORS` files to make sure credit is given - where credit is due. ([@othiym23](https://github.com/othiym23)) - -#### VERSION NUMBERS HAVE NEVER BEEN BIGGER - -* [`c929fd1`](https://github.com/npm/npm/commit/c929fd1d0604b5878ed05706447e078d3e41f5b3) - `readable-stream@1.1.13`: Manually deduped `v1.1.13` (streams3) to make - deduping more reliable on `npm@<3`. ([@othiym23](https://github.com/othiym23)) -* [`a9b4b78`](https://github.com/npm/npm/commit/a9b4b78dcc85571fd1cdd737903f7f37a5e6a755) - `request@2.57.0`: Replace dependency on IncomingMessage's `.client` with - `.socket` as the former was deprecated in io.js 2.2.0. - ([@othiym23](https://github.com/othiym23)) -* [`4b5e557`](https://github.com/npm/npm/commit/4b5e557a23cdefd521ad154111e3d4dcc81f1cdb) - `abbrev@1.0.7`: Better testing, with coverage. - ([@othiym23](https://github.com/othiym23)) -* [`561affe`](https://github.com/npm/npm/commit/561affee21df9bbea5a47298f2452f533be8f359) - `semver@4.3.6`: .npmignore added for less cruft, and better testing, with coverage. - ([@othiym23](https://github.com/othiym23)) -* [`60aef3c`](https://github.com/npm/npm/commit/60aef3cf5d84d757752db3eb8ede2cb385469e7b) - `graceful-fs@3.0.8`: io.js fixes. - ([@zkat](https://github.com/zkat)) -* [`f8bd453`](https://github.com/npm/npm/commit/f8bd453b1a1c46ba7666cb166595e8a011eae443) - `config-chain@1.1.9`: Added MIT license to package.json - ([@zkat](https://github.com/zkat)) - -### v2.11.1 (2015-05-28): - -This release brought to you from poolside at the Omni Amelia Island Resort and -JSConf 2015, which is why it's so tiny. - -#### CONFERENCE WIFI CAN'T STOP THESE BUG FIXES - -* [`cf109a6`](https://github.com/npm/npm/commit/cf109a682f38a059a994da953d5c1b4aaece5e2f) - [#8381](https://github.com/npm/npm/issues/8381) Documented a subtle gotcha - with `.npmrc`, which is that it needs to have its permissions set such that - only the owner can read or write the file. - ([@colakong](https://github.com/colakong)) -* [`180da67`](https://github.com/npm/npm/commit/180da67c9fa53103d625e2f031626c2453c7ebcd) - [#8365](https://github.com/npm/npm/issues/8365) Git 2.3 adds support for - `GIT_SSH_COMMAND`, which allows you to pass an explicit git command (with, - for example, a specific identity passed in on the command line). - ([@nmalaguti](https://github.com/nmalaguti)) - -#### MY (VIRGIN) PINA COLADA IS GETTING LOW, BETTER UPGRADE THESE DEPENDENCIES - -* [`b72de41`](https://github.com/npm/npm/commit/b72de41c5cc9f0c46d3fa8f062c75bd273641474) - `node-gyp@2.0.0`: Use a newer version of `gyp`, and generally improve support - for Visual Studios and Windows. - ([@TooTallNate](https://github.com/TooTallNate)) -* [`8edbe21`](https://github.com/npm/npm/commit/8edbe210af41e8f248f5bb92c72de92f54fda3b1) - `node-gyp@2.0.1`: Don't crash when Python's version doesn't parse as valid - semver. ([@TooTallNate](https://github.com/TooTallNate)) -* [`ba0e0a8`](https://github.com/npm/npm/commit/ba0e0a845a4f29717aba566b416a27d1a22f5d08) - `glob@5.0.10`: Add coverage to tests. ([@isaacs](https://github.com/isaacs)) -* [`7333701`](https://github.com/npm/npm/commit/7333701b5d4f01673f37d64992c63c4e15864d6d) - `request@2.56.0`: Bug fixes and dependency upgrades. - ([@simov](https://github.com/simov)) - -### v2.11.0 (2015-05-21): - -For the first time in a very long time, we've added new events to the life -cycle used by `npm run-script`. Since running `npm version (major|minor|patch)` -is typically the last thing many developers do before publishing their updated -packages, it makes sense to add life cycle hooks to run tests or otherwise -preflight the package before doing a full publish. Thanks, as always, to the -indefatigable [@watilde](https://github.com/watilde) for yet another great -usability improvement for npm! - -#### FEATURELETS - -* [`b07f7c7`](https://github.com/npm/npm/commit/b07f7c7c1e5021730b3c320f1b3a46e70f8a21ff) - [#7906](https://github.com/npm/npm/issues/7906) - Add new [`scripts`](https://github.com/npm/npm/blob/master/doc/misc/npm-scripts.md) to - allow you to run scripts before and after - the [`npm version`](https://github.com/npm/npm/blob/master/doc/cli/npm-version.md) - command has run. This makes it easy to, for instance, require that your - test suite passes before bumping the version by just adding `"preversion": - "npm test"` to the scripts section of your `package.json`. - ([@watilde](https://github.com/watilde)) -* [`8a46136`](https://github.com/npm/npm/commit/8a46136f42e416cbadb533bcf89d73d681ed421d) - [#8185](https://github.com/npm/npm/issues/8185) - When we get a "not found" error from the registry, we'll now check to see - if the package name you specified is invalid and if so, give you a better - error message. ([@thefourtheye](https://github.com/thefourtheye)) - -#### BUG FIXES - -* [`9bcf573`](https://github.com/npm/npm/commit/9bcf5730bd0316f210dafea898afe9103849cea9) - [#8324](https://github.com/npm/npm/pull/8324) On Windows, when you've configured a - custom `node-gyp`, run it with node itself instead of using the default open action (which - is almost never what you want). ([@bangbang93](https://github.com/bangbang93)) -* [`1da9b04`](https://github.com/npm/npm/commit/1da9b0411d3416c7fca17d08cbbcfca7ae86e92d) - [#7195](https://github.com/npm/npm/issues/7195) - [#7260](https://github.com/npm/npm/issues/7260) `npm-registry-client@6.4.0`: - (Re-)allow publication of existing mixed-case packages (part 1). - ([@smikes](https://github.com/smikes)) -* [`e926783`](https://github.com/npm/npm/commit/e9267830ab261c751f12723e84d2458ae9238646) - [#7195](https://github.com/npm/npm/issues/7195) - [#7260](https://github.com/npm/npm/issues/7260) - `normalize-package-data@2.2.0`: (Re-)allow publication of existing mixed-case - packages (part 2). ([@smikes](https://github.com/smikes)) - -#### DOCUMENTATION IMPROVEMENTS - -* [`f62ee05`](https://github.com/npm/npm/commit/f62ee05333b141539a8e851c620dd2e82ff06860) - [#8314](https://github.com/npm/npm/issues/8314) Update the README to warn - folks away from using the CLI's internal API. For the love of glob, just use a - child process to run the CLI! ([@claycarpenter](https://github.com/claycarpenter)) -* [`1093921`](https://github.com/npm/npm/commit/1093921c04db41ab46db24a170a634a4b2acd8d9) - [#8279](https://github.com/npm/npm/pull/8279) - Update the documentation to note that, yes, you can publish scoped packages to the - public registry now! ([@mantoni](https://github.com/mantoni)) -* [`f87cde5`](https://github.com/npm/npm/commit/f87cde5234a760d3e515ffdaacaed6f5b71dbf44) - [#8292](https://github.com/npm/npm/pull/8292) - Fix typo in an example and grammar in the description in - the [shrinkwrap documentation](https://github.com/npm/npm/blob/master/doc/cli/npm-shrinkwrap.md). - ([@vshih](https://github.com/vshih)) -* [`d3526ce`](https://github.com/npm/npm/commit/d3526ceb09a0c29fdb7d4124536ae09057d033e7) - Improve the formatting in - the [shrinkwrap documentation](https://github.com/npm/npm/blob/master/doc/cli/npm-shrinkwrap.md). - ([@othiym23](https://github.com/othiym23)) -* [`19fe6d2`](https://github.com/npm/npm/commit/19fe6d20883e28956ff916fe4dae42d73ee6195b) - [#8311](https://github.com/npm/npm/pull/8311) - Update [README.md](https://github.com/npm/npm#readme) to use syntax highlighting in - its code samples and bits of shell scripts. ([@SimenB](https://github.com/SimenB)) - -#### DEPENDENCY UPDATES! ALWAYS AND FOREVER! - -* [`fc52160`](https://github.com/npm/npm/commit/fc52160d0223226fffe4166f42fdfd3b899b3c1e) - [#4700](https://github.com/npm/npm/issues/4700) [#5044](https://github.com/npm/npm/issues/5044) - `init-package-json@1.6.0`: Make entering an invalid version while running `npm init` give - you an immediate error and prompt you to correct it. ([@watilde](https://github.com/watilde)) -* [`738853e`](https://github.com/npm/npm/commit/738853eb1f55636476a2a410c2c04732eec9d51e) - [#7763](https://github.com/npm/npm/issues/7763) `fs-write-stream-atomic@1.0.3`: Fix a bug - where errors would not propagate, making error messages unhelpful. - ([@iarna](https://github.com/iarna)) -* [`6d74a2d`](https://github.com/npm/npm/commit/6d74a2d2ac7f92750cf6a2cfafae1af23b569098) - `npm-package-arg@4.0.1`: Fix tests on windows ([@Bacra](https://github.com)) and with - more recent `hosted-git-info`. ([@iarna](https://github.com/iarna)) -* [`50f7178`](https://github.com/npm/npm/commit/50f717852fbf713ef6cbc4e0a9ab42657decbbbd) - `hosted-git-info@2.1.4`: Correct spelling in its documentation. - ([@iarna](https://github.com/iarna)) -* [`d7956ca`](https://github.com/npm/npm/commit/d7956ca17c057d5383ff0d3fc5cf6ac2940b034d) - `glob@5.0.7`: Fix a bug where unusual error conditions could make - further use of the module fail. ([@isaacs](https://github.com/isaacs)) -* [`44f7d74`](https://github.com/npm/npm/commit/44f7d74c5d3181d37da7ea7949c86b344153f8d9) - `tap@1.1.0`: Update to the most recent tap to get a whole host of bug - fixes and integration with [coveralls](https://coveralls.io/). - ([@isaacs](https://github.com/isaacs)) -* [`c21e8a8`](https://github.com/npm/npm/commit/c21e8a8d94bcf0ad79dc583ddc53f8366d4813b3) - `nock@2.2.0` ([@othiym23](https://github.com/othiym23)) - -#### LICENSE FILES FOR THE LICENSE GOD - -* Add missing ISC license file to package ([@kasicka](https://github.com/kasicka)): - * [`aa9908c`](https://github.com/npm/npm/commit/aa9908c20017729673b9d410b77f9a16b7aae8a4) `realize-package-specifier@3.0.1` - * [`23a3b1a`](https://github.com/npm/npm/commit/23a3b1a726b9176c70ce0ccf3cd9d25c54429bdf) `fs-vacuum@1.2.6` - * [`8e04bba`](https://github.com/npm/npm/commit/8e04bba830d4353d84751d21803cd127c96153a7) `dezalgo@1.0.2` - * [`50f7178`](https://github.com/npm/npm/commit/50f717852fbf713ef6cbc4e0a9ab42657decbbbd) `hosted-git-info@2.1.4` - * [`6a54917`](https://github.com/npm/npm/commit/6a54917fbd4df995495a95d4b548defd44b77c93) `write-file-atomic@1.1.2` - * [`971f92c`](https://github.com/npm/npm/commit/971f92c4a4e5514217d1e4db45d1ccf71a60ff19) `async-some@1.0.2` - * [`67b50b7`](https://github.com/npm/npm/commit/67b50b7667a42bb3340a660eb2e617e1a554d2d4) `normalize-git-url@1.0.1` - -#### SPDX LICENSE UPDATES - -* Switch license to - [BSD-2-Clause](http://spdx.org/licenses/BSD-2-Clause.html#licenseText) from - plain "BSD" ([@isaacs](https://github.com/isaacs)): - * [`efdb733`](https://github.com/npm/npm/commit/efdb73332eeedcad4c609796929070b62abb37ab) `npm-user-validate@0.1.2` - * [`e926783`](https://github.com/npm/npm/commit/e9267830ab261c751f12723e84d2458ae9238646) `normalize-package-data@2.2.0` -* Switch license to [ISC](http://spdx.org/licenses/ISC.html#licenseText) from - [BSD](http://spdx.org/licenses/BSD-2-Clause.html#licenseText) - ([@isaacs](https://github.com/isaacs)): - * [`c300956`](https://github.com/npm/npm/commit/c3009565a964f0ead4ac4ab234b1a458e2365f17) `block-stream@0.0.8` - * [`1de1253`](https://github.com/npm/npm/commit/1de125355765fecd31e682ed0ff9d2edbeac0bb0) `lockfile@1.0.1` - * [`0d5698a`](https://github.com/npm/npm/commit/0d5698ab132e376c7aec93ae357c274932116220) `osenv@0.1.1` - * [`2e84921`](https://github.com/npm/npm/commit/2e84921474e1ffb18de9fce4616e73171fa8046d) `abbrev@1.0.6` - * [`872fac9`](https://github.com/npm/npm/commit/872fac9d10c11607e4d0348c08a683b84e64d30b) `chmodr@0.1.1` - * [`01eb7f6`](https://github.com/npm/npm/commit/01eb7f60acba584346ad8aae846657899f3b6887) `chownr@0.0.2` - * [`294336f`](https://github.com/npm/npm/commit/294336f0f31c7b9fe31a50075ed750db6db134d1) `read@1.0.6` - * [`ebdf6a1`](https://github.com/npm/npm/commit/ebdf6a14d17962cdb7128402c53b452f91d44ca7) `graceful-fs@3.0.7` -* Switch license to [ISC](http://spdx.org/licenses/ISC.html#licenseText) from - [MIT](http://spdx.org/licenses/MIT.html#licenseText) - ([@isaacs](https://github.com/isaacs)): - * [`e5d237f`](https://github.com/npm/npm/commit/e5d237fc0f436dd2a89437ebf8a9632a2e35ccbe) `nopt@3.0.2` - * [`79fef14`](https://github.com/npm/npm/commit/79fef1421b78f044980f0d1bf0e97039b6992710) `rimraf@2.3.4` - * [`22527da`](https://github.com/npm/npm/commit/22527da4816e7c2746cdc0317c5fb4a85152d554) `minimatch@2.0.8` - * [`882ac87`](https://github.com/npm/npm/commit/882ac87a6c4123ca985d7ad4394ea5085e5b0ef5) `lru-cache@2.6.4` - * [`9d9d015`](https://github.com/npm/npm/commit/9d9d015a2e972f68664dda54fbb204db28b21ede) `npmlog@1.2.1` - -### v2.10.1 (2015-05-14): - -#### BUG FIXES & DOCUMENTATION TWEAKS - -* [`dc77520`](https://github.com/npm/npm/commit/dc7752013ffce13a3d3f13e518a0052c22fc1158) - When getting back a 404 from a request to a private registry that uses a - registry path that extends past the root - (`http://registry.enterprise.co/path/to/registry`), display the name of the - nonexistent package, rather than the first element in the registry API path. - Sorry, Artifactory users! ([@hayes](https://github.com/hayes)) -* [`f70dea9`](https://github.com/npm/npm/commit/f70dea9b4766f6eaa55012c3e8087e9cb04fd4ce) - Make clearer that `--registry` can be used on a per-publish basis to push a - package to a non-default registry. ([@mischkl](https://github.com/mischkl)) -* [`a3e26f5`](https://github.com/npm/npm/commit/a3e26f5b4465991a941a325468ab7725670d2a94) - Did you know that GitHub shortcuts can have commit-ishes included - (`org/repo#branch`)? They can! ([@iarna](https://github.com/iarna)) -* [`0e2c091`](https://github.com/npm/npm/commit/0e2c091a539b61fdc60423b6bbaaf30c24e4b1b8) - Some errors from `readPackage` were being swallowed, potentially leading to - invalid package trees on disk. ([@smikes](https://github.com/smikes)) - -#### DEPENDENCY UPDATES! STILL! MORE! AGAIN! - -* [`0b901ad`](https://github.com/npm/npm/commit/0b901ad0811d84dda6ca0755a9adc8d47825edd0) - `lru-cache@2.6.3`: Removed some cruft from the published package. - ([@isaacs](https://github.com/isaacs)) -* [`d713e0b`](https://github.com/npm/npm/commit/d713e0b14930c563e3fdb6ac6323bae2a8924652) - `mkdirp@0.5.1`: Made compliant with `standard`, dropped support for Node 0.6, - added (Travis) support for Node 0.12 and io.js. - ([@isaacs](https://github.com/isaacs)) -* [`a2d6578`](https://github.com/npm/npm/commit/a2d6578b6554c5c9d48fe2006751759f4da57520) - `glob@1.0.3`: Updated to use `tap@1`. ([@isaacs](https://github.com/isaacs)) -* [`64cd1a5`](https://github.com/npm/npm/commit/64cd1a570aaa5f24ccba190948ec9456297c97f5) - `fstream@ 1.0.6`: Made compliant with [`standard`](http://npm.im/standard) - (done by [@othiym23](https://github.com/othiym23), and then debugged and - fixed by [@iarna](https://github.com/iarna)), and license changed to ISC. - ([@othiym23](https://github.com/othiym23) / - [@iarna](https://github.com/iarna)) -* [`b527a7c`](https://github.com/npm/npm/commit/b527a7c2ba3c4002f443dd2c536ff4ff41a38b86) - `which@1.1.1`: Callers can pass in their own `PATH` instead of relying on - `process.env`. ([@isaacs](https://github.com/isaacs)) - -### v2.10.0 (2015-05-8): - -#### THE IMPLICATIONS ARE MORE PROFOUND THAN THEY APPEAR - -If you've done much development in The Enterprise®™, you know that keeping -track of software licenses is far more important than one might expect / hope / -fear. Tracking licenses is a hassle, and while many (if not most) of us have -(reluctantly) gotten around to setting a license to use by default with all our -new projects (even if it's just WTFPL), that's about as far as most of us think -about it. In big enterprise shops, ensuring that projects don't inadvertently -use software with unacceptably encumbered licenses is serious business, and -developers spend a surprising (and appalling) amount of time ensuring that -licensing is covered by writing automated checkers and other license auditing -tools. - -The Linux Foundation has been working on a machine-parseable syntax for license -expressions in the form of [SPDX](https://spdx.org/), an appropriately -enterprisey acronym. IP attorney and JavaScript culture hero [Kyle -Mitchell](http://kemitchell.com/) has put a considerable amount of effort into -bringing SPDX to JavaScript and Node. He's written -[`spdx.js`](https://github.com/kemitchell/spdx.js), a JavaScript SPDX -expression parser, and has integrated it into npm in a few different ways. - -For you as a user of npm, this means: - -* npm now has proper support for dual licensing in `package.json`, due to - SPDX's compound expression syntax. Run `npm help package.json` for details. -* npm will warn you if the `package.json` for your project is either missing a - `"license"` field, or if the value of that field isn't a valid SPDX - expression (pro tip: `"BSD"` becomes `"BSD-2-Clause"` in SPDX (unless you - really want one of its variants); `"MIT"` and `"ISC"` are fine as-is; the - [full list](https://github.com/shinnn/spdx-license-ids/blob/master/spdx-license-ids.json) - is its own package). -* `npm init` now demands that you use a valid SPDX expression when using it - interactively (pro tip: I mostly use `npm init -y`, having previously run - `npm config set init.license=MIT` / `npm config set init.author.email=foo` / - `npm config set init.author.name=me`). -* The documentation for `package.json` has been updated to tell you how to use - the `"license"` field properly with SPDX. - -In general, this shouldn't be a big deal for anybody other than people trying -to run their own automated license validators, but in the long run, if -everybody switches to this format, many people's lives will be made much -simpler. I think this is an important improvement for npm and am very thankful -to Kyle for taking the lead on this. Also, even if you think all of this is -completely stupid, just [choose a license](http://en.wikipedia.org/wiki/License-free_software) -anyway. Future you will thank past you someday, unless you are -[djb](http://cr.yp.to/), in which case you are djb, and more power to you. - -* [`8669f7d`](https://github.com/npm/npm/commit/8669f7d88c472ccdd60e140106ac43cca636a648) - [#8179](https://github.com/npm/npm/issues/8179) Document how to use SPDX in - `license` stanzas in `package.json`, including how to migrate from old busted - license declaration arrays to fancy new compound-license clauses. - ([@kemitchell](https://github.com/kemitchell)) -* [`98ad98c`](https://github.com/npm/npm/commit/98ad98cb11f3d3ba29a488ef1ab050b066d9c7f6) - [#8197](https://github.com/npm/npm/issues/8197) `init-package-json@1.5.0` - Ensure that packages bootstrapped with `npm init` use an SPDX-compliant - license expression. ([@kemitchell](https://github.com/kemitchell)) -* [`2ad3905`](https://github.com/npm/npm/commit/2ad3905e9139b0be2b22accf707b814469de813e) - [#8197](https://github.com/npm/npm/issues/8197) - `normalize-package-data@2.1.0`: Warn when a package is missing a license - declaration, or using a license expression that isn't valid SPDX. - ([@kemitchell](https://github.com/kemitchell)) -* [`127bb73`](https://github.com/npm/npm/commit/127bb73ccccc59a1267851c702d8ebd3f3a97e81) - [#8197](https://github.com/npm/npm/issues/8197) `tar@2.1.1`: Switch from - `BSD` to `ISC` for license, where the latter is valid SPDX. - ([@othiym23](https://github.com/othiym23)) -* [`e9a933a`](https://github.com/npm/npm/commit/e9a933a9148180d9d799f99f4154f5110ff2cace) - [#8197](https://github.com/npm/npm/issues/8197) `once@1.3.2`: Switch from - `BSD` to `ISC` for license, where the latter is valid SPDX. - ([@othiym23](https://github.com/othiym23)) -* [`412401f`](https://github.com/npm/npm/commit/412401fb6a19b18f3e02d97a24d4dafed650c186) - [#8197](https://github.com/npm/npm/issues/8197) `semver@4.3.4`: Switch from - `BSD` to `ISC` for license, where the latter is valid SPDX. - ([@othiym23](https://github.com/othiym23)) - -As a corollary to the previous changes, I've put some work into making `npm -install` spew out fewer pointless warnings about missing values in transitive -dependencies. From now on, npm will only warn you about missing READMEs, -license fields, and the like for top-level projects (including packages you -directly install into your application, but we may relax that eventually). - -Practically _nobody_ liked having those warnings displayed for child -dependencies, for the simple reason that there was very little that anybody -could _do_ about those warnings, unless they happened to be the maintainers of -those dependencies themselves. Since many, many projects don't have -SPDX-compliant licenses, the number of warnings reached a level where they ran -the risk of turning into a block of visual noise that developers (read: me, and -probably you) would ignore forever. - -So I fixed it. If you still want to see the messages about child dependencies, -they're still there, but have been pushed down a logging level to `info`. You -can display them by running `npm install -d` or `npm install --loglevel=info`. - -* [`eb18245`](https://github.com/npm/npm/commit/eb18245f55fb4cd62a36867744bcd1b7be0a33e2) - Only warn on normalization errors for top-level dependencies. Transitive - dependency validation warnings are logged at `info` level. - ([@othiym23](https://github.com/othiym23)) - -#### BUG FIXES - -* [`e40e809`](https://github.com/npm/npm/commit/e40e8095d2bc9fa4eb8f01aa22067e0068fa8a54) - `tap@1.0.1`: TAP: The Next Generation. Fix up many tests to they work - properly with the new major version of `node-tap`. Look at all the colors! - ([@isaacs](https://github.com/isaacs)) -* [`f9314e9`](https://github.com/npm/npm/commit/f9314e97d26532c0ef2b03e98f3ed300b7cd5026) - `nock@1.9.0`: Minor tweaks and bug fixes. ([@pgte](https://github.com/pgte)) -* [`45c2b1a`](https://github.com/npm/npm/commit/45c2b1aaa051733fa352074994ae6e569fd51e8b) - [#8187](https://github.com/npm/npm/issues/8187) `npm ls` wasn't properly - recognizing dependencies installed from GitHub repositories as git - dependencies, and so wasn't displaying them as such. - ([@zornme](https://github.com/zornme)) -* [`1ab57c3`](https://github.com/npm/npm/commit/1ab57c38116c0403965c92bf60121f0f251433e4) - In some cases, `npm help` was using something that looked like a regular - expression where a glob pattern should be used, and vice versa. - ([@isaacs](https://github.com/isaacs)) - -### v2.9.1 (2015-04-30): - -#### WOW! MORE GIT FIXES! YOU LOVE THOSE! - -The first item below is actually a pretty big deal, as it fixes (with a -one-word change and a much, much longer test case (thanks again, -[@iarna](https://github.com/iarna))) a regression that's been around for months -now. If you're depending on multiple branches of a single git dependency in a -single project, you probably want to check out `npm@2.9.1` and verify that -things (again?) work correctly in your project. - -* [`178a6ad`](https://github.com/npm/npm/commit/178a6ad540215820d16217465a5f220d8c95a313) - [#7202](https://github.com/npm/npm/issues/7202) When caching git - dependencies, do so by the whole URL, including the branch name, so that if a - single application depends on multiple branches from the same repository (in - practice, multiple version tags), every install is of the correct version, - instead of reusing whichever branch the caching process happened to check out - first. ([@iarna](https://github.com/iarna)) -* [`63b79cc`](https://github.com/npm/npm/commit/63b79ccde092a9cb3b1f34abe43e1d2ba69c0dbf) - [#8084](https://github.com/npm/npm/issues/8084) Ensure that Bitbucket, - GitHub, and Gitlab dependencies are installed the same way as non-hosted git - dependencies, fixing `npm install --link`. - ([@laiso](https://github.com/laiso)) - -#### DOCUMENTATION FIXES AND TWEAKS - -These changes may seem simple and small (except Lin's fix to the package name -restrictions, which was more an egregious oversight on our part), but cleaner -documentation makes npm significantly more pleasant to use. I really appreciate -all the typo fixes, clarifications, and formatting tweaks people send us, and -am delighted that we get so many of these pull requests. Thanks, everybody! - -* [`ca478dc`](https://github.com/npm/npm/commit/ca478dcaa29b8f07cd6fe515a3c4518166819291) - [#8137](https://github.com/npm/npm/issues/8137) Somehow, we had failed to - clearly document the full restrictions on package names. - [@linclark](https://github.com/linclark) has now fixed that, although we will - take with us to our graves the reasons why the maximum package name length is 214 - characters (well, OK, it was that that was the longest name in the registry - when we decided to put a cap on the name length). - ([@linclark](https://github.com/linclark)) -* [`b574076`](https://github.com/npm/npm/commit/b5740767c320c1eff3576a8d63952534a0fbb936) - [#8079](https://github.com/npm/npm/issues/8079) Make the `npm shrinkwrap` - documentation use code formatting for examples consistently. It would be - great to do this for more commands HINT HINT. - ([@RichardLitt](https://github.com/RichardLitt)) -* [`1ff636e`](https://github.com/npm/npm/commit/1ff636e2db3852a53e38c866fed7eafdacd307fc) - [#8105](https://github.com/npm/npm/issues/8105) Document that the global - `npmrc` goes in `$PREFIX/etc/npmrc`, instead of `$PREFIX/npmrc`. - ([@anttti](https://github.com/anttti)) -* [`c3f2f7c`](https://github.com/npm/npm/commit/c3f2f7c299342e1c1eccc55a976a63c607f51621) - [#8127](https://github.com/npm/npm/issues/8127) Document how to use `npm run - build` directly (hint: it's different from `npm build`!). - ([@mikemaccana](https://github.com/mikemaccana)) -* [`873e467`](https://github.com/npm/npm/commit/873e46757e1986761b15353f94580a071adcb383) - [#8069](https://github.com/npm/npm/issues/8069) Take the old, dead npm - mailing list address out of `package.json`. It seems that people don't have - much trouble figuring out how to report errors to npm. - ([@robertkowalski](https://github.com/robertkowalski)) - -#### ENROBUSTIFICATIONMENT - -* [`5abfc9c`](https://github.com/npm/npm/commit/5abfc9c9017da714e47a3aece750836b4f9af6a9) - [#7973](https://github.com/npm/npm/issues/7973) `npm run-script` completion - will only suggest run scripts, instead of including dependencies. If for some - reason you still wanted it to suggest dependencies, let us know. - ([@mantoni](https://github.com/mantoni)) -* [`4b564f0`](https://github.com/npm/npm/commit/4b564f0ce979dc74c09604f4d46fd25a2ee63804) - [#8081](https://github.com/npm/npm/issues/8081) Use `osenv` to parse the - environment's `PATH` in a platform-neutral way. - ([@watilde](https://github.com/watilde)) -* [`a4b6238`](https://github.com/npm/npm/commit/a4b62387b41848818973eeed056fd5c6570274f3) - [#8094](https://github.com/npm/npm/issues/8094) When we refactored the - configuration code to split out checking for IPv4 local addresses, we - inadvertently completely broke it by failing to return the values. In - addition, just the call to `os.getInterfaces()` could throw on systems where - querying the network configuration requires elevated privileges (e.g. Amazon - Lambda). Add the return, and trap errors so they don't cause npm to explode. - Thanks to [@mhart](https://github.com/mhart) for bringing this to our - attention! ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY UPDATES WAIT FOR NO SOPHONT - -* [`000cd8b`](https://github.com/npm/npm/commit/000cd8b52104942ac3404f0ad0651d82f573da37) - `rimraf@2.3.3`: More informative assertions on argument validation failure. - ([@isaacs](https://github.com/isaacs)) -* [`530a2e3`](https://github.com/npm/npm/commit/530a2e369128270f3e098f0e9be061533003b0eb) - `lru-cache@2.6.2`: Revert to old key access-time behavior, as it was correct - all along. ([@isaacs](https://github.com/isaacs)) -* [`d88958c`](https://github.com/npm/npm/commit/d88958ca02ce81b027b9919aec539d0145875a59) - `minimatch@2.0.7`: Feature detection and test improvements. - ([@isaacs](https://github.com/isaacs)) -* [`3fa39e4`](https://github.com/npm/npm/commit/3fa39e4d492609d5d045033896dcd99f7b875329) - `nock@1.7.1` ([@pgte](https://github.com/pgte)) - -### v2.9.0 (2015-04-23): - -This week was kind of a breather to concentrate on fixing up the tests on the -`multi-stage` branch, and not mess with git issues for a little while. -Unfortunately, There are now enough severe git issues that we'll probably have -to spend another couple weeks tackling them. In the meantime, enjoy these two -small features. They're just enough to qualify for a semver-minor bump: - -#### NANOFEATURES - -* [`2799322`](https://github.com/npm/npm/commit/279932298ce5b589c5eea9439ac40b88b99c6a4a) - [#7426](https://github.com/npm/npm/issues/7426) Include local modules in `npm - outdated` and `npm update`. ([@ArnaudRinquin](https://github.com/ArnaudRinquin)) -* [`2114862`](https://github.com/npm/npm/commit/21148620fa03a582f4ec436bb16bd472664f2737) - [#8014](https://github.com/npm/npm/issues/8014) The prefix used before the - version on version tags is now configurable via `tag-version-prefix`. Be - careful with this one and read the docs before using it. - ([@kkragenbrink](https://github.com/kkragenbrink)) - -#### OTHER MINOR TWEAKS - -* [`18ce0ec`](https://github.com/npm/npm/commit/18ce0ecd2d94ad3af01e997f1396515892dd363c) - [#3032](https://github.com/npm/npm/issues/3032) `npm unpublish` will now use - the registry set in `package.json`, just like `npm publish`. This only - applies, for now, when unpublishing the entire package, as unpublishing a - single version requires the name be included on the command line and - therefore doesn't read from `package.json`. ([@watilde](https://github.com/watilde)) -* [`9ad2100`](https://github.com/npm/npm/commit/9ad210042242e51d52b2a8b633d8e59248f5faa4) - [#8008](https://github.com/npm/npm/issues/8008) Once again, when considering - what to install on `npm install`, include `devDependencies`. - ([@smikes](https://github.com/smikes)) -* [`5466260`](https://github.com/npm/npm/commit/546626059909dca1906454e820ca4e315c1795bd) - [#8003](https://github.com/npm/npm/issues/8003) Clarify the documentation - around scopes to make it easier to understand how they support private - packages. ([@smikes](https://github.com/smikes)) - -#### DEPENDENCIES WILL NOT STOP UNTIL YOU ARE VERY SLEEPY - -* [`faf65a7`](https://github.com/npm/npm/commit/faf65a7bbb2fad13216f64ed8f1243bafe743f97) - `init-package-json@1.4.2`: If there are multiple validation errors and - warnings, ensure they all get displayed (includes a rad new way of testing - `init-package-json` contributed by - [@michaelnisi](https://github.com/michaelnisi)). - ([@MisumiRize](https://github.com/MisumiRize)) -* [`7f10f38`](https://github.com/npm/npm/commit/7f10f38d29a8423d7cde8103fa7b64ac728da1e0) - `editor@1.0.0`: `1.0.0` is literally more than `0.1.0` (no change aside from - version number). ([@substack](https://github.com/substack)) -* [`4979af3`](https://github.com/npm/npm/commit/4979af3fcae5a3962383b7fdad3162381e62eefe) - [#6805](https://github.com/npm/npm/issues/6805) `npm-registry-client@6.3.3`: - Decode scoped package names sent by the registry so they look nicer. - ([@mmalecki](https://github.com/mmalecki)) - -### v2.8.4 (2015-04-16): - -This is the fourth release of npm this week, so it's mostly just landing a few -small outstanding PRs on dependencies and some tiny documentation tweaks. -`npm@2.8.3` is where the real action is. - -* [`ee2bd77`](https://github.com/npm/npm/commit/ee2bd77f3c64d38735d1d31028224a5c40422a9b) - [#7983](https://github.com/npm/npm/issues/7983) `tar@2.1.0`: Better error - reporting in corrupted tar files, and add support for the `fromBase` flag - (rescued from the dustbin of history by - [@deanmarano](https://github.com/deanmarano)). - ([@othiym23](https://github.com/othiym23)) -* [`d8eee6c`](https://github.com/npm/npm/commit/d8eee6cf9d2ff7aca68dfaed2de76824a3e0d9af) - `init-package-json@1.4.1`: Add support for a default author, and only add - scope to a package name once. ([@othiym23](https://github.com/othiym23)) -* [`4fc5d98`](https://github.com/npm/npm/commit/4fc5d98b785f601c60d4dc0a2c8674f0cccf6262) - `lru-cache@2.6.1`: Small tweaks to cache value aging and entry counting that - are irrelevant to npm. ([@isaacs](https://github.com/isaacs)) -* [`1fe5840`](https://github.com/npm/npm/commit/1fe584089f5bef133de5518aa26eaf6064be2bf7) - [#7946](https://github.com/npm/npm/issues/7946) Make `npm init` text - friendlier. ([@sandfox](https://github.com/sandfox)) - -### v2.8.3 (2015-04-15): - -#### TWO SMALL GIT TWEAKS - -This is the last of a set of releases intended to ensure npm's git support is -robust enough that we can stop working on it for a while. These fixes are -small, but prevent a common crasher and clear up one of the more confusing -error messages coming out of npm when working with repositories hosted on git. - -* [`387f889`](https://github.com/npm/npm/commit/387f889c0e8fb617d9cc9a42ed0a3ec49424ab5d) - [#7961](https://github.com/npm/npm/issues/7961) Ensure that hosted git SSH - URLs always have a valid protocol when stored in `resolved` fields in - `npm-shrinkwrap.json`. ([@othiym23](https://github.com/othiym23)) -* [`394c2f5`](https://github.com/npm/npm/commit/394c2f5a1227232c0baf42fbba1402aafe0d6ffb) - Switch the order in which hosted Git providers are checked to `git:`, - `git+https:`, then `git+ssh:` (from `git:`, `git+ssh:`, then `git+https:`) in - an effort to go from most to least likely to succeed, to make for less - confusing error message. ([@othiym23](https://github.com/othiym23)) - -### v2.8.2 (2015-04-14): - -#### PEACE IN OUR TIME - -npm has been having an issue with CouchDB's web server since the release -of io.js and Node.js 0.12.0 that has consumed a huge amount of my time -to little visible effect. Sam Mikes picked up the thread from me, and -after a [_lot_ of effort](https://github.com/npm/npm/issues/7699#issuecomment-93091111) -figured out that ultimately there are probably a couple problems with -the new HTTP Agent keep-alive handling in new versions of Node. In -addition, `npm-registry-client` was gratuitously sending a body along -with a GET request which was triggering the bugs. Sam removed about 10 bytes from -one file in `npm-registry-client`, and this problem, which has been bugging us for months, -completely went away. - -In conclusion, Sam Mikes is great, and anybody using a private registry -hosted on CouchDB should thank him for his hard work. Also, thanks to -the community at large for pitching in on this bug, which has been -around for months now. - -* [`431c3bf`](https://github.com/npm/npm/commit/431c3bf6cdec50f9f0c735f478cb2f3f337d3313) - [#7699](https://github.com/npm/npm/issues/7699) `npm-registry-client@6.3.2`: - Don't send body with HTTP GET requests when logging in. - ([@smikes](https://github.com/smikes)) - -### v2.8.1 (2015-04-12): - -#### CORRECTION: NPM'S GIT INTEGRATION IS DOING OKAY - -A [helpful bug report](https://github.com/npm/npm/issues/7872#issuecomment-91809553) -led to another round of changes to -[`hosted-git-info`](https://github.com/npm/hosted-git-info/commit/827163c74531b69985d1ede7abced4861e7b0cd4), -some additional test-writing, and a bunch of hands-on testing against actual -private repositories. While the complexity of npm's git dependency handling is -nearly fractal (because npm is very complex, and git is even more complex), -it's feeling way more solid than it has for a while. We think this is a -substantial improvement over what we had before, so give `npm@2.8.1` a shot if -you have particularly complex git use cases and -[let us know](https://github.com/npm/npm/issues/new) how it goes. - -(NOTE: These changes mostly affect cloning and saving references to packages -hosted in git repositories, and don't address some known issues with things -like lifecycle scripts not being run on npm dependencies. Work continues on -other issues that affect parity between git and npm registry packages.) - -* [`66377c6`](https://github.com/npm/npm/commit/66377c6ece2cf4d53d9a618b7d9824e1452bc293) - [#7872](https://github.com/npm/npm/issues/7872) `hosted-git-info@2.1.2`: Pass - through credentials embedded in SSH and HTTPs git URLs. - ([@othiym23](https://github.com/othiym23)) -* [`15efe12`](https://github.com/npm/npm/commit/15efe124753257728a0ddc64074fa5a4b9c2eb30) - [#7872](https://github.com/npm/npm/issues/7872) Use the new version of - `hosted-git-info` to pass along credentials embedded in git URLs. Test it. - Test it a lot. ([@othiym23](https://github.com/othiym23)) - -#### SCOPED DEPENDENCIES AND PEER DEPENDENCIES: NOT QUITE REESE'S - -Big thanks to [@ewie](https://github.com/ewie) for identifying an issue with -how npm was handling `peerDependencies` that were implicitly installed from the -`package.json` files of scoped dependencies. This -[will be a moot point](https://github.com/npm/npm/issues/6565#issuecomment-74971689) -with the release of `npm@3`, but until then, it's important that -`peerDependency` auto-installation work as expected. - -* [`b027319`](https://github.com/npm/npm/commit/b0273190c71eba14395ddfdd1d9f7ba625297523) - [#7920](https://github.com/npm/npm/issues/7920) Scoped packages with - `peerDependencies` were installing the `peerDependencies` into the wrong - directory. ([@ewie](https://github.com/ewie)) -* [`649e31a`](https://github.com/npm/npm/commit/649e31ae4fd02568bae5dc6b4ea783431ce3d63e) - [#7920](https://github.com/npm/npm/issues/7920) Test `peerDependency` - installs involving scoped packages using `npm-package-arg` instead of simple - path tests, for consistency. ([@othiym23](https://github.com/othiym23)) - -#### MAKING IT EASIER TO WRITE NPM TESTS, VERSION 0.0.1 - -[@iarna](https://github.com/iarna) and I -([@othiym23](https://github.com/othiym23)) have been discussing a -[candidate plan](https://github.com/npm/npm/wiki/rewriting-npm's-tests:-a-plan-maybe) -for improving npm's test suite, with the goal of making it easier for new -contributors to get involved with npm by reducing the learning curve -necessary to be able to write good tests for proposed changes. This is the -first substantial piece of that effort. Here's what the commit message for -[`ed7e249`](https://github.com/npm/npm/commit/ed7e249d50444312cd266942ce3b89e1ca049bdf) -had to say about this work: - -> It's too difficult for npm contributors to figure out what the conventional -> style is for tests. Part of the problem is that the documentation in -> CONTRIBUTING.md is inadequate, but another important factor is that the tests -> themselves are written in a variety of styles. One of the most notable -> examples of this is the fact that many tests use fixture directories to store -> precooked test scenarios and package.json files. -> -> This had some negative consequences: -> -> * tests weren't idempotent -> * subtle dependencies between tests existed -> * new tests get written in this deprecated style because it's not -> obvious that the style is out of favor -> * it's hard to figure out why a lot of those directories existed, -> because they served a variety of purposes, so it was difficult to -> tell when it was safe to remove them -> -> All in all, the fixture directories were a major source of technical debt, and -> cleaning them up, while time-consuming, makes the whole test suite much more -> approachable, and makes it more likely that new tests written by outside -> contributors will follow a conventional style. To support that, all of the -> tests touched by this changed were cleaned up to pass the `standard` style -> checker. - -And here's a little extra context from a comment I left on [#7929](https://github.com/npm/npm/issues/7929): - -> One of the other things that encouraged me was looking at this -> [presentation on technical debt](http://www.slideshare.net/nnja/pycon-2015-technical-debt-the-monster-in-your-closet) -> from Pycon 2015, especially slide 53, which I interpreted in terms of -> difficulty getting new contributors to submit patches to an OSS project like -> npm. npm has a long ways to go, but I feel good about this change. - -* [`ed7e249`](https://github.com/npm/npm/commit/ed7e249d50444312cd266942ce3b89e1ca049bdf) - [#7929](https://github.com/npm/npm/issues/7929) Eliminate fixture directories - from `test/tap`, leaving each test self-contained. - ([@othiym23](https://github.com/othiym23)) -* [`4928d30`](https://github.com/npm/npm/commit/4928d30140821c63e03fffed73f8d88ebdc43710) - [#7929](https://github.com/npm/npm/issues/7929) Move fixture files from - `test/tap/*` to `test/fixtures`. ([@othiym23](https://github.com/othiym23)) -* [`e925deb`](https://github.com/npm/npm/commit/e925debca91092a814c1a00933babc3a8cf975be) - [#7929](https://github.com/npm/npm/issues/7929) Tweak the run scripts to stop - slaughtering the CPU on doc rebuild. - ([@othiym23](https://github.com/othiym23)) -* [`65bf7cf`](https://github.com/npm/npm/commit/65bf7cffaf91c426b676c47529eee796f8b8b75c) - [#7923](https://github.com/npm/npm/issues/7923) Use an alias of scripts and - run-scripts in `npm run test-all` ([@watilde](https://github.com/watilde)) -* [`756a3fb`](https://github.com/npm/npm/commit/756a3fbb852a2469afe706635ed88d22c37743e5) - [#7923](https://github.com/npm/npm/issues/7923) Sync timeout time of `npm - run-script test-all` to be the same as `test` and `tap` scripts. - ([@watilde](https://github.com/watilde)) -* [`8299b5f`](https://github.com/npm/npm/commit/8299b5fb6373354a7fbaab6f333863758812ae90) - Set a timeout for tap tests for `npm run-script test-all`. - ([@othiym23](https://github.com/othiym23)) - -#### THE EVER-BEATING DRUM OF DEPENDENCY UPDATES - -* [`d90d0b9`](https://github.com/npm/npm/commit/d90d0b992acbf62fd5d68debf9d1dbd6cfa20804) - [#7924](https://github.com/npm/npm/issues/7924) Remove `child-process-close`, - as it was included for Node 0.6 compatibility, and npm no longer supports - 0.6. ([@robertkowalski](https://github.com/robertkowalski)) -* [`16427c1`](https://github.com/npm/npm/commit/16427c1f3ea3d71ee753c62eb4c2663c7b32b84f) - `lru-cache@2.5.2`: More accurate updating of expiry times when `maxAge` is - set. ([@isaacs](https://github.com/isaacs)) -* [`03cce83`](https://github.com/npm/npm/commit/03cce83b64344a9e0fe036dce214f4d68cfcc9e7) - `nock@1.6.0`: Mocked network error handling. - ([@pgte](https://github.com/pgte)) -* [`f93b1f0`](https://github.com/npm/npm/commit/f93b1f0b7eb5d1b8a7967e837bbd756db1091d00) - `glob@5.0.5`: Use `path-is-absolute` polyfill, allowing newer Node.js and - io.js versions to use `path.isAbsolute()`. - ([@sindresorhus](https://github.com/sindresorhus)) -* [`a70d694`](https://github.com/npm/npm/commit/a70d69495a6e96997e64855d9e749d943ee6d64f) - `request@2.55.0`: Bug fixes and simplification. - ([@simov](https://github.com/simov)) -* [`2aecc6f`](https://github.com/npm/npm/commit/2aecc6f4083526feeb14615b4e5484edc66175b5) - `columnify@1.5.1`: Switch to using babel from 6to5. - ([@timoxley](https://github.com/timoxley)) - -### v2.8.0 (2015-04-09): - -#### WE WILL NEVER BE DONE FIXING NPM'S GIT SUPPORT - -If you look at [the last release's release -notes](https://github.com/npm/npm/blob/master/CHANGELOG.md#git-mean-git-tuff-git-all-the-way-away-from-my-stuff), -you will note that they confidently assert that it's perfectly OK to force all -GitHub URLs through the same `git:` -> `git+ssh:` fallback flow for cloning. It -turns out that many users depend on `git+https:` URLs in their build -environments because they use GitHub auth tokens instead of SSH keys. Also, in -some cases you just want to be able to explicitly say how a given dependency -should be cloned from GitHub. - -Because of the way we resolved the inconsistency in GitHub shorthand handling -[before](https://github.com/npm/npm/blob/master/CHANGELOG.md#bug-fixes-1), this -turned out to be difficult to work around. So instead of hacking around it, we -completely redid how git is handled within npm and its attendant packages. -Again. This time, we changed things so that `normalize-package-data` and -`read-package-json` leave more of the git logic to npm itself, which makes -handling shorthand syntax consistently much easier, and also allows users to -resume using explicit, fully-qualified git URLs without npm messing with them. - -Here's a summary of what's changed: - -* Instead of converting the GitHub shorthand syntax to a `git+ssh:`, `git:`, or - `git+https:` URL and saving that, save the shorthand itself to - `package.json`. -* If presented with shortcuts, try cloning via the git protocol, SSH, and HTTPS - (in that order). -* No longer prompt for credentials -- it didn't work right with the spinner, - and wasn't guaranteed to work anyway. We may experiment with doing this a - better way in the future. Users can override this by setting `GIT_ASKPASS` in - their environment if they want to experiment with interactive cloning, but - should also set `--no-spin` on the npm command line (or run `npm config set - spin=false`). -* **EXPERIMENTAL FEATURE**: Add support for `github:`, `gist:`, `bitbucket:`, - and `gitlab:` shorthand prefixes. GitHub shortcuts will continue to be - normalized to `org/repo` instead of being saved as `github:org/repo`, but - `gitlab:`, `gist:`, and `bitbucket:` prefixes will be used on the command - line and from `package.json`. BE CAREFUL WITH THIS. `package.json` files - published with the new shorthand syntax can _only_ be read by `npm@2.8.0` and - later, and this feature is mostly meant for playing around with it. If you - want to save git dependencies in a form that older versions of npm can read, - use `--save-exact`, which will save the git URL and resolved commit hash of - the head of the branch in a manner similar to the way that `--save-exact` - pins versions for registry dependencies. This is documented (so check `npm - help install` for details), but we're not going to make a lot of noise about - it until it has a chance to bake in a little more. - -It is [@othiym23](https://github.com/othiym23)'s sincere hope that this will -resolve all of the inconsistencies users were seeing with GitHub and git-hosted -packages, but given the level of change here, that may just be a fond wish. -Extra testing of this change is requested. - -* [`6b0f588`](https://github.com/npm/npm/commit/6b0f58877f37df9904490ffbaaad33862bd36dce) - [#7867](https://github.com/npm/npm/issues/7867) Use git shorthand and git - URLs as presented by user. Support new `hosted-git-info` shortcut syntax. - Save shorthand in `package.json`. Try cloning via `git:`, `git+ssh:`, and - `git+https:`, in that order, when supported by the underlying hosting - provider. ([@othiym23](https://github.com/othiym23)) -* [`75d4267`](https://github.com/npm/npm/commit/75d426787869d54ca7400408f562f971b34649ef) - [#7867](https://github.com/npm/npm/issues/7867) Document new GitHub, GitHub - gist, Bitbucket, and GitLab shorthand syntax. - ([@othiym23](https://github.com/othiym23)) -* [`7d92c75`](https://github.com/npm/npm/commit/7d92c7592998d90ec883fa989ca74f04ec1b93de) - [#7867](https://github.com/npm/npm/issues/7867) When `--save-exact` is used - with git shorthand or URLs, save the fully-resolved URL, with branch name - resolved to the exact hash for the commit checked out. - ([@othiym23](https://github.com/othiym23)) -* [`9220e59`](https://github.com/npm/npm/commit/9220e59f8def8c82c6d331a39ba29ad4c44e3a9b) - [#7867](https://github.com/npm/npm/issues/7867) Ensure that non-prefixed and - non-normalized GitHub shortcuts are saved to `package.json`. - ([@othiym23](https://github.com/othiym23)) -* [`dd398e9`](https://github.com/npm/npm/commit/dd398e98a8eba27eeba84378200da3d078fdf980) - [#7867](https://github.com/npm/npm/issues/7867) `hosted-git-info@2.1.1`: - Ensure that `gist:` shorthand survives being round-tripped through - `package.json`. ([@othiym23](https://github.com/othiym23)) -* [`33d1420`](https://github.com/npm/npm/commit/33d1420bf2f629332fceb2ac7e174e63ac48f96a) - [#7867](https://github.com/npm/npm/issues/7867) `hosted-git-info@2.1.0`: Add - support for auth embedded directly in git URLs. - ([@othiym23](https://github.com/othiym23)) -* [`23a1d5a`](https://github.com/npm/npm/commit/23a1d5a540e8db27f5cd0245de7c3694e2bddad1) - [#7867](https://github.com/npm/npm/issues/7867) `hosted-git-info@2.0.2`: Make - it possible to determine in which form a hosted git URL was passed. - ([@iarna](https://github.com/iarna)) -* [`eaf75ac`](https://github.com/npm/npm/commit/eaf75acb718611ad5cfb360084ec86938d9c66c5) - [#7867](https://github.com/npm/npm/issues/7867) - `normalize-package-data@2.0.0`: Normalize GitHub specifiers so they pass - through shortcut syntax and preserve explicit URLs. - ([@iarna](https://github.com/iarna)) -* [`95e0535`](https://github.com/npm/npm/commit/95e0535e365e0aca49c634dd2061a0369b0475f1) - [#7867](https://github.com/npm/npm/issues/7867) `npm-package-arg@4.0.0`: Add - git URL and shortcut to hosted git spec and use `hosted-git-info@2.0.2`. - ([@iarna](https://github.com/iarna)) -* [`a808926`](https://github.com/npm/npm/commit/a8089268d5f3d57f42dbaba02ff6437da5121191) - [#7867](https://github.com/npm/npm/issues/7867) - `realize-package-specifier@3.0.0`: Use `npm-package-arg@4.0.0` and test - shortcut specifier behavior. ([@iarna](https://github.com/iarna)) -* [`6dd1e03`](https://github.com/npm/npm/commit/6dd1e039bddf8cf5383343f91d84bc5d78acd083) - [#7867](https://github.com/npm/npm/issues/7867) `init-package-json@1.4.0`: - Allow dependency on `read-package-json@2.0.0`. - ([@iarna](https://github.com/iarna)) -* [`63254bb`](https://github.com/npm/npm/commit/63254bb6358f66752aca6aa1a275271b3ae03f7c) - [#7867](https://github.com/npm/npm/issues/7867) `read-installed@4.0.0`: Use - `read-package-json@2.0.0`. ([@iarna](https://github.com/iarna)) -* [`254b887`](https://github.com/npm/npm/commit/254b8871f5a173bb464cc5b0ace460c7878b8097) - [#7867](https://github.com/npm/npm/issues/7867) `read-package-json@2.0.0`: - Use `normalize-package-data@2.0.0`. ([@iarna](https://github.com/iarna)) -* [`0b9f8be`](https://github.com/npm/npm/commit/0b9f8be62fe5252abe54d49e36a696f4816c2eca) - [#7867](https://github.com/npm/npm/issues/7867) `npm-registry-client@6.3.0`: - Mark compatibility with `normalize-package-data@2.0.0` and - `npm-package-arg@4.0.0`. ([@iarna](https://github.com/iarna)) -* [`f40ecaa`](https://github.com/npm/npm/commit/f40ecaad68f77abc50eb6f5b224e31dec3d250fc) - [#7867](https://github.com/npm/npm/issues/7867) Extract a common method to - use when cloning git repos for testing. - ([@othiym23](https://github.com/othiym23)) - -#### TEST FIXES FOR NODE 0.8 - -npm continues to [get closer](https://github.com/npm/npm/issues/7842) to being -completely green on Travis for Node 0.8. - -* [`26d36e9`](https://github.com/npm/npm/commit/26d36e9cf0eca69fe1863d2ea536c28555b9e8de) - [#7842](https://github.com/npm/npm/issues/7842) When spawning child - processes, map exit code 127 to ENOENT so Node 0.8 handles child process - failures the same as later versions. - ([@SonicHedgehog](https://github.com/SonicHedgehog)) -* [`54cd895`](https://github.com/npm/npm/commit/54cd8956ea783f96749e46597d8c2cb9397c5d5f) - [#7842](https://github.com/npm/npm/issues/7842) Node 0.8 requires -e with -p - when evaluating snippets; fix test. - ([@SonicHedgehog](https://github.com/SonicHedgehog)) - -#### SMALL FIX AND DOC TWEAK - -* [`20e9003`](https://github.com/npm/npm/commit/20e90031b847e9f7c7168f3dad8b1e526f9a2586) - `tar@2.0.1`: Fix regression where relative symbolic links within an - extraction root that pointed within an extraction root would get normalized - to absolute symbolic links. ([@isaacs](https://github.com/isaacs)) -* [`2ef8898`](https://github.com/npm/npm/commit/2ef88989c41bee1578570bb2172c90ede129dbd1) - [#7879](https://github.com/npm/npm/issues/7879) Better document that `npm - publish --tag=foo` will not set `latest` to that version. - ([@linclark](https://github.com/linclark)) - -### v2.7.6 (2015-04-02): - -#### GIT MEAN, GIT TUFF, GIT ALL THE WAY AWAY FROM MY STUFF - -Part of the reason that we're reluctant to take patches to how npm deals with -git dependencies is that every time we touch the git support, something breaks. -The last few releases are a case in point. `npm@2.7.4` completely broke -installing private modules from GitHub, and `npm@2.7.5` fixed them at the cost -of logging a misleading error message that caused many people to believe that -their dependencies hadn't been successfully installed when they actually had -been. - -This all started from a desire to ensure that GitHub shortcut syntax is being -handled correctly. The correct behavior is for npm to try to clone all -dependencies on GitHub (whether they're specified with the GitHub -`organization/repository` shortcut syntax or not) via the plain `git:` protocol -first, and to fall back to using `git+ssh:` if `git:` doesn't work. Previously, -sometimes npm would use `git:` and `git+ssh:` in some cases (most notably when -using GitHub shortcut syntax on the command line), and use `git+https:` in -others (when the GitHub shortcut syntax was present in `package.json`). This -led to subtle and hard-to-understand inconsistencies, and we're glad that as of -`npm@2.7.6`, we've finally gotten things to where they were before we started, -only slightly more consistent overall. - -We are now going to go back to our policy of being extremely reluctant to touch -the code that handles Git dependencies. - -* [`b747593`](https://github.com/npm/npm/commit/b7475936f473f029e6a027ba1b16277523747d0b) - [#7630](https://github.com/npm/npm/issues/7630) Don't automatically log all - git failures as errors. `maybeGithub` needs to be able to fail without - logging to support its fallback logic. - ([@othiym23](https://github.com/othiym23)) -* [`cd67a0d`](https://github.com/npm/npm/commit/cd67a0db07891d20871822696c26692c8a84866a) - [#7829](https://github.com/npm/npm/issues/7829) When fetching a git remote - URL, handle failures gracefully (without assuming standard output exists). - ([@othiym23](https://github.com/othiym23)) -* [`637c7d1`](https://github.com/npm/npm/commit/637c7d1411fe07f409cf91f2e65fd70685cb253c) - [#7829](https://github.com/npm/npm/issues/7829) When fetching a git remote - URL, handle failures gracefully (without assuming standard _error_ exists). - ([@othiym23](https://github.com/othiym23)) - -#### OTHER SIGNIFICANT FIXES - -* [`78005eb`](https://github.com/npm/npm/commit/78005ebb6f4103c20f077669c3929b7ea46a4c0d) - [#7743](https://github.com/npm/npm/issues/7743) Always quote arguments passed - to `npm run-script`. This allows build systems and the like to safely escape - glob patterns passed as arguments to `run-scripts` with `npm run-script - <script> -- <arguments>`. This is a tricky change to test, and may be - reverted or moved to `npm@3` if it turns out it breaks things for users. - ([@mantoni](https://github.com/mantoni)) -* [`da015ee`](https://github.com/npm/npm/commit/da015eee45f6daf384598151d06a9b57ffce136e) - [#7074](https://github.com/npm/npm/issues/7074) `read-package-json@1.3.3`: - `read-package-json` no longer caches `package.json` files, which trades a - very small performance loss for the elimination of a large class of really - annoying race conditions. See [#7074](https://github.com/npm/npm/issues/7074) - for the grisly details. ([@othiym23](https://github.com/othiym23)) -* [`dd20f57`](https://github.com/npm/npm/commit/dd20f5755291b9433f0d298ee0eead22cda6db36) - `init-package-json@1.3.2`: Only add the `@` to scoped package names if it's - not already there when reading from the filesystem - ([@watilde](https://github.com/watilde)), and support inline validation of - package names ([@michaelnisi](https://github.com/michaelnisi)). - -#### SMALL FIXES AND DEPENDENCY UPGRADES - -* [`1f380f6`](https://github.com/npm/npm/commit/1f380f66c1e944b8ffbf096fa94d09e931626e12) - [#7820](https://github.com/npm/npm/issues/7820) `are-we-there-yet@1.0.4`: Use - `readable-stream` instead of built-in `stream` module to better support - Node.js 0.8.x. ([@SonicHedgehog](https://github.com/SonicHedgehog)) -* [`d380188`](https://github.com/npm/npm/commit/d380188e161be31f5a4f53947de6bc28df4732d8) - `semver@4.3.3`: Don't throw on `semver.parse(null)`, and parse numeric - version strings more robustly. ([@isaacs](https://github.com/isaacs)) -* [`01d9964`](https://github.com/npm/npm/commit/01d99649265f921e1c61cf406613e7042bcea008) - `nock@1.4.0`: This change may need to be rolled back, or rolled forward, - because [nock depends on - `setImmediate`](https://github.com/npm/npm/issues/7842), which causes tests - to fail when run with Node.js 0.8. ([@othiym23](https://github.com/othiym23)) -* [`91f5cb1`](https://github.com/npm/npm/commit/91f5cb1fb91520fbe25a4da5b80848ed540b9ad3) - [#7791](https://github.com/npm/npm/issues/7791) Fix brackets in npmconf so - that `loaded` is set correctly. - ([@charmander](https://github.com/charmander)) -* [`1349e27`](https://github.com/npm/npm/commit/1349e27c936a8b0fc9f6440a6d6404ef3b19c587) - [#7818](https://github.com/npm/npm/issues/7818) Update `README.md` to point - out that the install script now lives on https://www.npmjs.com. - ([@weisjohn](https://github.com/weisjohn)) - -### v2.7.5 (2015-03-26): - -#### SECURITY FIXES - -* [`300834e`](https://github.com/npm/npm/commit/300834e91a4e2a95fb7fb59c309e7c3fc91d2312) - `tar@2.0.0`: Normalize symbolic links that point to targets outside the - extraction root. This prevents packages containing symbolic links from - overwriting targets outside the expected paths for a package. Thanks to [Tim - Cuthbertson](http://gfxmonk.net/) and the team at [Lift - Security](https://liftsecurity.io/) for working with the npm team to identify - this issue. ([@othiym23](https://github.com/othiym23)) -* [`0dc6875`](https://github.com/npm/npm/commit/0dc68757cffd5397c280bc71365d106523a5a052) - `semver@4.3.2`: Package versions can be no more than 256 characters long. - This prevents a situation in which parsing the version number can use - exponentially more time and memory to parse, leading to a potential denial of - service. Thanks to Adam Baldwin at Lift Security for bringing this to our - attention. ([@isaacs](https://github.com/isaacs)) - -#### BUG FIXES - -* [`5811468`](https://github.com/npm/npm/commit/5811468e104ccb6b26b8715dff390d68daa10066) - [#7713](https://github.com/npm/npm/issues/7713) Add a test for `npm link` and - `npm link <package>`. ([@watilde](https://github.com/watilde)) -* [`3cf3b0c`](https://github.com/npm/npm/commit/3cf3b0c8fddb6b66f969969feebea85fabd0360b) - [#7713](https://github.com/npm/npm/issues/7713) Only use absolute symbolic - links when `npm link`ing. ([@hokaccha](https://github.com/hokaccha)) -* [`f35aa93`](https://github.com/npm/npm/commit/f35aa933e136228a89e3fcfdebe8c7cc4f1e7c00) - [#7443](https://github.com/npm/npm/issues/7443) Keep relative URLs when - hitting search endpoint. ([@othiym23](https://github.com/othiym23)) -* [`eab6184`](https://github.com/npm/npm/commit/eab618425c51e3aa4416da28dcd8ca4ba63aec41) - [#7766](https://github.com/npm/npm/issues/7766) One last tweak to ensure that - GitHub shortcuts work with private repositories. - ([@iarna](https://github.com/iarna)) -* [`5d7f704`](https://github.com/npm/npm/commit/5d7f704823f5f92ddd7ff3e7dd2b8bcc66c73005) - [#7656](https://github.com/npm/npm/issues/7656) Don't try to load a deleted - CA file, allowing the `cafile` config to be changed. - ([@KenanY](https://github.com/KenanY)) -* [`a840a13`](https://github.com/npm/npm/commit/a840a13bbf0330157536381ea8e58d0bd93b4c05) - [#7746](https://github.com/npm/npm/issues/7746) Only fix up URL paths when - there are paths to fix up. ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY UPDATES - -* [`94df809`](https://github.com/npm/npm/commit/94df8095985bf5ba9d8db99dc445d05dac136aaf) - `request@2.54.0`: Fixes for Node.js 0.12 and io.js. - ([@simov](https://github.com/simov)) -* [`98a13ea`](https://github.com/npm/npm/commit/98a13eafdf098b53069ad15297008fcab9c61653) - `opener@1.4.1`: Deal with `start` on Windows more conventionally. - ([@domenic](https://github.com/domenic)) -* [`c2417c7`](https://github.com/npm/npm/commit/c2417c7702459a446f07d43ca3c4e99bde7fe9d6) - `require-inject@1.2.0`: Add installGlobally to bypass cleanups. - ([@iarna](https://github.com/iarna)) - -#### DOCUMENTATION FIXES - -* [`f87c728`](https://github.com/npm/npm/commit/f87c728f8732c9e977c0dc2060c0610649e79155) - [#7696](https://github.com/npm/npm/issues/7696) Months and minutes were - swapped in doc-build.sh ([@MeddahJ](https://github.com/MeddahJ)) -* [`4e216b2`](https://github.com/npm/npm/commit/4e216b29b30463f06afe6e3c645e205da5f50922) - [#7752](https://github.com/npm/npm/issues/7752) Update string examples to be - properly quoted. ([@snuggs](https://github.com/snuggs)) -* [`402f52a`](https://github.com/npm/npm/commit/402f52ab201efa348feb87cad753fc4b91e8a3fb) - [#7635](https://github.com/npm/npm/issues/7635) Clarify Windows installation - instructions. ([@msikma](https://github.com/msikma)) -* [`c910399`](https://github.com/npm/npm/commit/c910399ecfd8db49fe4496dd26887765a8aed20f) - small typo fix to `CHANGELOG.md` ([@e-jigsaw](https://github.com/e-jigsaw)) - -### v2.7.4 (2015-03-20): - -#### BUG FIXES - -* [`fe1bc38`](https://github.com/npm/npm/commit/fe1bc387a14475e373557de669e03d9d006d3173) - [#7672](https://github.com/npm/npm/issues/7672) `npm-registry-client@3.1.2`: - Fix client-side certificate handling by correcting property name. - ([@atamon](https://github.com/atamon)) -* [`3ce3cc2`](https://github.com/npm/npm/commit/3ce3cc242fc345bca6820185a4f5a013c5bc1944) - [#7635](https://github.com/npm/npm/issues/7635) `fstream-npm@1.0.2`: Raise a - more descriptive error when `bundledDependencies` isn't an array. - ([@KenanY](https://github.com/KenanY)) -* [`3a12723`](https://github.com/npm/npm/commit/3a127235076a1f00bc8befba56c024c6d0e7f477) - [#7661](https://github.com/npm/npm/issues/7661) Allow setting `--registry` on - the command line to trump the mapped registry for `--scope`. - ([@othiym23](https://github.com/othiym23)) -* [`89ce829`](https://github.com/npm/npm/commit/89ce829a00b526d0518f5cd855c323bffe182af0) - [#7630](https://github.com/npm/npm/issues/7630) `hosted-git-info@1.5.3`: Part - 3 of ensuring that GitHub shorthand is handled consistently. - ([@othiym23](https://github.com/othiym23)) -* [`63313eb`](https://github.com/npm/npm/commit/63313eb0c37891c355546fd1093010c8a0c3cd81) - [#7630](https://github.com/npm/npm/issues/7630) - `realize-package-specifier@2.2.0`: Part 2 of ensuring that GitHub shorthand - is handled consistently. ([@othiym23](https://github.com/othiym23)) -* [`3ed41bf`](https://github.com/npm/npm/commit/3ed41bf64a1bb752bb3155c74dd6ffbbd28c89c9) - [#7630](https://github.com/npm/npm/issues/7630) `npm-package-arg@3.1.1`: Part - 1 of ensuring that GitHub shorthand is handled consistently. - ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY UPDATES - -* [`6a498c6`](https://github.com/npm/npm/commit/6a498c6aaa00611a0a1ea405255900c327103f8b) - `npm-registry-couchapp@2.6.7`: Ensure that npm continues to work with new - registry architecture. ([@bcoe](https://github.com/bcoe)) -* [`bd72c47`](https://github.com/npm/npm/commit/bd72c47ce8c58e287d496902c11845c8fea420d6) - `glob@5.0.3`: Updated to latest version. - ([@isaacs](https://github.com/isaacs)) -* [`4bfbaa2`](https://github.com/npm/npm/commit/4bfbaa2d8b9dc7067d999de8f55676db3a4f4196) - `npmlog@1.2.0`: Getting up to date with latest version (but not using any of - the new features). ([@othiym23](https://github.com/othiym23)) - -#### A NEW REGRESSION TEST - -* [`3703b0b`](https://github.com/npm/npm/commit/3703b0b87c127a64649bdbfc3bc697ebccc4aa24) - Add regression test for `npm version` to ensure `message` property in config - continues to be honored. ([@dannyfritz](https://github.com/dannyfritz)) - -### v2.7.3 (2015-03-16): - -#### HAHA WHOOPS LIL SHINKWRAP ISSUE THERE LOL - -* [`1549106`](https://github.com/npm/npm/commit/1549106f518000633915686f5f1ccc6afcf77f8f) - [#7641](https://github.com/npm/npm/issues/7641) Due to 448efd0, running `npm - shrinkwrap --dev` caused production dependencies to no longer be included in - `npm-shrinkwrap.json`. Whoopsie! ([@othiym23](https://github.com/othiym23)) - -### v2.7.2 (2015-03-12): - -#### NPM GASTROENTEROLOGY - -* [`fb0ac26`](https://github.com/npm/npm/commit/fb0ac26eecdd76f6eaa4a96a865b7c6f52ce5aa5) - [#7579](https://github.com/npm/npm/issues/7579) Only block removing files and - links when we're sure npm isn't responsible for them. This change is hard to - summarize, because if things are working correctly you should never see it, - but if you want more context, just [go read the commit - message](https://github.com/npm/npm/commit/fb0ac26eecdd76f6eaa4a96a865b7c6f52ce5aa5), - which lays it all out. ([@othiym23](https://github.com/othiym23)) -* [`051c473`](https://github.com/npm/npm/commit/051c4738486a826300f205b71590781ce7744f01) - [#7552](https://github.com/npm/npm/issues/7552) `bundledDependencies` are now - properly included in the installation context. This is another fantastically - hard-to-summarize bug, and once again, I encourage you to [read the commit - message](https://github.com/npm/npm/commit/051c4738486a826300f205b71590781ce7744f01) - if you're curious about the details. The snappy takeaway is that this - unbreaks many use cases for `ember-cli`. ([@othiym23](https://github.com/othiym23)) - -#### LESS DRAMATIC CHANGES - -* [`fcd9247`](https://github.com/npm/npm/commit/fcd92476f3a9092f6f8c83a19a24fe63b206edcd) - [#7597](https://github.com/npm/npm/issues/7597) Awk varies pretty - dramatically from platform to platform, so use Perl to generate the AUTHORS - list instead. ([@KenanY](https://github.com/KenanY)) -* [`721b17a`](https://github.com/npm/npm/commit/721b17a31690bec074eb8763d823d6de63406005) - [#7598](https://github.com/npm/npm/issues/7598) `npm install --save` really - isn't experimental anymore. ([@RichardLitt](https://github.com/RichardLitt)) - -#### DEPENDENCY REFRESH - -* [`a91f2c7`](https://github.com/npm/npm/commit/a91f2c7c9a5183d9cde7aae040ebd9ccdf104be7) - [#7559](https://github.com/npm/npm/issues/7559) `node-gyp@1.0.3` Switch - `node-gyp` to use `stdio` instead of `customFds` so it stops printing a - deprecation warning every time you build a native dependency. - ([@jeffbski](https://github.com/jeffbski)) -* [`0c85db7`](https://github.com/npm/npm/commit/0c85db7f0dde41762411e40a029153e6a65ef483) - `rimraf@2.3.2`: Globbing now deals with paths containing valid glob - metacharacters better. ([@isaacs](https://github.com/isaacs)) -* [`d14588e`](https://github.com/npm/npm/commit/d14588ed09b032c4c770e34b4c0f2436f5fccf6e) - `minimatch@2.0.4`: Bug fixes. ([@isaacs](https://github.com/isaacs)) -* [`aa9952e`](https://github.com/npm/npm/commit/aa9952e8270a6c1b7f97e579875dd6e3aa22abfd) - `graceful-fs@3.0.6`: Bug fixes. ([@isaacs](https://github.com/isaacs)) - -### v2.7.1 (2015-03-05): - -#### GITSANITY - -* [`6823807`](https://github.com/npm/npm/commit/6823807bba6c00228a724e1205ae90d67df0adad) - [#7121](https://github.com/npm/npm/issues/7121) `npm install --save` for Git - dependencies saves the URL passed in, instead of the temporary directory used - to clone the remote repo. Fixes using Git dependencies when shrinkwrapping. - In the process, rewrote the Git dependency caching code. Again. No more - single-letter variable names, and a much clearer workflow. - ([@othiym23](https://github.com/othiym23)) -* [`c8258f3`](https://github.com/npm/npm/commit/c8258f31365b045e5fcf15b865a363abbc3be616) - [#7486](https://github.com/npm/npm/issues/7486) When installing Git remotes, - the caching code was passing in the function `gitEnv` instead of the results - of invoking it. ([@functino](https://github.com/functino)) -* [`c618eed`](https://github.com/npm/npm/commit/c618eeda3e321fd454d77c476b53a0330f2344cc) - [#2556](https://github.com/npm/npm/issues/2556) Make it possible to install - Git dependencies when using `--link` by not linking just the Git - dependencies. ([@smikes](https://github.com/smikes)) - -#### WHY DID THIS TAKE SO LONG. - -* [`abdd040`](https://github.com/npm/npm/commit/abdd040da90932535472f593d5433a67ee074801) - `read-package-json@1.3.2`: Provide more helpful error messages when JSON - parse errors are encountered by using a more forgiving JSON parser than - JSON.parse. ([@smikes](https://github.com/smikes)) - -#### BUGS & TWEAKS - -* [`c56cfcd`](https://github.com/npm/npm/commit/c56cfcd79cd8ab4ccd06d2c03d7e04030d576683) - [#7525](https://github.com/npm/npm/issues/7525) `npm dedupe` handles scoped - packages. ([@KidkArolis](https://github.com/KidkArolis)) -* [`1b8ba74`](https://github.com/npm/npm/commit/1b8ba7426393cbae2c76ad2c35953782d4401871) - [#7531](https://github.com/npm/npm/issues/7531) `npm stars` and `npm whoami` - will no longer send the registry the error text saying you need to log in as - your username. ([@othiym23](https://github.com/othiym23)) -* [`6de1e91`](https://github.com/npm/npm/commit/6de1e91116a5105dfa75126532b9083d8672e034) - [#6441](https://github.com/npm/npm/issues/6441) Prevent needless reinstalls - by only updating packages when the current version isn't the same as the - version returned as `wanted` by `npm outdated`. - ([@othiym23](https://github.com/othiym23)) -* [`2abc3ee`](https://github.com/npm/npm/commit/2abc3ee08f0cabc4e7bfd7b973c0b59dc44715ff) - Add `npm upgrade` as an alias for `npm update`. - ([@othiym23](https://github.com/othiym23)) -* [`bcd4722`](https://github.com/npm/npm/commit/bcd47224e18884191a5d0057c2b2fff83ac8206e) - [#7508](https://github.com/npm/npm/issues/7508) FreeBSD uses `EAI_FAIL` - instead of `ENOTFOUND`. ([@othiym23](https://github.com/othiym23)) -* [`21c1ac4`](https://github.com/npm/npm/commit/21c1ac41280f0716a208cde14025a2ad5ef61fed) - [#7507](https://github.com/npm/npm/issues/7507) Update support URL in generic - error handler to `https:` from `http:`. - ([@watilde](https://github.com/watilde)) -* [`b6bd99a`](https://github.com/npm/npm/commit/b6bd99a73f575545fbbaef95c12237c47dd32561) - [#7492](https://github.com/npm/npm/issues/7492) On install, the - `package.json` `engineStrict` deprecation only warns for the current package. - ([@othiym23](https://github.com/othiym23)) -* [`4ef1412`](https://github.com/npm/npm/commit/4ef1412d0061239da2b1c4460ed6db37cc9ded27) - [#7075](https://github.com/npm/npm/issues/7075) If you try to tag a release - as a valid semver range, `npm publish` and `npm tag` will error early instead - of proceeding. ([@smikes](https://github.com/smikes)) -* [`ad53d0f`](https://github.com/npm/npm/commit/ad53d0f666125d9f50d661b54901c6e5bab4d603) - Use `rimraf` in npm build script because Windows doesn't know what rm is. - ([@othiym23](https://github.com/othiym23)) -* [`8885c4d`](https://github.com/npm/npm/commit/8885c4dfb618f2838930b5c5149abea300a762d6) - `rimraf@2.3.1`: Better Windows support. - ([@isaacs](https://github.com/isaacs)) -* [`8885c4d`](https://github.com/npm/npm/commit/8885c4dfb618f2838930b5c5149abea300a762d6) - `glob@4.4.2`: Handle bad symlinks properly. - ([@isaacs](https://github.com/isaacs)) - -###E TYPSO & CLARFIICATIONS - -dId yuo know that submiting fxies for doc tpyos is an exclelent way to get -strated contriburting to a new open-saurce porject? - -* [`42c605c`](https://github.com/npm/npm/commit/42c605c7b401f603c32ea70427e1a7666adeafd9) - Fix typo in `CHANGELOG.md` ([@adrianblynch](https://github.com/adrianblynch)) -* [`c9bd58d`](https://github.com/npm/npm/commit/c9bd58dd637b9c41441023584a13e3818d5db336) - Add note about `node_modules/.bin` being added to the path in `npm - run-script`. ([@quarterto](https://github.com/quarterto)) -* [`903bdd1`](https://github.com/npm/npm/commit/903bdd105b205d6e45d3a2ab83eea8e4071e9aeb) - Matt Ranney confused the world when he renamed `node-redis` to `redis`. "The - world" includes npm's documentation. - ([@RichardLitt](https://github.com/RichardLitt)) -* [`dea9bb2`](https://github.com/npm/npm/commit/dea9bb2319183fe54bf4d173d8533d46d2c6611c) - Fix typo in contributor link. ([@watilde](https://github.com/watilde)) -* [`1226ca9`](https://github.com/npm/npm/commit/1226ca98d4d7650cc3ba16bf7ac62e44820f3bfa) - Properly close code block in npm-install.md. - ([@olizilla](https://github.com/olizilla)) - -### v2.7.0 (2015-02-26): - -#### SOMETIMES SEMVER MEANS "SUBJECTIVE-EMPATHETIC VERSIONING" - -For a very long time (maybe forever?), the documentation for `npm run-script` -has said that `npm restart` will only call `npm stop` and `npm start` when -there is no command defined as `npm restart` in `package.json`. The problem -with this documentation is that `npm run-script` was apparently never wired up -to actually work this way. - -Until now. - -If the patch below were landed on its own, free of context, it would be a -breaking change. But, since the "new" behavior is how the documentation claims -this feature has always worked, I'm classifying it as a patch-level bug fix. I -apologize in advance if this breaks anybody's deployment scripts, and if it -turns out to be a significant regression in practice, we can revert this change -and move it to `npm@3`, which is allowed to make breaking changes due to being -a new major version of semver. - -* [`2f6a1df`](https://github.com/npm/npm/commit/2f6a1df3e1e3e0a3bc4abb69e40f59a64204e7aa) - [#1999](https://github.com/npm/npm/issues/1999) Only run `stop` and `start` - scripts (plus their pre- and post- scripts) when there's no `restart` script - defined. This makes it easier to support graceful restarts of services - managed by npm. ([@watilde](https://github.com/watilde) / - [@scien](https://github.com/scien)) - -#### A SMALL FEATURE WITH BIG IMPLICATIONS - -* [`145af65`](https://github.com/npm/npm/commit/145af6587f45de135cc876be2027ed818ed4ca6a) - [#4887](https://github.com/npm/npm/issues/4887) Replace calls to the - `node-gyp` script bundled with npm by passing the - `--node-gyp=/path/to/node-gyp` option to npm. Swap in `pangyp` or a version - of `node-gyp` modified to work better with io.js without having to touch - npm's code! ([@ackalker](https://github.com/ackalker)) - -#### [@WATILDE'S](https://github.com/watilde) NPM USABILITY CORNER - -Following `npm@2.6.1`'s unexpected fix of many of the issues with `npm update --g` simply by making `--depth=0` the default for `npm outdated`, friend of npm -[@watilde](https://github.com/watilde) has made several modest changes to npm's -behavior that together justify bumping npm's minor version, as well as making -npm significantly more pleasant to use: - -* [`448efd0`](https://github.com/npm/npm/commit/448efd0eaa6f97af0889bf47efc543a1ea2f8d7e) - [#2853](https://github.com/npm/npm/issues/2853) Add support for `--dev` and - `--prod` to `npm ls`, so that you can list only the trees of production or - development dependencies, as desired. - ([@watilde](https://github.com/watilde)) -* [`a0a8777`](https://github.com/npm/npm/commit/a0a87777af8bee180e4e9321699f050c29ed5ac4) - [#7463](https://github.com/npm/npm/issues/7463) Split the list printed by - `npm run-script` into lifecycle scripts and scripts directly invoked via `npm - run-script`. ([@watilde](https://github.com/watilde)) -* [`a5edc17`](https://github.com/npm/npm/commit/a5edc17d5ef1435b468a445156a4a109df80f92b) - [#6749](https://github.com/npm/npm/issues/6749) `init-package-json@1.3.1`: - Support for passing scopes to `npm init` so packages are initialized as part - of that scope / organization / team. ([@watilde](https://github.com/watilde)) - -#### SMALLER FEATURES AND FIXES - -It turns out that quite a few pull requests had piled up on npm's issue -tracker, and they included some nice small features and fixes: - -* [`f33e8b8`](https://github.com/npm/npm/commit/f33e8b8ff2de094071c5976be95e35110cf2ab1a) - [#7354](https://github.com/npm/npm/issues/7354) Add `--if-present` flag to - allow e.g. CI systems to call (semi-) standard build tasks defined in - `package.json`, but don't raise an error if no such script is defined. - ([@jussi-kalliokoski](https://github.com/jussi-kalliokoski)) -* [`7bf85cc`](https://github.com/npm/npm/commit/7bf85cc372ab5698593b01e139c383fa62c92516) - [#4005](https://github.com/npm/npm/issues/4005) - [#6248](https://github.com/npm/npm/issues/6248) Globally unlink a package - when `npm rm` / `npm unlink` is called with no arguments. - ([@isaacs](https://github.com/isaacs)) -* [`a2e04bd`](https://github.com/npm/npm/commit/a2e04bd921feab8f9e40a27e180ca9308eb709d7) - [#7294](https://github.com/npm/npm/issues/7294) Ensure that when depending on - `git+<proto>` URLs, npm doesn't keep tacking additional `git+` prefixes onto - the front. ([@twhid](https://github.com/twhid)) -* [`0f87f5e`](https://github.com/npm/npm/commit/0f87f5ed28960d962f34977953561d22983da4f9) - [#6422](https://github.com/npm/npm/issues/6422) When depending on GitHub - private repositories, make sure we construct the Git URLS correctly. - ([@othiym23](https://github.com/othiym23)) -* [`50f461d`](https://github.com/npm/npm/commit/50f461d248c4d22e881a9535dccc1d57d994dbc7) - [#4595](https://github.com/npm/npm/issues/4595) Support finding compressed - manpages. It's still up to the system to figure out how to display them, - though. ([@pshevtsov](https://github.com/pshevtsov)) -* [`44da664`](https://github.com/npm/npm/commit/44da66456b530c049ff50953f78368460df87461) - [#7465](https://github.com/npm/npm/issues/7465) When calling git, log the - **full** command, with all arguments, on error. - ([@thriqon](https://github.com/thriqon)) -* [`9748d5c`](https://github.com/npm/npm/commit/9748d5cd195d0269b32caf45129a93d29359a796) - Add parent to error on `ETARGET` error. - ([@davglass](https://github.com/davglass)) -* [`37038d7`](https://github.com/npm/npm/commit/37038d7db47a986001f77ac17b3e164000fc8ff3) - [#4663](https://github.com/npm/npm/issues/4663) Remove hackaround for Linux - tests, as it's evidently no longer necessary. - ([@mmalecki](https://github.com/mmalecki)) -* [`d7b7853`](https://github.com/npm/npm/commit/d7b785393dffce93bb70317fbc039a6428ca37c5) - [#2612](https://github.com/npm/npm/issues/2612) Add support for path - completion on `npm install`, which narrows completion to only directories - containing `package.json` files. ([@deestan](https://github.com/deestan)) -* [`628fcdb`](https://github.com/npm/npm/commit/628fcdb0be4e14c0312085a50dc2ae01dc713fa6) - Remove all command completion calls to `-/short`, because it's been removed - from the primary registry for quite some time, and is generally a poor idea - on any registry with more than a few hundred packages. - ([@othiym23](https://github.com/othiym23)) -* [`3f6061d`](https://github.com/npm/npm/commit/3f6061d75650441ee690472d1fa9c8dd7a7b1b28) - [#6659](https://github.com/npm/npm/issues/6659) Instead of removing zsh - completion global, make it a local instead. - ([@othiym23](https://github.com/othiym23)) - -#### DOCUMENTATION TWEAKS - -* [`5bc70e6`](https://github.com/npm/npm/commit/5bc70e6cfb3598da433806c6f447fc94c8e1d35d) - [#7417](https://github.com/npm/npm/issues/7417) Provide concrete examples of - how the new `npm update` defaults work in practice, tied to actual test - cases. Everyone interested in using `npm update -g` now that it's been fixed - should read these documents, as should anyone interested in writing - documentation for npm. ([@smikes](https://github.com/smikes)) -* [`8ac6f21`](https://github.com/npm/npm/commit/8ac6f2123a6af13dc9447fad96ec9cb583c45a71) - [#6543](https://github.com/npm/npm/issues/6543) Clarify `npm-scripts` - warnings to de-emphasize dangers of using `install` scripts. - ([@zeke](https://github.com/zeke)) -* [`ebe3b37`](https://github.com/npm/npm/commit/ebe3b37098efdada41dcc4c52a291e29296ea242) - [#6711](https://github.com/npm/npm/issues/6711) Note that git tagging of - versions can be disabled via `--no-git-tag-verson`. - ([@smikes](https://github.com/smikes)) -* [`2ef5771`](https://github.com/npm/npm/commit/2ef5771632006e6cee8cf17f836c0f98ab494bd1) - [#6711](https://github.com/npm/npm/issues/6711) Document `git-tag-version` - configuration option. ([@KenanY](https://github.com/KenanY)) -* [`95e59b2`](https://github.com/npm/npm/commit/95e59b287c9517780318e145371a859e8ebb2d20) - Document that `NODE_ENV=production` behaves analogously to `--production` on - `npm install`. ([@stefaneg](https://github.com/stefaneg)) -* [`687117a`](https://github.com/npm/npm/commit/687117a5bcd6a838cd1532ea7020ec6fcf0c33c0) - [#7463](https://github.com/npm/npm/issues/7463) Document the new script - grouping behavior in the man page for `npm run-script`. - ([@othiym23](https://github.com/othiym23)) -* [`536b2b6`](https://github.com/npm/npm/commit/536b2b6f55c349247b3e79b5d11b4c033ef5a3df) - Rescue one of the the disabled tests and make it work properly. - ([@smikes](https://github.com/smikes)) - -#### DEPENDENCY UPDATES - -* [`89fc6a4`](https://github.com/npm/npm/commit/89fc6a4e7ff8c524675fcc14493ca0a1e3a76d38) - `which@1.0.9`: Test for being run as root, as well as the current user. - ([@isaacs](https://github.com/isaacs)) -* [`5d0612f`](https://github.com/npm/npm/commit/5d0612f31e226cba32a05351c47b055c0ab6c557) - `glob@4.4.1`: Better error message to explain why calling sync glob with a - callback results in an error. ([@isaacs](https://github.com/isaacs)) -* [`64b07f6`](https://github.com/npm/npm/commit/64b07f6caf6cb07e4102f1e4e5f2ff2b944e452e) - `tap@0.7.1`: More accurate counts of pending & skipped tests. - ([@rmg](https://github.com/rmg)) -* [`8fda451`](https://github.com/npm/npm/commit/8fda45195dae1d6f792be556abe87f7763fab09b) - `semver@4.3.1`: Make official the fact that `node-semver` has moved from - [@isaacs](https://github.com/isaacs)'s organization to - [@npm](https://github.com/npm)'s. ([@isaacs](https://github.com/isaacs)) - -### v2.6.1 (2015-02-19): - -* [`8b98f0e`](https://github.com/npm/npm/commit/8b98f0e709d77a8616c944aebd48ab726f726f76) - [#4471](https://github.com/npm/npm/issues/4471) `npm outdated` (and only `npm - outdated`) now defaults to `--depth=0`. See the [docs for - `--depth`](https://github.com/npm/npm/blob/82f484672adb1a3caf526a8a48832789495bb43d/doc/misc/npm-config.md#depth) - for the mildly confusing details. ([@smikes](https://github.com/smikes)) -* [`aa79194`](https://github.com/npm/npm/commit/aa791942a9f3c8af6a650edec72a675deb7a7c6e) - [#6565](https://github.com/npm/npm/issues/6565) Tweak `peerDependency` - deprecation warning to include which peer dependency on which package is - going to need to change. ([@othiym23](https://github.com/othiym23)) -* [`5fa067f`](https://github.com/npm/npm/commit/5fa067fd47682ac3cdb12a2b009d8ca59b05f992) - [#7171](https://github.com/npm/npm/issues/7171) Tweak `engineStrict` - deprecation warning to include which `package.json` is using it. - ([@othiym23](https://github.com/othiym23)) -* [`0fe0caa`](https://github.com/npm/npm/commit/0fe0caa7eddb7acdacbe5ee81ceabaca27175c78) - `glob@4.4.0`: Glob patterns can now ignore matches. - ([@isaacs](https://github.com/isaacs)) - -### v2.6.0 (2015-02-12): - -#### A LONG-AWAITED GUEST - -* [`38c4825`](https://github.com/npm/npm/commit/38c48254d3d217b4babf5027cb39492be4052fc2) - [#5068](https://github.com/npm/npm/issues/5068) Add new logout command, and - make it do something useful on both bearer-based and basic-based authed - clients. ([@othiym23](https://github.com/othiym23)) -* [`4bf0f5d`](https://github.com/npm/npm/commit/4bf0f5d56c33649124b486e016ba4a620c105c1c) - `npm-registry-client@6.1.1`: Support new `logout` endpoint to invalidate - token for sessions. ([@othiym23](https://github.com/othiym23)) - -#### DEPRECATIONS - -* [`c8e08e6`](https://github.com/npm/npm/commit/c8e08e6d91f4016c80f572aac5a2080df0f78098) - [#6565](https://github.com/npm/npm/issues/6565) Warn that `peerDependency` - behavior is changing and add a note to the docs. - ([@othiym23](https://github.com/othiym23)) -* [`7c81a5f`](https://github.com/npm/npm/commit/7c81a5f5f058941f635a92f22641ea68e79b60db) - [#7171](https://github.com/npm/npm/issues/7171) Warn that `engineStrict` in - `package.json` will be going away in the next major version of npm (coming - soon!) ([@othiym23](https://github.com/othiym23)) - -#### BUG FIXES & TWEAKS - -* [`add5890`](https://github.com/npm/npm/commit/add5890ce447dabf120b907a85f715df1e065f44) - [#4668](https://github.com/npm/npm/issues/4668) `read-package-json@1.3.1`: - Warn when a `bin` symbolic link is a dangling reference. - ([@nicks](https://github.com/nicks)) -* [`4b42071`](https://github.com/npm/npm/commit/4b420714dfb84338d85def78c30bd665e32d72c1) - `semver@4.3.0`: Add functions to extract parts of the version triple, fix a - typo. ([@isaacs](https://github.com/isaacs)) -* [`a9aff38`](https://github.com/npm/npm/commit/a9aff38719918486fc381d67ad3371c475632ff7) - Use full path for man pages as the symbolic link source, instead of just the - file name. ([@bengl](https://github.com/bengl)) -* [`6fd0fbd`](https://github.com/npm/npm/commit/6fd0fbd8a0347fd47cb7ee0064e0902a2f8a087c) - [#7233](https://github.com/npm/npm/issues/7233) Ensure `globalconfig` path - exists before trying to edit it. ([@ljharb](https://github.com/ljharb)) -* [`a0a2620`](https://github.com/npm/npm/commit/a0a262047647d9e2690cebe5a89e6a0dd33202bb) - `ini@1.3.3`: Allow embedded, quoted equals signs in ini field names. - ([@isaacs](https://github.com/isaacs)) - -Also typos and other documentation issues were addressed by -[@rutsky](https://github.com/rutsky), [@imurchie](https://github.com/imurchie), -[@marcin-wosinek](https://github.com/marcin-wosinek), -[@marr](https://github.com/marr), [@amZotti](https://github.com/amZotti), and -[@karlhorky](https://github.com/karlhorky). Thank you, everyone! - -### v2.5.1 (2015-02-06): - -This release doesn't look like much, but considerable effort went into ensuring -that npm's tests will pass on io.js 1.1.0 and Node 0.11.16 / 0.12.0 on both OS -X and Linux. - -**NOTE:** there are no actual changes to npm's code in `npm@2.5.1`. Only test -code (and the upgrade of `request` to the latest version) has changed. - -#### `npm-registry-mock@1.0.0`: - -* [`0e8d473`](https://github.com/npm/npm/commit/0e8d4736a1cbdda41ae8eba8a02c7ff7ce80c2ff) - [#7281](https://github.com/npm/npm/issues/7281) `npm-registry-mock@1.0.0`: - Clean up API, set `connection: close`. - ([@robertkowalski](https://github.com/robertkowalski)) -* [`4707bba`](https://github.com/npm/npm/commit/4707bba7d44dfab85cc45c2ecafa9c1601ba2e9a) - Further update tests to work with `npm-registry-mock@1.0.0`. - ([@othiym23](https://github.com/othiym23)) -* [`41a0f89`](https://github.com/npm/npm/commit/41a0f8959d4e02af9661588afa7d2b4543cc21b6) - Got rid of completely gratuitous global config manipulation in tests. - ([@othiym23](https://github.com/othiym23)) - -#### MINOR DEPENDENCY TWEAK - -* [`a4c7af9`](https://github.com/npm/npm/commit/a4c7af9c692f250c0fd017397ed9514fc263b752) - `request@2.53.0`: Tweaks to tunneling proxy behavior. - ([@nylen](https://github.com/nylen)) - -### v2.5.0 (2015-01-29): - -#### SMALL FEATURE I HAVE ALREADY USED TO MAINTAIN NPM ITSELF - -* [`9d61e96`](https://github.com/npm/npm/commit/9d61e96fb1f48687a85c211e4e0cd44c7f95a38e) - `npm outdated --long` now includes a column showing the type of dependency. - ([@watilde](https://github.com/watilde)) - -#### BUG FIXES & TWEAKS - -* [`fec4c96`](https://github.com/npm/npm/commit/fec4c967ee235030bf31393e8605e9e2811f4a39) - Allow `--no-proxy` to override `HTTP_PROXY` setting in environment. - ([@othiym23](https://github.com/othiym23)) -* [`589acb9`](https://github.com/npm/npm/commit/589acb9714f395c2ad0d98cb0ac4236f1842d2cc) - Only set `access` when publshing when it's explicitly set. - ([@othiym23](https://github.com/othiym23)) -* [`1027087`](https://github.com/npm/npm/commit/102708704c8c4f0ea99775d38f8d1efecf584940) - Add script and `Makefile` stanza to update AUTHORS. - ([@KenanY](https://github.com/KenanY)) -* [`eeff04d`](https://github.com/npm/npm/commit/eeff04da7979a0181becd36b8777d607e7aa1787) - Add `NPMOPTS` to top-level install in `Makefile` to override `userconfig`. - ([@aredridel](https://github.com/aredridel)) -* [`0d17328`](https://github.com/npm/npm/commit/0d173287336650606d4c91818bb7bcfb0c5d57a1) - `fstream@1.0.4`: Run chown only when necessary. - ([@silkentrance](https://github.com/silkentrance)) -* [`9aa4622`](https://github.com/npm/npm/commit/9aa46226ee63b9e183fd49fc72d9bdb0fae9605e) - `columnify@1.4.1`: ES6ified! ([@timoxley](https://github.com/timoxley)) -* [`51b2fd1`](https://github.com/npm/npm/commit/51b2fd1974e38b825ac5ca4a852ab3c4142624cc) - Update default version in `docs/npm-config.md`. - ([@lucthev](https://github.com/lucthev)) - -#### `npm-registry-client@6.0.7`: - -* [`f9313a0`](https://github.com/npm/npm/commit/f9313a066c9889a0ee898d8a35676e40b8101e7f) - [#7226](https://github.com/npm/npm/issues/7226) Ensure that all request - settings are copied onto the agent. - ([@othiym23](https://github.com/othiym23)) -* [`e186f6e`](https://github.com/npm/npm/commit/e186f6e7cfeb4db9c94d7375638f0b2f0d472947) - Only set `access` on publish when it differs from the norm. - ([@othiym23](https://github.com/othiym23)) -* [`f9313a0`](https://github.com/npm/npm/commit/f9313a066c9889a0ee898d8a35676e40b8101e7f) - Allow overriding request's environment-based proxy handling. - ([@othiym23](https://github.com/othiym23)) -* [`f9313a0`](https://github.com/npm/npm/commit/f9313a066c9889a0ee898d8a35676e40b8101e7f) - Properly handle retry failures on fetch. - ([@othiym23](https://github.com/othiym23)) - -### v2.4.1 (2015-01-23): - -![bridge that doesn't meet in the middle](http://www.static-18.themodernnomad.com/wp-content/uploads/2011/08/bridge-fail.jpg) - -Let's accentuate the positive: the `dist-tag` endpoints for `npm dist-tag -{add,rm,ls}` are now live on the public npm registry. - -* [`f70272b`](https://github.com/npm/npm/commit/f70272bed7d77032d1e21553371dd5662fef32f2) - `npm-registry-client@6.0.3`: Properly escape JSON tag version strings and - filter `_etag` from CouchDB docs. ([@othiym23](https://github.com/othiym23)) - -### v2.4.0 (2015-01-22): - -#### REGISTRY 2: ACCESS AND DIST-TAGS - -NOTE: This week's registry-2 commands are leading the implementation on -registry.npmjs.org a little bit, so some of the following may not work for -another week or so. Also note that `npm access` has documentation and -subcommands that are not yet finished, because they depend on incompletely -specified registry API endpoints. Things are coming together very quickly, -though, so expect the missing pieces to be filled in the coming weeks. - -* [`c963eb2`](https://github.com/npm/npm/commit/c963eb295cf766921b1680f4a71fd0ed3e1bcad8) - [#7181](https://github.com/npm/npm/issues/7181) NEW `npm access public` and - `npm access restricted`: Toggle visibility of scoped packages. - ([@othiym23](https://github.com/othiym23)) -* [`dc51810`](https://github.com/npm/npm/commit/dc51810e08c0f104259146c9c035d255de4f7d1d) - [#6243](https://github.com/npm/npm/issues/6243) / - [#6854](https://github.com/npm/npm/issues/6854) NEW `npm dist-tags`: Directly - manage `dist-tags` on packages. Most notably, `dist-tags` can now be deleted. - ([@othiym23](https://github.com/othiym23)) -* [`4c7c132`](https://github.com/npm/npm/commit/4c7c132a6b8305dca2974943226c39c0cdc64ff9) - [#7181](https://github.com/npm/npm/issues/7181) / - [#6854](https://github.com/npm/npm/issues/6854) `npm-registry-client@6.0.1`: - Add new `access` and `dist-tags` endpoints - ([@othiym23](https://github.com/othiym23)) - -#### NOT EXACTLY SELF-DEPRECATING - -* [`10d5c77`](https://github.com/npm/npm/commit/10d5c77653487f15759ac7de262a97e9c655240c) - [#6274](https://github.com/npm/npm/issues/6274) Deprecate `npm tag` in favor - of `npm dist-tag`. ([@othiym23](https://github.com/othiym23)) - -#### BUG FIX AND TINY FEATURE - -* [`29a6ef3`](https://github.com/npm/npm/commit/29a6ef38ef86ac318c5d9ea4bee28ce614672fa6) - [#6850](https://github.com/npm/npm/issues/6850) Be smarter about determining - base of file deletion when unbuilding. ([@phated](https://github.com/phated)) -* [`4ad01ea`](https://github.com/npm/npm/commit/4ad01ea2930a7a1cf88be121cc5ce9eba40c6807) - `init-package-json@1.2.0`: Support `--save-exact` in `npm init`. - ([@gustavnikolaj](https://github.com/gustavnikolaj)) - -### v2.3.0 (2015-01-15): - -#### REGISTRY 2: OH MY STARS! WHO AM I? - -* [`e662a60`](https://github.com/npm/npm/commit/e662a60e2f9a542effd8e72279d4622fe514415e) - The new `whoami` endpoint might not return a value. - ([@othiym23](https://github.com/othiym23)) -* [`c2cccd4`](https://github.com/npm/npm/commit/c2cccd4bbc65885239ed646eb510155f7b8af13d) - `npm-registry-client@5.0.0`: Includes the following fine changes - ([@othiym23](https://github.com/othiym23)): - * [`ba6b73e`](https://github.com/npm/npm-registry-client/commit/ba6b73e351027246c228622014e4441412409bad) - [#92](https://github.com/npm/npm-registry-client/issues/92) BREAKING CHANGE: - Move `/whoami` endpoint out of the package namespace (to `/-/whoami`). - ([@othiym23](https://github.com/othiym23)) - * [`3b174b7`](https://github.com/npm/npm-registry-client/commit/3b174b75c0c9ea77e298e6bb664fb499824ecc7c) - [#93](https://github.com/npm/npm-registry-client/issues/93) Registries based - on token-based auth can now offer starring. - ([@bcoe](https://github.com/bcoe)) - * [`4701a29`](https://github.com/npm/npm-registry-client/commit/4701a29bcda41bc14aa91f361dd0d576e24677d7) - Fix HTTP[S] connection keep-alive on Node 0.11 / io.js 1.0. - ([@fengmk2](https://github.com/fengmk2)) - -#### BETTER REGISTRY METADATA CACHING - -* [`98e1e10`](https://github.com/npm/npm/commit/98e1e1080df1f2cab16ed68035603950ea3d2d48) - [#6791](https://github.com/npm/npm/issues/6791) Add caching based on - Last-Modified / If-Modified-Since headers. Includes this - `npm-registry-client@5.0.0` change ([@lxe](https://github.com/lxe)): - * [`07bc335`](https://github.com/npm/npm-registry-client/commit/07bc33502b93554cd7539bfcce37d6e2d5404cd0) - [#86](https://github.com/npm/npm-registry-client/issues/86) Add Last-Modified - / If-Modified-Since cache header handling. ([@lxe](https://github.com/lxe)) - -#### HOW MUCH IS THAT WINDOWS IN THE DOGGY? - -* [`706d49a`](https://github.com/npm/npm/commit/706d49ab45521360fce1a68779b8de899015d8c2) - [#7107](https://github.com/npm/npm/issues/7107) `getCacheStat` passes a stub - stat on Windows. ([@rmg](https://github.com/rmg)) -* [`5fce278`](https://github.com/npm/npm/commit/5fce278a688a1cb79183e012bde40b089c2e97a4) - [#5267](https://github.com/npm/npm/issues/5267) Use `%COMSPEC%` when set on - Windows. ([@edmorley](https://github.com/edmorley)) -* [`cc2e099`](https://github.com/npm/npm/commit/cc2e09912ce2f91567c485422e4e797c4deb9842) - [#7083](https://github.com/npm/npm/issues/7083) Ensure Git cache prefix - exists before repo clone on Windows. - ([@othiym23](https://github.com/othiym23)) - -#### THRILLING BUG FIXES - -* [`c6fb430`](https://github.com/npm/npm/commit/c6fb430e55672b3caf87d25cbd2aeeebc449e2f2) - [#4197](https://github.com/npm/npm/issues/4197) Report `umask` as a 0-padded - octal literal. ([@smikes](https://github.com/smikes)) -* [`209713e`](https://github.com/npm/npm/commit/209713ebd4b77da11ce27d90c3346f78d760ba52) - [#4197](https://github.com/npm/npm/issues/4197) `umask@1.1.0`: Properly - handle `umask`s (i.e. not decimal numbers). - ([@smikes](https://github.com/smikes)) -* [`9eac0a1`](https://github.com/npm/npm/commit/9eac0a14488c5979ebde4c17881c8cd74f395069) - Make the example for bin links non-destructive. - ([@KevinSheedy](https://github.com/KevinSheedy)) -* [`6338bcf`](https://github.com/npm/npm/commit/6338bcfcd9cd1b0cc48b051dae764dc436ab5332) - `glob@4.3.5`: " -> ', for some reason. ([@isaacs](https://github.com/isaacs)) - -### v2.2.0 (2015-01-08): - -* [`88c531d`](https://github.com/npm/npm/commit/88c531d1c0b3aced8f2a09632db01b5635e7226a) - [#7056](https://github.com/npm/npm/issues/7056) version doesn't need a - package.json. ([@othiym23](https://github.com/othiym23)) -* [`2656c19`](https://github.com/npm/npm/commit/2656c19f6b915c3173acc3b6f184cc321563da5f) - [#7095](https://github.com/npm/npm/issues/7095) Link to npm website instead - of registry. ([@konklone](https://github.com/konklone)) -* [`c76b801`](https://github.com/npm/npm/commit/c76b8013bf1758587565822626171b76cb465c9e) - [#7067](https://github.com/npm/npm/issues/7067) Obfuscate secrets, including - nerfed URLs. ([@smikes](https://github.com/smikes)) -* [`17f66ce`](https://github.com/npm/npm/commit/17f66ceb1bd421084e4ae82a6b66634a6e272929) - [#6849](https://github.com/npm/npm/issues/6849) Explain the tag workflow more - clearly. ([@smikes](https://github.com/smikes)) -* [`e309df6`](https://github.com/npm/npm/commit/e309df642de33d10d6dffadaa8a5d214a924d0dc) - [#7096](https://github.com/npm/npm/issues/7096) Really, `npm update -g` is - almost always a terrible idea. ([@smikes](https://github.com/smikes)) -* [`acf287d`](https://github.com/npm/npm/commit/acf287d2547c8a0a8871652c164019261b666d55) - [#6999](https://github.com/npm/npm/issues/6999) `npm run-script env`: add a - new default script that will print out environment values. - ([@gcb](https://github.com/gcb)) -* [`560c009`](https://github.com/npm/npm/commit/560c00945d4dec926cd29193e336f137c7f3f951) - [#6745](https://github.com/npm/npm/issues/6745) Document `npm update --dev`. - ([@smikes](https://github.com/smikes)) -* [`226a677`](https://github.com/npm/npm/commit/226a6776a1a9e28570485623b8adc2ec4b041335) - [#7046](https://github.com/npm/npm/issues/7046) We have never been the Node - package manager. ([@linclark](https://github.com/linclark)) -* [`38eef22`](https://github.com/npm/npm/commit/38eef2248f03bb8ab04cae1833e2a228fb887f3c) - `npm-install-checks@1.0.5`: Compatibility with npmlog@^1. - ([@iarna](https://github.com/iarna)) - -### v2.1.18 (2015-01-01): - -* [`bf8640b`](https://github.com/npm/npm/commit/bf8640b0395b5dff71260a0cede7efc699a7bcf5) - [#7044](https://github.com/npm/npm/issues/7044) Document `.npmignore` syntax. - ([@zeke](https://github.com/zeke)) - -### v2.1.17 (2014-12-25): - -merry npm xmas - -Working with [@phated](https://github.com/phated), I discovered that npm still -had some lingering race conditions around how it handles Git dependencies. The -following changes were intended to remedy to these issues. Thanks to -[@phated](https://github.com/phated) for all his help getting to the bottom of -these. - -* [`bdf1c84`](https://github.com/npm/npm/commit/bdf1c8483f5c4ad79b712db12d73276e15883923) - [#7006](https://github.com/npm/npm/issues/7006) Only `chown` template and - top-level Git cache directories. ([@othiym23](https://github.com/othiym23)) -* [`581a72d`](https://github.com/npm/npm/commit/581a72da18f35ec87edef6255adf4ef4714a478c) - [#7006](https://github.com/npm/npm/issues/7006) Map Git remote inflighting to - clone paths rather than Git URLs. ([@othiym23](https://github.com/othiym23)) -* [`1c48d08`](https://github.com/npm/npm/commit/1c48d08dea31a11ac11a285cac598a482481cade) - [#7009](https://github.com/npm/npm/issues/7009) `normalize-git-url@1.0.0`: - Normalize Git URLs while caching. ([@othiym23](https://github.com/othiym23)) -* [`5423cf0`](https://github.com/npm/npm/commit/5423cf0be8ff2b76bfff7c8e780e5f261235a86a) - [#7009](https://github.com/npm/npm/issues/7009) Pack tarballs to their final - locations atomically. ([@othiym23](https://github.com/othiym23)) -* [`7f6557f`](https://github.com/npm/npm/commit/7f6557ff317469ee4a87c542ff9a991e74ce9f38) - [#7009](https://github.com/npm/npm/issues/7009) Inflight local directory - packing, just to be safe. ([@othiym23](https://github.com/othiym23)) - -Other changes: - -* [`1c491e6`](https://github.com/npm/npm/commit/1c491e65d70af013e8d5ac008d6d9762d6d91793) - [#6991](https://github.com/npm/npm/issues/6991) `npm version`: fix regression - in dirty-checking behavior ([@rlidwka](https://github.com/rlidwka)) -* [`55ceb2b`](https://github.com/npm/npm/commit/55ceb2b08ff8a0f56b94cc972ca15d7862e8733c) - [#1991](https://github.com/npm/npm/issues/1991) modify docs to reflect actual - `npm restart` behavior ([@smikes](https://github.com/smikes)) -* [`fb8e31b`](https://github.com/npm/npm/commit/fb8e31b95476a50bda35a665a99eec8a5d25a4db) - [#6982](https://github.com/npm/npm/issues/6982) when doing registry - operations, ensure registry URL always ends with `/` - ([@othiym23](https://github.com/othiym23)) -* [`5bcba65`](https://github.com/npm/npm/commit/5bcba65bed2678ffe80fb596f72abe9871d131c8) - pull whitelisted Git environment variables out into a named constant - ([@othiym23](https://github.com/othiym23)) -* [`be04bbd`](https://github.com/npm/npm/commit/be04bbdc52ebfc820cd939df2f7d79fe87067747) - [#7000](https://github.com/npm/npm/issues/7000) No longer install badly-named - manpage files, and log an error when trying to uninstall them. - ([@othiym23](https://github.com/othiym23)) -* [`6b7c5ec`](https://github.com/npm/npm/commit/6b7c5eca6b65e1247d0e51f6400cf2637ac880ce) - [#7011](https://github.com/npm/npm/issues/7011) Send auth for tarball fetches - for packages in `npm-shrinkwrap.json` from private registries. - ([@othiym23](https://github.com/othiym23)) -* [`9b9de06`](https://github.com/npm/npm/commit/9b9de06a99893b40aa23f0335726dec6df7979db) - `glob@4.3.2`: Better handling of trailing slashes. - ([@isaacs](https://github.com/isaacs)) -* [`030f3c7`](https://github.com/npm/npm/commit/030f3c7450b8ce124a19073bfbae0948a0a1a02c) - `semver@4.2.0`: Diffing between version strings. - ([@isaacs](https://github.com/isaacs)) - -### v2.1.16 (2014-12-22): - -* [`a4e4e33`](https://github.com/npm/npm/commit/a4e4e33edb35c68813f04bf42bdf933a6f727bcd) - [#6987](https://github.com/npm/npm/issues/6987) `read-installed@3.1.5`: fixed - a regression where a new / empty package would cause read-installed to throw. - ([@othiym23](https://github.com/othiym23) / - [@pgilad](https://github.com/pgilad)) - -### v2.1.15 (2014-12-18): - -* [`e5a2dee`](https://github.com/npm/npm/commit/e5a2dee47c74f26c56fee5998545b97497e830c8) - [#6951](https://github.com/npm/npm/issues/6951) `fs-vacuum@1.2.5`: Use - `path-is-inside` for better Windows normalization. - ([@othiym23](https://github.com/othiym23)) -* [`ac6167c`](https://github.com/npm/npm/commit/ac6167c2b9432939c57296f7ddd11ad5f8f918b2) - [#6955](https://github.com/npm/npm/issues/6955) Call `path.normalize` in - `lib/utils/gently-rm.js` for better Windows normalization. - ([@ben-page](https://github.com/ben-page)) -* [`c625d71`](https://github.com/npm/npm/commit/c625d714795e3b5badd847945e2401adfad5a196) - [#6964](https://github.com/npm/npm/issues/6964) Clarify CA configuration - docs. ([@jeffjo](https://github.com/jeffjo)) -* [`58b8cb5`](https://github.com/npm/npm/commit/58b8cb5cdf26a854358b7c2ab636572dba9bac16) - [#6950](https://github.com/npm/npm/issues/6950) Fix documentation typos. - ([@martinvd](https://github.com/martinvd)) -* [`7c1299d`](https://github.com/npm/npm/commit/7c1299d00538ea998684a1903a4091eafc63b7f1) - [#6909](https://github.com/npm/npm/issues/6909) Remove confusing mention of - rubygems `~>` semver operator. ([@mjtko](https://github.com/mjtko)) -* [`7dfdcc6`](https://github.com/npm/npm/commit/7dfdcc6debd8ef1fc52a2b508997d15887aad824) - [#6909](https://github.com/npm/npm/issues/6909) `semver@4.1.1`: Synchronize - documentation with PR [#6909](https://github.com/npm/npm/issues/6909) - ([@othiym23](https://github.com/othiym23)) -* [`adfddf3`](https://github.com/npm/npm/commit/adfddf3b682e0ae08e4b59d87c1b380dd651c572) - [#6925](https://github.com/npm/npm/issues/6925) Correct typo in - `doc/api/npm-ls.md` ([@oddurs](https://github.com/oddurs)) -* [`f5c534b`](https://github.com/npm/npm/commit/f5c534b711ab173129baf366c4f08d68f6117333) - [#6920](https://github.com/npm/npm/issues/6920) Remove recommendation to run - as root from `README.md`. - ([@robertkowalski](https://github.com/robertkowalski)) -* [`3ef4459`](https://github.com/npm/npm/commit/3ef445922cd39f25b992d91bd22c4d367882ea22) - [#6920](https://github.com/npm/npm/issues/6920) `npm-@googlegroups.com` has - gone the way of all things. That means it's gone. - ([@robertkowalski](https://github.com/robertkowalski)) - -### v2.1.14 (2014-12-13): - -* [`cf7aeae`](https://github.com/npm/npm/commit/cf7aeae3c3a24e48d3de4006fa082f0c6040922a) - [#6923](https://github.com/npm/npm/issues/6923) Overaggressive link update - for new website broke node-gyp. ([@othiym23](https://github.com/othiym23)) - -### v2.1.13 (2014-12-11): - -* [`cbb890e`](https://github.com/npm/npm/commit/cbb890eeacc0501ba1b8c6955f1c829c8af9f486) - [#6897](https://github.com/npm/npm/issues/6897) npm is a nice package manager - that runs server-side JavaScript. ([@othiym23](https://github.com/othiym23)) -* [`d9043c3`](https://github.com/npm/npm/commit/d9043c3b8d7450c3cb9ca795028c0e1c05377820) - [#6893](https://github.com/npm/npm/issues/6893) Remove erroneous docs about - preupdate / update / postupdate lifecycle scripts, which have never existed. - ([@devTristan](https://github.com/devTristan)) -* [`c5df4d0`](https://github.com/npm/npm/commit/c5df4d0d683cd3506808d1cd1acebff02a8b82db) - [#6884](https://github.com/npm/npm/issues/6884) Update npmjs.org to npmjs.com - in docs. ([@linclark](https://github.com/linclark)) -* [`cb6ff8d`](https://github.com/npm/npm/commit/cb6ff8dace1b439851701d4784d2d719c22ca7a7) - [#6879](https://github.com/npm/npm/issues/6879) npm version: Update - shrinkwrap post-check. ([@othiym23](https://github.com/othiym23)) -* [`2a340bd`](https://github.com/npm/npm/commit/2a340bdd548c6449468281e1444a032812bff677) - [#6868](https://github.com/npm/npm/issues/6868) Use magic numbers instead of - regexps to distinguish tarballs from other things. - ([@daxxog](https://github.com/daxxog)) -* [`f1c8bdb`](https://github.com/npm/npm/commit/f1c8bdb3f6b753d0600597e12346bdc3a34cb9c1) - [#6861](https://github.com/npm/npm/issues/6861) `npm-registry-client@4.0.5`: - Distinguish between error properties that are part of the response and error - strings that should be returned to the user. - ([@disrvptor](https://github.com/disrvptor)) -* [`d3a1b63`](https://github.com/npm/npm/commit/d3a1b6397fddef04b5198ca89d36d720aeb05eb6) - [#6762](https://github.com/npm/npm/issues/6762) Make `npm outdated` ignore - private packages. ([@KenanY](https://github.com/KenanY)) -* [`16d8542`](https://github.com/npm/npm/commit/16d854283ca5bcdb0cb2812fc5745d841652b952) - install.sh: Drop support for node < 0.8, remove engines bits. - ([@isaacs](https://github.com/isaacs)) -* [`b9c6046`](https://github.com/npm/npm/commit/b9c60466d5b713b1dc2947da14a5dfe42352e029) - `init-package-json@1.1.3`: ([@terinstock](https://github.com/terinstock)) - noticed that `init.license` configuration doesn't stick. Make sure that - dashed defaults don't trump dotted parameters. - ([@othiym23](https://github.com/othiym23)) -* [`b6d6acf`](https://github.com/npm/npm/commit/b6d6acfc02c8887f78067931babab8f7c5180fed) - `which@1.0.8`: No longer use graceful-fs for some reason. - ([@isaacs](https://github.com/isaacs)) -* [`d39f673`](https://github.com/npm/npm/commit/d39f673caf08a90fb2bb001d79c98062d2cd05f4) - `request@2.51.0`: Incorporate bug fixes. ([@nylen](https://github.com/nylen)) -* [`c7ad727`](https://github.com/npm/npm/commit/c7ad7279cc879930ec58ccc62fa642e621ecb65c) - `columnify@1.3.2`: Incorporate bug fixes. - ([@timoxley](https://github.com/timoxley)) - -### v2.1.12 (2014-12-04): - -* [`e5b1e44`](https://github.com/npm/npm/commit/e5b1e448bb4a9d6eae4ba0f67b1d3c2cea8ed383) - add alias verison=version ([@isaacs](https://github.com/isaacs)) -* [`5eed7bd`](https://github.com/npm/npm/commit/5eed7bddbd7bb92a44c4193c93e8529500c558e6) - `request@2.49.0` ([@nylen](https://github.com/nylen)) -* [`e72f81d`](https://github.com/npm/npm/commit/e72f81d8412540ae7d1e0edcc37c11bcb8169051) - `glob@4.3.1` / `minimatch@2.0.1` ([@isaacs](https://github.com/isaacs)) -* [`b8dcc36`](https://github.com/npm/npm/commit/b8dcc3637b5b71933b97162b7aff1b1a622c13e2) - `graceful-fs@3.0.5` ([@isaacs](https://github.com/isaacs)) - -### v2.1.11 (2014-11-27): - -* [`4861d28`](https://github.com/npm/npm/commit/4861d28ad0ebd959fe6bc15b9c9a50fcabe57f55) - `which@1.0.7`: License update. ([@isaacs](https://github.com/isaacs)) -* [`30a2ea8`](https://github.com/npm/npm/commit/30a2ea80c891d384b31a1cf28665bba4271915bd) - `ini@1.3.2`: License update. ([@isaacs](https://github.com/isaacs)) -* [`6a4ea05`](https://github.com/npm/npm/commit/6a4ea054f6ddf52fc58842ba2046564b04c5c0e2) - `fstream@1.0.3`: Propagate error events to downstream streams. - ([@gfxmonk](https://github.com/gfxmonk)) -* [`a558695`](https://github.com/npm/npm/commit/a5586954f1c18df7c96137e0a79f41a69e7a884e) - `tar@1.0.3`: Don't extract broken files, propagate `drain` event. - ([@gfxmonk](https://github.com/gfxmonk)) -* [`989624e`](https://github.com/npm/npm/commit/989624e8321f87734c1b1272fc2f646e7af1f81c) - [#6767](https://github.com/npm/npm/issues/6767) Actually pass parameters when - adding git repo to cache under Windows. - ([@othiym23](https://github.com/othiym23)) -* [`657af73`](https://github.com/npm/npm/commit/657af7308f7d6cd2f81389fcf0d762252acaf1ce) - [#6774](https://github.com/npm/npm/issues/6774) When verifying paths on - unbuild, resolve both source and target as symlinks. - ([@hokaccha](https://github.com/hokaccha)) -* [`fd19c40`](https://github.com/npm/npm/commit/fd19c4046414494f9647a6991c00f8406a939929) - [#6713](https://github.com/npm/npm/issues/6713) - `realize-package-specifier@1.3.0`: Make it so that `npm install foo@1` work - when a file named `1` exists. ([@iarna](https://github.com/iarna)) -* [`c8ac37a`](https://github.com/npm/npm/commit/c8ac37a470491b2ed28514536e2e198494638c79) - `npm-registry-client@4.0.4`: Fix regression in failed fetch retries. - ([@othiym23](https://github.com/othiym23)) - -### v2.1.10 (2014-11-20): - -* [`756f3d4`](https://github.com/npm/npm/commit/756f3d40fe18bc02bc93afe17016dfcc266c4b6b) - [#6735](https://github.com/npm/npm/issues/6735) Log "already built" messages - at info, not error. ([@smikes](https://github.com/smikes)) -* [`1b7330d`](https://github.com/npm/npm/commit/1b7330dafba3bbba171f74f1e58b261cb1b9301e) - [#6729](https://github.com/npm/npm/issues/6729) `npm-registry-client@4.0.3`: - GitHub won't redirect you through an HTML page to a compressed tarball if you - don't tell it you accept JSON responses. - ([@KenanY](https://github.com/KenanY)) -* [`d9c7857`](https://github.com/npm/npm/commit/d9c7857be02dacd274e55bf6d430d90d91509d53) - [#6506](https://github.com/npm/npm/issues/6506) - `readdir-scoped-modules@1.0.1`: Use `graceful-fs` so the whole dependency - tree gets read, even in case of `EMFILE`. - ([@sakana](https://github.com/sakana)) -* [`3a085be`](https://github.com/npm/npm/commit/3a085be158ace8f1e4395e69f8c102d3dea00c5f) - Grammar fix in docs. ([@icylace](https://github.com/icylace)) -* [`3f8e2ff`](https://github.com/npm/npm/commit/3f8e2ff8342d327d6f1375437ecf4bd945dc360f) - Did you know that npm has a Code of Conduct? Add a link to it to - CONTRIBUTING.md. ([@isaacs](https://github.com/isaacs)) -* [`319ccf6`](https://github.com/npm/npm/commit/319ccf633289e06e57a80d74c39706899348674c) - `glob@4.2.1`: Performance tuning. ([@isaacs](https://github.com/isaacs)) -* [`835f046`](https://github.com/npm/npm/commit/835f046e7568c33e81a0b48c84cff965024d8b8a) - `readable-stream@1.0.33`: Bug fixes. ([@rvagg](https://github.com/rvagg)) -* [`a34c38d`](https://github.com/npm/npm/commit/a34c38d0732fb246d11f2a776d2ad0d8db654338) - `request@2.48.0`: Bug fixes. ([@nylen](https://github.com/nylen)) - -### v2.1.9 (2014-11-13): - -* [`eed9f61`](https://github.com/npm/npm/commit/eed9f6101963364acffc59d7194fc1655180e80c) - [#6542](https://github.com/npm/npm/issues/6542) `npm owner add / remove` now - works properly with scoped packages - ([@othiym23](https://github.com/othiym23)) -* [`cd25973`](https://github.com/npm/npm/commit/cd25973825aa5315b7ebf26227bd32bd6be5533f) - [#6548](https://github.com/npm/npm/issues/6548) using sudo won't leave the - cache's git directories with bad permissions - ([@othiym23](https://github.com/othiym23)) -* [`56930ab`](https://github.com/npm/npm/commit/56930abcae6a6ea41f1b75e23765c61259cef2dd) - fixed irregular `npm cache ls` output (yes, that's a thing) - ([@othiym23](https://github.com/othiym23)) -* [`740f483`](https://github.com/npm/npm/commit/740f483db6ec872b453065842da080a646c3600a) - legacy tests no longer poison user's own cache - ([@othiym23](https://github.com/othiym23)) -* [`ce37f14`](https://github.com/npm/npm/commit/ce37f142a487023747a9086335618638ebca4372) - [#6169](https://github.com/npm/npm/issues/6169) add terse output similar to - `npm publish / unpublish` for `npm owner add / remove` - ([@KenanY](https://github.com/KenanY)) -* [`bf2b8a6`](https://github.com/npm/npm/commit/bf2b8a66d7188900bf1e957c052b893948b67e0e) - [#6680](https://github.com/npm/npm/issues/6680) pass auth credentials to - registry when downloading search index - ([@terinjokes](https://github.com/terinjokes)) -* [`00ecb61`](https://github.com/npm/npm/commit/00ecb6101422984696929f602e14da186f9f669c) - [#6400](https://github.com/npm/npm/issues/6400) `.npmignore` is respected for - git repos on cache / pack / publish - ([@othiym23](https://github.com/othiym23)) -* [`d1b3a9e`](https://github.com/npm/npm/commit/d1b3a9ec5e2b6d52765ba5da5afb08dba41c49c1) - [#6311](https://github.com/npm/npm/issues/6311) `npm ls -l --depth=0` no - longer prints phantom duplicate children - ([@othiym23](https://github.com/othiym23)) -* [`07c5f34`](https://github.com/npm/npm/commit/07c5f34e45c9b18c348ed53b5763b1c5d4325740) - [#6690](https://github.com/npm/npm/issues/6690) `uid-number@0.0.6`: clarify - confusing names in error-handling code ([@isaacs](https://github.com/isaacs)) -* [`1ac9be9`](https://github.com/npm/npm/commit/1ac9be9f3bab816211d72d13cb05b5587878a586) - [#6684](https://github.com/npm/npm/issues/6684) `npm init`: don't report - write if canceled ([@smikes](https://github.com/smikes)) -* [`7bb207d`](https://github.com/npm/npm/commit/7bb207d1d6592a9cffc986871e4b671575363c2f) - [#5754](https://github.com/npm/npm/issues/5754) never remove app directories - on failed install ([@othiym23](https://github.com/othiym23)) -* [`705ce60`](https://github.com/npm/npm/commit/705ce601e7b9c5428353e02ebb30cb76c1991fdd) - [#5754](https://github.com/npm/npm/issues/5754) `fs-vacuum@1.2.2`: don't - throw when another fs task writes to a directory being vacuumed - ([@othiym23](https://github.com/othiym23)) -* [`1b650f4`](https://github.com/npm/npm/commit/1b650f4f217c413a2ffb96e1701beb5aa67a0de2) - [#6255](https://github.com/npm/npm/issues/6255) ensure that order credentials - are used from `.npmrc` doesn't regress - ([@othiym23](https://github.com/othiym23)) -* [`9bb2c34`](https://github.com/npm/npm/commit/9bb2c3435cedef40b45d3e9bd7a8edfb8cbe7209) - [#6644](https://github.com/npm/npm/issues/6644) `warn` rather than `info` on - fetch failure ([@othiym23](https://github.com/othiym23)) -* [`e34a7b6`](https://github.com/npm/npm/commit/e34a7b6b7371b1893a062f627ae8e168546d7264) - [#6524](https://github.com/npm/npm/issues/6524) `npm-registry-client@4.0.2`: - proxy via `request` more transparently - ([@othiym23](https://github.com/othiym23)) -* [`40afd6a`](https://github.com/npm/npm/commit/40afd6aaf34c11a10e80ec87b115fb2bb907e3bd) - [#6524](https://github.com/npm/npm/issues/6524) push proxy settings into - `request` ([@tauren](https://github.com/tauren)) - -### v2.1.8 (2014-11-06): - -* [`063d843`](https://github.com/npm/npm/commit/063d843965f9f0bfa5732d7c2d6f5aa37a8260a2) - npm version now updates version in npm-shrinkwrap.json - ([@faiq](https://github.com/faiq)) -* [`3f53cd7`](https://github.com/npm/npm/commit/3f53cd795f8a600e904a97f215ba5b5a9989d9dd) - [#6559](https://github.com/npm/npm/issues/6559) save local dependencies in - npm-shrinkwrap.json ([@Torsph](https://github.com/Torsph)) -* [`e249262`](https://github.com/npm/npm/commit/e24926268b2d2220910bc81cce6d3b2e08d94eb1) - npm-faq.md: mention scoped pkgs in namespace Q - ([@smikes](https://github.com/smikes)) -* [`6b06ec4`](https://github.com/npm/npm/commit/6b06ec4ef5da490bdca1512fa7f12490245c192b) - [#6642](https://github.com/npm/npm/issues/6642) `init-package-json@1.1.2`: - Handle both `init-author-name` and `init.author.name`. - ([@othiym23](https://github.com/othiym23)) -* [`9cb334c`](https://github.com/npm/npm/commit/9cb334c8a895a55461aac18791babae779309a0e) - [#6409](https://github.com/npm/npm/issues/6409) document commit-ish with - GitHub URLs ([@smikes](https://github.com/smikes)) -* [`0aefae9`](https://github.com/npm/npm/commit/0aefae9bc2598a4b7a3ee7bb2306b42e3e12bb28) - [#2959](https://github.com/npm/npm/issues/2959) npm run no longer fails - silently ([@flipside](https://github.com/flipside)) -* [`e007a2c`](https://github.com/npm/npm/commit/e007a2c1e4fac1759fa61ac6e78c6b83b2417d11) - [#3908](https://github.com/npm/npm/issues/3908) include command in spawn - errors ([@smikes](https://github.com/smikes)) - -### v2.1.7 (2014-10-30): - -* [`6750b05`](https://github.com/npm/npm/commit/6750b05dcba20d8990a672957ec56c48f97e241a) - [#6398](https://github.com/npm/npm/issues/6398) `npm-registry-client@4.0.0`: - consistent API, handle relative registry paths, use auth more consistently - ([@othiym23](https://github.com/othiym23)) -* [`7719cfd`](https://github.com/npm/npm/commit/7719cfdd8b204dfeccc41289707ea58b4d608905) - [#6560](https://github.com/npm/npm/issues/6560) use new npm-registry-client - API ([@othiym23](https://github.com/othiym23)) -* [`ed61971`](https://github.com/npm/npm/commit/ed619714c93718b6c1922b8c286f4b6cd2b97c80) - move caching of search metadata from `npm-registry-client` to npm itself - ([@othiym23](https://github.com/othiym23)) -* [`3457041`](https://github.com/npm/npm/commit/34570414cd528debeb22943873440594d7f47abf) - handle caching of metadata independently from `npm-registry-client` - ([@othiym23](https://github.com/othiym23)) -* [`20a331c`](https://github.com/npm/npm/commit/20a331ced6a52faac6ec242e3ffdf28bcd447c40) - [#6538](https://github.com/npm/npm/issues/6538) map registry URLs to - credentials more safely ([@indexzero](https://github.com/indexzero)) -* [`4072e97`](https://github.com/npm/npm/commit/4072e97856bf1e7affb38333d080c172767eea27) - [#6589](https://github.com/npm/npm/issues/6589) `npm-registry-client@4.0.1`: - allow publishing of packages with names identical to built-in Node modules - ([@feross](https://github.com/feross)) -* [`254f0e4`](https://github.com/npm/npm/commit/254f0e4adaf2c56e9df25c7343c43b0b0804a3b5) - `tar@1.0.2`: better error-handling ([@runk](https://github.com/runk)) -* [`73ee2aa`](https://github.com/npm/npm/commit/73ee2aa4f1a47e43fe7cf4317a5446875f7521fa) - `request@2.47.0` ([@mikeal](https://github.com/mikeal)) - -### v2.1.6 (2014-10-23): - -* [`681b398`](https://github.com/npm/npm/commit/681b3987a18e7aba0aaf78c91a23c7cc0ab82ce8) - [#6523](https://github.com/npm/npm/issues/6523) fix default `logelevel` doc - ([@KenanY](https://github.com/KenanY)) -* [`80b368f`](https://github.com/npm/npm/commit/80b368ffd786d4d008734b56c4a6fe12d2cb2926) - [#6528](https://github.com/npm/npm/issues/6528) `npm version` should work in - a git directory without git ([@terinjokes](https://github.com/terinjokes)) -* [`5f5f9e4`](https://github.com/npm/npm/commit/5f5f9e4ddf544c2da6adf3f8c885238b0e745076) - [#6483](https://github.com/npm/npm/issues/6483) `init-package-json@1.1.1`: - Properly pick up default values from environment variables. - ([@othiym23](https://github.com/othiym23)) -* [`a114870`](https://github.com/npm/npm/commit/a1148702f53f82d49606b2e4dac7581261fff442) - perl 5.18.x doesn't like -pi without filenames - ([@othiym23](https://github.com/othiym23)) -* [`de5ba00`](https://github.com/npm/npm/commit/de5ba007a48db876eb5bfb6156435f3512d58977) - `request@2.46.0`: Tests and cleanup. - ([@othiym23](https://github.com/othiym23)) -* [`76933f1`](https://github.com/npm/npm/commit/76933f169f17b5273b32e924a7b392d5729931a7) - `fstream-npm@1.0.1`: Always include `LICENSE[.*]`, `LICENCE[.*]`, - `CHANGES[.*]`, `CHANGELOG[.*]`, and `HISTORY[.*]`. - ([@jonathanong](https://github.com/jonathanong)) - -### v2.1.5 (2014-10-16): - -* [`6a14b23`](https://github.com/npm/npm/commit/6a14b232a0e34158bd95bb25c607167be995c204) - [#6397](https://github.com/npm/npm/issues/6397) Defactor npmconf back into - npm. ([@othiym23](https://github.com/othiym23)) -* [`4000e33`](https://github.com/npm/npm/commit/4000e3333a76ca4844681efa8737cfac24b7c2c8) - [#6323](https://github.com/npm/npm/issues/6323) Install `peerDependencies` - from top. ([@othiym23](https://github.com/othiym23)) -* [`5d119ae`](https://github.com/npm/npm/commit/5d119ae246f27353b14ff063559d1ba8c616bb89) - [#6498](https://github.com/npm/npm/issues/6498) Better error messages on - malformed `.npmrc` properties. ([@nicks](https://github.com/nicks)) -* [`ae18efb`](https://github.com/npm/npm/commit/ae18efb65fed427b1ef18e4862885bf60b87b92e) - [#6093](https://github.com/npm/npm/issues/6093) Replace instances of 'hash' - with 'object' in documentation. ([@zeke](https://github.com/zeke)) -* [`53108b2`](https://github.com/npm/npm/commit/53108b276fec5f97a38250933a2768d58b6928da) - [#1558](https://github.com/npm/npm/issues/1558) Clarify how local paths - should be used. ([@KenanY](https://github.com/KenanY)) -* [`344fa1a`](https://github.com/npm/npm/commit/344fa1a219ac8867022df3dc58a47636dde8a242) - [#6488](https://github.com/npm/npm/issues/6488) Work around bug in marked. - ([@othiym23](https://github.com/othiym23)) - -OUTDATED DEPENDENCY CLEANUP JAMBOREE - -* [`60c2942`](https://github.com/npm/npm/commit/60c2942e13655d9ecdf6e0f1f97f10cb71a75255) - `realize-package-specifier@1.2.0`: Handle names and rawSpecs more - consistently. ([@iarna](https://github.com/iarna)) -* [`1b5c95f`](https://github.com/npm/npm/commit/1b5c95fbda77b87342bd48c5ecac5b1fd571ccfe) - `sha@1.3.0`: Change line endings? - ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`d7dee3f`](https://github.com/npm/npm/commit/d7dee3f3f7d9e7c2061a4ecb4dd93e3e4bfe4f2e) - `request@2.45.0`: Dependency updates, better proxy support, better compressed - response handling, lots of 'use strict'. - ([@mikeal](https://github.com/mikeal)) -* [`3d75180`](https://github.com/npm/npm/commit/3d75180c2cc79fa3adfa0e4cb783a27192189a65) - `opener@1.4.0`: Added gratuitous return. - ([@Domenic](https://github.com/Domenic)) -* [`8e2703f`](https://github.com/npm/npm/commit/8e2703f78d280d1edeb749e257dda1f288bad6e3) - `retry@0.6.1` / `npm-registry-client@3.2.4`: Change of ownership. - ([@tim-kos](https://github.com/tim-kos)) -* [`c87b00f`](https://github.com/npm/npm/commit/c87b00f82f92434ee77831915012c77a6c244c39) - `once@1.3.1`: Wrap once with wrappy. ([@isaacs](https://github.com/isaacs)) -* [`01ec790`](https://github.com/npm/npm/commit/01ec790fd47def56eda6abb3b8d809093e8f493f) - `npm-user-validate@0.1.1`: Correct repository URL. - ([@robertkowalski](https://github.com/robertkowalski)) -* [`389e52c`](https://github.com/npm/npm/commit/389e52c2d94c818ca8935ccdcf392994fec564a2) - `glob@4.0.6`: Now absolutely requires `graceful-fs`. - ([@isaacs](https://github.com/isaacs)) -* [`e15ab15`](https://github.com/npm/npm/commit/e15ab15a27a8f14cf0d9dc6f11dee452080378a0) - `ini@1.3.0`: Tighten up whitespace handling. - ([@isaacs](https://github.com/isaacs)) -* [`7610f3e`](https://github.com/npm/npm/commit/7610f3e62e699292ece081bfd33084d436e3246d) - `archy@1.0.0` ([@substack](https://github.com/substack)) -* [`9c13149`](https://github.com/npm/npm/commit/9c1314985e513e20ffa3ea0ca333ba2ab78299c9) - `semver@4.1.0`: Add support for prerelease identifiers. - ([@bromanko](https://github.com/bromanko)) -* [`f096c25`](https://github.com/npm/npm/commit/f096c250441b031d758f03afbe8d2321f94c7703) - `graceful-fs@3.0.4`: Add a bunch of additional tests, skip the unfortunate - complications of `graceful-fs@3.0.3`. ([@isaacs](https://github.com/isaacs)) - -### v2.1.4 (2014-10-09): - -* [`3aeb440`](https://github.com/npm/npm/commit/3aeb4401444fad83cc7a8d11bf2507658afa5248) - [#6442](https://github.com/npm/npm/issues/6442) proxying git needs `GIT_SSL_CAINFO` - ([@wmertens](https://github.com/wmertens)) -* [`a8da8d6`](https://github.com/npm/npm/commit/a8da8d6e0cd56d97728c0b76b51604ee06ef6264) - [#6413](https://github.com/npm/npm/issues/6413) write builtin config on any - global npm install ([@isaacs](https://github.com/isaacs)) -* [`9e4d632`](https://github.com/npm/npm/commit/9e4d632c0142ba55df07d624667738b8727336fc) - [#6343](https://github.com/npm/npm/issues/6343) don't pass run arguments to - pre & post scripts ([@TheLudd](https://github.com/TheLudd)) -* [`d831b1f`](https://github.com/npm/npm/commit/d831b1f7ca1a9921ea5b394e39b7130ecbc6d7b4) - [#6399](https://github.com/npm/npm/issues/6399) race condition: inflight - installs, prevent `peerDependency` problems - ([@othiym23](https://github.com/othiym23)) -* [`82b775d`](https://github.com/npm/npm/commit/82b775d6ff34c4beb6c70b2344d491a9f2026577) - [#6384](https://github.com/npm/npm/issues/6384) race condition: inflight - caching by URL rather than semver range - ([@othiym23](https://github.com/othiym23)) -* [`7bee042`](https://github.com/npm/npm/commit/7bee0429066fedcc9e6e962c043eb740b3792809) - `inflight@1.0.4`: callback can take arbitrary number of parameters - ([@othiym23](https://github.com/othiym23)) -* [`3bff494`](https://github.com/npm/npm/commit/3bff494f4abf17d6d7e0e4a3a76cf7421ecec35a) - [#5195](https://github.com/npm/npm/issues/5195) fixed regex color regression - for `npm search` ([@chrismeyersfsu](https://github.com/chrismeyersfsu)) -* [`33ba2d5`](https://github.com/npm/npm/commit/33ba2d585160a0a2a322cb76c4cd989acadcc984) - [#6387](https://github.com/npm/npm/issues/6387) allow `npm view global` if - package is specified ([@evanlucas](https://github.com/evanlucas)) -* [`99c4cfc`](https://github.com/npm/npm/commit/99c4cfceed413396d952cf05f4e3c710f9682c23) - [#6388](https://github.com/npm/npm/issues/6388) npm-publish → - npm-developers(7) ([@kennydude](https://github.com/kennydude)) - -TEST CLEANUP EXTRAVAGANZA: - -* [`8d6bfcb`](https://github.com/npm/npm/commit/8d6bfcb88408f5885a2a67409854c43e5c3a23f6) - tap tests run with no system-wide side effects - ([@chrismeyersfsu](https://github.com/chrismeyersfsu)) -* [`7a1472f`](https://github.com/npm/npm/commit/7a1472fbdbe99956ad19f629e7eb1cc07ba026ef) - added npm cache cleanup script - ([@chrismeyersfsu](https://github.com/chrismeyersfsu)) -* [`0ce6a37`](https://github.com/npm/npm/commit/0ce6a3752fa9119298df15671254db6bc1d8e64c) - stripped out dead test code (othiym23) -* replace spawn with common.npm (@chrismeyersfsu): - * [`0dcd614`](https://github.com/npm/npm/commit/0dcd61446335eaf541bf5f2d5186ec1419f86a42) - test/tap/cache-shasum-fork.js - * [`97f861c`](https://github.com/npm/npm/commit/97f861c967606a7e51e3d5047cf805d9d1adea5a) - test/tap/false_name.js - * [`d01b3de`](https://github.com/npm/npm/commit/d01b3de6ce03f25bbf3db97bfcd3cc85830d6801) - test/tap/git-cache-locking.js - * [`7b63016`](https://github.com/npm/npm/commit/7b63016778124c6728d6bd89a045c841ae3900b6) - test/tap/pack-scoped.js - * [`c877553`](https://github.com/npm/npm/commit/c877553265c39673e03f0a97972f692af81a595d) - test/tap/scripts-whitespace-windows.js - * [`df98525`](https://github.com/npm/npm/commit/df98525331e964131299d457173c697cfb3d95b9) - test/tap/prepublish.js - * [`99c4cfc`](https://github.com/npm/npm/commit/99c4cfceed413396d952cf05f4e3c710f9682c23) - test/tap/prune.js - -### v2.1.3 (2014-10-02): - -BREAKING CHANGE FOR THE SQRT(i) PEOPLE ACTUALLY USING `npm submodule`: - -* [`1e64473`](https://github.com/npm/npm/commit/1e6447360207f45ad6188e5780fdf4517de6e23d) - `rm -rf npm submodule` command, which has been broken since the Carter - Administration ([@isaacs](https://github.com/isaacs)) - -BREAKING CHANGE IF YOU ARE FOR SOME REASON STILL USING NODE 0.6 AND YOU SHOULD -NOT BE DOING THAT CAN YOU NOT: - -* [`3e431f9`](https://github.com/npm/npm/commit/3e431f9d6884acb4cde8bcb8a0b122a76b33ee1d) - [joyent/node#8492](https://github.com/joyent/node/issues/8492) bye bye - customFds, hello stdio ([@othiym23](https://github.com/othiym23)) - -Other changes: - -* [`ea607a8`](https://github.com/npm/npm/commit/ea607a8a20e891ad38eed11b5ce2c3c0a65484b9) - [#6372](https://github.com/npm/npm/issues/6372) noisily error (without - aborting) on multi-{install,build} ([@othiym23](https://github.com/othiym23)) -* [`3ee2799`](https://github.com/npm/npm/commit/3ee2799b629fd079d2db21d7e8f25fa7fa1660d0) - [#6372](https://github.com/npm/npm/issues/6372) only make cache creation - requests in flight ([@othiym23](https://github.com/othiym23)) -* [`1a90ec2`](https://github.com/npm/npm/commit/1a90ec2f2cfbefc8becc6ef0c480e5edacc8a4cb) - [#6372](https://github.com/npm/npm/issues/6372) wait to put Git URLs in - flight until normalized ([@othiym23](https://github.com/othiym23)) -* [`664795b`](https://github.com/npm/npm/commit/664795bb7d8da7142417b3f4ef5986db3a394071) - [#6372](https://github.com/npm/npm/issues/6372) log what is and isn't in - flight ([@othiym23](https://github.com/othiym23)) -* [`00ef580`](https://github.com/npm/npm/commit/00ef58025a1f52dfabf2c4dc3898621d16a6e062) - `inflight@1.0.3`: fix largely theoretical race condition, because we really - really hate race conditions ([@isaacs](https://github.com/isaacs)) -* [`1cde465`](https://github.com/npm/npm/commit/1cde4658d897ae0f93ff1d65b258e1571b391182) - [#6363](https://github.com/npm/npm/issues/6363) - `realize-package-specifier@1.1.0`: handle local dependencies better - ([@iarna](https://github.com/iarna)) -* [`86f084c`](https://github.com/npm/npm/commit/86f084c6c6d7935cd85d72d9d94b8784c914d51e) - `realize-package-specifier@1.0.2`: dependency realization! in its own module! - ([@iarna](https://github.com/iarna)) -* [`553d830`](https://github.com/npm/npm/commit/553d830334552b83606b6bebefd821c9ea71e964) - `npm-package-arg@2.1.3`: simplified semver, better tests - ([@iarna](https://github.com/iarna)) -* [`bec9b61`](https://github.com/npm/npm/commit/bec9b61a316c19f5240657594f0905a92a474352) - `readable-stream@1.0.32`: for some reason - ([@rvagg](https://github.com/rvagg)) -* [`ff08ec5`](https://github.com/npm/npm/commit/ff08ec5f6d717bdbd559de0b2ede769306a9a763) - `dezalgo@1.0.1`: use wrappy for instrumentability - ([@isaacs](https://github.com/isaacs)) - -### v2.1.2 (2014-09-29): - -* [`a1aa20e`](https://github.com/npm/npm/commit/a1aa20e44bb8285c6be1e7fa63b9da920e3a70ed) - [#6282](https://github.com/npm/npm/issues/6282) - `normalize-package-data@1.0.3`: don't prune bundledDependencies - ([@isaacs](https://github.com/isaacs)) -* [`a1f5fe1`](https://github.com/npm/npm/commit/a1f5fe1005043ce20a06e8b17a3e201aa3215357) - move locks back into cache, now path-aware - ([@othiym23](https://github.com/othiym23)) -* [`a432c4b`](https://github.com/npm/npm/commit/a432c4b48c881294d6d79b5f41c2e1c16ad15a8a) - convert lib/utils/tar.js to use atomic streams - ([@othiym23](https://github.com/othiym23)) -* [`b8c3c74`](https://github.com/npm/npm/commit/b8c3c74a3c963564233204161cc263e0912c930b) - `fs-write-stream-atomic@1.0.2`: Now works with streams1 fs.WriteStreams. - ([@isaacs](https://github.com/isaacs)) -* [`c7ab76f`](https://github.com/npm/npm/commit/c7ab76f44cce5f42add5e3ba879bd10e7e00c3e6) - logging cleanup ([@othiym23](https://github.com/othiym23)) -* [`4b2d95d`](https://github.com/npm/npm/commit/4b2d95d0641435b09d047ae5cb2226f292bf38f0) - [#6329](https://github.com/npm/npm/issues/6329) efficiently validate tmp - tarballs safely ([@othiym23](https://github.com/othiym23)) - -### v2.1.1 (2014-09-26): - -* [`563225d`](https://github.com/npm/npm/commit/563225d813ea4c12f46d4f7821ac7f76ba8ee2d6) - [#6318](https://github.com/npm/npm/issues/6318) clean up locking; prefix - lockfile with "." ([@othiym23](https://github.com/othiym23)) -* [`c7f30e4`](https://github.com/npm/npm/commit/c7f30e4550fea882d31fcd4a55b681cd30713c44) - [#6318](https://github.com/npm/npm/issues/6318) remove locking code around - tarball packing and unpacking ([@othiym23](https://github.com/othiym23)) - -### v2.1.0 (2014-09-25): - -NEW FEATURE: - -* [`3635601`](https://github.com/npm/npm/commit/36356011b6f2e6a5a81490e85a0a44eb27199dd7) - [#5520](https://github.com/npm/npm/issues/5520) Add `'npm view .'`. - ([@evanlucas](https://github.com/evanlucas)) - -Other changes: - -* [`f24b552`](https://github.com/npm/npm/commit/f24b552b596d0627549cdd7c2d68fcf9006ea50a) - [#6294](https://github.com/npm/npm/issues/6294) Lock cache → lock cache - target. ([@othiym23](https://github.com/othiym23)) -* [`ad54450`](https://github.com/npm/npm/commit/ad54450104f94c82c501138b4eee488ce3a4555e) - [#6296](https://github.com/npm/npm/issues/6296) Ensure that npm-debug.log - file is created when rollbacks are done. - ([@isaacs](https://github.com/isaacs)) -* [`6810071`](https://github.com/npm/npm/commit/681007155a40ac9d165293bd6ec5d8a1423ccfca) - docs: Default loglevel "http" → "warn". - ([@othiym23](https://github.com/othiym23)) -* [`35ac89a`](https://github.com/npm/npm/commit/35ac89a940f23db875e882ce2888208395130336) - Skip installation of installed scoped packages. - ([@timoxley](https://github.com/timoxley)) -* [`e468527`](https://github.com/npm/npm/commit/e468527256ec599892b9b88d61205e061d1ab735) - Ensure cleanup executes for scripts-whitespace-windows test. - ([@timoxley](https://github.com/timoxley)) -* [`ef9101b`](https://github.com/npm/npm/commit/ef9101b7f346797749415086956a0394528a12c4) - Ensure cleanup executes for packed-scope test. - ([@timoxley](https://github.com/timoxley)) -* [`69b4d18`](https://github.com/npm/npm/commit/69b4d18cdbc2ae04c9afaffbd273b436a394f398) - `fs-write-stream-atomic@1.0.1`: Fix a race condition in our race-condition - fixer. ([@isaacs](https://github.com/isaacs)) -* [`26b17ff`](https://github.com/npm/npm/commit/26b17ff2e3b21ee26c6fdbecc8273520cff45718) - [#6272](https://github.com/npm/npm/issues/6272) `npmconf` decides what the - default prefix is. ([@othiym23](https://github.com/othiym23)) -* [`846faca`](https://github.com/npm/npm/commit/846facacc6427dafcf5756dcd36d9036539938de) - Fix development dependency is preferred over dependency. - ([@andersjanmyr](https://github.com/andersjanmyr)) -* [`9d1a9db`](https://github.com/npm/npm/commit/9d1a9db3af5adc48a7158a5a053eeb89ee41a0e7) - [#3265](https://github.com/npm/npm/issues/3265) Re-apply a71615a. Fixes - [#3265](https://github.com/npm/npm/issues/3265) again, with a test! - ([@glasser](https://github.com/glasser)) -* [`1d41db0`](https://github.com/npm/npm/commit/1d41db0b2744a7bd50971c35cc060ea0600fb4bf) - `marked-man@0.1.4`: Fixes formatting of synopsis blocks in man docs. - ([@kapouer](https://github.com/kapouer)) -* [`a623da0`](https://github.com/npm/npm/commit/a623da01bea1b2d3f3a18b9117cfd2d8e3cbdd77) - [#5867](https://github.com/npm/npm/issues/5867) Specify dummy git template - dir when cloning to prevent copying hooks. - ([@boneskull](https://github.com/boneskull)) - -### v2.0.2 (2014-09-19): - -* [`42c872b`](https://github.com/npm/npm/commit/42c872b32cadc0e555638fc78eab3a38a04401d8) - [#5920](https://github.com/npm/npm/issues/5920) - `fs-write-stream-atomic@1.0.0` ([@isaacs](https://github.com/isaacs)) -* [`6784767`](https://github.com/npm/npm/commit/6784767fe15e28b44c81a1d4bb1738c642a65d78) - [#5920](https://github.com/npm/npm/issues/5920) make all write streams atomic - ([@isaacs](https://github.com/isaacs)) -* [`f6fac00`](https://github.com/npm/npm/commit/f6fac000dd98ebdd5ea1d5921175735d463d328b) - [#5920](https://github.com/npm/npm/issues/5920) barf on 0-length cached - tarballs ([@isaacs](https://github.com/isaacs)) -* [`3b37592`](https://github.com/npm/npm/commit/3b37592a92ea98336505189ae8ca29248b0589f4) - `write-file-atomic@1.1.0`: use graceful-fs - ([@iarna](https://github.com/iarna)) - -### v2.0.1 (2014-09-18): - -* [`74c5ab0`](https://github.com/npm/npm/commit/74c5ab0a676793c6dc19a3fd5fe149f85fecb261) - [#6201](https://github.com/npm/npm/issues/6201) `npmconf@2.1.0`: scope - always-auth to registry URI ([@othiym23](https://github.com/othiym23)) -* [`774b127`](https://github.com/npm/npm/commit/774b127da1dd6fefe2f1299e73505d9146f00294) - [#6201](https://github.com/npm/npm/issues/6201) `npm-registry-client@3.2.2`: - use scoped always-auth settings ([@othiym23](https://github.com/othiym23)) -* [`f2d2190`](https://github.com/npm/npm/commit/f2d2190aa365d22378d03afab0da13f95614a583) - [#6201](https://github.com/npm/npm/issues/6201) support saving - `--always-auth` when logging in ([@othiym23](https://github.com/othiym23)) -* [`17c941a`](https://github.com/npm/npm/commit/17c941a2d583210fe97ed47e2968d94ce9f774ba) - [#6163](https://github.com/npm/npm/issues/6163) use `write-file-atomic` - instead of `fs.writeFile()` ([@fiws](https://github.com/fiws)) -* [`fb5724f`](https://github.com/npm/npm/commit/fb5724fd98e1509c939693568df83d11417ea337) - [#5925](https://github.com/npm/npm/issues/5925) `npm init -f`: allow `npm - init` to run without prompting - ([@michaelnisi](https://github.com/michaelnisi)) -* [`b706d63`](https://github.com/npm/npm/commit/b706d637d5965dbf8f7ce07dc5c4bc80887f30d8) - [#3059](https://github.com/npm/npm/issues/3059) disable prepublish when - running `npm install --production` - ([@jussi-kalliokoski](https://github.com/jussi-kalliokoski)) -* [`119f068`](https://github.com/npm/npm/commit/119f068eae2a36fa8b9c9ca557c70377792243a4) - attach the node version used when publishing a package to its registry - metadata ([@othiym23](https://github.com/othiym23)) -* [`8fe0081`](https://github.com/npm/npm/commit/8fe008181665519c2ac201ee432a3ece9798c31f) - seriously, don't use `npm -g update npm` - ([@thomblake](https://github.com/thomblake)) -* [`ea5b3d4`](https://github.com/npm/npm/commit/ea5b3d446b86dcabb0dbc6dba374d3039342ecb3) - `request@2.44.0` ([@othiym23](https://github.com/othiym23)) - -### v2.0.0 (2014-09-12): - -BREAKING CHANGES: - -* [`4378a17`](https://github.com/npm/npm/commit/4378a17db340404a725ffe2eb75c9936f1612670) - `semver@4.0.0`: prerelease versions no longer show up in ranges; `^0.x.y` - behaves the way it did in `semver@2` rather than `semver@3`; docs have been - reorganized for comprehensibility ([@isaacs](https://github.com/isaacs)) -* [`c6ddb64`](https://github.com/npm/npm/commit/c6ddb6462fe32bf3a27b2c4a62a032a92e982429) - npm now assumes that node is newer than 0.6 - ([@isaacs](https://github.com/isaacs)) - -Other changes: - -* [`ea515c3`](https://github.com/npm/npm/commit/ea515c3b858bf493a7b87fa4cdc2110a0d9cef7f) - [#6043](https://github.com/npm/npm/issues/6043) `slide@1.1.6`: wait until all - callbacks have finished before proceeding - ([@othiym23](https://github.com/othiym23)) -* [`0b0a59d`](https://github.com/npm/npm/commit/0b0a59d504f20f424294b1590ace73a7464f0378) - [#6043](https://github.com/npm/npm/issues/6043) defer rollbacks until just - before the CLI exits ([@isaacs](https://github.com/isaacs)) -* [`a11c88b`](https://github.com/npm/npm/commit/a11c88bdb1488b87d8dcac69df9a55a7a91184b6) - [#6175](https://github.com/npm/npm/issues/6175) pack scoped packages - correctly ([@othiym23](https://github.com/othiym23)) -* [`e4e48e0`](https://github.com/npm/npm/commit/e4e48e037d4e95fdb6acec80b04c5c6eaee59970) - [#6121](https://github.com/npm/npm/issues/6121) `read-installed@3.1.2`: don't - mark linked dev dependencies as extraneous - ([@isaacs](https://github.com/isaacs)) -* [`d673e41`](https://github.com/npm/npm/commit/d673e4185d43362c2b2a91acbca8c057e7303c7b) - `cmd-shim@2.0.1`: depend on `graceful-fs` directly - ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`9d54d45`](https://github.com/npm/npm/commit/9d54d45e602d595bdab7eae09b9fa1dc46370147) - `npm-registry-couchapp@2.5.3`: make tests more reliable on Travis - ([@iarna](https://github.com/iarna)) -* [`673d738`](https://github.com/npm/npm/commit/673d738c6142c3d043dcee0b7aa02c9831a2e0ca) - ensure permissions are set correctly in cache when running as root - ([@isaacs](https://github.com/isaacs)) -* [`6e6a5fb`](https://github.com/npm/npm/commit/6e6a5fb74af10fd345411df4e121e554e2e3f33e) - prepare for upgrade to `node-semver@4.0.0` - ([@isaacs](https://github.com/isaacs)) -* [`ab8dd87`](https://github.com/npm/npm/commit/ab8dd87b943262f5996744e8d4cc30cc9358b7d7) - swap out `ronn` for `marked-man@0.1.3` ([@isaacs](https://github.com/isaacs)) -* [`803da54`](https://github.com/npm/npm/commit/803da5404d5a0b7c9defa3fe7fa0f2d16a2b19d3) - `npm-registry-client@3.2.0`: prepare for `node-semver@4.0.0` and include more - error information ([@isaacs](https://github.com/isaacs)) -* [`4af0e71`](https://github.com/npm/npm/commit/4af0e7134f5757c3d456d83e8349224a4ba12660) - make default error display less scary ([@isaacs](https://github.com/isaacs)) -* [`4fd9e79`](https://github.com/npm/npm/commit/4fd9e7901a15abff7a3dd478d99ce239b9580bca) - `npm-registry-client@3.2.1`: handle errors returned by the registry much, - much better ([@othiym23](https://github.com/othiym23)) -* [`ca791e2`](https://github.com/npm/npm/commit/ca791e27e97e51c1dd491bff6622ac90b54c3e23) - restore a long (always?) missing pass for deduping - ([@othiym23](https://github.com/othiym23)) -* [`ca0ef0e`](https://github.com/npm/npm/commit/ca0ef0e99bbdeccf28d550d0296baa4cb5e7ece2) - correctly interpret relative paths for local dependencies - ([@othiym23](https://github.com/othiym23)) -* [`5eb8db2`](https://github.com/npm/npm/commit/5eb8db2c370eeb4cd34f6e8dc6a935e4ea325621) - `npm-package-arg@2.1.2`: support git+file:// URLs for local bare repos - ([@othiym23](https://github.com/othiym23)) -* [`860a185`](https://github.com/npm/npm/commit/860a185c43646aca84cb93d1c05e2266045c316b) - tweak docs to no longer advocate checking in `node_modules` - ([@hunterloftis](https://github.com/hunterloftis)) -* [`80e9033`](https://github.com/npm/npm/commit/80e9033c40e373775e35c674faa6c1948661782b) - add links to nodejs.org downloads to docs - ([@meetar](https://github.com/meetar)) - -### v2.0.0-beta.3 (2014-09-04): - -* [`fa79413`](https://github.com/npm/npm/commit/fa794138bec8edb7b88639db25ee9c010d2f4c2b) - [#6119](https://github.com/npm/npm/issues/6119) fall back to registry installs - if package.json is missing in a local directory ([@iarna](https://github.com/iarna)) -* [`16073e2`](https://github.com/npm/npm/commit/16073e2d8ae035961c4c189b602d4aacc6d6b387) - `npm-package-arg@2.1.0`: support file URIs as local specs - ([@othiym23](https://github.com/othiym23)) -* [`9164acb`](https://github.com/npm/npm/commit/9164acbdee28956fa816ce5e473c559395ae4ec2) - `github-url-from-username-repo@1.0.2`: don't match strings that are already - URIs ([@othiym23](https://github.com/othiym23)) -* [`4067d6b`](https://github.com/npm/npm/commit/4067d6bf303a69be13f3af4b19cf4fee1b0d3e12) - [#5629](https://github.com/npm/npm/issues/5629) support saving of local packages - in `package.json` ([@dylang](https://github.com/dylang)) -* [`1b2ffdf`](https://github.com/npm/npm/commit/1b2ffdf359a8c897a78f91fc5a5d535c97aaec97) - [#6097](https://github.com/npm/npm/issues/6097) document scoped packages - ([@seldo](https://github.com/seldo)) -* [`0a67d53`](https://github.com/npm/npm/commit/0a67d536067c4808a594d81288d34c0f7e97e105) - [#6007](https://github.com/npm/npm/issues/6007) `request@2.42.0`: properly - set headers on proxy requests ([@isaacs](https://github.com/isaacs)) -* [`9bac6b8`](https://github.com/npm/npm/commit/9bac6b860b674d24251bb7b8ba412fdb26cbc836) - `npmconf@2.0.8`: disallow semver ranges in tag configuration - ([@isaacs](https://github.com/isaacs)) -* [`d2d4d7c`](https://github.com/npm/npm/commit/d2d4d7cd3c32f91a87ffa11fe464d524029011c3) - [#6082](https://github.com/npm/npm/issues/6082) don't allow tagging with a - semver range as the tag name ([@isaacs](https://github.com/isaacs)) - -### v2.0.0-beta.2 (2014-08-29): - -SPECIAL LABOR DAY WEEKEND RELEASE PARTY WOOO - -* [`ed207e8`](https://github.com/npm/npm/commit/ed207e88019de3150037048df6267024566e1093) - `npm-registry-client@3.1.7`: Clean up auth logic and improve logging around - auth decisions. Also error on trying to change a user document without - writing to it. ([@othiym23](https://github.com/othiym23)) -* [`66c7423`](https://github.com/npm/npm/commit/66c7423b7fb07a326b83c83727879410d43c439f) - `npmconf@2.0.7`: support -C as an alias for --prefix - ([@isaacs](https://github.com/isaacs)) -* [`0dc6a07`](https://github.com/npm/npm/commit/0dc6a07c778071c94c2251429c7d107e88a45095) - [#6059](https://github.com/npm/npm/issues/6059) run commands in prefix, not - cwd ([@isaacs](https://github.com/isaacs)) -* [`65d2179`](https://github.com/npm/npm/commit/65d2179af96737eb9038eaa24a293a62184aaa13) - `github-url-from-username-repo@1.0.1`: part 3 handle slashes in branch names - ([@robertkowalski](https://github.com/robertkowalski)) -* [`e8d75d0`](https://github.com/npm/npm/commit/e8d75d0d9f148ce2b3e8f7671fa281945bac363d) - [#6057](https://github.com/npm/npm/issues/6057) `read-installed@3.1.1`: - properly handle extraneous dev dependencies of required dependencies - ([@othiym23](https://github.com/othiym23)) -* [`0602f70`](https://github.com/npm/npm/commit/0602f708f070d524ad41573afd4c57171cab21ad) - [#6064](https://github.com/npm/npm/issues/6064) ls: do not show deps of - extraneous deps ([@isaacs](https://github.com/isaacs)) - -### v2.0.0-beta.1 (2014-08-28): - -* [`78a1fc1`](https://github.com/npm/npm/commit/78a1fc12307a0cbdbc944775ed831b876ee65855) - `github-url-from-git@1.4.0`: add support for git+https and git+ssh - ([@stefanbuck](https://github.com/stefanbuck)) -* [`bf247ed`](https://github.com/npm/npm/commit/bf247edf5429c6b3ec4d4cb798fa0eb0a9c19fc1) - `columnify@1.2.1` ([@othiym23](https://github.com/othiym23)) -* [`4bbe682`](https://github.com/npm/npm/commit/4bbe682a6d4eabcd23f892932308c9f228bf4de3) - `cmd-shim@2.0.0`: upgrade to graceful-fs 3 - ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`ae1d590`](https://github.com/npm/npm/commit/ae1d590bdfc2476a4ed446e760fea88686e3ae05) - `npm-package-arg@2.0.4`: accept slashes in branch names - ([@thealphanerd](https://github.com/thealphanerd)) -* [`b2f51ae`](https://github.com/npm/npm/commit/b2f51aecadf585711e145b6516f99e7c05f53614) - `semver@3.0.1`: semver.clean() is cleaner - ([@isaacs](https://github.com/isaacs)) -* [`1d041a8`](https://github.com/npm/npm/commit/1d041a8a5ebd5bf6cecafab2072d4ec07823adab) - `github-url-from-username-repo@1.0.0`: accept slashes in branch names - ([@robertkowalski](https://github.com/robertkowalski)) -* [`02c85d5`](https://github.com/npm/npm/commit/02c85d592c4058e5d9eafb0be36b6743ae631998) - `async-some@1.0.1` ([@othiym23](https://github.com/othiym23)) -* [`5af493e`](https://github.com/npm/npm/commit/5af493efa8a463cd1acc4a9a394699e2c0793b9c) - ensure lifecycle spawn errors caught properly - ([@isaacs](https://github.com/isaacs)) -* [`60fe012`](https://github.com/npm/npm/commit/60fe012fac9570d6c72554cdf34a6fa95bf0f0a6) - `npmconf@2.0.6`: init.version defaults to 1.0.0 - ([@isaacs](https://github.com/isaacs)) -* [`b4c717b`](https://github.com/npm/npm/commit/b4c717bbf58fb6a0d64ad229036c79a184297ee2) - `npm-registry-client@3.1.4`: properly encode % in passwords - ([@isaacs](https://github.com/isaacs)) -* [`7b55f44`](https://github.com/npm/npm/commit/7b55f44420252baeb3f30da437d22956315c31c9) - doc: Fix 'npm help index' ([@isaacs](https://github.com/isaacs)) - -### v2.0.0-beta.0 (2014-08-21): - -* [`685f8be`](https://github.com/npm/npm/commit/685f8be1f2770cc75fd0e519a8d7aac72735a270) - `npm-registry-client@3.1.3`: Print the notification header returned by the - registry, and make sure status codes are printed without gratuitous quotes - around them. ([@isaacs](https://github.com/isaacs) / - [@othiym23](https://github.com/othiym23)) -* [`a8cb676`](https://github.com/npm/npm/commit/a8cb676aef0561eaf04487d2719672b097392c85) - [#5900](https://github.com/npm/npm/issues/5900) remove `npm` from its own - `engines` field in `package.json`. None of us remember why it was there. - ([@timoxley](https://github.com/timoxley)) -* [`6c47201`](https://github.com/npm/npm/commit/6c47201a7d071e8bf091b36933daf4199cc98e80) - [#5752](https://github.com/npm/npm/issues/5752), - [#6013](https://github.com/npm/npm/issues/6013) save git URLs correctly in - `_resolved` fields ([@isaacs](https://github.com/isaacs)) -* [`e4e1223`](https://github.com/npm/npm/commit/e4e1223a91c37688ba3378e1fc9d5ae045654d00) - [#5936](https://github.com/npm/npm/issues/5936) document the use of tags in - `package.json` ([@KenanY](https://github.com/KenanY)) -* [`c92b8d4`](https://github.com/npm/npm/commit/c92b8d4db7bde2a501da5b7d612684de1d629a42) - [#6004](https://github.com/npm/npm/issues/6004) manually installed scoped - packages are tracked correctly ([@dead](https://github.com/dead)-horse) -* [`21ca0aa`](https://github.com/npm/npm/commit/21ca0aaacbcfe2b89b0a439d914da0cae62de550) - [#5945](https://github.com/npm/npm/issues/5945) link scoped packages - correctly ([@dead](https://github.com/dead)-horse) -* [`16bead7`](https://github.com/npm/npm/commit/16bead7f2c82aec35b83ff0ec04df051ba456764) - [#5958](https://github.com/npm/npm/issues/5958) ensure that file streams work - in all versions of node ([@dead](https://github.com/dead)-horse) -* [`dbf0cab`](https://github.com/npm/npm/commit/dbf0cab29d0db43ac95e4b5a1fbdea1e0af75f10) - you can now pass quoted args to `npm run-script` - ([@bcoe](https://github.com/bcoe)) -* [`0583874`](https://github.com/npm/npm/commit/05838743f01ccb8d2432b3858d66847002fb62df) - `tar@1.0.1`: Add test for removing an extract target immediately after - unpacking. - ([@isaacs](https://github.com/isaacs)) -* [`cdf3b04`](https://github.com/npm/npm/commit/cdf3b0428bc0b0183fb41dcde9e34e8f42c5e3a7) - `lockfile@1.0.0`: Fix incorrect interaction between `wait`, `stale`, and - `retries` options. Part 2 of race condition leading to `ENOENT` - ([@isaacs](https://github.com/isaacs)) - errors. -* [`22d72a8`](https://github.com/npm/npm/commit/22d72a87a9e1a9ab56d9585397f63551887d9125) - `fstream@1.0.2`: Fix a double-finish call which can result in excess FS - operations after the `close` event. Part 1 of race condition leading to - `ENOENT` errors. - ([@isaacs](https://github.com/isaacs)) - -### v2.0.0-alpha.7 (2014-08-14): - -* [`f23f1d8`](https://github.com/npm/npm/commit/f23f1d8e8f86ec1b7ab8dad68250bccaa67d61b1) - doc: update version doc to include `pre-*` increment args - ([@isaacs](https://github.com/isaacs)) -* [`b6bb746`](https://github.com/npm/npm/commit/b6bb7461824d4dc1c0936f46bd7929b5cd597986) - build: add 'make tag' to tag current release as latest - ([@isaacs](https://github.com/isaacs)) -* [`27c4bb6`](https://github.com/npm/npm/commit/27c4bb606e46e5eaf604b19fe8477bc6567f8b2e) - build: publish with `--tag=v1.4-next` ([@isaacs](https://github.com/isaacs)) -* [`cff66c3`](https://github.com/npm/npm/commit/cff66c3bf2850880058ebe2a26655dafd002495e) - build: add script to output `v1.4-next` publish tag - ([@isaacs](https://github.com/isaacs)) -* [`22abec8`](https://github.com/npm/npm/commit/22abec8833474879ac49b9604c103bc845dad779) - build: remove outdated `docpublish` make target - ([@isaacs](https://github.com/isaacs)) -* [`1be4de5`](https://github.com/npm/npm/commit/1be4de51c3976db8564f72b00d50384c921f0917) - build: remove `unpublish` step from `make publish` - ([@isaacs](https://github.com/isaacs)) -* [`e429e20`](https://github.com/npm/npm/commit/e429e2011f4d78e398f2461bca3e5a9a146fbd0c) - doc: add new changelog ([@othiym23](https://github.com/othiym23)) -* [`9243d20`](https://github.com/npm/npm/commit/9243d207896ea307082256604c10817f7c318d68) - lifecycle: test lifecycle path modification - ([@isaacs](https://github.com/isaacs)) -* [`021770b`](https://github.com/npm/npm/commit/021770b9cb07451509f0a44afff6c106311d8cf6) - lifecycle: BREAKING CHANGE do not add the directory containing node executable - ([@chulkilee](https://github.com/chulkilee)) -* [`1d5c41d`](https://github.com/npm/npm/commit/1d5c41dd0d757bce8b87f10c4135f04ece55aeb9) - install: rename .gitignore when unpacking foreign tarballs - ([@isaacs](https://github.com/isaacs)) -* [`9aac267`](https://github.com/npm/npm/commit/9aac2670a73423544d92b27cc301990a16a9563b) - cache: detect non-gzipped tar files more reliably - ([@isaacs](https://github.com/isaacs)) -* [`3f24755`](https://github.com/npm/npm/commit/3f24755c8fce3c7ab11ed1dc632cc40d7ef42f62) - `readdir-scoped-modules@1.0.0` ([@isaacs](https://github.com/isaacs)) -* [`151cd2f`](https://github.com/npm/npm/commit/151cd2ff87b8ac2fc9ea366bc9b7f766dc5b9684) - `read-installed@3.1.0` ([@isaacs](https://github.com/isaacs)) -* [`f5a9434`](https://github.com/npm/npm/commit/f5a94343a8ebe4a8cd987320b55137aef53fb3fd) - test: fix Travis timeouts ([@dylang](https://github.com/dylang)) -* [`126cafc`](https://github.com/npm/npm/commit/126cafcc6706814c88af3042f2ffff408747bff4) - `npm-registry-couchapp@2.5.0` ([@othiym23](https://github.com/othiym23)) - -### v2.0.0-alpha.6 (2014-08-07): - -BREAKING CHANGE: - -* [`ea547e2`](https://github.com/npm/npm/commit/ea547e2) Bump semver to - version 3: `^0.x.y` is now functionally the same as `=0.x.y`. - ([@isaacs](https://github.com/isaacs)) - -Other changes: - -* [`d987707`](https://github.com/npm/npm/commit/d987707) move fetch into - npm-registry-client ([@othiym23](https://github.com/othiym23)) -* [`9b318e2`](https://github.com/npm/npm/commit/9b318e2) `read-installed@3.0.0` - ([@isaacs](https://github.com/isaacs)) -* [`9d73de7`](https://github.com/npm/npm/commit/9d73de7) remove unnecessary - mkdirps ([@isaacs](https://github.com/isaacs)) -* [`33ccd13`](https://github.com/npm/npm/commit/33ccd13) Don't squash execute - perms in `_git-remotes/` dir ([@adammeadows](https://github.com/adammeadows)) -* [`48fd233`](https://github.com/npm/npm/commit/48fd233) `npm-package-arg@2.0.1` - ([@isaacs](https://github.com/isaacs)) - -### v2.0.0-alpha-5 (2014-07-22): - -This release bumps up to 2.0 because of this breaking change, which could -potentially affect how your package's scripts are run: - -* [`df4b0e7`](https://github.com/npm/npm/commit/df4b0e7fc1abd9a54f98db75ec9e4d03d37d125b) - [#5518](https://github.com/npm/npm/issues/5518) BREAKING CHANGE: support - passing arguments to `run` scripts ([@bcoe](https://github.com/bcoe)) - -Other changes: - -* [`cd422c9`](https://github.com/npm/npm/commit/cd422c9de510766797c65720d70f085000f50543) - [#5748](https://github.com/npm/npm/issues/5748) link binaries for scoped - packages ([@othiym23](https://github.com/othiym23)) -* [`4c3c778`](https://github.com/npm/npm/commit/4c3c77839920e830991e0c229c3c6a855c914d67) - [#5758](https://github.com/npm/npm/issues/5758) `npm link` includes scope - when linking scoped package ([@fengmk2](https://github.com/fengmk2)) -* [`f9f58dd`](https://github.com/npm/npm/commit/f9f58dd0f5b715d4efa6619f13901916d8f99c47) - [#5707](https://github.com/npm/npm/issues/5707) document generic pre- / - post-commands ([@sudodoki](https://github.com/sudodoki)) -* [`ac7a480`](https://github.com/npm/npm/commit/ac7a4801d80361b41dce4a18f22bcdf75e396000) - [#5406](https://github.com/npm/npm/issues/5406) `npm cache` displays usage - when called without arguments - ([@michaelnisi](https://github.com/michaelnisi)) -* [`f4554e9`](https://github.com/npm/npm/commit/f4554e99d34f77a8a02884493748f7d49a9a9d8b) - Test fixes for Windows ([@isaacs](https://github.com/isaacs)) -* update dependencies ([@othiym23](https://github.com/othiym23)) diff --git a/changelogs/CHANGELOG-3.md b/changelogs/CHANGELOG-3.md deleted file mode 100644 index fc55a696fb22a..0000000000000 --- a/changelogs/CHANGELOG-3.md +++ /dev/null @@ -1,5245 +0,0 @@ -### v3.10.10 (2016-11-04) - -See the discussion on [#14042](https://github.com/npm/npm/issues/14042) for -more context on this release, which is intended to address a serious regression -in shrinkwrap behavior in the version of the CLI currently bundled with Node.js -6 LTS "Boron". You should never install this version directly; instead update -to `npm@4`, which has everything in this release and more. - -#### REGRESSION FIX - -* [`9aebe98`](https://github.com/npm/npm/commit/9aebe982114ea2107f46baa1dcb11713b4aaad04) - [#14117](https://github.com/npm/npm/pull/14117) - Fixes a bug where installing a shrinkwrapped package would fail if the - platform failed to install an optional dependency included in the shrinkwrap. - ([@watilde](https://github.com/watilde)) - -#### UPDATE SUPPORT MATRIX - -With the advent of the second official Node.js LTS release, Node 6.x -'Boron', the Node.js project has now officially dropped versions 0.10 -and 0.12 out of the maintenance phase of LTS. (Also, Node 5 was never -part of LTS, and will see no further support now that Node 7 has been -released.) As a small team with limited resources, the npm CLI team is -following suit and dropping those versions of Node from its CI test -matrix. - -* [`c82ecfd`](https://github.com/npm/npm/commit/c82ecfdbe0b5f318a175714a8753efe4dfd3e4b3) - [#14503](https://github.com/npm/npm/pull/14503) - Node 6 is LTS; 5.x, 0.10, and 0.12 are unsupported. - ([@othiym23](https://github.com/othiym23)) - -### v3.10.9 (2016-10-06) - -Hi everyone! This is the last of our monthly releases. We're going to give -an every-two-weeks schedule a try starting with our next release. We'll -reevaluate in a quarter, but we suspect that will be what we'll stick with. -You might be wondering _why_ we've been fiddling with the release cadence? Well, -we've been trying to tune it to to minimize the overhead for our little team. - -This is ALSO the ULTIMATE release of `npm` version 3. That's right, in -just two weeks' time (October 20th for you fans of calendar time), our dear -`npm` will be hitting the big 4.0. - -**DON'T PANIC** - -This is gonna be a much, MUCH smaller major version than 3.x was. Maybe even -smaller than 2.x was. I can't tell you everything that'll be in there just -yet, but at the very least it's going to have what's in our -[4.x milestone](https://github.com/npm/npm/pulls?q=is%3Aopen+is%3Apr+milestone%3A4.x), -PLUS, the first steps in -[making `prepublish` work](https://github.com/npm/npm/issues/10074) the way -people expect it to. - -**NOW ABOUT THIS RELEASE** - -This release sees a whole slew of bug fixes. Notably a bunch of lifecycle -fixes and a really important shrinkwrap fix. - -#### LIFECYCLE FIXES - -* [`d388f90`](https://github.com/npm/npm/commit/d388f90732981633b3cdb4fc7fb0fababd4e64ab) - [#13942](https://github.com/npm/npm/pull/13942) - Fix current working directory while running shrinkwrap lifecycle scripts. - Previously if you ran a shrinkwrap from another lifecycle script AND - `node_modules` existed (and if you're running `npm shrinkwrap` it probably - should) then `npm` would run the shrinkwrap lifecycle from the - `node_modules` folder instead of the package folder. - ([@evocateur](https://github.com/evocateur)) - ([@iarna](https://github.com/iarna)) -* [`c3b6cdf`](https://github.com/npm/npm/commit/c3b6cdfedcdb4d9e7712be5245d9b274828d88d1) - [#13964](https://github.com/npm/npm/pull/13964) - Fix bug where the `uninstall` lifecycles weren't being run when you - reinstalled/updated an existing module. - ([@iarna](https://github.com/iarna)) -* [`72bb89c`](https://github.com/npm/npm/commit/72bb89c1aa9811a18cbd766f3da73da76eb920c6) - [#13344](https://github.com/npm/npm/pull/13344) - When running lifecycles use `TMPDIR` if it's writable and fall back to the - current working directory if not. Previously we just assumed `TMPDIR` - wouldn't be writable (as we might have been running as `nobody` and - `nobody` on some systems can't write to `TMPDIR`). - ([@aaronjensen](https://github.com/aaronjensen)) - -#### SHRINKWRAP GIT & TAGGED DEPENDENCY FIX - -* [`3b5eee0`](https://github.com/npm/npm/commit/3b5eee0d31737d1c2518ed95dcc7aaaaa93c253c) - [#13941](https://github.com/npm/npm/pull/13941) - Fix git and tagged dependency matching with shrinkwraps. Previously git - and tag (ie `foo@latest`) dependencies installed from a shrinkwrap would - always be flagged as invalid. - ([@iarna](https://github.com/iarna)) - -#### BUG FIXES - -* [`bf3bd1e`](https://github.com/npm/npm/commit/bf3bd1e4347ee2c5de08d23558c4444749178c8b) - [#14143](https://github.com/npm/npm/pull/14143) - Fix bug in `npm version` where `npm-shrinkwrap.json` wouldn't be updated - if you ran `npm version` from outside of your project root. - ([@lholmquist](https://github.com/lholmquist)) -* [`1089878`](https://github.com/npm/npm/commit/1089878f58977559414c8a9addfc69a9c68905b0) - [#13613](https://github.com/npm/npm/pull/13613) - Log 'skipping action' as 'verbose' instead of 'warn'. This removes a lot of - clutter when there are links in your `node_modules`. The long term plan is - to entirely blind `npm` to what's inside links, which will make this code - go away entirely. - ([@timoxley](https://github.com/timoxley)) -* [`952f1e1`](https://github.com/npm/npm/commit/952f1e109a070ab4066179f6104ba9394300e342) - [#13999](https://github.com/npm/npm/pull/13999) - Fix a bug where setting `bin` to `null` in your `package.json` would result - in `npm` crashing. - ([@IonicaBizau](https://github.com/IonicaBizau)) -* [`fcf8b11`](https://github.com/npm/npm/commit/fcf8b11fb7fcf8902f6a887c3d5f0aef2897dde0) - [#14032](https://github.com/npm/npm/pull/14032) - When using `npm view`, if you specified a version that didn't exist it - would previously print `undefined` (even if you asked for JSON output). It - now prints nothing in this situation. This brings `npm@3`'s behavior in - line with `npm@2`. - ([@roblg](https://github.com/roblg)) -* [`93c689f`](https://github.com/npm/npm/commit/93c689ff44c6042a2dcde7fe0d74d2264237d666) - [#14032](https://github.com/npm/npm/pull/14032) - When using `npm view --json` with a version range that matches multiple - versions we now return a list of all of the metadata for all of those - versions. Previously we picked one and only returned that. This brings - `npm@3`'s behavior in line with `npm@2`. - ([@roblg](https://github.com/roblg)) -* [`2411728`](https://github.com/npm/npm/commit/24117289e09c373b845150c45e4793d98fe7cf4b) - [#14045](https://github.com/npm/npm/pull/14045) - Fix a Windows-only bug in the `git` tests. The tests had rather particular - ideas about what arguments would be passed to `git` and on Windows they - got this wrong. - ([@watilde](https://github.com/watilde)) - -#### DOCUMENTATION & MISC - -* [`30772cc`](https://github.com/npm/npm/commit/30772cc5f80923bf21c003fbe53e5fed9d3a5d97) - [#13904](https://github.com/npm/npm/pull/13904) - Update `package.json` example to include GitHub branches. - ([@stevokk](https://github.com/stevokk)) -* [`f66876f`](https://github.com/npm/npm/commit/f66876f75c204fb78028cf2ff7979f80355bd06c) - [#14010](https://github.com/npm/npm/pull/14010) - Update the GitHub issue template to reflect Apple's change in name of its - desktop operating system. - ([@AlexChesters](https://github.com/AlexChesters)) - -#### DEPENDENCY UPDATES - -* [`b3f9bf1`](https://github.com/npm/npm/commit/b3f9bf1ada3f93e6775f5c232350030db6635d0c) - [#13918](https://github.com/npm/npm/issues/13918) - `graceful-fs@4.1.9`: - Fix the _uid must be an unsigned int_ bug that's been around forever but that - `npm` started tickling in v3.10.8. - ([@addaleax](https://github.com/addaleax)) - Also fixes wrapper to `fs.readdir` to actually pass through (rather than - drop) optional arguments. - ([@isaacs](https://github.com/isaacs)) -* [`9402ead`](https://github.com/npm/npm/commit/9402ead67e3be9b431ade637fbfac86204ee96fe) - [isaacs/node-glob#293](https://github.com/isaacs/node-glob/pull/293) - `glob@7.1.0`: - Add `absolute` option for `match` event. - ([@phated](https://github.com/phated)) -* [`58b83db`](https://github.com/npm/npm/commit/58b83db327dd87bf7cb5a7d503303537718f2f30) - `asap@2.0.5` - ([@kriskowal](https://github.com/kriskowal)) -* [`5707e6e`](https://github.com/npm/npm/commit/5707e6e55b220439c3f83e77daf4c70d72eb46f0) - `sorted-object@2.0.1` - ([@domenic](https://github.com/domenic)) -* [`9d20910`](https://github.com/npm/npm/commit/9d209107ce49a7424c50459284280cd2e6e215d1) - `request@2.75.0` - ([@simov](https://github.com/simov)) -* [`dea4848`](https://github.com/npm/npm/commit/dea48487a9d03492edc68670d05776d32d9ee8cf) - `path-is-inside@1.0.2` - ([@domenic](https://github.com/domenic)) -* [`b3f3db5`](https://github.com/npm/npm/commit/b3f3db52e864d607b6d9b18920e2f58acc4b1616) - `opener@1.4.2` - ([@dominic](https://github.com/dominic)) -* [`6bb5f95`](https://github.com/npm/npm/commit/6bb5f953888bbaaeeb624d623c2a9746d1c243a0) - `lockfile@1.0.2` - ([@isaacs](https://github.com/isaacs)) -* [`13f7c0a`](https://github.com/npm/npm/commit/13f7c0a73212284b53a2d96882fc298afbf9609c) - `config-chain@1.1.11` - ([@dominictarr](https://github.com/dominictarr)) - -### v3.10.8 (2016-09-08) - -Monthly releases are so big! Just look at all this stuff! - -Our quarter of monthly releases is almost over. The next one, in October, might -very well be our last one as we move to trying something different and learning -lessons from our little experiment. - -You may also want to keep an eye our for `npm@4` next month, since we're -planning on finally releasing it then and including a (small) number of breaking -changes we've been meaning to do for a long time. Don't worry, though: `npm@3` -will still be around for a bit and will keep getting better and better, and is -most likely going to be the version that `node@6` uses once it goes to LTS. - -As some of us have mentioned before, npm is likely to start doing more regular -semver-major bumps, while keeping those bumps significantly smaller than the -huge effort that was `npm@3` -- we're not very likely to do a world-shaking -thing like that for a while, if ever. - -All that said, let's move on to the patches included in v3.10.8! - -#### SHRINKWRAP LEVEL UP - -The most notable part of this release is a series of commits meant to make `npm -shrinkwrap` more consistent. By itself, shrinkwrap seems like a fairly -straightforward thing to implement, but things get complicated when it starts -interacting with `devDependencies`, `optionalDependencies`, and -`bundledDependencies`. These commits address some corner cases related to these. - -* [`a7eca32`](https://github.com/npm/npm/commit/a7eca3246fbbcbb05434cb6677f65d14c945d74f) - [#10073](https://github.com/npm/npm/pull/10073) - Record if a dependency is only used as a devDependency and exclude it from the - shrinkwrap file. - ([@bengl](https://github.com/bengl)) -* [`1eabcd1`](https://github.com/npm/npm/commit/1eabcd16bf2590364ca20831096350073539bf3a) - [#10073](https://github.com/npm/npm/pull/10073) - Record if a dependency is optional to shrinkwrap. - ([@bengl](https://github.com/bengl)) -* [`03efc89`](https://github.com/npm/npm/commit/03efc89522c99ee0fa37d8f4a99bc3b44255ef98) - [#13692](https://github.com/npm/npm/pull/13692/) - We were doing a weird thing where we used a `package.json` field `installable` - to check to see if we'd checked for platform compatibility, and if not did - so. But this was the only place that was ever done so there was no reason to - implement it in such an obfuscated manner. - Instead it now just directly checks and then records that its done so on the - node object with `knownInstallable`. This is useful to know because modules - expanded via shrinkwrap don't go through this– `inflateShrinkwrap` does not - currently have any rollback semantics and so checking this sort of thing there - is unhelpful. - ([@iarna](https://github.com/iarna)) -* [`ff87938`](https://github.com/npm/npm/commit/ff879382fda21dac7216a5f666287b3a7e74a947) - [#11735](https://github.com/npm/npm/issues/11735) - Running `npm install --save-dev` will now update shrinkwrap file, but only - if there already are devDependencies in it. - ([@szimek](https://github.com/szimek)) -* [`c00ca3a`](https://github.com/npm/npm/commit/c00ca3aef836709eeaeade91c5305bc2fbda2e8a) - [#13394](https://github.com/npm/npm/issues/13394) - Check installability of modules from shrinkwrap, since modules that came into - the tree vie shrinkwrap won't already have this information recorded in - advance. - ([@iarna](https://github.com/iarna)) - -#### INSTALLER ERROR REPORTING LEVEL UP - -As part of the shrinkwrap push, there were also a lot of error-reporting -improvements. Some to add more detail to error objects, others to fix bugs and -inconsistencies. - -* [`2cdd713`](https://github.com/npm/npm/commit/2cdd7132abddcc7f826a355c14348ce9a5897ffe) - Consistently set code on `ETARGET` when fetching package metadata if no - compatible version is found. - ([@iarna](https://github.com/iarna)) -* [`cabcd17`](https://github.com/npm/npm/commit/cabcd173f2923cb5b77e7be0e42eea2339a24727) - [#13692](https://github.com/npm/npm/pull/13692/) - Include installer warning details at the `verbose` log level. - ([@iarna](https://github.com/iarna)) -* [`95a4044`](https://github.com/npm/npm/commit/95a4044cbae93d19d0da0f3cd04ea8fa620295d9) - [`dbb14c2`](https://github.com/npm/npm/commit/dbb14c241d982596f1cdaee251658f5716989fd2) - [`9994383`](https://github.com/npm/npm/commit/9994383959798f80749093301ec43a8403566bb6) - [`7417000`](https://github.com/npm/npm/commit/74170003db0c53def9b798cb6fe3fe7fc3e06482) - [`f45f85d`](https://github.com/npm/npm/commit/f45f85dac800372d63dfa8653afccbf5bcae7295) - [`e79cc1b`](https://github.com/npm/npm/commit/e79cc1b11440f0d122c4744d5eff98def9553f4a) - [`146ee39`](https://github.com/npm/npm/commit/146ee394b1f7a33cf409a30b835a85d939acb438) - [#13692](https://github.com/npm/npm/pull/13692/) - Improve various bits of error reporting, adding more error information and - some related refactoring. - ([@iarna](https://github.com/iarna)) - -#### MISCELLANEOUS BUGS LEVEL UP - -* [`116b6c6`](https://github.com/npm/npm/commit/116b6c60a174ea0cc49e4d62717e4e26175b6534) - [#13456](https://github.com/npm/npm/issues/13456) - In lifecycle scripts, any `node_modules/.bin` existing in the hierarchy - should be turned into an entry in the PATH environment variable. - However, prior to this commit, it was splitting based on the string - `node_modules`, rather than restricting it to only path portions like - `/node_modules/` or `\node_modules\`. So, a path containing an entry - like `my_node_modules` would be improperly split. - ([@isaacs](https://github.com/isaacs)) -* [`0a28dd0`](https://github.com/npm/npm/commit/0a28dd0104e5b4a8cc0cb038bd213e6a50827fe8) - [npm/fstream-npm#23](https://github.com/npm/fstream-npm/pull/23) - `fstream-npm@1.2.0`: - Always ignore `*.orig` files, which are generated by git when using `git - mergetool`, by default. - ([@zkat](https://github.com/zkat)) -* [`a3a2fb9`](https://github.com/npm/npm/commit/a3a2fb97adc87c2aa9b2b8957861b30efafc7ad0) - [#13708](https://github.com/npm/npm/pull/13708) - Always ignore `*.orig` files, which are generated by git when using `git - mergetool`, by default. - ([@boneskull](https://github.com/boneskull)) - -#### TOOLING LEVEL UP - -* [`e1d7e6c`](https://github.com/npm/npm/commit/e1d7e6ce551cbc42026cdcadcb37ea515059c972) - Add helper for generating test skeletons. - ([@iarna](https://github.com/iarna)) -* [`4400b35`](https://github.com/npm/npm/commit/4400b356bca9175935edad1469c608c909bc01bf) - Fix fixture creation and cleanup in `maketest`. - ([@iarna](https://github.com/iarna)) - -#### DOCUMENTATION LEVEL UP - -* [`8eb9460`](https://github.com/npm/npm/commit/8eb94601fe895b97cbcf8c6134e6b371c5371a1e) - [#13717](https://github.com/npm/npm/pull/13717) - Document that `npm link` will link the files specified in the `bin` field of - `package.json` to `{prefix}/bin/{name}`. - ([@legodude17](https://github.com/legodude17)) -* [`a66e5e9`](https://github.com/npm/npm/commit/a66e5e9c388878fe03fb29014c3b95d28bedd3c1) - [#13682](https://github.com/npm/npm/pull/13682) - Minor grammar fix in documentation for `npm scripts`. - ([@Ajedi32](https://github.com/Ajedi32)) -* [`74b8043`](https://github.com/npm/npm/commit/74b80437ffdfcf8172f6ed4f39bfb021608dd9dd) - [#13655](https://github.com/npm/npm/pull/13655) - Document line comment syntax for `.npmrc`. - ([@mdjasper](https://github.com/mdjasper)) -* [`b352a84`](https://github.com/npm/npm/commit/b352a84c2c7ad15e9c669af75f65cdaa964f86c0) - [#12438](https://github.com/npm/npm/issues/12438) - Remind folks to use `#!/usr/bin/env node` in their `bin` scripts to make files - executable directly. - ([@mxstbr](https://github.com/mxstbr)) -* [`b82fd83`](https://github.com/npm/npm/commit/b82fd838edbfff5d2833a62f6d8ae8ea2df5a1f2) - [#13493](https://github.com/npm/npm/pull/13493) - Document that the user config file can itself be configured either through the - `$NPM_CONFIG_USERCONFIG` environment variable, or `--userconfig` command line - flag. - ([@jasonkarns](https://github.com/jasonkarns)) -* [`8a02699`](https://github.com/npm/npm/commit/8a026992a03d90e563a97c70e90926862120693b) - [#13911](https://github.com/npm/npm/pull/13911) - Minor documentation reword and cleanup. - ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY LEVEL UP - -* [`2818fb0`](https://github.com/npm/npm/commit/2818fb0f6081d68a91f0905945ad102f26c6cf85) - `glob@7.0.6` - ([@isaacs](https://github.com/isaacs)) -* [`d88ec81`](https://github.com/npm/npm/commit/d88ec81ad33eb2268fcd517d35346a561bc59aff) - `graceful-fs@4.1.6` - ([@francescoinfante](https://github.com/francescoinfante)) -* [`4727f86`](https://github.com/npm/npm/commit/4727f8646daca7b3e3c1c95860e02acf583b9dae) - `lodash.clonedeep@4.5.0` - ([@jdalton](https://github.com/jdalton)) -* [`c347678`](https://github.com/npm/npm/commit/c3476780ef4483425e4ae1d095a5884b46b8db86) - `lodash.union@4.6.0` - ([@jdalton](https://github.com/jdalton)) -* [`530bd4d`](https://github.com/npm/npm/commit/530bd4d2ae6f704f624e4f7bf64f911f37e2b7f8) - `lodash.uniq@4.5.0` - ([@jdalton](https://github.com/jdalton)) -* [`483d56a`](https://github.com/npm/npm/commit/483d56ae8137eca0c0f7acd5d1c88ca6d5118a6a) - `lodash.without@4.4.0` - ([@jdalton](https://github.com/jdalton)) -* [`6c934df`](https://github.com/npm/npm/commit/6c934df6e74bacd0ed40767b319936837a43b586) - `inherits@2.0.3` - ([@isaacs](https://github.com/isaacs)) -* [`a65ed7c`](https://github.com/npm/npm/commit/a65ed7cbd3c950383a14461a4b2c87b67ef773b9) - `npm-registry-client@7.2.1`: - * [npm/npm-registry-client#142](https://github.com/npm/npm-registry-client/pull/142) Fix `EventEmitter` warning spam from error handlers on socket. ([@addaleax](https://github.com/addaleax)) - * [npm/npm-registry-client#131](https://github.com/npm/npm-registry-client/pull/131) Adds support for streaming request bodies. ([@aredridel](https://github.com/aredridel)) - * Fixes [#13656](https://github.com/npm/npm/issues/13656). - * Dependency updates. - * Documentation improvements. - ([@othiym23](https://github.com/othiym23)) -* [`2b88d62`](https://github.com/npm/npm/commit/2b88d62e6a730716b27052c0911c094d01830a60) - [npm/npmlog#34](https://github.com/npm/npmlog/pull/34) - `npmlog@4.0.0`: - Allows creating log levels that are empty strings or 0 - ([@rwaldron](https://github.com/rwaldron)) -* [`242babb`](https://github.com/npm/npm/commit/242babbd02274ee2d212ae143992c20f47ef0066) - `once@1.4.0` - ([@zkochan](https://github.com/zkochan)) -* [`6d8ba2b`](https://github.com/npm/npm/commit/6d8ba2b4918e2295211130af68ee8a67099139e0) - `readable-stream@2.1.5` - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`855c099`](https://github.com/npm/npm/commit/855c099482a8d93b7f0646bd7bcf8a31f81868e0) - `retry@0.10.0` - ([@tim-kos](https://github.com/tim-kos)) -* [`80540c5`](https://github.com/npm/npm/commit/80540c52b252615ae8a6271b3df870eabfea935e) - `semver@5.3.0`: - * Add `minSatisfying` - * Add `prerelease(v)` - ([@isaacs](https://github.com/isaacs)) -* [`8aaac52`](https://github.com/npm/npm/commit/8aaac52ffae8e689fae265712913b1e2a36b1aa6) - `which@1.2.1` - ([@isaacs](https://github.com/isaacs)) -* [`85108a2`](https://github.com/npm/npm/commit/85108a29108ab0a57997572dc14f87eb706890ba) - `write-file-atomic@1.2.0`: - Preserve chmod and chown from the overwritten file - ([@iarna](https://github.com/iarna)) -* [`291a377`](https://github.com/npm/npm/commit/291a377f32f5073102a8ede61a27e6a9b37154c2) - Update npm documentation to reflect documentation for `semver@5.3.0`. - ([@zkat](https://github.com/zkat)) - -### v3.10.7 (2016-08-11) - -Hi all, today's our first release coming out of the new monthly release -cadence. See below for details. We're all recovered from conferences now -and raring to go! We've got some pretty keen bug fixes and a bunch of -documentation and dependency updates. It's hard to narrow it down to just a -few, but of note are scoped packages in bundled dependencies, the -`preinstall` lifecycle fix, the shrinkwrap and Git dependencies fix and the -fix to a crasher involving cycles in development dependencies. - -#### NEW RELEASE CADENCE - -Releasing npm has been, for the most part, a very prominent part of our -weekly process process. As part of our efforts to find the most effective -ways to allocate our team's resources, we decided last month that we would -try and slow our releases down to a monthly cadence, and see if we found -ourselves with as much extra time and attention as we expected to have. -Process experiments are useful for finding more effective ways to do our -work, and we're at least going to keep doing this for a whole quarter, and -then measure how well it worked out. It's entirely likely that we'll switch -back to a more frequent cadence, specially if we find that the value that -weekly cadence was providing the community is not worth sacrificing for a -bit of extra time. Does this affect you significantly? Let us know! - -#### SCOPED PACKAGES IN BUNDLED DEPENDENCIES - -Prior to this release and -[v2.15.10](https://github.com/npm/npm/releases/v2.15.10), npm had ignored -scoped modules found in `bundleDependencies`. - -* [`29cf56d`](https://github.com/npm/npm/commit/29cf56dbae8e3dd16c24876f998051623842116a) - [#8614](https://github.com/npm/npm/issues/8614) - Include scoped packages in bundled dependencies. - ([@forivall](https://github.com/forivall)) - -#### `preinstall` LIFECYCLE IN CURRENT PROJECT - -* [`b7f13bc`](https://github.com/npm/npm/commit/b7f13bc80b89b025be0c53d81b90ec8f2cebfab7) - [#13259](https://github.com/npm/npm/pull/13259) - Run top level preinstall before installing dependencies - ([@palmerj3](https://github.com/palmerj3)) - -#### BETTER SHRINKWRAP WITH GIT DEPENDENCIES - -* [`0f7e319`](https://github.com/npm/npm/commit/0f7e3197bcec7a328b603efdffd3681bbc40f585) - [#12718](https://github.com/npm/npm/issues/12718.) - Update outdated git dependencies found in shrinkwraps. Previously, if the - module version was the same then no update would be completed even if the - committish had changed. - ([@kossnocorp](https://github.com/kossnocorp)) - - -#### CYCLES IN DEVELOPMENT DEPENDENCIES NO LONGER CRASH - -* [`1691de6`](https://github.com/npm/npm/commit/1691de668d34cd92ab3de08bf3a06085388f2f07) - [#13327](https://github.com/npm/npm/issues/13327) - Fix bug where cycles found in development dependencies could result in - infinite recursion that resulted in crashes. - ([@iarna](https://github.com/iarna)) - -#### IMPROVE "NOT UPDATING LINKED MODULE" WARNINGS - -* [`1619871`](https://github.com/npm/npm/commit/1619871ac0cc8839dc9962c78e736095976c1eb4) - [#12893](https://github.com/npm/npm/pull/12893) - Only warn about symlink update if version number differs - The update-linked action outputs a warning that it needs to update the - linked package, but can't, There is no need for the package to be updated if - it is already at the correct version. This change does a check before - logging the warning. - ([@DaveEmmerson](https://github.com/DaveEmmerson)) - -#### MORE BUG FIXES - -* [`8f8d1b3`](https://github.com/npm/npm/commit/8f8d1b33a78c79aff9de73df362abaa7f05751d2) - [#11398](https://github.com/npm/npm/issues/11398) - Fix bug where `package.json` files that contained a `type` property could - cause crashes. `type` is not a `package.json` property that npm makes use - of and having it should be (and now is) harmless. - ([@zkat](https://github.com/zkat)) -* [`e7fa6c6`](https://github.com/npm/npm/commit/e7fa6c6a2c1de2a214479daa8c6901eebb350381) - [#13353](https://github.com/npm/npm/issues/13353) - Add GIT_EXEC_PATH to Git environment whitelist. - ([@mhart](https://github.com/mhart)) -* [`c23af21`](https://github.com/npm/npm/commit/c23af21d4cedd7fedcb4168672044db76ad054a8) - [#13626](https://github.com/npm/npm/pull/13626) - Use HTTPS issues URL in the error message for type validation errors. - ([@watilde](https://github.com/watilde)) - -#### INCLUDE `npm login` IN COMMAND SUMMARY - -* [`ab0c4b1`](https://github.com/npm/npm/commit/ab0c4b137b05762e75e0913038b606f087b58aa0) - [#13581](https://github.com/npm/npm/issues/13581) - The `login` command has long been an alias for `adduser`. - At the same time, there is an expectation not just of that - particular word being something to look for, but of there being - clear symmetry with `logout`. - So it was a bit confusing when `login` didn't show up in - `npm help` on a technicality. This seems like an acceptable - exception to the rule that says "no aliases in `npm help`". - ([@zkat](https://github.com/zkat)) - -#### DOCUMENTATION - -* [`e2d7e78`](https://github.com/npm/npm/commit/e2d7e7820a7875ed96e0382dc1e91b8df4e83746) - [#13319](https://github.com/npm/npm/pull/13319) - As Node.js 0.8 is no longer supported, remove mention of it from the README. - ([@watilde](https://github.com/watilde)) -* [`c565d89`](https://github.com/npm/npm/commit/c565d893a38efb6006e841450503329c9e58f100) - [#13349](https://github.com/npm/npm/pull/13349) - Updated the scripts documentation to explain the different between `version` and `preversion`. - ([@christophehurpeau](https://github.com/christophehurpeau)) -* [`fa8f87f`](https://github.com/npm/npm/commit/fa8f87f1ec92e543dd975156c4b184eb3e0b80cb) - [#10167](https://github.com/npm/npm/pull/10167) - Clarify in scope documentation that npm@2 is required for scoped packages. - ([@danpaz](https://github.com/danpaz)) - -#### DEPENDENCIES - -* [`124427e`](https://github.com/npm/npm/commit/124427eabbfd200aa145114e389e19692559ff1e) - [#8614](https://github.com/npm/npm/issues/8614) - `fstream-npm@1.1.1`: - Fixes bug with inclusion of scoped bundled dependencies. - ([@forivall](https://github.com/forivall)) -* [`7e0cdff`](https://github.com/npm/npm/commit/7e0cdff04714709f6dc056b19422d3f937502f1c) - [#13497](https://github.com/npm/npm/pull/13497) - `graceful-fs@4.1.5`: - `graceful-fs` had a [bug fix](https://github.com/isaacs/node-graceful-fs/pull/71) which - fixes a problem ([nodejs/node#7846](https://github.com/nodejs/node/pull/7846)) exposed - by recent changes to Node.js. - ([@thefourtheye](https://github.com/thefourtheye)) -* [`9b88cb8`](https://github.com/npm/npm/commit/9b88cb89f138443f324094685f4de073f33ecef0) - [#9984](https://github.com/npm/npm/issues/9984) - `request@2.74.0`: - Update request library to at least 2.73 to fix a bug where `npm install` would crash with - _Cannot read property 'emit' of null._ - - Update `request` dependency `tough-cookie` to `2.3.0` to - to address [https://nodesecurity.io/advisories/130](https://nodesecurity.io/advisories/130). - Versions 0.9.7 through 2.2.2 contain a vulnerable regular expression that, - under certain conditions involving long strings of semicolons in the - "Set-Cookie" header, causes the event loop to block for excessive amounts of - time. - ([@zarenner](https://github.com/zarenner)) - ([@stash-sfdc](https://github.com/stash-sfdc)) -* [`bf78ce5`](https://github.com/npm/npm/commit/bf78ce5ef5d2d6e95177193cca5362dd27bff968) - [#13387](https://github.com/npm/npm/issues/13387) - `minimatch@3.0.3`: - Handle extremely long and terrible patterns more gracefully. - There were some magic numbers that assumed that every extglob pattern starts - and ends with a specific number of characters in the regular expression. - Since !(||) patterns are a little bit more complicated, this led to creating - an invalid regular expression and throwing. - ([@isaacs](https://github.com/isaacs)) -* [`803e538`](https://github.com/npm/npm/commit/803e538efaae4b56a764029742adcf6761e8398b) - [isaacs/rimraf#111](https://github.com/isaacs/rimraf/issues/111) - `rimraf@2.5.4`: Clarify assertions: cb is required, options are not. - ([@isaacs](https://github.com/isaacs)) -* [`a9f84ef`](https://github.com/npm/npm/commit/a9f84ef61b4c719b646bf9cda00577ef16e3a113) - `lodash.without@4.2.0` - ([@jdalton](https://github.com/jdalton)) -* [`f59ff1c`](https://github.com/npm/npm/commit/f59ff1c2701f1bfd21bfdb97b4571823b614f694) - `lodash.uniq@4.4.0` - ([@jdalton](https://github.com/jdalton)) -* [`8cc027e`](https://github.com/npm/npm/commit/8cc027e5e81623260a49b31fe406ce483258b203) - `lodash.union@4.5.0` - ([@jdalton](https://github.com/jdalton)) -* [`0a6c1e4`](https://github.com/npm/npm/commit/0a6c1e4302a153fb055f495043ed33afd8324193) - `lodash.without@4.3.0` - ([@jdalton](https://github.com/jdalton)) -* [`4ab0181`](https://github.com/npm/npm/commit/4ab0181fca2eda18888b865ef691b83d30fb0c33) - `lodash.clonedeep@4.4.1` - ([@jdalton](https://github.com/jdalton)) - -### v3.10.6 (2016-07-07) - -This week we have a bunch of bug fixes for ya! A shrinkwrap regression -introduced in 3.10.0, better lifecycle `PATH` behavior, improvements when -working with registries other than `registry.npmjs.org` and a fix for -hopefully the last _don't print a progress bar over my interactive thingy_ -bug. - -#### SHRINKWRAP AND DEV DEPENDENCIES - -The rewrite in 3.10.0 triggered a bug where dependencies of devDependencies -would be included in your shrinkwrap even if you didn't request -devDependencies. - -* [`2484529`](https://github.com/npm/npm/commit/2484529ab56a42e5d6f13c48006f39a596d9e327) - [#13308](https://github.com/npm/npm/pull/13308) - Fix bug where deps of devDependencies would be incorrectly included in - shrinkwraps. - ([@iarna](https://github.com/iarna)) - -#### BETTER PATH LIFECYCLE BEHAVIOR - -We've been around the details on this one a few times in recent months and -hopefully this will bring is to where we want to be. - -* [`81051a9`](https://github.com/npm/npm/commit/81051a90eee66a843f76eb8cccedbb1d0a5c1f47) - [#12968](https://github.com/npm/npm/pull/12968) - When running lifecycle scripts, only prepend directory containing the node - binary to PATH if not already in PATH. - ([@segrey](https://github.com/segrey)) - -#### BETTER INTERACTIONS WITH THIRD PARTY REGISTRIES - -* [`071193c`](https://github.com/npm/npm/commit/071193c8e193767dd1656cb27556cb3751d77a3b) - [#10869](https://github.com/npm/npm/pull/10869) - If the registry returns a list of versions some of which are invalid, skip - those when picking a version to install. This can't happen with - registry.npmjs.org as it will normalize versions published with it, but it - can happen with other registries. - ([@gregersrygg](https://github.com/gregersrygg)) - -#### ONE LAST TOO-MUCH-PROGRESS CORNER - -* [`1244cc1`](https://github.com/npm/npm/commit/1244cc16dc5a0536acf26816a1deeb8e221d67eb) - [#13305](https://github.com/npm/npm/pull/13305) - Disable progress bar in `npm edit` and `npm config edit`. - ([@watilde](https://github.com/watilde)) - -#### HTML DOCS IMPROVEMENTS - -* [`58da923`](https://github.com/npm/npm/commit/58da9234ae72a5474b997f890a1155ee9785e6f1) - [#13225](https://github.com/npm/npm/issues/13225) - Fix HTML character set declaration in generated HTML documentation. - ([@KenanY](https://github.com/KenanY)) -* [`d1f0bf4`](https://github.com/npm/npm/commit/d1f0bf4303566f8690502034f82bbb449850958d) - [#13250](https://github.com/npm/npm/pull/13250) - Optimize png images using zopflipng. - ([@PeterDaveHello](https://github.com/PeterDaveHello)) - -#### DEPENDENCY UPDATES (THAT MATTER) - -* [`c7567e5`](https://github.com/npm/npm/commit/c7567e58618b63f97884afa104d2f560c9272dd5) - [npm/npm-user-validate#9](https://github.com/npm/npm-user-validate/pull/9) - `npm-user-validate@0.1.5`: - Lower the username length limits to 214 from 576 to match `registry.npmjs.org`'s limits. - ([@aredridel](https://github.com/aredridel)) -* [`22802c9`](https://github.com/npm/npm/commit/22802c9db3cf990c905e8f61304db9b5571d7964) - [#isaacs/rimraf](https://github.com/npm/npm/issues/isaacs/rimraf) - `rimraf@2.5.3`: - Fixes EPERM errors when running `lstat` on read-only directories. - ([@isaacs](https://github.com/isaacs)) -* [`ce6406f`](https://github.com/npm/npm/commit/ce6406f4b6c4dffbb5cd8a3c049f6663a5665522) - `glob@7.0.5`: - Forces the use of `minimatch` to 3.0.2, which improved handling of long and - complicated patterns. - ([@isaacs](https://github.com/isaacs)) - - -### v3.10.5 (2016-07-05) - -This is a fix to this week's testing release to correct the update of -`node-gyp` which somehow got mangled. - -* [`ca97ce2`](https://github.com/npm/npm/commit/ca97ce2e8d8ba44c445b39ffa40daf397d5601b3) - [#13256](https://github.com/npm/npm/issues/13256) - Fresh reinstall of `node-gyp@3.4.0`. - ([@zkat](https://github.com/zkat)) - -### v3.10.4 (2016-06-30) - -Hey y'all! This release includes a bunch of fixes we've been working on as we -continue on our `big-bug` push. There's still [a lot of it left to -do](https://github.com/npm/npm/labels/big-bug), but once this is done, things -should just generally be more stable, installs should be more reliable and -correct, and we'll be able to move on to more future work. We'll keep doing our -best! 🙌 - -#### RACES AS WACKY AS [REDLINE](https://en.wikipedia.org/wiki/Redline_\(2009_film\)) - -Races are notoriously hard to squash, and tend to be some of the more common -recurring bugs we see on the CLI. [@julianduque](https://github.com/julianduque) -did some pretty awesome [sleuthing -work](https://github.com/npm/npm/issues/12669) to track down a cache race and -helpfully submitted a patch. There were some related races in the same area that -also got fixed at around the same time, mostly affecting Windows users. - -* [`2a37c97`](https://github.com/npm/npm/commit/2a37c97121483db2b6f817fe85c2a5a77b76080e) - [#12669](https://github.com/npm/npm/issues/12669) - [#13023](https://github.com/npm/npm/pull/13023) - The CLI is pretty aggressive about correcting permissions across the cache - whenever it writes to it. This aggressiveness caused a couple of races where - temporary cache files would get picked up by `fs.readdir`, and removed before - `chownr` was called on them, causing `ENOENT` errors. While the solution might - seem a bit hamfisted, it's actually perfectly safe and appropriate in this - case to just ignore those resulting `ENOENT` errors. - ([@julianduque](https://github.com/julianduque)) -* [`ea018b9`](https://github.com/npm/npm/commit/ea018b9e3856d1798d199ae3ebce4ed07eea511b) - [#13023](https://github.com/npm/npm/pull/13023) - If a user were to have SUDO_UID and SUDO_GID, they'd be able to get into a - pretty weird state. This fixes that corner case. - ([@zkat](https://github.com/zkat)) -* [`703ca3a`](https://github.com/npm/npm/commit/703ca3abbf4f1cb4dff08be32acd2142d5493482) - [#13023](https://github.com/npm/npm/pull/13023) - A missing `return` was causing `chownr` to be called on Windows, even though - that's literally pointless, and causing crashes in the process, instead of - short-circuiting. This was entirely dependent on which callback happened to be - called first, and in some cases, the failing one would win the race. This - should prevent this from happening in the future. - ([@zkat](https://github.com/zkat)) -* [`69267f4`](https://github.com/npm/npm/commit/69267f4fbd1467ce576f173909ced361f8fe2a9d) - [#13023](https://github.com/npm/npm/pull/13023) - Added tests to verify `correct-mkdir` race patch. - ([@zkat](https://github.com/zkat)) -* [`e5f50ea`](https://github.com/npm/npm/commit/e5f50ea9f84fe8cac6978d18f7efdf43834928e7) - [#13023](https://github.com/npm/npm/pull/13023) - Added tests to verify `addLocal` race patch. - ([@zkat](https://github.com/zkat)) - -#### SHRINKWRAP IS COMPLICATED BUT IT'S BETTER NOW - -[@iarna](https://github.com/iarna) did some heroic hacking to refactor a bunch -of `shrinkwrap`-related bits and fixed some resolution and pathing issues that -were biting users. The code around that stuff got more readable/maintainable in -the process, too! - -* [`346bba1`](https://github.com/npm/npm/commit/346bba1e1fee9cc814b07c56f598a73be5c21686) - [#13214](https://github.com/npm/npm/pull/13214) - Resolve local dependencies in `npm-shrinkwrap.json` relative to the top of the - tree. - ([@iarna](https://github.com/iarna)) -* [`4a67fdb`](https://github.com/npm/npm/commit/4a67fdbd0f160deb6644a9c4c5b587357db04d2d) - [#13213](https://github.com/npm/npm/pull/13213) - If you run `npm install modulename` it should, if a `npm-shrinkwrap.json` is - present, use the version found there. If not, it'll use the version found in - your `package.json`, and failing *that*, use `latest`. - This fixes a case where the first check was being bypassed because version - resolution was being done prior to loading the shrinkwrap, and so checks to - match the shrinkwrap version couldn't succeed. - ([@iarna](https://github.com/iarna)) -* [`afa2133`](https://github.com/npm/npm/commit/afa2133a5d8ac4f6f44cdc6083d89ad7f946f5bb) - [#13214](https://github.com/npm/npm/pull/13214) - Refactor shrinkwrap specifier lookup into shared function. - ([@iarna](https://github.com/iarna)) -* [`2820b56`](https://github.com/npm/npm/commit/2820b56a43e1cc1e12079a4c886f6c14fe8c4f10) - [#13214](https://github.com/npm/npm/pull/13214) - Refactor operations in `inflate-shrinkwrap.js` into separate functions for - added clarity. - ([@iarna](https://github.com/iarna)) -* [`ee5bfb3`](https://github.com/npm/npm/commit/ee5bfb3e56ee7ae582bec9f741f32b224c279947) - Fix Windows path issue in a shrinkwrap test. - ([@zkat](https://github.com/zkat)) - -#### OTHER BUGFIXES - -* [`a11a7b2`](https://github.com/npm/npm/commit/a11a7b2e7df9478ac9101b06eead4a74c41a648d) - [#13212](https://github.com/npm/npm/pull/13212) - Resolve local paths passed in through the command line relative to current - directory, instead of relative to the `package.json`. - ([@iarna](https://github.com/iarna)) - -#### DEPENDENCY UPDATES - -* [`900a5b7`](https://github.com/npm/npm/commit/900a5b7f18b277786397faac05853c030263feb8) - [#13199](https://github.com/npm/npm/pull/13199) - [`node-gyp@3.4.0`](https://github.com/nodejs/node-gyp/blob/master/CHANGELOG.md): - AIX, Visual Studio 2015, and logging improvements. Oh my~! - ([@rvagg](https://github.com/rvagg)) - -#### DOCUMENTATION FIXES - -* [`c6942a7`](https://github.com/npm/npm/commit/c6942a7d6acb2b8c73206353bbec03380a056af4) - [#13134](https://github.com/npm/npm/pull/13134) - Fixed a few typos in `CHANGELOG.md`. - ([@watilde](https://github.com/watilde)) -* [`e63d913`](https://github.com/npm/npm/commit/e63d913127731ece56dcd69c7c0182af21be58f8) - [#13156](https://github.com/npm/npm/pull/13156) - Fix old reference to `doc/install` in a source comment. - ([@sheerun](https://github.com/sheerun)) -* [`099d23c`](https://github.com/npm/npm/commit/099d23cc8f38b524dc19a25857b2ebeca13c49d6) - [#13113](https://github.com/npm/npm/issues/13113) - [#13189](https://github.com/npm/npm/pull/13189) - Fixes a link to `npm-tag(3)` that was breaking to instead point to - `npm-dist-tag(1)`, as reported by [@SimenB](https://github.com/SimenB) - ([@macdonst](https://github.com/macdonst)) - -### v3.10.3 (2016-06-23) - -Given that we had not one, but two updates to our RC this past week, it -should come as no surprise that this week's full release is a bit -lighter. We have some documentation patches and a couple of bug fixes via -dependency updates. - -If you haven't yet checked out last week's release, -[v3.10.0](https://github.com/npm/npm/releases/tag/v3.10.0) -and the two follow up releases -[v3.10.1](https://github.com/npm/npm/releases/tag/v3.10.1) -and -[v3.10.2](https://github.com/npm/npm/releases/tag/v3.10.2), -you really should do so. They're the most important releases we've had in -quite a while, fixing a bunch of critical bugs (including an issue -impacting publishing with Node.js 6.x) and of course, bringing in the new -and improved progress bar. - -#### BUM SYMLINKS BURN NO MORE - -There's been a bug lurking where broken symlinks in your `node_modules` -folder could cause all manner of mischief, from crashes to empty `npm ls` -results. The intrepid [@watilde](https://github.com/watilde) tracked this -down for us. - -This addresses the root cause of the outdated crasher we protected -against earlier this week in -[#13115](https://github.com/npm/npm/issues/13115). - -This also fixes [#9564](https://github.com/npm/npm/issues/9564), the -problem where a bad symlink in your global modules would result in an -empty result when you ran `npm ls -g`. - -This ALSO likely fixes numerous "Missing argument #1" errors. (But surely -not all of them as that's actually just a generic arity and -type-validation failure.) - -* [`ca92ac4`](https://github.com/npm/npm/commit/ca92ac455b841a708dd89262ff88d503b125d717) - [npm/read-package-tree#6](https://github.com/npm/read-package-tree/pull/6) - `read-package-tree@5.1.5`: - Make bad symlinks be non-fatal errors when reading the tree off disk. - ([@watilde](https://github.com/watilde)) - -#### BETTER UNICODE DETECTION - -* [`6c3f7f0`](https://github.com/npm/npm/commit/6c3f7f043f09fc2aa19ffd3f956787635fa6f4d0) - `has-unicode@2.0.1`: - Fix unicode detection on a number of Linux distributions. - ([@Darkhogg](https://github.com/Darkhogg)) ([@gagern](https://github.com/gagern)) - - -#### DOCUMENTATION FIXES - -* [`b9243ee`](https://github.com/npm/npm/commit/b9243ee60a3d60505c2502dc8633811b42c8aaea) - [#13127](https://github.com/npm/npm/pull/13127) - Remove extra backtick from `npm ls` documentation. - ([@shvaikalesh](https://github.com/shvaikalesh)) -* [`e05c0c2`](https://github.com/npm/npm/commit/e05c0c243cc702f9c392c001f668a90b57eaeb0e) - [iarna/has-unicode#3](https://github.com/iarna/has-unicode/pull/3) - [iarna/has-unicode#4](https://github.com/iarna/has-unicode/pull/4) - [#13084](https://github.com/npm/npm/pull/13084) - Correct changelog entry for shrinkwrap lifecycle order. - ([@SimenB](https://github.com/SimenB)) -* [`823994f`](https://github.com/npm/npm/commit/823994f100a0e59e1dd109e312811f971968ec75) - [#13080](https://github.com/npm/npm/pull/13080) - Describe using `npm pack` to see a dry run of publication results in - the `npm publish` documentation. - ([@laughinghan](https://github.com/laughinghan)) - -#### DEPENDENCY UPDATES - -* [`e44d2db`](https://github.com/npm/npm/commit/e44d2db1ad0d860ca08e99c81135bd399fb733b1) - `aproba@1.0.4`: Documentation updates and minor refactoring. - ([@iarna](https://github.com/iarna)) - -### v3.10.2 (2016-06-17): - -This is a quick hotfix release with two small bug fixes. First, there was -an issue where the new progress bar would overwrite interactive prompts, -that is, those found in `npm login` and `npm init`. Second, if the -directory you were running `npm outdated` on was a bad link or otherwise had -unrecoverable errors then npm would crash instead of printing the error. - -* [`fbefb86`](https://github.com/npm/npm/commit/fbefb8675b26320b295f481b4872ce99f0180807) - [`7779e9f`](https://github.com/npm/npm/commit/7779e9fb9430f6547532c67f2471864d62bbd5bc) - [#13105](https://github.com/npm/npm/issues/13105) - Disable progress bar in `adduser` and `init`. -* [`6a33b2c`](https://github.com/npm/npm/commit/6a33b2c13f637a41e25cd0339925bc430b50358a) - [#13115](https://github.com/npm/npm/issues/13115) - Ensure that errors reading the package tree for `outdated` does not result - in crashes. - ([@iarna](https://github.com/iarna)) - -### v3.10.1 (2016-06-17): - -There are two very important bug fixes and one long-awaited (and significant!) -deprecation in this hotfix release. [Hold on.](http://butt.holdings/) - -#### *WHOA* - -When Node.js 6.0.0 was released, the CLI team noticed an alarming upsurge in -bugs related to important files (like `README.md`) not being included in -published packages. The new bugs looked much like -[#5082](https://github.com/npm/npm/issues/5082), which had been around in one -form or another since April, 2014. #5082 used to be a very rare (and obnoxious) -bug that the CLI team hadn't had much luck reproducing, and we'd basically -marked it down as a race condition that arose on machines using slow and / or -rotating-media-based hard drives. - -Under 6.0.0, the behavior was reliable enough to be nearly deterministic, and -made it very difficult for publishers using `.npmignore` files in combination -with `"files"` stanzas in `package.json` to get their packages onto the -registry without one or more files missing from the packed tarball. The entire -saga is contained within [the issue](https://github.com/npm/npm/issues/5082), -but the summary is that an improvement to the performance of -[`fs.realpath()`](https://nodejs.org/api/fs.html#fs_fs_realpath_path_options_callback) -made it much more likely that the packing code would lose the race. - -Fixing this has proven to be very difficult, in part because the code used by -npm to produce package tarballs is more complicated than, strictly speaking, it -needs to be. [**@evanlucas**](https://github.com/evanlucas) contributed [a -patch](https://github.com/npm/fstream/pull/50) that passed the tests in a -[special test suite](https://github.com/othiym23/eliminate-5082) that I -([**@othiym23**](https://github.com/othiym23)) created (with help from -[**@addaleax**](https://github.com/addaleax)), but only _after_ we'd released -the fixed version of that package did we learn that it actually made the -problem _worse_ in other situations in npm proper. Eventually, -[**@rvagg**](https://github.com/rvagg) put together a more durable fix that -appears to completely address the errant behavior under Node.js 6.0.0. That's -the patch included in this release. Everybody should chip in for redback -insurance for Rod and his family; he's done the community a huge favor. - -Does this mean the long (2+ year) saga of #5082 is now over? At this point, I'm -going to quote from my latest summary on the issue: - -> The CLI team (mostly me, with input from the rest of the team) has decided that -> the overall complexity of the interaction between `fstream`, `fstream-ignore`, -> `fstream-npm`, and `node-tar` has grown more convoluted than the team is -> comfortable (maybe even capable of) supporting. -> -> - While I believe that @rvagg's (very targeted) fix addresses _this_ issue, I -> would be shocked if there aren't other race conditions in npm's packing -> logic. I've already identified a couple other places in the code that are -> most likely race conditions, even if they're harder to trigger than the -> current one. -> - The way that dependency bundling is integrated leads to a situation in -> which a bunch of logic is duplicated between `fstream-npm` and -> `lib/utils/tar.js` in npm itself, and the way `fstream`'s extension -> mechanism works makes this difficult to clean up. This caused a nasty -> regression ([#13088](https://github.com/npm/fstream/pull/50), see below) as -> of ~`npm@3.8.7` where the dependencies of `bundledDependencies` were no -> longer being included in the built package tarballs. -> - The interaction between `.npmignore`, `.gitignore`, and `files` is hopelessly -> complicated, scattered in many places throughout the code. We've been -> discussing [making the ignores and includes logic clearer and more -> predictable](https://github.com/npm/npm/wiki/Files-and-Ignores), and the -> current code fights our efforts to clean that up. -> -> So, our intention is still to replace `fstream`, `fstream-ignore`, and -> `fstream-npm` with something much simpler and purpose-built. There's no real -> reason to have a stream abstraction here when a simple recursive-descent -> filesystem visitor and a synchronous function that can answer whether a given -> path should be included in the packed tarball would do the job adequately. -> -> What's not yet clear is whether we'll need to replace `node-tar` in the -> process. `node-tar` is a very robust implementation of tar (it handles, like, -> everything), and it also includes some very important tweaks to prevent several -> classes of security exploits involving maliciously crafted packages. However, -> its packing API involves passing in an `fstream` instance, so we'd either need -> to produce something that follows enough of `fstream`'s contract for `node-tar` -> to keep working, or swap `node-tar` out for something like `tar-stream` (and -> then ensuring that our use of `tar-stream` is secure, which could involve -> security patches for either npm or `tar-stream`). - -The testing and review of `fstream@1.0.10` that the team has done leads us to -believe that this bug is fixed, but I'm feeling more than a little paranoid -about fstream now, so it's important that people keep a close eye on their -publishes for a while and let us know immediately if they notice any -irregularities. - -* [`8802f6c`](https://github.com/npm/npm/commit/8802f6c152ea35cb9e5269c077c3a2f9df411afc) - [#5082](https://github.com/npm/npm/issues/5082) `fstream@1.0.10`: Ensure that - entries are collected after a paused stream resumes. - ([@rvagg](https://github.com/rvagg)) -* [`c189723`](https://github.com/npm/npm/commit/c189723110497a17dac3b0596f2916deeed93ee7) - [#5082](https://github.com/npm/npm/issues/5082) Remove the warning introduced - in `npm@3.10.0`, because it should no longer be necessary. - ([@othiym23](https://github.com/othiym23)) - -#### *ERK* - -Because the interaction between `fstream`, `fstream-ignore`, `fsream-npm`, and -`node-tar` is so complex, it's proven difficult to add support for npm features -like `bundledDependencies` without duplicating some logic within npm's code -base. While [fixing a completely unrelated -bug](https://github.com/npm/npm/issues/9642), we "cleaned up" some of this -seemingly duplicated code, and in the process removed the code that ensured -that the dependencies of `bundledDependencies` are themselves bundled. We've -brought that code back into the code base (without reopening #9642), and added -a test to ensure that this regression can't recur. - -* [`1b6ceca`](https://github.com/npm/npm/commit/1b6ceca32fc81ca7cc7ac2eb7d11f687e6f87f26) - [#13088](https://github.com/npm/npm/issues/13088) Partially restore npm's own - version of the `fstream-npm` function `applyIgnores` to ensure that the - dependencies of `bundledDependencies` are included in published packages. - ([@iarna](https://github.com/iarna)) - -#### GOODBYE, FAITHFUL FRIEND - -At NodeConf Adventure 2016 (RIP in peace, Mikeal Rogers's NodeConf!), the CLI -team had an opportunity to talk to representatives from some of the larger -companies that we knew were still using Node.js 0.8 in production. After asking -them whether they were still using 0.8, we got back blank stares and questions -like, "0.8? You mean, from four years ago?" After establishing that being able -to run npm in their legacy environments was no longer necessary, the CLI team -made the decision to drop support for 0.8. (Faithful observers of our [team -meetings](https://github.com/npm/npm/issues?utf8=%E2%9C%93&q=is%3Aissue+npm+cli+team+meeting+) -will have known this was the plan for NodeConf since the beginning of 2016.) - -In practice, this means only what's in the commit below: we've removed 0.8 from -our continuous integration test matrix below, and will no longer be habitually -testing changes under Node 0.8. We may also give ourselves permission to use -`setImmediate()` in test code. However, since the project still supports -Node.js 0.10 and 0.12, it's unlikely that patches that rely on ES 2015 -functionality will land anytime soon. - -Looking forward, the team's current plan is to drop support for Node.js 0.10 -when its LTS maintenance window expires in October, 2016, and 0.12 when its -maintenance / LTS window ends at the end of 2016. We will also drop support for -Node.js 5.x when Node.js 6 becomes LTS and Node.js 7 is released, also in the -October-December 2016 timeframe. - -(Confused about Node.js's LTS policy? [Don't -be!](https://github.com/nodejs/LTS) If you look at [this -diagram](https://github.com/nodejs/LTS/blob/ce364a94b0e0619eba570cd57be396573e1ef889/schedule.png), -it should make all of the preceding clear.) - -If, in practice, this doesn't work with distribution packagers or other -community stakeholders responsible for packaging and distributing Node.js and -npm, please reach out to us. Aligning the npm CLI's LTS policy with Node's -helps everybody minimize the amount of work they need to do, and since all of -our teams are small and very busy, this is somewhere between a necessity and -non-negotiable. - -* [`d6afd5f`](https://github.com/npm/npm/commit/d6afd5ffb1b19e5d94aeee666afcb8adaced58db) - Remove 0.8 from the Node.js testing matrix, and reorder to match real-world - priority, with comments. ([@othiym23](https://github.com/othiym23)) - -### v3.10.0 (2016-06-16): - -Do we have a release for you! We have our first new lifecycle since -`version`, a new progress bar and a bunch of bug fixes. -[I'm](https://github.com/iarna) really excited about this release, let me -tell you!! - -#### DANGER: PUBLISHING ON NODE 6.0.0 - -Publishing and packing are buggy under Node versions greater than 6.0.0. -Please use Node.js LTS (4.4.x) to publish packages. See -[#5082](https://github.com/npm/npm/issues/5082) for details and current -status. - -* [`4e52cef`](https://github.com/npm/npm/commit/4e52cef3d4170c8abab98149666ec599f8363233) - [#13077](https://github.com/npm/npm/pull/13077) - Warn when using Node 6+. - ([@othiym23](https://github.com/othiym23)) - -#### NEW LIFECYCLE SCRIPT: `shrinkwrap` - -* [`e8c80f2`](https://github.com/npm/npm/commit/e8c80f20bfd5d1618e85dbab41660d6f3e5ce405) - [#10744](https://github.com/npm/npm/issues/10744) - You can now add `preshrinkwrap`, `shrinkwrap` and `postshrinkwrap` to your `package.json` - scripts section. They are run when you run `npm shrinkwrap` or `npm install --save` with - an `npm-shrinkwrap.json` present in your module directory. - - `preshrinkwrap` and `shrinkwrap` is run prior to generating the new `npm-shrinkwrap.json` - and `postshrinkwrap` is run after. - ([@SimenB](https://github.com/SimenB)) - -#### NEW PROGRESS BAR - -![Install with new progress bar](http://shared.by.re-becca.org/misc-images/new-gauge-color.gif) - -We have a new progress bar and a bunch of related improvements! - -##### BLOCKING BLOCKING - -**!!WARNING!!** As a part of this change we now explicitly set -`process.stdout` and `process.stderr` to be _blocking_ if they are ttys, -using [set-blocking](https://www.npmjs.com/package/set-blocking). This is -necessary to ensure that we can fully erase the progress bar before we start -writing other things out to the console. - -Prior to Node.js 6.0.0, they were already blocking on Windows, and MacOS. -Meanwhile, on Linux they were always non-blocking but had large (64kb) -buffers, which largely made this a non-issue there. Starting with Node.js -6.0.0 they became non-blocking on MacOS and that caused some unexpected -issues (see [nodejs/node#6456](https://github.com/nodejs/node/issues/6456)). - -If you are a Linux user, it's plausible that this might have a performance -impact if your terminal can't keep up with output rate. If you experience -this, we want to know! Please [file an -issue](https://github.com/npm/npm/issues/new) at our issue tracker. - -##### BETTER LAYOUT - -Let's start by talking about what goes into the new progress bar: - -``` -⸨░░░░░░░░░░⠂⠂⠂⠂⠂⠂⠂⠂⸩ ⠹ loadExtraneous: verb afterAdd /Users/rebecca/.npm/null/0.0.0/package/package.json written - ↑‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ ↑ ‾‾‾‾‾‾‾‾‾↑‾‾‾‾ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾↑‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ - percent complete spinner current thing we're doing most recent log line -``` - -The _spinner_ is intended as an activity indicator–it moves whenever -npm sends something to its logs. It also spins at a constant speed while -waiting on the network. - -The _current thing we're doing_ relates to how we track how much work has -been done. It's the name of the unit of work we most recently started or -completed some of. Sometimes these names are more obvious than others and -that's something we'll look at improving over time. - -And finally, the _most recent log line_ is exactly that, it's the most -recent line that you would have seen if you were running with -`--loglevel=silly` or were watching the `npm-debug.log`. These are written -to be useful to the npm developers above all else, so they may sometimes be -a little cryptic. - -* [`6789978`](https://github.com/npm/npm/commit/6789978ab0713f67928177a9109fed43953ccbda) - [#13075](https://github.com/npm/npm/pull/13075) - `npmlog@3.1.2`: Update to the latest npmlog, which includes the new and - improved progress bar layout. - ([@iarna](https://github.com/iarna)) - -##### MORE PERFORMANT - -The underlying code for the progress bar was rewritten, in part with -performance in mind. Previously whenever you updated the progress bar it -would check an internal variable for how long it had been since the last -update and if it had been long enough, it would print out what you gave it. -With the new progress bar we do updates at a fixed interval (with -`setInterval`) and "updating" the progress bar just updates some variables -that will be used when the next tick of the progress bar happens. Currently -progress bar updates happen every 50ms, although that's open to tuning. - -##### WIDE(R) COMPATIBILITY - -I spent a lot of time working our Unicode support. There were a few issues -that plagued us: - -Previously one of the characters we used was _ambiguous width_ which means -that it was possible to configure your terminal to display it as _full -width_. If you did this, the output would be broken because we assumed it -was a _half width_ character. We no longer use any of these characters. - -Previously, we defaulted to using Unicode on Windows. This isn't a safe -assumption, however, as folks in non-US locales often use other code pages -for their terminals. Windows doesn't provide* any facility available to -Node.js for determining the current code page, so we no longer try to use -Unicode on Windows. - -_\* The facilities it does provide are a command line tool and a windows -system call. The former isn't satisfactory for speed reasons and the latter -can't be accessed from a JS-only Node.js program._ - -##### FOR THE FUTURE: THEMES - -The new version of the progress bar library supports plugable themes. Adding -support to npm shouldn't be too difficult. The built in themes are: - -* `ASCII` – The fallback theme which is always available. -* `colorASCII` – Inverts the color of the completed portion of the progress - bar. The default on Windows and usually on Linux. (Color support is - determined by looking at the `TERM` environment variable.) -* `brailleSpinner` – A braille based spinner and other unicode enhancements. MacOS only. -* `colorBrailleSpinner` – The default on MacOS, a combination of the above two. - -##### LESS GARBLED OUTPUT - -As a part of landing this I've also taken the opportunity to more -systematically disable the progress bar prior to printing to `stdout` or -running external commands (in particular: git). This should ensure that the -progress bar doesn't get left on screen after something else prints -something. We also are now much more zealous about erasing the progress bar -on exit, so if you `Ctrl-C` out of an install we'll still cleanup the -progress bar. - -* [`63f153c`](https://github.com/npm/npm/commit/63f153c743f9354376bfb9dad42bd028a320fd1f) - [#13075](https://github.com/npm/npm/pull/13075) - Consistently make sure that the progress bar is hidden before we try to - write to stdout. - ([@iarna](https://github.com/iarna)) -* [`8da79fa`](https://github.com/npm/npm/commit/8da79fa60de4972dca406887623d4e430d1609a1) - [#13075](https://github.com/npm/npm/pull/13075) - Be more methodical about disabling progress bars before running external - commands. - ([@iarna](https://github.com/iarna)) - -#### REPLACE `process.nextTick` WITH `asap` ASAP - -* [`5873b56`](https://github.com/npm/npm/commit/5873b56cb315437dfe97e747811c0b9c297bfd38) - [`254ad7e`](https://github.com/npm/npm/commit/254ad7e38f978b81046d242297fe8b122bfb5852) - [#12754](https://github.com/npm/npm/issues/12754) - Use `asap` in preference over `process.nextTick` to avoid recursion warnings. - Under the hood `asap` uses `setImmediate` when available and falls back to - `process.nextTick` when it's not. Versions of node that don't support - `setImmediate` have a version of `process.nextTick` that actually behaves - like the current `setImmediate`. - ([@lxe](https://github.com/lxe)) - -#### FIXES AND REFACTORING - -Sometimes the installer would get it into its head that it could move or -remove things that it really shouldn't have. While the reproducers for this were -often a bit complicated (the core reproducer involved five symlinks(!)), it turns -out this is an easy scenario to end up in if your project has a bunch of small -modules and you're linking them while developing them. - -Fixing this ended up involving doing an important and overdue rewrite of how -the installer keeps track of (and interrogates) the relationships between -modules. This likely fixes other related bugs, and in the coming weeks -we'll verify and close them as we find them. There are a whole slew of -commits related to this rewrite, and if you'd like to learn more check -out the PR where I describe what I did in detail: [#12775](https://github.com/npm/npm/pull/12775) - -* [`8f3e111`](https://github.com/npm/npm/commit/8f3e111fdd2ce7824864f77b04e5206bdaf961a1) - [`c0b0ed1`](https://github.com/npm/npm/commit/c0b0ed1e9945c01b2e68bf22af3fe4005aa4bcd4) - [#10800](https://github.com/npm/npm/issues/10800) - Remove install pruning stage–this was obsoleted by making the installer keep - itself up to date as it goes along. This is NOT related to `npm prune`. - ([@iarna](https://github.com/iarna)) - -#### MAKE OUTDATED MORE WIDELY LEGIBLE - -* [`21c60e9`](https://github.com/npm/npm/commit/21c60e9bb56d47da17b79681f2142b3dcf4c804b) - [#12843](https://github.com/npm/npm/pull/12843) - In `npm outdated, stop coloring the _Location_ and _Package Type_ columns. - Previously they were colored dark gray, which was hard to read for some - users. - ([@tribou](https://github.com/tribou)) - -#### DOCUMENTATION UPDATE - -* [`eb0a72e`](https://github.com/npm/npm/commit/eb0a72eb95862c1d0d41a259d138ab601d538793) - [#12983](https://github.com/npm/npm/pull/12983) - Describe how to run the lifecycle scripts of dependencies. How you do - this changed with `npm` v2. - ([@Tapppi](https://github.com/Tapppi)) - -### DEPENDENCY UPDATES - -* [`da743dc`](https://github.com/npm/npm/commit/da743dc2153fed8baca3dada611b188f53ab5931) - `which@1.2.10`: - Fix bug where unnecessary special case path handling for Windows could - produce unexpected results on Unix systems. - ([@isaacs](https://github.com/isaacs)) -* [`4533bd5`](https://github.com/npm/npm/commit/4533bd501d54aeedfec3884f4fd54e8c2edd6020) - `npm-user-validate@0.1.4`: - Validate the length of usernames. - ([@aredridel](https://github.com/aredridel)) -* [`4a18922`](https://github.com/npm/npm/commit/4a18922e56f9dc902fbb4daa8f5fafa4a1b89376) - `glob@7.0.4`: - Fixes issues with Node 6 and "long or excessively symlink-looping paths". - ([@isaacs](https://github.com/isaacs)) -* [`257fe11`](https://github.com/npm/npm/commit/257fe11052987e5cfec2abdf52392dd95a6c6ef3) - `npm-package-arg@4.2.0`: - Add `escapedName` to the result. It is suitable for passing through to a - registry without further processing. - ([@nexdrew](https://github.com/nexdrew)) -* [`dda3ca7`](https://github.com/npm/npm/commit/dda3ca70f74879106589ef29e167c8b91ef5aa4c) - `wrappy@1.0.2` - ([@zkat](https://github.com/zkat)) -* [`25f1db5`](https://github.com/npm/npm/commit/25f1db504d0fd8c97211835f0027027fe95e0ef3) - `readable-stream@2.1.4` - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`9d64fe6`](https://github.com/npm/npm/commit/9d64fe676ebc6949c687ffb85bd93eca3137fc0d) - `abbrev@1.0.9` - ([@isaacs](https://github.com/isaacs)) - -### v3.9.6 (2016-06-02): - -#### SMALL OUTPUT TWEAK - -* [`0bdc9d1`](https://github.com/npm/npm/commit/0bdc9d13b73df07e63a58470ea001fda490e5869) - [#12879](https://github.com/npm/npm/pull/12879) - The usage output for npm commands was somehow under the impression that - the singular form of `aliases` is `aliase`. This has been corrected to show - `alias` instead. - ([@intelliot](https://github.com/intelliot)) - -#### DOC UPDATES - -* [`f771b49`](https://github.com/npm/npm/commit/f771b49f5d65bbef540c231fbfcca71cacdce4db) - [#12933](https://github.com/npm/npm/pull/12933) - Add `config.gypi` to list of files that are always ignored in the - `package.json` manpage. - ([@Jokero](https://github.com/Jokero)) - -#### DEPENDENCY UPDATES - -* [`61c1d9c`](https://github.com/npm/npm/commit/61c1d9cd4b2296bd41d55a5c58e35ca5f028b9bc) - [#12926](https://github.com/npm/npm/pull/12926) - Removed unused dependency `lodash.isarray`. - ([@mmalecki](https://github.com/mmalecki)) -* [`168ed28`](https://github.com/npm/npm/commit/168ed2834b2c6db8bb39f81baadc0bf275807328) - [#12926](https://github.com/npm/npm/pull/12926) - Removed unused dependency `lodash.keys`. - ([@mmalecki](https://github.com/mmalecki)) - -### v3.9.5 (2016-05-27): - -Just a quick point release. We had an issue where I (Kat) included the -`.nyc_output/` directory in `npm@3.9.3` and `npm@3.9.4`. The issue got reported -right after that second release -([`#12873`](https://github.com/npm/npm/issues/12873)), and now there's this -small point release that's there to fix the issue sooner. - -* [`f96aea0`](https://github.com/npm/npm/commit/f96aea085be981cdb59bd09f16da40717426f981) - [#12878](https://github.com/npm/npm/pull/12878) - Ignore `.nyc_output` to avoid an accidental publish or commit filled with - code coverage data. - ([@TheAlphaNerd](https://github.com/TheAlphaNerd)) - -### v3.9.4 (2016-05-26): - -Hey all! It's that time again! - -This week continues our current `big-bug` squashing push, although there's none -that are ready to release quite yet -- we're working on it! - -It's also worth noting that we're entering the main part of conference season, -so you can probably expect a bit of a dev slowdown as a lot of us wombats attend -or speak at the various conferences. Remember [npm.camp](npm.camp) is happening -in 2 months and the lineup is looking pretty great! Tickets are still on sale. -Come hang out with us! WOO FUN! 🎉😸 - -#### BUGFIX - -* [`cac0038`](https://github.com/npm/npm/commit/cac0038868b18295f9f299e762e20034f32a3e11) - [#12845](https://github.com/npm/npm/pull/12845) - Progress bar during tarball packing now prints `pack:packagename` instead of - `pack:[object Object]`. - ([@iarna](https://github.com/iarna)) - -#### DOC UPDATES - -* [`0b81622`](https://github.com/npm/npm/commit/0b816225c743c9203db5d92fb4dd3a9293833298) - [#12840](https://github.com/npm/npm/pull/12840) - Remove sexualized language from comment in code. - ([@geek](https://github.com/geek)) -* [`d6dff24`](https://github.com/npm/npm/commit/d6dff2481cb587c392f22afb893ac3136371a64c) - [#12802](https://github.com/npm/npm/pull/12802) - Small grammar fix in `cli/npm.md`. - ([@andresilveira](https://github.com/andresilveira)) -* [`cb38e0f`](https://github.com/npm/npm/commit/cb38e0fff82a6c1c110026b95b07a8c32e27ec01) - [#12782](https://github.com/npm/npm/pull/12782) - Documents that `NOTICE` files started getting included after - [npm/fstream-npm#17](https://github.com/npm/fstream-npm/pull/17). - ([@SimenB](https://github.com/SimenB)) -* [`70a3ae4`](https://github.com/npm/npm/commit/70a3ae4d4ec76b3ec51f00bf5261f1147829f9fe) - [#12776](https://github.com/npm/npm/pull/12776) - `npm run-script` used to have a `<pkg>` argument that allowed you to target - specific packages' scripts. This was removed as one of the breaking changes - for `npm@2`. - This patch removes a mention of that argument, which really doesn't exist - anymore. - ([@fibo](https://github.com/fibo)) - -#### DEP UPDATES - -* [`4a4470d`](https://github.com/npm/npm/commit/4a4470ddd1d9b0b62cb94f3bff5ab6b8e6db527a) - `aproba@1.0.3` - ([@iarna](https://github.com/iarna)) - -#### TEST IMPROVEMENTS - -So it turns out, `t.comment` in `tap` is actually pretty nice! -There's also a couple other test improvements by Rebecca landing here. - -* [`9fd04dd`](https://github.com/npm/npm/commit/9fd04dd6be493465d7ac5f14dd9328e66069c1bf) - [#12851](https://github.com/npm/npm/pull/12851) - Rewrite `shrinkwrap-prod-dependency-also` test to use `common.npm` - ([@iarna](https://github.com/iarna)) -* [`3bc4a8e`](https://github.com/npm/npm/commit/3bc4a8ee58cb0e0adc84b4f135330f2b1e20d992) - [#12851](https://github.com/npm/npm/pull/12851) - Clean up `rm-linked` test. - ([@iarna](https://github.com/iarna)) -* [`bf7f7f2`](https://github.com/npm/npm/commit/bf7f7f273a794f7573bbbc84b1c216fdcd9e0ef9) - [#12851](https://github.com/npm/npm/pull/12851) - Clean up `outdated-symlink` test. - ([@iarna](https://github.com/iarna)) -* [`ca0baa4`](https://github.com/npm/npm/commit/ca0baa4dac85b1df4e26ef0c73d39314ca6858ca) - [#12851](https://github.com/npm/npm/pull/12851) - Improve diagnostics for `shrinkwrap-scoped-auth` test. - ([@iarna](https://github.com/iarna)) -* [`fbec9fd`](https://github.com/npm/npm/commit/fbec9fd5bb0abce589120d14c1f2b03b58cecce1) - [#12851](https://github.com/npm/npm/pull/12851) - Rewrite `shrinkwrap-dev-dependency` test to use `common.npm`. - ([@iarna](https://github.com/iarna)) - -### v3.9.3 (2016-05-19): - -This week continues our `big-bug` squashing adventure! Things are churning along -nicely, and we've gotten a lot of fantastic contributions from the community. -Please keep it up! - -A quick note on last week's release: We had a small `npm shrinkwrap`-related -crasher in `npm@3.9.1`, so once this release goes out, `v3.9.2` is going to be -`npm@latest`. Please update if you ended up in with that previous version! - -Remember we have a weekly team meeting, and you can [suggest agenda items in the -GitHub issue](https://github.com/npm/npm/issues/12761). Keep an eye out for the -`#npmweekly` tag on Twitter, too, and join the conversation! We'll do our best -to address questions y'all send us. ✌ - -#### FIXES - -* [`42d71be`](https://github.com/npm/npm/commit/42d71be2cec674dd9e860ad414f53184f667620d) - [#12685](https://github.com/npm/npm/pull/12685) - When using `npm ls <pkg>` without a semver specifier, `npm ls` would skip - any packages in your tree that matched by name, but had a prerelease version - in their `package.json`. This patch fixes it so `npm ls` does a simple name - match unless you use the `npm ls <pkg>@<version>` format. - ([@zkat](https://github.com/zkat)) -* [`c698ae6`](https://github.com/npm/npm/commit/c698ae666afc92fbc0fcba3c082cfa9b34a4420d) - [#12685](https://github.com/npm/npm/pull/12685) - Added some tests for more basic `npm ls` functionality. - ([@zkat](https://github.com/zkat)) - -### NOTABLE DEPENDENCY UPDATES - -* [`3a6fe23`](https://github.com/npm/npm/commit/3a6fe2373c45e80a1f28aaf176d552f6f97cf131) - [npm/fstream-npm#17](https://github.com/npm/fstream-npm/pull/17) - `fstream-npm@1.1.0`: - `fstream-npm` always includes NOTICE files now. - ([@kemitchell](https://github.com/kemitchell)) -* [`df04e05`](https://github.com/npm/npm/commit/df04e05af1f257a1903372e1baf334c0969fbdbd) - [#10013](https://github.com/npm/npm/issues/10013) - `read-package-tree@5.1.4`: - Fixes an issue where `npm install` would fail if your `node_modules` was - symlinked. - ([@iarna](https://github.com/iarna)) -* [`584676f`](https://github.com/npm/npm/commit/584676f85eaebcb9d6c4d70d2ad320be8a8d6a74) - [npm/init-package-json#62](https://github.com/npm/init-package-json/pull/62) - `init-package-json@1.9.4`: - Stop using `package` for a variable, which defeats some bundlers and linters. - ([@adius](https://github.com/adius)) -* [`935a7e3`](https://github.com/npm/npm/commit/935a7e359535e13924934811b77924cbad82619a) - `readable-stream@2.1.3`: - Node 6 build and buffer-related updates. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) - -#### OTHER DEPENDENCY UPDATES - -* [`4c4609e`](https://github.com/npm/npm/commit/4c4609ea49e77303f9d72af6757620e6b3a9a6a9) - `inflight@1.0.5` - ([@zkat](https://github.com/zkat)) -* [`7a3030d`](https://github.com/npm/npm/commit/7a3030d3d44ea2136425f72950ba22e6efd441d9) - `hosted-git-info@2.1.5` - ([@zkat](https://github.com/zkat)) -* [`5ed4b58`](https://github.com/npm/npm/commit/5ed4b58409eeb134bca1c96252682fd7600d9906) - `which@1.2.9` - ([@isaacs](https://github.com/isaacs)) - -### v3.9.2 (2016-05-17) - -This is a quick patch release. The previous release, 3.9.1, introduced a -bug where npm would crash given a combination of specific package tree on -disk and a shrinkwrap. - -* [`cde367f`](https://github.com/npm/npm/commit/cde367fbb6eebc5db68a44b12a5c7bea158d70db) - [#12724](https://github.com/npm/npm/issues/12724) - Fix crasher when inflating shrinkwraps with packages on disk that were - installed by older npm versions. - ([@iarna](https://github.com/iarna)) - -### v3.9.1 (2016-05-12) - -HI all! We have bug fixes to a couple of the hairy corners of `npm`, in the -form of shrinkwraps and bundled dependencies. Plus some documentation improvements -and our lodash deps bot a bump. - -This is our first week really focused on getting the -[big bugs](https://github.com/npm/npm/issues?q=is%3Aopen+is%3Aissue+label:big-bug) -list down. Our work from this week will be landing next week, and I can't -wait to tell you about that! (It's about symlinks!) - -#### SHRINKWRAP FIX - -* [`b894413`](https://github.com/npm/npm/commit/b8944139a935680c4a267468bb2d3c3082b5609f) - [#12372](https://github.com/npm/npm/issues/12372) - Changing a nested dependency in an `npm-shrinkwrap.json` and then running `npm install` - would not get up the updated package. This corrects that. - ([@misterbyrne](https://github.com/misterbyrne)) - -#### BUNDLED DEPENDENCIES FIX - -* [`d0c6d19`](https://github.com/npm/npm/commit/d0c6d194471be8ce3e7b41b744b24f63dd1a3f6f) - [#12476](https://github.com/npm/npm/pull/12476) - Protects against a crasher when a bundled dep is missing a package.json. - ([@dflupu](https://github.com/dflupu)) - -#### DOCS IMPROVEMENTS - -* [`6699aa5`](https://github.com/npm/npm/commit/6699aa53c0a729cfc921ac1d8107c320e5a5ac95) - [#12585](https://github.com/npm/npm/pull/12585) - Document that engineStrict is quite gone. Not "deprecated" so much as "extirpated". - ([@othiym23](https://github.com/othiym23)) -* [`7a41a84`](https://github.com/npm/npm/commit/7a41a84b655be3204d2e80848278a510e42c80e7) - [#12636](https://github.com/npm/npm/pull/12636) - Improve `npm-scripts` documentation regarding when `node-gyp` is used. - ([@reconbot](https://github.com/reconbot)) -* [`4c4b4ba`](https://github.com/npm/npm/commit/4c4b4badf09b9b50cdca85314429a0111bb35cb1) - [#12586](https://github.com/npm/npm/pull/12586) - Correct `package.json` documentation as to when `node-gyp rebuild` called. - This now matches https://docs.npmjs.com/misc/scripts#default-values - ([@reconbot](https://github.com/reconbot)) - -#### DEPENDENCY UPDATES - -* [`cfa797f`](https://github.com/npm/npm/commit/cfa797fedd34696d45b61e3ae0398407afece880) - `lodash._baseuniq@4.6.0` - ([@jdalton](https://github.com/jdalton)) -* [`ab6f180`](https://github.com/npm/npm/commit/ab6f1801971b513f9294b4b8902034ab402af02d) - `lodash.keys@4.0.7` - ([@jdalton](https://github.com/jdalton)) -* [`4b8d8b6`](https://github.com/npm/npm/commit/4b8d8b63e760a8aa03e8bffa974495dfafbfcb06) - `lodash.union@4.4.0` - ([@jdalton](https://github.com/jdalton)) -* [`46099d3`](https://github.com/npm/npm/commit/46099d34542760098e5d13c7468a405a724ca407) - `lodash.uniq@4.3.0` - ([@jdalton](https://github.com/jdalton)) -* [`fff89c6`](https://github.com/npm/npm/commit/fff89c6826c86e9e789adcc9c398385539306042) - `lodash.without@4.2.0` - ([@jdalton](https://github.com/jdalton)) - -### v3.9.0 (2016-05-05) - -Wow! This is a big release week! We've completed the fixes that let the -test suite pass on Windows, plus more general bug fixes we found while -fixing things on Windows. Plus a warning to help folks work around a common -footgun. PLUS an improvement to how npm works with long cache timeouts. - -#### INFINITE CACHE A LITTLE BETTER - -* [`111ae3e`](https://github.com/npm/npm/commit/111ae3ec366ece7ebcf5988f5bc2a7cd70737dfe) - [#8581](https://github.com/npm/npm/issues/8581) - When a package is fetched from the cache which cannot satisfy the version - requirements, an attempt to fetch it from the network is made. This is - helpful for folks using high values for `--cache-min` who are willing to - accept possibly not-the-most-recent modules in return for less network - traffic. - ([@Zirak](https://github.com/Zirak)) - -#### WARNING: FOOTGUN - -* [`60b9a05`](https://github.com/npm/npm/commit/60b9a051aa46b8892fe63b3681839a6fd6642bfd) - [#12475](https://github.com/npm/npm/pull/12475) - Options can only start with ASCII dashes. Ordinarily this isn't a problem - but many web documentation tools "helpfully" convert `--` into an emdash - (–), or `-` into an endash (–). If you copy and paste from this documentation - your commands won't work the way you expect. This adds a warning that tries - to be a little more descriptive about why your command is failing. - ([@iarna](https://github.com/iarna)) - -#### WINDOWS CI - -We have [Windows CI](https://ci.appveyor.com/project/npm/npm) setup now! We still have to -tweak it a little bit around paths to the git binaries, but it's otherwise ready! - -* [`bb5d6cb`](https://github.com/npm/npm/commit/bb5d6cbf46b2609243d3b384caadd196e665a797) - [#11444](https://github.com/npm/npm/pull/11444) - Add AppVeyor to CI matrix. - ([@othiym23](https://github.com/othiym23)) - -#### COVERAGE DATA - -Not only do our tests produce coverage reports after they run now, we also -automatically [update Coveralls](https://coveralls.io/github/npm/npm) with -results from [Travis CI](travis-ci.org/npm/npm) runs. - -* [`044cbab`](https://github.com/npm/npm/commit/044cbab0d49adeeb0d9310c64fee6c9759cc7428) - [#11444](https://github.com/npm/npm/pull/11444) - Enable coverage reporting for every test run. - ([@othiym23](https://github.com/othiym23)) - -#### EVERYONE BUGS - -* [`37c6a51`](https://github.com/npm/npm/commit/37c6a51c71b0feec8f639b3199a8a9172e58deec) - [#12150](https://github.com/npm/npm/pull/12150) - Ensure that 'npm cache ls' outputs real filenames. Previously it would - sometimes double up the package name in the path it printed. - ([@isaacs](https://github.com/isaacs)) -* [`d3ce0b2`](https://github.com/npm/npm/commit/d3ce0b253eb519375071aee29db4ee129dbcdf5c) - [#11444](https://github.com/npm/npm/pull/11444) - Fix unbuilding bins for scoped modules. - ([@iarna](https://github.com/iarna)) -* [`e928a30`](https://github.com/npm/npm/commit/e928a30947477a09245f54e9381f46b97bee32d5) - [#11444](https://github.com/npm/npm/pull/11444) - Make handling of local modules (eg `npm install /path/to/my/module`) more - consistent when saved to a `package.json`. There were bugs previously where - it wouldn't consistently resolve relative paths in the same way. - ([@iarna](https://github.com/iarna)) -* [`b820ed4`](https://github.com/npm/npm/commit/b820ed4fc04e21577fa66f7c9482b5ab002e7985) - [#11444](https://github.com/npm/npm/pull/11444) - Under certain circumstances the paths produced for linking, either - relative or absolute, would end up basing off the wrong virtual cwd. - This resulted in failures for `npm link` in this situations. - ([@iarna](https://github.com/iarna)) - -#### WINDOWS BUGS - -* [`7380425`](https://github.com/npm/npm/commit/7380425d810fb8bfc69405a9cbbdec19978a7bee) - [#11444](https://github.com/npm/npm/pull/11444) - Scoped module names were not being correctly inferred from the path on Windows. - ([@zkat](https://github.com/zkat)) -* [`91fc24f`](https://github.com/npm/npm/commit/91fc24f2763c2e0591093099ffc866c735f27fde) - [#11444](https://github.com/npm/npm/pull/11444) - Explore with a command to run didn't work properly in Windows– it would pop open a new - cmd window and leave it there. - ([@iarna](https://github.com/iarna)) - -#### WINDOWS REFACTORING - -* [`f07e643`](https://github.com/npm/npm/commit/f07e6430d4ca02f811138f6140a8bad927607a1f) - [#11444](https://github.com/npm/npm/pull/11444) - Move exec path escaping out to its own function. This turns out to be - tricky to get right because how you escape commands to run on Windows via - cmd is different then how you escape them at other times. Specifically, - you HAVE to quote each directory segment that has a quote in it, that is: - `C:\"Program Files"\MyApp\MyApp.exe` By contrast, if that were an argument - to a command being run, you CAN'T DO quote it that way, instead you have - to wrap the entire path in quotes, like so: `"C:\Program - Files\MyApp\MyApp.exe"`. - ([@iarna](https://github.com/iarna)) -* [`2e01d29`](https://github.com/npm/npm/commit/2e01d299f8244134b1aa040cab1b59c72c9df4da) - [#11444](https://github.com/npm/npm/pull/11444) - Create a single function for detecting if we're running on Windows (and - using a Windows shell like cmd) and use this instead of doing it one-off - all over the place. - ([@iarna](https://github.com/iarna)) - -#### FIX WINDOWS TESTS - -As I said before, our tests are passing on Windows! 🎉 - -* [`ef0dd74`](https://github.com/npm/npm/commit/ef0dd74583be25c72343ed07d1127e4d0cc02df9) - [#11444](https://github.com/npm/npm/pull/11444) - The fruits of many weeks of labor, fix our tests to pass on Windows. - ([@zkat](https://github.com/zkat)) - ([@iarna](https://github.com/iarna)) - -#### DEPENDENCY UPDATES - -* [`8fccda8`](https://github.com/npm/npm/commit/8fccda8587209659c469ab55c608b0e2d7533530) - [#11444](https://github.com/npm/npm/pull/11444) - `normalize-git-url@3.0.2`: - Fix file URLs on Windows. - ([@zkat](https://github.com/zkat)) -* [`f53a154`](https://github.com/npm/npm/commit/f53a154df8e0696623e6a71f33e0a7c11a7555aa) - `readable-stream@2.1.2`: - When readable-stream is disabled, reuse result of `require('stream')` - instead of calling it every time. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`02841cf`](https://github.com/npm/npm/commit/02841cfb81d6ba86f691ab43d9bbdac29aec27e7) - [#11444](https://github.com/npm/npm/pull/11444) - `realize-package-specifier@3.0.2`: - Resolve local package paths relative to package root, not cwd. - ([@zkat](https://github.com/zkat)) - ([@iarna](https://github.com/iarna)) -* [`247c1c5`](https://github.com/npm/npm/commit/247c1c5ae08c882c9232ca605731039168bae6ed) - [#11444](https://github.com/npm/npm/pull/11444) - `npm-package-arg@4.1.1`: - Fix Windows file URIs with leading slashes. - ([@zkat](https://github.com/zkat)) -* [`365c72b`](https://github.com/npm/npm/commit/365c72bc3ecd9e45f9649725dd635d5625219d8c) - `which@1.2.8` - ([@isaacs](https://github.com/isaacs)) -* [`e568caa`](https://github.com/npm/npm/commit/e568caabb8390a924ce1cfa51fc914ee6c1637a2) - `graceful-fs@4.1.4` - ([@isaacs](https://github.com/isaacs)) -* [`304b974`](https://github.com/npm/npm/commit/304b97434959a58f84383bcccc0357c51a4eb39a) - [#11444](https://github.com/npm/npm/pull/11444) - `standard@6.0.8` - ([@feross](https://github.com/feross)) - -### v3.8.9 (2016-04-28) - -Our biggest news this week is that we got the -[Windows test suite passing](https://github.com/npm/npm/pull/11444)! -It'll take a little longer to get it passing in our -[Windows CI](https://ci.appveyor.com/project/npm/npm/) but that's coming -soon too. - -That means we'll be shifting gears away from tests to fixing -[Big Bugs™](https://github.com/npm/npm/issues?q=is%3Aopen+is%3Aissue+label%3Abig-bug) again. -Join us at our [team meeting](https://github.com/npm/npm/issues/12517) next -Tuesday to learn more about that. - -#### BUG FIXES AND REFACTORING - -* [`60da618`](https://github.com/npm/npm/commit/60da61862885fa904afba7d121860b4282a5b0df) - [#12347](https://github.com/npm/npm/issues/12347) - Fix a bug that could result in shrinkwraps missing the `resolved` field, which is - necessary in producing a fully reproducible build. - ([@sminnee](https://github.com/sminnee)) -* [`8597ba4`](https://github.com/npm/npm/commit/8597ba432e91245a1000953b612eb01308178bad) - [#12009](https://github.com/npm/npm/issues/12009) - Fix a bug in `npm view <packagename> versions` that resulted in bad output if you - didn't also pass in `--json`. - ([@watilde](https://github.com/watilde)) -* [`20125f1`](https://github.com/npm/npm/commit/20125f19b96fd05af63f8c0bd243ffb25780279a) - [`a53feac`](https://github.com/npm/npm/commit/a53feac2647f7dc4245f1700dfbdd1aba8745672) - [`6cfbae4`](https://github.com/npm/npm/commit/6cfbae403abc3cf690565b09569f71cdd41a8372) - [#12485](https://github.com/npm/npm/pull/12485) - Refactor how the help summaries for commands are produced, such that we only have - one list of command aliases. - ([@watilde](https://github.com/watilde)) -* [`2ae210c`](https://github.com/npm/npm/commit/2ae210c76ab6fd15fcf15dc1808b01ca0b94fc9e) - `read-package-json@2.0.4`: - Fix a crash we discovered while fixing up the Windows test suite where if - you had a file in your `node_modules` it would cause a crash on Windows - (but not MacOS/Linux). - - This makes the error code you get on Windows match that from MacOS/Linux - if you try to read a `package.json` from a path that includes a file, not - a folder. - ([@zkat](https://github.com/zkat)) - -### v3.8.8 (2016-04-21) - -Hi all! Long time no see! We've been heads-down working through getting -[our test suite passing on Windows](https://github.com/npm/npm/pull/11444). -Did you know that we have -[Windows CI](https://ci.appveyor.com/project/npm/npm) now running over at -Appveyor? In the meantime, we've got a bunch of dependency updates, some -nice documentation improvements and error messages when your `package.json` -contains invalid JSON. (Yeah, I thought we did that last one before too!) - -#### BAD JSON IS BAD - -* [`769e620`](https://github.com/npm/npm/commit/769e6200722d8060b6769e47354032c51cfa85a1) - [#12406](https://github.com/npm/npm/pull/12406) - Failing to parse the top level `package.json` should be an error. - ([@watilde](https://github.com/watilde)) - -#### DOCUMENTATION - -* [`7d64301`](https://github.com/npm/npm/commit/7d643018af5051c920cc73f17bfe32b7ff86e108) - [#12415](https://github.com/npm/npm/pull/12415) - Clarify that when configuring client-side certificates for authenticating - to non-npm registries that `cert` and `key` are not filesystem paths and should - actually include the certificate and key data. - ([@rvedotrc](https://github.com/rvedotrc)) -* [`f8539b8`](https://github.com/npm/npm/commit/f8539b8c986e81771ccc8ced7e716718423d3187) - [#12324](https://github.com/npm/npm/pull/12324) - Describe how `npm run` sets `NODE` and `PATH` in more detail. - Note that `npm run` changes `PATH` to include the current node - interpreter’s directory. - ([@addaleax](https://github.com/addaleax)) -* [`2b57606`](https://github.com/npm/npm/commit/2b57606852a2c2a03e4c4b7dcda85b807619c2cf) - [#11461](https://github.com/npm/npm/pull/11461) - Clarify the documentation for the package.json homepage field. - ([@stevemao](https://github.com/stevemao)) - -#### TESTS - -* [`b5a0fbb`](https://github.com/npm/npm/commit/b5a0fbb9e1a2c4fb003dd748264571aa6e3c9e70) - [#12329](https://github.com/npm/npm/pull/12329) - Fix progress config testing to ignore local user configs. - Previously, _any_ local setting would cause the tests to fail as - they were trying to test what the default values for the progress - bar would be in different environments and any explicit setting - overrides those defaults. - ([@iarna](https://github.com/iarna)) -* [`3d195bc`](https://github.com/npm/npm/commit/3d195bc0a72b40df02a5c56e4f3be44152e8222b) - The lifecycle-signal test could crash on v0.8 due to its use of `Number.parseInt`, which - isn't available in that version of node. Fortunately `global.parseInt` _is_, so - we just use that instead. - ([@iarna](https://github.com/iarna)) - -#### DEPENDENCY UPDATES - -* [`05a28e3`](https://github.com/npm/npm/commit/05a28e38586082ac4bbf26ee6f863cc8d07054d6) - `npm-package-arg@4.1.1`: - Under some circumstances `file://` URLs on Windows were not handled correctly. - - Also, stop converting local module/tarballs into full paths in this - module. We do already do that in `realize-package-specifier`, which is - more appropriate as it knows what package we're installing relative to. - ([@zkat](https://github.com/zkat)) -* [`ada2e93`](https://github.com/npm/npm/commit/ada2e93e8b276000150a9aa93fff69ec366e03d6) - `realize-package-specifier@3.0.3`: - Require the new `npm-package-arg`, plus fix a case where specifiers that were - maybe a tag, maybe a local filename were resolved differently than those that were - definitely a local filename. - ([@zkat](https://github.com/zkat)) ([@iarna](https://github.com/iarna)) -* [`adc515b`](https://github.com/npm/npm/commit/adc515b22775871386cd62390079fb4bf8e1714a) - `fs-vacuum@1.2.9`: - A fix for AIX where a non-empty directory can cause `fs.rmDir` to fail with `EEXIST` instead of `ENOTEMPTY` - and three new tests - ([@richardlau](https://github.com/richardlau)) - - Code cleanup, CI & dependency updates. - ([@othiym23](https://github.com/othiym23)) -* [`ef53a46`](https://github.com/npm/npm/commit/ef53a46906ce872a4541b605dd42a563cc26e614) - `tap@5.7.1` - ([@isaacs](https://github.com/isaacs)) -* [`df1f2e4`](https://github.com/npm/npm/commit/df1f2e4838b4d7ea2ea2321a95ae868c0ec0a520) - `request@2.72.0`: - Fix crashes when response headers indicate gzipped content but the body is - empty. - Add support for the deflate content encoding. - ([@simov](https://github.com/simov)) -* [`776c599`](https://github.com/npm/npm/commit/776c599b204632aca9d29fd92ea5c4f099fdea9f) - `readable-stream@2.1.0`: - Adds READABLE_STREAM env var that, if set to `disable`, will make - `readable-stream` use the local native node streams instead. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`10d6d55`](https://github.com/npm/npm/commit/10d6d5547354fcf50e930c7932ba4d63c0b6009c) - `normalize-git-url@3.0.2`: - Add support `git+file://` type URLs. - ([@zkat](https://github.com/zkat)) -* [`75017ae`](https://github.com/npm/npm/commit/75017aeecec69a1efd546df908aa5befc4467f36) - `lodash.union@4.3.0` - ([@jdalton](https://github.com/jdalton)) - -### v3.8.7 (2016-04-07) - -#### IMPROVED DIAGNOSTICS - -* [`38cf79f`](https://github.com/npm/npm/commit/38cf79ffa564ef5cb6677b476e06d0e45351592a) - [#12083](https://github.com/npm/npm/pull/12083) - If you `ignore-scripts` to disable lifecycles, this makes npm report when it skips running - a script. - ([@bfred-it](https://github.com/bfred-it)) - -#### IMPROVE AUTO-INCLUDES - -* [`c615182`](https://github.com/npm/npm/commit/c615182c8b47e418338eb1317b99bb66987cda54) - [#11995](https://github.com/npm/npm/pull/11995) - There were bugs where modules whose names matched the special files that npm always - includes would be included, for example, the `history` package was always included. - - With `npm@3` such extraneously bundled modules would not be ordinarily - used, as things in `node_modules` in packages are ignored entirely if the - package isn't marked as bundling modules. - - Because of this `npm@3` behavior, the `files-and-ignores` test failed to catch this as - it was testing _install output_ not what got packed. That has also been fixed. - ([@glenjamin](https://github.com/glenjamin)) - -#### DOCUMENTATION UPDATES - -* [`823d9df`](https://github.com/npm/npm/commit/823d9dfa91d7086a26620f007aee4e3cd77b6153) - [#12107](https://github.com/npm/npm/pull/12107) - In the command summary for `adduser` mention that `login` is an alias. - ([@gnerkus](https://github.com/gnerkus)) -* [`7aaf47e`](https://github.com/npm/npm/commit/7aaf47e124c45dde72c961638b770ee535fb2776) - [#12244](https://github.com/npm/npm/pull/12244) - Update the README to suggest npm@3 for Windows users. Also add a reference to - [Microsoft's npm upgrade tool](https://github.com/felixrieseberg/npm-windows-upgrade). - ([@felixrieseberg](https://github.com/felixrieseberg)) - -#### DEPENDENCY UPDATES - -* [`486bbc0`](https://github.com/npm/npm/commit/486bbc0e1b101f847e890e6f1925dc8cb253cf3e) - `request@2.70.0` - ([@simov](https://github.com/simov)) -* [`b1aff34`](https://github.com/npm/npm/commit/b1aff346fc41f13e3306b437e1831942aacf2f54) - `lodash.keys@4.0.6` - ([@jdalton](https://github.com/jdalton)) - -### v3.8.6 (2016-03-31) - -Heeeeeey y'all. - -Kat here! Rebecca's been schmoozing with folks at [Microsoft -Build](https://build.microsoft.com/), so I'm doing the `npm@3` release this -week. - -Speaking of Build, it looks like Microsoft is doing some bash thing. This might -be really good news for our Windows users once it rolls around. We're keeping an -eye out and feeling hopeful. 🙆 - -As far as the release goes: We're really happy to be getting more and more -community contributions! Keep it up! We really appreciate folks trying to help -us, and we'll do our best to help point you in the right direction. Even things -like documentation are a huge help. And remember -- you get socks for it, too! - -#### FIXES - -* [`f8fb4d8`](https://github.com/npm/npm/commit/f8fb4d83923810eb78d075bd200a9376c64c3e3a) - [#12079](https://github.com/npm/npm/pull/12079) - Back in `npm@3.2.2` we included [a patch that made it so `npm install pkg` was - basically `npm install pkg@latest` instead of - `pkg@*`](https://github.com/npm/npm/pull/9170) - This is probably what most users expected, but it also ended up [breaking `npm - deprecate`](https://github.com/npm/npm/pull/9170) when no version was provided - for a package. In that case, we were using `*` to mean "deprecate all - versions" and relying on the `pkg` -> `pkg@*` conversion. - This patch fixes `npm deprecate pkg` to work as it used to by special casing - that particular command's behavior. - ([@polm](https://github.com/polm)) -* [`458f773`](https://github.com/npm/npm/commit/458f7734f3376aba0b6ff16d34a25892f7717e40) - [#12146](https://github.com/npm/npm/pull/12146) - Adds `make doc-clean` to `prepublish` script, to clear out previously built - docs before publishing a new npm version - ([@watilde](https://github.com/watilde)) -* [`f0d1521`](https://github.com/npm/npm/commit/f0d1521038e956b2197673f36c464684293ce99d) - [#12146](https://github.com/npm/npm/pull/12146) - Adds `doc-clean` phony target to `make publish`. - ([@watilde](https://github.com/watilde)) - -#### DOC UPDATES - -* [`ea92ffc`](https://github.com/npm/npm/commit/ea92ffc9dd2a063896353fc52c104e85ec061360) - [#12147](https://github.com/npm/npm/pull/12147) - Document that the current behavior of `engines` is just to warn if the node - platform is incompatible. - ([@reconbot](https://github.com/reconbot)) -* [`cd1ba44`](https://github.com/npm/npm/commit/cd1ba4423b3ca889c741141b95b0d9472b9f71ea) - [#12143](https://github.com/npm/npm/pull/12143) - Remove `npm faq` command, since the [FAQ was - removed](https://github.com/npm/npm/pull/10547). - ([@watilde](https://github.com/watilde)) -* [`50a12cb`](https://github.com/npm/npm/commit/50a12cb1f5f158af78d6962ad20ff0a98bc18f18) - [#12143](https://github.com/npm/npm/pull/12143) - Remove references to the FAQ from the docs, since [it was - removed](https://github.com/npm/npm/pull/10547). - ([@watilde](https://github.com/watilde)) -* [`60051c2`](https://github.com/npm/npm/commit/60051c25e2ab80c667137dfcd04b242eea25980e) - [#12093](https://github.com/npm/npm/pull/12093) - Update `bugs` url in `package.json` to use the `https` URL for Github. - ([@watilde](https://github.com/watilde)) -* [`af30c37`](https://github.com/npm/npm/commit/af30c374ef22ed1a1c71b14fced7c4b8350e4e82) - [#12075](https://github.com/npm/npm/pull/12075) - Add the `--ignore-scripts` flag to the `npm install` docs. - ([@paulirish](https://github.com/paulirish)) -* [`632b214`](https://github.com/npm/npm/commit/632b214b2f2450e844410792e5947e46844612ff) - [#12063](https://github.com/npm/npm/pull/12063) - Various minor fixes to the html docs homepage. - ([@watilde](https://github.com/watilde)) - -#### DEP BUMPS - -* [`3da0171`](https://github.com/npm/npm/commit/3da01716a0e41d6b5adee2b4fc70fcaf08c0eb24) - `lodash.without@4.1.2` - ([@jdalton](https://github.com/jdalton)) -* [`69ccf6d`](https://github.com/npm/npm/commit/69ccf6dd4caf95cd0628054307487cae1885acd0) - `lodash.uniq@4.2.1` - ([@jdalton](https://github.com/jdalton)) -* [`b50c41a`](https://github.com/npm/npm/commit/b50c41a9930dc5353a23c5ae2ff87bb99e11d482) - `lodash.union@4.2.1` - ([@jdalton](https://github.com/jdalton)) -* [`59c1ad7`](https://github.com/npm/npm/commit/59c1ad7b6f243d07618ed5703bd11d787732fc57) - `lodash.clonedeep@4.3.2` - ([@jdalton](https://github.com/jdalton)) -* [`2b4f797`](https://github.com/npm/npm/commit/2b4f797dba8e7a1376c8335b7223e82d02cd8243) - `lodash._baseuniq@4.5.1` - ([@jdalton](https://github.com/jdalton)) - -### v3.8.5 (2016-03-24) - -Like my esteemed colleague [@zkat](https://github.com/zkat) said in this -week's [LTS release notes](https://github.com/npm/npm/releases/tag/v2.15.2), -this week is another small release but we are continuing to work on our -[Windows efforts](https://github.com/npm/npm/pull/11444). - -You may also be interested in reading the [LTS process and -policy](https://github.com/npm/npm/wiki/LTS) that -[@othiym23](https://github.com/othiym23) put together recently. If you have any -feedback, we would love to hear. - -#### DOCTOR IT HURTS WHEN LINK TO MY LINK - -Well then, don't do that. - -* [`0d4a0b1`](https://github.com/npm/npm/commit/0d4a0b1) - [#11442](https://github.com/npm/npm/pull/11442) - Fail if the user asks us to make a link from a module back on to itself. - ([@antialias](https://github.com/antialias)) - -#### ERR MODULE LIST TOO LONG - -* [`b271ed2`](https://github.com/npm/npm/commit/b271ed2) - [#11983](https://github.com/npm/npm/issues/11983) - Exit early if no arguments were provided to search instead of trying to display all the modules, - running out of memory, and then crashing. - ([@SimenB](https://github.com/SimenB)) - -#### ELIMINATE UNUSED MODULE - -* [`b8c7cd7`](https://github.com/npm/npm/commit/b8c7cd7) - [#12000](https://github.com/npm/npm/pull/12000) - Stop depending on [`async-some`](https://npmjs.com/package/async-some) as it's no - longer used in npm. - ([@watilde](https://github.com/watilde)) - -#### DOCUMENTATION IMPROVEMENTS - -* [`fdd6b28`](https://github.com/npm/npm/commit/fdd6b28) - [#11884](https://github.com/npm/npm/pull/11884) - Include `node_modules` in the list of files and directories that npm won't - include in packages ordinarily. (Modules listed in `bundledDependencies` and things - that those modules rely on, ARE included of course.) - ([@Jameskmonger](https://github.com/Jameskmonger)) -* [`aac15eb`](https://github.com/npm/npm/commit/aac15eb) - [#12006](https://github.com/npm/npm/pull/12006) - Fix typo in npm-orgs documentation, where teams docs went to access docs and vice versa. - ([@yaelz](https://github.com/yaelz)) - -#### FEWER NETWORK TESTS - -* [`3e41360`](https://github.com/npm/npm/commit/3e41360) - [#11987](https://github.com/npm/npm/pull/11987) - Fix test that was inappropriately hitting the network - ([@yodeyer](https://github.com/yodeyer)) - -### v3.8.4 (2016-03-24) - -Was erroneously released with just a changelog typo correction and was -otherwise the same as 3.8.3. - -### v3.8.3 (2016-03-17): - -#### SECURITY ADVISORY: BEARER TOKEN DISCLOSURE - -This release includes [the fix for a -vulnerability](https://github.com/npm/npm/commit/f67ecad59e99a03e5aad8e93cd1a086ae087cb29) -that could cause the unintentional leakage of bearer tokens. - -Here are details on this vulnerability and how it affects you. - -##### DETAILS - -Since 2014, npm’s registry has used HTTP bearer tokens to authenticate requests -from the npm’s command-line interface. A design flaw meant that the CLI was -sending these bearer tokens with _every_ request made by logged-in users, -regardless of the destination of their request. (The bearers only should have -been included for requests made against a registry or registries used for the -current install.) - -An attacker could exploit this flaw by setting up an HTTP server that could -collect authentication information, then use this authentication information to -impersonate the users whose tokens they collected. This impersonation would -allow them to do anything the compromised users could do, including publishing -new versions of packages. - -With the fixes we’ve released, the CLI will only send bearer tokens with -requests made against a registry. - -##### THINK YOU'RE AT RISK? REGENERATE YOUR TOKENS - -If you believe that your bearer token may have been leaked, [invalidate your -current npm bearer tokens](https://www.npmjs.com/settings/tokens) and rerun -`npm login` to generate new tokens. Keep in mind that this may cause continuous -integration builds in services like Travis to break, in which case you’ll need -to update the tokens in your CI server’s configuration. - -##### WILL THIS BREAK MY CURRENT SETUP? - -Maybe. - -npm’s CLI team believes that the fix won’t break any existing registry setups. -Due to the large number of registry software suites out in the wild, though, -it’s possible our change will be breaking in some cases. - -If so, please [file an issue](https://github.com/npm/npm/issues/new) describing -the software you’re using and how it broke. Our team will work with you to -mitigate the breakage. - -##### CREDIT & THANKS - -Thanks to Mitar, Will White & the team at Mapbox, Max Motovilov, and James -Taylor for reporting this vulnerability to npm. - -#### PERFORMANCE IMPROVEMENTS - -The updated [`are-we-there-yet`](https://npmjs.com/package/are-we-there-yet) -changes how it tracks how complete things are to be much more efficient. -The summary is that `are-we-there-yet` was refactored to remove an expensive -tree walk. - -The result for you should be faster installs when working with very large trees. - -Previously `are-we-there-yet` computed this when you asked by passing the request down -its tree of progress indicators, totaling up the results. In doing so, it had to walk the -entire tree of progress indicators. - -By contrast, `are-we-there-yet` now updates a running total when a change -is made, bubbling that up the tree from whatever branch made progress. This -bubbling was already going on so there was nearly no cost associated with taking advantage of it. - -* [`32f2bd0`](https://github.com/npm/npm/commit/32f2bd0e26116db253e619d67c4feae1de3ad2c2) - `npmlog@2.0.3`: - Bring in substantial performance improvements from `are-we-there-yet`. - ([@iarna](https://github.com/iarna)) - -#### DUCT TAPE FOR BUGS - -* [`473d324`](https://github.com/npm/npm/commit/473d3244a8ddfd6b260d0aa0d395b119d595bf97) - [#11947](https://github.com/npm/npm/pull/11947) - Guard against bugs that could cause the installer to crash with errors like: - - ``` - TypeError: Cannot read property 'target' of null - ``` - - This doesn't fix the bugs, but it does at least make the installer less - likely to explode. - ([@thefourtheye](https://github.com/thefourtheye)) - -#### DOC FIXES - -* [`ffa428a`](https://github.com/npm/npm/commit/ffa428a4eee482aa620819bc8df994a76fad7b0c) - [#11880](https://github.com/npm/npm/pull/11880) - Fix typo in `npm install` documentation. - ([@watilde](https://github.com/watilde)) - -#### DEPENDENCY UPDATES - -* [`7537fe1`](https://github.com/npm/npm/commit/7537fe1748c27e6f1144b279b256cd3376d5c41c) - `sorted-object@2.0.0`: - Create objects with `{}` instead of `Object.create(null)` to make the results - strictly equal to what, say, parsed JSON would provide. - ([@domenic](https://github.com/domenic)) -* [`8defb0f`](https://github.com/npm/npm/commit/8defb0f7b3ebdbe15c9ef5036052c10eda7e3161) - `readable-stream@2.0.6`: - Fix sync write issue on 0.10. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) - -#### TEST FIXES FOR THE SELF TESTS - -* [`c3edeab`](https://github.com/npm/npm/commit/c3edeabece4400308264e7cf4bc4448bd2729f55) - [#11912](https://github.com/npm/npm/pull/11912) - Change the self installation test to do its work in `/tmp`. - Previously this was installing into a temp subdir in `test/tap`, which - wouldn't catch the case where a module was installed in the local - `node_modules` folder but not in dependencies, as node would look up - the tree and use the copy from the version of npm being tested. - ([@iarna](https://github.com/iarna)) - -### v3.8.2 (2016-03-10): - -#### HAVING TROUBLE INSTALLING C MODULES ON ANDROID? - -This release includes an updated `node-gyp` with fixes for Android. - -* [`634ecba`](https://github.com/npm/npm/commit/634ecba320fb5a3287e8b7debfd8b931827b9e19) - `node-gyp@3.3.1`: - Fix bug in builds for Android. - ([@bnoordhuis](https://github.com/bnoordhuis)) - -#### NPM LOGOUT CLEANS UP BETTER - -* [`460ed21`](https://github.com/npm/npm/commit/460ed217876ac78d21477c288f1c06563fb770b4) - [#10529](https://github.com/npm/npm/issues/10529) - If you ran `npm logout` with a scope, while we did invalidate your auth - token, we weren't removing the auth token from your config file. This patch causes - the auth token to be removed. - ([@wyze](https://github.com/wyze)) - -#### HELP MORE HELPFUL - -* [`d1d0233`](https://github.com/npm/npm/commit/d1d02335d297da2734b538de44d8967bdcd354cf) - [#11003](https://github.com/npm/npm/issues/11003) - Update help to only show command names and their shortcuts. Previously - some typo corrections were shown, along with various alternate - spellings. - ([@watilde](https://github.com/watilde)) -* [`47928cd`](https://github.com/npm/npm/commit/47928cd6264e1d6d0ef67435b71c66d01bea664a) - [#11003](https://github.com/npm/npm/issues/11003) - Remove "version" typo from the help listing. - ([@doug-wade](https://github.com/doug-wade)) - -#### MORE COMPLETE CONFIG LISTINGS - -* [`cf5fd40`](https://github.com/npm/npm/commit/cf5fd401494d96325d74a8bb8c326aa0045a714c) - [#11472](https://github.com/npm/npm/issues/11472) - Make `npm config list` include the per-project `.npmrc` in the output. - ([@mjomble](https://github.com/mjomble)) - -#### DEPTH LIMITED PARSEABLE DEP LISTINGS - -* [`611070f`](https://github.com/npm/npm/commit/611070f0f7a1e185c75cadae46179194084b398f) - [#11495](https://github.com/npm/npm/issues/11495) - Made `npm ls --parseable` honor the `--depth=#` option. - ([@zacdoe](https://github.com/zacdoe)) - -#### PROGRESS FOR THE (NON) UNICODE REVOLUTION - -* [`ff90382`](https://github.com/npm/npm/commit/ff9038227a1976b5e936442716d9877f43c6c9b4) - [#11781](https://github.com/npm/npm/issues/11781) - Make the progress bars honor the unicode option. - ([@watilde](https://github.com/watilde)) - -#### `npm view --json`, NOW ACTUALLY JSON - -* [`24ab70a`](https://github.com/npm/npm/commit/24ab70a4ccfeaa005b80252da313bb589510668e) - [#11808](https://github.com/npm/npm/issues/11808) - Make `npm view` produce valid JSON when requested with `--json`. - Previously `npm view` produced some sort of weird hybrid output, with multiple - JSON docs. - ([@doug-wade](https://github.com/doug-wade)) - -#### DOCUMENTATION CHANGES - -* [`6fb0499`](https://github.com/npm/npm/commit/6fb0499bea868fdc637656d210c94f051481ecd4) - [#11726](https://github.com/npm/npm/issues/11726) - Previously we patched the `npm update` docs to suggest using `--depth - Infinity` instead of `--depth 9999`, but that was a mistake. We forgot - that `npm outdated` (on which `npm update` is built) has a special - case where it treats `Infinity` as `0`. This reverts that patch. - ([@GriffinSchneider](https://github.com/GriffinSchneider)) -* [`f0bf684`](https://github.com/npm/npm/commit/f0bf684a87ea5eea03432a17f38678fed4960d43) - [#11748](https://github.com/npm/npm/pull/11748) - Document all of the various aliases for commands in the documentation - for those commands. - ([@watilde](https://github.com/watilde)) -* [`fe04443`](https://github.com/npm/npm/commit/fe04443d8988e2e41bd4047078e06a26d05d380d) - [#10968](https://github.com/npm/npm/issues/10968) - The `npm-scope` document notes that scopes have been available on the - public registry for a while. This adds that you'll need `npm@2` or later - to use them. - ([@doug-wade](https://github.com/doug-wade)) -* [`3db37a5`](https://github.com/npm/npm/commit/3db37a52b2b2e3193ef250ad2cf96dfd2def2777) - [#11820](https://github.com/npm/npm/pull/11820) - The command `npm link` should be linking package from local folder to - global, and `npm link package-name` should be from global to local. The - description in the documentation was reversed and this fixes that. - ([@rhgb](https://github.com/rhgb)) - -#### GLOB FOR THE GLOB THRONE - -* [`be55882`](https://github.com/npm/npm/commit/be55882dc4ee5ce0777b4badc9141dab5bf5be4d) - `glob@7.0.3`: - Fix a race condition and some windows edge cases. - ([@isaacs](https://github.com/isaacs)) - -### v3.8.1 (2016-03-03): - -This week the install summary got better, killing your npm process now -also kills the scripts it was running and a rarely used search flag got -documented. - -Our improvements on the test suite on Windows are beginning to pick up -steam, you can follow along by -[watching the PR](https://github.com/npm/npm/pull/11444). - -#### BETTER INSTALL SUMMARIES - -* [`e40d457`](https://github.com/npm/npm/commit/e40d4572cc98db06757df5b8bb6b7dbd0546d3d7) - [#11699](https://github.com/npm/npm/issues/11699) - Ensure that flags like `--production` passed to install don't result in - the summary at the end being incorrectly filtered. That summary is - produced by the same code as `npm ls` and therefore responds to flags - the same way it does. This is undesirable when it's an install summary, - however, as we don't want it to filter anything. - - This fixes an issue where `npm install --production <module>` would - result in npm exiting with an error code. The `--production` flag would - make `npm ls` filter out `<module>` as it wasn't saved to the - `package.json` and thus wasn't a production dependency. The install - report is limited to show just the modules installed, so with that - filtered out nothing is available. With nothing available `npm ls` - would set `npm` to exit with an error code. - ([@ixalon](https://github.com/ixalon)) -* [`99337b4`](https://github.com/npm/npm/commit/99337b469163a4b211b9c6ff1aa9712ae0d601d2) - [#11600](https://github.com/npm/npm/pull/11600) - Make the report of installed modules really only show those modules - that were installed. Previously it selected which modules from your - tree to display based on `name@version` which worked great when your - tree was deduped but would list things it hadn't touched when there - were duplicates. - ([@iarna](https://github.com/iarna)) - -#### SCRIPTS BETTER FOLLOW THE LEADER - -* [`5454347`](https://github.com/npm/npm/commit/545434766eb3681d3f40b745f9f3187ed63f310a) - [#10868](https://github.com/npm/npm/pull/10868) - When running a lifecycle script, say through `npm start`, killing npm - wouldn't forward that on to the children. It does now. - ([@daniel-pedersen](https://github.com/daniel-pedersen)) - -#### SEARCHING SPECIFIC REGISTRIES - -* [`6020447`](https://github.com/npm/npm/commit/60204479f76458a9864aa530cda2b3333f95c2b0) - [#11490](https://github.com/npm/npm/pull/11490) - Add docs for using the `--registry` flag with search. - ([@plumlee](https://github.com/plumlee)) - -#### LODASH UPDATES - -* [`bb14204`](https://github.com/npm/npm/commit/bb14204183dad620a6650452a26cdc64111f8136) - `lodash.without@4.1.1` - ([@jdalton](https://github.com/jdalton)) -* [`0089059`](https://github.com/npm/npm/commit/0089059c562aee9ad0398e55d2c12c68a6150e79) - `lodash.keys@4.0.5` - ([@jdalton](https://github.com/jdalton)) -* [`6ee1de4`](https://github.com/npm/npm/commit/6ee1de4474d9683a1f7023067d440780eeb10311) - `lodash.clonedeep@4.3.1` - ([@jdalton](https://github.com/jdalton)) - -### v3.8.0 (2016-02-25): - -This week brings a quality of life improvement for some Windows users, and -an important knob to be tuned for folks experiencing network problems. - -#### LIMIT CONCURRENT REQUESTS - -We've long known that `npm`'s tendency to try to request all your -dependencies simultaneously upset some network hardware (particular, -consumer grade routers & proxies of all sorts). One of the reasons that we're -planning to write our own npm specific version of `request` is to be able to -more easily control this sort of thing. - -But fortunately, you don't have to wait for that. -[@misterbyrne](https://github.com/misterbyrne) took a look at our existing -code and realized it could be added painlessly TODAY. The new default -maximum is `50`, instead of `Infinity`. If you're having network issues you -can try setting that value down to something lower (if you do, please let us -know... the default is subject to tuning). - -* [`910f9ac`](https://github.com/npm/npm/commit/910f9accf398466b8497952bee9f566ab50ade8c) - [`f7be667`](https://github.com/npm/npm/commit/f7be667548a132ec190ac9d60a31885a7b4fe2b3) - Add a new config option, `maxsockets` and `npm-registry-client@7.1.0` to - take advantage of it. - ([@misterbyrne](https://github.com/misterbyrne)) - -#### WINDOWS GIT BASH - -We think it's pretty keen too, we were making it really hard to actually -upgrade if you were using it. NO MORE! - -* [`d60351c`](https://github.com/npm/npm/commit/d60351ccae87d71a5f5eac73e3085c6290b52a69) - [#11524](https://github.com/npm/npm/issues/11524) - Prefer locally installed npm in Git Bash -- previous behavior was to use - the global one. This was done previously for other shells, but not for Git - Bash. - ([@destroyerofbuilds](https://github.com/destroyerofbuilds)) - -#### DOCUMENTATION IMPROVEMENTS - -* [`b63de3c`](https://github.com/npm/npm/commit/b63de3c97c4c27078944249a4d5bbe1c502c23bc) - [#11636](https://github.com/npm/npm/issues/11636) - Document `--save-bundle` option in main install page. - ([@datyayu](https://github.com/datyayu)) -* [`3d26453`](https://github.com/npm/npm/commit/3d264532d6d9df60420e985334aebb53c668d32b) - [#11644](https://github.com/npm/npm/pull/11644) - Add `directories.test` to the `package.json` documentation. - ([@lewiscowper](https://github.com/lewiscowper)) -* [`b64d124`](https://github.com/npm/npm/commit/b64d12432fdad344199b678d700306340d3607eb) - [#11441](https://github.com/npm/npm/pull/11441) - Add a link in documentation to the contribution guidelines. - ([@watilde](https://github.com/watilde)) -* [`82fc548`](https://github.com/npm/npm/commit/82fc548b0e2abbdc4f7968c20b118c30cca79a24) - [#11441](https://github.com/npm/npm/pull/11441/commits) - Remove mentions of the long defunct Google group. - ([@watilde](https://github.com/watilde)) -* [`c6ad091`](https://github.com/npm/npm/commit/c6ad09131af2e2766d6034257a8fcaa294184121) - [#11474](https://github.com/npm/npm/pull/11474) - Correct invalid JSON in npm-update docs. - ([@robludwig](https://github.com/robludwig)) -* [`4906c90`](https://github.com/npm/npm/commit/4906c90ed2668adf59ebee759c7ebb811aa46e57) - Expand on the documentation for `bundlededDependencies`, explaining what they are - and when you might want to use them. - ([@gnerkus](https://github.com/gnerkus)) - -#### DEPENDENCY UPDATES - -* [`93cdc25`](https://github.com/npm/npm/commit/93cdc25432b71cbc9c25c54ae316770e18f4b01e) - `strip-ansi@3.0.1`: - Non-user visible tests & maintainer doc updates. - ([@jbnicolai](https://github.com/jbnicolai)) -* [`3b2ccef`](https://github.com/npm/npm/commit/3b2ccef30dc2038b99ba93cd1404a1d01dac8790) - `lodash.keys@4.0.4` - ([@jdalton](https://github.com/jdalton)) -* [`30e9eb9`](https://github.com/npm/npm/commit/30e9eb97397a8f85081d328ea9aa54c2a7852613) - `lodash._baseuniq@4.5.0` - ([@jdalton](https://github.com/jdalton)) - - -### v3.7.5 (2016-02-22): - -A quick fixup release because when I updated glob, I missed the subdep copies of itself -that it installed deeper in the tree. =/ - -This only effected people trying to update to `3.7.4` from `npm@2` or `npm@1`. Updates from -`npm@3` worked fine (as it fixes up the missing subdeps during installation). - -#### OH MY GLOB - -* [`63fa704`](https://github.com/npm/npm/commit/63fa7044569127e6e29510dc499a865189806076) - [#11633](https://github.com/npm/npm/issues/11633) - When updating the top level `npm` to `glob@7`, the subdeps that - still depended on `glob@6` got new versions installed but they - weren't added to the commit. This adds them back in. - ([@iarna](https://github.com/iarna)) - -### v3.7.4 (2016-02-18): - -I'm ([@iarna](https://github.com/iarna)) back from vacation in the frozen -wastes of Maine! This release sees a couple of bug fixes, some -documentation updates, a bunch of dependency updates and improvements to our -test suite. - -#### FIXES FOR `update`, FIXES FOR `ls` - -* [`53cdb96`](https://github.com/npm/npm/commit/53cdb96634fc329378b4ea4e767ba9987986a76e) - [#11362](https://github.com/npm/npm/issues/11362) - Make `npm update` stop trying to update linked packages. - ([@rhendric](https://github.com/rhendric)) -* [`8d90d25`](https://github.com/npm/npm/commit/8d90d25b3da086843ce43911329c9572bd109078) - [#11559](https://github.com/npm/npm/issues/11559) - Only list runtime dependencies when doing `npm ls --production`. - ([@yibn2008](https://github.com/yibn2008)) - -#### @wyze, DOCUMENTATION HERO OF THE PEOPLE, GETS THEIR OWN HEADER - -* [`b78b301`](https://github.com/npm/npm/commit/b78b30171038ab737eff0b070281277e35af25b4) - [#11416](https://github.com/npm/npm/pull/11416) - Logout docs were using a section copy-pasted from the adduser docs. - ([@wyze](https://github.com/wyze)) -* [`649e28f`](https://github.com/npm/npm/commit/649e28f50aa323e75202eeedb824434535a0a4a0) - [#11414](https://github.com/npm/npm/pull/11414) - Add colon for consistency. - ([@wyze](https://github.com/wyze)) - -#### WHITTLING AWAY AT PATH LENGTHS - -So for all of you who don't know -- Node.js does, in fact, support long Windows -paths. Unfortunately, depending on the tool and the Windows version, a lot of -external tooling does not. This means, for example, that some (all?) versions of -Windows Explorer *can literally never delete npm from their system entirely -because of deeply-nested npm dependencies*. Which is pretty gnarly. - -Incidentally, if you run into that in particularly, you can use -[rimraf](npm.im/rimraf) to remove such files 💁. - -The latest victim of this issue was the Node.js CI setup for testing on Windows, -which uses some tooling or another that croaks on the usual path length limit -for that OS: 255 characters. - -This isn't ordinarily an issue with `npm@3` as it produces mostly flat -trees, but you may be surprised to learn that `npm`'s own distribution isn't -flat, due to needing to be compatible with `npm@1.2`, which ships with -`node@0.8`! - -We've taken another baby step towards alleviating this in this release by -updating a couple of dependencies that were preventing `npmlog` from deduping, -and then doing a dedupe on that and `gauge`. Hopefully it helps. - -* [`f3c32bc`](https://github.com/npm/npm/commit/f3c32bc3127301741d2fa3a26be6f5f127a35908) - [#11528](https://github.com/npm/npm/pull/11528) - `node-gyp@3.3.0`: - Update to a more recent version that uses a version of npmlog compatible - with npm itself. Also adds: AIX support, new `gyp`, `--cafile` command - line option, and allows configuration of Node.js and io.js mirrors. - ([@rvagg](https://github.com/rvagg)) - -#### INTERNAL TEST IMPROVEMENTS - -The `npm` core team's time recently has been sunk into `npm`'s many years of -tech debt. Specifically, we've been working on improving the test suite. -This isn't user visible, but in future should mean a more stable, easier to -contribute to `npm`. Ordinarily we don't report these kinds of changes in -the change log, but I thought I might share this week as this chunk is -bigger than usual. - -* [`07f020a`](https://github.com/npm/npm/commit/07f020a09e94ae393c67526985444e128ef6f83c) - [#11292](https://github.com/npm/npm/pull/11292) - `tacks@1.0.9`: - Add a package that provides a tool to generate fixtures from folders and, relatedly, - a module that an create and tear down filesystem fixtures easily. - ([@iarna](https://github.com/iarna)) -* [`0837346`](https://github.com/npm/npm/commit/083734631f9b11b17c08bca8ba8cb736a7b1e3fb) - [#11292](https://github.com/npm/npm/pull/11292) - Remove all the relatively cryptic legacy tests and creates new tap tests - that check the same functionality. The *legacy* tests were tests that - were originally a shell script that was ported to javascript early in - `npm`'s history. - ([@iarna](https://github.com/iarna)) - ([@zkat](https://github.com/zkat)) -* [`5a701e7`](https://github.com/npm/npm/commit/5a701e71a0130787fb98450f9de92117b4ef88e1) - [#11292](https://github.com/npm/npm/pull/11292) - Test that we don't leak auth info into the environment. - ([@zkat](https://github.com/zkat)) -* [`502d7d0`](https://github.com/npm/npm/commit/502d7d0628f08b09d8d13538ebccc63de8b3edf5) - [#11292](https://github.com/npm/npm/pull/11292) - Test that env vars properly passed into scripts. - ([@zkat](https://github.com/zkat)) -* [`420f267`](https://github.com/npm/npm/commit/420f2672ee8c909f18bee10b1fc7d4ad91cf328b) - [#11292](https://github.com/npm/npm/pull/11292) - Test that npm's distribution binary is complete and can be installed and used. - ([@iarna](https://github.com/iarna)) -* [`b7e99be`](https://github.com/npm/npm/commit/b7e99be1b1086f2d6098c653c1e20791269c9177) - [#11292](https://github.com/npm/npm/pull/11292) - Test that the `package.json` `files` section and `.npmignore` do what - they're supposed to. - ([@zkat](https://github.com/zkat)) - -#### DEPENDENCY UPDATES - -* [`4611098`](https://github.com/npm/npm/commit/4611098fd8c65d61a0645deb05bf38c81300ffca) - `rimraf@2.5.2`: - Use `glob@7.0.0`. - ([@isaacs](https://github.com/isaacs)) -* [`41b2772`](https://github.com/npm/npm/commit/41b2772cb83627f3b5b926cf81e150e7148cb124) - `glob@7.0.0`: - Raise error if `options.cwd` is specified, and not a directory. - ([@isaacs](https://github.com/isaacs)) -* [`c14e74a`](https://github.com/npm/npm/commit/c14e74ab5d17c764f3aa37123a9632fa965f8760) - `gauge@1.2.7`: Update to newer lodash versions, for a smaller tree. - ([@iarna](https://github.com/iarna)) -* [`d629363`](https://github.com/npm/npm/commit/d6293630ddc25bfa26d19b6be4fd2685976d7358) - `lodash.without@4.1.0` - ([@jdalton](https://github.com/jdalton)) -* [`3ea4c80`](https://github.com/npm/npm/commit/3ea4c8049ca8df9f64426b1db8a29b9579950134) - `lodash.uniq@4.2.0` - ([@jdalton](https://github.com/jdalton)) -* [`8ddcc8d`](https://github.com/npm/npm/commit/8ddcc8deb554660a3f7f474fae9758c967d94552) - `lodash.union@4.2.0` - ([@jdalton](https://github.com/jdalton)) -* [`2b656a6`](https://github.com/npm/npm/commit/2b656a672d351f32ee2af24dcee528356dcd64f4) - `lodash.keys@4.0.3` - ([@jdalton](https://github.com/jdalton)) -* [`ac171f8`](https://github.com/npm/npm/commit/ac171f8f0318a7dd3c515f3b83502dfa9e87adb8) - `lodash.isarguments@3.0.7` - ([@jdalton](https://github.com/jdalton)) -* [`bcccd90`](https://github.com/npm/npm/commit/bcccd9057b75d800c799ab15f00924f700415d3e) - `lodash.clonedeep@4.3.0` - ([@jdalton](https://github.com/jdalton)) -* [`8165bca`](https://github.com/npm/npm/commit/8165bca537d86305a3d08f080f86223a26615aa8) - `lodash._baseuniq@4.4.0` - ([@jdalton](https://github.com/jdalton)) - -### v3.7.3 (2016-02-11): - -Hey all! We've got a pretty small release this week -- just documentation -updates and a couple of dependencies. This release also includes a particular -dependency upgrade that makes it so we're exclusively using the latest version -of `graceful-fs`, which'll make it so things keep working with future Node.js -releases. - -A certain internal Node.js API was deprecated and slated for future removal from -Node Core. This API was critical for versions of `graceful-fs@<4`, before a -different approach was used to achieve similar ends. By upgrading this library, -and making sure all our dependencies are also updated, we've ensured npm will -continue to work once the API is finally removed. Older versions of npm, on the -other hand, will simply not work on future versions of Node.js. - -#### DEPENDENCY UPGRADES - -* [`29536f4`](https://github.com/npm/npm/commit/29536f42da6c06091c9acbc8952f72daa8a9412c) - `cmd-shim@2.0.2`: - Final straggler using `graceful-fs@<4`. - ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`5f59e74`](https://github.com/npm/npm/commit/5f59e748ef4c066756bb204a452cecd0543c7a2f) - `lodash.uniq@4.1.0` - ([@jdalton](https://github.com/jdalton)) -* [`987cabe`](https://github.com/npm/npm/commit/987cabe8a18abcb5a685685958bf74c7258a979c) - `lodash.union@4.1.0` - ([@jdalton](https://github.com/jdalton)) -* [`5c641f0`](https://github.com/npm/npm/commit/5c641f05fdc153c6bb06a89c46fe2a345ce413db) - `lodash.clonedeep@4.1.0` - ([@jdalton](https://github.com/jdalton)) - -#### EVERYONE GETTING SOCKS LIKE IT'S OPRAH'S SHOW - -* [`9ea5658`](https://github.com/npm/npm/commit/9ea56582ca4d0991dbed44f992c88f08a643cb4b) - [#11410](https://github.com/npm/npm/pull/11410) - Fixed a small spelling error in `npm-config.md`. - ([@pra85](https://github.com/pra85)) -* [`2a11e56`](https://github.com/npm/npm/commit/2a11e562a14bce18b6ddca6c20d17f97b6a8ec2f) - [#11403](https://github.com/npm/npm/pull/11403) - Removes `--depth Infinity` warning from documentation -- this operation should - actually be totally safe as of `npm@3`. (The warning remains for `npm@2`.) - ([@Aourin](https://github.com/Aourin)) -* [`42a4727`](https://github.com/npm/npm/commit/42a4727bfb1e21c890b8e2babda55e06ac2bda29) - [#11391](https://github.com/npm/npm/pull/11391) - Fixed versions of `shrinkwrap.json` in examples in documentation for `npm - shrinkwrap`, which did not quite match up. - ([@xcatliu](https://github.com/xcatliu)) - -### v3.7.2 (2016-02-04): - -This week, the CLI team has been busy working on rewriting tests to support -getting coverage reports going and running all of our tests on Windows. -Meanwhile, we've got a bunch of dependency updates and one or two other -things. - -#### TESTS WENT INTO HIDING - -Last week we took a patch from [@substack](https://github.com/substack) to -stop the installer from reordering arrays in an installed module's -`package.json`... but somehow I dropped the test when I was rebasing. - -* [`21b9271`](https://github.com/npm/npm/commit/21b927182514a0ff6d9f34480bfc39f72e3e9f8c) - [#10063](https://github.com/npm/npm/issues/10063) - Restore test that verifies that we don't re-order arrays in a module's - `package.json` on install. - ([@substack](https://github.com/substack)) - -#### DOCUMENTATION FIXES - -* [`c67521d`](https://github.com/npm/npm/commit/c67521dc6c1e41d39d02c74105e41442851d23bb) - [#11348](https://github.com/npm/npm/pull/11348) - Improve the documentation around which files are ALWAYS included in published packages - and which are ALWAYS excluded. - ([@jscissr](https://github.com/jscissr)) -* [`7ef6793`](https://github.com/npm/npm/commit/7ef6793cd191cc8d88340f7e1ce9c9e3d6f0b2f4) - [#11348](https://github.com/npm/npm/pull/11348) - The release date on the 3.7.0 changelog entry was wrong. I honestly don't - know how I keep doing this. =D - ([@rafek](https://github.com/rafek)) - -#### DEPENDENCY UPDATES - -* [`8a3c80c`](https://github.com/npm/npm/commit/8a3c80c4fd3d82fe937f30bc7cbd3dee51a8a893) - `graceful-fs@4.1.3`: - Fix a bug where close wasn't getting made graceful. - ([@isaacs](https://github.com/isaacs)) - -`lodash` saw updates across most of its modules this week with browser -campatibility fixes that don't really impact us. - -* [`2df342b`](https://github.com/npm/npm/commit/2df342bf30efa99b98016acc8a5dc03e00b58b9c) - `lodash.without@4.0.2` - ([@jdalton](https://github.com/jdalton)) -* [`86aa91d`](https://github.com/npm/npm/commit/86aa91dce60f6b6a92bb3ba2bf6e6be1f6afc750) - `lodash.uniq@4.0.2` - ([@jdalton](https://github.com/jdalton)) -* [`0a94bf6`](https://github.com/npm/npm/commit/0a94bf6af0ebd38d080f92257e0cd9bae40b31ff) - `lodash.union@4.0.2` - ([@jdalton](https://github.com/jdalton)) -* [`b4c9582`](https://github.com/npm/npm/commit/b4c9582b4ef5991f3d155e0c6142ed1c631860af) - `lodash.isarguments@3.0.6` - ([@jdalton](https://github.com/jdalton)) -* [`efe766c`](https://github.com/npm/npm/commit/efe766c63c0948a4ae4c0d12f2b834629ab86e92) - `lodash.keys@4.0.2`: Minor code cleanup and the above. - ([@jdalton](https://github.com/jdalton)) -* [`36abb24`](https://github.com/npm/npm/commit/36abb24ef31017adbf325e7f833d5d4b0f03f5d4) - `lodash.clonedeep@4.0.4`: - Add support for cloning prototype objects and the above. - ([@jdalton](https://github.com/jdalton)) - -### v3.7.1 (2016-02-01): - -Super quick Monday patch on last week's release. - -If you ever wondered why we release things to the `npm@next` tag for a week -before promoting them to `npm@latest`, this is it! - -#### RELEASE TRAIN VINDICATED (again) - -* [`adcaf04`](adcaf047811dcc475ab1984fc93fe34540fc03d7) - [#11349](https://github.com/npm/npm/issues/11349) - Revert last weeks change to use JSON clone instead of `lodash.cloneDeep`. - ([@iarna](https://github.com/iarna)) - -### v3.7.0 (2016-01-29): - -Hi all! This week brings us some important performance improvements, -support for git submodules(!) and a bunch of bug fixes. - -#### PERFORMANCE - -`gauge`, the module responsible for drawing `npm`'s progress bars, had an -embarrassing bug in its debounce implementation that resulted in it, on many -systems, actually being _slower_ than if it hadn't been debouncing. This was -due to it destroying and then creating a timer object any time it got an -update while waiting on its minimum update period to elapse. This only was -a measurable slowdown when sending thousands of updates a second, but -unfortunately parts of `npm`'s logging do exactly that. This has been patched -to eliminate that churn, and our testing shows the progress bar as being -eliminated as a source of slow down. - -Meanwhile, `are-we-there-yet` is the module that tracks just how complete -our big asynchronous install process is. [@STRML](https://github.com/STRML) -spent some time auditing its source and made a few smaller performance -improvements to it. Most impactful was eliminating a bizarre bit of code -that was both binding to AND closing over the current object. I don't have -any explanation for how that crept in. =D - -* [`c680fa9`](https://github.com/npm/npm/commit/c680fa9f8135759eb5512f4b86e47fa265733f79) - `npmlog@2.0.2`: New `are-we-there-yet` with performance patches from - [@STRML](https://github.com/STRML). New `gauge` with timer churn - performance patch. - ([@iarna](https://github.com/iarna)) - -We were also using `lodash`'s `cloneDeep` on `package.json` data which is -definitely overkill, seeing as `package.json` data has all the restrictions -of being `json`. The fix for this is just swapping that out for something -that does a pair of `JSON.stringify`/`JSON.parse`, which is distinctly more -speedy. - -* [`1d1ea7e`](https://github.com/npm/npm/commit/1d1ea7eeb958034878eb6573149aeecc686888d3) - [#11306](https://github.com/npm/npm/pull/11306) - Use JSON clone instead of `lodash.cloneDeep`. - ([@STRML](https://github.com/STRML)) - -#### NEW FEATURE: GIT SUBMODULE SUPPORT - -Long, long requested– the referenced issue is from 2011– we're finally -getting rudimentary git submodule support. - -* [`39dea9c`](https://github.com/npm/npm/commit/39dea9ca4216c6ea628f5ca47d2b34a4b251a1ed) - [#1876](https://github.com/npm/npm/issues/1876) - Add support for git submodules in git remotes. This is a fairly simple - approach, which does not leverage the git caching mechanism to cache - submodules. It also doesn't provide a means to disable automatic - initialization, e.g. via a setting in the `.gitmodules` file. - ([@gagern](https://github.com/gagern)) - -#### ROBUSTNESS - -* [`5dec02a`](https://github.com/npm/npm/commit/5dec02a3d0e82202c021e27aff9d006283fdc25a) - [#10347](https://github.com/npm/npm/issues/10347) - There is an obscure feature that lets you monkey-patch npm when it starts - up. If the module being required with this feature failed, it would - previously just make `npm` error out– this reduces that to a warning. - ([@evanlucas](https://github.com/evanlucas)) - -#### BUG FIXES - -* [`9ab8b8d`](https://github.com/npm/npm/commit/9ab8b8d047792612ae7f9a6079745d51d5283a53) - [#10820](https://github.com/npm/npm/issues/10820) - Fix a bug with `npm ls` where if you asked for ONLY production dependencies in output - it would exclude dependencies that were BOTH production AND development dependencies. - ([@davidvgalbraith](https://github.com/davidvgalbraith)) -* [`6803fed`](https://github.com/npm/npm/commit/6803fedadb8f9b36cd85f7338ecf75d1d183c833) - [#8982](https://github.com/npm/npm/issues/8982) - Fix a bug where, under some circumstances, if you had a path that - contained the name of a package being installed somewhere in it, `npm` - would incorrectly refuse to run lifecycle scripts. - ([@elvanja](https://github.com/elvanja)) -* [`3eae40b`](https://github.com/npm/npm/commit/3eae40b7a681aa067dfe4fea8c9a76da5b508b48) - [#9253](https://github.com/npm/npm/issues/9253) - Fix a bug where, when running lifecycle scripts, if the Node.js binary you ran - `npm` with wasn't in your `PATH`, `npm` wouldn't use it to run your scripts. - ([@segrey](https://github.com/segrey)) -* [`61daa6a`](https://github.com/npm/npm/commit/61daa6ae8cbc041d3a0d8a6f8f268b47dd8176eb) - [#11014](https://github.com/npm/npm/issues/11014) - Fix a bug where running `rimraf node_modules/<package>` followed by `npm - rm --save <package>` would fail. `npm` now correctly removes the module - from your `package.json` even though it doesn't exist on disk. - ([@davidvgalbraith](https://github.com/davidvgalbraith)) -* [`a605586`](https://github.com/npm/npm/commit/a605586df134ee97c95f89c4b4bd6bc73f7aa439) - [#9679](https://github.com/npm/npm/issues/9679) - Fix a bug where `npm install --save git+https://…` would save a `https://` - url to your `package.json` which was a problem because `npm` wouldn't then - know that it was a git repo. - ([@gagern](https://github.com/gagern)) -* [`bbdc700`](https://github.com/npm/npm/commit/bbdc70024467c365cc4e06b8410947c04b6f145b) - [#10063](https://github.com/npm/npm/issues/10063) - Fix a bug where `npm` would change the order of array properties in the - `package.json` files of dependencies. `npm` adds a bunch of stuff to - `package.json` files in your `node_modules` folder for debugging and - bookkeeping purposes. As a part of this process it sorts the object to - reduce file churn when it does updates. This fixes a bug where the arrays - in the object were also getting sorted. This wasn't a problem for - properties that `npm` itself maintains, but _is_ a problem for properties - used by other packages. - ([@substack](https://github.com/substack)) - -#### DOCS IMPROVEMENTS - -* [`2609a29`](https://github.com/npm/npm/commit/2609a2950704f577ac888668e81ba514568fab44) - [#11273](https://github.com/npm/npm/pull/11273) - Include an example of viewing package version history in the `npm view` documentation. - ([@vedatmahir](https://github.com/vedatmahir)) -* [`719ea9c`](https://github.com/npm/npm/commit/719ea9c45a5c3233f3afde043b89824aad2df0a7) - [#11272](https://github.com/npm/npm/pull/11272) - Fix typographical issue in `npm update` documentation. - ([@jonathanp](https://github.com/jonathanp)) -* [`cb9df5a`](https://github.com/npm/npm/commit/cb9df5a37091e06071d8704b629e7ebaa41c37fe) - [#11215](https://github.com/npm/npm/pull/11215) - Do not call `SEE LICENSE IN <filename>` an _SPDX expression_, as it's not. - ([@kemitchell](https://github.com/kemitchell)) -* [`f427934`](https://github.com/npm/npm/commit/f4279346c368da4bca09385f773e8eed1d389e5e) - [#11196](https://github.com/npm/npm/pull/11196) - Correct the `package.json` examples in the `npm update` documentation to actually be - valid JSON and not just JavaScript object literals. - ([@s100](https://github.com/s100)) - -#### DEPENDENCY UPDATES - -* [`a7b2407`](https://github.com/npm/npm/commit/a7b24074cb59a1ab17c0d8eff1498047e6a123e5) - `retry@0.9.0`: New features and interface agnostic refactoring. - ([@tim-kos](https://github.com/tim-kos)) -* [`220fc77`](https://github.com/npm/npm/commit/220fc7702ae3e5d601dfefd3e95c14e9b32327de) - `request@2.69.0`: - A bunch of small bug fixes and module updates. - ([@simov](https://github.com/simov)) -* [`9e5c84f`](https://github.com/npm/npm/commit/9e5c84f1903748897e54f8ff099729ff744eab0f) - `which@1.2.4`: - Update `isexe` and fix bug in `pathExt`, in which files without extensions - would sometimes be preferred to files with extensions on Windows, even though - those without extensions aren't executable. - `pathExt` is a list of extensions that are considered executable (exe, cmd, - bat, com on Windows). - ([@isaacs](https://github.com/isaacs)) -* [`375b9c4`](https://github.com/npm/npm/commit/375b9c42fe0c6de47ac2f92527354b2ea79b7968) - `rimraf@2.5.1`: Minor doc formatting fixes. - ([@isaacs](https://github.com/isaacs)) -* [`ef1971e`](https://github.com/npm/npm/commit/ef1971e6270c2bc72e6392b51a8b84f52708f7e7) - `lodash.clonedeep@4.0.2`: - Misc minor code cleanup. No functional changes. - ([@jdalton](https://github.com/jdalton)) - -### v3.6.0 (2016-01-20): - -Hi all! This is a bigger release, in part 'cause we didn't have one last -week. The most important thing you need to know is that when `npm@3.6.0` replaces -`npm@3.5.4` as `next`, `npm@3.5.4` WILL NOT be moved on to `latest`. This is due to -a packaging error that tickles bugs in some earlier releases and makes upgrades to it -from those versions break the install. - -#### NEW FEATURES‼ - -* [`ff504d4`](https://github.com/npm/npm/commit/ff504d449ea1fa996cbb02c8078964643c51e5f6) - [#8752](https://github.com/npm/npm/issues/8752) - In `npm outdated`, report symlinked packages as having a wanted & latest - version of `linked`. - ([@halhenke](https://github.com/halhenke)) -* [`f44d8c9`](https://github.com/npm/npm/commit/f44d8c9a3940f7041f8136f8754a54b13f1f9d60) - [#10775](https://github.com/npm/npm/issues/10775) - Add a success message to `adduser` / `login`. - ([@ekmartin](https://github.com/ekmartin)) -* [`3109303`](https://github.com/npm/npm/commit/310930395c9bf1577cf085b9742210bfc71bb019) - [#10043](https://github.com/npm/npm/pull/10043) - Warn if you try to use `npm run x` if you don't have a `node_modules` folder, since - whatever you're trying to do _probably_ won't work. - ([@timkrins](https://github.com/timkrins)) - -* [`9ed2849`](https://github.com/npm/npm/commit/9ed2849cd7e8cc97111dca42a940905284afe55d) - [`e9f1ad8`](https://github.com/npm/npm/commit/e9f1ad88ce58ecd111811e11afa52ac19fc8696e) - [`f10d300`](https://github.com/npm/npm/commit/f10d300e5effa7a5756c8d461eef284c283a41d1) - [`8b593d8`](https://github.com/npm/npm/commit/8b593d8d187d6ac85d2a59cbe647afb5516c1b94) - [#10717](https://github.com/npm/npm/pull/10717) - `npm version` can now take a `from-git` argument, which instructs `npm` to read the - version from git and update your `package.json` to what it finds. This is in contrast - to its normal use where `npm` _tells_ git about your new version. - ([@ekmartin](https://github.com/ekmartin)) - -#### 3.5.4 WAS NOT SO GREAT - -The `npm@3.5.4` package was missing some dependencies. Specifically, `glob` -and `has-unicode` had major release updates which meant that subdeps that -relied on older major versions couldn't use the npm supplied versions any -more, and so they needed their own copies. - -This went undetected because the actions necessary to run the tests (which -check for this sort of thing) resolved the missing modules. - -Further, it didn't have symptoms when upgrading from _most_ versions of npm. -Unfortunately, some versions had bugs that were tickled by this and resulted -in broken upgrades, most notably, `npm@3.3.12`, the version that's been in -Node.js 5. - -* [`1d3325c`](https://github.com/npm/npm/commit/1d3325c040621a4792db80fb232f4994b9d5c5f2) - [`02611c6`](https://github.com/npm/npm/commit/02611c673a4d2bbe8fcef8d48407768da31c90d2) - [`39d5fea`](https://github.com/npm/npm/commit/39d5feadefdde38d75a18f23343bc6ec37153638) - [`7d0e830`](https://github.com/npm/npm/commit/7d0e830f26c73b9d9277b29949227ba9cca27fd9) - [#11129](https://github.com/npm/npm/pull/11129) - Update the underlying dependencies to allow use for the new versions of - `glob` and `has-unicode`. - ([@iarna](https://github.com/iarna)) - -#### WHEN MISSING PATHS ARE OK - -* [`bb638fa`](https://github.com/npm/npm/commit/bb638fa4f48d24d2c9935861d5d751c5621eea49) - [#11212](https://github.com/npm/npm/pull/11212) - When trying to determine if a file was controlled by npm before going to - remove it, we check to see if it is inside any of a list of paths that npm - considers to be under its control. Not all of those paths always exist - (and that's ok!) Previously we were calling it a failure to match if ANY - of them didn't exist. We now only do so if NONE of them exist. If some - do, then we do our usual checks on them. - - This showed up as an error where you would see something like: - ``` - npm warn gentlyRm not removing /path/to/thing as it wasn't installed by /path/to/other/thing - ``` - But it totally was installed by it. - ([@iarna](https://github.com/iarna)) - -#### BETTER NODE PRE-RELEASE SUPPORT - -Historically, if you used a pre-release version of Node.js, you would get -dozens and dozens of warnings when EVERY engine check failed across all of -your modules, because `>= 0.10.0` doesn't match prereleases. - -You might find this stream of redundant warnings undesirable. I do. - -We've moved this into a SINGLE warning you'll get about using a pre-release -version of Node.js and now suppress those other warnings. - -* [`6952f79`](https://github.com/npm/npm/commit/6952f7981e451a2d599a4f513573af208bdfe103) - [#11212](https://github.com/npm/npm/pull/11212) - Engine check warnings are now issued along with any other warnings about - your tree, instead of emitting in the middle of your install (and then - disappearing behind the giant tree of stuff installed). - ([@iarna](https://github.com/iarna)) -* [`ee2ebe9`](https://github.com/npm/npm/commit/ee2ebe96fb3d105787835b72085bbd2eee66a629) - [#11212](https://github.com/npm/npm/pull/11212) - Suppress engine verification warnings about pre-release versions of Node.js. - ([@iarna](https://github.com/iarna)) -* [`135b7e0`](https://github.com/npm/npm/commit/135b7e078311e8b4e2c8e2b662eed9ba6c2e2537) - [#11212](https://github.com/npm/npm/pull/11212) - Explicitly warn, in only one place, if you are using a pre-release version - of Node.js. - ([@iarna](https://github.com/iarna)) - -#### BUG FIXES - -* [`ea331c8`](https://github.com/npm/npm/commit/ea331c82157c65f7643cd4b49fd24031c84bf601) - [#10938](https://github.com/npm/npm/issues/10938) - When removing a package, sometimes the `node_modules/.bin` wouldn't be - cleaned up entirely. This would result in package folders that contained - only a `node_modules/.bin` directory. In turn, this would result in `npm - ls` and other tools complaining about these broken directories. - To fix this, the `unbuild` step now explicitly deletes the - `node_modules/.bin` folder as its final step. - ([@chrisirhc](https://github.com/chrisirhc)) -* [`00720db`](https://github.com/npm/npm/commit/00720db2c326cf8f968c662444a4575ae8c3020a) - [#11158](https://github.com/npm/npm/pull/11158) - On Windows, the `node-gyp` wrapper would fail if your path to `node-gyp` - contained spaces. This fixes that problem by quoting use of that path. - ([@orangemocha](https://github.com/orangemocha)) -* [`69ac933`](https://github.com/npm/npm/commit/69ac9333506752bf2e5af70b3b3e03c6181de3e7) - [#11142](https://github.com/npm/npm/pull/11142) - Fix a race condition when making directories in the cache, which could - lead to `ENOENT` failures. - ([@Jimbly](https://github.com/Jimbly)) -* [`e982858`](https://github.com/npm/npm/commit/e982858d9bed65cede9cbb12df9216a4bb9e6fc9) - [#9696](https://github.com/npm/npm/issues/9696) - When replacing the `package.json` in the cache you sometimes see `EPERM` errors on - Windows that you wouldn't on Unix-like operating systems. This ignores those errors - and allows Windows to continue. Longer term, we'll be adding something to retry - these errors, but ultimately fail if there really is an ongoing permissions issue. - ([@orangemocha](https://github.com/orangemocha)) - -#### DOC CHANGES - -* [`3666081`](https://github.com/npm/npm/commit/3666081abd02184ba97a7cdb6ae238085d640b4b) - [#11188](https://github.com/npm/npm/pull/11188) - Add brief description to publish documentation of what's included in - published tarballs. - ([@beaugunderson](https://github.com/beaugunderson)) -* [`b463e34`](https://github.com/npm/npm/commit/b463e3424b296cfc4bd384fc8bfe0e2329649164) - [#11150](https://github.com/npm/npm/pull/11150) - In npm update docs, advise use of `--depth Infinity` instead of `--depth - 9999`. - ([@halhenke](https://github.com/halhenke)) -* [`382e71a`](https://github.com/npm/npm/commit/382e71a7ee5d1ca3dba55c1e753d529eb8ae6895) - [#11128](https://github.com/npm/npm/pull/11128) - In the `package.json` docs, make the reference to the "Local Paths" section - a link to it as well. - ([@orangejulius](https://github.com/orangejulius)) -* [`5277e7f`](https://github.com/npm/npm/commit/5277e7f236e8cb40d7f4a1054506f2d3d159716e) - [#11090](https://github.com/npm/npm/pull/11090) - Fix the 3.5.4 release date in CHANGELOG.md. - ([@ashleygwilliams](https://github.com/ashleygwilliams)) -* [`e6d238a`](https://github.com/npm/npm/commit/e6d238a3d90beeb0af23fa75a9b5e50671d6e4c5) - [#11130](https://github.com/npm/npm/pull/11130) - Eliminate the "using npm programmatically" section from the README. The - documentation for this was removed a while ago and is unsupported. - ([@ljharb](https://github.com/ljharb)) - -#### DEPENDENCY UPDATES - -* [`b0dde5c`](https://github.com/npm/npm/commit/b0dde5c3407b58d78969d3da01af2629fcba1c73) - `config-chain@1.1.10`: Update tests for most recent version of `ini`. - ([@dominictarr](https://github.com/dominictarr)) -* [`c62f414`](https://github.com/npm/npm/commit/c62f414534971761a48ce3cbc3e25214fb09e494) - `glob@6.0.4`: Eliminated use of `util._extend`. - ([@isaacs](https://github.com/isaacs)) -* [`98a6779`](https://github.com/npm/npm/commit/98a67797978ed7ce534e16b705d3a2a9ca0e6cc1) - `lodash.clonedeep@4.0.1`: Bug fixes, including the non-linear performance - that was biting npm a while back. - ([@jdalton](https://github.com/jdalton)) -* [`0e8c4ce`](https://github.com/npm/npm/commit/0e8c4cebddaefbf5eca0abaad512db266c6722c9) - `lodash.without@4.0.1` - ([@jdalton](https://github.com/jdalton)) -* [`1fd19f5`](https://github.com/npm/npm/commit/1fd19f57a3551d7d30a6b8a9ce967ef50e0ff0ba) - `lodash.uniq@4.0.1` - ([@jdalton](https://github.com/jdalton)) -* [`b7486c5`](https://github.com/npm/npm/commit/b7486c550f3391f733d1e1907652be95fddf4368) - `lodash.union@4.0.1` - ([@jdalton](https://github.com/jdalton)) -* [`54bb591`](https://github.com/npm/npm/commit/54bb5911e18f8fb86eb94159f34b13f0c0aa2e30) - `lodash.keys@4.0.0` - ([@jdalton](https://github.com/jdalton)) -* [`26f7a7a`](https://github.com/npm/npm/commit/26f7a7aaae0575a85deba2241ee69b433dd1ba98) - `lodash.isarray@4.0.0` - ([@jdalton](https://github.com/jdalton)) -* [`ed38bd3`](https://github.com/npm/npm/commit/ed38bd3baf544dfc0630fd321d279f137700bd4d) - `lodash.isarguments@3.0.5` - ([@jdalton](https://github.com/jdalton)) - -### v3.5.4 (2016-01-07): - -I hope you all had fantastic winter holidays, if it's winter where you are -and if there are holidays‼ We went a few weeks without releases because -staff was taking time away from work here and there. A new year has come -and we're back now, and refreshed and ready to dig in! - -This week brings us a bunch of documentation improvements and some module -updates. The core team's focus continues to be on improving tests, -particularly with Windows, so there's not too much to call out here. - -#### DOCUMENTATION IMPROVEMENTS - -* [`6b0031e`](https://github.com/npm/npm/commit/6b0031e28c0b10fb2622fdadde41f5cd294348e8) - [#11044](https://github.com/npm/npm/pull/11044) - Correct documentation regarding the defaults for the `color` config option. - ([@scottaddie](https://github.com/scottaddie)) -* [`c6ce69e`](https://github.com/npm/npm/commit/c6ce69eaed7f17b5f1876ac13ecfae3d14a72f24) - [#10990](https://github.com/npm/npm/pull/10990) - Drop mentions in documentation of `process.installPrefix`, as it hasn't - been a thing since Node.js 0.6 and we don't support that. - ([@jeffmcmahan](https://github.com/jeffmcmahan)) -* [`dee92d1`](https://github.com/npm/npm/commit/dee92d1f78608a10becf57aae86d5d495f2272bd) - [#11037](https://github.com/npm/npm/pull/11037) - Clarify the documentation on the max length of the `name` property in - `package.json` files. - ([@scottaddie](https://github.com/scottaddie)) -* [`4b9d7bb`](https://github.com/npm/npm/commit/4b9d7bb1a4fc3f1edcf563379abfd2273af10881) - [#10787](https://github.com/npm/npm/pull/10787) - Make the formatting in the documentation for `npm dist-tag` more - consistent with other docs. - ([@cvrebert](https://github.com/cvrebert)) -* [`7f77a80`](https://github.com/npm/npm/commit/7f77a80d561ee4b2b8c0aba1226fe89dfe339bcd) - [#10787](https://github.com/npm/npm/pull/10787) - Add documentation to the `npm dist-tag` docs that explains in greater - detail how `latest` is different than other tags. Further, improve the - documentation with better examples. Add a discussion of common practice - for using dist tags to manage alpha's and beta's. - ([@cvrebert](https://github.com/cvrebert)) -* [`6db58dd`](https://github.com/npm/npm/commit/6db58dd0d7719c4675a239d43164edc066842b14) - [`2ee6371`](https://github.com/npm/npm/commit/2ee6371911bd3a4d566c5d7bc8734facc60cb27c) - [#10788](https://github.com/npm/npm/pull/10788) - [#10789](https://github.com/npm/npm/pull/10789) - Improve documentation cross referencing. - ([@cvrebert](https://github.com/cvrebert)) -* [`7ba629a`](https://github.com/npm/npm/commit/7ba629a2ad3eaf736529e053b533cabe3a0d7123) - [#10790](https://github.com/npm/npm/pull/10790) - Document more clearly that `npm install foo` means `npm install - foo@latest`. - ([@cvrebert](https://github.com/cvrebert)) - -#### A FEW MODULE UPDATES - -* [`fc2e8d5`](https://github.com/npm/npm/commit/fc2e8d58a91728cb06936eea686efaa4fdec3f06) - `glob@6.0.3`: Remove deprecated features and fix a bunch of bugs. - ([@isaacs](https://github.com/isaacs)) -* [`5b820c4`](https://github.com/npm/npm/commit/5b820c4e17c907fa8c23771c0cd8e74dd5fdaa51) - `has-unicode@2.0.0`: Change the default on Windows to be false, as - international Windows installs often install to non-unicode codepages and - there's no way to detect this short of a system call or a call to a - command line program. - ([@iarna](https://github.com/iarna)) -* [`238fe84`](https://github.com/npm/npm/commit/238fe84ac61297f1d71701d80368afaa40463305) - `which@1.2.1`: Fixed bugs with uid/gid checks and with quoted Windows PATH - parts. - ([@isaacs](https://github.com/isaacs)) -* [`5e510e1`](https://github.com/npm/npm/commit/5e510e13d022a22d58742b126482d3b38a14cc83) - `rimraf@2.5.0`: Add ability to disable glob support / pass in options. - ([@isaacs](https://github.com/isaacs)) -* [`7558215`](https://github.com/npm/npm/commit/755821569466b7be0883f4b0573eeb83c24109eb) - `readable-stream@2.0.5`: Minor performance improvements. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`64e8499`](https://github.com/npm/npm/commit/64e84992c812a73d590be443c09a6977d0ae9040) - `fs-write-stream-atomic@1.0.8`: Rewrite to use modern streams even on 0.8 - plus a bunch of tests. - ([@iarna](https://github.com/iarna)) -* [`74d92a0`](https://github.com/npm/npm/commit/74d92a08d72ce3603244de4bb3e3706d2b928cef) - `columnify@1.5.4`: Some bug fixes around large inputs. - ([@timoxley](https://github.com/timoxley)) - -#### FIX NPM'S TESTS ON 0.8 - -This doesn't impact you as a user of npm, and ordinarily that means we -wouldn't call it out here, but if you've ever wanted to contribute, having -that green travis badge makes it a lot easier to do so with confidence! - -* [`b14cdbb`](https://github.com/npm/npm/commit/b14cdbb6002b04bfbefaff70cc45810c20d5a366) - [#10872](https://github.com/npm/npm/pull/10872) - Rewrite tests using nock to use other alternatives. - ([@zkat](https://github.com/zkat)) -* [`59ed01a`](https://github.com/npm/npm/commit/59ed01a8ea7960b1467aed52164fc36a03c77770) - [#10872](https://github.com/npm/npm/pull/10872) - Work around Node.js 0.8 http back-pressure bug. - - 0.8 http streams have a bug, where if they're paused with data in their - buffers when the socket closes, they call `end` before emptying those - buffers, which results in the entire pipeline ending and thus the point - that applied backpressure never being able to trigger a `resume`. - - We work around this by piping into a pass through stream that has - unlimited buffering. The pass through stream is from readable-stream and - is thus a current streams3 implementation that is free of these bugs even - on 0.8. - ([@iarna](https://github.com/iarna)) - -### v3.5.3 (2015-12-10): - -Did you know that Bob Ross reached the rank of master sergeant in the US Air -Force before becoming perhaps the most soothing painter of all time? - -#### TWO HAPPY LITTLE BUG FIXES - -* [`71c9590`](https://github.com/npm/npm/commit/71c9590be61b6a7b7fa8b6dc19baa588cda26a27) - [#10505](https://github.com/npm/npm/issues/10505) `npm ls --json --depth=0` - now respects the depth parameter, when it is zero and when it is not zero. - ([@MarkReeder](https://github.com/MarkReeder)) -* [`954fa67`](https://github.com/npm/npm/commit/954fa67f1ca3739992abd244e217a0aaf8465660) - [#9099](https://github.com/npm/npm/issues/9099) I had always thought you - could run `npm version` from subdirectories in your project, which is great, - because now you can. I guess I was just ahead of my time. - ([@ekmartin](https://github.com/ekmartin)) - -#### NOW PAINT IN SOME NICE DOCS CHANGES - -* [`b88c37c`](https://github.com/npm/npm/commit/b88c37c1cced40e9e41402cc54a5efc3c33cd13e) - [#10546](https://github.com/npm/npm/issues/10546) Goodbye, FAQ! You were - cheeky and fun until you weren't! Don't worry: npm still loves everyone, - especially you! ([@ashleygwilliams](https://github.com/ashleygwilliams)) -* [`2d3afe9`](https://github.com/npm/npm/commit/2d3afe9644ba69681a36721e79c45d27def71939) - [#10570](https://github.com/npm/npm/issues/10570) Update documentation URLs - to be HTTPS everywhere sensible. No HTTP shall be spared! - ([@rsp](https://github.com/rsp)) -* [`6abd0e0`](https://github.com/npm/npm/commit/6abd0e0626d0f642ce0dae0e128ced80433f15a1) - [#10650](https://github.com/npm/npm/issues/10650) Correctly note that there - are two lifecycle scripts run by an install phase in an example, instead of - three. ([@eymengunay](https://github.com/eymengunay)) -* [`a5e8df5`](https://github.com/npm/npm/commit/a5e8df53b8d6d75398cb6a55a44dcf374b0f1661) - [#10687](https://github.com/npm/npm/issues/10687) `npm outdated`'s output can - be a little puzzling sometimes. I've attempted to make it clearer, with some - examples, of what's going on with "wanted" and "latest" in more cases. - ([@othiym23](https://github.com/othiym23)) -* [`8f52833`](https://github.com/npm/npm/commit/8f52833f5d15c4f94467234607d40e75198af1aa) - [#10700](https://github.com/npm/npm/issues/10700) Hey, do you remember when - `search.npmjs.org` was a thing? I think I do? The last time I used it was in - like 2012, and it's gone now, so remove it from the docs. - ([@gagern](https://github.com/gagern)) -* [`b6a53b8`](https://github.com/npm/npm/commit/b6a53b889c948053dcbf6d7aab9ad1cd4226dc32) - [npm/docs#477](https://github.com/npm/docs/issues/477) Continue to airbrush - the CLI API docs out of history. ([@verpixelt](https://github.com/verpixelt)) -* [`b835b72`](https://github.com/npm/npm/commit/b835b72d1dd23b0a17321a85d8d395322d18005d) - `semver@5.1.0`: Include BNF for SemVer expression grammar (which is also now - included in `npm help semver`). ([@isaacs](https://github.com/isaacs)) - -#### LAND YOUR DEPENDENCY UPGRADES IN PAIRS SO EVERYONE HAS A FRIEND - -* [`95e99fa`](https://github.com/npm/npm/commit/95e99faadcdc85a16210dd79c0e7d83add1b9f3e) - `request@2.67.0` ([@simov](https://github.com/simov)) -* [`b49199a`](https://github.com/npm/npm/commit/b49199ac96dfb1afe5719286621a318576dd69ae) - [isaacs/rimraf#89](https://github.com/isaacs/rimraf/pull/89) `rimraf@2.4.4` - ([@zerok](https://github.com/zerok)) -* [`6632418`](https://github.com/npm/npm/commit/66324189a734a1665e1b78a06ba44089d9c3a11c) - [npm/nopt#51](https://github.com/npm/nopt/pull/51) `nopt@3.0.6` - ([@wbecker](https://github.com/wbecker)) -* [`f0a3b3e`](https://github.com/npm/npm/commit/f0a3b3e0dbbdaf11ec55dccd59cc21bfa05f9240) - [isaacs/once#7](https://github.com/isaacs/once/pull/7) `once@1.3.3` - ([@floatdrop](https://github.com/floatdrop)) - -### v3.5.2 (2015-12-03): - -Weeeelcome to another npm release! The short version is that we fixed -some `ENOENT` and some modules that resulted in modules going missing. We -also eliminated the use of MD5 in our code base to help folks using -Node.js in FIPS mode. And we fixed a bad URL in our license file. - -#### FIX URL IN LICENSE - -The license incorrectly identified the registry URL as -`registry.npmjs.com` and this has been corrected to `registry.npmjs.org`. - -* [`cb6d81b`](https://github.com/npm/npm/commit/cb6d81bd611f68c6126a90127a9dfe5604d46c8c) - [#10685](https://github.com/npm/npm/pull/10685) - Fix npm public registry URL in notices. - ([@kemitchell](https://github.com/kemitchell)) - -#### ENOENT? MORE LIKE ENOMOREBUGS - -The headliner this week was uncovered by the fixes to bundled dependency -handling over the past few releases. What had been a frustratingly -intermittent and hard to reproduce bug became something that happened -every time in Travis. This fixes another whole bunch of errors where you -would, while running an install have it crash with an `ENOENT` on -`rename`, or the install would finish but some modules would be -mysteriously missing and you'd have to install a second time. - -What's going on was a bit involved, so bear with me: - -`npm@3` generates a list of actions to take against the tree on disk. -With the exception of lifecycle scripts, it expects these all to be able -to act independently without interfering with each other. - -This means, for instance, that one should be able to upgrade `b` in -`a→b→c` without having npm reinstall `c`. - -That works fine by the way. - -But it also means that the move action should be able to move `b` in -`a→b→c@1.0.1` to `a→d→b→c@1.0.2` without moving or removing `c@1.0.1` and -while leaving `c@1.0.2` in place if it was already installed. - -That is, the `move` action moves an individual node, replacing itself -with an empty spot if it had children. This is not, as it might first -appear, something where you move an entire branch to another location on -the tree. - -When moving `b` we already took care to leave `c@1.0.1` in place so that -other moves (or removes) could handle it, but we were stomping on the -destination and so `c@1.0.2` was being removed. - -* [`f4385d8`](https://github.com/npm/npm/commit/f4385d8e7678349e75c80fae8a1f8f366f197937) - [#10655](https://github.com/npm/npm/pull/10655) - Preserve destination `node_modules` when moving. - ([@iarna](https://github.com/iarna)) - -There was also a bug with `remove` where it was pruning the entire tree -at the remove point, prior to running moves and adds. - -This was fine most of the time, but if we were moving one of the deps out -from inside it, kaboom. - -* [`19c626d`](https://github.com/npm/npm/commit/19c626d69888f0cdc6e960254b3fdf523ec4b52c) - [#10655](https://github.com/npm/npm/pull/10655) - Get rid of the remove commit phase– we could have it prune _just_ the - module being removed, but that isn't gaining us anything. - ([@iarna](https://github.com/iarna)) - -After all that, we shouldn't be upgrading the `add` of a bundled package -to a `move`. Moves save us from having to extract the package, but with a -bundled dependency it's included in another package already so that -doesn't gain us anything. - -* [`641a93b`](https://github.com/npm/npm/commit/641a93bd66a6aa4edf2d6167344b50d1a2afb593) - [#10655](https://github.com/npm/npm/pull/10655) - Don't convert adds to moves with bundled deps. - ([@iarna](https://github.com/iarna)) - -While I was in there, I also took some time to improve diagnostics to -make this sort of thing easier to track down in the future: - -* [`a04ec04`](https://github.com/npm/npm/commit/a04ec04804e562b511cd31afe89c8ba94aa37ff2) - [#10655](https://github.com/npm/ npm/pull/10655) - Wrap rename so errors have stack traces. - ([@iarna](https://github.com/iarna)) -* [`8ea142f`](https://github.com/npm/npm/commit/8ea142f896a2764290ca5472442b27b047ab7a1a) - [#10655](https://github.com/npm/npm/pull/10655) - Add silly logging so function is debuggable - ([@iarna](https://github.com/iarna)) - -#### NO MORE MD5 - -We updated modules that had been using MD5 for non-security purposes. -While this is perfectly safe, if you compile Node in FIPS-compliance mode -it will explode if you try to use MD5. We've replaced MD5 with Murmur, -which conveys our intent better and is faster to boot. - -* [`f068b26`](https://github.com/npm/npm/commit/f068b2661a8d0269c184867e003cd08cb6c56cf2) - [#10629](https://github.com/npm/npm/issues/10629) - `unique-filename@1.1.0` - ([@iarna](https://github.com/iarna)) -* [`dba1b24`](https://github.com/npm/npm/commit/dba1b2402aaa2beceec798d3bd22d00650e01069) - [#10629](https://github.com/npm/npm/issues/10629) - `write-file-atomic@1.1.4` - ([@othiym23](https://github.com/othiym23)) -* [`8347a30`](https://github.com/npm/npm/commit/8347a308ef0d2cf0f58f96bba3635af642ec611f) - [#10629](https://github.com/npm/npm/issues/10629) - `fs-write-stream-atomic@1.0.5` - ([@othiym23](https://github.com/othiym23)) - -#### DEPENDENCY UPDATES - -* [`9e2a2bb`](https://github.com/npm/npm/commit/9e2a2bb5bc71a0ab3b3637e8eec212aa22d5c99f) - [nodejs/node-gyp#831](https://github.com/nodejs/node-gyp/pull/831) - `node-gyp@3.2.1`: - Improved \*BSD support. - ([@bnoordhuis](https://github.com/bnoordhuis)) - -### v3.5.1 (2015-11-25): - -#### THE npm CLI !== THE npm REGISTRY !== npm, INC. - -npm-the-CLI is licensed under the terms of the [Artistic License -2.0](https://github.com/npm/npm/blob/8d79c1a39dae908f27eaa37ff6b23515d505ef29/LICENSE), -which is a liberal open-source license that allows you to take this code and do -pretty much whatever you like with it (that is, of course, not legal language, -and if you're doing anything with npm that leaves you in doubt about your legal -rights, please seek the review of qualified counsel, which is to say, not -members of the CLI team, none of whom have passed the bar, to my knowledge). At -the same time the primary registry the CLI uses when looking up and downloading -packages is a commercial service run by npm, Inc., and it has its own [Terms of -Use](https://www.npmjs.com/policies/terms). - -Aside from clarifying the terms of use (and trying to make sure they're more -widely known), the only recent changes to npm's licenses have been making the -split between the CLI and registry clearer. You are still free to do whatever -you like with the CLI's source, and you are free to view, download, and publish -packages to and from `registry.npmjs.org`, but now the existing terms under -which you can do so are more clearly documented. Aside from the two commits -below, see also [the release notes for -`npm@3.4.1`](https://github.com/npm/npm/releases/tag/v3.4.1), which is where -the split between the CLI's code and the terms of use for the registry was -first made more clear. - -* [`35a5dd5`](https://github.com/npm/npm/commit/35a5dd5abbfeec4f98a2b4534ec4ef5d16760581) - [#10532](https://github.com/npm/npm/issues/10532) Clarify that - `registry.npmjs.org` is the default, but that you're free to use the npm CLI - with whatever registry you wish. ([@kemitchell](https://github.com/kemitchell)) -* [`fa6b013`](https://github.com/npm/npm/commit/fa6b0136a0e4a19d8979b2013622e5ff3f0446f8) - [#10532](https://github.com/npm/npm/issues/10532) Having semi-duplicate - release information in `README.md` was confusing and potentially inaccurate, - so remove it. ([@kemitchell](https://github.com/kemitchell)) - -#### EASE UP ON WINDOWS BASH USERS - -It turns out that a fair number of us use bash on Windows (through MINGW or -bundled with Git, plz – Cygwin is still a bridge too far, for both npm and -Node.js). [@jakub-g](https://github.com/jakub-g) did us all a favor and relaxed -the check for npm completion to support MINGW bash. Thanks, Jakub! - -* [`09498e4`](https://github.com/npm/npm/commit/09498e45c5c9e683f092ab1372670f81db4762b6) - [#10156](https://github.com/npm/npm/issues/10156) completion: enable on - Windows in git bash ([@jakub-g](https://github.com/jakub-g)) - -#### THE ONGOING SAGA OF BUNDLED DEPENDENCIES - -`npm@3.5.0` fixed up a serious issue with how `npm@3.4.1` (and potentially -`npm@3.4.0` and `npm@3.3.12`) handled the case in which dependencies bundled -into a package tarball are handled improperly when one or more of their own -dependencies are older than what's latest on the registry. Unfortunately, in -fixing that (quite severe) regression (see [`npm@3.5.0`'s release notes' for -details](https://github.com/npm/npm/releases/tag/v3.5.0)), we introduced a new -(small, and fortunately cosmetic) issue where npm superfluously warns you about -bundled dependencies being stale. We have now fixed that, and hope that we -haven't introduced any _other_ regressions in the process. :D - -* [`20824a7`](https://github.com/npm/npm/commit/20824a75bf7639fb0951a588e3c017a370ae6ec2) - [#10501](https://github.com/npm/npm/issues/10501) Only warn about replacing - bundled dependencies when actually doing so. ([@iarna](https://github.com/iarna)) - -#### MAKE NODE-GYP A LITTLE BLUER - -* [`1d14d88`](https://github.com/npm/npm/commit/1d14d882c3b5af0a7fee46e8e0e343d07e4c38cb) - `node-gyp@3.2.0`: Support AIX, use `which` to find Python, updated to a newer - version of `gyp`, and more! ([@bnoordhuis](https://github.com/bnoordhuis)) - -#### A BOUNTEOUS THANKSGIVING CORNUCOPIA OF DOC TWEAKS - -These are great! Keep them coming! Sorry for letting them pile up so deep, -everybody. Also, a belated Thanksgiving to our Canadian friends, and a happy -Thanksgiving to all our friends in the USA. - -* [`4659f1c`](https://github.com/npm/npm/commit/4659f1c5ad617c46a5e89b48abf0b1c4e6f04307) - [#10244](https://github.com/npm/npm/issues/10244) In `npm@3`, `npm dedupe` - doesn't take any arguments, so update documentation to reflect that. - ([@bengotow](https://github.com/bengotow)) -* [`625a7ee`](https://github.com/npm/npm/commit/625a7ee6b4391e90cb28a95f20a73fd794e1eebe) - [#10250](https://github.com/npm/npm/issues/10250) Correct order of `org:team` - in `npm team` documentation. ([@louislarry](https://github.com/louislarry)) -* [`bea7f87`](https://github.com/npm/npm/commit/bea7f87399d784e3a6d3393afcca658a61a40d77) - [#10371](https://github.com/npm/npm/issues/10371) Remove broken / duplicate - link to tag. ([@WickyNilliams](https://github.com/WickyNilliams)) -* [`0a25e29`](https://github.com/npm/npm/commit/0a25e2956e9ddd4065d6bd929559321afc512fde) - [#10419](https://github.com/npm/npm/issues/10419) Remove references to - nonexistent `npm-rm(1)` documentation. ([@KenanY](https://github.com/KenanY)) -* [`19b94e1`](https://github.com/npm/npm/commit/19b94e1e6781fe2f98ada0a3f49a1bda25e3e32d) - [#10474](https://github.com/npm/npm/issues/10474) Clarify that install finds - dependencies in `package.json`. ([@sleekweasel](https://github.com/sleekweasel)) -* [`b25efc8`](https://github.com/npm/npm/commit/b25efc88067c843ffdda86ea0f50f95d136a638e) - [#9948](https://github.com/npm/npm/issues/9948) Encourage users to file an - issue, rather than emailing authors. ([@trodrigues](https://github.com/trodrigues)) -* [`24f4ced`](https://github.com/npm/npm/commit/24f4cedc83b10061f26362bf2f005ab935e0cbfe) - [#10497](https://github.com/npm/npm/issues/10497) Clarify what a package is - slightly. ([@aredridel](https://github.com/aredridel)) -* [`e8168d4`](https://github.com/npm/npm/commit/e8168d40caae00b2914ea09dbe4bd1b09ba3dcd5) - [#10539](https://github.com/npm/npm/issues/10539) Remove an extra, spuriously - capitalized letter. ([@alexlukin-softgrad](https://github.com/alexlukin-softgrad)) - -### v3.5.0 (2015-11-19): - -#### TEEN ORCS AT THE GATES - -This week heralds the general release of the primary npm registry's [new -support for private packages for -organizations](http://blog.npmjs.org/post/133542170540/private-packages-for-organizations). -For many potential users, it's the missing piece needed to make it easy for you -to move your organization's private work onto npm. And now it's here! The -functionality to support it has been in place in the CLI for a while now, -thanks to [@zkat](https://github.com/zkat)'s hard work. - -During our final testing before the release, our ace support team member -[@snopeks](https://github.com/snopeks) noticed that there had been some drift -between the CLI team's implementation and what npm was actually preparing to -ship. In the interests of everyone having a smooth experience with this -_extremely useful_ new feature, we quickly made a few changes to square up the -CLI and the web site experiences. - -* [`d7fb92d`](https://github.com/npm/npm/commit/d7fb92d1c53ba5196ad6dd2101a06792a4c0412b) - [#9327](https://github.com/npm/npm/issues/9327) `npm access` no longer has - problems when run in a directory that doesn't contain a `package.json`. - ([@othiym23](https://github.com/othiym23)) -* [`17df3b5`](https://github.com/npm/npm/commit/17df3b5d5dffb2e9c223b9cfa2d5fd78c39492a4) - [npm/npm-registry-client#126](https://github.com/npm/npm-registry-client/issues/126) - `npm-registry-client@7.0.8`: Allow the CLI to grant, revoke, and list - permissions on unscoped (public) packages on the primary registry. - ([@othiym23](https://github.com/othiym23)) - -#### NON-OPTIONAL INSTALLS, DEFINITELY NON-OPTIONAL - -* [`180263b`](https://github.com/npm/npm/commit/180263b) - [#10465](https://github.com/npm/npm/pull/10465) - When a non-optional dep fails, we check to see if it's only required by - ONLY optional dependencies. If it is, we make it fail all the deps in - that chain (and roll them back). If it isn't then we give an error. - - We do this by walking up through all of our ancestors until we either hit an - optional dependency or the top of the tree. If we hit the top, we know to - give the error. - - If you installed a module by hand but didn't `--save` it, your module - won't have the top of the tree as an anscestor and so this code was - failing to abort the install with an error - - This updates the logic so that hitting the top OR a module that was - requested by the user will trigger the error message. - ([@iarna](https://github.com/iarna)) - -* [`b726a0e`](https://github.com/npm/npm/commit/b726a0e) - [#9204](https://github.com/npm/npm/issues/9204) - Ideally we would like warnings about your install to come AFTER the - output from your compile steps or the giant tree of installed modules. - - To that end, we've moved warnings about failed optional deps to the show - after your install completes. - ([@iarna](https://github.com/iarna)) - -#### OVERRIDING BUNDLING - -* [`aed71fb`](https://github.com/npm/npm/commit/aed71fb) - [#10482](https://github.com/npm/npm/issues/10482) - We've been in our bundled modules code a lot lately, and our last go at - this introduced a new bug, where if you had a module `a` that bundled - a module `b`, which in turn required `c`, and the version of `c` that - got bundled wasn't compatible with `b`'s `package.json`, we would then - install a compatible version of `c`, but also erase `b` at the same time. - - This fixes that. It also reworks our bundled module support to be much - closer to being in line with how we handle non-bundled modules and we're - hopeful this will reduce any future errors around them. The new structure - is hopefully much easier to reason about anyway. - ([@iarna](https://github.com/iarna)) - -#### A BRIEF NOTE ON NPM'S BACKWARDS COMPATIBILITY - -We don't often have much to say about the changes we make to our internal -testing and tooling, but I'm going to take this opportunity to reiterate that -npm tries hard to maintain compatibility with a wide variety of Node versions. -As this change shows, we want to ensure that npm works the same across: - -* Node.js 0.8 -* Node.js 0.10 -* Node.js 0.12 -* the latest io.js release -* Node.js 4 LTS -* Node.js 5 - -Contributors who send us pull requests often notice that it's very rare that -our tests pass across all of those versions (ironically, almost entirely due to -the packages we use for testing instead of any issues within npm itself). We're -currently beginning an effort, lasting the rest of 2015, to clean up our test -suite, and not only get it passing on all of the above versions of Node.js, but -working solidly on Windows as well. This is a compounding form of technical -debt that we're finally paying down, and our hope is that cleaning up the tests -will produce a more robust CLI that's a lot easier to write patches for. - -* [`791ec6b`](https://github.com/npm/npm/commit/791ec6b1bac0d1df59f5ebb4ccd16a29a5dc73f0) - [#10233](https://github.com/npm/npm/issues/10233) Update Node.js versions - that Travis uses to test npm. ([@iarna](https://github.com/iarna)) - -#### 0.8 + npm <1.4 COMPATIBLE? SURE WHY NOT - -Hey, you found the feature we added! - -* [`231c58a`](https://github.com/npm/npm/commit/231c58a) - [#10337](https://github.com/npm/npm/pull/10337) - Add two new flags, first `--legacy-bundling` which installs your - dependencies such that if you bundle those dependencies, npm versions - prior to `1.4` can still install them. This eliminates all automatic - deduping. - - Second, `--global-style` which will install modules in your `node_modules` - folder with the same layout as global modules. Only your direct - dependencies will show in `node_modules` and everything they depend on - will be flattened in their `node_modules` folders. This obviously will - eliminate some deduping. - ([@iarna](https://github.com/iarna)) - -#### TYPOS IN THE LICENSE, OH MY - -* [`8d79c1a`](https://github.com/npm/npm/commit/8d79c1a39dae908f27eaa37ff6b23515d505ef29) - [#10478](https://github.com/npm/npm/issues/10478) Correct two typos in npm's - LICENSE. ([@jorrit](https://github.com/jorrit)) - -### v3.4.1 (2015-11-12): - -#### ASK FOR NOTHING, GET LATEST - -When you run `npm install foo`, you probably expect that you'll get the -`latest` version of `foo`, whatever that is. And good news! That's what -this change makes it do. - -We _think_ this is what everyone wants, but if this causes problems for -you, we want to know! If it proves problematic for people we will consider -reverting it (preferably before this becomes `npm@latest`). - -Previously, when you ran `npm install foo` we would act as if you typed -`npm install foo@*`. Now, like any range-type specifier, in addition to -matching the range, it would also have to be `<=` the value of the -`latest` dist-tag. Further, it would exclude prerelease versions from the -list of versions considered for a match. - -This worked as expected most of the time, unless your `latest` was a -prerelease version, in which case that version wouldn't be used, to -everyone's surprise. Worse, if all your versions were prerelease versions -it would just refuse to install anything. (We fixed that in -[`npm@3.2.2`](https://github.com/npm/npm/releases/tag/v3.2.2) with -[`e4a38080`](https://github.com/npm/npm/commit/e4a38080).) - -* [`1e834c2`](https://github.com/npm/npm/commit/1e834c2) - [#10189](https://github.com/npm/npm/issues/10189) - `npm-package-arg@4.1.0` Change the default version from `*` to `latest`. - ([@zkat](https://github.com/zkat)) - -#### BUGS - -* [`bec4a84`](https://github.com/npm/npm/commit/bec4a84) - [#10338](https://github.com/npm/npm/pull/10338) - Failed installs could result in more rollback (removal of just installed - packages) than we intended. This bug was first introduced by - [`83975520`](https://github.com/npm/npm/commit/83975520). - ([@iarna](https://github.com/iarna)) -* [`06c732f`](https://github.com/npm/npm/commit/06c732f) - [#10338](https://github.com/npm/npm/pull/10338) - Updating a module could result in the module stealing some of its - dependencies from the top level, potentially breaking other modules or - resulting in many redundant installations. This bug was first introduced - by [`971fd47a`](https://github.com/npm/npm/commit/971fd47a). - ([@iarna](https://github.com/iarna)) -* [`5653366`](https://github.com/npm/npm/commit/5653366) - [#9980](https://github.com/npm/npm/issues/9980) - npm, when removing a module, would refuse to remove the symlinked - binaries if the module itself was symlinked as well. npm goes to some - effort to ensure that it doesn't remove things that aren't is, and this - code was being too conservative. This code has been rewritten to be - easier to follow and to be unit-testable. - ([@iarna](https://github.com/iarna)) - -#### LICENSE CLARIFICATION - -* [`80acf20`](https://github.com/npm/npm/commit/80acf20) - [#10326](https://github.com/npm/npm/pull/10326) - Update npm's licensing to more completely cover all of the various - things that are npm. - ([@kemitchell](https://github.com/kemitchell)) - -#### CLOSER TO GREEN TRAVIS - -* [`fc12da9`](https://github.com/npm/npm/commit/fc12da9) - [#10232](https://github.com/npm/npm/pull/10232) - `nock@1.9.0` - Downgrade nock to a version that doesn't depend on streams2 in core so - that more of our tests can pass in 0.8. - ([@iarna](https://github.com/iarna)) - -### v3.4.0 (2015-11-05): - -#### A NEW FEATURE - -This was a group effort, with [@isaacs](https://github.com/isaacs) -dropping the implementation in back in August. Then, a few days ago, -[@ashleygwilliams](https://github.com/ashleygwilliams) wrote up docs and -just today [@othiym23](https://github.com/othiym23) wrote a test. - -It's a handy shortcut to update a dependency and then make sure tests -still pass. - -This new command: - -``` -npm install-test x -``` - -is the equivalent of running: - -``` -npm install x && npm test -``` - -* [`1ac3e08`](https://github.com/npm/npm/commit/1ac3e08) - [`bcb04f6`](https://github.com/npm/npm/commit/bcb04f6) - [`b6c17dd`](https://github.com/npm/npm/commit/b6c17dd) - [#9443](https://github.com/npm/npm/pull/9443) - Add `npm install-test` command, alias `npm it`. - ([@isaacs](https://github.com/isaacs), - [@ashleygwilliams](https://github.com/ashleygwilliams), - [@othiym23](https://github.com/othiym23)) - -#### BUG FIXES VIA DEPENDENCY UPDATES - -* [`31c0080`](https://github.com/npm/npm/commit/31c0080) - [#8640](https://github.com/npm/npm/issues/8640) - [npm/normalize-package-data#69](https://github.com/npm/normalize-package-data/pull/69) - `normalize-package-data@2.3.5`: - Fix a bug where if you didn't specify the name of a scoped module's - binary, it would install it such that it was impossible to call it. - ([@iarna](https://github.com/iarna)) -* [`02b37bc`](https://github.com/npm/npm/commit/02b37bc) - [npm/fstream-npm#14](https://github.com/npm/fstream-npm/pull/14) - `fstream-npm@1.0.7`: - Only filter `config.gypi` when it's in the build directory. - ([@mscdex](https://github.com/mscdex)) -* [`accb9d2`](https://github.com/npm/npm/commit/accb9d2) - [npm/fstream-npm#15](https://github.com/npm/fstream-npm/pull/15) - `fstream-npm@1.0.6`: - Stop including directories that happened to have names matching whitelisted - npm files in npm module tarballs. The most common cause was that if you had - a README directory then everything in it would be included if wanted it - or not. - ([@taion](https://github.com/taion)) - -#### DOCUMENTATION FIXES - -* [`7cf6366`](https://github.com/npm/npm/commit/7cf6366) - [#10036](https://github.com/npm/npm/pull/10036) - Fix typo / over-abbreviation. - ([@ifdattic](https://github.com/ifdattic)) -* [`d0ad8f4`](https://github.com/npm/npm/commit/d0ad8f4) - [#10176](https://github.com/npm/npm/pull/10176) - Fix broken link, scopes => scope. - ([@ashleygwilliams](https://github.com/ashleygwilliams)) -* [`d623783`](https://github.com/npm/npm/commit/d623783) - [#9460](https://github.com/npm/npm/issue/9460) - Specifying the default command run by "npm start" and the - fact that you can pass it arguments. - ([@JuanCaicedo](https://github.com/JuanCaicedo)) - -#### DEPENDENCY UPDATES FOR THEIR OWN SAKE - -* [`0a4c29e`](https://github.com/npm/npm/commit/0a4c29e) - [npm/npmlog#19](https://github.com/npm/npmlog/pull/19) - `npmlog@2.0.0`: Make it possible to emit log messages with `error` as the - prefix. - ([@bengl](https://github.com/bengl)) -* [`9463ce9`](https://github.com/npm/npm/commit/9463ce9) - `read-package-json@2.0.2`: - Minor cleanups. - ([@KenanY](https://github.com/KenanY)) - -### v3.3.12 (2015-11-02): - -Hi, a little hot-fix release for a bug introduced in 3.3.11. The ENOENT fix -last week ([`f0e2088`](https://github.com/npm/npm/commit/f0e2088)) broke -upgrades of modules that have bundled dependencies (like `npm`, augh!) - -* [`aedf7cf`](https://github.com/npm/npm/commit/aedf7cf) - [#10192](//github.com/npm/npm/pull/10192) - If a bundled module is going to be replacing a module that's currently on - disk (for instance, when you upgrade a module that includes bundled - dependencies) we want to select the version from the bundle in preference - over the one that was there previously. - ([@iarna](https://github.com/iarna)) - -### v3.3.11 (2015-10-29): - -This is a dependency update week, so that means no PRs from our lovely -users. Look for those next week. As it happens, the dependencies updated -were just devdeps, so nothing for you all to worry about. - -But the bug fixes, oh geez, I tracked down some really long standing stuff -this week!! The headliner is those intermittent `ENOENT` errors that no one -could reproduce consistently? I think they're nailed! But also pretty -important, the bug where `hapi` would install w/ a dep missing? Squashed! - -#### EEEEEEENOENT - -* [`f0e2088`](https://github.com/npm/npm/commit/f0e2088) - [#10026](https://github.com/npm/npm/issues/10026) - Eliminate some, if not many, of the `ENOENT` errors `npm@3` has seen over - the past few months. This was happening when npm would, in its own mind, - correct a bundled dependency, due to a `package.json` specifying an - incompatible version. Then, when npm extracted the bundled version, what - was on disk didn't match its mind and… well, when it tried to act on what - was in its mind, we got an `ENOENT` because it didn't actually exist on - disk. - ([@iarna](https://github.com/iarna)) - -#### PARTIAL SHRINKWRAPS, NO LONGER A BAD DAY - -* [`712fd9c`](https://github.com/npm/npm/commit/712fd9c) - [#10153](https://github.com/npm/npm/pull/10153) - Imagine that you have a module, let's call it `fun-time`, and it depends - on two dependencies, `need-fun@1` and `need-time`. Further, `need-time` - requires `need-fun@2`. So after install the logical tree will look like - this: - - ``` - fun-time - ├── need-fun@1 - └── need-time - └── need-fun@2 - ``` - - Now, the `fun-time` author also distributes a shrinkwrap, but it only includes - the `need-fun@1` in it. - - Resolving dependencies would look something like this: - - 1. Require `need-fun@1`: Use version from shrinkwrap (ignoring version) - 2. Require `need-time`: User version in package.json - 1. Require `need-fun@2`: Use version from shrinkwrap, which oh hey, is - already installed at the top level, so no further action is needed. - - Which results in this tree: - - ``` - fun-time - ├── need-fun@1 - └── need-time - ``` - - We're ignoring the version check on things specified in the shrinkwrap - so that you can override the version that will be installed. This is - because you may want to use a different version than is specified - by your dependencies' dependencies' `package.json` files. - - To fix this, we now only allow overrides of a dependency version when - that dependency is a child (in the tree) of the thing that requires it. - This means that when we're looking for `need-fun@2` we'll see `need-fun@1` - and reject it because, although it's from a shrinkwrap, it's parent is - `fun-time` and the package doing the requiring is `need-time`. - - ([@iarna](https://github.com/iarna)) - -#### STRING `package.bin` AND NON-NPMJS REGISTRIES - -* [`3de1463`](https://github.com/npm/npm/commit/3de1463) - [#9187](https://github.com/npm/npm/issues/9187) - If you were using a module with the `bin` field in your `package.json` set - to a string on a non-npmjs registry then npm would crash, due to the our - expectation that the `bin` field would be an object. We now pass all - `package.json` data through a routine that normalizes the format, - including the `bin` field. (This is the same routine that your - `package.json` is passed through when read off of disk or sent to the - registry for publication.) Doing this also ensures that older modules on - npm's own registry will be treated exactly the same as new ones. (In the - past we weren't always super careful about scrubbing `package.json` data - on publish. And even when we were, those rules have subtly changed over - time.) - ([@iarna](https://github.com/iarna)) - -### v3.3.10 (2015-10-22): - -Hey you all! Welcome to a busy bug fix and PR week. We've got changes -to how `npm install` replaces dependencies during updates, improvements -to shrinkwrap behavior, and all sorts of doc updates. - -In other news, `npm@3` landed in node master in preparation for `node@5` -with [`41923c0`](https://github.com/nodejs/node/commit/41923c0). - -#### UPDATED DEPS NOW MAKE MORE SENSE - -* [`971fd47`](https://github.com/npm/npm/commit/971fd47) - [#9929](https://github.com/npm/npm/pull/9929) - Make the tree more consistent by doing updates in place. This means - that trees after a dependency version update will more often look - the same as after a fresh install. - ([@iarna](https://github.com/iarna)) - -#### SHRINKWRAP + DEV DEPS NOW RESPECTED - -* [`eb28a8c`](https://github.com/npm/npm/commit/eb28a8c) - [#9647](https://github.com/npm/npm/issues/9647) - If a shrinkwrap already has dev deps, don't throw them away when - someone later runs `npm install --save`. - ([@iarna](https://github.com/iarna)) - -#### FANTASTIC DOCUMENTATION UPDATES - -* [`291162c`](https://github.com/npm/npm/commit/291162c) - [#10021](https://github.com/npm/npm/pull/10021) - Improve wording in the FAQ to be more empathetic and less jokey. - ([@TaMe3971](https://github.com/TaMe3971)) -* [`9a28c54`](https://github.com/npm/npm/commit/9a28c54) - [#10020](https://github.com/npm/npm/pull/10020) - Document the command to see the list of config defaults in the section - on config defaults. - ([@lady3bean](https://github.com/lady3bean)) -* [`8770b0a`](https://github.com/npm/npm/commit/8770b0a) - [#7600](https://github.com/npm/npm/issues/7600) - Add shortcuts to all command documentation. - ([@RichardLitt](https://github.com/RichardLitt)) -* [`e9b7d0d`](https://github.com/npm/npm/commit/e9b7d0d) - [#9950](https://github.com/npm/npm/pull/9950) - On errors that can be caused by outdated node & npm, suggest updating - as a part of the error message. - ([@ForbesLindesay](https://github.com/ForbesLindesay)) - -#### NEW STANDARD HAS ALWAYS BEEN STANDARD - -* [`40c1b0f`](https://github.com/npm/npm/commit/40c1b0f) - [#9954](https://github.com/npm/npm/pull/9954) - Update to `standard@5` and reformat the source to work with it. - ([@cbas](https://github.com/cbas)) - -### v3.3.9 (2015-10-15): - -This week sees a few small changes ready to land: - -#### TRAVIS NODE 0.8 BUILDS REJOICE - -* [`25a234b`](https://github.com/npm/npm/commit/25a234b) - [#9668](https://github.com/npm/npm/issues/9668) - Install `npm@3`'s bundled dependencies with `npm@2`, so that the ancient npm - that ships with node 0.8 can install `npm@3` directly. - ([@othiym23](https://github.com/othiym23)) - -#### SMALL ERROR MESSAGE IMPROVEMENT - -* [`a332f61`](https://github.com/npm/npm/commit/a332f61) - [#9927](https://github.com/npm/npm/pull/9927) - Update error messages where we report a list of versions that you could - have installed to show this as a comma separated list instead of as JSON. - ([@iarna](https://github.com/iarna)) - -#### DEPENDENCY UPDATES - -* [`4cd74b0`](https://github.com/npm/npm/commit/4cd74b0) - `nock@2.15.0` - ([@pgte](https://github.com/pgte)) -* [`9360976`](https://github.com/npm/npm/commit/9360976) - `tap@2.1.1` - ([@isaacs](https://github.com/isaacs)) -* [`1ead0a4`](https://github.com/npm/npm/commit/1ead0a4) - `which@1.2.0` - ([@isaacs](https://github.com/isaacs)) -* [`759f88a`](https://github.com/npm/npm/commit/759f88a) - `has-unicode@1.0.1` - ([@iarna](https://github.com/iarna)) - -### v3.3.8 (2015-10-12): - -This is a small update release, we're reverting -[`22a3af0`](https://github.com/npm/npm/commit/22a3af0) from last week's -release, as it is resulting in crashes. We'll revisit this PR during this -week. - -* [`ddde1d5`](https://github.com/npm/npm/commit/ddde1d5) - Revert "lifecycle: Swap out custom logic with add-to-path module" - ([@iarna](https://github.com/iarna)) - -### v3.3.7 (2015-10-08): - -So, as Kat mentioned in last week's 2.x release, we're now swapping weeks -between accepting PRs and doing dependency updates, in an effort to keep -release management work from taking over our lives. This week is a PR week, -so we've got a bunch of goodies for you. - -Relatedly, this week means 3.3.6 is now `latest` and it is WAY faster than -previous 3.x releases. Give it or this a look! - -#### OPTIONAL DEPS, MORE OPTIONAL - -* [`2289234`](https://github.com/npm/npm/commit/2289234) - [#9643](https://github.com/npm/npm/issues/9643) - [#9664](https://github.com/npm/npm/issues/9664) - `npm@3` was triggering `npm@2`'s build mechanics when it was linking bin files - into the tree. This was originally intended to trigger rebuilds of - bundled modules, but `npm@3`'s flat module structure confused it. This - caused two seemingly unrelated issues. First, failing optional - dependencies could under some circumstances (if they were built during - this phase) trigger a full build failure. And second, rebuilds were being - triggered of already installed modules, again, in some circumstances. - Both of these are fixed by disabling the `npm@2` mechanics and adding a - special rebuild phase for the initial installation of bundled modules. - ([@iarna](https://github.com/iarna)) - -#### BAD NAME, NO CRASH - -* [`b78fec9`](https://github.com/npm/npm/commit/b78fec9) - [#9766](https://github.com/npm/npm/issues/9766) - Refactor all attempts to read the module name or package name to go via a - single function, with appropriate guards unusual circumstances where they - aren't where we expect them. This ultimately will ensure we don't see any - more recurrences of the `localeCompare` error and related crashers. - ([@iarna](https://github.com/iarna)) - -#### MISCELLANEOUS BUG FIXES - -* [`22a3af0`](https://github.com/npm/npm/commit/22a3af0) - [#9553](https://github.com/npm/npm/pull/9553) - Factor the lifecycle code to manage paths out into its own module and use that. - ([@kentcdodds](https://github.com/kentcdodds)) -* [`6a29fe3`](https://github.com/npm/npm/commit/6a29fe3) - [#9677](https://github.com/npm/npm/pull/9677) - Start testing our stuff in node 4 on travis - ([@fscherwi](https://github.com/fscherwi)) -* [`508c6a4`](https://github.com/npm/npm/commit/508c6a4) - [#9669](https://github.com/npm/npm/issues/9669) - Make `recalculateMetadata` more resilient to unexpectedly bogus dependency specifiers. - ([@tmct](https://github.com/tmct)) -* [`3c44763`](https://github.com/npm/npm/commit/3c44763) - [#9643](https://github.com/npm/npm/issues/9463) - Update `install --only` to ignore the `NODE_ENV` var and _just_ use the only - value, if specified. - ([@watilde](https://github.com/watilde)) -* [`87336c3`](https://github.com/npm/npm/commit/87336c3) - [#9879](https://github.com/npm/npm/pull/9879) - `npm@3`'s shrinkwrap was refusing to shrinkwrap if an optional dependency - was missing– patch it to allow this. - ([@mantoni](https://github.com/mantoni)) - -#### DOCUMENTATION UPDATES - -* [`82659fd`](https://github.com/npm/npm/commit/82659fd) - [#9208](https://github.com/npm/npm/issues/9208) - Correct the npm style guide around quote usage - ([@aaroncrows](https://github.com/aaroncrows)) -* [`a69c83a`](https://github.com/npm/npm/commit/a69c83a) - [#9645](https://github.com/npm/npm/pull/9645) - Fix spelling error in README - ([@dkoleary88](https://github.com/dkoleary88)) -* [`f2cf054`](https://github.com/npm/npm/commit/f2cf054) - [#9714](https://github.com/npm/npm/pull/9714) - Fix typos in our documentation - ([@reggi](https://github.com/reggi)) -* [`7224bef`](https://github.com/npm/npm/commit/7224bef) - [#9759](https://github.com/npm/npm/pull/9759) - Fix typo in npm-team docs - ([@zkat](https://github.com/zkat)) -* [`7e6e007`](https://github.com/npm/npm/commit/7e6e007) - [#9820](https://github.com/npm/npm/pull/9820) - Correct documentation as to `binding.gyp` - ([@KenanY](https://github.com/KenanY)) - -### v3.3.6 (2015-09-30): - -I have the most exciting news for you this week. YOU HAVE NO IDEA. Well, -ok, maybe you do if you follow my twitter. - -Performance just got 5 bazillion times better (under some circumstances, -ymmv, etc). So– my test scenario is our very own website. In `npm@2`, on my -macbook running `npm ls` takes about 5 seconds. Personally it's more than -I'd like, but it's entire workable. In `npm@3` it has been taking _50_ seconds, -which is appalling. But after doing some work on Monday isolating the performance -issues I've been able to reduce `npm@3`'s run time back down to 5 seconds. - -Other scenarios were even worse, there was one that until now in `npm@3` that -took almost 6 minutes, and has been reduced to 14 seconds. - -* [`7bc0d4c`](https://github.com/npm/npm/commit/7bc0d4c) - [`cf42217`](https://github.com/npm/npm/commit/cf42217) - [#8826](https://github.com/npm/npm/issues/8826) - Stop using deepclone on super big datastructures. Avoid cloning - all-together even when that means mutating things, when possible. - Otherwise use a custom written tree-copying function that understands - the underlying datastructure well enough to only copy what we absolutely - need to. - ([@iarna](https://github.com/iarna)) - -In other news, look for us this Friday and Saturday at the amazing -[Open Source and Feelings](https://osfeels.com) conference, where something like a -third of the company will be attending. - -#### And finally a dependency update - -* [`a6a4437`](https://github.com/npm/npm/commit/a6a4437) - `glob@5.0.15` - ([@isaacs](https://github.com/isaacs)) - -#### And some subdep updates - -* [`cc5e6a0`](https://github.com/npm/npm/commit/cc5e6a0) - `hoek@2.16.3` - ([@nlf](https://github.com/nlf)) -* [`912a516`](https://github.com/npm/npm/commit/912a516) - `boom@2.9.0` - ([@arb](https://github.com/arb)) -* [`63944e9`](https://github.com/npm/npm/commit/63944e9) - `bluebird@2.10.1` - ([@petkaantonov](https://github.com/petkaantonov)) -* [`ef16003`](https://github.com/npm/npm/commit/ef16003) - `mime-types@2.1.7` & `mime-db@1.19.0` - ([@dougwilson](https://github.com/dougwilson)) -* [`2b8c0dd`](https://github.com/npm/npm/commit/2b8c0dd) - `request@2.64.0` - ([@simov](https://github.com/simov)) -* [`8139124`](https://github.com/npm/npm/commit/8139124) - `brace-expansion@1.1.1` - ([@juliangruber](https://github.com/juliangruber)) - -### v3.3.5 (2015-09-24): - -Some of you all may not be aware, but npm is ALSO a company. I tell you this -'cause npm-the-company had an all-staff get together this week, flying in -our remote folks from around the world. That was great, but it also -basically eliminated normal work on Monday and Tuesday. - -Still, we've got a couple of really important bug fixes this week. Plus a -lil bit from the [now LTS 2.x branch](https://github.com/npm/npm/releases/tag/v2.14.6). - -#### ATTENTION WINDOWS USERS - -If you previously updated to npm 3 and you try to update again, you may get -an error messaging telling you that npm won't install npm into itself. Until you -are at 3.3.5 or greater, you can get around this with `npm install -f -g npm`. - -* [`bef06f5`](https://github.com/npm/npm/commit/bef06f5) - [#9741](https://github.com/npm/npm/pull/9741) Uh... so... er... it - seems that since `npm@3.2.0` on Windows with a default configuration, it's - been impossible to update npm. Well, that's not actually true, there's a - work around (see above), but it shouldn't be complaining in the first - place. - ([@iarna](https://github.com/iarna)) - -#### STACK OVERFLOWS ON PUBLISH - -* [`330b496`](https://github.com/npm/npm/commit/330b496) - [#9667](https://github.com/npm/npm/pull/9667) - We were keeping track of metadata about your project while packing the - tree in a way that resulted in this data being written to packed tar files - headers. When this metadata included cycles, it resulted in the the tar - file entering an infinite recursive loop and eventually crashing with a - stack overflow. - - I've patched this by keeping track of your metadata by closing over the - variables in question instead, and I've further restricted gathering and - tracking the metadata to times when it's actually needed. (Which is only - if you need bundled modules.) - ([@iarna](https://github.com/iarna)) - -#### LESS CRASHY ERROR MESSAGES ON BAD PACKAGES - -* [`829921f`](https://github.com/npm/npm/commit/829921f) - [#9741](https://github.com/npm/npm/pull/9741) - Packages with invalid names or versions were crashing the installer. These - are now captured and warned as was originally intended. - ([@iarna](https://github.com/iarna)) - -#### ONE DEPENDENCY UPDATE - -* [`963295c`](https://github.com/npm/npm/commit/963295c) - `npm-install-checks@2.0.1` - ([@iarna](https://github.com/iarna)) - -#### AND ONE SUBDEPENDENCY - -* [`448737d`](https://github.com/npm/npm/commit/448737d) - `request@2.63.0` - ([@simov](https://github.com/simov)) - -### v3.3.4 (2015-09-17): - -This is a relatively quiet release, bringing a few bug fixes and -some module updates, plus via the -[2.14.5 release](https://github.com/npm/npm/releases/tag/v2.14.5) -some forward compatibility fixes with versions of Node that -aren't yet released. - -#### NO BETA NOTICE THIS TIME!! - -But, EXCITING NEWS FRIENDS, this week marks the exit of `npm@3` -from beta. This means that the week of this release, -[v3.3.3](https://github.com/npm/npm/releases/tag/v3.3.3) will -become `latest` and this version (v3.3.4) will become `next`!! - -#### CRUFT FOR THE CRUFT GODS - -What I call "cruft", by which I mean, files sitting around in -your `node_modules` folder, will no longer produce warnings in -`npm ls` nor during `npm install`. This brings `npm@3`'s behavior -in line with `npm@2`. - -* [`a127801`](https://github.com/npm/npm/commit/a127801) - [#9285](https://github.com/npm/npm/pull/9586) - Stop warning about cruft in module directories. - ([@iarna](https://github.com/iarna)) - -#### BETTER ERROR MESSAGE - -* [`95ee92c`](https://github.com/npm/npm/commit/95ee92c) - [#9433](https://github.com/npm/npm/issues/9433) - Give better error messages for invalid URLs in the dependency - list. - ([@jamietre](https://github.com/jamietre)) - -#### MODULE UPDATES - -* [`ebb92ca`](https://github.com/npm/npm/commit/ebb92ca) - `retry@0.8.0` ([@tim-kos](https://github.com/tim-kos)) -* [`55f1285`](https://github.com/npm/npm/commit/55f1285) - `normalize-package-data@2.3.4` ([@zkat](https://github.com/zkat)) -* [`6d4ebff`](https://github.com/npm/npm/commit/6d4ebff) - `sha@2.0.1` ([@ForbesLindesay](https://github.com/ForbesLindesay)) -* [`09a9c7a`](https://github.com/npm/npm/commit/09a9c7a) - `semver@5.0.3` ([@isaacs](https://github.com/isaacs)) -* [`745000f`](https://github.com/npm/npm/commit/745000f) - `node-gyp@3.0.3` ([@rvagg](https://github.com/rvagg)) - -#### SUB DEP MODULE UPDATES - -* [`578ca25`](https://github.com/npm/npm/commit/578ca25) - `request@2.62.0` ([@simov](https://github.com/simov)) -* [`1d8996e`](https://github.com/npm/npm/commit/1d8996e) - `jju@1.2.1` ([@rlidwka](https://github.com/rlidwka)) -* [`6da1ba4`](https://github.com/npm/npm/commit/6da1ba4) - `hoek@2.16.2` ([@nlf](https://github.com/nlf)) - -### v3.3.3 (2015-09-10): - -This short week brought us brings us a few small bug fixes, a -doc change and a whole lotta dependency updates. - -Plus, as usual, this includes a forward port of everything in -[`npm@2.14.4`](https://github.com/npm/npm/releases/tag/v2.14.4). - -#### BETA BUT NOT FOREVER - -**_THIS IS BETA SOFTWARE_**. `npm@3` will remain in beta until -we're confident that it's stable and have assessed the effect of -the breaking changes on the community. During that time we will -still be doing `npm@2` releases, with `npm@2` tagged as `latest` -and `next`. We'll _also_ be publishing new releases of `npm@3` -as `npm@v3.x-next` and `npm@v3.x-latest` alongside those -versions until we're ready to switch everyone over to `npm@3`. -We need your help to find and fix its remaining bugs. It's a -significant rewrite, so we are _sure_ there still significant -bugs remaining. So do us a solid and deploy it in non-critical -CI environments and for day-to-day use, but maybe don't use it -for production maintenance or frontline continuous deployment -just yet. - -#### REMOVE INSTALLED BINARIES ON WINDOWS - -So waaaay back at the start of August, I fixed a bug with -[#9198](https://github.com/npm/npm/pull/9198). That fix made it -so that if you had two modules installed that both installed the -same binary (eg `gulp` & `gulp-cli`), that removing one wouldn't -remove the binary if it was owned by the other. - -It did this by doing some hocus-pocus that, turns out, was -Unix-specific, so on Windows it just threw up its hands and -stopped removing installed binaries at all. Not great. - -So today we're fixing that– it let us maintain the same safety -that we added in #9198, but ALSO works with Windows. - -* [`25fbaed`](https://github.com/npm/npm/commit/25fbaed) - [#9394](https://github.com/npm/npm/issues/9394) - Treat cmd-shims the same way we treat symlinks - ([@iarna](https://github.com/iarna)) - -#### API DOCUMENTATION HAS BEEN SACRIFICED THE API GOD - -The documentation of the internal APIs of npm is going away, -because it would lead people into thinking they should integrate -with npm by using it. Please don't do that! In the future, we'd -like to give you a suite of stand alone modules that provide -better, more stand alone APIs for your applications to build on. -But for now, call the npm binary with `process.exec` or -`process.spawn` instead. - -* [`2fb60bf`](https://github.com/npm/npm/commit/2fb60bf) - Remove misleading API documentation - ([@othiym23](https://github.com/othiym23)) - -#### ALLOW `npm link` ON WINDOWS W/ PRERELEASE VERSIONS OF NODE - -We never meant to have this be a restriction in the first place -and it was only just discovered with the recent node 4.0.0 -release candidate. - -* [`6665e54`](https://github.com/npm/npm/commit/6665e54) - [#9505](https://github.com/npm/npm/pull/9505) - Allow npm link to run on Windows with prerelease versions of - node - ([@jon-hall](https://github.com/jon-hall)) - -#### graceful-fs update - -We're updating all of npm's deps to use the most recent -`graceful-fs`. This turns out to be important for future not yet -released versions of node, because older versions monkey-patch -`fs` in ways that will break in the future. Plus it ALSO makes -use of `process.binding` which is an internal API that npm -definitely shouldn't have been using. We're not done yet, but -this is the bulk of them. - -* [`e7bc98e`](https://github.com/npm/npm/commit/e7bc98e) - `write-file-atomic@1.1.3` - ([@iarna](https://github.com/iarna)) -* [`7417600`](https://github.com/npm/npm/commit/7417600) - `tar@2.2.1` - ([@zkat](https://github.com/zkat)) -* [`e4e9d40`](https://github.com/npm/npm/commit/e4e9d40) - `read-package-json@2.0.1` - ([@zkat](https://github.com/zkat)) -* [`481611d`](https://github.com/npm/npm/commit/481611d) - `read-installed@4.0.3` - ([@zkat](https://github.com/zkat)) -* [`0dabbda`](https://github.com/npm/npm/commit/0dabbda) - `npm-registry-client@7.0.4` - ([@zkat](https://github.com/zkat)) -* [`c075a91`](https://github.com/npm/npm/commit/c075a91) - `fstream@1.0.8` - ([@zkat](https://github.com/zkat)) -* [`2e4341a`](https://github.com/npm/npm/commit/2e4341a) - `fs-write-stream-atomic@1.0.4` - ([@zkat](https://github.com/zkat)) -* [`18ad16e`](https://github.com/npm/npm/commit/18ad16e) - `fs-vacuum@1.2.7` - ([@zkat](https://github.com/zkat)) - -#### DEPENDENCY UPDATES - -* [`9d6666b`](https://github.com/npm/npm/commit/9d6666b) - `node-gyp@3.0.1` - ([@rvagg](https://github.com/rvagg)) -* [`349c4df`](https://github.com/npm/npm/commit/349c4df) - `retry@0.7.0` - ([@tim-kos](https://github.com/tim-kos)) -* [`f507551`](https://github.com/npm/npm/commit/f507551) - `which@1.1.2` - ([@isaacs](https://github.com/isaacs)) -* [`e5b6743`](https://github.com/npm/npm/commit/e5b6743) - `nopt@3.0.4` - ([@zkat](https://github.com/zkat)) - -#### THE DEPENDENCIES OF OUR DEPENDENCIES ARE OUR DEPENDENCIES UPDATES - -* [`316382d`](https://github.com/npm/npm/commit/316382d) - `mime-types@2.1.6` & `mime-db@1.18.0` -* [`64b741e`](https://github.com/npm/npm/commit/64b741e) - `spdx-correct@1.0.1` -* [`fff62ac`](https://github.com/npm/npm/commit/fff62ac) - `process-nextick-args@1.0.3` -* [`9d6488c`](https://github.com/npm/npm/commit/9d6488c) - `cryptiles@2.0.5` -* [`1912012`](https://github.com/npm/npm/commit/1912012) - `bluebird@2.10.0` -* [`4d09402`](https://github.com/npm/npm/commit/4d09402) - `readdir-scoped-modules@1.0.2` - -### v3.3.2 (2015-09-04): - -#### PLEASE HOLD FOR THE NEXT AVAILABLE MAINTAINER - -This is a tiny little maintenance release, both to update dependencies and to -keep `npm@3` up to date with changes made to `npm@2`. -[@othiym23](https://github.com/othiym23) is putting out this release (again) as -his esteemed colleague [@iarna](https://github.com/iarna) finishes relocating -herself, her family, and her sizable anime collection all the way across North -America. It contains [all the goodies in -`npm@2.14.3`](https://github.com/npm/npm/releases/tag/v2.14.3) and one other -dependency update. - -#### BETA WARNINGS FOR FUN AND PROFIT - -**_THIS IS BETA SOFTWARE_**. `npm@3` will remain in beta until we're -confident that it's stable and have assessed the effect of the breaking -changes on the community. During that time we will still be doing `npm@2` -releases, with `npm@2` tagged as `latest` and `next`. We'll _also_ be -publishing new releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` -alongside those versions until we're ready to switch everyone over to -`npm@3`. We need your help to find and fix its remaining bugs. It's a -significant rewrite, so we are _sure_ there still significant bugs -remaining. So do us a solid and deploy it in non-critical CI environments -and for day-to-day use, but maybe don't use it for production maintenance or -frontline continuous deployment just yet. - -That said, it's getting there! It will be leaving beta very soon! - -#### ONE OTHER DEPENDENCY UPDATE - -* [`bb5de34`](https://github.com/npm/npm/commit/bb5de3493531228df0bd3f0742d5493c826be6dd) - `is-my-json-valid@2.12.2`: Upgrade to a new, modernized version of - `json-pointer`. ([@mafintosh](https://github.com/mafintosh)) - -### v3.3.1 (2015-08-27): - -Hi all, this `npm@3` update brings you another round of bug fixes. The -headliner here is that `npm update` works again. We're running down the -clock on blocker 3.x issues! Shortly after that hits zero we'll be -promoting 3.x to latest!! - -And of course, we have changes that were brought forward from 2.x. Check out -the release notes for -[2.14.1](https://github.com/npm/npm/releases/tag/v2.14.1) and -[2.14.2](https://github.com/npm/npm/releases/tag/v2.14.2). - -#### BETA WARNINGS FOR FUN AND PROFIT - -**_THIS IS BETA SOFTWARE_**. `npm@3` will remain in beta until we're -confident that it's stable and have assessed the effect of the breaking -changes on the community. During that time we will still be doing `npm@2` -releases, with `npm@2` tagged as `latest` and `next`. We'll _also_ be -publishing new releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` -alongside those versions until we're ready to switch everyone over to -`npm@3`. We need your help to find and fix its remaining bugs. It's a -significant rewrite, so we are _sure_ there still significant bugs -remaining. So do us a solid and deploy it in non-critical CI environments -and for day-to-day use, but maybe don't use it for production maintenance or -frontline continuous deployment just yet. - -#### NPM UPDATE, NOW AGAIN YOUR FRIEND - -* [`f130a00`](https://github.com/npm/npm/commit/f130a00) - [#9095](https://github.com/npm/npm/issues/9095) - `npm update` once again works! Previously, after selecting packages - to update, it would then pick the wrong location to run the install - from. ([@iarna](https://github.com/iarna)) - -#### MORE VERBOSING FOR YOUR VERBOSE LIFECYCLES - -* [`d088b7d`](https://github.com/npm/npm/commit/d088b7d) - [#9227](https://github.com/npm/npm/pull/9227) - Add some additional logging at the verbose and silly levels - when running lifecycle scripts. Hopefully this will make - debugging issues with them a bit easier! - ([@saper](https://github.com/saper)) - -#### AND SOME OTHER BUG FIXES… - -* [`f4a5784`](https://github.com/npm/npm/commit/f4a5784) - [#9308](https://github.com/npm/npm/issues/9308) - Make fetching metadata for local modules faster! This ALSO means - that doing things like running `npm repo` won't build your - module and maybe run `prepublish`. - ([@iarna](https://github.com/iarna)) - -* [`4468c92`](https://github.com/npm/npm/commit/4468c92) - [#9205](https://github.com/npm/npm/issues/9205) - Fix a bug where local modules would sometimes not resolve relative - links using the correct base path. - ([@iarna](https://github.com/iarna)) - -* [`d395a6b`](https://github.com/npm/npm/commit/d395a6b) - [#8995](https://github.com/npm/npm/issues/8995) - Certain combinations of packages could result in different install orders for their - initial installation than for reinstalls run on the same folder. - ([@iarna](https://github.com/iarna)) - -* [`d119ea6`](https://github.com/npm/npm/commit/d119ea6) - [#9113](https://github.com/npm/npm/issues/9113) - Make extraneous packages _always_ up in `npm ls`. Previously, if an - extraneous package had a dependency that depended back on the original - package this would result in the package not showing up in `ls`. - ([@iarna](https://github.com/iarna)) - -* [`02420dc`](https://github.com/npm/npm/commit/02420dc) - [#9113](https://github.com/npm/npm/issues/9113) - Stop warning about missing top level package.json files. Errors in said - files will still be reported. - ([@iarna](https://github.com/iarna)) - -#### SOME DEP UPDATES - -* [`1ed1364`](https://github.com/npm/npm/commit/1ed1364) `rimraf@2.4.3` - ([@isaacs](https://github.com/isaacs)) Added EPERM to delay/retry loop -* [`e7b8315`](https://github.com/npm/npm/commit/e7b8315) `read@1.0.7` - Smaller distribution package, better metadata - ([@isaacs](https://github.com/isaacs)) - -#### SOME DEPS OF DEPS UPDATES - -* [`b273bcc`](https://github.com/npm/npm/commit/b273bcc) `mime-types@2.1.5` -* [`df6e225`](https://github.com/npm/npm/commit/df6e225) `mime-db@1.17.0` -* [`785f2ad`](https://github.com/npm/npm/commit/785f2ad) `is-my-json-valid@2.12.1` -* [`88170dd`](https://github.com/npm/npm/commit/88170dd) `form-data@1.0.0-rc3` -* [`af5357b`](https://github.com/npm/npm/commit/af5357b) `request@2.61.0` -* [`337f96a`](https://github.com/npm/npm/commit/337f96a) `chalk@1.1.1` -* [`3dfd74d`](https://github.com/npm/npm/commit/3dfd74d) `async@1.4.2` - -### v3.3.0 (2015-08-13): - -This is a pretty EXCITING week. But I may be a little excitable– or -possibly sleep deprived, it's sometimes hard to tell them apart. =D So -[Kat](https://github.com/zkat) really went the extra mile this week and got -the client side support for teams and orgs out in this week's 2.x release. -You can't use that just yet, 'cause we have to turn on some server side -stuff too, but this way it'll be there for you all the moment we do! Check -out the details over in the [2.14.0 release -notes](https://github.com/npm/npm/releases/tag/v2.14.0)! - -But we over here in 3.x ALSO got a new feature this week, check out the new -`--only` and `--also` flags for better control over when dev and production -dependencies are used by various npm commands. - -That, and some important bug fixes round out this week. Enjoy everyone! - -#### NEVER SHALL NOT BETA THE BETA - -**_THIS IS BETA SOFTWARE_**. EXCITING NEW BETA WARNING!!! Ok, I fibbed, -EXACTLY THE SAME BETA WARNINGS: `npm@3` will remain in beta until we're -confident that it's stable and have assessed the effect of the breaking -changes on the community. During that time we will still be doing `npm@2` -releases, with `npm@2` tagged as `latest` and `next`. We'll _also_ be -publishing new releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` -alongside those versions until we're ready to switch everyone over to -`npm@3`. We need your help to find and fix its remaining bugs. It's a -significant rewrite, so we are _sure_ there still significant bugs -remaining. So do us a solid and deploy it in non-critical CI environments -and for day-to-day use, but maybe don't use it for production maintenance or -frontline continuous deployment just yet. - -#### ONLY ALSO DEV - -Hey we've got a SUPER cool new feature for you all, thanks to the fantastic -work of [@davglass](https://github.com/davglass) and -[@bengl](https://github.com/bengl) we have `--only=prod`, -`--only=dev`, `--also=prod` and `--also=dev` options. These apply in -various ways to: `npm install`, `npm ls`, `npm outdated` and `npm update`. - -So for instance: - -``` -npm install --only=dev -``` - -Only installs dev dependencies. By contrast: - -``` -npm install --only=prod -``` - -Will only install prod dependencies and is very similar to `--production` -but differs in that it doesn't set the environment variables that -`--production` does. - -The related new flag, `--also` is most useful with things like: - -``` -npm shrinkwrap --also=dev -``` - -As shrinkwraps don't include dev deps by default. This replaces passing in -`--dev` in that scenario. - -And that leads into the fact that this deprecates `--dev` as its semantics -across commands were inconsistent and confusing. - -* [`3ab1eea`](https://github.com/npm/npm/commit/3ab1eea) - [#9024](https://github.com/npm/npm/pull/9024) - Add support for `--only`, `--also` and deprecate `--dev` - ([@bengl](https://github.com/bengl)) - -#### DON'T TOUCH! THAT'S NOT YOUR BIN - -* [`b31812e`](https://github.com/npm/npm/commit/b31812e) - [#8996](https://github.com/npm/npm/pull/8996) - When removing a module that has bin files, if one that we're going to - remove is a symlink to a DIFFERENT module, leave it alone. This only happens - when you have two modules that try to provide the same bin. - ([@iarna](https://github.com/iarna)) - -#### THERE'S AN END IN SIGHT - -* [`d2178a9`](https://github.com/npm/npm/commit/d2178a9) - [#9223](https://github.com/npm/npm/pull/9223) - Close a bunch of infinite loops that could show up with symlink cycles in your dependencies. - ([@iarna](https://github.com/iarna)) - -#### OOPS DIDN'T MEAN TO FIX THAT - -Well, not _just_ yet. This was scheduled for next week, but it snuck into -2.x this week. - -* [`139dd92`](https://github.com/npm/npm/commit/139dd92) - [#8716](https://github.com/npm/npm/pull/8716) - `npm init` will now only pick up the modules you install, not everything - else that got flattened with them. - ([@iarna](https://github.com/iarna)) - -### v3.2.2 (2015-08-08): - -Lot's of lovely bug fixes for `npm@3`. I'm also suuuuper excited that I -think we have a handle on stack explosions that effect a small portion of -our users. We also have some tantalizing clues as to where some low hanging -fruit may be for performance issues. - -And of course, in addition to the `npm@3` specific bug fixes, there are some -great one's coming in from `npm@2`! [@othiym23](https://github.com/othiym23) -put together that release this week– check out its -[release notes](https://github.com/npm/npm/releases/tag/v2.13.4) for the deets. - -#### AS ALWAYS STILL BETA - -**_THIS IS BETA SOFTWARE_**. Just like the airline safety announcements, -we're not taking this plane off till we finish telling you: `npm@3` will -remain in beta until we're confident that it's stable and have assessed the -effect of the breaking changes on the community. During that time we will -still be doing `npm@2` releases, with `npm@2` tagged as `latest` and `next`. -We'll _also_ be publishing new releases of `npm@3` as `npm@v3.x-next` and -`npm@v3.x-latest` alongside those versions until we're ready to switch -everyone over to `npm@3`. We need your help to find and fix its remaining -bugs. It's a significant rewrite, so we are _sure_ there still significant -bugs remaining. So do us a solid and deploy it in non-critical CI -environments and for day-to-day use, but maybe don't use it for production -maintenance or frontline continuous deployment just yet. - -#### BUG FIXES - -* [`a8c8a13`](https://github.com/npm/npm/commit/a8c8a13) - [#9050](https://github.com/npm/npm/issues/9050) - Resolve peer deps relative to the parent of the requirer - ([@iarna](http://github.com/iarna)) -* [`05f0226`](https://github.com/npm/npm/commit/05f0226) - [#9077](https://github.com/npm/npm/issues/9077) - Fix crash when saving `git+ssh` urls - ([@iarna](http://github.com/iarna)) -* [`e4a3808`](https://github.com/npm/npm/commit/e4a3808) - [#8951](https://github.com/npm/npm/issues/8951) - Extend our patch to allow `*` to match something when a package only has - prerelease versions to everything and not just the cache. - ([@iarna](http://github.com/iarna)) -* [`d135abf`](https://github.com/npm/npm/commit/d135abf) - [#8871](https://github.com/npm/npm/issues/8871) - Don't warn about a missing `package.json` or missing fields in the global - install directory. - ([@iarna](http://github.com/iarna)) - -#### DEP VERSION BUMPS - -* [`990ee4f`](https://github.com/npm/npm/commit/990ee4f) - `path-is-inside@1.0.1` ([@domenic](https://github.com/domenic)) -* [`1f71ec0`](https://github.com/npm/npm/commit/1f71ec0) - `lodash.clonedeep@3.0.2` ([@jdalton](https://github.com/jdalton)) -* [`a091354`](https://github.com/npm/npm/commit/a091354) - `marked@0.3.5` ([@chjj](https://github.com/chjj)) -* [`fc51f28`](https://github.com/npm/npm/commit/fc51f28) - `tap@1.3.2` ([@isaacs](https://github.com/isaacs)) -* [`3569ec0`](https://github.com/npm/npm/commit/3569ec0) - `nock@2.10.0` ([@pgte](https://github.com/pgte)) -* [`ad5f6fd`](https://github.com/npm/npm/commit/ad5f6fd) - `npm-registry-mock@1.0.1` ([@isaacs](https://github.com/isaacs)) - -### v3.2.1 (2015-07-31): - -#### AN EXTRA QUIET RELEASE - -A bunch of stuff got deferred for various reasons, which just means more -branches to land next week! - -Don't forget to check out [Kat's 2.x release](https://github.com/npm/npm/releases/tag/v2.13.4) for other quiet goodies. - -#### AS ALWAYS STILL BETA - -**_THIS IS BETA SOFTWARE_**. Yes, we're still reminding you of this. No, -you can't be excused. `npm@3` will remain in beta until we're confident -that it's stable and have assessed the effect of the breaking changes on the -community. During that time we will still be doing `npm@2` releases, with -`npm@2` tagged as `latest` and `next`. We'll _also_ be publishing new -releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` alongside those -versions until we're ready to switch everyone over to `npm@3`. We need your -help to find and fix its remaining bugs. It's a significant rewrite, so we -are _sure_ there still significant bugs remaining. So do us a solid and -deploy it in non-critical CI environments and for day-to-day use, but maybe -don't use it for production maintenance or frontline continuous deployment -just yet. - - -#### MAKING OUR TESTS TEST THE THING THEY TEST - -* [`6e53c3d`](https://github.com/npm/npm/commit/6e53c3d) - [#8985](https://github.com/npm/npm/pull/8985) - Many thanks to @bengl for noticing that one of our tests wasn't testing - what it claimed it was testing! ([@bengl](https://github.com/bengl)) - -#### MY PACKAGE.JSON WAS ALREADY IN THE RIGHT ORDER - -* [`eb2c7aa`](https://github.com/npm/npm/commit/d00d0f) - [#9068](https://github.com/npm/npm/pull/9079) - Stop sorting keys in the `package.json` that we haven't edited. Many - thanks to [@Qix-](https://github.com/Qix-) for bringing this up and - providing a first pass at a patch for this. - ([@iarna](https://github.com/iarna)) - -#### DEV DEP UPDATE - -* [`555f60c`](https://github.com/npm/npm/commit/555f60c) `marked@0.3.4` - -### v3.2.0 (2015-07-24): - -#### MORE CONFIG, BETTER WINDOWS AND A BUG FIX - -This is a smallish release with a new config option and some bug fixes. And -lots of module updates. - -#### BETA BETAS ON - -**_THIS IS BETA SOFTWARE_**. Yes, we're still reminding you of this. No, -you can't be excused. `npm@3` will remain in beta until we're confident -that it's stable and have assessed the effect of the breaking changes on the -community. During that time we will still be doing `npm@2` releases, with -`npm@2` tagged as `latest` and `next`. We'll _also_ be publishing new -releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` alongside those -versions until we're ready to switch everyone over to `npm@3`. We need your -help to find and fix its remaining bugs. It's a significant rewrite, so we -are _sure_ there still significant bugs remaining. So do us a solid and -deploy it in non-critical CI environments and for day-to-day use, but maybe -don't use it for production maintenance or frontline continuous deployment -just yet. - - -#### NEW CONFIGS, LESS PROGRESS - -* [`423d8f7`](https://github.com/npm/npm/commit/423d8f7) - [#8704](https://github.com/npm/npm/issues/8704) - Add the ability to disable the new progress bar with `--no-progress` - ([@iarna](https://github.com/iarna)) - -#### AND BUG FIXES - -* [`b3ee452`](https://github.com/npm/npm/commit/b3ee452) - [#9038](https://github.com/npm/npm/pull/9038) - We previously disabled the use of the new `fs.access` API on Windows, but - the bug we were seeing is fixed in `io.js@1.5.0` so we now use `fs.access` - if you're using that version or greater. - ([@iarna](https://github.com/iarna)) - -* [`b181fa3`](https://github.com/npm/npm/commit/b181fa3) - [#8921](https://github.com/npm/npm/issues/8921) - [#8637](https://github.com/npm/npm/issues/8637) - Rejigger how we validate modules for install. This allow is to fix - a problem where arch/os checking wasn't being done at all. - It also made it easy to add back in a check that declines to - install a module in itself unless you force it. - ([@iarna](https://github.com/iarna)) - -#### AND A WHOLE BUNCH OF SUBDEP VERSIONS - -These are all development dependencies and semver-compatible subdep -upgrades, so they should not have visible impact on users. - -* [`6b3f6d9`](https://github.com/npm/npm/commit/6b3f6d9) `standard@4.3.3` -* [`f4e22e5`](https://github.com/npm/npm/commit/f4e22e5) `readable-stream@2.0.2` (inside concat-stream) -* [`f130bfc`](https://github.com/npm/npm/commit/f130bfc) `minimatch@2.0.10` (inside node-gyp's copy of glob) -* [`36c6a0d`](https://github.com/npm/npm/commit/36c6a0d) `caseless@0.11.0` -* [`80df59c`](https://github.com/npm/npm/commit/80df59c) `chalk@1.1.0` -* [`ea935d9`](https://github.com/npm/npm/commit/ea935d9) `bluebird@2.9.34` -* [`3588a0c`](https://github.com/npm/npm/commit/3588a0c) `extend@3.0.0` -* [`c6a8450`](https://github.com/npm/npm/commit/c6a8450) `form-data@1.0.0-rc2` -* [`a04925b`](https://github.com/npm/npm/commit/a04925b) `har-validator@1.8.0` -* [`ee7c095`](https://github.com/npm/npm/commit/ee7c095) `has-ansi@2.0.0` -* [`944fc34`](https://github.com/npm/npm/commit/944fc34) `hawk@3.1.0` -* [`783dc7b`](https://github.com/npm/npm/commit/783dc7b) `lodash._basecallback@3.3.1` -* [`acef0fe`](https://github.com/npm/npm/commit/acef0fe) `lodash._baseclone@3.3.0` -* [`dfe959a`](https://github.com/npm/npm/commit/dfe959a) `lodash._basedifference@3.0.3` -* [`a03bc76`](https://github.com/npm/npm/commit/a03bc76) `lodash._baseflatten@3.1.4` -* [`8a07d50`](https://github.com/npm/npm/commit/8a07d50) `lodash._basetostring@3.0.1` -* [`7785e3f`](https://github.com/npm/npm/commit/7785e3f) `lodash._baseuniq@3.0.3` -* [`826fb35`](https://github.com/npm/npm/commit/826fb35) `lodash._createcache@3.1.2` -* [`76030b3`](https://github.com/npm/npm/commit/76030b3) `lodash._createpadding@3.6.1` -* [`1a49ec6`](https://github.com/npm/npm/commit/1a49ec6) `lodash._getnative@3.9.1` -* [`eebe47f`](https://github.com/npm/npm/commit/eebe47f) `lodash.isarguments@3.0.4` -* [`09994d4`](https://github.com/npm/npm/commit/09994d4) `lodash.isarray@3.0.4` -* [`b6f8dbf`](https://github.com/npm/npm/commit/b6f8dbf) `lodash.keys@3.1.2` -* [`c67dd6b`](https://github.com/npm/npm/commit/c67dd6b) `lodash.pad@3.1.1` -* [`4add042`](https://github.com/npm/npm/commit/4add042) `lodash.repeat@3.0.1` -* [`e04993c`](https://github.com/npm/npm/commit/e04993c) `lru-cache@2.6.5` -* [`2ed7da4`](https://github.com/npm/npm/commit/2ed7da4) `mime-db@1.15.0` -* [`ae08244`](https://github.com/npm/npm/commit/ae08244) `mime-types@2.1.3` -* [`e71410e`](https://github.com/npm/npm/commit/e71410e) `os-homedir@1.0.1` -* [`67c13e0`](https://github.com/npm/npm/commit/67c13e0) `process-nextick-args@1.0.2` -* [`12ee041`](https://github.com/npm/npm/commit/12ee041) `qs@4.0.0` -* [`15564a6`](https://github.com/npm/npm/commit/15564a6) `spdx-license-ids@1.0.2` -* [`8733bff`](https://github.com/npm/npm/commit/8733bff) `supports-color@2.0.0` -* [`230943c`](https://github.com/npm/npm/commit/230943c) `tunnel-agent@0.4.1` -* [`26a4653`](https://github.com/npm/npm/commit/26a4653) `ansi-styles@2.1.0` -* [`3d27081`](https://github.com/npm/npm/commit/3d27081) `bl@1.0.0` -* [`9efa110`](https://github.com/npm/npm/commit/9efa110) `async@1.4.0` - -#### MERGED FORWARD - -* As usual, we've ported all the `npm@2` goodies in this week's - [v2.13.3](https://github.com/npm/npm/releases/tag/v2.13.3) - release. - -### v3.1.3 (2015-07-17): - -Rebecca: So Kat, I hear this week's other release uses a dialog between us to -explain what changed? - -Kat: Well, you could say that… - -Rebecca: I would! This week I fixed more `npm@3` bugs! - -Kat: That sounds familiar. - -Rebecca: Eheheheh, well, before we look at those, a word from our sponsor… - -#### BETA IS AS BETA DOES - -**_THIS IS BETA SOFTWARE_**. Yes, we're still reminding you of this. No, -you can't be excused. `npm@3` will remain in beta until we're confident -that it's stable and have assessed the effect of the breaking changes on the -community. During that time we will still be doing `npm@2` releases, with -`npm@2` tagged as `latest` and `next`. We'll _also_ be publishing new -releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` alongside those -versions until we're ready to switch everyone over to `npm@3`. We need your -help to find and fix its remaining bugs. It's a significant rewrite, so we -are _sure_ there still significant bugs remaining. So do us a solid and -deploy it in non-critical CI environments and for day-to-day use, but maybe -don't use it for production maintenance or frontline continuous deployment -just yet. - -Rebecca: Ok, enough of the dialoguing, that's Kat's schtick. But do remember -kids, betas hide in dark hallways waiting to break your stuff, stuff like… - -#### SO MANY LINKS YOU COULD MAKE A CHAIN - -* [`6d69ec9`](https://github.com/npm/npm/6d69ec9) - [#8967](https://github.com/npm/npm/issues/8967) - Removing a module linked into your globals would result in having - all of its subdeps removed. Since the npm release process does - exactly this, it burned me -every- -single- -week-. =D - While we're here, we also removed extraneous warns that used to - spill out when you'd remove a symlink. - ([@iarna](https://github.com/iarna)) - -* [`fdb360f`](https://github.com/npm/npm/fdb360f) - [#8874](https://github.com/npm/npm/issues/8874) - Linking scoped modules was failing outright, but this fixes that - and updates our tests so we don't do it again. - ([@iarna](https://github.com/iarna)) - -#### WE'LL TRY NOT TO CRACK YOUR WINDOWS - -* [`9fafb18`](https://github.com/npm/npm/9fafb18) - [#8701](https://github.com/npm/npm/issues/8701) - `npm@3` introduced permissions checks that run before it actually tries to - do something. This saves you from having an install fail half way - through. We did this using the shiny new `fs.access` function available - in `node 0.12` and `io.js`, with fallback options for older nodes. Unfortunately - the way we implemented the fallback caused racey problems for Windows systems. - This fixes that by ensuring we only ever run any one check on a directory once. - BUT it turns out there are bugs in `fs.access` on Windows. So this ALSO just disables - the use of `fs.access` on Windows entirely until that settles out. - ([@iarna](https://github.com/iarna)) - -#### ZOOM ZOOM, DEP UPDATES - -* [`5656baa`](https://github.com/npm/npm/5656baa) - `gauge@1.2.2`: Better handle terminal resizes while printing the progress bar - ([@iarna](https://github.com/iarna)) - -#### MERGED FORWARD - -* Check out Kat's [super-fresh release notes for v2.13.2](https://github.com/npm/npm/releases/tag/v2.13.2) - and see all the changes we ported from `npm@2`. - -### v3.1.2 - -#### SO VERY BETA RELEASE - -So, `v3.1.1` managed to actually break installing local modules. And then -immediately after I drove to an island for the weekend. 😁 So let's get -this fixed outside the usual release train! - -Fortunately it didn't break installing _global_ modules and so you could -swap it out for another version at least. - -#### DISCLAIMER MEANS WHAT IT SAYS - -**_THIS IS BETA SOFTWARE_**. Yes, we're still reminding you of this. No, -you can't be excused. `npm@3` will remain in beta until we're confident -that it's stable and have assessed the effect of the breaking changes on the -community. During that time we will still be doing `npm@2` releases, with -`npm@2` tagged as `latest` and `next`. We'll _also_ be publishing new -releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` alongside those -versions until we're ready to switch everyone over to `npm@3`. We need your -help to find and fix its remaining bugs. It's a significant rewrite, so we -are _sure_ there still significant bugs remaining. So do us a solid and -deploy it in non-critical CI environments and for day-to-day use, but maybe -don't use it for production maintenance or frontline continuous deployment -just yet. - -#### THIS IS IT, THE REASON - -* [`f5e19df`](https://github.com/npm/npm/commit/f5e19df) - [#8893](https://github.com/npm/npm/issues/8893) - Fix crash when installing local modules introduced by the fix for - [#8608](https://github.com/npm/npm/issues/8608) - ([@iarna](https://github.com/iarna) - -### v3.1.1 - -#### RED EYE RELEASE - -Rebecca's up too late writing tests, so you can have `npm@3` bug fixes! Lots -of great new issues from you all! ❤️️ Keep it up! - -#### YUP STILL BETA, PLEASE PAY ATTENTION - -**_THIS IS BETA SOFTWARE_**. Yes, we're still reminding you of this. No, -you can't be excused. `npm@3` will remain in beta until we're confident -that it's stable and have assessed the effect of the breaking changes on the -community. During that time we will still be doing `npm@2` releases, with -`npm@2` tagged as `latest` and `next`. We'll _also_ be publishing new -releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` alongside those -versions until we're ready to switch everyone over to `npm@3`. We need your -help to find and fix its remaining bugs. It's a significant rewrite, so we -are _sure_ there still significant bugs remaining. So do us a solid and -deploy it in non-critical CI environments and for day-to-day use, but maybe -don't use it for production maintenance or frontline continuous deployment -just yet. - -#### BOOGS - -* [`9badfd6`](https://github.com/npm/npm/commit/9babfd63f19f2d80b2d2624e0963b0bdb0d76ef4) - [#8608](https://github.com/npm/npm/issues/8608) - Make global installs and uninstalls MUCH faster by only reading the directories of - modules referred to by arguments. - ([@iarna](https://github.com/iarna) -* [`075a5f0`](https://github.com/npm/npm/commit/075a5f046ab6837f489b08d44cb601e9fdb369b7) - [#8660](https://github.com/npm/npm/issues/8660) - Failed optional deps would still result in the optional deps own - dependencies being installed. We now find them and fail them out of the - tree. - ([@iarna](https://github.com/iarna) -* [`c9fbbb5`](https://github.com/npm/npm/commit/c9fbbb540083396ea58fd179d81131d959d8e049) - [#8863](https://github.com/npm/npm/issues/8863) - The "no compatible version found" error message was including only the - version requested, not the name of the package we wanted. Ooops! - ([@iarna](https://github.com/iarna) -* [`32e6bbd`](https://github.com/npm/npm/commit/32e6bbd21744dcbe8c0720ab53f60caa7f2a0588) - [#8806](https://github.com/npm/npm/issues/8806) - The "uninstall" lifecycle was being run after all of a module's dependencies has been - removed. This reverses that order-- this means "uninstall" lifecycles can make use - of the package's dependencies. - ([@iarna](https://github.com/iarna) - -#### MERGED FORWARD - -* Check out the [v2.13.1 release notes](https://github.com/npm/npm/releases/tag/v2.13.1) - and see all the changes we ported from `npm@2`. - -### v3.1.0 (2015-07-02): - -This has been a brief week of bug fixes, plus some fun stuff merged forward -from this weeks 2.x release. See the -[2.13.0 release notes](https://github.com/npm/npm/releases/tag/v2.13.0) -for details on that. - -You all have been AWESOME with -[all](https://github.com/npm/npm/milestones/3.x) -[the](https://github.com/npm/npm/milestones/3.2.0) -`npm@3` bug reports! Thank you and keep up the great work! - -#### NEW PLACE, SAME CODE - -Remember how last week we said `npm@3` would go to `3.0-next` and latest -tags? Yeaaah, no, please use `npm@v3.x-next` and `npm@v3.x-latest` going forward. - -I dunno why we said "suuure, we'll never do a feature release till we're out -of beta" when we're still forward porting `npm@2.x` features. `¯\_(ツ)_/¯` - -If you do accidentally use the old tag names, I'll be maintaining them -for a few releases, but they won't be around forever. - -#### YUP STILL BETA, PLEASE PAY ATTENTION - -**_THIS IS BETA SOFTWARE_**. `npm@3` will remain in beta until we're -confident that it's stable and have assessed the effect of the breaking -changes on the community. During that time we will still be doing `npm@2` -releases, with `npm@2` tagged as `latest` and `next`. We'll _also_ be -publishing new releases of `npm@3` as `npm@v3.x-next` and `npm@v3.x-latest` -alongside those versions until we're ready to switch everyone over to -`npm@3`. We need your help to find and fix its remaining bugs. It's a -significant rewrite, so we are _sure_ there still significant bugs -remaining. So do us a solid and deploy it in non-critical CI environments -and for day-to-day use, but maybe don't use it for production maintenance -or frontline continuous deployment just yet. - -#### BUGS ON THE WINDOWS - - * [`0030ade`](https://github.com/npm/npm/commit/0030ade) - [#8685](https://github.com/npm/npm/issues/8685) - Windows would hang when trying to clone git repos - ([@euprogramador](https://github.com/npm/npm/pull/8777)) - * [`b259bcc`](https://github.com/npm/npm/commit/b259bcc) - [#8786](https://github.com/npm/npm/pull/8786) - Windows permissions checks would cause installations to fail under some - circumstances. We're disabling the checks entirely for this release. - I'm hoping to check back with this next week to get a Windows friendly - fix in. - ([@iarna](https://github.com/iarna)) - -#### SO MANY BUGS SQUASHED, JUST CALL US RAID - - * [`0848698`](https://github.com/npm/npm/commit/0848698) - [#8686](https://github.com/npm/npm/pull/8686) - Stop leaving progress bar cruft on the screen during publication - ([@ajcrites](https://github.com/ajcrites)) - * [`57c3cea`](https://github.com/npm/npm/commit/57c3cea) - [#8695](https://github.com/npm/npm/pull/8695) - Remote packages with shrinkwraps made npm cause node + iojs to explode - and catch fire. NO MORE. - ([@iarna](https://github.com/iarna)) - * [`2875ba3`](https://github.com/npm/npm/commit/2875ba3) - [#8723](https://github.com/npm/npm/pull/8723) - I uh, told you that engineStrict checking had gone away last week. - TURNS OUT I LIED. So this is making that actually be true. - ([@iarna](https://github.com/iarna)) - * [`28064e5`](https://github.com/npm/npm/commit/28064e5) - [#3358](https://github.com/npm/npm/issues/3358) - Consistently allow Unicode BOMs at the start of package.json files. - Previously this was allowed some of time, like when you were installing - modules, but not others, like running npm version or installing w/ - `--save`. - ([@iarna](https://github.com/iarna)) - * [`3cb6ad2`](https://github.com/npm/npm/commit/3cb6ad2) - [#8736](https://github.com/npm/npm/issues/8766) - `npm@3` wasn't running the "install" lifecycle in your current (toplevel) - module. This broke modules that relied on C compilation. BOO. - ([@iarna](https://github.com/iarna)) - * [`68da583`](https://github.com/npm/npm/commit/68da583) - [#8766](https://github.com/npm/npm/issues/8766) - To my great shame, `npm link package` wasn't working AT ALL if you - didn't have `package` already installed. - ([@iarna](https://github.com/iarna)) - * [`edd7448`](https://github.com/npm/npm/commit/edd7448) - `read-package-tree@5.0.0`: This update makes read-package-tree not explode - when there's bad data in your node_modules folder. `npm@2` silently - ignores this sort of thing. - ([@iarna](https://github.com/iarna)) - * [`0bb08c8`](https://github.com/npm/npm/commit/0bb08c8) - [#8778](https://github.com/npm/npm/pull/8778) - RELATEDLY, we now show any errors from your node_modules folder after - your installation completes as warnings. We're also reporting these in - `npm ls` now. - ([@iarna](https://github.com/iarna)) - * [`6c248ff`](https://github.com/npm/npm/commit/6c248ff) - [#8779](https://github.com/npm/npm/pull/8779) - Hey, you know how we used to complain if your `package.json` was - missing stuff? Well guess what, we are again. I know, I know, you can - thank me later. - ([@iarna](https://github.com/iarna)) - * [`d6f7c98`](https://github.com/npm/npm/commit/d6f7c98) - So, when we were rolling back after errors we had untested code that - tried to undo moves. Being untested it turns out it was very broken. - I've removed it until we have time to do this right. - ([@iarna](https://github.com/iarna)) - -#### NEW VERSION - -Just the one. Others came in via the 2.x release. Do check out its -changelog, immediately following this message. - - * [`4e602c5`](https://github.com/npm/npm/commit/4e602c5) `lodash@3.2.2` - -### v3.0.0 (2015-06-25): - -Wow, it's finally here! This has been a long time coming. We are all -delighted and proud to be getting this out into the world, and are looking -forward to working with the npm user community to get it production-ready -as quickly as possible. - -`npm@3` constitutes a nearly complete rewrite of npm's installer to be -easier to maintain, and to bring a bunch of valuable new features and -design improvements to you all. - -[@othiym23](https://github.com/othiym23) and -[@isaacs](https://github.com/isaacs) have been -[talking about the changes](http://blog.npmjs.org/post/91303926460/npm-cli-roadmap-a-periodic-update) -in this release for well over a year, and it's been the primary focus of -[@iarna](https://github.com/iarna) since she joined the team. - -Given that this is a near-total rewrite, all changes listed here are -[@iarna](https://github.com/iarna)'s work unless otherwise specified. - -#### NO, REALLY, READ THIS PARAGRAPH. IT'S THE IMPORTANT ONE. - -**_THIS IS BETA SOFTWARE_**. `npm@3` will remain in beta until we're -confident that it's stable and have assessed the effect of the breaking -changes on the community. During that time we will still be doing `npm@2` -releases, with `npm@2` tagged as `latest` and `next`. We'll _also_ be -publishing new releases of `npm@3` as `npm@3.0-next` and `npm@3.0-latest` -alongside those versions until we're ready to switch everyone over to -`npm@3`. We need your help to find and fix its remaining bugs. It's a -significant rewrite, so we are _sure_ there still significant bugs -remaining. So do us a solid and deploy it in non-critical CI environments -and for day-to-day use, but maybe don't use it for production maintenance -or frontline continuous deployment just yet. - -#### BREAKING CHANGES - -##### `peerDependencies` - -`grunt`, `gulp`, and `broccoli` plugin maintainers take note! You will be -affected by this change! - -* [#6930](https://github.com/npm/npm/issues/6930) - ([#6565](https://github.com/npm/npm/issues/6565)) - `peerDependencies` no longer cause _anything_ to be implicitly installed. - Instead, npm will now warn if a packages `peerDependencies` are missing, - but it's up to the consumer of the module (i.e. you) to ensure the peers - get installed / are included in `package.json` as direct `dependencies` - or `devDependencies` of your package. -* [#3803](https://github.com/npm/npm/issues/3803) - npm also no longer checks `peerDependencies` until after it has fully - resolved the tree. - -This shifts the responsibility for fulfilling peer dependencies from library -/ framework / plugin maintainers to application authors, and is intended to -get users out of the dependency hell caused by conflicting `peerDependency` -constraints. npm's job is to keep you _out_ of dependency hell, not put you -in it. - -##### `engineStrict` - -* [#6931](https://github.com/npm/npm/issues/6931) The rarely-used - `package.json` option `engineStrict` has been deprecated for several - months, producing warnings when it was used. Starting with `npm@3`, the - value of the field is ignored, and engine violations will only produce - warnings. If you, as a user, want strict `engines` field enforcement, - just run `npm config set engine-strict true`. - -As with the peer dependencies change, this is about shifting control from -module authors to application authors. It turns out `engineStrict` was very -difficult to understand even harder to use correctly, and more often than -not just made modules using it difficult to deploy. - -##### `npm view` - -* [`77f1aec`](https://github.com/npm/npm/commit/77f1aec) With `npm view` (aka - `npm info`), always return arrays for versions, maintainers, etc. Previously - npm would return a plain value if there was only one, and multiple values if - there were more. ([@KenanY](https://github.com/KenanY)) - -#### KNOWN BUGS - -Again, this is a _**BETA RELEASE**_, so not everything is working just yet. -Here are the issues that we already know about. If you run into something -that isn't on this list, -[let us know](https://github.com/npm/npm/issues/new)! - -* [#8575](https://github.com/npm/npm/issues/8575) - Circular deps will never be removed by the prune-on-uninstall code. -* [#8588](https://github.com/npm/npm/issues/8588) - Local deps where the dep name and the name in the package.json differ - don't result in an error. -* [#8637](https://github.com/npm/npm/issues/8637) - Modules can install themselves as direct dependencies. `npm@2` declined to - do this. -* [#8660](https://github.com/npm/npm/issues/8660) - Dependencies of failed optional dependencies aren't rolled back when the - optional dependency is, and then are reported as extraneous thereafter. - -#### NEW FEATURES - -##### The multi-stage installer! - -* [#5919](https://github.com/npm/npm/issues/5919) - Previously the installer had a set of steps it executed for each package - and it would immediately start executing them as soon as it decided to - act on a package. - - But now it executes each of those steps at the same time for all - packages, waiting for all of one stage to complete before moving on. This - eliminates many race conditions and makes the code easier to reason - about. - -This fixes, for instance: - -* [#6926](https://github.com/npm/npm/issues/6926) - ([#5001](https://github.com/npm/npm/issues/5001), - [#6170](https://github.com/npm/npm/issues/6170)) - `install` and `postinstall` lifecycle scripts now only execute `after` - all the module with the script's dependencies are installed. - -##### Install: it looks different! - -You'll now get a tree much like the one produced by `npm ls` that -highlights in orange the packages that were installed. Similarly, any -removed packages will have their names prefixed by a `-`. - -Also, `npm outdated` used to include the name of the module in the -`Location` field: - -``` -Package Current Wanted Latest Location -deep-equal MISSING 1.0.0 1.0.0 deep-equal -glob 4.5.3 4.5.3 5.0.10 rimraf > glob -``` - -Now it shows the module that required it as the final point in the -`Location` field: - -``` -Package Current Wanted Latest Location -deep-equal MISSING 1.0.0 1.0.0 npm -glob 4.5.3 4.5.3 5.0.10 npm > rimraf -``` - -Previously the `Location` field was telling you where the module was on -disk. Now it tells you what requires the module. When more than one thing -requires the module you'll see it listed once for each thing requiring it. - -##### Install: it works different! - -* [#6928](https://github.com/npm/npm/issues/6928) - ([#2931](https://github.com/npm/npm/issues/2931) - [#2950](https://github.com/npm/npm/issues/2950)) - `npm install` when you have an `npm-shrinkwrap.json` will ensure you have - the modules specified in it are installed in exactly the shape specified - no matter what you had when you started. -* [#6913](https://github.com/npm/npm/issues/6913) - ([#1341](https://github.com/npm/npm/issues/1341) - [#3124](https://github.com/npm/npm/issues/3124) - [#4956](https://github.com/npm/npm/issues/4956) - [#6349](https://github.com/npm/npm/issues/6349) - [#5465](https://github.com/npm/npm/issues/5465)) - `npm install` when some of your dependencies are missing sub-dependencies - will result in those sub-dependencies being installed. That is, `npm - install` now knows how to fix broken installs, most of the time. -* [#5465](https://github.com/npm/npm/issues/5465) - If you directly `npm install` a module that's already a subdep of - something else and your new version is incompatible, it will now install - the previous version nested in the things that need it. -* [`a2b50cf`](https://github.com/npm/npm/commit/a2b50cf) - [#5693](https://github.com/npm/npm/issues/5693) - When installing a new module, if it's mentioned in your - `npm-shrinkwrap.json` or your `package.json` use the version specifier - from there if you didn't specify one yourself. - -##### Flat, flat, flat! - -Your dependencies will now be installed *maximally flat*. Insofar as is -possible, all of your dependencies, and their dependencies, and THEIR -dependencies will be installed in your project's `node_modules` folder with no -nesting. You'll only see modules nested underneath one another when two (or -more) modules have conflicting dependencies. - -* [#3697](https://github.com/npm/npm/issues/3697) - This will hopefully eliminate most cases where Windows users ended up - with paths that were too long for Explorer and other standard tools to - deal with. -* [#6912](https://github.com/npm/npm/issues/6912) - ([#4761](https://github.com/npm/npm/issues/4761) - [#4037](https://github.com/npm/npm/issues/4037)) - This also means that your installs will be deduped from the start. -* [#5827](https://github.com/npm/npm/issues/5827) - This deduping even extends to git deps. -* [#6936](https://github.com/npm/npm/issues/6936) - ([#5698](https://github.com/npm/npm/issues/5698)) - Various commands are dedupe aware now. - -This has some implications for the behavior of other commands: - -* `npm uninstall` removes any dependencies of the module that you specified - that aren't required by any other module. Previously, it would only - remove those that happened to be installed under it, resulting in left - over cruft if you'd ever deduped. -* `npm ls` now shows you your dependency tree organized around what - requires what, rather than where those modules are on disk. -* [#6937](https://github.com/npm/npm/issues/6937) - `npm dedupe` now flattens the tree in addition to deduping. - -And bundling of dependencies when packing or publishing changes too: - -* [#2442](https://github.com/npm/npm/issues/2442) - bundledDependencies no longer requires that you specify deduped sub deps. - npm can now see that a dependency is required by something bundled and - automatically include it. To put that another way, bundledDependencies - should ONLY include things that you included in dependencies, - optionalDependencies or devDependencies. -* [#5437](https://github.com/npm/npm/issues/5437) - When bundling a dependency that's both a `devDependency` and the child of - a regular `dependency`, npm bundles the child dependency. - -As a demonstration of our confidence in our own work, npm's own -dependencies are now flattened, deduped, and bundled in the `npm@3` style. -This means that `npm@3` can't be packed or published by `npm@2`, which is -something to be aware of if you're hacking on npm. - -##### Shrinkwraps: they are a-changin'! - -First of all, they should be idempotent now -([#5779](https://github.com/npm/npm/issues/5779)). No more differences -because the first time you install (without `npm-shrinkwrap.json`) and the -second time (with `npm-shrinkwrap.json`). - -* [#6781](https://github.com/npm/npm/issues/6781) - Second, if you save your changes to `package.json` and you have - `npm-shrinkwrap.json`, then it will be updated as well. This applies to - all of the commands that update your tree: - * `npm install --save` - * `npm update --save` - * `npm dedupe --save` ([#6410](https://github.com/npm/npm/issues/6410)) - * `npm uninstall --save` -* [#4944](https://github.com/npm/npm/issues/4944) - ([#5161](https://github.com/npm/npm/issues/5161) - [#5448](https://github.com/npm/npm/issues/5448)) - Third, because `node_modules` folders are now deduped and flat, - shrinkwrap has to also be smart enough to handle this. - -And finally, enjoy this shrinkwrap bug fix: - -* [#3675](https://github.com/npm/npm/issues/3675) - When shrinkwrapping a dependency that's both a `devDependency` and the - child of a regular `dependency`, npm now correctly includes the child. - -##### The Age of Progress (Bars)! - -* [#6911](https://github.com/npm/npm/issues/6911) - ([#1257](https://github.com/npm/npm/issues/1257) - [#5340](https://github.com/npm/npm/issues/5340) - [#6420](https://github.com/npm/npm/issues/6420)) - The spinner is gone (yay? boo? will you miss it?), and in its place npm - has _progress bars_, so you actually have some sense of how long installs - will take. It's provided in Unicode and non-Unicode variants, and Unicode - support is automatically detected from your environment. - -#### TINY JEWELS - -The bottom is where we usually hide the less interesting bits of each -release, but each of these are small but incredibly useful bits of this -release, and very much worth checking out: - -* [`9ebe312`](https://github.com/npm/npm/commit/9ebe312) - Build system maintainers, rejoice: npm does a better job of cleaning up - after itself in your temporary folder. -* [#6942](https://github.com/npm/npm/issues/6942) - Check for permissions issues prior to actually trying to install - anything. -* Emit warnings at the end of the installation when possible, so that - they'll be on your screen when npm stops. -* [#3505](https://github.com/npm/npm/issues/3505) - `npm --dry-run`: You can now ask that npm only report what it _would have - done_ with the new `--dry-run` flag. This can be passed to any of the - commands that change your `node_modules` folder: `install`, `uninstall`, - `update` and `dedupe`. -* [`81b46fb`](https://github.com/npm/npm/commit/81b46fb) - npm now knows the correct URLs for `npm bugs` and `npm repo` for - repositories hosted on Bitbucket and GitLab, just like it does for GitHub - (and GitHub support now extends to projects hosted as gists as well as - traditional repositories). -* [`5be4008a`](https://github.com/npm/npm/commit/5be4008a09730cfa3891d9f145e4ec7f2accd144) - npm has been cleaned up to pass the [`standard`](http://npm.im/standard) - style checker. Forrest and Rebecca both feel this makes it easier to read - and understand the code, and should also make it easier for new - contributors to put merge-ready patches. - ([@othiym23](https://github.com/othiym23)) - -#### ZARRO BOOGS - -* [`6401643`](https://github.com/npm/npm/commit/6401643) - Make sure the global install directory exists before installing to it. - ([@thefourtheye](https://github.com/thefourtheye)) -* [#6158](https://github.com/npm/npm/issues/6158) - When we remove modules we do so inside-out running unbuild for each one. -* [`960a765`](https://github.com/npm/npm/commit/960a765) - The short usage information for each subcommand has been brought in sync - with the documentation. ([@smikes](https://github.com/smikes)) diff --git a/changelogs/CHANGELOG-4.md b/changelogs/CHANGELOG-4.md deleted file mode 100644 index 2c971bb1c4d9d..0000000000000 --- a/changelogs/CHANGELOG-4.md +++ /dev/null @@ -1,1566 +0,0 @@ -## v4.6.1 (2017-04-21) - -A little release to tide you over while we hammer out the last bits for npm@5. - -### FEATURES - -* [`d13c9b2f2`](https://github.com/npm/npm/commit/d13c9b2f24b6380427f359b6e430b149ac8aaa79) - `init-package-json@1.10.0`: - The `name:` prompt is now `package name:` to make this less ambiguous for new users. - - The default package name is now a valid package name. For example: If your package directory - has mixed case, the default package name will be all lower case. -* [`f08c66323`](https://github.com/npm/npm/commit/f08c663231099f7036eb82b92770806a3a79cdf1) - [#16213](https://github.com/npm/npm/pull/16213) - Add `--allow-same-version` option to `npm version` so that you can use `npm version` to run - your version lifecycles and tag your git repo without actually changing the version number in - your `package.json`. - ([@lucastheisen](https://github.com/lucastheisen)) -* [`f5e8becd0`](https://github.com/npm/npm/commit/f5e8becd05e0426379eb0c999abdbc8e87a7f6f2) - Timing has been added throughout the install implementation. You can see it by running - a command with `--loglevel=timing`. You can also run commands with `--timing` which will write - an `npm-debug.log` even on success and add an entry to `_timing.json` in your cache with - the timing information from that run. - ([@iarna](https://github.com/iarna)) - -### BUG FIXES - -* [`9c860f2ed`](https://github.com/npm/npm/commit/9c860f2ed3bdea1417ed059b019371cd253db2ad) - [#16021](https://github.com/npm/npm/pull/16021) - Fix a crash in `npm doctor` when used with a registry that does not support - the `ping` API endpoint. - ([@watilde](https://github.com/watilde)) -* [`65b9943e9`](https://github.com/npm/npm/commit/65b9943e9424c67547b0029f02b0258e35ba7d26) - [#16364](https://github.com/npm/npm/pull/16364) - Shorten the ELIFECYCLE error message. The shorter error message should make it much - easier to discern the actual cause of the error. - ([@j-f1](https://github.com/j-f1)) -* [`a87a4a835`](https://github.com/npm/npm/commit/a87a4a8359693518ee41dfeb13c5a8929136772a) - `npmlog@4.0.2`: - Fix flashing of the progress bar when your terminal is very narrow. - ([@iarna](https://github.com/iarna)) -* [`41c10974f`](https://github.com/npm/npm/commit/41c10974fe95a2e520e33e37725570c75f6126ea) - `write-file-atomic@1.3.2`: - Wait for `fsync` to complete before considering our file written to disk. - This will improve certain sorts of Windows diagnostic problems. -* [`2afa9240c`](https://github.com/npm/npm/commit/2afa9240ce5b391671ed5416464f2882d18a94bc) - [#16336](https://github.com/npm/npm/pull/16336) - Don't ham-it-up when expecting JSON. - ([@bdukes](https://github.com/bdukes)) - -### DOCUMENTATION FIXES - -* [`566f3eebe`](https://github.com/npm/npm/commit/566f3eebe741f935b7c1e004bebf19b8625a1413) - [#16296](https://github.com/npm/npm/pull/16296) - Use a single convention when referring to the `<command>` you're running. - ([@desfero](https://github.com/desfero)) -* [`ccbb94934`](https://github.com/npm/npm/commit/ccbb94934d4f677f680c3e2284df3d0ae0e65758) - [#16267](https://github.com/npm/npm/pull/16267) - Fix a missing space in the example package.json. - ([@famousgarkin](https://github.com/famousgarkin)) - -### DEPENDENCY UPDATES - -* [`ebde4ea33`](https://github.com/npm/npm/commit/ebde4ea3363dfc154c53bd537189503863c9b3a4) - `hosted-git-info@2.4.2` -* [`c46ad71bb`](https://github.com/npm/npm/commit/c46ad71bbe27aaa9ee10e107d8bcd665d98544d7) - `init-package-json@1.9.6` -* [`d856d570d`](https://github.com/npm/npm/commit/d856d570d2df602767c039cf03439d647bba2e3d) - `npm-registry-client@8.1.1` -* [`4a2e14436`](https://github.com/npm/npm/commit/4a2e1443613a199665e7adbda034d5b9d10391a2) - `readable-stream@2.2.9` -* [`f0399138e`](https://github.com/npm/npm/commit/f0399138e6d6f1cd7f807d523787a3b129996301) - `normalize-package-data@2.3.8` - -### v4.5.0 (2017-03-24) - -Welcome a wrinkle on npm's registry API! - -Codename: Corgi - -![corgi-meme](https://cloud.githubusercontent.com/assets/757502/24126107/64c14268-0d89-11e7-871b-d457e6d0082b.jpg) - -This release has some bug fixes, but it's mostly about bringing support for -MUCH smaller package metadata. How much smaller? Well, for npm itself it -reduces 416K of gzip compressed JSON to 24K. - -As a user, all you have to do is update to get to use the new API. If -you're interested in the details we've [documented the -changes](https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md) -in detail. - -#### CORGUMENTS - -Package metadata: now smaller. This means a smaller cache and less to download. - -* [`86dad0d74`](https://github.com/npm/npm/commit/86dad0d747f288eab467d49c9635644d3d44d6f0) - Add support for filtered package metadata. - ([@iarna](https://github.com/iarna)) -* [`41789cffa`](https://github.com/npm/npm/commit/41789cffac9845603f4bdf3f5b03f412144a0e9f) - `npm-registry-client@8.1.0` - ([@iarna](https://github.com/iarna)) - -#### NO SHRINKWRAP, NO PROBLEM - -Previously we needed to extract every package's tarball to look for an -`npm-shrinkwrap.json` before we could begin working through what its -dependencies were. This was one of the things stopping npm's network -accesses from happening more concurrently. The new filtered package -metadata provides a new key, `_hasShrinkwrap`. When that's set to `false` -then we know we don't have to look for one. - -* [`4f5060eb3`](https://github.com/npm/npm/commit/4f5060eb31b9091013e1d6a34050973613a294a3) - [#15969](https://github.com/npm/npm/pull/15969) - Add support for skipping `npm-shrinkwrap.json` extraction when the - registry can affirm that one doesn't exist. - ([@iarna](https://github.com/iarna)) - -#### INTERRUPTING SCRIPTS - -* [`878aceb25`](https://github.com/npm/npm/commit/878aceb25e6d6052dac15da74639ce274c8e62c5) - [#16129](https://github.com/npm/npm/pull/16129) - Better handle Ctrl-C while running scripts. `npm` will now no longer exit - until the script it is running has exited. If you press Ctrl-C a second - time it kill the script rather than just forwarding the Ctrl-C. - ([@jaridmargolin](https://github.com/jaridmargolin)) - -#### DEPENDENCY UPDATES: - -* [`def75eebf`](https://github.com/npm/npm/commit/def75eebf1ad437bf4fd3f5e103cc2d963bd2a73) - `hosted-git-info@2.4.1`: - Preserve case of the user name part of shortcut specifiers, previously they were lowercased. - ([@iarna](https://github.com/iarna)) -* [`eb3789fd1`](https://github.com/npm/npm/commit/eb3789fd18cfb063de9e6f80c3049e314993d235) - `node-gyp@3.6.0`: Add support for VS2017 and Chakracore improvements. - ([@refack](https://github.com/refack)) - ([@kunalspathak](https://github.com/kunalspathak)) -* [`245e25315`](https://github.com/npm/npm/commit/245e25315524b95c0a71c980223a27719392ba75) - `readable-stream@2.2.6` ([@mcollina](https://github.com/mcollina)) -* [`30357ebc5`](https://github.com/npm/npm/commit/30357ebc5691d7c9e9cdc6e0fe7dc6253220c9c2) - `which@1.2.14` ([@isaacs](https://github.com/isaacs)) - -### v4.4.4 (2017-03-16) - -😩😤😅 Okay! We have another `next` -release for ya today. So, yes! With v4.4.3 we fixed the bug that made -bundled scoped modules uninstallable. But somehow I overlooked the fact -that we: A) were using these and B) that made upgrading to v4.4.3 impossible. 😭 - -So I've renamed those two scoped modules to no longer use scopes and we now -have a shiny new test to ensure that scoped modules don't creep into our -transitive deps and make it impossible to upgrade to `npm`. - -(None of our woes applies to most of you all because most of you all don't -use bundled dependencies. `npm` does because we want the published artifact to be -installable without having to already have `npm`.) - -* [`2a7409fcb`](https://github.com/npm/npm/commit/2a7409fcba6a8fab716c80f56987b255983e048e) - [#16066](https://github.com/npm/npm/pull/16066) - Ensure we aren't using any scoped modules - Because `npm`s prior 4.4.3 can't install dependencies that have bundled scoped - modules. This didn't show up sooner because they ALSO had a bug that caused - bundled scoped modules to not be included in the bundle. - ([@iarna](https://github.com/iarna)) -* [`eb4c70796`](https://github.com/npm/npm/commit/eb4c70796c38f24ee9357f5d4a0116db582cc7a9) - [#16066](https://github.com/npm/npm/pull/16066) - Switch to move-concurrently to remove scoped dependency - ([@iarna](https://github.com/iarna)) - -### v4.4.3 (2017-03-15) - -This is a small patch release, mostly because the published tarball for -v4.4.2 was missing a couple of modules, due to a bug involving scoped -modules, bundled dependencies and legacy tree layouts. - -There are a couple of other things here that happened to be ready to go. So -without further ado… - -#### BUG FIXES - -* [`3d80f8f70`](https://github.com/npm/npm/commit/3d80f8f70679ad2b8ce7227d20e8dbce257a47b9) - [npm/fs-vacuum#6](https://github.com/npm/fs-vacuum/pull/6) - `fs-vacuum@1.2.1`: Make sure we never, ever remove home directories. Previously if your - home directory was entirely empty then we might `rmdir` it. - ([@helio-frota](https://github.com/helio-frota)) -* [`1af85ca9f`](https://github.com/npm/npm/commit/1af85ca9f4d625f948e85961372de7df3f3774e2) - [#16040](https://github.com/npm/npm/pull/16040) - Fix bug where bundled transitive dependencies that happened to be - installed under bundled scoped dependencies wouldn't be included in the - tarball when building a package. - ([@iarna](https://github.com/iarna)) -* [`13c7fdc2e`](https://github.com/npm/npm/commit/13c7fdc2e87456a87b1c9385a3daeae228ed7c95) - [#16040](https://github.com/npm/npm/pull/16040) - Fix a bug where bundled scoped dependencies couldn't be extracted. - ([@iarna](https://github.com/iarna)) -* [`d6cde98c2`](https://github.com/npm/npm/commit/d6cde98c2513fe160eab41e31c3198dfde993207) - [#16040](https://github.com/npm/npm/pull/16040) - Stop printing `ENOENT` errors more than once. - ([@iarna](https://github.com/iarna)) -* [`722fbf0f6`](https://github.com/npm/npm/commit/722fbf0f6cf4413cdc24b610bbd60a7dbaf2adfe) - [#16040](https://github.com/npm/npm/pull/16040) - Rewrite the `extract` action for greater clarity. - Specifically, this involves moving things around structurally to do the same - thing [`d0c6d194`](https://github.com/npm/npm/commit/d0c6d194) did, but in a more comprehensive manner. - This also fixes a long standing bug where errors from the move step would be - eaten during this phase and as a result we would get mysterious crashes in - the finalize phase when finalize tried to act on them. - ([@iarna](https://github.com/iarna)) -* [`6754dabb6`](https://github.com/npm/npm/commit/6754dabb6bd3301504efb3b62f36d3fe70958c19) - [#16040](https://github.com/npm/npm/pull/16040) - Flatten out `@npmcorp/move`'s deps for backwards compatibility reasons. Versions prior to this - one will fail to install any package that bundles a scoped dependency. This was responsible - for `ENOENT` errors during the `finalize` phase. - ([@iarna](https://github.com/iarna)) - -#### DOC UPDATES - -* [`fba51c582`](https://github.com/npm/npm/commit/fba51c582d1d08dd4aa6eb27f9044dddba91bb18) - [#15960](https://github.com/npm/npm/pull/15960) - Update troubleshooting and contribution guide links. - ([@watilde](https://github.com/watilde)) - - -### v4.4.2 (2017-03-09): - -This week, the focus on the release was mainly going through [all of npm's deps -that we manage -ourselves](https://github.com/npm/npm/wiki/npm-maintained-dependencies), and -making sure all their PRs and versions were up to date. That means there's a few -fixes here and there. Nothing too big codewise, though. - -The most exciting part of this release is probably our [shiny new -Contributing](https://github.com/npm/npm/blob/latest/CONTRIBUTING.md) and -[Troubleshooting](https://github.com/npm/npm/blob/latest/TROUBLESHOOTING.md) -docs! [@snopeks](https://github.com/snopeks) did some ✨fantastic✨ work hashing it -out, and we're really hoping this is a nice big step towards making contributing -to npm easier. The troubleshooting doc will also hopefully solve common issues -for people! Do you think something is missing from it? File a PR and we'll add -it! The current document is just a baseline for further editing and additions. - -Also there's maybe a bit of an easter egg in this release. 'Cause those are fun and I'm a huge nerd. 😉 - -#### DOCUMENTATION AHOY - -* [`07e997a`](https://github.com/npm/npm/commit/07e997a7ecedba7b29ad76ffb2ce990d5c0200fc) - [#15756](https://github.com/npm/npm/pull/15756) - Overhaul `CONTRIBUTING.md` and add new `TROUBLESHOOTING.md` files. 🙌🏼 - ([@snopeks](https://github.com/snopeks)) -* [`2f3e4b6`](https://github.com/npm/npm/commit/2f3e4b645cdc268889cf95ba24b2aae572d722ad) - [#15833](https://github.com/npm/npm/pull/15833) - Mention the [24-hour unpublish - policy](http://blog.npmjs.org/post/141905368000/changes-to-npms-unpublish-policy) - on the main registry. - ([@carols10cents](https://github.com/carols10cents)) - -#### NOT REALLY FEATURES, NOT REALLY BUGFIXES. MORE LIKE TWEAKS? 🤔 - -* [`84be534`](https://github.com/npm/npm/commit/84be534aedb78c65cd8012427fc04871ceeccf90) - [#15888](https://github.com/npm/npm/pull/15888) - Stop flattening `ls`-tree output. From now on, deduped deps will be marked as - such in the place where they would've been before getting hoisted by the - installer. - ([@iarna](https://github.com/iarna)) -* [`e9a5dca`](https://github.com/npm/npm/commit/e9a5dca369ead646ab5922326cede1406c62bd3b) - [#15967](https://github.com/npm/npm/pull/15967) - Limit metadata fetches to 10 concurrent requests. - ([@iarna](https://github.com/iarna)) -* [`46aa9bc`](https://github.com/npm/npm/commit/46aa9bcae088740df86234fc199f7aef53b116df) - [#15967](https://github.com/npm/npm/pull/15967) - Limit concurrent installer actions to 10. - ([@iarna](https://github.com/iarna)) - -#### BUGFIXES - -* [`c3b994b`](https://github.com/npm/npm/commit/c3b994b71565eb4f943cce890bb887d810e6e2d4) - [#15901](https://github.com/npm/npm/pull/15901) - Use EXDEV aware move instead of rename. This will allow moving across devices - and moving when filesystems don't support renaming directories full of files. It might make folks using Docker a bit happier. - ([@iarna](https://github.com/iarna)) -* [`0de1a9c`](https://github.com/npm/npm/commit/0de1a9c1db90e6705c65c068df1fe82899e60d68) - [#15735](https://github.com/npm/npm/pull/15735) - Autocomplete support for npm scripts with `:` colons in the name. - ([@beyondcompute](https://github.com/beyondcompute)) -* [`84b0b92`](https://github.com/npm/npm/commit/84b0b92e7f78ec4add42e8161c555325c99b7f98) - [#15874](https://github.com/npm/npm/pull/15874) - Stop using [undocumented](https://github.com/nodejs/node/pull/11355) - `res.writeHeader` alias for `res.writeHead`. - ([@ChALkeR](https://github.com/ChALkeR)) -* [`895ffe4`](https://github.com/npm/npm/commit/895ffe4f3eecd674796395f91c30eda88aca6b36) - [#15824](https://github.com/npm/npm/pull/15824) - Fix empty versions column in `npm search` output. - ([@bcoe](https://github.com/bcoe)) -* [`38c8d7a`](https://github.com/npm/npm/commit/38c8d7adc1f43ab357d1e729ae7cd5d801a26e68) - `init-package-json@1.9.5`: [npm/init-package-json#61](https://github.com/npm/init-package-json/pull/61) Exclude existing `devDependencies` from being added to `dependencies`. Fixes [#12260](https://github.com/npm/npm/issues/12260). - ([@addaleax](https://github.com/addaleax)) - -### v4.4.1 (2017-03-06): - -This is a quick little patch release to forgo the update notification -checker if you're on an unsupported (but not otherwise broken) version of -Node.js. Right now that means 0.10 or 0.12. - -* [`56ac249`](https://github.com/npm/npm/commit/56ac249ef8ede1021f1bc62a0e4fe1e9ba556af2) - [#15864](https://github.com/npm/npm/pull/15864) - Only use `update-notifier` on supported versions. - ([@legodude17](https://github.com/legodude17)) - -### v4.4.0 (2017-02-23): - -Aaaah, [@iarna](https://github.com/iarna) here, it's been a little while -since I did one of these! This is a nice little release, we've got an -update notifier, vastly less verbose error messages, new warnings on package -metadata that will probably give you a bad day, and a sprinkling of bug -fixes. - -#### UPDATE NOTIFICATIONS - -We now have a little nudge to update your `npm`, courtesy of -[update-notifier](https://www.npmjs.com/package/update-notifier). - -* [`148ee66`](https://github.com/npm/npm/commit/148ee663740aa05877c64f16cdf18eba33fbc371) - [#15774](https://github.com/npm/npm/pull/15774) - `npm` will now check at start up to see if a newer version is available. - It will check once a day. If you want to disable this, set `optOut` to `true` in - `~/.config/configstore/update-notifier-npm.json`. - ([@ceejbot](https://github.com/ceejbot)) - -#### LESS VERBOSE ERROR MESSAGES - -`npm` has, for a long time, had very verbose error messages. There was a -lot of info in there, including the cause of the error you were seeing but -without a lot of experience reading them pulling that out was time consuming -and difficult. - -With this change the output is cut down substantially, centering the error -message. So, for example if you try to `npm run sdlkfj` then the entire -error you'll get will be: - -``` -npm ERR! missing script: sldkfj - -npm ERR! A complete log of this run can be found in: -npm ERR! /Users/rebecca/.npm/_logs/2017-02-24T00_41_36_988Z-debug.log -``` - -The CLI team has discussed cutting this down even further and stripping the -`npm ERR!` prefix off those lines too. We'd appreciate your feedback on -this! - -* [`e544124`](https://github.com/npm/npm/commit/e544124592583654f2970ec332003cfd00d04f2b) - [#15716](https://github.com/npm/npm/pull/15716) - Make error output less verbose. - ([@iarna](https://github.com/iarna)) -* [`166bda9`](https://github.com/npm/npm/commit/166bda97410d0518b42ed361020ade1887e684af) - [#15716](https://github.com/npm/npm/pull/15716) - Stop encouraging users to visit the issue tracker unless we know for - certain that it's an npm bug. - ([@iarna](https://github.com/iarna)) - -#### OTHER NEW FEATURES - -* [`53412eb`](https://github.com/npm/npm/commit/53412eb22c1c75d768e30f96d69ed620dfedabde) - [#15772](https://github.com/npm/npm/pull/15772) - We now warn if you have a module listed in both dependencies and - devDependencies. - ([@TedYav](https://github.com/TedYav)) -* [`426b180`](https://github.com/npm/npm/commit/426b1805904a13bdc5c0dd504105ba037270cbee) - [#15757](https://github.com/npm/npm/pull/15757) - Default reporting metrics to default registry. Previously it defaulted to using - `https://registry.npmjs.org`, now it will default to the result of - `npm config get registry`. For most folks this won't actually change anything, but it - means that folks who use a private registry will have metrics routed there by default. - This has the potential to be interesting because it means that in the - future private registry products ([npme](https://npme.npmjs.com/docs/)!) - will be able to report on these metrics. - ([@iarna](https://github.com/iarna)) - -#### BUG FIXES - -* [`8ea0de9`](https://github.com/npm/npm/commit/8ea0de98563648ba0db032acd4d23d27c4a50a66) - [#15716](https://github.com/npm/npm/pull/15716) - Write logs for `cb() never called` errors. -* [`c4e83dc`](https://github.com/npm/npm/commit/c4e83dca830b24305e3cb3201a42452d56d2d864) - Make it so that errors while reading the existing node_modules tree can't - result in installer crashes. - ([@iarna](https://github.com/iarna)) -* [`2690dc2`](https://github.com/npm/npm/commit/2690dc2684a975109ef44953c2cf0746dbe343bb) - Update `npm doctor` to not treat broken symlinks in your global modules as - a permission failure. This is particularly important if you link modules and your text - editor uses the convention of creating symlinks from `.#filename.js` to a - machine name and pid to lock files (eg emacs and compatible things). - ([@iarna](https://github.com/iarna)) -* [`f4c3f48`](https://github.com/npm/npm/commit/f4c3f489aa5787cf0d60e8436be2190e4b0d0ff7) - [#15777](https://github.com/npm/npm/pull/15777) - Not exactly a bug, but change a parameterless `.apply` to `.call`. - ([@notarseniy](https://github.com/notarseniy)) - -#### DEPENDENCY UPDATES - -* [`549dcff`](https://github.com/npm/npm/commit/549dcff58c7aaa1e7ba71abaa14008fdf2697297) - `rimraf@2.6.0`: - Retry EBUSY, ENOTEMPTY and EPERM on non-Windows platforms too. - More reliable `rimraf.sync` on Windows. - ([@isaacs](https://github.com/isaacs)) -* [`052dfb6`](https://github.com/npm/npm/commit/052dfb623da508f2b5f681da0258125552a18a4a) - `validate-npm-package-name@3.0.0`: - Remove ableist language in README. - Stop allowing ~'!()* in package names. - ([@tomdale](https://github.com/tomdale)) - ([@chrisdickinson](https://github.com/chrisdickinson)) -* [`6663ea6`](https://github.com/npm/npm/commit/6663ea6ac0f0ecec5a3f04a3c01a71499632f4dc) - `abbrev@1.1.0` ([@isaacs](https://github.com/isaacs)) -* [`be6de9a`](https://github.com/npm/npm/commit/be6de9aab9e20b6eac70884e8626161eebf8721a) - `opener@1.4.3` ([@dominic](https://github.com/dominic)) -* [`900a5e3`](https://github.com/npm/npm/commit/900a5e3e3411ec221306455f99b24b9ce35757c0) - `readable-stream@2.2.3` ([@RangerMauve](https://github.com/RangerMauve)) ([@mcollina](https://github.com/mcollina)) -* [`c972a8b`](https://github.com/npm/npm/commit/c972a8b0f20a61a79c45b6642f870bea8c55c7e4) - `tacks@1.2.6` - ([@iarna](https://github.com/iarna)) -* [`85a36ef`](https://github.com/npm/npm/commit/85a36efdac0c24501876875cb9ad40292024e0b0) - [`7ac9265`](https://github.com/npm/npm/commit/7ac9265c56b4d9eeaca6fcfb29513f301713e7bb) - `tap@10.2.0` - ([@isaacs](https://github.com/saacs)) - -### v4.3.0 (2017-02-09): - -Yay! Release time! It's a rainy day, and we have another smallish release for -y'all. These things are not necessarily related. Or are they 🌧🤔 - -As far as news go, you may have noticed that the CLI team dropped support for -`node@0.12` when that version went out of maintenance. Still, we've avoided -explicitly breaking it and `node@0.10` so far -- but not much longer. - -Sometime soon, the CLI team plans on switching over to language features only -available as of `node@4 LTS`, and will likely start dropping old versions of node -as they go out of maintenance. The new features are exciting! We're really -looking forward to using them in the core CLI (and its dependencies) as we keep up -with our current feature work. - -And speaking of features, this release is a minor bump due to a small change in -how `npm login` works for the sake of supporting OAuth-based login for npm -Enterprise users. But we won't leave the rest of y'all out -- we're working on a -larger version of this feature. Soon enough, you'll be able to log in to npm -with, say, GitHub -- and use some shiny features that come from the integration. -Or turn on 2FA and other such security features. Keep your eyes peeled for new -on this in the next few releases and our weekly newsletter! - -#### NEW AUTH TYPES - -There's a new command line option: `--auth-type`, which can be used to log in to -a supporting registry with OAuth2 or SAML. The current implementation is mainly -meant to support npmE customers, so if you're one of those: ask us about using -it! If not, just hold off cause we'll have a much more complete version of this -feature out soon. - -* [`ac8595e`](https://github.com/npm/npm/commit/ac8595e3c9b615ff95abc3301fac1262c434792c) [`bcf2dd8`](https://github.com/npm/npm/commit/bcf2dd8a165843255c06515fa044c6e4d3b71ca4) [`9298d20`](https://github.com/npm/npm/commit/9298d20af58b92572515bfa9cf7377bd4221dc7d) [`66b61bc`](https://github.com/npm/npm/commit/66b61bc42e81ee8a1ee00fc63517f62284140688) [`dc85de7`](https://github.com/npm/npm/commit/dc85de7df6bb61f7788611813ee82ae695a18f1f) - [#13389](https://github.com/npm/npm/pull/13389) - Implement single-sign-on support with `--auth-type` option. - ([@zkat](https://github.com/zkat)) - -#### FASTER STARTUP. SOMETIMES! - -`request` is pretty heavy. And it loads a bunch of things. It's actually a -pretty big chunk of npm's load time. This small patch by Rebecca will make it so -npm only loads that module when we're actually intending to make network -requests. Those of you who use npm commands that run offline might see a small -speedup in startup time. - -* [`ac73568`](https://github.com/npm/npm/commit/ac735682e666e8724549d56146821f3b8b018e25) - [#15631](https://github.com/npm/npm/pull/15631) - Lazy load `caching-registry-client`. - ([@iarna](https://github.com/iarna)) - -#### DOCUMENTATION - -* [`4ad9247`](https://github.com/npm/npm/commit/4ad9247aa82f7553c9667ee93c74ec7399d6ceec) - [#15630](https://github.com/npm/npm/pull/15630) - Fix formatting/rendering for root npm README. - ([@ungoldman](https://github.com/ungoldman)) - -#### DEPENDENCY UPDATES - -* [`8cc1112`](https://github.com/npm/npm/commit/8cc1112958638ff88ac2c24c4a065acacb93d64b) - [npm/hosted-git-info#21](https://github.com/npm/hosted-git-info/pull/21) - `hosted-git-info@2.2.0`: - Add support for `.tarball()` URLs. - ([@zkat](https://github.com/zkat)) -* [`6eacc1b`](https://github.com/npm/npm/commit/6eacc1bc1925fe3cc79fc97bdc3194d944fce55e) - `npm-registry-mock@1.1.0` - ([@addaleax](https://github.com/addaleax)) -* [`a9b6d77`](https://github.com/npm/npm/commit/a9b6d775e61cf090df0e13514c624f99bf31d1e7) - `aproba@1.1.1` - ([@iarna](https://github.com/iarna)) - -### v4.2.0 (2017-01-26): - -Hi all! I'm Kat, and I'm currently sitting in a train traveling at ~300km/h -through Spain. So clearly, this release should have *something* to do with -speed. And it does! Heck, with this release, you could say we're really -_blazing_, even. 🌲🔥😏 - -#### IMPROVED CLI SEARCH~ - -You might recall if you've been keeping up that one of the reasons for a -semver-major bump to `npm@4` was an improved CLI search (read: no longer blowing -up Node). The work done for that new search system, while still relying on a -full metadata download and local search, was also meant to act as groundwork for -then-ongoing work on a brand-new, smarter search system for npm. Shortly after -`npm@4` came out, the bulk of the server-side work was done, and with this -release, the npm CLI has integrated use of the new endpoint for high-quality, -fast-turnaround searches. - -No, seriously, it's *fast*. And *relevant*: - -[![GOTTA GO FAST! This is a gif of the new npm search returning results in around a second for `npm search web framework`.](https://cloud.githubusercontent.com/assets/17535/21954136/f007e8be-d9fd-11e6-9231-f899c12790e0.gif)](https://github.com/npm/npm/pull/15481) - -Give it a shot! And remember to check out the new website version of the search, -too, which uses the same backend as the CLI now. 🎉 - -Incidentally, the backend is a public service, so you can write your own search -tools, be they web-based, CLI, or GUI-based. You can read up on the [full -documentation for the search -endpoint](https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get-v1search), -and let us know about the cool things you come up with! - -* [`ce3ca51`](https://github.com/npm/npm/commit/ce3ca51ca2d60e15e901c8bf6256338e53e1eca2) - [#15481](https://github.com/npm/npm/pull/15481) - Add an internal `gunzip-maybe` utility for optional gunzipping. - ([@zkat](https://github.com/zkat)) -* [`e322932`](https://github.com/npm/npm/commit/e3229324d507fda10ea9e94fd4de8a4ae5025c75) [`a53055e`](https://github.com/npm/npm/commit/a53055e423f1fe168f05047aa0dfec6d963cb211) [`a1f4365`](https://github.com/npm/npm/commit/a1f436570730c6e4a173ca92d1967a87c29b7f2d) [`c56618c`](https://github.com/npm/npm/commit/c56618c62854ea61f6f716dffe7bcac80b5f4144) - [#15481](https://github.com/npm/npm/pull/15481) - Add support for using the new npm search endpoint for fast, quality search - results. Includes a fallback to "classic" search. - ([@zkat](https://github.com/zkat)) - -#### WHERE DID THE DEBUG LOGS GO - -This is another pretty significant change: Usually, when the npm process -crashed, you would get an `npm-debug.log` in your current working directory. -This debug log would get cleared out as soon as you ran npm again. This was a -bit annoying because 1) you would get a random file in your `git status` that -you might accidentally commit, and 2) if you hit a hard-to-reproduce bug and -instinctually tried again, you would no longer have access to the repro -`npm-debug.log`. - -So now, any time a crash happens, we'll save your debug logs to your cache -folder, under `_logs` (`~/.npm` on *nix, by default -- use `npm config get -cache` to see what your current value is). The cache will now hold a -(configurable) number of `npm-debug.log` files, which you can access in the -future. Hopefully this will help clean stuff up and reduce frustration from -missed repros! In the future, this will also be used by `npm report` to make it -super easy to put up issues about crashes you run into with npm. 💃🕺🏿👯‍♂️ - -* [`04fca22`](https://github.com/npm/npm/commit/04fca223a0f704b69340c5f81b26907238fad878) - [#11439](https://github.com/npm/npm/pull/11439) - Put debug logs in `$(npm get cache)/_logs` and store multiple log files. - ([@KenanY](https://github.com/KenanY)) - ([@othiym23](https://github.com/othiym23)) - ([@isaacs](https://github.com/isaacs)) - ([@iarna](https://github.com/iarna)) - -#### DOCS - -* [`ae8e71c`](https://github.com/npm/npm/commit/ae8e71c2b7d64d782af287a21e146d7cea6e5273) - [#15402](https://github.com/npm/npm/pull/15402) - Add missing backtick in one of the `npm doctor` messages. - ([@watilde](https://github.com/watilde), [@charlotteis](https://github.com/charlotteis)) -* [`821fee6`](https://github.com/npm/npm/commit/821fee6d0b12a324e035c397ae73904db97d07d2) - [#15480](https://github.com/npm/npm/pull/15480) - Clarify that unscoped packages can depend on scoped packages and vice-versa. - ([@chocolateboy](https://github.com/chocolateboy)) -* [`2ee45a8`](https://github.com/npm/npm/commit/2ee45a884137ae0706b7c741c671fef2cb3bac96) - [#15515](https://github.com/npm/npm/pull/15515) - Update minimum supported Node version number in the README to `node@>=4`. - ([@watilde](https://github.com/watilde)) -* [`af06aa9`](https://github.com/npm/npm/commit/af06aa9a357578a8fd58c575f3dbe55bc65fc376) - [#15520](https://github.com/npm/npm/pull/15520) - Add section to `npm-scope` docs to explain that scope owners will own scoped - packages with that scope. That is, user `@alice` is not allowed to publish to - `@bob/my-package` unless explicitly made an owner by user (or org) `@bob`. - ([@hzoo](https://github.com/hzoo)) -* [`bc892e6`](https://github.com/npm/npm/commit/bc892e6d07a4c6646480703641a4d71129c38b6d) - [#15539](https://github.com/npm/npm/pull/15539) - Replace `http` with `https` and fix typos in some docs. - ([@watilde](https://github.com/watilde)) -* [`1dfe875`](https://github.com/npm/npm/commit/1dfe875b9ac61a0ab9f61a2eab02bacf6cce583c) - [#15545](https://github.com/npm/npm/pull/15545) - Update Node.js download link to point to the right place. - ([@watilde](https://github.com/watilde)) - -#### DEPENDENCIES - - * [`b824bfb`](https://github.com/npm/npm/commit/b824bfbeb2d89c92762e9170b026af98b5a3668a) - `ansi-regex@2.1.1` - * [`81ea3e8`](https://github.com/npm/npm/commit/81ea3e8e4ea34cd9c2b418512dcb508abcee1380) - `mississippi@1.3.0` - -#### MISC - -* [`98df212`](https://github.com/npm/npm/commit/98df212a91fd6ff4a02b9cd247f4166f93d3977a) - [#15492](https://github.com/npm/npm/pull/15492) - Update the "master" node version used for AppVeyor to `node@7`. - ([@watilde](https://github.com/watilde)) -* [`d75fc03`](https://github.com/npm/npm/commit/d75fc03eda5364f12ac266fa4f66e31c2e44e864) - [#15413](https://github.com/npm/npm/pull/15413) - `npm run-script` now exits with the child process' exit code on exit. - ([@kapals](https://github.com/kapals)) - -### v4.1.2 (2017-01-12) - -We have a twee little release this week as we come back from the holidays. - -#### 0.12 IS UNSUPPORTED NOW (really) - -After [jumping the gun a -little](https://github.com/npm/npm/releases/tag/v4.0.2), we can now -officially remove 0.12 from our supported versions list. The Node.js -project has now officially ended even maintenance support for 0.12 and thus, -so will we. To reiterate from the last time we did this: - -What this means: - -* Your contributions will no longer block on the tests passing on 0.12. -* We will no longer block dependency upgrades on working with 0.12. -* Bugs filed on the npm CLI that are due to incompatibilities with 0.12 - (and older versions) will be closed with a strong urging to upgrade to a - supported version of Node. -* On the flip side, we'll continue to (happily!) accept patches that - address regressions seen when running the CLI with Node.js 0.12. - -What this doesn't mean: - -* The CLI is going to start depending on ES2015+ features. npm continues - to work, in almost all cases, all the way back to Node.js 0.8, and our - long history of backwards compatibility is a source of pride for the - team. -* We aren't concerned about the problems of users who, for whatever - reason, can't update to newer versions of npm. As mentioned above, we're - happy to take community patches intended to address regressions. - -We're not super interested in taking sides on what version of Node.js -you "should" be running. We're a workflow tool, and we understand that -you all have a diverse set of operational environments you need to be -able to support. At the same time, we _are_ a small team, and we need -to put some limits on what we support. Tracking what's supported by our -runtime's own team seems most practical, so that's what we're doing. - -* [`c7bbba8`](https://github.com/npm/npm/commit/c7bbba8744b62448103a1510c65d9751288abb5d) - Remove 0.12 from our supported versions list. - ([@iarna](https://github.com/iarna)) - -#### WRITING TO SYMLINKED `package.json` (AND OTHER FILES) - -If your `package.json`, `npm-shrinkwrap.json` or `.npmrc` were a symlink and -you used an `npm` command that modified one of these (eg `npm config set` or -`npm install --save`) then previously we would have removed your symlink and -replaced it with an ordinary file. While making these files symlinks is pretty -uncommon, this was still surprising behavior. With this fix we now overwrite -the _destination_ of the symlink and preserve the symlink itself. - -* [`a583983`](https://github.com/npm/npm/commit/a5839833d3de7072be06884b91902c093aff1aed) - [write-file-atomic/#5](https://github.com/npm/write-file-atomic/issues/5) - [#10223](https://github.com/npm/npm/10223) - `write-file-atomic@1.3.1`: - When the target is a symlink, write-file-atomic now overwrites the - _destination_ of the symlink, instead of replacing the symlink itself. This - makes it's behavior match `fs.writeFile`. - - Fixed a bug where it would ALWAYS fs.stat to look up default mode and chown - values even if you'd passed them in. (It still used the values you passed - in, but did a needless stat.) - ([@iarna](https://github.com/iarna)) - -#### DEPENDENCY UPDATES - -* [`521f230`](https://github.com/npm/npm/commit/521f230dd57261e64ac9613b3db62f5312971dca) - `node-gyp@3.5.0`: - Improvements to how Python is located. New `--devdir` flag. - ([@bnoordhuis](https://github.com/bnoordhuis)) - ([@mhart](https://github.com/mhart)) -* [`ccd83e8`](https://github.com/npm/npm/commit/ccd83e8a70d35fb0904f8a9adb2ff7ac8a6b2706) - `JSONStream@1.3.0`: - Add new emitPath option. - ([@nathanwills](https://github.com/nathanwills)) - -#### TEST IMPROVEMENTS - -* [`d76e084`](https://github.com/npm/npm/commit/d76e08463fd65705217624b861a1443811692f34) - Disable metric reporting for test suite even if the user has it enabled. - ([@iarna](https://github.com/iarna)) - -### v4.1.1 (2016-12-16) - -This fixes a bug in the metrics reporting where, if you had enabled it then -installs would create a metrics reporting process, that would create a -metrics reporting process, that would… well, you get the idea. The only -way to actually kill these processes is to turn off your networking, then -on MacOS/Linux kill them with `kill -9`. Alternatively you can just reboot. - -Anyway, this is a quick release to fix that bug: - -* [`51c393f`](https://github.com/npm/npm/commit/51c393feff5f4908c8a9fb02baef505b1f2259be) - [#15237](https://github.com/npm/npm/pull/15237) - Don't launch a metrics sender process if we're running from a metrics - sender process. - ([@iarna](https://github.com/iarna)) - -### v4.1.0 (2016-12-15) - -I'm really excited about `npm@4.1.0`. I know, I know, I'm kinda overexcited -in my changelogs, but this one is GREAT. We've got a WHOLE NEW subcommand, I -mean, when was the last time you saw that? YEARS! And we have the beginnings -of usage metrics reporting. Then there's a fix for a really subtle bug that -resulted in `shasum` errors. And then we also have a few more bug fixes and -other improvements. - -#### ANONYMOUS METRIC REPORTING - -We're adding the ability for you all to help us track the quality of your -experiences using `npm`. Metrics will be sent if you run: - -``` -npm config set send-metrics true -``` - -Then `npm` will report to `registry.npmjs.org` the number of successful and -failed installations you've had. The data contains no identifying -information and npm will not attempt to correlate things like IP address -with the metrics being submitted. - -Currently we only track number of successful and failed installations. In -the future we would like to find additional metrics to help us better -quantify the quality of the `npm` experience. - -* [`190a658`](https://github.com/npm/npm/commit/190a658c4222f6aa904cbc640fc394a5c875e4db) - [#15084](https://github.com/npm/npm/pull/15084) - Add facility for recording and reporting success metrics. - ([@iarna](https://github.com/iarna)) -* [`87afc8b`](https://github.com/npm/npm/commit/87afc8b466f553fb49746c932c259173de48d0a4) - [npm/npm-registry-client#147](https://github.com/npm/npm-registry-client/pull/148) - `npm-registry-client@7.4.5`: - Add support for sending anonymous CLI metrics. - ([@iarna](https://github.com/iarna), - [@sisidovski](https://github.com/sisidovski)) - -### NPM DOCTOR - -<pre> -<u>Check</u> <u>Value</u> <u>Recommendation</u> -npm ping ok -npm -v v4.0.5 -node -v v4.6.1 Use node v6.9.2 -npm config get registry https://registry.npmjs.org/ -which git /Users/rebecca/bin/git -Perms check on cached files ok -Perms check on global node_modules ok -Perms check on local node_modules ok -Checksum cached files ok -</pre> - -It's a rare day that we add a new command to `npm`, so I'm excited to -present to you `npm doctor`. It checks for a number of common problems and -provides some recommended solutions. It was put together through the hard -work of [@watilde](https://github.com/watilde). - -* [`2359505`](https://github.com/npm/npm/commit/23595055669f76c9fe8f5f1cf4a705c2e794f0dc) - [`0209ee5`](https://github.com/npm/npm/commit/0209ee50448441695fbf9699019d34178b69ba73) - [#14582](https://github.com/npm/npm/pull/14582) - Add new `npm doctor` to give your project environment a health check. - ([@watilde](https://github.com/watilde)) - -#### FIX MAJOR SOURCE OF SHASUM ERRORS - -If you've been getting intermittent shasum errors then you'll be pleased to -know that we've tracked down at least one source of them, if not THE source -of them. - -* [`87afc8b`](https://github.com/npm/npm/commit/87afc8b466f553fb49746c932c259173de48d0a4) - [#14626](https://github.com/npm/npm/issues/14626) - [npm/npm-registry-client#148](https://github.com/npm/npm-registry-client/pull/148) - `npm-registry-client@7.4.5`: - Fix a bug where an `ECONNRESET` while fetching a package file would result - in a partial download that would be reported as a "shasum mismatch". It - now throws away the partial download and retries it. - ([@iarna](https://github.com/iarna)) - -#### FILE URLS AND NODE.JS 7 - -When `npm` was formatting `file` URLs we took advantage of `url.format` to -construct them. Node.js 7 changed the behavior in such a way that our use of -`url.format` stopped producing URLs that we could make use of. - -The reasons for this have to do with the `file` URL specification and how -invalid (according to the specification) URLs are handled. How this changed -is most easily explained with a table: - -<table> -<tr><th></th><th>URL</th><th>Node.js <= 6</th><th><tt>npm</tt>'s understanding</th><th>Node.js 7</th><th><tt>npm</tt>'s understanding</th></tr> -<tr><td>VALID</td><td><tt>file:///abc/def</tt></td><td><tt>file:///abc/def</tt></td><td><tt>/abc/def</tt></td><td><tt>file:///abc/def</tt></td><td><tt>/abc/def</tt></td></tr> -<tr><td>invalid</td><td><tt>file:/abc/def</tt></td><td><tt>file:/abc/def</tt></td><td><tt>/abc/def</tt></td><td><tt>file:///abc/def</tt></td><td><tt>/abc/def</tt></td></tr> -<tr><td>invalid</td><td><tt>file:abc/def</tt></td><td><tt>file:abc/def</tt></td><td><tt>$CWD/abc/def</tt></td><td><tt>file://abc/def</tt></td><td><tt>/def</tt> on the <tt>abc</tt> host</td></tr> -<tr><td>invalid</td><td><tt>file:../abc/def</tt></td><td><tt>file:../abc/def</tt></td><td><tt>$CWD/../abc/def</tt></td><td><tt>file://../abc/def</tt></td><td><tt>/abc/def</tt> on the <tt>..</tt> host</td></tr> -</table> - -So the result was that passing a `file` URL that npm had received that used -through Node.js 7's `url.format` changed its meaning as far as `npm` was -concerned. As those kinds of URLs are, per the specification, invalid, how -they should be handled is undefined and so the change in Node.js wasn't a -bug per se. - -Our solution is to stop using `url.format` when constructing this kind of -URL. - -* [`173935b`](https://github.com/npm/npm/commit/173935b4298e09c4fdcb8f3a44b06134d5aff181) - [#15114](https://github.com/npm/npm/issues/15114) - Stop using `url.format` for relative local dep paths. - ([@zkat](https://github.com/zkat)) - -#### EXTRANEOUS LIFECYCLE SCRIPT EXECUTION WHEN REMOVING - -* [`afb1dfd`](https://github.com/npm/npm/commit/afb1dfd944e57add25a05770c0d52d983dc4e96c) - [#15090](https://github.com/npm/npm/pull/15090) - Skip top level lifecycles when uninstalling. - ([@iarna](https://github.com/iarna)) - -#### REFACTORING AND INTERNALS - -* [`c9b279a`](https://github.com/npm/npm/commit/c9b279aca0fcb8d0e483e534c7f9a7250e2a9392) - [#15205](https://github.com/npm/npm/pull/15205) - [#15196](https://github.com/npm/npm/pull/15196) - Only have one function that determines which version of a package to use - given a specifier and a list of versions. - ([@iarna](https://github.com/iarna), - [@zkat](https://github.com/zkat)) - -* [`981ce63`](https://github.com/npm/npm/commit/981ce6395e7892dde2591b44e484e191f8625431) - [#15090](https://github.com/npm/npm/pull/15090) - Rewrite prune to use modern npm plumbing. - ([@iarna](https://github.com/iarna)) - -* [`bc4b739`](https://github.com/npm/npm/commit/bc4b73911f58a11b4a2d28b49e24b4dd7365f95b) - [#15089](https://github.com/npm/npm/pull/15089) - Rename functions and variables in the module that computes what changes to - make to your installation. - ([@iarna](https://github.com/iarna)) - -* [`2449f74`](https://github.com/npm/npm/commit/2449f74a202b3efdb1b2f5a83356a78ea9ecbe35) - [#15089](https://github.com/npm/npm/pull/15089) - When computing changes to make to your installation, use a function to add - new actions to take instead of just pushing on a list. - ([@iarna](https://github.com/iarna)) - -#### IMPROVED LOGGING - -* [`335933a`](https://github.com/npm/npm/commit/335933a05396258eead139d27eea3f7668ccdfab) - [#15089](https://github.com/npm/npm/pull/15089) - Log when we remove obsolete dependencies in the tree. - ([@iarna](https://github.com/iarna)) - -#### DOCUMENTATION - -* [`33ca4e6`](https://github.com/npm/npm/commit/33ca4e6db3c1878cbc40d5e862ab49bb0e82cfb2) - [#15157](https://github.com/npm/npm/pull/15157) - Update `npm cache` docs to use more consistent language - ([@JonahMoses](https://github.com/JonahMoses)) - -#### DEPENDENCY UPDATES - -* [`c2d22fa`](https://github.com/npm/npm/commit/c2d22faf916e8260136a1cc95913ca474421c0d3) - [#15215](https://github.com/npm/npm/pull/15215) - `nopt@4.0.1`: - The breaking change is a small tweak to how empty string values are - handled. See the brand-new - [CHANGELOG.md for nopt](https://github.com/npm/nopt/blob/v4.0.1/CHANGELOG.md) for further - details about what's changed in this release! - ([@adius](https://github.com/adius), - [@samjonester](https://github.com/samjonester), - [@elidoran](https://github.com/elidoran), - [@helio](https://github.com/helio), - [@silkentrance](https://github.com/silkentrance), - [@othiym23](https://github.com/othiym23)) -* [`54d949b`](https://github.com/npm/npm/commit/54d949b05adefffeb7b5b10229c5fe0ccb929ac3) - [npm/lockfile#24](https://github.com/npm/lockfile/pull/24) - `lockfile@1.0.3`: - Handled case where callback was not passed in by the user. - ([@ORESoftware](https://github.com/ORESoftware)) -* [`54acc03`](https://github.com/npm/npm/commit/54acc0389b39850c0725d0868cb5e61317b57503) - `npmlog@4.0.2`: - Documentation update. - ([@helio-frota](https://github.com/helio-frota)) -* [`57f4bc1`](https://github.com/npm/npm/commit/57f4bc1150322294c1ea0a287ad0a8e457c151e6) - `osenv@0.1.4`: - Test changes. - ([@isaacs](https://github.com/isaacs)) -* [`bea1a2d`](https://github.com/npm/npm/commit/bea1a2d0db566560e13ecc1d5f42e55811269c88) - `retry@0.10.1`: - No changes. - ([@tim-kos](https://github.com/tim-kos)) -* [`6749e39`](https://github.com/npm/npm/commit/6749e395f868109afd97f79d36507e6567dd48fb) - [kapouer/marked-man#9](https://github.com/kapouer/marked-man/pull/9) - `marked-man@0.2.0`: - Add table support. - ([@gholk](https://github.com/gholk)) - -### v4.0.5 (2016-12-01) - -It's that time of year! December is upon us, which means y'all are just going to -be doing a lot less, in general, for the next month or so. The "Xmas Chasm", as -we like to call it, has already begun. So for those of you reading it from the -other side: Hi! Welcome back! - -This week's release is a relatively small one, involving just a few bugfixes and -dependency upgrades. The CLI team has been busy recently with scoping out -`npm@5`, and starting to do initial spec work for in-scope stuff. - -#### BUGFIXES - -On to the actual changes! - -* [`9776d8f`](https://github.com/npm/npm/commit/9776d8f70a0ea8d921cbbcab7a54e52c15fc455f) - [#15081](https://github.com/npm/npm/pull/15081) - `bundledDependencies` are intended to be left untouched by the installer, as - much as possible -- if they're bundled, we assume that you want to be - particular about the contents of your bundle. - - The installer used to have a corner case where existing dependencies that had - bundledDependencies would get clobbered by as the installer moved stuff - around, even though the installer already avoided moving deps that were - themselves bundled. This is now fixed, along with the connected crasher, and - your bundledDeps should be left even more intact than before! - ([@iarna](https://github.com/iarna)) -* [`fc61c08`](https://github.com/npm/npm/commit/fc61c082122104031ccfb2a888432c9f809a0e8b) - [#15082](https://github.com/npm/npm/pull/15082) - Initialize nodes from bundled dependencies. This should address - [#14427](https://github.com/npm/npm/issues/14427) and related issues, but it's - turned out to be a tremendously difficult issue to reproduce in a test. We - decided to include it even pending tests, because we found the root cause of - the errors. - ([@iarna](https://github.com/iarna)) -* [`d8471a2`](https://github.com/npm/npm/commit/d8471a294ef848fc893f60e17d6ec6695b975d16) - [#12811](https://github.com/npm/npm/pull/12811) - Consider `devDependencies` when deciding whether to hoist a package. This - should resolve a variety of missing dependency issues some folks were seeing - when `devDependencies` happened to also be dependencies of your - `dependencies`. This often manifested as modules going missing, or only being - installed, after `npm install` was called twice. - ([@schmod](https://github.com/schmod)) - -#### DEPENDENCY UPDATES - -* [`5978703`](https://github.com/npm/npm/commit/5978703da8669adae464789b1b15ee71d7f8d55d) - `graceful-fs@4.1.11`: - `EPERM` errors are Windows are now handled more gracefully. Windows users that - tended to see these errors due to, say, an antivirus-induced race condition, - should see them much more rarely, if at all. - ([@zkatr](https://github.com/zkat)) -* [`85b0174`](https://github.com/npm/npm/commit/85b0174ba9842e8e89f3c33d009e4b4a9e877c7d) - `request@2.79.0` - ([@zkat](https://github.com/zkat)) -* [`9664d36`](https://github.com/npm/npm/commit/9664d36653503247737630440bc2ff657de965c3) - `tap@8.0.1` - ([@zkat](https://github.com/zkat)) - -#### MISCELLANEOUS - -* [`f0f7b0f`](https://github.com/npm/npm/commit/f0f7b0fd025daa2b69994130345e6e8fdaaa0304) - [#15083](https://github.com/npm/npm/pull/15083) - Removed dead code. - ([@iarna](https://github.com/iarna)) * [`bc32afe`](https://github.com/npm/npm/commit/bc32afe4d12e3760fb5a26466dc9c26a5a2981d5) [`c8a22fe`](https://github.com/npm/npm/commit/c8a22fe5320550e09c978abe560b62ce732686f4) [`db2666d`](https://github.com/npm/npm/commit/db2666d8c078fc69d0c02c6a3de9b31be1e995e9) - [#15085](https://github.com/npm/npm/pull/15085) - Change some network tests so they can run offline. - ([@iarna](https://github.com/iarna)) -* [`744a39b`](https://github.com/npm/npm/commit/744a39b836821b388ad8c848bd898c1d006689a9) - [#15085](https://github.com/npm/npm/pull/15085) - Make Node.js tests compatible with Windows. - ([@iarna](https://github.com/iarna)) - -### v4.0.3 (2016-11-17) - -Hey you all, we've got a couple of bug fixes for you, a slew of -documentation improvements and some improvements to our CI environment. I -know we just got v4 out the door, but the CLI team is already busy planning -v5. We'll have more for you in early December. - -#### BUG FIXES - -* [`45d40d9`](https://github.com/npm/npm/commit/45d40d96d2cd145f1e36702d6ade8cd033f7f332) - [`ba2adc2`](https://github.com/npm/npm/commit/ba2adc2e822d5e75021c12f13e3f74ea2edbde32) - [`1dc8908`](https://github.com/npm/npm/commit/1dc890807bd78a1794063688af31287ed25a2f06) - [`2ba19ee`](https://github.com/npm/npm/commit/2ba19ee643d612d103cdd8f288d313b00d05ee87) - [#14403](https://github.com/npm/npm/pull/14403) - Fix a bug where a scoped module could produce crashes when incorrectly - computing the paths related to their location. This patch reorganizes how path information - is passed in to eliminate the possibility of this sort of bug. - ([@iarna](https://github.com/iarna)) - ([@NatalieWolfe](https://github.com/NatalieWolfe)) -* [`1011ec6`](https://github.com/npm/npm/commit/1011ec61230288c827a1c256735c55cf03d6228f) - [npm/npmlog#46](https://github.com/npm/npmlog/pull/46) - `npmlog@4.0.1`: Fix a bug where the progress bar would still display even if - you passed in `--no-progress`. - ([@iarna](https://github.com/iarna)) - -#### DOCUMENTATION UPDATES - -* [`c3ac177`](https://github.com/npm/npm/commit/c3ac177236124c80524c5f252ba8f6670f05dcd8) - [#14406](https://github.com/npm/npm/pull/14406) - Sync up the dispute policy included with the CLI with the [current official text](https://www.npmjs.com/policies/disputes). - ([@mike-engel](https://github.com/mike-engel)) -* [`9c663b2`](https://github.com/npm/npm/commit/9c663b2dd8552f892dc0205330bbc73a484ecd81) - [#14627](https://github.com/npm/npm/pull/14627) - Update build status branch in README. - ([@cameronroe](https://github.com/cameronroe)) -* [`8a8a0a3`](https://github.com/npm/npm/commit/8a8a0a3d490fc767def208f925cdff57e16e565b) - [#14609](https://github.com/npm/npm/pull/14609) - Update examples URLs of GitHub repos where those repos have moved to new URLs. - ([@dougwilson](https://github.com/dougwilson)) -* [`7a6425b`](https://github.com/npm/npm/commit/7a6425bcd4decde5d4b0af8b507e98723a07c680) - [#14472](https://github.com/npm/npm/pull/14472) - Document `sign-git-tag` in - [npm-version(1)](https://github.com/npm/npm/blob/release-next/doc/cli/npm-version.md)'s - configuration section. - ([@strugee](https://github.com/strugee)) -* [`f3087cc`](https://github.com/npm/npm/commit/f3087cc58c903d9a70275be805ebaf0eadbcbe1b) - [#14546](https://github.com/npm/npm/pull/14546) - Add a note about the dangers of configuring npm via uppercase env vars. - ([@tuhoojabotti](https://github.com/tuhoojabotti)) -* [`50e51b0`](https://github.com/npm/npm/commit/50e51b04a143959048cf9e1e4c8fe15094f480b0) - [#14559](https://github.com/npm/npm/pull/14559) - Remove documentation that incorrectly stated that we check `.npmrc` permissions. - ([@iarna](https://github.com/iarna)) - -##### OH UH, HELLO AGAIN NODE.JS 0.12 - -* [`6f0c353`](https://github.com/npm/npm/commit/6f0c353e4e89b0378a4c88c829ccf9a1c5ae829d) - [`f78bde6`](https://github.com/npm/npm/commit/f78bde6983bdca63d5fcb9c220c87e8f75ffb70e) - [#14591](https://github.com/npm/npm/pull/14591) - Reintroduce Node.js 0.12 to our support matrix. We jumped the gun when - removing it. We won't drop support for it till the Node.js project does - so at the end of December 2016. - ([@othiym23](https://github.com/othiym23)) - -#### TEST/CI UPDATES - -* [`aa73d1c`](https://github.com/npm/npm/commit/aa73d1c1cc22608f95382a35b33da252addff38e) - [`c914e80`](https://github.com/npm/npm/commit/c914e80f5abcb16c572fe756c89cf0bcef4ff991) -* [`58fe064`](https://github.com/npm/npm/commit/58fe064dcc80bc08c677647832f2adb4a56b538a) - [#14602](https://github.com/npm/npm/pull/14602) - When running tests with coverage, use nyc's cache. This provides an 8x speedup! - ([@bcoe](https://github.com/bcoe)) -* [`ba091ce`](https://github.com/npm/npm/commit/ba091ce843af5d694f4540e825b095435b3558d8) - [#14435](https://github.com/npm/npm/pull/14435) - Remove an unused zero byte `package.json` found in the test fixtures. - ([@baderbuddy](https://github.com/baderbuddy)) - -#### DEPENDENCY UPDATES - -* [`442e01e`](https://github.com/npm/npm/commit/442e01e42d8a439809f6726032e3b73ac0d2b2f8) - `readable-stream@2.2.2`: - Bring in latest changes from Node.js 7.x. - ([@calvinmetcalf](https://github.com/calvinmetcalf)) -* [`bfc4a1c`](https://github.com/npm/npm/commit/bfc4a1c0c17ef0a00dfaa09beba3389598a46535) - `which@1.2.12`: - Remove unused require. - ([@isaacs](https://github.com/isaacs)) - -#### DEV DEPENDENCY UPDATES - -* [`7075b05`](https://github.com/npm/npm/commit/7075b054d8d2452bb53bee9b170498a48a0dc4e9) - `marked-man@0.1.6` - ([@kapouer](https://github.com/kapouer)) -* [`3e13fea`](https://github.com/npm/npm/commit/3e13fea907ee1141506a6de7d26cbc91c28fdb80) - `tap@8.0.0` - ([@isaacs](https://github.com/isaacs)) - -### v4.0.2 (2016-11-03) - -Hola, amigxs. I know it's been a long time since I rapped at ya, but I -been spending a lotta time quietly reflecting on all the things going on -in my life. I was, like, [in Japan for a while](https://gist.github.com/othiym23/c98bd4ef5d9fb3f496835bd481ef40ae), -and before that my swell colleagues [@zkat](https://github.com/zkat) and -[@iarna](https://github.com/iarna) have been very capably managing the release -process for quite a while. But I returned from Japan somewhat refreshed, very -jetlagged, and filled with a burning urge to get `npm@4` as stable as possible -before we push it out to the user community at large, so I decided to do this -release myself. (Also, huge thanks to Kat and Rebecca for putting out `npm@4` -so capably while I was on vacation! So cool to return to a major release having -gone so well without my involvement!) - -That said... - -#### NEVER TRUST AN X.0.0 RELEASE - -Even though 4.0.1 came out hard on the heels of 4.0.0 with a couple -critical fixes, we've found a couple other major issues that we want to -see fixed before making `npm@4` into `npm@latest`. Some of these are -arguably breaking changes on their own, so now is the time to get them -out if we're going to do so before `npm@5`, and all of them are pretty -significant blockers for a substantial number of users, so now is the -best time to fix them. - -##### PREPUBLISHONLY WHOOPS - -The code running the `publish*` lifecycle events was very confusingly written. -In fact, we didn't really figure out what it was doing until we added the new -`prepublishOnly` event and it was running people's scripts from the wrong -directory. We made it simpler. See the [commit -message](https://github.com/npm/npm/commit/8b32d67aa277fd7e62edbed886387a855f58387f) -for details. - -Because the change is no longer running publish events when publishing prebuilt -artifacts, it's technically a breaking / semver-major change. In the off chance -that the new behavior breaks any of y'all's workflows, let us know, and we can -roll some or all of this change back until `npm@5` (or forever, if that works -better for you). - -* [`8b32d67`](https://github.com/npm/npm/commit/8b32d67aa277fd7e62edbed886387a855f58387f) - [#14502](https://github.com/npm/npm/pull/14502) - Simplify lifecycle invocation and fix `prepublishOnly`. - ([@othiym23](https://github.com/othiym23)) - -##### G'BYE NODE.JS 0.10, 0.12, and 5.X; HI THERE, NODE 7 - -With the advent of the second official Node.js LTS release, Node 6.x -'Boron', the Node.js project has now officially dropped versions 0.10 -and 0.12 out of the maintenance phase of LTS. (Also, Node 5 was never -part of LTS, and will see no further support now that Node 7 has been -released.) As a small team with limited resources, the npm CLI team is -following suit and dropping those versions of Node from its CI test -matrix. - -What this means: - -* Your contributions will no longer block on the tests passing on 0.10 and 0.12. -* We will no longer block dependency upgrades on working with 0.10 and 0.12. -* Bugs filed on the npm CLI that are due to incompatibilities with 0.10 - or 0.12 (and older versions) will be closed with a strong urging to - upgrade to a supported version of Node. -* On the flip side, we'll continue to (happily!) accept patches that - address regressions seen when running the CLI with Node.js 0.10 and - 0.12. - -What this doesn't mean: - -* The CLI is going to start depending on ES2015+ features. npm continues - to work, in almost all cases, all the way back to Node.js 0.8, and our - long history of backwards compatibility is a source of pride for the - team. -* We aren't concerned about the problems of users who, for whatever - reason, can't update to newer versions of npm. As mentioned above, we're - happy to take community patches intended to address regressions. - -We're not super interested in taking sides on what version of Node.js -you "should" be running. We're a workflow tool, and we understand that -you all have a diverse set of operational environments you need to be -able to support. At the same time, we _are_ a small team, and we need -to put some limits on what we support. Tracking what's supported by our -runtime's own team seems most practical, so that's what we're doing. - -* [`ab630c9`](https://github.com/npm/npm/commit/ab630c9a7a1b40cdd4f1244be976c25ab1525907) - [#14503](https://github.com/npm/npm/pull/14503) - Node 6 is LTS; 5.x, 0.10, and 0.12 are unsupported. - ([@othiym23](https://github.com/othiym23)) -* [`731ae52`](https://github.com/npm/npm/commit/731ae526fb6e9951c43d82a26ccd357b63cc56c2) - [#14503](https://github.com/npm/npm/pull/14503) - Update supported version expression. - ([@othiym23](https://github.com/othiym23)) - -##### DISENTANGLING SCOPE - -The new `Npm-Scope` header was previously reusing the `scope` -configuration option to pass the current scope back to your current -registry (which, as [described -previously](https://github.com/npm/npm/blob/release-next/CHANGELOG.md#send-extra-headers-to-registry), is meant to set up some upcoming -registry features). It turns out that had some [seriously weird -consequences](https://github.com/npm/npm/issues/14412) in the case where -you were already configuring `scope` in your own environment. The CLI -now uses separate configuration for this. - -* [`39358f7`](https://github.com/npm/npm/commit/39358f732ded4aa46d86d593393a0d6bca5dc12a) - [#14477](https://github.com/npm/npm/pull/14477) - Differentiate registry scope from project scope in configuration. - ([@zkat](https://github.com/zkat)) - -#### SMALLER CHANGES - -* [`7f41295`](https://github.com/npm/npm/commit/7f41295775f28b958a926f9cb371cb37b05771dd) - [#14519](https://github.com/npm/npm/pull/14519) - Document that as of `npm@4.0.1`, `npm shrinkwrap` now includes `devDependencies` unless - instructed otherwise. - ([@iarna](https://github.com/iarna)) -* [`bdc2f9e`](https://github.com/npm/npm/commit/bdc2f9e255ddf1a47fd13ec8749d17ed41638b2c) - [#14501](https://github.com/npm/npm/pull/14501) - The `ENOSELF` error message is tricky to word. It's also an error that - normally bites new users. Clean it up in an effort to make it easier - to understand what's going on. - ([@snopeks](https://github.com/snopeks), [@zkat](https://github.com/zkat)) - -#### DEPENDENCY UPGRADES - -* [`a52d0f0`](https://github.com/npm/npm/commit/a52d0f0c9cf2de5caef77e12eabd7dca9e89b49c) - `glob@7.1.1`: - - Handle files without associated perms on Windows. - - Fix failing case with `absolute` option. - ([@isaacs](https://github.com/isaacs), [@phated](https://github.com/phated)) -* [`afda66d`](https://github.com/npm/npm/commit/afda66d9afcdcbae1d148f589287583c4182d124) - [isaacs/node-graceful-fs#97](https://github.com/isaacs/node-graceful-fs/pull/97) - `graceful-fs@4.1.10`: Better backoff for EPERM on Windows. - ([@sam-github](https://github.com/sam-github)) -* [`e0023c0`](https://github.com/npm/npm/commit/e0023c089ded9161fbcbe544f12b07e12e3e5729) - [npm/inflight#3](https://github.com/npm/inflight/pull/3) - `inflight@1.0.6`: Clean up even if / when a callback throws. - ([@phated](https://github.com/phated)) -* [`1d91594`](https://github.com/npm/npm/commit/1d9159440364d2fe21e8bc15e08e284aaa118347) - `request@2.78.0` - ([@othiym23](https://github.com/othiym23)) - -### v4.0.1 (2016-10-24) - -Ayyyy~ 🌊 - -So thanks to folks who were running on `npm@next`, we managed to find a few -issues of notes in that preview version, and we're rolling out a small patch -change to fix them. Most notably, anyone who was using a symlinked `node` binary -(for example, if they installed Node.js through `homebrew`), was getting a very -loud warning every time they ran scripts. Y'all should get warnings in a more -useful way, now that we're resolving those path symlinks. - -Another fairly big change that we decided to slap into this version, since -`npm@4.0.0` is never going to be `latest`, is to make it so `devDependencies` -are included in `npm-shrinkwrap.json` by default -- if you do not want this, use -`--production` with `npm shrinkwrap`. - -#### BIG FIXES/CHANGES - -* [`eff46dd`](https://github.com/npm/npm/commit/eff46dd498ed007bfa77ab7782040a3a828b852d) - [#14374](https://github.com/npm/npm/pull/14374) - Fully resolve the path for `node` executables in both `$PATH` and - `process.execPath` to avoid issues with symlinked `node`. - ([@addaleax](https://github.com/addaleax)) -* [`964f2d3`](https://github.com/npm/npm/commit/964f2d3a0675584267e6ece95b0115a53c6ca6a9) - [#14375](https://github.com/npm/npm/pull/14375) - Make including `devDependencies` in `npm-shrinkwrap.json` the default. This - should help make the transition to `npm@5` smoother in the future. - ([@iarna](https://github.com/iarna)) - -#### BUGFIXES - -* [`a5b0a8d`](https://github.com/npm/npm/commit/a5b0a8db561916086fc7dbd6eb2836c952a42a7e) - [#14400](https://github.com/npm/npm/pull/14400) - Recently, we've had some consistent timeout failures while running the test - suite under Travis. This tweak to tests should take care of those issues and - Travis should go back to being reliably green. - ([@iarna](https://github.com/iarna)) - -#### DOC PATCHES - -* [`c5907b2`](https://github.com/npm/npm/commit/c5907b2fc1a82ec919afe3b370ecd34d8895c7a2) - [#14251](https://github.com/npm/npm/pull/14251) - Update links to Node.js downloads. They previously pointed to 404 pages.😬 - ([@ArtskydJ](https://github.com/ArtskydJ)) -* [`0c122f2`](https://github.com/npm/npm/commit/0c122f24ff1d4d400975edda2b7262aaaf6f7d69) - [#14380](https://github.com/npm/npm/pull/14380) - Add note and clarification on when `prepare` script is run. Make it more - consistent with surrounding descriptions. - ([@SimenB](https://github.com/SimenB)) -* [`51a62ab`](https://github.com/npm/npm/commit/51a62abd88324ba3dad18e18ca5e741f1d60883c) - [#14359](https://github.com/npm/npm/pull/14359) - Fixes typo in `npm@4` changelog. - ([@kimroen](https://github.com/kimroen)) - -### v4.0.0 (2016-10-20) - -Welcome to `npm@4`, friends! - -This is our first semver major release since the release of `npm@3` just over a -year ago. Back then, `@3` turned out to be a bit of a ground-shaking release, -with a brand-new installer with significant structural changes to how npm set up -your tree. This is the end of an era, in a way. `npm@4` also marks the release -when we move *both* `npm@2` and `npm@3` into maintenance: We will no longer be -updating those release branches with anything except critical bugfixes and -security patches. - -While its predecessor had some pretty serious impaact, `npm@4` is expected to -have a much smaller effect on your day-to-day use of npm. Over the past year, -we've collected a handful of breaking changes that we wanted to get in which are -only breaking under a strict semver interpretation (which we follow). Some of -these are simple usability improvements, while others fix crashes and serious -issues that required a major release to include. - -We hope this release sees you well, and you can look forward to an accelerated -release pace now that the CLI team is done focusing on sustaining work -- our -Windows fixing and big bugs pushes -- and we can start focusing again on -usability, features, and performance. Keep an eye out for `npm@5` in Q1 2017, -too: We're planning a major overhaul of `shrinkwrap` as well as various speed -and usability fixes for that release. It's gonna be a fun ride. I promise. 😘 - -#### BRIEF OVERVIEW OF **BREAKING** CHANGES - -The following breaking changes are included in this release: - -* `npm search` rewritten to stream results, and no longer supports sorting. -* `npm scripts` no longer prepend the path of the node executable used to run - npm before running scripts. A `--scripts-prepend-node-path` option has been - added to configure this behavior. -* `npat` has been removed. -* `prepublish` has been deprecated, replaced by `prepare`. A `prepublishOnly` - script has been temporarily added, which will *only* run on `npm publish`. -* `npm outdated` exits with exit code `1` if it finds any outdated packages. -* `npm tag` has been removed after a deprecation cycle. Use `npm dist-tag`. -* Partial shrinkwraps are no longer supported. `npm-shrinkwrap.json` is - considered a complete installation manifest except for `devDependencies`. -* npm's default git branch is no longer `master`. We'll be using `latest` from - now on. - -#### SEARCH REWRITE (**BREAKING**) - -Let's face it -- `npm search` simply doesn't work anymore. Apart from the fact -that it grew slower over the years, it's reached a point where we can no longer -fit the entire registry metadata in memory, and anyone who tries to use the -command now sees a really awful memory overflow crash from node. - -It's still going to be some time before the CLI, registry, and web team are able -to overhaul `npm search` altogether, but until then, we've rewritten the -previous `npm search` implementation to *stream* results on the fly, from both -the search endpoint and a local cache. In absolute terms, you won't see a -performance increase and this patch *does* come at the cost of sorting -capabilities, but what it does do is start outputting results as it finds them. -This should make the experience much better, overall, and we believe this is an -acceptable band-aid until we have that search endpoint in place. - -Incidentally, if you want a really nice search experience, we recommend checking -out [npms.io](http://npms.io), which includes a handy-dandy -[`npms-cli`](https://npm.im/npms-cli) for command-line usage -- it's an npm -search site that returns high-quality results quickly and is operated by members -of the npm community. - -* [`cfd43b4`](https://github.com/npm/npm/commit/cfd43b49aed36d0e8ea6c35b07ed8b303b69be61) [`2b8057b`](https://github.com/npm/npm/commit/2b8057be2e1b51e97b1f8f38d7f58edf3ce2c145) - [#13746](https://github.com/npm/npm/pull/13746) - Stream search process end-to-end. - ([@zkat](https://github.com/zkat) and [@aredridel](https://github.com/aredridel)) -* [`50f4ec8`](https://github.com/npm/npm/commit/50f4ec8e8ce642aa6a58cb046b2b770ccf0029db) [`70b4bc2`](https://github.com/npm/npm/commit/70b4bc22ec8e81cd33b9448f5b45afd1a50d50ba) [`8fb470f`](https://github.com/npm/npm/commit/8fb470fe755c4ad3295cb75d7b4266f8e67f8d38) [`ac3a6e0`](https://github.com/npm/npm/commit/ac3a6e0eba61fb40099b1370c74ad1598777def4) [`bad54dd`](https://github.com/npm/npm/commit/bad54dd9f1119fe900a8d065f8537c6f1968b589) [`87d504e`](https://github.com/npm/npm/commit/87d504e0a61bccf09f5e975007d018de3a1c5f50) - [#13746](https://github.com/npm/npm/pull/13746) - Updated search-related tests. - ([@zkat](https://github.com/zkat)) -* [`3596de8`](https://github.com/npm/npm/commit/3596de88598c69eb5bae108703c8e74ca198b20c) - [#13746](https://github.com/npm/npm/pull/13746) - `JSONStream@1.2.1` - ([@zkat](https://github.com/zkat)) -* [`4b09209`](https://github.com/npm/npm/commit/4b09209bb605f547243065032a8b37772669745f) - [#13746](https://github.com/npm/npm/pull/13746) - `mississippi@1.2.0` - ([@zkat](https://github.com/zkat)) -* [`b650b39`](https://github.com/npm/npm/commit/b650b39d42654abb9eed1c7cd463b1c595ca2ef9) - [#13746](https://github.com/npm/npm/pull/13746) - `sorted-union-stream@2.1.3` - ([@zkat](https://github.com/zkat)) - -#### SCRIPT NODE PATH (**BREAKING**) - -Thanks to some great work by [@addaleax](https://github.com/addaleax), we've -addressed a fairly tricky issue involving the node process used by `npm -scripts`. - -Previously, npm would prefix the path of the node executable to the script's -`PATH`. This had the benefit of making sure that the node process would be the -same for both npm and `scripts` unless you had something like -[`node-bin`](https://npm.im/node-bin) in your `node_modules`. And it turns out -lots of people relied on this behavior being this way! - -It turns out that this had some unintended consequences: it broke systems like -[`nyc`](https://npm.im/nyc), but also completely broke/defeated things like -[`rvm`](https://rvm.io/) and -[`virtualenv`](https://virtualenv.pypa.io/en/stable/) by often causing things -that relied on them to fall back to the global system versions of ruby and -python. - -In the face of two perfectly valid, and used alternatives, we decided that the -second case was much more surprising for users, and that we should err on the -side of doing what those users expect. Anna put some hard work in and managed to -put together a patch that changes npm's behavior such that we no longer prepend -the node executable's path *by default*, and adds a new option, -`--scripts-prepend-node-path`, to allow users who rely on this behavior to have -it add the node path for them. - -This patch also makes it so this feature is discoverable by people who might run -into the first case above, by warning if the node executable is either missing -or shadowed by another one in `PATH`. This warning can also be disabled with the -`--scripts-prepend-node-path` option as needed. - -* [`3fb1eb3`](https://github.com/npm/npm/commit/3fb1eb3e00b5daf37f14e437d2818e9b65a43392) [`6a7d375`](https://github.com/npm/npm/commit/6a7d375d779ba5416fd5df154c6da673dd745d9d) [`378ae08`](https://github.com/npm/npm/commit/378ae08851882d6d2bc9b631b16b8c875d0b9704) - [#13409](https://github.com/npm/npm/pull/13409) - Add a `--scripts-prepend-node-path` option to configure whether npm prepends - the current node executable's path to `PATH`. - ([@addaleax](https://github.com/addaleax)) -* [`70b352c`](https://github.com/npm/npm/commit/70b352c6db41533b9a4bfaa9d91f7a2a1178f74e) - [#13409](https://github.com/npm/npm/pull/13409) - Change the default behaviour of npm to never prepending the current node - executable’s directory to `PATH` but printing a warning in the cases in which - it previously did. - ([@addaleax](https://github.com/addaleax)) - -#### REMOVE `npat` (**BREAKING**) - -Let's be real here -- almost no one knows this feature ever existed, and it's a -vestigial feature of the days when the ideal for npm was to distribute full -packages that could be directly developed on, even from the registry. - -It turns out the npm community decided to go a different way: primarily -publishing packages in a production-ready format, with no tests, build tools, -etc. And so, we say goodbye to `npat`. - -* [`e16c14a`](https://github.com/npm/npm/commit/e16c14afb6f52cb8b7adf60b2b26427f76773f2e) - [#14329](https://github.com/npm/npm/pull/14329) - Remove the npat feature. - ([@iarna](https://github.com/iarna)) - -#### NEW `prepare` SCRIPT. `prepublish` DEPRECATED (**BREAKING**) - -If there's anything that really seemed to confuse users, it's that the -`prepublish` script ran when invoking `npm install` without any arguments. - -Turns out many, many people really expected that it would only run on `npm -publish`, even if it actually did what most people expected: prepare the package -for publishing on the registry. - -And so, we've added a `prepare` command that runs in the exact same cases where -`prepublish` ran, and we've begun a deprecation cycle for `prepublish` itself -**only when run by `npm install`**, which will now include a warning any time -you use it that way. - -We've also added a `prepublishOnly` script which will execute **only** when `npm -publish` is invoked. Eventually, `prepublish` will stop executing on `npm -install`, and `prepublishOnly` will be removed, leaving `prepare` and -`prepublish` as two distinct lifecycles. - -* [`9b4a227`](https://github.com/npm/npm/commit/9b4a2278cee0a410a107c8ea4d11614731e0a943) [`bc32078`](https://github.com/npm/npm/commit/bc32078fa798acef0e036414cb448645f135b570) - [#14290](https://github.com/npm/npm/pull/14290) - Add `prepare` and `prepublishOnly` lifecycle events. - ([@othiym23](https://github.com/othiym23)) -* [`52fdefd`](https://github.com/npm/npm/commit/52fdefddb48f0c39c6e8eb4c118eb306c9436117) - [#14290](https://github.com/npm/npm/pull/14290) - Warn when running `prepublish` on `npm pack`. - ([@othiym23](https://github.com/othiym23)) -* [`4c2a948`](https://github.com/npm/npm/commit/4c2a9481b564cae3df3f4643766db4b987018a7b) [`a55bd65`](https://github.com/npm/npm/commit/a55bd651284552b93f7d972a2e944f65c1aa6c35) - [#14290](https://github.com/npm/npm/pull/14290) - Added `prepublish` warnings to `npm install`. - ([@zkat](https://github.com/zkat)) -* [`c27412b`](https://github.com/npm/npm/commit/c27412bb9fc7b09f7707c7d9ad23128959ae1abc) - [#14290](https://github.com/npm/npm/pull/14290) - Replace `prepublish` with `prepare` in `npm help package.json` documentation. - ([@zkat](https://github.com/zkat)) - -#### NO MORE PARTIAL SHRINKWRAPS (**BREAKING**) - -That's right. No more partial shrinkwraps. That means that if you have an -`npm-shrinkwrap.json` in your project, npm will no longer install anything that -isn't explicitly listed there, unless it's a `devDependency`. This will open -doors to some nice optimizations and make use of `npm shrinkwrap` just generally -smoother by removing some awful corner cases. We will also skip `devDependency` -installation from `package.json` if you added `devDependencies` to your -shrinkwrap by using `npm shrinkwrap --dev`. - -* [`b7dfae8`](https://github.com/npm/npm/commit/b7dfae8fd4dc0456605f7a921d20a829afd50864) - [#14327](https://github.com/npm/npm/pull/14327) - Use `readShrinkwrap` to read top level shrinkwrap. There's no reason for npm - to be doing its own bespoke heirloom-grade artisanal thing here. - ([@iarna](https://github.com/iarna)) -* [`0ae1f4b`](https://github.com/npm/npm/commit/0ae1f4b9d83af2d093974beb33f26d77fcc95bb9) [`4a54997`](https://github.com/npm/npm/commit/4a549970dc818d78b6de97728af08a1edb5ae7f0) [`f22a1ae`](https://github.com/npm/npm/commit/f22a1ae54b5d47f1a056a6e70868013ebaf66b79) [`3f61189`](https://github.com/npm/npm/commit/3f61189cb3843fee9f54288fefa95ade9cace066) - [#14327](https://github.com/npm/npm/pull/14327) - Treat shrinkwrap as canonical. That is, don't try to fill in for partial - shrinkwraps. Partial shrinkwraps should produce partial installs. If your - shrinkwrap contains NO `devDependencies` then we'll still try to install them - from your `package.json` instead of assuming you NEVER want `devDependencies`. - ([@iarna](https://github.com/iarna)) - -#### `npm tag` REMOVED (**BREAKING**) - -* [`94255da`](https://github.com/npm/npm/commit/94255da8ffc2d9ed6a0434001a643c1ad82fa483) - [#14328](https://github.com/npm/npm/pull/14328) - Remove deprecated tag command. Folks must use the `dist-tag` command from now - on. - ([@iarna](https://github.com/iarna)) - -#### NON-ZERO EXIT CODE ON OUTDATED DEPENDENCIES (**BREAKING**) - -* [`40a04d8`](https://github.com/npm/npm/commit/40a04d888d10a5952d5ca4080f2f5d2339d2038a) [`e2fa18d`](https://github.com/npm/npm/commit/e2fa18d9f7904eb048db7280b40787cb2cdf87b3) [`3ee3948`](https://github.com/npm/npm/commit/3ee39488b74c7d35fbb5c14295e33b5a77578104) [`3fa25d0`](https://github.com/npm/npm/commit/3fa25d02a8ff07c42c595f84ae4821bc9ee908df) - [#14013](https://github.com/npm/npm/pull/14013) - Do `exit 1` if any outdated dependencies are found by `npm outdated`. - ([@watilde](https://github.com/watilde)) -* [`c81838a`](https://github.com/npm/npm/commit/c81838ae96b253f4b1ac66af619317a3a9da418e) - [#14013](https://github.com/npm/npm/pull/14013) - Log non-zero exit codes at `verbose` level -- this isn't something command - line tools tend to do. It's generally the shell's job to display, if at all. - ([@zkat](https://github.com/zkat)) - -#### SEND EXTRA HEADERS TO REGISTRY - -For the purposes of supporting shiny new registry features, we've started -sending `Npm-Scope` and `Npm-In-CI` headers in outgoing requests. - -* [`846f61c`](https://github.com/npm/npm/commit/846f61c1dd4a033f77aa736ab01c27ae6724fe1c) - [npm/npm-registry-client#145](https://github.com/npm/npm-registry-client/pull/145) - [npm/npm-registry-client#147](https://github.com/npm/npm-registry-client/pull/147) - `npm-registry-client@7.3.0`: - * Allow npm to add headers to outgoing requests. - * Add `Npm-In-CI` header that reports whether we're running in CI. - ([@iarna](https://github.com/iarna)) -* [`6b6bb08`](https://github.com/npm/npm/commit/6b6bb08af661221224a81df8adb0b72019ca3e11) - [#14129](https://github.com/npm/npm/pull/14129) - Send `Npm-Scope` header along with requests to registry. `Npm-Scope` is set to - the `@scope` of the current top level project. This will allow registries to - implement user/scope-aware features and services. - ([@iarna](https://github.com/iarna)) -* [`506de80`](https://github.com/npm/npm/commit/506de80dc0a0576ec2aab0ed8dc3eef3c1dabc23) - [#14129](https://github.com/npm/npm/pull/14129) - Add test to ensure `Npm-In-CI` header is being sent when CI is set in env. - ([@iarna](https://github.com/iarna)) - -#### BUGFIXES - -* [`bc84012`](https://github.com/npm/npm/commit/bc84012c2c615024b08868acbd8df53a7ca8d146) - [#14117](https://github.com/npm/npm/pull/14117) - Fixes a bug where installing a shrinkwrapped package would fail if the - platform failed to install an optional dependency included in the shrinkwrap. - ([@watilde](https://github.com/watilde)) -* [`a40b32d`](https://github.com/npm/npm/commit/a40b32dc7fe18f007a672219a12d6fecef800f9d) - [#13519](https://github.com/npm/npm/pull/13519) - If a package has malformed metadata, `node.requiredBy` is sometimes missing. - Stop crashing when that happens. - ([@creationix](https://github.com/creationix)) - -#### OTHER PATCHES - -* [`643dae2`](https://github.com/npm/npm/commit/643dae2197c56f1c725ecc6539786bf82962d0fe) - [#14244](https://github.com/npm/npm/pull/14244) - Remove some ancient aliases that we'd rather not have around. - ([@zkat](https://github.com/zkat)) -* [`bdeac3e`](https://github.com/npm/npm/commit/bdeac3e0fb226e4777d4be5cd3c3bec8231c8044) - [#14230](https://github.com/npm/npm/pull/14230) - Detect unsupported Node.js versions and warn about it. Also error on really - old versions where we know we can't work. - ([@iarna](https://github.com/iarna)) - -#### DOC UPDATES - -* [`9ca18ad`](https://github.com/npm/npm/commit/9ca18ada7cc1c10b2d32bbb59d5a99dd1c743109) - [#13746](https://github.com/npm/npm/pull/13746) - Updated docs for `npm search` options. - ([@zkat](https://github.com/zkat)) -* [`e02a47f`](https://github.com/npm/npm/commit/e02a47f9698ff082488dc2b1738afabb0912793e) - Move the `npm@3` changelog into the archived changelogs directory. - ([@zkat](https://github.com/zkat)) -* [`c12bbf8`](https://github.com/npm/npm/commit/c12bbf8c5a5dff24a191b66ac638f552bfb76601) - [#14290](https://github.com/npm/npm/pull/14290) - Document prepublish-on-install deprecation. - ([@othiym23](https://github.com/othiym23)) -* [`c246a75`](https://github.com/npm/npm/commit/c246a75ac8697f4ca11d316b7e7db5f24af7972b) - [#14129](https://github.com/npm/npm/pull/14129) - Document headers added by npm to outgoing registry requests. - ([@iarna](https://github.com/iarna)) - -#### DEPENDENCIES - -* [`cb20c73`](https://github.com/npm/npm/commit/cb20c7373a32daaccba2c1ad32d0b7e1fc01a681) - [#13953](https://github.com/npm/npm/pull/13953) - `signal-exit@3.0.1` - ([@benjamincoe](https://github.com/benjamincoe)) diff --git a/changelogs/CHANGELOG-5.md b/changelogs/CHANGELOG-5.md deleted file mode 100644 index ea8331b1b76f3..0000000000000 --- a/changelogs/CHANGELOG-5.md +++ /dev/null @@ -1,2360 +0,0 @@ -## v5.10.0 (2018-05-10): - -### AUDIT SHOULDN'T WAIT FOREVER - -This will likely be reduced further with the goal that the audit process -shouldn't noticibly slow down your builds regardless of your network -situation. - -* [`3dcc240db`](https://github.com/npm/npm/commit/3dcc240dba5258532990534f1bd8a25d1698b0bf) - Timeout audit requests eventually. - ([@iarna](https://github.com/iarna)) - - -## v5.10.0-next.1 (2018-05-07): - -### EXTENDED `npm init` SCAFFOLDING - -Thanks to the wonderful efforts of [@jdalton](https://github.com/jdalton) of -lodash fame, `npm init` can now be used to invoke custom scaffolding tools! - -You can now do things like `npm init react-app` or `npm init esm` to scaffold an -npm package by running `create-react-app` and `create-esm`, respectively. This -also adds an `npm create` alias, to correspond to Yarn's `yarn create` feature, -which inspired this. - -* [`adc009ed4`](https://github.com/npm/npm/commit/adc009ed4114ed1e692f8ef15123af6040615cee) - [`f363edd04`](https://github.com/npm/npm/commit/f363edd04f474fa64e4d97228c0b2a7858f21e7c) - [`f03b45fb2`](https://github.com/npm/npm/commit/f03b45fb217df066c3cb7715f9c0469d84e5aa8e) - [`13adcbb52`](https://github.com/npm/npm/commit/13adcbb527fb8214e5f2233706c6b72ce072f3fa) - [#20303](https://github.com/npm/npm/pull/20303) - [#20372](https://github.com/npm/npm/pull/20372) - Add an `npm init` feature that calls out to `npx` when invoked with positional - arguments. ([@jdalton](https://github.com/jdalton)) - -### DEPENDENCY AUDITING - -This version of npm adds a new command, `npm audit`, which will run a security -audit of your project's dependency tree and notify you about any actions you may -need to take. - -The registry-side services required for this command to work will be available -on the main npm registry in the coming weeks. Until then, you won't get much out -of trying to use this on the CLI. - -As part of this change, the npm CLI now sends scrubbed and cryptographically -anonymized metadata about your dependency tree to your configured registry, to -allow notifying you about the existence of critical security flaws. For details -about how the CLI protects your privacy when it shares this metadata, see `npm -help audit`, or [read the docs for `npm audit` -online](https://github.com/npm/npm/blob/release-next/doc/cli/npm-audit.md). You -can disable this altogether by doing `npm config set audit false`, but will no -longer benefit from the service. - -* [`c81dfb91b`](https://github.com/npm/npm/commit/c81dfb91bc031f1f979fc200bb66718a7e8e1551) - `npm-registry-fetch@1.1.1` - ([@iarna](https://github.com/iarna)) -* [`b096f44a9`](https://github.com/npm/npm/commit/b096f44a96d185c45305b9b6a5f26d3ccbbf759d) - `npm-audit-report@1.0.9` - ([@iarna](https://github.com/iarna)) -* [`43b20b204`](https://github.com/npm/npm/commit/43b20b204ff9a86319350988d6774397b7da4593) - [#20389](https://github.com/npm/npm/pull/20389) - Add new `npm audit` command. - ([@iarna](https://github.com/iarna)) -* [`49ddb3f56`](https://github.com/npm/npm/commit/49ddb3f5669e90785217a639f936f4e38390eea2) - [#20389](https://github.com/npm/npm/pull/20389) - Temporarily suppress git metadata till there's an opt-in. - ([@iarna](https://github.com/iarna)) -* [`5f1129c4b`](https://github.com/npm/npm/commit/5f1129c4b072172c72cf9cff501885e2c11998ea) - [#20389](https://github.com/npm/npm/pull/20389) - Document the new command. - ([@iarna](https://github.com/iarna)) -* [`9a07b379d`](https://github.com/npm/npm/commit/9a07b379d24d089687867ca34df6e1e6189c72f1) - [#20389](https://github.com/npm/npm/pull/20389) - Default audit to off when running the npm test suite itself. - ([@iarna](https://github.com/iarna)) -* [`a6e2f1284`](https://github.com/npm/npm/commit/a6e2f12849b84709d89b3dc4f096e8c6f7db7ebb) - Make sure we hide stream errors on background audit submissions. Previously some classes - of error could end up being displayed (harmlessly) during installs. - ([@iarna](https://github.com/iarna)) -* [`aadbf3f46`](https://github.com/npm/npm/commit/aadbf3f4695e75b236ee502cbe41e51aec318dc3) - Include session and scope in requests (as we do in other requests to the registry). - ([@iarna](https://github.com/iarna)) -* [`7d43ddf63`](https://github.com/npm/npm/commit/7d43ddf6366d3bfc18ea9ccef8c7b8e43d3b79f5) - Exit with non-zero status when vulnerabilities are found. So you can have `npm audit` as a test or prepublish step! - ([@iarna](https://github.com/iarna)) -* [`bc3fc55fa`](https://github.com/npm/npm/commit/bc3fc55fae648da8efaf1be5b86078f0f736282e) - Verify lockfile integrity before running. You'd get an error either way, but this way it's - faster and can give you more concrete instructions on how to fix it. - ([@iarna](https://github.com/iarna)) -* [`2ac8edd42`](https://github.com/npm/npm/commit/2ac8edd4248f2393b35896f0300b530e7666bb0e) - Refuse to run in global mode. Audits require a lockfile and globals don't have one. Yet. - ([@iarna](https://github.com/iarna)) - -### CTRL-C OUT DURING PACKAGE EXTRACTION AS MUCH AS YOU WANT! - -* [`663d8b5e5`](https://github.com/npm/npm/commit/663d8b5e5427c2243149d2dd6968faa117e9db3f) - [npm/lockfile#29](https://github.com/npm/lockfile/pull/29) - `lockfile@1.0.4`: - Switches to `signal-exit` to detect abnormal exits and remove locks. - ([@Redsandro](https://github.com/Redsandro)) - -### SHRONKWRAPS AND LACKFILES - -If a published modules had legacy `npm-shrinkwrap.json` we were saving -ordinary registry dependencies (`name@version`) to your `package-lock.json` -as `https://` URLs instead of versions. - -* [`36f998411`](https://github.com/npm/npm/commit/36f9984113e39d7b190010a2d0694ee025924dcb) - When saving the lock-file compute how the dependency is being required instead of using - `_resolved` in the `package.json`. This fixes the bug that was converting - registry dependencies into `https://` dependencies. - ([@iarna](https://github.com/iarna)) -* [`113e1a3af`](https://github.com/npm/npm/commit/113e1a3af2f487c753b8871d51924682283c89fc) - When encountering a `https://` URL in our lockfiles that point at our default registry, extract - the version and use them as registry dependencies. This lets us heal - `package-lock.json` files produced by 6.0.0 - ([@iarna](https://github.com/iarna)) - -### MORE `package-lock.json` FORMAT CHANGES?! - -* [`074502916`](https://github.com/npm/npm/commit/0745029168dfdfee0d1823137550e6ebccf741a5) - [#20384](https://github.com/npm/npm/pull/20384) - Add `from` field back into package-lock for git dependencies. This will give - npm the information it needs to figure out whether git deps are valid, - specially when running with legacy install metadata or in - `--package-lock-only` mode when there's no `node_modules`. This should help - remove a significant amount of git-related churn on the lock-file. - ([@zkat](https://github.com/zkat)) - -### DOCUMENTATION IMPROVEMENTS - -* [`e0235ebb6`](https://github.com/npm/npm/commit/e0235ebb6e560f0114b8babedb6949385ab9bd57) - [#20384](https://github.com/npm/npm/pull/20384) - Update the lock-file spec doc to mention that we now generate the from field for `git`-type dependencies. - ([@watilde](https://github.com/watilde)) -* [`35de04676`](https://github.com/npm/npm/commit/35de04676a567ef11e1dd031d566231021d8aff2) - [#20408](https://github.com/npm/npm/pull/20408) - Describe what the colors in outdated mean. - ([@teameh](https://github.com/teameh)) - -### BUGFIXES - -* [`1b535cb9d`](https://github.com/npm/npm/commit/1b535cb9d4a556840aeab2682cc8973495c9919a) - [#20358](https://github.com/npm/npm/pull/20358) - `npm install-test` (aka `npm it`) will no longer generate `package-lock.json` - when running with `--no-package-lock` or `package-lock=false`. - ([@raymondfeng](https://github.com/raymondfeng)) -* [`268f7ac50`](https://github.com/npm/npm/commit/268f7ac508cda352d61df63a2ae7148c54bdff7c) - [`5f84ebdb6`](https://github.com/npm/npm/commit/5f84ebdb66e35486d1dec1ca29e9ba0e4c5b6d5f) - [`c12e61431`](https://github.com/npm/npm/commit/c12e61431ecf4f77e56dc8aa55c41d5d7eeaacad) - [#20390](https://github.com/npm/npm/pull/20390) - Fix a scenario where a git dependency had a comittish associated with it - that was not a complete commitid. `npm` would never consider that entry - in the `package.json` as matching the entry in the `package-lock.json` and - this resulted in inappropriate pruning or reinstallation of git - dependencies. This has been addressed in two ways, first, the addition of the - `from` field as described in [#20384](https://github.com/npm/npm/pull/20384) means - we can exactly match the `package.json`. Second, when that's missing (when working with - older `package-lock.json` files), we assume that the match is ok. (If - it's not, we'll fix it up when a real installation is done.) - ([@iarna](https://github.com/iarna)) - -### DOCS - -* [`7b13bf5e3`](https://github.com/npm/npm/commit/7b13bf5e373e2ae2466ecaa3fd6dcba67a97f462) - [#20331](https://github.com/npm/npm/pull/20331) - Fix broken link to 'private-modules' page. The redirect went away when the new - npm website went up, but the new URL is better anyway. - ([@vipranarayan14](https://github.com/vipranarayan14)) -* [`1c4ffddce`](https://github.com/npm/npm/commit/1c4ffddce05c25ef51e254dfc6a9a97e03c711ce) - [#20279](https://github.com/npm/npm/pull/20279) - Document the `--if-present` option for `npm run-script`. - ([@aleclarson](https://github.com/aleclarson)) - -### DEPENDENCY UPDATES - -* [`815d91ce0`](https://github.com/npm/npm/commit/815d91ce0e8044775e884c1dab93052da57f6650) - `libnpx@10.2.0` - ([@zkat](https://github.com/zkat)) -* [`02715f19f`](https://github.com/npm/npm/commit/02715f19fbcdecec8990b92fc60b1a022c59613b) - `update-notifier@2.5.0` - ([@alexccl](https://github.com/alexccl)) -* [`08c4ddd9e`](https://github.com/npm/npm/commit/08c4ddd9eb560aa6408a1bb1c1d2d9aa6ba46ba0) - `tar@4.4.2` - ([@isaacs](https://github.com/isaacs)) -* [`53718cb12`](https://github.com/npm/npm/commit/53718cb126956851850839b4d7d3041d4e9a80d0) - `tap@11.1.4` - ([@isaacs](https://github.com/isaacs)) -* [`0a20cf546`](https://github.com/npm/npm/commit/0a20cf546a246ac12b5fe2b6235ffb8649336ec4) - `safe-buffer@5.1.2` - ([@feross](https://github.com/feross)) -* [`e8c8e844c`](https://github.com/npm/npm/commit/e8c8e844c194351fe2d65cf3af79ef318bbc8bec) - `retry@0.12.0` - ([@tim-kos](https://github.com/tim-kos)) -* [`76c7f21bd`](https://github.com/npm/npm/commit/76c7f21bd04407d529edc4a76deaa85a2d6b6e6f) - `read-package-tree@5.2.1` - ([@zkat](https://github.com/zkat)) -* [`c8b0aa07b`](https://github.com/npm/npm/commit/c8b0aa07b34a0b0f8bc85154da75d9fb458eb504) - `query-string@6.1.0` - ([@sindresorhus](https://github.com/sindresorhus)) -* [`abfd366b4`](https://github.com/npm/npm/commit/abfd366b4709325f954f2b1ee5bd475330aab828) - `npm-package-arg@6.1.0` - ([@zkat](https://github.com/zkat)) -* [`bd29baf83`](https://github.com/npm/npm/commit/bd29baf834c3e16a9b3d7b60cdb4f462889800bf) - `lock-verify@2.0.2` - ([@iarna](https://github.com/iarna)) - -## v5.10.0-next.0 (2018-04-12): - -### NEW FEATURES - -* [`32ec2f54b`](https://github.com/npm/npm/commit/32ec2f54b2ad7370f2fd17e6e2fbbb2487c81266) - [#20257](https://github.com/npm/npm/pull/20257) - Add shasum and integrity to the new `npm view` output. - ([@zkat](https://github.com/zkat)) -* [`a22153be2`](https://github.com/npm/npm/commit/a22153be239dfd99d87a1a1c7d2c3700db0bebf3) - [#20126](https://github.com/npm/npm/pull/20126) - Add `npm cit` command that's equivalent of `npm ci && npm t` that's equivalent of `npm it`. - ([@SimenB](https://github.com/SimenB)) - -### BUG FIXES - -* [`089aeaf44`](https://github.com/npm/npm/commit/089aeaf4479f286b1ce62716c6442382ff0f2150) - Fix a bug where OTPs passed in via the commandline would have leading - zeros deleted resulted in authentication failures. - ([@iarna](https://github.com/iarna)) -* [`6eaa860ea`](https://github.com/npm/npm/commit/6eaa860ead3222a6dbd6d370b4271e7bf242b30b) - Eliminate direct use of `new Buffer` in `npm`. While the use of it in `npm` was safe, there - are two other reasons for this change: - - 1. Node 10 emits warnings about its use. - 2. Users who require npm as a library (which they definitely should not do) - can call the functions that call `new Buffer` in unsafe ways, if they try - really hard. - - ([@iarna](https://github.com/iarna)) - -* [`85900a294`](https://github.com/npm/npm/commit/85900a2944fed14bc8f59c48856fb797faaafedc) - Starting with 5.8.0 the `requires` section of the lock-file saved version ranges instead of - specific versions. Due to a bug, further actions on the same lock-file would result in the - range being switched back to a version. This corrects that, keeping ranges when they appear. - ([@iarna](https://github.com/iarna)) -* [`0dffa9c2a`](https://github.com/npm/npm/commit/0dffa9c2ae20b669f65c8e596dafd63e52248250) - [`609d6f6e1`](https://github.com/npm/npm/commit/609d6f6e1b39330b64ca4677a531819f2143a283) - [`08f81aa94`](https://github.com/npm/npm/commit/08f81aa94171987a8e1b71a87034e7b028bb9fc7) - [`f8b76e076`](https://github.com/npm/npm/commit/f8b76e0764b606e2c129cbaa66e48ac6a3ebdf8a) - [`6d609822d`](https://github.com/npm/npm/commit/6d609822d00da7ab8bd05c24ec4925094ecaef53) - [`59d080a22`](https://github.com/npm/npm/commit/59d080a22f7314a8e4df6e4f85c84777c1e4be42) - Restore the ability to bundle dependencies that are uninstallable from the - registry. This also eliminates needless registry lookups for bundled - dependencies. - - Fixed a bug where attempting to install a dependency that is bundled - inside another module without reinstalling that module would result in - ENOENT errors. - ([@iarna](https://github.com/iarna)) -* [`db846c2d5`](https://github.com/npm/npm/commit/db846c2d57399f277829036f9d96cd767088097e) - [#20029](https://github.com/npm/npm/pull/20029) - Allow packages with non-registry specifiers to follow the fast path that - the we use with the lock-file for registry specifiers. This will improve install time - especially when operating only on the package-lock (`--package-lock-only`). - - ([@zkat](https://github.com/zkat)) - - Fix the a bug where `npm i --only=prod` could remove development - dependencies from lock-file. - ([@iarna](https://github.com/iarna)) -* [`3e12d2407`](https://github.com/npm/npm/commit/3e12d2407446661d3dd226b03a2b6055b7932140) - [#20122](https://github.com/npm/npm/pull/20122) - Improve the update-notifier messaging (borrowing ideas from pnpm) and - eliminate false positives. - ([@zkat](https://github.com/zkat)) -* [`f18be9b39`](https://github.com/npm/npm/commit/f18be9b39888d05c7f98946c53214f40914f6284) - [#20154](https://github.com/npm/npm/pull/20154) - Let version succeed when `package-lock.json` is gitignored. - ([@nwoltman](https://github.com/nwoltman)) -* [`ced29253d`](https://github.com/npm/npm/commit/ced29253df6c6d67e4bf47ca83e042db4fb19034) - [#20212](https://github.com/npm/npm/pull/20212) - Ensure that we only create an `etc` directory if we are actually going to write files to it. - ([@buddydvd](https://github.com/buddydvd)) -* [`8e21b19a8`](https://github.com/npm/npm/commit/8e21b19a8c5e7d71cb51f3cc6a8bfaf7749ac2c5) - [#20140](https://github.com/npm/npm/pull/20140) - Note in documentation that `package-lock.json` version gets touched by `npm version`. - ([@srl295](https://github.com/srl295)) -* [`5d17c87d8`](https://github.com/npm/npm/commit/5d17c87d8d27caeac71f291fbd62628f2765fda2) - [#20032](https://github.com/npm/npm/pull/20032) - Fix bug where unauthenticated errors would get reported as both 404s and - 401s, i.e. `npm ERR! 404 Registry returned 401`. In these cases the error - message will now be much more informative. - ([@iarna](https://github.com/iarna)) -* [`05ff6c9b1`](https://github.com/npm/npm/commit/05ff6c9b14cb095988b768830e51789d6b6b8e6e) - [#20082](https://github.com/npm/npm/pull/20082) - Allow optional @ prefix on scope with `npm team` commands for parity with other commands. - ([@bcoe](https://github.com/bcoe)) -* [`6bef53891`](https://github.com/npm/npm/commit/6bef538919825b8cd2e738333bdd7b6ca2e2e0e3) - [#19580](https://github.com/npm/npm/pull/19580) - Improve messaging when two-factor authentication is required while publishing. - ([@jdeniau](https://github.com/jdeniau)) -* [`155dab2bd`](https://github.com/npm/npm/commit/155dab2bd7b06724eca190abadd89c9f03f85446) - Fix a bug where optional status of a dependency was not being saved to - the package-lock on the initial install. - ([@iarna](https://github.com/iarna)) -* [`8d6a4cafc`](https://github.com/npm/npm/commit/8d6a4cafc2e6963d9ec7c828e1af6f2abc12e7f3) - [`a0937e9af`](https://github.com/npm/npm/commit/a0937e9afe126dce7a746c1a6270b1ac69f2a9b3) - Ensure that `--no-optional` does not remove optional dependencies from the lock-file. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCY UPDATES - -* [`8baa37551`](https://github.com/npm/npm/commit/8baa37551945bc329a6faf793ec5e3e2feff489b) - [zkat/cipm#46](https://github.com/zkat/cipm/pull/46) - `libcipm@1.6.2`: - Detect binding.gyp for default install lifecycle. Let's `npm ci` work on projects that - have their own C code. - ([@caleblloyd](https://github.com/caleblloyd)) -* [`323f74242`](https://github.com/npm/npm/commit/323f74242066c989f7faf94fb848ff8f3b677619) - [zkat/json-parse-better-errors#1](https://github.com/zkat/json-parse-better-errors/pull/1) - `json-parse-better-errors@1.0.2` - ([@Hoishin](https://github.com/Hoishin)) -* [`d0cf1f11e`](https://github.com/npm/npm/commit/d0cf1f11e5947446f74881a3d15d6a504baea619) - `readable-stream@2.3.6` - ([@mcollina](https://github.com/mcollina)) -* [`9e9fdba5e`](https://github.com/npm/npm/commit/9e9fdba5e7b7f3a1dd73530dadb96d9e3445c48d) - `update-notifier@2.4.0` - ([@sindersorhus](https://github.com/sindersorhus)) -* [`57fa33870`](https://github.com/npm/npm/commit/57fa338706ab122ab7e13d2206016289c5bdacf3) - `marked@0.3.1` - ([@joshbruce](https://github.com/joshbruce)) -* [`d2b20d34b`](https://github.com/npm/npm/commit/d2b20d34b60f35eecf0d51cd1f05de79b0e15096) - [#20276](https://github.com/npm/npm/pull/20276) - `node-gyp@3.6.2` -* [`2b5700679`](https://github.com/npm/npm/commit/2b5700679fce9ee0c24c4509618709a4a35a3d27) - [zkat/npx#172](https://github.com/zkat/npx/pull/172) - `libnpx@10.1.1` - ([@jdalton](https://github.com/jdalton)) - -## v5.9.0 (2018-03-23): - -Coming to you this week are a fancy new package view, pack/publish previews -and a handful of bug fixes! Let's get right in! - -### NEW PACKAGE VIEW - -There's a new `npm view` in town. You might it as `npm info` or `npm show`. -The new output gives you a nicely summarized view that for most packages -fits on one screen. If you ask it for `--json` you'll still get the same -results, so your scripts should still work fine. - -* [`143cdbf13`](https://github.com/npm/npm/commit/143cdbf1327f7d92ccae405bc05d95d28939a837) - [#19910](https://github.com/npm/npm/pull/19910) - Add humanized default view. - ([@zkat](https://github.com/zkat)) -* [`ca84be91c`](https://github.com/npm/npm/commit/ca84be91c434fb7fa472ee4c0b7341414acf52b5) - [#19910](https://github.com/npm/npm/pull/19910) - `tiny-relative-date@1.3.0` - ([@zkat](https://github.com/zkat)) -* [`9a5807c4f`](https://github.com/npm/npm/commit/9a5807c4f813c49b854170b6111c099b3054faa2) - [#19910](https://github.com/npm/npm/pull/19910) - `cli-columns@3.1.2` - ([@zkat](https://github.com/zkat)) -* [`23b4a4fac`](https://github.com/npm/npm/commit/23b4a4fac0fbfe8e03e2f65d9f674f163643d15d) - [#19910](https://github.com/npm/npm/pull/19910) - `byte-size@4.0.2` - -### PACK AND PUBLISH PREVIEWS - -The `npm pack` and `npm publish` commands print out a summary of the files -included in the package. They also both now take the `--dry-run` flag, so -you can double check your `.npmignore` settings before doing a publish. - -* [`116e9d827`](https://github.com/npm/npm/commit/116e9d8271d04536522a7f02de1dde6f91ca5e6e) - [#19908](https://github.com/npm/npm/pull/19908) - Add package previews to pack and publish. Also add --dry-run and --json - flags. - ([@zkat](https://github.com/zkat)) - -### MERGE CONFLICT, SMERGE CONFLICT - -If you resolve a `package-lock.json` merge conflict with `npm install` we -now suggest you setup a merge driver to handle these automatically for you. -If you're reading this and you'd like to set it up now, run: - -```console -npx npm-merge-driver install -g -``` - -* [`5ebe99719`](https://github.com/npm/npm/commit/5ebe99719d11fedeeec7a55f1b389dcf556f32f3) - [#20071](https://github.com/npm/npm/pull/20071) - suggest installing the merge driver - ([@zkat](https://github.com/zkat)) - -### MISC BITS - -* [`a05e27b71`](https://github.com/npm/npm/commit/a05e27b7104f9a79f5941e7458c4658872e5e0cd) - Going forward, record requested ranges not versions in the package-lock. - ([@iarna](https://github.com/iarna)) -* [`f721eec59`](https://github.com/npm/npm/commit/f721eec599df4bdf046d248e0f50822d436654b4) - Add 10 to Node.js supported version list. It's not out yet, but soon my pretties... - ([@iarna](https://github.com/iarna)) - -### DEPENDENCY UPDATES - -* [`40aabb94e`](https://github.com/npm/npm/commit/40aabb94e3f24a9feabb9c490403e10ec9dc254f) - `libcipm@1.6.1`: - Fix bugs on docker and with some `prepare` scripts and `npm ci`. - Fix a bug where script hooks wouldn't be called with `npm ci`. - Fix a bug where `npm ci` and `--prefix` weren't compatible. - ([@isaacseymour](https://github.com/isaacseymour)) - ([@umarov](https://github.com/umarov)) - ([@mikeshirov](https://github.com/mikeshirov)) - ([@billjanitsch](https://github.com/billjanitsch)) -* [`a85372e67`](https://github.com/npm/npm/commit/a85372e671eab46e62caa46631baa30900e32114) - `tar@4.4.1`: - Switch to safe-buffer and Buffer.from. - ([@isaacs](https://github.com/isaacs)) - ([@ChALkeR](https://github.com/ChALkeR)) -* [`588eabd23`](https://github.com/npm/npm/commit/588eabd23fa04420269b9326cab26d974d9c151f) - `lru-cache@4.1.2`: -* [`07f27ee89`](https://github.com/npm/npm/commit/07f27ee898f3c3199e75427017f2b6a189b1a85b) - `qrcode-terminal@0.12.0`: -* [`01e4e29bc`](https://github.com/npm/npm/commit/01e4e29bc879bdaa0e92f0b58e3725a41377d21c) - `request@2.85.0` -* [`344ba8819`](https://github.com/npm/npm/commit/344ba8819f485c72e1c7ac3e656d7e9210ccf607) - `worker-farm@1.6.0` -* [`dc6df1bc4`](https://github.com/npm/npm/commit/dc6df1bc4677164b9ba638e87c1185b857744720) - `validate-npm-package-license@3.0.3` -* [`97a976696`](https://github.com/npm/npm/commit/97a9766962ab5125af3b2a1f7b4ef550a2e3599b) - `ssri@5.3.0` -* [`9b629d0c6`](https://github.com/npm/npm/commit/9b629d0c69599635ee066cb71fcc1b0155317f19) - `query-string@5.1.1` - -## v5.8.0 (2018-03-08): - -Hey again, everyone! While last release was focused largely around PRs from the -CLI team, this release is mostly pulling in community PRs in npm itself and its -dependencies! We've got a good chunk of wonderful contributions for y'all, and -even new features and performance improvements! 🎉 - -We're hoping to continue our biweekly (as in every-other-week biweekly) release -schedule from now on, so you should be seeing more steady npm releases from here -on out. And that's good, 'cause we've got a _ton_ of new stuff on our roadmap -for this year. Keep an eye out for exciting news. 👀 - -### FEATURES - -* [`2f513fe1c`](https://github.com/npm/npm/commit/2f513fe1ce6db055b04a63fe4360212a83f77b34) - [#19904](https://github.com/npm/npm/pull/19904) - Make a best-attempt at preserving line ending style when saving - `package.json`/`package-lock.json`/`npm-shrinkwrap.json`. This goes - hand-in-hand with a previous patch to preserve detected indentation style. - ([@tuananh](https://github.com/tuananh)) -* [`d3cfd41a2`](https://github.com/npm/npm/commit/d3cfd41a28253db5a18260f68642513cbbc93e3b) - `pacote@7.6.1` ([@zkat](https://github.com/zkat)) - * Enable `file:`-based `resolved` URIs in `package-lock.json`. - * Retry git-based operations on certain types of failure. -* [`ecfbb16dc`](https://github.com/npm/npm/commit/ecfbb16dc705f28aa61b3223bdbf9e47230a0fa4) - [#19929](https://github.com/npm/npm/pull/19929) - Add support for the [`NO_COLOR` standard](http://no-color.org). This gives a - cross-application, consistent way of disabling ANSI color code output. Note - that npm already supported this through `--no-color` or - `npm_config_color='false'` configurations, so this is just another way to do - it. - ([@chneukirchen](https://github.com/chneukirchen)) -* [`fc8761daf`](https://github.com/npm/npm/commit/fc8761daf1e8749481457973890fa516eb96a195) - [#19629](https://github.com/npm/npm/pull/19629) - Give more detailed, contextual information when npm fails to parse - `package-lock.json` and `npm-shrinkwrap.json`, instead of saying `JSON parse - error` and leaving you out in the cold. - ([@JoshuaKGoldberg](https://github.com/JoshuaKGoldberg)) -* [`1d368e1e6`](https://github.com/npm/npm/commit/1d368e1e63229f236b9dbabf628989fa3aa98bdb) - [#19157](https://github.com/npm/npm/pull/19157) - Add `--no-proxy` config option. Previously, you needed to use the `NO_PROXY` - environment variable to use this feature -- now it's an actual npm option. - ([@Saturate](https://github.com/Saturate)) -* [`f0e998daa`](https://github.com/npm/npm/commit/f0e998daa049810d5f928615132250021e46451d) - [#18426](https://github.com/npm/npm/pull/18426) - Do environment variable replacement in config files even for config keys or - fragments of keys. - ([@misak113](https://github.com/misak113)) -* [`9847c82a8`](https://github.com/npm/npm/commit/9847c82a8528cfdf5968e9bb00abd8ed47903b5c) - [#18384](https://github.com/npm/npm/pull/18384) - Better error messaging and suggestions when users get `EPERM`/`EACCES` errors. - ([@chrisjpatty](https://github.com/chrisjpatty)) -* [`b9d0c0c01`](https://github.com/npm/npm/commit/b9d0c0c0173542a8d741a9a17b9fb34fbaf5068e) - [#19448](https://github.com/npm/npm/pull/19448) - Holiday celebrations now include all JavaScripters, not just Node developers. - ([@isaacs](https://github.com/isaacs)) - -### NPM CI - -I hope y'all have been having fun with `npm ci` so far! Since this is the first -release since that went out, we've had a few fixes and improvements now that -folks have actually gotten their hands on it! Benchmarks have been super -promising so far, and I've gotten messages from a lot of you saying you've sped -up your CI work by **2-5x** in some cases! Have a good example? Tell us on -Twitter! - -`npm ci` is, right now, [the fastest -installer](http://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable) -you can use in CI situations, so go check it out if you haven't already! We'll -continue doing performance improvements on it, and a lot of those will help make -`npm install` fast as well. 🏎😎 - -* [`0d7f203d9`](https://github.com/npm/npm/commit/0d7f203d9e86cc6c8d69107689ea60fc7cbab424) - `libcipm@1.6.0` - ([@zkat](https://github.com/zkat)) - -This `libcipm` release includes a number of improvements: - -* **PERFORMANCE** Reduce calls to `read-package-json` and separate JSON update phase from man/bin linking phase. `npm ci` should be noticeably faster. -* **FEATURE** Progress bar now fills up as packages are installed, instead of sitting there doing nothing. -* **BUGFIX** Add support for `--only` and `--also` options. -* **BUFGIX** Linking binaries and running scripts in parallel was causing packages to sometimes clobber each other when hoisted, as well as potentially running too many run-scripts in parallel. This is now a serial operation, and it turns out to have had relatively little actual performance impact. -* **BUGFIX** Stop adding `_from` to directory deps (aka `file:packages/my-dep`). - -### BUGFIXES - -* [`58d2aa58d`](https://github.com/npm/npm/commit/58d2aa58d5f9c4db49f57a5f33952b3106778669) - [#20027](https://github.com/npm/npm/pull/20027) - Use a specific mtime when packing tarballs instead of the beginning of epoch - time. This should allow `npm pack` to generate tarballs with identical hashes - for identical contents, while fixing issues with some `zip` implementations - that do not support pre-1980 timestamps. - ([@isaacs](https://github.com/isaacs)) -* [`4f319de1d`](https://github.com/npm/npm/commit/4f319de1d6e8aca5fb68f78023425233da4f07f6) - Don't fall back to couch adduser if we didn't try couch login. - ([@iarna](https://github.com/iarna)) -* [`c8230c9bb`](https://github.com/npm/npm/commit/c8230c9bbd596156a4a8cfe62f2370f81d22bd9f) - [#19608](https://github.com/npm/npm/pull/19608) - Fix issue where using the npm-bundled `npx` on Windows was invoking `npx - prefix` (and downloading that package). - ([@laggingreflex](https://github.com/laggingreflex)) -* [`d70c01970`](https://github.com/npm/npm/commit/d70c01970311f4e84b35eef8559c114136a9ebc7) - [#18953](https://github.com/npm/npm/pull/18953) - Avoid using code that depends on `node@>=4` in the `unsupported` check, so npm - can report the issue normally instead of syntax-crashing. - ([@deployable](https://github.com/deployable)) - -### DOCUMENTATION - -* [`4477ca2d9`](https://github.com/npm/npm/commit/4477ca2d993088ac40ef5cf39d1f9c68be3d6252) - `marked@0.3.17`: Fixes issue preventing correct rendering of backticked - strings. man pages should be rendering correctly now instead of having empty - spaces wherever backticks were used. - ([@joshbruce](https://github.com/joshbruce)) -* [`71076ebda`](https://github.com/npm/npm/commit/71076ebdaddd04f2bf330fe668f15750bcff00ea) - [#19950](https://github.com/npm/npm/pull/19950) - Add a note to install --production. - ([@kyranet](https://github.com/kyranet)) -* [`3a33400b8`](https://github.com/npm/npm/commit/3a33400b89a8dd00fa9a49fcb57a8add36f79fa6) - [#19957](https://github.com/npm/npm/pull/19957) - nudge around some details in ci docs - ([@zkat](https://github.com/zkat)) -* [`06038246a`](https://github.com/npm/npm/commit/06038246a3fa58d6f42bb4ab897aa534ff6ed282) - [#19893](https://github.com/npm/npm/pull/19893) - Add a common open reason to the issue template. - ([@MrStonedOne](https://github.com/MrStonedOne)) -* [`7376dd8af`](https://github.com/npm/npm/commit/7376dd8afb654929adade126b4925461aa52da12) - [#19870](https://github.com/npm/npm/pull/19870) - Fix typo in `npm-config.md` - ([@joebowbeer](https://github.com/joebowbeer)) -* [`5390ed4fa`](https://github.com/npm/npm/commit/5390ed4fa2b480f7c58fff6ee670120149ec2d45) - [#19858](https://github.com/npm/npm/pull/19858) - Fix documented default value for config save option. It was still documented - as `false`, even though `npm@5.0.0` set it to `true` by default. - ([@nalinbhardwaj](https://github.com/nalinbhardwaj)) -* [`dc36d850a`](https://github.com/npm/npm/commit/dc36d850a1d763f71a98c99db05ca875dab124ed) - [#19552](https://github.com/npm/npm/pull/19552) - Rework `npm update` docs now that `--save` is on by default. - ([@selbekk](https://github.com/selbekk)) -* [`5ec5dffc8`](https://github.com/npm/npm/commit/5ec5dffc80527d9330388ff82926dd890f4945af) - [#19726](https://github.com/npm/npm/pull/19726) - Clarify that `name` and `version` fields are optional if your package is not - supposed to be installable as a dependency. - ([@ngarnier](https://github.com/ngarnier)) -* [`046500994`](https://github.com/npm/npm/commit/0465009942d6423f878c1359e91972fa5990f996) - [#19676](https://github.com/npm/npm/pull/19676) - Fix documented cache location on Windows. - ([@VladRassokhin](https://github.com/VladRassokhin)) -* [`ffa84cd0f`](https://github.com/npm/npm/commit/ffa84cd0f43c07858506764b4151ba6af11ea120) - [#19475](https://github.com/npm/npm/pull/19475) - Added example for `homepage` field from `package.json`. - ([@cg-cnu](https://github.com/cg-cnu)) -* [`de72d9a18`](https://github.com/npm/npm/commit/de72d9a18ae650ebaee0fdd6694fc89b1cbe8e95) - [#19307](https://github.com/npm/npm/pull/19307) - Document the `requires` field in `npm help package-lock.json`. - ([@jcrben](https://github.com/jcrben)) -* [`35c4abded`](https://github.com/npm/npm/commit/35c4abdedfa622f27e8ee47aa6e293f435323623) - [#18976](https://github.com/npm/npm/pull/18976) - Typo fix in coding style documentation. - ([@rinfan](https://github.com/rinfan)) -* [`0616fd22a`](https://github.com/npm/npm/commit/0616fd22a4e4f2b2998bb70d86d269756aab64be) - [#19216](https://github.com/npm/npm/pull/19216) - Add `edit` section to description in `npm-team.md`. - ([@WispProxy](https://github.com/WispProxy)) -* [`c2bbaaa58`](https://github.com/npm/npm/commit/c2bbaaa582d024cc48b410757efbb81d95837d43) - [#19194](https://github.com/npm/npm/pull/19194) - Tiny style fix in `npm.md`. - ([@WispProxy](https://github.com/WispProxy)) -* [`dcdfdcbb0`](https://github.com/npm/npm/commit/dcdfdcbb0035ef3290bd0912f562e26f6fc4ea94) - [#19192](https://github.com/npm/npm/pull/19192) - Document `--development` flag in `npm-ls.md`. - ([@WispProxy](https://github.com/WispProxy)) -* [`d7ff07135`](https://github.com/npm/npm/commit/d7ff07135a685dd89c15e29d6a28fca33cf448b0) - [#18514](https://github.com/npm/npm/pull/18514) - Make it so `javascript` -> `JavaScript`. This is important. - ([@masonpawsey](https://github.com/masonpawsey)) -* [`7a8705113`](https://github.com/npm/npm/commit/7a870511327d31e8921d6afa845ec8065c60064b) - [#18407](https://github.com/npm/npm/pull/18407) - Clarify the mechanics of the `file` field in `package.json` a bit. - ([@bmacnaughton](https://github.com/bmacnaughton)) -* [`b2a1cf084`](https://github.com/npm/npm/commit/b2a1cf0844ceaeb51ed04f3ae81678527ec9ae68) - [#18382](https://github.com/npm/npm/pull/18382) - Document the [`browser` - field](https://github.com/defunctzombie/package-browser-field-spec) in - `package.json`. - ([@mxstbr](https://github.com/mxstbr)) - -### MISC - -* [`b8a48a959`](https://github.com/npm/npm/commit/b8a48a9595b379cfc2a2c576f61062120ea0caf7) - [#19907](https://github.com/npm/npm/pull/19907) - Consolidate code for stringifying `package.json` and package locks. Also adds - tests have been added to test that `package[-lock].json` files are written to - disk with their original line endings. - ([@nwoltman](https://github.com/nwoltman)) -* [`b4f707d9f`](https://github.com/npm/npm/commit/b4f707d9f543f0995ed5811827a892fc8b2192b5) - [#19879](https://github.com/npm/npm/pull/19879) - Remove unused devDependency `nock` from `.gitignore`. - ([@watilde](https://github.com/watilde)) -* [`8150dd5f7`](https://github.com/npm/npm/commit/8150dd5f72520eb143f75e44787a5775bd8b8ebc) - [#16540](https://github.com/npm/npm/pull/16540) - Stop doing an `uninstall` when using `make clean`. - ([@metux](https://github.com/metux)) - -### OTHER DEPENDENCY BUMPS - -* [`ab237a2a5`](https://github.com/npm/npm/commit/ab237a2a5dcf70ee490e2f0322dfedb1560251d4) - `init-package-json@1.10.3` - ([@zkat](https://github.com/zkat)) -* [`f6d668941`](https://github.com/npm/npm/commit/f6d6689414f00a67a1f34afc6791bdc7d7be4d9b) - `npm-lifecycle@2.0.1` - ([@zkat](https://github.com/zkat)) -* [`882bfbdfa`](https://github.com/npm/npm/commit/882bfbdfaa3eb09b35875e648545cb6967f72562) - `npm-registry-client@8.5.1` - ([@zkat](https://github.com/zkat)) -* [`6ae38055b`](https://github.com/npm/npm/commit/6ae38055ba69db5785ee6c394372de0333763822) - `read-package-json@2.0.1`: Support git packed refs `--all` mode. - ([@zkat](https://github.com/zkat)) -* [`89db703ae`](https://github.com/npm/npm/commit/89db703ae4e25b9fb6c9d7c5119520107a23a752) - `readable-stream@2.3.5` - ([@mcollina](https://github.com/mcollina)) -* [`634dfa5f4`](https://github.com/npm/npm/commit/634dfa5f476b7954b136105a8f9489f5631085a3) - `worker-farm@1.5.4` - ([@rvagg](https://github.com/rvagg)) -* [`92ad34439`](https://github.com/npm/npm/commit/92ad344399f7a23e308d0f3f02547656a47ae6c5) - `hosted-git-info@2.6.0` - ([@zkat](https://github.com/zkat)) -* [`75279c488`](https://github.com/npm/npm/commit/75279c4884d02bd7d451b66616e320eb8cb03bcb) - `tar@4.4.0` - ([@isaacs](https://github.com/isaacs)) -* [`228aba276`](https://github.com/npm/npm/commit/228aba276b19c987cd5989f9bb9ffbe25edb4030) - `write-file-atomic@2.3.0` - ([@iarna](https://github.com/iarna)) -* [`006e9d272`](https://github.com/npm/npm/commit/006e9d272914fc3ba016f110b1411dd20f8a937d) - `libnpx@10.0.1` - ([@zkat](https://github.com/zkat)) -* [`9985561e6`](https://github.com/npm/npm/commit/9985561e666473deeb352c1d4252adf17c2fa01d) - `mississippi@3.0.0` - ([@bcomnes](https://github.com/bcomnes)) -* [`1dc6b3b52`](https://github.com/npm/npm/commit/1dc6b3b525967bc8526aa4765e987136cb570e8e) - `tap@11.1.2` - ([@isaacs](https://github.com/isaacs)) - -## v5.7.1 (2018-02-22): - -This release reverts a patch that could cause some ownership changes on system -files when running from some directories when also using `sudo`. 😲 - -Thankfully, it only affected users running `npm@next`, which is part of our -staggered release system, which we use to prevent issues like this from going -out into the wider world before we can catch them. Users on `latest` would have -never seen this! - -The original patch was added to increase consistency and reliability of methods -npm uses to avoid writing files as `root` in places it shouldn't, but the change -was applied in places that should have used regular `mkdirp`. This release -reverts that patch. - -* [`74e149da6`](https://github.com/npm/npm/commit/74e149da6efe6ed89477faa81fef08eee7999ad0) - [`#19883`](https://github.com/npm/npm/issue/19883) - Revert "*: Switch from mkdirp to correctMkdir to preserve perms and owners" - This reverts commit [`94227e15`](https://github.com/npm/npm/commit/94227e15eeced836b3d7b3d2b5e5cc41d4959cff). - ([@zkat](https://github.com/zkat)) - -## v5.7.0 (2018-02-20): - -Hey y'all, it's been a while. Expect our release rate to increase back to -normal here, as we've got a lot in the pipeline. Right now we've got a -bunch of things from folks at npm. In the next release we'll be focusing on -user contributions and there are a lot of them queued up! - -This release brings a bunch of exciting new features and bug fixes. - -### PACKAGE-LOCK GIT MERGE CONFLICT RESOLUTION - -Allow `npm install` to fix `package-lock.json` and `npm-shrinkwrap.json` -files that have merge conflicts in them without your having to edit them. -It works in conjunction with -[`npm-merge-driver`](https://www.npmjs.com/package/npm-merge-driver) to -entirely eliminate package-lock merge conflicts. - -* [`e27674c22`](https://github.com/npm/npm/commit/e27674c221dc17473f23bffa50123e49a021ae34) - Automatically resolve merge conflicts in lock-files. - ([@zkat](https://github.com/zkat)) - -### NPM CI - -The new `npm ci` command installs from your lock-file ONLY. If your -`package.json` and your lock-file are out of sync then it will report an error. - -It works by throwing away your `node_modules` and recreating it from scratch. - -Beyond guaranteeing you that you'll only get what is in your lock-file it's -also much faster (2x-10x!) than `npm install` when you don't start with a -`node_modules`. - -As you may take from the name, we expect it to be a big boon to continuous -integration environments. We also expect that folks who do production -deploys from git tags will see major gains. - -* [`5e4de9c99`](https://github.com/npm/npm/commit/5e4de9c99c934e25ef7b9c788244cc3c993da559) - Add new `npm ci` installer. - ([@zkat](https://github.com/zkat)) - -### OTHER NEW FEATURES - -* [`4d418c21b`](https://github.com/npm/npm/commit/4d418c21b051f23a3b6fb085449fdf4bf4f826f5) - [#19817](https://github.com/npm/npm/pull/19817) - Include contributor count in installation summary. - ([@kemitchell](https://github.com/kemitchell)) -* [`17079c2a8`](https://github.com/npm/npm/commit/17079c2a880d3a6f8a67c8f17eedc7eb51b8f0f8) - Require password to change email through `npm profile`. - ([@iarna](https://github.com/iarna)) -* [`e7c5d226a`](https://github.com/npm/npm/commit/e7c5d226ac0ad3da0e38f16721c710909d0a9847) - [`4f5327c05`](https://github.com/npm/npm/commit/4f5327c0556764aa1bbc9b58b1a8c8a84136c56a) - [#19780](https://github.com/npm/npm/pull/19780) - Add support for web-based logins. This is not yet available on the registry, however. - ([@isaacs](https://github.com/isaacs)) - -### BIG FIXES TO PRUNING - -* [`827951590`](https://github.com/npm/npm/commit/8279515903cfa3026cf7096189485cdf29f74a8f) - Handle running `npm install package-name` with a `node_modules` containing - packages without sufficient metadata to verify their origin. The only way - to get install packages like this is to use a non-`npm` package manager. - Previously `npm` removed any packages that it couldn't verify. Now it - will leave them untouched as long as you're not asking for a full install. - On a full install they will be reinstalled (but the same versions will be - maintained). - - This will fix problems for folks who are using a third party package - manager to install packages that have `postinstall` scripts that run - `npm install`. - ([@iarna](https://github.com/iarna)) -* [`3b305ee71`](https://github.com/npm/npm/commit/3b305ee71e2bf852ff3037366a1774b8c5fcc0a5) - Only auto-prune on installs that will create a lock-file. This restores - `npm@4` compatible behavior when the lock-file is disabled. When using a - lock-file `npm` will continue to remove anything in your `node_modules` - that's not in your lock-file. ([@iarna](https://github.com/iarna)) -* [`cec5be542`](https://github.com/npm/npm/commit/cec5be5427f7f5106a905de8630e1243e9b36ef4) - Fix bug where `npm prune --production` would remove dev deps from the lock - file. It will now only remove them from `node_modules` not from your lock - file. - ([@iarna](https://github.com/iarna)) -* [`857dab03f`](https://github.com/npm/npm/commit/857dab03f2d58586b45d41d3e5af0fb2d4e824d0) - Fix bug where git dependencies would be removed or reinstalled when - installing other dependencies. - ([@iarna](https://github.com/iarna)) - -### BUG FIXES TO TOKENS AND PROFILES - -* [`a66e0cd03`](https://github.com/npm/npm/commit/a66e0cd0314893b745e6b9f6ca1708019b1d7aa3) - For CIDR filtered tokens, allow comma separated CIDR ranges, as documented. Previously - you could only pass in multiple cidr ranges with multiple `--cidr` command line options. - ([@iarna](https://github.com/iarna)) -* [`d259ab014`](https://github.com/npm/npm/commit/d259ab014748634a89cad5b20eb7a40f3223c0d5) - Fix token revocation when an OTP is required. Previously you had to pass - it in via `--otp`. Now it will prompt you for an OTP like other - `npm token` commands. - ([@iarna](https://github.com/iarna)) -* [`f8b1f6aec`](https://github.com/npm/npm/commit/f8b1f6aecadd3b9953c2b8b05d15f3a9cff67cfd) - Update token and profile commands to support legacy (username/password) authentication. - (The npm registry uses tokens, not username/password pairs, to authenticate commands.) - ([@iarna](https://github.com/iarna)) - -### OTHER BUG FIXES - -* [`6954dfc19`](https://github.com/npm/npm/commit/6954dfc192f88ac263f1fcc66cf820a21f4379f1) - Fix a bug where packages would get pushed deeper into the tree when upgrading without - an existing copy on disk. Having packages deeper in the tree ordinarily is harmless but - is not when peerDependencies are in play. - ([@iarna](https://github.com/iarna)) -* [`1ca916a1e`](https://github.com/npm/npm/commit/1ca916a1e9cf94691d1ff2e5e9d0204cfaba39e1) - Fix bug where when switching from a linked module to a non-linked module, the dependencies - of the module wouldn't be installed on the first run of `npm install`. - ([@iarna](https://github.com/iarna)) -* [`8c120ebb2`](https://github.com/npm/npm/commit/8c120ebb28e87bc6fe08a3fad1bb87b50026a33a) - Fix integrity matching to eliminate spurious EINTEGRITY errors. - ([@zkat](https://github.com/zkat)) -* [`94227e15e`](https://github.com/npm/npm/commit/94227e15eeced836b3d7b3d2b5e5cc41d4959cff) - More consistently make directories using perm and ownership preserving features. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCY UPDATES - -* [`364b23c7f`](https://github.com/npm/npm/commit/364b23c7f8a231c0df3866d6a8bde4d3f37bbc00) - [`f2049f9e7`](https://github.com/npm/npm/commit/f2049f9e7992e6edcfce8619b59746789367150f) - `cacache@10.0.4` - ([@zkat](https://github.com/zkat)) -* [`d183d7675`](https://github.com/npm/npm/commit/d183d76757e8a29d63a999d7fb4edcc1486c25c1) - `find-npm-prefix@1.0.2`: - ([@iarna](https://github.com/iarna)) -* [`ffd6ea62c`](https://github.com/npm/npm/commit/ffd6ea62ce583baff38cf4901cf599639bc193c8) - `fs-minipass@1.2.5` -* [`ee63b8a31`](https://github.com/npm/npm/commit/ee63b8a311ac53b0cf2efa79babe61a2c4083ef6) - `ini@1.3.5` - ([@isaacs](https://github.com/isaacs)) -* [`6f73f5509`](https://github.com/npm/npm/commit/6f73f5509e9e8d606526565c7ceb71c62642466e) - `JSONStream@1.3.2` - ([@dominictarr](https://github.com/dominictarr)) -* [`26cd64869`](https://github.com/npm/npm/commit/26cd648697c1324979289e381fe837f9837f3874) - [`9bc6230cf`](https://github.com/npm/npm/commit/9bc6230cf34a09b7e4358145ff0ac3c69c23c3f6) - `libcipm@1.3.3` - ([@zkat](https://github.com/zkat)) -* [`21a39be42`](https://github.com/npm/npm/commit/21a39be4241a60a898d11a5967f3fc9868ef70c9) - `marked@0.3.1`:5 - ([@joshbruce](https://github.com/joshbruce)) -* [`dabdf57b2`](https://github.com/npm/npm/commit/dabdf57b2d60d665728894b4c1397b35aa9d41c0) - `mississippi@2.0.0` -* [`2594c5867`](https://github.com/npm/npm/commit/2594c586723023edb1db172779afb2cbf8b30c08) - `npm-registry-couchapp@2.7.1` - ([@iarna](https://github.com/iarna)) -* [`8abb3f230`](https://github.com/npm/npm/commit/8abb3f230f119fe054353e70cb26248fc05db0b9) - `osenv@0.1.5` - ([@isaacs](https://github.com/isaacs)) -* [`11a0b00bd`](https://github.com/npm/npm/commit/11a0b00bd3c18625075dcdf4a5cb6500b33c6265) - `pacote@7.3.3` - ([@zkat](https://github.com/zkat)) -* [`9b6bdb2c7`](https://github.com/npm/npm/commit/9b6bdb2c77e49f6d473e70de4cd83c58d7147965) - `query-string@5.1.0` - ([@sindresorhus](https://github.com/sindresorhus)) -* [`d6d17d6b5`](https://github.com/npm/npm/commit/d6d17d6b532cf4c3461b1cf2e0404f7c62c47ec4) - `readable-stream@2.3.4` - ([@mcollina](https://github.com/mcollina)) -* [`51370aad5`](https://github.com/npm/npm/commit/51370aad561b368ccc95c1c935c67c8cd2844d40) - `semver@5.5.0` - ([@isaacs](https://github.com/isaacs)) -* [`0db14bac7`](https://github.com/npm/npm/commit/0db14bac762dd59c3fe17c20ee96d2426257cdd5) - [`81da938ab`](https://github.com/npm/npm/commit/81da938ab6efb881123cdcb44f7f84551924c988) - [`9999e83f8`](https://github.com/npm/npm/commit/9999e83f87c957113a12a6bf014a2099d720d716) - `ssri@5.2.4` - ([@zkat](https://github.com/zkat)) -* [`f526992ab`](https://github.com/npm/npm/commit/f526992ab6f7322a0b3a8d460dc48a2aa4a59a33) - `tap@11.1.1` - ([@isaacs](https://github.com/isaacs)) -* [`be096b409`](https://github.com/npm/npm/commit/be096b4090e2a33ae057912d28fadc5a53bd3391) - [`dc3059522`](https://github.com/npm/npm/commit/dc3059522758470adc225f0651be72c274bd29ef) - `tar@4.3.3` -* [`6b552daac`](https://github.com/npm/npm/commit/6b552daac952f413ed0e2df762024ad219a8dc0a) - `uuid@3.2.1` - ([@broofa](https://github.com/broofa)) -* [`8c9011b72`](https://github.com/npm/npm/commit/8c9011b724ad96060e7e82d9470e9cc3bb64e9c6) - `worker-farm@1.5.2` - ([@rvagg](https://github.com/rvagg)) - - -## v5.6.0 (2017-11-27): - -### Features! - -You may have noticed this is a semver-minor bump. Wondering why? This is why! - -* [`bc263c3fd`](https://github.com/npm/npm/commit/bc263c3fde6ff4b04deee132d0a9d89379e28c27) - [#19054](https://github.com/npm/npm/pull/19054) - **Fully cross-platform `package-lock.json`**. Installing a failing optional - dependency on one platform no longer removes it from the dependency tree, - meaning that `package-lock.json` should now be generated consistently across - platforms! 🎉 - ([@iarna](https://github.com/iarna)) -* [`f94fcbc50`](https://github.com/npm/npm/commit/f94fcbc50d8aec7350164df898d1e12a1e3da77f) - [#19160](https://github.com/npm/npm/pull/19160) - Add `--package-lock-only` config option. This makes it so you can generate a - target `package-lock.json` without performing a full install of - `node_modules`. - ([@alopezsanchez](https://github.com/alopezsanchez)) -* [`66d18280c`](https://github.com/npm/npm/commit/66d18280ca320f880f4377cf80a8052491bbccbe) - [#19104](https://github.com/npm/npm/pull/19104) - Add new `--node-options` config to pass through a custom `NODE_OPTIONS` for - lifecycle scripts. - ([@bmeck](https://github.com/bmeck)) -* [`114d518c7`](https://github.com/npm/npm/commit/114d518c75732c42acbef3acab36ba1d0fd724e2) - Ignore mtime when packing tarballs: This means that doing `npm pack` on the - same repository should yield two tarballs with the same checksum. This will - also help prevent cache bloat when using git dependencies. In the future, this - will allow npm to explicitly cache git dependencies. - ([@isaacs](https://github.com/isaacs)) - -### Node 9 - -Previously, it turns out npm broke on the latest Node, `node@9`. We went ahead -and fixed it up so y'all should be able to use the latest npm again! - -* [`4ca695819`](https://github.com/npm/npm/commit/4ca6958196ae41cef179473e3f7dbed9df9a32f1) - `minizlib@1.0.4`: `Fix node@9` incompatibility. - ([@isaacs](https://github.com/isaacs)) -* [`c851bb503`](https://github.com/npm/npm/commit/c851bb503a756b7cd48d12ef0e12f39e6f30c577) - `tar@4.0.2`: Fix `node@9` incompatibility. - ([@isaacs](https://github.com/isaacs)) -* [`6caf23096`](https://github.com/npm/npm/commit/6caf2309613d14ce77923ad3d1275cb89c6cf223) - Remove "unsupported" warning for Node 9 now that things are fixed. - ([@iarna](https://github.com/iarna)) -* [`1930b0f8c`](https://github.com/npm/npm/commit/1930b0f8c44373301edc9fb6ccdf7efcb350fa42) - Update test matrix with `node@8` LTS and `node@9`. - ([@iarna](https://github.com/iarna)) - -### Bug Fixes - -* [`b70321733`](https://github.com/npm/npm/commit/b7032173361665a12c9e4200bdc3f0eb4dee682f) - [#18881](https://github.com/npm/npm/pull/18881) - When dealing with a `node_modules` that was created with older versions of npm - (and thus older versions of npa) we need to gracefully handle older spec - entries. Failing to do so results in us treating those packages as if they - were http remote deps, which results in invalid lock files with `version` set - to tarball URLs. This should now be fixed. - ([@iarna](https://github.com/iarna)) -* [`2f9c5dd00`](https://github.com/npm/npm/commit/2f9c5dd0046a53ece3482e92a412413f5aed6955) - [#18880](https://github.com/npm/npm/pull/18880) - Stop overwriting version in package data on disk. This is another safeguard - against the version overwriting that's plagued some folks upgrading from older - package-locks. - ([@iarna](https://github.com/iarna)) - ([@joshclow](https://github.com/joshclow)) -* [`a93e0a51d`](https://github.com/npm/npm/commit/a93e0a51d3dafc31c809ca28cd7dfa71b2836f86) - [#18846](https://github.com/npm/npm/pull/18846) - Correctly save transitive dependencies when using `npm update` in - `package-lock.json`. - ([@iarna](https://github.com/iarna)) -* [`fdde7b649`](https://github.com/npm/npm/commit/fdde7b649987b2acd9a37ef203f1e263fdf6fece) - [#18825](https://github.com/npm/npm/pull/18825) - Fix typo and concatenation in error handling. - ([@alulsh](https://github.com/alulsh)) -* [`be67de7b9`](https://github.com/npm/npm/commit/be67de7b90790cef0a9f63f91c2f1a00942205ee) - [#18711](https://github.com/npm/npm/pull/18711) - Upgrade to bearer tokens from legacy auth when enabling 2FA. - ([@iarna](https://github.com/iarna)) -* [`bfdf0fd39`](https://github.com/npm/npm/commit/bfdf0fd39646b03db8e543e2bec7092da7880596) - [#19033](https://github.com/npm/npm/pull/19033) - Fix issue where files with `@` signs in their names would not get included - when packing tarballs. - ([@zkat](https://github.com/zkat)) -* [`b65b89bde`](https://github.com/npm/npm/commit/b65b89bdeaa65516f3e13afdb6e9aeb22d8508f4) - [#19048](https://github.com/npm/npm/pull/19048) - Fix problem where `npm login` was ignoring various networking-related options, - such as custom certs. - ([@wejendorp](https://github.com/wejendorp)) -* [`8c194b86e`](https://github.com/npm/npm/commit/8c194b86ec9617e2bcc31f30ee4772469a0bb440) - `npm-packlist@1.1.10`: Include `node_modules/` directories not in the root. - ([@isaacs](https://github.com/isaacs)) -* [`d7ef6a20b`](https://github.com/npm/npm/commit/d7ef6a20b44e968cb92babab1beb51f99110781d) - `libnpx@9.7.1`: Fix some *nix binary path escaping issues. - ([@zkat](https://github.com/zkat)) -* [`981828466`](https://github.com/npm/npm/commit/981828466a5936c70abcccea319b227c443e812b) - `cacache@10.0.1`: Fix fallback to `copy-concurrently` when file move fails. - This might fix permissions and such issues on platforms that were getting - weird filesystem errors during install. - ([@karolba](https://github.com/karolba)) -* [`a0be6bafb`](https://github.com/npm/npm/commit/a0be6bafb6dd7acb3e7b717c27c8575a2215bfff) - `pacote@7.0.2`: Includes a bunch of fixes, specially for issues around git - dependencies. Shasum-related errors should be way less common now, too. - ([@zkat](https://github.com/zkat)) -* [`b80d650de`](https://github.com/npm/npm/commit/b80d650def417645d2525863e9f17af57a917b42) - [#19163](https://github.com/npm/npm/pull/19163) - Fix a number of git and tarball specs and checksum errors. - ([@zkat](https://github.com/zkat)) -* [`cac225025`](https://github.com/npm/npm/commit/cac225025fa06cd055286e75541138cd95f52def) - [#19054](https://github.com/npm/npm/pull/19054) - Don't count failed optionals when summarizing installed packages. - ([@iarna](https://github.com/iarna)) - -### UX - -* [`b1ec2885c`](https://github.com/npm/npm/commit/b1ec2885c43f8038c4e05b83253041992fdfe382) - [#18326](https://github.com/npm/npm/pull/18326) - Stop truncating output of `npm view`. This means, for example, that you no - longer need to use `--json` when a package has a lot of versions, to see the - whole list. - ([@SimenB](https://github.com/SimenB)) -* [`55a124e0a`](https://github.com/npm/npm/commit/55a124e0aa6097cb46f1484f666444b2a445ba57) - [#18884](https://github.com/npm/npm/pull/18884) - Profile UX improvements: better messaging on unexpected responses, and stop - claiming we set passwords to null when resetting them. - ([@iarna](https://github.com/iarna)) -* [`635481c61`](https://github.com/npm/npm/commit/635481c6143bbe10a6f89747795bf4b83f75a7e9) - [#18844](https://github.com/npm/npm/pull/18844) - Improve error messaging for OTP/2FA. - ([@iarna](https://github.com/iarna)) -* [`52b142ed5`](https://github.com/npm/npm/commit/52b142ed5e0f13f23c99209932e8de3f7649fd47) - [#19054](https://github.com/npm/npm/pull/19054) - Stop running the same rollback multiple times. This should address issues - where Windows users saw strange failures when `fsevents` failed to install. - ([@iarna](https://github.com/iarna)) -* [`798428b0b`](https://github.com/npm/npm/commit/798428b0b7b6cfd6ce98041c45fc0a36396e170c) - [#19172](https://github.com/npm/npm/pull/19172) - `bin-links@1.1.0`: Log the fact line endings are being changed upon install. - ([@marcosscriven](https://github.com/marcosscriven)) - -### Refactors - -Usually, we don't include internal refactor stuff in our release notes, but it's -worth calling out some of them because they're part of a larger effort the CLI -team and associates are undertaking to modularize npm itself so other package -managers and associated tools can reuse all that code! - -* [`9d22c96b7`](https://github.com/npm/npm/commit/9d22c96b7160729c8126a38dcf554611b9e3ba87) - [#18500](https://github.com/npm/npm/pull/18500) - Extract bin-links and gentle-fs to a separate library. This will allow - external tools to do bin linking and certain fs operations in an - npm-compatible way! - ([@mikesherov](https://github.com/mikesherov)) -* [`015a7803b`](https://github.com/npm/npm/commit/015a7803b7b63bc8543882196d987b92b461932d) - [#18883](https://github.com/npm/npm/pull/18883) - Capture logging from log events on the process global. This allows npm to use - npmlog to report logging from external libraries like `npm-profile`. - ([@iarna](https://github.com/iarna)) -* [`c930e98ad`](https://github.com/npm/npm/commit/c930e98adc03cef357ae5716269a04d74744a852) - `npm-lifecycle@2.0.0`: Use our own `node-gyp`. This means npm no longer needs - to pull some maneuvers to make sure `node-gyp` is in the right place, and that - external packages using `npm-lifecycle` will get working native builds without - having to do their own `node-gyp` maneuvers. - ([@zkochan](https://github.com/zkochan)) -* [`876f0c8f3`](https://github.com/npm/npm/commit/876f0c8f341f8915e338b409f4b8616bb5263500) [`829893d61`](https://github.com/npm/npm/commit/829893d617bf81bba0d1ce4ea303f76ea37a2b2d) - [#19099](https://github.com/npm/npm/pull/19099) - `find-npm-prefix@1.0.1`: npm's prefix-finding logic is now a standalone - module. That is, the logic that figures out where the root of your project is - if you've `cd`'d into a subdirectory. Did you know you can run `npm install` - from these subdirectories, and it'll only affect the root? It works like git! - ([@iarna](https://github.com/iarna)) - -### Docs - -* [`7ae12b21c`](https://github.com/npm/npm/commit/7ae12b21cc841f76417d3bb13b74f177319d4deb) - [#18823](https://github.com/npm/npm/pull/18823) - Fix spelling of the word authenticator. Because English is hard. - ([@tmcw](https://github.com/tmcw)) -* [`5dfc3ab7b`](https://github.com/npm/npm/commit/5dfc3ab7bc2cb0fa7d9a8c00aa95fecdd14d7ae1) - [#18742](https://github.com/npm/npm/pull/18742) - Explicitly state 'github:foo/bar' as a valid shorthand for hosted git specs. - ([@felicio](https://github.com/felicio)) -* [`a9dc098a6`](https://github.com/npm/npm/commit/a9dc098a6eb7a87895f52a101ac0d41492da698e) - [#18679](https://github.com/npm/npm/pull/18679) - Add some documentation about the `script-shell` config. - ([@gszabo](https://github.com/gszabo)) -* [`24d7734d1`](https://github.com/npm/npm/commit/24d7734d1a1e906c83c53b6d1853af8dc758a998) - [#18571](https://github.com/npm/npm/pull/18571) - Change `verboten` to `forbidden`. - ([@devmount](https://github.com/devmount)) -* [`a8a45668f`](https://github.com/npm/npm/commit/a8a45668fb9b8eb84234fe89234bdcdf644ead58) - [#18568](https://github.com/npm/npm/pull/18568) - Improve wording for the docs for the "engines" section of package.json files. - ([@apitman](https://github.com/apitman)) -* [`dbc7e5b60`](https://github.com/npm/npm/commit/dbc7e5b602870330a8cdaf63bd303cd9050f792f) - [#19118](https://github.com/npm/npm/pull/19118) - Use valid JSON in example for bundledDependencies. - ([@charmander](https://github.com/charmander)) -* [`779339485`](https://github.com/npm/npm/commit/779339485bab5137d0fdc68d1ed6fa987aa8965a) - [#19162](https://github.com/npm/npm/pull/19162) - Remove trailing white space from `npm access` docs. - ([@WispProxy](https://github.com/WispProxy)) - -### Dependency Bumps - -* [`0e7cac941`](https://github.com/npm/npm/commit/0e7cac9413ff1104cf242cc3006f42aa1c2ab63f) - `bluebird@3.5.1` - ([@petkaantonov](https://github.com/petkaantonov)) -* [`c4d5887d9`](https://github.com/npm/npm/commit/c4d5887d978849ddbe2673630de657f141ae5bcf) - `update-notifier@2.3.0` - ([@sindresorhus](https://github.com/sindresorhus)) -* [`eb19a9691`](https://github.com/npm/npm/commit/eb19a9691cf76fbc9c5b66aa7aadb5d905af467a) - `npm-package-arg@6.0.0` - ([@zkat](https://github.com/zkat)) -* [`91d5dca96`](https://github.com/npm/npm/commit/91d5dca96772bc5c45511ddcbeeb2685c7ea68e8) - `npm-profile@2.0.5` - ([@iarna](https://github.com/iarna)) -* [`8de66c46e`](https://github.com/npm/npm/commit/8de66c46e57e4b449c9540c8ecafbc4fd58faff5) - `ssri@5.0.0` - ([@zkat](https://github.com/zkat)) -* [`cfbc3ea69`](https://github.com/npm/npm/commit/cfbc3ea69a8c62dc8e8543193c3ac472631dcef9) - `worker-farm@1.5.1` - ([@rvagg](https://github.com/rvagg)) -* [`60c228160`](https://github.com/npm/npm/commit/60c228160f22d41c2b36745166c9e8c2d84fee58) - `query-string@5.0.1` - ([@sindresorhus](https://github.com/sindresorhus)) -* [`72cad8c66`](https://github.com/npm/npm/commit/72cad8c664efd8eb1bec9a418bccd6c6ca9290de) - `copy-concurrently@1.0.5` - ([@iarna](https://github.com/iarna)) - -## v5.5.1 (2017-10-04): - -A very quick, record time, patch release, of a bug fix to a (sigh) last minute bug fix. - -* [`e628e058b`](https://github.com/npm/npm/commit/e628e058b) - Fix login to properly recognize OTP request and store bearer tokens. - ([@iarna](https://github.com/iarna)) - -## v5.5.0 (2017-10-04): - -Hey y'all, this is a big new feature release! We've got some security -related goodies plus a some quality-of-life improvements for anyone who uses -the public registry (so, virtually everyone). - -The changes largely came together in one piece, so I'm just gonna leave the commit line here: - -* [`f6ebf5e8b`](https://github.com/npm/npm/commit/f6ebf5e8bd6a212c7661e248c62c423f2b54d978) - [`f97ad6a38`](https://github.com/npm/npm/commit/f97ad6a38412581d059108ea29be470acb4fa510) - [`f644018e6`](https://github.com/npm/npm/commit/f644018e6ef1ff7523c6ec60ae55a24e87a9d9ae) - [`8af91528c`](https://github.com/npm/npm/commit/8af91528ce6277cd3a8c7ca8c8102671baf10d2f) - [`346a34260`](https://github.com/npm/npm/commit/346a34260b5fba7de62717135f3e083cc4820853) - Two factor authentication, profile editing and token management. - ([@iarna](https://github.com/iarna)) - -### TWO FACTOR AUTHENTICATION - -You can now enable two-factor authentication for your npm account. You can -even do it from the CLI. In fact, you have to, for the time being: - -``` -npm profile enable-tfa -``` - -With the default two-factor authentication mode you'll be prompted to enter -a one-time password when logging in, when publishing and when modifying access rights to -your modules. - -### TOKEN MANAGEMENT - -You can now create, list and delete authentication tokens from the comfort -of the command line. Authentication tokens created this way can have NEW -restrictions placed on them. For instance, you can create a `read-only` -token to give to your CI. It will be able to download your private modules -but it won't be able to publish or modify modules. You can also create -tokens that can only be used from certain network addresses. This way you -can lock down access to your corporate VPN or other trusted machines. - -Deleting tokens isn't new, you could [do it via the -website](https://www.npmjs.com/settings/tokens) but now you can do it via -the CLI as well. - -### CHANGE YOUR PASSWORD, SET YOUR EMAIL - -You can finally change your password from the CLI with `npm profile set -password`! You can also update your email address with `npm profile set -email <address>`. If you change your email address we'll send you a new -verification email so you verify that its yours. - -### AND EVERYTHING ELSE ON YOUR PROFILE - -You can also update all of the other attributes of your profile that -previously you could only update via the website: `fullname`, `homepage`, -`freenode`, `twitter` and `github`. - -### AVAILABLE STAND ALONE - -All of these features were implemented in a stand alone library, so if you -have use for them in your own project you can find them in -[npm-profile](https://www.npmjs.com/package/npm-profile) on the registry. -There's also a little mini-cli written just for it at -[npm-profile-cli](https://www.npmjs.com/package/npm-profile-cli). You might -also be interested in the [API -documentation](https://github.com/npm/registry/tree/master/docs) for these -new features: [user profile editing](https://github.com/npm/registry/blob/master/docs/user/profile.md) and -[authentication](https://github.com/npm/registry/blob/master/docs/user/authentication.md). - -### BUG FIXES - -* [`5ee55dc71`](https://github.com/npm/npm/commit/5ee55dc71b8b74b8418c3d5ec17483a07b3b6777) - install.sh: Drop support for upgrading from npm@1 as npm@5 can't run on - any Node.js version that ships npm@1. This fixes an issue some folks were seeing when trying - to upgrade using `curl | http://npmjs.com/install.sh`. - ([@iarna](https://github.com/iarna)) -* [`5cad1699a`](https://github.com/npm/npm/commit/5cad1699a7a0fc85ac7f77a95087a9647f75e344) - `npm-lifecycle@1.0.3` Fix a bug where when more than one lifecycle script - got queued to run, npm would crash. - ([@zkat](https://github.com/zkat)) -* [`cd256cbb2`](https://github.com/npm/npm/commit/cd256cbb2f97fcbcb82237e94b66eac80e493626) - `npm-packlist@1.1.9` Fix a bug where test directories would always be - excluded from published modules. - ([@isaacs](https://github.com/isaacs)) -* [`2a11f0215`](https://github.com/npm/npm/commit/2a11f021561acb1eb1ad4ad45ad955793b1eb4af) - Fix formatting of unsupported version warning - ([@iarna](https://github.com/iarna)) - -### DEPENDENCY UPDATES - -* [`6d2a285a5`](https://github.com/npm/npm/commit/6d2a285a58655f10834f64d38449eb1f3c8b6c47) - `npm-registry-client@8.5.0` -* [`69e64e27b`](https://github.com/npm/npm/commit/69e64e27bf58efd0b76b3cf6e8182c77f8cc452f) - `request@2.83.0` -* [`34e0f4209`](https://github.com/npm/npm/commit/34e0f42090f6153eb5462f742e402813e4da56c8) - `abbrev@1.1.1` -* [`10d31739d`](https://github.com/npm/npm/commit/10d31739d39765f1f0249f688bd934ffad92f872) - `aproba@1.2.0` -* [`2b02e86c0`](https://github.com/npm/npm/commit/2b02e86c06cf2a5fe7146404f5bfd27f190ee4f4) - `meant@1.0.1` -* [`b81fff808`](https://github.com/npm/npm/commit/b81fff808ee269361d3dcf38c1b6019f1708ae02) - `rimraf@2.6.2`: - Fixes a long standing bug in rimraf's attempts to work around Windows limitations - where it owns a file and can change its perms but can't remove it without - first changing its perms. This _may_ be an improvement for Windows users of npm under - some circumstances. - ([@isaacs](https://github.com/isaacs)) - -## v5.4.2 (2017-09-14): - -This is a small bug fix release wrapping up most of the issues introduced with 5.4.0. - -### Bugs - -* [`0b28ac72d`](https://github.com/npm/npm/commit/0b28ac72d29132e9b761717aba20506854465865) - [#18458](https://github.com/npm/npm/pull/18458) - Fix a bug on Windows where rolling back of failed optional dependencies would fail. - ([@marcins](https://github.com/marcins)) -* [`3a1b29991`](https://github.com/npm/npm/commit/3a1b299913ce94fdf25ed3ae5c88fe6699b04e24) - `write-file-atomic@2.1.0` Revert update of `write-file-atomic`. There were changes made to it - that were resulting in EACCES errors for many users. - ([@iarna](https://github.com/iarna)) -* [`cd8687e12`](https://github.com/npm/npm/commit/cd8687e1257f59a253436d69e8d79a29c85d00c8) - Fix a bug where if npm decided it needed to move a module during an upgrade it would strip - out much of the `package.json`. This would result in broken trees after package updates. -* [`5bd0244ee`](https://github.com/npm/npm/commit/5bd0244eec347ce435e88ff12148c35da7c69efe) - [#18385](https://github.com/npm/npm/pull/18385) - Fix `npm outdated` when run on non-registry dependencies. - ([@joshclow](https://github.com/joshclow)) - ([@iarna](https://github.com/iarna)) - -### Ux - -* [`339f17b1e`](https://github.com/npm/npm/commit/339f17b1e6816eccff7df97875db33917eccdd13) - Report unsupported node versions with greater granularity. - ([@iarna](https://github.com/iarna)) - -### Docs - -* [`b2ab6f43b`](https://github.com/npm/npm/commit/b2ab6f43b8ae645134238acd8dd3083e5ba8846e) - [#18397](https://github.com/npm/npm/pull/18397) - Document that the default loglevel with `npm@5` is `notice`. - ([@KenanY](https://github.com/KenanY)) -* [`e5aedcd82`](https://github.com/npm/npm/commit/e5aedcd82af81fa9e222f9210f6f890c72a18dd3) - [#18372](https://github.com/npm/npm/pull/18372) - In npm-config documentation, note that env vars use \_ in place of -. - ([@jakubholynet](https://github.com/jakubholynet)) - -## v5.4.1 (2017-09-06): - -This is a very small bug fix release to fix a problem where permissions on -installed binaries were being set incorrectly. - -* [`767ff6eee`](https://github.com/npm/npm/commit/767ff6eee7fa3a0f42ad677dedc0ec1f0dc15e7c) - [zkat/pacote#117](https://github.com/zkat/pacote/pull/117) - [#18324](https://github.com/npm/npm/issues/18324) - `pacote@6.0.2` - ([@zkat](https://github.com/zkat)) - -## v5.4.0 (2017-08-22): - -Here's another ~~small~~ big release, with a ~~handful~~ bunch of fixes and -a couple of ~~small~~ new features! This release has been incubating rather -longer than usual and it's grown quite a bit in that time. I'm also excited -to say that it has contributions from **27** different folks, which is a new -record for us. Our previous record was 5.1.0 at 21. Before that the record -had been held by 1.3.16 since _December of 2013_. - -![chart of contributor counts by version, showing an increasing rate over time and spikes mid in the 1.x series and later at 5.x](https://pbs.twimg.com/media/DH38rbZUwAAf9hS.jpg) - -If you can't get enough of the bleeding edge, I encourage you to check out -our canary release of npm. Get it with `npm install -g npmc`. It's going to -be seeing some exciting stuff in the next couple of weeks, starting with a -rewritten `npm dedupe`, but moving on to… well, you'll just have to wait and -find out. - -### PERFORMANCE - -* [`d080379f6`](https://github.com/npm/npm/commit/d080379f620c716afa2c1d2e2ffc0a1ac3459194) - `pacote@6.0.1` Updates extract to use tar@4, which is much faster than the - older tar@2. It reduces install times by as much as 10%. - ([@zkat](https://github.com/zkat)) -* [`4cd6a1774`](https://github.com/npm/npm/commit/4cd6a1774f774506323cae5685c9ca9a10deab63) - [`0195c0a8c`](https://github.com/npm/npm/commit/0195c0a8cdf816834c2f737372194ddc576c451d) - [#16804](https://github.com/npm/npm/pull/16804) - `tar@4.0.1` Update publish to use tar@4. tar@4 brings many advantages - over tar@2: It's faster, better tested and easier to work with. It also - produces exactly the same byte-for-byte output when producing tarballs - from the same set of files. This will have some nice carry on effects for - things like caching builds from git. And finally, last but certainly not - least, upgrading to it also let's us finally eliminate `fstream`—if - you know what that is you'll know why we're so relieved. - ([@isaacs](https://github.com/isaacs)) - -### FEATURES - -* [`1ac470dd2`](https://github.com/npm/npm/commit/1ac470dd283cc7758dc37721dd6331d5b316dc99) - [#10382](https://github.com/npm/npm/pull/10382) - If you make a typo when writing a command now, npm will print a brief "did you - mean..." message with some possible alternatives to what you meant. - ([@watilde](https://github.com/watilde)) -* [`20c46228d`](https://github.com/npm/npm/commit/20c46228d8f9243910f8c343f4830d52455d754e) - [#12356](https://github.com/npm/npm/pull/12356) - When running lifecycle scripts, `INIT_CWD` will now contain the original - working directory that npm was executed from. Remember that you can use `npm - run-script` even if you're not inside your package root directory! - ([@MichaelQQ](https://github.com/MichaelQQ)) -* [`be91e1726`](https://github.com/npm/npm/commit/be91e1726e9c21c4532723e4f413b73a93dd53d1) - [`4e7c41f4a`](https://github.com/npm/npm/commit/4e7c41f4a29744a9976cc22c77eee9d44172f21e) - `libnpx@9.6.0`: Fixes a number of issues on Windows and adds support for - several more languages: Korean, Norwegian (bokmål and nynorsk), Ukrainian, - Serbian, Bahasa Indonesia, Polish, Dutch and Arabic. - ([@zkat](https://github.com/zkat)) -* [`2dec601c6`](https://github.com/npm/npm/commit/2dec601c6d5a576751d50efbcf76eaef4deff31e) - [#17142](https://github.com/npm/npm/pull/17142) - Add the new `commit-hooks` option to `npm version` so that you can disable commit - hooks when committing the version bump. - ([@faazshift](https://github.com/faazshift)) -* [`bde151902`](https://github.com/npm/npm/commit/bde15190230b5c62dbd98095311eab71f6b52321) - [#14461](https://github.com/npm/npm/pull/14461) - Make output from `npm ping` clear as to its success or failure. - ([@legodude17](https://github.com/legodude17)) - -### BUGFIXES - -* [`b6d5549d2`](https://github.com/npm/npm/commit/b6d5549d2c2d38dd0e4319c56b69ad137f0d50cd) - [#17844](https://github.com/npm/npm/pull/17844) - Make package-lock.json sorting locale-agnostic. Previously, sorting would vary - by locale, due to using `localeCompare` for key sorting. This'll give you - a little package-lock.json churn as it reshuffles things, sorry! - ([@LotharSee](https://github.com/LotharSee)) -* [`44b98b9dd`](https://github.com/npm/npm/commit/44b98b9ddcfcccf68967fdf106fca52bf0c3da4b) - [#17919](https://github.com/npm/npm/pull/17919) - Fix a crash where `npm prune --production` would fail while removing `.bin`. - ([@fasterthanlime](https://github.com/fasterthanlime)) -* [`c3d1d3ba8`](https://github.com/npm/npm/commit/c3d1d3ba82aa41dfb2bd135e6cdc59f8d33cd9fb) - [#17816](https://github.com/npm/npm/pull/17816) - Fail more smoothly when attempting to install an invalid package name. - ([@SamuelMarks](https://github.com/SamuelMarks)) -* [`55ac2fca8`](https://github.com/npm/npm/commit/55ac2fca81bf08338302dc7dc2070494e71add5c) - [#12784](https://github.com/npm/npm/pull/12784) - Guard against stack overflows when marking packages as failed. - ([@vtravieso](https://github.com/vtravieso)) -* [`597cc0e4b`](https://github.com/npm/npm/commit/597cc0e4b5e6ee719014e3171d4e966df42a275c) - [#15087](https://github.com/npm/npm/pull/15087) - Stop outputting progressbars or using color on dumb terminals. - ([@iarna](https://github.com/iarna)) -* [`7a7710ba7`](https://github.com/npm/npm/commit/7a7710ba72e6f82414653c2e7e91fea9a1aba7e2) - [#15088](https://github.com/npm/npm/pull/15088) - Don't exclude modules that are both dev & prod when using `npm ls --production`. - ([@iarna](https://github.com/iarna)) -* [`867df2b02`](https://github.com/npm/npm/commit/867df2b0214689822b87b51578e347f353be97e8) - [#18164](https://github.com/npm/npm/pull/18164) - Only do multiple procs on OSX for now. We've seen a handful of issues - relating to this in Docker and in on Windows with antivirus. - ([@zkat](https://github.com/zkat)) -* [`23540af7b`](https://github.com/npm/npm/commit/23540af7b0ec5f12bbdc1558745c8c4f0861042b) - [#18117](https://github.com/npm/npm/pull/18117) - Some package managers would write spaces to the \_from field in package.json's in the - form of `name @spec`. This was causing npm to fail to interpret them. We now handle that - correctly and doubly make sure we don't do that ourselves. - ([@IgorNadj](https://github.com/IgorNadj)) -* [`0ef320cb4`](https://github.com/npm/npm/commit/0ef320cb40222693b7367b97c60ddffabc2d58c5) - [#16634](https://github.com/npm/npm/pull/16634) - Convert any bin script with a shbang a the start to Unix line-endings. (These sorts of scripts - are not compatible with Windows line-endings even on Windows.) - ([@ScottFreeCode](https://github.com/ScottFreeCode)) -* [`71191ca22`](https://github.com/npm/npm/commit/71191ca2227694355c49dfb187104f68df5126bd) - [#16476](https://github.com/npm/npm/pull/16476) - `npm-lifecycle@1.0.2` Running an install with `--ignore-scripts` was resulting in the - the package object being mutated to have the lifecycle scripts removed from it and that - in turn was being written out to disk, causing further problems. This fixes that: - No more mutation, no more unexpected changes. - ([@addaleax](https://github.com/addaleax)) -* [`459fa9d51`](https://github.com/npm/npm/commit/459fa9d51600904ee75ed6267b159367a1209793) - [npm/read-package-json#74](https://github.com/npm/read-package-json/pull/74) - [#17802](https://github.com/npm/npm/pull/17802) - `read-package-json@2.0.1` Use unix-style slashes for generated bin - entries, which lets them be cross platform even when produced on Windows. - ([@iarna](https://github.com/iarna)) -* [`5ec72ab5b`](https://github.com/npm/npm/commit/5ec72ab5b27c5c83cee9ff568cf75a9479d4b83a) - [#18229](https://github.com/npm/npm/pull/18229) - Make install.sh find nodejs on debian. - ([@cebe](https://github.com/cebe)) - -### DOCUMENTATION - -* [`b019680db`](https://github.com/npm/npm/commit/b019680db78ae0a6dff2289dbfe9f61fccbbe824) - [#10846](https://github.com/npm/npm/pull/10846) - Remind users that they have to install missing `peerDependencies` manually. - ([@ryanflorence](https://github.com/ryanflorence)) -* [`3aee5986a`](https://github.com/npm/npm/commit/3aee5986a65add2f815b24541b9f4b69d7fb445f) - [#17898](https://github.com/npm/npm/pull/17898) - Minor punctuation fixes to the README. - ([@AndersDJohnson](https://github.com/AndersDJohnson)) -* [`e0d0a7e1d`](https://github.com/npm/npm/commit/e0d0a7e1dda2c43822b17eb71f4d51900575cc61) - [#17832](https://github.com/npm/npm/pull/17832) - Fix grammar, format, and spelling in documentation for `run-script`. - ([@simonua](https://github.com/simonua)) -* [`3fd6a5f2f`](https://github.com/npm/npm/commit/3fd6a5f2f8802a9768dba2ec32c593b5db5a878d) - [#17897](https://github.com/npm/npm/pull/17897) - Add more info about using `files` with `npm pack`/`npm publish`. - ([@davidjgoss](https://github.com/davidjgoss)) -* [`f00cdc6eb`](https://github.com/npm/npm/commit/f00cdc6eb90a0735bc3c516720de0b1428c79c31) - [#17785](https://github.com/npm/npm/pull/17785) - Add a note about filenames for certificates on Windows, which use a different - extension and file type. - ([@lgp1985](https://github.com/lgp1985)) -* [`0cea6f974`](https://github.com/npm/npm/commit/0cea6f9741243b1937abfa300c2a111d9ed79143) - [#18022](https://github.com/npm/npm/pull/18022) - Clarify usage for the `files` field in `package.json`. - ([@xcambar](https://github.com/xcambar)) -* [`a0fdd1571`](https://github.com/npm/npm/commit/a0fdd15710971234cbc57086cd1a4dc037a39471) - [#15234](https://github.com/npm/npm/pull/15234) - Clarify the behavior of the `files` array in the package-json docs. - ([@jbcpollak](https://github.com/jbcpollak)) -* [`cecd6aa5d`](https://github.com/npm/npm/commit/cecd6aa5d4dd04af765b26b749c1cd032f7eb913) - [#18137](https://github.com/npm/npm/pull/18137) - Clarify interaction between npmignore and files in package.json. - ([@supertong](https://github.com/supertong)) -* [`6b8972039`](https://github.com/npm/npm/commit/6b89720396767961001e727fc985671ce88b901b) - [#18044](https://github.com/npm/npm/pull/18044) - Corrected the typo in package-locks docs. - ([@vikramnr](https://github.com/vikramnr)) -* [`6e012924f`](https://github.com/npm/npm/commit/6e012924f99c475bc3637c86ab6a113875405fc7) - [#17667](https://github.com/npm/npm/pull/17667) - Fix description of package.json in npm-scripts docs. - ([@tripu](https://github.com/tripu)) - -### POSSIBLY INTERESTING DEPENDENCY UPDATES - -* [`48d84171a`](https://github.com/npm/npm/commit/48d84171a302fde2510b3f31e4a004c5a4d39c73) - [`f60b05d63`](https://github.com/npm/npm/commit/f60b05d6307a7c46160ce98d6f3ccba89411c4ba) - `semver@5.4.1` Perf improvements. - ([@zkat](https://github.com/zkat)) -* [`f4650b5d4`](https://github.com/npm/npm/commit/f4650b5d4b2be2c04c229cc53aa930e260af9b4e) - `write-file-atomic@2.3.0`: - Serialize writes to the same file so that results are deterministic. - Cleanup tempfiles when process is interrupted or killed. - ([@ferm10n](https://github.com/ferm10n)) - ([@iarna](https://github.com/iarna)) - -### CHORES - -* [`96d78df98`](https://github.com/npm/npm/commit/96d78df9843187bc53be2c93913e8567003ccb73) - [`80e2f4960`](https://github.com/npm/npm/commit/80e2f4960691bc5dbd8320002e4d9143784b9ce9) - [`4f49f687b`](https://github.com/npm/npm/commit/4f49f687bbd54b6a0e406936ae35593d8e971e1e) - [`07d2296b1`](https://github.com/npm/npm/commit/07d2296b10e3d8d6f079eba3a61f0258501d7161) - [`a267ab430`](https://github.com/npm/npm/commit/a267ab4309883012a9d55934533c5915e9842277) - [#18176](https://github.com/npm/npm/pull/18176) - [#18025](https://github.com/npm/npm/pull/18025) - Move the lifecycle code out of npm into a separate library, - [`npm-lifecycle`](https://github.com/npm/lifecycle). Shh, I didn't tell you this, but this - portends to some pretty cool stuff to come very soon now. - ([@mikesherov](https://github.com/mikesherov)) -* [`0933c7eaf`](https://github.com/npm/npm/commit/0933c7eaf9cfcdf56471fe4e71c403e2016973da) - [#18025](https://github.com/npm/npm/pull/18025) - Force Travis to use Precise instead of Trusty. We have issues with our - couchdb setup and Trusty. =/ - ([@mikesherov](https://github.com/mikesherov)) -* [`afb086230`](https://github.com/npm/npm/commit/afb086230223f3c4fcddee4e958d18fce5db0ff9) - [#18138](https://github.com/npm/npm/pull/18138) - Fix typos in files-and-ignores test. - ([@supertong](https://github.com/supertong)) -* [`3e6d11cde`](https://github.com/npm/npm/commit/3e6d11cde096b4ee7b07e7569b37186aa2115b1a) - [#18175](https://github.com/npm/npm/pull/18175) - Update dependencies to eliminate transitive dependencies with the WTFPL license, which - some more serious corporate lawyery types aren't super comfortable with. - ([@zkat](https://github.com/zkat)) -* [`ee4c9bd8a`](https://github.com/npm/npm/commit/ee4c9bd8ae574a0d6b24725ba6c7b718d8aaad8d) - [#16474](https://github.com/npm/npm/pull/16474) - The tests in `test/tap/lifecycle-signal.js`, as well as the features - they are testing, are partially broken. This moves them from - being skipped in CI to being disabled only for certain platforms. - In particular, because `npm` spawns its lifecycle scripts in a - shell, signals are not necessarily forwarded by the shell and - won’t cause scripts to exit; also, shells may report the signal - they receive using their exit status, rather than terminating - themselves with a signal. - ([@addaleax](https://github.com/addaleax)) -* [`9462e5d9c`](https://github.com/npm/npm/commit/9462e5d9cfbaa50218de6d0a630d6552e72ad0a8) - [#16547](https://github.com/npm/npm/pull/16547) - Remove unused file: bin/read-package-json.js - ([@metux](https://github.com/metux)) -* [`0756d687d`](https://github.com/npm/npm/commit/0756d687d4ccfcd4a7fd83db0065eceb9261befb) - [#16550](https://github.com/npm/npm/pull/16550) - The build tools for the documentation need to be built/installed - before the documents, even with parallel builds. - Make has a simple mechanism which was made exactly for that: - target dependencies. - ([@metux](https://github.com/metux)) - -## v5.3.0 (2017-07-12): - -As mentioned before, we're continuing to do relatively rapid, smaller releases -as we keep working on stomping out `npm@5` issues! We've made a lot of progress -since 5.0 already, and this release is no exception. - -### FEATURES - -* [`1e3a46944`](https://github.com/npm/npm/commit/1e3a469448b5db8376e6f64022c4c0c78cdb1686) - [#17616](https://github.com/npm/npm/pull/17616) - Add `--link` filter option to `npm ls`. - ([@richardsimko](https://github.com/richardsimko)) -* [`33df0aaa`](https://github.com/npm/npm/commit/33df0aaaa7271dac982b86f2701d10152c4177c8) - `libnpx@9.2.0`: - * 4 new languages - Czech, Italian, Turkish, and Chinese (Traditional)! This means npx is available in 14 different languages! - * New --node-arg option lets you pass CLI arguments directly to node when the target binary is found to be a Node.js script. - ([@zkat](https://github.com/zkat)) - -### BUGFIXES - -* [`33df0aaa`](https://github.com/npm/npm/commit/33df0aaaa7271dac982b86f2701d10152c4177c8) - `libnpx@9.2.0`: - * npx should now work on (most) Windows installs. A couple of issues remain. - * Prevent auto-fallback from going into an infinite loop when npx disappears. - * `npx npx npx npx npx npx npx npx` works again. - * `update-notifier` will no longer run for the npx bundled with npm. - * `npx <cmd>` in a subdirectory of your project should be able to find your `node_modules/.bin` now. Oops - ([@zkat](https://github.com/zkat)) -* [`8e979bf80`](https://github.com/npm/npm/commit/8e979bf80fb93233f19db003f08443e26cfc5e64) - Revert change where npm stopped flattening modules that required peerDeps. - This caused problems because folks were using peer deps to indicate that the - target of the peer dep needed to be able to require the dependency and had - been relying on the fact that peer deps didn't change the shape of the tree - (as of npm@3). - The fix that will actually work for people is for a peer dep to insist on - never being installed deeper than the the thing it relies on. At the moment - this is tricky because the thing the peer dep relies on may not yet have - been added to the tree, so we don't know where it is. - ([@iarna](https://github.com/iarna)) -* [`7f28a77f3`](https://github.com/npm/npm/commit/7f28a77f33ef501065f22e8d5e8cffee3195dccd) - [#17733](https://github.com/npm/npm/pull/17733) - Split remove and unbuild actions into two to get uninstall lifecycles and the - removal of transitive symlinks during uninstallation to run in the right - order. - ([@iarna](https://github.com/iarna)) -* [`637f2548f`](https://github.com/npm/npm/commit/637f2548facae011eebf5e5c38bfe56a6c2db9fa) - [#17748](https://github.com/npm/npm/pull/17748) - When rolling back use symlink project-relative path, fixing some issues with - `fs-vacuum` getting confused while removing symlinked things. - ([@iarna](https://github.com/iarna)) -* [`f153b5b22`](https://github.com/npm/npm/commit/f153b5b22f647d4d403f5b8cecd2ce63ac75b07c) - [#17706](https://github.com/npm/npm/pull/17706) - Use semver to compare node versions in npm doctor instead of plain `>` - comparison. - ([@leo-shopify](https://github.com/leo-shopify)) -* [`542f7561`](https://github.com/npm/npm/commit/542f7561d173eca40eb8d838a16a0ed582fef989) - [#17742](https://github.com/npm/npm/pull/17742) - Fix issue where `npm version` would sometimes not commit package-locks. - ([@markpeterfejes](https://github.com/markpeterfejes)) -* [`51a9e63d`](https://github.com/npm/npm/commit/51a9e63d31cb5ac52259dcf1c364004286072426) - [#17777](https://github.com/npm/npm/pull/17777) - Fix bug exposed by other bugfixes where the wrong package would be removed. - ([@iarna](https://github.com/iarna)) - -### DOCUMENTATION - -Have we mentioned we really like documentation patches? Keep sending them in! -Small patches are just fine, and they're a great way to get started contributing -to npm! - -* [`fb42d55a9`](https://github.com/npm/npm/commit/fb42d55a9a97afa5ab7db38b3b99088cf68684ea) - [#17728](https://github.com/npm/npm/pull/17728) - Document semver git urls in package.json docs. - ([@sankethkatta](https://github.com/sankethkatta)) -* [`f398c700f`](https://github.com/npm/npm/commit/f398c700fb0f2f3665ebf45995a910ad16cd8d05) - [#17684](https://github.com/npm/npm/pull/17684) - Tweak heading hierarchy in package.json docs. - ([@sonicdoe](https://github.com/sonicdoe)) -* [`d5ad65e50`](https://github.com/npm/npm/commit/d5ad65e50a573cdf9df4155225e869cd6c88ca5e) - [#17691](https://github.com/npm/npm/pull/17691) - Explicitly document `--no-save` flag for uninstall. - ([@timneedham](https://github.com/timneedham)) - -## v5.2.0 (2017-07-05): - -It's only been a couple of days but we've got some bug fixes we wanted to -get out to you all. We also believe that -[`npx`](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) is ready to be bundled -with npm, which we're really excited about! - -### npx!!! - -npx is a tool intended to help round out the experience of using packages -from the npm registry — the same way npm makes it super easy to install and -manage dependencies hosted on the registry, npx is meant to make it easy to -use CLI tools and other executables hosted on the registry. It greatly -simplifies a number of things that, until now, required a bit of ceremony to -do with plain npm. - -![](https://cdn-images-1.medium.com/max/1600/1*OlIRsvVO5aK7ja9HmwXz_Q.gif) - -[@zkat](https://github.com/zkat) has a [great introduction post to npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) -that I highly recommend you give a read - -* [`fb040bee0`](https://github.com/npm/npm/commit/fb040bee0710759c60e45bf8fa2a3b8ddcf4212a) - [#17685](https://github.com/npm/npm/pull/17685) - Bundle npx with npm itself. - ([@zkat](https://github.com/zkat)) - -### BUG FIXES - -* [`9fe905c39`](https://github.com/npm/npm/commit/9fe905c399d07a3c00c7b22035ddb6b7762731e6) - [#17652](https://github.com/npm/npm/pull/17652) - Fix max callstack exceeded loops with trees with circular links. - ([@iarna](https://github.com/iarna)) -* [`c0a289b1b`](https://github.com/npm/npm/commit/c0a289b1ba6b99652c43a955b23acbf1de0b56ae) - [#17606](https://github.com/npm/npm/pull/17606) - Make sure that when write package.json and package-lock.json we always use unix path separators. - ([@Standard8](https://github.com/Standard8)) -* [`1658b79ca`](https://github.com/npm/npm/commit/1658b79cad89ccece5ae5ce3c2f691d44b933116) - [#17654](https://github.com/npm/npm/pull/17654) - Make `npm outdated` show results for globals again. Previously it never thought they were out of date. - ([@iarna](https://github.com/iarna)) -* [`06c154fd6`](https://github.com/npm/npm/commit/06c154fd653d18725d2e760ba825d43cdd807420) - [#17678](https://github.com/npm/npm/pull/17678) - Stop flattening modules that have peer dependencies. We're making this - change to support scenarios where the module requiring a peer dependency - is flattened but the peer dependency itself is not, due to conflicts. In - those cases the module requiring the peer dep can't be flattened past the - location its peer dep was placed in. This initial fix is naive, never - flattening peer deps, and we can look into doing something more - sophisticated later on. - ([@iarna](https://github.com/iarna)) -* [`88aafee8b`](https://github.com/npm/npm/commit/88aafee8b5b232b7eeb5690279a098d056575791) - [#17677](https://github.com/npm/npm/pull/17677) - There was an issue where updating a flattened dependency would sometimes - unflatten it. This only happened when the dependency had dependencies - that in turn required the original dependency. - ([@iarna](https://github.com/iarna)) -* [`b58ec8eab`](https://github.com/npm/npm/commit/b58ec8eab3b4141e7f1b8b42d8cc24f716a804d8) - [#17626](https://github.com/npm/npm/pull/17626) - Integrators who were building their own copies of npm ran into issues because - `make install` and https://npmjs.com/install.sh weren't aware that - `npm install` creates links now when given a directory to work on. This does not impact folks - installing npm with `npm install -g npm`. - ([@iarna](https://github.com/iarna)) - -### DOC FIXES - -* [`10bef735e`](https://github.com/npm/npm/commit/10bef735e825acc8278827d34df415dfcd8c67d4) - [#17645](https://github.com/npm/npm/pull/17645) - Fix some github issue links in the 5.1.0 changelog - ([@schmod](https://github.com/schmod)) -* [`85fa9dcb2`](https://github.com/npm/npm/commit/85fa9dcb2f0b4f51b515358e0184ec82a5845227) - [#17634](https://github.com/npm/npm/pull/17634) - Fix typo in package-lock docs. - ([@sonicdoe](https://github.com/sonicdoe)) -* [`688699bef`](https://github.com/npm/npm/commit/688699befc2d147288c69a9405fb8354ecaebe36) - [#17628](https://github.com/npm/npm/pull/17628) - Recommend that folks looking for support join us on https://package.community/ or message - [@npm_support](https://twitter.com/npm_support) on Twitter. - ([@strugee](https://github.com/strugee)) - - -## v5.1.0 (2017-07-05): - -Hey y'all~ - -We've got some goodies for you here, including `npm@5`'s first semver-minor -release! This version includes a huge number of fixes, particularly for some of -the critical bugs users were running into after upgrading npm. You should -overall see a much more stable experience, and we're going to continue hacking -on fixes for the time being. Semver-major releases, specially for tools like -npm, are bound to cause some instability, and getting `npm@5` stable is the CLI -team's top priority for now! - -Not that bugfixes are the only things that landed, either: between improvements -that fell out of the bugfixes, and some really cool work by community members -like [@mikesherov](https://github.com/mikesherov), `npm@5.1.0` is **_twice as -fast_** as `npm@5.0.0` in some benchmarks. We're not stopping there, either: you -can expect a steady stream of speed improvements over the course of the year. -It's not _top_ priority, but we'll keep doing what we can to make sure npm saves -its users as much time as possible. - -Hang on to your seats. At **100 commits**, this release is a bit of a doozy. 😎 - -### FEATURES - -Semver-minor releases, of course, mean that there's a new feature somewhere, -right? Here's what's bumping that number for us this time: - -* [`a09c1a69d`](https://github.com/npm/npm/commit/a09c1a69df05b753464cc1272cdccc6af0f4da5a) - [#16687](https://github.com/npm/npm/pull/16687) - Allow customizing the shell used to execute `run-script`s. - ([@mmkal](https://github.com/mmkal)) -* [`4f45ba222`](https://github.com/npm/npm/commit/4f45ba222e2ac6dbe6d696cb7a8e678bbda7c839) [`a48958598`](https://github.com/npm/npm/commit/a489585985540deed4edc03418636c9e97aa9e40) [`901bef0e1`](https://github.com/npm/npm/commit/901bef0e1ea806fc08d8d58744a9f813b6c020ab) - [#17508](https://github.com/npm/npm/pull/17508) - Add a new `requires` field to `package-lock.json` with information about the - _logical_ dependency tree. This includes references to the specific version - each package is intended to see, and can be used for many things, such as - [converting `package-lock.json` to other lockfile - formats](https://twitter.com/maybekatz/status/880578566907248640), various - optimizations, and verifying correctness of a package tree. - ([@iarna](https://github.com/iarna)) -* [`47e8fc8eb`](https://github.com/npm/npm/commit/47e8fc8eb9b5faccef9e03ab991cf37458c16249) - [#17508](https://github.com/npm/npm/pull/17508) - Make `npm ls` take package locks (and shrinkwraps) into account. This means - `npm ls` can now be used to see [which dependencies are - missing](https://twitter.com/maybekatz/status/880446509547794437), so long as - a package lock has been previously generated with it in. - ([@iarna](https://github.com/iarna)) -* [`f0075e7ca`](https://github.com/npm/npm/commit/f0075e7caa3e151424a254d7809ae4489ed8df90) - [#17508](https://github.com/npm/npm/pull/17508) - Take `package.json` changes into account when running installs -- if you - remove or add a dependency to `package.json` manually, npm will now pick that - up and update your tree and package lock accordingly. - ([@iarna](https://github.com/iarna)) -* [`83a5455aa`](https://github.com/npm/npm/commit/83a5455aac3c5cc2511ab504923b652b13bd66a0) - [#17205](https://github.com/npm/npm/pull/17205) - Add `npm udpate` as an alias for `npm update`, for symmetry with - `install`/`isntall`. - ([@gdassori](https://github.com/gdassori)) -* [`57225d394`](https://github.com/npm/npm/commit/57225d394b6174eb0be48393d8e18da0991f67b6) - [#17120](https://github.com/npm/npm/pull/17120) - npm will no longer warn about `preferGlobal`, and the option is now - deprecated. - ([@zkat](https://github.com/zkat)) -* [`82df7bb16`](https://github.com/npm/npm/commit/82df7bb16fc29c47a024db4a8c393e55f883744b) - [#17351](https://github.com/npm/npm/pull/17351) - As some of you may already know `npm build` doesn't do what a lot of people - expect: It's mainly an npm plumbing command, and is part of the more familiar - `npm rebuild` command. That said, a lot of users assume that this is the way - to run an npm `run-script` named `build`, which is an incredibly common script - name to use. To clarify things for users, and encourage them to use `npm run - build` instead, npm will now warn if `npm build` is run without any arguments. - ([@lennym](https://github.com/lennym)) - -### PERFORMANCE - -* [`59f86ef90`](https://github.com/npm/npm/commit/59f86ef90a58d8dc925c9613f1c96e68bee5ec7b) [`43be9d222`](https://github.com/npm/npm/commit/43be9d2222b23ebb0a427ed91824ae217e6d077a) [`e906cdd98`](https://github.com/npm/npm/commit/e906cdd980b4722e66618ce295c682b9a8ffaf8f) - [#16633](https://github.com/npm/npm/pull/16633) - npm now parallelizes tarball extraction across multiple child process workers. - This can significantly speed up installations, specially when installing from - cache, and will improve with number of processors. - ([@zkat](https://github.com/zkat)) -* [`e0849878d`](https://github.com/npm/npm/commit/e0849878dd248de8988c2ef3fc941054625712ca) - [#17441](https://github.com/npm/npm/pull/17441) - Avoid building environment for empty lifecycle scripts. This change alone - accounted for as much as a 15% speed boost for npm installations by outright - skipping entire steps of the installer when not needed. - ([@mikesherov](https://github.com/mikesherov)) -* [`265c2544c`](https://github.com/npm/npm/commit/265c2544c8ded10854909243482e6437ed03c261) - [npm/hosted-git-info#24](https://github.com/npm/hosted-git-info/pull/24) - `hosted-git-info@2.5.0`: Add caching to `fromURL`, which gets called many, - many times by the installer. This improved installation performance by around - 10% on realistic application repositories. - ([@mikesherov](https://github.com/mikesherov)) -* [`901d26cb`](https://github.com/npm/npm/commit/901d26cb656e7e773d9a38ef4eac9263b95e07c8) - [npm/read-package-json#20](https://github.com/npm/read-package-json/pull/70) - `read-package-json@2.0.9`: Speed up installs by as much as 20% by - reintroducing a previously-removed cache and making it actually be correct - this time around. - ([@mikesherov](https://github.com/mikesherov)) -* [`44e37045d`](https://github.com/npm/npm/commit/44e37045d77bc40adf339b423d42bf5e9b4d4d91) - Eliminate `Bluebird.promisifyAll` from our codebase. - ([@iarna](https://github.com/iarna)) -* [`3b4681b53`](https://github.com/npm/npm/commit/3b4681b53db7757985223932072875d099694677) - [#17508](https://github.com/npm/npm/pull/17508) - Stop calling `addBundle` on locked deps, speeding up the - `package-lock.json`-based fast path. - ([@iarna](https://github.com/iarna)) - -### BUGFIXES - -* [#17508](https://github.com/npm/npm/pull/17508) - This is a big PR that fixes a variety of issues when installing from package - locks. If you were previously having issues with missing dependencies or - unwanted removals, this might have fixed it: - * It introduces a new `package-lock.json` field, called `requires`, which tracks which modules a given module requires. - * It fixes [#16839](https://github.com/npm/npm/issues/16839) which was caused by not having this information available, particularly when git dependencies were involved. - * It fixes [#16866](https://github.com/npm/npm/issues/16866), allowing the `package.json` to trump the `package-lock.json`. - * `npm ls` now loads the shrinkwrap, which opens the door to showing a full tree of dependencies even when nothing is yet installed. (It doesn't do that yet though.) - ([@iarna](https://github.com/iarna)) -* [`656544c31`](https://github.com/npm/npm/commit/656544c31cdef3cef64fc10c24f03a8ae2685e35) [`d21ab57c3`](https://github.com/npm/npm/commit/d21ab57c3ef4f01d41fb6c2103debe884a17dc22) - [#16637](https://github.com/npm/npm/pull/16637) - Fix some cases where `npm prune` was leaving some dependencies unpruned if - to-be-pruned dependencies depended on them. - ([@exogen](https://github.com/exogen)) -* [`394436b09`](https://github.com/npm/npm/commit/394436b098dcca2d252061f95c4eeb92c4a7027c) - [#17552](https://github.com/npm/npm/pull/17552) - Make `refresh-package-json` re-verify the package platform. This fixes an - issue most notably experienced by Windows users using `create-react-app` where - `fsevents` would not short-circuit and cause a crash during its - otherwise-skipped native build phase. - ([@zkat](https://github.com/zkat)) -* [`9e5a94354`](https://github.com/npm/npm/commit/9e5a943547b29c8d022192afd9398b3a136a7e5a) - [#17590](https://github.com/npm/npm/pull/17590) - Fix an issue where `npm@5` would crash when trying to remove packages - installed with `npm@<5`. - ([@iarna](https://github.com/iarna)) -* [`c3b586aaf`](https://github.com/npm/npm/commit/c3b586aafa9eabac572eb6e2b8a7266536dbc65b) - [#17141](https://github.com/npm/npm/issues/17141) - Don't update the package.json when modifying packages that don't go there. - This was previously causing `package.json` to get a `"false": {}` field added. - ([@iarna](https://github.com/iarna)) -* [`d04a23de2`](https://github.com/npm/npm/commit/d04a23de21dd9991b32029d839b71e10e07b400d) [`4a5b360d5`](https://github.com/npm/npm/commit/4a5b360d561f565703024085da0927ccafe8793e) [`d9e53db48`](https://github.com/npm/npm/commit/d9e53db48ca227b21bb67df48c9b3580cb390e9e) - `pacote@2.7.38`: - * [zkat/pacote#102](https://github.com/zkat/pacote/pull/102) Fix issue with tar extraction and special characters. - * Enable loose semver parsing in some missing corner cases. - ([@colinrotherham](https://github.com/colinrotherham), [@zkat](https://github.com/zkat), [@mcibique](https://github.com/mcibique)) -* [`e2f815f87`](https://github.com/npm/npm/commit/e2f815f87676b7c50b896e939cee15a01aa976e4) - [#17104](https://github.com/npm/npm/pull/17104) - Write an empty str and wait for flush to exit to reduce issues with npm - exiting before all output is complete when it's a child process. - ([@zkat](https://github.com/zkat)) -* [`835fcec60`](https://github.com/npm/npm/commit/835fcec601204971083aa3a281c3a9da6061a7c2) - [#17060](https://github.com/npm/npm/pull/17060) - Make git repos with prepare scripts always install with both dev and prod - flags. - ([@intellix](https://github.com/intellix)) -* [`f1dc8a175`](https://github.com/npm/npm/commit/f1dc8a175eed56f1ed23bd5773e5e10beaf6cb31) - [#16879](https://github.com/npm/npm/pull/16879) - Fix support for `always-auth` and `_auth`. They are now both available in both - unscoped and registry-scoped configurations. - ([@jozemlakar](https://github.com/jozemlakar)) -* [`ddd8a1ca2`](https://github.com/npm/npm/commit/ddd8a1ca2fa3377199af74ede9d0c1a406d19793) - Serialize package specs to prevent `[object Object]` showing up in logs during - extraction. - ([@zkat](https://github.com/zkat)) -* [`99ef3b52c`](https://github.com/npm/npm/commit/99ef3b52caa7507e87a4257e622f8964b1c1f5f3) - [#17505](https://github.com/npm/npm/pull/17505) - Stop trying to commit updated `npm-shrinkwrap.json` and `package-lock.json` if - they're `.gitignore`d. - ([@zkat](https://github.com/zkat)) -* [`58be2ec59`](https://github.com/npm/npm/commit/58be2ec596dfb0353ad2570e6750e408339f1478) - Make sure uid and gid are getting correctly set even when they're `0`. This - should fix some Docker-related issues with bad permissions/broken ownership. - ([@rgrove](https://github.com/rgrove)) - ([@zkat](https://github.com/zkat)) -* [`9d1e3b6fa`](https://github.com/npm/npm/commit/9d1e3b6fa01bb563d76018ee153259d9507658cf) - [#17506](https://github.com/npm/npm/pull/17506) - Skip writing package.json and locks if on-disk version is identical to the new - one. - ([@zkat](https://github.com/zkat)) -* [`3fc6477a8`](https://github.com/npm/npm/commit/3fc6477a89773786e6c43ef43a23e5cdc662ff8e) - [#17592](https://github.com/npm/npm/pull/17592) - Fix an issue where `npm install -g .` on a package with no `name` field would - cause the entire global `node_modules` directory to be replaced with a symlink - to `$CWD`. lol. - ([@iarna](https://github.com/iarna)) -* [`06ba0a14a`](https://github.com/npm/npm/commit/06ba0a14a6c1c8cdcc8c062b68c8c63041b0cec0) - [#17591](https://github.com/npm/npm/pull/17591) - Fix spurious removal reporting: if you tried to remove something that didn't - actually exist, npm would tell you it removed 1 package even though there was - nothing to do. - ([@iarna](https://github.com/iarna)) -* [`20ff05f8`](https://github.com/npm/npm/commit/20ff05f8fe0ad8c36e1323d30b63b4d2ff7e11ef) - [#17629](https://github.com/npm/npm/pull/17629) - When removing a link, keep dependencies installed inside of it instead of - removing them, if the link is outside the scope of the current project. This - fixes an issue where removing globally-linked packages would remove all their - dependencies in the source directory, as well as some ergonomic issues when - using links in other situations. - ([@iarna](https://github.com/iarna)) - -### DOCS - -* [`fd5fab595`](https://github.com/npm/npm/commit/fd5fab5955a20a9bb8c0e77092ada1435f73a8d2) - [#16441](https://github.com/npm/npm/pull/16441) - Add spec for `npm-shrinkwrap.json` and `package-lock.json` from RFC. - ([@iarna](https://github.com/iarna)) -* [`9589c1ccb`](https://github.com/npm/npm/commit/9589c1ccb3f794abaaa48c2a647ada311dd881ef) - [#17451](https://github.com/npm/npm/pull/17451) - Fix typo in changelog. - ([@watilde](https://github.com/watilde)) -* [`f8e76d856`](https://github.com/npm/npm/commit/f8e76d8566ae1965e57d348df74edad0643b66a6) - [#17370](https://github.com/npm/npm/pull/17370) - Correct the default prefix config path for Windows operating systems in the - documentation for npm folders. - ([@kierendixon](https://github.com/kierendixon)) -* [`d0f3b5a12`](https://github.com/npm/npm/commit/d0f3b5a127718b0347c6622a2b9c28341c530d36) - [#17369](https://github.com/npm/npm/pull/17369) - Fix `npm-config` reference to `userconfig` & `globalconfig` environment - variables. - ([@racztiborzoltan](https://github.com/racztiborzoltan)) -* [`87629880a`](https://github.com/npm/npm/commit/87629880a71baec352c1b5345bc29268d6212467) - [#17336](https://github.com/npm/npm/pull/17336) - Remove note in docs about `prepublish` being entirely removed. - ([@Hirse](https://github.com/Hirse)) -* [`a1058afd9`](https://github.com/npm/npm/commit/a1058afd9a7a569bd0ac65b86eadd4fe077a7221) - [#17169](https://github.com/npm/npm/pull/17169) - Document `--no-package-lock` flag. - ([@leggsimon](https://github.com/leggsimon)) -* [`32fc6e41a`](https://github.com/npm/npm/commit/32fc6e41a2ce4dbcd5ce1e5f291e2e2efc779d48) - [#17250](https://github.com/npm/npm/pull/17250) - Fix a typo in the shrinkwrap docs. - ([@Zarel](https://github.com/Zarel)) -* [`f19bd3c8c`](https://github.com/npm/npm/commit/f19bd3c8cbd37c8a99487d6b5035282580ac3e9d) - [#17249](https://github.com/npm/npm/pull/17249) - Fix a package-lock.json cross-reference link. - ([@not-an-aardvark](https://github.com/not-an-aardvark)) -* [`153245edc`](https://github.com/npm/npm/commit/153245edc4845db670ada5e95ef384561706a751) - [#17075](https://github.com/npm/npm/pull/17075/files) - Fix a typo in `npm-config` docs. - ([@KennethKinLum](https://github.com/KennethKinLum)) -* [`c9b534a14`](https://github.com/npm/npm/commit/c9b534a148818d1a97787c0dfdba5f64ce3618a6) - [#17074](https://github.com/npm/npm/pull/17074) - Clarify config documentation with multiple boolean flags. - ([@KennethKinLum](https://github.com/KennethKinLum)) -* [`e111b0a40`](https://github.com/npm/npm/commit/e111b0a40c4bc6691d7b8d67ddce5419e67bfd27) - [#16768](https://github.com/npm/npm/pull/16768) - Document the `-l` option to `npm config list`. - ([@happylynx](https://github.com/happylynx)) -* [`5a803ebad`](https://github.com/npm/npm/commit/5a803ebadd61229bca3d64fb3ef1981729b2548e) - [#16548](https://github.com/npm/npm/pull/16548) - Fix permissions for documentation files. Some of them had `+x` set. (???) - ([@metux](https://github.com/metux)) -* [`d57d4f48c`](https://github.com/npm/npm/commit/d57d4f48c6cd00fdf1e694eb49e9358071d8e105) - [#17319](https://github.com/npm/npm/pull/17319) - Document that the `--silent` option for `npm run-script` can be used to - suppress `npm ERR!` output on errors. - ([@styfle](https://github.com/styfle)) - -### MISC - -Not all contributions need to be visible features, docs, or bugfixes! It's super -helpful when community members go over our code and help clean it up, too! - -* [`9e5b76140`](https://github.com/npm/npm/commit/9e5b76140ffdb7dcd12aa402793644213fb8c5d7) - [#17411](https://github.com/npm/npm/pull/17411) - Convert all callback-style `move` usage to use Promises. - ([@vramana](https://github.com/vramana)) -* [`0711c08f7`](https://github.com/npm/npm/commit/0711c08f779ac641ec42ecc96f604c8861008b28) - [#17394](https://github.com/npm/npm/pull/17394) - Remove unused argument in `deepSortObject`. - ([@vramana](https://github.com/vramana)) -* [`7d650048c`](https://github.com/npm/npm/commit/7d650048c8ed5faa0486492f1eeb698e7383e32f) - [#17563](https://github.com/npm/npm/pull/17563) - Refactor some code to use `Object.assign`. - ([@vramana](https://github.com/vramana)) -* [`993f673f0`](https://github.com/npm/npm/commit/993f673f056aea5f602ea04b1e697b027c267a2d) - [#17600](https://github.com/npm/npm/pull/17600) - Remove an old comment. - ([@vramana](https://github.com/vramana)) - -## v5.0.4 (2017-06-13): - -Hey y'all. This is another minor patch release with a variety of little fixes -we've been accumulating~ - -* [`f0a37ace9`](https://github.com/npm/npm/commit/f0a37ace9ab7879cab20f2b0fcd7840bfc305feb) - Fix `npm doctor` when hitting registries without `ping`. - ([@zkat](https://github.com/zkat)) -* [`64f0105e8`](https://github.com/npm/npm/commit/64f0105e81352b42b72900d83b437b90afc6d9ce) - Fix invalid format error when setting cache-related headers. - ([@zkat](https://github.com/zkat)) -* [`d2969c80e`](https://github.com/npm/npm/commit/d2969c80e4178faebf0f7c4cab6eb610dd953cc6) - Fix spurious `EINTEGRITY` issue. - ([@zkat](https://github.com/zkat)) -* [`800cb2b4e`](https://github.com/npm/npm/commit/800cb2b4e2d0bd00b5c9082a896f2110e907eb0b) - [#17076](https://github.com/npm/npm/pull/17076) - Use legacy `from` field to improve upgrade experience from legacy shrinkwraps - and installs. - ([@zkat](https://github.com/zkat)) -* [`4100d47ea`](https://github.com/npm/npm/commit/4100d47ea58b4966c02604f71350b5316108df6a) - [#17007](https://github.com/npm/npm/pull/17007) - Restore loose semver parsing to match older npm behavior when running into - invalid semver ranges in dependencies. - ([@zkat](https://github.com/zkat)) -* [`35316cce2`](https://github.com/npm/npm/commit/35316cce2ca2d8eb94161ec7fe7e8f7bec7b3aa7) - [#17005](https://github.com/npm/npm/pull/17005) - Emulate npm@4's behavior of simply marking the peerDep as invalid, instead of - crashing. - ([@zkat](https://github.com/zkat)) -* [`e7e8ee5c5`](https://github.com/npm/npm/commit/e7e8ee5c57c7238655677e118a8809b652019f53) - [#16937](https://github.com/npm/npm/pull/16937) - Workaround for separate bug where `requested` was somehow null. - ([@forivall](https://github.com/forivall)) -* [`2d9629bb2`](https://github.com/npm/npm/commit/2d9629bb2043cff47eaad2654a64d2cef5725356) - Better logging output for git errors. - ([@zkat](https://github.com/zkat)) -* [`2235aea73`](https://github.com/npm/npm/commit/2235aea73569fb9711a06fa6344ef31247177dcd) - More scp-url fixes: parsing only worked correctly when a committish was - present. - ([@zkat](https://github.com/zkat)) -* [`80c33cf5e`](https://github.com/npm/npm/commit/80c33cf5e6ef207450949764de41ea96538c636e) - Standardize package permissions on tarball extraction, instead of using perms - from the tarball. This matches previous npm behavior and fixes a number of - incompatibilities in the wild. - ([@zkat](https://github.com/zkat)) -* [`2b1e40efb`](https://github.com/npm/npm/commit/2b1e40efba0b3d1004259efa4275cf42144e3ce3) - Limit shallow cloning to hosts which are known to support it. - ([@zkat](https://github.com/zkat)) - -## v5.0.3 (2017-06-05) - -Happy Monday, y'all! We've got another npm release for you with the fruits of -our ongoing bugsquashing efforts. You can expect at least one more this week, -but probably more -- and as we announced last week, we'll be merging fixes more -rapidly into the `npmc` canary so you can get everything as soon as possible! - -Hope y'all are enjoying npm5 in the meantime, and don't hesitate to file issues -for anything you find! The goal is to get this release rock-solid as soon as we -can. 💚 - -* [`6e12a5cc0`](https://github.com/npm/npm/commit/6e12a5cc022cb5a157a37df7283b6d7b3d49bdab) - Bump several dependencies to get improvements and bugfixes: - * `cacache`: content files (the tarballs) are now read-only. - * `pacote`: fix failing clones with bad heads, send extra TLS-related opts to proxy, enable global auth configurations and `_auth`-based auth. - * `ssri`: stop crashing with `can't call method find of undefined` when running into a weird `opts.integrity`/`opts.algorithms` conflict during verification. - ([@zkat](https://github.com/zkat)) -* [`89cc8e3e1`](https://github.com/npm/npm/commit/89cc8e3e12dad67fd9844accf4d41deb4c180c5c) - [#16917](https://github.com/npm/npm/pull/16917) - Send `ca`, `cert` and `key` config through to network layer. - ([@colinrotherham](https://github.com/colinrotherham)) -* [`6a9b51c67`](https://github.com/npm/npm/commit/6a9b51c67ba3df0372991631992748329b84f2e7) - [#16929](https://github.com/npm/npm/pull/16929) - Send `npm-session` header value with registry requests again. - ([@zarenner](https://github.com/zarenner)) -* [`662a15ab7`](https://github.com/npm/npm/commit/662a15ab7e790e87f5e5a35252f05d5a4a0724a1) - Fix `npm doctor` so it stop complaining about read-only content files in the - cache. - ([@zkat](https://github.com/zkat)) -* [`191d10a66`](https://github.com/npm/npm/commit/191d10a6616d72e26d89fd00f5a4f6158bfbc526) - [#16918](https://github.com/npm/npm/pull/16918) - Clarify prepublish deprecation message. - ([@Hirse](https://github.com/Hirse)) - -## v5.0.2 (2017-06-02) - -Here's another patch release, soon after the other! - -This particular release includes a slew of fixes to npm's git support, which was -causing some issues for a chunk of people, specially those who were using -self-hosted/Enterprise repos. All of those should be back in working condition -now. - -There's another shiny thing you might wanna know about: npm has a Canary release -now! The `npm5` experiment we did during our beta proved to be incredibly -successful: users were able to have a tight feedback loop between reports and -getting the bugfixes they needed, and the CLI team was able to roll out -experimental patches and have the community try them out right away. So we want -to keep doing that. - -From now on, you'll be able to install the 'npm canary' with `npm i -g npmc`. -This release will be a separate binary (`npmc`. Because canary. Get it?), which -will update independently of the main CLI. Most of the time, this will track -`release-next` or something close to it. We might occasionally toss experimental -branches in there to see if our more adventurous users run into anything -interesting with it. For example, the current canary (`npmc@5.0.1-canary.6`) -includes an [experimental multiproc -branch](https://github.com/npm/npm/pull/16633) that parallelizes tarball -extraction across multiple processes. - -If you find any issues while running the canary version, please report them and -let us know it came from `npmc`! It would be tremendously helpful, and finding -things early is a huge reason to have it there. Happy hacking! - -### A NOTE ABOUT THE ISSUE TRACKER - -Just a heads up: We're preparing to do a massive cleanup of the issue tracker. -It's been a long time since it was something we could really keep up with, and -we didn't have a process for dealing with it that could actually be sustainable. - -We're still sussing the details out, and we'll talk about it more when we're -about to do it, but the plan is essentially to close old, abandoned issues and -start over. We will also [add some automation](https://github.com/probot) around -issue management so that things that we can't keep up with don't just stay -around forever. - -Stay tuned! - -### GIT YOLO - -* [`1f26e9567`](https://github.com/npm/npm/commit/1f26e9567a6d14088704e121ebe787c38b6849a4) - `pacote@2.7.27`: Fixes installing committishes that look like semver, even - though they're not using the required `#semver:` syntax. - ([@zkat](https://github.com/zkat)) -* [`85ea1e0b9`](https://github.com/npm/npm/commit/85ea1e0b9478551265d03d545e7dc750b9edf547) - `npm-package-arg@5.1.1`: This includes the npa git-parsing patch to make it so - non-hosted SCP-style identifiers are correctly handled. Previously, npa would - mangle them (even though hosted-git-info is doing the right thing for them). - ([@zkat](https://github.com/zkat)) - -### COOL NEW OUTPUT - -The new summary output has been really well received! One downside that reared -its head as more people used it, though, is that it doesn't really tell you -anything about the toplevel versions it installed. So, if you did `npm i -g -foo`, it would just say "added 1 package". This patch by -[@rmg](https://github.com/rmg) keeps things concise while still telling you -what you got! So now, you'll see something like this: - -``` -$ npm i -g foo bar -+ foo@1.2.3 -+ bar@3.2.1 -added 234 packages in .005ms -``` - -* [`362f9fd5b`](https://github.com/npm/npm/commit/362f9fd5bec65301082416b4292b8fe3eb7f824a) - [#16899](https://github.com/npm/npm/pull/16899) - For every package that is given as an argument to install, print the name and - version that was actually installed. - ([@rmg](https://github.com/rmg)) - -### OTHER BUGFIXES - -* [`a47593a98`](https://github.com/npm/npm/commit/a47593a98a402143081d7077d2ac677d13083010) - [#16835](https://github.com/npm/npm/pull/16835) - Fix a crash while installing with `--no-shrinkwrap`. - ([@jacknagel](https://github.com/jacknagel)) - -### DOC UPDATES - -* [`89e0cb816`](https://github.com/npm/npm/commit/89e0cb8165dd9c3c7ac74d531617f367099608f4) - [#16818](https://github.com/npm/npm/pull/16818) - Fixes a spelling error in the docs. Because the CLI team has trouble spelling - "package", I guess. - ([@ankon](https://github.com/ankon)) -* [`c01fbc46e`](https://github.com/npm/npm/commit/c01fbc46e151bcfb359fd68dd7faa392789b4f55) - [#16895](https://github.com/npm/npm/pull/16895) - Remove `--save` from `npm init` instructions, since it's now the default. - ([@jhwohlgemuth](https://github.com/jhwohlgemuth)) -* [`80c42d218`](https://github.com/npm/npm/commit/80c42d2181dd4d1b79fcee4e9233df268dfb30b7) - Guard against cycles when inflating bundles, as symlinks are bundles now. - ([@iarna](https://github.com/iarna)) -* [`7fe7f8665`](https://github.com/npm/npm/commit/7fe7f86658798db6667df89afc75588c0e43bc94) - [#16674](https://github.com/npm/npm/issues/16674) - Write the builtin config for `npmc`, not just `npm`. This is hardcoded for npm - self-installations and is needed for Canary to work right. - ([@zkat](https://github.com/zkat)) - -### DEP UPDATES - -* [`63df4fcdd`](https://github.com/npm/npm/commit/63df4fcddc7445efb50cc7d8e09cdd45146d3e39) - [#16894](https://github.com/npm/npm/pull/16894) - [`node-gyp@3.6.2`](https://github.com/nodejs/node-gyp/blob/master/CHANGELOG.md#v362-2017-06-01): - Fixes an issue parsing SDK versions on Windows, among other things. - ([@refack](https://github.com/refack)) -* [`5bb15c3c4`](https://github.com/npm/npm/commit/5bb15c3c4f0d7d77c73fd6dafa38ac36549b6e00) - `read-package-tree@5.1.6`: Fixes some racyness while reading the tree. - ([@iarna](https://github.com/iarna)) -* [`a6f7a52e7`](https://github.com/npm/npm/commit/a6f7a52e7) - `aproba@1.1.2`: Remove nested function declaration for speed up - ([@mikesherov](https://github.com/mikesherov)) - -## v5.0.1 (2017-05-31): - -Hey y'all! Hope you're enjoying the new npm! - -As you all know, fresh software that's gone through major overhauls tends to -miss a lot of spots the old one used to handle well enough, and `npm@5` is no -exception. The CLI team will be doing faster release cycles that go directly to -the `latest` tag for a couple of weeks while 5 stabilizes a bit and we're -confident the common low-hanging fruit people are running into are all taken -care of. - -With that said: this is our first patch release! The biggest focus is fixing up -a number of git-related issues that folks ran into right out the door. It also -fixes other things, like some proxy/auth-related issues, and even has a neat -speed boost! (You can expect more speed bumps in the coming releases as pending -work starts landing, too!) - -Thanks everyone who's been reporting issues and submitting patches! - -### BUGFIXES - -* [`e61e68dac`](https://github.com/npm/npm/commit/e61e68dac4fa51c0540a064204a75b19f8052e58) - [#16762](https://github.com/npm/npm/pull/16762) - Make `npm publish` obey the `--tag` flag again. - ([@zkat](https://github.com/zkat)) -* [`923fd58d3`](https://github.com/npm/npm/commit/923fd58d312f40f8c17b232ad1dfc8e2ff622dbd) - [#16749](https://github.com/npm/npm/pull/16749) - Speed up installations by nearly 20% by... removing one line of code. (hah) - ([@mikesherov](https://github.com/mikesherov)) -* [`9aac984cb`](https://github.com/npm/npm/commit/9aac984cbbfef22182ee42b51a193c0b47146ad6) - Guard against a particular failure mode for a bug still being hunted down. - ([@iarna](https://github.com/iarna)) -* [`80ab521f1`](https://github.com/npm/npm/commit/80ab521f18d34df109de0c5dc9eb1cde5ff6d7e8) - Pull in dependency updates for various core deps: - * New `pacote` fixes several git-related bugs. - * `ssri` update fixes crash on early node@4 versions. - * `make-fetch-happen` update fixes proxy authentication issue. - * `npm-user-validate` adds regex for blocking usernames with illegal chars. - ([@zkat](https://github.com/zkat)) -* [`7e5ce87b8`](https://github.com/npm/npm/commit/7e5ce87b84880c7433ee4c07d2dd6ce8806df436) - `pacote@2.7.26`: - Fixes various other git issues related to commit hashes. - ([@zkat](https://github.com/zkat)) -* [`acbe85bfc`](https://github.com/npm/npm/commit/acbe85bfc1a68d19ca339a3fb71da0cffbf58926) - [#16791](https://github.com/npm/npm/pull/16791) - `npm view` was calling `cb` prematurely and giving partial output when called - in a child process. - ([@zkat](https://github.com/zkat)) -* [`ebafe48af`](https://github.com/npm/npm/commit/ebafe48af91f702ccefc8c619d52fed3b8dfd3c7) - [#16750](https://github.com/npm/npm/pull/16750) - Hamilpatch the Musical: Talk less, complete more. - ([@aredridel](https://github.com/aredridel)) - -### DOCUMENTATION - -* [`dc2823a6c`](https://github.com/npm/npm/commit/dc2823a6c5fc098041e61515c643570819d059d2) - [#16799](https://github.com/npm/npm/pull/16799) - Document that `package-lock.json` is never allowed in tarballs. - ([@sonicdoe](https://github.com/sonicdoe)) -* [`f3cb84b44`](https://github.com/npm/npm/commit/f3cb84b446c51d628ee0033cdf13752c15b31a29) - [#16771](https://github.com/npm/npm/pull/16771) - Fix `npm -l` usage information for the `test` command. - ([@grawlinson](https://github.com/grawlinson)) - -### OTHER CHANGES - -* [`661262309`](https://github.com/npm/npm/commit/66126230912ab5ab35287b40a9908e036fa73994) - [#16756](https://github.com/npm/npm/pull/16756) - remove unused argument - ([@Aladdin-ADD](https://github.com/Aladdin-ADD)) -* [`c3e0b4287`](https://github.com/npm/npm/commit/c3e0b4287ea69735cc367aa7bb7e7aa9a6d9804b) - [#16296](https://github.com/npm/npm/pull/16296) - preserve same name convention for command - ([@desfero](https://github.com/desfero)) -* [`9f814831d`](https://github.com/npm/npm/commit/9f814831d330dde7702973186aea06caaa77ff31) - [#16757](https://github.com/npm/npm/pull/16757) - remove unused argument - ([@Aladdin-ADD](https://github.com/Aladdin-ADD)) -* [`3cb843239`](https://github.com/npm/npm/commit/3cb8432397b3666d88c31131dbb4599016a983ff) - minor linter fix - ([@zkat](https://github.com/zkat)) - -## v5.0.0 (2017-05-25) - -Wowowowowow npm@5! - -This release marks months of hard work for the young, scrappy, and hungry CLI -team, and includes some changes we've been hoping to do for literally years. -npm@5 takes npm a pretty big step forward, significantly improving its -performance in almost all common situations, fixing a bunch of old errors due to -the architecture, and just generally making it more robust and fault-tolerant. -It comes with changes to make life easier for people doing monorepos, for users -who want consistency/security guarantees, and brings semver support to git -dependencies. See below for all the deets! - -### Breaking Changes - -* Existing npm caches will no longer be used: you will have to redownload any cached packages. There is no tool or intention to reuse old caches. ([#15666](https://github.com/npm/npm/pull/15666)) - -* `npm install ./packages/subdir` will now create a symlink instead of a regular installation. `file://path/to/tarball.tgz` will not change -- only directories are symlinked. ([#15900](https://github.com/npm/npm/pull/15900)) - -* npm will now scold you if you capitalize its name. seriously it will fight you. - -* [npm will `--save` by default now](https://twitter.com/maybekatz/status/859229741676625920). Additionally, `package-lock.json` will be automatically created unless an `npm-shrinkwrap.json` exists. ([#15666](https://github.com/npm/npm/pull/15666)) - -* Git dependencies support semver through `user/repo#semver:^1.2.3` ([#15308](https://github.com/npm/npm/pull/15308)) ([#15666](https://github.com/npm/npm/pull/15666)) ([@sankethkatta](https://github.com/sankethkatta)) - -* Git dependencies with `prepare` scripts will have their `devDependencies` installed, and `npm install` run in their directory before being packed. - -* `npm cache` commands have been rewritten and don't really work anything like they did before. ([#15666](https://github.com/npm/npm/pull/15666)) - -* `--cache-min` and `--cache-max` have been deprecated. ([#15666](https://github.com/npm/npm/pull/15666)) - -* Running npm while offline will no longer insist on retrying network requests. npm will now immediately fall back to cache if possible, or fail. ([#15666](https://github.com/npm/npm/pull/15666)) - -* package locks no longer exclude `optionalDependencies` that failed to build. This means package-lock.json and npm-shrinkwrap.json should now be cross-platform. ([#15900](https://github.com/npm/npm/pull/15900)) - -* If you generated your package lock against registry A, and you switch to registry B, npm will now try to [install the packages from registry B, instead of A](https://twitter.com/maybekatz/status/862834964932435969). If you want to use different registries for different packages, use scope-specific registries (`npm config set @myscope:registry=https://myownregist.ry/packages/`). Different registries for different unscoped packages are not supported anymore. - -* Shrinkwrap and package-lock no longer warn and exit without saving the lockfile. - -* Local tarballs can now only be installed if they have a file extensions `.tar`, `.tar.gz`, or `.tgz`. - -* A new loglevel, `notice`, has been added and set as default. - -* One binary to rule them all: `./cli.js` has been removed in favor of `./bin/npm-cli.js`. In case you were doing something with `./cli.js` itself. ([#12096](https://github.com/npm/npm/pull/12096)) ([@watilde](https://github.com/watilde)) - -* Stub file removed ([#16204](https://github.com/npm/npm/pull/16204)) ([@watilde](https://github.com/watilde)) - -* The "extremely legacy" `_token` couchToken has been removed. ([#12986](https://github.com/npm/npm/pull/12986)) - -### Feature Summary - -#### Installer changes - -* A new, standardised lockfile feature meant for cross-package-manager compatibility (`package-lock.json`), and a new format and semantics for shrinkwrap. ([#16441](https://github.com/npm/npm/pull/16441)) - -* `--save` is no longer necessary. All installs will be saved by default. You can prevent saving with `--no-save`. Installing optional and dev deps is unchanged: use `-D/--save-dev` and `-O/--save-optional` if you want them saved into those fields instead. Note that since npm@3, npm will automatically update npm-shrinkwrap.json when you save: this will also be true for `package-lock.json`. ([#15666](https://github.com/npm/npm/pull/15666)) - -* Installing a package directory now ends up creating a symlink and does the Right Thing™ as far as saving to and installing from the package lock goes. If you have a monorepo, this might make things much easier to work with, and probably a lot faster too. 😁 ([#15900](https://github.com/npm/npm/pull/15900)) - -* Project-level (toplevel) `preinstall` scripts now run before anything else, and can modify `node_modules` before the CLI reads it. - -* Two new scripts have been added, `prepack` and `postpack`, which will run on both `npm pack` and `npm publish`, but NOT on `npm install` (without arguments). Combined with the fact that `prepublishOnly` is run before the tarball is generated, this should round out the general story as far as putzing around with your code before publication. - -* Git dependencies with `prepare` scripts will now [have their devDependencies installed, and their prepare script executed](https://twitter.com/maybekatz/status/860363896443371520) as if under `npm pack`. - -* Git dependencies now support semver-based matching: `npm install git://github.com/npm/npm#semver:^5` (#15308, #15666) - -* `node-gyp` now supports `node-gyp.cmd` on Windows ([#14568](https://github.com/npm/npm/pull/14568)) - -* npm no longer blasts your screen with the whole installed tree. Instead, you'll see a summary report of the install that is much kinder on your shell real-estate. Specially for large projects. ([#15914](https://github.com/npm/npm/pull/15914)): -``` -$ npm install -npm added 125, removed 32, updated 148 and moved 5 packages in 5.032s. -$ -``` - -* `--parseable` and `--json` now work more consistently across various commands, particularly `install` and `ls`. - -* Indentation is now [detected and preserved](https://twitter.com/maybekatz/status/860690502932340737) for `package.json`, `package-lock.json`, and `npm-shrinkwrap.json`. If the package lock is missing, it will default to `package.json`'s current indentation. - -#### Publishing - -* New [publishes will now include *both* `sha512`](https://twitter.com/maybekatz/status/863201943082065920) and `sha1` checksums. Versions of npm from 5 onwards will use the strongest algorithm available to verify downloads. [npm/npm-registry-client#157](https://github.com/npm/npm-registry-client/pull/157) - -#### Cache Rewrite! - -We've been talking about rewriting the cache for a loooong time. So here it is. -Lots of exciting stuff ahead. The rewrite will also enable some exciting future -features, but we'll talk about those when they're actually in the works. #15666 -is the main PR for all these changes. Additional PRs/commits are linked inline. - -* Package metadata, package download, and caching infrastructure replaced. - -* It's a bit faster. [Hopefully it will be noticeable](https://twitter.com/maybekatz/status/865393382260056064). 🤔 - -* With the shrinkwrap and package-lock changes, tarballs will be looked up in the cache by content address (and verified with it). - -* Corrupted cache entries will [automatically be removed and re-fetched](https://twitter.com/maybekatz/status/854933138182557696) on integrity check failure. - -* npm CLI now supports tarball hashes with any hash function supported by Node.js. That is, it will [use `sha512` for tarballs from registries that send a `sha512` checksum as the tarball hash](https://twitter.com/maybekatz/status/858137093624573953). Publishing with `sha512` is added by [npm/npm-registry-client#157](https://github.com/npm/npm-registry-client/pull/157) and may be backfilled by the registry for older entries. - -* Remote tarball requests are now cached. This means that even if you're missing the `integrity` field in your shrinkwrap or package-lock, npm will be able to install from the cache. - -* Downloads for large packages are streamed in and out of disk. npm is now able to install packages of """any""" size without running out of memory. Support for publishing them is pending (due to registry limitations). - -* [Automatic fallback-to-offline mode](https://twitter.com/maybekatz/status/854176565587984384). npm will seamlessly use your cache if you are offline, or if you lose access to a particular registry (for example, if you can no longer access a private npm repo, or if your git host is unavailable). - -* A new `--prefer-offline` option will make npm skip any conditional requests (304 checks) for stale cache data, and *only* hit the network if something is missing from the cache. - -* A new `--prefer-online` option that will force npm to revalidate cached data (with 304 checks), ignoring any staleness checks, and refreshing the cache with revalidated, fresh data. - -* A new `--offline` option will force npm to use the cache or exit. It will error with an `ENOTCACHED` code if anything it tries to install isn't already in the cache. - -* A new `npm cache verify` command that will garbage collect your cache, reducing disk usage for things you don't need (-handwave-), and will do full integrity verification on both the index and the content. This is also hooked into `npm doctor` as part of its larger suite of checking tools. - -* The new cache is *very* fault tolerant and supports concurrent access. - * Multiple npm processes will not corrupt a shared cache. - * Corrupted data will not be installed. Data is checked on both insertion and extraction, and treated as if it were missing if found to be corrupted. I will literally bake you a cookie if you manage to corrupt the cache in such a way that you end up with the wrong data in your installation (installer bugs notwithstanding). - * `npm cache clear` is no longer useful for anything except clearing up disk space. - -* Package metadata is cached separately per registry and package type: you can't have package name conflicts between locally-installed packages, private repo packages, and public repo packages. Identical tarball data will still be shared/deduplicated as long as their hashes match. - -* HTTP cache-related headers and features are "fully" (lol) supported for both metadata and tarball requests -- if you have your own registry, you can define your own cache settings the CLI will obey! - -* `prepublishOnly` now runs *before* the tarball to publish is created, after `prepare` has run. diff --git a/changelogs/CHANGELOG-6.md b/changelogs/CHANGELOG-6.md deleted file mode 100644 index 0f07a687af988..0000000000000 --- a/changelogs/CHANGELOG-6.md +++ /dev/null @@ -1,2910 +0,0 @@ -## 6.14.8 (2020-08-17) - -### BUG FIXES -* [`9262e8c88`](https://github.com/npm/cli/commit/9262e8c88f2f828206423928b8e21eea67f4801a) - [#1575](https://github.com/npm/cli/pull/1575) - npm install --dev deprecation message - ([@sandratatarevicova](https://github.com/sandratatarevicova)) -* [`765cfe0bc`](https://github.com/npm/cli/commit/765cfe0bc05a10b72026291ff0ca7c9ca5cb3f57) - [#1658](https://github.com/npm/cli/issues/1658) - remove unused broken require - ([@aduh95](https://github.com/aduh95)) -* [`4e28de79a`](https://github.com/npm/cli/commit/4e28de79a3a0aacc7603010a592beb448ceb6f5f) - [#1663](https://github.com/npm/cli/pull/1663) - Do not send user secret in the referer header - ([@assapir](https://github.com/assapir)) - -### DOCUMENTATION -* [`8abdf30c9`](https://github.com/npm/cli/commit/8abdf30c95ec90331456f3f2ed78e2703939bb74) - [#1572](https://github.com/npm/cli/pull/1572) - docs: add missing metadata in semver page - ([@tripu](https://github.com/tripu)) -* [`8cedcca46`](https://github.com/npm/cli/commit/8cedcca464ced5aab58be83dd5049c3df13384de) - [#1614](https://github.com/npm/cli/pull/1614) - Node-gyp supports both Python and legacy Python - ([@cclauss](https://github.com/cclauss)) - -### DEPENDENCIES -* [`a303b75fd`](https://github.com/npm/cli/commit/a303b75fd7c4b2644da02ad2ad46d80dfceec3c5) - `update-notifier@2.5.0` -* [`c48600832`](https://github.com/npm/cli/commit/c48600832aff4cc349f59997e08dc4bbde15bd49) - `npm-registry-fetch@4.0.7` -* [`a6e9fc4df`](https://github.com/npm/cli/commit/a6e9fc4df7092ba3eb5394193638b33c24855c36) - `meant@1.0.2`: - -## 6.14.7 (2020-07-21) - -### BUG FIXES -* [`de5108836`](https://github.com/npm/cli/commit/de5108836189bddf28d4d3542f9bd5869cc5c2e9) [#784](https://github.com/npm/cli/pull/784) npm explore spawn shell correctly ([@jasisk](https://github.com/jasisk)) -* [`36e6c01d3`](https://github.com/npm/cli/commit/36e6c01d334c4db75018bc6a4a0bef726fd41ce4) git tag handling regression on shrinkwrap ([@claudiahdz](https://github.com/claudiahdz)) -* [`1961c9369`](https://github.com/npm/cli/commit/1961c9369c92bf8fe530cecba9834ca3c7f5567c) [#288](https://github.com/npm/cli/pull/288) Fix package id in shrinkwrap lifecycle step output ([@bz2](https://github.com/bz2)) -* [`87888892a`](https://github.com/npm/cli/commit/87888892a1282cc3edae968c3ae4ec279189271c) [#1009](https://github.com/npm/cli/pull/1009) gracefully handle error during npm install ([@danielleadams](https://github.com/danielleadams)) -* [`6fe2bdc25`](https://github.com/npm/cli/commit/6fe2bdc25e7961956e5c0067fa4db54ff1bd0dbd) [#1547](https://github.com/npm/cli/pull/1547) npm ls --parseable --long output ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES -* [`2d78481c7`](https://github.com/npm/cli/commit/2d78481c7ec178e628ce23df940f73a05d5c6367) update mkdirp on tacks ([@claudiahdz](https://github.com/claudiahdz)) -* [`4e129d105`](https://github.com/npm/cli/commit/4e129d105eba3b12d474caa6e5ca216a98deb75a) uninstall npm-registry-couchapp ([@claudiahdz](https://github.com/claudiahdz)) -* [`8e1869e27`](https://github.com/npm/cli/commit/8e1869e278d1dd37ddefd6b4e961d1bb17fc9d09) update marked dev dep ([@claudiahdz](https://github.com/claudiahdz)) -* [`6a6151f37`](https://github.com/npm/cli/commit/6a6151f377063c6aca852c859c01910edd235ec6) `libnpx@10.2.4` ([@claudiahdz](https://github.com/claudiahdz)) -* [`dc21422eb`](https://github.com/npm/cli/commit/dc21422eb1ca1a4a19f160fad0e924566e08c496) `bin-links@1.1.8` ([@claudiahdz](https://github.com/claudiahdz)) -* [`d341f88ce`](https://github.com/npm/cli/commit/d341f88ce6feb3df1dcb37f34910fcc6c1db85f2) `gentle-fs@2.3.1` ([@claudiahdz](https://github.com/claudiahdz)) -* [`3e168d49b`](https://github.com/npm/cli/commit/3e168d49b41574809cae2ad013776a00d3f20ff4) `libcipm@4.0.8` ([@claudiahdz](https://github.com/claudiahdz)) -* [`6ae942a51`](https://github.com/npm/cli/commit/6ae942a510520b7dff11b5b78eebeff1706e38af) `npm-audit-report@1.3.3` ([@claudiahdz](https://github.com/claudiahdz)) -* [`6a35e3dee`](https://github.com/npm/cli/commit/6a35e3deec275bf2ae76603acd424a0640458047) `npm-lifecycle@3.1.5` ([@claudiahdz](https://github.com/claudiahdz)) - -## 6.14.6 (2020-07-07) - -### BUG FIXES -* [`a9857b8f6`](https://github.com/npm/cli/commit/a9857b8f6869451ff058789c4631fadfde5bbcbc) chore: remove auth info from logs ([@claudiahdz](https://github.com/claudiahdz)) -* [`b7ad77598`](https://github.com/npm/cli/commit/b7ad77598112908d60195d0fbc472b3c84275fd5) [#1416](https://github.com/npm/cli/pull/1416) fix: wrong `npm doctor` command result ([@vanishcode](https://github.com/vanishcode)) - -### DEPENDENCIES -* [`94eca6377`](https://github.com/npm/cli/commit/94eca637756376b949edfb697e179a1fdcc231ee) `npm-registry-fetch@4.0.5` ([@claudiahdz](https://github.com/claudiahdz)) -* [`c49b6ae28`](https://github.com/npm/cli/commit/c49b6ae28791ff7184288be16654f97168aa9705) [#1418](https://github.com/npm/cli/pull/1418) `spdx-license-ids@3.0.5` ([@kemitchell](https://github.com/kemitchell)) - -### DOCUMENTATION -* [`2e052984b`](https://github.com/npm/cli/commit/2e052984b08c09115ed75387fb2c961631d85d77) - [#1459](https://github.com/npm/cli/pull/1459) - chore(docs): fixed links to cli commands ([@claudiahdz](https://github.com/claudiahdz)) -* [`0ca3509ca`](https://github.com/npm/cli/commit/0ca3509ca940865392daeeabb39192f7d5af9f5e) - [#1283](https://github.com/npm/cli/pull/1283) Update npm-link.md ([@peterfich](https://github.com/peterfich)) -* [`3dd429e9a`](https://github.com/npm/cli/commit/3dd429e9aad760ce2ff9e522b34ebfebd85b460c) - [#1377](https://github.com/npm/cli/pull/1377) - Add note about dropped `*` filenames ([@maxwellgerber](https://github.com/maxwellgerber)) -* [`9a2e2e797`](https://github.com/npm/cli/commit/9a2e2e797e5c91e7f4f261583a1906e2c440cc2f) - [#1429](https://github.com/npm/cli/pull/1429) Fix typo ([@seanpoulter](https://github.com/seanpoulter)) - -## 6.14.5 (2020-05-01) - -### BUG FIXES - -* [`33ec41f18`](https://github.com/npm/cli/commit/33ec41f18f557146607cb14a7a38c707fce6d42c) [#758](https://github.com/npm/cli/pull/758) fix: relativize file links when inflating shrinkwrap ([@jsnajdr](https://github.com/jsnajdr)) -* [`94ed456df`](https://github.com/npm/cli/commit/94ed456dfb0b122fd4192429024f034d06c3c454) [#1162](https://github.com/npm/cli/pull/1162) fix: npm init help output ([@mum-never-proud](https://github.com/mum-never-proud)) - -### DEPENDENCIES - -* [`5587ac01f`](https://github.com/npm/cli/commit/5587ac01ffd0d2ea830a6bbb67bb34a611ffc409) `npm-registry-fetch@4.0.4` - * [`fc5d94c39`](https://github.com/npm/npm-registry-fetch/commit/fc5d94c39ca218d78df77249ab3a6bf1d9ed9db1) fix: removed default timeout -* [`07a4d8884`](https://github.com/npm/cli/commit/07a4d8884448359bac485a49c05fd2d23d06834b) `graceful-fs@4.2.4` -* [`8228d1f2e`](https://github.com/npm/cli/commit/8228d1f2e427ad9adee617266108acd1ee39b4a5) `mkdirp@0.5.5` -* [`e6d208317`](https://github.com/npm/cli/commit/e6d20831740a84aea766da2a2913cf82a4d56ada) `nopt@4.0.3` - -## 6.14.4 (2020-03-24) - -### DEPENDENCIES - -* Bump `minimist@1.2.5` transitive dep to resolve security issue - * [`9c554fd8c`](https://github.com/npm/cli/commit/9c554fd8cd1e9aeb8eb122ccfa3c78d12af4097a) `update-notifier@2.5.0` - * bump `deep-extend@1.2.5` - * bump `deep-extend@0.6.0` - * bump `is-ci@1.2.1` - * bump `is-retry-allowed@1.2.0` - * bump `rc@1.2.8` - * bump `registry-auth-token@3.4.0` - * bump `widest-line@2.0.1` -* [`136832dca`](https://github.com/npm/cli/commit/136832dcae13cb5518b1fe17bd63ea9b2a195f92) `mkdirp@0.5.4` -* [`8bf99b2b5`](https://github.com/npm/cli/commit/8bf99b2b58c14d45dc6739fce77de051ebc8ffb7) [#1053](https://github.com/npm/cli/pull/1053) deps: updates term-size to use signed binary - * [`d2f08a1bdb`](https://github.com/nodejs/node/commit/d2f08a1bdb78655c4a3fc49825986c148d14117e) ([@rvagg](https://github.com/rvagg)) - -## 6.14.3 (2020-03-19) - -### DOCUMENTATION - -* [`4ad221487`](https://github.com/npm/cli/commit4ad2214873cddfd4a0eff1bd188516b08fae9f9e) [#1020](https://github.com/npm/cli/pull/1020) docs(teams): updated team docs to reflect MFA workflow ([@blkdm0n](https://github.com/blkdm0n)) -* [`4a31a4ba2`](https://github.com/npm/cli/commit/4a31a4ba2db0a5db2d1d0890ee934ba1babb73a6) [#1034](https://github.com/npm/cli/pull/1034) docs: cleanup ([@ruyadorno](https://github.com/ruyadorno)) -* [`0eac801cd`](https://github.com/npm/cli/commit/0eac801cdef344e9fbda6270145e062211255b0e) [#1013](https://github.com/npm/cli/pull/1013) docs: fix links to cli commands ([@alenros](https://github.com/alenros)) -* [`7d8e5b99c`](https://github.com/npm/cli/commit/7d8e5b99c4ef8c394cffa7fc845f54a25ff37e3a) [#755](https://github.com/npm/cli/pull/755) docs: correction to `npm update -g` behaviour ([@johnkennedy9147](https://github.com/johnkennedy9147)) - -### DEPENDENCIES - -* [`e11167646`](https://github.com/npm/cli/commit/e111676467f090f73802b97e8da7ece481b18f99) `mkdirp@0.5.3` - * [`c5b97d17d`](https://github.com/isaacs/node-mkdirp/commit/c5b97d17d45a22bcf4c815645cbb989dab57ddd8) fix: bump `minimist` dep to resolve security issue ([@isaacs](https://github.com/isaacs)) -* [`c50d679c6`](https://github.com/npm/cli/commit/c50d679c68b39dd03ad127d34f540ddcb1b1e804) `rimraf@2.7.1` -* [`a2de99ff9`](https://github.com/npm/cli/commit/a2de99ff9e02425a3ccc25280f390178be755a36) `npm-registry-mock@1.3.1` -* [`217debeb9`](https://github.com/npm/cli/commit/217debeb9812e037a6686cbf6ec67a0cd47fa68a) `npm-registry-couchapp@2.7.4` - -## 6.14.2 (2020-03-03) - -### DOCUMENTATION -* [`f9248c0be`](https://github.com/npm/cli/commit/f9248c0be63fba37a30098dc9215c752474380e3) [#730](https://github.com/npm/cli/pull/730) chore(docs): update unpublish docs & policy reference ([@nomadtechie](https://github.com/nomadtechie), [@mikemimik](https://github.com/mikemimik)) - -### DEPENDENCIES - -* [`909cc3918`](https://github.com/npm/cli/commit/909cc39180a352f206898481add5772206c8b65f) `hosted-git-info@2.8.8` ([@darcyclarke](https://github.com/darcyclarke)) - * [`5038b1891`](https://github.com/npm/hosted-git-info/commit/5038b1891a61ca3cd7453acbf85d7011fe0086bb) fix: regression in old node versions w/ respect to url.URL implmentation -* [`9204ffa58`](https://github.com/npm/cli/commit/9204ffa584c140c5e22b1ee37f6df2c98f5dc70b) `npm-profile@4.0.4` ([@isaacs](https://github.com/isaacs)) - * [`6bcf0860a`](https://github.com/npm/npm-profile/commit/6bcf0860a3841865099d0115dbcbde8b78109bd9) fix: treat non-http/https login urls as invalid -* [`0365d39bd`](https://github.com/npm/cli/commit/0365d39bdc74960a18caac674f51d0e2a98b31e6) `glob@7.1.6` ([@isaacs](https://github.com/isaacs)) -* [`dab030536`](https://github.com/nodejs/node-gyp/commit/dab030536b6a70ecae37debc74c581db9e5280fd) `node-gyp@5.1.0` ([@rvagg](https://github.com/rvagg)) - -## 6.14.1 (2020-02-26) - -* [`303e5c11e`](https://github.com/npm/cli/commit/303e5c11e7db34cf014107aecd2e81c821bfde8d) - `hosted-git-info@2.8.7` - Fixes a regression where scp-style git urls are passed to the WhatWG URL - parser, which does not handle them properly. - ([@isaacs](https://github.com/isaacs)) - -## 6.14.0 (2020-02-25) - -### FEATURES -* [`30f170877`](https://github.com/npm/cli/commit/30f170877954acd036cb234a581e4eb155049b82) [#731](https://github.com/npm/cli/pull/731) add support for multiple funding sources ([@ljharb](https://github.com/ljharb) & [@ruyadorno](hhttps://github.com/ruyadorno/)) - -### BUG FIXES -* [`55916b130`](https://github.com/npm/cli/commit/55916b130ef52984584678f2cc17c15c1f031cb5) [#508](https://github.com/npm/cli/pull/508) fix: check `npm.config` before accessing its members ([@kaiyoma](https://github.com/kaiyoma)) -* [`7d0cd65b2`](https://github.com/npm/cli/commit/7d0cd65b23c0986b631b9b54d87bbe74902cc023) [#733](https://github.com/npm/cli/pull/733) fix: access grant with unscoped packages ([@netanelgilad](https://github.com/netanelgilad)) -* [`28c3d40d6`](https://github.com/npm/cli/commit/28c3d40d65eef63f9d6ccb60b99ac57f5057a46e), [`0769c5b20`](https://github.com/npm/cli/commit/30f170877954acd036cb234a581e4eb155049b82) [#945](https://github.com/npm/cli/pull/945), [#697](https://github.com/npm/cli/pull/697) fix: allow new major versions of node to be automatically considered "supported" ([@isaacs](https://github.com/isaacs), [@ljharb](https://github.com/ljharb)) - -### DEPENDENCIES -* [`6f39e93`](https://github.com/npm/hosted-git-info/commit/6f39e93bae9162663af6f15a9d10bce675dd5de3) `hosted-git-info@2.8.6` ([@darcyclarke](https://github.com/darcyclarke)) - * fix: passwords & usernames are escaped properly in git deps ([@stevenhilder](https://github.com/stevenhilder)) -* [`f14b594ee`](https://github.com/npm/cli/commit/f14b594ee9dbfc98ed0b65c65d904782db4f31ad) `chownr@1.1.4` ([@isaacs](https://github.com/isaacs)) -* [`77044150b`](https://github.com/npm/cli/commit/77044150b763d67d997f9ff108219132ea922678) `npm-packlist@1.4.8` ([@isaacs](https://github.com/isaacs)) -* [`1d112461a`](https://github.com/npm/cli/commit/1d112461ad8dc99e5ff7fabb5177e8c2f89a9755) `npm-registry-fetch@4.0.3` ([@isaacs](https://github.com/isaacs)) - * [`ba8b4fe`](https://github.com/npm/npm-registry-fetch/commit/ba8b4fe60eb6cdf9b39012560aec596eda8ce924) fix: always bypass cache when ?write=true -* [`a47fed760`](https://github.com/npm/cli/commit/a47fed7603a6ed31dcc314c0c573805f05a96830) `readable-stream@3.6.0` - * [`3bbf2d6`](https://github.com/nodejs/readable-stream/commit/3bbf2d6feb45b03f4e46a2ae8251601ad2262121) fix: babel's "loose mode" class transform enbrittles BufferList ([@ljharb](https://github.com/ljharb)) - -### DOCUMENTATION -* [`284c1c055`](https://github.com/npm/cli/commit/284c1c055a28c4b334496101799acefe3c54ceb3), [`fbb5f0e50`](https://github.com/npm/cli/commit/fbb5f0e50e54425119fa3f03c5de93e4cb6bfda7) [#729](https://github.com/npm/cli/pull/729) update lifecycle hooks docs - ([@seanhealy](https://github.com/seanhealy), [@mikemimik](https://github.com/mikemimik)) -* [`1c272832d`](https://github.com/npm/cli/commit/1c272832d048300e409882313305c416dc6f21a2) [#787](https://github.com/npm/cli/pull/787) fix: trademarks typo ([@dnicolson](https://github.com/dnicolson)) -* [`f6ff41776`](https://github.com/npm/cli/commit/f6ff417767d52418cc8c9e7b9731ede2c3916d2e) [#936](https://github.com/npm/cli/pull/936) fix: postinstall example ([@ajaymathur](https://github.com/ajaymathur)) -* [`373224b16`](https://github.com/npm/cli/commit/373224b16e019b7b63d8f0b4c5d4adb7e5cb80dd) [#939](https://github.com/npm/cli/pull/939) fix: bad links in publish docs ([@vit100](https://github.com/vit100)) - -### MISCELLANEOUS -* [`85c79636d`](https://github.com/npm/cli/commit/85c79636df31bac586c0e380c4852ee155a7723c) [#736](https://github.com/npm/cli/pull/736) add script to update dist-tags ([@mikemimik](https://github.com/mikemimik)) - -## 6.13.7 (2020-01-28) - -### BUG FIXES -* [`7dbb91438`](https://github.com/npm/cli/commit/7dbb914382ecd2074fffb7eba81d93262e2d23c6) - [#655](https://github.com/npm/cli/pull/655) - Update CI detection cases - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES -* [`0fb1296c7`](https://github.com/npm/cli/commit/0fb1296c7d6d4bb9e78c96978c433cd65e55c0ea) - `libnpx@10.2.2` - ([@mikemimik](https://github.com/mikemimik)) -* [`c9b69d569`](https://github.com/npm/cli/commit/c9b69d569fec7944375a746e9c08a6fa9bec96ff) - `node-gyp@5.0.7` - ([@mikemimik](https://github.com/mikemimik)) -* [`e8dbaf452`](https://github.com/npm/cli/commit/e8dbaf452a1f6c5350bb0c37059b89a7448e7986) - `bin-links@1.1.7` - ([@mikemimik](https://github.com/mikemimik)) - * [#613](https://github.com/npm/cli/issues/613) Fixes bin entry for package - -## 6.13.6 (2020-01-09) - -### DEPENDENCIES - -* [`6dba897a1`](https://github.com/npm/cli/commit/6dba897a1e2d56388fb6df0c814b0bb85af366b4) - `pacote@9.5.12`: - * [`d2f4176`](https://github.com/npm/pacote/commit/d2f4176b6af393d7e29de27e9b638dbcbab9a0c7) - fix(git): Do not drop uid/gid when executing in root-owned directory - ([@isaacs](https://github.com/isaacs)) - -## 6.13.5 (2020-01-09) - -### BUG FIXES - -* [`fd0a802ec`](https://github.com/npm/cli/commit/fd0a802ec468ec7b98d6c15934c355fef0e7ff60) [#550](https://github.com/npm/cli/pull/550) Fix cache location for `npm ci` ([@zhenyavinogradov](https://github.com/zhenyavinogradov)) -* [`4b30f3cca`](https://github.com/npm/cli/commit/4b30f3ccaebf50d6ab3bad130ff94827c017cc16) [#648](https://github.com/npm/cli/pull/648) fix(version): using 'allow-same-version', git commit --allow-empty and git tag -f ([@rhengles](https://github.com/rhengles)) - -### TESTING - -* [`e16f68d30`](https://github.com/npm/cli/commit/e16f68d30d59ce1ddde9fe62f7681b2c07fce84d) test(ci): add failing cache config test ([@ruyadorno](https://github.com/ruyadorno)) -* [`3f009fbf2`](https://github.com/npm/cli/commit/3f009fbf2c42f68c5127efecc6e22db105a74fe0) [#659](https://github.com/npm/cli/pull/659) test: fix bin-overwriting test on Windows ([@isaacs](https://github.com/isaacs)) -* [`43ae0791f`](https://github.com/npm/cli/commit/43ae0791f74f68e02850201a64a6af693657b241) [#601](https://github.com/npm/cli/pull/601) ci: Allow builds to run even if one fails ([@XhmikosR](https://github.com/XhmikosR)) -* [`4a669bee4`](https://github.com/npm/cli/commit/4a669bee4ac54c70adc6979d45cd0605b6dc33fd) [#603](https://github.com/npm/cli/pull/603) Remove the unused appveyor.yml ([@XhmikosR](https://github.com/XhmikosR)) -* [`9295046ac`](https://github.com/npm/cli/commit/9295046ac92bbe82f4d84e1ec90cc81d3b80bfc7) [#600](https://github.com/npm/cli/pull/600) ci: switch to `actions/checkout@v2` ([@XhmikosR](https://github.com/XhmikosR)) - -### DOCUMENTATION - -* [`f2d770ac7`](https://github.com/npm/cli/commit/f2d770ac768ea84867772b90a3c9acbdd0c1cb6a) [#569](https://github.com/npm/cli/pull/569) fix netlify publish path config ([@claudiahdz](https://github.com/claudiahdz)) -* [`462cf0983`](https://github.com/npm/cli/commit/462cf0983dbc18a3d93f77212ca69f878060b2ec) [#627](https://github.com/npm/cli/pull/627) update gatsby dependencies ([@felixonmars](https://github.com/felixonmars)) -* [`6fb5dbb72`](https://github.com/npm/cli/commit/6fb5dbb7213c4c050c9a47a7d5131447b8b7dcc8) - [#532](https://github.com/npm/cli/pull/532) docs: clarify usage of global prefix ([@jgehrcke](https://github.com/jgehrcke)) - -## 6.13.4 (2019-12-11) - -## BUGFIXES - -* [`320ac9aee`](https://github.com/npm/cli/commit/320ac9aeeafd11bb693c53b31148b8d10c4165e8) - [npm/bin-links#12](https://github.com/npm/bin-links/pull/12) - [npm/gentle-fs#7](https://github.com/npm/gentle-fs/pull/7) - Do not remove global bin/man links inappropriately - ([@isaacs](https://github.com/isaacs)) - -## DEPENDENCIES - -* [`52fd21061`](https://github.com/npm/cli/commit/52fd21061ff8b1a73429294620ffe5ebaaa60d3e) - `gentle-fs@2.3.0` - ([@isaacs](https://github.com/isaacs)) -* [`d06f5c0b0`](https://github.com/npm/cli/commit/d06f5c0b0611c43b6e70ded92af24fa5d83a0f48) - `bin-links@1.1.6` - ([@isaacs](https://github.com/isaacs)) - -## 6.13.3 (2019-12-09) - -### DEPENDENCIES - -* [`19ce061a2`](https://github.com/npm/cli/commit/19ce061a2ee165d8de862c8f0f733c222846b9e1) - `bin-links@1.1.5` Properly normalize, sanitize, and verify `bin` entries - in `package.json`. -* [`59c836aae`](https://github.com/npm/cli/commit/59c836aae8d0104a767e80c540b963c91774012a) - `npm-packlist@1.4.7` -* [`fb4ecd7d2`](https://github.com/npm/cli/commit/fb4ecd7d2810b0b4897daaf081a5e2f3f483b310) - `pacote@9.5.11` - * [`5f33040`](https://github.com/npm/pacote/commit/5f3304028b6985fd380fc77c4840ff12a4898301) - [#476](https://github.com/npm/cli/issues/476) - [npm/pacote#22](https://github.com/npm/pacote/issues/22) - [npm/pacote#14](https://github.com/npm/pacote/issues/14) fix: Do not - drop perms in git when not root ([isaacs](https://github.com/isaacs), - [@darcyclarke](https://github.com/darcyclarke)) - * [`6f229f7`](https://github.com/npm/pacote/6f229f78d9911b4734f0a19c6afdc5454034c759) - sanitize and normalize package bin field - ([isaacs](https://github.com/isaacs)) -* [`1743cb339`](https://github.com/npm/cli/commit/1743cb339767e86431dcd565c7bdb0aed67b293d) - `read-package-json@2.1.1` - - -## 6.13.2 (2019-12-03) - -### BUG FIXES - -* [`4429645b3`](https://github.com/npm/cli/commit/4429645b3538e1cda54d8d1b7ecb3da7a88fdd3c) - [#546](https://github.com/npm/cli/pull/546) - fix docs target typo - ([@richardlau](https://github.com/richardlau)) -* [`867642942`](https://github.com/npm/cli/commit/867642942bec69bb9ab71cff1914fb6a9fe67de8) - [#142](https://github.com/npm/cli/pull/142) - fix(packageRelativePath): fix 'where' for file deps - ([@larsgw](https://github.com/larsgw)) -* [`d480f2c17`](https://github.com/npm/cli/commit/d480f2c176e6976b3cca3565e4c108b599b0379b) - [#527](https://github.com/npm/cli/pull/527) - Revert "windows: Add preliminary WSL support for npm and npx" - ([@craigloewen-msft](https://github.com/craigloewen-msft)) -* [`e4b97962e`](https://github.com/npm/cli/commit/e4b97962e5fce0d49beb541ce5a0f96aee0525de) - [#504](https://github.com/npm/cli/pull/504) - remove unnecessary package.json read when reading shrinkwrap - ([@Lighting-Jack](https://github.com/Lighting-Jack)) -* [`1c65d26ac`](https://github.com/npm/cli/commit/1c65d26ac9f10ac0037094c207d216fbf0e969bf) - [#501](https://github.com/npm/cli/pull/501) - fix(fund): open url for string shorthand - ([@ruyadorno](https://github.com/ruyadorno)) -* [`ae7afe565`](https://github.com/npm/cli/commit/ae7afe56504dbffabf9f73d55b6dac1e3e9fed4a) - [#263](https://github.com/npm/cli/pull/263) - Don't log error message if git tagging is disabled - ([@woppa684](https://github.com/woppa684)) -* [`4c1b16f6a`](https://github.com/npm/cli/commit/4c1b16f6aecaf78956b9335734cfde2ac076ee11) - [#182](https://github.com/npm/cli/pull/182) - Warn the user that it is uninstalling npm-install - ([@Hoidberg](https://github.com/Hoidberg)) - -## 6.13.1 (2019-11-18) - -### BUG FIXES - -* [`938d6124d`](https://github.com/npm/cli/commit/938d6124d6d15d96b5a69d0ae32ef59fceb8ceab) - [#472](https://github.com/npm/cli/pull/472) - fix(fund): support funding string shorthand - ([@ruyadorno](https://github.com/ruyadorno)) -* [`b49c5535b`](https://github.com/npm/cli/commit/b49c5535b7c41729a8d167b035924c3c66b36de0) - [#471](https://github.com/npm/cli/pull/471) - should not publish tap-snapshot folder - ([@ruyadorno](https://github.com/ruyadorno)) -* [`3471d5200`](https://github.com/npm/cli/commit/3471d5200217bfa612b1a262e36c9c043a52eb09) - [#253](https://github.com/npm/cli/pull/253) - Add preliminary WSL support for npm and npx - ([@infinnie](https://github.com/infinnie)) -* [`3ef295f23`](https://github.com/npm/cli/commit/3ef295f23ee1b2300abf13ec19e935c47a455179) - [#486](https://github.com/npm/cli/pull/486) - print quick audit report for human output - ([@isaacs](https://github.com/isaacs)) - -### TESTING - -* [`dbbf977ac`](https://github.com/npm/cli/commit/dbbf977acd1e74bcdec859c562ea4a2bc0536442) - [#278](https://github.com/npm/cli/pull/278) - added workflow to trigger and run benchmarks - ([@mikemimik](https://github.com/mikemimik)) -* [`b4f5e3825`](https://github.com/npm/cli/commit/b4f5e3825535256aaada09c5e8f104570a3d96a4) - [#457](https://github.com/npm/cli/pull/457) - feat(docs): adding tests and updating docs to reflect changes in registry teams API. - ([@nomadtechie](https://github.com/nomadtechie)) -* [`454c7dd60`](https://github.com/npm/cli/commit/454c7dd60c78371bf606f11a17ed0299025bc37c) - [#456](https://github.com/npm/cli/pull/456) - fix git configs for git 2.23 and above - ([@isaacs](https://github.com/isaacs)) - -### DOCUMENTATION - -* [`b8c1576a4`](https://github.com/npm/cli/commit/b8c1576a448566397c721655b95fc90bf202b35a) [`30b013ae8`](https://github.com/npm/cli/commit/30b013ae8eacd04b1b8a41ce2ed0dd50c8ebae25) [`26c1b2ef6`](https://github.com/npm/cli/commit/26c1b2ef6be1595d28d935d35faa8ec72daae544) [`9f943a765`](https://github.com/npm/cli/commit/9f943a765faf6ebb8a442e862b808dbb630e018d) [`c0346b158`](https://github.com/npm/cli/commit/c0346b158fc25ab6ca9954d4dd78d9e62f573a41) [`8e09d5ad6`](https://github.com/npm/cli/commit/8e09d5ad67d4f142241193cecbce61c659389be3) [`4a2f551ee`](https://github.com/npm/cli/commit/4a2f551eeb3285f6f200534da33644789715a41a) [`87d67258c`](https://github.com/npm/cli/commit/87d67258c213d9ea9a49ce1804294a718f08ff13) [`5c3b32722`](https://github.com/npm/cli/commit/5c3b3272234764c8b4d2d798b69af077b5a529c7) [`b150eaeff`](https://github.com/npm/cli/commit/b150eaeff428180bfa03be53fd741d5625897758) [`7555a743c`](https://github.com/npm/cli/commit/7555a743ce4c3146d6245dd63f91503c7f439a6c) [`b89423e2f`](https://github.com/npm/cli/commit/b89423e2f6a09b290b15254e7ff7e8033b434d83) - [#463](https://github.com/npm/cli/pull/463) - [#285](https://github.com/npm/cli/pull/285) - [#268](https://github.com/npm/cli/pull/268) - [#232](https://github.com/npm/cli/pull/232) - [#485](https://github.com/npm/cli/pull/485) - [#453](https://github.com/npm/cli/pull/453) - docs cleanup: typos, styling and content - ([@claudiahdz](https://github.com/claudiahdz)) - ([@XhmikosR](https://github.com/XhmikosR)) - ([@mugli](https://github.com/mugli)) - ([@brettz9](https://github.com/brettz9)) - ([@mkotsollaris](https://github.com/mkotsollaris)) - -### DEPENDENCIES - -* [`661d86cd2`](https://github.com/npm/cli/commit/661d86cd229b14ddf687b7f25a66941a79d233e7) - `make-fetch-happen@5.0.2` - ([@claudiahdz](https://github.com/claudiahdz)) - -## 6.13.0 (2019-11-05) - -### NEW FEATURES - -* [`4414b06d9`](https://github.com/npm/cli/commit/4414b06d944c56bee05ccfb85260055a767ee334) - [#273](https://github.com/npm/cli/pull/273) - add fund command - ([@ruyadorno](https://github.com/ruyadorno)) - -### DOCUMENTATION - -* [`ae4c74d04`](https://github.com/npm/cli/commit/ae4c74d04f820a0255a92bdfe77ecf97af134fae) - [#274](https://github.com/npm/cli/pull/274) - migrate existing docs to gatsby - ([@claudiahdz](https://github.com/claudiahdz)) -* [`4ff1bb180`](https://github.com/npm/cli/commit/4ff1bb180b1db8c72e51b3d57bd4e268b738e049) - [#277](https://github.com/npm/cli/pull/277) - updated documentation copy - ([@oletizi](https://github.com/oletizi)) - -### BUG FIXES - -* [`e4455409f`](https://github.com/npm/cli/commit/e4455409fe6fe9c198b250b488129171f0b4624a) - [#281](https://github.com/npm/cli/pull/281) - delete ps1 files on package removal - ([@NoDocCat](https://github.com/NoDocCat)) -* [`cd14d4701`](https://github.com/npm/cli/commit/cd14d47014e8c96ffd6a18791e8752028b19d637) - [#279](https://github.com/npm/cli/pull/279) - update supported node list to remove v6.0, v6.1, v9.0 - v9.2 - ([@ljharb](https://github.com/ljharb)) - -### DEPENDENCIES - -* [`a37296b20`](https://github.com/npm/cli/commit/a37296b20ca3e19c2bbfa78fedcfe695e03fda69) - `pacote@9.5.9` -* [`d3cb3abe8`](https://github.com/npm/cli/commit/d3cb3abe8cee54bd2624acdcf8043932ef0d660a) - `read-cmd-shim@1.0.5` - -### TESTING - -* [`688cd97be`](https://github.com/npm/cli/commit/688cd97be94ca949719424ff69ff515a68c5caba) - [#272](https://github.com/npm/cli/pull/272) - use github actions for CI - ([@JasonEtco](https://github.com/JasonEtco)) -* [`9a2d8af84`](https://github.com/npm/cli/commit/9a2d8af84f7328f13d8f578cf4b150b9d5f09517) - [#240](https://github.com/npm/cli/pull/240) - Clean up some flakiness and inconsistency - ([@isaacs](https://github.com/isaacs)) - -## 6.12.1 (2019-10-29) - -### BUG FIXES - -* [`6508e833d`](https://github.com/npm/cli/commit/6508e833df35a3caeb2b496f120ce67feff306b6) - [#269](https://github.com/npm/cli/pull/269) - add node v13 as a supported version - ([@ljharb](https://github.com/ljharb)) -* [`b6588a8f7`](https://github.com/npm/cli/commit/b6588a8f74fb8b1ad103060b73c4fd5174b1d1f6) - [#265](https://github.com/npm/cli/pull/265) - Fix regression in lockfile repair for sub-deps - ([@feelepxyz](https://github.com/feelepxyz)) -* [`d5dfe57a1`](https://github.com/npm/cli/commit/d5dfe57a1d810fe7fd64edefc976633ee3a4da53) - [#266](https://github.com/npm/cli/pull/266) - resolve circular dependency in pack.js - ([@addaleax](https://github.com/addaleax)) - -### DEPENDENCIES - -* [`73678bb59`](https://github.com/npm/cli/commit/73678bb590a8633c3bdbf72e08f1279f9e17fd28) - `chownr@1.1.3` -* [`4b76926e2`](https://github.com/npm/cli/commit/4b76926e2058ef30ab1d5e2541bb96d847653417) - `graceful-fs@4.2.3` -* [`c691f36a9`](https://github.com/npm/cli/commit/c691f36a9c108b6267859fe61e4a38228b190c17) - `libcipm@4.0.7` -* [`5e1a14975`](https://github.com/npm/cli/commit/5e1a14975311bfdc43df8e1eb317ae5690ee580c) - `npm-packlist@1.4.6` -* [`c194482d6`](https://github.com/npm/cli/commit/c194482d65ee81a5a0a6281c7a9f984462286c56) - `npm-registry-fetch@4.0.2` -* [`bc6a8e0ec`](https://github.com/npm/cli/commit/bc6a8e0ec966281e49b1dc66f9c641ea661ab7a6) - `tar@4.4.1` -* [`4dcca3cbb`](https://github.com/npm/cli/commit/4dcca3cbb161da1f261095d9cdd26e1fbb536a8d) - `uuid@3.3.3` - -## 6.12.0 (2019-10-08): - -Now `npm ci` runs prepare scripts for git dependencies, and respects the -`--no-optional` argument. Warnings for `engine` mismatches are printed -again. Various other fixes and cleanups. - -### BUG FIXES - -* [`890b245dc`](https://github.com/npm/cli/commit/890b245dc1f609590d8ab993fac7cf5a37ed46a5) - [#252](https://github.com/npm/cli/pull/252) ci: add dirPacker to options - ([@claudiahdz](https://github.com/claudiahdz)) -* [`f3299acd0`](https://github.com/npm/cli/commit/f3299acd0b4249500e940776aca77cc6c0977263) - [#257](https://github.com/npm/cli/pull/257) - [npm.community#4792](https://npm.community/t/engines-and-engines-strict-ignored/4792) - warn message on engine mismatch - ([@ruyadorno](https://github.com/ruyadorno)) -* [`bbc92fb8f`](https://github.com/npm/cli/commit/bbc92fb8f3478ff67071ebaff551f01c1ea42ced) - [#259](https://github.com/npm/cli/pull/259) - [npm.community#10288](https://npm.community/t/npm-token-err-figgypudding-options-cannot-be-modified-use-concat-instead/10288) - Fix figgyPudding error in `npm token` - ([@benblank](https://github.com/benblank)) -* [`70f54dcb5`](https://github.com/npm/cli/commit/70f54dcb5693b301c6b357922b7e8d16b57d8b00) - [#241](https://github.com/npm/cli/pull/241) doctor: Make OK more - consistent ([@gemal](https://github.com/gemal)) - -### FEATURES - -* [`ed993a29c`](https://github.com/npm/cli/commit/ed993a29ccf923425317c433844d55dbea2f23ee) - [#249](https://github.com/npm/cli/pull/249) Add CI environment variables - to user-agent ([@isaacs](https://github.com/isaacs)) -* [`f6b0459a4`](https://github.com/npm/cli/commit/f6b0459a466a2c663dbd549cdc331e7732552dca) - [#248](https://github.com/npm/cli/pull/248) Add option to save - package-lock without formatting Adds a new config - `--format-package-lock`, which defaults to true. - ([@bl00mber](https://github.com/bl00mber)) - -### DEPENDENCIES - -* [`0ca063c5d`](https://github.com/npm/cli/commit/0ca063c5dc961c4aa17373f4b33fb54c51c8c8d6) - `npm-lifecycle@3.1.4`: - - fix: filter functions and undefined out of makeEnv - ([@isaacs](https://github.com/isaacs)) -* [`5df6b0ea2`](https://github.com/npm/cli/commit/5df6b0ea2e3106ba65bba649cc8d7f02f4738236) - `libcipm@4.0.4`: - - fix: pack git directories properly - ([@claudiahdz](https://github.com/claudiahdz)) - - respect no-optional argument - ([@cruzdanilo](https://github.com/cruzdanilo)) -* [`7e04f728c`](https://github.com/npm/cli/commit/7e04f728cc4cd4853a8fc99e2df0a12988897589) - `tar@4.4.12` -* [`5c380e5a3`](https://github.com/npm/cli/commit/5c380e5a33d760bb66a4285b032ae5f50af27199) - `stringify-package@1.0.1` ([@isaacs](https://github.com/isaacs)) -* [`62f2ca692`](https://github.com/npm/cli/commit/62f2ca692ac0c0467ef4cf74f91777a5175258c4) - `node-gyp@5.0.5` ([@isaacs](https://github.com/isaacs)) -* [`0ff0ea47a`](https://github.com/npm/cli/commit/0ff0ea47a8840dd7d952bde7f7983a5016cda8ea) - `npm-install-checks@3.0.2` ([@isaacs](https://github.com/isaacs)) -* [`f46edae94`](https://github.com/npm/cli/commit/f46edae9450b707650a0efab09aa1e9295a18070) - `hosted-git-info@2.8.5` ([@isaacs](https://github.com/isaacs)) - -### TESTING - -* [`44a2b036b`](https://github.com/npm/cli/commit/44a2b036b34324ec85943908264b2e36de5a9435) - [#262](https://github.com/npm/cli/pull/262) fix root-ownership race - conditions in meta-test ([@isaacs](https://github.com/isaacs)) - -## 6.11.3 (2019-09-03): - -Fix npm ci regressions and npm outdated depth. - -### BUG FIXES - -* [`235ed1d28`](https://github.com/npm/cli/commit/235ed1d2838ef302bb995e183980209d16c51b9b) - [#239](https://github.com/npm/cli/pull/239) - Don't override user specified depth in outdated - Restores ability to update packages using `--depth` as suggested by `npm audit`. - ([@G-Rath](https://github.com/G-Rath)) -* [`1fafb5151`](https://github.com/npm/cli/commit/1fafb51513466cd793866b576dfea9a8963a3335) - [#242](https://github.com/npm/cli/pull/242) - [npm.community#9586](https://npm.community/t/6-11-1-some-dependencies-are-no-longer-being-installed/9586/4) - Revert "install: do not descend into directory deps' child modules" - ([@isaacs](https://github.com/isaacs)) -* [`cebf542e6`](https://github.com/npm/cli/commit/cebf542e61dcabdd2bd3b876272bf8eebf7d01cc) - [#243](https://github.com/npm/cli/pull/243) - [npm.community#9720](https://npm.community/t/6-11-2-npm-ci-installs-package-with-wrong-permissions/9720) - ci: pass appropriate configs for file/dir modes - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`e5fbb7ed1`](https://github.com/npm/cli/commit/e5fbb7ed1fc7ef5c6ca4790e2d0dc441e0ac1596) - `read-cmd-shim@1.0.4` - ([@claudiahdz](https://github.com/claudiahdz)) -* [`23ce65616`](https://github.com/npm/cli/commit/23ce65616c550647c586f7babc3c2f60115af2aa) - `npm-pick-manifest@3.0.2` - ([@claudiahdz](https://github.com/claudiahdz)) - -## 6.11.2 (2019-08-22): - -Fix a recent Windows regression, and two long-standing Windows bugs. Also, -get CI running on Windows, so these things are less likely in the future. - -### DEPENDENCIES - -* [`9778a1b87`](https://github.com/npm/cli/commit/9778a1b878aaa817af6e99385e7683c2a389570d) - `cmd-shim@3.0.3`: Fix regression where shims fail to preserve exit code - ([@isaacs](https://github.com/isaacs)) -* [`bf93e91d8`](https://github.com/npm/cli/commit/bf93e91d879c816a055d5913e6e4210d7299f299) - `npm-package-arg@6.1.1`: Properly handle git+file: urls on Windows when a - drive letter is included. ([@isaacs](https://github.com/isaacs)) - -### BUGFIXES - -* [`6cc4cc66f`](https://github.com/npm/cli/commit/6cc4cc66f1fb050dc4113e35cab59197fd48e04a) - escape args properly on Windows Bash Despite being bash, Node.js running - on windows git mingw bash still executes child processes using cmd.exe. - As a result, arguments in this environment need to be escaped in the - style of cmd.exe, not bash. ([@isaacs](https://github.com/isaacs)) - -### TESTS - -* [`291aba7b8`](https://github.com/npm/cli/commit/291aba7b821e247b96240b1ec037310ead69a594) - make tests pass on Windows ([@isaacs](https://github.com/isaacs)) -* [`fea3a023a`](https://github.com/npm/cli/commit/fea3a023a80863f32a5f97f5132401b1a16161b8) - travis: run tests on Windows as well - ([@isaacs](https://github.com/isaacs)) - -## 6.11.1 (2019-08-20): - -Fix a regression for windows command shim syntax. - -* [`37db29647`](https://github.com/npm/cli/commit/37db2964710c80003604b7e3c1527d17be7ed3d0) - `cmd-shim@3.0.2` ([@isaacs](https://github.com/isaacs)) - -## v6.11.0 (2019-08-20): - -A few meaty bugfixes, and introducing `peerDependenciesMeta`. - -### FEATURES - -* [`a12341088`](https://github.com/npm/cli/commit/a12341088820c0e7ef6c1c0db3c657f0c2b3943e) - [#224](https://github.com/npm/cli/pull/224) Implements - peerDependenciesMeta ([@arcanis](https://github.com/arcanis)) -* [`2f3b79bba`](https://github.com/npm/cli/commit/2f3b79bbad820fd4a398aa494b19f79b7fd520a1) - [#234](https://github.com/npm/cli/pull/234) add new forbidden 403 error - code ([@claudiahdz](https://github.com/claudiahdz)) - -### BUGFIXES - -* [`24acc9fc8`](https://github.com/npm/cli/commit/24acc9fc89d99d87cc66206c6c6f7cdc82fbf763) - and - [`45772af0d`](https://github.com/npm/cli/commit/45772af0ddca54b658cb2ba2182eec26d0a4729d) - [#217](https://github.com/npm/cli/pull/217) - [npm.community#8863](https://npm.community/t/installing-the-same-module-under-multiple-relative-paths-fails-on-linux/8863) - [npm.community#9327](https://npm.community/t/reinstall-breaks-after-npm-update-to-6-10-2/9327,) - do not descend into directory deps' child modules, fix shrinkwrap files - that inappropriately list child nodes of symlink packages - ([@isaacs](https://github.com/isaacs) and - [@salomvary](https://github.com/salomvary)) -* [`50cfe113d`](https://github.com/npm/cli/commit/50cfe113da5fcc59c1d99b0dcf1050ace45803c7) - [#229](https://github.com/npm/cli/pull/229) fixed typo in semver doc - ([@gall0ws](https://github.com/gall0ws)) -* [`e8fb2a1bd`](https://github.com/npm/cli/commit/e8fb2a1bd9785e0092e9926f4fd65ad431e38452) - [#231](https://github.com/npm/cli/pull/231) Fix spelling mistakes in - CHANGELOG-3.md ([@XhmikosR](https://github.com/XhmikosR)) -* [`769d2e057`](https://github.com/npm/cli/commit/769d2e057daf5a2cbfe0ce86f02550e59825a691) - [npm/uid-number#7](https://github.com/npm/uid-number/issues/7) Better - error on invalid `--user`/`--group` configs. This addresses the issue - when people fail to install binary packages on Docker and other - environments where there is no 'nobody' user. - ([@isaacs](https://github.com/isaacs)) -* [`8b43c9624`](https://github.com/npm/cli/commit/8b43c962498c8e2707527e4fca442d7a4fa51595) - [nodejs/node#28987](https://github.com/nodejs/node/issues/28987) - [npm.community#6032](https://npm.community/t/npm-ci-doesnt-respect-npmrc-variables/6032) - [npm.community#6658](https://npm.community/t/npm-ci-doesnt-fill-anymore-the-process-env-npm-config-cache-variable-on-post-install-scripts/6658) - [npm.community#6069](https://npm.community/t/npm-ci-does-not-compile-native-dependencies-according-to-npmrc-configuration/6069) - [npm.community#9323](https://npm.community/t/npm-6-9-x-not-passing-environment-to-node-gyp-regression-from-6-4-x/9323/2) - Fix the regression where random config values in a .npmrc file are not - passed to lifecycle scripts, breaking build processes which rely on them. - ([@isaacs](https://github.com/isaacs)) -* [`8b85eaa47`](https://github.com/npm/cli/commit/8b85eaa47da3abaacc90fe23162a68cc6e1f0404) - save files with inferred ownership rather than relying on `SUDO_UID` and - `SUDO_GID`. ([@isaacs](https://github.com/isaacs)) -* [`b7f6e5f02`](https://github.com/npm/cli/commit/b7f6e5f0285515087b4614d81db17206524c0fdb) - Infer ownership of shrinkwrap files - ([@isaacs](https://github.com/isaacs)) -* [`54b095d77`](https://github.com/npm/cli/commit/54b095d77b3b131622b3cf4cb5c689aa2dd10b6b) - [#235](https://github.com/npm/cli/pull/235) Add spec to dist-tag remove - function ([@theberbie](https://github.com/theberbie)) - -### DEPENDENCIES - -* [`dc8f9e52f`](https://github.com/npm/cli/commit/dc8f9e52f0bb107c0a6b20cc0c97cbc3b056c1b3) - `pacote@9.5.7`: Infer the ownership of all unpacked files in - `node_modules`, so that we never have user-owned files in root-owned - folders, or root-owned files in user-owned folders. - ([@isaacs](https://github.com/isaacs)) -* [`bb33940c3`](https://github.com/npm/cli/commit/bb33940c32aad61704084e61ebd1bd8e7cacccc8) - `cmd-shim@3.0.0`: - * [`9c93ac3`](https://github.com/npm/cmd-shim/commit/9c93ac39e95b0d6ae852e842e4c5dba5e19687c2) - [#2](https://github.com/npm/cmd-shim/pull/2) - [npm#3380](https://github.com/npm/npm/issues/3380) Handle environment - variables properly ([@basbossink](https://github.com/basbossink)) - * [`2d277f8`](https://github.com/npm/cmd-shim/commit/2d277f8e84d45401747b0b9470058f168b974ad5) - [#25](https://github.com/npm/cmd-shim/pull/25) - [#36](https://github.com/npm/cmd-shim/pull/36) - [#35](https://github.com/npm/cmd-shim/pull/35) Fix 'no shebang' case by - always providing `$basedir` in shell script - ([@igorklopov](https://github.com/igorklopov)) - * [`adaf20b`](https://github.com/npm/cmd-shim/commit/adaf20b7fa2c09c2111a2506c6a3e53ed0831f88) - [#26](https://github.com/npm/cmd-shim/pull/26) Fix `$*` causing an - error when arguments contain parentheses - ([@satazor](https://github.com/satazor)) - * [`49f0c13`](https://github.com/npm/cmd-shim/commit/49f0c1318fd384e0031c3fd43801f0e22e1e555f) - [#30](https://github.com/npm/cmd-shim/pull/30) Fix paths for MSYS/MINGW - bash ([@dscho](https://github.com/dscho)) - * [`51a8af3`](https://github.com/npm/cmd-shim/commit/51a8af30990cb072cb30d67fc1b564b14746bba9) - [#34](https://github.com/npm/cmd-shim/pull/34) Add proper support for - PowerShell ([@ExE-Boss](https://github.com/ExE-Boss)) - * [`4c37e04`](https://github.com/npm/cmd-shim/commit/4c37e048dee672237e8962fdffca28e20e9f976d) - [#10](https://github.com/npm/cmd-shim/issues/10) Work around quoted - batch file names ([@isaacs](https://github.com/isaacs)) -* [`a4e279544`](https://github.com/npm/cli/commit/a4e279544f7983e0adff1e475e3760f1ea85825a) - `npm-lifecycle@3.1.3` ([@isaacs](https://github.com/isaacs)): - * fail properly if `uid-number` raises an error -* [`7086a1809`](https://github.com/npm/cli/commit/7086a1809bbfda9be81344b3949c7d3ac687ffc4) - `libcipm@4.0.3` ([@isaacs](https://github.com/isaacs)) -* [`8845141f9`](https://github.com/npm/cli/commit/8845141f9d7827dae572c8cf26f2c775db905bd3) - `read-package-json@2.1.0` ([@isaacs](https://github.com/isaacs)) -* [`51c028215`](https://github.com/npm/cli/commit/51c02821575d80035ebe853492d110db11a7d1b9) - `bin-links@1.1.3` ([@isaacs](https://github.com/isaacs)) -* [`534a5548c`](https://github.com/npm/cli/commit/534a5548c9ebd59f0dd90e9ccca148ed8946efa6) - `read-cmd-shim@1.0.3` ([@isaacs](https://github.com/isaacs)) -* [`3038f2fd5`](https://github.com/npm/cli/commit/3038f2fd5b1d7dd886ee72798241d8943690f508) - `gentle-fs@2.2.1` ([@isaacs](https://github.com/isaacs)) -* [`a609a1648`](https://github.com/npm/cli/commit/a609a16489f76791697d270b499fd4949ab1f8c3) - `graceful-fs@4.2.2` ([@isaacs](https://github.com/isaacs)) -* [`f0346f754`](https://github.com/npm/cli/commit/f0346f75490619a81b310bfc18646ae5ae2e0ea4) - `cacache@12.0.3` ([@isaacs](https://github.com/isaacs)) -* [`ca9c615c8`](https://github.com/npm/cli/commit/ca9c615c8cff5c7db125735eb09f84d912d18694) - `npm-pick-manifest@3.0.0` ([@isaacs](https://github.com/isaacs)) -* [`b417affbf`](https://github.com/npm/cli/commit/b417affbf7133dc7687fd809e4956a43eae3438a) - `pacote@9.5.8` ([@isaacs](https://github.com/isaacs)) - -### TESTS - -* [`b6df0913c`](https://github.com/npm/cli/commit/b6df0913ca73246f1fa6cfa0e81e34ba5f2b6204) - [#228](https://github.com/npm/cli/pull/228) Proper handing of - /usr/bin/node lifecycle-path test - ([@olivr70](https://github.com/olivr70)) -* [`aaf98e88c`](https://github.com/npm/cli/commit/aaf98e88c78fd6c850d0a3d3ee2f61c02f63bc8c) - `npm-registry-mock@1.3.0` ([@isaacs](https://github.com/isaacs)) - -## v6.10.3 (2019-08-06): - -### BUGFIXES - -* [`27cccfbda`](https://github.com/npm/cli/commit/27cccfbdac8526cc807b07f416355949b1372a9b) - [#223](https://github.com/npm/cli/pull/223) vulns → vulnerabilities in - npm audit output ([@sapegin](https://github.com/sapegin)) -* [`d5e865eb7`](https://github.com/npm/cli/commit/d5e865eb79329665a927cc2767b4395c03045dbb) - [#222](https://github.com/npm/cli/pull/222) - [#226](https://github.com/npm/cli/pull/226) install, doctor: don't crash - if registry unset ([@dmitrydvorkin](https://github.com/dmitrydvorkin), - [@isaacs](https://github.com/isaacs)) -* [`5b3890226`](https://github.com/npm/cli/commit/5b389022652abeb0e1c278a152550eb95bc6c452) - [#227](https://github.com/npm/cli/pull/227) - [npm.community#9167](https://npm.community/t/npm-err-cb-never-called-permission-denied/9167/5) - Handle unhandledRejections, tell user what to do when encountering an - `EACCES` error in the cache. ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`77516df6e`](https://github.com/npm/cli/commit/77516df6eac94a6d7acb5e9ca06feaa0868d779b) - `licensee@7.0.3` ([@isaacs](https://github.com/isaacs)) -* [`ceb993590`](https://github.com/npm/cli/commit/ceb993590e4e376a9a78264ce7bb4327fbbb37fe) - `query-string@6.8.2` ([@isaacs](https://github.com/isaacs)) -* [`4050b9189`](https://github.com/npm/cli/commit/4050b91898c60e9b22998cf82b70b9b822de592a) - `hosted-git-info@2.8.2` - * [#46](https://github.com/npm/hosted-git-info/issues/46) - [#43](https://github.com/npm/hosted-git-info/issues/43) - [#47](https://github.com/npm/hosted-git-info/pull/47) - [#44](https://github.com/npm/hosted-git-info/pull/44) Add support for - GitLab subgroups ([@mterrel](https://github.com/mterrel), - [@isaacs](https://github.com/isaacs), - [@ybiquitous](https://github.com/ybiquitous)) - * [`3b1d629`](https://github.com/npm/hosted-git-info/commit/3b1d629) - [#48](https://github.com/npm/hosted-git-info/issues/48) fix http - protocol using sshurl by default - ([@fengmk2](https://github.com/fengmk2)) - * [`5d4a8d7`](https://github.com/npm/hosted-git-info/commit/5d4a8d7) - ignore noCommittish on tarball url generation - ([@isaacs](https://github.com/isaacs)) - * [`1692435`](https://github.com/npm/hosted-git-info/commit/1692435) - use gist tarball url that works for anonymous gists - ([@isaacs](https://github.com/isaacs)) - * [`d5cf830`](https://github.com/npm/hosted-git-info/commit/d5cf8309be7af884032616c63ea302ce49dd321c) - Do not allow invalid gist urls ([@isaacs](https://github.com/isaacs)) - * [`e518222`](https://github.com/npm/hosted-git-info/commit/e5182224351183ce619dd5ef00019ae700ed37b7) - Use LRU cache to prevent unbounded memory consumption - ([@iarna](https://github.com/iarna)) - -## v6.10.2 (2019-07-23): - -tl;dr - Fixes several issues with the cache when npm is run as `sudo` on -Unix systems. - -### TESTING - -* [`2a78b96f8`](https://github.com/npm/cli/commit/2a78b96f830bbd834720ccc9eacccc54915ae6f7) - check test cache for root-owned files - ([@isaacs](https://github.com/isaacs)) -* [`108646ebc`](https://github.com/npm/cli/commit/108646ebc12f3eeebaa0a45884c45991a45e57e4) - run sudo tests on Travis-CI ([@isaacs](https://github.com/isaacs)) -* [`cf984e946`](https://github.com/npm/cli/commit/cf984e946f453cbea2fcc7a59608de3f24ab74c3) - set --no-esm tap flag ([@isaacs](https://github.com/isaacs)) -* [`8e0a3100d`](https://github.com/npm/cli/commit/8e0a3100dffb3965bb3dc4240e82980dfadf2f3c) - add script to run tests and leave fixtures for inspection and debugging - ([@isaacs](https://github.com/isaacs)) - -### BUGFIXES - -* [`25f4f73f6`](https://github.com/npm/cli/commit/25f4f73f6dc9744757787c82351120cd1baee5f8) - add a util for writing arbitrary files to cache This prevents metrics - timing and debug logs from becoming root-owned. - ([@isaacs](https://github.com/isaacs)) -* [`2c61ce65d`](https://github.com/npm/cli/commit/2c61ce65d6b67100fdf3fcb9729055b669cb1a1d) - infer cache owner from parent dir in `correct-mkdir` util - ([@isaacs](https://github.com/isaacs)) -* [`235e5d6df`](https://github.com/npm/cli/commit/235e5d6df6f427585ec58425f1f3339d08f39d8a) - ensure correct owner on cached all-packages metadata - ([@isaacs](https://github.com/isaacs)) -* [`e2d377bb6`](https://github.com/npm/cli/commit/e2d377bb6419d8a3c1d80a73dba46062b4dad336) - [npm.community#8540](https://npm.community/t/npm-audit-fails-with-child-requires-fails-because-requires-must-be-an-object/8540) - audit: report server error on failure - ([@isaacs](https://github.com/isaacs)) -* [`52576a39e`](https://github.com/npm/cli/commit/52576a39ed75d94c46bb2c482fd38d2c6ea61c56) - [#216](https://github.com/npm/cli/pull/216) - [npm.community#5385](https://npm.community/t/6-8-0-npm-ci-fails-with-local-dependency/5385) - [npm.community#6076](https://npm.community/t/npm-ci-fail-to-local-packages/6076) - Fix `npm ci` with `file:` dependencies. Partially reverts - [#40](https://github.com/npm/cli/pull/40)/[#86](https://github.com/npm/cli/pull/86), - recording dependencies of linked deps in order for `npm ci` to work. - ([@jfirebaugh](https://github.com/jfirebaugh)) - -### DEPENDENCIES - -* [`0fefdee13`](https://github.com/npm/cli/commit/0fefdee130fd7d0dbb240fb9ecb50a793fbf3d29) - `cacache@12.0.2` ([@isaacs](https://github.com/isaacs)) - * infer uid/gid instead of accepting as options, preventing the - overwhelming majority of cases where root-owned files end up in the - cache folder. - ([ac84d14](https://github.com/npm/cacache/commit/ac84d14)) - ([@isaacs](https://github.com/isaacs)) - ([#1](https://github.com/npm/cacache/pull/1)) - * **i18n:** add another error message - ([676cb32](https://github.com/npm/cacache/commit/676cb32)) - ([@zkat](https://github.com/zkat)) -* [`e1d87a392`](https://github.com/npm/cli/commit/e1d87a392371a070b0788ab7bfc62be18b21e9ad) - `pacote@9.5.4` ([@isaacs](https://github.com/isaacs)) - * git: ensure stream failures are reported - ([7f07b5d](https://github.com/npm/pacote/commit/7f07b5d)) - [#1](https://github.com/npm/pacote/issues/1) - ([@lddubeau](https://github.com/lddubeau)) -* [`3f035bf09`](https://github.com/npm/cli/commit/3f035bf098e2feea76574cec18b04812659aa16d) - `infer-owner@1.0.4` ([@isaacs](https://github.com/isaacs)) -* [`ba3283112`](https://github.com/npm/cli/commit/ba32831126591d2f6f48e31a4a2329b533b1ff19) - `npm-registry-fetch@4.0.0` ([@isaacs](https://github.com/isaacs)) -* [`ee90c334d`](https://github.com/npm/cli/commit/ee90c334d271383d0325af42f20f80f34cb61f07) - `libnpm@3.0.1` ([@isaacs](https://github.com/isaacs)) -* [`1e480c384`](https://github.com/npm/cli/commit/1e480c38416982ae28b5cdd48c698ca59d3c0395) - `libnpmaccess@3.0.2` ([@isaacs](https://github.com/isaacs)) -* [`7662ee850`](https://github.com/npm/cli/commit/7662ee850220c71ecaec639adbc7715286f0d28b) - `libnpmhook@5.0.3` ([@isaacs](https://github.com/isaacs)) -* [`1357fadc6`](https://github.com/npm/cli/commit/1357fadc613d0bfeb40f9a8f3ecace2face2fe2c) - `libnpmorg@1.0.1` ([@isaacs](https://github.com/isaacs)) -* [`a621b5cb6`](https://github.com/npm/cli/commit/a621b5cb6c881f95a11af86a8051754a67ae017c) - `libnpmsearch@2.0.2` ([@isaacs](https://github.com/isaacs)) -* [`560cd31dd`](https://github.com/npm/cli/commit/560cd31dd51b6aa2e396ccdd7289fab0a50b5608) - `libnpmteam@1.0.2` ([@isaacs](https://github.com/isaacs)) -* [`de7ae0867`](https://github.com/npm/cli/commit/de7ae0867d4c0180edc283457ce0b4e8e5eee554) - `npm-profile@4.0.2` ([@isaacs](https://github.com/isaacs)) -* [`e95da463c`](https://github.com/npm/cli/commit/e95da463cb7a325457ef411a569d7ef4bf76901d) - `libnpm@3.0.1` ([@isaacs](https://github.com/isaacs)) -* [`554b641d4`](https://github.com/npm/cli/commit/554b641d49d135ae8d137e83aa288897c32dacc6) - `npm-registry-fetch@4.0.0` ([@isaacs](https://github.com/isaacs)) -* [`06772f34a`](https://github.com/npm/cli/commit/06772f34ab851440dcd78574736936c674a84aed) - `node-gyp@5.0.3` ([@isaacs](https://github.com/isaacs)) -* [`85358db80`](https://github.com/npm/cli/commit/85358db80d6ccb5f7bc9a0b4d558ac6dd2468394) - `npm-lifecycle@3.1.2` ([@isaacs](https://github.com/isaacs)) - * [`051cf20`](https://github.com/npm/npm-lifecycle/commit/051cf20072a01839c17920d2e841756251c4f924) - [#26](https://github.com/npm/npm-lifecycle/pull/26) fix switches for - alternative shells on Windows - ([@gucong3000](https://github.com/gucong3000)) - * [`3aaf954`](https://github.com/npm/npm-lifecycle/commit/3aaf95435965e8f7acfd955582cf85237afd2c9b) - [#25](https://github.com/npm/npm-lifecycle/pull/25) set only one PATH - env variable for child process on Windows - ([@zkochan](https://github.com/zkochan)) - * [`ea18ed2`](https://github.com/npm/npm-lifecycle/commit/ea18ed2b754ca7f11998cad70d88e9004c5bef4a) - [#36](https://github.com/npm/npm-lifecycle/pull/36) - [#11](https://github.com/npm/npm-lifecycle/issue/11) - [#18](https://github.com/npm/npm-lifecycle/issue/18) remove - procInterrupt listener on SIGINT in procError - ([@mattshin](https://github.com/mattshin)) - * [`5523951`](https://github.com/npm/npm-lifecycle/commit/55239519c57b82521605622e6c71640a31ed4586) - [#29](https://github.com/npm/npm-lifecycle/issue/29) - [#30](https://github.com/npm/npm-lifecycle/pull/30) Use platform - specific path casing if present - ([@mattezell](https://github.com/mattezell)) - -## v6.10.1 (2019-07-11): - -### BUGFIXES - -* [`3cbd57712`](https://github.com/npm/cli/commit/3cbd577120a9da6e51bb8b13534d1bf71ea5712c) - fix(git): strip GIT environs when running git - ([@isaacs](https://github.com/isaacs)) -* [`a81a8c4c4`](https://github.com/npm/cli/commit/a81a8c4c466f510215a51cef1bb08544d11844fe) - [#206](https://github.com/npm/cli/pull/206) improve isOnly(Dev,Optional) - ([@larsgw](https://github.com/larsgw)) -* [`172f9aca6`](https://github.com/npm/cli/commit/172f9aca67a66ee303c17f90a994cd52fc66552a) - [#179](https://github.com/npm/cli/pull/179) fix-xmas-underline - ([@raywu0123](https://github.com/raywu0123)) -* [`f52673fc7`](https://github.com/npm/cli/commit/f52673fc7284e58af8c04533e82b76bf7add72cf) - [#212](https://github.com/npm/cli/pull/212) build: use `/usr/bin/env` to - load bash ([@rsmarples](https://github.com/rsmarples)) - -### DEPENDENCIES - -* [`ef4445ad3`](https://github.com/npm/cli/commit/ef4445ad34a53b5639499c8e3c9752f62ee6f37c) - [#208](https://github.com/npm/cli/pull/208) `node-gyp@5.0.2` - ([@irega](https://github.com/irega)) -* [`c0d611356`](https://github.com/npm/cli/commit/c0d611356f7b23077e97574b01c8886e544db425) - `npm-lifecycle@3.0.0` ([@isaacs](https://github.com/isaacs)) -* [`7716ba972`](https://github.com/npm/cli/commit/7716ba9720270d5b780755a5bb1ce79702067f1f) - `libcipm@4.0.0` ([@isaacs](https://github.com/isaacs)) -* [`42d22e837`](https://github.com/npm/cli/commit/42d22e8374c7d303d94e405d7385d94dd2558814) - `libnpm@3.0.0` ([@isaacs](https://github.com/isaacs)) -* [`a2ea7f9ff`](https://github.com/npm/cli/commit/a2ea7f9ff64ae743d05fdbf7d46fb9afafa8aa6f) - `semver@5.7.0` ([@isaacs](https://github.com/isaacs)) -* [`429226a5e`](https://github.com/npm/cli/commit/429226a5e992cd907d4f19bd738037007cf78c1f) - `lru-cache@5.1.1` ([@isaacs](https://github.com/isaacs)) -* [`175670ea6`](https://github.com/npm/cli/commit/175670ea65cca03f8b2e957df3dd4b8b0efd0e1f) - `npm-registry-fetch@3.9.1`: ([@isaacs](https://github.com/isaacs)) -* [`0d0517f7f`](https://github.com/npm/cli/commit/0d0517f7f8c902b5064ac18fb4015b31750ad2b2) - `call-limit@1.1.1` ([@isaacs](https://github.com/isaacs)) -* [`741400429`](https://github.com/npm/cli/commit/74140042917ea241062a812ceb65c5423c2bafa9) - `glob@7.1.4` ([@isaacs](https://github.com/isaacs)) -* [`bddd60e30`](https://github.com/npm/cli/commit/bddd60e302283a4a70d35f8f742e42bd13f4dabf) - `inherits@2.0.4` ([@isaacs](https://github.com/isaacs)) -* [`4acf03fd1`](https://github.com/npm/cli/commit/4acf03fd140ed3ddb2dcf3fdc9756bc3f5a8bcbb) - `libnpmsearch@2.0.1` ([@isaacs](https://github.com/isaacs)) -* [`c2bd17291`](https://github.com/npm/cli/commit/c2bd17291a86bea7ced2fbd07d66d013bd7a7560) - `marked@0.6.3` ([@isaacs](https://github.com/isaacs)) -* [`7f0221bb1`](https://github.com/npm/cli/commit/7f0221bb1bb41ffc933c785940e227feae38c80c) - `marked-man@0.6.0` ([@isaacs](https://github.com/isaacs)) -* [`f458fe7dd`](https://github.com/npm/cli/commit/f458fe7dd3bebddf603aaae183a424ea8aaa018f) - `npm-lifecycle@2.1.1` ([@isaacs](https://github.com/isaacs)) -* [`009752978`](https://github.com/npm/cli/commit/0097529780269c28444f1efa0d7c131d47a933eb) - `node-gyp@4.0.0` ([@isaacs](https://github.com/isaacs)) -* [`0fa2bb438`](https://github.com/npm/cli/commit/0fa2bb4386379d6e9d8c95db08662ec0529964f9) - `query-string@6.8.1` ([@isaacs](https://github.com/isaacs)) -* [`b86450929`](https://github.com/npm/cli/commit/b86450929796950a1fe4b1f9b02b1634c812f3bb) - `tar-stream@2.1.0` ([@isaacs](https://github.com/isaacs)) -* [`25db00fe9`](https://github.com/npm/cli/commit/25db00fe953453198adb9e1bd71d1bc2a9f04aaa) - `worker-farm@1.7.0` ([@isaacs](https://github.com/isaacs)) -* [`8dfbe8610`](https://github.com/npm/cli/commit/8dfbe861085dfa8fa56bb504b4a00fba04c34f9d) - `readable-stream@3.4.0` ([@isaacs](https://github.com/isaacs)) -* [`f6164d5dd`](https://github.com/npm/cli/commit/f6164d5ddd072eabdf2237f1694a31efd746eb1d) - [isaacs/chownr#21](https://github.com/isaacs/chownr/pull/21) - [isaacs/chownr#20](https://github.com/isaacs/chownr/issues/20) - [npm.community#7901](https://npm.community/t/7901/) - [npm.community#8203](https://npm.community/t/8203) `chownr@1.1.2` This - fixes an EISDIR error from cacache on Darwin in Node versions prior to - 10.6. ([@isaacs](https://github.com/isaacs)) - -## v6.10.0 (2019-07-03): - -### FEATURES - -* [`87fef4e35`](https://github.com/npm/cli/commit/87fef4e35) - [#176](https://github.com/npm/cli/pull/176) fix: Always return JSON for - outdated --json ([@sreeramjayan](https://github.com/sreeramjayan)) -* [`f101d44fc`](https://github.com/npm/cli/commit/f101d44fc) - [#203](https://github.com/npm/cli/pull/203) fix(unpublish): add space - after hyphen ([@ffflorian](https://github.com/ffflorian)) -* [`a4475de4c`](https://github.com/npm/cli/commit/a4475de4c) - [#202](https://github.com/npm/cli/pull/202) enable production flag for - npm audit ([@CalebCourier](https://github.com/CalebCourier)) -* [`d192904d0`](https://github.com/npm/cli/commit/d192904d0) - [#178](https://github.com/npm/cli/pull/178) fix: Return a value for - `view` when in silent mode - ([@stayradiated](https://github.com/stayradiated)) -* [`39d473adf`](https://github.com/npm/cli/commit/39d473adf) - [#185](https://github.com/npm/cli/pull/185) Allow git to follow global - tagsign config ([@junderw](https://github.com/junderw)) - -### BUGFIXES - -* [`d9238af0b`](https://github.com/npm/cli/commit/d9238af0b) - [#201](https://github.com/npm/cli/pull/163) - [npm/npm#17858](https://github.com/npm/npm/issues/17858) - [npm/npm#18042](https://github.com/npm/npm/issues/18042) - [npm.community#644](https://npm.community/t/644) do not crash when - removing nameless packages - ([@SteveVanOpstal](https://github.com/SteveVanOpstal) and - [@isaacs](https://github.com/isaacs)) -* [`4bec4f111`](https://github.com/npm/cli/commit/4bec4f111) - [#200](https://github.com/npm/cli/pull/200) Check for `node` (as well as - `node.exe`) in npm's local dir on Windows - ([@rgoulais](https://github.com/rgoulais)) -* [`ce93dab2d`](https://github.com/npm/cli/commit/ce93dab2db423ef23b3e08a0612dafbeb2d25789) - [#180](https://github.com/npm/cli/pull/180) - [npm.community#6187](https://npm.community/t/6187) Fix handling of - `remote` deps in `npm outdated` ([@larsgw](https://github.com/larsgw)) - -### TESTING - -* [`a823f3084`](https://github.com/npm/cli/commit/a823f3084) travis: Update - to include new v12 LTS ([@isaacs](https://github.com/isaacs)) -* [`33e2d1dac`](https://github.com/npm/cli/commit/33e2d1dac) fix flaky - debug-logs test ([@isaacs](https://github.com/isaacs)) -* [`e9411c6cd`](https://github.com/npm/cli/commit/e9411c6cd) Don't time out - waiting for gpg user input ([@isaacs](https://github.com/isaacs)) -* [`d2d301704`](https://github.com/npm/cli/commit/d2d301704) - [#195](https://github.com/npm/cli/pull/195) Add the arm64 check for - legacy-platform-all.js test case. - ([@ossdev07](https://github.com/ossdev07)) -* [`a4dc34243`](https://github.com/npm/cli/commit/a4dc34243) parallel tests - ([@isaacs](https://github.com/isaacs)) - -### DOCUMENTATION - -* [`f5857e263`](https://github.com/npm/cli/commit/f5857e263) - [#192](https://github.com/npm/cli/pull/192) Clarify usage of - bundledDependencies - ([@john-osullivan](https://github.com/john-osullivan)) -* [`747fdaf66`](https://github.com/npm/cli/commit/747fdaf66) - [#159](https://github.com/npm/cli/pull/159) doc: add --audit-level param - ([@ngraef](https://github.com/ngraef)) - -### DEPENDENCIES - -* [`e36b3c320`](https://github.com/npm/cli/commit/e36b3c320) - graceful-fs@4.2.0 ([@isaacs](https://github.com/isaacs)) -* [`6bb935c09`](https://github.com/npm/cli/commit/6bb935c09) - read-package-tree@5.3.1 ([@isaacs](https://github.com/isaacs)) - * [`e9cd536`](https://github.com/npm/read-package-tree/commit/e9cd536) - Use custom caching `realpath` implementation, dramatically reducing - `lstat` calls when reading the package tree - ([@isaacs](https://github.com/isaacs)) -* [`39538b460`](https://github.com/npm/cli/commit/39538b460) - write-file-atomic@2.4.3 ([@isaacs](https://github.com/isaacs)) - * [`f8b1552`](https://github.com/npm/write-file-atomic/commit/f8b1552) - [#38](https://github.com/npm/write-file-atomic/pull/38) Ignore errors - raised by `fs.closeSync` ([@lukeapage](https://github.com/lukeapage)) -* [`042193069`](https://github.com/npm/cli/commit/042193069) pacote@9.5.1 - ([@isaacs](https://github.com/isaacs)) - * [`8bbd051`](https://github.com/npm/pacote/commit/8bbd051) - [#172](https://github.com/zkat/pacote/pull/172) limit git retry - times, avoid unlimited retries ([小秦](https://github.com/xqin)) - * [`92f5e4c`](https://github.com/npm/pacote/commit/92f5e4c) - [#170](https://github.com/zkat/pacote/pull/170) fix(errors): Fix - "TypeError: err.code.match is not a function" error - ([@jviotti](https://github.com/jviotti)) -* [`8bd8e909f`](https://github.com/npm/cli/commit/8bd8e909f) cacache@11.3.3 - ([@isaacs](https://github.com/isaacs)) - * [`47de8f5`](https://github.com/npm/cacache/commit/47de8f5) - [#146](https://github.com/zkat/cacache/pull/146) - [npm.community#2395](https://npm.community/t/2395) fix(config): Add - ssri config 'error' option ([@larsgw](https://github.com/larsgw)) - * [`5156561`](https://github.com/npm/cacache/commit/5156561) - fix(write): avoid a `cb never called` situation - ([@zkat](https://github.com/zkat)) - * [`90f40f0`](https://github.com/npm/cacache/commit/90f40f0) - [#166](https://github.com/zkat/cacache/pull/166) - [#165](https://github.com/zkat/cacache/issues/165) docs: Fix docs for - `path` property in get.info - ([@hdgarrood](https://github.com/hdgarrood)) -* [`bf61c45c6`](https://github.com/npm/cli/commit/bf61c45c6) bluebird@3.5.5 - ([@isaacs](https://github.com/isaacs)) -* [`f75d46a9d`](https://github.com/npm/cli/commit/f75d46a9d) tar@4.4.10 - ([@isaacs](https://github.com/isaacs)) - * [`c80341a`](https://github.com/npm/node-tar/commit/c80341a) - [#215](https://github.com/npm/node-tar/pull/215) Fix - encoding/decoding of base-256 numbers - ([@justfalter](https://github.com/justfalter)) - * [`77522f0`](https://github.com/npm/node-tar/commit/77522f0) - [#204](https://github.com/npm/node-tar/issues/204) - [#214](https://github.com/npm/node-tar/issues/214) Use `stat` instead - of `lstat` when checking CWD ([@stkb](https://github.com/stkb)) -* [`ec6236210`](https://github.com/npm/cli/commit/ec6236210) - npm-packlist@1.4.4 ([@isaacs](https://github.com/isaacs)) - * [`63d1e3e`](https://github.com/npm/npm-packlist/commit/63d1e3e) - [#30](https://github.com/npm/npm-packlist/issues/30) Sort package - tarball entries by file type for compression benefits - ([@isaacs](https://github.com/isaacs)) - * [`7fcd045`](https://github.com/npm/npm-packlist/commit/7fcd045) - Ignore `.DS_Store` files as well as folders - ([@isaacs](https://github.com/isaacs)) - * [`68b7c96`](https://github.com/npm/npm-packlist/commit/68b7c96) Never - include .git folders in package root. (Note: this prevents the issue - that broke the v6.9.1 release.) - ([@isaacs](https://github.com/isaacs)) -* [`57bef61bc`](https://github.com/npm/cli/commit/57bef61bc) update fstream - in node-gyp ([@isaacs](https://github.com/isaacs)) - * Addresses [security advisory - #886](https://www.npmjs.com/advisories/886) -* [`acbbf7eee`](https://github.com/npm/cli/commit/acbbf7eee) - [#183](https://github.com/npm/cli/pull/183) licensee@7.0.2 - ([@kemitchell](https://github.com/kemitchell)) -* [`011ae67f0`](https://github.com/npm/cli/commit/011ae67f0) - readable-stream@3.3.0 ([@isaacs](https://github.com/isaacs)) -* [`f5e884909`](https://github.com/npm/cli/commit/f5e884909) - npm-registry-mock@1.2.1 ([@isaacs](https://github.com/isaacs)) -* [`b57d07e35`](https://github.com/npm/cli/commit/b57d07e35) - npm-registry-couchapp@2.7.2 ([@isaacs](https://github.com/isaacs)) - -## v6.9.2 (2019-06-27): - -This release is identical to v6.9.1, but we had to publish a new version -due to [a .git directory in the release](https://npm.community/t/8454). - -## v6.9.1 (2019-06-26): - -### BUGFIXES - -* [`6b1a9da0e`](https://github.com/npm/cli/commit/6b1a9da0e0f5c295cdaf4dea4b73bd221d778611) - [#165](https://github.com/npm/cli/pull/165) - Update `knownBroken` version. - ([@ljharb](https://github.com/ljharb)) -* [`d07547154`](https://github.com/npm/cli/commit/d07547154eb8a88aa4fde8a37e128e1e3272adc1) - [npm.community#5929](https://npm.community/t/npm-outdated-throw-an-error-cannot-read-property-length-of-undefined/5929) - Fix `outdated` rendering for global dependencies. - ([@zkat](https://github.com/zkat)) -* [`e4a1f1745`](https://github.com/npm/cli/commit/e4a1f174514a57580fd5e0fa33eee0f42bba77fc) - [npm.community#6259](https://npm.community/t/npm-token-create-doesnt-work-in-6-6-0-6-9-0/6259) - Fix OTP for token create and remove. - ([@zkat](https://github.com/zkat)) - -### DEPENDENCIES - -* [`a163a9c35`](https://github.com/npm/cli/commit/a163a9c35f6f341de343562368056258bba5d7dc) - `sha@3.0.0` - ([@aeschright](https://github.com/aeschright)) -* [`47b08b3b9`](https://github.com/npm/cli/commit/47b08b3b9860438b416efb438e975a628ec2eed5) - `query-string@6.4.0` - ([@aeschright](https://github.com/aeschright)) -* [`d6a956cff`](https://github.com/npm/cli/commit/d6a956cff6357e6de431848e578c391768685a64) - `readable-stream@3.2.0` - ([@aeschright](https://github.com/aeschright)) -* [`10b8bed2b`](https://github.com/npm/cli/commit/10b8bed2bb0afac5451164e87f25924cc1ac6f2e) - `tacks@1.3.0` - ([@aeschright](https://github.com/aeschright)) -* [`e7483704d`](https://github.com/npm/cli/commit/e7483704dda1acffc8c6b8c165c14c8a7512f3c8) - `tap@12.6.0` - ([@aeschright](https://github.com/aeschright)) -* [`3242fe698`](https://github.com/npm/cli/commit/3242fe698ead46a9cda94e1a4d489cd84a85d7e3) - `tar-stream@2.0.1` - ([@aeschright](https://github.com/aeschright)) - -## v6.9.0 (2019-02-20): - -### FEATURES - -* [`2ba3a0f67`](https://github.com/npm/cli/commit/2ba3a0f6721f6d5a16775aebce6012965634fc7c) - [#90](https://github.com/npm/cli/pull/90) - Time traveling installs using the `--before` flag. - ([@zkat](https://github.com/zkat)) -* [`b7b54f2d1`](https://github.com/npm/cli/commit/b7b54f2d18e2d8d65ec67c850b21ae9f01c60e7e) - [#3](https://github.com/npm/cli/pull/3) - Add support for package aliases. This allows packages to be installed under a - different directory than the package name listed in `package.json`, and adds a - new dependency type to allow this to be done for registry dependencies. - ([@zkat](https://github.com/zkat)) -* [`684bccf06`](https://github.com/npm/cli/commit/684bccf061dfc97bb759121bc0ad635e01c65868) - [#146](https://github.com/npm/cli/pull/146) - Always save `package-lock.json` when using `--package-lock-only`. - ([@aeschright](https://github.com/aeschright)) -* [`b8b8afd40`](https://github.com/npm/cli/commit/b8b8afd4048b4ba1181e00ba2ac49ced43936ce0) - [#139](https://github.com/npm/cli/pull/139) - Make empty-string run-scripts run successfully as a no-op. - ([@vlasy](https://github.com/vlasy)) -* [`8047b19b1`](https://github.com/npm/cli/commit/8047b19b1b994fd4b4e7b5c91d7cc4e0384bd5e4) - [npm.community#3784](https://npm.community/t/3784) - Match git semver ranges when flattening the tree. - ([@larsgw](https://github.com/larsgw)) -* [`e135c2bb3`](https://github.com/npm/cli/commit/e135c2bb360dcf00ecee34a95985afec21ba3655) - [npm.community#1725](https://npm.community/t/1725?u=larsgw) - Re-enable updating local packages. - ([@larsgw](https://github.com/larsgw)) - -### BUGFIXES - -* [`cf09fbaed`](https://github.com/npm/cli/commit/cf09fbaed489d908e9b551382cc5f61bdabe99a9) - [#153](https://github.com/npm/cli/pull/153) - Set modified to undefined in `npm view` when `time` is not available. This - fixes a bug where `npm view` would crash on certain third-party registries. - ([@simonua](https://github.com/simonua)) -* [`774fc26ee`](https://github.com/npm/cli/commit/774fc26eeb01345c11bd8c97e2c4f328d419d9b5) - [#154](https://github.com/npm/cli/pull/154) - Print out tar version in `install.sh` only when the flag is supported not all - the tar implementations support --version flag. This allows the install script - to work in OpenBSD, for example. - ([@agudulin](https://github.com/agudulin)) -* [`863baff11`](https://github.com/npm/cli/commit/863baff11d8c870f1a0d9619bb5133c67d71e407) - [#158](https://github.com/npm/cli/pull/158) - Fix typo in error message for `npm stars`. - ([@phihag](https://github.com/phihag)) -* [`a805a95ad`](https://github.com/npm/cli/commit/a805a95ad8832ef5008671f4bd4c11b83e32e0f2) - [npm.community#4227](https://npm.community/t/4227) - Strip version info from pkg on E404. This improves the error messaging format. - ([@larsgw](https://github.com/larsgw)) - -### DOCS - -* [`5d7633833`](https://github.com/npm/cli/commit/5d76338338621fd0b3d4f7914a51726d27569ee1) - [#160](https://github.com/npm/cli/pull/160) - Add `npm add` as alias to npm install in docs. - ([@ahasall](https://github.com/ahasall)) -* [`489c2211c`](https://github.com/npm/cli/commit/489c2211c96a01d65df50fd57346c785bcc3efe6) - [#162](https://github.com/npm/cli/pull/162) - Fix link to RFC #10 in the changelog. - ([@mansona](https://github.com/mansona)) -* [`433020ead`](https://github.com/npm/cli/commit/433020ead5251b562bc3b0f5f55341a5b8cc9023) - [#135](https://github.com/npm/cli/pull/135) - Describe exit codes in npm-audit docs. - ([@emilis-tm](https://github.com/emilis-tm)) - -### DEPENDENCIES - -* [`ee6b6746b`](https://github.com/npm/cli/commit/ee6b6746b04f145dfe489af2d26667ac32ba0cef) - [zkat/make-fetch-happen#29](https://github.com/zkat/make-fetch-happen/issues/29) - `agent-base@4.2.1` - ([@TooTallNate](https://github.com/TooTallNate)) -* [`2ce23baf5`](https://github.com/npm/cli/commit/2ce23baf53b1ce7d11b8efb80c598ddaf9cef9e7) - `lock-verify@2.1.0`: - Adds support for package aliases - ([@zkat](https://github.com/zkat)) -* [`baaedbc6e`](https://github.com/npm/cli/commit/baaedbc6e2fc370d73b35e7721794719115507cc) - `pacote@9.5.0`: - Adds opts.before support - ([@zkat](https://github.com/zkat)) -* [`57e771a03`](https://github.com/npm/cli/commit/57e771a032165d1e31e71d0ff7530442139c21a6) - [#164](https://github.com/npm/cli/pull/164) - `licensee@6.1.0` - ([@kemitchell](https://github.com/kemitchell)) -* [`2b78288d4`](https://github.com/npm/cli/commit/2b78288d4accd10c1b7cc6c36bc28045f5634d91) - add core to default inclusion tests in pack - ([@Kat Marchán](https://github.com/Kat Marchán)) -* [`9b8b6513f`](https://github.com/npm/cli/commit/9b8b6513fbce92764b32a067322984985ff683fe) - [npm.community#5382](https://npm.community/t/npm-pack-leaving-out-files-6-8-0-only/5382) - `npm-packlist@1.4.1`: Fixes bug where `core/` directories were being suddenly excluded. - ([@zkat](https://github.com/zkat)) - -## v6.8.0 (2019-02-07): - -This release includes an implementation of [RFC #10](https://github.com/npm/rfcs/blob/latest/implemented/0010-monorepo-subdirectory-declaration.md), documenting an optional field that can be used to specify -the directory path for a package within a monorepo. - -### NEW FEATURES - -* [`3663cdef2`](https://github.com/npm/cli/commit/3663cdef205fa9ba2c2830e5ef7ceeb31c30298c) - [#140](https://github.com/npm/cli/pull/140) - Update package.json docs to include repository.directory details. - ([@greysteil](https://github.com/greysteil)) - -### BUGFIXES - -* [`550bf703a`](https://github.com/npm/cli/commit/550bf703ae3e31ba6a300658ae95b6937f67b68f) - Add @types to ignore list to fix git clean -fd. - ([@zkat](https://github.com/zkat)) -* [`cdb059293`](https://github.com/npm/cli/commit/cdb0592939d6256c80f7ec5a2b6251131a512a2a) - [#144](https://github.com/npm/cli/pull/144) - Fix common.npm callback arguments. - ([@larsgw](https://github.com/larsgw)) -* [`25573e9b9`](https://github.com/npm/cli/commit/25573e9b9d5d26261c68d453f06db5b3b1cd6789) - [npm.community#4770](https://npm.community/t/https://npm.community/t/4770) - Show installed but unmet peer deps. - ([@larsgw](https://github.com/larsgw)) -* [`ce2c4bd1a`](https://github.com/npm/cli/commit/ce2c4bd1a2ce7ac1727a4ca9a350b743a2e27b2a) - [#149](https://github.com/npm/cli/pull/149) - Use figgy-config to make sure extra opts are there. - ([@zkat](https://github.com/zkat)) -* [`3c22d1a35`](https://github.com/npm/cli/commit/3c22d1a35878f73c0af8ea5968b962a85a1a9b84) - [npm.community#5101](https://npm.community/t/npm-6-6-0-breaks-access-to-ls-collaborators/5101) - Fix `ls-collaborators` access error for non-scoped case. - ([@zkat](https://github.com/zkat)) -* [`d5137091d`](https://github.com/npm/cli/commit/d5137091dd695a2980f7ade85fdc56b2421ff677) - [npm.community#754](https://npm.community/t/npm-install-for-package-with-local-dependency-fails/754) - Fix issue with sub-folder local references. - ([@iarna](https://github.com/iarna)) - ([@jhecking](https://github.com/jhecking)) - -### DEPENDENCY BUMPS - -* [`d72141080`](https://github.com/npm/cli/commit/d72141080ec8fcf35bcc5650245efbe649de053e) - `npm-registry-couchapp@2.7.1` - ([@zkat](https://github.com/zkat)) -* [`671cad1b1`](https://github.com/npm/cli/commit/671cad1b18239d540da246d6f78de45d9f784396) - `npm-registry-fetch@3.9.0`: - Make sure publishing with legacy username:password `_auth` works again. - ([@zkat](https://github.com/zkat)) -* [`95ca1aef4`](https://github.com/npm/cli/commit/95ca1aef4077c8e68d9f4dce37f6ba49b591c4ca) - `pacote@9.4.1` - ([@aeschright](https://github.com/aeschright)) -* [`322fef403`](https://github.com/npm/cli/commit/322fef40376e71cd100159dc914e7ca89faae327) - `normalize-package-data@2.5.0` - ([@aeschright](https://github.com/aeschright)) -* [`32d34c0da`](https://github.com/npm/cli/commit/32d34c0da4f393a74697297667eb9226155ecc6b) - `npm-packlist@1.3.0` - ([@aeschright](https://github.com/aeschright)) -* [`338571cf0`](https://github.com/npm/cli/commit/338571cf0bd3a1e2ea800464d57581932ff0fb11) - `read-package-tree@5.2.2` - ([@zkat](https://github.com/zkat)) - -### MISC - -* [`89b23a5f7`](https://github.com/npm/cli/commit/89b23a5f7b0ccdcdda1d7d4d3eafb6903156d186) - [#120](https://github.com/npm/cli/pull/120) - Use `const` in lib/fetch-package-metadata.md. - ([@watilde](https://github.com/watilde)) -* [`4970d553c`](https://github.com/npm/cli/commit/4970d553c0ea66128931d118469fd31c87cc7986) - [#126](https://github.com/npm/cli/pull/126) - Replace ronn with marked-man in `.npmignore`. - ([@watilde](https://github.com/watilde)) -* [`d9b6090dc`](https://github.com/npm/cli/commit/d9b6090dc26cd0fded18b4f80248cff3e51bb185) - [#138](https://github.com/npm/cli/pull/138) - Reduce work to test if executable ends with a 'g'. - ([@elidoran](https://github.com/elidoran)) - ([@larsgw](https://github.com/larsgw)) - -## v6.7.0 (2019-01-23): - -Hey y'all! This is a quick hotfix release that includes some important fixes to -`npm@6.6.0` related to the large rewrite/refactor. We're tagging it as a feature -release because the changes involve some minor new features, and semver is -semver, but there's nothing major here. - -### NEW FEATURES - -* [`50463f58b`](https://github.com/npm/cli/commit/50463f58b4b70180a85d6d8c10fcf50d8970ef5e) - Improve usage errors to `npm org` commands and add optional filtering to `npm - org ls` subcommand. - ([@zkat](https://github.com/zkat)) - -### BUGFIXES - -* [`4027070b0`](https://github.com/npm/cli/commit/4027070b03be3bdae2515f2291de89b91f901df9) - Fix default usage printout for `npm org` so you actually see how it's supposed - to be used. - ([@zkat](https://github.com/zkat)) -* [`cfea6ea5b`](https://github.com/npm/cli/commit/cfea6ea5b67ec5e4ec57e3a9cb8c82d018cb5476) - fix default usage message for npm hook - ([@zkat](https://github.com/zkat)) - -### DOCS - -* [`e959e1421`](https://github.com/npm/cli/commit/e959e14217d751ddb295565fd75cc81de1ee0d5b) - Add manpage for `npm org` command. - ([@zkat](https://github.com/zkat)) - -### DEPENDENCY BUMPS - -* [`8543fc357`](https://github.com/npm/cli/commit/8543fc3576f64e91f7946d4c56a5ffb045b55156) - `pacote@9.4.0`: Fall back to "fullfat" packuments on ETARGET errors. This will - make it so that, when a package is published but the corgi follower hasn't - caught up, users can still install a freshly-published package. - ([@zkat](https://github.com/zkat)) -* [`75475043b`](https://github.com/npm/cli/commit/75475043b03a254b2e7db2c04c3f0baea31d8dc5) - [npm.community#4752](https://npm.community/t/npm-6-6-0-broke-authentication-with-npm-registry-couchapp/4752) - `libnpmpublish@1.1.1`: Fixes auth error for username/password legacy authentication. - ([@sreeramjayan](https://github.com/sreeramjayan)) -* [`0af8c00ac`](https://github.com/npm/cli/commit/0af8c00acb01849362ffca25b567cc62447c7175) - [npm.community#4746](https://npm.community/t/npm-6-6-0-release-breaking-docker-npm-ci-commands/4746) - `libcipm@3.0.3`: Fixes issue with "cannot run in wd" errors for run-scripts. - ([@zkat](https://github.com/zkat)) -* [`5a7962e46`](https://github.com/npm/cli/commit/5a7962e46f582c6bd91784b0ddc941ed45e9f802) - `write-file-atomic@2.4.2`: - Fixes issues with leaking `signal-exit` instances and file descriptors. - ([@iarna](https://github.com/iarna)) - -## v6.6.0 (2019-01-17): - -### REFACTORING OUT npm-REGISTRY-CLIENT - -Today is an auspicious day! This release marks the end of a massive internal -refactor to npm that means we finally got rid of the legacy -[`npm-registry-client`](https://npm.im/npm-registry-client) in favor of the -shiny, new, `window.fetch`-like -[`npm-registry-fetch`](https://npm.im/npm-registry-fetch). - -Now, the installer had already done most of this work with the release of -`npm@5`, but it turns out _every other command_ still used the legacy client. -This release updates all of those commands to use the new client, and while -we're at it, adds a few extra goodies: - -* All OTP-requiring commands will now **prompt**. `--otp` is no longer required for `dist-tag`, `access`, et al. -* We're starting to integrate a new config system which will eventually get extracted into a standalone package. -* We now use [`libnpm`](https://npm.im/libnpm) for the API functionality of a lot of our commands! That means you can install a library if you want to write your own tooling around them. -* There's now an `npm org` command for managing users in your org. -* [`pacote`](https://npm.im/pacote) now consumes npm-style configurations, instead of its own naming for various config vars. This will make it easier to load npm configs using `libnpm.config` and hand them directly to `pacote`. - -There's too many commits to list all of them here, so check out the PR if you're -curious about details: - -* [`c5af34c05`](https://github.com/npm/cli/commit/c5af34c05fd569aecd11f18d6d0ddeac3970b253) - [npm-registry-client@REMOVED](https://www.youtube.com/watch\?v\=kPIdRJlzERo) - ([@zkat](https://github.com/zkat)) -* [`4cca9cb90`](https://github.com/npm/cli/commit/4cca9cb9042c0eeb743377e8f1ae1c07733df43f) - [`ad67461dc`](https://github.com/npm/cli/commit/ad67461dc3a73d5ae6569fdbee44c67e1daf86e7) - [`77625f9e2`](https://github.com/npm/cli/commit/77625f9e20d4285b7726b3bf3ebc10cb21c638f0) - [`6e922aefb`](https://github.com/npm/cli/commit/6e922aefbb4634bbd77ed3b143e0765d63afc7f9) - [`584613ea8`](https://github.com/npm/cli/commit/584613ea8ff94b927db4957e5647504b30ca2b1f) - [`64de4ebf0`](https://github.com/npm/cli/commit/64de4ebf019b217179039124c6621e74651e4d27) - [`6cd87d1a9`](https://github.com/npm/cli/commit/6cd87d1a9bb90e795f9891ea4db384435f4a8930) - [`2786834c0`](https://github.com/npm/cli/commit/2786834c0257b8bb1bbb115f1ce7060abaab2e17) - [`514558e09`](https://github.com/npm/cli/commit/514558e094460fd0284a759c13965b685133b3fe) - [`dec07ebe3`](https://github.com/npm/cli/commit/dec07ebe3312245f6421c6e523660be4973ae8c2) - [`084741913`](https://github.com/npm/cli/commit/084741913c4fdb396e589abf3440b4be3aa0b67e) - [`45aff0e02`](https://github.com/npm/cli/commit/45aff0e02251785a85e56eafacf9efaeac6f92ae) - [`846ddcc44`](https://github.com/npm/cli/commit/846ddcc44538f2d9a51ac79405010dfe97fdcdeb) - [`8971ba1b9`](https://github.com/npm/cli/commit/8971ba1b953d4f05ff5094f1822b91526282edd8) - [`99156e081`](https://github.com/npm/cli/commit/99156e081a07516d6c970685bc3d858f89dc4f9c) - [`ab2155306`](https://github.com/npm/cli/commit/ab215530674d7f6123c9572d0ad4ca9e9b5fb184) - [`b37a66542`](https://github.com/npm/cli/commit/b37a66542ca2879069b2acd338b1904de71b7f40) - [`d2af0777a`](https://github.com/npm/cli/commit/d2af0777ac179ff5009dbbf0354a4a84f151b60f) - [`e0b4c6880`](https://github.com/npm/cli/commit/e0b4c6880504fa2e8491c2fbd098efcb2e496849) - [`ff72350b4`](https://github.com/npm/cli/commit/ff72350b4c56d65e4a92671d86a33080bf3c2ea5) - [`6ed943303`](https://github.com/npm/cli/commit/6ed943303ce7a267ddb26aa25caa035f832895dd) - [`90a069e7d`](https://github.com/npm/cli/commit/90a069e7d4646682211f4cabe289c306ee1d5397) - [`b24ed5fdc`](https://github.com/npm/cli/commit/b24ed5fdc3a4395628465ae5273bad54eea274c8) - [`ec9fcc14f`](https://github.com/npm/cli/commit/ec9fcc14f4e0e2f3967e2fd6ad8b8433076393cb) - [`8a56fa39e`](https://github.com/npm/cli/commit/8a56fa39e61136da45565447fe201a57f04ad4cd) - [`41d19e18f`](https://github.com/npm/cli/commit/41d19e18f769c6f0acfdffbdb01d12bf332908ce) - [`125ff9551`](https://github.com/npm/cli/commit/125ff9551595dda9dab2edaef10f4c73ae8e1433) - [`1c3b226ff`](https://github.com/npm/cli/commit/1c3b226ff37159c426e855e83c8f6c361603901d) - [`3c0a7b06b`](https://github.com/npm/cli/commit/3c0a7b06b6473fe068fc8ae8466c07a177975b87) - [`08fcb3f0f`](https://github.com/npm/cli/commit/08fcb3f0f26e025702b35253ed70a527ab69977f) - [`c8135d97a`](https://github.com/npm/cli/commit/c8135d97a424b38363dc4530c45e4583471e9849) - [`ae936f22c`](https://github.com/npm/cli/commit/ae936f22ce80614287f2769e9aaa9a155f03cc15) - [#2](https://github.com/npm/cli/pull/2) - Move rest of commands to `npm-registry-fetch` and use [`figgy-pudding`](https://npm.im/figgy-pudding) for configs. - ([@zkat](https://github.com/zkat)) - -### NEW FEATURES - -* [`02c837e01`](https://github.com/npm/cli/commit/02c837e01a71a26f37cbd5a09be89df8a9ce01da) - [#106](https://github.com/npm/cli/pull/106) - Make `npm dist-tags` the same as `npm dist-tag ls`. - ([@isaacs](https://github.com/isaacs)) -* [`1065a7809`](https://github.com/npm/cli/commit/1065a7809161fd4dc23e96b642019fc842fdacf2) - [#65](https://github.com/npm/cli/pull/65) - Add support for `IBM i`. - ([@dmabupt](https://github.com/dmabupt)) -* [`a22e6f5fc`](https://github.com/npm/cli/commit/a22e6f5fc3e91350d3c64dcc88eabbe0efbca759) - [#131](https://github.com/npm/cli/pull/131) - Update profile to support new npm-profile API. - ([@zkat](https://github.com/zkat)) - -### BUGFIXES - -* [`890a74458`](https://github.com/npm/cli/commit/890a74458dd4a55e2d85f3eba9dbf125affa4206) - [npm.community#3278](https://npm.community/t/3278) - Fix support for passing git binary path config with `--git`. - ([@larsgw](https://github.com/larsgw)) -* [`90e55a143`](https://github.com/npm/cli/commit/90e55a143ed1de8678d65c17bc3c2b103a15ddac) - [npm.community#2713](https://npm.community/t/npx-envinfo-preset-jest-fails-on-windows-with-a-stack-trace/2713) - Check for `npm.config`'s existence in `error-handler.js` to prevent weird - errors when failures happen before config object is loaded. - ([@BeniCheni](https://github.com/BeniCheni)) -* [`134207174`](https://github.com/npm/cli/commit/134207174652e1eb6d7b0f44fd9858a0b6a0cd6c) - [npm.community#2569](https://npm.community/t/2569) - Fix checking for optional dependencies. - ([@larsgw](https://github.com/larsgw)) -* [`7a2f6b05d`](https://github.com/npm/cli/commit/7a2f6b05d27f3bcf47a48230db62e86afa41c9d3) - [npm.community#4172](https://npm.community/t/4172) - Remove tink experiments. - ([@larsgw](https://github.com/larsgw)) -* [`c5b6056b6`](https://github.com/npm/cli/commit/c5b6056b6b35eefb81ae5fb00a5c7681c5318c22) - [#123](https://github.com/npm/cli/pull/123) - Handle git branch references correctly. - ([@johanneswuerbach](https://github.com/johanneswuerbach)) -* [`f58b43ef2`](https://github.com/npm/cli/commit/f58b43ef2c5e3dea2094340a0cf264b2d11a5da4) - [npm.community#3983](https://npm.community/t/npm-audit-error-messaging-update-for-401s/3983) - Report any errors above 400 as potentially not supporting audit. - ([@zkat](https://github.com/zkat)) -* [`a5c9e6f35`](https://github.com/npm/cli/commit/a5c9e6f35a591a6e2d4b6ace5c01bc03f2b75fdc) - [#124](https://github.com/npm/cli/pull/124) - Set default homepage to an empty string. - ([@anchnk](https://github.com/anchnk)) -* [`5d076351d`](https://github.com/npm/cli/commit/5d076351d7ec1d3585942a9289548166a7fbbd4c) - [npm.community#4054](https://npm.community/t/4054) - Fix npm-prefix description. - ([@larsgw](https://github.com/larsgw)) - -### DOCS - -* [`31a7274b7`](https://github.com/npm/cli/commit/31a7274b70de18b24e7bee51daa22cc7cbb6141c) - [#71](https://github.com/npm/cli/pull/71) - Fix typo in npm-token documentation. - ([@GeorgeTaveras1231](https://github.com/GeorgeTaveras1231)) -* [`2401b7592`](https://github.com/npm/cli/commit/2401b7592c6ee114e6db7077ebf8c072b7bfe427) - Correct docs for fake-registry interface. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCIES - -* [`9cefcdc1d`](https://github.com/npm/cli/commit/9cefcdc1d2289b56f9164d14d7e499e115cfeaee) - `npm-registry-fetch@3.8.0` - ([@zkat](https://github.com/zkat)) -* [`1c769c9b3`](https://github.com/npm/cli/commit/1c769c9b3e431d324c1a5b6dd10e1fddb5cb88c7) - `pacote@9.1.0` - ([@zkat](https://github.com/zkat)) -* [`f3bc5539b`](https://github.com/npm/cli/commit/f3bc5539b30446500abcc3873781b2c717f8e22c) - `figgy-pudding@3.5.1` - ([@zkat](https://github.com/zkat)) -* [`bf7199d3c`](https://github.com/npm/cli/commit/bf7199d3cbf50545da1ebd30d28f0a6ed5444a00) - `npm-profile@4.0.1` - ([@zkat](https://github.com/zkat)) -* [`118c50496`](https://github.com/npm/cli/commit/118c50496c01231cab3821ae623be6df89cb0a32) - `semver@5.5.1` - ([@isaacs](https://github.com/isaacs)) -* [`eab4df925`](https://github.com/npm/cli/commit/eab4df9250e9169c694b3f6c287d2932bf5e08fb) - `libcipm@3.0.2` - ([@zkat](https://github.com/zkat)) -* [`b86e51573`](https://github.com/npm/cli/commit/b86e515734faf433dc6c457c36c1de52795aa870) - `libnpm@1.4.0` - ([@zkat](https://github.com/zkat)) -* [`56fffbff2`](https://github.com/npm/cli/commit/56fffbff27fe2fae8bef27d946755789ef0d89bd) - `get-stream@4.1.0` - ([@zkat](https://github.com/zkat)) -* [`df972e948`](https://github.com/npm/cli/commit/df972e94868050b5aa42ac18b527fd929e1de9e4) - npm-profile@REMOVED - ([@zkat](https://github.com/zkat)) -* [`32c73bf0e`](https://github.com/npm/cli/commit/32c73bf0e3f0441d0c7c940292235d4b93aa87e2) - `libnpm@2.0.1` - ([@zkat](https://github.com/zkat)) -* [`569491b80`](https://github.com/npm/cli/commit/569491b8042f939dc13986b6adb2a0a260f95b63) - `licensee@5.0.0` - ([@zkat](https://github.com/zkat)) -* [`a3ba0ccf1`](https://github.com/npm/cli/commit/a3ba0ccf1fa86aec56b1ad49883abf28c1f56b3c) - move rimraf to prod deps - ([@zkat](https://github.com/zkat)) -* [`f63a0d6cf`](https://github.com/npm/cli/commit/f63a0d6cf0b7db3dcc80e72e1383c3df723c8119) - `spdx-license-ids@3.0.3`: - Ref: https://github.com/npm/cli/pull/121 - ([@zkat](https://github.com/zkat)) -* [`f350e714f`](https://github.com/npm/cli/commit/f350e714f66a77f71a7ebe17daeea2ea98179a1a) - `aproba@2.0.0` - ([@aeschright](https://github.com/aeschright)) -* [`a67e4d8b2`](https://github.com/npm/cli/commit/a67e4d8b214e58ede037c3854961acb33fd889da) - `byte-size@5.0.1` - ([@aeschright](https://github.com/aeschright)) -* [`8bea4efa3`](https://github.com/npm/cli/commit/8bea4efa34857c4e547904b3630dd442def241de) - `cacache@11.3.2` - ([@aeschright](https://github.com/aeschright)) -* [`9d4776836`](https://github.com/npm/cli/commit/9d4776836a4eaa4b19701b4e4f00cd64578bf078) - `chownr@1.1.1` - ([@aeschright](https://github.com/aeschright)) -* [`70da139e9`](https://github.com/npm/cli/commit/70da139e97ed1660c216e2d9b3f9cfb986bfd4a4) - `ci-info@2.0.0` - ([@aeschright](https://github.com/aeschright)) -* [`bcdeddcc3`](https://github.com/npm/cli/commit/bcdeddcc3d4dc242f42404223dafe4afdc753b32) - `cli-table3@0.5.1` - ([@aeschright](https://github.com/aeschright)) -* [`63aab82c7`](https://github.com/npm/cli/commit/63aab82c7bfca4f16987cf4156ddebf8d150747c) - `is-cidr@3.0.0` - ([@aeschright](https://github.com/aeschright)) -* [`d522bd90c`](https://github.com/npm/cli/commit/d522bd90c3b0cb08518f249ae5b90bd609fff165) - `JSONStream@1.3.5` - ([@aeschright](https://github.com/aeschright)) -* [`2a59bfc79`](https://github.com/npm/cli/commit/2a59bfc7989bd5575d8cbba912977c6d1ba92567) - `libnpmhook@5.0.2` - ([@aeschright](https://github.com/aeschright)) -* [`66d60e394`](https://github.com/npm/cli/commit/66d60e394e5a96330f90e230505758f19a3643ac) - `marked@0.6.0` - ([@aeschright](https://github.com/aeschright)) -* [`8213def9a`](https://github.com/npm/cli/commit/8213def9aa9b6e702887e4f2ed7654943e1e4154) - `npm-packlist@1.2.0` - ([@aeschright](https://github.com/aeschright)) -* [`e4ffc6a2b`](https://github.com/npm/cli/commit/e4ffc6a2bfb8d0b7047cb6692030484760fc8c91) - `unique-filename@1.1.1` - ([@aeschright](https://github.com/aeschright)) -* [`09a5c2fab`](https://github.com/npm/cli/commit/09a5c2fabe0d1c00ec8c99f328f6d28a3495eb0b) - `semver@5.6.0` - ([@aeschright](https://github.com/aeschright)) -* [`740e79e17`](https://github.com/npm/cli/commit/740e79e17a78247f73349525043c9388ce94459a) - `rimraf@2.6.3` - ([@aeschright](https://github.com/aeschright)) -* [`455476c8d`](https://github.com/npm/cli/commit/455476c8d148ca83a4e030e96e93dcf1c7f0ff5f) - `require-inject@1.4.4` - ([@aeschright](https://github.com/aeschright)) -* [`3f40251c5`](https://github.com/npm/cli/commit/3f40251c5868feaacbcdbcb1360877ce76998f5e) - `npm-pick-manifest@2.2.3` - ([@aeschright](https://github.com/aeschright)) -* [`4ffa8a8e9`](https://github.com/npm/cli/commit/4ffa8a8e9e80e5562898dd76fe5a49f5694f38c8) - `query-string@6.2.0` - ([@aeschright](https://github.com/aeschright)) -* [`a0a0ca9ec`](https://github.com/npm/cli/commit/a0a0ca9ec2a962183d420fa751f4139969760f18) - `pacote@9.3.0` - ([@aeschright](https://github.com/aeschright)) -* [`5777ea8ad`](https://github.com/npm/cli/commit/5777ea8ad2058be3166a6dad2d31d2d393c9f778) - `readable-stream@3.1.1` - ([@aeschright](https://github.com/aeschright)) -* [`887e94386`](https://github.com/npm/cli/commit/887e94386f42cb59a5628e7762b3662d084b23c8) - `lru-cache@4.1.5` - ([@aeschright](https://github.com/aeschright)) -* [`41f15524c`](https://github.com/npm/cli/commit/41f15524c58c59d206c4b1d25ae9e0f22745213b) - Updating semver docs. - ([@aeschright](https://github.com/aeschright)) -* [`fb3bbb72d`](https://github.com/npm/cli/commit/fb3bbb72d448ac37a465b31233b21381917422f3) - `npm-audit-report@1.3.2`: - ([@melkikh](https://github.com/melkikh)) - -### TESTING - -* [`f1edffba9`](https://github.com/npm/cli/commit/f1edffba90ebd96cf88675d2e18ebc48954ba50e) - Modernize maketest script. - ([@iarna](https://github.com/iarna)) -* [`ae263473d`](https://github.com/npm/cli/commit/ae263473d92a896b482830d4019a04b5dbd1e9d7) - maketest: Use promise based example common.npm call. - ([@iarna](https://github.com/iarna)) -* [`d9970da5e`](https://github.com/npm/cli/commit/d9970da5ee97a354eab01cbf16f9101693a15d2d) - maketest: Use newEnv for env production. - ([@iarna](https://github.com/iarna)) - -### MISCELLANEOUS - -* [`c665f35aa`](https://github.com/npm/cli/commit/c665f35aacdb8afdbe35f3dd7ccb62f55ff6b896) - [#119](https://github.com/npm/cli/pull/119) - Replace var with const/let in lib/repo.js. - ([@watilde](https://github.com/watilde)) -* [`46639ba9f`](https://github.com/npm/cli/commit/46639ba9f04ea729502f1af28b02eb67fb6dcb66) - Update package-lock.json for https tarball URLs - ([@aeschright](https://github.com/aeschright)) - -## v6.5.0 (2018-11-28): - -### NEW FEATURES - -* [`fc1a8d185`](https://github.com/npm/cli/commit/fc1a8d185fc678cdf3784d9df9eef9094e0b2dec) - Backronym `npm ci` to `npm clean-install`. - ([@zkat](https://github.com/zkat)) -* [`4be51a9cc`](https://github.com/npm/cli/commit/4be51a9cc65635bb26fa4ce62233f26e0104bc20) - [#81](https://github.com/npm/cli/pull/81) - Adds 'Homepage' to outdated --long output. - ([@jbottigliero](https://github.com/jbottigliero)) - -### BUGFIXES - -* [`89652cb9b`](https://github.com/npm/cli/commit/89652cb9b810f929f5586fc90cc6794d076603fb) - [npm.community#1661](https://npm.community/t/1661) - Fix sign-git-commit options. They were previously totally wrong. - ([@zkat](https://github.com/zkat)) -* [`414f2d1a1`](https://github.com/npm/cli/commit/414f2d1a1bdffc02ed31ebb48a43216f284c21d4) - [npm.community#1742](https://npm.community/t/npm-audit-making-non-rfc-compliant-requests-to-server-resulting-in-400-bad-request-pr-with-fix/1742) - Set lowercase headers for npm audit requests. - ([@maartenba](https://github.com/maartenba)) -* [`a34246baf`](https://github.com/npm/cli/commit/a34246bafe73218dc9e3090df9ee800451db2c7d) - [#75](https://github.com/npm/cli/pull/75) - Fix `npm edit` handling of scoped packages. - ([@larsgw](https://github.com/larsgw)) -* [`d3e8a7c72`](https://github.com/npm/cli/commit/d3e8a7c7240dd25379a5bcad324a367c58733c73) - [npm.community#2303](https://npm.community/t/npm-ci-logs-success-to-stderr/2303) - Make summary output for `npm ci` go to `stdout`, not `stderr`. - ([@alopezsanchez](https://github.com/alopezsanchez)) -* [`71d8fb4a9`](https://github.com/npm/cli/commit/71d8fb4a94d65e1855f6d0c5f2ad2b7c3202e3c4) - [npm.community#1377](https://npm.community/t/unhelpful-error-message-when-publishing-without-logging-in-error-eperm-operation-not-permitted-unlink/1377/3) - Close the file descriptor during publish if exiting upload via an error. This - will prevent strange error messages when the upload fails and make sure - cleanup happens correctly. - ([@macdja38](https://github.com/macdja38)) - -### DOCS UPDATES - -* [`b1a8729c8`](https://github.com/npm/cli/commit/b1a8729c80175243fbbeecd164e9ddd378a09a50) - [#60](https://github.com/npm/cli/pull/60) - Mention --otp flag when prompting for OTP. - ([@bakkot](https://github.com/bakkot)) -* [`bcae4ea81`](https://github.com/npm/cli/commit/bcae4ea8173e489a76cc226bbd30dd9eabe21ec6) - [#64](https://github.com/npm/cli/pull/64) - Clarify that git dependencies use the default branch, not just `master`. - ([@zckrs](https://github.com/zckrs)) -* [`15da82690`](https://github.com/npm/cli/commit/15da8269032bf509ade3252978e934f2a61d4499) - [#72](https://github.com/npm/cli/pull/72) - `bash_completion.d` dir is sometimes found in `/etc` not `/usr/local`. - ([@RobertKielty](https://github.com/RobertKielty)) -* [`8a6ecc793`](https://github.com/npm/cli/commit/8a6ecc7936dae2f51638397ff5a1d35cccda5495) - [#74](https://github.com/npm/cli/pull/74) - Update OTP documentation for `dist-tag add` to clarify `--otp` is needed right - now. - ([@scotttrinh](https://github.com/scotttrinh)) -* [`dcc03ec85`](https://github.com/npm/cli/commit/dcc03ec858bddd7aa2173b5a86b55c1c2385a2a3) - [#82](https://github.com/npm/cli/pull/82) - Note that `prepare` runs when installing git dependencies. - ([@seishun](https://github.com/seishun)) -* [`a91a470b7`](https://github.com/npm/cli/commit/a91a470b71e08ccf6a75d4fb8c9937789fa8d067) - [#83](https://github.com/npm/cli/pull/83) - Specify that --dry-run isn't available in older versions of npm publish. - ([@kjin](https://github.com/kjin)) -* [`1b2fabcce`](https://github.com/npm/cli/commit/1b2fabccede37242233755961434c52536224de5) - [#96](https://github.com/npm/cli/pull/96) - Fix inline code tag issue in docs. - ([@midare](https://github.com/midare)) -* [`6cc70cc19`](https://github.com/npm/cli/commit/6cc70cc1977e58a3e1ea48e660ffc6b46b390e59) - [#68](https://github.com/npm/cli/pull/68) - Add semver link and a note on empty string format to `deprecate` doc. - ([@neverett](https://github.com/neverett)) -* [`61dbbb7c3`](https://github.com/npm/cli/commit/61dbbb7c3474834031bce88c423850047e8131dc) - Fix semver docs after version update. - ([@zkat](https://github.com/zkat)) -* [`4acd45a3d`](https://github.com/npm/cli/commit/4acd45a3d0ce92f9999446226fe7dfb89a90ba2e) - [#78](https://github.com/npm/cli/pull/78) - Correct spelling across various docs. - ([@hugovk](https://github.com/hugovk)) - -### DEPENDENCIES - -* [`4f761283e`](https://github.com/npm/cli/commit/4f761283e8896d0ceb5934779005646463a030e8) - `figgy-pudding@3.5.1` - ([@zkat](https://github.com/zkat)) -* [`3706db0bc`](https://github.com/npm/cli/commit/3706db0bcbc306d167bb902362e7f6962f2fe1a1) - [npm.community#1764](https://npm.community/t/crash-invalid-config-key-requested-error/1764) - `ssri@6.0.1` - ([@zkat](https://github.com/zkat)) -* [`83c2b117d`](https://github.com/npm/cli/commit/83c2b117d0b760d0ea8d667e5e4bdfa6a7a7a8f6) - `bluebird@3.5.2` - ([@petkaantonov](https://github.com/petkaantonov)) -* [`2702f46bd`](https://github.com/npm/cli/commit/2702f46bd7284fb303ca2119d23c52536811d705) - `ci-info@1.5.1` - ([@watson](https://github.com/watson)) -* [`4db6c3898`](https://github.com/npm/cli/commit/4db6c3898b07100e3a324e4aae50c2fab4b93a04) - `config-chain@1.1.1`:2 - ([@dawsbot](https://github.com/dawbot)) -* [`70bee4f69`](https://github.com/npm/cli/commit/70bee4f69bb4ce4e18c48582fe2b48d8b4aba566) - `glob@7.1.3` - ([@isaacs](https://github.com/isaacs)) -* [`e469fd6be`](https://github.com/npm/cli/commit/e469fd6be95333dcaa7cf377ca3620994ca8d0de) - `opener@1.5.1`: - Fix browser opening under Windows Subsystem for Linux (WSL). - ([@thijsputman](https://github.com/thijsputman)) -* [`03840dced`](https://github.com/npm/cli/commit/03840dced865abdca6e6449ea030962e5b19db0c) - `semver@5.5.1` - ([@iarna](https://github.com/iarna)) -* [`161dc0b41`](https://github.com/npm/cli/commit/161dc0b4177e76306a0e3b8660b3b496cc3db83b) - `bluebird@3.5.3` - ([@petkaantonov](https://github.com/petkaantonov)) -* [`bb6f94395`](https://github.com/npm/cli/commit/bb6f94395491576ec42996ff6665df225f6b4377) - `graceful-fs@4.1.1`:5 - ([@isaacs](https://github.com/isaacs)) -* [`43b1f4c91`](https://github.com/npm/cli/commit/43b1f4c91fa1d7b3ebb6aa2d960085e5f3ac7607) - `tar@4.4.8` - ([@isaacs](https://github.com/isaacs)) -* [`ab62afcc4`](https://github.com/npm/cli/commit/ab62afcc472de82c479bf91f560a0bbd6a233c80) - `npm-packlist@1.1.1`:2 - ([@isaacs](https://github.com/isaacs)) -* [`027f06be3`](https://github.com/npm/cli/commit/027f06be35bb09f390e46fcd2b8182539939d1f7) - `ci-info@1.6.0` - ([@watson](https://github.com/watson)) - -### MISCELLANEOUS - -* [`27217dae8`](https://github.com/npm/cli/commit/27217dae8adbc577ee9cb323b7cfe9c6b2493aca) - [#70](https://github.com/npm/cli/pull/70) - Automatically audit dependency licenses for npm itself. - ([@kemitchell](https://github.com/kemitchell)) - -## v6.4.1 (2018-08-22): - -### BUGFIXES - -* [`4bd40f543`](https://github.com/npm/cli/commit/4bd40f543dc89f0721020e7d0bb3497300d74818) - [#42](https://github.com/npm/cli/pull/42) - Prevent blowing up on malformed responses from the `npm audit` endpoint, such - as with third-party registries. - ([@framp](https://github.com/framp)) -* [`0e576f0aa`](https://github.com/npm/cli/commit/0e576f0aa6ea02653d948c10f29102a2d4a31944) - [#46](https://github.com/npm/cli/pull/46) - Fix `NO_PROXY` support by renaming npm-side config to `--noproxy`. The - environment variable should still work. - ([@SneakyFish5](https://github.com/SneakyFish5)) -* [`d8e811d6a`](https://github.com/npm/cli/commit/d8e811d6adf3d87474982cb831c11316ac725605) - [#33](https://github.com/npm/cli/pull/33) - Disable `update-notifier` checks when a CI environment is detected. - ([@Sibiraj-S](https://github.com/Sibiraj-S)) -* [`1bc5b8cea`](https://github.com/npm/cli/commit/1bc5b8ceabc86bfe4777732f25ffef0f3de81bd1) - [#47](https://github.com/npm/cli/pull/47) - Fix issue where `postpack` scripts would break if `pack` was used with - `--dry-run`. - ([@larsgw](https://github.com/larsgw)) - -### DEPENDENCY BUMPS - -* [`4c57316d5`](https://github.com/npm/cli/commit/4c57316d5633e940105fa545b52d8fbfd2eb9f75) - `figgy-pudding@3.4.1` - ([@zkat](https://github.com/zkat)) -* [`85f4d7905`](https://github.com/npm/cli/commit/85f4d79059865d5267f3516b6cdbc746012202c6) - `cacache@11.2.0` - ([@zkat](https://github.com/zkat)) -* [`d20ac242a`](https://github.com/npm/cli/commit/d20ac242aeb44aa3581c65c052802a02d5eb22f3) - `npm-packlist@1.1.11`: - No real changes in npm-packlist, but npm-bundled included a - circular dependency fix, as well as adding a proper LICENSE file. - ([@isaacs](https://github.com/isaacs)) -* [`e8d5f4418`](https://github.com/npm/cli/commit/e8d5f441821553a31fc8cd751670663699d2c8ce) - [npm.community#632](https://npm.community/t/using-npm-ci-does-not-run-prepare-script-for-git-modules/632) - `libcipm@2.0.2`: - Fixes issue where `npm ci` wasn't running the `prepare` lifecycle script when - installing git dependencies - ([@edahlseng](https://github.com/edahlseng)) -* [`a5e6f78e9`](https://github.com/npm/cli/commit/a5e6f78e916873f7d18639ebdb8abd20479615a9) - `JSONStream@1.3.4`: - Fixes memory leak problem when streaming large files (like legacy npm search). - ([@daern91](https://github.com/daern91)) -* [`3b940331d`](https://github.com/npm/cli/commit/3b940331dcccfa67f92366adb7ffd9ecf7673a9a) - [npm.community#1042](https://npm.community/t/3-path-variables-are-assigned-to-child-process-launched-by-npm/1042) - `npm-lifecycle@2.1.0`: - Fixes issue for Windows user where multiple `Path`/`PATH` variables were being - added to the environment and breaking things in all sorts of fun and - interesting ways. - ([@JimiC](https://github.com/JimiC)) -* [`d612d2ce8`](https://github.com/npm/cli/commit/d612d2ce8fab72026f344f125539ecbf3746af9a) - `npm-registry-client@8.6.0` - ([@iarna](https://github.com/iarna)) -* [`1f6ba1cb1`](https://github.com/npm/cli/commit/1f6ba1cb174590c1f5d2b00e2ca238dfa39d507a) - `opener@1.5.0` - ([@domenic](https://github.com/domenic)) -* [`37b8f405f`](https://github.com/npm/cli/commit/37b8f405f35c861b7beeed56f71ad20b0bf87889) - `request@2.88.0` - ([@mikeal](https://github.com/mikeal)) -* [`bb91a2a14`](https://github.com/npm/cli/commit/bb91a2a14562e77769057f1b6d06384be6d6bf7f) - `tacks@1.2.7` - ([@iarna](https://github.com/iarna)) -* [`30bc9900a`](https://github.com/npm/cli/commit/30bc9900ae79c80bf0bdee0ae6372da6f668124c) - `ci-info@1.4.0`: - Adds support for two more CI services - ([@watson](https://github.com/watson)) -* [`1d2fa4ddd`](https://github.com/npm/cli/commit/1d2fa4dddcab8facfee92096cc24b299387f3182) - `marked@0.5.0` - ([@joshbruce](https://github.com/joshbruce)) - -### DOCUMENTATION - -* [`08ecde292`](https://github.com/npm/cli/commit/08ecde2928f8c89a2fdaa800ae845103750b9327) - [#54](https://github.com/npm/cli/pull/54) - Mention registry terms of use in manpage and registry docs and update language - in README for it. - ([@kemitchell](https://github.com/kemitchell)) -* [`de956405d`](https://github.com/npm/cli/commit/de956405d8b72354f98579d00c6dd30ac3b9bddf) - [#41](https://github.com/npm/cli/pull/41) - Add documentation for `--dry-run` in `install` and `pack` docs. - ([@reconbot](https://github.com/reconbot)) -* [`95031b90c`](https://github.com/npm/cli/commit/95031b90ce0b0c4dcd5e4eafc86e3e5bfd59fb3e) - [#48](https://github.com/npm/cli/pull/48) - Update republish time and lightly reorganize republish info. - ([@neverett](https://github.com/neverett)) -* [`767699b68`](https://github.com/npm/cli/commit/767699b6829b8b899d5479445e99b0ffc43ff92d) - [#53](https://github.com/npm/cli/pull/53) - Correct `npm@6.4.0` release date in changelog. - ([@charmander](https://github.com/charmander)) -* [`3fea3166e`](https://github.com/npm/cli/commit/3fea3166eb4f43f574fcfd9ee71a171feea2bc29) - [#55](https://github.com/npm/cli/pull/55) - Align command descriptions in help text. - ([@erik](https://github.com/erik)) - -## v6.4.0 (2018-08-09): - -### NEW FEATURES - -* [`6e9f04b0b`](https://github.com/npm/cli/commit/6e9f04b0baed007169d4e0c341f097cf133debf7) - [npm/cli#8](https://github.com/npm/cli/pull/8) - Search for authentication token defined by environment variables by preventing - the translation layer from env variable to npm option from breaking - `:_authToken`. - ([@mkhl](https://github.com/mkhl)) -* [`84bfd23e7`](https://github.com/npm/cli/commit/84bfd23e7d6434d30595594723a6e1976e84b022) - [npm/cli#35](https://github.com/npm/cli/pull/35) - Stop filtering out non-IPv4 addresses from `local-addrs`, making npm actually - use IPv6 addresses when it must. - ([@valentin2105](https://github.com/valentin2105)) -* [`792c8c709`](https://github.com/npm/cli/commit/792c8c709dc7a445687aa0c8cba5c50bc4ed83fd) - [npm/cli#31](https://github.com/npm/cli/pull/31) - configurable audit level for non-zero exit - `npm audit` currently exits with exit code 1 if any vulnerabilities are found of any level. - Add a flag of `--audit-level` to `npm audit` to allow it to pass if only vulnerabilities below a certain level are found. - Example: `npm audit --audit-level=high` will exit with 0 if only low or moderate level vulns are detected. - ([@lennym](https://github.com/lennym)) - -### BUGFIXES - -* [`d81146181`](https://github.com/npm/cli/commit/d8114618137bb5b9a52a86711bb8dc18bfc8e60c) - [npm/cli#32](https://github.com/npm/cli/pull/32) - Don't check for updates to npm when we are updating npm itself. - ([@olore](https://github.com/olore)) - -### DEPENDENCY UPDATES - -A very special dependency update event! Since the [release of -`node-gyp@3.8.0`](https://github.com/nodejs/node-gyp/pull/1521), an awkward -version conflict that was preventing `request` from begin flattened was -resolved. This means two things: - -1. We've cut down the npm tarball size by another 200kb, to 4.6MB -2. `npm audit` now shows no vulnerabilities for npm itself! - -Thanks, [@rvagg](https://github.com/rvagg)! - -* [`866d776c2`](https://github.com/npm/cli/commit/866d776c27f80a71309389aaab42825b2a0916f6) - `request@2.87.0` - ([@simov](https://github.com/simov)) -* [`f861c2b57`](https://github.com/npm/cli/commit/f861c2b579a9d4feae1653222afcefdd4f0e978f) - `node-gyp@3.8.0` - ([@rvagg](https://github.com/rvagg)) -* [`32e6947c6`](https://github.com/npm/cli/commit/32e6947c60db865257a0ebc2f7e754fedf7a6fc9) - [npm/cli#39](https://github.com/npm/cli/pull/39) - `colors@1.1.2`: - REVERT REVERT, newer versions of this library are broken and print ansi - codes even when disabled. - ([@iarna](https://github.com/iarna)) -* [`beb96b92c`](https://github.com/npm/cli/commit/beb96b92caf061611e3faafc7ca10e77084ec335) - `libcipm@2.0.1` - ([@zkat](https://github.com/zkat)) -* [`348fc91ad`](https://github.com/npm/cli/commit/348fc91ad223ff91cd7bcf233018ea1d979a2af1) - `validate-npm-package-license@3.0.4`: Fixes errors with empty or string-only - license fields. - ([@Gudahtt](https://github.com/Gudahtt)) -* [`e57d34575`](https://github.com/npm/cli/commit/e57d3457547ef464828fc6f82ae4750f3e511550) - `iferr@1.0.2` - ([@shesek](https://github.com/shesek)) -* [`46f1c6ad4`](https://github.com/npm/cli/commit/46f1c6ad4b2fd5b0d7ec879b76b76a70a3a2595c) - `tar@4.4.6` - ([@isaacs](https://github.com/isaacs)) -* [`50df1bf69`](https://github.com/npm/cli/commit/50df1bf691e205b9f13e0fff0d51a68772c40561) - `hosted-git-info@2.7.1` - ([@iarna](https://github.com/iarna)) - ([@Erveon](https://github.com/Erveon)) - ([@huochunpeng](https://github.com/huochunpeng)) - -### DOCUMENTATION - -* [`af98e76ed`](https://github.com/npm/cli/commit/af98e76ed96af780b544962aa575585b3fa17b9a) - [npm/cli#34](https://github.com/npm/cli/pull/34) - Remove `npm publish` from list of commands not affected by `--dry-run`. - ([@joebowbeer](https://github.com/joebowbeer)) -* [`e2b0f0921`](https://github.com/npm/cli/commit/e2b0f092193c08c00f12a6168ad2bd9d6e16f8ce) - [npm/cli#36](https://github.com/npm/cli/pull/36) - Tweak formatting in repository field examples. - ([@noahbenham](https://github.com/noahbenham)) -* [`e2346e770`](https://github.com/npm/cli/commit/e2346e7702acccefe6d711168c2b0e0e272e194a) - [npm/cli#14](https://github.com/npm/cli/pull/14) - Used `process.env` examples to make accessing certain `npm run-scripts` - environment variables more clear. - ([@mwarger](https://github.com/mwarger)) - -## v6.3.0 (2018-08-01): - -This is basically the same as the prerelease, but two dependencies have been -bumped due to bugs that had been around for a while. - -* [`0a22be42e`](https://github.com/npm/cli/commit/0a22be42eb0d40cd0bd87e68c9e28fc9d72c0e19) - `figgy-pudding@3.2.0` - ([@zkat](https://github.com/zkat)) -* [`0096f6997`](https://github.com/npm/cli/commit/0096f69978d2f40b170b28096f269b0b0008a692) - `cacache@11.1.0` - ([@zkat](https://github.com/zkat)) - -## v6.3.0-next.0 (2018-07-25): - -### NEW FEATURES - -* [`ad0dd226f`](https://github.com/npm/cli/commit/ad0dd226fb97a33dcf41787ae7ff282803fb66f2) - [npm/cli#26](https://github.com/npm/cli/pull/26) - `npm version` now supports a `--preid` option to specify the preid for - prereleases. For example, `npm version premajor --preid rc` will tag a version - like `2.0.0-rc.0`. - ([@dwilches](https://github.com/dwilches)) - -### MESSAGING IMPROVEMENTS - -* [`c1dad1e99`](https://github.com/npm/cli/commit/c1dad1e994827f2eab7a13c0f6454f4e4c22ebc2) - [npm/cli#6](https://github.com/npm/cli/pull/6) - Make `npm audit fix` message provide better instructions for vulnerabilities - that require manual review. - ([@bradsk88](https://github.com/bradsk88)) -* [`15c1130fe`](https://github.com/npm/cli/commit/15c1130fe81961706667d845aad7a5a1f70369f3) - Fix missing colon next to tarball url in new `npm view` output. - ([@zkat](https://github.com/zkat)) -* [`21cf0ab68`](https://github.com/npm/cli/commit/21cf0ab68cf528d5244ae664133ef400bdcfbdb6) - [npm/cli#24](https://github.com/npm/cli/pull/24) - Use the default OTP explanation everywhere except when the context is - "OTP-aware" (like when setting double-authentication). This improves the - overall CLI messaging when prompting for an OTP code. - ([@jdeniau](https://github.com/jdeniau)) - -### MISC - -* [`a9ac8712d`](https://github.com/npm/cli/commit/a9ac8712dfafcb31a4e3deca24ddb92ff75e942d) - [npm/cli#21](https://github.com/npm/cli/pull/21) - Use the extracted `stringify-package` package. - ([@dpogue](https://github.com/dpogue)) -* [`9db15408c`](https://github.com/npm/cli/commit/9db15408c60be788667cafc787116555507dc433) - [npm/cli#27](https://github.com/npm/cli/pull/27) - `wrappy` was previously added to dependencies in order to flatten it, but we - no longer do legacy-style for npm itself, so it has been removed from - `package.json`. - ([@rickschubert](https://github.com/rickschubert)) - -### DOCUMENTATION - -* [`3242baf08`](https://github.com/npm/cli/commit/3242baf0880d1cdc0e20b546d3c1da952e474444) - [npm/cli#13](https://github.com/npm/cli/pull/13) - Update more dead links in README.md. - ([@u32i64](https://github.com/u32i64)) -* [`06580877b`](https://github.com/npm/cli/commit/06580877b6023643ec780c19d84fbe120fe5425c) - [npm/cli#19](https://github.com/npm/cli/pull/19) - Update links in docs' `index.html` to refer to new bug/PR URLs. - ([@watilde](https://github.com/watilde)) -* [`ca03013c2`](https://github.com/npm/cli/commit/ca03013c23ff38e12902e9569a61265c2d613738) - [npm/cli#15](https://github.com/npm/cli/pull/15) - Fix some typos in file-specifiers docs. - ([@Mstrodl](https://github.com/Mstrodl)) -* [`4f39f79bc`](https://github.com/npm/cli/commit/4f39f79bcacef11bf2f98d09730bc94d0379789b) - [npm/cli#16](https://github.com/npm/cli/pull/16) - Fix some typos in file-specifiers and package-lock docs. - ([@watilde](https://github.com/watilde)) -* [`35e51f79d`](https://github.com/npm/cli/commit/35e51f79d1a285964aad44f550811aa9f9a72cd8) - [npm/cli#18](https://github.com/npm/cli/pull/18) - Update build status badge url in README. - ([@watilde](https://github.com/watilde)) -* [`a67db5607`](https://github.com/npm/cli/commit/a67db5607ba2052b4ea44f66657f98b758fb4786) - [npm/cli#17](https://github.com/npm/cli/pull/17/) - Replace TROUBLESHOOTING.md with [posts in - npm.community](https://npm.community/c/support/troubleshooting). - ([@watilde](https://github.com/watilde)) -* [`e115f9de6`](https://github.com/npm/cli/commit/e115f9de65bf53711266152fc715a5012f7d3462) - [npm/cli#7](https://github.com/npm/cli/pull/7) - Use https URLs in documentation when appropriate. Happy [Not Secure Day](https://arstechnica.com/gadgets/2018/07/todays-the-day-that-chrome-brands-plain-old-http-as-not-secure/)! - ([@XhmikosR](https://github.com/XhmikosR)) - -## v6.2.0 (2018-07-13): - -In case you missed it, [we -moved!](https://blog.npmjs.org/post/175587538995/announcing-npmcommunity). We -look forward to seeing future PRs landing in -[npm/cli](https://github.com/npm/cli) in the future, and we'll be chatting with -you all in [npm.community](https://npm.community). Go check it out! - -This final release of `npm@6.2.0` includes a couple of features that weren't -quite ready on time but that we'd still like to include. Enjoy! - -### FEATURES - -* [`244b18380`](https://github.com/npm/npm/commit/244b18380ee55950b13c293722771130dbad70de) - [#20554](https://github.com/npm/npm/pull/20554) - Add support for tab-separated output for `npm audit` data with the - `--parseable` flag. - ([@luislobo](https://github.com/luislobo)) -* [`7984206e2`](https://github.com/npm/npm/commit/7984206e2f41b8d8361229cde88d68f0c96ed0b8) - [#12697](https://github.com/npm/npm/pull/12697) - Add new `sign-git-commit` config to control whether the git commit itself gets - signed, or just the tag (which is the default). - ([@tribou](https://github.com/tribou)) - -### FIXES - -* [`4c32413a5`](https://github.com/npm/npm/commit/4c32413a5b42e18a34afb078cf00eed60f08e4ff) - [#19418](https://github.com/npm/npm/pull/19418) - Do not use `SET` to fetch the env in git-bash or Cygwin. - ([@gucong3000](https://github.com/gucong3000)) - -### DEPENDENCY BUMPS - -* [`d9b2712a6`](https://github.com/npm/npm/commit/d9b2712a670e5e78334e83f89a5ed49616f1f3d3) - `request@2.81.0`: Downgraded to allow better deduplication. This does - introduce a bunch of `hoek`-related audit reports, but they don't affect npm - itself so we consider it safe. We'll upgrade `request` again once `node-gyp` - unpins it. - ([@simov](https://github.com/simov)) -* [`2ac48f863`](https://github.com/npm/npm/commit/2ac48f863f90166b2bbf2021ed4cc04343d2503c) - `node-gyp@3.7.0` - ([@MylesBorins](https://github.com/MylesBorins)) -* [`8dc6d7640`](https://github.com/npm/npm/commit/8dc6d76408f83ba35bda77a2ac1bdbde01937349) - `cli-table3@0.5.0`: `cli-table2` is unmaintained and required `lodash`. With - this dependency bump, we've removed `lodash` from our tree, which cut back - tarball size by another 300kb. - ([@Turbo87](https://github.com/Turbo87)) -* [`90c759fee`](https://github.com/npm/npm/commit/90c759fee6055cf61cf6709432a5e6eae6278096) - `npm-audit-report@1.3.1` - ([@zkat](https://github.com/zkat)) -* [`4231a0a1e`](https://github.com/npm/npm/commit/4231a0a1eb2be13931c3b71eba38c0709644302c) - Add `cli-table3` to bundleDeps. - ([@iarna](https://github.com/iarna)) -* [`322d9c2f1`](https://github.com/npm/npm/commit/322d9c2f107fd82a4cbe2f9d7774cea5fbf41b8d) - Make `standard` happy. - ([@iarna](https://github.com/iarna)) - -### DOCS - -* [`5724983ea`](https://github.com/npm/npm/commit/5724983ea8f153fb122f9c0ccab6094a26dfc631) - [#21165](https://github.com/npm/npm/pull/21165) - Fix some markdown formatting in npm-disputes.md. - ([@hchiam](https://github.com/hchiam)) -* [`738178315`](https://github.com/npm/npm/commit/738178315fe48e463028657ea7ae541c3d63d171) - [#20920](https://github.com/npm/npm/pull/20920) - Explicitly state that republishing an unpublished package requires a 72h - waiting period. - ([@gmattie](https://github.com/gmattie)) -* [`f0a372b07`](https://github.com/npm/npm/commit/f0a372b074cc43ee0e1be28dbbcef0d556b3b36c) - Replace references to the old repo or issue tracker. We're at npm/cli now! - ([@zkat](https://github.com/zkat)) - -## v6.2.0-next.1 (2018-07-05): - -This is a quick patch to the release to fix an issue that was preventing users -from installing `npm@next`. - -* [`ecdcbd745`](https://github.com/npm/npm/commit/ecdcbd745ae1edd9bdd102dc3845a7bc76e1c5fb) - [#21129](https://github.com/npm/npm/pull/21129) - Remove postinstall script that depended on source files, thus preventing - `npm@next` from being installable from the registry. - ([@zkat](https://github.com/zkat)) - -## v6.2.0-next.0 (2018-06-28): - -### NEW FEATURES - -* [`ce0793358`](https://github.com/npm/npm/commit/ce07933588ec2da1cc1980f93bdaa485d6028ae2) - [#20750](https://github.com/npm/npm/pull/20750) - You can now disable the update notifier entirely by using - `--no-update-notifier` or setting it in your config with `npm config set - update-notifier false`. - ([@travi](https://github.com/travi)) -* [`d2ad776f6`](https://github.com/npm/npm/commit/d2ad776f6dcd92ae3937465736dcbca171131343) - [#20879](https://github.com/npm/npm/pull/20879) - When `npm run-script <script>` fails due to a typo or missing script, npm will - now do a "did you mean?..." for scripts that do exist. - ([@watilde](https://github.com/watilde)) - -### BUGFIXES - -* [`8f033d72d`](https://github.com/npm/npm/commit/8f033d72da3e84a9dbbabe3a768693817af99912) - [#20948](https://github.com/npm/npm/pull/20948) - Fix the regular expression matching in `xcode_emulation` in `node-gyp` to also - handle version numbers with multiple-digit major versions which would - otherwise break under use of XCode 10. - ([@Trott](https://github.com/Trott)) -* [`c8ba7573a`](https://github.com/npm/npm/commit/c8ba7573a4ea95789f674ce038762d6a77a8b047) - Stop trying to hoist/dedupe bundles dependencies. - ([@iarna](https://github.com/iarna)) -* [`cd698f068`](https://github.com/npm/npm/commit/cd698f06840b7c9407ac802efa96d16464722a7d) - [#20762](https://github.com/npm/npm/pull/20762) - Add synopsis to brief help for `npm audit` and suppress trailing newline. - ([@wyardley](https://github.com/wyardley)) -* [`6808ee3bd`](https://github.com/npm/npm/commit/6808ee3bd59560b1334a18aa6c6e0120094b03c0) - [#20881](https://github.com/npm/npm/pull/20881) - Exclude /.github directory from npm tarball. - ([@styfle](https://github.com/styfle)) -* [`177cbb476`](https://github.com/npm/npm/commit/177cbb4762c1402bfcbf0636c4bc4905fd684fc1) - [#21105](https://github.com/npm/npm/pull/21105) - Add suggestion to use a temporary cache instead of `npm cache clear --force`. - ([@karanjthakkar](https://github.com/karanjthakkar)) - -### DOCS - -* [`7ba3fca00`](https://github.com/npm/npm/commit/7ba3fca00554b884eb47f2ed661693faf2630b27) - [#20855](https://github.com/npm/npm/pull/20855) - Direct people to npm.community instead of the GitHub issue tracker on error. - ([@zkat](https://github.com/zkat)) -* [`88efbf6b0`](https://github.com/npm/npm/commit/88efbf6b0b403c5107556ff9e1bb7787a410d14d) - [#20859](https://github.com/npm/npm/pull/20859) - Fix typo in registry docs. - ([@strugee](https://github.com/strugee)) -* [`61bf827ae`](https://github.com/npm/npm/commit/61bf827aea6f98bba08a54e60137d4df637788f9) - [#20947](https://github.com/npm/npm/pull/20947) - Fixed a small grammar error in the README. - ([@bitsol](https://github.com/bitsol)) -* [`f5230c90a`](https://github.com/npm/npm/commit/f5230c90afef40f445bf148cbb16d6129a2dcc19) - [#21018](https://github.com/npm/npm/pull/21018) - Small typo fix in CONTRIBUTING.md. - ([@reggi](https://github.com/reggi)) -* [`833efe4b2`](https://github.com/npm/npm/commit/833efe4b2abcef58806f823d77ab8bb8f4f781c6) - [#20986](https://github.com/npm/npm/pull/20986) - Document current structure/expectations around package tarballs. - ([@Maximaximum](https://github.com/Maximaximum)) -* [`9fc0dc4f5`](https://github.com/npm/npm/commit/9fc0dc4f58d728bac6a8db7143d04863d7b653db) - [#21019](https://github.com/npm/npm/pull/21019) - Clarify behavior of `npm link ../path` shorthand. - ([@davidgilbertson](https://github.com/davidgilbertson)) -* [`3924c72d0`](https://github.com/npm/npm/commit/3924c72d06b9216ac2b6a9d951fd565a1d5eda89) - [#21064](https://github.com/npm/npm/pull/21064) - Add missing "if" - ([@roblourens](https://github.com/roblourens)) - -### DEPENDENCY SHUFFLE! - -We did some reshuffling and moving around of npm's own dependencies. This -significantly reduces the total bundle size of the npm pack, from 8MB to 4.8MB -for the distributed tarball! We also moved around what we actually commit to the -repo as far as devDeps go. - -* [`0483f5c5d`](https://github.com/npm/npm/commit/0483f5c5deaf18c968a128657923103e49f4e67a) - Flatten and dedupe our dependencies! - ([@iarna](https://github.com/iarna)) -* [`ef9fa1ceb`](https://github.com/npm/npm/commit/ef9fa1ceb5f9d175fd453138b1a26d45a5071dfd) - Remove unused direct dependency `ansi-regex`. - ([@iarna](https://github.com/iarna)) -* [`0d14b0bc5`](https://github.com/npm/npm/commit/0d14b0bc59812f4e33798194e11ffacbea3c0493) - Reshuffle ansi-regex for better deduping. - ([@iarna](https://github.com/iarna)) -* [`68a101859`](https://github.com/npm/npm/commit/68a101859b2b6f78b2e7c3a936492acdb15f7c4a) - Reshuffle strip-ansi for better deduping. - ([@iarna](https://github.com/iarna)) -* [`0d5251f97`](https://github.com/npm/npm/commit/0d5251f97dc8b8b143064869e530d465c757ffbb) - Reshuffle is-fullwidth-code-point for better deduping. - ([@iarna](https://github.com/iarna)) -* [`2d0886632`](https://github.com/npm/npm/commit/2d08866327013522fc5fbe61ed872b8f30e92775) - Add fake-registry, npm-registry-mock replacement. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCIES - -* [`8cff8eea7`](https://github.com/npm/npm/commit/8cff8eea75dc34c9c1897a7a6f65d7232bb0c64c) - `tar@4.4.3` - ([@zkat](https://github.com/zkat)) -* [`bfc4f873b`](https://github.com/npm/npm/commit/bfc4f873bd056b7e3aee389eda4ecd8a2e175923) - `pacote@8.1.6` - ([@zkat](https://github.com/zkat)) -* [`532096163`](https://github.com/npm/npm/commit/53209616329119be8fcc29db86a43cc8cf73454d) - `libcipm@2.0.0` - ([@zkat](https://github.com/zkat)) -* [`4a512771b`](https://github.com/npm/npm/commit/4a512771b67aa06505a0df002a9027c16a238c71) - `request@2.87.0` - ([@iarna](https://github.com/iarna)) -* [`b7cc48dee`](https://github.com/npm/npm/commit/b7cc48deee45da1feab49aa1dd4d92e33c9bcac8) - `which@1.3.1` - ([@iarna](https://github.com/iarna)) -* [`bae657c28`](https://github.com/npm/npm/commit/bae657c280f6ea8e677509a9576e1b47c65c5441) - `tar@4.4.4` - ([@iarna](https://github.com/iarna)) -* [`3d46e5c4e`](https://github.com/npm/npm/commit/3d46e5c4e3c5fecd9bf05a7425a16f2e8ad5c833) - `JSONStream@1.3.3` - ([@iarna](https://github.com/iarna)) -* [`d0a905daf`](https://github.com/npm/npm/commit/d0a905dafc7e3fcd304e8053acbe3da40ba22554) - `is-cidr@2.0.6` - ([@iarna](https://github.com/iarna)) -* [`4fc1f815f`](https://github.com/npm/npm/commit/4fc1f815fec5a7f6f057cf305e01d4126331d1f2) - `marked@0.4.0` - ([@iarna](https://github.com/iarna)) -* [`f72202944`](https://github.com/npm/npm/commit/f722029441a088d03df94bdfdeeec51cfd318659) - `tap@12.0.1` - ([@iarna](https://github.com/iarna)) -* [`bdce96eb3`](https://github.com/npm/npm/commit/bdce96eb3c30fcff873aa3f1190e8ae4928d690b) - `npm-profile@3.0.2` - ([@iarna](https://github.com/iarna)) -* [`fe4240e85`](https://github.com/npm/npm/commit/fe4240e852144770bf76d7b1952056ca5baa63cf) - `uuid@3.3.2` - ([@zkat](https://github.com/zkat)) - -## v6.1.0 (2018-05-17): - -### FIX WRITE AFTER END ERROR - -First introduced in 5.8.0, this finally puts to bed errors where you would -occasionally see `Error: write after end at MiniPass.write`. - -* [`171f3182f`](https://github.com/npm/npm/commit/171f3182f32686f2f94ea7d4b08035427e0b826e) - [node-tar#180](https://github.com/npm/node-tar/issues/180) - [npm.community#35](https://npm.community/t/write-after-end-when-installing-packages-with-5-8-and-later/35) - `pacote@8.1.5`: Fix write-after-end errors. - ([@zkat](https://github.com/zkat)) - -### DETECT CHANGES IN GIT SPECIFIERS - -* [`0e1726c03`](https://github.com/npm/npm/commit/0e1726c0350a02d5a60f5fddb1e69c247538625e) - We can now determine if the commitid of a git dependency in the lockfile is derived - from the specifier in the package.json and if it isn't we now trigger an update for it. - ([@iarna](https://github.com/iarna)) - -### OTHER BUGS - -* [`442d2484f`](https://github.com/npm/npm/commit/442d2484f686e3a371b07f8473a17708f84d9603) - [`2f0c88351`](https://github.com/npm/npm/commit/2f0c883519f17c94411dd1d9877c5666f260c12f) - [`631d30a34`](https://github.com/npm/npm/commit/631d30a340f5805aed6e83f47a577ca4125599b2) - When requesting the update of a direct dependency that was also a - transitive dependency to a version incompatible with the transitive - requirement and you had a lock-file but did not have a `node_modules` - folder then npm would fail to provide a new copy of the transitive - dependency, resulting in an invalid lock-file that could not self heal. - ([@iarna](https://github.com/iarna)) -* [`be5dd0f49`](https://github.com/npm/npm/commit/be5dd0f496ec1485b1ea3094c479dfc17bd50d82) - [#20715](https://github.com/npm/npm/pull/20715) - Cleanup output of `npm ci` summary report. - ([@legodude17](https://github.com/legodude17)) -* [`98ffe4adb`](https://github.com/npm/npm/commit/98ffe4adb55a6f4459271856de2e27e95ee63375) - Node.js now has a test that scans for things that look like conflict - markers in source code. This was triggering false positives on a fixture in a test - of npm's ability to heal lockfiles with conflicts in them. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCY UPDATES - -* [`3f2e306b8`](https://github.com/npm/npm/commit/3f2e306b884a027df03f64524beb8658ce1772cb) - Using `npm audit fix`, replace some transitive dependencies with security - issues with versions that don't have any. - ([@iarna](https://github.com/iarna)) -* [`1d07134e0`](https://github.com/npm/npm/commit/1d07134e0b157f7484a20ce6987ff57951842954) - `tar@4.4.1`: - Dropping to 4.4.1 from 4.4.2 due to https://github.com/npm/node-tar/issues/183 - ([@zkat](https://github.com/zkat)) - - -## v6.1.0-next.0 (2018-05-17): - -Look at that! A feature bump! `npm@6` was super-exciting not just because it -used a bigger number than ever before, but also because it included a super -shiny new command: `npm audit`. Well, we've kept working on it since then and -have some really nice improvements for it. You can expect more of them, and the -occasional fix, in the next few releases as more users start playing with it and -we get more feedback about what y'all would like to see from something like -this. - -I, for one, have started running it (and the new subcommand...) in all my -projects, and it's one of those things that I don't know how I ever functioned --without- it! This will make a world of difference to so many people as far as -making the npm ecosystem a higher-quality, safer commons for all of us. - -This is also a good time to remind y'all that we have a new [RFCs -repository](https://github.com/npm/rfcs), along with a new process for them. -This repo is open to anyone's RFCs, and has already received some great ideas -about where we can take the CLI (and, to a certain extent, the registry). It's a -great place to get feedback, and completely replaces feature requests in the -main repo, so we won't be accepting feature requests there at all anymore. Check -it out if you have something you'd like to suggest, or if you want to keep track -of what the future might look like! - -### NEW FEATURE: `npm audit fix` - -This is the biggie with this release! `npm audit fix` does exactly what it says -on the tin. It takes all the actionable reports from your `npm audit` and runs -the installs automatically for you, so you don't have to try to do all that -mechanical work yourself! - -Note that by default, `npm audit fix` will stick to semver-compatible changes, -so you should be able to safely run it on most projects and carry on with your -day without having to track down what breaking changes were included. If you -want your (toplevel) dependencies to accept semver-major bumps as well, you can -use `npm audit fix --force` and it'll toss those in, as well. Since it's running -the npm installer under the hood, it also supports `--production` and -`--only=dev` flags, as well as things like `--dry-run`, `--json`, and -`--package-lock-only`, if you want more control over what it does. - -Give it a whirl and tell us what you think! See `npm help audit` for full docs! - -* [`3800a660d`](https://github.com/npm/npm/commit/3800a660d99ca45c0175061dbe087520db2f54b7) - Add `npm audit fix` subcommand to automatically fix detected vulnerabilities. - ([@zkat](https://github.com/zkat)) - -### OTHER NEW `audit` FEATURES - -* [`1854b1c7f`](https://github.com/npm/npm/commit/1854b1c7f09afceb49627e539a086d8a3565601c) - [#20568](https://github.com/npm/npm/pull/20568) - Add support for `npm audit --json` to print the report in JSON format. - ([@finnp](https://github.com/finnp)) -* [`85b86169d`](https://github.com/npm/npm/commit/85b86169d9d0423f50893d2ed0c7274183255abe) - [#20570](https://github.com/npm/npm/pull/20570) - Include number of audited packages in `npm install` summary output. - ([@zkat](https://github.com/zkat)) -* [`957cbe275`](https://github.com/npm/npm/commit/957cbe27542d30c33e58e7e6f2f04eeb64baf5cd) - `npm-audit-report@1.2.1`: - Overhaul audit install and detail output format. The new format is terser and - fits more closely into the visual style of the CLI, while still providing you - with the important bits of information you need. They also include a bit more - detail on the footer about what actions you can take! - ([@zkat](https://github.com/zkat)) - -### NEW FEATURE: GIT DEPS AND `npm init <pkg>`! - -Another exciting change that came with `npm@6` was the new `npm init` command -that allows for community-authored generators. That means you can, for example, -do `npm init react-app` and it'll one-off download, install, and run -[`create-react-app`](https://npm.im/create-react-app) for you, without requiring -or keeping around any global installs. That is, it basically just calls out to -[`npx`](https://npm.im/npx). - -The first version of this command only really supported registry dependencies, -but now, [@jdalton](https://github.com/jdalton) went ahead and extended this -feature so you can use hosted git dependencies, and their shorthands. - -So go ahead and do `npm init facebook/create-react-app` and it'll grab the -package from the github repo now! Or you can use it with a private github -repository to maintain your organizational scaffolding tools or whatnot. ✨ - -* [`483e01180`](https://github.com/npm/npm/commit/483e011803af82e63085ef41b7acce5b22aa791c) - [#20403](https://github.com/npm/npm/pull/20403) - Add support for hosted git packages to `npm init <name>`. - ([@jdalton](https://github.com/jdalton)) - -### BUGFIXES - -* [`a41c0393c`](https://github.com/npm/npm/commit/a41c0393cba710761a15612c6c85c9ef2396e65f) - [#20538](https://github.com/npm/npm/pull/20538) - Make the new `npm view` work when the license field is an object instead of a - string. - ([@zkat](https://github.com/zkat)) -* [`eb7522073`](https://github.com/npm/npm/commit/eb75220739302126c94583cc65a5ff12b441e3c6) - [#20582](https://github.com/npm/npm/pull/20582) - Add support for environments (like Docker) where the expected binary for - opening external URLs is not available. - ([@bcoe](https://github.com/bcoe)) -* [`212266529`](https://github.com/npm/npm/commit/212266529ae72056bf0876e2cff4b8ba01d09d0f) - [#20536](https://github.com/npm/npm/pull/20536) - Fix a spurious colon in the new update notifier message and add support for - the npm canary. - ([@zkat](https://github.com/zkat)) -* [`5ee1384d0`](https://github.com/npm/npm/commit/5ee1384d02c3f11949d7a26ec6322488476babe6) - [#20597](https://github.com/npm/npm/pull/20597) - Infer a version range when a `package.json` has a dist-tag instead of a - version range in one of its dependency specs. Previously, this would cause - dependencies to be flagged as invalid. - ([@zkat](https://github.com/zkat)) -* [`4fa68ae41`](https://github.com/npm/npm/commit/4fa68ae41324293e59584ca6cf0ac24b3e0825bb) - [#20585](https://github.com/npm/npm/pull/20585) - Make sure scoped bundled deps are shown in the new publish preview, too. - ([@zkat](https://github.com/zkat)) -* [`1f3ee6b7e`](https://github.com/npm/npm/commit/1f3ee6b7e1b36b52bdedeb9241296d4e66561d48) - `cacache@11.0.2`: - Stop dropping `size` from metadata on `npm cache verify`. - ([@jfmartinez](https://github.com/jfmartinez)) -* [`91ef93691`](https://github.com/npm/npm/commit/91ef93691a9d6ce7c016fefdf7da97854ca2b2ca) - [#20513](https://github.com/npm/npm/pull/20513) - Fix nested command aliases. - ([@mmermerkaya](https://github.com/mmermerkaya)) -* [`18b2b3cf7`](https://github.com/npm/npm/commit/18b2b3cf71a438648ced1bd13faecfb50c71e979) - `npm-lifecycle@2.0.3`: - Make sure different versions of the `Path` env var on Windows all get - `node_modules/.bin` prepended when running lifecycle scripts. - ([@laggingreflex](https://github.com/laggingreflex)) - -### DOCUMENTATION - -* [`a91d87072`](https://github.com/npm/npm/commit/a91d87072f292564e58dcab508b5a8c6702b9aae) - [#20550](https://github.com/npm/npm/pull/20550) - Update required node versions in README. - ([@legodude17](https://github.com/legodude17)) -* [`bf3cfa7b8`](https://github.com/npm/npm/commit/bf3cfa7b8b351714c4ec621e1a5867c8450c6fff) - Pull in changelogs from the last `npm@5` release. - ([@iarna](https://github.com/iarna)) -* [`b2f14b14c`](https://github.com/npm/npm/commit/b2f14b14ca25203c2317ac2c47366acb50d46e69) - [#20629](https://github.com/npm/npm/pull/20629) - Make tone in `publishConfig` docs more neutral. - ([@jeremyckahn](https://github.com/jeremyckahn)) - -### DEPENDENCY BUMPS - -* [`5fca4eae8`](https://github.com/npm/npm/commit/5fca4eae8a62a7049b1ae06aa0bbffdc6e0ad6cc) - `byte-size@4.0.3` - ([@75lb](https://github.com/75lb)) -* [`d9ef3fba7`](https://github.com/npm/npm/commit/d9ef3fba79f87c470889a6921a91f7cdcafa32b9) - `lru-cache@4.1.3` - ([@isaacs](https://github.com/isaacs)) -* [`f1baf011a`](https://github.com/npm/npm/commit/f1baf011a0d164f8dc8aa6cd31e89225e3872e3b) - `request@2.86.0` - ([@simonv](https://github.com/simonv)) -* [`005fa5420`](https://github.com/npm/npm/commit/005fa542072f09a83f77a9d62c5e53b8f6309371) - `require-inject@1.4.3` - ([@iarna](https://github.com/iarna)) -* [`1becdf09a`](https://github.com/npm/npm/commit/1becdf09a2f19716726c88e9a2342e1e056cfc71) - `tap@11.1.5` - ([@isaacs](https://github.com/isaacs)) - -## v6.0.1 (2018-05-09): - -### AUDIT SHOULDN'T WAIT FOREVER - -This will likely be reduced further with the goal that the audit process -shouldn't noticibly slow down your builds regardless of your network -situation. - -* [`3dcc240db`](https://github.com/npm/npm/commit/3dcc240dba5258532990534f1bd8a25d1698b0bf) - Timeout audit requests eventually. - ([@iarna](https://github.com/iarna)) - -### Looking forward - -We're still a way from having node@11, so now's a good time to ensure we -don't warn about being used with it. - -* [`ed1aebf55`](https://github.com/npm/npm/commit/ed1aebf55) - Allow node@11, when it comes. - ([@iarna](https://github.com/iarna)) - -## v6.0.1-next.0 (2018-05-03): - -### CTRL-C OUT DURING PACKAGE EXTRACTION AS MUCH AS YOU WANT! - -* [`b267bbbb9`](https://github.com/npm/npm/commit/b267bbbb9ddd551e3dbd162cc2597be041b9382c) - [npm/lockfile#29](https://github.com/npm/lockfile/pull/29) - `lockfile@1.0.4`: - Switches to `signal-exit` to detect abnormal exits and remove locks. - ([@Redsandro](https://github.com/Redsandro)) - -### SHRONKWRAPS AND LACKFILES - -If a published modules had legacy `npm-shrinkwrap.json` we were saving -ordinary registry dependencies (`name@version`) to your `package-lock.json` -as `https://` URLs instead of versions. - -* [`89102c0d9`](https://github.com/npm/npm/commit/89102c0d995c3d707ff2b56995a97a1610f8b532) - When saving the lock-file compute how the dependency is being required instead of using - `_resolved` in the `package.json`. This fixes the bug that was converting - registry dependencies into `https://` dependencies. - ([@iarna](https://github.com/iarna)) -* [`676f1239a`](https://github.com/npm/npm/commit/676f1239ab337ff967741895dbe3a6b6349467b6) - When encountering a `https://` URL in our lockfiles that point at our default registry, extract - the version and use them as registry dependencies. This lets us heal - `package-lock.json` files produced by 6.0.0 - ([@iarna](https://github.com/iarna)) - -### AUDIT AUDIT EVERYWHERE - -You can't use it _quite_ yet, but we do have a few last moment patches to `npm audit` to make -it even better when it is turned on! - -* [`b2e4f48f5`](https://github.com/npm/npm/commit/b2e4f48f5c07b8ebc94a46ce01a810dd5d6cd20c) - Make sure we hide stream errors on background audit submissions. Previously some classes - of error could end up being displayed (harmlessly) during installs. - ([@iarna](https://github.com/iarna)) -* [`1fe0c7fea`](https://github.com/npm/npm/commit/1fe0c7fea226e592c96b8ab22fd9435e200420e9) - Include session and scope in requests (as we do in other requests to the registry). - ([@iarna](https://github.com/iarna)) -* [`d04656461`](https://github.com/npm/npm/commit/d046564614639c37e7984fff127c79a8ddcc0c92) - Exit with non-zero status when vulnerabilities are found. So you can have `npm audit` as a test or prepublish step! - ([@iarna](https://github.com/iarna)) -* [`fcdbcbacc`](https://github.com/npm/npm/commit/fcdbcbacc16d96a8696dde4b6d7c1cba77828337) - Verify lockfile integrity before running. You'd get an error either way, but this way it's - faster and can give you more concrete instructions on how to fix it. - ([@iarna](https://github.com/iarna)) -* [`2ac8edd42`](https://github.com/npm/npm/commit/2ac8edd4248f2393b35896f0300b530e7666bb0e) - Refuse to run in global mode. Audits require a lockfile and globals don't have one. Yet. - ([@iarna](https://github.com/iarna)) - -### DOCUMENTATION IMPROVEMENTS - -* [`b7fca1084`](https://github.com/npm/npm/commit/b7fca1084b0be6f8b87ec0807c6daf91dbc3060a) - [#20407](https://github.com/npm/npm/pull/20407) - Update the lock-file spec doc to mention that we now generate the from field for `git`-type dependencies. - ([@watilde](https://github.com/watilde)) -* [`7a6555e61`](https://github.com/npm/npm/commit/7a6555e618e4b8459609b7847a9e17de2d4fa36e) - [#20408](https://github.com/npm/npm/pull/20408) - Describe what the colors in outdated mean. - ([@teameh](https://github.com/teameh)) - -### DEPENDENCY UPDATES - -* [`5e56b3209`](https://github.com/npm/npm/commit/5e56b3209c4719e3c4d7f0d9346dfca3881a5d34) - `npm-audit-report@1.0.8` - ([@evilpacket](https://github.com/evilpacket)) -* [`58a0b31b4`](https://github.com/npm/npm/commit/58a0b31b43245692b4de0f1e798fcaf71f8b7c31) - `lock-verify@2.0.2` - ([@iarna](https://github.com/iarna)) -* [`e7a8c364f`](https://github.com/npm/npm/commit/e7a8c364f3146ffb94357d8dd7f643e5563e2f2b) - [zkat/pacote#148](https://github.com/zkat/pacote/pull/148) - `pacote@8.1.1` - ([@redonkulus](https://github.com/redonkulus)) -* [`46c0090a5`](https://github.com/npm/npm/commit/46c0090a517526dfec9b1b6483ff640227f0cd10) - `tar@4.4.2` - ([@isaacs](https://github.com/isaacs)) -* [`8a16db3e3`](https://github.com/npm/npm/commit/8a16db3e39715301fd085a8f4c80ae836f0ec714) - `update-notifier@2.5.0` - ([@alexccl](https://github.com/alexccl)) -* [`696375903`](https://github.com/npm/npm/commit/6963759032fe955c1404d362e14f458d633c9444) - `safe-buffer@5.1.2` - ([@feross](https://github.com/feross)) -* [`c949eb26a`](https://github.com/npm/npm/commit/c949eb26ab6c0f307e75a546f342bb2ec0403dcf) - `query-string@6.1.0` - ([@sindresorhus](https://github.com/sindresorhus)) - -## v6.0.0 (2018-04-20): - -Hey y'all! Here's another `npm@6` release -- with `node@10` around the corner, -this might well be the last prerelease before we tag `6.0.0`! There's two major -features included with this release, along with a few miscellaneous fixes and -changes. - -### EXTENDED `npm init` SCAFFOLDING - -Thanks to the wonderful efforts of [@jdalton](https://github.com/jdalton) of -lodash fame, `npm init` can now be used to invoke custom scaffolding tools! - -You can now do things like `npm init react-app` or `npm init esm` to scaffold an -npm package by running `create-react-app` and `create-esm`, respectively. This -also adds an `npm create` alias, to correspond to Yarn's `yarn create` feature, -which inspired this. - -* [`008a83642`](https://github.com/npm/npm/commit/008a83642e04360e461f56da74b5557d5248a726) [`ed81d1426`](https://github.com/npm/npm/commit/ed81d1426776bcac47492cabef43f65e1d4ab536) [`833046e45`](https://github.com/npm/npm/commit/833046e45fe25f75daffd55caf25599a9f98c148) - [#20303](https://github.com/npm/npm/pull/20303) - Add an `npm init` feature that calls out to `npx` when invoked with positional - arguments. ([@jdalton](https://github.com/jdalton)) - -### DEPENDENCY AUDITING - -This version of npm adds a new command, `npm audit`, which will run a security -audit of your project's dependency tree and notify you about any actions you may -need to take. - -The registry-side services required for this command to work will be available -on the main npm registry in the coming weeks. Until then, you won't get much out -of trying to use this on the CLI. - -As part of this change, the npm CLI now sends scrubbed and cryptographically -anonymized metadata about your dependency tree to your configured registry, to -allow notifying you about the existence of critical security flaws. For details -about how the CLI protects your privacy when it shares this metadata, see `npm -help audit`, or [read the docs for `npm audit` -online](https://github.com/npm/npm/blob/release-next/doc/cli/npm-audit.md). You -can disable this altogether by doing `npm config set audit false`, but will no -longer benefit from the service. - -* [`f4bc648ea`](https://github.com/npm/npm/commit/f4bc648ea7b19d63cc9878c9da2cb1312f6ce152) - [#20389](https://github.com/npm/npm/pull/20389) - `npm-registry-fetch@1.1.0` - ([@iarna](https://github.com/iarna)) -* [`594d16987`](https://github.com/npm/npm/commit/594d16987465014d573c51a49bba6886cc19f8e8) - [#20389](https://github.com/npm/npm/pull/20389) - `npm-audit-report@1.0.5` - ([@iarna](https://github.com/iarna)) -* [`8c77dde74`](https://github.com/npm/npm/commit/8c77dde74a9d8f9007667cd1732c3329e0d52617) [`1d8ac2492`](https://github.com/npm/npm/commit/1d8ac2492196c4752b2e41b23d5ddc92780aaa24) [`552ff6d64`](https://github.com/npm/npm/commit/552ff6d64a5e3bcecb33b2a861c49a3396adad6d) [`09c734803`](https://github.com/npm/npm/commit/09c73480329e75e44fb8e55ca522f798be68d448) - [#20389](https://github.com/npm/npm/pull/20389) - Add new `npm audit` command. - ([@iarna](https://github.com/iarna)) -* [`be393a290`](https://github.com/npm/npm/commit/be393a290a5207dc75d3d70a32973afb3322306c) - [#20389](https://github.com/npm/npm/pull/20389) - Temporarily suppress git metadata till there's an opt-in. - ([@iarna](https://github.com/iarna)) -* [`8e713344f`](https://github.com/npm/npm/commit/8e713344f6e0828ddfb7733df20d75e95a5382d8) - [#20389](https://github.com/npm/npm/pull/20389) - Document the new command. - ([@iarna](https://github.com/iarna)) -* - [#20389](https://github.com/npm/npm/pull/20389) - Default audit to off when running the npm test suite itself. - ([@iarna](https://github.com/iarna)) - -### MORE `package-lock.json` FORMAT CHANGES?! - -* [`820f74ae2`](https://github.com/npm/npm/commit/820f74ae22b7feb875232d46901cc34e9ba995d6) - [#20384](https://github.com/npm/npm/pull/20384) - Add `from` field back into package-lock for git dependencies. This will give - npm the information it needs to figure out whether git deps are valid, - specially when running with legacy install metadata or in - `--package-lock-only` mode when there's no `node_modules`. This should help - remove a significant amount of git-related churn on the lock-file. - ([@zkat](https://github.com/zkat)) - -### BUGFIXES - -* [`9d5d0a18a`](https://github.com/npm/npm/commit/9d5d0a18a5458655275056156b5aa001140ae4d7) - [#20358](https://github.com/npm/npm/pull/20358) - `npm install-test` (aka `npm it`) will no longer generate `package-lock.json` - when running with `--no-package-lock` or `package-lock=false`. - ([@raymondfeng](https://github.com/raymondfeng)) -* [`e4ed976e2`](https://github.com/npm/npm/commit/e4ed976e20b7d1114c920a9dc9faf351f89a31c9) - [`2facb35fb`](https://github.com/npm/npm/commit/2facb35fbfbbc415e693d350b67413a66ff96204) - [`9c1eb945b`](https://github.com/npm/npm/commit/9c1eb945be566e24cbbbf186b0437bdec4be53fc) - [#20390](https://github.com/npm/npm/pull/20390) - Fix a scenario where a git dependency had a comittish associated with it - that was not a complete commitid. `npm` would never consider that entry - in the `package.json` as matching the entry in the `package-lock.json` and - this resulted in inappropriate pruning or reinstallation of git - dependencies. This has been addressed in two ways, first, the addition of the - `from` field as described in [#20384](https://github.com/npm/npm/pull/20384) means - we can exactly match the `package.json`. Second, when that's missing (when working with - older `package-lock.json` files), we assume that the match is ok. (If - it's not, we'll fix it up when a real installation is done.) - ([@iarna](https://github.com/iarna)) - - -### DEPENDENCIES - -* [`1c1f89b73`](https://github.com/npm/npm/commit/1c1f89b7319b2eef6adee2530c4619ac1c0d83cf) - `libnpx@10.2.0` - ([@zkat](https://github.com/zkat)) -* [`242d8a647`](https://github.com/npm/npm/commit/242d8a6478b725778c00be8ba3dc85f367006a61) - `pacote@8.1.0` - ([@zkat](https://github.com/zkat)) - -### DOCS - -* [`a1c77d614`](https://github.com/npm/npm/commit/a1c77d614adb4fe6769631b646b817fd490d239c) - [#20331](https://github.com/npm/npm/pull/20331) - Fix broken link to 'private-modules' page. The redirect went away when the new - npm website went up, but the new URL is better anyway. - ([@vipranarayan14](https://github.com/vipranarayan14)) -* [`ad7a5962d`](https://github.com/npm/npm/commit/ad7a5962d758efcbcfbd9fda9a3d8b38ddbf89a1) - [#20279](https://github.com/npm/npm/pull/20279) - Document the `--if-present` option for `npm run-script`. - ([@aleclarson](https://github.com/aleclarson)) - -## v6.0.0-next.1 (2018-04-12): - -### NEW FEATURES - -* [`a9e722118`](https://github.com/npm/npm/commit/a9e7221181dc88e14820d0677acccf0648ac3c5a) - [#20256](https://github.com/npm/npm/pull/20256) - Add support for managing npm webhooks. This brings over functionality - previously provided by the [`wombat`](https://www.npmjs.com/package/wombat) CLI. - ([@zkat](https://github.com/zkat)) -* [`8a1a64203`](https://github.com/npm/npm/commit/8a1a64203cca3f30999ea9e160eb63662478dcee) - [#20126](https://github.com/npm/npm/pull/20126) - Add `npm cit` command that's equivalent of `npm ci && npm t` that's equivalent of `npm it`. - ([@SimenB](https://github.com/SimenB)) -* [`fe867aaf1`](https://github.com/npm/npm/commit/fe867aaf19e924322fe58ed0cf0a570297a96559) - [`49d18b4d8`](https://github.com/npm/npm/commit/49d18b4d87d8050024f8c5d7a0f61fc2514917b1) - [`ff6b31f77`](https://github.com/npm/npm/commit/ff6b31f775f532bb8748e8ef85911ffb35a8c646) - [`78eab3cda`](https://github.com/npm/npm/commit/78eab3cdab6876728798f876d569badfc74ce68f) - The `requires` field in your lock-file will be upgraded to use ranges from - versions on your first use of npm. - ([@iarna](https://github.com/iarna)) -* [`cf4d7b4de`](https://github.com/npm/npm/commit/cf4d7b4de6fa241a656e58f662af0f8d7cd57d21) - [#20257](https://github.com/npm/npm/pull/20257) - Add shasum and integrity to the new `npm view` output. - ([@zkat](https://github.com/zkat)) - -### BUG FIXES - -* [`685764308`](https://github.com/npm/npm/commit/685764308e05ff0ddb9943b22ca77b3a56d5c026) - Fix a bug where OTPs passed in via the commandline would have leading - zeros deleted resulted in authentication failures. - ([@iarna](https://github.com/iarna)) -* [`8f3faa323`](https://github.com/npm/npm/commit/8f3faa3234b2d2fcd2cb05712a80c3e4133c8f45) - [`6800f76ff`](https://github.com/npm/npm/commit/6800f76ffcd674742ba8944f11f6b0aa55f4b612) - [`ec90c06c7`](https://github.com/npm/npm/commit/ec90c06c78134eb2618612ac72288054825ea941) - [`825b5d2c6`](https://github.com/npm/npm/commit/825b5d2c60e620da5459d9dc13d4f911294a7ec2) - [`4785f13fb`](https://github.com/npm/npm/commit/4785f13fb69f33a8c624ecc8a2be5c5d0d7c94fc) - [`bd16485f5`](https://github.com/npm/npm/commit/bd16485f5b3087625e13773f7251d66547d6807d) - Restore the ability to bundle dependencies that are uninstallable from the - registry. This also eliminates needless registry lookups for bundled - dependencies. - - Fixed a bug where attempting to install a dependency that is bundled - inside another module without reinstalling that module would result in - ENOENT errors. - ([@iarna](https://github.com/iarna)) -* [`429498a8c`](https://github.com/npm/npm/commit/429498a8c8d4414bf242be6a3f3a08f9a2adcdf9) - [#20029](https://github.com/npm/npm/pull/20029) - Allow packages with non-registry specifiers to follow the fast path that - the we use with the lock-file for registry specifiers. This will improve install time - especially when operating only on the package-lock (`--package-lock-only`). - ([@zkat](https://github.com/zkat)) - - Fix the a bug where `npm i --only=prod` could remove development - dependencies from lock-file. - ([@iarna](https://github.com/iarna)) -* [`834b46ff4`](https://github.com/npm/npm/commit/834b46ff48ade4ab4e557566c10e83199d8778c6) - [#20122](https://github.com/npm/npm/pull/20122) - Improve the update-notifier messaging (borrowing ideas from pnpm) and - eliminate false positives. - ([@zkat](https://github.com/zkat)) -* [`f9de7ef3a`](https://github.com/npm/npm/commit/f9de7ef3a1089ceb2610cd27bbd4b4bc2979c4de) - [#20154](https://github.com/npm/npm/pull/20154) - Let version succeed when `package-lock.json` is gitignored. - ([@nwoltman](https://github.com/nwoltman)) -* [`f8ec52073`](https://github.com/npm/npm/commit/f8ec520732bda687bc58d9da0873dadb2d65ca96) - [#20212](https://github.com/npm/npm/pull/20212) - Ensure that we only create an `etc` directory if we are actually going to write files to it. - ([@buddydvd](https://github.com/buddydvd)) -* [`ab489b753`](https://github.com/npm/npm/commit/ab489b75362348f412c002cf795a31dea6420ef0) - [#20140](https://github.com/npm/npm/pull/20140) - Note in documentation that `package-lock.json` version gets touched by `npm version`. - ([@srl295](https://github.com/srl295)) -* [`857c2138d`](https://github.com/npm/npm/commit/857c2138dae768ea9798782baa916b1840ab13e8) - [#20032](https://github.com/npm/npm/pull/20032) - Fix bug where unauthenticated errors would get reported as both 404s and - 401s, i.e. `npm ERR! 404 Registry returned 401`. In these cases the error - message will now be much more informative. - ([@iarna](https://github.com/iarna)) -* [`d2d290bca`](https://github.com/npm/npm/commit/d2d290bcaa85e44a4b08cc40cb4791dd4f81dfc4) - [#20082](https://github.com/npm/npm/pull/20082) - Allow optional @ prefix on scope with `npm team` commands for parity with other commands. - ([@bcoe](https://github.com/bcoe)) -* [`b5babf0a9`](https://github.com/npm/npm/commit/b5babf0a9aa1e47fad8a07cc83245bd510842047) - [#19580](https://github.com/npm/npm/pull/19580) - Improve messaging when two-factor authentication is required while publishing. - ([@jdeniau](https://github.com/jdeniau)) -* [`471ee1c5b`](https://github.com/npm/npm/commit/471ee1c5b58631fe2e936e32480f3f5ed6438536) - [`0da38b7b4`](https://github.com/npm/npm/commit/0da38b7b4aff0464c60ad12e0253fd389efd5086) - Fix a bug where optional status of a dependency was not being saved to - the package-lock on the initial install. - ([@iarna](https://github.com/iarna)) -* [`b3f98d8ba`](https://github.com/npm/npm/commit/b3f98d8ba242a7238f0f9a90ceea840b7b7070af) - [`9dea95e31`](https://github.com/npm/npm/commit/9dea95e319169647bea967e732ae4c8212608f53) - Ensure that `--no-optional` does not remove optional dependencies from the lock-file. - ([@iarna](https://github.com/iarna)) - -### MISCELLANEOUS - -* [`ec6b12099`](https://github.com/npm/npm/commit/ec6b120995c9c1d17ff84bf0217ba5741365af2d) - Exclude all tests from the published version of npm itself. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCY UPDATES - -* [`73dc97455`](https://github.com/npm/npm/commit/73dc974555217207fb384e39d049da19be2f79ba) - [zkat/cipm#46](https://github.com/zkat/cipm/pull/46) - `libcipm@1.6.2`: - Detect binding.gyp for default install lifecycle. Let's `npm ci` work on projects that - have their own C code. - ([@caleblloyd](https://github.com/caleblloyd)) -* [`77c3f7a00`](https://github.com/npm/npm/commit/77c3f7a0091f689661f61182cd361465e2d695d5) - `iferr@1.0.0` -* [`dce733e37`](https://github.com/npm/npm/commit/dce733e37687c21cb1a658f06197c609ac39c793) - [zkat/json-parse-better-errors#1](https://github.com/zkat/json-parse-better-errors/pull/1) - `json-parse-better-errors@1.0.2` - ([@Hoishin](https://github.com/Hoishin)) -* [`c52765ff3`](https://github.com/npm/npm/commit/c52765ff32d195842133baf146d647760eb8d0cd) - `readable-stream@2.3.6` - ([@mcollina](https://github.com/mcollina)) -* [`e160adf9f`](https://github.com/npm/npm/commit/e160adf9fce09f226f66e0892cc3fa45f254b5e8) - `update-notifier@2.4.0` - ([@sindersorhus](https://github.com/sindersorhus)) -* [`9a9d7809e`](https://github.com/npm/npm/commit/9a9d7809e30d1add21b760804be4a829e3c7e39e) - `marked@0.3.1` - ([@joshbruce](https://github.com/joshbruce)) -* [`f2fbd8577`](https://github.com/npm/npm/commit/f2fbd857797cf5c12a68a6fb0ff0609d373198b3) - [#20256](https://github.com/npm/npm/pull/20256) - `figgy-pudding@2.0.1` - ([@zkat](https://github.com/zkat)) -* [`44972d53d`](https://github.com/npm/npm/commit/44972d53df2e0f0cc22d527ac88045066205dbbf) - [#20256](https://github.com/npm/npm/pull/20256) - `libnpmhook@3.0.0` - ([@zkat](https://github.com/zkat)) -* [`cfe562c58`](https://github.com/npm/npm/commit/cfe562c5803db08a8d88957828a2cd1cc51a8dd5) - [#20276](https://github.com/npm/npm/pull/20276) - `node-gyp@3.6.2` -* [`3c0bbcb8e`](https://github.com/npm/npm/commit/3c0bbcb8e5440a3b90fabcce85d7a1d31e2ecbe7) - [zkat/npx#172](https://github.com/zkat/npx/pull/172) - `libnpx@10.1.1` - ([@jdalton](https://github.com/jdalton)) -* [`0573d91e5`](https://github.com/npm/npm/commit/0573d91e57c068635a3ad4187b9792afd7b5e22f) - [zkat/cacache#128](https://github.com/zkat/cacache/pull/128) - `cacache@11.0.1` - ([@zkat](https://github.com/zkat)) -* [`396afa99f`](https://github.com/npm/npm/commit/396afa99f61561424866d5c8dd7aedd6f91d611a) - `figgy-pudding@3.1.0` - ([@zkat](https://github.com/zkat)) -* [`e7f869c36`](https://github.com/npm/npm/commit/e7f869c36ec1dacb630e5ab749eb3bb466193f01) - `pacote@8.0.0` - ([@zkat](https://github.com/zkat)) -* [`77dac72df`](https://github.com/npm/npm/commit/77dac72dfdb6add66ec859a949b1d2d788a379b7) - `ssri@6.0.0` - ([@zkat](https://github.com/zkat)) -* [`0b802f2a0`](https://github.com/npm/npm/commit/0b802f2a0bfa15c6af8074ebf9347f07bccdbcc7) - `retry@0.12.0` - ([@iarna](https://github.com/iarna)) -* [`4781b64bc`](https://github.com/npm/npm/commit/4781b64bcc47d4e7fb7025fd6517cde044f6b5e1) - `libnpmhook@4.0.1` - ([@zkat](https://github.com/zkat)) -* [`7bdbaeea6`](https://github.com/npm/npm/commit/7bdbaeea61853280f00c8443a3b2d6e6b893ada9) - `npm-package-arg@6.1.0` - ([@zkat](https://github.com/zkat)) -* [`5f2bf4222`](https://github.com/npm/npm/commit/5f2bf4222004117eb38c44ace961bd15a779fd66) - `read-package-tree@5.2.1` - ([@zkat](https://github.com/zkat)) - -## v6.0.0-0 (2018-03-23): - -Sometimes major releases are a big splash, sometimes they're something -smaller. This is the latter kind. That said, we expect to keep this in -release candidate status until Node 10 ships at the end of April. There -will likely be a few more features for the 6.0.0 release line between now -and then. We do expect to have a bigger one later this year though, so keep -an eye out for `npm@7`! - -### *BREAKING* AVOID DEPRECATED - -When selecting versions to install, we now avoid deprecated versions if -possible. For example: - -``` -Module: example -Versions: -1.0.0 -1.1.0 -1.1.2 -1.1.3 (deprecated) -1.2.0 (latest) -``` - -If you ask `npm` to install `example@~1.1.0`, `npm` will now give you `1.1.2`. - -By contrast, if you installed `example@~1.1.3` then you'd get `1.1.3`, as -it's the only version that can match the range. - -* [`78bebc0ce`](https://github.com/npm/npm/commit/78bebc0cedc4ce75c974c47b61791e6ca1ccfd7e) - [#20151](https://github.com/npm/npm/pull/20151) - Skip deprecated versions when possible. - ([@zkat](https://github.com/zkat)) - -### *BREAKING* UPDATE AND OUTDATED - -When `npm install` is finding a version to install, it first checks to see -if the specifier you requested matches the `latest` tag. If it doesn't, -then it looks for the highest version that does. This means you can do -release candidates on tags other than `latest` and users won't see them -unless they ask for them. Promoting them is as easy as setting the `latest` -tag to point at them. - -Historically `npm update` and `npm outdated` worked differently. They just -looked for the most recent thing that matched the semver range, disregarding -the `latest` tag. We're changing it to match `npm install`'s behavior. - -* [`3aaa6ef42`](https://github.com/npm/npm/commit/3aaa6ef427b7a34ebc49cd656e188b5befc22bae) - Make update and outdated respect latest interaction with semver as install does. - ([@iarna](https://github.com/iarna)) -* [`e5fbbd2c9`](https://github.com/npm/npm/commit/e5fbbd2c999ab9c7ec15b30d8b4eb596d614c715) - `npm-pick-manifest@2.1.0` - ([@iarna](https://github.com/iarna)) - -### PLUS ONE SMALLER PATCH - -Technically this is a bug fix, but the change in behavior is enough of an -edge case that I held off on bringing it in until a major version. - -When we extract a binary and it starts with a shebang (or "hash bang"), that -is, something like: - -``` -#!/usr/bin/env node -``` - -If the file has Windows line endings we strip them off of the first line. -The reason for this is that shebangs are only used in Unix-like environments -and the files with them can't be run if the shebang has a Windows line ending. - -Previously we converted ALL line endings from Windows to Unix. With this -patch we only convert the line with the shebang. (Node.js works just fine -with either set of line endings.) - -* [`814658371`](https://github.com/npm/npm/commit/814658371bc7b820b23bc138e2b90499d5dda7b1) - [`7265198eb`](https://github.com/npm/npm/commit/7265198ebb32d35937f4ff484b0167870725b054) - `bin-links@1.1.2`: - Only rewrite the CR after a shebang (if any) when fixing up CR/LFs. - ([@iarna](https://github.com/iarna)) - -### *BREAKING* SUPPORTED NODE VERSIONS - -Per our supported Node.js policy, we're dropping support for both Node 4 and -Node 7, which are no longer supported by the Node.js project. - -* [`077cbe917`](https://github.com/npm/npm/commit/077cbe917930ed9a0c066e10934d540e1edb6245) - Drop support for Node 4 and Node 7. - ([@iarna](https://github.com/iarna)) - -### DEPENDENCIES - -* [`478fbe2d0`](https://github.com/npm/npm/commit/478fbe2d0bce1534b1867e0b80310863cfacc01a) - `iferr@1.0.0` -* [`b18d88178`](https://github.com/npm/npm/commit/b18d88178a4cf333afd896245a7850f2f5fb740b) - `query-string@6.0.0` -* [`e02fa7497`](https://github.com/npm/npm/commit/e02fa7497f89623dc155debd0143aa54994ace74) - `is-cidr@2.0.5` -* [`c8f8564be`](https://github.com/npm/npm/commit/c8f8564be6f644e202fccd9e3de01d64f346d870) - [`311e55512`](https://github.com/npm/npm/commit/311e5551243d67bf9f0d168322378061339ecff8) - `standard@11.0.1` diff --git a/changelogs/CHANGELOG-7.md b/changelogs/CHANGELOG-7.md deleted file mode 100644 index 81249c78aa65b..0000000000000 --- a/changelogs/CHANGELOG-7.md +++ /dev/null @@ -1,3644 +0,0 @@ -## v7.24.2 (2021-10-04) - -### BUG FIXES - -* [`56d6cfdc0`](https://github.com/npm/cli/commit/56d6cfdc0745fe919645389b94efb36760eb4179) - [#3804](https://github.com/npm/cli/issues/3804) - encode url before opening - ([@isaacs](https://github.com/isaacs)) -* [`075fe5056`](https://github.com/npm/cli/commit/075fe50565ae5c66df727cdd7df9dd5ed8cd4015) - [#3799](https://github.com/npm/cli/issues/3799) - restore exit code on "npm outdated" - ([@gfyoung](https://github.com/gfyoung)) -* [`dbb90f799`](https://github.com/npm/cli/commit/dbb90f7997900b8ae6026dddaa718efe9a1db2f4) - [#3809](https://github.com/npm/cli/issues/3809) - use Intl.Collator for string sorting when available - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`69ab10bbf`](https://github.com/npm/cli/commit/69ab10bbf83d42a5d3b5d3f43e5e5b861f3dfed0) - `is-core-module@2.7.0` -* [`e94ddeaca`](https://github.com/npm/cli/commit/e94ddeaca1e75ecc8f54ebcb3df222965e3635d1) - `@npmcli/arborist@2.9.0`: - * fix: avoid infinite loops in peer dep replacements - * fix: use Intl.Collator for string sorting when available - * feat(vuln): expose isDirect - -### DOCUMENTATION - -* [`f425950a6`](https://github.com/npm/cli/commit/f425950a6ca671b2df20703f70b59022c2858d4d) - [#3805](https://github.com/npm/cli/issues/3805) - remove npm Enterprise from documentation - ([@ethomson](https://github.com/ethomson)) -* [`bb0b2da6c`](https://github.com/npm/cli/commit/bb0b2da6c0275dd8c9eda894452ce45b2e8c4c51) - [#3699](https://github.com/npm/cli/issues/3699) - fix(docs): add note about workspace script order - ([@behnammodi](https://github.com/behnammodi)) - -## v7.24.1 (2021-09-23) - -### DEPENDENCIES - -* [`1be8d41e6`](https://github.com/npm/cli/commit/1be8d41e6f23f7a3d8411a31099ab546fbcb5bfa) - `socks-proxy-agent@6.1.0`: - * feat: allow passing tls connection options -* [`eafd55eae`](https://github.com/npm/cli/commit/eafd55eae219a6c15d2857d06b673a67d7f7d060) - `glob@7.2.0` - -### DOCS - -* [`dae5ce305`](https://github.com/npm/cli/commit/dae5ce3055ded57eab8aa3425004c60224a6fe67) - [#3784](https://github.com/npm/cli/issues/3784) - docs: document special meaning of registry.npmjs.com - ([@everett1992](https://github.com/everett1992)) - -## v7.24.0 (2021-09-16) - -### FEATURES - -* [`c7787b3fb`](https://github.com/npm/cli/commit/c7787b3fb7630aab84aae83ebf9a7117c7173b6b) - [`1fbbe1e04`](https://github.com/npm/cli/commit/1fbbe1e04be5d79c7b49910324e64c19ed599eeb) - bundled npm-install-checks ([@wraithgar](https://github.com/wraithgar)) - -### BUG FIXES - -* [`0320bd77e`](https://github.com/npm/cli/commit/0320bd77e2a38f48a88e377df4b122fd21043a83) - [#3739](https://github.com/npm/cli/issues/3739) - fix(view): Show the correct publish date for versions selected by range ([@andersk](https://github.com/andersk)) -* [`e4a521857`](https://github.com/npm/cli/commit/e4a5218573583149af795982a39fa64a4116cdab) - [#3748](https://github.com/npm/cli/issues/3748) - fix(install.sh): don't remove old npm first - ([@wraithgar](https://github.com/wraithgar)) -* [`b4aac345b`](https://github.com/npm/cli/commit/b4aac345b0a7cdec4d713c5be4daea37330b2b26) - [#3754](https://github.com/npm/cli/issues/3754) - fix(config): user-agent properly shows ci - ([@wraithgar](https://github.com/wraithgar)) -* [`b807cd62e`](https://github.com/npm/cli/commit/b807cd62eabe337e3243415c9870ea36d9289e12) - [#3738](https://github.com/npm/cli/issues/3738) - fix(search): return valid json for no results - ([@AyushRawal](https://github.com/AyushRawal)) -* [`2def17a3b`](https://github.com/npm/cli/commit/2def17a3b625b92b40c6185ff4b47e8ed006492c) - [#3760](https://github.com/npm/cli/issues/3760) - fix(install): use configured registry when checking manifest - ([@yacoman89](https://github.com/yacoman89)) -* [`ca792acdd`](https://github.com/npm/cli/commit/ca792acdd4ba683d8415c88188ec6739033fb4fd) - [#3761](https://github.com/npm/cli/issues/3761) - fix(logs): clean args for failed commands - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`59743972c`](https://github.com/npm/cli/commit/59743972c2ae1d2dd601aaa6c59974c686b1cb29) - [#3747](https://github.com/npm/cli/issues/3747) - fix(did-you-mean): succeed if cwd is not a package - ([@wraithgar](https://github.com/wraithgar)) -* [`ac8e4ad18`](https://github.com/npm/cli/commit/ac8e4ad18a6b726dd2c3abcb0f605701cca0ae2c) - `init-package-json@2.0.5`: - * fix: bin script path -* [`371655a6b`](https://github.com/npm/cli/commit/371655a6b0e6664fec67f16cb247cc9f174a5197) - `minipass@3.1.5`: - * fix: re-emit 'error' event if missed and new listener added - * fix: do not blow up if process is missing - -### DOCUMENTATION - -* [`4d93b484a`](https://github.com/npm/cli/commit/4d93b484abb50e3704fb436db572b93fb36c7ac3) - [#3759](https://github.com/npm/cli/issues/3759) - fix(docs): use correct hyperlink to package-json - ([@nategreen](https://github.com/nategreen)) - -## v7.23.0 (2021-09-09) - -### FEATURES - -* [`6c12500ae`](https://github.com/npm/cli/commit/6c12500ae14a6f8b78e3ab091ee6cc8e2ea9fd23) - [#3731](https://github.com/npm/cli/issues/3731) - feat(install): very strict global npm engines - ([@wraithgar](https://github.com/wraithgar)) - -### BUG FIXES - -* [`1ad093824`](https://github.com/npm/cli/commit/1ad0938243110d983284e8763da41a57b561563d) - [#3732](https://github.com/npm/cli/issues/3732) - fix(error-message): clean urls from 404 error - ([@wraithgar](https://github.com/wraithgar)) - -### DOCUMENTATION - -* [`64f7d1a55`](https://github.com/npm/cli/commit/64f7d1a55db99b1aaf8fb59557b3dedcdcd954a0) - [#3727](https://github.com/npm/cli/issues/3727) - docs(contributing): add note on changes to tooling - ([@darcyclarke](https://github.com/darcyclarke)) -* [`eda9162f2`](https://github.com/npm/cli/commit/eda9162f2db19b512d3af6b0d43201d54045c13a) - [#3715](https://github.com/npm/cli/issues/3715) - Add --if-present flag documentation to workspaces - ([@Matsuuu](https://github.com/Matsuuu)) - -## v7.22.0 (2021-09-02) - -### BUG FIXES -* [`6f431fe23`](https://github.com/npm/cli/commit/6f431fe2325f77b4370f95848359a36fe7a011d1) - [#3690](https://github.com/npm/cli/issues/3690) - Fix one “see also” link - ([@tripu](https://github.com/tripu)) - -### DEPENDENCIES -* [`033e948c9`](https://github.com/npm/cli/commit/033e948c95b3455812e03a860ad1bd96a635e7eb) - `read-package-json@4.1.1`: - * feat: add types lookup - * fix(man): don't lose relative man path -* [`1fa549db0`](https://github.com/npm/cli/commit/1fa549db0955b55fd680a658809a6d97be306b06) - `@npmcli/config@2.3.0`: - * feat: export npm_config_local_prefix and npm_config_global_prefix to the environment -* [`e91578d10`](https://github.com/npm/cli/commit/e91578d10b1d5d930fec32e7070d975af4892140) - `minpass-fetch@1.4.1`: - * Made rejectUnauthorized depend on NODE_TLS_REJECT_UNAUTHORIZED -* [`6125db545`](https://github.com/npm/cli/commit/6125db545315da0217fe7b05062fd0a504c9a45b) - `are-we-there-yet@1.1.6` -* [`0dcda73b0`](https://github.com/npm/cli/commit/0dcda73b022083338c4cb755390a275757b9627b) - `string_decoder@1.3.0` -* [`4b913417c`](https://github.com/npm/cli/commit/4b913417c4e30980505a02eec50810f895dd52d7) - `npmlog@5.0.1` -* [`876c755eb`](https://github.com/npm/cli/commit/876c755eb0dfc215123682f798b5fca415f7c7d9) - `@npmcli/arborist@2.8.3`: - * fix: do not fail adding unresolvable optional dep - -## v7.21.1 (2021-08-26) - -### BUG FIXES - -* [`4e52217cb`](https://github.com/npm/cli/commit/4e52217cb25a697b0f6b0131bcb8c87e0dbcda53) - [#3684](https://github.com/npm/cli/issues/3684) - fix(config): respect --global, --package-lock-only - ([@nlf](https://github.com/nlf)) - -### DEPENDENCIES - -* [`e3878536f`](https://github.com/npm/cli/commit/e3878536f3612d9ddc3002c126cfa9a91021c7db) - `make-fetch-happen@9.1.0`: - * fix: use the same strictSSL default as tls.connect -* [`145f70cc1`](https://github.com/npm/cli/commit/145f70cc1b78dee4ffa53f557fa72d0948696839) - `read-package-json@4.0.1`: - * fix: Add gitHead in subdirectories too - * fix(man): don't resolve paths to man files -* [`3f4d37143`](https://github.com/npm/cli/commit/3f4d371432a1fc8280e73d8467acd0eed0bbef26) - `tar@6.1.11`: - * fix: perf regression on hot string munging path -* [`e63a942c6`](https://github.com/npm/cli/commit/e63a942c685233fa546788981ed9c144220d50e1) - `cacache@15.3.0`: - * feat: introduce @npmcli/fs for tmp dir methods - -### DOCUMENTATION - -* [`957fa6040`](https://github.com/npm/cli/commit/957fa604035992285572f63c38545eea86bbb1ff) - [#3681](https://github.com/npm/cli/issues/3681) - clarify uninstall lifecycle script - ([@fritzy](https://github.com/fritzy)) - -## v7.21.0 (2021-08-19) - -### FEATURES - -* [`ff34d6cd6`](https://github.com/npm/cli/commit/ff34d6cd6f2077962cba1ef9c893a958ac7174f8) - [#3592](https://github.com/npm/cli/issues/3592) - feat(cache): initial implementation of ls and rm - ([@fritzy](https://github.com/fritzy)) - -### BUG FIXES - -* [`32e88c943`](https://github.com/npm/cli/commit/32e88c94387bda6b25f66019793efcda8f01ef6e) - [#3640](https://github.com/npm/cli/issues/3640) - fix(did-you-mean): switch levenshtein libraries - ([@wraithgar](https://github.com/wraithgar)) -* [`487731cd5`](https://github.com/npm/cli/commit/487731cd56a22272c6ff72ef2fa7822368bf63e3) - [#3658](https://github.com/npm/cli/issues/3658) - fix(logging): sanitize logged argv - ([@wraithgar](https://github.com/wraithgar)) -* [`68a19bb02`](https://github.com/npm/cli/commit/68a19bb02aa0d7a566c8e2245f1e524b915faf09) - [#3661](https://github.com/npm/cli/issues/3661) - fix(error-message): look for er.path not er.file - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`df57f0d53`](https://github.com/npm/cli/commit/df57f0d532d406b3b1409454ea5f2255fcd08248) - `@npmcli/run-script@1.8.6` -* [`8183976cf`](https://github.com/npm/cli/commit/8183976cfa53bab6e9116ec5de97b04225c5d09b) - `normalize-package-data@3.0.3`: - * fix: account for "licence" as spelling variant -* [`f07772401`](https://github.com/npm/cli/commit/f07772401c3712d5f9b0dfeef88e1943229cfa79) - `init-package-json@2.0.4` -* [`991a3bd39`](https://github.com/npm/cli/commit/991a3bd39f0abf8614373f267419c7b8f6e279ac) - `read-package-json@4.0.0` -* [`e9e5ee560`](https://github.com/npm/cli/commit/e9e5ee560e2baf694843df852d027fb9f2dbcb06) - `@npmcli/arborist@2.8.2`: - * fix: treat top-level global packages as "top" nodes - * fix: load global symlinks implicitly as file: deps - * fix(reify): debug crash when extracting into symlink - * fix: node_modules must be a directory - * fix: make Node.children() a case-insensitive Map - * fix(reify): verify existing deps in nm are dirs -* [`b6f40b5f8`](https://github.com/npm/cli/commit/b6f40b5f85094387f2fa8d42b6a624644b8ddcf1) - `tar@6.1.10`: - * fix: prune dirCache properly for unicode, windows - * fix: reserve paths properly for unicode, windows - * fix: prevent path escape using drive-relative paths - * fix: drop dirCache for symlink on all platforms -* [`218cacadc`](https://github.com/npm/cli/commit/218cacadcf35879ce178813c699258e7ffe91fe9) - `is-core-module@2.6.0` -* [`7ac621cd1`](https://github.com/npm/cli/commit/7ac621cd14f2ffbf5c15c3258f537fdfddc21ac6) - `smart-buffer@4.2.0` -* [`94f92de13`](https://github.com/npm/cli/commit/94f92de138432c900b195b71949f4933e872f26a) - `make-fetch-happen@9.0.5` -* [`71cdfd898`](https://github.com/npm/cli/commit/71cdfd8983cd0c61f39bdf91f87d40aad3b081c2) - `spdx-license-ids@3.0.10`: - * update license list to v3.14 - -### DOCUMENTATION - -* [`ff6626ab6`](https://github.com/npm/cli/commit/ff6626ab6ca9b4e189a3bc56a762104927dbeedb) - [#3630](https://github.com/npm/cli/issues/3630) - fix(docs): update npm-publish access flag info - ([@austincho](https://github.com/austincho)) - -## v7.20.6 (2021-08-12) - -### DEPENDENCIES - -* [`5bebf280f`](https://github.com/npm/cli/commit/5bebf280f228e818524f6989caab1cfba1ffaf90) - `tar@6.1.8` - * fix: reserve paths case-insensitively -* [`5d89de44d`](https://github.com/npm/cli/commit/5d89de44daa636dc151eaefcafabb357540d35ce) - `tar@6.1.7`: - * fix: normalize paths on Windows systems -* [`a1bdbea97`](https://github.com/npm/cli/commit/a1bdbea974ebfc6694b4c8ad5da86215c2924dde) - [#3569](https://github.com/npm/cli/issues/3569) - * remove byte-size - ([@wraithgar](https://github.com/wraithgar)) -* [`61782fa85`](https://github.com/npm/cli/commit/61782fa858c278455ce144f975c6b0e3ea2d9944) - `@npmcli/map-workspaces@1.0.4`: - * fix: better error message for duplicate workspace names -* [`b88f770fa`](https://github.com/npm/cli/commit/b88f770faa2651ca0833e1c9eb361e9e07e0bbc3) - `@npmcli/arborist@2.8.1`: - * [#3632] Fix "cannot read property path of null" error in 'npm dedupe' - * fix(shrinkwrap): always set name on the root node - -### DOCUMENTATION - -* [`001f2c1b7`](https://github.com/npm/cli/commit/001f2c1b7e9474049a45709f0e80ee3c474a4ba9) - [#3621](https://github.com/npm/cli/issues/3621) - fix(docs): do not include certain files - ([@AkiJoey](https://github.com/AkiJoey)) -* [`d1812f1a6`](https://github.com/npm/cli/commit/d1812f1a627d6a4d4cb6d07d7735d2d2cc2cf264) - [#3630](https://github.com/npm/cli/issues/3630) - fix(docs): update npm-publish access flag info - ([@austincho](https://github.com/austincho)) -* [`d5a099c7b`](https://github.com/npm/cli/commit/d5a099c7bf62977a5a5d8242c61f323a88e27c73) - [#3615](https://github.com/npm/cli/issues/3615) - fix(readme): add nvm-windows to installers links - ([@Yash-Singh1](https://github.com/Yash-Singh1)) - -## v7.20.5 (2021-08-05) - -### DEPENDENCIES - -* [`44377738e`](https://github.com/npm/cli/commit/44377738ef6b53607a7b17162aec984d5dcf7c58) - `graceful-fs@4.2.8` - * fix: start retrying immediately, stop after 60 seconds - - -## v7.20.4 (2021-08-05) - -### BUG FIXES - -* [`6a8086e25`](https://github.com/npm/cli/commit/6a8086e258aa209b877e182db4b75f11de5b291d) - [#3463](https://github.com/npm/cli/issues/3463) - fix(tests): move more tests to use real npm - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`15fae4941`](https://github.com/npm/cli/commit/15fae4941475f4398e47d9cc4eb6a73683e15aac) - `tar@6.1.6`: - * fix: properly handle top-level files when using strip - * Avoid an unlikely but theoretically possible redos - * WriteEntry backpressure - * fix(unpack): always resume parsing after an entry error - * fix(unpack): fix hang on large file on open() fail - * fix: properly prefix hard links -* [`745326de0`](https://github.com/npm/cli/commit/745326de0fae9f27f1deaf7729777aae48ac29fc) - `libnpmexec@2.0.1`: - * Clear progress bar which overlays confirm prompt -* [`e82bcd4e8`](https://github.com/npm/cli/commit/e82bcd4e8355d083f8f3eedb6251a5f3053d6dfd) - `graceful-fs@4.2.7`: - * fix: start retrying immediately, stop after 10 attempts - -## v7.20.3 (2021-07-29) - -### BUG FIXES - -* [`66dc5f94d`](https://github.com/npm/cli/commit/66dc5f94dfb5bc99c715e075cde1ab9c1ec84a83) - [#3588](https://github.com/npm/cli/issues/3588) - update eresolve explanations for new arborist data provided -* [`99575acab`](https://github.com/npm/cli/commit/99575acab5c93c03c59cb918c7916647b2c0be51) - [#3591](https://github.com/npm/cli/issues/3591) - fix(node_modules): remove duplicated file - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`97cb5ec31`](https://github.com/npm/cli/commit/97cb5ec312e151527ba2aab77ed0307917e1d845) - `@npmcli/arborist@2.8.0`: - * Refactor ideal tree building to handle more complicated - peerDependencies use cases. - * Do not modify ideal tree while checking if a peerSet can be placed. -* [`7db1a0a26`](https://github.com/npm/cli/commit/7db1a0a264cf67d2a2a3cdc71bbf09b36dc45075) - chore(deps): `mime-types@1.49.0` `mime-db@1.49.0` - -## v7.20.2 (2021-07-27) - -### DEPENDENCIES - -* [`f5aab1f88`](https://github.com/npm/cli/commit/f5aab1f8878b4e9a6f4d47dddc449e18a190e201) - `tar@6.1.1` - * fix: strip absolute paths more comprehensively -* [`ce8fb0f69`](https://github.com/npm/cli/commit/ce8fb0f69ae1b3fdd8834cf073d3d30c2bfc7bc6) - `tar@6.1.2` - * fix: Remove paths from dirCache when no longer dirs -* [`ced85087a`](https://github.com/npm/cli/commit/ced85087ac5fce5984ae28af910357a9a94434d7) - `gauge@3.0.1` - * add missing dependency to package.json - -## v7.20.1 (2021-07-22) - -### BUG FIXES - -* [`009ad1e68`](https://github.com/npm/cli/commit/009ad1e683aa061d7e5c78b9362b0bd1b14ee643) - [#3561](https://github.com/npm/cli/issues/3561) - fix(exit-handler): always warn if not called - ([@wraithgar](https://github.com/wraithgar)) -* [`eb67054c8`](https://github.com/npm/cli/commit/eb67054c8303348b25f9717c8f82c8d8d494a242) - [#3563](https://github.com/npm/cli/issues/3563) - fix(config): consolidate use of npm.color - ([@wraithgar](https://github.com/wraithgar)) - -### DOCUMENTATION - -* [`a014f3d28`](https://github.com/npm/cli/commit/a014f3d284e49cd085cfd060a71a161b93bca9d1) - [#3562](https://github.com/npm/cli/issues/3562) - fix(docs): typo in `npm cmd` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`1fe1c9b74`](https://github.com/npm/cli/commit/1fe1c9b74ea3c3d5bb5b3696b954422b9b55dd91) - [#3523](https://github.com/npm/cli/issues/3523) - fix(docs): updated policy urls - ([@DemiraDimitrova](https://github.com/DemiraDimitrova)) - -### DEPENDENCIES - -* [`d7f29e8c9`](https://github.com/npm/cli/commit/d7f29e8c94ae77661390f82ae72efc1bd6fcfbc3) - `read-package-json-fast@2.0.3`: - - feat: load directories.bin as a bin object -* [`b1fefa73d`](https://github.com/npm/cli/commit/b1fefa73db2f8d9c55b4447ffc1cdbaf8e9bb298) - `npmlog@5.0.0` - * Drop support for node 6 and 8 -* [`b6e09971a`](https://github.com/npm/cli/commit/b6e09971a8f9a3c92188838b69be0a0dda27f0bb) - remove ignored files from node_modules - ([@Ruy Adorno](https://github.com/Ruy Adorno)) -* [`cf737c505`](https://github.com/npm/cli/commit/cf737c505e76a473850c5244b17f3469efbc3c02) - `debug@4.3.2` - -## v7.20.0 (2021-07-15) - -### FEATURES - -* [`f17aca5cd`](https://github.com/npm/cli/commit/f17aca5cdf355aaa7e1f517d1b3bb4213f4df092) - [#3487](https://github.com/npm/cli/issues/3487) - feat: add `npm pkg` command - ([@ruyadorno](https://github.com/ruyadorno)) -* [`98905ae37`](https://github.com/npm/cli/commit/98905ae3759165cd6d6f6306f31acc6a2baa4cde) - [#3471](https://github.com/npm/cli/issues/3471) - feat(config): introduce `location` parameter - ([@nlf](https://github.com/nlf)) - -### BUG FIXES - -* [`4755b0728`](https://github.com/npm/cli/commit/4755b072877f547585cb0e2562261b2c87e2ff0b) - [#3498](https://github.com/npm/cli/issues/3498) - friendlier errors for `ERR_SOCKET_TIMEOUT` - ([@nlf](https://github.com/nlf)) -* [`3ecf19cdc`](https://github.com/npm/cli/commit/3ecf19cdc35684ccb15280b2c34d27496aa1c634) - [#3508](https://github.com/npm/cli/issues/3508) - fix(config): fix noproxy - ([@wraithgar](https://github.com/wraithgar)) -* [`c3bd10e46`](https://github.com/npm/cli/commit/c3bd10e461976a073e6a898c46f8bde28b17668f) - [#3499](https://github.com/npm/cli/issues/3499) - fix(update-notifier): don't force black background - ([@wraithgar](https://github.com/wraithgar)) -* [`89483e888`](https://github.com/npm/cli/commit/89483e888acc56386b9ebc4d70a4676e4a5a5cb1) - [#3497](https://github.com/npm/cli/issues/3497) - fix(usage): better audit/boolean flag usage output - ([@wraithgar](https://github.com/wraithgar)) -* [`feeb8e42a`](https://github.com/npm/cli/commit/feeb8e42a7b0510023175dc86269edb544d97601) - [#3495](https://github.com/npm/cli/issues/3495) - fix(publish): obey --ignore-scripts flag - ([@wraithgar](https://github.com/wraithgar)) -* [`103c8c3ef`](https://github.com/npm/cli/commit/103c8c3ef3ba7ff0483557f32eebc4c6298285e3) - [#3479](https://github.com/npm/cli/issues/3479) - chore(exit): log any un-ended timings - ([@wraithgar](https://github.com/wraithgar)) -* [`efc4313c2`](https://github.com/npm/cli/commit/efc4313c2062ffad22aa24e5198d575a7eb5f20e) - [#3482](https://github.com/npm/cli/issues/3482) - chore(refactor): refactor exit handler and tests - ([@wraithgar](https://github.com/wraithgar)) -* [`d8eb49b70`](https://github.com/npm/cli/commit/d8eb49b705acb50b6bed971bfcce4db6e18e73dd) - [#3540](https://github.com/npm/cli/issues/3540) - fix(bundle-and-ignore): case sensitivity cleanup - ([@wraithgar](https://github.com/wraithgar)) - -### DOCUMENTATION - -* [`339145f64`](https://github.com/npm/cli/commit/339145f64f82d540dbc72ef97b54ae20c34315dd) - [#3491](https://github.com/npm/cli/issues/3491) - fix(docs): clarify what install type gets `.bin` - ([@wraithgar](https://github.com/wraithgar)) -* [`74c99755e`](https://github.com/npm/cli/commit/74c99755e522f9cfc0d602841568d5e1f835fcaf) - [#3494](https://github.com/npm/cli/issues/3494) - fix(docs): add npm update example - ([@wraithgar](https://github.com/wraithgar)) -* [`801a52330`](https://github.com/npm/cli/commit/801a52330636008fecadc812916c76fb945ce1f6) - [#3542](https://github.com/npm/cli/issues/3542) - fix(docs): correct Node.js JavaScript stylings - ([@relrelb](https://github.com/relrelb)) -* [`791416713`](https://github.com/npm/cli/commit/791416713d64c072d73bffbab2daf7b8eb3c4868) - [#3546](https://github.com/npm/cli/issues/3546) - fix(docs): how to see background script output - ([@cinderblock](https://github.com/cinderblock)) - -### DEPENDENCIES - -* [`691816f3d`](https://github.com/npm/cli/commit/691816f3de2a679152644a60f3e2c5962df6a81d) - `@npmcli/arborist@2.7.1` - * fixes running prepare scripts for workspaces on reify - * ensure pacote always compares correct integrity values -* [`b9597e944`](https://github.com/npm/cli/commit/b9597e944377e74907607ee280ec1e8c31dd3156) - `make-fetch-happen@9.0.4` - * fix: retry socket timeout failures - * fix: clean up invalid indexes and content after cacache read errors -* [`f573e7c56`](https://github.com/npm/cli/commit/f573e7c56e8505fd6dcc3e5f5b5be401d0a45b58) - `minipass-fetch@1.3.4` - * fix: correctly handle error events that happen after response events -* [`2d5797ea0`](https://github.com/npm/cli/commit/2d5797ea01e17b1559d792613446e1435e588a35) - `pacote@11.3.5` - * fix: show more actionable messages for git pathspec errors - * fix: include all dep types when building for prepare - * fix: do not set mtime when unpacking - -## v7.19.1 (2021-07-01) - -### BUG FIXES - -* [`013f0262d`](https://github.com/npm/cli/commit/013f0262db3e16605820f6117749fd3ebc70f6d1) - [#3469](https://github.com/npm/cli/issues/3469) - fix(exitHandler): write code to logfile - ([@wraithgar](https://github.com/wraithgar)) -* [`0dd0341ac`](https://github.com/npm/cli/commit/0dd0341ac9a65a2df8fc262ad9a56b7351f99d66) - [#3474](https://github.com/npm/cli/issues/3474) - fix(ping): make "npm ping" echo a right time - ([@aluneed](https://github.com/aluneed)) -* [`d2e298f3c`](https://github.com/npm/cli/commit/d2e298f3cbab278071480f94ff7d916d42cbf43b) - [#3484](https://github.com/npm/cli/issues/3484) - fix(deprecate): add undeprecate support - ([@wraithgar](https://github.com/wraithgar)) - - ### DOCUMENTATION - -* [`9dd32d08e`](https://github.com/npm/cli/commit/9dd32d08e09c21c9a4517161abfc7eed6518faf2) - [#3485](https://github.com/npm/cli/issues/3485) - fix(docs): remove npm package config override - ([@wraithgar](https://github.com/wraithgar)) -* [`a4e095618`](https://github.com/npm/cli/commit/a4e095618cda72244a18aaff9d6660b9082a2b84) - [#3486](https://github.com/npm/cli/issues/3486) - fix(docs): remove .hooks scripts - ([@wraithgar](https://github.com/wraithgar)) - -### TESTING - -* [`5f8ccccef`](https://github.com/npm/cli/commit/5f8ccccef9fc19229320df8cbcae9fcea8d31388) - [#3483](https://github.com/npm/cli/issues/3483) - chore(tests): clean snapshot for lib/view.js tests - ([@wraithgar](https://github.com/wraithgar)) - -## v7.19.0 (2021-06-24) - -### FEATURES - -* [`23ce3af19`](https://github.com/npm/cli/commit/23ce3af199c8a14ef16c63fc638a1ac21fd9a9b0) - [#3460](https://github.com/npm/cli/issues/3460) - feat(ls): report *why* something is invalid - ([@isaacs](https://github.com/isaacs)) - -### BUG FIXES - -* [`53f81af31`](https://github.com/npm/cli/commit/53f81af319f298a0fdd8f143184c3e89770f24ea) - [#3450](https://github.com/npm/cli/issues/3450) - fix(docs): Improve phrasing of workspace example - ([@lumaxis](https://github.com/lumaxis)) -* [`78da60ffe`](https://github.com/npm/cli/commit/78da60ffefcfd457a4432ce1492ee7b53d854450) - [#3454](https://github.com/npm/cli/issues/3454) - chore(linting): add bin and clean up lib/ls.js -* [`54eae3063`](https://github.com/npm/cli/commit/54eae3063eeb197225ee930525a1316e34ecf34c) - [#3416](https://github.com/npm/cli/issues/3416) - chore(errorHandler): rename to exit handler - ([@wraithgar](https://github.com/wraithgar)) -* [`d0f50b156`](https://github.com/npm/cli/commit/d0f50b156725e5b414050d9e9a59d5fad8a39a3d) - [#3451](https://github.com/npm/cli/issues/3451) - chore(refactor): async npm.load - ([@wraithgar](https://github.com/wraithgar)) -* [`87f67d9ef`](https://github.com/npm/cli/commit/87f67d9efaf6f897cf0d74e738c2625a21044109) - [#3458](https://github.com/npm/cli/issues/3458) - chore(tests): expose real mock npm object - ([@wraithgar](https://github.com/wraithgar)) -* [`f3dce0917`](https://github.com/npm/cli/commit/f3dce0917088dc37795af39e7f6b5089beff984c) - [#3459](https://github.com/npm/cli/issues/3459) - chore(config): snapshot config descriptions - ([@wraithgar](https://github.com/wraithgar)) -* [`6254b6f72`](https://github.com/npm/cli/commit/6254b6f726a301908f73b36ccfa52cd4fd6619e5) - [#3234](https://github.com/npm/cli/issues/3234) - [#3455](https://github.com/npm/cli/issues/3455) - @npmcli/package-json refactor - ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`fe4138381`](https://github.com/npm/cli/commit/fe4138381fd2e8c919bb9f794e20033ff049f783) - `@npmcli/arborist@2.6.4`: - * bin: allow turning off timer display with --timers=false - * fix: do not try to inflate a fresh lockfile - * fix(diff): walk target children if root is a link - * chore: @npmcli/package-json refactor - -## v7.18.1 (2021-06-17) - -## BUG FIXES - -* [`fce30e423`](https://github.com/npm/cli/commit/fce30e423745a2b81530176d2f08ca84896eef4c) - [#3435](https://github.com/npm/cli/issues/3435) - fix(docs): rebuild config docs - ([@wraithgar](https://github.com/wraithgar)) - -## v7.18.0 (2021-06-17) - -## FEATURES - -* [`ae285b391`](https://github.com/npm/cli/commit/ae285b39191f3a0c4edfb045a334057bef4567b5) - [#3408](https://github.com/npm/cli/issues/3408) - feat(ls): support `--package-lock-only` flag - ([@G-Rath](https://github.com/G-Rath)) -* [`c984fb59c`](https://github.com/npm/cli/commit/c984fb59c5af087b91acd927cbbacad7c6a46576) - [#3420](https://github.com/npm/cli/issues/3420) - feat(pack): add pack-destination config - ([@wraithgar](https://github.com/wraithgar)) - -## BUG FIXES - -* [`40829ec40`](https://github.com/npm/cli/commit/40829ec40c33a6d23f18715e60e3395bdcb0467e) - [#2554](https://github.com/npm/cli/issues/2554) - [#3399](https://github.com/npm/cli/issues/3399) - fix(link): do not prune packages - ([@ruyadorno](https://github.com/ruyadorno)) -* [`102d4e6fb`](https://github.com/npm/cli/commit/102d4e6fb3c3b02148dbeee977a7d1e6372340d5) - [#3417](https://github.com/npm/cli/issues/3417) - fix(workspaces): explicitly error in global mode - ([@wraithgar](https://github.com/wraithgar)) -* [`993df3041`](https://github.com/npm/cli/commit/993df3041f5bdaa496c3c8d80f00d16b9cf0a1e6) - [#3423](https://github.com/npm/cli/issues/3423) - fix(docs): ls command usage instructions - ([@gurdiga](https://github.com/gurdiga)) -* [`dcc13662c`](https://github.com/npm/cli/commit/dcc13662c1d3e22eaf392647a9cddbb5b0710d24) - [#3418](https://github.com/npm/cli/issues/3418) - fix(config): update link definition - ([@wraithgar](https://github.com/wraithgar)) -* [`b19e56c2e`](https://github.com/npm/cli/commit/b19e56c2e54c035518165470c10480201cefa997) - [#3382](https://github.com/npm/cli/issues/3382) - [#3429](https://github.com/npm/cli/issues/3429) - fix(ls): respect prod config for workspaces - ([@ruyadorno](https://github.com/ruyadorno)) -* [`c99b8b53c`](https://github.com/npm/cli/commit/c99b8b53c3d7a9b0daa6d4416e9c40202ddd59a2) - [#3430](https://github.com/npm/cli/issues/3430) - fix(config): add flatOptions.npxCache - ([@wraithgar](https://github.com/wraithgar)) -* [`e5abf2a21`](https://github.com/npm/cli/commit/e5abf2a2171d95bafc0993f337230d2b6633a6ed) - [#3386](https://github.com/npm/cli/issues/3386) - chore(libnpmdiff): added as workspace - ([@ruyadorno](https://github.com/ruyadorno)) -* [`c6a8734d7`](https://github.com/npm/cli/commit/c6a8734d7d6e4b6d061110a01e45e1d418d56489) - [#3388](https://github.com/npm/cli/issues/3388) - chore(refactor): finish passing npm context - ([@wraithgar](https://github.com/wraithgar)) -* [`d16ee452a`](https://github.com/npm/cli/commit/d16ee452a4a034caada4e9b96faf5c453a658876) - [#3426](https://github.com/npm/cli/issues/3426) - chore(tests): use path.resolve - ([@wraithgar](https://github.com/wraithgar)) - -## DEPENDENCIES - -* [`6b951c042`](https://github.com/npm/cli/commit/6b951c042084e639be929a7ea783c2d85b311bad) - `libnpmversion@1.2.1`: - * fix(retrieve-tag): pass match in a way git accepts -* [`de820a021`](https://github.com/npm/cli/commit/de820a0213f54bbcd155dff25b05d072d5c4a57a) - `npm-package-arg@8.1.5`: - * fix: Make file: URLs (mostly) RFC 8909 compliant -* [`16a95c647`](https://github.com/npm/cli/commit/16a95c64731609c69630c17c45b16edb53ee81b2) - `@npmcli/arborist@2.6.3`: - * fix(inventory) handle old and british forms of 'license' - * fix: removes [_complete] check to apply correct metadata - * ensure node.fsParent is not set to node itself - * fix extraneous deps on load-actual -* [`d341bd86c`](https://github.com/npm/cli/commit/d341bd86ce05fabe44f3be5888ba2611b61914b4) - `make-fetch-happen@9.0.3`: - * fix: implement cache modes correctly -* [`c90612cf5`](https://github.com/npm/cli/commit/c90612cf566d563199553749900d8b05367e2532) - `libnpmexec@2.0.0`: - * use new npxCache option - - -## v7.17.0 (2021-06-10) - -## FEATURES - -* [`ef668ab57`](https://github.com/npm/cli/commit/ef668ab57b15789c6e2971ac39d8ecb3757629fa) - [#3368](https://github.com/npm/cli/issues/3368) - feat(diff): add workspace support - ([@wraithgar](https://github.com/wraithgar)) - -## BUG FIXES - -* [`26d00c477`](https://github.com/npm/cli/commit/26d00c47785dfb300eab6a926f9d7c4d566776b1) - [#3364](https://github.com/npm/cli/issues/3364) - fix(tests): mock writeFile in pack tests so we dont create 0 byte files in the repo - ([@nlf](https://github.com/nlf)) -* [`f130a81d6`](https://github.com/npm/cli/commit/f130a81d62bf4f540ab252a09ff5a618827f9265) - [#3367](https://github.com/npm/cli/issues/3367) - fix(linting): add scripts, docs, smoke-tests - ([@wraithgar](https://github.com/wraithgar)) -* [`992799cd8`](https://github.com/npm/cli/commit/992799cd8c4427ed8c57270b399b2d6bbc94f2a8) - [#3383](https://github.com/npm/cli/issues/3383) - fix(login): properly save scope if defined - ([@wraithgar](https://github.com/wraithgar)) - -## DOCUMENTATION - -* [`844229519`](https://github.com/npm/cli/commit/844229519dd51d0bcafc8c39109a671b6333cf6c) - [#3392](https://github.com/npm/cli/issues/3392) - docs(workspaces): update using npm section - Added examples of using `npm init` to bootstrap a new workspace and a - section on how to add/manage dependencies to workspaces. - ([@ruyadorno](https://github.com/ruyadorno)) - -## DEPENDENCIES - -* [`3654890fb`](https://github.com/npm/cli/commit/3654890fb3be8b57e73f7e6ac4d895017603ca9e) - remove ignored dep - ([@nlf](https://github.com/nlf)) -* [`a4a0e68a9`](https://github.com/npm/cli/commit/a4a0e68a9e34a4c99e10e4fb8c5f89d323a4192f) - [#3362](https://github.com/npm/cli/issues/3362) - check less stuff into node_modules - ([@isaacs](https://github.com/isaacs)) -* [`7d5b049b6`](https://github.com/npm/cli/commit/7d5b049b654f96fc4c49d2f18a19adb4aa0f7d3c) - [#3365](https://github.com/npm/cli/issues/3365) - chore(package) Use a "files" list - ([@isaacs](https://github.com/isaacs)) - -## v7.16.0 (2021-06-03) - -## FEATURES - -* [`e92b5f2ba`](https://github.com/npm/cli/commit/e92b5f2ba07746ae07646566f3dc73c9e004a2fc) - `npm-registry-fetch@11.0.0` - * feat: improved logging of cache status - -## BUG FIXES - -* [`e864bd3ce`](https://github.com/npm/cli/commit/e864bd3ce8e8467e0f8ebb499dc2daf06143bc33) - [#3345](https://github.com/npm/cli/issues/3345) - fix(update-notifier): do not update notify when installing npm@spec - ([@isaacs](https://github.com/isaacs)) -* [`aafe23572`](https://github.com/npm/cli/commit/aafe2357279230e333d3342752a28fce6b9cd152) - [#3348](https://github.com/npm/cli/issues/3348) - fix(update-notifier): parallelize check for updates - ([@isaacs](https://github.com/isaacs)) - -## DOCUMENTATION - -* [`bc9c57dda`](https://github.com/npm/cli/commit/bc9c57dda7cf3abcdee17550205daf1a82e90438) - [#3353](https://github.com/npm/cli/issues/3353) - fix(docs): remove documentation for '--scripts-prepend-node-path' as it was removed in npm@7 - ([@gimli01](https://github.com/gimli01)) -* [`ca2822110`](https://github.com/npm/cli/commit/ca28221103aa0e9ccba7043ac515a541b625c53a) - [#3360](https://github.com/npm/cli/issues/3360) - fix(docs): link foreground-scripts w/ loglevel - ([@wraithgar](https://github.com/wraithgar)) -* [`fb630b5a9`](https://github.com/npm/cli/commit/fb630b5a9af86c71602803297634ec291eeedee0) - [#3342](https://github.com/npm/cli/issues/3342) - chore(docs): manage docs as a workspace - ([@ruyadorno](https://github.com/ruyadorno)) - -## DEPENDENCIES - -* [`54de5c6a4`](https://github.com/npm/cli/commit/54de5c6a4cd593bbbe364132f3f7348586441b31) - `npm-package-arg@8.1.4`: - * fix: trim whitespace from fetchSpec - * fix: handle file: when root directory begins with a special character -* [`e92b5f2ba`](https://github.com/npm/cli/commit/e92b5f2ba07746ae07646566f3dc73c9e004a2fc) - `make-fetch-happen@9.0.1` - * breaking: complete refactor of caching. drops warning headers, - prevents cache indexes from growing for every request, correctly - handles varied requests to the same url, and now caches redirects. - * fix: support url-encoded proxy authorization - * fix: do not lazy-load proxy agents or agentkeepalive. fixes the - intermittent failures to update npm on slower connections. - `npm-registry-fetch@11.0.0` - * breaking: drop handling of deprecated warning headers - * docs: fix header type for npm-command - * docs: update registry param - * feat: improved logging of cache status -* [`23c50a45f`](https://github.com/npm/cli/commit/23c50a45f59ea3ed4c36f35df15e54adc5603034) - `make-fetch-happen@9.0.2`: - * fix: work around negotiator's lazy loading - -## AUTOMATION - -* [`c4ef78b08`](https://github.com/npm/cli/commit/c4ef78b08e6859fc191cabbe58c8d88c070e0612) - [#3344](https://github.com/npm/cli/issues/3344) - fix(automation): update incorrect variable name in create-cli-deps-pr workflow - ([@gimli01](https://github.com/gimli01)) - -## v7.15.1 (2021-05-31) - -### BUG FIXES - -* [`598a17a26`](https://github.com/npm/cli/commit/598a17a2671c9e3bc204dddd6488169c9a72c6a1) - [#3329](https://github.com/npm/cli/issues/3329) - fix(libnpmexec): don't detach output from npm - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`c4fc03e9e`](https://github.com/npm/cli/commit/c4fc03e9eb3a6386e8feacb67c19f0a1578dfe38) - `@npmcli/arborist@2.6.1` - * fixes reifying deps with mismatching version ranges between - actual and virtual trees -* [`9159fa62a`](https://github.com/npm/cli/commit/9159fa62a10dee09daef178fc7be161a02824004) - `libnpmexec@1.2.0` - -## v7.15.0 (2021-05-27) - -### FEATURES - -* [`399ff8cbc`](https://github.com/npm/cli/commit/399ff8cbccd5198f637518ccafa86c43bab47a4a) - [#3312](https://github.com/npm/cli/issues/3312) - feat(link): add workspace support - ([@isaacs](https://github.com/isaacs)) - -### BUG FIXES - -* [`46a9bcbcb`](https://github.com/npm/cli/commit/46a9bcbcb0bb2435dca6f45a61b8631f580c7f06) - [#3282](https://github.com/npm/cli/issues/3282) - fix(docs): proper postinstall script file name - ([@KevinFCormier](https://github.com/KevinFCormier)) -* [`83590d40f`](https://github.com/npm/cli/commit/83590d40f94347f21714dbd158b9ddcad9c82de9) - [#3272](https://github.com/npm/cli/issues/3272) - fix(ls): show relative paths from root - ([@isaacs](https://github.com/isaacs)) -* [`a574b518a`](https://github.com/npm/cli/commit/a574b518ae5b8f0664ed388cf1be6288d8c2e68d) - [#3304](https://github.com/npm/cli/issues/3304) - fix(completion): restore IFS even if `npm completion` returns error - ([@NariyasuHeseri](https://github.com/NariyasuHeseri)) -* [`554e8a5cd`](https://github.com/npm/cli/commit/554e8a5cd7034052a59a9ada31e4b8f73712211a) - [#3311](https://github.com/npm/cli/issues/3311) - set audit exit code properly - ([@isaacs](https://github.com/isaacs)) -* [`4a4fbe33c`](https://github.com/npm/cli/commit/4a4fbe33c51413adcd558b4af6f1e204b1b87e41) - [#3268](https://github.com/npm/cli/issues/3268) - [#3285](https://github.com/npm/cli/issues/3285) - fix(publish): skip private workspaces - ([@ruyadorno](https://github.com/ruyadorno)) - -### DOCUMENTATION - -* [`3c53d631f`](https://github.com/npm/cli/commit/3c53d631f557cf2484e2f6a6172c44e36aea4817) - [#3307](https://github.com/npm/cli/issues/3307) - fix(docs): typo in package-lock.json docs - ([@rethab](https://github.com/rethab)) -* [`96367f93f`](https://github.com/npm/cli/commit/96367f93f46c24494d084c8b8d34e4de9cd375da) - rebuild npm-pack doc - ([@isaacs](https://github.com/isaacs)) -* [`64b13dd10`](https://github.com/npm/cli/commit/64b13dd1082b6ca7eac4e8e329bfdd8cd8daf157) - [#3313](https://github.com/npm/cli/issues/3313) - Drop stale Python 3<->node-gyp remark - ([@spencerwilson](https://github.com/spencerwilson)) - -### DEPENDENCIES - -* [`7b56bfdf3`](https://github.com/npm/cli/commit/7b56bfdf3f2ac67a926fc7893b883a16b46eb3fd) - `cacache@15.2.0`: - * feat: allow fully deleting indices - * feat: add a validateEntry option to compact - * chore: lint - * chore: use standard npm style release scripts -* [`dbbc151a3`](https://github.com/npm/cli/commit/dbbc151a3bcf89e2627dc267063edd185ead1cb8) - `npm-audit-report@2.1.5`: - * fix(exit-code): account for null auditLevel default (#46) -* [`5b2604507`](https://github.com/npm/cli/commit/5b26045076477d3d350f539e60adf48a80376fda) - chore(package-lock): update devDependencies - ([@Gar](https://github.com/Gar)) - -### AUTOMATION - -* [`3d5df0082`](https://github.com/npm/cli/commit/3d5df0082ae904dacdea8644286e8362d4a2ed50) - [#3294](https://github.com/npm/cli/issues/3294) - chore(ci): move node release PR workflow to cli repo - ([@gimli01](https://github.com/gimli01)) - -## v7.14.0 (2021-05-20) - -### FEATURES - -* [`0d1a9d787`](https://github.com/npm/cli/commit/0d1a9d78779dc015242fc03d2dad2039004fa2df) - [#3227](https://github.com/npm/cli/issues/3227) - feat(install): add workspaces support to npm install commands - ([@isaacs](https://github.com/isaacs)) -* [`c18626f04`](https://github.com/npm/cli/commit/c18626f047e3a0fedd3c86554a4a0a8f27925e77) - [#3250](https://github.com/npm/cli/issues/3250) - feat(ls): add workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) -* [`41099d395`](https://github.com/npm/cli/commit/41099d3958d08f166313b7eb69b76458f8f9224c) - [#3265](https://github.com/npm/cli/issues/3265) - feat(explain): add workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) -* [`fde354669`](https://github.com/npm/cli/commit/fde35466915b5ac5958c827fa7e919e1f186db51) - [#3251](https://github.com/npm/cli/issues/3251) - feat(unpublish): add workspace/dry-run support - ([@wraithgar](https://github.com/wraithgar)) -* [`83df3666c`](https://github.com/npm/cli/commit/83df3666cd82819230fb45f2a40afd531fe3b3c7) - [#3260](https://github.com/npm/cli/issues/3260) - feat(outdated): add workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) -* [`63a7635f7`](https://github.com/npm/cli/commit/63a7635f7a2225a4edd1fe92f94a563965ac06c7) - [#3217](https://github.com/npm/cli/issues/3217) - feat(pack): add support to json config/output - ([@mrmlnc](https://github.com/mrmlnc)) - -### BUG FIXES - -* [`faa12ccc2`](https://github.com/npm/cli/commit/faa12ccc26b5f0790f79b2589780e536f4284491) - [#3253](https://github.com/npm/cli/issues/3253) - fix search description typos - ([@juanpicado](https://github.com/juanpicado)) -* [`2f5c28a68`](https://github.com/npm/cli/commit/2f5c28a68719e948d2efedf463ebcb35972aaefb) - [#3243](https://github.com/npm/cli/issues/3243) - fix(docs): autogenerate config docs for commands - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`ec256a14a`](https://github.com/npm/cli/commit/ec256a14aa6eb2bd59fd55dcc6a4bc0148662c4e) - `@npmcli/arborist@2.6.0` -* [`5f15aba86`](https://github.com/npm/cli/commit/5f15aba866026e7c0d6844e6c07a528dc7454f14) - `cacache@15.1.0` -* [`b3add87e6`](https://github.com/npm/cli/commit/b3add87e686968b7af3067c685d2561baf90e397) - [#3262](https://github.com/npm/cli/pull/3262) - `npm-registry-client@10.1.2`: - * fixed sso login token - -## v7.13.0 (2021-05-13) - -### FEATURES - -* [`076420c14`](https://github.com/npm/cli/commit/076420c149d097056f687e44e21744b743b86e4e) - [#3231](https://github.com/npm/cli/issues/3231) - feat(publish): add workspace support - ([@wraithgar](https://github.com/wraithgar)) -* [`370b36a36`](https://github.com/npm/cli/commit/370b36a36ca226840761e4214cbccaf2a1a90e3c) - [#3241](https://github.com/npm/cli/issues/3241) - feat(fund): add workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`0c18e4f77`](https://github.com/npm/cli/commit/0c18e4f774562fa054fedf323bea25805ebf39b3) - `@npmcli/arborist@2.5.0` -* [`b551c6811`](https://github.com/npm/cli/commit/b551c6811251dbc901f47fea3c137f93e205a9e4) - `libnpmfund@1.1.0` - -## v7.12.1 (2021-05-10) - -### BUG FIXES - -* [`de49f58f5`](https://github.com/npm/cli/commit/de49f58f55dc2ac3a5057cd492a43c32ae41381e) - [#3216](https://github.com/npm/cli/issues/3216) - fix(contributing): link to proper cli repo - ([@mrmlnc](https://github.com/mrmlnc)) -* [`1d092144e`](https://github.com/npm/cli/commit/1d092144eaaabff63ac8424b40b2286822be7677) - [#3203](https://github.com/npm/cli/issues/3203) - fix(packages): locale-agnostic string sorting - ([@isaacs](https://github.com/isaacs)) -* [`0696fca13`](https://github.com/npm/cli/commit/0696fca13d10726e04ca97ff50eef7bd7455a3ab) - [#3209](https://github.com/npm/cli/issues/3209) - fix(view): fix non-registry specs - ([@wraithgar](https://github.com/wraithgar)) -* [`71ac93597`](https://github.com/npm/cli/commit/71ac935976390e4fd05987ff510049f82bc6e2a9) - [#3206](https://github.com/npm/cli/issues/3206) - chore(github): Convert md issue template to yaml - ([@lukehefson](https://github.com/lukehefson)) -* [`6fb386d3b`](https://github.com/npm/cli/commit/6fb386d3bfbaa8e4771ff87a08de1f3aa6f9b34d) - [#3201](https://github.com/npm/cli/issues/3201) - fix(tests): increase test fuzziness - ([@wraithgar](https://github.com/wraithgar)) -* [`f3a662fcd`](https://github.com/npm/cli/commit/f3a662fcd869653f9753aef3d40cc96ed28ed509) - [#3211](https://github.com/npm/cli/issues/3211) - fix(tests): use config defaults - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`285976fd1`](https://github.com/npm/cli/commit/285976fd12f037f59da47307d98df7ebda5278d9) - `@npmcli/arborist@2.4.4` - * fix(reify): properly save spec if prerelease -* [`f9f24d17c`](https://github.com/npm/cli/commit/f9f24d17c29c421de3c9b82c6b98a40268aeb920) - `libnpmexec@1.1.1` - * fix(add): Specify 'en' locale to String.localeCompare -* [`cb9f17499`](https://github.com/npm/cli/commit/cb9f174996dbb4779a1be82890564f9abffb11f4) - `glob@7.1.7` - * force 'en' locale in string sorting -* [`24b4e4a41`](https://github.com/npm/cli/commit/24b4e4a41b451db3de381fac6b719149db14c288) - `ignore-walk@3.0.4` - * Avoid locale-specific sorting issues -* [`1eb7e5c7d`](https://github.com/npm/cli/commit/1eb7e5c7d466293b472c2506c64e5a89ec84ac2f) - `@npmcli/arborist@2.4.3` - * guard against locale-specific sorting -* [`a6a826067`](https://github.com/npm/cli/commit/a6a826067cb46c711521772c2d0158257d54400a) - `npm-packlist@2.2.2`: - * fix(sort): avoid locale-dependent sorting issues - -## v7.12.0 (2021-05-06) - -### FEATURES - -* [`701627c51`](https://github.com/npm/cli/commit/701627c5169934e59da2959d76a49c77278cc9dc) - [#3098](https://github.com/npm/cli/issues/3098) - feat(cache): Allow `add` to accept multiple specs - ([@mjsir911](https://github.com/mjsir911)) -* [`59171f030`](https://github.com/npm/cli/commit/59171f0304f048a009f1697eec6f74f778bc52ff) - [#3187](https://github.com/npm/cli/issues/3187) - feat(config): add workspaces boolean to user-agent - ([@nlf](https://github.com/nlf)) - -### BUG FIXES - -* [`2c9b8713c`](https://github.com/npm/cli/commit/2c9b8713c4c88fbd0c3c48eb0de84dbd7269398f) - [#3182](https://github.com/npm/cli/issues/3182) - fix(docs): fix broken links - ([@wangsai](https://github.com/wangsai)) -* [`88cbc8c44`](https://github.com/npm/cli/commit/88cbc8c447cbaef20b5a8f19246211ce4918f4d8) - [#3198](https://github.com/npm/cli/issues/3198) - fix(tests): reflect new libnpmexec logic - -### DEPENDENCIES - -* [`d01ce5e13`](https://github.com/npm/cli/commit/d01ce5e132cb4661698012fd5017753c2bdb660b) - `libnpmexec@1.1.0`: - * feat: add walk up dir lookup to satisfy local bins -* [`81c1dfaaa`](https://github.com/npm/cli/commit/81c1dfaaaf918229316a975aa8075769ffafdb6d) - `@npmcli/arborist@2.4.2`: - * fix(add): save packages in the right place - * fix(reify): do not clean up nodes with no parent - * fix(audit): support alias specs & root package names -* [`87c2303ea`](https://github.com/npm/cli/commit/87c2303eaa6edfa5309da0a30f5ad291b6d57640) - `@npmcli/git@2.0.9`: - * fix(clone): Do not allow git replacement objects by default -* [`99ff40dff`](https://github.com/npm/cli/commit/99ff40dff5e5e55a5d5f045ba90e76c08174ca38) - `npm-packlist@2.2.0`: - * feat(npmignore): Do not force include history, changelogs, notice - * fix(package.json): add missing bin/index.js to files - -## v7.11.2 (2021-04-29) - -### BUG FIXES - -* [`c371f183e`](https://github.com/npm/cli/commit/c371f183ebe833c2439e98b679f14e7a59f22c34) - [#3137](https://github.com/npm/cli/issues/3137) - [#3140](https://github.com/npm/cli/issues/3140) - fix(ls): do not warn on missing optional deps - ([@isaacs](https://github.com/isaacs)) -* [`861f606c7`](https://github.com/npm/cli/commit/861f606c7609d177c644814a171581afbb72f6db) - [#3156](https://github.com/npm/cli/issues/3156) - fix(build): make prune rule work on case-sensitive file systems - ([@lpinca](https://github.com/lpinca)) - -### DEPENDENCIES - -* [`fb79d89a0`](https://github.com/npm/cli/commit/fb79d89a07ef03e76633db275463f701d3dae42f) - `tap@15.0.6` -* [`ce3820043`](https://github.com/npm/cli/commit/ce38200437e9ed527df973794909b2699909bc9b) - `@npmcli/arborist@2.4.1` - * fix: prevent and eliminate unnecessary duplicates - * fix: support resolvable partial intersecting peerSets - -### DOCUMENTATION - -* [`e479f1dac`](https://github.com/npm/cli/commit/e479f1dac9a7639304d20116583034861635b2b1) - [#3146](https://github.com/npm/cli/issues/3146) - mention `directories.bin` in `bin` - ([@felipecrs](https://github.com/felipecrs)) - -## v7.11.1 (2021-04-23) - -### DEPENDENCIES - -* [`7925cca24`](https://github.com/npm/cli/commit/7925cca24543d9e1a8297844b3e53e11057643ef) - `pacote@11.3.3`: - * fix(registry): normalize manfest -* [`b61eac693`](https://github.com/npm/cli/commit/b61eac693df82c52b955e6c18ec4dcf4cedea8a3) - [#3130](https://github.com/npm/cli/issues/3130) - `@npmcli/config@2.2.0` -* [`c74e67fc6`](https://github.com/npm/cli/commit/c74e67fc6572bb001d74c7486c05d211a0e03de8) - [#3130](https://github.com/npm/cli/issues/3130) - `npm-registry-fetch@10.1.1` - -### DOCUMENTATION - -* [`72a7eeb49`](https://github.com/npm/cli/commit/72a7eeb493e0e71cba3af36490cb245030ed31a3) - Remove unused and incorrectly documented `--always-auth` config definition - ([@isaacs](https://github.com/isaacs)) - -## v7.11.0 (2021-04-22) - -### FEATURES - -* [`4c1f16d2c`](https://github.com/npm/cli/commit/4c1f16d2c29a7a56c19b97f2820e6305a6075083) - [#3095](https://github.com/npm/cli/issues/3095) - feat(init): add workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) - -### BUG FIXES - -* [`42ca59eee`](https://github.com/npm/cli/commit/42ca59eeedd3e402aa1c606941f7f52864e6039b) - [#3086](https://github.com/npm/cli/issues/3086) - fix(ls): do not exit with error when all problems are extraneous deps - ([@nlf](https://github.com/nlf)) -* [`2aecec591`](https://github.com/npm/cli/commit/2aecec591df6866e27d0b17dc49cef8f7d738d77) - [#2724](https://github.com/npm/cli/issues/2724) - [#3119](https://github.com/npm/cli/issues/3119) - fix(ls): make --long work when missing deps - ([@ruyadorno](https://github.com/ruyadorno)) -* [`42e0587a9`](https://github.com/npm/cli/commit/42e0587a9ea6940a5d5be5903370ad1113feef21) - [#3115](https://github.com/npm/cli/issues/3115) - fix(pack): refuse to pack invalid packument - ([@wraithgar](https://github.com/wraithgar)) -* [`1c4eff7b5`](https://github.com/npm/cli/commit/1c4eff7b513b8e84876818ede014d3ab19d203c6) - [#3126](https://github.com/npm/cli/issues/3126) - fix(logout): use isBasicAuth attribute - ([@wraithgar](https://github.com/wraithgar)) - -### DOCUMENTATION - -* [`c93f1c39e`](https://github.com/npm/cli/commit/c93f1c39e326feff0857712a10ef6183fbafe1ab) - [#3101](https://github.com/npm/cli/issues/3101) - chore(docs): update view docs - ([@wraithgar](https://github.com/wraithgar)) -* [`c4ff4bc11`](https://github.com/npm/cli/commit/c4ff4bc113c3a5b6ee5d74ab0b1adee95169ed32) - [npm/statusboard#313](https://github.com/npm/statusboard/issues/313) - [#3109](https://github.com/npm/cli/issues/3109) - fix(usage): fix refs to ws shorthand - ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`83166ebcc`](https://github.com/npm/cli/commit/83166ebcc4ba5e3bf215f08151437d96637f4f33) - `npm-registry-fetch@10.1.0` - * feat(auth): set isBasicAuth -* [`e02bda6da`](https://github.com/npm/cli/commit/e02bda6da68b8e8f490bf270cb5d6adec81685ea) - `npm-registry-fetch@10.0.0` - * feat(auth) load/send based on URI, not registry -* [`a0382deba`](https://github.com/npm/cli/commit/a0382deba346b09834e75db89e1fd4527f1f07dd) - `@npmcli/run-script@1.8.5` - * fix: windows ComSpec env variable name -* [`7f82ef5a8`](https://github.com/npm/cli/commit/7f82ef5a84d70e28983ed43ba1d8aced0fb4ba45) - `pacote@11.3.2` -* [`35e49b94f`](https://github.com/npm/cli/commit/35e49b94fba478a63df6cc9b62816eafe5f1fbdd) - `@npmcli/arborist@2.4.0` -* [`95faf8ce6`](https://github.com/npm/cli/commit/95faf8ce6c007082a02c160977da194c08ee9d82) - `libnpmaccess@4.0.2` -* [`17fffc0e4`](https://github.com/npm/cli/commit/17fffc0e42b2a9e7b84691093e45ba511906cbfa) - `libnpmhook@6.0.2` -* [`1b5a213aa`](https://github.com/npm/cli/commit/1b5a213aaf39652661ba72ba2e8751f049b170fb) - `libnpmorg@2.0.2` -* [`9f83e6484`](https://github.com/npm/cli/commit/9f83e6484aa163d066f318df42ec89c8234b614e) - `libnpmpublish@4.0.1` -* [`251f788c5`](https://github.com/npm/cli/commit/251f788c554a198ab42682453fa5504f8abe93fe) - `libnpmsearch@3.1.1` -* [`35873a989`](https://github.com/npm/cli/commit/35873a989fe67041ddcf30a0a278ed77ace5ee3c) - `libnpmteam@2.0.3` -* [`23e12b4d8`](https://github.com/npm/cli/commit/23e12b4d8f63d765a48036e7bb08f53319c73304) - `npm-profile@5.0.3` - -## v7.10.0 (2021-04-15) - -### FEATURES - -* [`f9b639eb6`](https://github.com/npm/cli/commit/f9b639eb6c504ded6cdd59e83e26a392bfe81e5d) - [#3052](https://github.com/npm/cli/issues/3052) - feat(bugs): fall back to email if provided - ([@Yash-Singh1](https://github.com/Yash-Singh1)) -* [`8c9e24778`](https://github.com/npm/cli/commit/8c9e24778db867cb3148bc247c7e321639aa9f58) - [#3055](https://github.com/npm/cli/issues/3055) - feat(version): add workspace support - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`f1e6743a6`](https://github.com/npm/cli/commit/f1e6743a6e8e32ddad6d1964eb05d17e6c50a456) - `libnpmversion@1.2.0` - * feat(retrieve-tag): retrieve unannotated git tags - * fix(retrieve-tag): use semver to look for semver -* [`3b476a24c`](https://github.com/npm/cli/commit/3b476a24cf0b2823fdf92505b84bddde4fcc8b14) - `@npmcl/git@2.0.8` - * fix(git): do not use shell when calling git -* [`dfcd0c1e2`](https://github.com/npm/cli/commit/dfcd0c1e2331c1f4b6573466b50505772eddaf22) - [#3069](https://github.com/npm/cli/issues/3069) - `tap@15.0.2` - -### DOCUMENTATION - -* [`90b61eda9`](https://github.com/npm/cli/commit/90b61eda9b41af108ed69fc0c43a522a92745047) - [#3053](https://github.com/npm/cli/issues/3053) - fix(contributing.md): explicitely outline dep updates - ([@darcyclarke](https://github.com/darcyclarke)) - -## v7.9.0 (2021-04-08) - -### FEATURES - -* [`1f3e88eba`](https://github.com/npm/cli/commit/1f3e88ebaf4901d8f9f07b43404d824fef7e5ff5) - [#3032](https://github.com/npm/cli/issues/3032) - feat(dist-tag): add workspace support - ([@nlf](https://github.com/nlf)) -* [`6e31df4e7`](https://github.com/npm/cli/commit/6e31df4e7957337962fd3d93e495931e3592bb9e) - [#3033](https://github.com/npm/cli/issues/3033) - feat(pack): add workspace support - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`ba4f7fea8`](https://github.com/npm/cli/commit/ba4f7fea8fca8e3509469a218f094fe69095888b) - `licensee@8.2.0` - -## v7.8.0 (2021-04-01) - -### FEATURES - - -* [`8bcc5d73f`](https://github.com/npm/cli/commit/8bcc5d73f35434e781ff56419dd7f0c380efd072) - [#2972](https://github.com/npm/cli/issues/2972) - feat(workspaces): add repo and docs - ([@wraithgar](https://github.com/wraithgar)) -* [`ec520ce32`](https://github.com/npm/cli/commit/ec520ce32d5e834a32ebd58491df4200e01ce690) - [#2998](https://github.com/npm/cli/issues/2998) - feat(set-script): implement workspaces -* [`32717a60e`](https://github.com/npm/cli/commit/32717a60eb55fcf8c7e5016223bfee78a6daba0e) - [#3001](https://github.com/npm/cli/issues/3001) - feat(view): add workspace support - ([@wraithgar](https://github.com/wraithgar)) -* [`7b177e43f`](https://github.com/npm/cli/commit/7b177e43f3bfb558bcd8723cdb2166a3df19647a) - [#3014](https://github.com/npm/cli/issues/3014) - feat(config): add 'envExport' flag - ([@isaacs](https://github.com/isaacs)) - -### BUG FIXES - -* [`4c4252348`](https://github.com/npm/cli/commit/4c4252348c538246e1072421d65f4558dc948080) - [#3016](https://github.com/npm/cli/issues/3016) - fix(usage): specify the key each time for multiples - ([@isaacs](https://github.com/isaacs)) -* [`9237d375b`](https://github.com/npm/cli/commit/9237d375b0b7d34c7dc5ba70aec7f616f4133732) - [#3013](https://github.com/npm/cli/issues/3013) - fix(docs): add workspaces configuration - ([@wraithgar](https://github.com/wraithgar)) -* [`cb6eb0d20`](https://github.com/npm/cli/commit/cb6eb0d206b7e2f63d5c7a7a17bea4aed1b9f2bf) - [#3015](https://github.com/npm/cli/issues/3015) - fix(ERESOLVE): better errors when current is missing - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`61da39beb`](https://github.com/npm/cli/commit/61da39beb5373320e2b591b61ecd6596eeaba6ed) - `@npmcli/config@2.1.0` - * feat(config): add support for envExport:false -* [`fb095a708`](https://github.com/npm/cli/commit/fb095a708a1f930bbd0195446ac611b82bfeff14) - `@npmcli/arborist@2.3.0`: - * [#2896](https://github.com/npm/cli/issues/2896) Provide currentEdge in - ERESOLVE if known, and address self-linking edge case. - * Add/remove dependencies to/from workspaces when set, not root project - * Only reify the portions of the dependency graph identified by the - `workspace` configuration value. - * Do not recursively `chown` the project root path. - -## v7.7.6 (2021-03-29) - -### BUG FIXES - -* [`9dd2ed518`](https://github.com/npm/cli/commit/9dd2ed5189b6f283094664e9e192cf1598ec3f79) - fix empty newline printed to stderr - ([@ruyadorno](https://github.com/ruyadorno)) -* [`9d391462a`](https://github.com/npm/cli/commit/9d391462a25f637219501e2430ef1f7b89710816) - [#2973](https://github.com/npm/cli/issues/2973) - fix spelling in workspaces.md file - ([@sethomas](https://github.com/sethomas)) -* [`4b100249a`](https://github.com/npm/cli/commit/4b100249a6cad67e002186816e64817313b636c7) - [#2979](https://github.com/npm/cli/issues/2979) - change 'maxsockets' default value back to 15 - ([@wallrat](https://github.com/wallrat)) - -### DEPENDENCIES - -* [`a28f89572`](https://github.com/npm/cli/commit/a28f89572a708cced69cc938f877eaa969dbad9e) - `libnpmversion@1.1.0` - * fix reading `script-shell` config on `npm version` lifecycle scripts -* [`03734c29e`](https://github.com/npm/cli/commit/03734c29e00191d17f164d1c0e75d9f228268842) - `npm-packlist@2.1.5` - * fix packaging `bundledDependencies` -* [`80ce2a019`](https://github.com/npm/cli/commit/80ce2a019526632b01b70e1c75c42608dc160332) - `@npmcli/metavuln-calculator@1.1.1` - * fix error auditing package documents with missing dependencies - -## v7.7.5 (2021-03-25) - -### BUG FIXES - -* [`95ba87622`](https://github.com/npm/cli/commit/95ba87622e00d68270eda9e071b19737718fca16) - [#2949](https://github.com/npm/cli/issues/2949) - fix handling manual indexes in `npm help` - ([@dmchurch](https://github.com/dmchurch)) -* [`59cf37962`](https://github.com/npm/cli/commit/59cf37962a2286e0f7d3bd37fa9c8bc3bac94218) - [#2958](https://github.com/npm/cli/issues/2958) - always set `npm.command` to canonical command name - ([@isaacs](https://github.com/isaacs)) -* [`1415b4bde`](https://github.com/npm/cli/commit/1415b4bdeeaabb6e0ba12b6b1b0cc56502bd64ab) - [#2964](https://github.com/npm/cli/issues/2964) - fix(config): properly translate user-agent - ([@wraithgar](https://github.com/wraithgar)) -* [`59271936d`](https://github.com/npm/cli/commit/59271936d90fbd6956a41967119f578c0ba63db9) - [#2965](https://github.com/npm/cli/issues/2965) - fix(config): tie save-exact/save-prefix together - ([@wraithgar](https://github.com/wraithgar)) - -### TESTS - -* [`97b415287`](https://github.com/npm/cli/commit/97b41528739460b2e9e72e09000aded412418cb2) - [#2959](https://github.com/npm/cli/issues/2959) - add smoke tests - ([@ruyadorno](https://github.com/ruyadorno)) - -## v7.7.4 (2021-03-24) - -### BUG FIXES - -* [`200bee74b`](https://github.com/npm/cli/commit/200bee74b31a738687446b7b535cac67b1c582fd) - [#2951](https://github.com/npm/cli/issues/2951) - fix(config): accept explicit `production=false` - ([@wraithgar](https://github.com/wraithgar)) -* [`7b45e9df6`](https://github.com/npm/cli/commit/7b45e9df6102c7bd6e403d1fdc9939581c38f546) - [#2950](https://github.com/npm/cli/issues/2950) - warn if using workspaces config options in `npm config` - ([@ruyadorno](https://github.com/ruyadorno)) - -## v7.7.3 (2021-03-24) - -### BUG FIXES - -* [`c76f04ac2`](https://github.com/npm/cli/commit/c76f04ac28ddf2ae4df4b3ce0aec684a118de1b5) - [#2925](https://github.com/npm/cli/issues/2925) - fix(set-script): add completion - ([@Yash-Singh1](https://github.com/Yash-Singh1)) -* [`0379eab69`](https://github.com/npm/cli/commit/0379eab698b78ae4aa89bbe2043607f420e52f11) - [#2929](https://github.com/npm/cli/issues/2929) - fix(install): ignore auditLevel - `npm install` should not be affected by the `auditLevel` config, as the - results of audit do not change its exit status. - ([@wraithgar](https://github.com/wraithgar)) -* [`98efadeb4`](https://github.com/npm/cli/commit/98efadeb4b2ae9289f14ed6f42a169230faf7239) - [#2923](https://github.com/npm/cli/issues/2923) - fix(audit-level): add `info` audit level - This is a valid level but wasn't configured to be allowed. - Also added this param to the usage output for `npm audit` - ([@wraithgar](https://github.com/wraithgar)) -* [`e8d2adcf4`](https://github.com/npm/cli/commit/e8d2adcf40ad63030f844c9aa44c6d16e2146797) - [#2945](https://github.com/npm/cli/issues/2945) - config should not error when workspaces are configured - ([@nlf](https://github.com/nlf)) -* [`aba2bc623`](https://github.com/npm/cli/commit/aba2bc623ea99e563b1b15b81dbb4ba94f86fe4c) - [#2944](https://github.com/npm/cli/issues/2944) - fix(progress): re-add progress bar to reify - The logger was no longer in flatOptions, we pass it in explicitly now - ([@wraithgar](https://github.com/wraithgar)) -* [`877b4ed29`](https://github.com/npm/cli/commit/877b4ed2925c97b5249a4d33575420dda64f7339) - [#2946](https://github.com/npm/cli/issues/2946) - fix(flatOptions): re-add `_auth` - This was not being added to flatOptions, and things like - `npm-registry-fetch` are looking for it. - ([@wraithgar](https://github.com/wraithgar)) - -## v7.7.2 (2021-03-24) - -### BUG FIXES -* [`a4df2b98d`](https://github.com/npm/cli/commit/a4df2b98d89429b19cd29b5fc895cdbfc0a6bd78) - [#2942](https://github.com/npm/cli/issues/2942) - Restore --dev flag, unify --omit flatteners - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES -* [`2cbfaac0e`](https://github.com/npm/cli/commit/2cbfaac0ecd5810316f6d76168ed9618bd11bf3a) - `hosted-git-info@4.0.2` - * [#83](https://github.com/npm/hosted-git-info/pull/83) Do not parse - urls for gitlab - ([@nlf](https://github.com/nlf)) - -## v7.7.1 (2021-03-24) - -### BUG FIXES - -* [`543b0e39b`](https://github.com/npm/cli/commit/543b0e39bcb94fc408804b01ca9c0d7b960b2681) - [#2930](https://github.com/npm/cli/issues/2930) - fix(uninstall): use correct local prefix - ([@jameschensmith](https://github.com/jameschensmith)) -* [`dce4960ef`](https://github.com/npm/cli/commit/dce4960ef6d52af128affe7755b2ca72de913b6c) - [#2932](https://github.com/npm/cli/issues/2932) - fix(config): flatten savePrefix properly - ([@wraithgar](https://github.com/wraithgar)) - -## v7.7.0 (2021-03-23) - -### FEATURES - -* [`33c4189f9`](https://github.com/npm/cli/commit/33c4189f939aebdfaf85ea419e6ea01d0977b79d) - [#2864](https://github.com/npm/cli/issues/2864) - add `npm run-script` workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) -* [`e1b3b318f`](https://github.com/npm/cli/commit/e1b3b318f095a7e1a7cc4b131907de4955275d9d) - [#2886](https://github.com/npm/cli/issues/2886) - add `npm exec` workspaces support - ([@ruyadorno](https://github.com/ruyadorno)) -* [`41facf643`](https://github.com/npm/cli/commit/41facf6435ced4e416d74111d9c3ff00ee19ab7d) - [#2859](https://github.com/npm/cli/issues/2859) - expanded "Did you mean?" suggestions for missing cmds and scripts - ([@wraithgar](https://github.com/wraithgar)) - -### BUG FIXES - -* [`8cce4282f`](https://github.com/npm/cli/commit/8cce4282f7bef11aeeb73cffd532b477b241985e) - [#2865](https://github.com/npm/cli/issues/2865) - `npm publish`: handle case where multiple config list is present - ([@kenrick95](https://github.com/kenrick95)) -* [`6598bfe86`](https://github.com/npm/cli/commit/6598bfe8697439e827d84981f8504febca64a55a) - mark deprecated configs - ([@isaacs](https://github.com/isaacs)) -* [`8a38afe77`](https://github.com/npm/cli/commit/8a38afe779ce71a10178ed62b13709d06adf7a66) - [#2881](https://github.com/npm/cli/issues/2881) - docs(package-json): document default main behavior - ([@klausbayrhammer](https://github.com/klausbayrhammer)) -* [`93a061d73`](https://github.com/npm/cli/commit/93a061d737dc769663652368e8586e4202267b9e) - [#2917](https://github.com/npm/cli/issues/2917) - add action items to `npm run` error output - ([@wraithgar](https://github.com/wraithgar)) - -### DOCUMENTATION - -* [`ad65bd910`](https://github.com/npm/cli/commit/ad65bd9101aa8e8b94bc1e48df3ef93deca6d30c) - [#2860](https://github.com/npm/cli/issues/2860) - fix link in configuring-npm - ([@varmakarthik12](https://github.com/varmakarthik12)) -* [`b419bfb02`](https://github.com/npm/cli/commit/b419bfb0259596fb338d45b2eaeab25a7a0d1f1e) - [#2876](https://github.com/npm/cli/issues/2876) - fix test-coverage command in contributing guide - ([@chowkapow](https://github.com/chowkapow)) - -### DEPENDENCIES - -* [`7b5606b93`](https://github.com/npm/cli/commit/7b5606b931083e8a70f5ea094c2b46f0b7a38a18) - `@npmcli/arborist@2.2.9` - * [#254](https://github.com/npm/arborist/pull/254) Honor explicit - prefix when saving dependencies - ([@jameschensmith](https://github.com/jameschensmith)) - * [#255](https://github.com/npm/arborist/pull/255) Never save to - `bundleDependencies` when saving a `peer` or `peerOptional` - dependency. ([@isaacs](https://github.com/isaacs)) -* [`f76e7c21f`](https://github.com/npm/cli/commit/f76e7c21ffd87b08593d8c396a78ab9c5fa790bd) - `pacote@11.3.1` - * increases tarball compression level -* [`4928512bc`](https://github.com/npm/cli/commit/4928512bcefd8448ff5852978cfc7f903e3ae996) - `semver@7.3.5` - * fix handling prereleases/ANY ranges in subset -* [`1924eb457`](https://github.com/npm/cli/commit/1924eb457aea7c93dfaf4a911355a63d84d66eee) - `libnpmversion@1.0.12` - * fix removing undescored-prefixed package.json properties in `npm version` -* [`916623056`](https://github.com/npm/cli/commit/91662305643509eebd2f79ed7e3ff01562aa4968) - `@npmcli/run-script@1.8.4` - * fix expanding windows-style environment variables -* [`a8d0751e4`](https://github.com/npm/cli/commit/a8d0751e4b7c7d8b808c8a49f288fc7272f729b0) - `npm-pick-manifest@6.1.1` - * fix running packages with a single executable binary with `npm exec` -* [`af7eaac50`](https://github.com/npm/cli/commit/af7eaac5018ed821d72d43d08f1d7e49e7491453) - `hosted-git-info@4.0.1` -* [`f52c51db1`](https://github.com/npm/cli/commit/f52c51db13c39cfbaed18dbd13ba7302a4b6a0d9) - `@npmcli/config@2.0.0` - -## v7.6.3 (2021-03-11) - -### DOCUMENTATION - -* [`8c44e999b`](https://github.com/npm/cli/commit/8c44e999bdf7639893535c55beebf7996da2c47f) - [#2855](https://github.com/npm/cli/issues/2855) - Correct "npm COMMAND help" to "npm help COMMAND" - ([@dwardu](https://github.com/dwardu)) - -### DEPENDENCIES - -* [`57ed390d6`](https://github.com/npm/cli/commit/57ed390d64a44ae0a1b2c4afd79d690170b194ec) - `@npmcli/arborist@2.2.8` - * Respect link deps when calculating peerDep sets - -## v7.6.2 (2021-03-09) - -### BUG FIXES - -* [`e0a3a5218`](https://github.com/npm/cli/commit/e0a3a5218cac7ca5850930aaaad8a939ddf75d4d) - [#2831](https://github.com/npm/cli/issues/2831) - Fix cb() never called in search with --json option - ([@fraqe](https://github.com/fraqe)) -* [`85a8694dd`](https://github.com/npm/cli/commit/85a8694dd9b4a924a474ba75261914511a216868) - [#2795](https://github.com/npm/cli/issues/2795) - fix(npm.output): make output go through npm.output - ([@wraithgar](https://github.com/wraithgar)) -* [`9fe0df5b5`](https://github.com/npm/cli/commit/9fe0df5b5d7606e5841288d9931be6c04767c9ca) - [#2821](https://github.com/npm/cli/issues/2821) - fix(usage): clean up usage declarations - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`7f470b5c2`](https://github.com/npm/cli/commit/7f470b5c25d544e36d97b28e28ae20dfa1d4ab31) - `@npmcli/arborist@2.2.7` - * fix(install): Do not revert a file: dep to version on bare name re-install -* [`e9b7fc275`](https://github.com/npm/cli/commit/e9b7fc275a0bdf8f00dbcf5dd2283675776fc459) - `libnpmdiff@2.0.4` - * fix(diff): Gracefully handle packages with prepare script -* [`c7314aa62`](https://github.com/npm/cli/commit/c7314aa62195b7f0d8886776692e8a2c892413ed) - `byte-size@7.0.1` -* [`864f48d43`](https://github.com/npm/cli/commit/864f48d4327269f521161cf89888ea2b6db5fdab) - `pacote@11.3.0` - -## v7.6.1 (2021-03-04) - -### BUG FIXES - -* [`3c9a589b0`](https://github.com/npm/cli/commit/3c9a589b004fa828a304abaf52d1d781710e1143) - [#2807](https://github.com/npm/cli/issues/2807) - `npm explain` show when an edge is a bundled edge - ([@kumavis](https://github.com/kumavis)) -* [`b33c760ce`](https://github.com/npm/cli/commit/b33c760cea7fe2696d35b5530abc1b455980fef1) - [#2766](https://github.com/npm/cli/issues/2766) - unused arguments cleanup - ([@sandersn](https://github.com/sandersn)) -* [`4a5dd3a5a`](https://github.com/npm/cli/commit/4a5dd3a5a200b3f4f7b47168497d8e03dca3a2ca) - [#2772](https://github.com/npm/cli/issues/2772) - fix(npm) pass npm context everywhere - ([@wraithgar](https://github.com/wraithgar)) -* [`e69be2ac5`](https://github.com/npm/cli/commit/e69be2ac5c35e985732e2baa00b70d39332e4b9f) - [#2789](https://github.com/npm/cli/issues/2789) - fix npm prefix on all Windows unix shells - ([@isaacs](https://github.com/isaacs)) -* [`2d682e4ca`](https://github.com/npm/cli/commit/2d682e4cab0cf109a16332f3222f1e9a4027db69) - [#2803](https://github.com/npm/cli/issues/2803) - fix(search): don't pass unused args - ([@wraithgar](https://github.com/wraithgar)) -* [`b3e7dd19b`](https://github.com/npm/cli/commit/b3e7dd19bb4888dad2bfb6702aed6560a7f91bf8) - [#2822](https://github.com/npm/cli/issues/2822) - fix(diff): set option "where" for pacote - ([@ruyadorno](https://github.com/ruyadorno)) -* [`96006640b`](https://github.com/npm/cli/commit/96006640b902d31415260df5ce3ad8d066a64623) - [#2824](https://github.com/npm/cli/issues/2824) - fix(repo, auth.sso): don't promisify open-url - ([@wraithgar](https://github.com/wraithgar)) - -### DOCUMENTATION - -* [`c8b73db82`](https://github.com/npm/cli/commit/c8b73db82f0f2445c20a0a64110586253accd66b) - [#2690](https://github.com/npm/cli/issues/2690) - fix(docs): update scripts docs - ([@wraithgar](https://github.com/wraithgar)) -* [`5d922394b`](https://github.com/npm/cli/commit/5d922394b7874b2b38d34f03f2decbe0eb3e8583) - [#2809](https://github.com/npm/cli/issues/2809) - update republish timeout after unpublish - ([@BAJ-](https://github.com/BAJ-)) - -### DEPENDENCIES - -* [`2d4ae598f`](https://github.com/npm/cli/commit/2d4ae598f30049680797685f76154b16a7e15a66) - `@npmcli/arborist@2.2.6` - -## v7.6.0 (2021-02-25) - -### FEATURES - -* [`983d218f7`](https://github.com/npm/cli/commit/983d218f7e68e3c7866f2efa23ea2aff7ff3881e) - [#2750](https://github.com/npm/cli/issues/2750) - feat(explain): mark when dependency is bundled - ([@kumavis](https://github.com/kumavis)) - -### DEPENDENCIES - -* [`b9fa7e32a`](https://github.com/npm/cli/commit/b9fa7e32a63a3dc3a4865865c4ca737c862b9cf2) - chore(package-lock): resetdeps and `eslint@7.20.0` - ([@wraithgar](https://github.com/wraithgar)) -* [`28d036ae9`](https://github.com/npm/cli/commit/28d036ae9179f742bd0518e558a54f014a7a895e) - `arborist@2.2.5` - * fix: hidden lockfiles were not respected on Node v10.0-10.12 - -### DOCUMENTATION - -* [`ba1adef42`](https://github.com/npm/cli/commit/ba1adef4292123e87e26b59e0c6fd6f5ff1fe775) - [#2760](https://github.com/npm/cli/issues/2760) - chore(docs): capitalize all Instaces of "package" - ([@MrBrain295](https://github.com/MrBrain295)) -* [`8bfa05fa1`](https://github.com/npm/cli/commit/8bfa05fa1dfd4a64381c7ec750df6d174724e8c1) - [#2775](https://github.com/npm/cli/issues/2775) - chore(docs): add navigation configuration - ([@ethomson](https://github.com/ethomson)) -* [`238e474a4`](https://github.com/npm/cli/commit/238e474a48ddecc33c76eb3d2c4d0642cfe8829a) - [#2778](https://github.com/npm/cli/issues/2778) - chore(docs):update unpublish cooldown - ([@christoflemke](https://github.com/christoflemke)) - -## v7.5.6 (2021-02-22) - -### BUG FIXES - -* [`4e58274ed`](https://github.com/npm/cli/commit/4e58274ed0fd2dd29d3c8d6c7c47f37a37dc0f0f) - [#2742](https://github.com/npm/cli/issues/2742) - Do not print error banner for shell proxy commands - ([@isaacs](https://github.com/isaacs)) - -### DOCS - -* [`3c72ab441`](https://github.com/npm/cli/commit/3c72ab4412111c708736e3a7b8342150372a4af4) - [#2749](https://github.com/npm/cli/issues/2749) - Capitalize Package in a Heading - ([@MrBrain295](https://github.com/MrBrain295)) - -### DEPENDENCIES - -* [`f3ae6ed0d`](https://github.com/npm/cli/commit/f3ae6ed0d25ce80868f59353ef71c09ac77b1cf5) - `read-package-json@3.0.1`, `read-package-json-fast@2.0.2` -* [`9b311fe52`](https://github.com/npm/cli/commit/9b311fe522077c7f8a242b94b0e1dbe746992bef) - [#2736](https://github.com/npm/cli/issue/2736) `@npmcli/arborist@2.2.4`: - * Do not rely on underscore fields in `package.json` files - * Do not remove global packages when updating by name - * Keep `yarn.lock` and `package-lock.json` more in sync - -## v7.5.5 (2021-02-22) - -### BUG FIXES -* [`49c95375a`](https://github.com/npm/cli/commit/49c95375af49308e2db6ba28e91c65193754e091) - [#2688](https://github.com/npm/cli/issues/2688) - fix shrinkwrap in node v10.0 - ([@ljharb](https://github.com/ljharb)) -* [`00afa3161`](https://github.com/npm/cli/commit/00afa316195f2db903146110a07ffdaec9bb6aa2) - [#2718](https://github.com/npm/cli/issues/2718) - restore the prefix on output from `npm version <inc>` - ([@nlf](https://github.com/nlf)) -* [`69e0c4e8c`](https://github.com/npm/cli/commit/69e0c4e8cd684c475a4450c40dfb32c995061aea) - [#2716](https://github.com/npm/cli/issues/2716) - throw an error when trying to dedupe in global mode - ([@nlf](https://github.com/nlf)) -* [`b018eb842`](https://github.com/npm/cli/commit/b018eb84266dc5a02274849135ca148cb59cc349) - [#2719](https://github.com/npm/cli/issues/2719) - obey silent loglevel in run-script - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES -* [`8c36697df`](https://github.com/npm/cli/commit/8c36697dfffe8b5e853fe889c9ead5578100c413) - `@npmcli/arborist@2.2.3` - * [#1875](https://github.com/npm/cli/issues/1875) - [arborist#230](https://github.com/npm/arborist/pull/230) - Set default advisory `severity`/`vulnerable_range` when missing from audit endpoint data - ([@isaacs](https://github.com/isaacs)) - * [npm/arborist#231](https://github.com/npm/arborist/pull/231) - skip optional deps with mismatched platform or engine - ([@nlf](https://github.com/nlf)) - * [#2251](https://github.com/npm/cli/issues/2251) - Unpack shrinkwrapped deps not already unpacked - ([@isaacs](https://github.com/isaacs), - [@nlf](https://github.com/nlf)) - * [#2714](https://github.com/npm/cli/issues/2714) - Do not write package.json if nothing changed - ([@isaacs](https://github.com/isaacs)) - * [npm/rfcs#324](https://github.com/npm/rfcs/issues/324) - Prefer peer over prod dep, if both specified - ([@isaacs](https://github.com/isaacs)) - * [npm/arborist#236](https://github.com/npm/arborist/issues/236) - Fix additional peerOptional conflict cases - ([@isaacs](https://github.com/isaacs)) -* [`d865b101f`](https://github.com/npm/cli/commit/d865b101f72142619531311645479f0596a68a1a) - `libnpmpack@2.0.1` - * respect silent loglevel -* [`e606953e5`](https://github.com/npm/cli/commit/e606953e5795803a7c4eddb4ea993735ef65ec95) - `libnpmversion@1.0.11` - * respect silent loglevel -* [`9c51005a1`](https://github.com/npm/cli/commit/9c51005a19fd4c3e7cd4c987d2e39d1b763036bf) - `npm-package-arg@8.1.1` - * do a better job of detecting git specifiers like `git@github.com:npm/cli` -* [`8b6bf0db4`](https://github.com/npm/cli/commit/8b6bf0db49a3378bd85a0d1ffdd19fbdd68a944a) - `pacote@11.2.7` - * respect silent loglevel - * fix INVALID_URL errors for certain git dependencies - -### TESTS -* [`80c2ac995`](https://github.com/npm/cli/commit/80c2ac995170a05b26856a2b72fe9c8163b2c999) - [#2717](https://github.com/npm/cli/issues/2717) - refactor publish tests - ([@wraithgar](https://github.com/wraithgar)) -* [`9d81e0ceb`](https://github.com/npm/cli/commit/9d81e0ceba7d69e0651662508415ee3705bddfd9) - [#2729](https://github.com/npm/cli/issues/2729) - fix typo in shrinkwrap tests - ([@eltociear](https://github.com/eltociear)) - -### DOCUMENTATION -* [`e3de7befb`](https://github.com/npm/cli/commit/e3de7befb3a9e2fcb7aac5b740d09b3b7d99d724) - [#2685](https://github.com/npm/cli/issues/2685) - docs(readme): add note back about branding/origin - ([@darcyclarke](https://github.com/darcyclarke)) -* [`38d87e7c2`](https://github.com/npm/cli/commit/38d87e7c24aea13b0f1c1157aad58d9d15bf8e63) - [#2698](https://github.com/npm/cli/issues/2698) - mention nodenv in README.md - ([@RA80533](https://github.com/RA80533)) -* [`af4422cdb`](https://github.com/npm/cli/commit/af4422cdbc110f93203667efc08b16f7aa74ac2f) - [#2711](https://github.com/npm/cli/issues/2711) - validate that the docs can be parsed by mdx - ([@ethomson](https://github.com/ethomson)) - - -## v7.5.4 (2021-02-12) - -### BUG FIXES - -* [`ef687f545`](https://github.com/npm/cli/commit/ef687f545b177d0496ce74faacf1bf738978355a) - [#2655](https://github.com/npm/cli/issues/2655) - fix(env): Do not clobber defined 'env' script - ([@isaacs](https://github.com/isaacs)) -* [`868954a72`](https://github.com/npm/cli/commit/868954a72c06ff2210b35e1e75571f4ec3357c43) - [#2654](https://github.com/npm/cli/issues/2654) - [fix] node v10.0 lacks `fs.promises` - ([@ljharb](https://github.com/ljharb)) - - -### DEPENDENCIES - -* [`14dd93853`](https://github.com/npm/cli/commit/14dd9385358b3815c2285526f7c2e53ed3c5e8da) - fix(package.json): resetdeps - ([@wraithgar](https://github.com/wraithgar)) -* [`39e4a6401`](https://github.com/npm/cli/commit/39e4a640130b85d62199a33cc2026b04390520ee) - `graceful-fs@4.2.6` -* [`96dffab98`](https://github.com/npm/cli/commit/96dffab988048164516d8cf73c1fbf66781f86df) - `eslint-plugin-promise@4.3.1` -* [`9a6e9d38a`](https://github.com/npm/cli/commit/9a6e9d38abccec793b6ac14871c2b639d62a6c41) - `@npmcli/run-script@1.8.3` - * fix fs.promises reference to run in node v10.0 -* [`584b746a2`](https://github.com/npm/cli/commit/584b746a2c8cdc697629298be27dd23d19de1231) - `@npmcli/git@2.0.5` -* [`6305ebde4`](https://github.com/npm/cli/commit/6305ebde43796737014aedbe019db8cd81dcbbec) - `make-fetch-happen@8.0.14` -* [`e99881117`](https://github.com/npm/cli/commit/e998811170ce5df00a725b2d683b4bff124c6792) - `libnpmversion@1.0.10` -* [`554d91cdf`](https://github.com/npm/cli/commit/554d91cdf82e9c92c2ac3752ed91e7081c2271e5) - chore(package-lock): rebuild package-lock - ([@wraithgar](https://github.com/wraithgar)) -* [`37e8cc507`](https://github.com/npm/cli/commit/37e8cc507b2ce0b89f92e7e77b1d909d1bf5513f) - `@npmcli/arborist@2.2.2` - * [#2505](https://github.com/npm/cli/issues/2505) properly install - dependenciess of linked dependencies - ([@ruyadorno](https://github.com/ruyadorno)) - * [#2504](https://github.com/npm/cli/issues/2504) Allow `--force` to - override conflicted optional peerDependencies - ([@isaacs](https://github.com/isaacs)) - * Ensure correct flags on shrinkwrapped module deps - ([@isaacs](https://github.com/isaacs)) - * Correct relative paths for global packages installed from tarball files - ([nlf](https://github.com/nlf)) -* [`7788ce47b`](https://github.com/npm/cli/commit/7788ce47bc264d9d951055da85f2b695eb8b3f15) - `@npmcli/map-workspaces@1.0.3` - -### TESTS - -* [`3a159d27e`](https://github.com/npm/cli/commit/3a159d27e976933098ec18fa9c3e474c85b5b332) - [#2681](https://github.com/npm/cli/issues/2681) - fix(tests): rewrite doctor tests - ([@ljharb](https://github.com/ljharb)) -* [`abcc96a20`](https://github.com/npm/cli/commit/abcc96a204ed581fc7cd603f47cdca0afe299530) - [#2682](https://github.com/npm/cli/issues/2682) - [tests] separate tests from linting and license validation - ([@ljharb](https://github.com/ljharb)) - -### DOCUMENTATION - -* [`7e1e84181`](https://github.com/npm/cli/commit/7e1e84181ccaca8a8b499a21b1aa7d731a14d5b7) - [#2662](https://github.com/npm/cli/issues/2662) - fix(docs): fix angle brackets in npm diff docs - ([@ethomson](https://github.com/ethomson)) - -## v7.5.3 (2021-02-08) - -### BUG FIXES - -* [`df596bf4c`](https://github.com/npm/cli/commit/df596bf4c10d6917672579cc38800f5e846002bc) - fix(publish): follow all configs for registry auth check - [#2602](https://github.com/npm/cli/issues/2602) - ([@wraithgar](https://github.com/wraithgar)) -* [`6d7afb03c`](https://github.com/npm/cli/commit/6d7afb03cd7602b60e709516711a2f94cd61ff25) - [#2613](https://github.com/npm/cli/issues/2613) - install script: pass -q to curl calls to disable user .curlrc files - ([@nlf](https://github.com/nlf)) - -### DEPENDENCIES - -* [`3294fed6f`](https://github.com/npm/cli/commit/3294fed6f18626516978c21fac5f28ecfdb58124) - `pacote@11.2.5` - * prevent infinite recursion in git dep preparation -* [`0f7a3a87c`](https://github.com/npm/cli/commit/0f7a3a87c12e30bdd2cdab596ca6511de787c969) - `read-package-json-fast@2.0.1` - * avoid duplicating optionalDependencies as dependencies in package.json -* [`6f46b0f7f`](https://github.com/npm/cli/commit/6f46b0f7fef9891e6de4af3547c70a67cb3a7a13) - `init-package-json@2.0.2` -* [`df4f65acc`](https://github.com/npm/cli/commit/df4f65acc4ceaf15db4c227670e80f94584c055c) - `@npmcli/arborist@2.2.0` -* [`7038c2ff4`](https://github.com/npm/cli/commit/7038c2ff49022f8babd495d1b831b5c82d6aed05) - `@npmcli/run-script@1.8.2` -* [`54cd4c87a`](https://github.com/npm/cli/commit/54cd4c87a71c9381519d8ac52e306096066dc92e) - `libnpmversion@1.0.8` -* [`9ab36aae4`](https://github.com/npm/cli/commit/9ab36aae429784df754211d5f086a515012b9bdd) - `graceful-fs@4.2.5` -* [`e1822cf27`](https://github.com/npm/cli/commit/e1822cf277336728f1d5696ffe0db3ea6e700d9e) - `@npmcli/installed-package-contents@1.0.7` - -## v7.5.2 (2021-02-02) - -### BUG FIXES - -* [`37613e4e6`](https://github.com/npm/cli/commit/37613e4e686e4891210acaabc9c23f41456eda3f) -[#2395](https://github.com/npm/cli/issues/2395) -[#2329](https://github.com/npm/cli/issues/2329) -fix(exec): use latest version when possible -([@wraithgar](https://github.com/wraithgar)) -* [`567c9bd03`](https://github.com/npm/cli/commit/567c9bd03a7669111fbba6eb6d1f12ed7cad5a1b) -fix(lib/npm): do not clobber config.execPath -([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`643709706`](https://github.com/npm/cli/commit/64370970653af5c8d7a2be2c2144e355aa6431b0) -`@npmcli/config@1.2.9` ([@isaacs](https://github.com/isaacs)) - * [`4c6be4a`](https://github.com/npm/config/commit/4c6be4a66a3e89ae607e08172b8543b588a95fb5) Restore npm v6 behavior with `INIT_CWD` - * [`bbebc66`](https://github.com/npm/config/commit/bbebc668888f71dba57959682364b6ff26ff4fac) Do not set the `PREFIX` environment variable - -## v7.5.1 (2021-02-01 - -### BUG FIXES - -* [`0ea134e41`](https://github.com/npm/cli/commit/0ea134e4190f322138299c51672eab5387ec41bb) - [#2587](https://github.com/npm/cli/issues/2587) - pass all settings through to pacote.packument, fixes #2060 - ([@nlf](https://github.com/nlf)) -* [`8c5ca2f51`](https://github.com/npm/cli/commit/8c5ca2f516f5ac87f3bbd7f1fd95c0b283a21f14) - Add test for npm-usage.js, and fix 'npm --long' output - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`7e4e88e93`](https://github.com/npm/cli/commit/7e4e88e938323e34a2a41176472d8e43e84bd4dd) - `@npmcli/arborist@2.1.1`, `pacote@11.2.4` - * Properly raise ERESOLVE errors on root dev dependencies - * Ignore ERESOLVE errors when performing git dep 'prepare' scripts - * Always reinstall packages that are explicitly requested - * fix global update all so it actually updates things - * Install bins properly when global root is a link - ([@isaacs](https://github.com/isaacs)) - -### DOCUMENTATION - -* [`23dac2fef`](https://github.com/npm/cli/commit/23dac2feff1d02193791c7e39d9e93bc9bf8e624) - [#2557](https://github.com/npm/cli/issues/2557) - npm team revamp - ([@ruyadorno](https://github.com/ruyadorno)) -* [`dd05ba0c0`](https://github.com/npm/cli/commit/dd05ba0c0b2f4c70eb8558c0ecc54889efbe98f5) - [#2572](https://github.com/npm/cli/issues/2572) - add note about `--force` overriding peer dependencies - ([@isaacs](https://github.com/isaacs)) -* [`e27639780`](https://github.com/npm/cli/commit/e276397809aceb01cc468e02a83bc6f2265376d9) - [#2584](https://github.com/npm/cli/issues/2584) - Fixed the spelling of contributor as it was written as conributor - ([@pavanbellamkonda](https://github.com/pavanbellamkonda)) -* [`13a5e3178`](https://github.com/npm/cli/commit/13a5e31781cdaa37d3f007e1c8583c7cb591c62a) - [#2502](https://github.com/npm/cli/issues/2502) - elaborate that npm help uses browser - ([@ariccio](https://github.com/ariccio)) - -## v7.5.0 (2021-01-28) - -### FEATURES - -* [`d011266b7`](https://github.com/npm/cli/commit/d011266b733367aad283ccbfb9d2b19442c3405f) - [#1319](https://github.com/npm/cli/issues/1319) - add npm diff command - ([@ruyadorno](https://github.com/ruyadorno)) - -### BUG FIXES - -* [`d2f8af2da`](https://github.com/npm/cli/commit/d2f8af2da64d510d3d363aec10531bebf840d84e) - [#2445](https://github.com/npm/cli/issues/2445) - publish: don't complain about missing auth until after registry is chosen - ([@dr-js](https://github.com/dr-js)) - -### DOCUMENTATION - -* [`8d3fd63aa`](https://github.com/npm/cli/commit/8d3fd63aaa6a5c9b3d2281dd0bd9e1c270b35941) - [#2559](https://github.com/npm/cli/issues/2559) - updates to readme, removal, contributing and several other docs - ([@darcyclarke](https://github.com/darcyclarke)) -* [`7772d9f9f`](https://github.com/npm/cli/commit/7772d9f9f9f853573a7ff8e7fb60c5e46566f596) - [#2542](https://github.com/npm/cli/issues/2542) - fix grammar on caching docs for search, exec and init - ([@wraithgar](https://github.com/wraithgar)) -* [`52e8a1aef`](https://github.com/npm/cli/commit/52e8a1aef4aab3f378c20276a9109bb3f00eccd5) - [#2558](https://github.com/npm/cli/issues/2558) - refreshed npm updated docs - ([@ruyadorno](https://github.com/ruyadorno)) -* [`abae00ca0`](https://github.com/npm/cli/commit/abae00ca05925e521696dd12480853509aab6c0a) - [#2565](https://github.com/npm/cli/issues/2565) - update npm command docs - ([@wraithgar](https://github.com/wraithgar)) -* [`9351cbf9a`](https://github.com/npm/cli/commit/9351cbf9afd2310c56b9953c005505ea5126a5d4) - [#2566](https://github.com/npm/cli/issues/2566) - refresh npm run-script docs - ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`56c08863e`](https://github.com/npm/cli/commit/56c08863e15cb9cf8662b99ddc627cfcdff0348d) - `hosted-git-info@3.0.8` -* [`18a93f06b`](https://github.com/npm/cli/commit/18a93f06b632be051b9455e32a85e4e75066f52c) - `ssri@8.0.1` -* [`cb768f671`](https://github.com/npm/cli/commit/cb768f671c4d8d5a09d9a6c5a74227d300e81104) - `@npmcli/move-file@1.1.1` -* [`32cc0a4be`](https://github.com/npm/cli/commit/32cc0a4be76465093e3d0f314215a0ec46dc03c6) - `minipass-fetch@1.3.3` - * fixes ssl settings passthrough -* [`530997968`](https://github.com/npm/cli/commit/530997968fbbd9e8bf016689b1d192daa812b4de) - `@npmcli/arborist@2.1.0` - * added signal handler to rollback when possible - * prevent ERESOLVEs caused by loose root dep specs - * detect conflicts among nested peerOptional deps - * properly buildIdealTree when root is a symlink - -## v7.4.3 (2021-01-21) - -### DOCUMENTATION - -* [`ec1f06d06`](https://github.com/npm/cli/commit/ec1f06d06447a29c74bee063cff103ede7a2111b) - [#2498](https://github.com/npm/cli/issues/2498) - docs(npm): update `npm` docs - ([@darcyclarke](https://github.com/darcyclarke)) - -### DEPENDENCIES -* [`bc23284cd`](https://github.com/npm/cli/commit/bc23284cd5c4cc4532875aff14df94213727a509) - [#2511](https://github.com/npm/cli/issues/2511) - remove coverage files - ([@ruyadorno](https://github.com/ruyadorno)) -* [`fcbc676b8`](https://github.com/npm/cli/commit/fcbc676b88e1b7c8d01a3799683cd388a82c44d6) - `pacote@11.2.3` -* [`ebd3a24ff`](https://github.com/npm/cli/commit/ebd3a24ff8381f2def306136b745d1615fd6139f) - `@npmcli/arborist@2.0.6` - * Preserve git+https auth when provided - -## v7.4.2 (2021-01-15) - -### DEPENDENCIES - -* [`e5ce6bbba`](https://github.com/npm/cli/commit/e5ce6bbbad82b85c8e74a4558503513e4f337476) - * `@npmcli/arborist@2.0.5` - * fix creating missing dirs when using --prefix and --global - * fix omit types of deps in global installs - * fix prioritizing npm-shrinkwrap.json over package-lock.json - * better cache system for packuments - * improves audit performance - -## v7.4.1 (2021-01-14) - -### BUG FIXES - -* [`23df96d33`](https://github.com/npm/cli/commit/23df96d3394ba0b69a37f416d7f0c26bb9354975) - [#2486](https://github.com/npm/cli/issues/2486) - npm link no longer deletes entire project when global prefix is a symlink - ([@nlf](https://github.com/nlf)) - -### DOCUMENTATION - -* [`7dd0dfc59`](https://github.com/npm/cli/commit/7dd0dfc59c861e7d3e30a86a8e6db10872fc6b44) - [#2459](https://github.com/npm/cli/issues/2459) - fix(docs): clean up `npm start` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`307b3bd9f`](https://github.com/npm/cli/commit/307b3bd9f90e96fcc8805a1d5ddec80787a3d3a7) - [#2460](https://github.com/npm/cli/issues/2460) - fix(docs): clean up `npm stop` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`23f01b739`](https://github.com/npm/cli/commit/23f01b739d7a01a7dc3672322e14eb76ff33d712) - [#2462](https://github.com/npm/cli/issues/2462) - fix(docs): clean up `npm test` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`4b43656fc`](https://github.com/npm/cli/commit/4b43656fc608783a29ccf8495dc305459abc5cc7) - [#2463](https://github.com/npm/cli/issues/2463) - fix(docs): clean up `npm prefix` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`1135539ba`](https://github.com/npm/cli/commit/1135539bac9f98bb1a5d5ed05227a8ecd19493d3) - [`a07bb8e69`](https://github.com/npm/cli/commit/a07bb8e692a85b55d51850534c09fa58224c2285) - [`9b55b798e`](https://github.com/npm/cli/commit/9b55b798ed8f2b9be7b3199a1bfc23b1cd89c4cd) - [`cd5eeaaa0`](https://github.com/npm/cli/commit/cd5eeaaa08eabb505b65747a428c3c59159663dc) - [`6df69ce10`](https://github.com/npm/cli/commit/6df69ce107912f8429665eb851825d2acebc8575) - [`dc6b2a8b0`](https://github.com/npm/cli/commit/dc6b2a8b032d118be3566ce0fa7c67c171c8d2cb) - [`a3c127446`](https://github.com/npm/cli/commit/a3c1274460e16d1edbdca6a0cee86ef313fdd961) - [#2464](https://github.com/npm/cli/issues/2464) - fix(docs): clean up `npm uninstall` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`cfdcf32fd`](https://github.com/npm/cli/commit/cfdcf32fd7628501712b8cad4a541c6b8e7b66bc) - [#2474](https://github.com/npm/cli/issues/2474) - fix(docs): clean up `npm unpublish` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`acd5b062a`](https://github.com/npm/cli/commit/acd5b062a811fcd98849df908ce26855823ca671) - [#2475](https://github.com/npm/cli/issues/2475) - fix(docs): update `package-lock.json` docs - ([@isaacs](https://github.com/isaacs)) -* [`b0b0edf6d`](https://github.com/npm/cli/commit/b0b0edf6de1678de7f4a000700c88daa5f7194ef) - [#2482](https://github.com/npm/cli/issues/2482) - fix(docs): clean up `npm token` docs - ([@wraithgar](https://github.com/wraithgar)) -* [`35559201a`](https://github.com/npm/cli/commit/35559201a4a0a5b111ce58d6824e5b4030eb4496) - [#2487](https://github.com/npm/cli/issues/2487) - fix(docs): clean up `npm search` docs - ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`ea8c02169`](https://github.com/npm/cli/commit/ea8c02169cfbf0484d67db7c0e7a6ec8aecb7210) - `@npmcli/arborist@2.0.5` -* [`fb6f2c313`](https://github.com/npm/cli/commit/fb6f2c313d1d9770cc7d02a3900c7945df3cb661) - `pacote@11.2.1` -* [`c549b7657`](https://github.com/npm/cli/commit/c549b76573b1835a63e1e5898e9c16860079d84e) - `make-fetch-happen@8.0.13` - -## v7.4.0 (2021-01-07) - -### FEATURES - -* [`47ed2dfd8`](https://github.com/npm/cli/commit/47ed2dfd865566643bc1d39e8a4f98d2e1add99a) - [#2456](https://github.com/npm/cli/issues/2456) add - `--foreground-scripts` option ([@isaacs](https://github.com/isaacs)) - -### BUG FIXES - -* [`d01746a5a`](https://github.com/npm/cli/commit/d01746a5a6dde115ee6a600cdf54c9b35afcab3f) - [#2444](https://github.com/npm/cli/issues/2444) - [#1103](https://github.com/npm/cli/issues/1103) Remove deprecated - `process.umask()` ([@isaacs](https://github.com/isaacs)) -* [`b2e2edf8a`](https://github.com/npm/cli/commit/b2e2edf8aee57347c96a61209c7a10139a0cc85a) - [#2422](https://github.com/npm/cli/issues/2422) npm publish --dry-run - should not check login status ([@buyan302](https://github.com/buyan302)) -* [`99156df80`](https://github.com/npm/cli/commit/99156df8099f55bc69dfa99d7ddcf8d1d569016e) - [#2448](https://github.com/npm/cli/issues/2448) - [#2425](https://github.com/npm/cli/issues/2425) pass extra arguments - directly to run-script as an array ([@nlf](https://github.com/nlf)) -* [`907b34b2e`](https://github.com/npm/cli/commit/907b34b2ecc34ac376d989f824f7492064e43ef4) - [#2455](https://github.com/npm/cli/issues/2455) fix(ci): pay attention to - --ignore-scripts ([@wraithgar](https://github.com/wraithgar)) - -### DEPENDENCIES - -* [`7a49fd4af`](https://github.com/npm/cli/commit/7a49fd4afc8cd24db40aee008031ea648583d0bc) - `tar@6.1.0`, `pacote@11.1.14` -* [`54a7bd16c`](https://github.com/npm/cli/commit/54a7bd16c130525ade71ec9894af71c2825d8584) - `@npmcli/arborist@2.0.3` - -### DOCUMENTATION - -* [`a390d7456`](https://github.com/npm/cli/commit/a390d74561b72f0b13cba65844ce60c379198087) - [#2440](https://github.com/npm/cli/issues/2440) Updated the url for RFC - 19 so that it isn't a 404. - ([@therealjeffg](https://github.com/therealjeffg)) -* [`e02b46ad7`](https://github.com/npm/cli/commit/e02b46ad7acdeb9fbb63f782e546c2f8db94ae6e) - [#2436](https://github.com/npm/cli/issues/2436) Grammatical Fix in npm-ls - Documentation 'Therefore' is spelled 'Therefor' - ([@marsonya](https://github.com/marsonya)) -* [`0fed44dea`](https://github.com/npm/cli/commit/0fed44dea12f125b639b5e3575adcea74a86d3a0) - [#2417](https://github.com/npm/cli/issues/2417) Fix npm bug reporting url - ([@AkiaCode](https://github.com/AkiaCode)) - -## 7.3.0 (2020-12-18) - -### FEATURES - -* [`a9b8bf263`](https://github.com/npm/cli/commit/a9b8bf2634c627fbb16ca3a6bb2c2f1058c3e586) - [#2362](https://github.com/npm/cli/issues/2362) - Support multiple set/get/deletes in npm config - ([@isaacs](https://github.com/isaacs)) - -### BUG FIXES - -* [`9eef63849`](https://github.com/npm/cli/commit/9eef638499c88689acb00d812c10f0407cb95c08) - Pass full set of options to login helper functions. - This fixes `npm login --no-strict-ssl`, as well as a host of other - options that one might want to set while logging in. - Reported by: [@toddself](https://github.com/toddself) - ([@isaacs](https://github.com/isaacs)) -* [`628a554bc`](https://github.com/npm/cli/commit/628a554bc113e4e115d34778bfe8a77cfad1d933) - [#2358](https://github.com/npm/cli/issues/2358) - fix doctor test to work correctly for node pre-release versions - ([@nlf](https://github.com/nlf)) -* [`be4a0900b`](https://github.com/npm/cli/commit/be4a0900b14b2c6315bf62bed8f5affb648215ae) - [#2360](https://github.com/npm/cli/issues/2360) - raise an error early if publishing without login, registry - ([@isaacs](https://github.com/isaacs)) -* [`44d433105`](https://github.com/npm/cli/commit/44d4331058c53909ada62470b23b2185102b2128) - [#2366](https://github.com/npm/cli/issues/2366) - Include prerelease versions when deprecating - ([@tiegz](https://github.com/tiegz)) -* [`cba3341da`](https://github.com/npm/cli/commit/cba3341dae4c92541049dc976e82e2ba19566e95) - [#2373](https://github.com/npm/cli/issues/2373) - npm profile refactor - ([@ruyadorno](https://github.com/ruyadorno)) -* [`7539504e3`](https://github.com/npm/cli/commit/7539504e3abdec28039a7798e5ccb745b536cb6e) - [#2382](https://github.com/npm/cli/issues/2382) - remove the metrics sender - ([@nlf](https://github.com/nlf)) - -### DOCS - -* [`b98569a8c`](https://github.com/npm/cli/commit/b98569a8ca28dbd611fe84492aee996e2e567b55) - add note about `INIT_CWD` to run-script doc -* [`292929279`](https://github.com/npm/cli/commit/292929279854a06ca60ff737b574cbd6503ec5db) - [#2368](https://github.com/npm/cli/issues/2368) - Revert bug-reporting links to GH. - Re: <https://blog.npmjs.org/post/188841555980/updates-to-community-docs-more> - ([@tiegz](https://github.com/tiegz)) -* [`f4560626f`](https://github.com/npm/cli/commit/f4560626f09dba4889d752f7f739aa5a5f3da741) - update `ISSUE_TEMPLATE` with modern links - ([@isaacs](https://github.com/isaacs)) -* [`bc1c567ed`](https://github.com/npm/cli/commit/bc1c567ed3d853ed4f01d33a800eb453956de6ef) - update npm command doc feature request links - ([@isaacs](https://github.com/isaacs)) -* [`0ad958fe1`](https://github.com/npm/cli/commit/0ad958fe1cb811699caca235f361c8328baac8c4) - [#2381](https://github.com/npm/cli/issues/2381) - (docs,test): assorted typo fixes - ([@XhmikosR](https://github.com/XhmikosR)) - -### TESTING - -* [`a92d310b7`](https://github.com/npm/cli/commit/a92d310b7e9e4c48b08f52785c2e3a6d52a82ad7) - [#2361](https://github.com/npm/cli/issues/2361) - Add max-len to lint rules - ([@Edu93Jer](https://github.com/Edu93Jer)) - -### DEPENDENCIES - -* [`4fc2f3e05`](https://github.com/npm/cli/commit/4fc2f3e05b600aa64fe5eb6b8b77bc070e5a9403) - [#2300](https://github.com/npm/cli/issues/2300) - `@npmcli/config@1.2.8`: - * Support setting email without username/password - -## 7.2.0 (2020-12-15) - -### FEATURES - -* [`a9c4b158c`](https://github.com/npm/cli/commit/a9c4b158c46dd0d0c8d8744a97750ffd0c30cc09) - [#2342](https://github.com/npm/cli/issues/2342) - allow npm rebuild to accept a path to a module - ([@nlf](https://github.com/nlf)) - -### DEPENDENCIES - -* [`beb371800`](https://github.com/npm/cli/commit/beb371800292140bf3882253c447168a378bc154) - [#2334](https://github.com/npm/cli/issues/2334) - remove unused top level dep tough-cookie - ([@darcyclarke](https://github.com/darcyclarke)) -* [`d45e181d1`](https://github.com/npm/cli/commit/d45e181d17dd88d82b3a97f8d9cd5fa5b6230e48) - [#2335](https://github.com/npm/cli/issues/2335) - `ini@2.0.0`, `@npmcli/config@1.2.7` - ([@isaacs](https://github.com/isaacs)) -* [`ef4b18b5a`](https://github.com/npm/cli/commit/ef4b18b5a70381b264d234817cff32eeb6848a73) - [#2309](https://github.com/npm/cli/issues/2309) - `@npmcli/arborist@2.0.2` - * properly remove deps when no lockfile and package.json is present -* [`c6c013e6e`](https://github.com/npm/cli/commit/c6c013e6ebc4fe036695db1fd491eb68f3b57c68) - `readdir-scoped-modules@1.1.0` -* [`a1a2134aa`](https://github.com/npm/cli/commit/a1a2134aa9a1092493db6d6c9a729ff5203f0dd4) - remove unused sorted-object dep - ([@nlf](https://github.com/nlf)) -* [`85c2a2d31`](https://github.com/npm/cli/commit/85c2a2d318ae066fb2c161174f5aea97e18bc9c5) - [#2344](https://github.com/npm/cli/issues/2344) - remove editor dependency - ([@nlf](https://github.com/nlf)) - -### TESTING - -* [`3a6dd511c`](https://github.com/npm/cli/commit/3a6dd511c944c5f2699825a99bba1dde333a45ef) - npm edit - ([@nlf](https://github.com/nlf)) -* [`3ba5de4e7`](https://github.com/npm/cli/commit/3ba5de4e7f6c5c0f995a29844926d6ed2833addd) - [#2347](https://github.com/npm/cli/issues/2347) - npm help-search - ([@nlf](https://github.com/nlf)) -* [`6caf19f49`](https://github.com/npm/cli/commit/6caf19f491e144be3e2a1a50f492dad48b01f361) - [#2348](https://github.com/npm/cli/issues/2348) - npm help - ([@nlf](https://github.com/nlf)) -* [`cb5847e32`](https://github.com/npm/cli/commit/cb5847e3203c52062485b5de68e4f6d29b33c361) - [#2349](https://github.com/npm/cli/issues/2349) - npm hook - ([@nlf](https://github.com/nlf)) -* [`996a2f6b1`](https://github.com/npm/cli/commit/996a2f6b130d6678998a2f6a5ec97d75534d5f66) - [#2353](https://github.com/npm/cli/issues/2353) - npm org - ([@nlf](https://github.com/nlf)) -* [`8c67c38a4`](https://github.com/npm/cli/commit/8c67c38a4f476ff5be938db6b6b3ee9ac6b44db5) - [#2354](https://github.com/npm/cli/issues/2354) - npm set - ([@nlf](https://github.com/nlf)) - -## 7.1.2 (2020-12-11) - -### DEPENDENCIES - -* [`c3ba1daf7`](https://github.com/npm/cli/commit/c3ba1daf7cd335d72aeba80ae0e9f9d215ca9ea5) - [#2033](https://github.com/npm/cli/issues/2033) `@npmcli/config@1.2.6`: - * Set `INIT_CWD` to initial current working directory - * Set `NODE` to initial process.execPath -* [`8029608b9`](https://github.com/npm/cli/commit/8029608b914fe5ba35a7cd37ae95ab93b0532e2e) - `json-parse-even-better-errors@2.3.1` -* [`0233818e6`](https://github.com/npm/cli/commit/0233818e606888b80881b17a2c6aca9f10a619b2) - [#2332](https://github.com/npm/cli/issues/2332) `treeverse@1.0.4` -* [`e401d6bb3`](https://github.com/npm/cli/commit/e401d6bb37ffc767b4fefe89878dd3c3ef490b2c) - `ini@1.3.8` -* [`011bb1220`](https://github.com/npm/cli/commit/011bb122035dcd43769ec35982662cca41635068) - [#2320](https://github.com/npm/cli/issues/2320) `@npmcli/arborist@2.0.1`: - * Do not save with `^` and no version - -### BUGFIXES - -* [`244c2069f`](https://github.com/npm/cli/commit/244c2069fd093f053d3061c85575ac13e72e2454) - [#2325](https://github.com/npm/cli/issues/2325) npm search - include/exclude ([@ruyadorno](https://github.com/ruyadorno)) -* [`d825e901e`](https://github.com/npm/cli/commit/d825e901eceea4cf8d860e35238dc30008eb4da4) - [#1905](https://github.com/npm/cli/issues/1905) - [#2316](https://github.com/npm/cli/issues/2316) run install scripts for - root project -* [`315449142`](https://github.com/npm/cli/commit/31544914294948085a84097af7f0f5de2a2e8f7e) - [#2331](https://github.com/npm/cli/issues/2331) - [#2021](https://github.com/npm/cli/issues/2021) Set `NODE_ENV=production` - if 'dev' is on the omit list ([@isaacs](https://github.com/isaacs)) - -### TESTING - -* [`c243e3b9d`](https://github.com/npm/cli/commit/c243e3b9d9bda0580a0fc1b3e230b4d47412176e) - [#2313](https://github.com/npm/cli/issues/2313) tests: completion - ([@nlf](https://github.com/nlf)) -* [`7ff6efbb8`](https://github.com/npm/cli/commit/7ff6efbb866591b2330b967215cef8146dff3ebf) - [#2314](https://github.com/npm/cli/issues/2314) npm team - ([@ruyadorno](https://github.com/ruyadorno)) -* [`7a4f0c96c`](https://github.com/npm/cli/commit/7a4f0c96c2ab9f264f7bda2caf7e72c881571270) - [#2323](https://github.com/npm/cli/issues/2323) npm doctor - ([@nlf](https://github.com/nlf)) - -### DOCUMENTATION - -* [`e340cf64b`](https://github.com/npm/cli/commit/e340cf64ba31ef329a9049b60c32ffd0342cfb7d) - [#2330](https://github.com/npm/cli/issues/2330) explain through - run-script ([@isaacs](https://github.com/isaacs)) - -## 7.1.1 (2020-12-08) - -### DEPENDENCIES - -* [`bf09e719c`](https://github.com/npm/cli/commit/bf09e719c7f563a255b1e9af6b1237ebc5598db6) - `@npmcli/arborist@2.0.0` - * Much stricter tree integrity guarantees - * Fix issues where the root project is a symlink, or linked as a - workspace -* [`7ceb5b728`](https://github.com/npm/cli/commit/7ceb5b728b9f326c567f5ffe5831c9eccf013aa0) - `ini@1.3.6` -* [`77c6ced2a`](https://github.com/npm/cli/commit/77c6ced2a6daaadbff715c8f05b2e61ba76e9bab) - `make-fetch-happen@8.0.11` - * Avoid caching headers that are hazardous or unnecessary to leave - lying around (authorization, npm-session, etc.) - * [#38](https://github.com/npm/make-fetch-happen/pull/38) Include query - string in cache key ([@jpb](https://github.com/jpb)) -* [`0ef25b6cd`](https://github.com/npm/cli/commit/0ef25b6cd2921794d36f066e2b11c406342cf167) - `libnpmsearch@3.1.0`: - * Update to accept query params as options, so we can paginate. - ([@nlf](https://github.com/nlf)) -* [`518a66450`](https://github.com/npm/cli/commit/518a664500bcde30475788e8c1c3e651f23e881b) - `@npmcli/config@1.2.4`: - * Do not allow path options to be set to a boolean `false` value -* [`3d7aff9d8`](https://github.com/npm/cli/commit/3d7aff9d8dd1cf29956aa306464cd44fbc2af426) - update all dependencies using latest npm to install them - -### TESTS - -* [`2848f5940`](https://github.com/npm/cli/commit/2848f594034b87939bfc5546e3e603f123d98a01) - [npm/statusboard#173](https://github.com/npm/statusboard/issues/173) - [#2293](https://github.com/npm/cli/issues/2293) npm shrinkwrap - ([@ruyadorno](https://github.com/ruyadorno)) -* [`f6824459a`](https://github.com/npm/cli/commit/f6824459ae0c86e2fa9c84b3dcec85f572ae8e1b) - [#2302](https://github.com/npm/cli/issues/2302) npm deprecate - ([@nlf](https://github.com/nlf)) -* [`b7d74b627`](https://github.com/npm/cli/commit/b7d74b627859f08fca23209d6e0d3ec6657a4489) - [npm/statusboard#180](https://github.com/npm/statusboard/issues/180) - [#2304](https://github.com/npm/cli/issues/2304) npm unpublish - ([@ruyadorno](https://github.com/ruyadorno)) - -### FEATURES - -* [`3db90d944`](https://github.com/npm/cli/commit/3db90d94474f673591811fdab5eb6a5bfdeba261) - [#2303](https://github.com/npm/cli/issues/2303) allow for passing object - keys to searchopts to allow pagination ([@nlf](https://github.com/nlf)) - -## 7.1.0 (2020-12-04) - -### FEATURES - -* [`6b1575110`](https://github.com/npm/cli/commit/6b15751106beb99234aa4bf39ae05cf40076d42a) - [#2237](https://github.com/npm/cli/pull/2237) - add `npm set-script` command - ([@Yash-Singh1](https://github.com/Yash-Singh1)) -* [`15d7333f8`](https://github.com/npm/cli/commit/15d7333f832e3d68ae16895569f27a27ef86573e) - add interactive `npm exec` - ([@isaacs](https://github.com/isaacs)) - -### BUG FIXES - -* [`2a1192e4b`](https://github.com/npm/cli/commit/2a1192e4b03acdf6e6e24e58de68f736ab9bb35f) - [#2202](https://github.com/npm/cli/pull/2202) - Do not run interactive `npm exec` in CI when a TTY - ([@isaacs](https://github.com/isaacs)) - -### DOCUMENTATION - -* [`0599cc37d`](https://github.com/npm/cli/commit/0599cc37df453bf79d47490eb4fca3cd63f67f80) - [#2271](https://github.com/npm/cli/pull/2271) - don't wrap code block - ([@ethomson](https://github.com/ethomson)) - -### DEPENDENCIES - -* [`def85c726`](https://github.com/npm/cli/commit/def85c72640ffe2d27977c56b7aa06c6f6346ca9) - `@npmcli/arborist@1.0.14` - * fixes running `npm exec` from file system root folder -* [`4c94673ab`](https://github.com/npm/cli/commit/4c94673ab5399d27e5a48e52f7a65b038a456265) - `semver@7.3.4` - -## 7.0.15 (2020-11-27) - -### DEPENDENCIES - -* [`00e6028ef`](https://github.com/npm/cli/commit/00e6028ef83bf76eaae10241fd7ba59e39768603) - `@npmcli/arborist@1.0.13` - * do not override user-defined shorthand values when saving `package.json` - -### BUG FIXES - -* [`9c3413fbc`](https://github.com/npm/cli/commit/9c3413fbcb37e79fc0b3d980e0b5810d7961277c) - [#2034](https://github.com/npm/cli/issues/2034) - [#2245](https://github.com/npm/cli/issues/2245) - `npm link <pkg>` should not save `package.json` - ([@ruyadorno](https://github.com/ruyadorno)) - -### DOCUMENTATION - -* [`1875347f9`](https://github.com/npm/cli/commit/1875347f9f4f2b50c28fe8857c5533eeebf42da2) - [#2196](https://github.com/npm/cli/issues/2196) - remove doc on obsolete `unsafe-perm` flag - ([@kaizhu256](https://github.com/kaizhu256)) -* [`f51e50603`](https://github.com/npm/cli/commit/f51e5060340c783a8a00dadd98e5786960caf43f) - [#2200](https://github.com/npm/cli/issues/2200) - `config.md` cleanup - ([@alexwoollam](https://github.com/alexwoollam)) -* [`997cbdb40`](https://github.com/npm/cli/commit/997cbdb400bcd22e457e8a06b69a7be697cfd66d) - [#2238](https://github.com/npm/cli/issues/2238) - Fix broken link to `package.json` documentation - ([@d-fischer](https://github.com/d-fischer)) -* [`9da972dc4`](https://github.com/npm/cli/commit/9da972dc44c21cf0e337f1c3fca44eb9df3e40d5) - [#2241](https://github.com/npm/cli/issues/2241) - `npm star` docs cleanup - ([@ruyadorno](https://github.com/ruyadorno)) - -## 7.0.14 (2020-11-23) - -### DEPENDENCIES -* [`09d21ab90`](https://github.com/npm/cli/commit/09d21ab903dcfebdfd446b8b29ad46c425b6510e) - `@npmcli/run-script@1.8.1` - - fix a regression in how scripts are escaped - -## 7.0.13 (2020-11-20) - -### BUG FIXES -* [`5fc56b6db`](https://github.com/npm/cli/commit/5fc56b6dbcc7d7d1463a761abb67d2fc16ad3657) - [npm/statusboard#174](https://github.com/npm/statusboard/issues/174) - [#2204](https://github.com/npm/cli/issues/2204) - fix npm unstar command - ([@ruyadorno](https://github.com/ruyadorno)) -* [`7842b4d4d`](https://github.com/npm/cli/commit/7842b4d4dca1e076b0d26d554f9dce67484cd7be) - [npm/statusboard#182](https://github.com/npm/statusboard/issues/182) - [#2205](https://github.com/npm/cli/issues/2205) - fix npm version usage output - ([@ruyadorno](https://github.com/ruyadorno)) -* [`a0adbf9f8`](https://github.com/npm/cli/commit/a0adbf9f8f77531fcf81ae31bbc7102698765ee3) - [#2206](https://github.com/npm/cli/issues/2206) - [#2213](https://github.com/npm/cli/issues/2213) - fix: fix flatOptions usage in npm init - ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`3daaf000a`](https://github.com/npm/cli/commit/3daaf000aee0ba81af855977d7011850e79099e6) - `@npmcli/arborist@1.0.12` - - fixes some windows specific bugs in how paths are handled and compared - -### DOCUMENTATION - -* [`084a7b6ad`](https://github.com/npm/cli/commit/084a7b6ad6eaf9f2d92eb05da93e745f5357cce2) - [#2210](https://github.com/npm/cli/issues/2210) - docs: Fix typo - ([@HollowMan6](https://github.com/HollowMan6)) - -## 7.0.12 (2020-11-17) - -### BUG FIXES - -* [`7b89576bd`](https://github.com/npm/cli/commit/7b89576bd1fa557a312a841afa66b895558d1b12) - [#2174](https://github.com/npm/cli/issues/2174) - fix running empty scripts with `npm run-script` - ([@nlf](https://github.com/nlf)) -* [`bc9afb195`](https://github.com/npm/cli/commit/bc9afb195f5aad7c06bc96049c0f00dc8e752dee) - [#2002](https://github.com/npm/cli/issues/2002) - [#2184](https://github.com/npm/cli/issues/2184) - Preserve builtin conf when installing npm globally - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`b74c05d88`](https://github.com/npm/cli/commit/b74c05d88dc48fabef031ea66ffaa4e548845655) - `@npmcli/run-script@1.8.0` - * fix windows command-line argument escaping - -### DOCUMENTATION - -* [`4e522fdc9`](https://github.com/npm/cli/commit/4e522fdc917bc85af2ca8ff7669a0178e2f35123) - [#2179](https://github.com/npm/cli/issues/2179) - remove mention to --parseable option from `npm audit` docs - ([@Primajin](https://github.com/Primajin)) - -## 7.0.11 (2020-11-13) - -### DEPENDENCIES - -* [`629a667a9`](https://github.com/npm/cli/commit/629a667a9b30b0b870075da965606979622a5e2e) - `eslint@7.13.0` -* [`de9891bd2`](https://github.com/npm/cli/commit/de9891bd2a16fe890ff5cfb140c7b1209aeac0de) - `eslint-plugin-standard@4.1.0` -* [`c3e7aa31c`](https://github.com/npm/cli/commit/c3e7aa31c565dfe21cd1f55a8433bfbcf58aa289) - [#2123](https://github.com/npm/cli/issues/2123) - [#1957](https://github.com/npm/cli/issues/1957) - `@npmcli/arborist@1.0.11` - -### BUG FIXES - -* [`a8aa38513`](https://github.com/npm/cli/commit/a8aa38513ad5c4ad44e6bb3e1499bfc40c31e213) - [#2134](https://github.com/npm/cli/issues/2134) - [#2156](https://github.com/npm/cli/issues/2156) - Fix `cannot read property length of undefined` in `ERESOLVE` explanation code - ([@isaacs](https://github.com/isaacs)) -* [`1dbf0f9bb`](https://github.com/npm/cli/commit/1dbf0f9bb26ba70f4c6d0a807701d7652c31d7d4) - [#2150](https://github.com/npm/cli/issues/2150) - [#2155](https://github.com/npm/cli/issues/2155) - send json errors to stderr, not stdout - ([@isaacs](https://github.com/isaacs)) -* [`fd1d7a21b`](https://github.com/npm/cli/commit/fd1d7a21b247bb35d112c51ff8d8a06fd83c8b44) - [#1927](https://github.com/npm/cli/issues/1927) - [#2154](https://github.com/npm/cli/issues/2154) - Set process.title a bit more usefully - ([@isaacs](https://github.com/isaacs)) -* [`2a80c67ef`](https://github.com/npm/cli/commit/2a80c67ef8c12c3d9d254f5be6293a6461067d99) - [#2008](https://github.com/npm/cli/issues/2008) - [#2153](https://github.com/npm/cli/issues/2153) - Support legacy auth tokens for registries that use them - ([@ruyadorno](https://github.com/ruyadorno)) -* [`786e36404`](https://github.com/npm/cli/commit/786e36404068fd51657ddac766e066a98754edbf) - [#2017](https://github.com/npm/cli/issues/2017) - [#2159](https://github.com/npm/cli/issues/2159) - pass all options to Arborist for `npm ci` - ([@darcyclarke](https://github.com/darcyclarke)) -* [`b47ada7d1`](https://github.com/npm/cli/commit/b47ada7d1623e9ee586ee0cf781ee3ac5ea3c223) - [#2161](https://github.com/npm/cli/issues/2161) - fixed typo - ([@scarabedore](https://github.com/scarabedore)) - -## 7.0.10 (2020-11-10) - -### DOCUMENTATION - -* [`e48badb03`](https://github.com/npm/cli/commit/e48badb03058286a557584d7319db4143049cc6b) - [#2148](https://github.com/npm/cli/issues/2148) - Fix link in documentation - ([@gurdiga](https://github.com/gurdiga)) - -### BUG FIXES - -* [`8edbbdc70`](https://github.com/npm/cli/commit/8edbbdc706694fa32f52d0991c76ae9f207b7bbc) - [#1972](https://github.com/npm/cli/issues/1972) - Support exec auto pick bin when all bin is alias - ([@dr-js](https://github.com/dr-js)) - -### DEPENDENCIES - -* [`04a3e8c10`](https://github.com/npm/cli/commit/04a3e8c10c3f38e1c7a35976d77c2929bdc39868) - [#1962](https://github.com/npm/cli/issues/1962) - `@npmcli/arborist@1.0.10`: - * prevent self-assignment of parent/fsParent - * Support update options in global package space - -## 7.0.9 (2020-11-06) - -### BUG FIXES - -* [`96a0d2802`](https://github.com/npm/cli/commit/96a0d2802d3e619c6ea47290f5c460edfe94070a) - default the 'start' script when server.js present - ([@isaacs](https://github.com/isaacs)) -* [`7716e423e`](https://github.com/npm/cli/commit/7716e423ee92a81730c0dfe5b9ecb4bb41a3f947) - [#2075](https://github.com/npm/cli/issues/2075) - [#2071](https://github.com/npm/cli/issues/2071) print the registry when - using 'npm login' ([@Wicked7000](https://github.com/Wicked7000)) -* [`7046fe10c`](https://github.com/npm/cli/commit/7046fe10c5035ac57246a31ca8a6b09e3f5562bf) - [#2122](https://github.com/npm/cli/issues/2122) tests for `npm cache` - command ([@nlf](https://github.com/nlf)) - -### DEPENDENCIES - -* [`74325f53b`](https://github.com/npm/cli/commit/74325f53b9d813b0e42203c037189418fad2f64a) - [#2124](https://github.com/npm/cli/issues/2124) - `@npmcli/run-script@1.7.5`: - * Export the `isServerPackage` method - * Proxy signals to and from foreground child processes -* [`0e58e6f6b`](https://github.com/npm/cli/commit/0e58e6f6b8f0cd62294642a502c17561aaf46553) - [#1984](https://github.com/npm/cli/issues/1984) - [#2079](https://github.com/npm/cli/issues/2079) - [#1923](https://github.com/npm/cli/issues/1923) - [#606](https://github.com/npm/cli/issues/606) - [#2031](https://github.com/npm/cli/issues/2031) `@npmcli/arborist@1.0.9`: - * Process deps for all link nodes - * Use junctions instead of symlinks - * Use @npmcli/move-file instead of fs.rename -* [`1dad328a1`](https://github.com/npm/cli/commit/1dad328a17d93def7799545596b4eba9833b35aa) - [#1865](https://github.com/npm/cli/issues/1865) - [#2106](https://github.com/npm/cli/issues/2106) - [#2084](https://github.com/npm/cli/issues/2084) `pacote@11.1.13`: - * Properly set the installation command for `prepare` scripts when - installing git/dir deps -* [`e090d706c`](https://github.com/npm/cli/commit/e090d706ca637d4df96d28bff1660590aa3f3b62) - [#2097](https://github.com/npm/cli/issues/2097) `libnpmversion@1.0.7`: - * Do not crash when the package.json file lacks a 'version' field -* [`8fa541a10`](https://github.com/npm/cli/commit/8fa541a10dbdc09376175db7a378cc9b33e8b17b) - `cmark-gfm@0.8.4` - -## 7.0.8 (2020-11-03) - -### DOCUMENTATION - -* [`052e977b9`](https://github.com/npm/cli/commit/052e977b9d071e1b3654976881d10cd3ddcba788) - [#1822](https://github.com/npm/cli/issues/1822) - [#1247](https://github.com/npm/cli/issues/1247) - add section on peerDependenciesMeta field in package.json - ([@foxxyz](https://github.com/foxxyz)) -* [`52d32d175`](https://github.com/npm/cli/commit/52d32d1758c5ebc58944a1e8d98d57e30048e527) - [#1970](https://github.com/npm/cli/issues/1970) - match npm-exec.md -p usage with lib/exec.js - ([@dr-js](https://github.com/dr-js)) -* [`48ee8d01e`](https://github.com/npm/cli/commit/48ee8d01edd11ed6186c483e1169ff4d2070b963) - [#2096](https://github.com/npm/cli/issues/2096) - Fix RFC links in changelog - ([@jtojnar](https://github.com/jtojnar)) - - -### BUG FIXES - -* [`6cd3cd08a`](https://github.com/npm/cli/commit/6cd3cd08af56445e13757cac3af87f3e7d54ed27) - Support *all* conf keys in publishConfig -* [`a1f9be8a7`](https://github.com/npm/cli/commit/a1f9be8a7f9b7a3a813fc3e5e705bc982470b0e2) - [#2074](https://github.com/npm/cli/issues/2074) - Support publishing any kind of spec, not just directories - -### DEPENDENCIES - -* [`545382df6`](https://github.com/npm/cli/commit/545382df62e3014f3e51d7034e52498fb2b01a37) - `libnpmpublish@4.0.0`: - * Support publishing things other than folders -* [`7d88f1719`](https://github.com/npm/cli/commit/7d88f17197e3c8cca9b277378d6f9b054b1b7886) - `npm-registry-fetch@9.0.0` -* [`823b40a4e`](https://github.com/npm/cli/commit/823b40a4e9c6ef76388af6fe01a3624f6f7675be) - `pacote@11.1.12` -* [`90bf57826`](https://github.com/npm/cli/commit/90bf57826edf2f78ddf8deb0793115ead8a8b556) - `npm-profile@5.0.2` -* [`e5a413577`](https://github.com/npm/cli/commit/e5a4135770d13cf114fac439167637181f87d824) - `libnpmteam@2.0.2` -* [`fc5aa7b4a`](https://github.com/npm/cli/commit/fc5aa7b4ad45cb65893f734e1229a6720f7966e5) - `libnpmsearch@3.0.1` -* [`9fc1dee13`](https://github.com/npm/cli/commit/9fc1dee138ca33ecdbd57e63142b27c60cf88f9b) - `libnpmorg@2.0.1` -* [`0ea870ec5`](https://github.com/npm/cli/commit/0ea870ec5d2be1d44f050ad8bc24ed936cc45fde) - `libnpmhook@6.0.1` -* [`32fd744ea`](https://github.com/npm/cli/commit/32fd744ea745f297f0be79a80955f077a57c4ac7) - `libnpmaccess@4.0.1` -* [`fc76f3d9f`](https://github.com/npm/cli/commit/fc76f3d9fcf19e65a9373ab3d9068c4326d2f782) - `@npmcli/arborist@1.0.8` - * Fix `cannot read property 'description' of undefined` in `npm ls` - when `package-lock.json` is corrupted - * Do not allow peerDependencies to be nested under dependents in any - circumstances - * Always resolve peerDependencies in `--prefer-dedupe` mode - -## 7.0.7 (2020-10-30) - -### BUG FIXES - -* [`3990b422d`](https://github.com/npm/cli/commit/3990b422d3ff63c54d96b61596bdb8f26a45ca7b) - [#2067](https://github.com/npm/cli/pull/2067) - use sh as default unix shell, not bash - ([@isaacs](https://github.com/isaacs)) -* [`81d6ceef6`](https://github.com/npm/cli/commit/81d6ceef6947e46355eb3ddb05a73da50870dfc1) - [#1975](https://github.com/npm/cli/issues/1975) - fix npm exec on folders missing package.json - ([@ruyadorno](https://github.com/ruyadorno)) -* [`2a680e91a`](https://github.com/npm/cli/commit/2a680e91a2be1f3f03a6fbd946f74628ee1cb370) - [#2083](https://github.com/npm/cli/pull/2083) - delete the contents of `node_modules` only in `npm ci` - ([@nlf](https://github.com/nlf)) -* [`2636fe1f4`](https://github.com/npm/cli/commit/2636fe1f45383cb1b6fc164564dc49318815db37) - [#2086](https://github.com/npm/cli/pull/2086) - disable banner output if loglevel is silent in `npm run-script` - ([@macno](https://github.com/macno)) - -### DEPENDENCIES - -* [`4156f053e`](https://github.com/npm/cli/commit/4156f053ee8712a4b53a210e62fba1e6562ba43a) - `@npmcli/run-script@1.7.4` - * restore the default `npm start` script -* [`1900ae9ad`](https://github.com/npm/cli/commit/1900ae9adecd227dd6f8b49de61a99c978ba89cf) - `@npmcli/promise-spawn@1.3.2` - * fix errors when processing scripts as root -* [`8cb0c166c`](https://github.com/npm/cli/commit/8cb0c166ccc019146a7a94d13c12723f001d2551) - `@npmcli/arborist@1.0.6` - * make sure missing bin links get set on reify - -## 7.0.6 (2020-10-27) - -### BUG FIXES - -* [`46c7f792a`](https://github.com/npm/cli/commit/46c7f792ab16dd0b091e1ad6d37de860c8885883) - [#2047](https://github.com/npm/cli/pull/2047) - [#1935](https://github.com/npm/cli/issues/1935) - skip the prompt when in a known ci environment - ([@nlf](https://github.com/nlf)) -* [`f8f6e1fad`](https://github.com/npm/cli/commit/f8f6e1fad8057edc02e4ce4382b1bc086d01211c) - [#2049](https://github.com/npm/cli/pull/2049) - properly remove pycache in release script - ([@MylesBorins](https://github.com/MylesBorins)) -* [`5db95b393`](https://github.com/npm/cli/commit/5db95b393e9c461ad34c1774f3515c322bf375bf) - [#2050](https://github.com/npm/cli/pull/2050) - pack: do not show individual files of bundled deps - ([@isaacs](https://github.com/isaacs)) -* [`3ee8f3b34`](https://github.com/npm/cli/commit/3ee8f3b34055da2ef1e735e1a06f64593512f1e3) - [#2051](https://github.com/npm/cli/pull/2051) - view: Better errors when package.json is not JSON - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`99ae633f6`](https://github.com/npm/cli/commit/99ae633f6ccc8aa93dc3dcda863071658b0653db) - `libnpmversion@1.0.6` - - respect gitTagVersion = false -* [`d4173f58d`](https://github.com/npm/cli/commit/d4173f58ddefdd5456145f34f3c9f4ba5fca407e) - `@npmcli/promise-spawn@1.3.1` - - do not return empty buffer when stdio is inherited - - attach child process to returned promise -* [`c09380fa5`](https://github.com/npm/cli/commit/c09380fa51b720141a9971602f4bb7aabd4d6242) - `@npmcli/run-script@1.7.3` - - forward SIGINT and SIGTERM to children that inherit stdio -* [`b154861ad`](https://github.com/npm/cli/commit/b154861ad244b6a14020c43738d0cce1948bfdd3) - `@npmcli/arborist@1.0.5` -* [`ffea6596b`](https://github.com/npm/cli/commit/ffea6596b8653da32a2b4c9a4903970e7146eee4) - `agent-base@6.0.2` - - support http proxy for https registries - -## 7.0.5 (2020-10-23) - -* [`77ad86b5e`](https://github.com/npm/cli/commit/77ad86b5eedf139dda3329a6686d5f104dc233bb) - Merge docs deps with main project - -## 7.0.4 (2020-10-23) - -### DOCUMENTATION - -* [`cc026daf8`](https://github.com/npm/cli/commit/cc026daf8c8330256de01375350a1407064562f9) - docs: `npm-dedupe` through `npm-install` -* [`aec77acf8`](https://github.com/npm/cli/commit/aec77acf886d73f85e747cafdf7a2b360befba16) - [#1915](https://github.com/npm/cli/pull/1915) - use "dockhand" for faster static documentation generation - ([@ethomson](https://github.com/ethomson)) -* [`aeb10d210`](https://github.com/npm/cli/commit/aeb10d210816cf6829e0ac557c79d9efd8c4bdd1) - [#2024](https://github.com/npm/cli/pull/2024) - Fix post-install script name - ([@irajtaghlidi](https://github.com/irajtaghlidi)) - -### BUG FIXES - -* [`59e8dd6c6`](https://github.com/npm/cli/commit/59e8dd6c621f9a5c6e0b65533d8256be87a8e0d3) - [#2015](https://github.com/npm/cli/issues/2015) - [#2016](https://github.com/npm/cli/pull/2016) - Properly set `npm_command` environment variable. - -### TESTS - -* [`39ad1ad9e`](https://github.com/npm/cli/commit/39ad1ad9e1e1a9530db5b90a588b5081b71abc8d) - [#2001](https://github.com/npm/cli/pull/2001) - `npm config` tests - ([@ruyadorno](https://github.com/ruyadorno)) -* [`b9c1caa8e`](https://github.com/npm/cli/commit/b9c1caa8e4cc7c900d09657425ea361db5974319) - [#2026](https://github.com/npm/cli/pull/2026) - `npm owner` test and refactor - ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`ed6e6a9d3`](https://github.com/npm/cli/commit/ed6e6a9d3c36ffc5fb77fc25b6d66dbcb26beeb9) - `eslint-plugin-standard@4.0.2` -* [`b737ee999`](https://github.com/npm/cli/commit/b737ee99961364827bacf210a3e5ca5d2b7edad2) - [#2009](https://github.com/npm/cli/issues/2009) - [#2007](https://github.com/npm/cli/issues/2007) - `npm-packlist@2.1.4`: - - * Maintain order in package.json files array globs - * Strip slashes from package files list results - -* [`783965508`](https://github.com/npm/cli/commit/783965508d49f8ab0d8ceff38bee700cd0a06a54) - [#1997](https://github.com/npm/cli/issues/1997) - [#2000](https://github.com/npm/cli/issues/2000) - [#2005](https://github.com/npm/cli/issues/2005) - `@npmcli/arborist@1.0.4` - - * Ensure that root is added when root.meta is set - * Include all edges in explain() output when a root edge exists - * Do not conflict on meta-peers that will not be replaced - * Install peerOptionals if explicitly requested, or dev - -## 7.0.3 (2020-10-20) - -### BUG FIXES - -* [`ce4724a38`](https://github.com/npm/cli/commit/ce4724a3835ded9a4a29d8d67323f925461155e5) - [#1986](https://github.com/npm/cli/pull/1986) - check `result` when determining exit code of `ls <filter>` - ([@G-Rath](https://github.com/G-Rath)) -* [`00d926f8d`](https://github.com/npm/cli/commit/00d926f8d884872d08d9a0cd73aa9cace2acb91b) - [#1987](https://github.com/npm/cli/pull/1987) - don't suppress run output when `--silent` is passed - ([@G-Rath](https://github.com/G-Rath)) -* [`043da2347`](https://github.com/npm/cli/commit/043da234745f36d55742e827314837dead5807ab) - improve cache clear error message - ([@isaacs](https://github.com/isaacs)) - -### DOCUMENTATION - -* [`a57f5c466`](https://github.com/npm/cli/commit/a57f5c466ceae59575ef05bb7941cce8752d8c58) - update docs for: access, adduser, audit, bin, bugs, build, cache, ci, - completion, config and dedupe - ([@isaacs](https://github.com/isaacs)) -* [`5b88b72b9`](https://github.com/npm/cli/commit/5b88b72b9821f7114cc4e475bbf52726a1674e52) - remove the long-gone bundle command - ([@isaacs](https://github.com/isaacs)) -* [`ae09aa5c1`](https://github.com/npm/cli/commit/ae09aa5c1cd150727b05ccfaeaba8d45e5697e50) - [#1993](https://github.com/npm/cli/pull/1993) - document --save-peer as a common option to npm install - ([@JakeChampion](https://github.com/JakeChampion)) -* [`c9993e6b1`](https://github.com/npm/cli/commit/c9993e6b1c2918699c2d125bf9b966f44f5d3ebe) - [#1982](https://github.com/npm/cli/pull/1982) - fix url links for init-package-json/node-semver - ([@takenspc](https://github.com/takenspc)) - -### DEPENDENCIES - -* [`5d9df8395`](https://github.com/npm/cli/commit/5d9df83958d3d5e6d8acad2ebabfbe5f3fd23c13) - `node-gyp@7.1.2` - -## 7.0.2 (2020-10-16) - -### DOCUMENTATION - -* [`9476734b7`](https://github.com/npm/cli/commit/9476734b7d5fa6df80ad17ad277a6bee9a16235c) - [#1967](https://github.com/npm/cli/pull/1967) - add mention to workspaces prepare lifecycle - ([@ruyadorno](https://github.com/ruyadorno)) - -### BUG FIXES - -* [`5cf71c689`](https://github.com/npm/cli/commit/5cf71c689bcfcd423405e59d05b7cc5704cb4c02) - [#1971](https://github.com/npm/cli/pull/1971) - owner rm at local pkg not work - ([@ShangguanQuail](https://github.com/ShangguanQuail)) - -### DEPENDENCIES - -* [`722b7ae63`](https://github.com/npm/cli/commit/722b7ae63da8b386fe188066dc2dae0121d9353b) - [#1974](https://github.com/npm/cli/pull/1974) - patch node-gyp - ([@targos](https://github.com/MylesBorins)) -* [`4ae825c01`](https://github.com/npm/cli/commit/4ae825c01c7ca3031361f9df72594a190c6ed1e4) - [#1976](https://github.com/npm/cli/pull/1976) - patch node-gyp - ([@MylesBorins](https://github.com/MylesBorins)) -* [`181eabf13`](https://github.com/npm/cli/commit/181eabf132c823af086380368de73d2f42e5aac1) - `@npmcli/arborist@1.0.3` - * fix workspaces `prepare` lifecycle scripts - * fix peer deps overchecks resulting in ERESOLVE -* [`6cc115409`](https://github.com/npm/cli/commit/6cc115409b7eb2df8e11db6232ee3d00e4316a7d) - `init-package-json@2.0.1` -* [`dbf9d6d1f`](https://github.com/npm/cli/commit/dbf9d6d1f060ea43b700409306574396a798127d) - `libnpmpublish@3.0.2` - -## 7.0.1 (2020-10-15) - -### DOCUMENTATION - -* [`03fca6a3b`](https://github.com/npm/cli/commit/03fca6a3b227f71562863bec7a1de1732bd719f1) - Adds docs on workspaces, explaining its basic concept and how to use it. - ([@ruyadorno](https://github.com/ruyadorno)) - -### BUG FIXES - -* [`2ccb63659`](https://github.com/npm/cli/commit/2ccb63659f9a757201658d5d019099b492d04a5b) - [#1951](https://github.com/npm/cli/issues/1951) - [#1956](https://github.com/npm/cli/pull/1956) - Handle errors from audit endpoint appropriately - ([@isaacs](https://github.com/isaacs)) - -### DEPENDENCIES - -* [`120e62736`](https://github.com/npm/cli/commit/120e6273604f15a2ce55668dfb2c23d06bf1e06c) - `node-gyp@7.1.1` -* [`6560b8d95`](https://github.com/npm/cli/commit/6560b8d952a613cefbd900186aa38df53bc201d1) - `@npmcli/arborist@1.0.2` - * do not drop scope information when fetching scoped package tarballs - * fix cycles/ordering resolution when peer deps require nesting -* [`282a1e008`](https://github.com/npm/cli/commit/282a1e00820b9abfb3465d044b30b2cade107909) - `npm-user-validate@1.0.1` -* [`b259edcb4`](https://github.com/npm/cli/commit/b259edcb4bac37e6f26d56af5f6666afbda8c126) - `hosted-git-info@3.0.7` - -## v7.0.0 (2020-10-12) - -### BUG FIXES - -* [`7bcdb3636`](https://github.com/npm/cli/commit/7bcdb3636e29291b9c722fe03a8450859dcb5b4f) - [#1949](https://github.com/npm/cli/pull/1949) fix: ensure `publishConfig` - is passed through ([@nlf](https://github.com/nlf)) -* [`97978462e`](https://github.com/npm/cli/commit/97978462e9050261e4ce2549e71fe94a48796577) - fix: patch `config.js` to remove duplicate vals - ([@darcyclarke](https://github.com/darcyclarke)) - -### DOCUMENTATION - -* [`60769d757`](https://github.com/npm/cli/commit/60769d757859c88e2cceab66975f182a47822816) - [#1911](https://github.com/npm/cli/pull/1911) docs: v7 npm-install - refresh ([@ruyadorno](https://github.com/ruyadorno)) -* [`08de49042`](https://github.com/npm/cli/commit/08de4904255742cbf7477a20bdeebe82f283a406) - [#1938](https://github.com/npm/cli/pull/1938) docs: v7 using npm config - updates ([@ruyadorno](https://github.com/ruyadorno)) - -### DEPENDENCIES - -* [`15366a1cf`](https://github.com/npm/cli/commit/15366a1cf0073327b90ac7eb977ff8a73b52cc62) - `npm-registry-fetch@8.1.5` -* [`f04a74140`](https://github.com/npm/cli/commit/f04a74140bf65db36be3c379e0eb20dd6db3cc5c) - `init-package-json@2.0.0` - * [`1de21dce0`](https://github.com/npm/cli/commit/1de21dce0e56874203a789ce33124a4fc4d3b15f) - fix: support dot-separated aliases defined in a `.npmrc` ini files - for `init-*` configs ([@ruyadorno](https://github.com/ruyadorno)) -* [`a67275cd9`](https://github.com/npm/cli/commit/a67275cd9a75fa05ee3d3265832d0a015b14e81c) - `eslint@7.11.0` -* [`6fb83b78d`](https://github.com/npm/cli/commit/6fb83b78db09adfafd7cbd4b926e77802c4993e4) - `hosted-git-info@3.0.6` -* [`1ca30cc9b`](https://github.com/npm/cli/commit/1ca30cc9b8e7edc2043c1f848855f19781729dc9) - `libnpmfund@1.0.0` -* [`28a2d2ba4`](https://github.com/npm/cli/commit/28a2d2ba4a63808614f5d98685a64531e3198b93) - `@npmcli/arborist@1.0.0` - * [npm/rfcs#239](https://github.com/npm/rfcs/pull/239) Improve handling - of conflicting `peerDependencies` in transitive dependencies, so that - `--force` will always accept a best effort override, and - `--strict-peer-deps` will fail faster on conflicts. -* [`9306c6833`](https://github.com/npm/cli/commit/9306c6833e2e77675e0cfddd569b6b54a8bcf172) - `libnpmfund@1.0.1` -* [`fafb348ef`](https://github.com/npm/cli/commit/fafb348ef976116d47ada238beb258d5db5758a7) - `npm-package-arg@8.1.0` -* [`365f2e756`](https://github.com/npm/cli/commit/365f2e7565d0cfde858a43d894a77fb3c6338bb7) - `read-package-json@3.0.0` - -## v7.0.0-rc.4 (2020-10-09) - -* [`09b456f2d`](https://github.com/npm/cli/commit/09b456f2d776e2757956d2b9869febd1e01a1076) - `@npmcli/config@1.2.1` - * [#1919](https://github.com/npm/cli/pull/1919) - exposes `npm_config_user_agent` env variable - ([@nlf](https://github.com/nlf)) -* [`e859fba9e`](https://github.com/npm/cli/commit/e859fba9e7c267b0587b7d22da72e33f3e8f906b) - [#1936](https://github.com/npm/cli/pull/1936) - fix npx for non-interactive shells - ([@nlf](https://github.com/nlf)) -* [`9320b8e4f`](https://github.com/npm/cli/commit/9320b8e4f0e0338ea95e970ec9bbf0704def64b8) - [#1906](https://github.com/npm/cli/pull/1906) - restore old npx behavior of running existing bins first - ([@nlf](https://github.com/nlf)) -* [`7bd47ca2c`](https://github.com/npm/cli/commit/7bd47ca2c718df0a7d809f1992b7a87eece3f6dc) - `@npmcli/arborist@0.0.33` - * fixed handling of invalid package.json file -* [`02737453b`](https://github.com/npm/cli/commit/02737453bc2363daeef8c4e4b7d239e2299029b2) - `make-fetch-happen@8.0.10` - * do not calculate integrity values of http errors - -## v7.0.0-rc.3 (2020-10-06) - -* [`d816c2efa`](https://github.com/npm/cli/commit/d816c2efae41930cbdf4fff8657e0adc450d1dd4) - [`c8f0d5457`](https://github.com/npm/cli/commit/c8f0d5457dd913b425987ae30a611d4eb9e84b7d) - [`d48086d0d`](https://github.com/npm/cli/commit/d48086d0d3e006e76f364fb2c62b406a97ce8f68) - [`f34595f2e`](https://github.com/npm/cli/commit/f34595f2e5814a929049aca0349ce418a7f400c6) - [#1902](https://github.com/npm/cli/pull/1902) - tests for several commands - ([@nlf](https://github.com/nlf)) -* [`6d49207db`](https://github.com/npm/cli/commit/6d49207dbc5d66f91f4f462f05dd8916046e3a7b) - [#1903](https://github.com/npm/cli/pull/1903) - Revert "Remove unused npx binary" - ([@MylesBorins](https://github.com/MylesBorins)) -* [`138dfc202`](https://github.com/npm/cli/commit/138dfc202f401d2d93b4b5d2499799be6eb4ff0b) - set executable permissions on bins that node installer uses -* [`b06d68078`](https://github.com/npm/cli/commit/b06d68078830cc2446b1e51553db10e87591865b) - `@npmcli/arborist@0.0.32` - * Do not remove `node_modules` folders from Workspaces when - `loadActual` races with `buildIdealTree` ([@ruyadorno](https://github.com/ruyadorno)) -* [`2509e3a1b`](https://github.com/npm/cli/commit/2509e3a1bf76289062f1f6f06eee184df386054b) - `uuid@8.3.1` - -## v7.0.0-rc.2 (2020-10-02) - -* [`6de81a013`](https://github.com/npm/cli/commit/6de81a013833e0961abdec6f7c1ad50b63faaae6) - `@npmcli/run-script@1.7.2` - * Fix regression running 'install' scripts when package.json does not - contain a scripts object - -## v7.0.0-rc.1 (2020-10-02) - -* [`281a7f39a`](https://github.com/npm/cli/commit/281a7f39ac314bd7657ce2bcd7918b21eee99210) - `@npmcli/arborist@0.0.31` - * Allow `npm update` to update bundled root dependencies - * Only do implicit node-gyp build for gyp files named `binding.gyp` -* [`384f5ec47`](https://github.com/npm/cli/commit/384f5ec47091eed66c2a47f2c98df3ba7506ec9f) - update minipass-fetch to fix many 'cb() never called' errors -* [`7b1e75906`](https://github.com/npm/cli/commit/7b1e75906351bd73cde2f745ccaf63b9ad7de435) - `@npmcli/run-script@1.7.1` - * Only do implicit node-gyp build for gyp files named `binding.gyp` -* [`c20e2f0c7`](https://github.com/npm/cli/commit/c20e2f0c7766a04f999fdc64faad29277904c2d3) - [#1892](https://github.com/npm/cli/pull/1892) - Support `--omit` options in npm outdated - -## v7.0.0-rc.0 (2020-10-01) - -* [`3b417055c`](https://github.com/npm/cli/commit/3b417055cf07c4ef8e4c5063f00d3c24b5f5cbd2) - [#1859](https://github.com/npm/cli/pull/1859) - fix `proxy` and `https-proxy` config support - ([@badeggg](https://github.com/badeggg)) -* [`dd7d7a284`](https://github.com/npm/cli/commit/dd7d7a284d5150d1804d0cd5a85519c86adf3bc2) - `@npmcli/arborist@0.0.30` - * [#1849](https://github.com/npm/cli/issues/1849) Do not drop peer/dev - dep while saving if both set - * Do not install or build if there is a global top bin conflict - * Default to building node-gyp dependencies -* [`40c17e12c`](https://github.com/npm/cli/commit/40c17e12c5a734c37b88692e36221ac974c0c63d) - `cli-table3@0.6.0` -* [`47a8ca1d7`](https://github.com/npm/cli/commit/47a8ca1d72f0f0835b45cfb2c4fb8ab1218dc14a) - `byte-size@7.0.0` -* [`81073f99a`](https://github.com/npm/cli/commit/81073f99a93b680e3ca08b8f099e9aca2aaf50be) - `eslint@7.10.0` -* [`67793abd4`](https://github.com/npm/cli/commit/67793abd4abdf315816b6266ddb045289f607b03) - `eslint-plugin-import@2.22.1` -* [`a27e8d006`](https://github.com/npm/cli/commit/a27e8d00664e5d4c3e81d664253a10176adb39c8) - `is-cidr@4.0.2` -* [`893fed45e`](https://github.com/npm/cli/commit/893fed45e2272ef764ebf927c659fcf5e7b355b3) - `marked-man@0.7.0` -* [`bc20e0c8a`](https://github.com/npm/cli/commit/bc20e0c8ae30a202c72af88586ab9c167dff980a) - `rimraf@3.0.2` -* [`a2b8fd3c1`](https://github.com/npm/cli/commit/a2b8fd3c153ecca55cb2d60654fff207688532ab) - `uuid@8.3.0` -* [`ee4c85b87`](https://github.com/npm/cli/commit/ee4c85b878410143644460c3860ab706a8c925e0) - `write-file-atomic@3.0.3` -* [`4bdad5fdf`](https://github.com/npm/cli/commit/4bdad5fdf6ef387e2159b529ba4652f0221433b5) - `bin-links@2.2.1` -* [`c394937ec`](https://github.com/npm/cli/commit/c394937ec1911cd17ec42c8fc74773047d47322c) - `@npmcli/run-script@1.7.0` - * Default to building node-gyp dependencies and projects -* remove many unused dependencies - ([@ruyadorno](https://github.com/ruyadorno)) - * [`558e9781a`](https://github.com/npm/cli/commit/558e9781ada06b66be4d2d5d0f7e763f645eda25) - deep-equal - * [`2aa9a1f8a`](https://github.com/npm/cli/commit/2aa9a1f8a5773b9a960b14b51c8111fb964bc9ae) - request - * [`d77594e52`](https://github.com/npm/cli/commit/d77594e52f2f7d65d45347f542f48e4dbb6d2f26) - npm-registry-couchapp - * [`8ec84d9f6`](https://github.com/npm/cli/commit/8ec84d9f691686da67bd14c2728472c94ab3b955) - tacks - * [`a07b421f7`](https://github.com/npm/cli/commit/a07b421f708c13d8239e7283ad89611b24b23d0a) - lincesee - * [`41126e165`](https://github.com/npm/cli/commit/41126e165d3d5625a55e140b84fdd02052520146) - npm-cache-filename - * [`130da51b5`](https://github.com/npm/cli/commit/130da51b553e550584f31e2a8a961f4338f2a0cd) - npm-registry-mock - * [`b355af486`](https://github.com/npm/cli/commit/b355af48696bb5001c6d2b938974d9ab9f5e2360) - sprintf-js - * [`721c0a873`](https://github.com/npm/cli/commit/721c0a8736f3cd0a0e75e0b89518a431553843c6) - uid-number - * [`9c920e5f5`](https://github.com/npm/cli/commit/9c920e5f584e4d912aabc6e412693f7142242a89) - umask - * [`aae1c38bb`](https://github.com/npm/cli/commit/aae1c38bbb983cf40e9b3df012b18bebba5e5400) - config-chain - * [`450845eac`](https://github.com/npm/cli/commit/450845eaceb7e178c8ec7867a67e5cc948986904) - find-npm-prefix - * [`963d542d3`](https://github.com/npm/cli/commit/963d542d385c7fe26830a885fe40d96010d01862) - has-unicode - * [`cad9cbc70`](https://github.com/npm/cli/commit/cad9cbc70561c8638ed6e56286f753693f411000) - infer-owner - * [`3ae02914d`](https://github.com/npm/cli/commit/3ae02914d49f3302d25c85d2242096bb2291f9f4) - lockfile - * [`7bc474d7c`](https://github.com/npm/cli/commit/7bc474d7cb2e2e083fd8358d0648d7c5fb43707f) - once - * [`5c5e0099a`](https://github.com/npm/cli/commit/5c5e0099a4708ec84da3d2e427e16c4a9cfe3c8a) - retry - * [`cfaddd334`](https://github.com/npm/cli/commit/cfaddd334b8b1eddcefa3cd2a9b823ec140271a4) - sha - * [`3a978ffc7`](https://github.com/npm/cli/commit/3a978ffc7fddd6802c81996a5710b2efd15edc11) - slide - -## v7.0.0-beta.13 (2020-09-29) - -* [`405e051f7`](https://github.com/npm/cli/commit/405e051f724a2e79844f78f8ea9ba019fdc513aa) - Fix EBADPLATFORM error message - ([@#1876](https://github.com/#1876)) -* [`e4d911d21`](https://github.com/npm/cli/commit/e4d911d219899c0fdc12f8951b7d70e0887909f8) - `@npmcli/arborist@0.0.28` - * fix: workspaces install entering an infinite loop - * Save provided range if not a subset of savePrefix - * package-lock.json custom indentation - * Check engine and platform when building ideal tree -* [`90550b2e0`](https://github.com/npm/cli/commit/90550b2e023e7638134e91c80ed96828afb41539) - [#1853](https://github.com/npm/cli/pull/1853) - test coverage and refactor for token command - ([@nlf](https://github.com/nlf)) -* [`2715220c9`](https://github.com/npm/cli/commit/2715220c9b5d3f325e65e95bae2b5af8a485a579) - [#1858](https://github.com/npm/cli/pull/1858) - [#1813](https://github.com/npm/cli/issues/1813) - do not include omitted optional dependencies in install output - ([@ruyadorno](https://github.com/ruyadorno)) -* [`e225ddcf8`](https://github.com/npm/cli/commit/e225ddcf8d74a6b1cfb24ec49e37e3f5d06e5151) - [#1862](https://github.com/npm/cli/pull/1862) - [#1861](https://github.com/npm/cli/issues/1861) - respect depth when running `npm ls <pkg>` - ([@ruyadorno](https://github.com/ruyadorno)) -* [`2469ae515`](https://github.com/npm/cli/commit/2469ae5153fa4114a72684376a1b226aa07edf81) - [#1870](https://github.com/npm/cli/pull/1870) - [#1780](https://github.com/npm/cli/issues/1780) - Add 'fetch-timeout' config - ([@isaacs](https://github.com/isaacs)) -* [`52114b75e`](https://github.com/npm/cli/commit/52114b75e83db8a5e08f23889cce41c89af9eb93) - [#1871](https://github.com/npm/cli/pull/1871) - fix `npm ls` for linked dependencies - ([@ruyadorno](https://github.com/ruyadorno)) -* [`9981211c0`](https://github.com/npm/cli/commit/9981211c070ce2b1e34d30223d12bd275adcacf5) - [#1857](https://github.com/npm/cli/pull/1857) - [#1703](https://github.com/npm/cli/issues/1703) - fix `npm outdated` parsing invalid specs - ([@ruyadorno](https://github.com/ruyadorno)) - -## v7.0.0-beta.12 (2020-09-22) - -* [`24f3a5448`](https://github.com/npm/cli/commit/24f3a5448f021ad603046dfb9fd97ed66bd63bba) - [#1811](https://github.com/npm/cli/issues/1811) - npm ci should never save package.json or lockfile - ([@isaacs](https://github.com/isaacs)) -* [`5e780a5f0`](https://github.com/npm/cli/commit/5e780a5f067476c1d207173fc9249faf9eaac0c2) - remove unused spec parameter, assign error code - ([@nlf](https://github.com/nlf)) -* [`f019a248a`](https://github.com/npm/cli/commit/f019a248a67e8c46dbe41bf31f4818c5ca2138bf) - Remove unused npx binary - ([@isaacs](https://github.com/isaacs)) -* [`db157b3ce`](https://github.com/npm/cli/commit/db157b3ceb46327ca2089604d5f4fc9de391584e) - `@npmcli/arborist@0.0.27` - * Resolve race condition with conflicting bin links in local installs - * [#1812](https://github.com/npm/cli/issues/1812) Log engine mismatches more usefully - * [#1814](https://github.com/npm/cli/issues/1814) Do not loop trying to resolve dependencies that fail to load - * [npm/rfcs#224](https://github.com/npm/rfcs/pull/224) Do not automatically install optional peer dependencies - * Add the `strictPeerDeps` option, defaulting to `false` - * fix forwarding configs to resolve pkg spec when adding new deps -* [`b3a50d275`](https://github.com/npm/cli/commit/b3a50d27501e47c61b52c3cc4de99ff4e4641efe) - [#1846](https://github.com/npm/cli/pull/1846) - `@npmcli/run-script@1.6.0` - * This updates node-gyp to v7, allowing us to deduplicate a lot of significant dependencies. -* [`a1d375f6b`](https://github.com/npm/cli/commit/a1d375f6b0ee358be41110a49acc1c9fdb775fbe) - [#1819](https://github.com/npm/cli/pull/1819) - Add `--strict-peer-deps` option - ([@isaacs](https://github.com/isaacs)) -* [`5837a4843`](https://github.com/npm/cli/commit/5837a4843ab1f19fb62f60151f522ca0fa5449ae) - [#1699](https://github.com/npm/cli/pull/1699) - Use allow/deny list in docs - ([@luciomartinez](https://github.com/luciomartinez)) - -## v7.0.0-beta.11 (2020-09-16) - -* [`63005f4a9`](https://github.com/npm/cli/commit/63005f4a98d55786fda46f3bbb3feab044d078df) - [#1639](https://github.com/npm/cli/issues/1639) - npm view should not output extra newline ([@MylesBorins](https://github.com/MylesBorins)) -* [`3743a42c8`](https://github.com/npm/cli/commit/3743a42c854d9ea7e333d7ff86d206a4b079a352) - [#1750](https://github.com/npm/cli/pull/1750) - add outdated tests ([@claudiahdz](https://github.com/claudiahdz)) -* [`2019abdf1`](https://github.com/npm/cli/commit/2019abdf159eb13c9fb3a2bd2f35897a8f52b0d9) - [#1786](https://github.com/npm/cli/pull/1786) - add lib/link.js tests ([@ruyadorno](https://github.com/ruyadorno)) -* [`2f8d11968`](https://github.com/npm/cli/commit/2f8d11968607a74c8def3c05266049bee5e313eb) - `@npmcli/arborist@0.0.25` - * add meta vulnerability calculator for faster audits - * changed parsing specs to be relative to cwd - * fix logging script execution - * fix properly following resolved symlinks - * fix package.json dependencies order -* [`49b2bf5a7`](https://github.com/npm/cli/commit/49b2bf5a798b49d52166744088a80b8a39ccaeb6) - `@npmcli/config@1.1.8` - * fix unknown envs to be passed through - * fix setting correct globalPrefix on load -* [`f9aac351d`](https://github.com/npm/cli/commit/f9aac351dd36a19d14e1f951a2e8e20b41545822) - `libnpmversion@1.0.5` - * fix git ignored lockfiles - -## v7.0.0-beta.10 (2020-09-08) - -* [`7418970f0`](https://github.com/npm/cli/commit/7418970f03229dd2bce7973b99b981779aee6916) - Improve output of dependency node explanations -* [`5e49bdaa3`](https://github.com/npm/cli/commit/5e49bdaa34e29dbd25c687f8e6881747a86b7435) - [#1776](https://github.com/npm/cli/pull/1776) Add 'npm explain' command - -## v7.0.0-beta.9 (2020-09-04) - -* [`ef8f5676b`](https://github.com/npm/cli/commit/ef8f5676b1c90dcf44256b8ed1f61ddb6277c23a) - [#1757](https://github.com/npm/cli/pull/1757) - view: always fetch fullMetadata, and preferOnline -* [`ac5aa709a`](https://github.com/npm/cli/commit/ac5aa709a8609ec2beb7a8c60b3bde18f882f4e8) - [#1758](https://github.com/npm/cli/pull/1758) - fix scope config -* [`a36e2537f`](https://github.com/npm/cli/commit/a36e2537fd4c81df53fb6de01900beb9fa4fa0aa) - outdated: don't throw on non-version/tag/range dep -* [`371f0f062`](https://github.com/npm/cli/commit/371f0f06215ad8caf598c20e3d0d38ff597531e9) - `@npmcli/arborist@0.0.20` - - * Provide explanation objects for `ERESOLVE` errors - * Support overriding certain classes of `ERESOLVE` errors with `--force` - * Detect changes to package.json requiring package-lock dependency flag - re-evaluation - -* [`2a4e2e9ef`](https://github.com/npm/cli/commit/2a4e2e9efecb7f86147e5071c59cfc2461a5a7f5) - [#1761](https://github.com/npm/cli/pull/1761) - Explain `ERESOLVE` errors -* [`8e3e83bd4`](https://github.com/npm/cli/commit/8e3e83bd4f816bfed0efb8266985143ee9b94b86) - `@npmcli/arborist@0.0.21` - - * Remove bin links on prune - * Remove unnecessary tree walk for workspace projects - * Install workspaces on update:true - -* [`d6b134fd9`](https://github.com/npm/cli/commit/d6b134fd9005d911343831270615f80dfead7e3d) - [#1738](https://github.com/npm/cli/pull/1738) - [#1734](https://github.com/npm/cli/pull/1734) - fix package spec parsing during cache add process - ([@mjeanroy](https://github.com/mjeanroy)) -* [`f105eb833`](https://github.com/npm/cli/commit/f105eb8333fa3300c5b47464b129c1b0057ed7bf) - `npm-audit-report@2.1.4`: - - * Do not crash on cyclical meta-vulnerability references - -* [`03a9f569b`](https://github.com/npm/cli/commit/03a9f569b5121a173f14711980db297d4a04ac6b) - `opener@1.5.2` -* [`5616a23b4`](https://github.com/npm/cli/commit/5616a23b4b868d19aa100a6d86d781cc9bfd94f7) - `@npmcli/git@2.0.4` - - * Support `.git` files, so that git worktrees are respected - -## v7.0.0-beta.8 (2020-09-01) - -* [`834e62a0e`](https://github.com/npm/cli/commit/834e62a0e5b76e97cfe9ea3d3188661579ebc874) - * fix: npm ls extraneous workspaces - * `@npmcli/arborist@0.0.19` -* [`758b02358`](https://github.com/npm/cli/commit/758b02358613591ea877e26fcdb76e5b1d40f892) - [#1739](https://github.com/npm/cli/pull/1739) - add full install options to npm exec - ([@ruyadorno](https://github.com/ruyadorno)) -* [`2ee7c8a98`](https://github.com/npm/cli/commit/2ee7c8a98cf01225a3c9ac247139243f868e2e03) - `@npmcli/config@1.1.7` - ([@ruyadorno](https://github.com/ruyadorno)) - -## v7.0.0-beta.7 (2020-08-25) - -* [`b38f68acd`](https://github.com/npm/cli/commit/b38f68acd9292b7432c936db3b6d2d12e896f45d) - ensure `npm-command` HTTP header is sent properly -* [`9f200abb9`](https://github.com/npm/cli/commit/9f200abb94ea2127d9a104c225159b1b7080c82c) - Properly exit with error status code -* [`aa0152b58`](https://github.com/npm/cli/commit/aa0152b58f34f8cdae05be63853c6e0ace03236a) - [#1719](https://github.com/npm/cli/pull/1719) Detect CI properly -* [`50f9740ca`](https://github.com/npm/cli/commit/50f9740ca8000b1c4bd3155bf1bc3d58fb6f0e20) - [#1717](https://github.com/npm/cli/pull/1717) fund with multiple funding - sources ([@ruyadorno](https://github.com/ruyadorno)) -* [`3a63ecb6f`](https://github.com/npm/cli/commit/3a63ecb6f6a0b235660f73a3ffa329b1f131b0c3) - [#1718](https://github.com/npm/cli/pull/1718) - [RFC-0029](https://github.com/npm/rfcs/blob/latest/implemented/0029-add-ability-to-skip-hooks.md) - add ability to skip pre/post hooks to `npm run-script` by using - `--ignore-scripts` ([@ruyadorno](https://github.com/ruyadorno)) - -## v7.0.0-beta.6 (2020-08-21) - -* [`707207bdd`](https://github.com/npm/cli/commit/707207bddb2900d6f7a57ff864cef26cda75a71a) - add `@npmcli/config` dependency - -* [`5cb9a1d4d`](https://github.com/npm/cli/commit/5cb9a1d4d985aaa8e988c51fe5ae7f7ed3602811) - [#1688](https://github.com/npm/cli/pull/1688) use `@npmcli/config` for - configuration ([@isaacs](https://github.com/isaacs)) - -* [`a4295f5db`](https://github.com/npm/cli/commit/a4295f5db7667e8cc6b83abdad168619ad31a12f) - `npm-registry-fetch@8.1.4`: - - * Redact passwords from HTTP logs - -* [`a5a6a516d`](https://github.com/npm/cli/commit/a5a6a516d16828c1375eaf41d04468d919df4a57) - `json-parse-even-better-errors@2.3.0`: - - * Adds support for indentation/newline formatting preservation - -* [`a14054558`](https://github.com/npm/cli/commit/a1405455843db1b14938596303b29fb3ad4f90f0) - `read-package-json-fast@1.2.1`: - - * Adds support for indentation/newline formatting preservation - -* [`f8603c8af`](https://github.com/npm/cli/commit/f8603c8affefc342d81c109e4676d498a8359b78) - `libnpmversion@1.0.4`: - - * Adds support for indentation/newline formatting preservation - -* [`9891fa71c`](https://github.com/npm/cli/commit/9891fa71c88f425bef8d881c3795e5823d732e1f) - `read-package-json@2.1.2`: - - * Adds support for indentation/newline formatting preservation - -* [`b44768aac`](https://github.com/npm/cli/commit/b44768aace0e9c938ebd6d05a5de1cc4368e2d7d) - [#1662](https://github.com/npm/cli/issues/1662) - [#1693](https://github.com/npm/cli/issues/1693) - [#1690](https://github.com/npm/cli/issues/1690) - `@npmcli/arborist@0.0.17`: - - * Load root project `package.json` when running loadVirtual. - * Fetch metadata from registry when loading tree from outdated - package-lock.json file. This avoids a situation where a lockfile or - shrinkwrap from npm v5 would result in deleting dependencies on - install. - * Preserve `package.json` and `package-lock.json` formatting in all - places where these files are written. - -* [`281da6fdc`](https://github.com/npm/cli/commit/281da6fdcda3fb3860b73ed35daa234ad228c363) - `tar@6.0.5` - -* [`1faa5b33d`](https://github.com/npm/cli/commit/1faa5b33dcc6d7e4eba1c0d85ad30cf0c237c9e1) - [#1655](https://github.com/npm/cli/issues/1655) show usage when - `help-search` finds no results - -* [`10fcff73a`](https://github.com/npm/cli/commit/10fcff73a3381ea5e6dcb03888679ae4b501d2f0) - [#1695](https://github.com/npm/cli/issues/1695) fix `pulseWhileDone` - promise handling - -* [`88e4241c5`](https://github.com/npm/cli/commit/88e4241c5d4f512a4e2b09d26fcdcc7f877e65ed) - [#1698](https://github.com/npm/cli/pull/1698) add lib/logout.js unit - tests ([@ruyadorno](https://github.com/ruyadorno)) - -## v7.0.0-beta.5 (2020-08-18) - -* [`b718b0e28`](https://github.com/npm/cli/commit/b718b0e2844d9244cc63667f62ccf81864cc1092) - [#1657](https://github.com/npm/cli/pull/1657) display multiple versions - when using `--json` with `npm view` - ([@claudiahdz](https://github.com/claudiahdz)) -* [`9e7cc42f6`](https://github.com/npm/cli/commit/9e7cc42f687b479d96d222b61f76b2a30c7e6507) - [#1071](https://github.com/npm/cli/pull/1071) migrate from `meant` to - `leven` ([@jamesgeorge007](https://github.com/jamesgeorge007)) -* [`85027f40c`](https://github.com/npm/cli/commit/85027f40ca5237bd750a5633104d12bcc248551c) - [#1664](https://github.com/npm/cli/pull/1664) refactor and add tests for - `npm adduser` ([@ruyadorno](https://github.com/ruyadorno)) -* [`6e03e5583`](https://github.com/npm/cli/commit/6e03e55833d50fd0f5b7824ed14b7e2b14f70eaf) - [#1672](https://github.com/npm/cli/pull/1672) refactor and add tests for - `npm audit` ([@claudiahdz](https://github.com/claudiahdz)) - -## v7.0.0-beta.4 (2020-08-11) - -Replace some environment variables that were excluded. This implements the -[amendment to RFC0021](https://github.com/npm/rfcs/pull/183). - -* [`631142f4a`](https://github.com/npm/cli/commit/631142f4a13959fbe02dc115fb6efa55a3368795) - `@npmcli/run-script@1.5.0` -* [`da95386ae`](https://github.com/npm/cli/commit/da95386aedb3f0c0cc51761bfa750b64ac0eabc9) - [#1650](https://github.com/npm/cli/pull/1650) - [#1652](https://github.com/npm/cli/pull/1652) - include booleans, skip already-set envs - -## v7.0.0-beta.3 (2020-08-10) - -Bring back support for `npm audit --production`, fix a minor `npm version` -annoyance, and track down a very serious issue where a project could be -blown away when it matches a meta-dep in the tree. - -* [`5fb217701`](https://github.com/npm/cli/commit/5fb217701c060e37a3fb4a2e985f80fb015157b9) - [#1641](https://github.com/npm/cli/issues/1641) `@npmcli/arborist@0.0.15` -* [`3598fe1f2`](https://github.com/npm/cli/commit/3598fe1f2dfe6c55221bbac8aaf21feab74a936a) - `@npmcli/arborist@0.0.16` Add support for `npm audit --production` -* [`8ba2aeaee`](https://github.com/npm/cli/commit/8ba2aeaeeb77718cb06fe577fdd56dcdcbfe9c52) - `libnpmversion@1.0.3` - -## v7.0.0-beta.2 (2020-08-07) - -New notification style for updates, and a working doctor. - -* [`cf2819210`](https://github.com/npm/cli/commit/cf2819210327952696346486002239f9fc184a3e) - [#1622](https://github.com/npm/cli/pull/1622) - Improve abbrevs for install and help -* [`d062b2c02`](https://github.com/npm/cli/commit/d062b2c02a4d6d5f1a274aa8eb9c5969ca6253db) - new npm-specific update-notifier implementation -* [`f6d468a3b`](https://github.com/npm/cli/commit/f6d468a3b4bef0b3cc134065d776969869fca51e) - update doctor command -* [`b8b4d77af`](https://github.com/npm/cli/commit/b8b4d77af836f8c49832dda29a0de1b3c2d39233) - [#1638](https://github.com/npm/cli/pull/1638) - Direct users to our GitHub issues instead of npm.community - -## v7.0.0-beta.1 (2020-08-05) - -Fix some issues found in the beta pubish process, and initial attempts to -use npm v7 with [citgm](https://github.com/nodejs/citgm/). - -* [`2c305e8b7`](https://github.com/npm/cli/commit/2c305e8b7bfa28b07812df74f46983fad2cb85b6) - output generated tarball filename -* [`0808328c9`](https://github.com/npm/cli/commit/0808328c93d9cd975837eeb53202ce3844e1cf70) - pack: set correct filename for scoped packages - ([@isaacs](https://github.com/isaacs)) -* [`cf27df035`](https://github.com/npm/cli/commit/cf27df035cfba4f859d14859229bb90841b8fda6) - `@npmcli/arborist@0.0.14` ([@isaacs](https://github.com/isaacs)) - -## v7.0.0-beta.0 (2020-08-04) - -Major refactoring and overhaul of, well, pretty much everything. Almost -all dependencies have been updated, many have been removed, and the entire -`Installer` class is moved into -[`@npmcli/arborist`](http://npm.im/@npmcli/arborist). - -### Some High-level Changes and Improvements - -- You can install GitHub pull requests by adding `#pull/<number>` to the - git url. So it'd be something like `npm install - github:user/project#pull/123` to install PR number 123 of the - `user/project` git repo. You can of course also use this in - dependencies, or anywhere else dependency specifiers are found. -- Initial Workspaces support is added. If you `npm install` in a project - with a `workspaces` declaration, npm will install all your sub-projects' - dependencies as well, and link everything up proper. -- `npm exec` is added, to run any arbitrary command as if it was an npm - script. This is sort of like `npx`, which is also ported to use `npm - exec` under the hood. -- `npm audit` output is tightened up, and prettified. Audit can also now - fix a few more classes of problems, sends far less data over the wire, - and doesn't place blame on the wrong maintainers. (Technically this is a - breaking change if you depend on the specific audit output, but it's - also a big improvement!) -- `npm install` got faster. Like a lot faster. "So fast you'll think it's - broken" faster. `npm ls` got even fasterer. A lot of stuff sped up, is - what we're saying. -- Support has been dropped for Node.js versions less than v10. - -### On the "Breaking" in "Breaking Changes" - -The Semantic Versioning specification precisely defines what constitutes a -"breaking" change. In a nutshell, it's any change that causes a you to -change _your_ code in order to start using _our_ code. We hasten to point -this out, because a "breaking change" does not mean that something about -the update is "broken", necessarily. - -We're sure that some things likely _are_ broken in this beta, because beta -software, and a healthy pessimism about things. But nothing is "broken" on -purpose here, and if you find a bug, we'd love for you to [let us -know](https://github.com/npm/cli/issues). - -### Known Issues, and What's Missing From This Beta (Why Not GA?) - -It's beta software! - -#### Tests - -We have not yet gotten to 100% test coverage of the npm CLI codebase. As -such, there are almost certainly bugs lying in wait. We _do_ have 100% -test coverage of most of the commands, and all recently-updated -dependencies in the npm stack, so it's certainly more well-tested than any -version of npm before. - -#### Docs - -The documentation is incorrect and out of date in most places. Prior to a -GA release, we'll be going through all of our documentation with a -fine-toothed comb to minimize the lies that it tells. - -#### Error Messaging - -There are a few cases where this release will just say something failed, -and not give you as much help as we'd like. We know, and we'll fix that -prior to the GA 7.0.0 release. - -In particular, if you install a project that has conflicting -`peerDependencies` in the tree, it'll just say "Unable to resolve package -tree". Prior to GA release, it'll tell you how to fix it. (For the time -being, just run it again with `--legacy-peer-deps`, and that'll make it -operate like npm v6.) - -#### Audit Issue - -There is a known performance issue in some cases that we've identified -where `npm audit` can spin wildly out of control like a dancer gripped by a -fever, heating up your laptop with fires of passion and CPU work. This -happens when a vulnerability is in a tree with a _lot_ of cross-linked -dependencies that all depend on one another. - -We have a fix for it, but if you run into this issue, you can run with -`--no-audit` to tell npm to chill out a little bit. - -That's about it! It's ready to use, and you should try it out. - -Now on to the list of **BREAKING CHANGES**! - -### Programmatic Usage - -- [RFC - 20](https://github.com/npm/rfcs/blob/latest/implemented/0020-npm-option-handling.md) - The CLI and its dependencies no longer use the `figgy-pudding` library - for configs. Configuration is done using a flat plain old JavaScript - object. -- The `lib/fetch-package-metadata.js` module is removed. Use - [`pacote`](http://npm.im/pacote) to fetch package metadata. -- [`@npmcli/arborist`](http://npm.im/@npmcli/arborist) should be used to do - most things programmatically involving dependency trees. -- The `onload-script` option is no longer supported. -- The `log-stream` option is no longer supported. -- `npm.load()` MUST be called with two arguments (the parsed cli options - and a callback). -- `npm.root` alias for `npm.dir` removed. -- The `package.json` in npm now defines an `exports` field, making it no - longer possible to `require()` npm's internal modules. (This was always - a bad idea, but now it won't work.) - -### All Registry Interactions - -The following affect all commands that contact the npm registry. - -- `referer` header no longer sent -- `npm-command` header added - -### All Lifecycle Scripts - -The environment for lifecycle scripts (eg, build scripts, `npm test`, etc.) -has changed. - -- [RFC - 21](https://github.com/npm/rfcs/blob/latest/implemented/0021-reduce-lifecycle-script-environment.md) - Environment no longer includes `npm_package_*` fields, or `npm_config_*` - fields for default configs. `npm_package_json`, `npm_package_integrity`, - `npm_package_resolved`, and `npm_command` environment variables added. - - (NB: this [will change a bit prior to a `v7.0.0` GA - release](https://github.com/npm/rfcs/pull/183)) - -- [RFC - 22](https://github.com/npm/rfcs/blob/latest/implemented/0022-quieter-install-scripts.md) - Scripts run during the normal course of installation are silenced unless - they exit in error (ie, with a signal or non-zero exit status code), and - are for a non-optional dependency. - -- [RFC - 24](https://github.com/npm/rfcs/blob/latest/implemented/0024-npm-run-traverse-directory-tree.md) - `PATH` environment variable includes all `node_modules/.bin` folders, - even if found outside of an existing `node_modules` folder hierarchy. - -- The `user`, `group`, `uid`, `gid`, and `unsafe-perms` configurations are - no longer relevant. When npm is run as root, scripts are always run with - the effective `uid` and `gid` of the working directory owner. - -- Commands that just run a single script (`npm test`, `npm start`, `npm - stop`, and `npm restart`) will now run their script even if - `--ignore-scripts` is set. Prior to the GA v7.0.0 release, [they will - _not_ run the pre/post scripts](https://github.com/npm/rfcs/pull/185), - however. (So, it'll be possible to run `npm test --ignore-scripts` to - run your test but not your linter, for example.) - -### npx - -The `npx` binary was rewritten in npm v7, and the standalone `npx` package -deprecated when v7.0.0 hits GA. `npx` uses the new `npm exec` command -instead of a separate argument parser and install process, with some -affordances to maintain backwards compatibility with the arguments it -accepted in previous versions. - -This resulted in some shifts in its functionality: - -- Any `npm` config value may be provided. -- To prevent security and user-experience problems from mistyping package - names, `npx` prompts before installing anything. Suppress this - prompt with the `-y` or `--yes` option. -- The `--no-install` option is deprecated, and will be converted to `--no`. -- Shell fallback functionality is removed, as it is not advisable. -- The `-p` argument is a shorthand for `--parseable` in npm, but shorthand - for `--package` in npx. This is maintained, but only for the `npx` - executable. (Ie, running `npm exec -p foo` will be different from - running `npx -p foo`.) -- The `--ignore-existing` option is removed. Locally installed bins are - always present in the executed process `PATH`. -- The `--npm` option is removed. `npx` will always use the `npm` it ships - with. -- The `--node-arg` and `-n` options are removed. -- The `--always-spawn` option is redundant, and thus removed. -- The `--shell` option is replaced with `--script-shell`, but maintained - in the `npx` executable for backwards compatibility. - -We do intend to continue supporting the `npx` that npm ships; just not the -`npm install -g npx` library that is out in the wild today. - -### Files On Disk - -- [RFC - 13](https://github.com/npm/rfcs/blob/latest/implemented/0013-no-package-json-_fields.md) - Installed `package.json` files no longer are mutated to include extra - metadata. (This extra metadata is stored in the lockfile.) -- `package-lock.json` is updated to a newer format, using - `"lockfileVersion": 2`. This format is backwards-compatible with npm CLI - versions using `"lockfileVersion": 1`, but older npm clients will print a - warning about the version mismatch. -- `yarn.lock` files used as source of package metadata and resolution - guidance, if available. (Prior to v7, they were ignored.) - -### Dependency Resolution - -These changes affect `install`, `ci`, `install-test`, `install-ci-test`, -`update`, `prune`, `dedupe`, `uninstall`, `link`, and `audit fix`. - -- [RFC - 25](https://github.com/npm/rfcs/blob/latest/implemented/0025-install-peer-deps.md) - `peerDependencies` are installed by default. This behavior can be - disabled by setting the `legacy-peer-deps` configuration flag. - - **BREAKING CHANGE**: this can cause some packages to not be - installable, if they have unresolveable peer dependency conflicts. - While the correct solution is to fix the conflict, this was not forced - upon users for several years, and some have come to rely on this lack - of correctness. Use the `--legacy-peer-deps` config flag if impacted. - -- [RFC - 23](https://github.com/npm/rfcs/blob/latest/implemented/0023-acceptDependencies.md) - Support for `acceptDependencies` is added. This can result in dependency - resolutions that previous versions of npm will incorrectly flag as invalid. - -- Git dependencies on known git hosts (GitHub, BitBucket, etc.) will - always attempt to fetch package contents from the relevant tarball CDNs - if possible, falling back to `git+ssh` for private packages. `resolved` - value in `package-lock.json` will always reflect the `git+ssh` url value. - Saved value in `package.json` dependencies will always reflect the - canonical shorthand value. - -- Support for the `--link` flag (to install a link to a globall-installed - copy of a module if present, otherwise install locally) has been removed. - Local installs are always local, and `npm link <pkg>` must be used - explicitly if desired. - -- Installing a dependency with the same name as the root project no longer - requires `--force`. (That is, the `ENOSELF` error is removed.) - -### Workspaces - -- [RFC - 26](https://github.com/npm/rfcs/blob/latest/implemented/0026-workspaces.md) - First phase of `workspaces` support is added. This changes npm's - behavior when a root project's `package.json` file contains a - `workspaces` field. - -### `npm update` - -- [RFC - 19](https://github.com/npm/rfcs/blob/latest/implemented/0019-remove-update-depth-option.md) - Update all dependencies when `npm update` is run without any arguments. - As it is no longer relevant, `--depth` config flag removed from `npm - update`. - -### `npm outdated` - -- [RFC - 27](https://github.com/npm/rfcs/blob/latest/implemented/0027-remove-depth-outdated.md) - Remove `--depth` config from `npm outdated`. Only top-level dependencies - are shown, unless `--all` config option is set. - -### `npm adduser`, `npm login` - -- The `--sso` options are deprecated, and will print a warning. - -### `npm audit` - -- Output and data structure is significantly refactored to call attention - to issues, identify classes of fixes not previously available, and - remove extraneous data not used for any purpose. - - **BREAKING CHANGE**: Any tools consuming the output of `npm audit` will - almost certainly need to be updated, as this has changed significantly, - both in the readable and `--json` output styles. - -### `npm dedupe` - -- Performs a full dependency tree reification to disk. As a result, `npm - dedupe` can cause missing or invalid packages to be installed or updated, - though it will only do this if required by the stated dependency - semantics. - -- Note that the `--prefer-dedupe` flag has been added, so that you may - install in a maximally deduplicated state from the outset. - -### `npm fund` - -- Human readable output updated, reinstating depth level to the printed - output. - -### `npm ls` - -- Extraneous dependencies are listed based on their location in the - `node_modules` tree. -- `npm ls` only prints the first level of dependencies by default. You can - make it print more of the tree by using `--depth=<n>` to set a specific - depth, or `--all` to print all of them. - -### `npm pack`, `npm publish` - -- Generated gzipped tarballs no longer contain the zlib OS indicator. As a - result, they are truly dependent _only_ on the contents of the package, - and fully reproducible. However, anyone relying on this byte to identify - the operating system of a package's creation may no longer rely on it. - -### `npm rebuild` - -- Runs package installation scripts as well as re-creating links to bins. - Properly respects the `--ignore-scripts` and `--bin-links=false` - configuration options. - -### `npm build`, `npm unbuild` - -- These two internal commands were removed, as they are no longer needed. - -### `npm test` - -- When no test is specified, will fail with `missing script: test` rather - than injecting a synthetic `echo 'Error: no test specified'` test script - into the `package.json` data. - -## Credits - -Huge thanks to the people who wrote code for this update, as well as our -group of dedicated Open RFC call participants. Your participation has -contributed immeasurably to the quality and design of npm. diff --git a/docs/.eslintrc.js b/docs/.eslintrc.js index 5db9f815536f1..f21d26eccec7d 100644 --- a/docs/.eslintrc.js +++ b/docs/.eslintrc.js @@ -10,6 +10,9 @@ const localConfigs = readdir(__dirname) module.exports = { root: true, + ignorePatterns: [ + 'tap-testdir*/', + ], extends: [ '@npmcli', ...localConfigs, diff --git a/docs/.eslintrc.local.json b/docs/.eslintrc.local.json new file mode 100644 index 0000000000000..2f2f707c490b9 --- /dev/null +++ b/docs/.eslintrc.local.json @@ -0,0 +1,5 @@ +{ + "rules": { + "import/no-extraneous-dependencies": "off" + } +} diff --git a/docs/.gitignore b/docs/.gitignore index 2231d46ac2b98..08e5141aa731c 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -3,21 +3,21 @@ # ignore everything in the root /* -# keep these -!/.eslintrc.local.* !**/.gitignore -!/docs/ -!/tap-snapshots/ -!/test/ -!/map.js -!/scripts/ -!/README* -!/LICENSE* -!/CHANGELOG* +!/.eslint.config.js !/.eslintrc.js +!/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ -!/content/ +!/CHANGELOG* +!/docs/ !/lib/ -!/nav.yml +!/LICENSE* +!/map.js !/package.json +!/README* +!/scripts/ +!/tap-snapshots/ +!/test/ +tap-testdir*/ diff --git a/docs/bin/build.js b/docs/bin/build.js new file mode 100644 index 0000000000000..602596bc2d494 --- /dev/null +++ b/docs/bin/build.js @@ -0,0 +1,9 @@ +const run = require('../lib/build.js') +const { paths } = require('../lib/index') + +run(paths) + .then((res) => console.error(`Wrote ${res.length} files`)) + .catch((err) => { + process.exitCode = 1 + console.error(err) + }) diff --git a/docs/bin/config-doc-command.js b/docs/bin/config-doc-command.js deleted file mode 100644 index f55213cdcfd6d..0000000000000 --- a/docs/bin/config-doc-command.js +++ /dev/null @@ -1,142 +0,0 @@ -const fs = require('fs').promises -const { resolve } = require('path') -const { definitions, aliases } = require('../lib/npm.js') - -const describeAll = (content) => - content.map(name => definitions[name].describe()).join( - '\n\n<!-- automatically generated, do not edit manually -->\n' + - '<!-- see lib/utils/config/definitions.js -->\n\n' - ) - -const describeUsage = ({ usage, configDoc, commandFile }) => { - const synopsis = [] - - // Grab the command name from the *.md filename - // NOTE: We cannot use the name property command file because in the case of - // `npx` the file being used is `lib/commands/exec.js` - const commandName = configDoc.split('/').pop().split('.')[0].replace('npm-', '') - synopsis.push('\n```bash') - - if (commandName) { - // special case for `npx`: - // `npx` is not technically a command in and of itself, - // so it just needs the usage and parameters of npm exec, and none of the aliases - if (commandName === 'npx') { - synopsis.push(usage.map(usageInfo => `npx ${usageInfo}`).join('\n')) - } else { - const baseCommand = `npm ${commandName}` - if (!usage) { - synopsis.push(baseCommand) - } else { - synopsis.push(usage.map(usageInfo => `${baseCommand} ${usageInfo}`).join('\n')) - } - - const cmdAliases = Object.keys(aliases).reduce((p, c) => { - if (aliases[c] === commandName) { - p.push(c) - } - return p - }, []) - - if (cmdAliases.length === 1) { - synopsis.push('') - synopsis.push(`alias: ${cmdAliases[0]}`) - } else if (cmdAliases.length > 1) { - synopsis.push('') - synopsis.push(`aliases: ${cmdAliases.join(', ')}`) - } - } - } else { - console.error(`could not determine command name from ${commandFile}`) - } - - synopsis.push('```') - return synopsis.join('\n') -} - -const addBetweenTags = ( - doc, - startTag, - endTag, - body, - sourceFilepath = 'lib/utils/config/definitions.js') => { - const startSplit = doc.split(startTag) - - if (startSplit.length !== 2) { - throw new Error('Did not find exactly one start tag') - } - - const endSplit = startSplit[1].split(endTag) - if (endSplit.length !== 2) { - throw new Error('Did not find exactly one end tag') - } - - return [ - startSplit[0], - startTag, - '\n<!-- automatically generated, do not edit manually -->\n' + - '<!-- see ' + sourceFilepath + ' -->\n', - body, - '\n\n<!-- automatically generated, do not edit manually -->\n' + - '<!-- see ' + sourceFilepath + ' -->', - '\n\n', - endTag, - endSplit[1], - ].join('') -} - -const TAGS = { - CONFIG: { - START: '<!-- AUTOGENERATED CONFIG DESCRIPTIONS START -->', - END: '<!-- AUTOGENERATED CONFIG DESCRIPTIONS END -->', - }, - USAGE: { - START: '<!-- AUTOGENERATED USAGE DESCRIPTIONS START -->', - END: '<!-- AUTOGENERATED USAGE DESCRIPTIONS END -->', - }, -} - -const addDescriptions = ({ doc, params }) => - addBetweenTags(doc, TAGS.CONFIG.START, TAGS.CONFIG.END, describeAll(params)) - -const addUsageDescriptions = ({ doc, usage, configDoc, commandFile }) => - addBetweenTags(doc, TAGS.USAGE.START, TAGS.USAGE.END, - describeUsage({ usage, configDoc, commandFile }), - commandFile - ) - -const run = async (configDoc, commandFile) => { - try { - // Note: commands without params skip this whole process. - const { params, usage } = require(resolve(commandFile)) - - // always write SOMETHING so that Make sees the file is up to date. - const doc = await fs.readFile(configDoc, 'utf8') - const hasTag = doc.includes(TAGS.CONFIG.START) - const hasUsageTag = doc.includes(TAGS.USAGE.START) - - if (params && params.length) { - let newDoc = hasTag ? addDescriptions({ doc, params }) : doc - newDoc = hasUsageTag - ? addUsageDescriptions({ doc: newDoc, usage, configDoc, commandFile }) - : newDoc - - if (!hasTag) { - console.error('WARNING: did not find config description section', configDoc) - } - - if ((usage && usage.length) && !hasUsageTag) { - console.error('WARNING: did not find usage description section', configDoc) - } - await fs.writeFile(configDoc, newDoc) - } - } catch (err) { - console.error(`WARNING: file cannot be open: ${configDoc}`) - throw err - } -} - -run(...process.argv.slice(2)).catch((err) => { - process.exitCode = 1 - console.error(err) -}) diff --git a/docs/bin/config-doc.js b/docs/bin/config-doc.js deleted file mode 100644 index 1aa96e53cbb43..0000000000000 --- a/docs/bin/config-doc.js +++ /dev/null @@ -1,63 +0,0 @@ -const fs = require('fs').promises -const { resolve, relative } = require('path') -const { shorthands, describeAll } = require('../lib/npm.js') - -const addBetweenTags = (doc, startTag, endTag, body) => { - const startSplit = doc.split(startTag) - if (startSplit.length !== 2) { - throw new Error('Did not find exactly one start tag') - } - - const endSplit = startSplit[1].split(endTag) - if (endSplit.length !== 2) { - throw new Error('Did not find exactly one end tag') - } - - return [ - startSplit[0], - startTag, - '\n<!-- automatically generated, do not edit manually -->\n' + - '<!-- see lib/utils/config/definitions.js -->\n', - body, - '\n\n<!-- automatically generated, do not edit manually -->\n' + - '<!-- see lib/utils/config/definitions.js -->\n', - endTag, - endSplit[1], - ].join('') -} - -const addDescriptions = doc => { - const startTag = '<!-- AUTOGENERATED CONFIG DESCRIPTIONS START -->' - const endTag = '<!-- AUTOGENERATED CONFIG DESCRIPTIONS END -->' - return addBetweenTags(doc, startTag, endTag, describeAll()) -} - -const addShorthands = doc => { - const startTag = '<!-- AUTOGENERATED CONFIG SHORTHANDS START -->' - const endTag = '<!-- AUTOGENERATED CONFIG SHORTHANDS END -->' - const body = Object.entries(shorthands) - .sort(([shorta, expansiona], [shortb, expansionb]) => { - // sort by what they're short FOR - return expansiona.join(' ').localeCompare(expansionb.join(' '), 'en') || - shorta.localeCompare(shortb, 'en') - }) - .map(([short, expansion]) => { - const dash = short.length === 1 ? '-' : '--' - return `* \`${dash}${short}\`: \`${expansion.join(' ')}\`` - }).join('\n') - return addBetweenTags(doc, startTag, endTag, body) -} - -const run = async (dir) => { - const configDoc = resolve(dir, '../content/using-npm/config.md') - const doc = await fs.readFile(configDoc, 'utf8') - - await fs.writeFile(configDoc, addDescriptions(addShorthands(doc))) - - return `updated ${relative(process.cwd(), configDoc)}` -} - -run(__dirname).then(console.log).catch((err) => { - process.exitCode = 1 - console.error(err) -}) diff --git a/docs/bin/dockhand.js b/docs/bin/dockhand.js deleted file mode 100644 index 56160136eed6f..0000000000000 --- a/docs/bin/dockhand.js +++ /dev/null @@ -1,322 +0,0 @@ -const path = require('path') -const fs = require('fs') -const yaml = require('yaml') -const cmark = require('cmark-gfm') -const mdx = require('@mdx-js/mdx') -const mkdirp = require('mkdirp') -const jsdom = require('jsdom') -const { version: VERSION } = require('../lib/npm.js') - -function ensureNavigationComplete (navPaths, fsPaths) { - const unmatchedNav = {} - const unmatchedFs = {} - - for (const navPath of navPaths) { - unmatchedNav[navPath] = true - } - - for (let fsPath of fsPaths) { - fsPath = path.sep + fsPath.replace(/\.md$/, '') - fsPath = fsPath.split(path.sep).join(path.posix.sep) - - if (unmatchedNav[fsPath]) { - delete unmatchedNav[fsPath] - } else { - unmatchedFs[fsPath] = true - } - } - - const toKeys = (v) => Object.keys(v).sort().map((p) => p.split(path.posix.sep).join(path.sep)) - const missingNav = toKeys(unmatchedNav) - const missingFs = toKeys(unmatchedFs) - - if (missingNav.length > 0 || missingFs.length > 0) { - let message = 'Error: documentation navigation (nav.yml) does not match filesystem.\n' - - if (missingNav.length > 0) { - message += '\nThe following path(s) exist on disk but are not present in nav.yml:\n\n' - - for (const n of missingNav) { - message += ` ${n}\n` - } - } - - if (missingNav.length > 0 && missingFs.length > 0) { - message += '\nThe following path(s) exist in nav.yml but are not present on disk:\n\n' - - for (const m of missingFs) { - message += ` ${m}\n` - } - } - - message += '\nUpdate nav.yml to ensure that all files are listed in the appropriate place.' - - return message - } -} - -function getNavigationPaths (entries) { - const paths = [] - - for (const entry of entries) { - if (entry.children) { - paths.push(...getNavigationPaths(entry.children)) - } else { - paths.push(entry.url) - } - } - - return paths -} - -async function renderFilesystemPaths ({ input, output, ...opts }, dirRelative = null) { - const paths = [] - - const dirPath = dirRelative ? path.join(input, dirRelative) : input - const children = fs.readdirSync(dirPath) - - for (const childFilename of children) { - const childRelative = dirRelative ? path.join(dirRelative, childFilename) : childFilename - const childPath = path.join(input, childRelative) - - if (fs.lstatSync(childPath).isDirectory()) { - paths.push(...(await renderFilesystemPaths({ input, output, ...opts }, childRelative))) - } else { - await renderFile(input, output, childRelative, opts) - paths.push(childRelative) - } - } - - return paths -} - -async function renderFile (root, outputRoot, childPath, { template, config }) { - const inputPath = path.join(root, childPath) - - if (!inputPath.match(/\.md$/)) { - console.error(`warning: unknown file type ${inputPath}, ignored`) - return - } - - const outputPath = path.join(outputRoot, childPath.replace(/\.md$/, '.html')) - - let md = fs.readFileSync(inputPath).toString() - let frontmatter = {} - - // Take the leading frontmatter out of the markdown - md = md.replace(/^---\n([\s\S]+)\n---\n/, (header, fm) => { - frontmatter = yaml.parse(fm, 'utf8') - return '' - }) - - // Replace any tokens in the source - md = md.replace(/@VERSION@/, VERSION) - - // Render the markdown into an HTML snippet using a GFM renderer. - const content = cmark.renderHtmlSync(md, { - smart: false, - githubPreLang: true, - strikethroughDoubleTilde: true, - unsafe: false, - extensions: { - table: true, - strikethrough: true, - tagfilter: true, - autolink: true, - }, - }) - - // Test that mdx can parse this markdown file. We don't actually - // use the output, it's just to ensure that the upstream docs - // site (docs.npmjs.com) can parse it when this file gets there. - try { - await mdx(md, { skipExport: true }) - } catch (error) { - throw new MarkdownError(childPath, error) - } - - // Inject this data into the template, using a mustache-like - // replacement scheme. - const html = template.replace(/{{\s*([\w.]+)\s*}}/g, (token, key) => { - switch (key) { - case 'content': - return `<div id="_content">${content}</div>` - case 'path': - return childPath - case 'url_path': - return encodeURI(childPath) - - case 'toc': - return '<div id="_table_of_contents"></div>' - - case 'title': - case 'section': - case 'description': - return frontmatter[key] - - case 'config.github_repo': - case 'config.github_branch': - case 'config.github_path': - return config[key.replace(/^config\./, '')] - - default: - console.error(`warning: unknown token '${token}' in ${inputPath}`) - return '' - } - }) - - const dom = new jsdom.JSDOM(html) - const document = dom.window.document - - // Rewrite relative URLs in links and image sources to be relative to - // this file; this is for supporting `file://` links. HTML pages need - // suffix appended. - const links = [ - { tag: 'a', attr: 'href', suffix: '.html' }, - { tag: 'img', attr: 'src' }, - ] - - for (const linktype of links) { - for (const tag of document.querySelectorAll(linktype.tag)) { - let url = tag.getAttribute(linktype.attr) - - if (url.startsWith('/')) { - const childDepth = childPath.split('/').length - 1 - const prefix = childDepth > 0 ? '../'.repeat(childDepth) : './' - - url = url.replace(/^\//, prefix) - - if (linktype.suffix) { - url += linktype.suffix - } - - tag.setAttribute(linktype.attr, url) - } - } - } - - // Give headers a unique id so that they can be linked within the doc - const headerIds = [] - for (const header of document.querySelectorAll('h1, h2, h3, h4, h5, h6')) { - if (header.getAttribute('id')) { - headerIds.push(header.getAttribute('id')) - continue - } - - const headerText = header.textContent - .replace(/[A-Z]/g, x => x.toLowerCase()) - .replace(/ /g, '-') - .replace(/[^a-z0-9-]/g, '') - let headerId = headerText - let headerIncrement = 1 - - while (document.getElementById(headerId) !== null) { - headerId = headerText + ++headerIncrement - } - - headerIds.push(headerId) - header.setAttribute('id', headerId) - } - - // Walk the dom and build a table of contents - const toc = document.getElementById('_table_of_contents') - - if (toc) { - toc.appendChild(generateTableOfContents(document)) - } - - // Write the final output - const output = dom.serialize() - - mkdirp.sync(path.dirname(outputPath)) - fs.writeFileSync(outputPath, output) -} - -function generateTableOfContents (document) { - const headers = [] - walkHeaders(document.getElementById('_content'), headers) - - // The nesting depth of headers are not necessarily the header level. - // (eg, h1 > h3 > h5 is a depth of three even though there's an h5.) - const hierarchy = [] - for (const header of headers) { - const level = headerLevel(header) - - while (hierarchy.length && hierarchy[hierarchy.length - 1].headerLevel > level) { - hierarchy.pop() - } - - if (!hierarchy.length || hierarchy[hierarchy.length - 1].headerLevel < level) { - const newList = document.createElement('ul') - newList.headerLevel = level - - if (hierarchy.length) { - hierarchy[hierarchy.length - 1].appendChild(newList) - } - - hierarchy.push(newList) - } - - const element = document.createElement('li') - - const link = document.createElement('a') - link.setAttribute('href', `#${header.getAttribute('id')}`) - link.innerHTML = header.innerHTML - element.appendChild(link) - - const list = hierarchy[hierarchy.length - 1] - list.appendChild(element) - } - - return hierarchy[0] -} - -function walkHeaders (element, headers) { - for (const child of element.childNodes) { - if (headerLevel(child)) { - headers.push(child) - } - - walkHeaders(child, headers) - } -} - -function headerLevel (node) { - const level = node.tagName ? node.tagName.match(/^[Hh]([123456])$/) : null - return level ? level[1] : 0 -} - -class MarkdownError extends Error { - constructor (file, inner) { - super(`failed to parse ${file}`) - this.file = file - this.inner = inner - } -} - -const run = async function (rootDir) { - const dir = (...p) => path.join(rootDir, '..', ...p) - - const config = require(dir('lib', 'config.json')) - const template = fs.readFileSync(dir('lib', 'template.html'), 'utf-8') - const nav = yaml.parse(fs.readFileSync(dir('nav.yml'), 'utf-8')) - - const navPaths = getNavigationPaths(nav) - const fsPaths = await renderFilesystemPaths({ - input: dir('content'), - output: dir('output'), - config, - template, - }) - - const navErrors = ensureNavigationComplete(navPaths, fsPaths) - if (navErrors) { - console.error(navErrors) - throw new Error('Nav Errors') - } -} - -run(__dirname).catch((err) => { - process.exitCode = 1 - console.error(err) -}) diff --git a/docs/bin/docs-build.js b/docs/bin/docs-build.js deleted file mode 100644 index 61343bfa45729..0000000000000 --- a/docs/bin/docs-build.js +++ /dev/null @@ -1,39 +0,0 @@ -const fs = require('fs').promises -const marked = require('marked-man') -const { version: VERSION } = require('../lib/npm.js') - -function frontmatter (_, p1) { - const fm = {} - - p1.split(/\r?\n/).forEach((kv) => { - const result = kv.match(/^([^\s:]+):\s*(.*)/) - if (result) { - fm[result[1]] = result[2] - } - }) - - return `# ${fm.title}(${fm.section}) - ${fm.description}` -} - -function replacer (_, p1) { - return 'npm help ' + p1.replace(/npm /, '') -} - -const run = async (src, dest = src) => { - const data = await fs.readFile(src, 'utf8') - - const result = data.replace(/@VERSION@/g, VERSION) - .replace(/^<!--.*-->$/gm, '') - .replace(/^---\n([\s\S]+\n)---/, frontmatter) - .replace(/\[([^\]]+)\]\(\/commands\/([^)]+)\)/g, replacer) - .replace(/\[([^\]]+)\]\(\/configuring-npm\/([^)]+)\)/g, replacer) - .replace(/\[([^\]]+)\]\(\/using-npm\/([^)]+)\)/g, replacer) - .trim() - - await fs.writeFile(dest, marked(result), 'utf8') -} - -run(...process.argv.slice(2)).catch((err) => { - process.exitCode = 1 - console.error(err) -}) diff --git a/docs/content/commands/npm-access.md b/docs/content/commands/npm-access.md deleted file mode 100644 index 162e94f1fec02..0000000000000 --- a/docs/content/commands/npm-access.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: npm-access -section: 1 -description: Set access level on published packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/access.js --> - -```bash -npm access public [<package>] -npm access restricted [<package>] -npm access grant <read-only|read-write> <scope:team> [<package>] -npm access revoke <scope:team> [<package>] -npm access 2fa-required [<package>] -npm access 2fa-not-required [<package>] -npm access ls-packages [<user>|<scope>|<scope:team>] -npm access ls-collaborators [<package> [<user>]] -npm access edit [<package>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/access.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Used to set access controls on private packages. - -For all of the subcommands, `npm access` will perform actions on the packages -in the current working directory if no package name is passed to the -subcommand. - -* public / restricted: - Set a package to be either publicly accessible or restricted. - -* grant / revoke: - Add or remove the ability of users and teams to have read-only or read-write - access to a package. - -* 2fa-required / 2fa-not-required: - Configure whether a package requires that anyone publishing it have two-factor - authentication enabled on their account. - -* ls-packages: - Show all of the packages a user or a team is able to access, along with the - access level, except for read-only public packages (it won't print the whole - registry listing) - -* ls-collaborators: - Show all of the access privileges for a package. Will only show permissions - for packages to which you have at least read access. If `<user>` is passed in, - the list is filtered only to teams _that_ user happens to belong to. - -* edit: - Set the access privileges for a package at once using `$EDITOR`. - -### Details - -`npm access` always operates directly on the current registry, configurable -from the command line using `--registry=<registry url>`. - -Unscoped packages are *always public*. - -Scoped packages *default to restricted*, but you can either publish them as -public using `npm publish --access=public`, or set their access as public using -`npm access public` after the initial publish. - -You must have privileges to set the access of a package: - -* You are an owner of an unscoped or scoped package. -* You are a member of the team that owns a scope. -* You have been given read-write privileges for a package, either as a member - of a team or directly as an owner. - -If you have two-factor authentication enabled then you'll be prompted to -provide an otp token, or may use the `--otp=...` option to specify it on -the command line. - -If your account is not paid, then attempts to publish scoped packages will -fail with an HTTP 402 status code (logically enough), unless you use -`--access=public`. - -Management of teams and team memberships is done with the `npm team` command. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [`libnpmaccess`](https://npm.im/libnpmaccess) -* [npm team](/commands/npm-team) -* [npm publish](/commands/npm-publish) -* [npm config](/commands/npm-config) -* [npm registry](/using-npm/registry) diff --git a/docs/content/commands/npm-adduser.md b/docs/content/commands/npm-adduser.md deleted file mode 100644 index 700aecb2255b2..0000000000000 --- a/docs/content/commands/npm-adduser.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: npm-adduser -section: 1 -description: Add a registry user account ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/adduser.js --> - -```bash -npm adduser - -aliases: login, add-user -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/adduser.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Create or verify a user named `<username>` in the specified registry, and -save the credentials to the `.npmrc` file. If no registry is specified, -the default registry will be used (see [`config`](/using-npm/config)). - -The username, password, and email are read in from prompts. - -To reset your password, go to <https://www.npmjs.com/forgot> - -To change your email address, go to <https://www.npmjs.com/email-edit> - -You may use this command multiple times with the same user account to -authorize on a new machine. When authenticating on a new machine, -the username, password and email address must all match with -your existing record. - -`npm login` is an alias to `adduser` and behaves exactly the same way. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `scope` - -* Default: the scope of the current project, if any, or "" -* Type: String - -Associate an operation with a scope for a scoped registry. - -Useful when logging in to or out of a private registry: - -``` -# log in, linking the scope to the custom registry -npm login --scope=@mycorp --registry=https://registry.mycorp.com - -# log out, removing the link and the auth token -npm logout --scope=@mycorp -``` - -This will cause `@mycorp` to be mapped to the registry for future -installation of packages specified according to the pattern -`@mycorp/package`. - -This will also cause `npm init` to create a scoped package. - -``` -# accept all defaults, and create a package named "@foo/whatever", -# instead of just named "whatever" -npm init --scope=@foo --yes -``` - - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `auth-type` - -* Default: "legacy" -* Type: "legacy", "web", "sso", "saml", "oauth", or "webauthn" - -NOTE: auth-type values "sso", "saml", "oauth", and "webauthn" will be -removed in a future version. - -What authentication strategy to use with `login`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm owner](/commands/npm-owner) -* [npm whoami](/commands/npm-whoami) -* [npm token](/commands/npm-token) -* [npm profile](/commands/npm-profile) diff --git a/docs/content/commands/npm-audit.md b/docs/content/commands/npm-audit.md deleted file mode 100644 index 48e0a3161e8f2..0000000000000 --- a/docs/content/commands/npm-audit.md +++ /dev/null @@ -1,471 +0,0 @@ ---- -title: npm-audit -section: 1 -description: Run a security audit ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/audit.js --> - -```bash -npm audit [fix|signatures] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/audit.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -The audit command submits a description of the dependencies configured in -your project to your default registry and asks for a report of known -vulnerabilities. If any vulnerabilities are found, then the impact and -appropriate remediation will be calculated. If the `fix` argument is -provided, then remediations will be applied to the package tree. - -The command will exit with a 0 exit code if no vulnerabilities were found. - -Note that some vulnerabilities cannot be fixed automatically and will -require manual intervention or review. Also note that since `npm audit -fix` runs a full-fledged `npm install` under the hood, all configs that -apply to the installer will also apply to `npm install` -- so things like -`npm audit fix --package-lock-only` will work as expected. - -By default, the audit command will exit with a non-zero code if any -vulnerability is found. It may be useful in CI environments to include the -`--audit-level` parameter to specify the minimum vulnerability level that -will cause the command to fail. This option does not filter the report -output, it simply changes the command's failure threshold. - -### Audit Signatures - -To ensure the integrity of packages you download from the public npm registry, or any registry that supports signatures, you can verify the registry signatures of downloaded packages using the npm CLI. - -Registry signatures can be verified using the following `audit` command: - -```bash -$ npm audit signatures -``` - -The npm CLI supports registry signatures and signing keys provided by any registry if the following conventions are followed: - -1. Signatures are provided in the package's `packument` in each published version within the `dist` object: - -```json -"dist":{ - "..omitted..": "..omitted..", - "signatures": [{ - "keyid": "SHA256:{{SHA256_PUBLIC_KEY}}", - "sig": "a312b9c3cb4a1b693e8ebac5ee1ca9cc01f2661c14391917dcb111517f72370809..." - }] -} -``` - -See this [example](https://registry.npmjs.org/light-cycle/1.4.3) of a signed package from the public npm registry. - -The `sig` is generated using the following template: `${package.name}@${package.version}:${package.dist.integrity}` and the `keyid` has to match one of the public signing keys below. - -2. Public signing keys are provided at `registry-host.tld/-/npm/v1/keys` in the following format: - -``` -{ - "keys": [{ - "expires": null, - "keyid": "SHA256:{{SHA256_PUBLIC_KEY}}", - "keytype": "ecdsa-sha2-nistp256", - "scheme": "ecdsa-sha2-nistp256", - "key": "{{B64_PUBLIC_KEY}}" - }] -} -``` - -Keys response: - -- `expires`: null or a simplified extended <a href="https://en.wikipedia.org/wiki/ISO_8601" target="_blank">ISO 8601 format</a>: `YYYY-MM-DDTHH:mm:ss.sssZ` -- `keydid`: sha256 fingerprint of the public key -- `keytype`: only `ecdsa-sha2-nistp256` is currently supported by the npm CLI -- `scheme`: only `ecdsa-sha2-nistp256` is currently supported by the npm CLI -- `key`: base64 encoded public key - -See this <a href="https://registry.npmjs.org/-/npm/v1/keys" target="_blank">example key's response from the public npm registry</a>. - -### Audit Endpoints - -There are two audit endpoints that npm may use to fetch vulnerability -information: the `Bulk Advisory` endpoint and the `Quick Audit` endpoint. - -#### Bulk Advisory Endpoint - -As of version 7, npm uses the much faster `Bulk Advisory` endpoint to -optimize the speed of calculating audit results. - -npm will generate a JSON payload with the name and list of versions of each -package in the tree, and POST it to the default configured registry at -the path `/-/npm/v1/security/advisories/bulk`. - -Any packages in the tree that do not have a `version` field in their -package.json file will be ignored. If any `--omit` options are specified -(either via the `--omit` config, or one of the shorthands such as -`--production`, `--only=dev`, and so on), then packages will be omitted -from the submitted payload as appropriate. - -If the registry responds with an error, or with an invalid response, then -npm will attempt to load advisory data from the `Quick Audit` endpoint. - -The expected result will contain a set of advisory objects for each -dependency that matches the advisory range. Each advisory object contains -a `name`, `url`, `id`, `severity`, `vulnerable_versions`, and `title`. - -npm then uses these advisory objects to calculate vulnerabilities and -meta-vulnerabilities of the dependencies within the tree. - -#### Quick Audit Endpoint - -If the `Bulk Advisory` endpoint returns an error, or invalid data, npm will -attempt to load advisory data from the `Quick Audit` endpoint, which is -considerably slower in most cases. - -The full package tree as found in `package-lock.json` is submitted, along -with the following pieces of additional metadata: - -* `npm_version` -* `node_version` -* `platform` -* `arch` -* `node_env` - -All packages in the tree are submitted to the Quick Audit endpoint. -Omitted dependency types are skipped when generating the report. - -#### Scrubbing - -Out of an abundance of caution, npm versions 5 and 6 would "scrub" any -packages from the submitted report if their name contained a `/` character, -so as to avoid leaking the names of potentially private packages or git -URLs. - -However, in practice, this resulted in audits often failing to properly -detect meta-vulnerabilities, because the tree would appear to be invalid -due to missing dependencies, and prevented the detection of vulnerabilities -in package trees that used git dependencies or private modules. - -This scrubbing has been removed from npm as of version 7. - -#### Calculating Meta-Vulnerabilities and Remediations - -npm uses the -[`@npmcli/metavuln-calculator`](http://npm.im/@npmcli/metavuln-calculator) -module to turn a set of security advisories into a set of "vulnerability" -objects. A "meta-vulnerability" is a dependency that is vulnerable by -virtue of dependence on vulnerable versions of a vulnerable package. - -For example, if the package `foo` is vulnerable in the range `>=1.0.2 -<2.0.0`, and the package `bar` depends on `foo@^1.1.0`, then that version -of `bar` can only be installed by installing a vulnerable version of `foo`. -In this case, `bar` is a "metavulnerability". - -Once metavulnerabilities for a given package are calculated, they are -cached in the `~/.npm` folder and only re-evaluated if the advisory range -changes, or a new version of the package is published (in which case, the -new version is checked for metavulnerable status as well). - -If the chain of metavulnerabilities extends all the way to the root -project, and it cannot be updated without changing its dependency ranges, -then `npm audit fix` will require the `--force` option to apply the -remediation. If remediations do not require changes to the dependency -ranges, then all vulnerable packages will be updated to a version that does -not have an advisory or metavulnerability posted against it. - -### Exit Code - -The `npm audit` command will exit with a 0 exit code if no vulnerabilities -were found. The `npm audit fix` command will exit with 0 exit code if no -vulnerabilities are found _or_ if the remediation is able to successfully -fix all vulnerabilities. - -If vulnerabilities were found the exit code will depend on the -`audit-level` configuration setting. - -### Examples - -Scan your project for vulnerabilities and automatically install any compatible -updates to vulnerable dependencies: - -```bash -$ npm audit fix -``` - -Run `audit fix` without modifying `node_modules`, but still updating the -pkglock: - -```bash -$ npm audit fix --package-lock-only -``` - -Skip updating `devDependencies`: - -```bash -$ npm audit fix --only=prod -``` - -Have `audit fix` install SemVer-major updates to toplevel dependencies, not -just SemVer-compatible ones: - -```bash -$ npm audit fix --force -``` - -Do a dry run to get an idea of what `audit fix` will do, and _also_ output -install information in JSON format: - -```bash -$ npm audit fix --dry-run --json -``` - -Scan your project for vulnerabilities and just show the details, without -fixing anything: - -```bash -$ npm audit -``` - -Get the detailed audit report in JSON format: - -```bash -$ npm audit --json -``` - -Fail an audit only if the results include a vulnerability with a level of moderate or higher: - -```bash -$ npm audit --audit-level=moderate -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `audit-level` - -* Default: null -* Type: null, "info", "low", "moderate", "high", "critical", or "none" - -The minimum level of vulnerability for `npm audit` to exit with a non-zero -exit code. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `force` - -* Default: false -* Type: Boolean - -Removes various protections against unfortunate side effects, common -mistakes, unnecessary performance degradation, and malicious input. - -* Allow clobbering non-npm files in global installs. -* Allow the `npm version` command to work on an unclean git repository. -* Allow deleting the cache folder with `npm cache clean`. -* Allow installing packages that have an `engines` declaration requiring a - different version of npm. -* Allow installing packages that have an `engines` declaration requiring a - different version of `node`, even if `--engine-strict` is enabled. -* Allow `npm audit fix` to install modules outside your stated dependency - range (including SemVer-major changes). -* Allow unpublishing all versions of a published package. -* Allow conflicting peerDependencies to be installed in the root project. -* Implicitly set `--yes` during `npm init`. -* Allow clobbering existing values in `npm pkg` -* Allow unpublishing of entire packages (not just a single version). - -If you don't have a clear idea of what you want to do, it is strongly -recommended that you do not use this option! - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock-only` - -* Default: false -* Type: Boolean - -If set to true, the current operation will only use the `package-lock.json`, -ignoring `node_modules`. - -For `update` this means only the `package-lock.json` will be updated, -instead of checking `node_modules` and downloading dependencies. - -For `list` this means the output will be based on the tree described by the -`package-lock.json`, rather than the contents of `node_modules`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm install](/commands/npm-install) -* [config](/using-npm/config) diff --git a/docs/content/commands/npm-bin.md b/docs/content/commands/npm-bin.md deleted file mode 100644 index 94b72cfd5c81c..0000000000000 --- a/docs/content/commands/npm-bin.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: npm-bin -section: 1 -description: Display npm bin folder ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/bin.js --> - -```bash -npm bin -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/bin.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Print the folder where npm will install executables. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm prefix](/commands/npm-prefix) -* [npm root](/commands/npm-root) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-bugs.md b/docs/content/commands/npm-bugs.md deleted file mode 100644 index 6b45f1f18ac66..0000000000000 --- a/docs/content/commands/npm-bugs.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: npm-bugs -section: 1 -description: Report bugs for a package in a web browser ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/bugs.js --> - -```bash -npm bugs [<pkgname> [<pkgname> ...]] - -alias: issues -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/bugs.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command tries to guess at the likely location of a package's bug -tracker URL or the `mailto` URL of the support email, and then tries to -open it using the `--browser` config param. If no package name is provided, it -will search for a `package.json` in the current folder and use the `name` property. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `browser` - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: null, Boolean, or String - -The browser that is called by npm commands to open websites. - -Set to `false` to suppress browser behavior and instead print urls to -terminal. - -Set to `true` to use default system URL opener. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm docs](/commands/npm-docs) -* [npm view](/commands/npm-view) -* [npm publish](/commands/npm-publish) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [package.json](/configuring-npm/package-json) diff --git a/docs/content/commands/npm-cache.md b/docs/content/commands/npm-cache.md deleted file mode 100644 index b5eddd46c05a7..0000000000000 --- a/docs/content/commands/npm-cache.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: npm-cache -section: 1 -description: Manipulates packages cache ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/cache.js --> - -```bash -npm cache add <package-spec> -npm cache clean [<key>] -npm cache ls [<name>@<version>] -npm cache verify -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/cache.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Used to add, list, or clean the npm cache folder. - -* add: - Add the specified packages to the local cache. This command is primarily - intended to be used internally by npm, but it can provide a way to - add data to the local installation cache explicitly. - -* clean: - Delete all data out of the cache folder. Note that this is typically - unnecessary, as npm's cache is self-healing and resistant to data - corruption issues. - -* verify: - Verify the contents of the cache folder, garbage collecting any unneeded - data, and verifying the integrity of the cache index and all cached data. - -### Details - -npm stores cache data in an opaque directory within the configured `cache`, -named `_cacache`. This directory is a -[`cacache`](http://npm.im/cacache)-based content-addressable cache that -stores all http request data as well as other package-related data. This -directory is primarily accessed through `pacote`, the library responsible -for all package fetching as of npm@5. - -All data that passes through the cache is fully verified for integrity on -both insertion and extraction. Cache corruption will either trigger an -error, or signal to `pacote` that the data must be refetched, which it will -do automatically. For this reason, it should never be necessary to clear -the cache for any reason other than reclaiming disk space, thus why `clean` -now requires `--force` to run. - -There is currently no method exposed through npm to inspect or directly -manage the contents of this cache. In order to access it, `cacache` must be -used directly. - -npm will not remove data by itself: the cache will grow as new packages are -installed. - -### A note about the cache's design - -The npm cache is strictly a cache: it should not be relied upon as a -persistent and reliable data store for package data. npm makes no guarantee -that a previously-cached piece of data will be available later, and will -automatically delete corrupted contents. The primary guarantee that the -cache makes is that, if it does return data, that data will be exactly the -data that was inserted. - -To run an offline verification of existing cache contents, use `npm cache -verify`. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `cache` - -* Default: Windows: `%LocalAppData%\npm-cache`, Posix: `~/.npm` -* Type: Path - -The location of npm's cache directory. See [`npm -cache`](/commands/npm-cache) - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm install](/commands/npm-install) -* [npm publish](/commands/npm-publish) -* [npm pack](/commands/npm-pack) -* https://npm.im/cacache -* https://npm.im/pacote -* https://npm.im/@npmcli/arborist -* https://npm.im/make-fetch-happen diff --git a/docs/content/commands/npm-ci.md b/docs/content/commands/npm-ci.md deleted file mode 100644 index 3ecd7c6efb095..0000000000000 --- a/docs/content/commands/npm-ci.md +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: npm-ci -section: 1 -description: Clean install a project ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/ci.js --> - -```bash -npm ci - -aliases: clean-install, ic, install-clean, isntall-clean -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/ci.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command is similar to [`npm install`](/commands/npm-install), except -it's meant to be used in automated environments such as test platforms, -continuous integration, and deployment -- or any situation where you want -to make sure you're doing a clean install of your dependencies. - -The main differences between using `npm install` and `npm ci` are: - -* The project **must** have an existing `package-lock.json` or - `npm-shrinkwrap.json`. -* If dependencies in the package lock do not match those in `package.json`, - `npm ci` will exit with an error, instead of updating the package lock. -* `npm ci` can only install entire projects at a time: individual - dependencies cannot be added with this command. -* If a `node_modules` is already present, it will be automatically removed - before `npm ci` begins its install. -* It will never write to `package.json` or any of the package-locks: - installs are essentially frozen. - -NOTE: If you create your `package-lock.json` file by running `npm install` -with flags that can affect the shape of your dependency tree, such as -`--legacy-peer-deps` or `--install-links`, you _must_ provide the same -flags to `npm ci` or you are likely to encounter errors. An easy way to do -this is to run, for example, -`npm config set legacy-peer-deps=true --location=project` and commit the -`.npmrc` file to your repo. - -### Example - -Make sure you have a package-lock and an up-to-date install: - -```bash -$ cd ./my/npm/project -$ npm install -added 154 packages in 10s -$ ls | grep package-lock -``` - -Run `npm ci` in that project - -```bash -$ npm ci -added 154 packages in 5s -``` - -Configure Travis CI to build using `npm ci` instead of `npm install`: - -```bash -# .travis.yml -install: -- npm ci -# keep the npm cache around to speed up installs -cache: - directories: - - "$HOME/.npm" -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-exact` - -* Default: false -* Type: Boolean - -Dependencies saved to package.json will be configured with an exact version -rather than using npm's default semver range operator. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm install](/commands/npm-install) -* [package-lock.json](/configuring-npm/package-lock-json) diff --git a/docs/content/commands/npm-completion.md b/docs/content/commands/npm-completion.md deleted file mode 100644 index d73a98f2e50f7..0000000000000 --- a/docs/content/commands/npm-completion.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: npm-completion -section: 1 -description: Tab Completion for npm ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/completion.js --> - -```bash -npm completion -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/completion.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Enables tab-completion in all npm commands. - -The synopsis above -loads the completions into your current shell. Adding it to -your ~/.bashrc or ~/.zshrc will make the completions available -everywhere: - -```bash -npm completion >> ~/.bashrc -npm completion >> ~/.zshrc -``` - -You may of course also pipe the output of `npm completion` to a file -such as `/usr/local/etc/bash_completion.d/npm` or -`/etc/bash_completion.d/npm` if you have a system that will read -that file for you. - -When `COMP_CWORD`, `COMP_LINE`, and `COMP_POINT` are defined in the -environment, `npm completion` acts in "plumbing mode", and outputs -completions based on the arguments. - -### See Also - -* [npm developers](/using-npm/developers) -* [npm](/commands/npm) diff --git a/docs/content/commands/npm-config.md b/docs/content/commands/npm-config.md deleted file mode 100644 index 28c6003571de5..0000000000000 --- a/docs/content/commands/npm-config.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: npm-config -section: 1 -description: Manage the npm configuration files ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/config.js --> - -```bash -npm config set <key>=<value> [<key>=<value> ...] -npm config get [<key> [<key> ...]] -npm config delete <key> [<key> ...] -npm config list [--json] -npm config edit - -alias: c -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/config.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -npm gets its config settings from the command line, environment -variables, `npmrc` files, and in some cases, the `package.json` file. - -See [npmrc](/configuring-npm/npmrc) for more information about the npmrc -files. - -See [config(7)](/using-npm/config) for a more thorough explanation of the -mechanisms involved, and a full list of config options available. - -The `npm config` command can be used to update and edit the contents -of the user and global npmrc files. - -### Sub-commands - -Config supports the following sub-commands: - -#### set - -```bash -npm config set key=value [key=value...] -npm set key=value [key=value...] -``` - -Sets each of the config keys to the value provided. - -If value is omitted, then it sets it to an empty string. - -Note: for backwards compatibility, `npm config set key value` is supported -as an alias for `npm config set key=value`. - -#### get - -```bash -npm config get [key ...] -npm get [key ...] -``` - -Echo the config value(s) to stdout. - -If multiple keys are provided, then the values will be prefixed with the -key names. - -If no keys are provided, then this command behaves the same as `npm config -list`. - -#### list - -```bash -npm config list -``` - -Show all the config settings. Use `-l` to also show defaults. Use `--json` -to show the settings in json format. - -#### delete - -```bash -npm config delete key [key ...] -``` - -Deletes the specified keys from all configuration files. - -#### edit - -```bash -npm config edit -``` - -Opens the config file in an editor. Use the `--global` flag to edit the -global config. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `editor` - -* Default: The EDITOR or VISUAL environment variables, or 'notepad.exe' on - Windows, or 'vim' on Unix systems -* Type: String - -The command to run for `npm edit` and `npm config edit`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `location` - -* Default: "user" unless `--global` is passed, which will also set this value - to "global" -* Type: "global", "user", or "project" - -When passed to `npm config` this refers to which config file to use. - -When set to "global" mode, packages are installed into the `prefix` folder -instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [package.json](/configuring-npm/package-json) -* [npmrc](/configuring-npm/npmrc) -* [npm](/commands/npm) diff --git a/docs/content/commands/npm-dedupe.md b/docs/content/commands/npm-dedupe.md deleted file mode 100644 index 570e018342f27..0000000000000 --- a/docs/content/commands/npm-dedupe.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -title: npm-dedupe -section: 1 -description: Reduce duplication in the package tree ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/dedupe.js --> - -```bash -npm dedupe - -alias: ddp -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/dedupe.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Searches the local package tree and attempts to simplify the overall -structure by moving dependencies further up the tree, where they can -be more effectively shared by multiple dependent packages. - -For example, consider this dependency graph: - -``` -a -+-- b <-- depends on c@1.0.x -| `-- c@1.0.3 -`-- d <-- depends on c@~1.0.9 - `-- c@1.0.10 -``` - -In this case, `npm dedupe` will transform the tree to: - -```bash -a -+-- b -+-- d -`-- c@1.0.10 -``` - -Because of the hierarchical nature of node's module lookup, b and d -will both get their dependency met by the single c package at the root -level of the tree. - -In some cases, you may have a dependency graph like this: - -``` -a -+-- b <-- depends on c@1.0.x -+-- c@1.0.3 -`-- d <-- depends on c@1.x - `-- c@1.9.9 -``` - -During the installation process, the `c@1.0.3` dependency for `b` was -placed in the root of the tree. Though `d`'s dependency on `c@1.x` could -have been satisfied by `c@1.0.3`, the newer `c@1.9.0` dependency was used, -because npm favors updates by default, even when doing so causes -duplication. - -Running `npm dedupe` will cause npm to note the duplication and -re-evaluate, deleting the nested `c` module, because the one in the root is -sufficient. - -To prefer deduplication over novelty during the installation process, run -`npm install --prefer-dedupe` or `npm config set prefer-dedupe true`. - -Arguments are ignored. Dedupe always acts on the entire tree. - -Note that this operation transforms the dependency tree, but will never -result in new modules being installed. - -Using `npm find-dupes` will run the command in `--dry-run` mode. - -Note: `npm dedupe` will never update the semver values of direct -dependencies in your project `package.json`, if you want to update -values in `package.json` you can run: `npm update --save` instead. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm find-dupes](/commands/npm-find-dupes) -* [npm ls](/commands/npm-ls) -* [npm update](/commands/npm-update) -* [npm install](/commands/npm-install) diff --git a/docs/content/commands/npm-deprecate.md b/docs/content/commands/npm-deprecate.md deleted file mode 100644 index 20f65140fc735..0000000000000 --- a/docs/content/commands/npm-deprecate.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: npm-deprecate -section: 1 -description: Deprecate a version of a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/deprecate.js --> - -```bash -npm deprecate <package-spec> <message> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/deprecate.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -This command will update the npm registry entry for a package, providing a -deprecation warning to all who attempt to install it. - -It works on [version ranges](https://semver.npmjs.com/) as well as specific -versions, so you can do something like this: - -```bash -npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3" -``` - -SemVer ranges passed to this command are interpreted such that they *do* -include prerelease versions. For example: - -```bash -npm deprecate my-thing@1.x "1.x is no longer supported" -``` - -In this case, a version `my-thing@1.0.0-beta.0` will also be deprecated. - -You must be the package owner to deprecate something. See the `owner` and -`adduser` help topics. - -To un-deprecate a package, specify an empty string (`""`) for the `message` -argument. Note that you must use double quotes with no space between them to -format an empty string. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm publish](/commands/npm-publish) -* [npm registry](/using-npm/registry) -* [npm owner](/commands/npm-owner) -* [npm adduser](/commands/npm-adduser) diff --git a/docs/content/commands/npm-diff.md b/docs/content/commands/npm-diff.md deleted file mode 100644 index 7dcc8af7c3b4c..0000000000000 --- a/docs/content/commands/npm-diff.md +++ /dev/null @@ -1,349 +0,0 @@ ---- -title: npm-diff -section: 1 -description: The registry diff command ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/diff.js --> - -```bash -npm diff [...<paths>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/diff.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Similar to its `git diff` counterpart, this command will print diff patches -of files for packages published to the npm registry. - -* `npm diff --diff=<spec-a> --diff=<spec-b>` - - Compares two package versions using their registry specifiers, e.g: - `npm diff --diff=pkg@1.0.0 --diff=pkg@^2.0.0`. It's also possible to - compare across forks of any package, - e.g: `npm diff --diff=pkg@1.0.0 --diff=pkg-fork@1.0.0`. - - Any valid spec can be used, so that it's also possible to compare - directories or git repositories, - e.g: `npm diff --diff=pkg@latest --diff=./packages/pkg` - - Here's an example comparing two different versions of a package named - `abbrev` from the registry: - - ```bash - npm diff --diff=abbrev@1.1.0 --diff=abbrev@1.1.1 - ``` - - On success, output looks like: - - ```bash - diff --git a/package.json b/package.json - index v1.1.0..v1.1.1 100644 - --- a/package.json - +++ b/package.json - @@ -1,6 +1,6 @@ - { - "name": "abbrev", - - "version": "1.1.0", - + "version": "1.1.1", - "description": "Like ruby's abbrev module, but in js", - "author": "Isaac Z. Schlueter <i@izs.me>", - "main": "abbrev.js", - ``` - - Given the flexible nature of npm specs, you can also target local - directories or git repos just like when using `npm install`: - - ```bash - npm diff --diff=https://github.com/npm/libnpmdiff --diff=./local-path - ``` - - In the example above we can compare the contents from the package installed - from the git repo at `github.com/npm/libnpmdiff` with the contents of the - `./local-path` that contains a valid package, such as a modified copy of - the original. - -* `npm diff` (in a package directory, no arguments): - - If the package is published to the registry, `npm diff` will fetch the - tarball version tagged as `latest` (this value can be configured using the - `tag` option) and proceed to compare the contents of files present in that - tarball, with the current files in your local file system. - - This workflow provides a handy way for package authors to see what - package-tracked files have been changed in comparison with the latest - published version of that package. - -* `npm diff --diff=<pkg-name>` (in a package directory): - - When using a single package name (with no version or tag specifier) as an - argument, `npm diff` will work in a similar way to - [`npm-outdated`](npm-outdated) and reach for the registry to figure out - what current published version of the package named `<pkg-name>` - will satisfy its dependent declared semver-range. Once that specific - version is known `npm diff` will print diff patches comparing the - current version of `<pkg-name>` found in the local file system with - that specific version returned by the registry. - - Given a package named `abbrev` that is currently installed: - - ```bash - npm diff --diff=abbrev - ``` - - That will request from the registry its most up to date version and - will print a diff output comparing the currently installed version to this - newer one if the version numbers are not the same. - -* `npm diff --diff=<spec-a>` (in a package directory): - - Similar to using only a single package name, it's also possible to declare - a full registry specifier version if you wish to compare the local version - of an installed package with the specific version/tag/semver-range provided - in `<spec-a>`. - - An example: assuming `pkg@1.0.0` is installed in the current `node_modules` - folder, running: - - ```bash - npm diff --diff=pkg@2.0.0 - ``` - - It will effectively be an alias to - `npm diff --diff=pkg@1.0.0 --diff=pkg@2.0.0`. - -* `npm diff --diff=<semver-a> [--diff=<semver-b>]` (in a package directory): - - Using `npm diff` along with semver-valid version numbers is a shorthand - to compare different versions of the current package. - - It needs to be run from a package directory, such that for a package named - `pkg` running `npm diff --diff=1.0.0 --diff=1.0.1` is the same as running - `npm diff --diff=pkg@1.0.0 --diff=pkg@1.0.1`. - - If only a single argument `<version-a>` is provided, then the current local - file system is going to be compared against that version. - - Here's an example comparing two specific versions (published to the - configured registry) of the current project directory: - - ```bash - npm diff --diff=1.0.0 --diff=1.1.0 - ``` - -Note that tag names are not valid `--diff` argument values, if you wish to -compare to a published tag, you must use the `pkg@tagname` syntax. - -#### Filtering files - -It's possible to also specify positional arguments using file names or globs -pattern matching in order to limit the result of diff patches to only a subset -of files for a given package, e.g: - - ```bash - npm diff --diff=pkg@2 ./lib/ CHANGELOG.md - ``` - -In the example above the diff output is only going to print contents of files -located within the folder `./lib/` and changed lines of code within the -`CHANGELOG.md` file. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `diff` - -* Default: -* Type: String (can be set multiple times) - -Define arguments to compare in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-name-only` - -* Default: false -* Type: Boolean - -Prints only filenames when using `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-unified` - -* Default: 3 -* Type: Number - -The number of lines of context to print in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-ignore-all-space` - -* Default: false -* Type: Boolean - -Ignore whitespace when comparing lines in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-no-prefix` - -* Default: false -* Type: Boolean - -Do not show any source or destination prefix in `npm diff` output. - -Note: this causes `npm diff` to ignore the `--diff-src-prefix` and -`--diff-dst-prefix` configs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-src-prefix` - -* Default: "a/" -* Type: String - -Source prefix to be used in `npm diff` output. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-dst-prefix` - -* Default: "b/" -* Type: String - -Destination prefix to be used in `npm diff` output. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-text` - -* Default: false -* Type: Boolean - -Treat all files as text in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `tag` - -* Default: "latest" -* Type: String - -If you ask npm to install a package and don't tell it a specific version, -then it will install the specified tag. - -Also the tag that is added to the package@version specified by the `npm tag` -command, if no explicit tag is given. - -When used by the `npm diff` command, this is the tag used to fetch the -tarball that will be compared with the local files by default. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> -## See Also - -* [npm outdated](/commands/npm-outdated) -* [npm install](/commands/npm-install) -* [npm config](/commands/npm-config) -* [npm registry](/using-npm/registry) diff --git a/docs/content/commands/npm-dist-tag.md b/docs/content/commands/npm-dist-tag.md deleted file mode 100644 index 123e67dbf3b23..0000000000000 --- a/docs/content/commands/npm-dist-tag.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: npm-dist-tag -section: 1 -description: Modify package distribution tags ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/dist-tag.js --> - -```bash -npm dist-tag add <package-spec (with version)> [<tag>] -npm dist-tag rm <package-spec> <tag> -npm dist-tag ls [<package-spec>] - -alias: dist-tags -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/dist-tag.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Add, remove, and enumerate distribution tags on a package: - -* add: Tags the specified version of the package with the specified tag, - or the `--tag` config if not specified. If you have two-factor - authentication on auth-and-writes then you’ll need to include a - one-time password on the command line with - `--otp <one-time password>`, or at the OTP prompt. - -* rm: Clear a tag that is no longer in use from the package. If you have - two-factor authentication on auth-and-writes then you’ll need to include - a one-time password on the command line with `--otp <one-time password>`, - or at the OTP prompt. - -* ls: Show all of the dist-tags for a package, defaulting to the package in - the current prefix. This is the default action if none is specified. - -A tag can be used when installing packages as a reference to a version instead -of using a specific version number: - -```bash -npm install <name>@<tag> -``` - -When installing dependencies, a preferred tagged version may be specified: - -```bash -npm install --tag <tag> -``` - -(This also applies to any other commands that resolve and install -dependencies, such as `npm dedupe`, `npm update`, and `npm audit fix`.) - -Publishing a package sets the `latest` tag to the published version unless the -`--tag` option is used. For example, `npm publish --tag=beta`. - -By default, `npm install <pkg>` (without any `@<version>` or `@<tag>` -specifier) installs the `latest` tag. - -### Purpose - -Tags can be used to provide an alias instead of version numbers. - -For example, a project might choose to have multiple streams of development -and use a different tag for each stream, e.g., `stable`, `beta`, `dev`, -`canary`. - -By default, the `latest` tag is used by npm to identify the current version -of a package, and `npm install <pkg>` (without any `@<version>` or `@<tag>` -specifier) installs the `latest` tag. Typically, projects only use the -`latest` tag for stable release versions, and use other tags for unstable -versions such as prereleases. - -The `next` tag is used by some projects to identify the upcoming version. - -Other than `latest`, no tag has any special significance to npm itself. - -### Caveats - -This command used to be known as `npm tag`, which only created new tags, -and so had a different syntax. - -Tags must share a namespace with version numbers, because they are -specified in the same slot: `npm install <pkg>@<version>` vs -`npm install <pkg>@<tag>`. - -Tags that can be interpreted as valid semver ranges will be rejected. For -example, `v1.4` cannot be used as a tag, because it is interpreted by -semver as `>=1.4.0 <1.5.0`. See <https://github.com/npm/npm/issues/6082>. - -The simplest way to avoid semver problems with tags is to use tags that do -not begin with a number or the letter `v`. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm publish](/commands/npm-publish) -* [npm install](/commands/npm-install) -* [npm dedupe](/commands/npm-dedupe) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-docs.md b/docs/content/commands/npm-docs.md deleted file mode 100644 index 790d563bdb1fb..0000000000000 --- a/docs/content/commands/npm-docs.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: npm-docs -section: 1 -description: Open documentation for a package in a web browser ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/docs.js --> - -```bash -npm docs [<pkgname> [<pkgname> ...]] - -alias: home -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/docs.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command tries to guess at the likely location of a package's -documentation URL, and then tries to open it using the `--browser` config -param. You can pass multiple package names at once. If no package name is -provided, it will search for a `package.json` in the current folder and use -the `name` property. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `browser` - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: null, Boolean, or String - -The browser that is called by npm commands to open websites. - -Set to `false` to suppress browser behavior and instead print urls to -terminal. - -Set to `true` to use default system URL opener. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm view](/commands/npm-view) -* [npm publish](/commands/npm-publish) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [package.json](/configuring-npm/package-json) diff --git a/docs/content/commands/npm-doctor.md b/docs/content/commands/npm-doctor.md deleted file mode 100644 index 7fb63bab16e83..0000000000000 --- a/docs/content/commands/npm-doctor.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: npm-doctor -section: 1 -description: Check your npm environment ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/doctor.js --> - -```bash -npm doctor -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/doctor.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -`npm doctor` runs a set of checks to ensure that your npm installation has -what it needs to manage your JavaScript packages. npm is mostly a -standalone tool, but it does have some basic requirements that must be met: - -+ Node.js and git must be executable by npm. -+ The primary npm registry, `registry.npmjs.com`, or another service that - uses the registry API, is available. -+ The directories that npm uses, `node_modules` (both locally and - globally), exist and can be written by the current user. -+ The npm cache exists, and the package tarballs within it aren't corrupt. - -Without all of these working properly, npm may not work properly. Many -issues are often attributable to things that are outside npm's code base, -so `npm doctor` confirms that the npm installation is in a good state. - -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 -`npm@latest` is better than an old version. - -`npm doctor` verifies the following items in your environment, and if there -are any recommended changes, it will display them. - -#### `npm ping` - -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`. - -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` - -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 -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. - -#### `node -v` - -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` - -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` - -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 -not accessible via your `PATH` so that npm can find it. This check ensures -that Git is available. - -#### Permissions checks - -* Your cache must be readable and writable by the user running npm. -* Global package binaries must be writable by the user running npm. -* Your local `node_modules` path, if you're running `npm doctor` with a - project directory, must be readable and writable by the user running npm. - -#### Validate the checksums of cached packages - -When an npm package is published, the publishing process generates a -checksum that npm uses at install time to verify that the package didn't -get corrupted in transit. `npm doctor` uses these checksums to validate the -package tarballs in your local cache (you can see where that cache is -located with `npm config get cache`). In the event that there are corrupt -packages in your cache, you should probably run `npm cache clean -f` and -reset the cache. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm bugs](/commands/npm-bugs) -* [npm help](/commands/npm-help) -* [npm ping](/commands/npm-ping) diff --git a/docs/content/commands/npm-edit.md b/docs/content/commands/npm-edit.md deleted file mode 100644 index 39fc49592c571..0000000000000 --- a/docs/content/commands/npm-edit.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: npm-edit -section: 1 -description: Edit an installed package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/edit.js --> - -```bash -npm edit <pkg>[/<subpkg>...] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/edit.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Selects a dependency in the current project and opens the package folder in -the default editor (or whatever you've configured as the npm `editor` -config -- see [`npm-config`](npm-config).) - -After it has been edited, the package is rebuilt so as to pick up any -changes in compiled packages. - -For instance, you can do `npm install connect` to install connect -into your package, and then `npm edit connect` to make a few -changes to your locally installed copy. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `editor` - -* Default: The EDITOR or VISUAL environment variables, or 'notepad.exe' on - Windows, or 'vim' on Unix systems -* Type: String - -The command to run for `npm edit` and `npm config edit`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm folders](/configuring-npm/folders) -* [npm explore](/commands/npm-explore) -* [npm install](/commands/npm-install) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-exec.md b/docs/content/commands/npm-exec.md deleted file mode 100644 index 3d8de1ea54ad6..0000000000000 --- a/docs/content/commands/npm-exec.md +++ /dev/null @@ -1,390 +0,0 @@ ---- -title: npm-exec -section: 1 -description: Run a command from a local or remote npm package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/exec.js --> - -```bash -npm exec -- <pkg>[@<version>] [args...] -npm exec --package=<pkg>[@<version>] -- <cmd> [args...] -npm exec -c '<cmd> [args...]' -npm exec --package=foo -c '<cmd> [args...]' - -alias: x -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/exec.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command allows you to run an arbitrary command from an npm package -(either one installed locally, or fetched remotely), in a similar context -as running it via `npm run`. - -Run without positional arguments or `--call`, this allows you to -interactively run commands in the same sort of shell environment that -`package.json` scripts are run. Interactive mode is not supported in CI -environments when standard input is a TTY, to prevent hangs. - -Whatever packages are specified by the `--package` option will be -provided in the `PATH` of the executed command, along with any locally -installed package executables. The `--package` option may be -specified multiple times, to execute the supplied command in an environment -where all specified packages are available. - -If any requested packages are not present in the local project -dependencies, then they are installed to a folder in the npm cache, which -is added to the `PATH` environment variable in the executed process. A -prompt is printed (which can be suppressed by providing either `--yes` or -`--no`). - -Package names provided without a specifier will be matched with whatever -version exists in the local project. Package names with a specifier will -only be considered a match if they have the exact same name and version as -the local dependency. - -If no `-c` or `--call` option is provided, then the positional arguments -are used to generate the command string. If no `--package` options -are provided, then npm will attempt to determine the executable name from -the package specifier provided as the first positional argument according -to the following heuristic: - -- If the package has a single entry in its `bin` field in `package.json`, - or if all entries are aliases of the same command, then that command - will be used. -- If the package has multiple `bin` entries, and one of them matches the - unscoped portion of the `name` field, then that command will be used. -- If this does not result in exactly one option (either because there are - no bin entries, or none of them match the `name` of the package), then - `npm exec` exits with an error. - -To run a binary _other than_ the named binary, specify one or more -`--package` options, which will prevent npm from inferring the package from -the first command argument. - -### `npx` vs `npm exec` - -When run via the `npx` binary, all flags and options *must* be set prior to -any positional arguments. When run via `npm exec`, a double-hyphen `--` -flag can be used to suppress npm's parsing of switches and options that -should be sent to the executed command. - -For example: - -``` -$ npx foo@latest bar --package=@npmcli/foo -``` - -In this case, npm will resolve the `foo` package name, and run the -following command: - -``` -$ foo bar --package=@npmcli/foo -``` - -Since the `--package` option comes _after_ the positional arguments, it is -treated as an argument to the executed command. - -In contrast, due to npm's argument parsing logic, running this command is -different: - -``` -$ npm exec foo@latest bar --package=@npmcli/foo -``` - -In this case, npm will parse the `--package` option first, resolving the -`@npmcli/foo` package. Then, it will execute the following command in that -context: - -``` -$ foo@latest bar -``` - -The double-hyphen character is recommended to explicitly tell npm to stop -parsing command line options and switches. The following command would -thus be equivalent to the `npx` command above: - -``` -$ npm exec -- foo@latest bar --package=@npmcli/foo -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `package` - -* Default: -* Type: String (can be set multiple times) - -The package or packages to install for [`npm exec`](/commands/npm-exec) - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `call` - -* Default: "" -* Type: String - -Optional companion option for `npm exec`, `npx` that allows for specifying a -custom command to be run along with the installed packages. - -```bash -npm exec --package yo --package generator-node --call "yo node" -``` - - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### Examples - -Run the version of `tap` in the local dependencies, with the provided -arguments: - -``` -$ npm exec -- tap --bail test/foo.js -$ npx tap --bail test/foo.js -``` - -Run a command _other than_ the command whose name matches the package name -by specifying a `--package` option: - -``` -$ npm exec --package=foo -- bar --bar-argument -# ~ or ~ -$ npx --package=foo bar --bar-argument -``` - -Run an arbitrary shell script, in the context of the current project: - -``` -$ npm x -c 'eslint && say "hooray, lint passed"' -$ npx -c 'eslint && say "hooray, lint passed"' -``` - -### Workspaces support - -You may use the `workspace` or `workspaces` configs in order to run an -arbitrary command from an npm package (either one installed locally, or fetched -remotely) in the context of the specified workspaces. -If no positional argument or `--call` option is provided, it will open an -interactive subshell in the context of each of these configured workspaces one -at a time. - -Given a project with configured workspaces, e.g: - -``` -. -+-- package.json -`-- packages - +-- a - | `-- package.json - +-- b - | `-- package.json - `-- c - `-- package.json -``` - -Assuming the workspace configuration is properly set up at the root level -`package.json` file. e.g: - -``` -{ - "workspaces": [ "./packages/*" ] -} -``` - -You can execute an arbitrary command from a package in the context of each of -the configured workspaces when using the `workspaces` configuration options, -in this example we're using **eslint** to lint any js file found within each -workspace folder: - -``` -npm exec --ws -- eslint ./*.js -``` - -#### Filtering workspaces - -It's also possible to execute a command in a single workspace using the -`workspace` config along with a name or directory path: - -``` -npm exec --workspace=a -- eslint ./*.js -``` - -The `workspace` config can also be specified multiple times in order to run a -specific script in the context of multiple workspaces. When defining values for -the `workspace` config in the command line, it also possible to use `-w` as a -shorthand, e.g: - -``` -npm exec -w a -w b -- eslint ./*.js -``` - -This last command will run the `eslint` command in both `./packages/a` and -`./packages/b` folders. - -### Compatibility with Older npx Versions - -The `npx` binary was rewritten in npm v7.0.0, and the standalone `npx` -package deprecated at that time. `npx` uses the `npm exec` -command instead of a separate argument parser and install process, with -some affordances to maintain backwards compatibility with the arguments it -accepted in previous versions. - -This resulted in some shifts in its functionality: - -- Any `npm` config value may be provided. -- To prevent security and user-experience problems from mistyping package - names, `npx` prompts before installing anything. Suppress this - prompt with the `-y` or `--yes` option. -- The `--no-install` option is deprecated, and will be converted to `--no`. -- Shell fallback functionality is removed, as it is not advisable. -- The `-p` argument is a shorthand for `--parseable` in npm, but shorthand - for `--package` in npx. This is maintained, but only for the `npx` - executable. -- The `--ignore-existing` option is removed. Locally installed bins are - always present in the executed process `PATH`. -- The `--npm` option is removed. `npx` will always use the `npm` it ships - with. -- The `--node-arg` and `-n` options are removed. -- The `--always-spawn` option is redundant, and thus removed. -- The `--shell` option is replaced with `--script-shell`, but maintained - in the `npx` executable for backwards compatibility. - -### A note on caching - -The npm cli utilizes its internal package cache when using the package -name specified. You can use the following to change how and when the -cli uses this cache. See [`npm cache`](/commands/npm-cache) for more on -how the cache works. - -#### prefer-online - -Forces staleness checks for packages, making the cli look for updates -immediately even if the package is already in the cache. - -#### prefer-offline - -Bypasses staleness checks for packages. Missing data will still be -requested from the server. To force full offline mode, use `offline`. - -#### offline - -Forces full offline mode. Any packages not locally cached will result in -an error. - -#### workspace - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result to selecting all of the - nested workspaces) - -This value is not exported to the environment for child processes. - -#### workspaces - -* Alias: `--ws` -* Type: Boolean -* Default: `false` - -Run scripts in the context of all configured workspaces for the current -project. - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [npm test](/commands/npm-test) -* [npm start](/commands/npm-start) -* [npm restart](/commands/npm-restart) -* [npm stop](/commands/npm-stop) -* [npm config](/commands/npm-config) -* [npm workspaces](/using-npm/workspaces) -* [npx](/commands/npx) diff --git a/docs/content/commands/npm-explain.md b/docs/content/commands/npm-explain.md deleted file mode 100644 index 5ba2fe8206ba1..0000000000000 --- a/docs/content/commands/npm-explain.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: npm-explain -section: 1 -description: Explain installed packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/explain.js --> - -```bash -npm explain <package-spec> - -alias: why -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/explain.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command will print the chain of dependencies causing a given package -to be installed in the current project. - -If one or more package specs are provided, then only packages matching -one of the specifiers will have their relationships explained. - -The package spec can also refer to a folder within `./node_modules` - -For example, running `npm explain glob` within npm's source tree will show: - -```bash -glob@7.1.6 -node_modules/glob - glob@"^7.1.4" from the root project - -glob@7.1.1 dev -node_modules/tacks/node_modules/glob - glob@"^7.0.5" from rimraf@2.6.2 - node_modules/tacks/node_modules/rimraf - rimraf@"^2.6.2" from tacks@1.3.0 - node_modules/tacks - dev tacks@"^1.3.0" from the root project -``` - -To explain just the package residing at a specific folder, pass that as the -argument to the command. This can be useful when trying to figure out -exactly why a given dependency is being duplicated to satisfy conflicting -version requirements within the project. - -```bash -$ npm explain node_modules/nyc/node_modules/find-up -find-up@3.0.0 dev -node_modules/nyc/node_modules/find-up - find-up@"^3.0.0" from nyc@14.1.1 - node_modules/nyc - nyc@"^14.1.1" from tap@14.10.8 - node_modules/tap - dev tap@"^14.10.8" from the root project -``` - -### Configuration -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm folders](/configuring-npm/folders) -* [npm ls](/commands/npm-ls) -* [npm install](/commands/npm-install) -* [npm link](/commands/npm-link) -* [npm prune](/commands/npm-prune) -* [npm outdated](/commands/npm-outdated) -* [npm update](/commands/npm-update) diff --git a/docs/content/commands/npm-explore.md b/docs/content/commands/npm-explore.md deleted file mode 100644 index 90753c7e09199..0000000000000 --- a/docs/content/commands/npm-explore.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: npm-explore -section: 1 -description: Browse an installed package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/explore.js --> - -```bash -npm explore <pkg> [ -- <command>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/explore.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Spawn a subshell in the directory of the installed package specified. - -If a command is specified, then it is run in the subshell, which then -immediately terminates. - -This is particularly handy in the case of git submodules in the -`node_modules` folder: - -```bash -npm explore some-dependency -- git pull origin master -``` - -Note that the package is *not* automatically rebuilt afterwards, so be -sure to use `npm rebuild <pkg>` if you make any changes. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `shell` - -* Default: SHELL environment variable, or "bash" on Posix, or "cmd.exe" on - Windows -* Type: String - -The shell to run for the `npm explore` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm folders](/configuring-npm/folders) -* [npm edit](/commands/npm-edit) -* [npm rebuild](/commands/npm-rebuild) -* [npm install](/commands/npm-install) diff --git a/docs/content/commands/npm-find-dupes.md b/docs/content/commands/npm-find-dupes.md deleted file mode 100644 index 4da6c296c6bf6..0000000000000 --- a/docs/content/commands/npm-find-dupes.md +++ /dev/null @@ -1,253 +0,0 @@ ---- -title: npm-find-dupes -section: 1 -description: Find duplication in the package tree ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/find-dupes.js --> - -```bash -npm find-dupes -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/find-dupes.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Runs `npm dedupe` in `--dry-run` mode, making npm only output the -duplications, without actually changing the package tree. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm dedupe](/commands/npm-dedupe) -* [npm ls](/commands/npm-ls) -* [npm update](/commands/npm-update) -* [npm install](/commands/npm-install) - diff --git a/docs/content/commands/npm-fund.md b/docs/content/commands/npm-fund.md deleted file mode 100644 index 8db0ce910de96..0000000000000 --- a/docs/content/commands/npm-fund.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: npm-fund -section: 1 -description: Retrieve funding information ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/fund.js --> - -```bash -npm fund [<package-spec>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/fund.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command retrieves information on how to fund the dependencies of a -given project. If no package name is provided, it will list all -dependencies that are looking for funding in a tree structure, listing -the type of funding and the url to visit. If a package name is provided -then it tries to open its funding url using the `--browser` config -param; if there are multiple funding sources for the package, the user -will be instructed to pass the `--which` option to disambiguate. - -The list will avoid duplicated entries and will stack all packages that -share the same url as a single entry. Thus, the list does not have the -same shape of the output from `npm ls`. - -#### Example - -### Workspaces support - -It's possible to filter the results to only include a single workspace -and its dependencies using the `workspace` config option. - -#### Example: - -Here's an example running `npm fund` in a project with a configured -workspace `a`: - -```bash -$ npm fund -test-workspaces-fund@1.0.0 -+-- https://example.com/a -| | `-- a@1.0.0 -| `-- https://example.com/maintainer -| `-- foo@1.0.0 -+-- https://example.com/npmcli-funding -| `-- @npmcli/test-funding -`-- https://example.com/org - `-- bar@2.0.0 -``` - -And here is an example of the expected result when filtering only by a -specific workspace `a` in the same project: - -```bash -$ npm fund -w a -test-workspaces-fund@1.0.0 -`-- https://example.com/a - | `-- a@1.0.0 - `-- https://example.com/maintainer - `-- foo@2.0.0 -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `browser` - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: null, Boolean, or String - -The browser that is called by npm commands to open websites. - -Set to `false` to suppress browser behavior and instead print urls to -terminal. - -Set to `true` to use default system URL opener. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `unicode` - -* Default: false on windows, true on mac/unix systems with a unicode locale, - as defined by the `LC_ALL`, `LC_CTYPE`, or `LANG` environment variables. -* Type: Boolean - -When set to true, npm uses unicode characters in the tree output. When -false, it uses ascii characters instead of unicode glyphs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `which` - -* Default: null -* Type: null or Number - -If there are multiple funding sources, which 1-indexed source URL to open. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -## See Also - -* [package spec](/using-npm/package-spec) -* [npm install](/commands/npm-install) -* [npm docs](/commands/npm-docs) -* [npm ls](/commands/npm-ls) -* [npm config](/commands/npm-config) -* [npm workspaces](/using-npm/workspaces) diff --git a/docs/content/commands/npm-help-search.md b/docs/content/commands/npm-help-search.md deleted file mode 100644 index 152f9f6bec16f..0000000000000 --- a/docs/content/commands/npm-help-search.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: npm-help-search -section: 1 -description: Search npm help documentation ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/help-search.js --> - -```bash -npm help-search <text> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/help-search.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -This command will search the npm markdown documentation files for the terms -provided, and then list the results, sorted by relevance. - -If only one result is found, then it will show that help topic. - -If the argument to `npm help` is not a known help topic, then it will call -`help-search`. It is rarely if ever necessary to call this command -directly. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm](/commands/npm) -* [npm help](/commands/npm-help) diff --git a/docs/content/commands/npm-help.md b/docs/content/commands/npm-help.md deleted file mode 100644 index 83c595db696b9..0000000000000 --- a/docs/content/commands/npm-help.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: npm-help -section: 1 -description: Get help on npm ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/help.js --> - -```bash -npm help <term> [<terms..>] - -alias: hlep -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/help.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -If supplied a topic, then show the appropriate documentation page. - -If the topic does not exist, or if multiple terms are provided, then npm -will run the `help-search` command to find a match. Note that, if -`help-search` finds a single subject, then it will run `help` on that -topic, so unique matches are equivalent to specifying a topic name. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `viewer` - -* Default: "man" on Posix, "browser" on Windows -* Type: String - -The program to use to view help content. - -Set to `"browser"` to view html help content in the default web browser. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm](/commands/npm) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [package.json](/configuring-npm/package-json) -* [npm help-search](/commands/npm-help-search) diff --git a/docs/content/commands/npm-hook.md b/docs/content/commands/npm-hook.md deleted file mode 100644 index 4a9805d02f9d4..0000000000000 --- a/docs/content/commands/npm-hook.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: npm-hook -section: 1 -description: Manage registry hooks ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/hook.js --> - -```bash -npm hook add <pkg> <url> <secret> [--type=<type>] -npm hook ls [pkg] -npm hook rm <id> -npm hook update <id> <url> <secret> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/hook.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Allows you to manage [npm -hooks](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm), -including adding, removing, listing, and updating. - -Hooks allow you to configure URL endpoints that will be notified whenever a -change happens to any of the supported entity types. Three different types -of entities can be watched by hooks: packages, owners, and scopes. - -To create a package hook, simply reference the package name. - -To create an owner hook, prefix the owner name with `~` (as in, -`~youruser`). - -To create a scope hook, prefix the scope name with `@` (as in, -`@yourscope`). - -The hook `id` used by `update` and `rm` are the IDs listed in `npm hook ls` -for that particular hook. - -The shared secret will be sent along to the URL endpoint so you can verify -the request came from your own configured hook. - -### Example - -Add a hook to watch a package for changes: - -```bash -$ npm hook add lodash https://example.com/ my-shared-secret -``` - -Add a hook to watch packages belonging to the user `substack`: - -```bash -$ npm hook add ~substack https://example.com/ my-shared-secret -``` - -Add a hook to watch packages in the scope `@npm` - -```bash -$ npm hook add @npm https://example.com/ my-shared-secret -``` - -List all your active hooks: - -```bash -$ npm hook ls -``` - -List your active hooks for the `lodash` package: - -```bash -$ npm hook ls lodash -``` - -Update an existing hook's url: - -```bash -$ npm hook update id-deadbeef https://my-new-website.here/ -``` - -Remove a hook: - -```bash -$ npm hook rm id-deadbeef -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* ["Introducing Hooks" blog post](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm) diff --git a/docs/content/commands/npm-init.md b/docs/content/commands/npm-init.md deleted file mode 100644 index f3124a7768dfc..0000000000000 --- a/docs/content/commands/npm-init.md +++ /dev/null @@ -1,327 +0,0 @@ ---- -title: npm-init -section: 1 -description: Create a package.json file ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/init.js --> - -```bash -npm init <package-spec> (same as `npx <package-spec>) -npm init <@scope> (same as `npx <@scope>/create`) - -aliases: create, innit -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/init.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -`npm init <initializer>` can be used to set up a new or existing npm -package. - -`initializer` in this case is an npm package named `create-<initializer>`, -which will be installed by [`npm-exec`](/commands/npm-exec), and then have its -main bin executed -- presumably creating or updating `package.json` and -running any other initialization-related operations. - -The init command is transformed to a corresponding `npm exec` operation as -follows: - -* `npm init foo` -> `npm exec create-foo` -* `npm init @usr/foo` -> `npm exec @usr/create-foo` -* `npm init @usr` -> `npm exec @usr/create` -* `npm init @usr@2.0.0` -> `npm exec @usr/create@2.0.0` -* `npm init @usr/foo@2.0.0` -> `npm exec @usr/create-foo@2.0.0` - -If the initializer is omitted (by just calling `npm init`), init will fall -back to legacy init behavior. It will ask you a bunch of questions, and -then write a package.json for you. It will attempt to make reasonable -guesses based on existing fields, dependencies, and options selected. It is -strictly additive, so it will keep any fields and values that were already -set. You can also use `-y`/`--yes` to skip the questionnaire altogether. If -you pass `--scope`, it will create a scoped package. - -*Note:* if a user already has the `create-<initializer>` package -globally installed, that will be what `npm init` uses. If you want npm -to use the latest version, or another specific version you must specify -it: - -* `npm init foo@latest` # fetches and runs the latest `create-foo` from - the registry -* `npm init foo@1.2.3` # runs `create-foo@1.2.3` specifically - -#### Forwarding additional options - -Any additional options will be passed directly to the command, so `npm init -foo -- --hello` will map to `npm exec -- create-foo --hello`. - -To better illustrate how options are forwarded, here's a more evolved -example showing options passed to both the **npm cli** and a create package, -both following commands are equivalent: - -- `npm init foo -y --registry=<url> -- --hello -a` -- `npm exec -y --registry=<url> -- create-foo --hello -a` - -### Examples - -Create a new React-based project using -[`create-react-app`](https://npm.im/create-react-app): - -```bash -$ npm init react-app ./my-react-app -``` - -Create a new `esm`-compatible package using -[`create-esm`](https://npm.im/create-esm): - -```bash -$ mkdir my-esm-lib && cd my-esm-lib -$ npm init esm --yes -``` - -Generate a plain old package.json using legacy init: - -```bash -$ mkdir my-npm-pkg && cd my-npm-pkg -$ git init -$ npm init -``` - -Generate it without having it ask any questions: - -```bash -$ npm init -y -``` - -### Workspaces support - -It's possible to create a new workspace within your project by using the -`workspace` config option. When using `npm init -w <dir>` the cli will -create the folders and boilerplate expected while also adding a reference -to your project `package.json` `"workspaces": []` property in order to make -sure that new generated **workspace** is properly set up as such. - -Given a project with no workspaces, e.g: - -``` -. -+-- package.json -``` - -You may generate a new workspace using the legacy init: - -```bash -$ npm init -w packages/a -``` - -That will generate a new folder and `package.json` file, while also updating -your top-level `package.json` to add the reference to this new workspace: - -``` -. -+-- package.json -`-- packages - `-- a - `-- package.json -``` - -The workspaces init also supports the `npm init <initializer> -w <dir>` -syntax, following the same set of rules explained earlier in the initial -**Description** section of this page. Similar to the previous example of -creating a new React-based project using -[`create-react-app`](https://npm.im/create-react-app), the following syntax -will make sure to create the new react app as a nested **workspace** within your -project and configure your `package.json` to recognize it as such: - -```bash -npm init -w packages/my-react-app react-app . -``` - -This will make sure to generate your react app as expected, one important -consideration to have in mind is that `npm exec` is going to be run in the -context of the newly created folder for that workspace, and that's the reason -why in this example the initializer uses the initializer name followed with a -dot to represent the current directory in that context, e.g: `react-app .`: - -``` -. -+-- package.json -`-- packages - +-- a - | `-- package.json - `-- my-react-app - +-- README - +-- package.json - `-- ... -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `yes` - -* Default: null -* Type: null or Boolean - -Automatically answer "yes" to any prompts that npm might print on the -command line. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `force` - -* Default: false -* Type: Boolean - -Removes various protections against unfortunate side effects, common -mistakes, unnecessary performance degradation, and malicious input. - -* Allow clobbering non-npm files in global installs. -* Allow the `npm version` command to work on an unclean git repository. -* Allow deleting the cache folder with `npm cache clean`. -* Allow installing packages that have an `engines` declaration requiring a - different version of npm. -* Allow installing packages that have an `engines` declaration requiring a - different version of `node`, even if `--engine-strict` is enabled. -* Allow `npm audit fix` to install modules outside your stated dependency - range (including SemVer-major changes). -* Allow unpublishing all versions of a published package. -* Allow conflicting peerDependencies to be installed in the root project. -* Implicitly set `--yes` during `npm init`. -* Allow clobbering existing values in `npm pkg` -* Allow unpublishing of entire packages (not just a single version). - -If you don't have a clear idea of what you want to do, it is strongly -recommended that you do not use this option! - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `scope` - -* Default: the scope of the current project, if any, or "" -* Type: String - -Associate an operation with a scope for a scoped registry. - -Useful when logging in to or out of a private registry: - -``` -# log in, linking the scope to the custom registry -npm login --scope=@mycorp --registry=https://registry.mycorp.com - -# log out, removing the link and the auth token -npm logout --scope=@mycorp -``` - -This will cause `@mycorp` to be mapped to the registry for future -installation of packages specified according to the pattern -`@mycorp/package`. - -This will also cause `npm init` to create a scoped package. - -``` -# accept all defaults, and create a package named "@foo/whatever", -# instead of just named "whatever" -npm init --scope=@foo --yes -``` - - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces-update` - -* Default: true -* Type: Boolean - -If set to true, the npm cli will run an update after operations that may -possibly change the workspaces installed to the `node_modules` folder. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [init-package-json module](http://npm.im/init-package-json) -* [package.json](/configuring-npm/package-json) -* [npm version](/commands/npm-version) -* [npm scope](/using-npm/scope) -* [npm exec](/commands/npm-exec) -* [npm workspaces](/using-npm/workspaces) diff --git a/docs/content/commands/npm-install-ci-test.md b/docs/content/commands/npm-install-ci-test.md deleted file mode 100644 index b886f8ab9599a..0000000000000 --- a/docs/content/commands/npm-install-ci-test.md +++ /dev/null @@ -1,326 +0,0 @@ ---- -title: npm-install-ci-test -section: 1 -description: Install a project with a clean slate and run tests ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/install-ci-test.js --> - -```bash -npm install-ci-test - -alias: cit -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/install-ci-test.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command runs `npm ci` followed immediately by `npm test`. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-exact` - -* Default: false -* Type: Boolean - -Dependencies saved to package.json will be configured with an exact version -rather than using npm's default semver range operator. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm install-test](/commands/npm-install-test) -* [npm ci](/commands/npm-ci) -* [npm test](/commands/npm-test) diff --git a/docs/content/commands/npm-install-test.md b/docs/content/commands/npm-install-test.md deleted file mode 100644 index d27686e731ce1..0000000000000 --- a/docs/content/commands/npm-install-test.md +++ /dev/null @@ -1,327 +0,0 @@ ---- -title: npm-install-test -section: 1 -description: Install package(s) and run tests ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/install-test.js --> - -```bash -npm install-test [<package-spec> ...] - -alias: it -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/install-test.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command runs an `npm install` followed immediately by an `npm test`. It -takes exactly the same arguments as `npm install`. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-exact` - -* Default: false -* Type: Boolean - -Dependencies saved to package.json will be configured with an exact version -rather than using npm's default semver range operator. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm install](/commands/npm-install) -* [npm install-ci-test](/commands/npm-install-ci-test) -* [npm test](/commands/npm-test) diff --git a/docs/content/commands/npm-install.md b/docs/content/commands/npm-install.md deleted file mode 100644 index d6ae4324ecefc..0000000000000 --- a/docs/content/commands/npm-install.md +++ /dev/null @@ -1,763 +0,0 @@ ---- -title: npm-install -section: 1 -description: Install a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/install.js --> - -```bash -npm install [<package-spec> ...] - -aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/install.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command installs a package and any packages that it depends on. If the -package has a package-lock, or an npm shrinkwrap file, or a yarn lock file, -the installation of dependencies will be driven by that, respecting the -following order of precedence: - -* `npm-shrinkwrap.json` -* `package-lock.json` -* `yarn.lock` - -See [package-lock.json](/configuring-npm/package-lock-json) and -[`npm shrinkwrap`](/commands/npm-shrinkwrap). - -A `package` is: - -* a) a folder containing a program described by a - [`package.json`](/configuring-npm/package-json) file -* b) a gzipped tarball containing (a) -* c) a url that resolves to (b) -* d) a `<name>@<version>` that is published on the registry (see - [`registry`](/using-npm/registry)) with (c) -* e) a `<name>@<tag>` (see [`npm dist-tag`](/commands/npm-dist-tag)) that - points to (d) -* f) a `<name>` that has a "latest" tag satisfying (e) -* g) a `<git remote url>` that resolves to (a) - -Even if you never publish your package, you can still get a lot of benefits -of using npm if you just want to write a node program (a), and perhaps if -you also want to be able to easily install it elsewhere after packing it up -into a tarball (b). - - -* `npm install` (in a package directory, no arguments): - - Install the dependencies to the local `node_modules` folder. - - In global mode (ie, with `-g` or `--global` appended to the command), - it installs the current package context (ie, the current working - directory) as a global package. - - By default, `npm install` will install all modules listed as - dependencies in [`package.json`](/configuring-npm/package-json). - - With the `--production` flag (or when the `NODE_ENV` environment - variable is set to `production`), npm will not install modules listed - in `devDependencies`. To install all modules listed in both - `dependencies` and `devDependencies` when `NODE_ENV` environment - variable is set to `production`, you can use `--production=false`. - - > NOTE: The `--production` flag has no particular meaning when adding a - dependency to a project. - -* `npm install <folder>`: - - If `<folder>` sits inside the root of your project, its dependencies will be installed and may - be hoisted to the top-level `node_modules` as they would for other - types of dependencies. If `<folder>` sits outside the root of your project, - *npm will not install the package dependencies* in the directory `<folder>`, - but it will create a symlink to `<folder>`. - - > NOTE: If you want to install the content of a directory like a package from the registry instead of creating a link, you would need to use the `--install-links` option. - - Example: - - ```bash - npm install ../../other-package --install-links - npm install ./sub-package - ``` - -* `npm install <tarball file>`: - - Install a package that is sitting on the filesystem. Note: if you just - want to link a dev directory into your npm root, you can do this more - easily by using [`npm link`](/commands/npm-link). - - Tarball requirements: - * The filename *must* use `.tar`, `.tar.gz`, or `.tgz` as the - extension. - * The package contents should reside in a subfolder inside the tarball - (usually it is called `package/`). npm strips one directory layer - when installing the package (an equivalent of `tar x - --strip-components=1` is run). - * The package must contain a `package.json` file with `name` and - `version` properties. - - Example: - - ```bash - npm install ./package.tgz - ``` - -* `npm install <tarball url>`: - - Fetch the tarball url, and then install it. In order to distinguish between - this and other options, the argument must start with "http://" or "https://" - - Example: - - ```bash - npm install https://github.com/indexzero/forever/tarball/v0.5.6 - ``` - -* `npm install [<@scope>/]<name>`: - - Do a `<name>@<tag>` install, where `<tag>` is the "tag" config. (See - [`config`](/using-npm/config). The config's default value is `latest`.) - - In most cases, this will install the version of the modules tagged as - `latest` on the npm registry. - - Example: - - ```bash - npm install sax - ``` - - `npm install` saves any specified packages into `dependencies` by default. - Additionally, you can control where and how they get saved with some - additional flags: - - * `-P, --save-prod`: Package will appear in your `dependencies`. This - is the default unless `-D` or `-O` are present. - - * `-D, --save-dev`: Package will appear in your `devDependencies`. - - * `-O, --save-optional`: Package will appear in your - `optionalDependencies`. - - * `--no-save`: Prevents saving to `dependencies`. - - When using any of the above options to save dependencies to your - package.json, there are two additional, optional flags: - - * `-E, --save-exact`: Saved dependencies will be configured with an - exact version rather than using npm's default semver range operator. - - * `-B, --save-bundle`: Saved dependencies will also be added to your - `bundleDependencies` list. - - Further, if you have an `npm-shrinkwrap.json` or `package-lock.json` - then it will be updated as well. - - `<scope>` is optional. The package will be downloaded from the registry - associated with the specified scope. If no registry is associated with - the given scope the default registry is assumed. See - [`scope`](/using-npm/scope). - - Note: if you do not include the @-symbol on your scope name, npm will - interpret this as a GitHub repository instead, see below. Scopes names - must also be followed by a slash. - - Examples: - - ```bash - npm install sax - npm install githubname/reponame - npm install @myorg/privatepackage - npm install node-tap --save-dev - npm install dtrace-provider --save-optional - npm install readable-stream --save-exact - npm install ansi-regex --save-bundle - ``` - - **Note**: If there is a file or folder named `<name>` in the current - working directory, then it will try to install that, and only try to - fetch the package by name if it is not valid. - -* `npm install <alias>@npm:<name>`: - - Install a package under a custom alias. Allows multiple versions of - a same-name package side-by-side, more convenient import names for - packages with otherwise long ones, and using git forks replacements - or forked npm packages as replacements. Aliasing works only on your - project and does not rename packages in transitive dependencies. - Aliases should follow the naming conventions stated in - [`validate-npm-package-name`](https://www.npmjs.com/package/validate-npm-package-name#naming-rules). - - Examples: - - ```bash - npm install my-react@npm:react - npm install jquery2@npm:jquery@2 - npm install jquery3@npm:jquery@3 - npm install npa@npm:npm-package-arg - ``` - -* `npm install [<@scope>/]<name>@<tag>`: - - Install the version of the package that is referenced by the specified tag. - If the tag does not exist in the registry data for that package, then this - will fail. - - Example: - - ```bash - npm install sax@latest - npm install @myorg/mypackage@latest - ``` - -* `npm install [<@scope>/]<name>@<version>`: - - Install the specified version of the package. This will fail if the - version has not been published to the registry. - - Example: - - ```bash - npm install sax@0.1.1 - npm install @myorg/privatepackage@1.5.0 - ``` - -* `npm install [<@scope>/]<name>@<version range>`: - - Install a version of the package matching the specified version range. - This will follow the same rules for resolving dependencies described in - [`package.json`](/configuring-npm/package-json). - - Note that most version ranges must be put in quotes so that your shell - will treat it as a single argument. - - Example: - - ```bash - npm install sax@">=0.1.0 <0.2.0" - npm install @myorg/privatepackage@"16 - 17" - ``` - -* `npm install <git remote url>`: - - Installs the package from the hosted git provider, cloning it with - `git`. For a full git remote url, only that URL will be attempted. - - ```bash - <protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>] - ``` - - `<protocol>` is one of `git`, `git+ssh`, `git+http`, `git+https`, or - `git+file`. - - If `#<commit-ish>` is provided, it will be used to clone exactly that - commit. If the commit-ish has the format `#semver:<semver>`, `<semver>` - can be any valid semver range or exact version, and npm will look for - any tags or refs matching that range in the remote repository, much as - it would for a registry dependency. If neither `#<commit-ish>` or - `#semver:<semver>` is specified, then the default branch of the - repository is used. - - If the repository makes use of submodules, those submodules will be - cloned as well. - - If the package being installed contains a `prepare` script, its - `dependencies` and `devDependencies` will be installed, and the prepare - script will be run, before the package is packaged and installed. - - The following git environment variables are recognized by npm and will - be added to the environment when running git: - - * `GIT_ASKPASS` - * `GIT_EXEC_PATH` - * `GIT_PROXY_COMMAND` - * `GIT_SSH` - * `GIT_SSH_COMMAND` - * `GIT_SSL_CAINFO` - * `GIT_SSL_NO_VERIFY` - - See the git man page for details. - - Examples: - - ```bash - npm install git+ssh://git@github.com:npm/cli.git#v1.0.27 - npm install git+ssh://git@github.com:npm/cli#pull/273 - npm install git+ssh://git@github.com:npm/cli#semver:^5.0 - npm install git+https://isaacs@github.com/npm/cli.git - npm install git://github.com/npm/cli.git#v1.0.27 - GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident' npm install git+ssh://git@github.com:npm/cli.git - ``` - -* `npm install <githubname>/<githubrepo>[#<commit-ish>]`: -* `npm install github:<githubname>/<githubrepo>[#<commit-ish>]`: - - Install the package at `https://github.com/githubname/githubrepo` by - attempting to clone it using `git`. - - If `#<commit-ish>` is provided, it will be used to clone exactly that - commit. If the commit-ish has the format `#semver:<semver>`, `<semver>` - can be any valid semver range or exact version, and npm will look for - any tags or refs matching that range in the remote repository, much as - it would for a registry dependency. If neither `#<commit-ish>` or - `#semver:<semver>` is specified, then the default branch is used. - - As with regular git dependencies, `dependencies` and `devDependencies` - will be installed if the package has a `prepare` script before the - package is done installing. - - Examples: - - ```bash - npm install mygithubuser/myproject - npm install github:mygithubuser/myproject - ``` - -* `npm install gist:[<githubname>/]<gistID>[#<commit-ish>|#semver:<semver>]`: - - Install the package at `https://gist.github.com/gistID` by attempting to - clone it using `git`. The GitHub username associated with the gist is - optional and will not be saved in `package.json`. - - As with regular git dependencies, `dependencies` and `devDependencies` will - be installed if the package has a `prepare` script before the package is - done installing. - - Example: - - ```bash - npm install gist:101a11beef - ``` - -* `npm install bitbucket:<bitbucketname>/<bitbucketrepo>[#<commit-ish>]`: - - Install the package at `https://bitbucket.org/bitbucketname/bitbucketrepo` - by attempting to clone it using `git`. - - If `#<commit-ish>` is provided, it will be used to clone exactly that - commit. If the commit-ish has the format `#semver:<semver>`, `<semver>` can - be any valid semver range or exact version, and npm will look for any tags - or refs matching that range in the remote repository, much as it would for a - registry dependency. If neither `#<commit-ish>` or `#semver:<semver>` is - specified, then `master` is used. - - As with regular git dependencies, `dependencies` and `devDependencies` will - be installed if the package has a `prepare` script before the package is - done installing. - - Example: - - ```bash - npm install bitbucket:mybitbucketuser/myproject - ``` - -* `npm install gitlab:<gitlabname>/<gitlabrepo>[#<commit-ish>]`: - - Install the package at `https://gitlab.com/gitlabname/gitlabrepo` - by attempting to clone it using `git`. - - If `#<commit-ish>` is provided, it will be used to clone exactly that - commit. If the commit-ish has the format `#semver:<semver>`, `<semver>` can - be any valid semver range or exact version, and npm will look for any tags - or refs matching that range in the remote repository, much as it would for a - registry dependency. If neither `#<commit-ish>` or `#semver:<semver>` is - specified, then `master` is used. - - As with regular git dependencies, `dependencies` and `devDependencies` will - be installed if the package has a `prepare` script before the package is - done installing. - - Example: - - ```bash - npm install gitlab:mygitlabuser/myproject - npm install gitlab:myusr/myproj#semver:^5.0 - ``` - -You may combine multiple arguments and even multiple types of arguments. -For example: - -```bash -npm install sax@">=0.1.0 <0.2.0" bench supervisor -``` - -The `--tag` argument will apply to all of the specified install targets. If -a tag with the given name exists, the tagged version is preferred over -newer versions. - -The `--dry-run` argument will report in the usual way what the install -would have done without actually installing anything. - -The `--package-lock-only` argument will only update the -`package-lock.json`, instead of checking `node_modules` and downloading -dependencies. - -The `-f` or `--force` argument will force npm to fetch remote resources -even if a local copy exists on disk. - -```bash -npm install sax --force -``` - -### Configuration - -See the [`config`](/using-npm/config) help doc. Many of the configuration -params have some effect on installation, since that's most of what npm -does. - -These are some of the most common options related to installation. - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-exact` - -* Default: false -* Type: Boolean - -Dependencies saved to package.json will be configured with an exact version -rather than using npm's default semver range operator. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### Algorithm - -Given a `package{dep}` structure: `A{B,C}, B{C}, C{D}`, -the npm install algorithm produces: - -```bash -A -+-- B -+-- C -+-- D -``` - -That is, the dependency from B to C is satisfied by the fact that A already -caused C to be installed at a higher level. D is still installed at the top -level because nothing conflicts with it. - -For `A{B,C}, B{C,D@1}, C{D@2}`, this algorithm produces: - -```bash -A -+-- B -+-- C - `-- D@2 -+-- D@1 -``` - -Because B's D@1 will be installed in the top-level, C now has to install -D@2 privately for itself. This algorithm is deterministic, but different -trees may be produced if two dependencies are requested for installation in -a different order. - -See [folders](/configuring-npm/folders) for a more detailed description of -the specific folder structures that npm creates. - -### See Also - -* [npm folders](/configuring-npm/folders) -* [npm update](/commands/npm-update) -* [npm audit](/commands/npm-audit) -* [npm fund](/commands/npm-fund) -* [npm link](/commands/npm-link) -* [npm rebuild](/commands/npm-rebuild) -* [npm scripts](/using-npm/scripts) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm registry](/using-npm/registry) -* [npm dist-tag](/commands/npm-dist-tag) -* [npm uninstall](/commands/npm-uninstall) -* [npm shrinkwrap](/commands/npm-shrinkwrap) -* [package.json](/configuring-npm/package-json) -* [workspaces](/using-npm/workspaces) diff --git a/docs/content/commands/npm-link.md b/docs/content/commands/npm-link.md deleted file mode 100644 index 8c1b422493bd5..0000000000000 --- a/docs/content/commands/npm-link.md +++ /dev/null @@ -1,407 +0,0 @@ ---- -title: npm-link -section: 1 -description: Symlink a package folder ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/link.js --> - -```bash -npm link [<package-spec>] - -alias: ln -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/link.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This is handy for installing your own stuff, so that you can work on it and -test iteratively without having to continually rebuild. - -Package linking is a two-step process. - -First, `npm link` in a package folder with no arguments will create a -symlink in the global folder `{prefix}/lib/node_modules/<package>` that -links to the package where the `npm link` command was executed. It will -also link any bins in the package to `{prefix}/bin/{name}`. Note that -`npm link` uses the global prefix (see `npm prefix -g` for its value). - -Next, in some other location, `npm link package-name` will create a -symbolic link from globally-installed `package-name` to `node_modules/` of -the current folder. - -Note that `package-name` is taken from `package.json`, _not_ from the -directory name. - -The package name can be optionally prefixed with a scope. See -[`scope`](/using-npm/scope). The scope must be preceded by an @-symbol and -followed by a slash. - -When creating tarballs for `npm publish`, the linked packages are -"snapshotted" to their current state by resolving the symbolic links, if -they are included in `bundleDependencies`. - -For example: - -```bash -cd ~/projects/node-redis # go into the package directory -npm link # creates global link -cd ~/projects/node-bloggy # go into some other package directory. -npm link redis # link-install the package -``` - -Now, any changes to `~/projects/node-redis` will be reflected in -`~/projects/node-bloggy/node_modules/node-redis/`. Note that the link -should be to the package name, not the directory name for that package. - -You may also shortcut the two steps in one. For example, to do the -above use-case in a shorter way: - -```bash -cd ~/projects/node-bloggy # go into the dir of your main project -npm link ../node-redis # link the dir of your dependency -``` - -The second line is the equivalent of doing: - -```bash -(cd ../node-redis; npm link) -npm link redis -``` - -That is, it first creates a global link, and then links the global -installation target into your project's `node_modules` folder. - -Note that in this case, you are referring to the directory name, -`node-redis`, rather than the package name `redis`. - -If your linked package is scoped (see [`scope`](/using-npm/scope)) your -link command must include that scope, e.g. - -```bash -npm link @myorg/privatepackage -``` - -### Caveat - -Note that package dependencies linked in this way are _not_ saved to -`package.json` by default, on the assumption that the intention is to have -a link stand in for a regular non-link dependency. Otherwise, for example, -if you depend on `redis@^3.0.1`, and ran `npm link redis`, it would replace -the `^3.0.1` dependency with `file:../path/to/node-redis`, which you -probably don't want! Additionally, other users or developers on your -project would run into issues if they do not have their folders set up -exactly the same as yours. - -If you are adding a _new_ dependency as a link, you should add it to the -relevant metadata by running `npm install <dep> --package-lock-only`. - -If you _want_ to save the `file:` reference in your `package.json` and -`package-lock.json` files, you can use `npm link <dep> --save` to do so. - -### Workspace Usage - -`npm link <pkg> --workspace <name>` will link the relevant package as a -dependency of the specified workspace(s). Note that It may actually be -linked into the parent project's `node_modules` folder, if there are no -conflicting dependencies. - -`npm link --workspace <name>` will create a global link to the specified -workspace(s). - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-exact` - -* Default: false -* Type: Boolean - -Dependencies saved to package.json will be configured with an exact version -rather than using npm's default semver range operator. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm developers](/using-npm/developers) -* [package.json](/configuring-npm/package-json) -* [npm install](/commands/npm-install) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-logout.md b/docs/content/commands/npm-logout.md deleted file mode 100644 index f0dd5cb856eae..0000000000000 --- a/docs/content/commands/npm-logout.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: npm-logout -section: 1 -description: Log out of the registry ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/logout.js --> - -```bash -npm logout -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/logout.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -When logged into a registry that supports token-based authentication, tell -the server to end this token's session. This will invalidate the token -everywhere you're using it, not just for the current environment. - -When logged into a legacy registry that uses username and password -authentication, this will clear the credentials in your user configuration. -In this case, it will _only_ affect the current environment. - -If `--scope` is provided, this will find the credentials for the registry -connected to that scope, if set. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `scope` - -* Default: the scope of the current project, if any, or "" -* Type: String - -Associate an operation with a scope for a scoped registry. - -Useful when logging in to or out of a private registry: - -``` -# log in, linking the scope to the custom registry -npm login --scope=@mycorp --registry=https://registry.mycorp.com - -# log out, removing the link and the auth token -npm logout --scope=@mycorp -``` - -This will cause `@mycorp` to be mapped to the registry for future -installation of packages specified according to the pattern -`@mycorp/package`. - -This will also cause `npm init` to create a scoped package. - -``` -# accept all defaults, and create a package named "@foo/whatever", -# instead of just named "whatever" -npm init --scope=@foo --yes -``` - - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm adduser](/commands/npm-adduser) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npm whoami](/commands/npm-whoami) diff --git a/docs/content/commands/npm-ls.md b/docs/content/commands/npm-ls.md deleted file mode 100644 index a7936fafc72a2..0000000000000 --- a/docs/content/commands/npm-ls.md +++ /dev/null @@ -1,314 +0,0 @@ ---- -title: npm-ls -section: 1 -description: List installed packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/ls.js --> - -```bash -npm ls <package-spec> - -alias: list -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/ls.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command will print to stdout all the versions of packages that are -installed, as well as their dependencies when `--all` is specified, in a -tree structure. - -Note: to get a "bottoms up" view of why a given package is included in the -tree at all, use [`npm explain`](/commands/npm-explain). - -Positional arguments are `name@version-range` identifiers, which will limit -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: - -```bash -npm@@VERSION@ /path/to/npm -└─┬ init-package-json@0.0.4 - └── promzard@0.1.5 -``` - -It will print out extraneous, missing, and invalid packages. - -If a project specifies git urls for dependencies these are shown -in parentheses after the `name@version` to make it easier for users to -recognize potential forks of a project. - -The tree shown is the logical dependency tree, based on package -dependencies, not the physical layout of your `node_modules` folder. - -When run as `ll` or `la`, it shows extended information by default. - -### Note: Design Changes Pending - -The `npm ls` command's output and behavior made a _ton_ of sense when npm -created a `node_modules` folder that naively nested every dependency. In -such a case, the logical dependency graph and physical tree of packages on -disk would be roughly identical. - -With the advent of automatic install-time deduplication of dependencies in -npm v3, the `ls` output was modified to display the logical dependency -graph as a tree structure, since this was more useful to most users. -However, without using `npm ls -l`, it became impossible to show _where_ a -package was actually installed much of the time! - -With the advent of automatic installation of `peerDependencies` in npm v7, -this gets even more curious, as `peerDependencies` are logically -"underneath" their dependents in the dependency graph, but are always -physically at or above their location on disk. - -Also, in the years since npm got an `ls` command (in version 0.0.2!), -dependency graphs have gotten much larger as a general rule. Therefore, in -order to avoid dumping an excessive amount of content to the terminal, `npm -ls` now only shows the _top_ level dependencies, unless `--all` is -provided. - -A thorough re-examination of the use cases, intention, behavior, and output -of this command, is currently underway. Expect significant changes to at -least the default human-readable `npm ls` output in npm v8. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `all` - -* Default: false -* Type: Boolean - -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `depth` - -* Default: `Infinity` if `--all` is set, otherwise `1` -* Type: null or Number - -The depth to go when recursing packages for `npm ls`. - -If not set, `npm ls` will show only the immediate dependencies of the root -project. If `--all` is set, then npm will show all dependencies by default. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `link` - -* Default: false -* Type: Boolean - -Used with `npm ls`, limiting output to only those packages that are linked. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock-only` - -* Default: false -* Type: Boolean - -If set to true, the current operation will only use the `package-lock.json`, -ignoring `node_modules`. - -For `update` this means only the `package-lock.json` will be updated, -instead of checking `node_modules` and downloading dependencies. - -For `list` this means the output will be based on the tree described by the -`package-lock.json`, rather than the contents of `node_modules`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `unicode` - -* Default: false on windows, true on mac/unix systems with a unicode locale, - as defined by the `LC_ALL`, `LC_CTYPE`, or `LANG` environment variables. -* Type: Boolean - -When set to true, npm uses unicode characters in the tree output. When -false, it uses ascii characters instead of unicode glyphs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm explain](/commands/npm-explain) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm folders](/configuring-npm/folders) -* [npm explain](/commands/npm-explain) -* [npm install](/commands/npm-install) -* [npm link](/commands/npm-link) -* [npm prune](/commands/npm-prune) -* [npm outdated](/commands/npm-outdated) -* [npm update](/commands/npm-update) diff --git a/docs/content/commands/npm-org.md b/docs/content/commands/npm-org.md deleted file mode 100644 index 975581c860df6..0000000000000 --- a/docs/content/commands/npm-org.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: npm-org -section: 1 -description: Manage orgs ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/org.js --> - -```bash -npm org set orgname username [developer | admin | owner] -npm org rm orgname username -npm org ls orgname [<username>] - -alias: ogr -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/org.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Example - -Add a new developer to an org: - -```bash -$ npm org set my-org @mx-smith -``` - -Add a new admin to an org (or change a developer to an admin): - -```bash -$ npm org set my-org @mx-santos admin -``` - -Remove a user from an org: - -```bash -$ npm org rm my-org mx-santos -``` - -List all users in an org: - -```bash -$ npm org ls my-org -``` - -List all users in JSON format: - -```bash -$ npm org ls my-org --json -``` - -See what role a user has in an org: - -```bash -$ npm org ls my-org @mx-santos -``` - -### Description - -You can use the `npm org` commands to manage and view users of an -organization. It supports adding and removing users, changing their roles, -listing them, and finding specific ones and their roles. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [using orgs](/using-npm/orgs) -* [Documentation on npm Orgs](https://docs.npmjs.com/orgs/) diff --git a/docs/content/commands/npm-outdated.md b/docs/content/commands/npm-outdated.md deleted file mode 100644 index c4e07a0cd36f0..0000000000000 --- a/docs/content/commands/npm-outdated.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -title: npm-outdated -section: 1 -description: Check for outdated packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/outdated.js --> - -```bash -npm outdated [<package-spec> ...] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/outdated.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command will check the registry to see if any (or, specific) installed -packages are currently outdated. - -By default, only the direct dependencies of the root project and direct -dependencies of your configured *workspaces* are shown. -Use `--all` to find all outdated meta-dependencies as well. - -In the output: - -* `wanted` is the maximum version of the package that satisfies the semver - range specified in `package.json`. If there's no available semver range - (i.e. you're running `npm outdated --global`, or the package isn't - included in `package.json`), then `wanted` shows the currently-installed - version. -* `latest` is the version of the package tagged as latest in the registry. - Running `npm publish` with no special configuration will publish the - package with a dist-tag of `latest`. This may or may not be the maximum - version of the package, or the most-recently published version of the - package, depending on how the package's developer manages the latest - [dist-tag](/commands/npm-dist-tag). -* `location` is where in the physical tree the package is located. -* `depended by` shows which package depends on the displayed dependency -* `package type` (when using `--long` / `-l`) tells you whether this - package is a `dependency` or a dev/peer/optional dependency. Packages not - included in `package.json` are always marked `dependencies`. -* `homepage` (when using `--long` / `-l`) is the `homepage` value contained - in the package's packument -* Red means there's a newer version matching your semver requirements, so - you should update now. -* Yellow indicates that there's a newer version _above_ your semver - requirements (usually new major, or new 0.x minor) so proceed with - caution. - -### An example - -```bash -$ npm outdated -Package Current Wanted Latest Location Depended by -glob 5.0.15 5.0.15 6.0.1 node_modules/glob dependent-package-name -nothingness 0.0.3 git git node_modules/nothingness dependent-package-name -npm 3.5.1 3.5.2 3.5.1 node_modules/npm dependent-package-name -local-dev 0.0.3 linked linked local-dev dependent-package-name -once 1.3.2 1.3.3 1.3.3 node_modules/once dependent-package-name -``` - -With these `dependencies`: -```json -{ - "glob": "^5.0.15", - "nothingness": "github:othiym23/nothingness#master", - "npm": "^3.5.1", - "once": "^1.3.1" -} -``` - -A few things to note: - -* `glob` requires `^5`, which prevents npm from installing `glob@6`, which - is outside the semver range. -* Git dependencies will always be reinstalled, because of how they're - specified. The installed committish might satisfy the dependency - specifier (if it's something immutable, like a commit SHA), or it might - not, so `npm outdated` and `npm update` have to fetch Git repos to check. - This is why currently doing a reinstall of a Git dependency always forces - a new clone and install. -* `npm@3.5.2` is marked as "wanted", but "latest" is `npm@3.5.1` because - npm uses dist-tags to manage its `latest` and `next` release channels. - `npm update` will install the _newest_ version, but `npm install npm` - (with no semver range) will install whatever's tagged as `latest`. -* `once` is just plain out of date. Reinstalling `node_modules` from - scratch or running `npm update` will bring it up to spec. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `all` - -* Default: false -* Type: Boolean - -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm update](/commands/npm-update) -* [npm dist-tag](/commands/npm-dist-tag) -* [npm registry](/using-npm/registry) -* [npm folders](/configuring-npm/folders) -* [npm workspaces](/using-npm/workspaces) diff --git a/docs/content/commands/npm-owner.md b/docs/content/commands/npm-owner.md deleted file mode 100644 index ebc29ef693939..0000000000000 --- a/docs/content/commands/npm-owner.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: npm-owner -section: 1 -description: Manage package owners ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/owner.js --> - -```bash -npm owner add <user> <package-spec> -npm owner rm <user> <package-spec> -npm owner ls <package-spec> - -alias: author -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/owner.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Manage ownership of published packages. - -* ls: List all the users who have access to modify a package and push new - versions. Handy when you need to know who to bug for help. -* add: Add a new user as a maintainer of a package. This user is enabled - to modify metadata, publish new versions, and add other owners. -* rm: Remove a user from the package owner list. This immediately revokes - their privileges. - -Note that there is only one level of access. Either you can modify a package, -or you can't. Future versions may contain more fine-grained access levels, but -that is not implemented at this time. - -If you have two-factor authentication enabled with `auth-and-writes` (see -[`npm-profile`](/commands/npm-profile)) then you'll need to include an otp -on the command line when changing ownership with `--otp`. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm profile](/commands/npm-profile) -* [npm publish](/commands/npm-publish) -* [npm registry](/using-npm/registry) -* [npm adduser](/commands/npm-adduser) diff --git a/docs/content/commands/npm-pack.md b/docs/content/commands/npm-pack.md deleted file mode 100644 index 7921042eae8fe..0000000000000 --- a/docs/content/commands/npm-pack.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: npm-pack -section: 1 -description: Create a tarball from a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/pack.js --> - -```bash -npm pack <package-spec> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/pack.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `pack-destination` - -* Default: "." -* Type: String - -Directory in which `npm pack` will save tarballs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### Description - -For anything that's installable (that is, a package folder, tarball, -tarball url, git url, name@tag, name@version, name, or scoped name), this -command will fetch it to the cache, copy the tarball to the current working -directory as `<name>-<version>.tgz`, and then write the filenames out to -stdout. - -If the same package is specified multiple times, then the file will be -overwritten the second time. - -If no arguments are supplied, then npm packs the current package folder. - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm-packlist package](http://npm.im/npm-packlist) -* [npm cache](/commands/npm-cache) -* [npm publish](/commands/npm-publish) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-ping.md b/docs/content/commands/npm-ping.md deleted file mode 100644 index 161d7292f8c97..0000000000000 --- a/docs/content/commands/npm-ping.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: npm-ping -section: 1 -description: Ping npm registry ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/ping.js --> - -```bash -npm ping -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/ping.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Ping the configured or given npm registry and verify authentication. -If it works it will output something like: - -```bash -npm notice PING https://registry.npmjs.org/ -npm notice PONG 255ms -``` -otherwise you will get an error: -```bash -npm notice PING http://foo.com/ -npm ERR! code E404 -npm ERR! 404 Not Found - GET http://www.foo.com/-/ping?write=true -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm doctor](/commands/npm-doctor) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-pkg.md b/docs/content/commands/npm-pkg.md deleted file mode 100644 index deff7e82c694d..0000000000000 --- a/docs/content/commands/npm-pkg.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: npm-pkg -section: 1 -description: Manages your package.json ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/pkg.js --> - -```bash -npm pkg set <key>=<value> [<key>=<value> ...] -npm pkg get [<key> [<key> ...]] -npm pkg delete <key> [<key> ...] -npm pkg set [<array>[<index>].<key>=<value> ...] -npm pkg set [<array>[].<key>=<value> ...] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/pkg.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -A command that automates the management of `package.json` files. -`npm pkg` provide 3 different sub commands that allow you to modify or retrieve -values for given object keys in your `package.json`. - -The syntax to retrieve and set fields is a dot separated representation of -the nested object properties to be found within your `package.json`, it's the -same notation used in [`npm view`](/commands/npm-view) to retrieve information -from the registry manifest, below you can find more examples on how to use it. - -Returned values are always in **json** format. - -* `npm pkg get <field>` - - Retrieves a value `key`, defined in your `package.json` file. - - For example, in order to retrieve the name of the current package, you - can run: - - ```bash - npm pkg get name - ``` - - It's also possible to retrieve multiple values at once: - - ```bash - npm pkg get name version - ``` - - You can view child fields by separating them with a period. To retrieve - the value of a test `script` value, you would run the following command: - - ```bash - npm pkg get scripts.test - ``` - - For fields that are arrays, requesting a non-numeric field will return - all of the values from the objects in the list. For example, to get all - the contributor emails for a package, you would run: - - ```bash - npm pkg get contributors.email - ``` - - You may also use numeric indices in square braces to specifically select - an item in an array field. To just get the email address of the first - contributor in the list, you can run: - - ```bash - npm pkg get contributors[0].email - ``` - - For complex fields you can also name a property in square brackets - to specifically select a child field. This is especially helpful - with the exports object: - - ```bash - npm pkg get "exports[.].require" - ``` - -* `npm pkg set <field>=<value>` - - Sets a `value` in your `package.json` based on the `field` value. When - saving to your `package.json` file the same set of rules used during - `npm install` and other cli commands that touches the `package.json` file - are used, making sure to respect the existing indentation and possibly - applying some validation prior to saving values to the file. - - The same syntax used to retrieve values from your package can also be used - to define new properties or overriding existing ones, below are some - examples of how the dot separated syntax can be used to edit your - `package.json` file. - - Defining a new bin named `mynewcommand` in your `package.json` that points - to a file `cli.js`: - - ```bash - npm pkg set bin.mynewcommand=cli.js - ``` - - Setting multiple fields at once is also possible: - - ```bash - npm pkg set description='Awesome package' engines.node='>=10' - ``` - - It's also possible to add to array values, for example to add a new - contributor entry: - - ```bash - npm pkg set contributors[0].name='Foo' contributors[0].email='foo@bar.ca' - ``` - - You may also append items to the end of an array using the special - empty bracket notation: - - ```bash - npm pkg set contributors[].name='Foo' contributors[].name='Bar' - ``` - - It's also possible to parse values as json prior to saving them to your - `package.json` file, for example in order to set a `"private": true` - property: - - ```bash - npm pkg set private=true --json - ``` - - It also enables saving values as numbers: - - ```bash - npm pkg set tap.timeout=60 --json - ``` - -* `npm pkg delete <key>` - - Deletes a `key` from your `package.json` - - The same syntax used to set values from your package can also be used - to remove existing ones. For example, in order to remove a script named - build: - - ```bash - npm pkg delete scripts.build - ``` - -### Workspaces support - -You can set/get/delete items across your configured workspaces by using the -`workspace` or `workspaces` config options. - -For example, setting a `funding` value across all configured workspaces -of a project: - -```bash -npm pkg set funding=https://example.com --ws -``` - -When using `npm pkg get` to retrieve info from your configured workspaces, the -returned result will be in a json format in which top level keys are the -names of each workspace, the values of these keys will be the result values -returned from each of the configured workspaces, e.g: - -``` -npm pkg get name version --ws -{ - "a": { - "name": "a", - "version": "1.0.0" - }, - "b": { - "name": "b", - "version": "1.0.0" - } -} -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `force` - -* Default: false -* Type: Boolean - -Removes various protections against unfortunate side effects, common -mistakes, unnecessary performance degradation, and malicious input. - -* Allow clobbering non-npm files in global installs. -* Allow the `npm version` command to work on an unclean git repository. -* Allow deleting the cache folder with `npm cache clean`. -* Allow installing packages that have an `engines` declaration requiring a - different version of npm. -* Allow installing packages that have an `engines` declaration requiring a - different version of `node`, even if `--engine-strict` is enabled. -* Allow `npm audit fix` to install modules outside your stated dependency - range (including SemVer-major changes). -* Allow unpublishing all versions of a published package. -* Allow conflicting peerDependencies to be installed in the root project. -* Implicitly set `--yes` during `npm init`. -* Allow clobbering existing values in `npm pkg` -* Allow unpublishing of entire packages (not just a single version). - -If you don't have a clear idea of what you want to do, it is strongly -recommended that you do not use this option! - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> -## See Also - -* [npm install](/commands/npm-install) -* [npm init](/commands/npm-init) -* [npm config](/commands/npm-config) -* [npm set-script](/commands/npm-set-script) -* [workspaces](/using-npm/workspaces) diff --git a/docs/content/commands/npm-prefix.md b/docs/content/commands/npm-prefix.md deleted file mode 100644 index 39328bcc88a14..0000000000000 --- a/docs/content/commands/npm-prefix.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: npm-prefix -section: 1 -description: Display prefix ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/prefix.js --> - -```bash -npm prefix [-g] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/prefix.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Print the local prefix to standard output. This is the closest parent directory -to contain a `package.json` file or `node_modules` directory, unless `-g` is -also specified. - -If `-g` is specified, this will be the value of the global prefix. See -[`npm config`](/commands/npm-config) for more detail. - -### Example - -```bash -npm prefix -/usr/local/projects/foo -``` - -```bash -npm prefix -g -/usr/local -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm root](/commands/npm-root) -* [npm bin](/commands/npm-bin) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-profile.md b/docs/content/commands/npm-profile.md deleted file mode 100644 index af1f9d8aa1063..0000000000000 --- a/docs/content/commands/npm-profile.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: npm-profile -section: 1 -description: Change settings on your registry profile ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/profile.js --> - -```bash -npm profile enable-2fa [auth-only|auth-and-writes] -npm profile disable-2fa -npm profile get [<key>] -npm profile set <key> <value> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/profile.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Change your profile information on the registry. Note that this command -depends on the registry implementation, so third-party registries may not -support this interface. - -* `npm profile get [<property>]`: 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 | -+-----------------+---------------------------+ -``` - -* `npm profile set <property> <value>`: Set the value of a profile - property. You can set the following properties this way: email, fullname, - homepage, freenode, twitter, github - -* `npm profile set password`: Change your password. This is interactive, - you'll be prompted for your current password and a new password. You'll - also be prompted for an OTP if you have two-factor authentication - enabled. - -* `npm profile enable-2fa [auth-and-writes|auth-only]`: Enables two-factor - authentication. Defaults to `auth-and-writes` mode. Modes are: - * `auth-only`: Require an OTP when logging in or making changes to your - account's authentication. The OTP will be required on both the website - and the command line. - * `auth-and-writes`: Requires an OTP at all the times `auth-only` does, - and also requires one when publishing a module, setting the `latest` - dist-tag, or changing access via `npm access` and `npm owner`. - -* `npm profile disable-2fa`: Disables two-factor authentication. - -### Details - -Some of these commands may not be available on non npmjs.com registries. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm adduser](/commands/npm-adduser) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm owner](/commands/npm-owner) -* [npm whoami](/commands/npm-whoami) -* [npm token](/commands/npm-token) diff --git a/docs/content/commands/npm-prune.md b/docs/content/commands/npm-prune.md deleted file mode 100644 index 28f02f6add190..0000000000000 --- a/docs/content/commands/npm-prune.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: npm-prune -section: 1 -description: Remove extraneous packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/prune.js --> - -```bash -npm prune [[<@scope>/]<pkg>...] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/prune.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command removes "extraneous" packages. If a package name is provided, -then only packages matching one of the supplied names are removed. - -Extraneous packages are those present in the `node_modules` folder that are -not listed as any package's dependency list. - -If the `--production` flag is specified or the `NODE_ENV` environment -variable is set to `production`, this command will remove the packages -specified in your `devDependencies`. Setting `--no-production` will negate -`NODE_ENV` being set to `production`. - -If the `--dry-run` flag is used then no changes will actually be made. - -If the `--json` flag is used, then the changes `npm prune` made (or would -have made with `--dry-run`) are printed as a JSON object. - -In normal operation, extraneous modules are pruned automatically, so you'll -only need this command with the `--production` flag. However, in the real -world, operation is not always "normal". When crashes or mistakes happen, -this command can help clean up any resulting garbage. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm uninstall](/commands/npm-uninstall) -* [npm folders](/configuring-npm/folders) -* [npm ls](/commands/npm-ls) diff --git a/docs/content/commands/npm-publish.md b/docs/content/commands/npm-publish.md deleted file mode 100644 index 536d04988e684..0000000000000 --- a/docs/content/commands/npm-publish.md +++ /dev/null @@ -1,243 +0,0 @@ ---- -title: npm-publish -section: 1 -description: Publish a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/publish.js --> - -```bash -npm publish <package-spec> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/publish.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Publishes a package to the registry so that it can be installed by name. - -By default npm will publish to the public registry. This can be -overridden by specifying a different default registry or using a -[`scope`](/using-npm/scope) in the name, combined with a -scope-configured registry (see -[`package.json`](/configuring-npm/package-json)). - - -A `package` is interpreted the same way as other commands (like -`npm install` and can be: - -* a) a folder containing a program described by a - [`package.json`](/configuring-npm/package-json) file -* b) a gzipped tarball containing (a) -* c) a url that resolves to (b) -* d) a `<name>@<version>` that is published on the registry (see - [`registry`](/using-npm/registry)) with (c) -* e) a `<name>@<tag>` (see [`npm dist-tag`](/commands/npm-dist-tag)) that - points to (d) -* f) a `<name>` that has a "latest" tag satisfying (e) -* g) a `<git remote url>` that resolves to (a) - -The publish will fail if the package name and version combination already -exists in the specified registry. - -Once a package is published with a given name and version, that specific -name and version combination can never be used again, even if it is removed -with [`npm unpublish`](/commands/npm-unpublish). - -As of `npm@5`, both a sha1sum and an integrity field with a sha512sum of the -tarball will be submitted to the registry during publication. Subsequent -installs will use the strongest supported algorithm to verify downloads. - -Similar to `--dry-run` see [`npm pack`](/commands/npm-pack), which figures -out the files to be included and packs them into a tarball to be uploaded -to the registry. - -### Files included in package - -To see what will be included in your package, run `npx npm-packlist`. All -files are included by default, with the following exceptions: - -- Certain files that are relevant to package installation and distribution - are always included. For example, `package.json`, `README.md`, - `LICENSE`, and so on. - -- If there is a "files" list in - [`package.json`](/configuring-npm/package-json), then only the files - specified will be included. (If directories are specified, then they - will be walked recursively and their contents included, subject to the - same ignore rules.) - -- If there is a `.gitignore` or `.npmignore` file, then ignored files in - that and all child directories will be excluded from the package. If - _both_ files exist, then the `.gitignore` is ignored, and only the - `.npmignore` is used. - - `.npmignore` files follow the [same pattern - rules](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#_ignoring) - as `.gitignore` files - -- If the file matches certain patterns, then it will _never_ be included, - unless explicitly added to the `"files"` list in `package.json`, or - un-ignored with a `!` rule in a `.npmignore` or `.gitignore` file. - -- Symbolic links are never included in npm packages. - - -See [`developers`](/using-npm/developers) for full details on what's -included in the published package, as well as details on how the package is -built. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `tag` - -* Default: "latest" -* Type: String - -If you ask npm to install a package and don't tell it a specific version, -then it will install the specified tag. - -Also the tag that is added to the package@version specified by the `npm tag` -command, if no explicit tag is given. - -When used by the `npm diff` command, this is the tag used to fetch the -tarball that will be compared with the local files by default. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `access` - -* Default: 'restricted' for scoped packages, 'public' for unscoped packages -* Type: null, "restricted", or "public" - -When publishing scoped packages, the access level defaults to `restricted`. -If you want your scoped package to be publicly viewable (and installable) -set `--access=public`. The only valid values for `access` are `public` and -`restricted`. Unscoped packages _always_ have an access level of `public`. - -Note: Using the `--access` flag on the `npm publish` command will only set -the package access level on the initial publish of the package. Any -subsequent `npm publish` commands using the `--access` flag will not have an -effect to the access level. To make changes to the access level after the -initial publish use `npm access`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm-packlist package](http://npm.im/npm-packlist) -* [npm registry](/using-npm/registry) -* [npm scope](/using-npm/scope) -* [npm adduser](/commands/npm-adduser) -* [npm owner](/commands/npm-owner) -* [npm deprecate](/commands/npm-deprecate) -* [npm dist-tag](/commands/npm-dist-tag) -* [npm pack](/commands/npm-pack) -* [npm profile](/commands/npm-profile) diff --git a/docs/content/commands/npm-query.md b/docs/content/commands/npm-query.md deleted file mode 100644 index 424b9e7e45ae8..0000000000000 --- a/docs/content/commands/npm-query.md +++ /dev/null @@ -1,236 +0,0 @@ ---- -title: npm-query -section: 1 -description: Dependency selector query ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/query.js --> - -```bash -npm query <selector> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/query.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -The `npm query` command allows for usage of css selectors in order to retrieve -an array of dependency objects. - -### Piping npm query to other commands - -```bash -# find all dependencies with postinstall scripts & uninstall them -npm query ":attr(scripts, [postinstall])" | jq 'map(.name)|join("\n")' -r | xargs -I {} npm uninstall {} - -# find all git dependencies & explain who requires them -npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {} -``` - -### Extended Use Cases & Queries - -```stylus -// all deps -* - -// all direct deps -:root > * - -// direct production deps -:root > .prod - -// direct development deps -:root > .dev - -// any peer dep of a direct deps -:root > * > .peer - -// any workspace dep -.workspace - -// all workspaces that depend on another workspace -.workspace > .workspace - -// all workspaces that have peer deps -.workspace:has(.peer) - -// any dep named "lodash" -// equivalent to [name="lodash"] -#lodash - -// any deps named "lodash" & within semver range ^"1.2.3" -#lodash@^1.2.3 -// equivalent to... -[name="lodash"]:semver(^1.2.3) - -// get the hoisted node for a given semver range -#lodash@^1.2.3:not(:deduped) - -// querying deps with a specific version -#lodash@2.1.5 -// equivalent to... -[name="lodash"][version="2.1.5"] - -// has any deps -:has(*) - -// deps with no other deps (ie. "leaf" nodes) -:empty - -// manually querying git dependencies -[repository^=github:], -[repository^=git:], -[repository^=https://github.com], -[repository^=http://github.com], -[repository^=https://github.com], -[repository^=+git:...] - -// querying for all git dependencies -:type(git) - -// get production dependencies that aren't also dev deps -.prod:not(.dev) - -// get dependencies with specific licenses -[license=MIT], [license=ISC] - -// find all packages that have @ruyadorno as a contributor -:attr(contributors, [email=ruyadorno@github.com]) -``` - -### Example Response Output - -- an array of dependency objects is returned which can contain multiple copies of the same package which may or may not have been linked or deduped - -```json -[ - { - "name": "", - "version": "", - "description": "", - "homepage": "", - "bugs": {}, - "author": {}, - "license": {}, - "funding": {}, - "files": [], - "main": "", - "browser": "", - "bin": {}, - "man": [], - "directories": {}, - "repository": {}, - "scripts": {}, - "config": {}, - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "bundledDependencies": {}, - "peerDependencies": {}, - "peerDependenciesMeta": {}, - "engines": {}, - "os": [], - "cpu": [], - "workspaces": {}, - "keywords": [], - ... - }, - ... -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> -## See Also - -* [dependency selector](/using-npm/dependency-selector) - diff --git a/docs/content/commands/npm-rebuild.md b/docs/content/commands/npm-rebuild.md deleted file mode 100644 index 6a396421213d3..0000000000000 --- a/docs/content/commands/npm-rebuild.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: npm-rebuild -section: 1 -description: Rebuild a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/rebuild.js --> - -```bash -npm rebuild [<package-spec>] ...] - -alias: rb -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/rebuild.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command runs the `npm build` command on the matched folders. This is -useful when you install a new version of node, and must recompile all your -C++ addons with the new binary. It is also useful when installing with -`--ignore-scripts` and `--no-bin-links`, to explicitly choose which -packages to build and/or link bins. - -If one or more package specs are provided, then only packages with a -name and version matching one of the specifiers will be rebuilt. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm install](/commands/npm-install) diff --git a/docs/content/commands/npm-repo.md b/docs/content/commands/npm-repo.md deleted file mode 100644 index fc540a9382b23..0000000000000 --- a/docs/content/commands/npm-repo.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: npm-repo -section: 1 -description: Open package repository page in the browser ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/repo.js --> - -```bash -npm repo [<pkgname> [<pkgname> ...]] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/repo.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command tries to guess at the likely location of a package's -repository URL, and then tries to open it using the `--browser` config -param. If no package name is provided, it will search for a `package.json` -in the current folder and use the `repository` property. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `browser` - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: null, Boolean, or String - -The browser that is called by npm commands to open websites. - -Set to `false` to suppress browser behavior and instead print urls to -terminal. - -Set to `true` to use default system URL opener. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm docs](/commands/npm-docs) -* [npm config](/commands/npm-config) diff --git a/docs/content/commands/npm-restart.md b/docs/content/commands/npm-restart.md deleted file mode 100644 index 048bebb1659bd..0000000000000 --- a/docs/content/commands/npm-restart.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: npm-restart -section: 1 -description: Restart a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/restart.js --> - -```bash -npm restart [-- <args>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/restart.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This restarts a project. It is equivalent to running `npm run-script -restart`. - -If the current project has a `"restart"` script specified in -`package.json`, then the following scripts will be run: - -1. prerestart -2. restart -3. postrestart - -If it does _not_ have a `"restart"` script specified, but it does have -`stop` and/or `start` scripts, then the following scripts will be run: - -1. prerestart -2. prestop -3. stop -4. poststop -6. prestart -7. start -8. poststart -9. postrestart - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `script-shell` - -* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows -* Type: null or String - -The shell to use for scripts run with the `npm exec`, `npm run` and `npm -init <package-spec>` commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [npm test](/commands/npm-test) -* [npm start](/commands/npm-start) -* [npm stop](/commands/npm-stop) -* [npm restart](/commands/npm-restart) diff --git a/docs/content/commands/npm-root.md b/docs/content/commands/npm-root.md deleted file mode 100644 index 40b58e4b33d0b..0000000000000 --- a/docs/content/commands/npm-root.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: npm-root -section: 1 -description: Display npm root ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/root.js --> - -```bash -npm root -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/root.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -Print the effective `node_modules` folder to standard out. - -Useful for using npm in shell scripts that do things with the -`node_modules` folder. For example: - -```bash -#!/bin/bash -global_node_modules="$(npm root --global)" -echo "Global packages installed in: ${global_node_modules}" -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm prefix](/commands/npm-prefix) -* [npm bin](/commands/npm-bin) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-run-script.md b/docs/content/commands/npm-run-script.md deleted file mode 100644 index f606ec6bf59e5..0000000000000 --- a/docs/content/commands/npm-run-script.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -title: npm-run-script -section: 1 -description: Run arbitrary package scripts ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/run-script.js --> - -```bash -npm run-script <command> [-- <args>] - -aliases: run, rum, urn -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/run-script.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This runs an arbitrary command from a package's `"scripts"` object. If no -`"command"` is provided, it will list the available scripts. - -`run[-script]` is used by the test, start, restart, and stop commands, but -can be called directly, as well. When the scripts in the package are -printed out, they're separated into lifecycle (test, start, restart) and -directly-run scripts. - -Any positional arguments are passed to the specified script. Use `--` to -pass `-`-prefixed flags and options which would otherwise be parsed by npm. - -For example: - -```bash -npm run test -- --grep="pattern" -``` - -The arguments will only be passed to the script specified after `npm run` -and not to any `pre` or `post` script. - -The `env` script is a special built-in command that can be used to list -environment variables that will be available to the script at runtime. If an -"env" command is defined in your package, it will take precedence over the -built-in. - -In addition to the shell's pre-existing `PATH`, `npm run` adds -`node_modules/.bin` to the `PATH` provided to scripts. Any binaries -provided by locally-installed dependencies can be used without the -`node_modules/.bin` prefix. For example, if there is a `devDependency` on -`tap` in your package, you should write: - -```bash -"scripts": {"test": "tap test/*.js"} -``` - -instead of - -```bash -"scripts": {"test": "node_modules/.bin/tap test/*.js"} -``` - -The actual shell your script is run within is platform dependent. By default, -on Unix-like systems it is the `/bin/sh` command, on Windows it is -`cmd.exe`. -The actual shell referred to by `/bin/sh` also depends on the system. -You can customize the shell with the `script-shell` configuration. - -Scripts are run from the root of the package folder, regardless of what the -current working directory is when `npm run` is called. If you want your -script to use different behavior based on what subdirectory you're in, you -can use the `INIT_CWD` environment variable, which holds the full path you -were in when you ran `npm run`. - -`npm run` sets the `NODE` environment variable to the `node` executable -with which `npm` is executed. - -If you try to run a script without having a `node_modules` directory and it -fails, you will be given a warning to run `npm install`, just in case you've -forgotten. - -### Workspaces support - -You may use the `workspace` or `workspaces` configs in order to run an -arbitrary command from a package's `"scripts"` object in the context of the -specified workspaces. If no `"command"` is provided, it will list the available -scripts for each of these configured workspaces. - -Given a project with configured workspaces, e.g: - -``` -. -+-- package.json -`-- packages - +-- a - | `-- package.json - +-- b - | `-- package.json - `-- c - `-- package.json -``` - -Assuming the workspace configuration is properly set up at the root level -`package.json` file. e.g: - -``` -{ - "workspaces": [ "./packages/*" ] -} -``` - -And that each of the configured workspaces has a configured `test` script, -we can run tests in all of them using the `workspaces` config: - -``` -npm test --workspaces -``` - -#### Filtering workspaces - -It's also possible to run a script in a single workspace using the `workspace` -config along with a name or directory path: - -``` -npm test --workspace=a -``` - -The `workspace` config can also be specified multiple times in order to run a -specific script in the context of multiple workspaces. When defining values for -the `workspace` config in the command line, it also possible to use `-w` as a -shorthand, e.g: - -``` -npm test -w a -w b -``` - -This last command will run `test` in both `./packages/a` and `./packages/b` -packages. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `if-present` - -* Default: false -* Type: Boolean - -If true, npm will not exit with an error code when `run-script` is invoked -for a script that isn't defined in the `scripts` section of `package.json`. -This option can be used when it's desirable to optionally run a script when -it's present and fail if the script fails. This is useful, for example, when -running scripts that may only apply for some builds in an otherwise generic -CI setup. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `script-shell` - -* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows -* Type: null or String - -The shell to use for scripts run with the `npm exec`, `npm run` and `npm -init <package-spec>` commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm scripts](/using-npm/scripts) -* [npm test](/commands/npm-test) -* [npm start](/commands/npm-start) -* [npm restart](/commands/npm-restart) -* [npm stop](/commands/npm-stop) -* [npm config](/commands/npm-config) -* [npm workspaces](/using-npm/workspaces) diff --git a/docs/content/commands/npm-search.md b/docs/content/commands/npm-search.md deleted file mode 100644 index 340dea9684d00..0000000000000 --- a/docs/content/commands/npm-search.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: npm-search -section: 1 -description: Search for packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/search.js --> - -```bash -npm search [search terms ...] - -aliases: find, s, se -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/search.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Search the registry for packages matching the search terms. `npm search` -performs a linear, incremental, lexically-ordered search through package -metadata for all files in the registry. If your terminal has color -support, it will further highlight the matches in the results. This can -be disabled with the config item `color` - -Additionally, using the `--searchopts` and `--searchexclude` options -paired with more search terms will include and exclude further patterns. -The main difference between `--searchopts` and the standard search terms -is that the former does not highlight results in the output and you can -use them more fine-grained filtering. Additionally, you can add both of -these to your config to change default search filtering behavior. - -Search also allows targeting of maintainers in search results, by prefixing -their npm username with `=`. - -If a term starts with `/`, then it's interpreted as a regular expression -and supports standard JavaScript RegExp syntax. In this case search will -ignore a trailing `/` . (Note you must escape or quote many regular -expression characters in most shells.) - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `color` - -* Default: true unless the NO_COLOR environ is set to something other than '0' -* Type: "always" or Boolean - -If false, never shows colors. If `"always"` then always shows colors. If -true, then only prints color codes for tty file descriptors. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `description` - -* Default: true -* Type: Boolean - -Show the description in `npm search` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `searchopts` - -* Default: "" -* Type: String - -Space-separated options that are always passed to search. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `searchexclude` - -* Default: "" -* Type: String - -Space-separated options that limit the results from search. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `prefer-online` - -* Default: false -* Type: Boolean - -If true, staleness checks for cached data will be forced, making the CLI -look for updates immediately even for fresh package data. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `prefer-offline` - -* Default: false -* Type: Boolean - -If true, staleness checks for cached data will be bypassed, but missing data -will be requested from the server. To force full offline mode, use -`--offline`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `offline` - -* Default: false -* Type: Boolean - -Force offline mode: no network requests will be done during install. To -allow the CLI to fill in missing cache data, see `--prefer-offline`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm view](/commands/npm-view) -* [npm cache](/commands/npm-cache) -* https://npm.im/npm-registry-fetch diff --git a/docs/content/commands/npm-set-script.md b/docs/content/commands/npm-set-script.md deleted file mode 100644 index 8695b43f14423..0000000000000 --- a/docs/content/commands/npm-set-script.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: npm-set-script -section: 1 -description: Set tasks in the scripts section of package.json ---- - -### Synopsis -An npm command that lets you create a task in the `scripts` section of the `package.json`. - -Deprecated. - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/set-script.js --> - -```bash -npm set-script [<script>] [<command>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/set-script.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - - -**Example:** - -* `npm set-script start "http-server ."` - -```json -{ - "name": "my-project", - "scripts": { - "start": "http-server .", - "test": "some existing value" - } -} -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm install](/commands/npm-install) -* [npm test](/commands/npm-test) -* [npm start](/commands/npm-start) diff --git a/docs/content/commands/npm-shrinkwrap.md b/docs/content/commands/npm-shrinkwrap.md deleted file mode 100644 index 043b4ad1b1bb4..0000000000000 --- a/docs/content/commands/npm-shrinkwrap.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: npm-shrinkwrap -section: 1 -description: Lock down dependency versions for publication ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/shrinkwrap.js --> - -```bash -npm shrinkwrap -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/shrinkwrap.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -This command repurposes `package-lock.json` into a publishable -`npm-shrinkwrap.json` or simply creates a new one. The file created and -updated by this command will then take precedence over any other existing -or future `package-lock.json` files. For a detailed explanation of the -design and purpose of package locks in npm, see -[package-lock-json](/configuring-npm/package-lock-json). - -### See Also - -* [npm install](/commands/npm-install) -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [package.json](/configuring-npm/package-json) -* [package-lock.json](/configuring-npm/package-lock-json) -* [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) -* [npm ls](/commands/npm-ls) diff --git a/docs/content/commands/npm-star.md b/docs/content/commands/npm-star.md deleted file mode 100644 index 3e81c6a55bbb0..0000000000000 --- a/docs/content/commands/npm-star.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: npm-star -section: 1 -description: Mark your favorite packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/star.js --> - -```bash -npm star [<package-spec>...] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/star.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -"Starring" a package means that you have some interest in it. It's -a vaguely positive way to show that you care. - -It's a boolean thing. Starring repeatedly has no additional effect. - -### More - -There's also these extra commands to help you manage your favorite packages: - -#### Unstar - -You can also "unstar" a package using [`npm unstar`](/commands/npm-unstar) - -"Unstarring" is the same thing, but in reverse. - -#### Listing stars - -You can see all your starred packages using [`npm stars`](/commands/npm-stars) - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `unicode` - -* Default: false on windows, true on mac/unix systems with a unicode locale, - as defined by the `LC_ALL`, `LC_CTYPE`, or `LANG` environment variables. -* Type: Boolean - -When set to true, npm uses unicode characters in the tree output. When -false, it uses ascii characters instead of unicode glyphs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm unstar](/commands/npm-unstar) -* [npm stars](/commands/npm-stars) -* [npm view](/commands/npm-view) -* [npm whoami](/commands/npm-whoami) -* [npm adduser](/commands/npm-adduser) diff --git a/docs/content/commands/npm-stars.md b/docs/content/commands/npm-stars.md deleted file mode 100644 index b9153831533af..0000000000000 --- a/docs/content/commands/npm-stars.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: npm-stars -section: 1 -description: View packages marked as favorites ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/stars.js --> - -```bash -npm stars [<user>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/stars.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -If you have starred a lot of neat things and want to find them again -quickly this command lets you do just that. - -You may also want to see your friend's favorite packages, in this case -you will most certainly enjoy this command. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm star](/commands/npm-star) -* [npm unstar](/commands/npm-unstar) -* [npm view](/commands/npm-view) -* [npm whoami](/commands/npm-whoami) -* [npm adduser](/commands/npm-adduser) diff --git a/docs/content/commands/npm-start.md b/docs/content/commands/npm-start.md deleted file mode 100644 index 148f92606d83f..0000000000000 --- a/docs/content/commands/npm-start.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: npm-start -section: 1 -description: Start a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/start.js --> - -```bash -npm start [-- <args>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/start.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This runs a predefined command specified in the `"start"` property of -a package's `"scripts"` object. - -If the `"scripts"` object does not define a `"start"` property, npm -will run `node server.js`. - -Note that this is different from the default node behavior of running -the file specified in a package's `"main"` attribute when evoking with -`node .` - -As of [`npm@2.0.0`](https://blog.npmjs.org/post/98131109725/npm-2-0-0), you can -use custom arguments when executing scripts. Refer to [`npm run-script`](/commands/npm-run-script) for more details. - -### Example - -```json -{ - "scripts": { - "start": "node foo.js" - } -} -``` - -```bash -npm start - -> npm@x.x.x start -> node foo.js - -(foo.js output would be here) - -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `script-shell` - -* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows -* Type: null or String - -The shell to use for scripts run with the `npm exec`, `npm run` and `npm -init <package-spec>` commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [npm test](/commands/npm-test) -* [npm restart](/commands/npm-restart) -* [npm stop](/commands/npm-stop) diff --git a/docs/content/commands/npm-stop.md b/docs/content/commands/npm-stop.md deleted file mode 100644 index a3084e8432ba7..0000000000000 --- a/docs/content/commands/npm-stop.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: npm-stop -section: 1 -description: Stop a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/stop.js --> - -```bash -npm stop [-- <args>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/stop.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This runs a predefined command specified in the "stop" property of a -package's "scripts" object. - -Unlike with [npm start](/commands/npm-start), there is no default script -that will run if the `"stop"` property is not defined. - -### Example - -```json -{ - "scripts": { - "stop": "node bar.js" - } -} -``` - -```bash -npm stop - -> npm@x.x.x stop -> node bar.js - -(bar.js output would be here) - -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `script-shell` - -* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows -* Type: null or String - -The shell to use for scripts run with the `npm exec`, `npm run` and `npm -init <package-spec>` commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [npm test](/commands/npm-test) -* [npm start](/commands/npm-start) -* [npm restart](/commands/npm-restart) diff --git a/docs/content/commands/npm-team.md b/docs/content/commands/npm-team.md deleted file mode 100644 index dc26fb53aaff1..0000000000000 --- a/docs/content/commands/npm-team.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: npm-team -section: 1 -description: Manage organization teams and team memberships ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/team.js --> - -```bash -npm team create <scope:team> [--otp <otpcode>] -npm team destroy <scope:team> [--otp <otpcode>] -npm team add <scope:team> <user> [--otp <otpcode>] -npm team rm <scope:team> <user> [--otp <otpcode>] -npm team ls <scope>|<scope:team> -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/team.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Used to manage teams in organizations, and change team memberships. Does not -handle permissions for packages. - -Teams must always be fully qualified with the organization/scope they belong to -when operating on them, separated by a colon (`:`). That is, if you have a -`newteam` team in an `org` organization, you must always refer to that team -as `@org:newteam` in these commands. - -If you have two-factor authentication enabled in `auth-and-writes` mode, then -you can provide a code from your authenticator with `[--otp <otpcode>]`. -If you don't include this then you will be prompted. - -* create / destroy: - Create a new team, or destroy an existing one. Note: You cannot remove the - `developers` team, <a href="https://docs.npmjs.com/about-developers-team" target="_blank">learn more.</a> - - Here's how to create a new team `newteam` under the `org` org: - - ```bash - npm team create @org:newteam - ``` - - You should see a confirming message such as: `+@org:newteam` once the new - team has been created. - -* add: - Add a user to an existing team. - - Adding a new user `username` to a team named `newteam` under the `org` org: - - ```bash - npm team add @org:newteam username - ``` - - On success, you should see a message: `username added to @org:newteam` - -* rm: - Using `npm team rm` you can also remove users from a team they belong to. - - Here's an example removing user `username` from `newteam` team - in `org` organization: - - ```bash - npm team rm @org:newteam username - ``` - - Once the user is removed a confirmation message is displayed: - `username removed from @org:newteam` - -* ls: - If performed on an organization name, will return a list of existing teams - under that organization. If performed on a team, it will instead return a list - of all users belonging to that particular team. - - Here's an example of how to list all teams from an org named `org`: - - ```bash - npm team ls @org - ``` - - Example listing all members of a team named `newteam`: - - ```bash - npm team ls @org:newteam - ``` - -### Details - -`npm team` always operates directly on the current registry, configurable from -the command line using `--registry=<registry url>`. - -You must be a *team admin* to create teams and manage team membership, under -the given organization. Listing teams and team memberships may be done by -any member of the organization. - -Organization creation and management of team admins and *organization* members -is done through the website, not the npm CLI. - -To use teams to manage permissions on packages belonging to your organization, -use the `npm access` command to grant or revoke the appropriate permissions. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm access](/commands/npm-access) -* [npm config](/commands/npm-config) -* [npm registry](/using-npm/registry) diff --git a/docs/content/commands/npm-test.md b/docs/content/commands/npm-test.md deleted file mode 100644 index 72bb899d0b916..0000000000000 --- a/docs/content/commands/npm-test.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: npm-test -section: 1 -description: Test a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/test.js --> - -```bash -npm test [-- <args>] - -aliases: tst, t -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/test.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This runs a predefined command specified in the `"test"` property of -a package's `"scripts"` object. - -### Example - -```json -{ - "scripts": { - "test": "node test.js" - } -} -``` - -```bash -npm test -> npm@x.x.x test -> node test.js - -(test.js output would be here) -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `script-shell` - -* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows -* Type: null or String - -The shell to use for scripts run with the `npm exec`, `npm run` and `npm -init <package-spec>` commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [npm start](/commands/npm-start) -* [npm restart](/commands/npm-restart) -* [npm stop](/commands/npm-stop) diff --git a/docs/content/commands/npm-token.md b/docs/content/commands/npm-token.md deleted file mode 100644 index 856ad68c9c94f..0000000000000 --- a/docs/content/commands/npm-token.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: npm-token -section: 1 -description: Manage your authentication tokens ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/token.js --> - -```bash -npm token list -npm token revoke <id|token> -npm token create [--read-only] [--cidr=list] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/token.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -This lets you list, create and revoke authentication tokens. - -* `npm token list`: - 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 | | -+--------+---------+------------+----------+----------------+ -``` - -* `npm token create [--read-only] [--cidr=<cidr-ranges>]`: - Create a new authentication token. It can be `--read-only`, or accept - a list of - [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) - ranges with which to limit use of this token. This will prompt you for - your password, and, if you have two-factor authentication enabled, an - otp. - - Currently, the cli can not generate automation tokens. Please refer to - the [docs - 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 | -+----------------+--------------------------------------+ -``` - -* `npm token revoke <token|id>`: - Immediately removes an authentication token from the registry. You - will no longer be able to use it. This can accept both complete - tokens (such as those you get back from `npm token create`, and those - found in your `.npmrc`), and ids as seen in the parseable or json - output of `npm token list`. This will NOT accept the truncated token - found in the normal `npm token list` output. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `read-only` - -* Default: false -* Type: Boolean - -This is used to mark a token as unable to publish when configuring limited -access tokens with the `npm token create` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cidr` - -* Default: null -* Type: null or String (can be set multiple times) - -This is a list of CIDR address to be used when configuring limited access -tokens with the `npm token create` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm adduser](/commands/npm-adduser) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm owner](/commands/npm-owner) -* [npm whoami](/commands/npm-whoami) -* [npm profile](/commands/npm-profile) diff --git a/docs/content/commands/npm-uninstall.md b/docs/content/commands/npm-uninstall.md deleted file mode 100644 index e39c7e328b20a..0000000000000 --- a/docs/content/commands/npm-uninstall.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: npm-uninstall -section: 1 -description: Remove a package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/uninstall.js --> - -```bash -npm uninstall [<@scope>/]<pkg>... - -aliases: unlink, remove, rm, r, un -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/uninstall.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This uninstalls a package, completely removing everything npm installed -on its behalf. - -It also removes the package from the `dependencies`, `devDependencies`, -`optionalDependencies`, and `peerDependencies` objects in your -`package.json`. - -Further, if you have an `npm-shrinkwrap.json` or `package-lock.json`, npm -will update those files as well. - -`--no-save` will tell npm not to remove the package from your -`package.json`, `npm-shrinkwrap.json`, or `package-lock.json` files. - -`--save` or `-S` will tell npm to remove the package from your -`package.json`, `npm-shrinkwrap.json`, and `package-lock.json` files. -This is the default, but you may need to use this if you have for -instance `save=false` in your `npmrc` file - -In global mode (ie, with `-g` or `--global` appended to the command), -it uninstalls the current package context as a global package. -`--no-save` is ignored in this case. - -Scope is optional and follows the usual rules for [`scope`](/using-npm/scope). - -### Examples - -```bash -npm uninstall sax -``` - -`sax` will no longer be in your `package.json`, `npm-shrinkwrap.json`, or -`package-lock.json` files. - -```bash -npm uninstall lodash --no-save -``` - -`lodash` will not be removed from your `package.json`, -`npm-shrinkwrap.json`, or `package-lock.json` files. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm prune](/commands/npm-prune) -* [npm install](/commands/npm-install) -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) diff --git a/docs/content/commands/npm-unpublish.md b/docs/content/commands/npm-unpublish.md deleted file mode 100644 index 9ad99e72a5a8e..0000000000000 --- a/docs/content/commands/npm-unpublish.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: npm-unpublish -section: 1 -description: Remove a package from the registry ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/unpublish.js --> - -```bash -npm unpublish [<package-spec>] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/unpublish.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -To learn more about how the npm registry treats unpublish, see our <a -href="https://docs.npmjs.com/policies/unpublish" target="_blank" -rel="noopener noreferrer"> unpublish policies</a> - -### Warning - -Consider using the [`deprecate`](/commands/npm-deprecate) command instead, -if your intent is to encourage users to upgrade, or if you no longer -want to maintain a package. - -### Description - -This removes a package version from the registry, deleting its entry and -removing the tarball. - -The npm registry will return an error if you are not [logged -in](/commands/npm-adduser). - -If you do not specify a version or if you remove all of a package's -versions then the registry will remove the root package entry entirely. - -Even if you unpublish a package version, that specific name and version -combination can never be reused. In order to publish the package again, -you must use a new version number. If you unpublish the entire package, -you may not publish any new versions of that package until 24 hours have -passed. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `force` - -* Default: false -* Type: Boolean - -Removes various protections against unfortunate side effects, common -mistakes, unnecessary performance degradation, and malicious input. - -* Allow clobbering non-npm files in global installs. -* Allow the `npm version` command to work on an unclean git repository. -* Allow deleting the cache folder with `npm cache clean`. -* Allow installing packages that have an `engines` declaration requiring a - different version of npm. -* Allow installing packages that have an `engines` declaration requiring a - different version of `node`, even if `--engine-strict` is enabled. -* Allow `npm audit fix` to install modules outside your stated dependency - range (including SemVer-major changes). -* Allow unpublishing all versions of a published package. -* Allow conflicting peerDependencies to be installed in the root project. -* Implicitly set `--yes` during `npm init`. -* Allow clobbering existing values in `npm pkg` -* Allow unpublishing of entire packages (not just a single version). - -If you don't have a clear idea of what you want to do, it is strongly -recommended that you do not use this option! - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm deprecate](/commands/npm-deprecate) -* [npm publish](/commands/npm-publish) -* [npm registry](/using-npm/registry) -* [npm adduser](/commands/npm-adduser) -* [npm owner](/commands/npm-owner) -* [npm login](/commands/npm-adduser) diff --git a/docs/content/commands/npm-unstar.md b/docs/content/commands/npm-unstar.md deleted file mode 100644 index 636e1b6ac0a94..0000000000000 --- a/docs/content/commands/npm-unstar.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: npm-unstar -section: 1 -description: Remove an item from your favorite packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/unstar.js --> - -```bash -npm unstar [<package-spec>...] -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/unstar.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -"Unstarring" a package is the opposite of [`npm star`](/commands/npm-star), -it removes an item from your list of favorite packages. - -### More - -There's also these extra commands to help you manage your favorite packages: - -#### Star - -You can "star" a package using [`npm star`](/commands/npm-star) - -#### Listing stars - -You can see all your starred packages using [`npm stars`](/commands/npm-stars) - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `unicode` - -* Default: false on windows, true on mac/unix systems with a unicode locale, - as defined by the `LC_ALL`, `LC_CTYPE`, or `LANG` environment variables. -* Type: Boolean - -When set to true, npm uses unicode characters in the tree output. When -false, it uses ascii characters instead of unicode glyphs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm star](/commands/npm-star) -* [npm stars](/commands/npm-stars) -* [npm view](/commands/npm-view) -* [npm whoami](/commands/npm-whoami) -* [npm adduser](/commands/npm-adduser) - diff --git a/docs/content/commands/npm-update.md b/docs/content/commands/npm-update.md deleted file mode 100644 index 421d04ca3dc58..0000000000000 --- a/docs/content/commands/npm-update.md +++ /dev/null @@ -1,457 +0,0 @@ ---- -title: npm-update -section: 1 -description: Update packages ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/update.js --> - -```bash -npm update [<pkg>...] - -aliases: up, upgrade, udpate -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/update.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command will update all the packages listed to the latest version -(specified by the `tag` config), respecting the semver constraints of -both your package and its dependencies (if they also require the same -package). - -It will also install missing packages. - -If the `-g` flag is specified, this command will update globally installed -packages. - -If no package name is specified, all packages in the specified location (global -or local) will be updated. - -Note that by default `npm update` will not update the semver values of direct -dependencies in your project `package.json`, if you want to also update -values in `package.json` you can run: `npm update --save` (or add the -`save=true` option to a [configuration file](/configuring-npm/npmrc) -to make that the default behavior). - -### Example - -For the examples below, assume that the current package is `app` and it depends -on dependencies, `dep1` (`dep2`, .. etc.). The published versions of `dep1` -are: - -```json -{ - "dist-tags": { "latest": "1.2.2" }, - "versions": [ - "1.2.2", - "1.2.1", - "1.2.0", - "1.1.2", - "1.1.1", - "1.0.0", - "0.4.1", - "0.4.0", - "0.2.0" - ] -} -``` - -#### Caret Dependencies - -If `app`'s `package.json` contains: - -```json -"dependencies": { - "dep1": "^1.1.1" -} -``` - -Then `npm update` will install `dep1@1.2.2`, because `1.2.2` is `latest` and -`1.2.2` satisfies `^1.1.1`. - -#### Tilde Dependencies - -However, if `app`'s `package.json` contains: - -```json -"dependencies": { - "dep1": "~1.1.1" -} -``` - -In this case, running `npm update` will install `dep1@1.1.2`. Even though the -`latest` tag points to `1.2.2`, this version do not satisfy `~1.1.1`, which is -equivalent to `>=1.1.1 <1.2.0`. So the highest-sorting version that satisfies -`~1.1.1` is used, which is `1.1.2`. - -#### Caret Dependencies below 1.0.0 - -Suppose `app` has a caret dependency on a version below `1.0.0`, for example: - -```json -"dependencies": { - "dep1": "^0.2.0" -} -``` - -`npm update` will install `dep1@0.2.0`, because there are no other -versions which satisfy `^0.2.0`. - -If the dependence were on `^0.4.0`: - -```json -"dependencies": { - "dep1": "^0.4.0" -} -``` - -Then `npm update` will install `dep1@0.4.1`, because that is the highest-sorting -version that satisfies `^0.4.0` (`>= 0.4.0 <0.5.0`) - - -#### Subdependencies - -Suppose your app now also has a dependency on `dep2` - -```json -{ - "name": "my-app", - "dependencies": { - "dep1": "^1.0.0", - "dep2": "1.0.0" - } -} -``` - -and `dep2` itself depends on this limited range of `dep1` - -```json -{ -"name": "dep2", - "dependencies": { - "dep1": "~1.1.1" - } -} -``` - -Then `npm update` will install `dep1@1.1.2` because that is the highest -version that `dep2` allows. npm will prioritize having a single version -of `dep1` in your tree rather than two when that single version can -satisfy the semver requirements of multiple dependencies in your tree. -In this case if you really did need your package to use a newer version -you would need to use `npm install`. - - -#### Updating Globally-Installed Packages - -`npm update -g` will apply the `update` action to each globally installed -package that is `outdated` -- that is, has a version that is different from -`wanted`. - -Note: Globally installed packages are treated as if they are installed with a -caret semver range specified. So if you require to update to `latest` you may -need to run `npm install -g [<pkg>...]` - -NOTE: If a package has been upgraded to a version newer than `latest`, it will -be _downgraded_. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm install](/commands/npm-install) -* [npm outdated](/commands/npm-outdated) -* [npm shrinkwrap](/commands/npm-shrinkwrap) -* [npm registry](/using-npm/registry) -* [npm folders](/configuring-npm/folders) -* [npm ls](/commands/npm-ls) diff --git a/docs/content/commands/npm-version.md b/docs/content/commands/npm-version.md deleted file mode 100644 index 8e3334d788984..0000000000000 --- a/docs/content/commands/npm-version.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -title: npm-version -section: 1 -description: Bump a package version ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/version.js --> - -```bash -npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git] - -alias: verison -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/version.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `allow-same-version` - -* Default: false -* Type: Boolean - -Prevents throwing an error when `npm version` is used to set the new version -to the same value as the current version. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `commit-hooks` - -* Default: true -* Type: Boolean - -Run git commit hooks when using the `npm version` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `git-tag-version` - -* Default: true -* Type: Boolean - -Tag the commit when using the `npm version` command. Setting this to false -results in no commit being made at all. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `preid` - -* Default: "" -* Type: String - -The "prerelease identifier" to use as a prefix for the "prerelease" part of -a semver. Like the `rc` in `1.2.0-rc.8`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `sign-git-tag` - -* Default: false -* Type: Boolean - -If set to true, then the `npm version` command will tag the version using -`-s` to add a signature. - -Note that git requires you to have set up GPG keys in your git configs for -this to work properly. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces-update` - -* Default: true -* Type: Boolean - -If set to true, the npm cli will run an update after operations that may -possibly change the workspaces installed to the `node_modules` folder. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### Description - -Run this in a package directory to bump the version and write the new data -back to `package.json`, `package-lock.json`, and, if present, -`npm-shrinkwrap.json`. - -The `newversion` argument should be a valid semver string, a valid second -argument to [semver.inc](https://github.com/npm/node-semver#functions) (one -of `patch`, `minor`, `major`, `prepatch`, `preminor`, `premajor`, -`prerelease`), or `from-git`. In the second case, the existing version will -be incremented by 1 in the specified field. `from-git` will try to read -the latest git tag, and use that as the new npm version. - -If run in a git repo, it will also create a version commit and tag. This -behavior is controlled by `git-tag-version` (see below), and can be -disabled on the command line by running `npm --no-git-tag-version version`. -It will fail if the working directory is not clean, unless the `-f` or -`--force` flag is set. - -If supplied with `-m` or `--message` config option, npm will use it as a -commit message when creating a version commit. If the `message` config -contains `%s` then that will be replaced with the resulting version number. -For example: - -```bash -npm version patch -m "Upgrade to %s for reasons" -``` - -If the `sign-git-tag` config is set, then the tag will be signed using the -`-s` flag to git. Note that you must have a default GPG key set up in your -git config for this to work properly. For example: - -```bash -$ npm config set sign-git-tag true -$ npm version patch - -You need a passphrase to unlock the secret key for -user: "isaacs (http://blog.izs.me/) <i@izs.me>" -2048-bit RSA key, ID 6C481CF6, created 2010-08-31 - -Enter passphrase: -``` - -If `preversion`, `version`, or `postversion` are in the `scripts` property -of the package.json, they will be executed as part of running `npm -version`. - -The exact order of execution is as follows: - -1. Check to make sure the git working directory is clean before we get - started. Your scripts may add files to the commit in future steps. - This step is skipped if the `--force` flag is set. -2. Run the `preversion` script. These scripts have access to the old - `version` in package.json. A typical use would be running your full - test suite before deploying. Any files you want added to the commit - should be explicitly added using `git add`. -3. Bump `version` in `package.json` as requested (`patch`, `minor`, - `major`, etc). -4. Run the `version` script. These scripts have access to the new `version` - in package.json (so they can incorporate it into file headers in - generated files for example). Again, scripts should explicitly add - generated files to the commit using `git add`. -5. Commit and tag. -6. Run the `postversion` script. Use it to clean up the file system or - automatically push the commit and/or tag. - -Take the following example: - -```json -{ - "scripts": { - "preversion": "npm test", - "version": "npm run build && git add -A dist", - "postversion": "git push && git push --tags && rm -rf build/temp" - } -} -``` - -This runs all your tests and proceeds only if they pass. Then runs your -`build` script, and adds everything in the `dist` directory to the commit. -After the commit, it pushes the new commit and tag up to the server, and -deletes the `build/temp` directory. - -### See Also - -* [npm init](/commands/npm-init) -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [package.json](/configuring-npm/package-json) -* [config](/using-npm/config) diff --git a/docs/content/commands/npm-view.md b/docs/content/commands/npm-view.md deleted file mode 100644 index d9d1daac0cda7..0000000000000 --- a/docs/content/commands/npm-view.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: npm-view -section: 1 -description: View registry info ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/view.js --> - -```bash -npm view [<package-spec>] [<field>[.subfield]...] - -aliases: info, show, v -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/view.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command shows data about a package and prints it to stdout. - -As an example, to view information about the `connect` package from the registry, you would run: - -```bash -npm view connect -``` - -The default version is `"latest"` if unspecified. - -Field names can be specified after the package descriptor. -For example, to show the dependencies of the `ronn` package at version -`0.3.5`, you could do the following: - -```bash -npm view ronn@0.3.5 dependencies -``` - -You can view child fields by separating them with a period. -To view the git repository URL for the latest version of `npm`, you would run the following command: - -```bash -npm view npm repository.url -``` - -This makes it easy to view information about a dependency with a bit of -shell scripting. For example, to view all the data about the version of -`opts` that `ronn` depends on, you could write the following: - -```bash -npm view opts@$(npm view ronn dependencies.opts) -``` - -For fields that are arrays, requesting a non-numeric field will return -all of the values from the objects in the list. For example, to get all -the contributor email addresses for the `express` package, you would run: - -```bash -npm view express contributors.email -``` - -You may also use numeric indices in square braces to specifically select -an item in an array field. To just get the email address of the first -contributor in the list, you can run: - -```bash -npm view express contributors[0].email -``` - -Multiple fields may be specified, and will be printed one after another. -For example, to get all the contributor names and email addresses, you -can do this: - -```bash -npm view express contributors.name contributors.email -``` - -"Person" fields are shown as a string if they would be shown as an -object. So, for example, this will show the list of `npm` contributors in -the shortened string format. (See [`package.json`](/configuring-npm/package-json) for more on this.) - -```bash -npm view npm contributors -``` - -If a version range is provided, then data will be printed for every -matching version of the package. This will show which version of `jsdom` -was required by each matching version of `yui3`: - -```bash -npm view yui3@'>0.5.4' dependencies.jsdom -``` - -To show the `connect` package version history, you can do -this: - -```bash -npm view connect versions -``` - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### Output - -If only a single string field for a single version is output, then it -will not be colorized or quoted, to enable piping the output to -another command. If the field is an object, it will be output as a JavaScript object literal. - -If the `--json` flag is given, the outputted fields will be JSON. - -If the version range matches multiple versions then each printed value -will be prefixed with the version it applies to. - -If multiple fields are requested, then each of them is prefixed with -the field name. - -### See Also - -* [package spec](/using-npm/package-spec) -* [npm search](/commands/npm-search) -* [npm registry](/using-npm/registry) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm docs](/commands/npm-docs) diff --git a/docs/content/commands/npm-whoami.md b/docs/content/commands/npm-whoami.md deleted file mode 100644 index 18416f633a1d8..0000000000000 --- a/docs/content/commands/npm-whoami.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: npm-whoami -section: 1 -description: Display npm username ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/whoami.js --> - -```bash -npm whoami -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/whoami.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -Note: This command is unaware of workspaces. - -### Description - -Display the npm username of the currently logged-in user. - -If logged into a registry that provides token-based authentication, then -connect to the `/-/whoami` registry endpoint to find the username -associated with the token, and print to standard output. - -If logged into a registry that uses Basic Auth, then simply print the -`username` portion of the authentication string. - -### Configuration - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See Also - -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm adduser](/commands/npm-adduser) diff --git a/docs/content/commands/npm.md b/docs/content/commands/npm.md deleted file mode 100644 index 18a68d03cd44f..0000000000000 --- a/docs/content/commands/npm.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: npm -section: 1 -description: javascript package manager ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Version - -@VERSION@ - -### 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 -conflicts intelligently. - -It is extremely configurable to support a variety of use cases. Most -commonly, you use it to publish, discover, install, and develop node -programs. - -Run `npm help` to get a list of available commands. - -### Important - -npm comes preconfigured to use npm's public registry at -https://registry.npmjs.org by default. Use of the npm public registry is -subject to terms of use available at -https://docs.npmjs.com/policies/terms. - -You can configure npm to use any compatible registry you like, and even -run your own registry. Use of someone else's registry is governed by -their terms of use. - -### Introduction - -You probably got npm because you want to install stuff. - -The very first thing you will most likely want to run in any node -program is `npm install` to install its dependencies. - -You can also run `npm install blerg` to install the latest version of -"blerg". Check out [`npm install`](/commands/npm-install) for more -info. It can do a lot of stuff. - -Use the `npm search` command to show everything that's available in the -public registry. Use `npm ls` to show everything you've installed. - -### Dependencies - -If a package lists a dependency using a git URL, npm will install that -dependency using the [`git`](https://github.com/git-guides/install-git) -command and will generate an error if it is not installed. - -If one of the packages npm tries to install is a native node module and -requires compiling of C++ Code, npm will use -[node-gyp](https://github.com/nodejs/node-gyp) for that task. -For a Unix system, [node-gyp](https://github.com/nodejs/node-gyp) -needs Python, make and a buildchain like GCC. On Windows, -Python and Microsoft Visual Studio C++ are needed. For more information -visit [the node-gyp repository](https://github.com/nodejs/node-gyp) and -the [node-gyp Wiki](https://github.com/nodejs/node-gyp/wiki). - -### Directories - -See [`folders`](/configuring-npm/folders) to learn about where npm puts -stuff. - -In particular, npm has two modes of operation: - -* local mode: - npm installs packages into the current project directory, which - defaults to the current working directory. Packages install to - `./node_modules`, and bins to `./node_modules/.bin`. -* global mode: - npm installs packages into the install prefix at - `$npm_config_prefix/lib/node_modules` and bins to - `$npm_config_prefix/bin`. - -Local mode is the default. Use `-g` or `--global` on any command to -run in global mode instead. - -### Developer Usage - -If you're using npm to develop and publish your code, check out the -following help topics: - -* json: - Make a package.json file. See - [`package.json`](/configuring-npm/package-json). -* link: - Links your current working code into Node's path, so that you don't - have to reinstall every time you make a change. Use [`npm - link`](/commands/npm-link) to do this. -* install: - It's a good idea to install things if you don't need the symbolic - link. Especially, installing other peoples code from the registry is - done via [`npm install`](/commands/npm-install) -* adduser: - Create an account or log in. When you do this, npm will store - credentials in the user config file. -* publish: - Use the [`npm publish`](/commands/npm-publish) command to upload your - code to the registry. - -#### Configuration - -npm is extremely configurable. It reads its configuration options from -5 places. - -* Command line switches: - Set a config with `--key val`. All keys take a value, even if they - are booleans (the config parser doesn't know what the options are at - the time of parsing). If you do not provide a value (`--key`) then - the option is set to boolean `true`. -* Environment Variables: - Set any config by prefixing the name in an environment variable with - `npm_config_`. For example, `export npm_config_key=val`. -* User Configs: - The file at `$HOME/.npmrc` is an ini-formatted list of configs. If - present, it is parsed. If the `userconfig` option is set in the cli - or env, that file will be used instead. -* Global Configs: - The file found at `./etc/npmrc` (relative to the global prefix will be - parsed if it is found. See [`npm prefix`](/commands/npm-prefix) for - more info on the global prefix. If the `globalconfig` option is set - in the cli, env, or user config, then that file is parsed instead. -* Defaults: - npm's default configuration options are defined in - lib/utils/config-defs.js. These must not be changed. - -See [`config`](/using-npm/config) for much much more information. - -### Contributions - -Patches welcome! - -If you would like to help, but don't know what to work on, read the -[contributing -guidelines](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md) and -check the issues list. - -### Bugs - -When you find issues, please report them: -<https://github.com/npm/cli/issues> - -Please be sure to follow the template and bug reporting guidelines. - -### Feature Requests - -Discuss new feature ideas on our discussion forum: - -* <https://github.com/npm/feedback> - -Or suggest formal RFC proposals: - -* <https://github.com/npm/rfcs> - -### See Also - -* [npm help](/commands/npm-help) -* [package.json](/configuring-npm/package-json) -* [npmrc](/configuring-npm/npmrc) -* [npm config](/commands/npm-config) -* [npm install](/commands/npm-install) -* [npm prefix](/commands/npm-prefix) -* [npm publish](/commands/npm-publish) diff --git a/docs/content/commands/npx.md b/docs/content/commands/npx.md deleted file mode 100644 index e7e59d00d84c1..0000000000000 --- a/docs/content/commands/npx.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: npx -section: 1 -description: Run a command from a local or remote npm package ---- - -### Synopsis - -<!-- AUTOGENERATED USAGE DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/exec.js --> - -```bash -npx -- <pkg>[@<version>] [args...] -npx --package=<pkg>[@<version>] -- <cmd> [args...] -npx -c '<cmd> [args...]' -npx --package=foo -c '<cmd> [args...]' -``` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/commands/exec.js --> - -<!-- AUTOGENERATED USAGE DESCRIPTIONS END --> - -### Description - -This command allows you to run an arbitrary command from an npm package -(either one installed locally, or fetched remotely), in a similar context -as running it via `npm run`. - -Whatever packages are specified by the `--package` option will be -provided in the `PATH` of the executed command, along with any locally -installed package executables. The `--package` option may be -specified multiple times, to execute the supplied command in an environment -where all specified packages are available. - -If any requested packages are not present in the local project -dependencies, then they are installed to a folder in the npm cache, which -is added to the `PATH` environment variable in the executed process. A -prompt is printed (which can be suppressed by providing either `--yes` or -`--no`). - -Package names provided without a specifier will be matched with whatever -version exists in the local project. Package names with a specifier will -only be considered a match if they have the exact same name and version as -the local dependency. - -If no `-c` or `--call` option is provided, then the positional arguments -are used to generate the command string. If no `--package` options -are provided, then npm will attempt to determine the executable name from -the package specifier provided as the first positional argument according -to the following heuristic: - -- If the package has a single entry in its `bin` field in `package.json`, - or if all entries are aliases of the same command, then that command - will be used. -- If the package has multiple `bin` entries, and one of them matches the - unscoped portion of the `name` field, then that command will be used. -- If this does not result in exactly one option (either because there are - no bin entries, or none of them match the `name` of the package), then - `npm exec` exits with an error. - -To run a binary _other than_ the named binary, specify one or more -`--package` options, which will prevent npm from inferring the package from -the first command argument. - -### `npx` vs `npm exec` - -When run via the `npx` binary, all flags and options *must* be set prior to -any positional arguments. When run via `npm exec`, a double-hyphen `--` -flag can be used to suppress npm's parsing of switches and options that -should be sent to the executed command. - -For example: - -``` -$ npx foo@latest bar --package=@npmcli/foo -``` - -In this case, npm will resolve the `foo` package name, and run the -following command: - -``` -$ foo bar --package=@npmcli/foo -``` - -Since the `--package` option comes _after_ the positional arguments, it is -treated as an argument to the executed command. - -In contrast, due to npm's argument parsing logic, running this command is -different: - -``` -$ npm exec foo@latest bar --package=@npmcli/foo -``` - -In this case, npm will parse the `--package` option first, resolving the -`@npmcli/foo` package. Then, it will execute the following command in that -context: - -``` -$ foo@latest bar -``` - -The double-hyphen character is recommended to explicitly tell npm to stop -parsing command line options and switches. The following command would -thus be equivalent to the `npx` command above: - -``` -$ npm exec -- foo@latest bar --package=@npmcli/foo -``` - -### Examples - -Run the version of `tap` in the local dependencies, with the provided -arguments: - -``` -$ npm exec -- tap --bail test/foo.js -$ npx tap --bail test/foo.js -``` - -Run a command _other than_ the command whose name matches the package name -by specifying a `--package` option: - -``` -$ npm exec --package=foo -- bar --bar-argument -# ~ or ~ -$ npx --package=foo bar --bar-argument -``` - -Run an arbitrary shell script, in the context of the current project: - -``` -$ npm x -c 'eslint && say "hooray, lint passed"' -$ npx -c 'eslint && say "hooray, lint passed"' -``` - -### Compatibility with Older npx Versions - -The `npx` binary was rewritten in npm v7.0.0, and the standalone `npx` -package deprecated at that time. `npx` uses the `npm exec` -command instead of a separate argument parser and install process, with -some affordances to maintain backwards compatibility with the arguments it -accepted in previous versions. - -This resulted in some shifts in its functionality: - -- Any `npm` config value may be provided. -- To prevent security and user-experience problems from mistyping package - names, `npx` prompts before installing anything. Suppress this - prompt with the `-y` or `--yes` option. -- The `--no-install` option is deprecated, and will be converted to `--no`. -- Shell fallback functionality is removed, as it is not advisable. -- The `-p` argument is a shorthand for `--parseable` in npm, but shorthand - for `--package` in npx. This is maintained, but only for the `npx` - executable. -- The `--ignore-existing` option is removed. Locally installed bins are - always present in the executed process `PATH`. -- The `--npm` option is removed. `npx` will always use the `npm` it ships - with. -- The `--node-arg` and `-n` options are removed. -- The `--always-spawn` option is redundant, and thus removed. -- The `--shell` option is replaced with `--script-shell`, but maintained - in the `npx` executable for backwards compatibility. - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [npm scripts](/using-npm/scripts) -* [npm test](/commands/npm-test) -* [npm start](/commands/npm-start) -* [npm restart](/commands/npm-restart) -* [npm stop](/commands/npm-stop) -* [npm config](/commands/npm-config) -* [npm exec](/commands/npm-exec) diff --git a/docs/content/configuring-npm/folders.md b/docs/content/configuring-npm/folders.md deleted file mode 100644 index 5bab80ec169c5..0000000000000 --- a/docs/content/configuring-npm/folders.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: folders -section: 5 -description: Folder Structures Used by npm ---- - -### Description - -npm puts various things on your computer. That's its job. - -This document will tell you what it puts where. - -#### tl;dr - -* Local install (default): puts stuff in `./node_modules` of the current - package root. -* Global install (with `-g`): puts stuff in /usr/local or wherever node - is installed. -* Install it **locally** if you're going to `require()` it. -* Install it **globally** if you're going to run it on the command line. -* If you need both, then install it in both places, or use `npm link`. - -#### prefix Configuration - -The `prefix` config defaults to the location where node is installed. -On most systems, this is `/usr/local`. On Windows, it's `%AppData%\npm`. -On Unix systems, it's one level up, since node is typically installed at -`{prefix}/bin/node` rather than `{prefix}/node.exe`. - -When the `global` flag is set, npm installs things into this prefix. -When it is not set, it uses the root of the current package, or the -current working directory if not in a package already. - -#### Node Modules - -Packages are dropped into the `node_modules` folder under the `prefix`. -When installing locally, this means that you can -`require("packagename")` to load its main module, or -`require("packagename/lib/path/to/sub/module")` to load other modules. - -Global installs on Unix systems go to `{prefix}/lib/node_modules`. -Global installs on Windows go to `{prefix}/node_modules` (that is, no -`lib` folder.) - -Scoped packages are installed the same way, except they are grouped together -in a sub-folder of the relevant `node_modules` folder with the name of that -scope prefix by the @ symbol, e.g. `npm install @myorg/package` would place -the package in `{prefix}/node_modules/@myorg/package`. See -[`scope`](/using-npm/scope) for more details. - -If you wish to `require()` a package, then install it locally. - -#### Executables - -When in global mode, executables are linked into `{prefix}/bin` on Unix, -or directly into `{prefix}` on Windows. Ensure that path is in your -terminal's `PATH` environment to run them. - -When in local mode, executables are linked into -`./node_modules/.bin` so that they can be made available to scripts run -through npm. (For example, so that a test runner will be in the path -when you run `npm test`.) - -#### Man Pages - -When in global mode, man pages are linked into `{prefix}/share/man`. - -When in local mode, man pages are not installed. - -Man pages are not installed on Windows systems. - -#### Cache - -See [`npm cache`](/commands/npm-cache). Cache files are stored in `~/.npm` on Posix, or -`%AppData%/npm-cache` on Windows. - -This is controlled by the `cache` configuration param. - -#### Temp Files - -Temporary files are stored by default in the folder specified by the -`tmp` config, which defaults to the TMPDIR, TMP, or TEMP environment -variables, or `/tmp` on Unix and `c:\windows\temp` on Windows. - -Temp files are given a unique folder under this root for each run of the -program, and are deleted upon successful exit. - -### More Information - -When installing locally, npm first tries to find an appropriate -`prefix` folder. This is so that `npm install foo@1.2.3` will install -to the sensible root of your package, even if you happen to have `cd`ed -into some other folder. - -Starting at the $PWD, npm will walk up the folder tree checking for a -folder that contains either a `package.json` file, or a `node_modules` -folder. If such a thing is found, then that is treated as the effective -"current directory" for the purpose of running npm commands. (This -behavior is inspired by and similar to git's .git-folder seeking -logic when running git commands in a working dir.) - -If no package root is found, then the current folder is used. - -When you run `npm install foo@1.2.3`, then the package is loaded into -the cache, and then unpacked into `./node_modules/foo`. Then, any of -foo's dependencies are similarly unpacked into -`./node_modules/foo/node_modules/...`. - -Any bin files are symlinked to `./node_modules/.bin/`, so that they may -be found by npm scripts when necessary. - -#### Global Installation - -If the `global` configuration is set to true, then npm will -install packages "globally". - -For global installation, packages are installed roughly the same way, -but using the folders described above. - -#### Cycles, Conflicts, and Folder Parsimony - -Cycles are handled using the property of node's module system that it -walks up the directories looking for `node_modules` folders. So, at every -stage, if a package is already installed in an ancestor `node_modules` -folder, then it is not installed at the current location. - -Consider the case above, where `foo -> bar -> baz`. Imagine if, in -addition to that, baz depended on bar, so you'd have: -`foo -> bar -> baz -> bar -> baz ...`. However, since the folder -structure is: `foo/node_modules/bar/node_modules/baz`, there's no need to -put another copy of bar into `.../baz/node_modules`, since when it calls -require("bar"), it will get the copy that is installed in -`foo/node_modules/bar`. - -This shortcut is only used if the exact same -version would be installed in multiple nested `node_modules` folders. It -is still possible to have `a/node_modules/b/node_modules/a` if the two -"a" packages are different versions. However, without repeating the -exact same package multiple times, an infinite regress will always be -prevented. - -Another optimization can be made by installing dependencies at the -highest level possible, below the localized "target" folder. - -#### Example - -Consider this dependency graph: - -```bash -foo -+-- blerg@1.2.5 -+-- bar@1.2.3 -| +-- blerg@1.x (latest=1.3.7) -| +-- baz@2.x -| | `-- quux@3.x -| | `-- bar@1.2.3 (cycle) -| `-- asdf@* -`-- baz@1.2.3 - `-- quux@3.x - `-- bar -``` - -In this case, we might expect a folder structure like this: - -```bash -foo -+-- node_modules - +-- blerg (1.2.5) <---[A] - +-- bar (1.2.3) <---[B] - | `-- node_modules - | +-- baz (2.0.2) <---[C] - | | `-- node_modules - | | `-- quux (3.2.0) - | `-- asdf (2.3.4) - `-- baz (1.2.3) <---[D] - `-- node_modules - `-- quux (3.2.0) <---[E] -``` - -Since foo depends directly on `bar@1.2.3` and `baz@1.2.3`, those are -installed in foo's `node_modules` folder. - -Even though the latest copy of blerg is 1.3.7, foo has a specific -dependency on version 1.2.5. So, that gets installed at [A]. Since the -parent installation of blerg satisfies bar's dependency on `blerg@1.x`, -it does not install another copy under [B]. - -Bar [B] also has dependencies on baz and asdf, so those are installed in -bar's `node_modules` folder. Because it depends on `baz@2.x`, it cannot -re-use the `baz@1.2.3` installed in the parent `node_modules` folder [D], -and must install its own copy [C]. - -Underneath bar, the `baz -> quux -> bar` dependency creates a cycle. -However, because bar is already in quux's ancestry [B], it does not -unpack another copy of bar into that folder. - -Underneath `foo -> baz` [D], quux's [E] folder tree is empty, because its -dependency on bar is satisfied by the parent folder copy installed at [B]. - -For a graphical breakdown of what is installed where, use `npm ls`. - -#### Publishing - -Upon publishing, npm will look in the `node_modules` folder. If any of -the items there are not in the `bundleDependencies` array, then they will -not be included in the package tarball. - -This allows a package maintainer to install all of their dependencies -(and dev dependencies) locally, but only re-publish those items that -cannot be found elsewhere. See [`package.json`](/configuring-npm/package-json) for more information. - -### See also - -* [package.json](/configuring-npm/package-json) -* [npm install](/commands/npm-install) -* [npm pack](/commands/npm-pack) -* [npm cache](/commands/npm-cache) -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [config](/using-npm/config) -* [npm publish](/commands/npm-publish) diff --git a/docs/content/configuring-npm/install.md b/docs/content/configuring-npm/install.md deleted file mode 100644 index 43fce4868ba97..0000000000000 --- a/docs/content/configuring-npm/install.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: install -section: 5 -description: Download and install node and npm ---- - -### Description - -To publish and install packages to and from the public npm registry, you -must install Node.js and the npm command line interface using either a Node -version manager or a Node installer. **We strongly recommend using a Node -version manager to install Node.js and npm.** We do not recommend using a -Node installer, since the Node installation process installs npm in a -directory with local permissions and can cause permissions errors when you -run npm packages globally. - -### Overview - -- [Checking your version of npm and - Node.js](#checking-your-version-of-npm-and-node-js) -- [Using a Node version manager to install Node.js and - npm](#using-a-node-version-manager-to-install-node-js-and-npm) -- [Using a Node installer to install Node.js and - npm](#using-a-node-installer-to-install-node-js-and-npm) - -### Checking your version of npm and Node.js - -To see if you already have Node.js and npm installed and check the -installed version, run the following commands: - -``` -node -v -npm -v -``` - -### Using a Node version manager to install Node.js and npm - -Node version managers allow you to install and switch between multiple -versions of Node.js and npm on your system so you can test your -applications on multiple versions of npm to ensure they work for users on -different versions. - -#### OSX or Linux Node version managers - -* [nvm](https://github.com/creationix/nvm) -* [n](https://github.com/tj/n) - -#### Windows Node version managers - -* [nodist](https://github.com/marcelklehr/nodist) -* [nvm-windows](https://github.com/coreybutler/nvm-windows) - -### Using a Node installer to install Node.js and npm - -If you are unable to use a Node version manager, you can use a Node -installer to install both Node.js and npm on your system. - -* [Node.js installer](https://nodejs.org/en/download/) -* [NodeSource installer](https://github.com/nodesource/distributions). If - you use Linux, we recommend that you use a NodeSource installer. - -#### OS X or Windows Node installers - -If you're using OS X or Windows, use one of the installers from the -[Node.js download page](https://nodejs.org/en/download/). Be sure to -install the version labeled **LTS**. Other versions have not yet been -tested with npm. - -#### Linux or other operating systems Node installers - -If you're using Linux or another operating system, use one of the following -installers: - -- [NodeSource installer](https://github.com/nodesource/distributions) - (recommended) -- One of the installers on the [Node.js download - page](https://nodejs.org/en/download/) - -Or see [this page](https://nodejs.org/en/download/package-manager/) to -install npm for Linux in the way many Linux developers prefer. - -#### Less-common operating systems - -For more information on installing Node.js on a variety of operating -systems, see [this page][pkg-mgr]. - -[pkg-mgr]: https://nodejs.org/en/download/package-manager/ diff --git a/docs/content/configuring-npm/npm-shrinkwrap-json.md b/docs/content/configuring-npm/npm-shrinkwrap-json.md deleted file mode 100644 index ab0a241079380..0000000000000 --- a/docs/content/configuring-npm/npm-shrinkwrap-json.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: npm-shrinkwrap.json -section: 5 -description: A publishable lockfile ---- - -### Description - -`npm-shrinkwrap.json` is a file created by [`npm -shrinkwrap`](/commands/npm-shrinkwrap). It is identical to -`package-lock.json`, with one major caveat: Unlike `package-lock.json`, -`npm-shrinkwrap.json` may be included when publishing a package. - -The recommended use-case for `npm-shrinkwrap.json` is applications deployed -through the publishing process on the registry: for example, daemons and -command-line tools intended as global installs or `devDependencies`. It's -strongly discouraged for library authors to publish this file, since that -would prevent end users from having control over transitive dependency -updates. - -If both `package-lock.json` and `npm-shrinkwrap.json` are present in a -package root, `npm-shrinkwrap.json` will be preferred over the -`package-lock.json` file. - -For full details and description of the `npm-shrinkwrap.json` file format, -refer to the manual page for -[package-lock.json](/configuring-npm/package-lock-json). - -### See also - -* [npm shrinkwrap](/commands/npm-shrinkwrap) -* [package-lock.json](/configuring-npm/package-lock-json) -* [package.json](/configuring-npm/package-json) -* [npm install](/commands/npm-install) diff --git a/docs/content/configuring-npm/npmrc.md b/docs/content/configuring-npm/npmrc.md deleted file mode 100644 index 83310ffa9c7f2..0000000000000 --- a/docs/content/configuring-npm/npmrc.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: npmrc -section: 5 -description: The npm config files ---- - -### Description - -npm gets its config settings from the command line, environment variables, -and `npmrc` files. - -The `npm config` command can be used to update and edit the contents of the -user and global npmrc files. - -For a list of available configuration options, see -[config](/using-npm/config). - -### Files - -The four relevant files are: - -* per-project config file (/path/to/my/project/.npmrc) -* per-user config file (~/.npmrc) -* global config file ($PREFIX/etc/npmrc) -* npm builtin config file (/path/to/npm/npmrc) - -All npm config files are an ini-formatted list of `key = value` parameters. -Environment variables can be replaced using `${VARIABLE_NAME}`. For -example: - -```bash -prefix = ${HOME}/.npm-packages -``` - -Each of these files is loaded, and config options are resolved in priority -order. For example, a setting in the userconfig file would override the -setting in the globalconfig file. - -Array values are specified by adding "[]" after the key name. For example: - -```bash -key[] = "first value" -key[] = "second value" -``` - -#### Comments - -Lines in `.npmrc` files are interpreted as comments when they begin with a -`;` or `#` character. `.npmrc` files are parsed by -[npm/ini](https://github.com/npm/ini), which specifies this comment syntax. - -For example: - -```bash -# last modified: 01 Jan 2016 -; Set a new registry for a scoped package -@myscope:registry=https://mycustomregistry.example.org -``` - -#### Per-project config file - -When working locally in a project, a `.npmrc` file in the root of the -project (ie, a sibling of `node_modules` and `package.json`) will set -config values specific to this project. - -Note that this only applies to the root of the project that you're running -npm in. It has no effect when your module is published. For example, you -can't publish a module that forces itself to install globally, or in a -different location. - -Additionally, this file is not read in global mode, such as when running -`npm install -g`. - -#### Per-user config file - -`$HOME/.npmrc` (or the `userconfig` param, if set in the environment or on -the command line) - -#### Global config file - -`$PREFIX/etc/npmrc` (or the `globalconfig` param, if set above): This file -is an ini-file formatted list of `key = value` parameters. Environment -variables can be replaced as above. - -#### Built-in config file - -`path/to/npm/itself/npmrc` - -This is an unchangeable "builtin" configuration file that npm keeps -consistent across updates. Set fields in here using the `./configure` -script that comes with npm. This is primarily for distribution maintainers -to override default configs in a standard and consistent manner. - -### See also - -* [npm folders](/configuring-npm/folders) -* [npm config](/commands/npm-config) -* [config](/using-npm/config) -* [package.json](/configuring-npm/package-json) -* [npm](/commands/npm) diff --git a/docs/content/configuring-npm/package-json.md b/docs/content/configuring-npm/package-json.md deleted file mode 100644 index b0231662f6930..0000000000000 --- a/docs/content/configuring-npm/package-json.md +++ /dev/null @@ -1,1170 +0,0 @@ ---- -title: package.json -section: 5 -description: Specifics of npm's package.json handling ---- - -### Description - -This document is all you need to know about what's required in your -package.json file. It must be actual JSON, not just a JavaScript object -literal. - -A lot of the behavior described in this document is affected by the config -settings described in [`config`](/using-npm/config). - -### name - -If you plan to publish your package, the *most* important things in your -package.json are the name and version fields as they will be required. The -name and version together form an identifier that is assumed to be -completely unique. Changes to the package should come along with changes -to the version. If you don't plan to publish your package, the name and -version fields are optional. - -The name is what your thing is called. - -Some rules: - -* The name must be less than or equal to 214 characters. This includes the - scope for scoped packages. -* The names of scoped packages can begin with a dot or an underscore. This - is not permitted without a scope. -* New packages must not have uppercase letters in the name. -* The name ends up being part of a URL, an argument on the command line, - and a folder name. Therefore, the name can't contain any non-URL-safe - characters. - -Some tips: - -* Don't use the same name as a core Node module. -* Don't put "js" or "node" in the name. It's assumed that it's js, since - you're writing a package.json file, and you can specify the engine using - the "engines" field. (See below.) -* The name will probably be passed as an argument to require(), so it - should be something short, but also reasonably descriptive. -* You may want to check the npm registry to see if there's something by - that name already, before you get too attached to it. - <https://www.npmjs.com/> - -A name can be optionally prefixed by a scope, e.g. `@myorg/mypackage`. See -[`scope`](/using-npm/scope) for more detail. - -### version - -If you plan to publish your package, the *most* important things in your -package.json are the name and version fields as they will be required. The -name and version together form an identifier that is assumed to be -completely unique. Changes to the package should come along with changes -to the version. If you don't plan to publish your package, the name and -version fields are optional. - -Version must be parseable by -[node-semver](https://github.com/npm/node-semver), which is bundled with -npm as a dependency. (`npm install semver` to use it yourself.) - -### description - -Put a description in it. It's a string. This helps people discover your -package, as it's listed in `npm search`. - -### keywords - -Put keywords in it. It's an array of strings. This helps people discover -your package as it's listed in `npm search`. - -### homepage - -The url to the project homepage. - -Example: - -```json -"homepage": "https://github.com/owner/project#readme" -``` - -### bugs - -The url to your project's issue tracker and / or the email address to which -issues should be reported. These are helpful for people who encounter -issues with your package. - -It should look like this: - -```json -{ - "url" : "https://github.com/owner/project/issues", - "email" : "project@hostname.com" -} -``` - -You can specify either one or both values. If you want to provide only a -url, you can specify the value for "bugs" as a simple string instead of an -object. - -If a url is provided, it will be used by the `npm bugs` command. - -### license - -You should specify a license for your package so that people know how they -are permitted to use it, and any restrictions you're placing on it. - -If you're using a common license such as BSD-2-Clause or MIT, add a current -SPDX license identifier for the license you're using, like this: - -```json -{ - "license" : "BSD-3-Clause" -} -``` - -You can check [the full list of SPDX license -IDs](https://spdx.org/licenses/). Ideally you should pick one that is -[OSI](https://opensource.org/licenses/alphabetical) approved. - -If your package is licensed under multiple common licenses, use an [SPDX -license expression syntax version 2.0 -string](https://spdx.dev/specifications/), like this: - -```json -{ - "license" : "(ISC OR GPL-3.0)" -} -``` -If you are using a license that hasn't been assigned an SPDX identifier, or if -you are using a custom license, use a string value like this one: - -```json -{ - "license" : "SEE LICENSE IN <filename>" -} -``` -Then include a file named `<filename>` at the top level of the package. - -Some old packages used license objects or a "licenses" property containing -an array of license objects: - -```json -// Not valid metadata -{ - "license" : { - "type" : "ISC", - "url" : "https://opensource.org/licenses/ISC" - } -} - -// Not valid metadata -{ - "licenses" : [ - { - "type": "MIT", - "url": "https://www.opensource.org/licenses/mit-license.php" - }, - { - "type": "Apache-2.0", - "url": "https://opensource.org/licenses/apache2.0.php" - } - ] -} -``` - -Those styles are now deprecated. Instead, use SPDX expressions, like this: - -```json -{ - "license": "ISC" -} -``` - -```json -{ - "license": "(MIT OR Apache-2.0)" -} -``` - -Finally, if you do not wish to grant others the right to use a private or -unpublished package under any terms: - -```json -{ - "license": "UNLICENSED" -} -``` - -Consider also setting `"private": true` to prevent accidental publication. - -### people fields: author, contributors - -The "author" is one person. "contributors" is an array of people. A -"person" is an object with a "name" field and optionally "url" and "email", -like this: - -```json -{ - "name" : "Barney Rubble", - "email" : "b@rubble.com", - "url" : "http://barnyrubble.tumblr.com/" -} -``` - -Or you can shorten that all into a single string, and npm will parse it for -you: - -```json -{ - "author": "Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)" -} -``` - -Both email and url are optional either way. - -npm also sets a top-level "maintainers" field with your npm user info. - -### funding - -You can specify an object containing a URL that provides up-to-date -information about ways to help fund development of your package, or a -string URL, or an array of these: - -```json -{ - "funding": { - "type" : "individual", - "url" : "http://example.com/donate" - }, - - "funding": { - "type" : "patreon", - "url" : "https://www.patreon.com/my-account" - }, - - "funding": "http://example.com/donate", - - "funding": [ - { - "type" : "individual", - "url" : "http://example.com/donate" - }, - "http://example.com/donateAlso", - { - "type" : "patreon", - "url" : "https://www.patreon.com/my-account" - } - ] -} -``` - -Users can use the `npm fund` subcommand to list the `funding` URLs of all -dependencies of their project, direct and indirect. A shortcut to visit -each funding url is also available when providing the project name such as: -`npm fund <projectname>` (when there are multiple URLs, the first one will -be visited) - -### files - -The optional `files` field is an array of file patterns that describes the -entries to be included when your package is installed as a dependency. File -patterns follow a similar syntax to `.gitignore`, but reversed: including a -file, directory, or glob pattern (`*`, `**/*`, and such) will make it so -that file is included in the tarball when it's packed. Omitting the field -will make it default to `["*"]`, which means it will include all files. - -Some special files and directories are also included or excluded regardless -of whether they exist in the `files` array (see below). - -You can also provide a `.npmignore` file in the root of your package or in -subdirectories, which will keep files from being included. At the root of -your package it will not override the "files" field, but in subdirectories -it will. The `.npmignore` file works just like a `.gitignore`. If there is -a `.gitignore` file, and `.npmignore` is missing, `.gitignore`'s contents -will be used instead. - -Files included with the "package.json#files" field _cannot_ be excluded -through `.npmignore` or `.gitignore`. - -Certain files are always included, regardless of settings: - -* `package.json` -* `README` -* `LICENSE` / `LICENCE` -* The file in the "main" field - -`README` & `LICENSE` can have any case and extension. - -Conversely, some files are always ignored: - -* `.git` -* `CVS` -* `.svn` -* `.hg` -* `.lock-wscript` -* `.wafpickle-N` -* `.*.swp` -* `.DS_Store` -* `._*` -* `npm-debug.log` -* `.npmrc` -* `node_modules` -* `config.gypi` -* `*.orig` -* `package-lock.json` (use - [`npm-shrinkwrap.json`](/configuring-npm/npm-shrinkwrap-json) if you wish - it to be published) - -### main - -The main field is a module ID that is the primary entry point to your -program. That is, if your package is named `foo`, and a user installs it, -and then does `require("foo")`, then your main module's exports object will -be returned. - -This should be a module relative to the root of your package folder. - -For most modules, it makes the most sense to have a main script and often -not much else. - -If `main` is not set it defaults to `index.js` in the package's root folder. - -### browser - -If your module is meant to be used client-side the browser field should be -used instead of the main field. This is helpful to hint users that it might -rely on primitives that aren't available in Node.js modules. (e.g. -`window`) - -### bin - -A lot of packages have one or more executable files that they'd like to -install into the PATH. npm makes this pretty easy (in fact, it uses this -feature to install the "npm" executable.) - -To use this, supply a `bin` field in your package.json which is a map of -command name to local file name. When this package is installed -globally, that file will be linked where global bins go so it is -available to run by name. When this package is installed as a -dependency in another package, the file will be linked where it will be -available to that package either directly by `npm exec` or by name in other -scripts when invoking them via `npm run-script`. - - -For example, myapp could have this: - -```json -{ - "bin": { - "myapp": "./cli.js" - } -} -``` - -So, when you install myapp, it'll create a symlink from the `cli.js` script -to `/usr/local/bin/myapp`. - -If you have a single executable, and its name should be the name of the -package, then you can just supply it as a string. For example: - -```json -{ - "name": "my-program", - "version": "1.2.5", - "bin": "./path/to/program" -} -``` - -would be the same as this: - -```json -{ - "name": "my-program", - "version": "1.2.5", - "bin": { - "my-program": "./path/to/program" - } -} -``` - -Please make sure that your file(s) referenced in `bin` starts with -`#!/usr/bin/env node`, otherwise the scripts are started without the node -executable! - -Note that you can also set the executable files using [directories.bin](#directoriesbin). - -See [folders](/configuring-npm/folders#executables) for more info on -executables. - -### man - -Specify either a single file or an array of filenames to put in place for -the `man` program to find. - -If only a single file is provided, then it's installed such that it is the -result from `man <pkgname>`, regardless of its actual filename. For -example: - -```json -{ - "name": "foo", - "version": "1.2.3", - "description": "A packaged foo fooer for fooing foos", - "main": "foo.js", - "man": "./man/doc.1" -} -``` - -would link the `./man/doc.1` file in such that it is the target for `man -foo` - -If the filename doesn't start with the package name, then it's prefixed. -So, this: - -```json -{ - "name": "foo", - "version": "1.2.3", - "description": "A packaged foo fooer for fooing foos", - "main": "foo.js", - "man": [ - "./man/foo.1", - "./man/bar.1" - ] -} -``` - -will create files to do `man foo` and `man foo-bar`. - -Man files must end with a number, and optionally a `.gz` suffix if they are -compressed. The number dictates which man section the file is installed -into. - -```json -{ - "name": "foo", - "version": "1.2.3", - "description": "A packaged foo fooer for fooing foos", - "main": "foo.js", - "man": [ - "./man/foo.1", - "./man/foo.2" - ] -} -``` - -will create entries for `man foo` and `man 2 foo` - -### directories - -The CommonJS [Packages](http://wiki.commonjs.org/wiki/Packages/1.0) spec -details a few ways that you can indicate the structure of your package -using a `directories` object. If you look at [npm's -package.json](https://registry.npmjs.org/npm/latest), you'll see that it -has directories for doc, lib, and man. - -In the future, this information may be used in other creative ways. - -#### directories.bin - -If you specify a `bin` directory in `directories.bin`, all the files in -that folder will be added. - -Because of the way the `bin` directive works, specifying both a `bin` path -and setting `directories.bin` is an error. If you want to specify -individual files, use `bin`, and for all the files in an existing `bin` -directory, use `directories.bin`. - -#### directories.man - -A folder that is full of man pages. Sugar to generate a "man" array by -walking the folder. - -### repository - -Specify the place where your code lives. This is helpful for people who -want to contribute. If the git repo is on GitHub, then the `npm docs` -command will be able to find you. - -Do it like this: - -```json -{ - "repository": { - "type": "git", - "url": "https://github.com/npm/cli.git" - } -} -``` - -The URL should be a publicly available (perhaps read-only) url that can be -handed directly to a VCS program without any modification. It should not -be a url to an html project page that you put in your browser. It's for -computers. - -For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the -same shortcut syntax you use for `npm install`: - -```json -{ - "repository": "npm/npm", - - "repository": "github:user/repo", - - "repository": "gist:11081aaa281", - - "repository": "bitbucket:user/repo", - - "repository": "gitlab:user/repo" -} -``` - -If the `package.json` for your package is not in the root directory (for -example if it is part of a monorepo), you can specify the directory in -which it lives: - -```json -{ - "repository": { - "type": "git", - "url": "https://github.com/facebook/react.git", - "directory": "packages/react-dom" - } -} -``` - -### scripts - -The "scripts" property is a dictionary containing script commands that are -run at various times in the lifecycle of your package. The key is the -lifecycle event, and the value is the command to run at that point. - -See [`scripts`](/using-npm/scripts) to find out more about writing package -scripts. - -### config - -A "config" object can be used to set configuration parameters used in -package scripts that persist across upgrades. For instance, if a package -had the following: - -```json -{ - "name": "foo", - "config": { - "port": "8080" - } -} -``` - -It could also have a "start" command that referenced the -`npm_package_config_port` environment variable. - -### dependencies - -Dependencies are specified in a simple object that maps a package name to a -version range. The version range is a string which has one or more -space-separated descriptors. Dependencies can also be identified with a -tarball or git URL. - -**Please do not put test harnesses or transpilers or other "development" -time tools in your `dependencies` object.** See `devDependencies`, below. - -See [semver](https://github.com/npm/node-semver#versions) for more details about specifying version ranges. - -* `version` Must match `version` exactly -* `>version` Must be greater than `version` -* `>=version` etc -* `<version` -* `<=version` -* `~version` "Approximately equivalent to version" See - [semver](https://github.com/npm/node-semver#versions) -* `^version` "Compatible with version" See [semver](https://github.com/npm/node-semver#versions) -* `1.2.x` 1.2.0, 1.2.1, etc., but not 1.3.0 -* `http://...` See 'URLs as Dependencies' below -* `*` Matches any version -* `""` (just an empty string) Same as `*` -* `version1 - version2` Same as `>=version1 <=version2`. -* `range1 || range2` Passes if either range1 or range2 are satisfied. -* `git...` See 'Git URLs as Dependencies' below -* `user/repo` See 'GitHub URLs' below -* `tag` A specific version tagged and published as `tag` See [`npm - dist-tag`](/commands/npm-dist-tag) -* `path/path/path` See [Local Paths](#local-paths) below - -For example, these are all valid: - -```json -{ - "dependencies": { - "foo": "1.0.0 - 2.9999.9999", - "bar": ">=1.0.2 <2.1.2", - "baz": ">1.0.2 <=2.3.4", - "boo": "2.0.1", - "qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0", - "asd": "http://asdf.com/asdf.tar.gz", - "til": "~1.2", - "elf": "~1.2.3", - "two": "2.x", - "thr": "3.3.x", - "lat": "latest", - "dyl": "file:../dyl" - } -} -``` - -#### URLs as Dependencies - -You may specify a tarball URL in place of a version range. - -This tarball will be downloaded and installed locally to your package at -install time. - -#### Git URLs as Dependencies - -Git urls are of the form: - -```bash -<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>] -``` - -`<protocol>` is one of `git`, `git+ssh`, `git+http`, `git+https`, or -`git+file`. - -If `#<commit-ish>` is provided, it will be used to clone exactly that -commit. If the commit-ish has the format `#semver:<semver>`, `<semver>` can -be any valid semver range or exact version, and npm will look for any tags -or refs matching that range in the remote repository, much as it would for -a registry dependency. If neither `#<commit-ish>` or `#semver:<semver>` is -specified, then the default branch is used. - -Examples: - -```bash -git+ssh://git@github.com:npm/cli.git#v1.0.27 -git+ssh://git@github.com:npm/cli#semver:^5.0 -git+https://isaacs@github.com/npm/cli.git -git://github.com/npm/cli.git#v1.0.27 -``` - -When installing from a `git` repository, the presence of certain fields in the -`package.json` will cause npm to believe it needs to perform a build. To do so -your repository will be cloned into a temporary directory, all of its deps -installed, relevant scripts run, and the resulting directory packed and -installed. - -This flow will occur if your git dependency uses `workspaces`, or if any of the -following scripts are present: - -* `build` -* `prepare` -* `prepack` -* `preinstall` -* `install` -* `postinstall` - -If your git repository includes pre-built artifacts, you will likely want to -make sure that none of the above scripts are defined, or your dependency -will be rebuilt for every installation. - -#### GitHub URLs - -As of version 1.1.65, you can refer to GitHub urls as just "foo": -"user/foo-project". Just as with git URLs, a `commit-ish` suffix can be -included. For example: - -```json -{ - "name": "foo", - "version": "0.0.0", - "dependencies": { - "express": "expressjs/express", - "mocha": "mochajs/mocha#4727d357ea", - "module": "user/repo#feature\/branch" - } -} -``` - -#### Local Paths - -As of version 2.0.0 you can provide a path to a local directory that -contains a package. Local paths can be saved using `npm install -S` or `npm -install --save`, using any of these forms: - -```bash -../foo/bar -~/foo/bar -./foo/bar -/foo/bar -``` - -in which case they will be normalized to a relative path and added to your -`package.json`. For example: - -```json -{ - "name": "baz", - "dependencies": { - "bar": "file:../foo/bar" - } -} -``` - -This feature is helpful for local offline development and creating tests -that require npm installing where you don't want to hit an external server, -but should not be used when publishing packages to the public registry. - -*note*: Packages linked by local path will not have their own -dependencies installed when `npm install` is ran in this case. You must -run `npm install` from inside the local path itself. - -### devDependencies - -If someone is planning on downloading and using your module in their -program, then they probably don't want or need to download and build the -external test or documentation framework that you use. - -In this case, it's best to map these additional items in a -`devDependencies` object. - -These things will be installed when doing `npm link` or `npm install` from -the root of a package, and can be managed like any other npm configuration -param. See [`config`](/using-npm/config) for more on the topic. - -For build steps that are not platform-specific, such as compiling -CoffeeScript or other languages to JavaScript, use the `prepare` script to -do this, and make the required package a devDependency. - -For example: - -```json -{ - "name": "ethopia-waza", - "description": "a delightfully fruity coffee varietal", - "version": "1.2.3", - "devDependencies": { - "coffee-script": "~1.6.3" - }, - "scripts": { - "prepare": "coffee -o lib/ -c src/waza.coffee" - }, - "main": "lib/waza.js" -} -``` - -The `prepare` script will be run before publishing, so that users can -consume the functionality without requiring them to compile it themselves. -In dev mode (ie, locally running `npm install`), it'll run this script as -well, so that you can test it easily. - -### peerDependencies - -In some cases, you want to express the compatibility of your package with a -host tool or library, while not necessarily doing a `require` of this host. -This is usually referred to as a *plugin*. Notably, your module may be -exposing a specific interface, expected and specified by the host -documentation. - -For example: - -```json -{ - "name": "tea-latte", - "version": "1.3.5", - "peerDependencies": { - "tea": "2.x" - } -} -``` - -This ensures your package `tea-latte` can be installed *along* with the -second major version of the host package `tea` only. `npm install -tea-latte` could possibly yield the following dependency graph: - -```bash -├── tea-latte@1.3.5 -└── tea@2.2.0 -``` - -In npm versions 3 through 6, `peerDependencies` were not automatically -installed, and would raise a warning if an invalid version of the peer -dependency was found in the tree. As of npm v7, peerDependencies _are_ -installed by default. - -Trying to install another plugin with a conflicting requirement may cause -an error if the tree cannot be resolved correctly. For this reason, make -sure your plugin requirement is as broad as possible, and not to lock it -down to specific patch versions. - -Assuming the host complies with [semver](https://semver.org/), only changes -in the host package's major version will break your plugin. Thus, if you've -worked with every 1.x version of the host package, use `"^1.0"` or `"1.x"` -to express this. If you depend on features introduced in 1.5.2, use -`"^1.5.2"`. - -### peerDependenciesMeta - -When a user installs your package, npm will emit warnings if packages -specified in `peerDependencies` are not already installed. The -`peerDependenciesMeta` field serves to provide npm more information on how -your peer dependencies are to be used. Specifically, it allows peer -dependencies to be marked as optional. - -For example: - -```json -{ - "name": "tea-latte", - "version": "1.3.5", - "peerDependencies": { - "tea": "2.x", - "soy-milk": "1.2" - }, - "peerDependenciesMeta": { - "soy-milk": { - "optional": true - } - } -} -``` - -Marking a peer dependency as optional ensures npm will not emit a warning -if the `soy-milk` package is not installed on the host. This allows you to -integrate and interact with a variety of host packages without requiring -all of them to be installed. - -### bundleDependencies - -This defines an array of package names that will be bundled when publishing -the package. - -In cases where you need to preserve npm packages locally or have them -available through a single file download, you can bundle the packages in a -tarball file by specifying the package names in the `bundleDependencies` -array and executing `npm pack`. - -For example: - -If we define a package.json like this: - -```json -{ - "name": "awesome-web-framework", - "version": "1.0.0", - "bundleDependencies": [ - "renderized", - "super-streams" - ] -} -``` - -we can obtain `awesome-web-framework-1.0.0.tgz` file by running `npm pack`. -This file contains the dependencies `renderized` and `super-streams` which -can be installed in a new project by executing `npm install -awesome-web-framework-1.0.0.tgz`. Note that the package names do not -include any versions, as that information is specified in `dependencies`. - -If this is spelled `"bundledDependencies"`, then that is also honored. - -Alternatively, `"bundleDependencies"` can be defined as a boolean value. A -value of `true` will bundle all dependencies, a value of `false` will bundle -none. - -### optionalDependencies - -If a dependency can be used, but you would like npm to proceed if it cannot -be found or fails to install, then you may put it in the -`optionalDependencies` object. This is a map of package name to version or -url, just like the `dependencies` object. The difference is that build -failures do not cause installation to fail. Running `npm install ---no-optional` will prevent these dependencies from being installed. - -It is still your program's responsibility to handle the lack of the -dependency. For example, something like this: - -```js -try { - var foo = require('foo') - var fooVersion = require('foo/package.json').version -} catch (er) { - foo = null -} -if ( notGoodFooVersion(fooVersion) ) { - foo = null -} - -// .. then later in your program .. - -if (foo) { - foo.doFooThings() -} -``` - -Entries in `optionalDependencies` will override entries of the same name in -`dependencies`, so it's usually best to only put in one place. - -### overrides - -If you need to make specific changes to dependencies of your dependencies, for -example replacing the version of a dependency with a known security issue, -replacing an existing dependency with a fork, or making sure that the same -version of a package is used everywhere, then you may add an override. - -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. - -To make sure the package `foo` is always installed as version `1.0.0` no matter -what version your dependencies rely on: - -```json -{ - "overrides": { - "foo": "1.0.0" - } -} -``` - -The above is a short hand notation, the full object form can be used to allow -overriding a package itself as well as a child of the package. This will cause -`foo` to always be `1.0.0` while also making `bar` at any depth beyond `foo` -also `1.0.0`: - -```json -{ - "overrides": { - "foo": { - ".": "1.0.0", - "bar": "1.0.0" - } - } -} -``` - -To only override `foo` to be `1.0.0` when it's a child (or grandchild, or great -grandchild, etc) of the package `bar`: - -```json -{ - "overrides": { - "bar": { - "foo": "1.0.0" - } - } -} -``` - -Keys can be nested to any arbitrary length. To override `foo` only when it's a -child of `bar` and only when `bar` is a child of `baz`: - -```json -{ - "overrides": { - "baz": { - "bar": { - "foo": "1.0.0" - } - } - } -} -``` - -The key of an override can also include a version, or range of versions. -To override `foo` to `1.0.0`, but only when it's a child of `bar@2.0.0`: - -```json -{ - "overrides": { - "bar@2.0.0": { - "foo": "1.0.0" - } - } -} -``` - -You may not set an override for a package that you directly depend on unless -both the dependency and the override itself share the exact same spec. To make -this limitation easier to deal with, overrides may also be defined as a -reference to a spec for a direct dependency by prefixing the name of the -package you wish the version to match with a `$`. - -```json -{ - "dependencies": { - "foo": "^1.0.0" - }, - "overrides": { - // BAD, will throw an EOVERRIDE error - // "foo": "^2.0.0" - // GOOD, specs match so override is allowed - // "foo": "^1.0.0" - // BEST, the override is defined as a reference to the dependency - "foo": "$foo", - // the referenced package does not need to match the overridden one - "bar": "$foo" - } -} -``` - -### engines - -You can specify the version of node that your stuff works on: - -```json -{ - "engines": { - "node": ">=0.10.3 <15" - } -} -``` - -And, like with dependencies, if you don't specify the version (or if you -specify "\*" as the version), then any version of node will do. - -You can also use the "engines" field to specify which versions of npm are -capable of properly installing your program. For example: - -```json -{ - "engines": { - "npm": "~1.0.20" - } -} -``` - -Unless the user has set the `engine-strict` config flag, this field is -advisory only and will only produce warnings when your package is installed -as a dependency. - -### os - -You can specify which operating systems your -module will run on: - -```json -{ - "os": [ - "darwin", - "linux" - ] -} -``` - -You can also block instead of allowing operating systems, just prepend the -blocked os with a '!': - -```json -{ - "os": [ - "!win32" - ] -} -``` - -The host operating system is determined by `process.platform` - -It is allowed to both block and allow an item, although there isn't any -good reason to do this. - -### cpu - -If your code only runs on certain cpu architectures, -you can specify which ones. - -```json -{ - "cpu": [ - "x64", - "ia32" - ] -} -``` - -Like the `os` option, you can also block architectures: - -```json -{ - "cpu": [ - "!arm", - "!mips" - ] -} -``` - -The host architecture is determined by `process.arch` - -### private - -If you set `"private": true` in your package.json, then npm will refuse to -publish it. - -This is a way to prevent accidental publication of private repositories. -If you would like to ensure that a given package is only ever published to -a specific registry (for example, an internal registry), then use the -`publishConfig` dictionary described below to override the `registry` -config param at publish-time. - -### publishConfig - -This is a set of config values that will be used at publish-time. It's -especially handy if you want to set the tag, registry or access, so that -you can ensure that a given package is not tagged with "latest", published -to the global public registry or that a scoped module is private by -default. - -See [`config`](/using-npm/config) to see the list of config options that -can be overridden. - -### workspaces - -The optional `workspaces` field is an array of file patterns that describes -locations within the local file system that the install client should look -up to find each [workspace](/using-npm/workspaces) that needs to be -symlinked to the top level `node_modules` folder. - -It can describe either the direct paths of the folders to be used as -workspaces or it can define globs that will resolve to these same folders. - -In the following example, all folders located inside the folder -`./packages` will be treated as workspaces as long as they have valid -`package.json` files inside them: - -```json -{ - "name": "workspace-example", - "workspaces": [ - "./packages/*" - ] -} -``` - -See [`workspaces`](/using-npm/workspaces) for more examples. - -### DEFAULT VALUES - -npm will default some values based on package contents. - -* `"scripts": {"start": "node server.js"}` - - If there is a `server.js` file in the root of your package, then npm will - default the `start` command to `node server.js`. - -* `"scripts":{"install": "node-gyp rebuild"}` - - If there is a `binding.gyp` file in the root of your package and you have - not defined an `install` or `preinstall` script, npm will default the - `install` command to compile using node-gyp. - -* `"contributors": [...]` - - If there is an `AUTHORS` file in the root of your package, npm will treat - each line as a `Name <email> (url)` format, where email and url are - optional. Lines which start with a `#` or are blank, will be ignored. - -### SEE ALSO - -* [semver](https://github.com/npm/node-semver#versions) -* [workspaces](/using-npm/workspaces) -* [npm init](/commands/npm-init) -* [npm version](/commands/npm-version) -* [npm config](/commands/npm-config) -* [npm help](/commands/npm-help) -* [npm install](/commands/npm-install) -* [npm publish](/commands/npm-publish) -* [npm uninstall](/commands/npm-uninstall) diff --git a/docs/content/configuring-npm/package-lock-json.md b/docs/content/configuring-npm/package-lock-json.md deleted file mode 100644 index 4aa8dc375c89f..0000000000000 --- a/docs/content/configuring-npm/package-lock-json.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: package-lock.json -section: 5 -description: A manifestation of the manifest ---- - -### Description - -`package-lock.json` is automatically generated for any operations where npm -modifies either the `node_modules` tree, or `package.json`. It describes the -exact tree that was generated, such that subsequent installs are able to -generate identical trees, regardless of intermediate dependency updates. - -This file is intended to be committed into source repositories, and serves -various purposes: - -* Describe a single representation of a dependency tree such that - teammates, deployments, and continuous integration are guaranteed to - install exactly the same dependencies. - -* Provide a facility for users to "time-travel" to previous states of - `node_modules` without having to commit the directory itself. - -* Facilitate greater visibility of tree changes through readable source - control diffs. - -* Optimize the installation process by allowing npm to skip repeated - metadata resolutions for previously-installed packages. - -* As of npm v7, lockfiles include enough information to gain a complete - picture of the package tree, reducing the need to read `package.json` - files, and allowing for significant performance improvements. - -### `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. - -The difference is that `package-lock.json` cannot be published, and it will -be ignored if found in any place other than the root project. - -In contrast, [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) allows -publication, and defines the dependency tree from the point encountered. -This is not recommended unless deploying a CLI tool or otherwise using the -publication process for producing production packages. - -If both `package-lock.json` and `npm-shrinkwrap.json` are present in the -root of a project, `npm-shrinkwrap.json` will take precedence and -`package-lock.json` will be ignored. - -### Hidden Lockfiles - -In order to avoid processing the `node_modules` folder repeatedly, npm as -of v7 uses a "hidden" lockfile present in -`node_modules/.package-lock.json`. This contains information about the -tree, and is used in lieu of reading the entire `node_modules` hierarchy -provided that the following conditions are met: - -- All package folders it references exist in the `node_modules` hierarchy. -- No package folders exist in the `node_modules` hierarchy that are not - listed in the lockfile. -- The modified time of the file is at least as recent as all of the package - folders it references. - -That is, the hidden lockfile will only be relevant if it was created as -part of the most recent update to the package tree. If another CLI mutates -the tree in any way, this will be detected, and the hidden lockfile will be -ignored. - -Note that it _is_ possible to manually change the _contents_ of a package -in such a way that the modified time of the package folder is unaffected. -For example, if you add a file to `node_modules/foo/lib/bar.js`, then the -modified time on `node_modules/foo` will not reflect this change. If you -are manually editing files in `node_modules`, it is generally best to -delete the file at `node_modules/.package-lock.json`. - -As the hidden lockfile is ignored by older npm versions, it does not -contain the backwards compatibility affordances present in "normal" -lockfiles. That is, it is `lockfileVersion: 3`, rather than -`lockfileVersion: 2`. - -### Handling Old Lockfiles - -When npm detects a lockfile from npm v6 or before during the package -installation process, it is automatically updated to fetch missing -information from either the `node_modules` tree or (in the case of empty -`node_modules` trees or very old lockfile formats) the npm registry. - -### File Format - -#### `name` - -The name of the package this is a package-lock for. This will match what's -in `package.json`. - -#### `version` - -The version of the package this is a package-lock for. This will match -what's in `package.json`. - -#### `lockfileVersion` - -An integer version, starting at `1` with the version number of this -document whose semantics were used when generating this -`package-lock.json`. - -Note that the file format changed significantly in npm v7 to track -information that would have otherwise required looking in `node_modules` or -the npm registry. Lockfiles generated by npm v7 will contain -`lockfileVersion: 2`. - -* No version provided: an "ancient" shrinkwrap file from a version of npm - prior to npm v5. -* `1`: The lockfile version used by npm v5 and v6. -* `2`: The lockfile version used by npm v7, which is backwards compatible - to v1 lockfiles. -* `3`: The lockfile version used by npm v7, _without_ backwards - compatibility affordances. This is used for the hidden lockfile at - `node_modules/.package-lock.json`, and will likely be used in a future - version of npm, once support for npm v6 is no longer relevant. - -npm will always attempt to get whatever data it can out of a lockfile, even -if it is not a version that it was designed to support. - -#### `packages` - -This is an object that maps package locations to an object containing the -information about that package. - -The root project is typically listed with a key of `""`, and all other -packages are listed with their relative paths from the root project folder. - -Package descriptors have the following fields: - -* version: The version found in `package.json` - -* resolved: The place where the package was actually resolved from. In - the case of packages fetched from the registry, this will be a url to a - tarball. In the case of git dependencies, this will be the full git url - with commit sha. In the case of link dependencies, this will be the - location of the link target. `registry.npmjs.org` is a magic value meaning - "the currently configured registry". - -* integrity: A `sha512` or `sha1` [Standard Subresource - Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) - string for the artifact that was unpacked in this location. - -* link: A flag to indicate that this is a symbolic link. If this is - present, no other fields are specified, since the link target will also - be included in the lockfile. - -* dev, optional, devOptional: If the package is strictly part of the - `devDependencies` tree, then `dev` will be true. If it is strictly part - of the `optionalDependencies` tree, then `optional` will be set. If it - is both a `dev` dependency _and_ an `optional` dependency of a non-dev - dependency, then `devOptional` will be set. (An `optional` dependency of - a `dev` dependency will have both `dev` and `optional` set.) - -* inBundle: A flag to indicate that the package is a bundled dependency. - -* hasInstallScript: A flag to indicate that the package has a `preinstall`, - `install`, or `postinstall` script. - -* hasShrinkwrap: A flag to indicate that the package has an - `npm-shrinkwrap.json` file. - -* bin, license, engines, dependencies, optionalDependencies: fields from - `package.json` - -#### dependencies - -Legacy data for supporting versions of npm that use `lockfileVersion: 1`. -This is a mapping of package names to dependency objects. Because the -object structure is strictly hierarchical, symbolic link dependencies are -somewhat challenging to represent in some cases. - -npm v7 ignores this section entirely if a `packages` section is present, -but does keep it up to date in order to support switching between npm v6 -and npm v7. - -Dependency objects have the following fields: - -* version: a specifier that varies depending on the nature of the package, - and is usable in fetching a new copy of it. - - * bundled dependencies: Regardless of source, this is a version number - that is purely for informational purposes. - * registry sources: This is a version number. (eg, `1.2.3`) - * git sources: This is a git specifier with resolved committish. (eg, - `git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e`) - * http tarball sources: This is the URL of the tarball. (eg, - `https://example.com/example-1.3.0.tgz`) - * local tarball sources: This is the file URL of the tarball. (eg - `file:///opt/storage/example-1.3.0.tgz`) - * local link sources: This is the file URL of the link. (eg - `file:libs/our-module`) - -* integrity: A `sha512` or `sha1` [Standard Subresource - Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) - string for the artifact that was unpacked in this location. For git - dependencies, this is the commit sha. - -* resolved: For registry sources this is path of the tarball relative to - the registry URL. If the tarball URL isn't on the same server as the - registry URL then this is a complete URL. `registry.npmjs.org` is a magic - value meaning "the currently configured registry". - -* bundled: If true, this is the bundled dependency and will be installed - by the parent module. When installing, this module will be extracted - from the parent module during the extract phase, not installed as a - separate dependency. - -* dev: If true then this dependency is either a development dependency ONLY - of the top level module or a transitive dependency of one. This is false - for dependencies that are both a development dependency of the top level - and a transitive dependency of a non-development dependency of the top - level. - -* optional: If true then this dependency is either an optional dependency - ONLY of the top level module or a transitive dependency of one. This is - false for dependencies that are both an optional dependency of the top - level and a transitive dependency of a non-optional dependency of the top - level. - -* requires: This is a mapping of module name to version. This is a list of - everything this module requires, regardless of where it will be - installed. The version should match via normal matching rules a - dependency either in our `dependencies` or in a level higher than us. - -* dependencies: The dependencies of this dependency, exactly as at the top - level. - -### See also - -* [npm shrinkwrap](/commands/npm-shrinkwrap) -* [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) -* [package.json](/configuring-npm/package-json) -* [npm install](/commands/npm-install) diff --git a/docs/content/using-npm/config.md b/docs/content/using-npm/config.md deleted file mode 100644 index cd13237f34dd3..0000000000000 --- a/docs/content/using-npm/config.md +++ /dev/null @@ -1,2134 +0,0 @@ ---- -title: config -section: 7 -description: More than you probably want to know about npm configuration ---- - -### Description - -npm gets its configuration values from the following sources, sorted by priority: - -#### Command Line Flags - -Putting `--foo bar` on the command line sets the `foo` configuration -parameter to `"bar"`. A `--` argument tells the cli parser to stop -reading flags. Using `--flag` without specifying any value will set -the value to `true`. - -Example: `--flag1 --flag2` will set both configuration parameters -to `true`, while `--flag1 --flag2 bar` will set `flag1` to `true`, -and `flag2` to `bar`. Finally, `--flag1 --flag2 -- bar` will set -both configuration parameters to `true`, and the `bar` is taken -as a command argument. - -#### Environment Variables - -Any environment variables that start with `npm_config_` will be -interpreted as a configuration parameter. For example, putting -`npm_config_foo=bar` in your environment will set the `foo` -configuration parameter to `bar`. Any environment configurations that -are not given a value will be given the value of `true`. Config -values are case-insensitive, so `NPM_CONFIG_FOO=bar` will work the -same. However, please note that inside [`scripts`](/using-npm/scripts) -npm will set its own environment variables and Node will prefer -those lowercase versions over any uppercase ones that you might set. -For details see [this issue](https://github.com/npm/npm/issues/14528). - -Notice that you need to use underscores instead of dashes, so `--allow-same-version` -would become `npm_config_allow_same_version=true`. - -#### npmrc Files - -The four relevant files are: - -* per-project configuration file (`/path/to/my/project/.npmrc`) -* per-user configuration file (defaults to `$HOME/.npmrc`; configurable via CLI - option `--userconfig` or environment variable `$NPM_CONFIG_USERCONFIG`) -* global configuration file (defaults to `$PREFIX/etc/npmrc`; configurable via - CLI option `--globalconfig` or environment variable `$NPM_CONFIG_GLOBALCONFIG`) -* npm's built-in configuration file (`/path/to/npm/npmrc`) - -See [npmrc](/configuring-npm/npmrc) for more details. - -#### Default Configs - -Run `npm config ls -l` to see a set of configuration parameters that are -internal to npm, and are defaults if nothing else is specified. - -### Shorthands and Other CLI Niceties - -The following shorthands are parsed on the command-line: - -<!-- AUTOGENERATED CONFIG SHORTHANDS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -* `-a`: `--all` -* `--enjoy-by`: `--before` -* `-c`: `--call` -* `--desc`: `--description` -* `-f`: `--force` -* `-g`: `--global` -* `--iwr`: `--include-workspace-root` -* `-L`: `--location` -* `-d`: `--loglevel info` -* `-s`: `--loglevel silent` -* `--silent`: `--loglevel silent` -* `--ddd`: `--loglevel silly` -* `--dd`: `--loglevel verbose` -* `--verbose`: `--loglevel verbose` -* `-q`: `--loglevel warn` -* `--quiet`: `--loglevel warn` -* `-l`: `--long` -* `-m`: `--message` -* `--local`: `--no-global` -* `-n`: `--no-yes` -* `--no`: `--no-yes` -* `-p`: `--parseable` -* `--porcelain`: `--parseable` -* `-C`: `--prefix` -* `--readonly`: `--read-only` -* `--reg`: `--registry` -* `-S`: `--save` -* `-B`: `--save-bundle` -* `-D`: `--save-dev` -* `-E`: `--save-exact` -* `-O`: `--save-optional` -* `-P`: `--save-prod` -* `-?`: `--usage` -* `-h`: `--usage` -* `-H`: `--usage` -* `--help`: `--usage` -* `-v`: `--version` -* `-w`: `--workspace` -* `--ws`: `--workspaces` -* `-y`: `--yes` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -<!-- AUTOGENERATED CONFIG SHORTHANDS END --> - -If the specified configuration param resolves unambiguously to a known -configuration parameter, then it is expanded to that configuration -parameter. For example: - -```bash -npm ls --par -# same as: -npm ls --parseable -``` - -If multiple single-character shorthands are strung together, and the -resulting combination is unambiguously not some other configuration -param, then it is expanded to its various component pieces. For -example: - -```bash -npm ls -gpld -# same as: -npm ls --global --parseable --long --loglevel info -``` - -### Config Settings - -<!-- AUTOGENERATED CONFIG DESCRIPTIONS START --> -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -#### `_auth` - -* Default: null -* Type: null or String - -A basic-auth string to use when authenticating against the npm registry. -This will ONLY be used to authenticate against the npm registry. For other -registries you will need to scope it like "//other-registry.tld/:_auth" - -Warning: This should generally not be set via a command-line option. It is -safer to use a registry-provided authentication bearer token stored in the -~/.npmrc file by running `npm login`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `access` - -* Default: 'restricted' for scoped packages, 'public' for unscoped packages -* Type: null, "restricted", or "public" - -When publishing scoped packages, the access level defaults to `restricted`. -If you want your scoped package to be publicly viewable (and installable) -set `--access=public`. The only valid values for `access` are `public` and -`restricted`. Unscoped packages _always_ have an access level of `public`. - -Note: Using the `--access` flag on the `npm publish` command will only set -the package access level on the initial publish of the package. Any -subsequent `npm publish` commands using the `--access` flag will not have an -effect to the access level. To make changes to the access level after the -initial publish use `npm access`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `all` - -* Default: false -* Type: Boolean - -When running `npm outdated` and `npm ls`, setting `--all` will show all -outdated or installed packages, rather than only those directly depended -upon by the current project. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `allow-same-version` - -* Default: false -* Type: Boolean - -Prevents throwing an error when `npm version` is used to set the new version -to the same value as the current version. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit` - -* Default: true -* Type: Boolean - -When "true" submit audit reports alongside the current npm command to the -default registry and all registries configured for scopes. See the -documentation for [`npm audit`](/commands/npm-audit) for details on what is -submitted. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `audit-level` - -* Default: null -* Type: null, "info", "low", "moderate", "high", "critical", or "none" - -The minimum level of vulnerability for `npm audit` to exit with a non-zero -exit code. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `auth-type` - -* Default: "legacy" -* Type: "legacy", "web", "sso", "saml", "oauth", or "webauthn" - -NOTE: auth-type values "sso", "saml", "oauth", and "webauthn" will be -removed in a future version. - -What authentication strategy to use with `login`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `before` - -* Default: null -* Type: null or Date - -If passed to `npm install`, will rebuild the npm tree such that only -versions that were available **on or before** the `--before` time get -installed. If there's no versions available for the current set of direct -dependencies, the command will error. - -If the requested version is a `dist-tag` and the given tag does not pass the -`--before` filter, the most recent version less than or equal to that tag -will be used. For example, `foo@latest` might install `foo@1.2` even though -`latest` is `2.0`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `bin-links` - -* Default: true -* Type: Boolean - -Tells npm to create symlinks (or `.cmd` shims on Windows) for package -executables. - -Set to false to have it not do this. This can be used to work around the -fact that some file systems don't support symlinks, even on ostensibly Unix -systems. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `browser` - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: null, Boolean, or String - -The browser that is called by npm commands to open websites. - -Set to `false` to suppress browser behavior and instead print urls to -terminal. - -Set to `true` to use default system URL opener. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ca` - -* Default: null -* Type: null or String (can be set multiple times) - -The Certificate Authority signing certificate that is trusted for SSL -connections to the registry. Values should be in PEM format (Windows calls -it "Base-64 encoded X.509 (.CER)") with newlines replaced by the string -"\n". For example: - -```ini -ca="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----" -``` - -Set to `null` to only allow "known" registrars, or to a specific CA cert to -trust only that specific signing authority. - -Multiple CAs can be trusted by specifying an array of certificates: - -```ini -ca[]="..." -ca[]="..." -``` - -See also the `strict-ssl` config. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cache` - -* Default: Windows: `%LocalAppData%\npm-cache`, Posix: `~/.npm` -* Type: Path - -The location of npm's cache directory. See [`npm -cache`](/commands/npm-cache) - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cafile` - -* Default: null -* Type: Path - -A path to a file containing one or multiple Certificate Authority signing -certificates. Similar to the `ca` setting, but allows for multiple CA's, as -well as for the CA information to be stored in a file on disk. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `call` - -* Default: "" -* Type: String - -Optional companion option for `npm exec`, `npx` that allows for specifying a -custom command to be run along with the installed packages. - -```bash -npm exec --package yo --package generator-node --call "yo node" -``` - - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cert` - -* Default: null -* Type: null or String - -A client certificate to pass when accessing the registry. Values should be -in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with -newlines replaced by the string "\n". For example: - -```ini -cert="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----" -``` - -It is _not_ the path to a certificate file, though you can set a -registry-scoped "certfile" path like -"//other-registry.tld/:certfile=/path/to/cert.pem". - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ci-name` - -* Default: The name of the current CI system, or `null` when not on a known CI - platform. -* Type: null or String - -The name of a continuous integration system. If not set explicitly, npm will -detect the current CI environment using the -[`@npmcli/ci-detect`](http://npm.im/@npmcli/ci-detect) module. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cidr` - -* Default: null -* Type: null or String (can be set multiple times) - -This is a list of CIDR address to be used when configuring limited access -tokens with the `npm token create` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `color` - -* Default: true unless the NO_COLOR environ is set to something other than '0' -* Type: "always" or Boolean - -If false, never shows colors. If `"always"` then always shows colors. If -true, then only prints color codes for tty file descriptors. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `commit-hooks` - -* Default: true -* Type: Boolean - -Run git commit hooks when using the `npm version` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `depth` - -* Default: `Infinity` if `--all` is set, otherwise `1` -* Type: null or Number - -The depth to go when recursing packages for `npm ls`. - -If not set, `npm ls` will show only the immediate dependencies of the root -project. If `--all` is set, then npm will show all dependencies by default. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `description` - -* Default: true -* Type: Boolean - -Show the description in `npm search` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff` - -* Default: -* Type: String (can be set multiple times) - -Define arguments to compare in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-dst-prefix` - -* Default: "b/" -* Type: String - -Destination prefix to be used in `npm diff` output. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-ignore-all-space` - -* Default: false -* Type: Boolean - -Ignore whitespace when comparing lines in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-name-only` - -* Default: false -* Type: Boolean - -Prints only filenames when using `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-no-prefix` - -* Default: false -* Type: Boolean - -Do not show any source or destination prefix in `npm diff` output. - -Note: this causes `npm diff` to ignore the `--diff-src-prefix` and -`--diff-dst-prefix` configs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-src-prefix` - -* Default: "a/" -* Type: String - -Source prefix to be used in `npm diff` output. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-text` - -* Default: false -* Type: Boolean - -Treat all files as text in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `diff-unified` - -* Default: 3 -* Type: Number - -The number of lines of context to print in `npm diff`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dry-run` - -* Default: false -* Type: Boolean - -Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, `install`, `update`, -`dedupe`, `uninstall`, as well as `pack` and `publish`. - -Note: This is NOT honored by other network related commands, eg `dist-tags`, -`owner`, etc. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `editor` - -* Default: The EDITOR or VISUAL environment variables, or 'notepad.exe' on - Windows, or 'vim' on Unix systems -* Type: String - -The command to run for `npm edit` and `npm config edit`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `engine-strict` - -* Default: false -* Type: Boolean - -If set to true, then npm will stubbornly refuse to install (or even consider -installing) any package that claims to not be compatible with the current -Node.js version. - -This can be overridden by setting the `--force` flag. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fetch-retries` - -* Default: 2 -* Type: Number - -The "retries" config for the `retry` module to use when fetching packages -from the registry. - -npm will retry idempotent read requests to the registry in the case of -network failures or 5xx HTTP errors. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fetch-retry-factor` - -* Default: 10 -* Type: Number - -The "factor" config for the `retry` module to use when fetching packages. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fetch-retry-maxtimeout` - -* Default: 60000 (1 minute) -* Type: Number - -The "maxTimeout" config for the `retry` module to use when fetching -packages. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fetch-retry-mintimeout` - -* Default: 10000 (10 seconds) -* Type: Number - -The "minTimeout" config for the `retry` module to use when fetching -packages. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fetch-timeout` - -* Default: 300000 (5 minutes) -* Type: Number - -The maximum amount of time to wait for HTTP requests to complete. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `force` - -* Default: false -* Type: Boolean - -Removes various protections against unfortunate side effects, common -mistakes, unnecessary performance degradation, and malicious input. - -* Allow clobbering non-npm files in global installs. -* Allow the `npm version` command to work on an unclean git repository. -* Allow deleting the cache folder with `npm cache clean`. -* Allow installing packages that have an `engines` declaration requiring a - different version of npm. -* Allow installing packages that have an `engines` declaration requiring a - different version of `node`, even if `--engine-strict` is enabled. -* Allow `npm audit fix` to install modules outside your stated dependency - range (including SemVer-major changes). -* Allow unpublishing all versions of a published package. -* Allow conflicting peerDependencies to be installed in the root project. -* Implicitly set `--yes` during `npm init`. -* Allow clobbering existing values in `npm pkg` -* Allow unpublishing of entire packages (not just a single version). - -If you don't have a clear idea of what you want to do, it is strongly -recommended that you do not use this option! - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `foreground-scripts` - -* Default: false -* Type: Boolean - -Run all build scripts (ie, `preinstall`, `install`, and `postinstall`) -scripts for installed packages in the foreground process, sharing standard -input, output, and error with the main npm process. - -Note that this will generally make installs run slower, and be much noisier, -but can be useful for debugging. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `format-package-lock` - -* Default: true -* Type: Boolean - -Format `package-lock.json` or `npm-shrinkwrap.json` as a human readable -file. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `fund` - -* Default: true -* Type: Boolean - -When "true" displays the message at the end of each `npm install` -acknowledging the number of dependencies looking for funding. See [`npm -fund`](/commands/npm-fund) for details. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `git` - -* Default: "git" -* Type: String - -The command to use for git commands. If git is installed on the computer, -but is not in the `PATH`, then set this to the full path to the git binary. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `git-tag-version` - -* Default: true -* Type: Boolean - -Tag the commit when using the `npm version` command. Setting this to false -results in no commit being made at all. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global` - -* Default: false -* Type: Boolean - -Operates in "global" mode, so that packages are installed into the `prefix` -folder instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `global-style` - -* Default: false -* Type: Boolean - -Causes npm to install the package into your local `node_modules` folder with -the same layout it uses with the global `node_modules` folder. Only your -direct dependencies will show in `node_modules` and everything they depend -on will be flattened in their `node_modules` folders. This obviously will -eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `globalconfig` - -* Default: The global --prefix setting plus 'etc/npmrc'. For example, - '/usr/local/etc/npmrc' -* Type: Path - -The config file to read for global config options. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `heading` - -* Default: "npm" -* Type: String - -The string that starts all the debugging log output. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `https-proxy` - -* Default: null -* Type: null or URL - -A proxy to use for outgoing https requests. If the `HTTPS_PROXY` or -`https_proxy` or `HTTP_PROXY` or `http_proxy` environment variables are set, -proxy settings will be honored by the underlying `make-fetch-happen` -library. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `if-present` - -* Default: false -* Type: Boolean - -If true, npm will not exit with an error code when `run-script` is invoked -for a script that isn't defined in the `scripts` section of `package.json`. -This option can be used when it's desirable to optionally run a script when -it's present and fail if the script fails. This is useful, for example, when -running scripts that may only apply for some builds in an otherwise generic -CI setup. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `ignore-scripts` - -* Default: false -* Type: Boolean - -If true, npm does not run scripts specified in package.json files. - -Note that commands explicitly intended to run a particular script, such as -`npm start`, `npm stop`, `npm restart`, `npm test`, and `npm run-script` -will still run their intended script if `ignore-scripts` is set, but they -will *not* run any pre- or post-scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include` - -* Default: -* Type: "prod", "dev", "optional", or "peer" (can be set multiple times) - -Option that allows for defining which types of dependencies to install. - -This is the inverse of `--omit=<type>`. - -Dependency types specified in `--include` will not be omitted, regardless of -the order in which omit/include are specified on the command-line. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-staged` - -* Default: false -* Type: Boolean - -Allow installing "staged" published packages, as defined by [npm RFC PR -#92](https://github.com/npm/rfcs/pull/92). - -This is experimental, and not implemented by the npm public registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `include-workspace-root` - -* Default: false -* Type: Boolean - -Include the workspace root when workspaces are enabled for a command. - -When false, specifying individual workspaces via the `workspace` config, or -all workspaces via the `workspaces` flag, will cause npm to operate only on -the specified workspaces, and not on the root project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init-author-email` - -* Default: "" -* Type: String - -The value `npm init` should use by default for the package author's email. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init-author-name` - -* Default: "" -* Type: String - -The value `npm init` should use by default for the package author's name. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init-author-url` - -* Default: "" -* Type: "" or URL - -The value `npm init` should use by default for the package author's -homepage. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init-license` - -* Default: "ISC" -* Type: String - -The value `npm init` should use by default for the package license. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init-module` - -* Default: "~/.npm-init.js" -* Type: Path - -A module that will be loaded by the `npm init` command. See the -documentation for the -[init-package-json](https://github.com/npm/init-package-json) module for -more information, or [npm init](/commands/npm-init). - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init-version` - -* Default: "1.0.0" -* Type: SemVer string - -The value that `npm init` should use by default for the package version -number, if not already set in package.json. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `install-links` - -* Default: false -* Type: Boolean - -When set file: protocol dependencies that exist outside of the project root -will be packed and installed as regular dependencies instead of creating a -symlink. This option has no effect on workspaces. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `json` - -* Default: false -* Type: Boolean - -Whether or not to output JSON data, rather than the normal output. - -* In `npm pkg set` it enables parsing set values with JSON.parse() before - saving them to your `package.json`. - -Not supported by all npm commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `key` - -* Default: null -* Type: null or String - -A client key to pass when accessing the registry. Values should be in PEM -format with newlines replaced by the string "\n". For example: - -```ini -key="-----BEGIN PRIVATE KEY-----\nXXXX\nXXXX\n-----END PRIVATE KEY-----" -``` - -It is _not_ the path to a key file, though you can set a registry-scoped -"keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem". - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-bundling` - -* Default: false -* Type: Boolean - -Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with `global-style` this option -will be preferred. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `legacy-peer-deps` - -* Default: false -* Type: Boolean - -Causes npm to completely ignore `peerDependencies` when building a package -tree, as in npm versions 3 through 6. - -If a package cannot be installed because of overly strict `peerDependencies` -that collide, it provides a way to move forward resolving the situation. - -This differs from `--omit=peer`, in that `--omit=peer` will avoid unpacking -`peerDependencies` on disk, but will still design a tree such that -`peerDependencies` _could_ be unpacked in a correct place. - -Use of `legacy-peer-deps` is not recommended, as it will not enforce the -`peerDependencies` contract that meta-dependencies may rely on. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `link` - -* Default: false -* Type: Boolean - -Used with `npm ls`, limiting output to only those packages that are linked. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `local-address` - -* Default: null -* Type: IP Address - -The IP address of the local interface to use when making connections to the -npm registry. Must be IPv4 in versions of Node prior to 0.12. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `location` - -* Default: "user" unless `--global` is passed, which will also set this value - to "global" -* Type: "global", "user", or "project" - -When passed to `npm config` this refers to which config file to use. - -When set to "global" mode, packages are installed into the `prefix` folder -instead of the current working directory. See -[folders](/configuring-npm/folders) for more on the differences in behavior. - -* packages are installed into the `{prefix}/lib/node_modules` folder, instead - of the current working directory. -* bin files are linked to `{prefix}/bin` -* man pages are linked to `{prefix}/share/man` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `lockfile-version` - -* Default: Version 2 if no lockfile or current lockfile version less than or - equal to 2, otherwise maintain current lockfile version -* Type: null, 1, 2, 3, "1", "2", or "3" - -Set the lockfile format version to be used in package-lock.json and -npm-shrinkwrap-json files. Possible options are: - -1: The lockfile version used by npm versions 5 and 6. Lacks some data that -is used during the install, resulting in slower and possibly less -deterministic installs. Prevents lockfile churn when interoperating with -older npm versions. - -2: The default lockfile version used by npm version 7. Includes both the -version 1 lockfile data and version 3 lockfile data, for maximum determinism -and interoperability, at the expense of more bytes on disk. - -3: Only the new lockfile information introduced in npm version 7. Smaller on -disk than lockfile version 2, but not interoperable with older npm versions. -Ideal if all users are on npm version 7 and higher. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `loglevel` - -* Default: "notice" -* Type: "silent", "error", "warn", "notice", "http", "timing", "info", - "verbose", or "silly" - -What level of logs to report. All logs are written to a debug log, with the -path to that file printed if the execution of a command fails. - -Any logs of a higher level than the setting are shown. The default is -"notice". - -See also the `foreground-scripts` config. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `logs-dir` - -* Default: A directory named `_logs` inside the cache -* Type: null or Path - -The location of npm's log directory. See [`npm logging`](/using-npm/logging) -for more information. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `logs-max` - -* Default: 10 -* Type: Number - -The maximum number of log files to store. - -If set to 0, no log files will be written for the current run. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `long` - -* Default: false -* Type: Boolean - -Show extended information in `ls`, `search`, and `help-search`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `maxsockets` - -* Default: 15 -* Type: Number - -The maximum number of connections to use per origin (protocol/host/port -combination). - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `message` - -* Default: "%s" -* Type: String - -Commit message which is used by `npm version` when creating version commit. - -Any "%s" in the message will be replaced with the version number. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `node-options` - -* Default: null -* Type: null or String - -Options to pass through to Node.js via the `NODE_OPTIONS` environment -variable. This does not impact how npm itself is executed but it does impact -how lifecycle scripts are called. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `node-version` - -* Default: Node.js `process.version` value -* Type: SemVer string - -The node version to use when checking a package's `engines` setting. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `noproxy` - -* Default: The value of the NO_PROXY environment variable -* Type: String (can be set multiple times) - -Domain extensions that should bypass any proxies. - -Also accepts a comma-delimited string. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `npm-version` - -* Default: Output of `npm --version` -* Type: SemVer string - -The npm version to use when checking a package's `engines` setting. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `offline` - -* Default: false -* Type: Boolean - -Force offline mode: no network requests will be done during install. To -allow the CLI to fill in missing cache data, see `--prefer-offline`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit` - -* Default: 'dev' if the `NODE_ENV` environment variable is set to - 'production', otherwise empty. -* Type: "dev", "optional", or "peer" (can be set multiple times) - -Dependency types to omit from the installation tree on disk. - -Note that these dependencies _are_ still resolved and added to the -`package-lock.json` or `npm-shrinkwrap.json` file. They are just not -physically installed on disk. - -If a package type appears in both the `--include` and `--omit` lists, then -it will be included. - -If the resulting omit list includes `'dev'`, then the `NODE_ENV` environment -variable will be set to `'production'` for all lifecycle scripts. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `omit-lockfile-registry-resolved` - -* Default: false -* Type: Boolean - -This option causes npm to create lock files without a `resolved` key for -registry dependencies. Subsequent installs will need to resolve tarball -endpoints with the configured registry, likely resulting in a longer install -time. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `otp` - -* Default: null -* Type: null or String - -This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with `npm access`. - -If not set, and a registry response fails with a challenge for a one-time -password, npm will prompt on the command line for one. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `pack-destination` - -* Default: "." -* Type: String - -Directory in which `npm pack` will save tarballs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package` - -* Default: -* Type: String (can be set multiple times) - -The package or packages to install for [`npm exec`](/commands/npm-exec) - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock` - -* Default: true -* Type: Boolean - -If set to false, then ignore `package-lock.json` files when installing. This -will also prevent _writing_ `package-lock.json` if `save` is true. - -This configuration does not affect `npm ci`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `package-lock-only` - -* Default: false -* Type: Boolean - -If set to true, the current operation will only use the `package-lock.json`, -ignoring `node_modules`. - -For `update` this means only the `package-lock.json` will be updated, -instead of checking `node_modules` and downloading dependencies. - -For `list` this means the output will be based on the tree described by the -`package-lock.json`, rather than the contents of `node_modules`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `parseable` - -* Default: false -* Type: Boolean - -Output parseable results from commands that write to standard output. For -`npm search`, this will be tab-separated table format. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `prefer-offline` - -* Default: false -* Type: Boolean - -If true, staleness checks for cached data will be bypassed, but missing data -will be requested from the server. To force full offline mode, use -`--offline`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `prefer-online` - -* Default: false -* Type: Boolean - -If true, staleness checks for cached data will be forced, making the CLI -look for updates immediately even for fresh package data. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `prefix` - -* Default: In global mode, the folder where the node executable is installed. - In local mode, the nearest parent folder containing either a package.json - file or a node_modules folder. -* Type: Path - -The location to install global items. If set on the command line, then it -forces non-global commands to run in the specified folder. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `preid` - -* Default: "" -* Type: String - -The "prerelease identifier" to use as a prefix for the "prerelease" part of -a semver. Like the `rc` in `1.2.0-rc.8`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `progress` - -* Default: `true` unless running in a known CI system -* Type: Boolean - -When set to `true`, npm will display a progress bar during time intensive -operations, if `process.stderr` is a TTY. - -Set to `false` to suppress the progress bar. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `proxy` - -* Default: null -* Type: null, false, or URL - -A proxy to use for outgoing http requests. If the `HTTP_PROXY` or -`http_proxy` environment variables are set, proxy settings will be honored -by the underlying `request` library. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `read-only` - -* Default: false -* Type: Boolean - -This is used to mark a token as unable to publish when configuring limited -access tokens with the `npm token create` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `rebuild-bundle` - -* Default: true -* Type: Boolean - -Rebuild bundled dependencies after installation. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `registry` - -* Default: "https://registry.npmjs.org/" -* Type: URL - -The base URL of the npm registry. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `replace-registry-host` - -* Default: "npmjs" -* Type: "npmjs", "never", "always", or String - -Defines behavior for replacing the registry host in a lockfile with the -configured registry. - -The default behavior is to replace package dist URLs from the default -registry (https://registry.npmjs.org) to the configured registry. If set to -"never", then use the registry value. If set to "always", then replace the -registry host with the configured host every time. - -You may also specify a bare hostname (e.g., "registry.npmjs.org"). - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save` - -* Default: `true` unless when using `npm update` where it defaults to `false` -* Type: Boolean - -Save installed packages to a `package.json` file as dependencies. - -When used with the `npm rm` command, removes the dependency from -`package.json`. - -Will also prevent writing to `package-lock.json` if set to `false`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-bundle` - -* Default: false -* Type: Boolean - -If a package would be saved at install time by the use of `--save`, -`--save-dev`, or `--save-optional`, then also put it in the -`bundleDependencies` list. - -Ignored if `--save-peer` is set, since peerDependencies cannot be bundled. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-dev` - -* Default: false -* Type: Boolean - -Save installed packages to a package.json file as `devDependencies`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-exact` - -* Default: false -* Type: Boolean - -Dependencies saved to package.json will be configured with an exact version -rather than using npm's default semver range operator. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-optional` - -* Default: false -* Type: Boolean - -Save installed packages to a package.json file as `optionalDependencies`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-peer` - -* Default: false -* Type: Boolean - -Save installed packages to a package.json file as `peerDependencies` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-prefix` - -* Default: "^" -* Type: String - -Configure how versions of packages installed to a package.json file via -`--save` or `--save-dev` get prefixed. - -For example if a package has version `1.2.3`, by default its version is set -to `^1.2.3` which allows minor upgrades for that package, but after `npm -config set save-prefix='~'` it would be set to `~1.2.3` which only allows -patch upgrades. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `save-prod` - -* Default: false -* Type: Boolean - -Save installed packages into `dependencies` specifically. This is useful if -a package already exists in `devDependencies` or `optionalDependencies`, but -you want to move it to be a non-optional production dependency. - -This is the default behavior if `--save` is true, and neither `--save-dev` -or `--save-optional` are true. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `scope` - -* Default: the scope of the current project, if any, or "" -* Type: String - -Associate an operation with a scope for a scoped registry. - -Useful when logging in to or out of a private registry: - -``` -# log in, linking the scope to the custom registry -npm login --scope=@mycorp --registry=https://registry.mycorp.com - -# log out, removing the link and the auth token -npm logout --scope=@mycorp -``` - -This will cause `@mycorp` to be mapped to the registry for future -installation of packages specified according to the pattern -`@mycorp/package`. - -This will also cause `npm init` to create a scoped package. - -``` -# accept all defaults, and create a package named "@foo/whatever", -# instead of just named "whatever" -npm init --scope=@foo --yes -``` - - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `script-shell` - -* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows -* Type: null or String - -The shell to use for scripts run with the `npm exec`, `npm run` and `npm -init <package-spec>` commands. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `searchexclude` - -* Default: "" -* Type: String - -Space-separated options that limit the results from search. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `searchlimit` - -* Default: 20 -* Type: Number - -Number of items to limit search results to. Will not apply at all to legacy -searches. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `searchopts` - -* Default: "" -* Type: String - -Space-separated options that are always passed to search. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `searchstaleness` - -* Default: 900 -* Type: Number - -The age of the cache, in seconds, before another registry request is made if -using legacy search endpoint. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `shell` - -* Default: SHELL environment variable, or "bash" on Posix, or "cmd.exe" on - Windows -* Type: String - -The shell to run for the `npm explore` command. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `sign-git-commit` - -* Default: false -* Type: Boolean - -If set to true, then the `npm version` command will commit the new package -version using `-S` to add a signature. - -Note that git requires you to have set up GPG keys in your git configs for -this to work properly. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `sign-git-tag` - -* Default: false -* Type: Boolean - -If set to true, then the `npm version` command will tag the version using -`-s` to add a signature. - -Note that git requires you to have set up GPG keys in your git configs for -this to work properly. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-peer-deps` - -* Default: false -* Type: Boolean - -If set to `true`, and `--legacy-peer-deps` is not set, then _any_ -conflicting `peerDependencies` will be treated as an install failure, even -if npm could reasonably guess the appropriate resolution based on non-peer -dependency relationships. - -By default, conflicting `peerDependencies` deep in the dependency graph will -be resolved using the nearest non-peer dependency specification, even if -doing so will result in some packages receiving a peer dependency outside -the range set in their package's `peerDependencies` object. - -When such and override is performed, a warning is printed, explaining the -conflict and the packages involved. If `--strict-peer-deps` is set, then -this warning is treated as a failure. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `strict-ssl` - -* Default: true -* Type: Boolean - -Whether or not to do SSL key validation when making requests to the registry -via https. - -See also the `ca` config. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `tag` - -* Default: "latest" -* Type: String - -If you ask npm to install a package and don't tell it a specific version, -then it will install the specified tag. - -Also the tag that is added to the package@version specified by the `npm tag` -command, if no explicit tag is given. - -When used by the `npm diff` command, this is the tag used to fetch the -tarball that will be compared with the local files by default. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `tag-version-prefix` - -* Default: "v" -* Type: String - -If set, alters the prefix used when tagging a new version when performing a -version increment using `npm-version`. To remove the prefix altogether, set -it to the empty string: `""`. - -Because other tools may rely on the convention that npm version tags look -like `v1.0.0`, _only use this property if it is absolutely necessary_. In -particular, use care when overriding this setting for public packages. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `timing` - -* Default: false -* Type: Boolean - -If true, writes a debug log to `logs-dir` and timing information to -`_timing.json` in the cache, even if the command completes successfully. -`_timing.json` is a newline delimited list of JSON objects. - -You can quickly view it with this [json](https://npm.im/json) command line: -`npm exec -- json -g < ~/.npm/_timing.json`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `umask` - -* Default: 0 -* Type: Octal numeric string in range 0000..0777 (0..511) - -The "umask" value to use when setting the file creation mode on files and -folders. - -Folders and executables are given a mode which is `0o777` masked against -this value. Other files are given a mode which is `0o666` masked against -this value. - -Note that the underlying system will _also_ apply its own umask value to -files and folders that are created, and npm does not circumvent this, but -rather adds the `--umask` config to it. - -Thus, the effective default umask value on most POSIX systems is 0o22, -meaning that folders and executables are created with a mode of 0o755 and -other files are created with a mode of 0o644. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `unicode` - -* Default: false on windows, true on mac/unix systems with a unicode locale, - as defined by the `LC_ALL`, `LC_CTYPE`, or `LANG` environment variables. -* Type: Boolean - -When set to true, npm uses unicode characters in the tree output. When -false, it uses ascii characters instead of unicode glyphs. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `update-notifier` - -* Default: true -* Type: Boolean - -Set to false to suppress the update notification when using an older version -of npm than the latest. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `usage` - -* Default: false -* Type: Boolean - -Show short usage output about the command specified. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `user-agent` - -* Default: "npm/{npm-version} node/{node-version} {platform} {arch} - workspaces/{workspaces} {ci}" -* Type: String - -Sets the User-Agent request header. The following fields are replaced with -their actual counterparts: - -* `{npm-version}` - The npm version in use -* `{node-version}` - The Node.js version in use -* `{platform}` - The value of `process.platform` -* `{arch}` - The value of `process.arch` -* `{workspaces}` - Set to `true` if the `workspaces` or `workspace` options - are set. -* `{ci}` - The value of the `ci-name` config, if set, prefixed with `ci/`, or - an empty string if `ci-name` is empty. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `userconfig` - -* Default: "~/.npmrc" -* Type: Path - -The location of user-level configuration settings. - -This may be overridden by the `npm_config_userconfig` environment variable -or the `--userconfig` command line option, but may _not_ be overridden by -settings in the `globalconfig` file. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `version` - -* Default: false -* Type: Boolean - -If true, output the npm version and exit successfully. - -Only relevant when specified explicitly on the command line. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `versions` - -* Default: false -* Type: Boolean - -If true, output the npm version as well as node's `process.versions` map and -the version in the current working directory's `package.json` file if one -exists, and exit successfully. - -Only relevant when specified explicitly on the command line. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `viewer` - -* Default: "man" on Posix, "browser" on Windows -* Type: String - -The program to use to view help content. - -Set to `"browser"` to view html help content in the default web browser. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `which` - -* Default: null -* Type: null or Number - -If there are multiple funding sources, which 1-indexed source URL to open. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspace` - -* Default: -* Type: String (can be set multiple times) - -Enable running a command in the context of the configured workspaces of the -current project while filtering by running only the workspaces defined by -this configuration option. - -Valid values for the `workspace` config are either: - -* Workspace names -* Path to a workspace directory -* Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - -When set for the `npm init` command, this may be set to the folder of a -workspace which does not yet exist, to create the folder and set it up as a -brand new workspace within the project. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces` - -* Default: null -* Type: null or Boolean - -Set to true to run the command in the context of **all** configured -workspaces. - -Explicitly setting this to false will cause commands like `install` to -ignore workspaces altogether. When not set explicitly: - -- Commands that operate on the `node_modules` tree (install, update, etc.) -will link workspaces into the `node_modules` folder. - Commands that do -other things (test, exec, publish, etc.) will operate on the root project, -_unless_ one or more workspaces are specified in the `workspace` config. - -This value is not exported to the environment for child processes. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `workspaces-update` - -* Default: true -* Type: Boolean - -If set to true, the npm cli will run an update after operations that may -possibly change the workspaces installed to the `node_modules` folder. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `yes` - -* Default: null -* Type: null or Boolean - -Automatically answer "yes" to any prompts that npm might print on the -command line. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `also` - -* Default: null -* Type: null, "dev", or "development" -* DEPRECATED: Please use --include=dev instead. - -When set to `dev` or `development`, this is an alias for `--include=dev`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cache-max` - -* Default: Infinity -* Type: Number -* DEPRECATED: This option has been deprecated in favor of `--prefer-online` - -`--cache-max=0` is an alias for `--prefer-online` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `cache-min` - -* Default: 0 -* Type: Number -* DEPRECATED: This option has been deprecated in favor of `--prefer-offline`. - -`--cache-min=9999 (or bigger)` is an alias for `--prefer-offline`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `dev` - -* Default: false -* Type: Boolean -* DEPRECATED: Please use --include=dev instead. - -Alias for `--include=dev`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init.author.email` - -* Default: "" -* Type: String -* DEPRECATED: Use `--init-author-email` instead. - -Alias for `--init-author-email` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init.author.name` - -* Default: "" -* Type: String -* DEPRECATED: Use `--init-author-name` instead. - -Alias for `--init-author-name` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init.author.url` - -* Default: "" -* Type: "" or URL -* DEPRECATED: Use `--init-author-url` instead. - -Alias for `--init-author-url` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init.license` - -* Default: "ISC" -* Type: String -* DEPRECATED: Use `--init-license` instead. - -Alias for `--init-license` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init.module` - -* Default: "~/.npm-init.js" -* Type: Path -* DEPRECATED: Use `--init-module` instead. - -Alias for `--init-module` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `init.version` - -* Default: "1.0.0" -* Type: SemVer string -* DEPRECATED: Use `--init-version` instead. - -Alias for `--init-version` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `only` - -* Default: null -* Type: null, "prod", or "production" -* DEPRECATED: Use `--omit=dev` to omit dev dependencies from the install. - -When set to `prod` or `production`, this is an alias for `--omit=dev`. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `optional` - -* Default: null -* Type: null or Boolean -* DEPRECATED: Use `--omit=optional` to exclude optional dependencies, or - `--include=optional` to include them. - -Default value does install optional deps unless otherwise omitted. - -Alias for --include=optional or --omit=optional - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `production` - -* Default: null -* Type: null or Boolean -* DEPRECATED: Use `--omit=dev` instead. - -Alias for `--omit=dev` - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `shrinkwrap` - -* Default: true -* Type: Boolean -* DEPRECATED: Use the --package-lock setting instead. - -Alias for --package-lock - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `sso-poll-frequency` - -* Default: 500 -* Type: Number -* DEPRECATED: The --auth-type method of SSO/SAML/OAuth will be removed in a - future version of npm in favor of web-based login. - -When used with SSO-enabled `auth-type`s, configures how regularly the -registry should be polled while the user is completing authentication. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `sso-type` - -* Default: "oauth" -* Type: null, "oauth", or "saml" -* DEPRECATED: The --auth-type method of SSO/SAML/OAuth will be removed in a - future version of npm in favor of web-based login. - -If `--auth-type=sso`, the type of SSO type to use. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> - -#### `tmp` - -* Default: The value returned by the Node.js `os.tmpdir()` method - <https://nodejs.org/api/os.html#os_os_tmpdir> -* Type: Path -* DEPRECATED: This setting is no longer used. npm stores temporary files in a - special location in the cache, and they are managed by - [`cacache`](http://npm.im/cacache). - -Historically, the location where temporary files were stored. No longer -relevant. - -<!-- automatically generated, do not edit manually --> -<!-- see lib/utils/config/definitions.js --> -<!-- AUTOGENERATED CONFIG DESCRIPTIONS END --> - -### See also - -* [npm config](/commands/npm-config) -* [npmrc](/configuring-npm/npmrc) -* [npm scripts](/using-npm/scripts) -* [npm folders](/configuring-npm/folders) -* [npm](/commands/npm) diff --git a/docs/content/using-npm/dependency-selectors.md b/docs/content/using-npm/dependency-selectors.md deleted file mode 100644 index 9d65baf631a7e..0000000000000 --- a/docs/content/using-npm/dependency-selectors.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: Dependency Selector Syntax & Querying -section: 7 -description: Dependency Selector Syntax & Querying ---- - -### Description - -The [`npm query`](/commands/npm-query) commmand exposes a new dependency selector syntax (informed by & respecting many aspects of the [CSS Selectors 4 Spec](https://dev.w3.org/csswg/selectors4/#relational)) which: - -- Standardizes the shape of, & querying of, dependency graphs with a robust object model, metadata & selector syntax -- Leverages existing, known language syntax & operators from CSS to make disparate package information broadly accessible -- Unlocks the ability to answer complex, multi-faceted questions about dependencies, their relationships & associative metadata -- Consolidates redundant logic of similar query commands in `npm` (ex. `npm fund`, `npm ls`, `npm outdated`, `npm audit` ...) - -### Dependency Selector Syntax `v1.0.0` - -#### Overview: - -- there is no "type" or "tag" selectors (ex. `div, h1, a`) as a dependency/target is the only type of `Node` that can be queried -- the term "dependencies" is in reference to any `Node` found in a `tree` returned by `Arborist` - -#### Combinators - -- `>` direct descendant/child -- ` ` any descendant/child -- `~` sibling - -#### Selectors - -- `*` universal selector -- `#<name>` dependency selector (equivalent to `[name="..."]`) -- `#<name>@<version>` (equivalent to `[name=<name>]:semver(<version>)`) -- `,` selector list delimiter -- `.` dependency type selector -- `:` pseudo selector - -#### Dependency Type Selectors - -- `.prod` dependency found in the `dependencies` section of `package.json`, or is a child of said dependency -- `.dev` dependency found in the `devDependencies` section of `package.json`, or is a child of said dependency -- `.optional` dependency found in the `optionalDependencies` section of `package.json`, or has `"optional": true` set in its entry in the `peerDependenciesMeta` section of `package.json`, or a child of said dependency -- `.peer` dependency found in the `peerDependencies` section of `package.json` -- `.workspace` dependency found in the [`workspaces`](https://docs.npmjs.com/cli/v8/using-npm/workspaces) section of `package.json` -- `.bundled` dependency found in the `bundleDependencies` section of `package.json`, or is a child of said dependency - -#### Pseudo Selectors -- [`:not(<selector>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:not) -- [`:has(<selector>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) -- [`:is(<selector list>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is) -- [`:root`](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) matches the root node/dependency -- [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) matches node/dependency it was queried against -- [`:empty`](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty) when a dependency has no dependencies -- [`:private`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#private) when a dependency is private -- `:link` when a dependency is linked (for instance, workspaces or packages manually [`linked`](https://docs.npmjs.com/cli/v8/commands/npm-link) -- `:deduped` when a dependency has been deduped (note that this does *not* always mean the dependency has been hoisted to the root of node_modules) -- `:override` when a dependency is an override (not implemented yet) -- `:extraneous` when a dependency exists but is not defined as a dependency of any node -- `:invalid` when a dependency version is out of its ancestors specified range -- `:missing` when a dependency is not found on disk -- `:semver(<spec>)` matching a valid [`node-semver`](https://github.com/npm/node-semver) spec -- `:path(<path>)` [glob](https://www.npmjs.com/package/glob) matching based on dependencies path relative to the project -- `:type(<type>)` [based on currently recognized types](https://github.com/npm/npm-package-arg#result-object) - -#### [Attribute Selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) - -The attribute selector evaluates the key/value pairs in `package.json` if they are `String`s. - -- `[]` attribute selector (ie. existence of attribute) -- `[attribute=value]` attribute value is equivalant... -- `[attribute~=value]` attribute value contains word... -- `[attribute*=value]` attribute value contains string... -- `[attribute|=value]` attribute value is equal to or starts with... -- `[attribute^=value]` attribute value starts with... -- `[attribute$=value]` attribute value ends with... - -#### `Array` & `Object` Attribute Selectors - -The generic `:attr()` pseudo selector standardizes a pattern which can be used for attribute selection of `Object`s, `Array`s or `Arrays` of `Object`s accessible via `Arborist`'s `Node.package` metadata. This allows for iterative attribute selection beyond top-level `String` evaluation. The last argument passed to `:attr()` must be an `attribute` selector or a nested `:attr()`. See examples below: - -#### `Objects` - -```css -/* return dependencies that have a `scripts.test` containing `"tap"` */ -*:attr(scripts, [test~=tap]) -``` - -#### Nested `Objects` - -Nested objects are expressed as sequential arguments to `:attr()`. - -```css -/* return dependencies that have a testling config for opera browsers */ -*:attr(testling, browsers, [~=opera]) -``` - -#### `Arrays` - -`Array`s specifically uses a special/reserved `.` character in place of a typical attribute name. `Arrays` also support exact `value` matching when a `String` is passed to the selector. - -##### Example of an `Array` Attribute Selection: -```css -/* removes the distinction between properties & arrays */ -/* ie. we'd have to check the property & iterate to match selection */ -*:attr([keywords^=react]) -*:attr(contributors, :attr([name~=Jordan])) -``` - -##### Example of an `Array` matching directly to a value: -```css -/* return dependencies that have the exact keyword "react" */ -/* this is equivalent to `*:keywords([value="react"])` */ -*:attr([keywords=react]) -``` - -##### Example of an `Array` of `Object`s: -```css -/* returns */ -*:attr(contributors, [email=ruyadorno@github.com]) -``` - -### Groups - -Dependency groups are defined by the package relationships to their ancestors (ie. the dependency types that are defined in `package.json`). This approach is user-centric as the ecosystem has been taught to think about dependencies in these groups first-and-foremost. Dependencies are allowed to be included in multiple groups (ex. a `prod` dependency may also be a `dev` dependency (in that it's also required by another `dev` dependency) & may also be `bundled` - a selector for that type of dependency would look like: `*.prod.dev.bundled`). - -- `.prod` -- `.dev` -- `.optional` -- `.peer` -- `.bundled` -- `.workspace` - -Please note that currently `workspace` deps are always `prod` dependencies. Additionally the `.root` dependency is also considered a `prod` dependency. - -### Programmatic Usage - -- `Arborist`'s `Node` Class has a `.querySelectorAll()` method - - this method will return a filtered, flattened dependency Arborist `Node` list based on a valid query selector - -```js -const Arborist = require('@npmcli/arborist') -const arb = new Arborist({}) -``` - -```js -// root-level -arb.loadActual((tree) => { - // query all production dependencies - const results = await tree.querySelectorAll('.prod') - console.log(results) -}) -``` - -```js -// iterative -arb.loadActual((tree) => { - // query for the deduped version of react - const results = await tree.querySelectorAll('#react:not(:deduped)') - // query the deduped react for git deps - const deps = await results[0].querySelectorAll(':type(git)') - console.log(deps) -}) -``` - -## See Also - -* [npm query](/commands/npm-query) -* [@npmcli/arborist](https://npm.im/@npmcli/arborist] diff --git a/docs/content/using-npm/developers.md b/docs/content/using-npm/developers.md deleted file mode 100644 index 5fc2e5876e3dd..0000000000000 --- a/docs/content/using-npm/developers.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -title: developers -section: 7 -description: Developer Guide ---- - -### Description - -So, you've decided to use npm to develop (and maybe publish/deploy) -your project. - -Fantastic! - -There are a few things that you need to do above the simple steps -that your users will do to install your program. - -### About These Documents - -These are man pages. If you install npm, you should be able to -then do `man npm-thing` to get the documentation on a particular -topic, or `npm help thing` to see the same information. - -### What is a Package - -A package is: - -* a) a folder containing a program described by a package.json file -* b) a gzipped tarball containing (a) -* c) a url that resolves to (b) -* d) a `<name>@<version>` that is published on the registry with (c) -* e) a `<name>@<tag>` that points to (d) -* f) a `<name>` that has a "latest" tag satisfying (e) -* g) a `git` url that, when cloned, results in (a). - -Even if you never publish your package, you can still get a lot of -benefits of using npm if you just want to write a node program (a), and -perhaps if you also want to be able to easily install it elsewhere -after packing it up into a tarball (b). - -Git urls can be of the form: - -```bash -git://github.com/user/project.git#commit-ish -git+ssh://user@hostname:project.git#commit-ish -git+http://user@hostname/project/blah.git#commit-ish -git+https://user@hostname/project/blah.git#commit-ish -``` - -The `commit-ish` can be any tag, sha, or branch which can be supplied as -an argument to `git checkout`. The default is whatever the repository uses -as its default branch. - -### The package.json File - -You need to have a `package.json` file in the root of your project to do -much of anything with npm. That is basically the whole interface. - -See [`package.json`](/configuring-npm/package-json) for details about what -goes in that file. At the very least, you need: - -* name: This should be a string that identifies your project. Please do - not use the name to specify that it runs on node, or is in JavaScript. - You can use the "engines" field to explicitly state the versions of node - (or whatever else) that your program requires, and it's pretty well - assumed that it's JavaScript. - - It does not necessarily need to match your github repository name. - - So, `node-foo` and `bar-js` are bad names. `foo` or `bar` are better. - -* version: A semver-compatible version. - -* engines: Specify the versions of node (or whatever else) that your - program runs on. The node API changes a lot, and there may be bugs or - new functionality that you depend on. Be explicit. - -* author: Take some credit. - -* scripts: If you have a special compilation or installation script, then - you should put it in the `scripts` object. You should definitely have at - least a basic smoke-test command as the "scripts.test" field. See - [scripts](/using-npm/scripts). - -* main: If you have a single module that serves as the entry point to your - program (like what the "foo" package gives you at require("foo")), then - you need to specify that in the "main" field. - -* directories: This is an object mapping names to folders. The best ones - to include are "lib" and "doc", but if you use "man" to specify a folder - full of man pages, they'll get installed just like these ones. - -You can use `npm init` in the root of your package in order to get you -started with a pretty basic package.json file. See [`npm -init`](/commands/npm-init) for more info. - -### Keeping files *out* of your Package - -Use a `.npmignore` file to keep stuff out of your package. If there's no -`.npmignore` file, but there *is* a `.gitignore` file, then npm will ignore -the stuff matched by the `.gitignore` file. If you *want* to include -something that is excluded by your `.gitignore` file, you can create an -empty `.npmignore` file to override it. Like `git`, `npm` looks for -`.npmignore` and `.gitignore` files in all subdirectories of your package, -not only the root directory. - -`.npmignore` files follow the [same pattern -rules](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#_ignoring) -as `.gitignore` files: - -* Blank lines or lines starting with `#` are ignored. -* Standard glob patterns work. -* You can end patterns with a forward slash `/` to specify a directory. -* You can negate a pattern by starting it with an exclamation point `!`. - -By default, the following paths and files are ignored, so there's no -need to add them to `.npmignore` explicitly: - -* `.*.swp` -* `._*` -* `.DS_Store` -* `.git` -* `.gitignore` -* `.hg` -* `.npmignore` -* `.npmrc` -* `.lock-wscript` -* `.svn` -* `.wafpickle-*` -* `config.gypi` -* `CVS` -* `npm-debug.log` - -Additionally, everything in `node_modules` is ignored, except for -bundled dependencies. npm automatically handles this for you, so don't -bother adding `node_modules` to `.npmignore`. - -The following paths and files are never ignored, so adding them to -`.npmignore` is pointless: - -* `package.json` -* `README` (and its variants) -* `CHANGELOG` (and its variants) -* `LICENSE` / `LICENCE` - -If, given the structure of your project, you find `.npmignore` to be a -maintenance headache, you might instead try populating the `files` -property of `package.json`, which is an array of file or directory names -that should be included in your package. Sometimes manually picking -which items to allow is easier to manage than building a block list. - -#### Testing whether your `.npmignore` or `files` config works - -If you want to double check that your package will include only the files -you intend it to when published, you can run the `npm pack` command locally -which will generate a tarball in the working directory, the same way it -does for publishing. - -### Link Packages - -`npm link` is designed to install a development package and see the -changes in real time without having to keep re-installing it. (You do -need to either re-link or `npm rebuild -g` to update compiled packages, -of course.) - -More info at [`npm link`](/commands/npm-link). - -### Before Publishing: Make Sure Your Package Installs and Works - -**This is important.** - -If you can not install it locally, you'll have -problems trying to publish it. Or, worse yet, you'll be able to -publish it, but you'll be publishing a broken or pointless package. -So don't do that. - -In the root of your package, do this: - -```bash -npm install . -g -``` - -That'll show you that it's working. If you'd rather just create a symlink -package that points to your working directory, then do this: - -```bash -npm link -``` - -Use `npm ls -g` to see if it's there. - -To test a local install, go into some other folder, and then do: - -```bash -cd ../some-other-folder -npm install ../my-package -``` - -to install it locally into the node_modules folder in that other place. - -Then go into the node-repl, and try using require("my-thing") to -bring in your module's main module. - -### Create a User Account - -Create a user with the adduser command. It works like this: - -```bash -npm adduser -``` - -and then follow the prompts. - -This is documented better in [npm adduser](/commands/npm-adduser). - -### Publish your Package - -This part's easy. In the root of your folder, do this: - -```bash -npm publish -``` - -You can give publish a url to a tarball, or a filename of a tarball, -or a path to a folder. - -Note that pretty much **everything in that folder will be exposed** -by default. So, if you have secret stuff in there, use a -`.npmignore` file to list out the globs to ignore, or publish -from a fresh checkout. - -### Brag about it - -Send emails, write blogs, blab in IRC. - -Tell the world how easy it is to install your program! - -### See also - -* [npm](/commands/npm) -* [npm init](/commands/npm-init) -* [package.json](/configuring-npm/package-json) -* [npm scripts](/using-npm/scripts) -* [npm publish](/commands/npm-publish) -* [npm adduser](/commands/npm-adduser) -* [npm registry](/using-npm/registry) diff --git a/docs/content/using-npm/logging.md b/docs/content/using-npm/logging.md deleted file mode 100644 index eb83b167e698b..0000000000000 --- a/docs/content/using-npm/logging.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Logging -section: 7 -description: Why, What & How We Log ---- - -### Description - -The `npm` CLI has various mechanisms for showing different levels of information back to end-users for certain commands, configurations & environments. - -### Setting Log File Location - -All logs are written to a debug log, with the path to that file printed if the execution of a command fails. - -The default location of the logs directory is a directory named `_logs` inside the npm cache. This can be changed -with the `logs-dir` config option. - -Log files will be removed from the `logs-dir` when the number of log files exceeds `logs-max`, with the oldest logs being deleted first. - -To turn off logs completely set `--logs-max=0`. - -### Setting Log Levels - -#### `loglevel` - -`loglevel` is a global argument/config that can be set to determine the type of information to be displayed. - -The default value of `loglevel` is `"notice"` but there are several levels/types of logs available, including: - -- `"silent"` -- `"error"` -- `"warn"` -- `"notice"` -- `"http"` -- `"timing"` -- `"info"` -- `"verbose"` -- `"silly"` - -All logs pertaining to a level proceeding the current setting will be shown. - -##### Aliases - -The log levels listed above have various corresponding aliases, including: - -- `-d`: `--loglevel info` -- `--dd`: `--loglevel verbose` -- `--verbose`: `--loglevel verbose` -- `--ddd`: `--loglevel silly` -- `-q`: `--loglevel warn` -- `--quiet`: `--loglevel warn` -- `-s`: `--loglevel silent` -- `--silent`: `--loglevel silent` - -#### `foreground-scripts` - -The `npm` CLI began hiding the output of lifecycle scripts for `npm install` as of `v7`. Notably, this means you will not see logs/output from packages that may be using "install scripts" to display information back to you or from your own project's scripts defined in `package.json`. If you'd like to change this behavior & log this output you can set `foreground-scripts` to `true`. - -### Timing Information - -The `--timing` config can be set which does two things: - -1. Always shows the full path to the debug log regardless of command exit status -1. Write timing information to a timing file in the cache or `logs-dir` - -This file is a newline delimited list of JSON objects that can be inspected to see timing data for each task in a `npm` CLI run. - -### Registry Response Headers - -#### `npm-notice` - -The `npm` CLI reads from & logs any `npm-notice` headers that are returned from the configured registry. This mechanism can be used by third-party registries to provide useful information when network-dependent requests occur. - -This header is not cached, and will not be logged if the request is served from the cache. - -### Logs and Sensitive Information - -The `npm` CLI makes a best effort to redact the following from terminal output and log files: - -- Passwords inside basic auth URLs -- npm tokens - -However, this behavior should not be relied on to keep all possible sensitive information redacted. If you are concerned about secrets in your log file or terminal output, you can use `--loglevel=silent` and `--logs-max=0` to ensure no logs are written to your terminal or filesystem. - -### See also - -* [config](/using-npm/config) diff --git a/docs/content/using-npm/orgs.md b/docs/content/using-npm/orgs.md deleted file mode 100644 index 5fe9ac6de377f..0000000000000 --- a/docs/content/using-npm/orgs.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: orgs -section: 7 -description: Working with Teams & Orgs ---- - -### Description - -There are three levels of org users: - -1. Super admin, controls billing & adding people to the org. -2. Team admin, manages team membership & package access. -3. Developer, works on packages they are given access to. - -The super admin is the only person who can add users to the org because it impacts the monthly bill. The super admin will use the website to manage membership. Every org has a `developers` team that all users are automatically added to. - -The team admin is the person who manages team creation, team membership, and package access for teams. The team admin grants package access to teams, not individuals. - -The developer will be able to access packages based on the teams they are on. Access is either read-write or read-only. - -There are two main commands: - -1. `npm team` see [npm team](/commands/npm-team) for more details -2. `npm access` see [npm access](/commands/npm-access) for more details - -### Team Admins create teams - -* Check who you’ve added to your org: - -```bash -npm team ls <org>:developers -``` - -* Each org is automatically given a `developers` team, so you can see the whole list of team members in your org. This team automatically gets read-write access to all packages, but you can change that with the `access` command. - -* Create a new team: - -```bash -npm team create <org:team> -``` - -* Add members to that team: - -```bash -npm team add <org:team> <user> -``` - -### Publish a package and adjust package access - -* In package directory, run - -```bash -npm init --scope=<org> -``` -to scope it for your org & publish as usual - -* Grant access: - -```bash -npm access grant <read-only|read-write> <org:team> [<package>] -``` - -* Revoke access: - -```bash -npm access revoke <org:team> [<package>] -``` - -### Monitor your package access - -* See what org packages a team member can access: - -```bash -npm access ls-packages <org> <user> -``` - -* See packages available to a specific team: - -```bash -npm access ls-packages <org:team> -``` - -* Check which teams are collaborating on a package: - -```bash -npm access ls-collaborators <pkg> -``` - -### See also - -* [npm team](/commands/npm-team) -* [npm access](/commands/npm-access) -* [npm scope](/using-npm/scope) diff --git a/docs/content/using-npm/package-spec.md b/docs/content/using-npm/package-spec.md deleted file mode 100644 index 0d3741018f036..0000000000000 --- a/docs/content/using-npm/package-spec.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: package-spec -section: 7 -description: Package name specifier ---- - - -### Description - -Commands like `npm install` and the dependency sections in the -`package.json` use a package name specifier. This can be many different -things that all refer to a "package". Examples include a package name, -git url, tarball, or local directory. These will generally be referred -to as `<package-spec>` in the help output for the npm commands that use -this package name specifier. - -### Package name - -* `[<@scope>/]<pkg>` -* `[<@scope>/]<pkg>@<tag>` -* `[<@scope>/]<pkg>@<version>` -* `[<@scope>/]<pkg>@<version range>` - -Refers to a package by name, with or without a scope, and optionally -tag, version, or version range. This is typically used in combination -with the [registry](/using-npm/config#registry) config to refer to a -package in a registry. - -Examples: -* `npm` -* `@npmcli/arborist` -* `@npmcli/arborist@latest` -* `npm@6.13.1` -* `npm@^4.0.0` - -### Aliases - -* `<alias>@npm:<name>` - -Primarily used by commands like `npm install` and in the dependency -sections in the `package.json`, this refers to a package by an alias. -The `<alias>` is the name of the package as it is reified in the -`node_modules` folder, and the `<name>` refers to a package name as -found in the configured registry. - -See `Package name` above for more info on referring to a package by -name, and [registry](/using-npm/config#registry) for configuring which -registry is used when referring to a package by name. - -Examples: -* `semver:@npm:@npmcli/semver-with-patch` -* `semver:@npm:semver@7.2.2` -* `semver:@npm:semver@legacy` - -### Folders - -* `<folder>` - -This refers to a package on the local filesystem. Specifically this is -a folder with a `package.json` file in it. This *should* always be -prefixed with a `/` or `./` (or your OS equivalent) to reduce confusion. -npm currently will parse a string with more than one `/` in it as a -folder, but this is legacy behavior that may be removed in a future -version. - -Examples: - -* `./my-package` -* `/opt/npm/my-package` - -### Tarballs - -* `<tarball file>` -* `<tarball url>` - -Examples: - -* `./my-package.tgz` -* `https://registry.npmjs.org/semver/-/semver-1.0.0.tgz` - -Refers to a package in a tarball format, either on the local filesystem -or remotely via url. This is the format that packages exist in when -uploaded to a registry. - -### git urls - -* `<git:// url>` -* `<github username>/<github project>` - -Refers to a package in a git repo. This can be a full git url, git -shorthand, or a username/package on GitHub. You can specify a -git tag, branch, or other git ref by appending `#ref`. - -Examples: - -* `https://github.com/npm/cli.git` -* `git@github.com:npm/cli.git` -* `git+ssh://git@github.com/npm/cli#v6.0.0` -* `github:npm/cli#HEAD` -* `npm/cli#c12ea07` - -### See also - -[npm-package-arg](https://npm.im/npm-package-arg) -[scope](/using-npm/scope) -[config](/using-npm/config) diff --git a/docs/content/using-npm/registry.md b/docs/content/using-npm/registry.md deleted file mode 100644 index 4a265db03f079..0000000000000 --- a/docs/content/using-npm/registry.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: registry -section: 7 -description: The JavaScript Package Registry ---- - -### Description - -To resolve packages by name and version, npm talks to a registry website -that implements the CommonJS Package Registry specification for reading -package info. - -npm is configured to use the **npm public registry** at -<https://registry.npmjs.org> by default. Use of the npm public registry is -subject to terms of use available at <https://docs.npmjs.com/policies/terms>. - -You can configure npm to use any compatible registry you like, and even run -your own registry. Use of someone else's registry may be governed by their -terms of use. - -npm's package registry implementation supports several -write APIs as well, to allow for publishing packages and managing user -account information. - -The npm public registry is powered by a CouchDB database, -of which there is a public mirror at <https://skimdb.npmjs.com/registry>. - -The registry URL used is determined by the scope of the package (see -[`scope`](/using-npm/scope). If no scope is specified, the default registry is used, which is -supplied by the `registry` config parameter. See [`npm config`](/commands/npm-config), -[`npmrc`](/configuring-npm/npmrc), and [`config`](/using-npm/config) for more on managing npm's configuration. - -When the default registry is used in a package-lock or shrinkwrap is has the -special meaning of "the currently configured registry". If you create a lock -file while using the default registry you can switch to another registry and -npm will install packages from the new registry, but if you create a lock -file while using a custom registry packages will be installed from that -registry even after you change to another registry. - -### Does npm send any information about me back to the registry? - -Yes. - -When making requests of the registry npm adds two headers with information -about your environment: - -* `Npm-Scope` – If your project is scoped, this header will contain its - scope. In the future npm hopes to build registry features that use this - information to allow you to customize your experience for your - organization. -* `Npm-In-CI` – Set to "true" if npm believes this install is running in a - continuous integration environment, "false" otherwise. This is detected by - looking for the following environment variables: `CI`, `TDDIUM`, - `JENKINS_URL`, `bamboo.buildKey`. If you'd like to learn more you may find - the [original PR](https://github.com/npm/npm-registry-client/pull/129) - interesting. - This is used to gather better metrics on how npm is used by humans, versus - build farms. - -The npm registry does not try to correlate the information in these headers -with any authenticated accounts that may be used in the same requests. - -### How can I prevent my package from being published in the official registry? - -Set `"private": true` in your `package.json` to prevent it from being -published at all, or -`"publishConfig":{"registry":"http://my-internal-registry.local"}` -to force it to be published only to your internal/private registry. - -See [`package.json`](/configuring-npm/package-json) for more info on what goes in the package.json file. - -### Where can I find my own, & other's, published packages? - -<https://www.npmjs.com/> - -### See also - -* [npm config](/commands/npm-config) -* [config](/using-npm/config) -* [npmrc](/configuring-npm/npmrc) -* [npm developers](/using-npm/developers) diff --git a/docs/content/using-npm/removal.md b/docs/content/using-npm/removal.md deleted file mode 100644 index c5e13b6741b6d..0000000000000 --- a/docs/content/using-npm/removal.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: removal -section: 7 -description: Cleaning the Slate ---- - -### Synopsis - -So sad to see you go. - -```bash -sudo npm uninstall npm -g -``` - -Or, if that fails, get the npm source code, and do: - -```bash -sudo make uninstall -``` - -### More Severe Uninstalling - -Usually, the above instructions are sufficient. That will remove -npm, but leave behind anything you've installed. - -If that doesn't work, or if you require more drastic measures, -continue reading. - -Note that this is only necessary for globally-installed packages. Local -installs are completely contained within a project's `node_modules` -folder. Delete that folder, and everything is gone less a package's -install script is particularly ill-behaved). - -This assumes that you installed node and npm in the default place. If -you configured node with a different `--prefix`, or installed npm with a -different prefix setting, then adjust the paths accordingly, replacing -`/usr/local` with your install prefix. - -To remove everything npm-related manually: - -```bash -rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/npm* -``` - -If you installed things *with* npm, then your best bet is to uninstall -them with npm first, and then install them again once you have a -proper install. This can help find any symlinks that are lying -around: - -```bash -ls -laF /usr/local/{lib/node{,/.npm},bin,share/man} | grep npm -``` - -Prior to version 0.3, npm used shim files for executables and node -modules. To track those down, you can do the following: - -```bash -find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ; -``` - -### See also - -* [npm uninstall](/commands/npm-uninstall) -* [npm prune](/commands/npm-prune) diff --git a/docs/content/using-npm/scope.md b/docs/content/using-npm/scope.md deleted file mode 100644 index 1abbe9081ead8..0000000000000 --- a/docs/content/using-npm/scope.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: scope -section: 7 -description: Scoped packages ---- - -### Description - -All npm packages have a name. Some package names also have a scope. A scope -follows the usual rules for package names (URL-safe characters, no leading dots -or underscores). When used in package names, scopes are preceded by an `@` symbol -and followed by a slash, e.g. - -```bash -@somescope/somepackagename -``` - -Scopes are a way of grouping related packages together, and also affect a few -things about the way npm treats the package. - -Each npm user/organization has their own scope, and only you can add packages -in your scope. This means you don't have to worry about someone taking your -package name ahead of you. Thus it is also a good way to signal official packages -for organizations. - -Scoped packages can be published and installed as of `npm@2` and are supported -by the primary npm registry. Unscoped packages can depend on scoped packages and -vice versa. The npm client is backwards-compatible with unscoped registries, -so it can be used to work with scoped and unscoped registries at the same time. - -### Installing scoped packages - -Scoped packages are installed to a sub-folder of the regular installation -folder, e.g. if your other packages are installed in `node_modules/packagename`, -scoped modules will be installed in `node_modules/@myorg/packagename`. The scope -folder (`@myorg`) is simply the name of the scope preceded by an `@` symbol, and can -contain any number of scoped packages. - -A scoped package is installed by referencing it by name, preceded by an -`@` symbol, in `npm install`: - -```bash -npm install @myorg/mypackage -``` - -Or in `package.json`: - -```json -"dependencies": { - "@myorg/mypackage": "^1.3.0" -} -``` - -Note that if the `@` symbol is omitted, in either case, npm will instead attempt to -install from GitHub; see [`npm install`](/commands/npm-install). - -### Requiring scoped packages - -Because scoped packages are installed into a scope folder, you have to -include the name of the scope when requiring them in your code, e.g. - -```javascript -require('@myorg/mypackage') -``` - -There is nothing special about the way Node treats scope folders. This -simply requires the `mypackage` module in the folder named `@myorg`. - -### Publishing scoped packages - -Scoped packages can be published from the CLI as of `npm@2` and can be -published to any registry that supports them, including the primary npm -registry. - -(As of 2015-04-19, and with npm 2.0 or better, the primary npm registry -**does** support scoped packages.) - -If you wish, you may associate a scope with a registry; see below. - -#### Publishing public scoped packages to the primary npm registry - -Publishing to a scope, you have two options: - -- Publishing to your user scope (example: `@username/module`) -- Publishing to an organization scope (example: `@org/module`) - -If publishing a public module to an organization scope, you must -first either create an organization with the name of the scope -that you'd like to publish to or be added to an existing organization -with the appropriate permisssions. For example, if you'd like to -publish to `@org`, you would need to create the `org` organization -on npmjs.com prior to trying to publish. - -Scoped packages are not public by default. You will need to specify -`--access public` with the initial `npm publish` command. This will publish -the package and set access to `public` as if you had run `npm access public` -after publishing. You do not need to do this when publishing new versions of -an existing scoped package. - -#### Publishing private scoped packages to the npm registry - -To publish a private scoped package to the npm registry, you must have -an [npm Private Modules](https://docs.npmjs.com/private-modules/intro) -account. - -You can then publish the module with `npm publish` or `npm publish ---access restricted`, and it will be present in the npm registry, with -restricted access. You can then change the access permissions, if -desired, with `npm access` or on the npmjs.com website. - -### Associating a scope with a registry - -Scopes can be associated with a separate registry. This allows you to -seamlessly use a mix of packages from the primary npm registry and one or more -private registries, such as [GitHub Packages](https://github.com/features/packages) or the open source [Verdaccio](https://verdaccio.org) -project. - -You can associate a scope with a registry at login, e.g. - -```bash -npm login --registry=http://reg.example.com --scope=@myco -``` - -Scopes have a many-to-one relationship with registries: one registry can -host multiple scopes, but a scope only ever points to one registry. - -You can also associate a scope with a registry using `npm config`: - -```bash -npm config set @myco:registry http://reg.example.com -``` - -Once a scope is associated with a registry, any `npm install` for a package -with that scope will request packages from that registry instead. Any -`npm publish` for a package name that contains the scope will be published to -that registry instead. - -### See also - -* [npm install](/commands/npm-install) -* [npm publish](/commands/npm-publish) -* [npm access](/commands/npm-access) -* [npm registry](/using-npm/registry) diff --git a/docs/content/using-npm/scripts.md b/docs/content/using-npm/scripts.md deleted file mode 100644 index 2b9171e4aefdd..0000000000000 --- a/docs/content/using-npm/scripts.md +++ /dev/null @@ -1,372 +0,0 @@ ---- -title: scripts -section: 7 -description: How npm handles the "scripts" field ---- - -### Description - -The `"scripts"` property of your `package.json` file supports a number -of built-in scripts and their preset life cycle events as well as -arbitrary scripts. These all can be executed by running -`npm run-script <stage>` or `npm run <stage>` for short. *Pre* and *post* -commands with matching names will be run for those as well (e.g. `premyscript`, -`myscript`, `postmyscript`). Scripts from dependencies can be run with -`npm explore <pkg> -- npm run <stage>`. - -### Pre & Post Scripts - -To create "pre" or "post" scripts for any scripts defined in the -`"scripts"` section of the `package.json`, simply create another script -*with a matching name* and add "pre" or "post" to the beginning of them. - -```json -{ - "scripts": { - "precompress": "{{ executes BEFORE the `compress` script }}", - "compress": "{{ run command to compress files }}", - "postcompress": "{{ executes AFTER `compress` script }}" - } -} -``` - -In this example `npm run compress` would execute these scripts as -described. - -### Life Cycle Scripts - -There are some special life cycle scripts that happen only in certain -situations. These scripts happen in addition to the `pre<event>`, `post<event>`, and -`<event>` scripts. - -* `prepare`, `prepublish`, `prepublishOnly`, `prepack`, `postpack`, `dependencies` - -**prepare** (since `npm@4.0.0`) -* Runs any time before the package is packed, i.e. during `npm publish` - and `npm pack` -* Runs BEFORE the package is packed -* Runs BEFORE the package is published -* Runs on local `npm install` without any arguments -* Run AFTER `prepublish`, but BEFORE `prepublishOnly` - -* NOTE: If a package being installed through git contains a `prepare` - script, its `dependencies` and `devDependencies` will be installed, and - the prepare script will be run, before the package is packaged and - installed. - -* As of `npm@7` these scripts run in the background. - To see the output, run with: `--foreground-scripts`. - -**prepublish** (DEPRECATED) -* Does not run during `npm publish`, but does run during `npm ci` - and `npm install`. See below for more info. - -**prepublishOnly** -* Runs BEFORE the package is prepared and packed, ONLY on `npm publish`. - -**prepack** -* Runs BEFORE a tarball is packed (on "`npm pack`", "`npm publish`", and when installing a git dependencies). -* NOTE: "`npm run pack`" is NOT the same as "`npm pack`". "`npm run pack`" is an arbitrary user defined script name, where as, "`npm pack`" is a CLI defined command. - -**postpack** -* Runs AFTER the tarball has been generated but before it is moved to its final destination (if at all, publish does not save the tarball locally) - -**dependencies** -* Runs AFTER any operations that modify the `node_modules` directory IF changes occurred. -* Does NOT run in global mode - -#### Prepare and Prepublish - -**Deprecation Note: prepublish** - -Since `npm@1.1.71`, the npm CLI has run the `prepublish` script for both `npm publish` and `npm install`, because it's a convenient way to prepare a package for use (some common use cases are described in the section below). It has also turned out to be, in practice, [very confusing](https://github.com/npm/npm/issues/10074). As of `npm@4.0.0`, a new event has been introduced, `prepare`, that preserves this existing behavior. A _new_ event, `prepublishOnly` has been added as a transitional strategy to allow users to avoid the confusing behavior of existing npm versions and only run on `npm publish` (for instance, running the tests one last time to ensure they're in good shape). - -See <https://github.com/npm/npm/issues/10074> for a much lengthier justification, with further reading, for this change. - -**Use Cases** - -If you need to perform operations on your package before it is used, in a way that is not dependent on the operating system or architecture of the target system, use a `prepublish` script. This includes tasks such as: - -* Compiling CoffeeScript source code into JavaScript. -* Creating minified versions of JavaScript source code. -* Fetching remote resources that your package will use. - -The advantage of doing these things at `prepublish` time is that they can be done once, in a single place, thus reducing complexity and variability. Additionally, this means that: - -* You can depend on `coffee-script` as a `devDependency`, and thus - your users don't need to have it installed. -* You don't need to include minifiers in your package, reducing - the size for your users. -* You don't need to rely on your users having `curl` or `wget` or - other system tools on the target machines. - -#### Dependencies - -The `dependencies` script is run any time an `npm` command causes changes to the `node_modules` directory. It is run AFTER the changes have been applied and the `package.json` and `package-lock.json` files have been updated. - -### Life Cycle Operation Order - -#### [`npm cache add`](/commands/npm-cache) - -* `prepare` - -#### [`npm ci`](/commands/npm-ci) - -* `preinstall` -* `install` -* `postinstall` -* `prepublish` -* `preprepare` -* `prepare` -* `postprepare` - - These all run after the actual installation of modules into - `node_modules`, in order, with no internal actions happening in between - -#### [`npm diff`](/commands/npm-diff) - -* `prepare` - -#### [`npm install`](/commands/npm-install) - -These also run when you run `npm install -g <pkg-name>` - -* `preinstall` -* `install` -* `postinstall` -* `prepublish` -* `preprepare` -* `prepare` -* `postprepare` - -If there is a `binding.gyp` file in the root of your package and you -haven't defined your own `install` or `preinstall` scripts, npm will -default the `install` command to compile using node-gyp via `node-gyp -rebuild` - -These are run from the scripts of `<pkg-name>` - -#### [`npm pack`](/commands/npm-pack) - -* `prepack` -* `prepare` -* `postpack` - -#### [`npm publish`](/commands/npm-publish) - -* `prepublishOnly` -* `prepack` -* `prepare` -* `postpack` -* `publish` -* `postpublish` - -`prepare` will not run during `--dry-run` - -#### [`npm rebuild`](/commands/npm-rebuild) - -* `preinstall` -* `install` -* `postinstall` -* `prepare` - -`prepare` is only run if the current directory is a symlink (e.g. with -linked packages) - -#### [`npm restart`](/commands/npm-restart) - -If there is a `restart` script defined, these events are run, otherwise -`stop` and `start` are both run if present, including their `pre` and -`post` iterations) - -* `prerestart` -* `restart` -* `postrestart` - -#### [`npm run <user defined>`](/commands/npm-run-script) - -* `pre<user-defined>` -* `<user-defined>` -* `post<user-defined>` - -#### [`npm start`](/commands/npm-start) - -* `prestart` -* `start` -* `poststart` - -If there is a `server.js` file in the root of your package, then npm -will default the `start` command to `node server.js`. `prestart` and -`poststart` will still run in this case. - -#### [`npm stop`](/commands/npm-stop) - -* `prestop` -* `stop` -* `poststop` - -#### [`npm test`](/commands/npm-test) - -* `pretest` -* `test` -* `posttest` - -#### [`npm version`](/commands/npm-version) - -* `preversion` -* `version` -* `postversion` - -#### A Note on a lack of [`npm uninstall`](/commands/npm-uninstall) scripts - -While npm v6 had `uninstall` lifecycle scripts, npm v7 does not. Removal of a package can happen for a wide variety of reasons, and there's no clear way to currently give the script enough context to be useful. - -Reasons for a package removal include: - -* a user directly uninstalled this package -* a user uninstalled a dependant package and so this dependency is being uninstalled -* a user uninstalled a dependant package but another package also depends on this version -* this version has been merged as a duplicate with another version -* etc. - -Due to the lack of necessary context, `uninstall` lifecycle scripts are not implemented and will not function. - -### User - -When npm is run as root, scripts are always run with the effective uid -and gid of the working directory owner. - -### Environment - -Package scripts run in an environment where many pieces of information -are made available regarding the setup of npm and the current state of -the process. - -#### path - -If you depend on modules that define executable scripts, like test -suites, then those executables will be added to the `PATH` for -executing the scripts. So, if your package.json has this: - -```json -{ - "name" : "foo", - "dependencies" : { - "bar" : "0.1.x" - }, - "scripts": { - "start" : "bar ./test" - } -} -``` - -then you could run `npm start` to execute the `bar` script, which is -exported into the `node_modules/.bin` directory on `npm install`. - -#### package.json vars - -The package.json fields are tacked onto the `npm_package_` prefix. So, -for instance, if you had `{"name":"foo", "version":"1.2.5"}` in your -package.json file, then your package scripts would have the -`npm_package_name` environment variable set to "foo", and the -`npm_package_version` set to "1.2.5". You can access these variables -in your code with `process.env.npm_package_name` and -`process.env.npm_package_version`, and so on for other fields. - -See [`package.json`](/configuring-npm/package-json) for more on package configs. - -#### current lifecycle event - -Lastly, the `npm_lifecycle_event` environment variable is set to -whichever stage of the cycle is being executed. So, you could have a -single script used for different parts of the process which switches -based on what's currently happening. - -Objects are flattened following this format, so if you had -`{"scripts":{"install":"foo.js"}}` in your package.json, then you'd -see this in the script: - -```bash -process.env.npm_package_scripts_install === "foo.js" -``` - -### Examples - -For example, if your package.json contains this: - -```json -{ - "scripts" : { - "install" : "scripts/install.js", - "postinstall" : "scripts/install.js", - "uninstall" : "scripts/uninstall.js" - } -} -``` - -then `scripts/install.js` will be called for the install -and post-install stages of the lifecycle, and `scripts/uninstall.js` -will be called when the package is uninstalled. Since -`scripts/install.js` is running for two different phases, it would -be wise in this case to look at the `npm_lifecycle_event` environment -variable. - -If you want to run a make command, you can do so. This works just -fine: - -```json -{ - "scripts" : { - "preinstall" : "./configure", - "install" : "make && make install", - "test" : "make test" - } -} -``` - -### Exiting - -Scripts are run by passing the line as a script argument to `sh`. - -If the script exits with a code other than 0, then this will abort the -process. - -Note that these script files don't have to be Node.js or even -JavaScript programs. They just have to be some kind of executable -file. - -### Best Practices - -* Don't exit with a non-zero error code unless you *really* mean it. - Except for uninstall scripts, this will cause the npm action to - fail, and potentially be rolled back. If the failure is minor or - only will prevent some optional features, then it's better to just - print a warning and exit successfully. -* Try not to use scripts to do what npm can do for you. Read through - [`package.json`](/configuring-npm/package-json) to see all the things that you can specify and enable - by simply describing your package appropriately. In general, this - will lead to a more robust and consistent state. -* Inspect the env to determine where to put things. For instance, if - the `npm_config_binroot` environment variable is set to `/home/user/bin`, then - don't try to install executables into `/usr/local/bin`. The user - probably set it up that way for a reason. -* Don't prefix your script commands with "sudo". If root permissions - are required for some reason, then it'll fail with that error, and - the user will sudo the npm command in question. -* Don't use `install`. Use a `.gyp` file for compilation, and `prepare` - for anything else. You should almost never have to explicitly set a - preinstall or install script. If you are doing this, please consider if - there is another option. The only valid use of `install` or `preinstall` - scripts is for compilation which must be done on the target architecture. -* Scripts are run from the root of the package folder, regardless of what the - current working directory is when `npm` is invoked. If you want your - script to use different behavior based on what subdirectory you're in, you - can use the `INIT_CWD` environment variable, which holds the full path you - were in when you ran `npm run`. - -### See Also - -* [npm run-script](/commands/npm-run-script) -* [package.json](/configuring-npm/package-json) -* [npm developers](/using-npm/developers) -* [npm install](/commands/npm-install) diff --git a/docs/content/using-npm/workspaces.md b/docs/content/using-npm/workspaces.md deleted file mode 100644 index 5b68ef8ce9d3d..0000000000000 --- a/docs/content/using-npm/workspaces.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: workspaces -section: 7 -description: Working with workspaces ---- - -### Description - -**Workspaces** is a generic term that refers to the set of features in the -npm cli that provides support to managing multiple packages from your local -file system from within a singular top-level, root package. - -This set of features makes up for a much more streamlined workflow handling -linked packages from the local file system. Automating the linking process -as part of `npm install` and avoiding manually having to use `npm link` in -order to add references to packages that should be symlinked into the current -`node_modules` folder. - -We also refer to these packages being auto-symlinked during `npm install` as a -single **workspace**, meaning it's a nested package within the current local -file system that is explicitly defined in the [`package.json`](/configuring-npm/package-json#workspaces) -`workspaces` configuration. - -### Defining workspaces - -Workspaces are usually defined via the `workspaces` property of the -[`package.json`](/configuring-npm/package-json#workspaces) file, e.g: - -```json -{ - "name": "my-workspaces-powered-project", - "workspaces": [ - "packages/a" - ] -} -``` - -Given the above `package.json` example living at a current working -directory `.` that contains a folder named `packages/a` that itself contains -a `package.json` inside it, defining a Node.js package, e.g: - -``` -. -+-- package.json -`-- packages - +-- a - | `-- package.json -``` - -The expected result once running `npm install` in this current working -directory `.` is that the folder `packages/a` will get symlinked to the -`node_modules` folder of the current working dir. - -Below is a post `npm install` example, given that same previous example -structure of files and folders: - -``` -. -+-- node_modules -| `-- a -> ../packages/a -+-- package-lock.json -+-- package.json -`-- packages - +-- a - | `-- package.json -``` - -### Getting started with workspaces - -You may automate the required steps to define a new workspace using -[npm init](/commands/npm-init). For example in a project that already has a -`package.json` defined you can run: - -``` -npm init -w ./packages/a -``` - -This command will create the missing folders and a new `package.json` -file (if needed) while also making sure to properly configure the -`"workspaces"` property of your root project `package.json`. - -### Adding dependencies to a workspace - -It's possible to directly add/remove/update dependencies of your workspaces -using the [`workspace` config](/using-npm/config#workspace). - -For example, assuming the following structure: - -``` -. -+-- package.json -`-- packages - +-- a - | `-- package.json - `-- b - `-- package.json -``` - -If you want to add a dependency named `abbrev` from the registry as a -dependency of your workspace **a**, you may use the workspace config to tell -the npm installer that package should be added as a dependency of the provided -workspace: - -``` -npm install abbrev -w a -``` - -Note: other installing commands such as `uninstall`, `ci`, etc will also -respect the provided `workspace` configuration. - -### Using workspaces - -Given the [specifities of how Node.js handles module resolution](https://nodejs.org/dist/latest-v14.x/docs/api/modules.html#modules_all_together) it's possible to consume any defined workspace -by its declared `package.json` `name`. Continuing from the example defined -above, let's also create a Node.js script that will require the workspace `a` -example module, e.g: - -``` -// ./packages/a/index.js -module.exports = 'a' - -// ./lib/index.js -const moduleA = require('a') -console.log(moduleA) // -> a -``` - -When running it with: - -`node lib/index.js` - -This demonstrates how the nature of `node_modules` resolution allows for -**workspaces** to enable a portable workflow for requiring each **workspace** -in such a way that is also easy to [publish](/commands/npm-publish) these -nested workspaces to be consumed elsewhere. - -### Running commands in the context of workspaces - -You can use the `workspace` configuration option to run commands in the context -of a configured workspace. -Additionally, if your current directory is in a workspace, the `workspace` -configuration is implicitly set, and `prefix` is set to the root workspace. - -Following is a quick example on how to use the `npm run` command in the context -of nested workspaces. For a project containing multiple workspaces, e.g: - -``` -. -+-- package.json -`-- packages - +-- a - | `-- package.json - `-- b - `-- package.json -``` - -By running a command using the `workspace` option, it's possible to run the -given command in the context of that specific workspace. e.g: - -``` -npm run test --workspace=a -``` - -You could also run the command within the workspace. - -``` -cd packages/a && npm run test -``` - -Either will run the `test` script defined within the -`./packages/a/package.json` file. - -Please note that you can also specify this argument multiple times in the -command-line in order to target multiple workspaces, e.g: - -``` -npm run test --workspace=a --workspace=b -``` - -It's also possible to use the `workspaces` (plural) configuration option to -enable the same behavior but running that command in the context of **all** -configured workspaces. e.g: - -``` -npm run test --workspaces -``` - -Will run the `test` script in both `./packages/a` and `./packages/b`. - -Commands will be run in each workspace in the order they appear in your `package.json` - -``` -{ - "workspaces": [ "packages/a", "packages/b" ] -} -``` - -Order of run is different with: - -``` -{ - "workspaces": [ "packages/b", "packages/a" ] -} -``` - -### Ignoring missing scripts - -It is not required for all of the workspaces to implement scripts run with the `npm run` command. - -By running the command with the `--if-present` flag, npm will ignore workspaces missing target script. - -``` -npm run test --workspaces --if-present -``` - -### See also - -* [npm install](/commands/npm-install) -* [npm publish](/commands/npm-publish) -* [npm run-script](/commands/npm-run-script) -* [config](/using-npm/config) - diff --git a/docs/lib/build.js b/docs/lib/build.js new file mode 100644 index 0000000000000..86f8acac102f1 --- /dev/null +++ b/docs/lib/build.js @@ -0,0 +1,147 @@ +const { join, dirname, basename, extname, sep, posix } = require('path') +const fs = require('fs/promises') +const ignoreWalk = require('ignore-walk') +const yaml = require('yaml') +const parseFrontMatter = require('front-matter') + +const checkNav = require('./check-nav.js') +const { DOC_EXT, ...transform } = require('./index.js') + +const mkDirs = async (paths) => { + const uniqDirs = [...new Set(paths.map((p) => dirname(p)))] + return Promise.all(uniqDirs.map((d) => fs.mkdir(d, { recursive: true }))) +} + +const rmAll = (...dirs) => Promise.all(dirs.map((d) => fs.rm(d, { recursive: true, force: true }))) +const readDocs = (path) => ignoreWalk({ path }).then(ps => ps.filter(p => extname(p) === DOC_EXT)) +const readMd = (path) => fs.readFile(path, 'utf-8').then(parseFrontMatter) +const readHtml = (path) => fs.readFile(path, 'utf-8') +const readYaml = (path) => fs.readFile(path, 'utf-8').then(yaml.parse) +const makeTransforms = (...args) => (src, trs) => trs.reduce((acc, tr) => tr(acc, ...args), src) + +const pAll = async (obj) => { + const entries = Object.entries(obj) + const results = await Promise.all(entries.map(e => e[1])) + return results.reduce((acc, res, index) => { + acc[entries[index][0]] = res + return acc + }, {}) +} + +const run = async ({ content, template, nav, man, html, md }) => { + await rmAll(man, html, md) + const [contentPaths, navFile, options] = await Promise.all([ + readDocs(content), + readYaml(nav), + pAll({ + template: readHtml(template), + // these deps are esm only so we have to import them once we + // are inside our main async function + unified: import('unified').then(r => r.unified), + remarkParse: import('remark-parse').then(r => r.default), + remarkGfm: import('remark-gfm').then(r => r.default), + remarkRehype: import('remark-rehype').then(r => r.default), + rehypeStringify: import('rehype-stringify').then(r => r.default), + remarkMan: import('remark-man').then(r => r.default), + }), + ]) + + const sources = await Promise.all(contentPaths.map(async (childPath) => { + const name = basename(childPath, DOC_EXT) + const fullPath = join(content, childPath) + const fullName = join(dirname(childPath), name).split(sep).join(posix.sep) + + const { body, attributes: data, frontmatter } = await readMd(fullPath) + + return { + body, + data, + frontmatter, + name, + fullName, + childPath, + } + })) + + const entriesByType = sources.reduce((acc, { + body, + data, + frontmatter, + name, + childPath, + fullName, + }) => { + const applyTransforms = makeTransforms({ + path: childPath, + data: { + ...data, + github_repo: 'npm/cli', + github_branch: 'latest', + github_path: 'docs/lib/content', + }, + frontmatter, + ...options, + }) + + const transformedSrc = applyTransforms(body, [ + transform.version, + ...(fullName.startsWith('commands/') + ? [transform.usage, transform.params] + : []), + ...(fullName === 'using-npm/config' + ? [transform.shorthands, transform.config] + : []), + ]) + + const aliases = [ + fullName === 'configuring-npm/package-json' && 'configuring-npm/npm-json', + fullName === 'configuring-npm/folders' && 'configuring-npm/npm-global', + ].filter(Boolean) + + if (data.section) { + const manSource = applyTransforms(transformedSrc, [ + transform.helpLinks, + transform.man, + ]) + // Man page aliases are only the basename since the man pages have no hierarchy + acc.man.push(...[name, ...aliases.map(a => basename(a))] + .map((p) => applyTransforms(p, [transform.manPath])) + .map((manPath) => ({ + path: manPath, + fullPath: join(man, manPath), + src: manSource, + })) + ) + } + + // html docs are used for npm help on Windows + const htmlSource = applyTransforms(transformedSrc, [transform.html]) + acc.html.push(...[fullName, ...aliases].map((htmlPath) => ({ + path: `${htmlPath}.html`, + fullPath: join(html, `${htmlPath}.html`), + src: htmlSource, + }))) + + // Markdown pages don't get aliases here. These are used to build the website so any redirects + // for these pages are applied in npm/documentation. Not ideal but there are also many more + // redirects that we would never apply to man or html docs pages + const mdSource = applyTransforms(transformedSrc, [transform.md]) + acc.md.push({ + path: childPath, + fullPath: join(md, childPath), + src: mdSource, + }) + + return acc + }, { man: [], html: [], md: [] }) + + const docEntries = Object.values(entriesByType).flat() + await mkDirs(docEntries.map(({ fullPath }) => fullPath)) + await Promise.all(docEntries.map(({ fullPath, src }) => fs.writeFile(fullPath, src, 'utf-8'))) + + checkNav(navFile, entriesByType.md.map(({ path }) => path), DOC_EXT) + + return docEntries +} + +module.exports = run diff --git a/docs/lib/check-nav.js b/docs/lib/check-nav.js new file mode 100644 index 0000000000000..0f9b3529c7546 --- /dev/null +++ b/docs/lib/check-nav.js @@ -0,0 +1,62 @@ +const { basename, join, dirname, sep, posix } = require('path') + +function ensureNavigationComplete (nav, fsPaths, ext) { + const navPaths = getNavigationPaths(nav) + const unmatchedNav = {} + const unmatchedFs = {} + + for (const navPath of navPaths) { + // every nav path starts as an unmatched fs path + unmatchedFs[navPath] = true + } + + for (const path of fsPaths) { + const key = posix.sep + join(dirname(path), basename(path, ext)).split(sep).join(posix.sep) + // for each fs path, if it exists in the nav we + // unmark it as unmatched on the filesystem. + // otherwise its unmarked in the nav + if (unmatchedFs[key]) { + delete unmatchedFs[key] + } else { + unmatchedNav[key] = true + } + } + + const toKeys = (v) => Object.keys(v).sort().map((p) => p.split(posix.sep).join(sep)) + const missingNav = toKeys(unmatchedNav) + const missingFs = toKeys(unmatchedFs) + + const errors = [] + + if (missingNav.length) { + errors.push('The following path(s) exist on disk but are not present in /lib/content/nav.yml:') + errors.push(...missingNav.map(n => ` ${n}`)) + } + + if (missingFs.length) { + errors.push('The following path(s) exist in lib/content/nav.yml but are not present on disk:') + errors.push(...missingFs.map(n => ` ${n}`)) + } + + if (errors.length) { + errors.unshift('Documentation navigation (lib/content/nav.yml) does not match filesystem.') + errors.push('Update nav.yml to ensure that all files are listed in the appropriate place.') + throw new Error(errors.join('\n')) + } +} + +function getNavigationPaths (entries) { + const paths = [] + + for (const entry of entries) { + if (entry.children) { + paths.push(...getNavigationPaths(entry.children)) + } else { + paths.push(entry.url) + } + } + + return paths +} + +module.exports = ensureNavigationComplete diff --git a/docs/lib/config.json b/docs/lib/config.json deleted file mode 100644 index c9f183e4e787c..0000000000000 --- a/docs/lib/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "github_repo": "npm/cli", - "github_branch": "latest", - "github_path": "docs/content" -} diff --git a/docs/lib/content/commands/npm-access.md b/docs/lib/content/commands/npm-access.md new file mode 100644 index 0000000000000..6b846e9158f6f --- /dev/null +++ b/docs/lib/content/commands/npm-access.md @@ -0,0 +1,51 @@ +--- +title: npm-access +section: 1 +description: Set access level on published packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Used to set access controls on private packages. + +For all of the subcommands, `npm access` will perform actions on the packages in the current working directory if no package name is passed to the subcommand. + +* grant / revoke: + Add or remove the ability of users and teams to have read-only or read-write access to a package. + +### Details + +`npm access` always operates directly on the current registry, configurable from the command line using `--registry=<registry url>`. + +Unscoped packages are *always public*. + +Scoped packages *default to restricted*, but you can either publish them as public using `npm publish --access=public`, or set their access as public using `npm access set status=public` after the initial publish. + +You must have privileges to set the access of a package: + +* You are an owner of an unscoped or scoped package. +* You are a member of the team that owns a scope. +* You have been given read-write privileges for a package, either as a member of a team or directly as an owner. + +If you have two-factor authentication enabled then you'll be prompted to provide a second factor, or may use the `--otp=...` option to specify it on the command line. + +If your account is not paid, then attempts to publish scoped packages will fail with an HTTP 402 status code (logically enough), unless you use +`--access=public`. + +Management of teams and team memberships is done with the `npm team` command. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [`libnpmaccess`](https://npm.im/libnpmaccess) +* [npm team](/commands/npm-team) +* [npm publish](/commands/npm-publish) +* [npm config](/commands/npm-config) +* [npm registry](/using-npm/registry) diff --git a/docs/lib/content/commands/npm-adduser.md b/docs/lib/content/commands/npm-adduser.md new file mode 100644 index 0000000000000..a7f0d0a1a9fbb --- /dev/null +++ b/docs/lib/content/commands/npm-adduser.md @@ -0,0 +1,33 @@ +--- +title: npm-adduser +section: 1 +description: Add a registry user account +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Create a new user in the specified registry, and save the credentials to the `.npmrc` file. +If no registry is specified, the default registry will be used (see [`registry`](/using-npm/registry)). + +When you run `npm adduser`, the CLI automatically generates a legacy token of `publish` type. +For more information, see [About legacy tokens](/about-access-tokens#about-legacy-tokens). + +When using `legacy` for your `auth-type`, the username, password, and email are read in from prompts. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm owner](/commands/npm-owner) +* [npm whoami](/commands/npm-whoami) +* [npm token](/commands/npm-token) +* [npm profile](/commands/npm-profile) diff --git a/docs/lib/content/commands/npm-audit.md b/docs/lib/content/commands/npm-audit.md new file mode 100644 index 0000000000000..6cd26b1406b4a --- /dev/null +++ b/docs/lib/content/commands/npm-audit.md @@ -0,0 +1,207 @@ +--- +title: npm-audit +section: 1 +description: Run a security audit +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +The audit command submits a description of the dependencies configured in your project to your default registry and asks for a report of known vulnerabilities. +If any vulnerabilities are found, then the impact and appropriate remediation will be calculated. +If the `fix` argument is provided, then remediations will be applied to the package tree. + +The command will exit with a 0 exit code if no vulnerabilities were found. + +Note that some vulnerabilities cannot be fixed automatically and will require manual intervention or review. +Also note that since `npm audit fix` runs a full-fledged `npm install` under the hood, all configs that apply to the installer will also apply to `npm install` -- so things like `npm audit fix --package-lock-only` will work as expected. + +By default, the audit command will exit with a non-zero code if any vulnerability is found. +It may be useful in CI environments to include the `--audit-level` parameter to specify the minimum vulnerability level that will cause the command to fail. +This option does not filter the report output, it simply changes the command's failure threshold. + +### Package lock + +By default npm requires a package-lock or shrinkwrap in order to run the audit. +You can bypass the package lock with `--no-package-lock` but be aware the results may be different with every run, since npm will re-build the dependency tree each time. + +### Audit Signatures + +To ensure the integrity of packages you download from the public npm registry, or any registry that supports signatures, you can verify the registry signatures of downloaded packages using the npm CLI. + +Registry signatures can be verified using the following `audit` command: + +```bash +$ npm audit signatures +``` + +The `audit signatures` command will also verify the provenance attestations of downloaded packages. +Because provenance attestations are such a new feature, security features may be added to (or changed in) the attestation format over time. +To ensure that you're always able to verify attestation signatures check that you're running the latest version of the npm CLI. Please note this often means updating npm beyond the version that ships with Node.js. + +The npm CLI supports registry signatures and signing keys provided by any registry if the following conventions are followed: + +1. Signatures are provided in the package's `packument` in each published version within the `dist` object: + +```json +"dist":{ + "..omitted..": "..omitted..", + "signatures": [{ + "keyid": "SHA256:{{SHA256_PUBLIC_KEY}}", + "sig": "a312b9c3cb4a1b693e8ebac5ee1ca9cc01f2661c14391917dcb111517f72370809..." + }] +} +``` + +See this [example](https://registry.npmjs.org/light-cycle/1.4.3) of a signed package from the public npm registry. + +The `sig` is generated using the following template: `${package.name}@${package.version}:${package.dist.integrity}` and the `keyid` has to match one of the public signing keys below. + +2. Public signing keys are provided at `registry-host.tld/-/npm/v1/keys` in the following format: + +``` +{ + "keys": [{ + "expires": null, + "keyid": "SHA256:{{SHA256_PUBLIC_KEY}}", + "keytype": "ecdsa-sha2-nistp256", + "scheme": "ecdsa-sha2-nistp256", + "key": "{{B64_PUBLIC_KEY}}" + }] +} +``` + +Keys response: + +- `expires`: null or a simplified extended [ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601): `YYYY-MM-DDTHH:mm:ss.sssZ` +- `keyid`: sha256 fingerprint of the public key +- `keytype`: only `ecdsa-sha2-nistp256` is currently supported by the npm CLI +- `scheme`: only `ecdsa-sha2-nistp256` is currently supported by the npm CLI +- `key`: base64 encoded public key + +See this [example key's response from the public npm registry](https://registry.npmjs.org/-/npm/v1/keys). + +### Audit Endpoints + +There are two audit endpoints that npm may use to fetch vulnerability information: the `Bulk Advisory` endpoint and the `Quick Audit` endpoint. + +#### Bulk Advisory Endpoint + +As of version 7, npm uses the much faster `Bulk Advisory` endpoint to optimize the speed of calculating audit results. + +npm will generate a JSON payload with the name and list of versions of each package in the tree, and POST it to the default configured registry at the path `/-/npm/v1/security/advisories/bulk`. + +Any packages in the tree that do not have a `version` field in their package.json file will be ignored. +If any `--omit` options are specified (either via the [`--omit` config](/using-npm/config#omit), or one of the shorthands such as `--production`, `--only=dev`, and so on), then packages will be omitted from the submitted payload as appropriate. + +If the registry responds with an error, or with an invalid response, then npm will attempt to load advisory data from the `Quick Audit` endpoint. + +The expected result will contain a set of advisory objects for each dependency that matches the advisory range. +Each advisory object contains a `name`, `url`, `id`, `severity`, `vulnerable_versions`, and `title`. + +npm then uses these advisory objects to calculate vulnerabilities and meta-vulnerabilities of the dependencies within the tree. + +#### Quick Audit Endpoint + +If the `Bulk Advisory` endpoint returns an error, or invalid data, npm will attempt to load advisory data from the `Quick Audit` endpoint, which is considerably slower in most cases. + +The full package tree as found in `package-lock.json` is submitted, along with the following pieces of additional metadata: + +* `npm_version` +* `node_version` +* `platform` +* `arch` +* `node_env` + +All packages in the tree are submitted to the Quick Audit endpoint. +Omitted dependency types are skipped when generating the report. + +#### Scrubbing + +Out of an abundance of caution, npm versions 5 and 6 would "scrub" any packages from the submitted report if their name contained a `/` character, so as to avoid leaking the names of potentially private packages or git URLs. + +However, in practice, this resulted in audits often failing to properly detect meta-vulnerabilities, because the tree would appear to be invalid due to missing dependencies, and prevented the detection of vulnerabilities in package trees that used git dependencies or private modules. + +This scrubbing has been removed from npm as of version 7. + +#### Calculating Meta-Vulnerabilities and Remediations + +npm uses the [`@npmcli/metavuln-calculator`](http://npm.im/@npmcli/metavuln-calculator) module to turn a set of security advisories into a set of "vulnerability" objects. +A "meta-vulnerability" is a dependency that is vulnerable by virtue of dependence on vulnerable versions of a vulnerable package. + +For example, if the package `foo` is vulnerable in the range `>=1.0.2 <2.0.0`, and the package `bar` depends on `foo@^1.1.0`, then that version of `bar` can only be installed by installing a vulnerable version of `foo`. +In this case, `bar` is a "metavulnerability". + +Once metavulnerabilities for a given package are calculated, they are cached in the `~/.npm` folder and only re-evaluated if the advisory range changes, or a new version of the package is published (in which case, the new version is checked for metavulnerable status as well). + +If the chain of metavulnerabilities extends all the way to the root project, and it cannot be updated without changing its dependency ranges, then `npm audit fix` will require the `--force` option to apply the remediation. +If remediations do not require changes to the dependency ranges, then all vulnerable packages will be updated to a version that does not have an advisory or metavulnerability posted against it. + +### Exit Code + +The `npm audit` command will exit with a 0 exit code if no vulnerabilities were found. +The `npm audit fix` command will exit with 0 exit code if no vulnerabilities are found _or_ if the remediation is able to successfully fix all vulnerabilities. + +If vulnerabilities were found the exit code will depend on the [`audit-level` config](/using-npm/config#audit-level). + +### Examples + +Scan your project for vulnerabilities and automatically install any compatible updates to vulnerable dependencies: + +```bash +$ npm audit fix +``` + +Run `audit fix` without modifying `node_modules`, but still updating the pkglock: + +```bash +$ npm audit fix --package-lock-only +``` + +Skip updating `devDependencies`: + +```bash +$ npm audit fix --only=prod +``` + +Have `audit fix` install SemVer-major updates to toplevel dependencies, not just SemVer-compatible ones: + +```bash +$ npm audit fix --force +``` + +Do a dry run to get an idea of what `audit fix` will do, and _also_ output install information in JSON format: + +```bash +$ npm audit fix --dry-run --json +``` + +Scan your project for vulnerabilities and just show the details, without fixing anything: + +```bash +$ npm audit +``` + +Get the detailed audit report in JSON format: + +```bash +$ npm audit --json +``` + +Fail an audit only if the results include a vulnerability with a level of moderate or higher: + +```bash +$ npm audit --audit-level=moderate +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm install](/commands/npm-install) +* [config](/using-npm/config) diff --git a/docs/lib/content/commands/npm-bugs.md b/docs/lib/content/commands/npm-bugs.md new file mode 100644 index 0000000000000..e68361084196d --- /dev/null +++ b/docs/lib/content/commands/npm-bugs.md @@ -0,0 +1,28 @@ +--- +title: npm-bugs +section: 1 +description: Report bugs for a package in a web browser +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command tries to guess at the likely location of a package's bug tracker URL or the `mailto` URL of the support email, and then tries to open it using the [`--browser` config](/using-npm/config#browser) param. +If no package name is provided, it will search for a `package.json` in the current folder and use the `name` property. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm docs](/commands/npm-docs) +* [npm view](/commands/npm-view) +* [npm publish](/commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [package.json](/configuring-npm/package-json) diff --git a/docs/lib/content/commands/npm-cache.md b/docs/lib/content/commands/npm-cache.md new file mode 100644 index 0000000000000..55835d23e1c92 --- /dev/null +++ b/docs/lib/content/commands/npm-cache.md @@ -0,0 +1,83 @@ +--- +title: npm-cache +section: 1 +description: Manipulates packages cache +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Used to add, list, or clean the `npm cache` folder. +Also used to view info about entries in the `npm exec` (aka `npx`) cache folder. + +#### `npm cache` + +* add: + Add the specified packages to the local cache. + This command is primarily intended to be used internally by npm, but it can provide a way to add data to the local installation cache explicitly. + +* clean: + Delete a single entry or all entries out of the cache folder. + Note that this is typically unnecessary, as npm's cache is self-healing and resistant to data corruption issues. + +* ls: + List given entries or all entries in the local cache. + +* verify: + Verify the contents of the cache folder, garbage collecting any unneeded data, and verifying the integrity of the cache index and all cached data. + +#### `npm cache npx` + +* ls: + List all entries in the npx cache. + +* rm: + Remove given entries or all entries from the npx cache. + +* info: + Get detailed information about given entries in the npx cache. + +### Details + +npm stores cache data in an opaque directory within the configured `cache`, named `_cacache`. +This directory is a [`cacache`](http://npm.im/cacache)-based content-addressable cache that stores all http request data as well as other package-related data. +This directory is primarily accessed through `pacote`, the library responsible for all package fetching as of npm@5. + +All data that passes through the cache is fully verified for integrity on both insertion and extraction. +Cache corruption will either trigger an error, or signal to `pacote` that the data must be refetched, which it will do automatically. +For this reason, it should never be necessary to clear the cache for any reason other than reclaiming disk space, thus why `clean` now requires `--force` to run. + +There is currently no method exposed through npm to inspect or directly manage the contents of this cache. +In order to access it, `cacache` must be used directly. + +npm will not remove data by itself: the cache will grow as new packages are installed. + +### A note about the cache's design + +The npm cache is strictly a cache: it should not be relied upon as a persistent and reliable data store for package data. +npm makes no guarantee that a previously-cached piece of data will be available later, and will automatically delete corrupted contents. +The primary guarantee that the cache makes is that, if it does return data, that data will be exactly the data that was inserted. + +To run an offline verification of existing cache contents, use `npm cache verify`. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm install](/commands/npm-install) +* [npm publish](/commands/npm-publish) +* [npm pack](/commands/npm-pack) +* [npm exec](/commands/npm-exec) +* https://npm.im/cacache +* https://npm.im/pacote +* https://npm.im/@npmcli/arborist +* https://npm.im/make-fetch-happen diff --git a/docs/lib/content/commands/npm-ci.md b/docs/lib/content/commands/npm-ci.md new file mode 100644 index 0000000000000..7c59b39c86a1c --- /dev/null +++ b/docs/lib/content/commands/npm-ci.md @@ -0,0 +1,69 @@ +--- +title: npm-ci +section: 1 +description: Clean install a project +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command is similar to [`npm install`](/commands/npm-install), except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment -- or any situation where you want to make sure you're doing a clean install of your dependencies. + +The main differences between using `npm install` and `npm ci` are: + +* The project **must** have an existing `package-lock.json` or + `npm-shrinkwrap.json`. +* If dependencies in the package lock do not match those in `package.json`, + `npm ci` will exit with an error, instead of updating the package lock. +* `npm ci` can only install entire projects at a time: individual dependencies cannot be added with this command. +* If a `node_modules` is already present, it will be automatically removed before `npm ci` begins its install. +* It will never write to `package.json` or any of the package-locks: + installs are essentially frozen. + +NOTE: If you create your `package-lock.json` file by running `npm install` with flags that can affect the shape of your dependency tree, such as +`--legacy-peer-deps` or `--install-links`, you _must_ provide the same flags to `npm ci` or you are likely to encounter errors. +An easy way to do this is to run, for example, +`npm config set legacy-peer-deps=true --location=project` and commit the +`.npmrc` file to your repo. + +### Example + +Make sure you have a package-lock and an up-to-date install: + +```bash +$ cd ./my/npm/project +$ npm install +added 154 packages in 10s +$ ls | grep package-lock +``` + +Run `npm ci` in that project + +```bash +$ npm ci +added 154 packages in 5s +``` + +Configure Travis CI to build using `npm ci` instead of `npm install`: + +```bash +# .travis.yml +install: +- npm ci +# keep the npm cache around to speed up installs +cache: + directories: + - "$HOME/.npm" +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm install](/commands/npm-install) +* [package-lock.json](/configuring-npm/package-lock-json) diff --git a/docs/lib/content/commands/npm-completion.md b/docs/lib/content/commands/npm-completion.md new file mode 100644 index 0000000000000..3019ce1fd4c5c --- /dev/null +++ b/docs/lib/content/commands/npm-completion.md @@ -0,0 +1,32 @@ +--- +title: npm-completion +section: 1 +description: Tab Completion for npm +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Enables tab-completion in all npm commands. + +The synopsis above loads the completions into your current shell. +Adding it to your ~/.bashrc or ~/.zshrc will make the completions available everywhere: + +```bash +npm completion >> ~/.bashrc +npm completion >> ~/.zshrc +``` + +You may of course also pipe the output of `npm completion` to a file such as `/usr/local/etc/bash_completion.d/npm` or +`/etc/bash_completion.d/npm` if you have a system that will read +that file for you. + +When `COMP_CWORD`, `COMP_LINE`, and `COMP_POINT` are defined in the environment, `npm completion` acts in "plumbing mode", and outputs completions based on the arguments. + +### See Also + +* [npm developers](/using-npm/developers) +* [npm](/commands/npm) diff --git a/docs/lib/content/commands/npm-config.md b/docs/lib/content/commands/npm-config.md new file mode 100644 index 0000000000000..831876bac290d --- /dev/null +++ b/docs/lib/content/commands/npm-config.md @@ -0,0 +1,99 @@ +--- +title: npm-config +section: 1 +description: Manage the npm configuration files +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +npm gets its config settings from the command line, environment variables, `npmrc` files, and in some cases, the `package.json` file. + +See [npmrc](/configuring-npm/npmrc) for more information about the npmrc files. + +See [config](/using-npm/config) for a more thorough explanation of the mechanisms involved, and a full list of config options available. + +The `npm config` command can be used to update and edit the contents of the user and global npmrc files. + +### Sub-commands + +Config supports the following sub-commands: + +#### set + +```bash +npm config set key=value [key=value...] +npm set key=value [key=value...] +``` + +Sets each of the config keys to the value provided. +Modifies the user configuration file unless [`location`](/commands/npm-config#location) is passed. + +If value is omitted, the key will be removed from your config file entirely. + +Note: for backwards compatibility, `npm config set key value` is supported as an alias for `npm config set key=value`. + +#### get + +```bash +npm config get [key ...] +npm get [key ...] +``` + +Echo the config value(s) to stdout. + +If multiple keys are provided, then the values will be prefixed with the key names. + +If no keys are provided, then this command behaves the same as `npm config list`. + +#### list + +```bash +npm config list +``` + +Show all the config settings. +Use `-l` to also show defaults. +Use `--json` to show the settings in json format. + +#### delete + +```bash +npm config delete key [key ...] +``` + +Deletes the specified keys from all configuration files. + +#### edit + +```bash +npm config edit +``` + +Opens the config file in an editor. +Use the `--global` flag to edit the global config. + +#### fix + +```bash +npm config fix +``` + +Attempts to repair invalid configuration items. +Usually this means attaching authentication config (i.e. +`_auth`, `_authToken`) to the configured `registry`. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [package.json](/configuring-npm/package-json) +* [npmrc](/configuring-npm/npmrc) +* [npm](/commands/npm) diff --git a/docs/lib/content/commands/npm-dedupe.md b/docs/lib/content/commands/npm-dedupe.md new file mode 100644 index 0000000000000..e3ef8c6157fd7 --- /dev/null +++ b/docs/lib/content/commands/npm-dedupe.md @@ -0,0 +1,71 @@ +--- +title: npm-dedupe +section: 1 +description: Reduce duplication in the package tree +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Searches the local package tree and attempts to simplify the overall structure by moving dependencies further up the tree, where they can be more effectively shared by multiple dependent packages. + +For example, consider this dependency graph: + +``` +a ++-- b <-- depends on c@1.0.x +| `-- c@1.0.3 +`-- d <-- depends on c@~1.0.9 + `-- c@1.0.10 +``` + +In this case, `npm dedupe` will transform the tree to: + +```bash +a ++-- b ++-- d +`-- c@1.0.10 +``` + +Because of the hierarchical nature of node's module lookup, b and d will both get their dependency met by the single c package at the root level of the tree. + +In some cases, you may have a dependency graph like this: + +``` +a ++-- b <-- depends on c@1.0.x ++-- c@1.0.3 +`-- d <-- depends on c@1.x + `-- c@1.9.9 +``` + +During the installation process, the `c@1.0.3` dependency for `b` was placed in the root of the tree. +Though `d`'s dependency on `c@1.x` could have been satisfied by `c@1.0.3`, the newer `c@1.9.9` dependency was used, because npm favors updates by default, even when doing so causes duplication. + +Running `npm dedupe` will cause npm to note the duplication and re-evaluate, deleting the nested `c` module, because the one in the root is sufficient. + +To prefer deduplication over novelty during the installation process, run `npm install --prefer-dedupe` or `npm config set prefer-dedupe true`. + +Arguments are ignored. +Dedupe always acts on the entire tree. + +Note that this operation transforms the dependency tree, but will never result in new modules being installed. + +Using `npm find-dupes` will run the command in `--dry-run` mode. + +Note: `npm dedupe` will never update the semver values of direct dependencies in your project `package.json`, if you want to update values in `package.json` you can run: `npm update --save` instead. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm find-dupes](/commands/npm-find-dupes) +* [npm ls](/commands/npm-ls) +* [npm update](/commands/npm-update) +* [npm install](/commands/npm-install) diff --git a/docs/lib/content/commands/npm-deprecate.md b/docs/lib/content/commands/npm-deprecate.md new file mode 100644 index 0000000000000..183c65113a160 --- /dev/null +++ b/docs/lib/content/commands/npm-deprecate.md @@ -0,0 +1,46 @@ +--- +title: npm-deprecate +section: 1 +description: Deprecate a version of a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will update the npm registry entry for a package, providing a deprecation warning to all who attempt to install it. + +It works on [version ranges](https://semver.npmjs.com/) as well as specific versions, so you can do something like this: + +```bash +npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3" +``` + +SemVer ranges passed to this command are interpreted such that they *do* include prerelease versions. +For example: + +```bash +npm deprecate my-thing@1.x "1.x is no longer supported" +``` + +In this case, a version `my-thing@1.0.0-beta.0` will also be deprecated. + +You must be the package owner to deprecate something. +See the `owner` and `adduser` help topics. + +To un-deprecate a package, specify an empty string (`""`) for the `message` argument. +Note that you must use double quotes with no space between them to format an empty string. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm publish](/commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm owner](/commands/npm-owner) +* [npm adduser](/commands/npm-adduser) diff --git a/docs/lib/content/commands/npm-diff.md b/docs/lib/content/commands/npm-diff.md new file mode 100644 index 0000000000000..fa6580e2a1f7d --- /dev/null +++ b/docs/lib/content/commands/npm-diff.md @@ -0,0 +1,119 @@ +--- +title: npm-diff +section: 1 +description: The registry diff command +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Similar to its `git diff` counterpart, this command will print diff patches of files for packages published to the npm registry. + +* `npm diff --diff=<spec-a> --diff=<spec-b>` + + Compares two package versions using their registry specifiers, e.g: `npm diff --diff=pkg@1.0.0 --diff=pkg@^2.0.0`. + It's also possible to compare across forks of any package, e.g: `npm diff --diff=pkg@1.0.0 --diff=pkg-fork@1.0.0`. + + Any valid spec can be used, so that it's also possible to compare directories or git repositories, e.g: `npm diff --diff=pkg@latest --diff=./packages/pkg` + + Here's an example comparing two different versions of a package named `abbrev` from the registry: + + ```bash + npm diff --diff=abbrev@1.1.0 --diff=abbrev@1.1.1 + ``` + + On success, output looks like: + + ```bash + diff --git a/package.json b/package.json + index v1.1.0..v1.1.1 100644 + --- a/package.json + +++ b/package.json + @@ -1,6 +1,6 @@ + { + "name": "abbrev", + - "version": "1.1.0", + + "version": "1.1.1", + "description": "Like ruby's abbrev module, but in js", + "author": "Isaac Z. Schlueter <i@izs.me>", + "main": "abbrev.js", + ``` + + Given the flexible nature of npm specs, you can also target local directories or git repos just like when using `npm install`: + + ```bash + npm diff --diff=https://github.com/npm/libnpmdiff --diff=./local-path + ``` + + In the example above we can compare the contents from the package installed from the git repo at `github.com/npm/libnpmdiff` with the contents of the `./local-path` that contains a valid package, such as a modified copy of the original. + +* `npm diff` (in a package directory, no arguments): + + If the package is published to the registry, `npm diff` will fetch the tarball version tagged as `latest` (this value can be configured using the `tag` option) and proceed to compare the contents of files present in that tarball, with the current files in your local file system. + + This workflow provides a handy way for package authors to see what package-tracked files have been changed in comparison with the latest published version of that package. + +* `npm diff --diff=<pkg-name>` (in a package directory): + + When using a single package name (with no version or tag specifier) as an argument, `npm diff` will work in a similar way to [`npm-outdated`](npm-outdated) and reach for the registry to figure out what current published version of the package named `<pkg-name>` will satisfy its dependent declared semver-range. + Once that specific version is known `npm diff` will print diff patches comparing the current version of `<pkg-name>` found in the local file system with that specific version returned by the registry. + + Given a package named `abbrev` that is currently installed: + + ```bash + npm diff --diff=abbrev + ``` + + That will request from the registry its most up to date version and will print a diff output comparing the currently installed version to this newer one if the version numbers are not the same. + +* `npm diff --diff=<spec-a>` (in a package directory): + + Similar to using only a single package name, it's also possible to declare a full registry specifier version if you wish to compare the local version of an installed package with the specific version/tag/semver-range provided in `<spec-a>`. + + An example: assuming `pkg@1.0.0` is installed in the current `node_modules` folder, running: + + ```bash + npm diff --diff=pkg@2.0.0 + ``` + + It will effectively be an alias to + `npm diff --diff=pkg@1.0.0 --diff=pkg@2.0.0`. + +* `npm diff --diff=<semver-a> [--diff=<semver-b>]` (in a package directory): + + Using `npm diff` along with semver-valid version numbers is a shorthand to compare different versions of the current package. + + It needs to be run from a package directory, such that for a package named `pkg` running `npm diff --diff=1.0.0 --diff=1.0.1` is the same as running `npm diff --diff=pkg@1.0.0 --diff=pkg@1.0.1`. + + If only a single argument `<version-a>` is provided, then the current local file system is going to be compared against that version. + + Here's an example comparing two specific versions (published to the configured registry) of the current project directory: + + ```bash + npm diff --diff=1.0.0 --diff=1.1.0 + ``` + +Note that tag names are not valid `--diff` argument values, if you wish to compare to a published tag, you must use the `pkg@tagname` syntax. + +#### Filtering files + +It's possible to also specify positional arguments using file names or globs pattern matching in order to limit the result of diff patches to only a subset of files for a given package, e.g: + + ```bash + npm diff --diff=pkg@2 ./lib/ CHANGELOG.md + ``` + +In the example above the diff output is only going to print contents of files located within the folder `./lib/` and changed lines of code within the `CHANGELOG.md` file. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> +## See Also + +* [npm outdated](/commands/npm-outdated) +* [npm install](/commands/npm-install) +* [npm config](/commands/npm-config) +* [npm registry](/using-npm/registry) diff --git a/docs/lib/content/commands/npm-dist-tag.md b/docs/lib/content/commands/npm-dist-tag.md new file mode 100644 index 0000000000000..fdd6e048d066c --- /dev/null +++ b/docs/lib/content/commands/npm-dist-tag.md @@ -0,0 +1,81 @@ +--- +title: npm-dist-tag +section: 1 +description: Modify package distribution tags +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Add, remove, and enumerate distribution tags on a package: + +* add: Tags the specified version of the package with the specified tag, or the [`--tag` config](/using-npm/config#tag) if not specified. + If you have two-factor authentication on auth-and-writes then you’ll need to include a one-time password on the command line with `--otp <one-time password>`, or go through a second factor flow based on your `authtype`. + +* rm: Clear a tag that is no longer in use from the package. + If you have two-factor authentication on auth-and-writes then you’ll need to include a one-time password on the command line with `--otp <one-time password>`, or go through a second factor flow based on your `authtype` + +* ls: Show all of the dist-tags for a package, defaulting to the package in the current prefix. + This is the default action if none is specified. + +A tag can be used when installing packages as a reference to a version instead of using a specific version number: + +```bash +npm install <name>@<tag> +``` + +When installing dependencies, a preferred tagged version may be specified: + +```bash +npm install --tag <tag> +``` + +(This also applies to any other commands that resolve and install dependencies, such as `npm dedupe`, `npm update`, and `npm audit fix`.) + +Publishing a package sets the `latest` tag to the published version unless the `--tag` option is used. +For example, `npm publish --tag=beta`. + +By default, `npm install <pkg>` (without any `@<version>` or `@<tag>` specifier) installs the `latest` tag. + +### Purpose + +Tags can be used to provide an alias instead of version numbers. + +For example, a project might choose to have multiple streams of development and use a different tag for each stream, e.g., `stable`, `beta`, `dev`, +`canary`. + +By default, the `latest` tag is used by npm to identify the current version of a package, and `npm install <pkg>` (without any `@<version>` or `@<tag>` specifier) installs the `latest` tag. +Typically, projects only use the `latest` tag for stable release versions, and use other tags for unstable versions such as prereleases. + +The `next` tag is used by some projects to identify the upcoming version. + +Other than `latest`, no tag has any special significance to npm itself. + +### Caveats + +This command used to be known as `npm tag`, which only created new tags, and so had a different syntax. + +Tags must share a namespace with version numbers, because they are specified in the same slot: `npm install <pkg>@<version>` vs `npm install <pkg>@<tag>`. + +Tags that can be interpreted as valid semver ranges will be rejected. +For example, `v1.4` cannot be used as a tag, because it is interpreted by semver as `>=1.4.0 <1.5.0`. +See <https://github.com/npm/npm/issues/6082>. + +The simplest way to avoid semver problems with tags is to use tags that do not begin with a number or the letter `v`. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm publish](/commands/npm-publish) +* [npm install](/commands/npm-install) +* [npm dedupe](/commands/npm-dedupe) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-docs.md b/docs/lib/content/commands/npm-docs.md new file mode 100644 index 0000000000000..816f228e6d527 --- /dev/null +++ b/docs/lib/content/commands/npm-docs.md @@ -0,0 +1,28 @@ +--- +title: npm-docs +section: 1 +description: Open documentation for a package in a web browser +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command tries to guess at the likely location of a package's documentation URL, and then tries to open it using the [`--browser` config](/using-npm/config#browser) param. +You can pass multiple package names at once. +If no package name is provided, it will search for a `package.json` in the current folder and use the `name` property. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm view](/commands/npm-view) +* [npm publish](/commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [package.json](/configuring-npm/package-json) diff --git a/docs/lib/content/commands/npm-doctor.md b/docs/lib/content/commands/npm-doctor.md new file mode 100644 index 0000000000000..3a007b4ee80f1 --- /dev/null +++ b/docs/lib/content/commands/npm-doctor.md @@ -0,0 +1,87 @@ +--- +title: npm-doctor +section: 1 +description: Check the health of your npm environment +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +`npm doctor` runs a set of checks to ensure that your npm installation has what it needs to manage your JavaScript packages. +npm is mostly a standalone tool, but it does have some basic requirements that must be met: + ++ Node.js and git must be executable by npm. ++ The primary npm registry, `registry.npmjs.com`, or another service that uses the registry API, is available. ++ The directories that npm uses, `node_modules` (both locally and globally), exist and can be written by the current user. ++ The npm cache exists, and the package tarballs within it aren't corrupt. + +Without all of these working properly, npm may not work properly. +Many issues are often attributable to things that are outside npm's code base, so `npm doctor` confirms that the npm installation is in a good state. + +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 `npm@latest` is better than an old version. + +`npm doctor` 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. + +#### `Connecting to the registry` + +By default, npm installs from the primary npm registry, +`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. + +#### `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 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. + +#### `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. + +#### `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. + +#### `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 not accessible via your `PATH` so that npm can find it. +This check ensures that Git is available. + +#### Permissions checks + +* Your cache must be readable and writable by the user running npm. +* Global package binaries must be writable by the user running npm. +* Your local `node_modules` path, if you're running `npm doctor` with a project directory, must be readable and writable by the user running npm. + +#### Validate the checksums of cached packages + +When an npm package is published, the publishing process generates a checksum that npm uses at install time to verify that the package didn't get corrupted in transit. +`npm doctor` uses these checksums to validate the package tarballs in your local cache (you can see where that cache is located with `npm config get cache`). +In the event that there are corrupt packages in your cache, you should probably run `npm cache clean -f` and reset the cache. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm bugs](/commands/npm-bugs) +* [npm help](/commands/npm-help) +* [npm ping](/commands/npm-ping) diff --git a/docs/lib/content/commands/npm-edit.md b/docs/lib/content/commands/npm-edit.md new file mode 100644 index 0000000000000..84186792aaf89 --- /dev/null +++ b/docs/lib/content/commands/npm-edit.md @@ -0,0 +1,29 @@ +--- +title: npm-edit +section: 1 +description: Edit an installed package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Selects a dependency in the current project and opens the package folder in the default editor (or whatever you've configured as the npm `editor` config -- see [`npm-config`](npm-config).) + +After it has been edited, the package is rebuilt so as to pick up any changes in compiled packages. + +For instance, you can do `npm install connect` to install connect into your package, and then `npm edit connect` to make a few changes to your locally installed copy. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm folders](/configuring-npm/folders) +* [npm explore](/commands/npm-explore) +* [npm install](/commands/npm-install) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-exec.md b/docs/lib/content/commands/npm-exec.md new file mode 100644 index 0000000000000..9869afe6ea41c --- /dev/null +++ b/docs/lib/content/commands/npm-exec.md @@ -0,0 +1,233 @@ +--- +title: npm-exec +section: 1 +description: Run a command from a local or remote npm package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via `npm run`. + +Run without positional arguments or `--call`, this allows you to interactively run commands in the same sort of shell environment that `package.json` scripts are run. +Interactive mode is not supported in CI environments when standard input is a TTY, to prevent hangs. + +Whatever packages are specified by the `--package` option will be provided in the `PATH` of the executed command, along with any locally installed package executables. +The `--package` option may be specified multiple times, to execute the supplied command in an environment where all specified packages are available. + +If any requested packages are not present in the local project dependencies, then a prompt is printed, which can be suppressed by providing either `--yes` or `--no`. +When standard input is not a TTY or a CI environment is detected, `--yes` is assumed. +The requested packages are installed to a folder in the npm cache, which is added to the `PATH` environment variable in the executed process. + +Package names provided without a specifier will be matched with whatever version exists in the local project. +Package names with a specifier will only be considered a match if they have the exact same name and version as the local dependency. + +If no `-c` or `--call` option is provided, then the positional arguments are used to generate the command string. +If no `--package` options are provided, then npm will attempt to determine the executable name from the package specifier provided as the first positional argument according to the following heuristic: + +- If the package has a single entry in its `bin` field in `package.json`, or if all entries are aliases of the same command, then that command will be used. +- If the package has multiple `bin` entries, and one of them matches the unscoped portion of the `name` field, then that command will be used. +- If this does not result in exactly one option (either because there are no bin entries, or none of them match the `name` of the package), then `npm exec` exits with an error. + +To run a binary _other than_ the named binary, specify one or more `--package` options, which will prevent npm from inferring the package from the first command argument. + +### `npx` vs `npm exec` + +When run via the `npx` binary, all flags and options *must* be set prior to any positional arguments. +When run via `npm exec`, a double-hyphen `--` flag can be used to suppress npm's parsing of switches and options that should be sent to the executed command. + +For example: + +``` +$ npx foo@latest bar --package=@npmcli/foo +``` + +In this case, npm will resolve the `foo` package name, and run the following command: + +``` +$ foo bar --package=@npmcli/foo +``` + +Since the `--package` option comes _after_ the positional arguments, it is treated as an argument to the executed command. + +In contrast, due to npm's argument parsing logic, running this command is different: + +``` +$ npm exec foo@latest bar --package=@npmcli/foo +``` + +In this case, npm will parse the `--package` option first, resolving the `@npmcli/foo` package. +Then, it will execute the following command in that context: + +``` +$ foo@latest bar +``` + +The double-hyphen character is recommended to explicitly tell npm to stop parsing command line options and switches. +The following command would thus be equivalent to the `npx` command above: + +``` +$ npm exec -- foo@latest bar --package=@npmcli/foo +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### Examples + +Run the version of `tap` in the local dependencies, with the provided arguments: + +``` +$ npm exec -- tap --bail test/foo.js +$ npx tap --bail test/foo.js +``` + +Run a command _other than_ the command whose name matches the package name by specifying a `--package` option: + +``` +$ npm exec --package=foo -- bar --bar-argument +# ~ or ~ +$ npx --package=foo bar --bar-argument +``` + +Run an arbitrary shell script, in the context of the current project: + +``` +$ npm x -c 'eslint && say "hooray, lint passed"' +$ npx -c 'eslint && say "hooray, lint passed"' +``` + +### Workspaces support + +You may use the [`workspace`](/using-npm/config#workspace) or [`workspaces`](/using-npm/config#workspaces) configs in order to run an arbitrary command from an npm package (either one installed locally, or fetched remotely) in the context of the specified workspaces. +If no positional argument or `--call` option is provided, it will open an interactive subshell in the context of each of these configured workspaces one at a time. + +Given a project with configured workspaces, e.g: + +``` +. ++-- package.json +`-- packages + +-- a + | `-- package.json + +-- b + | `-- package.json + `-- c + `-- package.json +``` + +Assuming the workspace configuration is properly set up at the root level `package.json` file. +e.g: + +``` +{ + "workspaces": [ "./packages/*" ] +} +``` + +You can execute an arbitrary command from a package in the context of each of the configured workspaces when using the [`workspaces` config options](/using-npm/config#workspace), in this example we're using **eslint** to lint any js file found within each workspace folder: + +``` +npm exec --ws -- eslint ./*.js +``` + +#### Filtering workspaces + +It's also possible to execute a command in a single workspace using the `workspace` config along with a name or directory path: + +``` +npm exec --workspace=a -- eslint ./*.js +``` + +The `workspace` config can also be specified multiple times in order to run a specific script in the context of multiple workspaces. +When defining values for the `workspace` config in the command line, it also possible to use `-w` as a shorthand, e.g: + +``` +npm exec -w a -w b -- eslint ./*.js +``` + +This last command will run the `eslint` command in both `./packages/a` and +`./packages/b` folders. + +### Compatibility with Older npx Versions + +The `npx` binary was rewritten in npm v7.0.0, and the standalone `npx` package deprecated at that time. +`npx` uses the `npm exec` command instead of a separate argument parser and install process, with some affordances to maintain backwards compatibility with the arguments it accepted in previous versions. + +This resulted in some shifts in its functionality: + +- Any `npm` config value may be provided. +- To prevent security and user-experience problems from mistyping package + names, `npx` prompts before installing anything. + Suppress this prompt with the `-y` or `--yes` option. +- The `--no-install` option is deprecated, and will be converted to `--no`. +- Shell fallback functionality is removed, as it is not advisable. +- The `-p` argument is a shorthand for `--parseable` in npm, but shorthand for `--package` in npx. + This is maintained, but only for the `npx` executable. +- The `--ignore-existing` option is removed. + Locally installed bins are always present in the executed process `PATH`. +- The `--npm` option is removed. + `npx` will always use the `npm` it ships with. +- The `--node-arg` and `-n` options are removed. +- The `--always-spawn` option is redundant, and thus removed. +- The `--shell` option is replaced with `--script-shell`, but maintained in the `npx` executable for backwards compatibility. + +### A note on caching + +The npm cli utilizes its internal package cache when using the package name specified. +You can use the following to change how and when the cli uses this cache. +See [`npm cache`](/commands/npm-cache) for more on how the cache works. + +#### prefer-online + +Forces staleness checks for packages, making the cli look for updates immediately even if the package is already in the cache. + +#### prefer-offline + +Bypasses staleness checks for packages. +Missing data will still be requested from the server. +To force full offline mode, use `offline`. + +#### offline + +Forces full offline mode. +Any packages not locally cached will result in an error. + +#### workspace + +* Default: +* Type: String (can be set multiple times) + +Enable running a command in the context of the configured workspaces of the current project while filtering by running only the workspaces defined by this configuration option. + +Valid values for the `workspace` config are either: + +* Workspace names +* Path to a workspace directory +* Path to a parent workspace directory (will result to selecting all of the nested workspaces) + +This value is not exported to the environment for child processes. + +#### workspaces + +* Alias: `--ws` +* Type: Boolean +* Default: `false` + +Run scripts in the context of all configured workspaces for the current project. + +### See Also + +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [npm test](/commands/npm-test) +* [npm start](/commands/npm-start) +* [npm restart](/commands/npm-restart) +* [npm stop](/commands/npm-stop) +* [npm config](/commands/npm-config) +* [npm workspaces](/using-npm/workspaces) +* [npx](/commands/npx) diff --git a/docs/lib/content/commands/npm-explain.md b/docs/lib/content/commands/npm-explain.md new file mode 100644 index 0000000000000..577a6521919ae --- /dev/null +++ b/docs/lib/content/commands/npm-explain.md @@ -0,0 +1,63 @@ +--- +title: npm-explain +section: 1 +description: Explain installed packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will print the chain of dependencies causing a given package to be installed in the current project. + +If one or more package specs are provided, then only packages matching one of the specifiers will have their relationships explained. + +The package spec can also refer to a folder within `./node_modules` + +For example, running `npm explain glob` within npm's source tree will show: + +```bash +glob@7.1.6 +node_modules/glob + glob@"^7.1.4" from the root project + +glob@7.1.1 dev +node_modules/tacks/node_modules/glob + glob@"^7.0.5" from rimraf@2.6.2 + node_modules/tacks/node_modules/rimraf + rimraf@"^2.6.2" from tacks@1.3.0 + node_modules/tacks + dev tacks@"^1.3.0" from the root project +``` + +To explain just the package residing at a specific folder, pass that as the argument to the command. +This can be useful when trying to figure out exactly why a given dependency is being duplicated to satisfy conflicting version requirements within the project. + +```bash +$ npm explain node_modules/nyc/node_modules/find-up +find-up@3.0.0 dev +node_modules/nyc/node_modules/find-up + find-up@"^3.0.0" from nyc@14.1.1 + node_modules/nyc + nyc@"^14.1.1" from tap@14.10.8 + node_modules/tap + dev tap@"^14.10.8" from the root project +``` + +### Configuration +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm folders](/configuring-npm/folders) +* [npm ls](/commands/npm-ls) +* [npm install](/commands/npm-install) +* [npm link](/commands/npm-link) +* [npm prune](/commands/npm-prune) +* [npm outdated](/commands/npm-outdated) +* [npm update](/commands/npm-update) diff --git a/docs/lib/content/commands/npm-explore.md b/docs/lib/content/commands/npm-explore.md new file mode 100644 index 0000000000000..f92d46629bcee --- /dev/null +++ b/docs/lib/content/commands/npm-explore.md @@ -0,0 +1,34 @@ +--- +title: npm-explore +section: 1 +description: Browse an installed package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Spawn a subshell in the directory of the installed package specified. + +If a command is specified, then it is run in the subshell, which then immediately terminates. + +This is particularly handy in the case of git submodules in the `node_modules` folder: + +```bash +npm explore some-dependency -- git pull origin master +``` + +Note that the package is *not* automatically rebuilt afterwards, so be sure to use `npm rebuild <pkg>` if you make any changes. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm folders](/configuring-npm/folders) +* [npm edit](/commands/npm-edit) +* [npm rebuild](/commands/npm-rebuild) +* [npm install](/commands/npm-install) diff --git a/docs/lib/content/commands/npm-find-dupes.md b/docs/lib/content/commands/npm-find-dupes.md new file mode 100644 index 0000000000000..ea77122aa3a47 --- /dev/null +++ b/docs/lib/content/commands/npm-find-dupes.md @@ -0,0 +1,25 @@ +--- +title: npm-find-dupes +section: 1 +description: Find duplication in the package tree +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Runs `npm dedupe` in `--dry-run` mode, making npm only output the duplications, without actually changing the package tree. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm dedupe](/commands/npm-dedupe) +* [npm ls](/commands/npm-ls) +* [npm update](/commands/npm-update) +* [npm install](/commands/npm-install) + diff --git a/docs/lib/content/commands/npm-fund.md b/docs/lib/content/commands/npm-fund.md new file mode 100644 index 0000000000000..1e9cc2255c1ec --- /dev/null +++ b/docs/lib/content/commands/npm-fund.md @@ -0,0 +1,66 @@ +--- +title: npm-fund +section: 1 +description: Retrieve funding information +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command retrieves information on how to fund the dependencies of a given project. +If no package name is provided, it will list all dependencies that are looking for funding in a tree structure, listing the type of funding and the url to visit. +If a package name is provided then it tries to open its funding url using the [`--browser` config](/using-npm/config#browser) param; if there are multiple funding sources for the package, the user will be instructed to pass the +`--which` option to disambiguate. + +The list will avoid duplicated entries and will stack all packages that share the same url as a single entry. +Thus, the list does not have the same shape of the output from `npm ls`. + +#### Example + +### Workspaces support + +It's possible to filter the results to only include a single workspace and its dependencies using the [`workspace` config](/using-npm/config#workspace) option. + +#### Example: + +Here's an example running `npm fund` in a project with a configured workspace `a`: + +```bash +$ npm fund +test-workspaces-fund@1.0.0 ++-- https://example.com/a +| | `-- a@1.0.0 +| `-- https://example.com/maintainer +| `-- foo@1.0.0 ++-- https://example.com/npmcli-funding +| `-- @npmcli/test-funding +`-- https://example.com/org + `-- bar@2.0.0 +``` + +And here is an example of the expected result when filtering only by a specific workspace `a` in the same project: + +```bash +$ npm fund -w a +test-workspaces-fund@1.0.0 +`-- https://example.com/a + | `-- a@1.0.0 + `-- https://example.com/maintainer + `-- foo@2.0.0 +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +## See Also + +* [package spec](/using-npm/package-spec) +* [npm install](/commands/npm-install) +* [npm docs](/commands/npm-docs) +* [npm ls](/commands/npm-ls) +* [npm config](/commands/npm-config) +* [npm workspaces](/using-npm/workspaces) diff --git a/docs/lib/content/commands/npm-help-search.md b/docs/lib/content/commands/npm-help-search.md new file mode 100644 index 0000000000000..095cb6878f337 --- /dev/null +++ b/docs/lib/content/commands/npm-help-search.md @@ -0,0 +1,27 @@ +--- +title: npm-help-search +section: 1 +description: Search npm help documentation +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will search the npm markdown documentation files for the terms provided, and then list the results, sorted by relevance. + +If only one result is found, then it will show that help topic. + +If the argument to `npm help` is not a known help topic, then it will call `help-search`. +It is rarely if ever necessary to call this command directly. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm](/commands/npm) +* [npm help](/commands/npm-help) diff --git a/docs/lib/content/commands/npm-help.md b/docs/lib/content/commands/npm-help.md new file mode 100644 index 0000000000000..a12a832243cee --- /dev/null +++ b/docs/lib/content/commands/npm-help.md @@ -0,0 +1,29 @@ +--- +title: npm-help +section: 1 +description: Get help on npm +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +If supplied a topic, then show the appropriate documentation page. + +If the topic does not exist, or if multiple terms are provided, then npm will run the `help-search` command to find a match. +Note that, if `help-search` finds a single subject, then it will run `help` on that topic, so unique matches are equivalent to specifying a topic name. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm](/commands/npm) +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [package.json](/configuring-npm/package-json) +* [npm help-search](/commands/npm-help-search) diff --git a/docs/lib/content/commands/npm-init.md b/docs/lib/content/commands/npm-init.md new file mode 100644 index 0000000000000..92092cff79f9f --- /dev/null +++ b/docs/lib/content/commands/npm-init.md @@ -0,0 +1,144 @@ +--- +title: npm-init +section: 1 +description: Create a package.json file +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +`npm init <initializer>` can be used to set up a new or existing npm package. + +`initializer` in this case is an npm package named `create-<initializer>`, +which will be installed by [`npm-exec`](/commands/npm-exec), and then have its main bin executed -- presumably creating or updating `package.json` and running any other initialization-related operations. + +The init command is transformed to a corresponding `npm exec` operation as follows: + +* `npm init foo` -> `npm exec create-foo` +* `npm init @usr/foo` -> `npm exec @usr/create-foo` +* `npm init @usr` -> `npm exec @usr/create` +* `npm init @usr@2.0.0` -> `npm exec @usr/create@2.0.0` +* `npm init @usr/foo@2.0.0` -> `npm exec @usr/create-foo@2.0.0` + +If the initializer is omitted (by just calling `npm init`), init will fall back to legacy init behavior. +It will ask you a bunch of questions, and then write a package.json for you. +It will attempt to make reasonable guesses based on existing fields, dependencies, and options selected. +It is strictly additive, so it will keep any fields and values that were already set. +You can also use `-y`/`--yes` to skip the questionnaire altogether. +If you pass `--scope`, it will create a scoped package. + +*Note:* if a user already has the `create-<initializer>` package globally installed, that will be what `npm init` uses. +If you want npm to use the latest version, or another specific version you must specify it: + +* `npm init foo@latest` # fetches and runs the latest `create-foo` from the registry +* `npm init foo@1.2.3` # runs `create-foo@1.2.3` specifically + +#### Forwarding additional options + +Any additional options will be passed directly to the command, so `npm init foo -- --hello` will map to `npm exec -- create-foo --hello`. + +To better illustrate how options are forwarded, here's a more evolved example showing options passed to both the **npm cli** and a create package, both following commands are equivalent: + +- `npm init foo -y --registry=<url> -- --hello -a` +- `npm exec -y --registry=<url> -- create-foo --hello -a` + +### Examples + +Create a new React-based project using [`create-react-app`](https://npm.im/create-react-app): + +```bash +$ npm init react-app ./my-react-app +``` + +Create a new `esm`-compatible package using [`create-esm`](https://npm.im/create-esm): + +```bash +$ mkdir my-esm-lib && cd my-esm-lib +$ npm init esm --yes +``` + +Generate a plain old package.json using legacy init: + +```bash +$ mkdir my-npm-pkg && cd my-npm-pkg +$ git init +$ npm init +``` + +Generate it without having it ask any questions: + +```bash +$ npm init -y +``` + +Set the private flag to `true` in package.json: +```bash +$ npm init --init-private -y +``` + +### Workspaces support + +It's possible to create a new workspace within your project by using the `workspace` config option. +When using `npm init -w <dir>` the cli will create the folders and boilerplate expected while also adding a reference to your project `package.json` `"workspaces": []` property in order to make sure that new generated **workspace** is properly set up as such. + +Given a project with no workspaces, e.g: + +``` +. ++-- package.json +``` + +You may generate a new workspace using the legacy init: + +```bash +$ npm init -w packages/a +``` + +That will generate a new folder and `package.json` file, while also updating your top-level `package.json` to add the reference to this new workspace: + +``` +. ++-- package.json +`-- packages + `-- a + `-- package.json +``` + +The workspaces init also supports the `npm init <initializer> -w <dir>` syntax, following the same set of rules explained earlier in the initial +**Description** section of this page. +Similar to the previous example of creating a new React-based project using [`create-react-app`](https://npm.im/create-react-app), the following syntax will make sure to create the new react app as a nested **workspace** within your project and configure your `package.json` to recognize it as such: + +```bash +npm init -w packages/my-react-app react-app . +``` + +This will make sure to generate your react app as expected, one important consideration to have in mind is that `npm exec` is going to be run in the context of the newly created folder for that workspace, and that's the reason why in this example the initializer uses the initializer name followed with a dot to represent the current directory in that context, e.g: `react-app .`: + +``` +. ++-- package.json +`-- packages + +-- a + | `-- package.json + `-- my-react-app + +-- README + +-- package.json + `-- ... +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [init-package-json module](http://npm.im/init-package-json) +* [package.json](/configuring-npm/package-json) +* [npm version](/commands/npm-version) +* [npm scope](/using-npm/scope) +* [npm exec](/commands/npm-exec) +* [npm workspaces](/using-npm/workspaces) diff --git a/docs/lib/content/commands/npm-install-ci-test.md b/docs/lib/content/commands/npm-install-ci-test.md new file mode 100644 index 0000000000000..9685eaaa1aa91 --- /dev/null +++ b/docs/lib/content/commands/npm-install-ci-test.md @@ -0,0 +1,23 @@ +--- +title: npm-install-ci-test +section: 1 +description: Install a project with a clean slate and run tests +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command runs `npm ci` followed immediately by `npm test`. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm install-test](/commands/npm-install-test) +* [npm ci](/commands/npm-ci) +* [npm test](/commands/npm-test) diff --git a/docs/lib/content/commands/npm-install-test.md b/docs/lib/content/commands/npm-install-test.md new file mode 100644 index 0000000000000..33c988a6d82c7 --- /dev/null +++ b/docs/lib/content/commands/npm-install-test.md @@ -0,0 +1,24 @@ +--- +title: npm-install-test +section: 1 +description: Install package(s) and run tests +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command runs an `npm install` followed immediately by an `npm test`. +It takes exactly the same arguments as `npm install`. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm install](/commands/npm-install) +* [npm install-ci-test](/commands/npm-install-ci-test) +* [npm test](/commands/npm-test) diff --git a/docs/lib/content/commands/npm-install.md b/docs/lib/content/commands/npm-install.md new file mode 100644 index 0000000000000..c9a3dc404e6ea --- /dev/null +++ b/docs/lib/content/commands/npm-install.md @@ -0,0 +1,407 @@ +--- +title: npm-install +section: 1 +description: Install a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command installs a package and any packages that it depends on. +If the package has a package-lock, or an npm shrinkwrap file, or a yarn lock file, the installation of dependencies will be driven by that, respecting the following order of precedence: + +* `npm-shrinkwrap.json` +* `package-lock.json` +* `yarn.lock` + +See [package-lock.json](/configuring-npm/package-lock-json) and [`npm shrinkwrap`](/commands/npm-shrinkwrap). + +#### How `npm install` uses `package-lock.json` + +When you run `npm install` without arguments, npm compares `package.json` and `package-lock.json`: + +* **If the lockfile's resolved versions satisfy the `package.json` ranges:** npm uses the exact versions from `package-lock.json` to ensure reproducible builds across environments. + +* **If the ranges don't match:** npm resolves new versions that satisfy the `package.json` ranges and updates `package-lock.json` accordingly. This happens when you modify version ranges in `package.json` (e.g., changing `^7.0.0` to `^8.0.0`). Note that changing a range within the same major version (e.g., `^7.0.0` to `^7.1.0`) will only update the metadata in the lockfile if the currently installed version still satisfies the new range. + +In essence, `package-lock.json` locks your dependencies to specific versions, but `package.json` is the source of truth for acceptable version ranges. When the lockfile's versions satisfy the `package.json` ranges, the lockfile wins. When they conflict, `package.json` wins and the lockfile is updated. + +If you want to install packages while ensuring that `package.json` is not modified and that both files are strictly in sync, use [`npm ci`](/commands/npm-ci) instead. + +A `package` is: + +* a) a folder containing a program described by a [`package.json`](/configuring-npm/package-json) file +* b) a gzipped tarball containing (a) +* c) a url that resolves to (b) +* d) a `<name>@<version>` that is published on the registry (see [`registry`](/using-npm/registry)) with (c) +* e) a `<name>@<tag>` (see [`npm dist-tag`](/commands/npm-dist-tag)) that points to (d) +* f) a `<name>` that has a "latest" tag satisfying (e) +* g) a `<git remote url>` that resolves to (a) + +Even if you never publish your package, you can still get a lot of benefits of using npm if you just want to write a node program (a), and perhaps if you also want to be able to easily install it elsewhere after packing it up into a tarball (b). + + +* `npm install` (in a package directory, no arguments): + + Install the dependencies to the local `node_modules` folder. + + In global mode (ie, with `-g` or `--global` appended to the command), it installs the current package context (ie, the current working directory) as a global package. + + By default, `npm install` will install all modules listed as dependencies in [`package.json`](/configuring-npm/package-json). + + With the `--production` flag (or when the `NODE_ENV` environment variable is set to `production`), npm will not install modules listed in `devDependencies`. + To install all modules listed in both `dependencies` and `devDependencies` when `NODE_ENV` environment variable is set to `production`, you can use `--production=false`. + + > NOTE: The `--production` flag has no particular meaning when adding a dependency to a project. + +* `npm install <folder>`: + + If `<folder>` sits inside the root of your project, its dependencies will be installed and may be hoisted to the top-level `node_modules` as they would for other types of dependencies. + If `<folder>` sits outside the root of your project, *npm will not install the package dependencies* in the directory `<folder>`, but it will create a symlink to `<folder>`. + + > NOTE: If you want to install the content of a directory like a package from the registry instead of creating a link, you would need to use the `--install-links` option. + + Example: + + ```bash + npm install ../../other-package --install-links + npm install ./sub-package + ``` + +* `npm install <tarball file>`: + + Install a package that is sitting on the filesystem. + Note: if you just want to link a dev directory into your npm root, you can do this more easily by using [`npm link`](/commands/npm-link). + + Tarball requirements: + * The filename *must* use `.tar`, `.tar.gz`, or `.tgz` as the extension. + * The package contents should reside in a subfolder inside the tarball (usually it is called `package/`). + npm strips one directory layer when installing the package (an equivalent of `tar x --strip-components=1` is run). + * The package must contain a `package.json` file with `name` and `version` properties. + + Example: + + ```bash + npm install ./package.tgz + ``` + +* `npm install <tarball url>`: + + Fetch the tarball url, and then install it. + In order to distinguish between this and other options, the argument must start with "http://" or "https://" + + Example: + + ```bash + npm install https://github.com/indexzero/forever/tarball/v0.5.6 + ``` + +* `npm install [<@scope>/]<name>`: + + Do a `<name>@<tag>` install, where `<tag>` is the "tag" config. + (See [`config`](/using-npm/config#tag). + The config's default value is `latest`.) + + In most cases, this will install the version of the modules tagged as `latest` on the npm registry. + + **Note:** When installing by name without specifying a version or tag, npm prioritizes versions that match the current Node.js version based on the package's `engines` field. If the `latest` tag points to a version incompatible with your current Node.js version, npm will install the newest compatible version instead. To install a specific version regardless of `engines` compatibility, explicitly specify the version or tag: `npm install <name>@latest`. + + Example: + + ```bash + npm install sax + ``` + + `npm install` saves any specified packages into `dependencies` by default. + Additionally, you can control where and how they get saved with some additional flags: + + * `-P, --save-prod`: Package will appear in your `dependencies`. + This is the default unless `-D` or `-O` are present. + + * `-D, --save-dev`: Package will appear in your `devDependencies`. + + * `--save-peer`: Package will appear in your `peerDependencies`. + + * `-O, --save-optional`: Package will appear in your + `optionalDependencies`. + + * `--no-save`: Prevents saving to `dependencies`. + + When using any of the above options to save dependencies to your package.json, there are two additional, optional flags: + + * `-E, --save-exact`: Saved dependencies will be configured with an exact version rather than using npm's default semver range operator. + + * `-B, --save-bundle`: Saved dependencies will also be added to your `bundleDependencies` list. + + Further, if you have an `npm-shrinkwrap.json` or `package-lock.json` then it will be updated as well. + + `<scope>` is optional. + The package will be downloaded from the registry associated with the specified scope. + If no registry is associated with the given scope the default registry is assumed. + See [`scope`](/using-npm/scope). + + Note: if you do not include the @-symbol on your scope name, npm will interpret this as a GitHub repository instead, see below. + Scopes names must also be followed by a slash. + + Examples: + + ```bash + npm install sax + npm install githubname/reponame + npm install @myorg/privatepackage + npm install node-tap --save-dev + npm install dtrace-provider --save-optional + npm install readable-stream --save-exact + npm install ansi-regex --save-bundle + ``` + +* `npm install <alias>@npm:<name>`: + + Install a package under a custom alias. + Allows multiple versions of a same-name package side-by-side, more convenient import names for packages with otherwise long ones, and using git forks replacements or forked npm packages as replacements. + Aliasing works only on your project and does not rename packages in transitive dependencies. + Aliases should follow the naming conventions stated in [`validate-npm-package-name`](https://www.npmjs.com/package/validate-npm-package-name#naming-rules). + + Examples: + + ```bash + npm install my-react@npm:react + npm install jquery2@npm:jquery@2 + npm install jquery3@npm:jquery@3 + npm install npa@npm:npm-package-arg + ``` + +* `npm install [<@scope>/]<name>@<tag>`: + + Install the version of the package that is referenced by the specified tag. + If the tag does not exist in the registry data for that package, then this will fail. + + Example: + + ```bash + npm install sax@latest + npm install @myorg/mypackage@latest + ``` + +* `npm install [<@scope>/]<name>@<version>`: + + Install the specified version of the package. + This will fail if the version has not been published to the registry. + + Example: + + ```bash + npm install sax@0.1.1 + npm install @myorg/privatepackage@1.5.0 + ``` + +* `npm install [<@scope>/]<name>@<version range>`: + + Install a version of the package matching the specified version range. + This will follow the same rules for resolving dependencies described in [`package.json`](/configuring-npm/package-json). + + Note that most version ranges must be put in quotes so that your shell will treat it as a single argument. + + Example: + + ```bash + npm install sax@">=0.1.0 <0.2.0" + npm install @myorg/privatepackage@"16 - 17" + ``` + + **Prerelease versions:** By default, version ranges only match stable versions. To include prerelease versions, they must be explicitly specified in the range. Prerelease versions are tied to a specific version triple (major.minor.patch). For example, `^1.2.3-beta.1` will only match prereleases for `1.2.x`, not `1.3.x`. To match all prereleases for a major version, use a range like `^1.0.0-0`, which will include all `1.x.x` prereleases. + + Example: + + ```bash + npm install package@^1.2.3-beta.1 # Matches 1.2.3-beta.1, 1.2.3-beta.2, 1.2.4-beta.1, etc. + npm install package@^1.0.0-0 # Matches all 1.x.x prereleases and stable versions + ``` + +* `npm install <git remote url>`: + + Installs the package from the hosted git provider, cloning it with `git`. + For a full git remote url, only that URL will be attempted. + + ```bash + <protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>] + ``` + + `<protocol>` is one of `git`, `git+ssh`, `git+http`, `git+https`, or + `git+file`. + + If `#<commit-ish>` is provided, it will be used to clone exactly that commit. + If the commit-ish has the format `#semver:<semver>`, `<semver>` can be any valid semver range or exact version, and npm will look for any tags or refs matching that range in the remote repository, much as it would for a registry dependency. + If neither `#<commit-ish>` or `#semver:<semver>` is specified, then the default branch of the repository is used. + + If the repository makes use of submodules, those submodules will be cloned as well. + + If the package being installed contains a `prepare` script, its `dependencies` and `devDependencies` will be installed, and the prepare script will be run, before the package is packaged and installed. + + The following git environment variables are recognized by npm and will be added to the environment when running git: + + * `GIT_ASKPASS` + * `GIT_EXEC_PATH` + * `GIT_PROXY_COMMAND` + * `GIT_SSH` + * `GIT_SSH_COMMAND` + * `GIT_SSL_CAINFO` + * `GIT_SSL_NO_VERIFY` + + See the git man page for details. + + Examples: + + ```bash + npm install git+ssh://git@github.com:npm/cli.git#v1.0.27 + npm install git+ssh://git@github.com:npm/cli#pull/273 + npm install git+ssh://git@github.com:npm/cli#semver:^5.0 + npm install git+https://isaacs@github.com/npm/cli.git + npm install git://github.com/npm/cli.git#v1.0.27 + GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident' npm install git+ssh://git@github.com:npm/cli.git + ``` + +* `npm install <githubname>/<githubrepo>[#<commit-ish>]`: +* `npm install github:<githubname>/<githubrepo>[#<commit-ish>]`: + + Install the package at `https://github.com/githubname/githubrepo` by attempting to clone it using `git`. + + If `#<commit-ish>` is provided, it will be used to clone exactly that commit. + If the commit-ish has the format `#semver:<semver>`, `<semver>` can be any valid semver range or exact version, and npm will look for any tags or refs matching that range in the remote repository, much as it would for a registry dependency. + If neither `#<commit-ish>` or `#semver:<semver>` is specified, then the default branch is used. + + As with regular git dependencies, `dependencies` and `devDependencies` will be installed if the package has a `prepare` script before the package is done installing. + + Examples: + + ```bash + npm install mygithubuser/myproject + npm install github:mygithubuser/myproject + ``` + +* `npm install gist:[<githubname>/]<gistID>[#<commit-ish>|#semver:<semver>]`: + + Install the package at `https://gist.github.com/gistID` by attempting to clone it using `git`. + The GitHub username associated with the gist is optional and will not be saved in `package.json`. + + As with regular git dependencies, `dependencies` and `devDependencies` will be installed if the package has a `prepare` script before the package is done installing. + + Example: + + ```bash + npm install gist:101a11beef + ``` + +* `npm install bitbucket:<bitbucketname>/<bitbucketrepo>[#<commit-ish>]`: + + Install the package at `https://bitbucket.org/bitbucketname/bitbucketrepo` by attempting to clone it using `git`. + + If `#<commit-ish>` is provided, it will be used to clone exactly that commit. + If the commit-ish has the format `#semver:<semver>`, `<semver>` can be any valid semver range or exact version, and npm will look for any tags or refs matching that range in the remote repository, much as it would for a registry dependency. + If neither `#<commit-ish>` or `#semver:<semver>` is specified, then `master` is used. + + As with regular git dependencies, `dependencies` and `devDependencies` will be installed if the package has a `prepare` script before the package is done installing. + + Example: + + ```bash + npm install bitbucket:mybitbucketuser/myproject + ``` + +* `npm install gitlab:<gitlabname>/<gitlabrepo>[#<commit-ish>]`: + + Install the package at `https://gitlab.com/gitlabname/gitlabrepo` by attempting to clone it using `git`. + + If `#<commit-ish>` is provided, it will be used to clone exactly that commit. + If the commit-ish has the format `#semver:<semver>`, `<semver>` can be any valid semver range or exact version, and npm will look for any tags or refs matching that range in the remote repository, much as it would for a registry dependency. + If neither `#<commit-ish>` or `#semver:<semver>` is specified, then `master` is used. + + As with regular git dependencies, `dependencies` and `devDependencies` will be installed if the package has a `prepare` script before the package is done installing. + + Example: + + ```bash + npm install gitlab:mygitlabuser/myproject + npm install gitlab:myusr/myproj#semver:^5.0 + ``` + +You may combine multiple arguments and even multiple types of arguments. +For example: + +```bash +npm install sax@">=0.1.0 <0.2.0" bench supervisor +``` + +The `--tag` argument will apply to all of the specified install targets. +If a tag with the given name exists, the tagged version is preferred over newer versions. + +**Note:** The `--tag` option only affects packages specified on the command line. It does not override version ranges specified in `package.json`. For example, if `package.json` specifies `"foo": "^1.0.0"` and you run `npm install --tag beta`, npm will still install a version matching `^1.0.0` even if the `beta` tag points to a different version. To install a tagged version, specify the package explicitly: `npm install foo@beta`. + +The `--dry-run` argument will report in the usual way what the install would have done without actually installing anything. + +The `--package-lock-only` argument will only update the `package-lock.json`, instead of checking `node_modules` and downloading dependencies. + +The `-f` or `--force` argument will force npm to fetch remote resources even if a local copy exists on disk. + +```bash +npm install sax --force +``` + +### Configuration + +See the [`config`](/using-npm/config) help doc. +Many of the configuration params have some effect on installation, since that's most of what npm does. + +These are some of the most common options related to installation. + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### Algorithm + +Given a `package{dep}` structure: `A{B,C}, B{C}, C{D}`, the npm install algorithm produces: + +```bash +A ++-- B ++-- C ++-- D +``` + +That is, the dependency from B to C is satisfied by the fact that A already caused C to be installed at a higher level. +D is still installed at the top level because nothing conflicts with it. + +For `A{B,C}, B{C,D@1}, C{D@2}`, this algorithm produces: + +```bash +A ++-- B ++-- C + `-- D@2 ++-- D@1 +``` + +Because B's D@1 will be installed in the top-level, C now has to install D@2 privately for itself. +This algorithm is deterministic, but different trees may be produced if two dependencies are requested for installation in a different order. + +See [folders](/configuring-npm/folders) for a more detailed description of the specific folder structures that npm creates. + +### See Also + +* [npm folders](/configuring-npm/folders) +* [npm update](/commands/npm-update) +* [npm audit](/commands/npm-audit) +* [npm fund](/commands/npm-fund) +* [npm link](/commands/npm-link) +* [npm rebuild](/commands/npm-rebuild) +* [npm scripts](/using-npm/scripts) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm registry](/using-npm/registry) +* [npm dist-tag](/commands/npm-dist-tag) +* [npm uninstall](/commands/npm-uninstall) +* [npm shrinkwrap](/commands/npm-shrinkwrap) +* [package.json](/configuring-npm/package-json) +* [workspaces](/using-npm/workspaces) diff --git a/docs/lib/content/commands/npm-link.md b/docs/lib/content/commands/npm-link.md new file mode 100644 index 0000000000000..347da3540b4a2 --- /dev/null +++ b/docs/lib/content/commands/npm-link.md @@ -0,0 +1,98 @@ +--- +title: npm-link +section: 1 +description: Symlink a package folder +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This is handy for installing your own stuff, so that you can work on it and test iteratively without having to continually rebuild. + +Package linking is a two-step process. + +First, `npm link` in a package folder with no arguments will create a symlink in the global folder `{prefix}/lib/node_modules/<package>` that links to the package where the `npm link` command was executed. +It will also link any bins in the package to `{prefix}/bin/{name}`. +Note that `npm link` uses the global prefix (see `npm prefix -g` for its value). + +Next, in some other location, `npm link package-name` will create a symbolic link from globally-installed `package-name` to `node_modules/` of the current folder. + +Note that `package-name` is taken from `package.json`, _not_ from the directory name. + +The package name can be optionally prefixed with a scope. +See [`scope`](/using-npm/scope). +The scope must be preceded by an @-symbol and followed by a slash. + +When creating tarballs for `npm publish`, the linked packages are "snapshotted" to their current state by resolving the symbolic links, if they are included in `bundleDependencies`. + +For example: + +```bash +cd ~/projects/node-redis # go into the package directory +npm link # creates global link +cd ~/projects/node-bloggy # go into some other package directory. +npm link redis # link-install the package +``` + +Now, any changes to `~/projects/node-redis` will be reflected in +`~/projects/node-bloggy/node_modules/node-redis/`. +Note that the link should be to the package name, not the directory name for that package. + +You may also shortcut the two steps in one. +For example, to do the above use-case in a shorter way: + +```bash +cd ~/projects/node-bloggy # go into the dir of your main project +npm link ../node-redis # link the dir of your dependency +``` + +The second line is the equivalent of doing: + +```bash +(cd ../node-redis; npm link) +npm link redis +``` + +That is, it first creates a global link, and then links the global installation target into your project's `node_modules` folder. + +Note that in this case, you are referring to the directory name, +`node-redis`, rather than the package name `redis`. + +If your linked package is scoped (see [`scope`](/using-npm/scope)) your link command must include that scope, e.g. + +```bash +npm link @myorg/privatepackage +``` + +### Caveat + +Note that package dependencies linked in this way are _not_ saved to `package.json` by default, on the assumption that the intention is to have a link stand in for a regular non-link dependency. +Otherwise, for example, if you depend on `redis@^3.0.1`, and ran `npm link redis`, it would replace the `^3.0.1` dependency with `file:../path/to/node-redis`, which you probably don't want! Additionally, other users or developers on your project would run into issues if they do not have their folders set up exactly the same as yours. + +If you are adding a _new_ dependency as a link, you should add it to the relevant metadata by running `npm install <dep> --package-lock-only`. + +If you _want_ to save the `file:` reference in your `package.json` and `package-lock.json` files, you can use `npm link <dep> --save` to do so. + +### Workspace Usage + +`npm link <pkg> --workspace <name>` will link the relevant package as a dependency of the specified workspace(s). +Note that It may actually be linked into the parent project's `node_modules` folder, if there are no conflicting dependencies. + +`npm link --workspace <name>` will create a global link to the specified workspace(s). + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm developers](/using-npm/developers) +* [package.json](/configuring-npm/package-json) +* [npm install](/commands/npm-install) +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-login.md b/docs/lib/content/commands/npm-login.md new file mode 100644 index 0000000000000..18d776e39a19b --- /dev/null +++ b/docs/lib/content/commands/npm-login.md @@ -0,0 +1,41 @@ +--- +title: npm-login +section: 1 +description: Login to a registry user account +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Verify a user in the specified registry, and save the credentials to the +`.npmrc` file. +If no registry is specified, the default registry will be used (see [`config`](/using-npm/config)). + +When you run `npm login`, the CLI automatically generates a legacy token of `publish` type. +For more information, see [About legacy tokens](/about-access-tokens#about-legacy-tokens). + +When using `legacy` for your `auth-type`, the username and password, are read in from prompts. + +To reset your password, go to <https://www.npmjs.com/forgot> + +To change your email address, go to <https://www.npmjs.com/email-edit> + +You may use this command multiple times with the same user account to authorize on a new machine. +When authenticating on a new machine, the username, password and email address must all match with your existing record. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm owner](/commands/npm-owner) +* [npm whoami](/commands/npm-whoami) +* [npm token](/commands/npm-token) +* [npm profile](/commands/npm-profile) diff --git a/docs/lib/content/commands/npm-logout.md b/docs/lib/content/commands/npm-logout.md new file mode 100644 index 0000000000000..4d31727bb02d5 --- /dev/null +++ b/docs/lib/content/commands/npm-logout.md @@ -0,0 +1,30 @@ +--- +title: npm-logout +section: 1 +description: Log out of the registry +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +When logged into a registry that supports token-based authentication, tell the server to end this token's session. +This will invalidate the token everywhere you're using it, not just for the current environment. + +When logged into a legacy registry that uses username and password authentication, this will clear the credentials in your user configuration. +In this case, it will _only_ affect the current environment. + +If `--scope` is provided, this will find the credentials for the registry connected to that scope, if set. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm adduser](/commands/npm-adduser) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npm whoami](/commands/npm-whoami) diff --git a/docs/lib/content/commands/npm-ls.md b/docs/lib/content/commands/npm-ls.md new file mode 100644 index 0000000000000..e2fafbc7807fb --- /dev/null +++ b/docs/lib/content/commands/npm-ls.md @@ -0,0 +1,51 @@ +--- +title: npm-ls +section: 1 +description: List installed packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will print to stdout all the versions of packages that are installed, as well as their dependencies when `--all` is specified, in a tree structure. + +Note: to get a "bottoms up" view of why a given package is included in the tree at all, use [`npm explain`](/commands/npm-explain). + +Positional arguments are `name@version-range` identifiers, which will limit 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: + +```bash +npm@@VERSION@ /path/to/npm +└─┬ init-package-json@0.0.4 + └── promzard@0.1.5 +``` + +It will print out extraneous, missing, and invalid packages. + +If a project specifies git urls for dependencies these are shown in parentheses after the `name@version` to make it easier for users to recognize potential forks of a project. + +The tree shown is the logical dependency tree, based on package dependencies, not the physical layout of your `node_modules` folder. + +When run as `ll` or `la`, it shows extended information by default. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm explain](/commands/npm-explain) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm folders](/configuring-npm/folders) +* [npm explain](/commands/npm-explain) +* [npm install](/commands/npm-install) +* [npm link](/commands/npm-link) +* [npm prune](/commands/npm-prune) +* [npm outdated](/commands/npm-outdated) +* [npm update](/commands/npm-update) diff --git a/docs/lib/content/commands/npm-org.md b/docs/lib/content/commands/npm-org.md new file mode 100644 index 0000000000000..3cf6f01dde7a3 --- /dev/null +++ b/docs/lib/content/commands/npm-org.md @@ -0,0 +1,61 @@ +--- +title: npm-org +section: 1 +description: Manage orgs +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Example + +Add a new developer to an org: + +```bash +$ npm org set my-org @mx-smith +``` + +Add a new admin to an org (or change a developer to an admin): + +```bash +$ npm org set my-org @mx-santos admin +``` + +Remove a user from an org: + +```bash +$ npm org rm my-org mx-santos +``` + +List all users in an org: + +```bash +$ npm org ls my-org +``` + +List all users in JSON format: + +```bash +$ npm org ls my-org --json +``` + +See what role a user has in an org: + +```bash +$ npm org ls my-org @mx-santos +``` + +### Description + +You can use the `npm org` commands to manage and view users of an organization. +It supports adding and removing users, changing their roles, listing them, and finding specific ones and their roles. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [using orgs](/using-npm/orgs) +* [Documentation on npm Orgs](https://docs.npmjs.com/orgs/) diff --git a/docs/lib/content/commands/npm-outdated.md b/docs/lib/content/commands/npm-outdated.md new file mode 100644 index 0000000000000..40da7c3146f28 --- /dev/null +++ b/docs/lib/content/commands/npm-outdated.md @@ -0,0 +1,78 @@ +--- +title: npm-outdated +section: 1 +description: Check for outdated packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will check the registry to see if any (or, specific) installed packages are currently outdated. + +By default, only the direct dependencies of the root project and direct dependencies of your configured *workspaces* are shown. +Use `--all` to find all outdated meta-dependencies as well. + +In the output: + +* `wanted` is the maximum version of the package that satisfies the semver range specified in `package.json`. + If there's no available semver range (i.e. you're running `npm outdated --global`, or the package isn't included in `package.json`), then `wanted` shows the currently-installed version. +* `latest` is the version of the package tagged as latest in the registry. + Running `npm publish` with no special configuration will publish the package with a dist-tag of `latest`. + This may or may not be the maximum version of the package, or the most-recently published version of the package, depending on how the package's developer manages the latest [dist-tag](/commands/npm-dist-tag). +* `location` is where in the physical tree the package is located. +* `depended by` shows which package depends on the displayed dependency +* `package type` (when using `--long` / `-l`) tells you whether this package is a `dependency` or a dev/peer/optional dependency. + Packages not included in `package.json` are always marked `dependencies`. +* `homepage` (when using `--long` / `-l`) is the `homepage` value contained in the package's packument +* `depended by location` (when using `--long` / `-l`) shows location of the package that depends on the displayed dependency +* Red means there's a newer version matching your semver requirements, so you should update now. +* Yellow indicates that there's a newer version _above_ your semver requirements (usually new major, or new 0.x minor) so proceed with caution. + +### An example + +```bash +$ npm outdated +Package Current Wanted Latest Location Depended by +glob 5.0.15 5.0.15 6.0.1 node_modules/glob dependent-package-name +nothingness 0.0.3 git git node_modules/nothingness dependent-package-name +npm 3.5.1 3.5.2 3.5.1 node_modules/npm dependent-package-name +local-dev 0.0.3 linked linked local-dev dependent-package-name +once 1.3.2 1.3.3 1.3.3 node_modules/once dependent-package-name +``` + +With these `dependencies`: +```json +{ + "glob": "^5.0.15", + "nothingness": "github:othiym23/nothingness#master", + "npm": "^3.5.1", + "once": "^1.3.1" +} +``` + +A few things to note: + +* `glob` requires `^5`, which prevents npm from installing `glob@6`, which is outside the semver range. +* Git dependencies will always be reinstalled, because of how they're specified. + The installed committish might satisfy the dependency specifier (if it's something immutable, like a commit SHA), or it might not, so `npm outdated` and `npm update` have to fetch Git repos to check. + This is why currently doing a reinstall of a Git dependency always forces a new clone and install. +* `npm@3.5.2` is marked as "wanted", but "latest" is `npm@3.5.1` because npm uses dist-tags to manage its `latest` and `next` release channels. + `npm update` will install the _newest_ version, but `npm install npm` (with no semver range) will install whatever's tagged as `latest`. +* `once` is just plain out of date. + Reinstalling `node_modules` from scratch or running `npm update` will bring it up to spec. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm update](/commands/npm-update) +* [npm dist-tag](/commands/npm-dist-tag) +* [npm registry](/using-npm/registry) +* [npm folders](/configuring-npm/folders) +* [npm workspaces](/using-npm/workspaces) diff --git a/docs/lib/content/commands/npm-owner.md b/docs/lib/content/commands/npm-owner.md new file mode 100644 index 0000000000000..4bea77a0f9aac --- /dev/null +++ b/docs/lib/content/commands/npm-owner.md @@ -0,0 +1,38 @@ +--- +title: npm-owner +section: 1 +description: Manage package owners +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Manage ownership of published packages. + +* ls: List all the users who have access to modify a package and push new versions. +Handy when you need to know who to bug for help. +* add: Add a new user as a maintainer of a package. +This user is enabled to modify metadata, publish new versions, and add other owners. +* rm: Remove a user from the package owner list. +This immediately revokes their privileges. + +Note that there is only one level of access. +Either you can modify a package, or you can't. +Future versions may contain more fine-grained access levels, but that is not implemented at this time. + +If you have two-factor authentication enabled with `auth-and-writes` (see [`npm-profile`](/commands/npm-profile)) then you'll need to go through a second factor flow when changing ownership or include an otp on the command line with `--otp`. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm profile](/commands/npm-profile) +* [npm publish](/commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm adduser](/commands/npm-adduser) diff --git a/docs/lib/content/commands/npm-pack.md b/docs/lib/content/commands/npm-pack.md new file mode 100644 index 0000000000000..b5f39bcc1ead0 --- /dev/null +++ b/docs/lib/content/commands/npm-pack.md @@ -0,0 +1,30 @@ +--- +title: npm-pack +section: 1 +description: Create a tarball from a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### Description + +For anything that's installable (that is, a package folder, tarball, tarball url, git url, name@tag, name@version, name, or scoped name), this command will fetch it to the cache, copy the tarball to the current working directory as `<name>-<version>.tgz`, and then write the filenames out to stdout. + +If the same package is specified multiple times, then the file will be overwritten the second time. + +If no arguments are supplied, then npm packs the current package folder. + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm-packlist package](http://npm.im/npm-packlist) +* [npm cache](/commands/npm-cache) +* [npm publish](/commands/npm-publish) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-ping.md b/docs/lib/content/commands/npm-ping.md new file mode 100644 index 0000000000000..76de695cfde3e --- /dev/null +++ b/docs/lib/content/commands/npm-ping.md @@ -0,0 +1,35 @@ +--- +title: npm-ping +section: 1 +description: Ping npm registry +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Ping the configured or given npm registry and verify authentication. +If it works it will output something like: + +```bash +npm notice PING https://registry.npmjs.org/ +npm notice PONG 255ms +``` +otherwise you will get an error: +```bash +npm notice PING http://foo.com/ +npm ERR! code E404 +npm ERR! 404 Not Found - GET http://www.foo.com/-/ping?write=true +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm doctor](/commands/npm-doctor) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-pkg.md b/docs/lib/content/commands/npm-pkg.md new file mode 100644 index 0000000000000..403b8f93cacc7 --- /dev/null +++ b/docs/lib/content/commands/npm-pkg.md @@ -0,0 +1,157 @@ +--- +title: npm-pkg +section: 1 +description: Manages your package.json +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +A command that automates the management of `package.json` files. +`npm pkg` provide 3 different sub commands that allow you to modify or retrieve values for given object keys in your `package.json`. + +The syntax to retrieve and set fields is a dot separated representation of the nested object properties to be found within your `package.json`, it's the same notation used in [`npm view`](/commands/npm-view) to retrieve information from the registry manifest, below you can find more examples on how to use it. + +Returned values are always in **json** format. + +* `npm pkg get <field>` + + Retrieves a value `key`, defined in your `package.json` file. + + For example, in order to retrieve the name of the current package, you can run: + + ```bash + npm pkg get name + ``` + + It's also possible to retrieve multiple values at once: + + ```bash + npm pkg get name version + ``` + + You can view child fields by separating them with a period. + To retrieve the value of a test `script` value, you would run the following command: + + ```bash + npm pkg get scripts.test + ``` + + For fields that are arrays, requesting a non-numeric field will return all of the values from the objects in the list. + For example, to get all the contributor emails for a package, you would run: + + ```bash + npm pkg get contributors.email + ``` + + You may also use numeric indices in square braces to specifically select an item in an array field. + To just get the email address of the first contributor in the list, you can run: + + ```bash + npm pkg get contributors[0].email + ``` + + For complex fields you can also name a property in square brackets to specifically select a child field. + This is especially helpful with the exports object: + + ```bash + npm pkg get "exports[.].require" + ``` + +* `npm pkg set <field>=<value>` + + Sets a `value` in your `package.json` based on the `field` value. + When saving to your `package.json` file the same set of rules used during `npm install` and other cli commands that touches the `package.json` file are used, making sure to respect the existing indentation and possibly applying some validation prior to saving values to the file. + + The same syntax used to retrieve values from your package can also be used to define new properties or overriding existing ones, below are some examples of how the dot separated syntax can be used to edit your `package.json` file. + + Defining a new bin named `mynewcommand` in your `package.json` that points to a file `cli.js`: + + ```bash + npm pkg set bin.mynewcommand=cli.js + ``` + + Setting multiple fields at once is also possible: + + ```bash + npm pkg set description='Awesome package' engines.node='>=10' + ``` + + It's also possible to add to array values, for example to add a new contributor entry: + + ```bash + npm pkg set contributors[0].name='Foo' contributors[0].email='foo@bar.ca' + ``` + + You may also append items to the end of an array using the special empty bracket notation: + + ```bash + npm pkg set contributors[].name='Foo' contributors[].name='Bar' + ``` + + It's also possible to parse values as json prior to saving them to your `package.json` file, for example in order to set a `"private": true` property: + + ```bash + npm pkg set private=true --json + ``` + + It also enables saving values as numbers: + + ```bash + npm pkg set tap.timeout=60 --json + ``` + +* `npm pkg delete <key>` + + Deletes a `key` from your `package.json` + + The same syntax used to set values from your package can also be used to remove existing ones. + For example, in order to remove a script named build: + + ```bash + npm pkg delete scripts.build + ``` + +* `npm pkg fix` + + Auto corrects common errors in your `package.json`. + npm already does this during `publish`, which leads to subtle (mostly harmless) differences between the contents of your `package.json` file and the manifest that npm uses during installation. + +### Workspaces support + +You can set/get/delete items across your configured workspaces by using the [`workspace`](/using-npm/config#workspace) or [`workspaces`](/using-npm/config#workspaces) config options. + +For example, setting a `funding` value across all configured workspaces of a project: + +```bash +npm pkg set funding=https://example.com --ws +``` + +When using `npm pkg get` to retrieve info from your configured workspaces, the returned result will be in a json format in which top level keys are the names of each workspace, the values of these keys will be the result values returned from each of the configured workspaces, e.g: + +``` +npm pkg get name version --ws +{ + "a": { + "name": "a", + "version": "1.0.0" + }, + "b": { + "name": "b", + "version": "1.0.0" + } +} +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> +## See Also + +* [npm install](/commands/npm-install) +* [npm init](/commands/npm-init) +* [npm config](/commands/npm-config) +* [workspaces](/using-npm/workspaces) diff --git a/docs/lib/content/commands/npm-prefix.md b/docs/lib/content/commands/npm-prefix.md new file mode 100644 index 0000000000000..b038cc20e2f51 --- /dev/null +++ b/docs/lib/content/commands/npm-prefix.md @@ -0,0 +1,40 @@ +--- +title: npm-prefix +section: 1 +description: Display prefix +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Print the local prefix to standard output. +This is the closest parent directory to contain a `package.json` file or `node_modules` directory, unless `-g` is also specified. + +If `-g` is specified, this will be the value of the global prefix. +See [`npm config`](/commands/npm-config) for more detail. + +### Example + +```bash +npm prefix +/usr/local/projects/foo +``` + +```bash +npm prefix -g +/usr/local +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm root](/commands/npm-root) +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-profile.md b/docs/lib/content/commands/npm-profile.md new file mode 100644 index 0000000000000..fc69cef28918e --- /dev/null +++ b/docs/lib/content/commands/npm-profile.md @@ -0,0 +1,64 @@ +--- +title: npm-profile +section: 1 +description: Change settings on your registry profile +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Change your profile information on the registry. +Note that this command depends on the registry implementation, so third-party registries may not support this interface. + +* `npm profile get [<property>]`: Display all of the properties of your profile, or one or more specific properties. +It looks like: + +``` +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 <property> <value>`: Set the value of a profile property. +You can set the following properties this way: email, fullname, homepage, freenode, twitter, github + +* `npm profile set password`: Change your password. +This is interactive, you'll be prompted for your current password and a new password. +You'll also be prompted for an OTP if you have two-factor authentication enabled. + +* `npm profile enable-2fa [auth-and-writes|auth-only]`: Enables two-factor authentication. +Defaults to `auth-and-writes` mode. +Modes are: + * `auth-only`: Require an OTP when logging in or making changes to your account's authentication. +The OTP will be required on both the website and the command line. + * `auth-and-writes`: Requires an OTP at all the times `auth-only` does, and also requires one when publishing a module, setting the `latest` dist-tag, or changing access via `npm access` and `npm owner`. + +* `npm profile disable-2fa`: Disables two-factor authentication. + +### Details + +Some of these commands may not be available on non npmjs.com registries. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm adduser](/commands/npm-adduser) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm owner](/commands/npm-owner) +* [npm whoami](/commands/npm-whoami) +* [npm token](/commands/npm-token) diff --git a/docs/lib/content/commands/npm-prune.md b/docs/lib/content/commands/npm-prune.md new file mode 100644 index 0000000000000..0bce8d7bff03a --- /dev/null +++ b/docs/lib/content/commands/npm-prune.md @@ -0,0 +1,35 @@ +--- +title: npm-prune +section: 1 +description: Remove extraneous packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command removes "extraneous" packages. +If a package name is provided, then only packages matching one of the supplied names are removed. + +Extraneous packages are those present in the `node_modules` folder that are not listed as any package's dependency list. + +If the `--omit=dev` flag is specified or the `NODE_ENV` environment variable is set to `production`, this command will remove the packages specified in your `devDependencies`. + +If the `--dry-run` flag is used then no changes will actually be made. + +If the `--json` flag is used, then the changes `npm prune` made (or would have made with `--dry-run`) are printed as a JSON object. + +In normal operation, extraneous modules are pruned automatically, so you'll only need this command with the `--production` flag. +However, in the real world, operation is not always "normal". When crashes or mistakes happen, this command can help clean up any resulting garbage. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm uninstall](/commands/npm-uninstall) +* [npm folders](/configuring-npm/folders) +* [npm ls](/commands/npm-ls) diff --git a/docs/lib/content/commands/npm-publish.md b/docs/lib/content/commands/npm-publish.md new file mode 100644 index 0000000000000..b2cf7f143e47f --- /dev/null +++ b/docs/lib/content/commands/npm-publish.md @@ -0,0 +1,106 @@ +--- +title: npm-publish +section: 1 +description: Publish a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Publishes a package to the registry so that it can be installed by name. + +### Examples + +Publish the package in the current directory: + +```bash +npm publish +``` + +Publish a specific workspace: + +```bash +npm publish --workspace=<workspace-name> +``` + +Publish multiple workspaces: + +```bash +npm publish --workspace=workspace-a --workspace=workspace-b +``` + +Publish all workspaces: + +```bash +npm publish --workspaces +``` + +By default npm will publish to the public registry. +This can be overridden by specifying a different default registry or using a [`scope`](/using-npm/scope) in the name, combined with a scope-configured registry (see [`package.json`](/configuring-npm/package-json)). + + +A `package` is interpreted the same way as other commands (like `npm install`) and can be: + +* a) a folder containing a program described by a [`package.json`](/configuring-npm/package-json) file +* b) a gzipped tarball containing (a) +* c) a url that resolves to (b) +* d) a `<name>@<version>` that is published on the registry (see [`registry`](/using-npm/registry)) with (c) +* e) a `<name>@<tag>` (see [`npm dist-tag`](/commands/npm-dist-tag)) that points to (d) +* f) a `<name>` that has a "latest" tag satisfying (e) +* g) a `<git remote url>` that resolves to (a) + +The publish will fail if the package name and version combination already exists in the specified registry. + +Once a package is published with a given name and version, that specific name and version combination can never be used again, even if it is removed with [`npm unpublish`](/commands/npm-unpublish). + +As of `npm@5`, both a sha1sum and an integrity field with a sha512sum of the tarball will be submitted to the registry during publication. +Subsequent installs will use the strongest supported algorithm to verify downloads. + +Similar to `--dry-run` see [`npm pack`](/commands/npm-pack), which figures out the files to be included and packs them into a tarball to be uploaded to the registry. + +### Files included in package + +To see what will be included in your package, run `npm pack --dry-run`. +All files are included by default, with the following exceptions: + +- Certain files that are relevant to package installation and distribution are always included. +For example, `package.json`, `README.md`, + `LICENSE`, and so on. + +- If there is a "files" list in [`package.json`](/configuring-npm/package-json), then only the files specified will be included. + (If directories are specified, then they will be walked recursively and their contents included, subject to the same ignore rules.) + +- If there is a `.gitignore` or `.npmignore` file, then ignored files in that and all child directories will be excluded from the package. + If _both_ files exist, then the `.gitignore` is ignored, and only the + `.npmignore` is used. + + `.npmignore` files follow the [same pattern rules](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#_ignoring) as `.gitignore` files + +- If the file matches certain patterns, then it will _never_ be included, unless explicitly added to the `"files"` list in `package.json`, or un-ignored with a `!` rule in a `.npmignore` or `.gitignore` file. + +- Symbolic links are never included in npm packages. + + +See [`developers`](/using-npm/developers) for full details on what's included in the published package, as well as details on how the package is built. + +See [`package.json`](/configuring-npm/package-json) for more info on what can and can't be ignored. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm-packlist package](http://npm.im/npm-packlist) +* [npm registry](/using-npm/registry) +* [npm scope](/using-npm/scope) +* [npm adduser](/commands/npm-adduser) +* [npm owner](/commands/npm-owner) +* [npm deprecate](/commands/npm-deprecate) +* [npm dist-tag](/commands/npm-dist-tag) +* [npm pack](/commands/npm-pack) +* [npm profile](/commands/npm-profile) diff --git a/docs/lib/content/commands/npm-query.md b/docs/lib/content/commands/npm-query.md new file mode 100644 index 0000000000000..815ca231afa94 --- /dev/null +++ b/docs/lib/content/commands/npm-query.md @@ -0,0 +1,164 @@ +--- +title: npm-query +section: 1 +description: Dependency selector query +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +The `npm query` command allows for usage of css selectors in order to retrieve an array of dependency objects. + +### Piping npm query to other commands + +```bash +# find all dependencies with postinstall scripts & uninstall them +npm query ":attr(scripts, [postinstall])" | jq 'map(.name)|join("\n")' -r | xargs -I {} npm uninstall {} + +# find all git dependencies & explain who requires them +npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {} +``` + +### Extended Use Cases & Queries + +```stylus +// all deps +* + +// all direct deps +:root > * + +// direct production deps +:root > .prod + +// direct development deps +:root > .dev + +// any peer dep of a direct deps +:root > * > .peer + +// any workspace dep +.workspace + +// all workspaces that depend on another workspace +.workspace > .workspace + +// all workspaces that have peer deps +.workspace:has(.peer) + +// any dep named "lodash" +// equivalent to [name="lodash"] +#lodash + +// any deps named "lodash" & within semver range ^"1.2.3" +#lodash@^1.2.3 +// equivalent to... +[name="lodash"]:semver(^1.2.3) + +// get the hoisted node for a given semver range +#lodash@^1.2.3:not(:deduped) + +// querying deps with a specific version +#lodash@2.1.5 +// equivalent to... +[name="lodash"][version="2.1.5"] + +// has any deps +:has(*) + +// deps with no other deps (ie. "leaf" nodes) +:empty + +// manually querying git dependencies +[repository^=github:], +[repository^=git:], +[repository^=https://github.com], +[repository^=http://github.com], +[repository^=https://github.com], +[repository^=+git:...] + +// querying for all git dependencies +:type(git) + +// get production dependencies that aren't also dev deps +.prod:not(.dev) + +// get dependencies with specific licenses +[license=MIT], [license=ISC] + +// find all packages that have @ruyadorno as a contributor +:attr(contributors, [email=ruyadorno@github.com]) +``` + +### Example Response Output + +- an array of dependency objects is returned which can contain multiple copies of the same package which may or may not have been linked or deduped + +```json +[ + { + "name": "", + "version": "", + "description": "", + "homepage": "", + "bugs": {}, + "author": {}, + "license": {}, + "funding": {}, + "files": [], + "main": "", + "browser": "", + "bin": {}, + "man": [], + "directories": {}, + "repository": {}, + "scripts": {}, + "config": {}, + "dependencies": {}, + "devDependencies": {}, + "optionalDependencies": {}, + "bundledDependencies": {}, + "peerDependencies": {}, + "peerDependenciesMeta": {}, + "engines": {}, + "os": [], + "cpu": [], + "workspaces": {}, + "keywords": [], + ... + }, + ... +``` + +### Expecting a certain number of results + +One common use of `npm query` is to make sure there is only one version of a certain dependency in your tree. +This is especially common for ecosystems like that rely on `typescript` where having state split across two different but identically-named packages causes bugs. +You can use the `--expect-results` or `--expect-result-count` in your setup to ensure that npm will exit with an exit code if your tree doesn't look like you want it to. + + +```sh +$ npm query '#react' --expect-result-count=1 +``` + +Perhaps you want to quickly check if there are any production dependencies that could be updated: + +```sh +$ npm query ':root>:outdated(in-range).prod' --no-expect-results +``` + +### Package lock only mode + +If package-lock-only is enabled, only the information in the package lock (or shrinkwrap) is loaded. +This means that information from the package.json files of your dependencies will not be included in the result set (e.g. description, homepage, engines). + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> +## See Also + +* [dependency selectors](/using-npm/dependency-selectors) + diff --git a/docs/lib/content/commands/npm-rebuild.md b/docs/lib/content/commands/npm-rebuild.md new file mode 100644 index 0000000000000..ed61ac8e8ffb7 --- /dev/null +++ b/docs/lib/content/commands/npm-rebuild.md @@ -0,0 +1,45 @@ +--- +title: npm-rebuild +section: 1 +description: Rebuild a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command does the following: + +1. Execute lifecycle scripts (`preinstall`, `install`, `postinstall`, `prepare`) +2. Links bins depending on whether bin links are enabled + +This command is particularly useful in scenarios including but not limited to: + +1. Installing a new version of **node.js**, where you need to recompile all your C++ add-ons with the updated binary. +2. Installing with `--ignore-scripts` and `--no-bin-links`, to explicitly choose which packages to build and/or link bins. + +If one or more package specs are provided, then only packages with a name and version matching one of the specifiers will be rebuilt. + +Usually, you should not need to run `npm rebuild` as it is already done for you as part of npm install (unless you suppressed these steps with `--ignore-scripts` or `--no-bin-links`). + +If there is a `binding.gyp` file in the root of your package, then npm will use a default install hook: + +``` +"scripts": { + "install": "node-gyp rebuild" +} +``` + +This default behavior is suppressed if the `package.json` has its own `install` or `preinstall` scripts. +It is also suppressed if the package specifies `"gypfile": false` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm install](/commands/npm-install) diff --git a/docs/lib/content/commands/npm-repo.md b/docs/lib/content/commands/npm-repo.md new file mode 100644 index 0000000000000..75d39df6cd5ba --- /dev/null +++ b/docs/lib/content/commands/npm-repo.md @@ -0,0 +1,23 @@ +--- +title: npm-repo +section: 1 +description: Open package repository page in the browser +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command tries to guess at the likely location of a package's repository URL, and then tries to open it using the [`--browser` config](/using-npm/config#browser) param. +If no package name is provided, it will search for a `package.json` in the current folder and use the `repository` property. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm docs](/commands/npm-docs) +* [npm config](/commands/npm-config) diff --git a/docs/lib/content/commands/npm-restart.md b/docs/lib/content/commands/npm-restart.md new file mode 100644 index 0000000000000..a4d283c5fce1d --- /dev/null +++ b/docs/lib/content/commands/npm-restart.md @@ -0,0 +1,44 @@ +--- +title: npm-restart +section: 1 +description: Restart a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This restarts a project. +It is equivalent to running `npm run restart`. + +If the current project has a `"restart"` script specified in `package.json`, then the following scripts will be run: + +1. prerestart +2. restart +3. postrestart + +If it does _not_ have a `"restart"` script specified, but it does have `stop` and/or `start` scripts, then the following scripts will be run: + +1. prerestart +2. prestop +3. stop +4. poststop +6. prestart +7. start +8. poststart +9. postrestart + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [npm test](/commands/npm-test) +* [npm start](/commands/npm-start) +* [npm stop](/commands/npm-stop) +* [npm restart](/commands/npm-restart) diff --git a/docs/lib/content/commands/npm-root.md b/docs/lib/content/commands/npm-root.md new file mode 100644 index 0000000000000..48420f39dfe34 --- /dev/null +++ b/docs/lib/content/commands/npm-root.md @@ -0,0 +1,33 @@ +--- +title: npm-root +section: 1 +description: Display npm root +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Print the effective `node_modules` folder to standard out. + +Useful for using npm in shell scripts that do things with the `node_modules` folder. +For example: + +```bash +#!/bin/bash +global_node_modules="$(npm root --global)" +echo "Global packages installed in: ${global_node_modules}" +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm prefix](/commands/npm-prefix) +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-run.md b/docs/lib/content/commands/npm-run.md new file mode 100644 index 0000000000000..ddabd699e6962 --- /dev/null +++ b/docs/lib/content/commands/npm-run.md @@ -0,0 +1,123 @@ +--- +title: npm-run +section: 1 +description: Run arbitrary package scripts +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This runs an arbitrary command from a package's `"scripts"` object. +If no +`"command"` is provided, it will list the available scripts. + +`run[-script]` is used by the test, start, restart, and stop commands, but can be called directly, as well. +When the scripts in the package are printed out, they're separated into lifecycle (test, start, restart) and directly-run scripts. + +Any positional arguments are passed to the specified script. +Use `--` to pass `-`-prefixed flags and options which would otherwise be parsed by npm. + +For example: + +```bash +npm run test -- --grep="pattern" +``` + +The arguments will only be passed to the script specified after `npm run` and not to any `pre` or `post` script. + +The `env` script is a special built-in command that can be used to list environment variables that will be available to the script at runtime. +If an "env" command is defined in your package, it will take precedence over the built-in. + +In addition to the shell's pre-existing `PATH`, `npm run` adds `node_modules/.bin` to the `PATH` provided to scripts. +Any binaries provided by locally-installed dependencies can be used without the `node_modules/.bin` prefix. +For example, if there is a `devDependency` on `tap` in your package, you should write: + +```bash +"scripts": {"test": "tap test/*.js"} +``` + +instead of + +```bash +"scripts": {"test": "node_modules/.bin/tap test/*.js"} +``` + +The actual shell your script is run within is platform dependent. +By default, on Unix-like systems it is the `/bin/sh` command, on Windows it is `cmd.exe`. +The actual shell referred to by `/bin/sh` also depends on the system. +You can customize the shell with the [`script-shell` config](/using-npm/config#script-shell). + +Scripts are run from the root of the package folder, regardless of what the current working directory is when `npm run` is called. +If you want your script to use different behavior based on what subdirectory you're in, you can use the `INIT_CWD` environment variable, which holds the full path you were in when you ran `npm run`. + +`npm run` sets the `NODE` environment variable to the `node` executable with which `npm` is executed. + +If you try to run a script without having a `node_modules` directory and it fails, you will be given a warning to run `npm install`, just in case you've forgotten. + +### Workspaces support + +You may use the [`workspace`](/using-npm/config#workspace) or [`workspaces`](/using-npm/config#workspaces) configs in order to run an arbitrary command from a package's `"scripts"` object in the context of the specified workspaces. +If no `"command"` is provided, it will list the available scripts for each of these configured workspaces. + +Given a project with configured workspaces, e.g: + +``` +. ++-- package.json +`-- packages + +-- a + | `-- package.json + +-- b + | `-- package.json + `-- c + `-- package.json +``` + +Assuming the workspace configuration is properly set up at the root level `package.json` file. +e.g: + +``` +{ + "workspaces": [ "./packages/*" ] +} +``` + +And that each of the configured workspaces has a configured `test` script, we can run tests in all of them using the [`workspaces` config](/using-npm/config#workspaces): + +``` +npm test --workspaces +``` + +#### Filtering workspaces + +It's also possible to run a script in a single workspace using the `workspace` config along with a name or directory path: + +``` +npm test --workspace=a +``` + +The `workspace` config can also be specified multiple times in order to run a specific script in the context of multiple workspaces. +When defining values for the `workspace` config in the command line, it also possible to use `-w` as a shorthand, e.g: + +``` +npm test -w a -w b +``` + +This last command will run `test` in both `./packages/a` and `./packages/b` packages. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm scripts](/using-npm/scripts) +* [npm test](/commands/npm-test) +* [npm start](/commands/npm-start) +* [npm restart](/commands/npm-restart) +* [npm stop](/commands/npm-stop) +* [npm config](/commands/npm-config) +* [npm workspaces](/using-npm/workspaces) diff --git a/docs/lib/content/commands/npm-sbom.md b/docs/lib/content/commands/npm-sbom.md new file mode 100644 index 0000000000000..2e2c53f1bf327 --- /dev/null +++ b/docs/lib/content/commands/npm-sbom.md @@ -0,0 +1,221 @@ +--- +title: npm-sbom +section: 1 +description: Generate a Software Bill of Materials (SBOM) +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +The `npm sbom` command generates a Software Bill of Materials (SBOM) listing the dependencies for the current project. +SBOMs can be generated in either [SPDX](https://spdx.dev/) or [CycloneDX](https://cyclonedx.org/) format. + +### Example CycloneDX SBOM + +```json +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:09f55116-97e1-49cf-b3b8-44d0207e7730", + "version": 1, + "metadata": { + "timestamp": "2023-09-01T00:00:00.001Z", + "lifecycles": [ + { + "phase": "build" + } + ], + "tools": [ + { + "vendor": "npm", + "name": "cli", + "version": "10.1.0" + } + ], + "component": { + "bom-ref": "simple@1.0.0", + "type": "library", + "name": "simple", + "version": "1.0.0", + "scope": "required", + "author": "John Doe", + "description": "simple react app", + "purl": "pkg:npm/simple@1.0.0", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "" + } + ], + "externalReferences": [], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ] + } + }, + "components": [ + { + "bom-ref": "lodash@4.17.21", + "type": "library", + "name": "lodash", + "version": "4.17.21", + "scope": "required", + "author": "John-David Dalton", + "description": "Lodash modular utilities.", + "purl": "pkg:npm/lodash@4.17.21", + "properties": [ + { + "name": "cdx:npm:package:path", + "value": "node_modules/lodash" + } + ], + "externalReferences": [ + { + "type": "distribution", + "url": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + }, + { + "type": "vcs", + "url": "git+https://github.com/lodash/lodash.git" + }, + { + "type": "website", + "url": "https://lodash.com/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/lodash/lodash/issues" + } + ], + "hashes": [ + { + "alg": "SHA-512", + "content": "bf690311ee7b95e713ba568322e3533f2dd1cb880b189e99d4edef13592b81764daec43e2c54c61d5c558dc5cfb35ecb85b65519e74026ff17675b6f8f916f4a" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ] + } + ], + "dependencies": [ + { + "ref": "simple@1.0.0", + "dependsOn": [ + "lodash@4.17.21" + ] + }, + { + "ref": "lodash@4.17.21", + "dependsOn": [] + } + ] +} +``` + +### Example SPDX SBOM + +```json +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "simple@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/simple-1.0.0-bf81090e-8bbc-459d-bec9-abeb794e096a", + "creationInfo": { + "created": "2023-09-01T00:00:00.001Z", + "creators": [ + "Tool: npm/cli-10.1.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-simple-1.0.0" + ], + "packages": [ + { + "name": "simple", + "SPDXID": "SPDXRef-Package-simple-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "description": "simple react app", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/simple@1.0.0" + } + ] + }, + { + "name": "lodash", + "SPDXID": "SPDXRef-Package-lodash-4.17.21", + "versionInfo": "4.17.21", + "packageFileName": "node_modules/lodash", + "description": "Lodash modular utilities.", + "downloadLocation": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "filesAnalyzed": false, + "homepage": "https://lodash.com/", + "licenseDeclared": "MIT", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/lodash@4.17.21" + } + ], + "checksums": [ + { + "algorithm": "SHA512", + "checksumValue": "bf690311ee7b95e713ba568322e3533f2dd1cb880b189e99d4edef13592b81764daec43e2c54c61d5c558dc5cfb35ecb85b65519e74026ff17675b6f8f916f4a" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-simple-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-simple-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-lodash-4.17.21", + "relationshipType": "DEPENDS_ON" + } + ] +} +``` + +### Package lock only mode + +If package-lock-only is enabled, only the information in the package lock (or shrinkwrap) is loaded. +This means that information from the package.json files of your dependencies will not be included in the result set (e.g. +description, homepage, engines). + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> +## See Also + +* [package spec](/using-npm/package-spec) +* [dependency selectors](/using-npm/dependency-selectors) +* [package.json](/configuring-npm/package-json) +* [workspaces](/using-npm/workspaces) + diff --git a/docs/lib/content/commands/npm-search.md b/docs/lib/content/commands/npm-search.md new file mode 100644 index 0000000000000..b5244df0d8117 --- /dev/null +++ b/docs/lib/content/commands/npm-search.md @@ -0,0 +1,39 @@ +--- +title: npm-search +section: 1 +description: Search for packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Search the registry for packages matching the search terms. +`npm search` +performs a linear, incremental, lexically-ordered search through package metadata for all files in the registry. +If your terminal has color support, it will further highlight the matches in the results. +This can be disabled with the config item `color` + +Additionally, using the `--searchopts` and `--searchexclude` options paired with more search terms will include and exclude further patterns. +The main difference between `--searchopts` and the standard search terms is that the former does not highlight results in the output and you can use them more fine-grained filtering. +Additionally, you can add both of these to your config to change default search filtering behavior. + +Search also allows targeting of maintainers in search results, by prefixing their npm username with `=`. + +If a term starts with `/`, then it's interpreted as a regular expression and supports standard JavaScript RegExp syntax. +In this case search will ignore a trailing `/` . (Note you must escape or quote many regular expression characters in most shells.) + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm view](/commands/npm-view) +* [npm cache](/commands/npm-cache) +* https://npm.im/npm-registry-fetch diff --git a/docs/lib/content/commands/npm-shrinkwrap.md b/docs/lib/content/commands/npm-shrinkwrap.md new file mode 100644 index 0000000000000..6eb53e288201f --- /dev/null +++ b/docs/lib/content/commands/npm-shrinkwrap.md @@ -0,0 +1,25 @@ +--- +title: npm-shrinkwrap +section: 1 +description: Lock down dependency versions for publication +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command repurposes `package-lock.json` into a publishable `npm-shrinkwrap.json` or simply creates a new one. +The file created and updated by this command will then take precedence over any other existing or future `package-lock.json` files. +For a detailed explanation of the design and purpose of package locks in npm, see [package-lock-json](/configuring-npm/package-lock-json). + +### See Also + +* [npm install](/commands/npm-install) +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [package.json](/configuring-npm/package-json) +* [package-lock.json](/configuring-npm/package-lock-json) +* [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) +* [npm ls](/commands/npm-ls) diff --git a/docs/lib/content/commands/npm-star.md b/docs/lib/content/commands/npm-star.md new file mode 100644 index 0000000000000..431ee396761aa --- /dev/null +++ b/docs/lib/content/commands/npm-star.md @@ -0,0 +1,44 @@ +--- +title: npm-star +section: 1 +description: Mark your favorite packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +"Starring" a package means that you have some interest in it. +It's a vaguely positive way to show that you care. + +It's a boolean thing. +Starring repeatedly has no additional effect. + +### More + +There's also these extra commands to help you manage your favorite packages: + +#### Unstar + +You can also "unstar" a package using [`npm unstar`](/commands/npm-unstar) + +"Unstarring" is the same thing, but in reverse. + +#### Listing stars + +You can see all your starred packages using [`npm stars`](/commands/npm-stars) + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm unstar](/commands/npm-unstar) +* [npm stars](/commands/npm-stars) +* [npm view](/commands/npm-view) +* [npm whoami](/commands/npm-whoami) +* [npm adduser](/commands/npm-adduser) diff --git a/docs/lib/content/commands/npm-stars.md b/docs/lib/content/commands/npm-stars.md new file mode 100644 index 0000000000000..750b7bacff970 --- /dev/null +++ b/docs/lib/content/commands/npm-stars.md @@ -0,0 +1,27 @@ +--- +title: npm-stars +section: 1 +description: View packages marked as favorites +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +If you have starred a lot of neat things and want to find them again quickly this command lets you do just that. + +You may also want to see your friend's favorite packages, in this case you will most certainly enjoy this command. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm star](/commands/npm-star) +* [npm unstar](/commands/npm-unstar) +* [npm view](/commands/npm-view) +* [npm whoami](/commands/npm-whoami) +* [npm adduser](/commands/npm-adduser) diff --git a/docs/lib/content/commands/npm-start.md b/docs/lib/content/commands/npm-start.md new file mode 100644 index 0000000000000..3c28b43359fed --- /dev/null +++ b/docs/lib/content/commands/npm-start.md @@ -0,0 +1,52 @@ +--- +title: npm-start +section: 1 +description: Start a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This runs a predefined command specified in the `"start"` property of a package's `"scripts"` object. + +If the `"scripts"` object does not define a `"start"` property, npm will run `node server.js`. + +Note that this is different from the default node behavior of running the file specified in a package's `"main"` attribute when evoking with `node .` + +As of [`npm@2.0.0`](https://blog.npmjs.org/post/98131109725/npm-2-0-0), you can use custom arguments when executing scripts. +Refer to [`npm run`](/commands/npm-run) for more details. + +### Example + +```json +{ + "scripts": { + "start": "node foo.js" + } +} +``` + +```bash +npm start + +> npm@x.x.x start +> node foo.js + +(foo.js output would be here) + +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [npm test](/commands/npm-test) +* [npm restart](/commands/npm-restart) +* [npm stop](/commands/npm-stop) diff --git a/docs/lib/content/commands/npm-stop.md b/docs/lib/content/commands/npm-stop.md new file mode 100644 index 0000000000000..c2fb903296f10 --- /dev/null +++ b/docs/lib/content/commands/npm-stop.md @@ -0,0 +1,47 @@ +--- +title: npm-stop +section: 1 +description: Stop a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This runs a predefined command specified in the "stop" property of a package's "scripts" object. + +Unlike with [npm start](/commands/npm-start), there is no default script that will run if the `"stop"` property is not defined. + +### Example + +```json +{ + "scripts": { + "stop": "node bar.js" + } +} +``` + +```bash +npm stop + +> npm@x.x.x stop +> node bar.js + +(bar.js output would be here) + +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [npm test](/commands/npm-test) +* [npm start](/commands/npm-start) +* [npm restart](/commands/npm-restart) diff --git a/docs/lib/content/commands/npm-team.md b/docs/lib/content/commands/npm-team.md new file mode 100644 index 0000000000000..65830bf43fe46 --- /dev/null +++ b/docs/lib/content/commands/npm-team.md @@ -0,0 +1,92 @@ +--- +title: npm-team +section: 1 +description: Manage organization teams and team memberships +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Used to manage teams in organizations, and change team memberships. +Does not handle permissions for packages. + +Teams must always be fully qualified with the organization/scope they belong to when operating on them, separated by a colon (`:`). +That is, if you have a `newteam` team in an `org` organization, you must always refer to that team as `@org:newteam` in these commands. + +If you have two-factor authentication enabled in `auth-and-writes` mode, then you can provide a code from your authenticator with `[--otp <otpcode>]`. +If you don't include this then you will be taken through a second factor flow based on your `authtype`. + +* create / destroy: + Create a new team, or destroy an existing one. + Note: You cannot remove the `developers` team, [learn more.](https://docs.npmjs.com/about-developers-team) + + Here's how to create a new team `newteam` under the `org` org: + + ```bash + npm team create @org:newteam + ``` + + You should see a confirming message such as: `+@org:newteam` once the new team has been created. + +* add: + Add a user to an existing team. + + Adding a new user `username` to a team named `newteam` under the `org` org: + + ```bash + npm team add @org:newteam username + ``` + + On success, you should see a message: `username added to @org:newteam` + +* rm: + Using `npm team rm` you can also remove users from a team they belong to. + + Here's an example removing user `username` from `newteam` team in `org` organization: + + ```bash + npm team rm @org:newteam username + ``` + + Once the user is removed a confirmation message is displayed: + `username removed from @org:newteam` + +* ls: + If performed on an organization name, will return a list of existing teams under that organization. + If performed on a team, it will instead return a list of all users belonging to that particular team. + + Here's an example of how to list all teams from an org named `org`: + + ```bash + npm team ls @org + ``` + + Example listing all members of a team named `newteam`: + + ```bash + npm team ls @org:newteam + ``` + +### Details + +`npm team` always operates directly on the current registry, configurable from the command line using `--registry=<registry url>`. + +You must be a *team admin* to create teams and manage team membership, under the given organization. +Listing teams and team memberships may be done by any member of the organization. + +Organization creation and management of team admins and *organization* members is done through the website, not the npm CLI. + +To use teams to manage permissions on packages belonging to your organization, use the `npm access` command to grant or revoke the appropriate permissions. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm access](/commands/npm-access) +* [npm config](/commands/npm-config) +* [npm registry](/using-npm/registry) diff --git a/docs/lib/content/commands/npm-test.md b/docs/lib/content/commands/npm-test.md new file mode 100644 index 0000000000000..143c3b60dca6d --- /dev/null +++ b/docs/lib/content/commands/npm-test.md @@ -0,0 +1,43 @@ +--- +title: npm-test +section: 1 +description: Test a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This runs a predefined command specified in the `"test"` property of a package's `"scripts"` object. + +### Example + +```json +{ + "scripts": { + "test": "node test.js" + } +} +``` + +```bash +npm test +> npm@x.x.x test +> node test.js + +(test.js output would be here) +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [npm start](/commands/npm-start) +* [npm restart](/commands/npm-restart) +* [npm stop](/commands/npm-stop) diff --git a/docs/lib/content/commands/npm-token.md b/docs/lib/content/commands/npm-token.md new file mode 100644 index 0000000000000..5395466c68920 --- /dev/null +++ b/docs/lib/content/commands/npm-token.md @@ -0,0 +1,43 @@ +--- +title: npm-token +section: 1 +description: Manage your authentication tokens +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This lets you list, create and revoke authentication tokens. + +#### Listing tokens + +When listing tokens, an abbreviated token will be displayed. For security purposes the full token is not displayed. + +#### Generating tokens + +When generating tokens, you will be prompted you for your password and, if you have two-factor authentication enabled, an otp. + +Please refer to the [docs website](https://docs.npmjs.com/creating-and-viewing-access-tokens) for more information on generating tokens for CI/CD. + +#### Revoking tokens + +When revoking a token, you can use the full token (e.g. what you get back from `npm token create`, or as can be found in an `.npmrc` file), or a truncated id. If the given truncated id is not distinct enough to differentiate between multiple existing tokens, you will need to use enough of the id to allow npm to distinguish between them. Full token ids can be found on the [npm website](https://www.npmjs.com), or in the `--parseable` or `--json` output of `npm token list`. This command will NOT accept the truncated token found in the normal `npm token list` output. + +A revoked token will immediately be removed from the registry and you will no longer be able to use it. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm adduser](/commands/npm-adduser) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm owner](/commands/npm-owner) +* [npm whoami](/commands/npm-whoami) +* [npm profile](/commands/npm-profile) diff --git a/docs/lib/content/commands/npm-undeprecate.md b/docs/lib/content/commands/npm-undeprecate.md new file mode 100644 index 0000000000000..5647990a56940 --- /dev/null +++ b/docs/lib/content/commands/npm-undeprecate.md @@ -0,0 +1,22 @@ +--- +title: npm-undeprecate +section: 1 +description: Undeprecate a version of a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will update the npm registry entry for a package, removing any deprecation warnings that currently exist. + +It works in the same way as [npm deprecate](/commands/npm-deprecate), except that this command removes deprecation warnings instead of adding them. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> +### See Also + +* [npm deprecate](/commands/npm-deprecate) diff --git a/docs/lib/content/commands/npm-uninstall.md b/docs/lib/content/commands/npm-uninstall.md new file mode 100644 index 0000000000000..ce0aa55966433 --- /dev/null +++ b/docs/lib/content/commands/npm-uninstall.md @@ -0,0 +1,55 @@ +--- +title: npm-uninstall +section: 1 +description: Remove a package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This uninstalls a package, completely removing everything npm installed on its behalf. + +It also removes the package from the `dependencies`, `devDependencies`, +`optionalDependencies`, and `peerDependencies` objects in your `package.json`. + +Further, if you have an `npm-shrinkwrap.json` or `package-lock.json`, npm will update those files as well. + +`--no-save` will tell npm not to remove the package from your `package.json`, `npm-shrinkwrap.json`, or `package-lock.json` files. + +`--save` or `-S` will tell npm to remove the package from your `package.json`, `npm-shrinkwrap.json`, and `package-lock.json` files. +This is the default, but you may need to use this if you have for instance `save=false` in your `npmrc` file + +In global mode (ie, with `-g` or `--global` appended to the command), it uninstalls the current package context as a global package. +`--no-save` is ignored in this case. + +Scope is optional and follows the usual rules for [`scope`](/using-npm/scope). + +### Examples + +```bash +npm uninstall sax +``` + +`sax` will no longer be in your `package.json`, `npm-shrinkwrap.json`, or `package-lock.json` files. + +```bash +npm uninstall lodash --no-save +``` + +`lodash` will not be removed from your `package.json`, +`npm-shrinkwrap.json`, or `package-lock.json` files. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm prune](/commands/npm-prune) +* [npm install](/commands/npm-install) +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/docs/lib/content/commands/npm-unpublish.md b/docs/lib/content/commands/npm-unpublish.md new file mode 100644 index 0000000000000..152af8b55212d --- /dev/null +++ b/docs/lib/content/commands/npm-unpublish.md @@ -0,0 +1,43 @@ +--- +title: npm-unpublish +section: 1 +description: Remove a package from the registry +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +To learn more about how the npm registry treats unpublish, see our [unpublish policies](https://docs.npmjs.com/policies/unpublish). + +### Warning + +Consider using the [`deprecate`](/commands/npm-deprecate) command instead, if your intent is to encourage users to upgrade, or if you no longer want to maintain a package. + +### Description + +This removes a package version from the registry, deleting its entry and removing the tarball. + +The npm registry will return an error if you are not [logged in](/commands/npm-adduser). + +If you do not specify a package name at all, the name and version to be unpublished will be pulled from the project in the current directory. + +If you specify a package name but do not specify a version or if you remove all of a package's versions then the registry will remove the root package entry entirely. + +Even if you unpublish a package version, that specific name and version combination can never be reused. +In order to publish the package again, you must use a new version number. +If you unpublish the entire package, you may not publish any new versions of that package until 24 hours have passed. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm deprecate](/commands/npm-deprecate) +* [npm publish](/commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm adduser](/commands/npm-adduser) +* [npm owner](/commands/npm-owner) +* [npm login](/commands/npm-adduser) diff --git a/docs/lib/content/commands/npm-unstar.md b/docs/lib/content/commands/npm-unstar.md new file mode 100644 index 0000000000000..51124d8b1e65a --- /dev/null +++ b/docs/lib/content/commands/npm-unstar.md @@ -0,0 +1,38 @@ +--- +title: npm-unstar +section: 1 +description: Remove an item from your favorite packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +"Unstarring" a package is the opposite of [`npm star`](/commands/npm-star), it removes an item from your list of favorite packages. + +### More + +There's also these extra commands to help you manage your favorite packages: + +#### Star + +You can "star" a package using [`npm star`](/commands/npm-star) + +#### Listing stars + +You can see all your starred packages using [`npm stars`](/commands/npm-stars) + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm star](/commands/npm-star) +* [npm stars](/commands/npm-stars) +* [npm view](/commands/npm-view) +* [npm whoami](/commands/npm-whoami) +* [npm adduser](/commands/npm-adduser) + diff --git a/docs/lib/content/commands/npm-update.md b/docs/lib/content/commands/npm-update.md new file mode 100644 index 0000000000000..b4d8516329faf --- /dev/null +++ b/docs/lib/content/commands/npm-update.md @@ -0,0 +1,147 @@ +--- +title: npm-update +section: 1 +description: Update packages +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command will update all the packages listed to the latest version (specified by the [`tag` config](/using-npm/config#tag)), respecting the semver constraints of both your package and its dependencies (if they also require the same package). + +It will also install missing packages. + +If the `-g` flag is specified, this command will update globally installed packages. + +If no package name is specified, all packages in the specified location (global or local) will be updated. + +Note that by default `npm update` will not update the semver values of direct dependencies in your project `package.json`. +If you want to also update values in `package.json` you can run: `npm update --save` (or add the `save=true` option to a [configuration file](/configuring-npm/npmrc) to make that the default behavior). + +### Example + +For the examples below, assume that the current package is `app` and it depends on dependencies, `dep1` (`dep2`, .. etc.). +The published versions of `dep1` are: + +```json +{ + "dist-tags": { "latest": "1.2.2" }, + "versions": [ + "1.2.2", + "1.2.1", + "1.2.0", + "1.1.2", + "1.1.1", + "1.0.0", + "0.4.1", + "0.4.0", + "0.2.0" + ] +} +``` + +#### Caret Dependencies + +If `app`'s `package.json` contains: + +```json +"dependencies": { + "dep1": "^1.1.1" +} +``` + +Then `npm update` will install `dep1@1.2.2`, because `1.2.2` is `latest` and +`1.2.2` satisfies `^1.1.1`. + +#### Tilde Dependencies + +However, if `app`'s `package.json` contains: + +```json +"dependencies": { + "dep1": "~1.1.1" +} +``` + +In this case, running `npm update` will install `dep1@1.1.2`. +Even though the `latest` tag points to `1.2.2`, this version does not satisfy `~1.1.1`, which is equivalent to `>=1.1.1 <1.2.0`. +So the highest-sorting version that satisfies +`~1.1.1` is used, which is `1.1.2`. + +#### Caret Dependencies below 1.0.0 + +Suppose `app` has a caret dependency on a version below `1.0.0`, for example: + +```json +"dependencies": { + "dep1": "^0.2.0" +} +``` + +`npm update` will install `dep1@0.2.0`. + +If the dependence were on `^0.4.0`: + +```json +"dependencies": { + "dep1": "^0.4.0" +} +``` + +Then `npm update` will install `dep1@0.4.1`, because that is the highest-sorting version that satisfies `^0.4.0` (`>= 0.4.0 <0.5.0`) + + +#### Subdependencies + +Suppose your app now also has a dependency on `dep2` + +```json +{ + "name": "my-app", + "dependencies": { + "dep1": "^1.0.0", + "dep2": "1.0.0" + } +} +``` + +and `dep2` itself depends on this limited range of `dep1` + +```json +{ +"name": "dep2", + "dependencies": { + "dep1": "~1.1.1" + } +} +``` + +Then `npm update` will install `dep1@1.1.2` because that is the highest version that `dep2` allows. + npm will prioritize having a single version of `dep1` in your tree rather than two when that single version can satisfy the semver requirements of multiple dependencies in your tree. +In this case if you really did need your package to use a newer version you would need to use `npm install`. + + +#### Updating Globally-Installed Packages + +`npm update -g` will apply the `update` action to each globally installed package that is `outdated` -- that is, has a version that is different from `wanted`. + +Note: Globally installed packages are treated as if they are installed with a caret semver range specified. +So if you require to update to `latest` you may need to run `npm install -g [<pkg>...]` + +NOTE: If a package has been upgraded to a version newer than `latest`, it will be _downgraded_. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm install](/commands/npm-install) +* [npm outdated](/commands/npm-outdated) +* [npm shrinkwrap](/commands/npm-shrinkwrap) +* [npm registry](/using-npm/registry) +* [npm folders](/configuring-npm/folders) +* [npm ls](/commands/npm-ls) diff --git a/docs/lib/content/commands/npm-version.md b/docs/lib/content/commands/npm-version.md new file mode 100644 index 0000000000000..4ea0837aa8446 --- /dev/null +++ b/docs/lib/content/commands/npm-version.md @@ -0,0 +1,95 @@ +--- +title: npm-version +section: 1 +description: Bump a package version +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### Description + +Run this in a package directory to bump the version and write the new data back to `package.json`, `package-lock.json`, and, if present, +`npm-shrinkwrap.json`. + +The `newversion` argument should be a valid semver string, a valid second argument to [semver.inc](https://github.com/npm/node-semver#functions) (one of `patch`, `minor`, `major`, `prepatch`, `preminor`, `premajor`, `prerelease`), or `from-git`. +In the second case, the existing version will be incremented by 1 in the specified field. +`from-git` will try to read the latest git tag, and use that as the new npm version. + +**Note:** If the current version is a prerelease version, `patch` will simply remove the prerelease suffix without incrementing the patch version number. For example, `1.2.0-5` becomes `1.2.0` with `npm version patch`, not `1.2.1`. + +If run in a git repo, it will also create a version commit and tag. +This behavior is controlled by `git-tag-version` (see below), and can be disabled on the command line by running `npm --no-git-tag-version version`. +It will fail if the working directory is not clean, unless the `-f` or `--force` flag is set. + +**Note:** Git integration requires a reasonably recent version of git (2.0.0 or later is recommended). If you encounter issues with git commands, ensure your git installation is up to date. + +If supplied with `-m` or [`--message` config](/using-npm/config#message) option, npm will use it as a commit message when creating a version commit. +If the `message` config contains `%s` then that will be replaced with the resulting version number. +For example: + +```bash +npm version patch -m "Upgrade to %s for reasons" +``` + +If the [`sign-git-tag` config](/using-npm/config#sign-git-tag) is set, then the tag will be signed using the `-s` flag to git. +Note that you must have a default GPG key set up in your git config for this to work properly. +For example: + +```bash +$ npm config set sign-git-tag true +$ npm version patch + +You need a passphrase to unlock the secret key for user: "isaacs (http://blog.izs.me/) <i@izs.me>" +2048-bit RSA key, ID 6C481CF6, created 2010-08-31 + +Enter passphrase: +``` + +If `preversion`, `version`, or `postversion` are in the `scripts` property of the package.json, they will be executed as part of running `npm version`. + +The exact order of execution is as follows: + +1. Check to make sure the git working directory is clean before we get started. + Your scripts may add files to the commit in future steps. + This step is skipped if the `--force` flag is set. +2. Run the `preversion` script. + These scripts have access to the old `version` in package.json. + A typical use would be running your full test suite before deploying. + Any files you want added to the commit should be explicitly added using `git add`. +3. Bump `version` in `package.json` as requested (`patch`, `minor`, `major`, etc). +4. Run the `version` script. + These scripts have access to the new `version` in package.json (so they can incorporate it into file headers in generated files for example). + Again, scripts should explicitly add generated files to the commit using `git add`. +5. Commit and tag. +6. Run the `postversion` script. + Use it to clean up the file system or automatically push the commit and/or tag. + +Take the following example: + +```json +{ + "scripts": { + "preversion": "npm test", + "version": "npm run build && git add -A dist", + "postversion": "git push && git push --tags && rm -rf build/temp" + } +} +``` + +This runs all your tests and proceeds only if they pass. +Then runs your `build` script, and adds everything in the `dist` directory to the commit. +After the commit, it pushes the new commit and tag up to the server, and deletes the `build/temp` directory. + +### See Also + +* [npm init](/commands/npm-init) +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [package.json](/configuring-npm/package-json) +* [config](/using-npm/config) diff --git a/docs/lib/content/commands/npm-view.md b/docs/lib/content/commands/npm-view.md new file mode 100644 index 0000000000000..32838a0cdf692 --- /dev/null +++ b/docs/lib/content/commands/npm-view.md @@ -0,0 +1,189 @@ +--- +title: npm-view +section: 1 +description: View registry info +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command shows data about a package and prints it to stdout. + +As an example, to view information about the `connect` package from the registry, you would run: + +```bash +npm view connect +``` + +The default version is `"latest"` if unspecified. + +Field names can be specified after the package descriptor. +For example, to show the dependencies of the `ronn` package at version +`0.3.5`, you could do the following: + +```bash +npm view ronn@0.3.5 dependencies +``` + +By default, `npm view` shows data about the current project context (by looking for a `package.json`). +To show field data for the current project use a file path (i.e. +`.`): + +```bash +npm view . dependencies +``` + +You can view child fields by separating them with a period. +To view the git repository URL for the latest version of `npm`, you would run the following command: + +```bash +npm view npm repository.url +``` + +This makes it easy to view information about a dependency with a bit of shell scripting. +For example, to view all the data about the version of `opts` that `ronn` depends on, you could write the following: + +```bash +npm view opts@$(npm view ronn dependencies.opts) +``` + +For fields that are arrays, requesting a non-numeric field will return all of the values from the objects in the list. +For example, to get all the contributor email addresses for the `express` package, you would run: + +```bash +npm view express contributors.email +``` + +You may also use numeric indices in square braces to specifically select an item in an array field. +To just get the email address of the first contributor in the list, you can run: + +```bash +npm view express contributors[0].email +``` + +If the field value you are querying for is a property of an object, you should run: + +```bash +npm view express time'[4.8.0]' +``` + +Note: When accessing object properties that contain special characters or numeric keys, you need to use quotes around the key name. +For example, to get the publish time of a specific version: + +```bash +npm view express "time[4.17.1]" +``` + +Without quotes, the shell may interpret the square brackets as glob patterns, causing the command to fail. +You can also access the time field for a specific version by specifying the version in the package descriptor: + +```bash +npm view express@4.17.1 time +``` + +This will return all version-time pairs, but the context will be for that specific version. + +Multiple fields may be specified, and will be printed one after another. +For example, to get all the contributor names and email addresses, you can do this: + +```bash +npm view express contributors.name contributors.email +``` + +"Person" fields are shown as a string if they would be shown as an object. +So, for example, this will show the list of `npm` contributors in the shortened string format. + (See [`package.json`](/configuring-npm/package-json) for more on this.) + +```bash +npm view npm contributors +``` + +If a version range is provided, then data will be printed for every matching version of the package. +This will show which version of `jsdom` was required by each matching version of `yui3`: + +```bash +npm view yui3@'>0.5.4' dependencies.jsdom +``` + +To show the `connect` package version history, you can do this: + +```bash +npm view connect versions +``` + +### Field Access Patterns + +The `npm view` command supports different ways to access nested fields and array elements in package metadata. Understanding these patterns makes it easier to extract specific information. + +#### Nested Object Fields + +Use dot notation to access nested object fields: + +```bash +# Access nested properties +npm view npm repository.url +npm view express bugs.url +``` + +#### Array Element Access + +For arrays, use numeric indices in square brackets to access specific elements: + +```bash +# Get the first contributor's email +npm view express contributors[0].email + +# Get the second maintainer's name +npm view express maintainers[1].name +``` + +#### Object Property Access + +For object properties (like accessing specific versions in the `time` field), use bracket notation with the property name in quotes: + +```bash +# Get publish time for a specific version +npm view express "time[4.17.1]" + +# Get dist-tags +npm view express "dist-tags.latest" +``` + +#### Extracting Fields from Arrays + +Request a non-numeric field on an array to get all values from objects in the list: + +```bash +# Get all contributor emails +npm view express contributors.email + +# Get all contributor names +npm view express contributors.name +``` + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### Output + +If only a single string field for a single version is output, then it will not be colorized or quoted, to enable piping the output to another command. +If the field is an object, it will be output as a JavaScript object literal. + +If the `--json` flag is given, the outputted fields will be JSON. + +If the version range matches multiple versions then each printed value will be prefixed with the version it applies to. + +If multiple fields are requested, then each of them is prefixed with the field name. + +### See Also + +* [package spec](/using-npm/package-spec) +* [npm search](/commands/npm-search) +* [npm registry](/using-npm/registry) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm docs](/commands/npm-docs) diff --git a/docs/lib/content/commands/npm-whoami.md b/docs/lib/content/commands/npm-whoami.md new file mode 100644 index 0000000000000..4f87e954761c2 --- /dev/null +++ b/docs/lib/content/commands/npm-whoami.md @@ -0,0 +1,27 @@ +--- +title: npm-whoami +section: 1 +description: Display npm username +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +Display the npm username of the currently logged-in user. + +If logged into a registry that provides token-based authentication, then connect to the `/-/whoami` registry endpoint to find the username associated with the token, and print to standard output. + +If logged into a registry that uses Basic Auth, then simply print the `username` portion of the authentication string. + +### Configuration + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See Also + +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm adduser](/commands/npm-adduser) diff --git a/docs/lib/content/commands/npm.md b/docs/lib/content/commands/npm.md new file mode 100644 index 0000000000000..44dd0475d145e --- /dev/null +++ b/docs/lib/content/commands/npm.md @@ -0,0 +1,144 @@ +--- +title: npm +section: 1 +description: javascript package manager +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Version + +@VERSION@ + +### 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 conflicts intelligently. + +It is extremely configurable to support a variety of use cases. +Most commonly, you use it to publish, discover, install, and develop node programs. + +Run `npm help` to get a list of available commands. + +### Important + +npm comes preconfigured to use npm's public registry at https://registry.npmjs.org by default. +Use of the npm public registry is subject to terms of use available at https://docs.npmjs.com/policies/terms. + +You can configure npm to use any compatible registry you like, and even run your own registry. +Use of someone else's registry is governed by their terms of use. + +### Introduction + +You probably got npm because you want to install stuff. + +The very first thing you will most likely want to run in any node program is `npm install` to install its dependencies. + +You can also run `npm install blerg` to install the latest version of "blerg". Check out [`npm install`](/commands/npm-install) for more info. +It can do a lot of stuff. + +Use the `npm search` command to show everything that's available in the public registry. +Use `npm ls` to show everything you've installed. + +### Dependencies + +If a package lists a dependency using a git URL, npm will install that dependency using the [`git`](https://github.com/git-guides/install-git) command and will generate an error if it is not installed. + +If one of the packages npm tries to install is a native node module and requires compiling of C++ Code, npm will use [node-gyp](https://github.com/nodejs/node-gyp) for that task. +For a Unix system, [node-gyp](https://github.com/nodejs/node-gyp) needs Python, make and a buildchain like GCC. On Windows, Python and Microsoft Visual Studio C++ are needed. +For more information visit [the node-gyp repository](https://github.com/nodejs/node-gyp) and the [node-gyp Wiki](https://github.com/nodejs/node-gyp/wiki). + +### Directories + +See [`folders`](/configuring-npm/folders) to learn about where npm puts stuff. + +In particular, npm has two modes of operation: + +* local mode: + npm installs packages into the current project directory, which defaults to the current working directory. + Packages install to `./node_modules`, and bins to `./node_modules/.bin`. +* global mode: + npm installs packages into the install prefix at `$NPM_CONFIG_PREFIX/lib/node_modules` and bins to `$NPM_CONFIG_PREFIX/bin`. + +Local mode is the default. +Use `-g` or `--global` on any command to run in global mode instead. + +### Developer Usage + +If you're using npm to develop and publish your code, check out the following help topics: + +* json: + Make a package.json file. + See [`package.json`](/configuring-npm/package-json). +* link: + Links your current working code into Node's path, so that you don't have to reinstall every time you make a change. + Use [`npm link`](/commands/npm-link) to do this. +* install: + It's a good idea to install things if you don't need the symbolic link. + Especially, installing other peoples code from the registry is done via [`npm install`](/commands/npm-install) +* adduser: + Create an account or log in. + When you do this, npm will store credentials in the user config file. +* publish: + Use the [`npm publish`](/commands/npm-publish) command to upload your code to the registry. + +#### Configuration + +npm is extremely configurable. +It reads its configuration options from 5 places. + +* Command line switches: + Set a config with `--key val`. + All keys take a value, even if they are booleans (the config parser doesn't know what the options are at the time of parsing). + If you do not provide a value (`--key`) then the option is set to boolean `true`. +* Environment Variables: + Set any config by prefixing the name in an environment variable with `NPM_CONFIG_`. + For example, `export NPM_CONFIG_KEY=val`. +* User Configs: + The file at `$HOME/.npmrc` is an ini-formatted list of configs. + If present, it is parsed. + If the `userconfig` option is set in the cli or env, that file will be used instead. +* Global Configs: + The file found at `./etc/npmrc` (relative to the global prefix will be parsed if it is found. + See [`npm prefix`](/commands/npm-prefix) for more info on the global prefix. + If the `globalconfig` option is set in the cli, env, or user config, then that file is parsed instead. +* Defaults: + npm's default configuration options are defined in `lib/utils/config/definitions.js`. + These must not be changed. + +See [`config`](/using-npm/config) for much, much, more information. + +### Contributions + +Patches welcome! + +If you would like to help, but don't know what to work on, read the [contributing guidelines](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md) and check the issues list. + +### Bugs + +When you find issues, please report them: +<https://github.com/npm/cli/issues> + +Please be sure to follow the template and bug reporting guidelines. + +### Feature Requests + +Discuss new feature ideas on our discussion forum: + +* <https://github.com/orgs/community/discussions/categories/npm> + +Or suggest formal RFC proposals: + +* <https://github.com/npm/rfcs> + +### See Also + +* [npm help](/commands/npm-help) +* [package.json](/configuring-npm/package-json) +* [npmrc](/configuring-npm/npmrc) +* [npm config](/commands/npm-config) +* [npm install](/commands/npm-install) +* [npm prefix](/commands/npm-prefix) +* [npm publish](/commands/npm-publish) diff --git a/docs/lib/content/commands/npx.md b/docs/lib/content/commands/npx.md new file mode 100644 index 0000000000000..598cbece85f67 --- /dev/null +++ b/docs/lib/content/commands/npx.md @@ -0,0 +1,134 @@ +--- +title: npx +section: 1 +description: Run a command from a local or remote npm package +--- + +### Synopsis + +<!-- AUTOGENERATED USAGE DESCRIPTIONS --> + +### Description + +This command allows you to run an arbitrary command from an npm package (either one installed locally, or fetched remotely), in a similar context as running it via `npm run`. + +Run this command to execute a package's binary. Any options and arguments after the package name are passed directly to the executed command, not to npx itself. For example, `npx create-react-app my-app --template typescript` will pass `my-app` and `--template typescript` to the `create-react-app` command. To see what options a specific package accepts, consult that package's documentation (e.g., at npmjs.com or in its repository). + +Whatever packages are specified by the `--package` option will be provided in the `PATH` of the executed command, along with any locally installed package executables. +The `--package` option may be specified multiple times, to execute the supplied command in an environment where all specified packages are available. + +If any requested packages are not present in the local project dependencies, then they are installed to a folder in the npm cache, which is added to the `PATH` environment variable in the executed process. +A prompt is printed (which can be suppressed by providing either `--yes` or `--no`). + +Package names provided without a specifier will be matched with whatever version exists in the local project. +Package names with a specifier will only be considered a match if they have the exact same name and version as the local dependency. + +If no `-c` or `--call` option is provided, then the positional arguments are used to generate the command string. +If no `--package` options are provided, then npm will attempt to determine the executable name from the package specifier provided as the first positional argument according to the following heuristic: + +- If the package has a single entry in its `bin` field in `package.json`, or if all entries are aliases of the same command, then that command will be used. +- If the package has multiple `bin` entries, and one of them matches the unscoped portion of the `name` field, then that command will be used. +- If this does not result in exactly one option (either because there are no bin entries, or none of them match the `name` of the package), then + `npm exec` exits with an error. + +To run a binary _other than_ the named binary, specify one or more +`--package` options, which will prevent npm from inferring the package from the first command argument. + +### `npx` vs `npm exec` + +When run via the `npx` binary, all flags and options *must* be set prior to any positional arguments. +When run via `npm exec`, a double-hyphen `--` flag can be used to suppress npm's parsing of switches and options that should be sent to the executed command. + +For example: + +``` +$ npx foo@latest bar --package=@npmcli/foo +``` + +In this case, npm will resolve the `foo` package name, and run the following command: + +``` +$ foo bar --package=@npmcli/foo +``` + +Since the `--package` option comes _after_ the positional arguments, it is treated as an argument to the executed command. + +In contrast, due to npm's argument parsing logic, running this command is different: + +``` +$ npm exec foo@latest bar --package=@npmcli/foo +``` + +In this case, npm will parse the `--package` option first, resolving the +`@npmcli/foo` package. +Then, it will execute the following command in that context: + +``` +$ foo@latest bar +``` + +The double-hyphen character is recommended to explicitly tell npm to stop parsing command line options and switches. +The following command would thus be equivalent to the `npx` command above: + +``` +$ npm exec -- foo@latest bar --package=@npmcli/foo +``` + +### Examples + +Run the version of `tap` in the local dependencies, with the provided arguments: + +``` +$ npm exec -- tap --bail test/foo.js +$ npx tap --bail test/foo.js +``` + +Run a command _other than_ the command whose name matches the package name by specifying a `--package` option: + +``` +$ npm exec --package=foo -- bar --bar-argument +# ~ or ~ +$ npx --package=foo bar --bar-argument +``` + +Run an arbitrary shell script, in the context of the current project: + +``` +$ npm x -c 'eslint && say "hooray, lint passed"' +$ npx -c 'eslint && say "hooray, lint passed"' +``` + +### Compatibility with Older npx Versions + +The `npx` binary was rewritten in npm v7.0.0, and the standalone `npx` package deprecated at that time. + `npx` uses the `npm exec` command instead of a separate argument parser and install process, with some affordances to maintain backwards compatibility with the arguments it accepted in previous versions. + +This resulted in some shifts in its functionality: + +- Any `npm` config value may be provided. +- To prevent security and user-experience problems from mistyping package names, `npx` prompts before installing anything. +Suppress this prompt with the `-y` or `--yes` option. +- The `--no-install` option is deprecated, and will be converted to `--no`. +- Shell fallback functionality is removed, as it is not advisable. +- The `-p` argument is a shorthand for `--parseable` in npm, but shorthand for `--package` in npx. +This is maintained, but only for the `npx` executable. +- The `--ignore-existing` option is removed. +Locally installed bins are always present in the executed process `PATH`. +- The `--npm` option is removed. + `npx` will always use the `npm` it ships with. +- The `--node-arg` and `-n` options have been removed. +Use [`NODE_OPTIONS`](https://nodejs.org/api/cli.html#node_optionsoptions) instead: e.g., + `NODE_OPTIONS="--trace-warnings --trace-exit" npx foo --random=true` +- The `--always-spawn` option is redundant, and thus removed. +- The `--shell` option is replaced with `--script-shell`, but maintained in the `npx` executable for backwards compatibility. + +### See Also + +* [npm run](/commands/npm-run) +* [npm scripts](/using-npm/scripts) +* [npm test](/commands/npm-test) +* [npm start](/commands/npm-start) +* [npm restart](/commands/npm-restart) +* [npm stop](/commands/npm-stop) +* [npm config](/commands/npm-config) +* [npm exec](/commands/npm-exec) diff --git a/docs/lib/content/configuring-npm/folders.md b/docs/lib/content/configuring-npm/folders.md new file mode 100644 index 0000000000000..56459c86930ba --- /dev/null +++ b/docs/lib/content/configuring-npm/folders.md @@ -0,0 +1,172 @@ +--- +title: folders +section: 5 +description: Folder Structures Used by npm +--- + +### Description + +npm puts various things on your computer. +That's its job. + +This document will tell you what it puts where. + +#### tl;dr + +* Local install (default): puts stuff in `./node_modules` of the current package root. +* Global install (with `-g`): puts stuff in /usr/local or wherever node is installed. +* Install it **locally** if you're going to `require()` it. +* Install it **globally** if you're going to run it on the command line. +* If you need both, then install it in both places, or use `npm link`. + +#### prefix Configuration + +The [`prefix` config](/using-npm/config#prefix) defaults to the location where node is installed. +On most systems, this is `/usr/local`. +On Windows, it's `%AppData%\npm`. +On Unix systems, it's one level up, since node is typically installed at `{prefix}/bin/node` rather than `{prefix}/node.exe`. + +When the `global` flag is set, npm installs things into this prefix. +When it is not set, it uses the root of the current package, or the current working directory if not in a package already. + +#### Node Modules + +Packages are dropped into the `node_modules` folder under the `prefix`. +When installing locally, this means that you can `require("packagename")` to load its main module, or `require("packagename/lib/path/to/sub/module")` to load other modules. + +Global installs on Unix systems go to `{prefix}/lib/node_modules`. +Global installs on Windows go to `{prefix}/node_modules` (that is, no `lib` folder.) + +Scoped packages are installed the same way, except they are grouped together in a sub-folder of the relevant `node_modules` folder with the name of that scope prefix by the @ symbol, e.g. `npm install @myorg/package` would place the package in `{prefix}/node_modules/@myorg/package`. +See [`scope`](/using-npm/scope) for more details. + +If you wish to `require()` a package, then install it locally. + +#### Executables + +When in global mode, executables are linked into `{prefix}/bin` on Unix, or directly into `{prefix}` on Windows. +Ensure that path is in your terminal's `PATH` environment to run them. + +When in local mode, executables are linked into `./node_modules/.bin` so that they can be made available to scripts run through npm. +(For example, so that a test runner will be in the path when you run `npm test`.) + +#### Man Pages + +When in global mode, man pages are linked into `{prefix}/share/man`. + +When in local mode, man pages are not installed. + +Man pages are not installed on Windows systems. + +#### Cache + +See [`npm cache`](/commands/npm-cache). +Cache files are stored in `~/.npm` on Posix, or `%LocalAppData%/npm-cache` on Windows. + +This is controlled by the [`cache` config](/using-npm/config#cache) param. + +### More Information + +When installing locally, npm first tries to find an appropriate `prefix` folder. +This is so that `npm install foo@1.2.3` will install to the sensible root of your package, even if you happen to have `cd`ed into some other folder. + +Starting at the $PWD, npm will walk up the folder tree checking for a folder that contains either a `package.json` file, or a `node_modules` folder. +If such a thing is found, then that is treated as the effective "current directory" for the purpose of running npm commands. +(This behavior is inspired by and similar to git's .git-folder seeking logic when running git commands in a working dir.) + +If no package root is found, then the current folder is used. + +When you run `npm install foo@1.2.3`, then the package is loaded into the cache, and then unpacked into `./node_modules/foo`. +Then, any of foo's dependencies are similarly unpacked into `./node_modules/foo/node_modules/...`. + +Any bin files are symlinked to `./node_modules/.bin/`, so that they may be found by npm scripts when necessary. + +#### Global Installation + +If the [`global` config](/using-npm/config#global) is set to true, then npm will install packages "globally". + +For global installation, packages are installed roughly the same way, but using the folders described above. + +#### Cycles, Conflicts, and Folder Parsimony + +Cycles are handled using the property of node's module system that it walks up the directories looking for `node_modules` folders. +So, at every stage, if a package is already installed in an ancestor `node_modules` folder, then it is not installed at the current location. + +Consider the case above, where `foo -> bar -> baz`. +Imagine if, in addition to that, baz depended on bar, so you'd have: +`foo -> bar -> baz -> bar -> baz ...`. +However, since the folder structure is: `foo/node_modules/bar/node_modules/baz`, there's no need to put another copy of bar into `.../baz/node_modules`, since when baz calls `require("bar")`, it will get the copy that is installed in `foo/node_modules/bar`. + +This shortcut is only used if the exact same version would be installed in multiple nested `node_modules` folders. +It is still possible to have `a/node_modules/b/node_modules/a` if the two "a" packages are different versions. +However, without repeating the exact same package multiple times, an infinite regress will always be prevented. + +Another optimization can be made by installing dependencies at the highest level possible, below the localized "target" folder (hoisting). +Since version 3, npm hoists dependencies by default. + +#### Example + +Consider this dependency graph: + +```bash +foo ++-- blerg@1.2.5 ++-- bar@1.2.3 +| +-- blerg@1.x (latest=1.3.7) +| +-- baz@2.x +| | `-- quux@3.x +| | `-- bar@1.2.3 (cycle) +| `-- asdf@* +`-- baz@1.2.3 + `-- quux@3.x + `-- bar +``` + +In this case, we might expect a folder structure like this (with all dependencies hoisted to the highest level possible): + +```bash +foo ++-- node_modules + +-- blerg (1.2.5) <---[A] + +-- bar (1.2.3) <---[B] + | +-- node_modules + | +-- baz (2.0.2) <---[C] + +-- asdf (2.3.4) + +-- baz (1.2.3) <---[D] + +-- quux (3.2.0) <---[E] +``` + +Since foo depends directly on `bar@1.2.3` and `baz@1.2.3`, those are installed in foo's `node_modules` folder. + +Even though the latest copy of blerg is 1.3.7, foo has a specific dependency on version 1.2.5. +So, that gets installed at [A]. +Since the parent installation of blerg satisfies bar's dependency on `blerg@1.x`, it does not install another copy under [B]. + +Bar [B] also has dependencies on baz and asdf. +Because it depends on `baz@2.x`, it cannot re-use the `baz@1.2.3` installed in the parent `node_modules` folder [D], and must install its own copy [C]. +In order to minimize duplication, npm hoists dependencies to the top level by default, so asdf is installed under [A]. + +Underneath bar, the `baz -> quux -> bar` dependency creates a cycle. +However, because bar is already in quux's ancestry [B], it does not unpack another copy of bar into that folder. +Likewise, quux's [E] folder tree is empty, because its dependency on bar is satisfied by the parent folder copy installed at [B]. + +For a graphical breakdown of what is installed where, use `npm ls`. + +#### Publishing + +Upon publishing, npm will look in the `node_modules` folder. +If any of the items there are not in the `bundleDependencies` array, then they will not be included in the package tarball. + +This allows a package maintainer to install all of their dependencies (and dev dependencies) locally, but only re-publish those items that cannot be found elsewhere. +See [`package.json`](/configuring-npm/package-json) for more information. + +### See also + +* [package.json](/configuring-npm/package-json) +* [npm install](/commands/npm-install) +* [npm pack](/commands/npm-pack) +* [npm cache](/commands/npm-cache) +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [config](/using-npm/config) +* [npm publish](/commands/npm-publish) diff --git a/docs/lib/content/configuring-npm/install.md b/docs/lib/content/configuring-npm/install.md new file mode 100644 index 0000000000000..1d7e7b80e6c22 --- /dev/null +++ b/docs/lib/content/configuring-npm/install.md @@ -0,0 +1,53 @@ +--- +title: install +section: 5 +description: Download and install node and npm +--- + +### Description + +To publish and install packages to and from the public npm registry, you must install Node.js and the npm command line interface using either a Node version manager or a Node installer. +**We strongly recommend using a Node version manager to install Node.js and npm.** We do not recommend using a +Node installer, since the Node installation process installs npm in a directory with local permissions and can cause permissions errors when you run npm packages globally. + +### Overview + +- [Checking your version of npm and Node.js](#checking-your-version-of-npm-and-nodejs) +- [Using a Node version manager to install Node.js and npm](#using-a-node-version-manager-to-install-nodejs-and-npm) +- [Using a Node installer to install Node.js and npm](#using-a-node-installer-to-install-nodejs-and-npm) + +### Checking your version of npm and Node.js + +To see if you already have Node.js and npm installed and check the installed version, run the following commands: + +``` +node -v +npm -v +``` + +### Using a Node version manager to install Node.js and npm + +Node version managers allow you to install and switch between multiple versions of Node.js and npm on your system so you can test your applications on multiple versions of npm to ensure they work for users on different versions. +You can [search for them on GitHub](https://github.com/search?q=node+version+manager+archived%3Afalse&type=repositories&ref=advsearch). + +### Using a Node installer to install Node.js and npm + +If you are unable to use a Node version manager, you can use a Node installer to install both Node.js and npm on your system. + +* [Node.js installer](https://nodejs.org/en/download/) +* [NodeSource installer](https://github.com/nodesource/distributions). +If you use Linux, we recommend that you use a NodeSource installer. + +#### macOS or Windows Node installers + +If you're using macOS or Windows, use one of the installers from the [Node.js download page](https://nodejs.org/en/download/). +Be sure to install the version labeled **LTS**. Other versions have not yet been tested with npm. + +#### Linux or other operating systems Node installers + +If you're using Linux or another operating system, use one of the following installers: + +- [NodeSource installer](https://github.com/nodesource/distributions) (recommended) +- One of the installers on the [Node.js download page](https://nodejs.org/en/download/) + +Or see [this page](https://nodejs.org/en/download/package-manager/) to install npm for Linux in the way many Linux developers prefer. diff --git a/docs/lib/content/configuring-npm/npm-shrinkwrap-json.md b/docs/lib/content/configuring-npm/npm-shrinkwrap-json.md new file mode 100644 index 0000000000000..4ea5e4dc20b1d --- /dev/null +++ b/docs/lib/content/configuring-npm/npm-shrinkwrap-json.md @@ -0,0 +1,25 @@ +--- +title: npm-shrinkwrap.json +section: 5 +description: A publishable lockfile +--- + +### Description + +`npm-shrinkwrap.json` is a file created by [`npm shrinkwrap`](/commands/npm-shrinkwrap). +It is identical to `package-lock.json`, with one major caveat: Unlike `package-lock.json`, +`npm-shrinkwrap.json` may be included when publishing a package. + +The recommended use-case for `npm-shrinkwrap.json` is applications deployed through the publishing process on the registry: for example, daemons and command-line tools intended as global installs or `devDependencies`. +It's strongly discouraged for library authors to publish this file, since that would prevent end users from having control over transitive dependency updates. + +If both `package-lock.json` and `npm-shrinkwrap.json` are present in a package root, `npm-shrinkwrap.json` will be preferred over the `package-lock.json` file. + +For full details and description of the `npm-shrinkwrap.json` file format, refer to the manual page for [package-lock.json](/configuring-npm/package-lock-json). + +### See also + +* [npm shrinkwrap](/commands/npm-shrinkwrap) +* [package-lock.json](/configuring-npm/package-lock-json) +* [package.json](/configuring-npm/package-json) +* [npm install](/commands/npm-install) diff --git a/docs/lib/content/configuring-npm/npmrc.md b/docs/lib/content/configuring-npm/npmrc.md new file mode 100644 index 0000000000000..41d7c5e462c51 --- /dev/null +++ b/docs/lib/content/configuring-npm/npmrc.md @@ -0,0 +1,133 @@ +--- +title: npmrc +section: 5 +description: The npm config files +--- + +### Description + +npm gets its config settings from the command line, environment variables, and `npmrc` files. + +The `npm config` command can be used to update and edit the contents of the user and global npmrc files. + +For a list of available configuration options, see [config](/using-npm/config). + +### Files + +The four relevant files are: + +* per-project config file (`/path/to/my/project/.npmrc`) +* per-user config file (`~/.npmrc`) +* global config file (`$PREFIX/etc/npmrc`) +* npm builtin config file (`/path/to/npm/npmrc`) + +All npm config files are an ini-formatted list of `key = value` parameters. +Environment variables can be replaced using `${VARIABLE_NAME}`. +By default if the variable is not defined, it is left unreplaced. +By adding `?` after variable name they can be forced to evaluate to an empty string instead. +For example: + +```bash +cache = ${HOME}/.npm-packages +node-options = "${NODE_OPTIONS?} --use-system-ca" +``` + +Each of these files is loaded, and config options are resolved in priority order. +For example, a setting in the userconfig file would override the setting in the globalconfig file. + +Array values are specified by adding "[]" after the key name. +For example: + +```bash +key[] = "first value" +key[] = "second value" +``` + +#### Comments + +Lines in `.npmrc` files are interpreted as comments when they begin with a +`;` or `#` character. +`.npmrc` files are parsed by +[npm/ini](https://github.com/npm/ini), which specifies this comment syntax. + +For example: + +```bash +# last modified: 01 Jan 2016 +; Set a new registry for a scoped package +@myscope:registry=https://mycustomregistry.example.org +``` + +#### Per-project config file + +When working locally in a project, a `.npmrc` file in the root of the project (ie, a sibling of `node_modules` and `package.json`) will set config values specific to this project. + +Note that this only applies to the root of the project that you're running npm in. +It has no effect when your module is published. +For example, you can't publish a module that forces itself to install globally, or in a different location. + +Additionally, this file is not read in global mode, such as when running `npm install -g`. + +#### Per-user config file + +`$HOME/.npmrc` (or the `userconfig` param, if set in the environment or on the command line) + +#### Global config file + +`$PREFIX/etc/npmrc` (or the `globalconfig` param, if set above): This file is an ini-file formatted list of `key = value` parameters. +Environment variables can be replaced as above. + +#### Built-in config file + +`path/to/npm/itself/npmrc` + +This is an unchangeable "builtin" configuration file that npm keeps consistent across updates. +Set fields in here using the `./configure` script that comes with npm. +This is primarily for distribution maintainers to override default configs in a standard and consistent manner. + +### Auth related configuration + +The settings `_auth`, `_authToken`, `username`, `_password`, `certfile`, and `keyfile` must all be scoped to a specific registry. +This ensures that `npm` will never send credentials to the wrong host. + +The full list is: + - `_auth` (base64 authentication string) + - `_authToken` (authentication token) + - `username` + - `_password` + - `email` + - `cafile` (path to certificate authority file) + - `certfile` (path to certificate file) + - `keyfile` (path to key file) + +In order to scope these values, they must be prefixed by a URI fragment. +If the credential is meant for any request to a registry on a single host, the scope may look like `//registry.npmjs.org/:`. +If it must be scoped to a specific path on the host that path may also be provided, such as +`//my-custom-registry.org/unique/path:`. + +``` +; bad config +_authToken=MYTOKEN + +; good config +@myorg:registry=https://somewhere-else.com/myorg +@another:registry=https://somewhere-else.com/another +//registry.npmjs.org/:_authToken=MYTOKEN + +; would apply to both @myorg and @another +//somewhere-else.com/:_authToken=MYTOKEN + +; would apply only to @myorg +//somewhere-else.com/myorg/:_authToken=MYTOKEN1 + +; would apply only to @another +//somewhere-else.com/another/:_authToken=MYTOKEN2 +``` + +### See also + +* [npm folders](/configuring-npm/folders) +* [npm config](/commands/npm-config) +* [config](/using-npm/config) +* [package.json](/configuring-npm/package-json) +* [npm](/commands/npm) diff --git a/docs/lib/content/configuring-npm/package-json.md b/docs/lib/content/configuring-npm/package-json.md new file mode 100644 index 0000000000000..27aeaf9f22176 --- /dev/null +++ b/docs/lib/content/configuring-npm/package-json.md @@ -0,0 +1,1195 @@ +--- +title: package.json +section: 5 +description: Specifics of npm's package.json handling +--- + +### Description + +This document is all you need to know about what's required in your package.json file. +It must be actual JSON, not just a JavaScript object literal. + +A lot of the behavior described in this document is affected by the config settings described in [`config`](/using-npm/config). + +### name + +If you plan to publish your package, the *most* important things in your package.json are the name and version fields as they will be required. +The name and version together form an identifier that is assumed to be completely unique. +Changes to the package should come along with changes to the version. +If you don't plan to publish your package, the name and version fields are optional. + +The name is what your thing is called. + +Some rules: + +* The name must be less than or equal to 214 characters. + This includes the scope for scoped packages. +* The names of scoped packages can begin with a dot or an underscore. + This is not permitted without a scope. +* New packages must not have uppercase letters in the name. +* The name ends up being part of a URL, an argument on the command line, and a folder name. + Therefore, the name can't contain any non-URL-safe characters. + +Some tips: + +* Don't use the same name as a core Node module. +* Don't put "js" or "node" in the name. + It's assumed that it's js, since you're writing a package.json file, and you can specify the engine using the "[engines](#engines)" field. + (See below.) +* The name will probably be passed as an argument to require(), so it should be something short, but also reasonably descriptive. +* You may want to check the npm registry to see if there's something by that name already, before you get too attached to it. + <https://www.npmjs.com/> + +A name can be optionally prefixed by a scope, e.g. `@npm/example`. +See [`scope`](/using-npm/scope) for more detail. + +### version + +If you plan to publish your package, the *most* important things in your package.json are the name and version fields as they will be required. +The name and version together form an identifier that is assumed to be completely unique. +Changes to the package should come along with changes to the version. +If you don't plan to publish your package, the name and version fields are optional. + +Version must be parseable by [node-semver](https://github.com/npm/node-semver), which is bundled with npm as a dependency. +(`npm install semver` to use it yourself.) + +### description + +Put a description in it. +It's a string. +This helps people discover your package, as it's listed in `npm search`. + +### keywords + +Put keywords in it. +It's an array of strings. +This helps people discover your package as it's listed in `npm search`. + +Example: + +```json +"keywords": [ + "node", + "javascript", + "npm" +] +``` + +### homepage + +The URL to the project homepage. + +Example: + +```json +"homepage": "https://github.com/npm/example#readme" +``` + +### bugs + +The URL to your project's issue tracker and / or the email address to which issues should be reported. +These are helpful for people who encounter issues with your package. + +It should look like this: + +```json +{ + "bugs": { + "url": "https://github.com/npm/example/issues", + "email": "example@npmjs.com" + } +} +``` + +You can specify either one or both values. +If you want to provide only a URL, you can specify the value for "bugs" as a simple string instead of an object. + +If a URL is provided, it will be used by the `npm bugs` command. + +### license + +You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you're placing on it. + +If you're using a common license such as BSD-2-Clause or MIT, add a current SPDX license identifier for the license you're using, like this: + +```json +{ + "license" : "BSD-3-Clause" +} +``` + +You can check [the full list of SPDX license IDs](https://spdx.org/licenses/). +Ideally, you should pick one that is [OSI](https://opensource.org/licenses/) approved. + +If your package is licensed under multiple common licenses, use an [SPDX license expression syntax version 2.0 string](https://spdx.dev/specifications/), like this: + +```json +{ + "license" : "(ISC OR GPL-3.0)" +} +``` +If you are using a license that hasn't been assigned an SPDX identifier, or if you are using a custom license, use a string value like this one: + +```json +{ + "license" : "SEE LICENSE IN <filename>" +} +``` +Then include a file named `<filename>` at the top level of the package. + +Some old packages used license objects or a "licenses" property containing an array of license objects: + +```json +// Not valid metadata +{ + "license" : { + "type" : "ISC", + "url" : "https://opensource.org/licenses/ISC" + } +} + +// Not valid metadata +{ + "licenses" : [ + { + "type": "MIT", + "url": "https://www.opensource.org/licenses/mit-license.php" + }, + { + "type": "Apache-2.0", + "url": "https://opensource.org/licenses/apache2.0.php" + } + ] +} +``` + +Those styles are now deprecated. +Instead, use SPDX expressions, like this: + +```json +{ + "license": "ISC" +} +``` + +```json +{ + "license": "(MIT OR Apache-2.0)" +} +``` + +Finally, if you do not wish to grant others the right to use a private or unpublished package under any terms: + +```json +{ + "license": "UNLICENSED" +} +``` + +Consider also setting `"private": true` to prevent accidental publication. + +### people fields: author, contributors + +The "author" is one person. +"contributors" is an array of people. +A "person" is an object with a "name" field and optionally "url" and "email", like this: + +```json +{ + "name" : "Barney Rubble", + "email" : "barney@npmjs.com", + "url" : "http://barnyrubble.npmjs.com/" +} +``` + +Or you can shorten that all into a single string, and npm will parse it for you: + +```json +{ + "author": "Barney Rubble <barney@npmjs.com> (http://barnyrubble.npmjs.com/)" +} +``` + +Both email and url are optional either way. + +npm also sets a top-level "maintainers" field with your npm user info. + +### funding + +You can specify an object containing a URL that provides up-to-date information about ways to help fund development of your package, a string URL, or an array of objects and string URLs: + +```json +{ + "funding": { + "type" : "individual", + "url" : "http://npmjs.com/donate" + } +} +``` + +```json +{ + "funding": { + "type" : "patreon", + "url" : "https://www.patreon.com/user" + } +} +``` + +```json +{ + "funding": "http://npmjs.com/donate" +} +``` + +```json +{ + "funding": [ + { + "type" : "individual", + "url" : "http://npmjs.com/donate" + }, + "http://npmjs.com/donate-also", + { + "type" : "patreon", + "url" : "https://www.patreon.com/user" + } + ] +} +``` + +Users can use the `npm fund` subcommand to list the `funding` URLs of all dependencies of their project, direct and indirect. +A shortcut to visit each funding URL is also available when providing the project name such as: +`npm fund <projectname>` (when there are multiple URLs, the first one will be visited) + +### files + +The optional `files` field is an array of file patterns that describes the entries to be included when your package is installed as a dependency. +File patterns follow a similar syntax to `.gitignore`, but reversed: including a file, directory, or glob pattern (`*`, `**/*`, and such) will make it so that file is included in the tarball when it's packed. +Omitting the field will make it default to `["*"]`, which means it will include all files. + +Some special files and directories are also included or excluded regardless of whether they exist in the `files` array (see below). + +You can also provide a `.npmignore` file in the root of your package or in subdirectories, which will keep files from being included. +At the root of your package it will not override the "files" field, but in subdirectories it will. +The `.npmignore` file works just like a `.gitignore`. +If there is a `.gitignore` file, and `.npmignore` is missing, `.gitignore`'s contents will be used instead. + +Certain files are always included, regardless of settings: + +* `package.json` +* `README` +* `LICENSE` / `LICENCE` +* The file in the "main" field +* The file(s) in the "bin" field + +`README` & `LICENSE` can have any case and extension. + +Some files are always ignored by default: + +* `*.orig` +* `.*.swp` +* `.DS_Store` +* `._*` +* `.git` +* `.hg` +* `.lock-wscript` +* `.npmrc` +* `.svn` +* `.wafpickle-N` +* `CVS` +* `config.gypi` +* `node_modules` +* `npm-debug.log` +* `package-lock.json` (use [`npm-shrinkwrap.json`](/configuring-npm/npm-shrinkwrap-json) if you wish it to be published) +* `pnpm-lock.yaml` +* `yarn.lock` +* `bun.lockb` + +Most of these ignored files can be included specifically if included in the `files` globs. +Exceptions to this are: + +* `.git` +* `.npmrc` +* `node_modules` +* `package-lock.json` +* `pnpm-lock.yaml` +* `yarn.lock` +* `bun.lockb` + +These cannot be included. + +### exports + +The "exports" provides a modern alternative to "main" allowing multiple entry points to be defined, conditional entry resolution support between environments, and preventing any other entry points besides those defined in "exports". This encapsulation allows module authors to clearly define the public interface for their package. +For more details see the [node.js documentation on package entry points](https://nodejs.org/api/packages.html#package-entry-points) + +### main + +The main field is a module ID that is the primary entry point to your program. +That is, if your package is named `foo`, and a user installs it, and then does `require("foo")`, then your main module's exports object will be returned. + +This should be a module relative to the root of your package folder. + +For most modules, it makes the most sense to have a main script and often not much else. + +If `main` is not set, it defaults to `index.js` in the package's root folder. + +### type + +The `type` field defines how Node.js should interpret `.js` files in your package. This field is not used by npm. + +See the [Node.js documentation on the type field](https://nodejs.org/api/packages.html#type) for more information. + +### browser + +If your module is meant to be used client-side the browser field should be used instead of the main field. +This is helpful to hint users that it might rely on primitives that aren't available in Node.js modules. +(e.g. `window`) + +### bin + +A lot of packages have one or more executable files that they'd like to install into the PATH. npm makes this pretty easy (in fact, it uses this feature to install the "npm" executable.) + +To use this, supply a `bin` field in your package.json which is a map of command name to local file name. +When this package is installed globally, that file will be either linked inside the global bins directory or a cmd (Windows Command File) will be created which executes the specified file in the `bin` field, so it is available to run by `name` or `name.cmd` (on Windows PowerShell). +When this package is installed as a dependency in another package, the file will be linked where it will be available to that package either directly by `npm exec` or by name in other scripts when invoking them via `npm run`. + + +For example, myapp could have this: + +```json +{ + "bin": { + "myapp": "bin/cli.js" + } +} +``` + +So, when you install myapp, in case of unix-like OS it'll create a symlink from the `cli.js` script to `/usr/local/bin/myapp` and in case of windows it will create a cmd file usually at `C:\Users\{Username}\AppData\Roaming\npm\myapp.cmd` which runs the `cli.js` script. + +If you have a single executable, and its name should be the name of the package, then you can just supply it as a string. +For example: + +```json +{ + "name": "my-program", + "version": "1.2.5", + "bin": "path/to/program" +} +``` + +would be the same as this: + +```json +{ + "name": "my-program", + "version": "1.2.5", + "bin": { + "my-program": "path/to/program" + } +} +``` + +Please make sure that your file(s) referenced in `bin` starts with `#!/usr/bin/env node`; otherwise, the scripts are started without the node executable! + +Note that you can also set the executable files using [directories.bin](#directoriesbin). + +See [folders](/configuring-npm/folders#executables) for more info on executables. + +### man + +Specify either a single file or an array of filenames to put in place for the `man` program to find. + +If only a single file is provided, then it's installed such that it is the result from `man <pkgname>`, regardless of its actual filename. +For example: + +```json +{ + "name": "foo", + "version": "1.2.3", + "description": "A packaged foo fooer for fooing foos", + "main": "foo.js", + "man": "./man/doc.1" +} +``` + +would link the `./man/doc.1` file in such that it is the target for `man foo` + +If the filename doesn't start with the package name, then it's prefixed. +So, this: + +```json +{ + "name": "foo", + "version": "1.2.3", + "description": "A packaged foo fooer for fooing foos", + "main": "foo.js", + "man": [ + "./man/foo.1", + "./man/bar.1" + ] +} +``` + +will create files to do `man foo` and `man foo-bar`. + +Man files must end with a number, and optionally a `.gz` suffix if they are compressed. +The number dictates which man section the file is installed into. + +```json +{ + "name": "foo", + "version": "1.2.3", + "description": "A packaged foo fooer for fooing foos", + "main": "foo.js", + "man": [ + "./man/foo.1", + "./man/foo.2" + ] +} +``` + +will create entries for `man foo` and `man 2 foo` + +### directories + +The CommonJS [Packages](http://wiki.commonjs.org/wiki/Packages/1.0) spec details a few ways that you can indicate the structure of your package using a `directories` object. +If you look at [npm's package.json](https://registry.npmjs.org/npm/latest), you'll see that it has directories for doc, lib, and man. + +In the future, this information may be used in other creative ways. + +#### directories.bin + +If you specify a `bin` directory in `directories.bin`, all the files in that folder will be added. + +Because of the way the `bin` directive works, specifying both a `bin` path and setting `directories.bin` is an error. +If you want to specify individual files, use `bin`, and for all the files in an existing `bin` directory, use `directories.bin`. + +#### directories.man + +A folder that is full of man pages. +Sugar to generate a "man" array by walking the folder. + +### repository + +Specify the place where your code lives. +This is helpful for people who want to contribute. +If the git repo is on GitHub, then the `npm repo` command will be able to find you. + +Do it like this: + +```json +{ + "repository": { + "type": "git", + "url": "git+https://github.com/npm/cli.git" + } +} +``` + +The URL should be a publicly available (perhaps read-only) URL that can be handed directly to a VCS program without any modification. +It should not be a URL to an html project page that you put in your browser. +It's for computers. + +For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same shortcut syntax you use for `npm install`: + +```json +{ + "repository": "npm/example", + + "repository": "github:npm/example", + + "repository": "gist:11081aaa281", + + "repository": "bitbucket:user/repo", + + "repository": "gitlab:user/repo" +} +``` + +**Note on normalization:** When you publish a package, npm normalizes the `repository` field to the full object format with a `url` property. If you use a shorthand format (like `"npm/example"`), you'll see a warning during `npm publish` indicating that the field was auto-corrected. While the shorthand format currently works, it's recommended to use the full object format in your `package.json` to avoid warnings and ensure future compatibility: + +```json +{ + "repository": { + "type": "git", + "url": "git+https://github.com/npm/example.git" + } +} +``` + +You can run `npm pkg fix` to automatically convert shorthand formats to the normalized object format. + +If the `package.json` for your package is not in the root directory (for example if it is part of a monorepo), you can specify the directory in which it lives: + +```json +{ + "repository": { + "type": "git", + "url": "git+https://github.com/npm/cli.git", + "directory": "workspaces/libnpmpublish" + } +} +``` + +### scripts + +The "scripts" property is a dictionary containing script commands that are run at various times in the lifecycle of your package. +The key is the lifecycle event, and the value is the command to run at that point. + +See [`scripts`](/using-npm/scripts) to find out more about writing package scripts. + +### gypfile + +If you have a binding.gyp file in the root of your package and you have not defined your own `install` or `preinstall` scripts, npm will default to building your module using node-gyp. + +To prevent npm from automatically building your module with node-gyp, set `gypfile` to `false`: + +```json +{ + "gypfile": false +} +``` + +This is useful for packages that include native addons but want to handle the build process differently, or packages that have a binding.gyp file but should not be built as a native addon. + +### config + +A "config" object can be used to set configuration parameters used in package scripts that persist across upgrades. +For instance, if a package had the following: + +```json +{ + "name": "foo", + "config": { + "port": "8080" + } +} +``` + +It could also have a "start" script that referenced the `npm_package_config_port` environment variable. + +### dependencies + +Dependencies are specified in a simple object that maps a package name to a version range. +The version range is a string which has one or more space-separated descriptors. +Dependencies can also be identified with a tarball or git URL. + +**Please do not put test harnesses or transpilers or other "development" time tools in your `dependencies` object.** +See `devDependencies`, below. + +See [semver](https://github.com/npm/node-semver#versions) for more details about specifying version ranges. + +* `version` Must match `version` exactly +* `>version` Must be greater than `version` +* `>=version` etc +* `<version` +* `<=version` +* `~version` "Approximately equivalent to version" See [semver](https://github.com/npm/node-semver#versions) +* `^version` "Compatible with version" See [semver](https://github.com/npm/node-semver#versions) +* `1.2.x` 1.2.0, 1.2.1, etc., but not 1.3.0 +* `http://...` See 'URLs as Dependencies' below +* `*` Matches any version +* `""` (just an empty string) Same as `*` +* `version1 - version2` Same as `>=version1 <=version2`. +* `range1 || range2` Passes if either range1 or range2 are satisfied. +* `git...` See 'Git URLs as Dependencies' below +* `user/repo` See 'GitHub URLs' below +* `tag` A specific version tagged and published as `tag` See [`npm dist-tag`](/commands/npm-dist-tag) +* `path/path/path` See [Local Paths](#local-paths) below +* `npm:@scope/pkg@version` Custom alias for a package See [`package-spec`](/using-npm/package-spec#aliases) + +For example, these are all valid: + +```json +{ + "dependencies": { + "foo": "1.0.0 - 2.9999.9999", + "bar": ">=1.0.2 <2.1.2", + "baz": ">1.0.2 <=2.3.4", + "boo": "2.0.1", + "qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0", + "asd": "http://npmjs.com/example.tar.gz", + "til": "~1.2", + "elf": "~1.2.3", + "two": "2.x", + "thr": "3.3.x", + "lat": "latest", + "dyl": "file:../dyl", + "kpg": "npm:pkg@1.0.0" + } +} +``` + +#### URLs as Dependencies + +You may specify a tarball URL in place of a version range. + +This tarball will be downloaded and installed locally to your package at install time. + +#### Git URLs as Dependencies + +Git URLs are of the form: + +```bash +<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>] +``` + +`<protocol>` is one of `git`, `git+ssh`, `git+http`, `git+https`, or `git+file`. + +If `#<commit-ish>` is provided, it will be used to clone exactly that commit. +If the commit-ish has the format `#semver:<semver>`, `<semver>` can be any valid semver range or exact version, and npm will look for any tags or refs matching that range in the remote repository, much as it would for a registry dependency. +If neither `#<commit-ish>` or `#semver:<semver>` is specified, then the default branch is used. + +Examples: + +```bash +git+ssh://git@github.com:npm/cli.git#v1.0.27 +git+ssh://git@github.com:npm/cli#semver:^5.0 +git+https://isaacs@github.com/npm/cli.git +git://github.com/npm/cli.git#v1.0.27 +``` + +When installing from a `git` repository, the presence of certain fields in the `package.json` will cause npm to believe it needs to perform a build. +To do so your repository will be cloned into a temporary directory, all of its deps installed, relevant scripts run, and the resulting directory packed and installed. + +This flow will occur if your git dependency uses `workspaces`, or if any of the following scripts are present: + +* `build` +* `prepare` +* `prepack` +* `preinstall` +* `install` +* `postinstall` + +If your git repository includes pre-built artifacts, you will likely want to make sure that none of the above scripts are defined, or your dependency will be rebuilt for every installation. + +#### GitHub URLs + +As of version 1.1.65, you can refer to GitHub URLs as just "foo": +"user/foo-project". Just as with git URLs, a `commit-ish` suffix can be included. +For example: + +```json +{ + "name": "foo", + "version": "0.0.0", + "dependencies": { + "express": "expressjs/express", + "mocha": "mochajs/mocha#4727d357ea", + "module": "npm/example-github-repo#feature\/branch" + } +} +``` + +#### Local Paths + +As of version 2.0.0 you can provide a path to a local directory that contains a package. +Local paths can be saved using `npm install -S` or `npm install --save`, using any of these forms: + +```bash +../foo/bar +~/foo/bar +./foo/bar +/foo/bar +``` + +in which case they will be normalized to a relative path and added to your `package.json`. +For example: + +```json +{ + "name": "baz", + "dependencies": { + "bar": "file:../foo/bar" + } +} +``` + +This feature is helpful for local offline development and creating tests that require npm installing where you don't want to hit an external server, but should not be used when publishing your package to the public registry. + +*note*: Packages linked by local path will not have their own dependencies installed when `npm install` is run. +You must run `npm install` from inside the local path itself. + +### devDependencies + +If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build the external test or documentation framework that you use. + +In this case, it's best to map these additional items in a `devDependencies` object. + +These things will be installed when doing `npm link` or `npm install` from the root of a package, and can be managed like any other npm configuration param. +See [`config`](/using-npm/config) for more on the topic. + +For build steps that are not platform-specific, such as compiling CoffeeScript or other languages to JavaScript, use the `prepare` script to do this, and make the required package a devDependency. + +For example: + +```json +{ + "name": "@npm/ethopia-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1.2.3", + "devDependencies": { + "coffee-script": "~1.6.3" + }, + "scripts": { + "prepare": "coffee -o lib/ -c src/waza.coffee" + }, + "main": "lib/waza.js" +} +``` + +The `prepare` script will be run before publishing, so that users can consume the functionality without requiring them to compile it themselves. +In dev mode (ie, locally running `npm install`), it'll run this script as well, so that you can test it easily. + +### peerDependencies + +In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a `require` of this host. +This is usually referred to as a *plugin*. Notably, your module may be exposing a specific interface, expected and specified by the host documentation. + +For example: + +```json +{ + "name": "@npm/tea-latte", + "version": "1.3.5", + "peerDependencies": { + "@npm/tea": "2.x" + } +} +``` + +This ensures your package `@npm/tea-latte` can be installed *along* with the second major version of the host package `@npm/tea` only. +`npm install tea-latte` could possibly yield the following dependency graph: + +```bash +├── @npm/tea-latte@1.3.5 +└── @npm/tea@2.2.0 +``` + +In npm versions 3 through 6, `peerDependencies` were not automatically installed, and would raise a warning if an invalid version of the peer dependency was found in the tree. +As of npm v7, peerDependencies _are_ installed by default. + +Trying to install another plugin with a conflicting requirement may cause an error if the tree cannot be resolved correctly. +For this reason, make sure your plugin requirement is as broad as possible, and not to lock it down to specific patch versions. + +Assuming the host complies with [semver](https://semver.org/), only changes in the host package's major version will break your plugin. +Thus, if you've worked with every 1.x version of the host package, use `"^1.0"` or `"1.x"` to express this. +If you depend on features introduced in 1.5.2, use `"^1.5.2"`. + +### peerDependenciesMeta + +The `peerDependenciesMeta` field serves to provide npm more information on how your peer dependencies are to be used. +Specifically, it allows peer dependencies to be marked as optional. +Npm will not automatically install optional peer dependencies. +This allows you to integrate and interact with a variety of host packages without requiring all of them to be installed. + +For example: + +```json +{ + "name": "@npm/tea-latte", + "version": "1.3.5", + "peerDependencies": { + "@npm/tea": "2.x", + "@npm/soy-milk": "1.2" + }, + "peerDependenciesMeta": { + "@npm/soy-milk": { + "optional": true + } + } +} +``` + +### bundleDependencies + +This defines an array of package names that will be bundled when publishing the package. + +In cases where you need to preserve npm packages locally or have them available through a single file download, you can bundle the packages in a tarball file by specifying the package names in the `bundleDependencies` array and executing `npm pack`. + +For example: + +If we define a package.json like this: + +```json +{ + "name": "@npm/awesome-web-framework", + "version": "1.0.0", + "bundleDependencies": [ + "@npm/renderized", + "@npm/super-streams" + ] +} +``` + +we can obtain `@npm/awesome-web-framework-1.0.0.tgz` file by running `npm pack`. +This file contains the dependencies `@npm/renderized` and `@npm/super-streams` which can be installed in a new project by executing `npm install awesome-web-framework-1.0.0.tgz`. +Note that the package names do not include any versions, as that information is specified in `dependencies`. + +If this is spelled `"bundledDependencies"`, then that is also honored. + +Alternatively, `"bundleDependencies"` can be defined as a boolean value. +A value of `true` will bundle all dependencies, a value of `false` will bundle none. + +### optionalDependencies + +If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the `optionalDependencies` object. +This is a map of package name to version or URL, just like the `dependencies` object. +The difference is that build failures do not cause installation to fail. +Running `npm install --omit=optional` will prevent these dependencies from being installed. + +It is still your program's responsibility to handle the lack of the dependency. +For example, something like this: + +```js +try { + var foo = require('@npm/foo') + var fooVersion = require('@npm/foo/package.json').version +} catch (er) { + foo = null +} +if ( notGoodFooVersion(fooVersion) ) { + foo = null +} + +// .. then later in your program .. + +if (foo) { + foo.doFooThings() +} +``` + +Entries in `optionalDependencies` will override entries of the same name in `dependencies`, so it's usually best to only put in one place. + +### overrides + +If you need to make specific changes to dependencies of your dependencies, for example replacing the version of a dependency with a known security issue, replacing an existing dependency with a fork, or making sure that the same version of a package is used everywhere, then you may add an override. + +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 `@npm/foo` is always installed as version `1.0.0` no matter what version your dependencies rely on: + +```json +{ + "overrides": { + "@npm/foo": "1.0.0" + } +} +``` + +The above is a short hand notation, the full object form can be used to allow overriding a package itself as well as a child of the package. +This will cause `@npm/foo` to always be `1.0.0` while also making `@npm/bar` at any depth beyond `@npm/foo` also `1.0.0`: + +```json +{ + "overrides": { + "@npm/foo": { + ".": "1.0.0", + "@npm/bar": "1.0.0" + } + } +} +``` + +To only override `@npm/foo` to be `1.0.0` when it's a child (or grandchild, or great grandchild, etc) of the package `@npm/bar`: + +```json +{ + "overrides": { + "@npm/bar": { + "@npm/foo": "1.0.0" + } + } +} +``` + +Keys can be nested to any arbitrary length. +To override `@npm/foo` only when it's a child of `@npm/bar` and only when `@npm/bar` is a child of `@npm/baz`: + +```json +{ + "overrides": { + "@npm/baz": { + "@npm/bar": { + "@npm/foo": "1.0.0" + } + } + } +} +``` + +The key of an override can also include a version, or range of versions. +To override `@npm/foo` to `1.0.0`, but only when it's a child of `@npm/bar@2.0.0`: + +```json +{ + "overrides": { + "@npm/bar@2.0.0": { + "@npm/foo": "1.0.0" + } + } +} +``` + +You may not set an override for a package that you directly depend on unless both the dependency and the override itself share the exact same spec. +To make this limitation easier to deal with, overrides may also be defined as a reference to a spec for a direct dependency by prefixing the name of the package you wish the version to match with a `$`. + +```json +{ + "dependencies": { + "@npm/foo": "^1.0.0" + }, + "overrides": { + // BAD, will throw an EOVERRIDE error + // "foo": "^2.0.0" + // GOOD, specs match so override is allowed + // "foo": "^1.0.0" + // BEST, the override is defined as a reference to the dependency + "@npm/foo": "$foo", + // the referenced package does not need to match the overridden one + "@npm/bar": "$foo" + } +} +``` + +#### Replacing a dependency with a fork + +You can replace a package with a different package or fork using several methods: + +**Using the `npm:` prefix to replace with a different package name:** + +```json +{ + "overrides": { + "package-name": "npm:@scope/forked-package@1.0.0" + } +} +``` + +**Using a GitHub repository (supports branches, tags, or commit hashes):** + +```json +{ + "overrides": { + "package-name": "github:username/repo#branch-name" + } +} +``` + +**Using a local file path:** + +```json +{ + "overrides": { + "package-name": "file:../local-fork" + } +} +``` + +These replacement methods work for both top-level overrides and nested overrides. +For example, to replace a transitive dependency with a fork: + +```json +{ + "overrides": { + "parent-package": { + "vulnerable-dep": "github:username/patched-fork#v2.0.1" + } + } +} +``` + +### engines + +You can specify the version of node that your stuff works on: + +```json +{ + "engines": { + "node": ">=0.10.3 <15" + } +} +``` + +And, like with dependencies, if you don't specify the version (or if you specify "\*" as the version), then any version of node will do. + +You can also use the "engines" field to specify which versions of npm are capable of properly installing your program. +For example: + +```json +{ + "engines": { + "npm": "~1.0.20" + } +} +``` + +Unless the user has set the [`engine-strict` config](/using-npm/config#engine-strict) flag, this field is advisory only and will only produce warnings when your package is installed as a dependency. + +### os + +You can specify which operating systems your module will run on: + +```json +{ + "os": [ + "darwin", + "linux" + ] +} +``` + +You can also block instead of allowing operating systems, just prepend the blocked os with a '!': + +```json +{ + "os": [ + "!win32" + ] +} +``` + +The host operating system is determined by `process.platform` + +It is allowed to both block and allow an item, although there isn't any good reason to do this. + +### cpu + +If your code only runs on certain cpu architectures, you can specify which ones. + +```json +{ + "cpu": [ + "x64", + "ia32" + ] +} +``` + +Like the `os` option, you can also block architectures: + +```json +{ + "cpu": [ + "!arm", + "!mips" + ] +} +``` + +The host architecture is determined by `process.arch` + +### libc + +If your code only runs or builds in certain versions of libc, you can specify which ones. +This field only applies if `os` is `linux`. + +```json +{ + "os": "linux", + "libc": "glibc" +} +``` + +### devEngines + +The `devEngines` field aids engineers working on a codebase to all be using the same tooling. + +You can specify a `devEngines` property in your `package.json` which will run before `install`, `ci`, and `run` commands. + + +> Note: `engines` and `devEngines` differ in object shape. +They also function very differently. +`engines` is designed to alert the user when a dependency uses a different npm or node version than the project it's being used in, whereas `devEngines` is used to alert people interacting with the source code of a project. + +The supported keys under the `devEngines` property are `cpu`, `os`, `libc`, `runtime`, and `packageManager`. +Each property can be an object or an array of objects. +Objects must contain `name`, and optionally can specify `version`, and `onFail`. +`onFail` can be `warn`, `error`, or `ignore`, and if left undefined is of the same value as `error`. +`npm` will assume that you're running with `node`. +Here's an example of a project that will fail if the environment is not `node` and `npm`. +If you set `runtime.name` or `packageManager.name` to any other string, it will fail within the npm CLI. + +```json +{ + "devEngines": { + "runtime": { + "name": "node", + "onFail": "error" + }, + "packageManager": { + "name": "npm", + "onFail": "error" + } + } +} +``` + +### private + +If you set `"private": true` in your package.json, then npm will refuse to publish it. + +This is a way to prevent accidental publication of private repositories. +If you would like to ensure that a given package is only ever published to a specific registry (for example, an internal registry), then use the `publishConfig` dictionary described below to override the `registry` config param at publish-time. + +### publishConfig + +This is a set of config values that will be used at publish-time. +It's especially handy if you want to set the tag, registry or access, so that you can ensure that a given package is not tagged with "latest", published to the global public registry or that a scoped module is private by default. + +See [`config`](/using-npm/config) to see the list of config options that can be overridden. + +### workspaces + +The optional `workspaces` field is an array of file patterns that describes locations within the local file system that the install client should look up to find each [workspace](/using-npm/workspaces) that needs to be symlinked to the top level `node_modules` folder. + +It can describe either the direct paths of the folders to be used as workspaces or it can define globs that will resolve to these same folders. + +In the following example, all folders located inside the folder `./packages` will be treated as workspaces as long as they have valid `package.json` files inside them: + +```json +{ + "name": "workspace-example", + "workspaces": [ + "./packages/*" + ] +} +``` + +See [`workspaces`](/using-npm/workspaces) for more examples. + +### DEFAULT VALUES + +npm will default some values based on package contents. + +* `"scripts": {"start": "node server.js"}` + + If there is a `server.js` file in the root of your package, then npm will default the `start` command to `node server.js`. + +* `"scripts":{"install": "node-gyp rebuild"}` + + If there is a `binding.gyp` file in the root of your package and you have not defined an `install` or `preinstall` script, npm will default the `install` command to compile using node-gyp. + +* `"contributors": [...]` + + If there is an `AUTHORS` file in the root of your package, npm will treat each line as a `Name <email> (url)` format, where email and url are optional. + Lines which start with a `#` or are blank, will be ignored. + +### SEE ALSO + +* [semver](https://github.com/npm/node-semver#versions) +* [workspaces](/using-npm/workspaces) +* [npm init](/commands/npm-init) +* [npm version](/commands/npm-version) +* [npm config](/commands/npm-config) +* [npm help](/commands/npm-help) +* [npm install](/commands/npm-install) +* [npm publish](/commands/npm-publish) +* [npm uninstall](/commands/npm-uninstall) diff --git a/docs/lib/content/configuring-npm/package-lock-json.md b/docs/lib/content/configuring-npm/package-lock-json.md new file mode 100644 index 0000000000000..4d81156bd9c3c --- /dev/null +++ b/docs/lib/content/configuring-npm/package-lock-json.md @@ -0,0 +1,182 @@ +--- +title: package-lock.json +section: 5 +description: A manifestation of the manifest +--- + +### Description + +`package-lock.json` is automatically generated for any operations where npm modifies either the `node_modules` tree, or `package.json`. +It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates. + +This file is intended to be committed into source repositories, and serves various purposes: + +* Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies. + +* Provide a facility for users to "time-travel" to previous states of `node_modules` without having to commit the directory itself. + +* Facilitate greater visibility of tree changes through readable source control diffs. + +* Optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages. + +* As of npm v7, lockfiles include enough information to gain a complete 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 the root of a project. + +The difference is that `package-lock.json` cannot be published, and it will be ignored if found in any place other than the root project. + +In contrast, [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) allows publication, and defines the dependency tree from the point encountered. +This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages. + +If both `package-lock.json` and `npm-shrinkwrap.json` are present in the root of a project, `npm-shrinkwrap.json` will take precedence and `package-lock.json` will be ignored. + +### Hidden Lockfiles + +In order to avoid processing the `node_modules` folder repeatedly, npm as of v7 uses a "hidden" lockfile present in `node_modules/.package-lock.json`. +This contains information about the tree, and is used in lieu of reading the entire `node_modules` hierarchy provided that the following conditions are met: + +- All package folders it references exist in the `node_modules` hierarchy. +- No package folders exist in the `node_modules` hierarchy that are not listed in the lockfile. +- The modified time of the file is at least as recent as all of the package folders it references. + +That is, the hidden lockfile will only be relevant if it was created as part of the most recent update to the package tree. +If another CLI mutates the tree in any way, this will be detected, and the hidden lockfile will be ignored. + +Note that it _is_ possible to manually change the _contents_ of a package in such a way that the modified time of the package folder is unaffected. +For example, if you add a file to `node_modules/foo/lib/bar.js`, then the modified time on `node_modules/foo` will not reflect this change. +If you are manually editing files in `node_modules`, it is generally best to delete the file at `node_modules/.package-lock.json`. + +As the hidden lockfile is ignored by older npm versions, it does not contain the backwards compatibility affordances present in "normal" lockfiles. +That is, it is `lockfileVersion: 3`, rather than `lockfileVersion: 2`. + +### Handling Old Lockfiles + +When npm detects a lockfile from npm v6 or before during the package installation process, it is automatically updated to fetch missing information from either the `node_modules` tree or (in the case of empty `node_modules` trees or very old lockfile formats) the npm registry. + +### File Format + +#### `name` + +The name of the package this is a package-lock for. +This will match what's in `package.json`. + +#### `version` + +The version of the package this is a package-lock for. +This will match what's in `package.json`. + +#### `lockfileVersion` + +An integer version, starting at `1` with the version number of this document whose semantics were used when generating this `package-lock.json`. + +Note that the file format changed significantly in npm v7 to track information that would have otherwise required looking in `node_modules` or the npm registry. +Lockfiles generated by npm v7 will contain `lockfileVersion: 2`. + +* No version provided: an "ancient" shrinkwrap file from a version of npm prior to npm v5. +* `1`: The lockfile version used by npm v5 and v6. +* `2`: The lockfile version used by npm v7 and v8. Backwards compatible to v1 lockfiles. +* `3`: The lockfile version used by npm v9 and above. + Backwards compatible to npm v7. + +npm will always attempt to get whatever data it can out of a lockfile, even if it is not a version that it was designed to support. + +#### `packages` + +This is an object that maps package locations to an object containing the information about that package. + +The root project is typically listed with a key of `""`, and all other packages are listed with their relative paths from the root project folder. + +Package descriptors have the following fields: + +* version: The version found in `package.json` + +* resolved: The place where the package was actually resolved from. + In the case of packages fetched from the registry, this will be a url to a tarball. + In the case of git dependencies, this will be the full git url with commit sha. + In the case of link dependencies, this will be the location of the link target. + `registry.npmjs.org` is a magic value meaning "the currently configured registry". + +* integrity: A `sha512` or `sha1` [Standard Subresource Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) string for the artifact that was unpacked in this location. + +* link: A flag to indicate that this is a symbolic link. + If this is present, no other fields are specified, since the link target will also be included in the lockfile. + +* dev, optional, devOptional: If the package is strictly part of the + `devDependencies` tree, then `dev` will be true. + If it is strictly part of the `optionalDependencies` tree, then `optional` will be set. + If it is both a `dev` dependency _and_ an `optional` dependency of a non-dev dependency, then `devOptional` will be set. + (An `optional` dependency of a `dev` dependency will have both `dev` and `optional` set.) + +* inBundle: A flag to indicate that the package is a bundled dependency. + +* hasInstallScript: A flag to indicate that the package has a `preinstall`, `install`, or `postinstall` script. + +* hasShrinkwrap: A flag to indicate that the package has an `npm-shrinkwrap.json` file. + +* bin, license, engines, dependencies, optionalDependencies: fields from `package.json` + +* os: An array of operating systems this package is compatible with, as specified in `package.json`. This field is included when the package specifies OS restrictions. + +* cpu: An array of CPU architectures this package is compatible with, as specified in `package.json`. This field is included when the package specifies CPU restrictions. + +* funding: Funding information for the package, as specified in `package.json`. This field contains details about how to support the package maintainers. + +#### dependencies + +Legacy data for supporting versions of npm that use `lockfileVersion: 1`. +This is a mapping of package names to dependency objects. +Because the object structure is strictly hierarchical, symbolic link dependencies are somewhat challenging to represent in some cases. + +npm v7 ignores this section entirely if a `packages` section is present, but does keep it up to date in order to support switching between npm v6 and npm v7. + +Dependency objects have the following fields: + +* version: a specifier that varies depending on the nature of the package, and is usable in fetching a new copy of it. + Note that for peer dependencies that are not installed, or optional dependencies that are not installed, this field may be omitted. + + * bundled dependencies: Regardless of source, this is a version number that is purely for informational purposes. + * registry sources: This is a version number. + (eg, `1.2.3`) + * git sources: This is a git specifier with resolved committish. + (eg, `git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e`) + * http tarball sources: This is the URL of the tarball. + (eg, `https://example.com/example-1.3.0.tgz`) + * local tarball sources: This is the file URL of the tarball. + (eg `file:///opt/storage/example-1.3.0.tgz`) + * local link sources: This is the file URL of the link. + (eg `file:libs/our-module`) + + **Note:** The `version` field may be omitted for certain types of dependencies, such as optional peer dependencies that are not installed. In these cases, only metadata fields like `dev`, `optional`, and `peer` will be present. + +* integrity: A `sha512` or `sha1` [Standard Subresource Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) string for the artifact that was unpacked in this location. + For git dependencies, this is the commit sha. + +* resolved: For registry sources this is path of the tarball relative to the registry URL. + If the tarball URL isn't on the same server as the registry URL then this is a complete URL. + `registry.npmjs.org` is a magic value meaning "the currently configured registry". + +* bundled: If true, this is the bundled dependency and will be installed by the parent module. + When installing, this module will be extracted from the parent module during the extract phase, not installed as a separate dependency. + +* dev: If true then this dependency is either a development dependency ONLY of the top level module or a transitive dependency of one. + This is false for dependencies that are both a development dependency of the top level and a transitive dependency of a non-development dependency of the top level. + +* optional: If true then this dependency is either an optional dependency ONLY of the top level module or a transitive dependency of one. + This is false for dependencies that are both an optional dependency of the top level and a transitive dependency of a non-optional dependency of the top level. + +* requires: This is a mapping of module name to version. + This is a list of everything this module requires, regardless of where it will be installed. + The version should match via normal matching rules a dependency either in our `dependencies` or in a level higher than us. + +* dependencies: The dependencies of this dependency, exactly as at the top level. + +### See also + +* [npm shrinkwrap](/commands/npm-shrinkwrap) +* [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) +* [package.json](/configuring-npm/package-json) +* [npm install](/commands/npm-install) diff --git a/docs/nav.yml b/docs/lib/content/nav.yml similarity index 95% rename from docs/nav.yml rename to docs/lib/content/nav.yml index 565537054a0d7..f6f8014f28071 100644 --- a/docs/nav.yml +++ b/docs/lib/content/nav.yml @@ -18,9 +18,6 @@ - title: npm audit url: /commands/npm-audit description: Run a security audit - - title: npm bin - url: /commands/npm-bin - description: Display npm bin folder - title: npm bugs url: /commands/npm-bugs description: Bugs for a package in a web browser maybe @@ -78,9 +75,6 @@ - title: npm help-search url: /commands/npm-help-search description: Get help on npm - - title: npm hook - url: /commands/npm-hook - description: Manage registry hooks - title: npm init url: /commands/npm-init description: Create a package.json file @@ -96,6 +90,9 @@ - title: npm link url: /commands/npm-link description: Symlink a package folder + - title: npm login + url: /commands/npm-login + description: Login to a registry user account - title: npm logout url: /commands/npm-logout description: Log out of the registry @@ -147,15 +144,15 @@ - title: npm root url: /commands/npm-root description: Display npm root - - title: npm run-script - url: /commands/npm-run-script + - title: npm run + url: /commands/npm-run description: Run arbitrary package scripts + - title: npm sbom + url: /commands/npm-sbom + description: Generate a Software Bill of Materials (SBOM) - title: npm search url: /commands/npm-search description: Search for packages - - title: npm set-script - url: /commands/npm-set-script - description: Set tasks in the scripts section of package.json - title: npm shrinkwrap url: /commands/npm-shrinkwrap description: Lock down dependency versions for publication @@ -180,6 +177,9 @@ - title: npm token url: /commands/npm-token description: Manage your authentication tokens + - title: npm undeprecate + url: /commands/npm-undeprecate + description: Undeprecate a version of a package - title: npm uninstall url: /commands/npm-uninstall description: Remove a package diff --git a/docs/lib/content/using-npm/config.md b/docs/lib/content/using-npm/config.md new file mode 100644 index 0000000000000..252bbcf3a27e2 --- /dev/null +++ b/docs/lib/content/using-npm/config.md @@ -0,0 +1,93 @@ +--- +title: config +section: 7 +description: More than you probably want to know about npm configuration +--- + +### Description + +This article details npm configuration in general. +To learn about the `config` command, see [`npm config`](/commands/npm-config). + +npm gets its configuration values from the following sources, sorted by priority: + +#### Command Line Flags + +Putting `--foo bar` on the command line sets the `foo` configuration parameter to `"bar"`. +A `--` argument tells the cli parser to stop reading flags. +Using `--flag` without specifying any value will set the value to `true`. + +Example: `--flag1 --flag2` will set both configuration parameters to `true`, while `--flag1 --flag2 bar` will set `flag1` to `true`, and `flag2` to `bar`. +Finally, `--flag1 --flag2 -- bar` will set both configuration parameters to `true`, and the `bar` is taken as a command argument. + +**Common examples:** + +* `npm install --prefix /path/to/dir` - Runs npm commands in a different directory without changing the current working directory +* `npm install --global` - Installs packages globally (shorthand: `-g`) +* `npm install --save-dev` - Saves to devDependencies (shorthand: `-D`) + +Any configuration option documented in the [Config Settings](#config-settings) section below can be set via command line flags using `--option-name value` syntax. + +#### Environment Variables + +Any environment variables that start with `npm_config_` will be interpreted as a configuration parameter. +For example, putting `npm_config_foo=bar` in your environment will set the `foo` configuration parameter to `bar`. +Any environment configurations that are not given a value will be given the value of `true`. +Config values are case-insensitive, so `NPM_CONFIG_FOO=bar` will work the same. +However, please note that inside [`scripts`](/using-npm/scripts) npm will set its own environment variables and Node will prefer those lowercase versions over any uppercase ones that you might set. +For details see [this issue](https://github.com/npm/npm/issues/14528). + +Notice that you need to use underscores instead of dashes, so `--allow-same-version` would become `npm_config_allow_same_version=true`. + +**Important:** When defining custom configuration keys in `.npmrc` files, use hyphens instead of underscores (e.g., `custom-key=value`). This ensures they can be overridden by environment variables, since npm automatically converts underscores to hyphens when reading environment variables. Keys with underscores in `.npmrc` files cannot be overridden via environment variables. + +#### npmrc Files + +The four relevant files are: + +* per-project configuration file (`/path/to/my/project/.npmrc`) +* per-user configuration file (defaults to `$HOME/.npmrc`; configurable via CLI option `--userconfig` or environment variable `$NPM_CONFIG_USERCONFIG`) +* global configuration file (defaults to `$PREFIX/etc/npmrc`; configurable via CLI option `--globalconfig` or environment variable `$NPM_CONFIG_GLOBALCONFIG`) +* npm's built-in configuration file (`/path/to/npm/npmrc`) + +See [npmrc](/configuring-npm/npmrc) for more details. + +#### Default Configs + +Run `npm config ls -l` to see a set of configuration parameters that are internal to npm, and are defaults if nothing else is specified. + +### Shorthands and Other CLI Niceties + +The following shorthands are parsed on the command-line: + +<!-- AUTOGENERATED CONFIG SHORTHANDS --> + +If the specified configuration param resolves unambiguously to a known configuration parameter, then it is expanded to that configuration parameter. +For example: + +```bash +npm ls --par +# same as: +npm ls --parseable +``` + +If multiple single-character shorthands are strung together, and the resulting combination is unambiguously not some other configuration param, then it is expanded to its various component pieces. +For example: + +```bash +npm ls -gpld +# same as: +npm ls --global --parseable --long --loglevel info +``` + +### Config Settings + +<!-- AUTOGENERATED CONFIG DESCRIPTIONS --> + +### See also + +* [npm config](/commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm scripts](/using-npm/scripts) +* [npm folders](/configuring-npm/folders) +* [npm](/commands/npm) diff --git a/docs/lib/content/using-npm/dependency-selectors.md b/docs/lib/content/using-npm/dependency-selectors.md new file mode 100644 index 0000000000000..9a1502e9349da --- /dev/null +++ b/docs/lib/content/using-npm/dependency-selectors.md @@ -0,0 +1,247 @@ +--- +title: Dependency Selector Syntax & Querying +section: 7 +description: Dependency Selector Syntax & Querying +--- + +### Description + +The [`npm query`](/commands/npm-query) command exposes a new dependency selector syntax (informed by & respecting many aspects of the [CSS Selectors 4 Spec](https://dev.w3.org/csswg/selectors4/#relational)) which: + +- Standardizes the shape of, & querying of, dependency graphs with a robust object model, metadata & selector syntax +- Leverages existing, known language syntax & operators from CSS to make disparate package information broadly accessible +- Unlocks the ability to answer complex, multi-faceted questions about dependencies, their relationships & associative metadata +- Consolidates redundant logic of similar query commands in `npm` (ex. +`npm fund`, `npm ls`, `npm outdated`, `npm audit` ...) + +### Dependency Selector Syntax + +#### Overview: + +- there is no "type" or "tag" selectors (ex. +`div, h1, a`) as a dependency/target is the only type of `Node` that can be queried +- the term "dependencies" is in reference to any `Node` found in a `tree` returned by `Arborist` + +#### Combinators + +- `>` direct descendant/child +- ` ` any descendant/child +- `~` sibling + +#### Selectors + +- `*` universal selector +- `#<name>` dependency selector (equivalent to `[name="..."]`) +- `#<name>@<version>` (equivalent to `[name=<name>]:semver(<version>)`) +- `,` selector list delimiter +- `.` dependency type selector +- `:` pseudo selector + +#### Dependency Type Selectors + +- `.prod` dependency found in the `dependencies` section of `package.json`, or is a child of said dependency +- `.dev` dependency found in the `devDependencies` section of `package.json`, or is a child of said dependency +- `.optional` dependency found in the `optionalDependencies` section of `package.json`, or has `"optional": true` set in its entry in the `peerDependenciesMeta` section of `package.json`, or a child of said dependency +- `.peer` dependency found in the `peerDependencies` section of `package.json` +- `.workspace` dependency found in the [`workspaces`](https://docs.npmjs.com/cli/v8/using-npm/workspaces) section of `package.json` +- `.bundled` dependency found in the `bundleDependencies` section of `package.json`, or is a child of said dependency + +#### Pseudo Selectors +- [`:not(<selector>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:not) +- [`:has(<selector>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) +- [`:is(<selector list>)`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is) +- [`:root`](https://developer.mozilla.org/en-US/docs/Web/CSS/:root) matches the root node/dependency +- [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) matches node/dependency it was queried against +- [`:empty`](https://developer.mozilla.org/en-US/docs/Web/CSS/:empty) when a dependency has no dependencies +- [`:private`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#private) when a dependency is private +- `:link` when a dependency is linked (for instance, workspaces or packages manually [`linked`](https://docs.npmjs.com/cli/v8/commands/npm-link) +- `:deduped` when a dependency has been deduped (note that this does *not* always mean the dependency has been hoisted to the root of node_modules) +- `:overridden` when a dependency has been overridden +- `:extraneous` when a dependency exists but is not defined as a dependency of any node +- `:invalid` when a dependency version is out of its ancestors specified range +- `:missing` when a dependency is not found on disk +- `:semver(<spec>, [selector], [function])` match a valid [`node-semver`](https://github.com/npm/node-semver) version or range to a selector +- `:path(<path>)` [glob](https://www.npmjs.com/package/glob) matching based on dependencies path relative to the project +- `:type(<type>)` [based on currently recognized types](https://github.com/npm/npm-package-arg#result-object) +- `:outdated(<type>)` when a dependency is outdated +- `:vuln(<selector>)` when a dependency has a known vulnerability + +##### `:semver(<spec>, [selector], [function])` + +The `:semver()` pseudo selector allows comparing fields from each node's `package.json` using [semver](https://github.com/npm/node-semver#readme) methods. +It accepts up to 3 parameters, all but the first of which are optional. + +- `spec` a semver version or range +- `selector` an attribute selector for each node (default `[version]`) +- `function` a semver method to apply, one of: `satisfies`, `intersects`, `subset`, `gt`, `gte`, `gtr`, `lt`, `lte`, `ltr`, `eq`, `neq` or the special function `infer` (default `infer`) + +When the special `infer` function is used the `spec` and the actual value from the node are compared. +If both are versions, according to `semver.valid()`, `eq` is used. +If both values are ranges, according to `!semver.valid()`, `intersects` is used. +If the values are mixed types `satisfies` is used. + +Some examples: + +- `:semver(^1.0.0)` returns every node that has a `version` satisfied by the provided range `^1.0.0` +- `:semver(16.0.0, :attr(engines, [node]))` returns every node which has an `engines.node` property satisfying the version `16.0.0` +- `:semver(1.0.0, [version], lt)` every node with a `version` less than `1.0.0` + +##### `:outdated(<type>)` + +The `:outdated` pseudo selector retrieves data from the registry and returns information about which of your dependencies are outdated. +The type parameter may be one of the following: + +- `any` (default) a version exists that is greater than the current one +- `in-range` a version exists that is greater than the current one, and satisfies at least one if its parent's dependencies +- `out-of-range` a version exists that is greater than the current one, does not satisfy at least one of its parent's dependencies +- `major` a version exists that is a semver major greater than the current one +- `minor` a version exists that is a semver minor greater than the current one +- `patch` a version exists that is a semver patch greater than the current one + +In addition to the filtering performed by the pseudo selector, some extra data is added to the resulting objects. +The following data can be found under the `queryContext` property of each node. + +- `versions` an array of every available version of the given node +- `outdated.inRange` an array of objects, each with a `from` and `versions`, where `from` is the on-disk location of the node that depends on the current node and `versions` is an array of all available versions that satisfies that dependency. +This is only populated if `:outdated(in-range)` is used. +- `outdated.outOfRange` an array of objects, identical in shape to `inRange`, but where the `versions` array is every available version that does not satisfy the dependency. +This is only populated if `:outdated(out-of-range)` is used. + +Some examples: + +- `:root > :outdated(major)` returns every direct dependency that has a new semver major release +- `.prod:outdated(in-range)` returns production dependencies that have a new release that satisfies at least one of its parent's dependencies + +##### `:vuln` + +The `:vuln` pseudo selector retrieves data from the registry and returns information about which if your dependencies has a known vulnerability. +Only dependencies whose current version matches a vulnerability will be returned. +For example if you have `semver@7.6.0` in your tree, a vulnerability for `semver` which affects versions `<=6.3.1` will not match. + +You can also filter results by certain attributes in advisories. +Currently that includes `severity` and `cwe`. +Note that severity filtering is done per severity, it does not include severities "higher" or "lower" than the one specified. + +In addition to the filtering performed by the pseudo selector, info about each relevant advisory will be added to the `queryContext` attribute of each node under the `advisories` attribute. + +Some examples: + +- `:root > .prod:vuln` returns direct production dependencies with any known vulnerability +- `:vuln([severity=high])` returns only dependencies with a vulnerability with a `high` severity. +- `:vuln([severity=high],[severity=moderate])` returns only dependencies with a vulnerability with a `high` or `moderate` severity. +- `:vuln([cwe=1333])` returns only dependencies with a vulnerability that includes CWE-1333 (ReDoS) + +#### [Attribute Selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) + +The attribute selector evaluates the key/value pairs in `package.json` if they are `String`s. + +- `[]` attribute selector (ie. +existence of attribute) +- `[attribute=value]` attribute value is equivalent... +- `[attribute~=value]` attribute value contains word... +- `[attribute*=value]` attribute value contains string... +- `[attribute|=value]` attribute value is equal to or starts with... +- `[attribute^=value]` attribute value starts with... +- `[attribute$=value]` attribute value ends with... + +#### `Array` & `Object` Attribute Selectors + +The generic `:attr()` pseudo selector standardizes a pattern which can be used for attribute selection of `Object`s, `Array`s or `Arrays` of `Object`s accessible via `Arborist`'s `Node.package` metadata. +This allows for iterative attribute selection beyond top-level `String` evaluation. +The last argument passed to `:attr()` must be an `attribute` selector or a nested `:attr()`. +See examples below: + +#### `Objects` + +```css +/* return dependencies that have a `scripts.test` containing `"tap"` */ +*:attr(scripts, [test~=tap]) +``` + +#### Nested `Objects` + +Nested objects are expressed as sequential arguments to `:attr()`. + +```css +/* return dependencies that have a [testling config](https://ci.testling.com/guide/advanced_configuration) for opera browsers */ +*:attr(testling, browsers, [~=opera]) +``` + +#### `Arrays` + +`Array`s specifically uses a special/reserved `.` character in place of a typical attribute name. +`Arrays` also support exact `value` matching when a `String` is passed to the selector. + +##### Example of an `Array` Attribute Selection: +```css +/* removes the distinction between properties & arrays */ +/* ie. we'd have to check the property & iterate to match selection */ +*:attr([keywords^=react]) +*:attr(contributors, :attr([name~=Jordan])) +``` + +##### Example of an `Array` matching directly to a value: +```css +/* return dependencies that have the exact keyword "react" */ +/* this is equivalent to `*:keywords([value="react"])` */ +*:attr([keywords=react]) +``` + +##### Example of an `Array` of `Object`s: +```css +/* returns */ +*:attr(contributors, [email=ruyadorno@github.com]) +``` + +### Groups + +Dependency groups are defined by the package relationships to their ancestors (ie. +the dependency types that are defined in `package.json`). +This approach is user-centric as the ecosystem has been taught to think about dependencies in these groups first-and-foremost. +Dependencies are allowed to be included in multiple groups (ex. +a `prod` dependency may also be a `dev` dependency (in that it's also required by another `dev` dependency) & may also be `bundled` - a selector for that type of dependency would look like: `*.prod.dev.bundled`). + +- `.prod` +- `.dev` +- `.optional` +- `.peer` +- `.bundled` +- `.workspace` + +Please note that currently `workspace` deps are always `prod` dependencies. +Additionally the `.root` dependency is also considered a `prod` dependency. + +### Programmatic Usage + +- `Arborist`'s `Node` Class has a `.querySelectorAll()` method + - this method will return a filtered, flattened dependency Arborist `Node` list based on a valid query selector + +```js +const Arborist = require('@npmcli/arborist') +const arb = new Arborist({}) +``` + +```js +// root-level +arb.loadActual().then(async (tree) => { + // query all production dependencies + const results = await tree.querySelectorAll('.prod') + console.log(results) +}) +``` + +```js +// iterative +arb.loadActual().then(async (tree) => { + // query for the deduped version of react + const results = await tree.querySelectorAll('#react:not(:deduped)') + // query the deduped react for git deps + const deps = await results[0].querySelectorAll(':type(git)') + console.log(deps) +}) +``` + +## See Also + +* [npm query](/commands/npm-query) +* [@npmcli/arborist](https://npm.im/@npmcli/arborist) diff --git a/docs/lib/content/using-npm/developers.md b/docs/lib/content/using-npm/developers.md new file mode 100644 index 0000000000000..0261d137b36b7 --- /dev/null +++ b/docs/lib/content/using-npm/developers.md @@ -0,0 +1,215 @@ +--- +title: developers +section: 7 +description: Developer Guide +--- + +### Description + +So, you've decided to use npm to develop (and maybe publish/deploy) your project. + +Fantastic! + +There are a few things that you need to do above the simple steps that your users will do to install your program. + +### About These Documents + +These are man pages. +If you install npm, you should be able to then do `man npm-thing` to get the documentation on a particular topic, or `npm help thing` to see the same information. + +### What is a Package + +A package is: + +* a) a folder containing a program described by a package.json file +* b) a gzipped tarball containing (a) +* c) a url that resolves to (b) +* d) a `<name>@<version>` that is published on the registry with (c) +* e) a `<name>@<tag>` that points to (d) +* f) a `<name>` that has a "latest" tag satisfying (e) +* g) a `git` url that, when cloned, results in (a). + +Even if you never publish your package, you can still get a lot of benefits of using npm if you just want to write a node program (a), and perhaps if you also want to be able to easily install it elsewhere after packing it up into a tarball (b). + +Git urls can be of the form: + +```bash +git://github.com/user/project.git#commit-ish +git+ssh://user@hostname:project.git#commit-ish +git+http://user@hostname/project/blah.git#commit-ish +git+https://user@hostname/project/blah.git#commit-ish +``` + +The `commit-ish` can be any tag, sha, or branch which can be supplied as an argument to `git checkout`. +The default is whatever the repository uses as its default branch. + +### The package.json File + +You need to have a `package.json` file in the root of your project to do much of anything with npm. +That is basically the whole interface. + +See [`package.json`](/configuring-npm/package-json) for details about what goes in that file. +At the very least, you need: + +* name: This should be a string that identifies your project. + Please do not use the name to specify that it runs on node, or is in JavaScript. + You can use the "engines" field to explicitly state the versions of node (or whatever else) that your program requires, and it's pretty well assumed that it's JavaScript. + + It does not necessarily need to match your github repository name. + + So, `node-foo` and `bar-js` are bad names. + `foo` or `bar` are better. + +* version: A semver-compatible version. + +* engines: Specify the versions of node (or whatever else) that your program runs on. + The node API changes a lot, and there may be bugs or new functionality that you depend on. + Be explicit. + +* author: Take some credit. + +* scripts: If you have a special compilation or installation script, then you should put it in the `scripts` object. + You should definitely have at least a basic smoke-test command as the "scripts.test" field. + See [scripts](/using-npm/scripts). + +* main: If you have a single module that serves as the entry point to your program (like what the "foo" package gives you at require("foo")), then you need to specify that in the "main" field. + +* directories: This is an object mapping names to folders. + The best ones to include are "lib" and "doc", but if you use "man" to specify a folder full of man pages, they'll get installed just like these ones. + +You can use `npm init` in the root of your package in order to get you started with a pretty basic package.json file. +See [`npm init`](/commands/npm-init) for more info. + +### Keeping files *out* of your Package + +Use a `.npmignore` file to keep stuff out of your package. +If there's no `.npmignore` file, but there *is* a `.gitignore` file, then npm will ignore the stuff matched by the `.gitignore` file. +If you *want* to include something that is excluded by your `.gitignore` file, you can create an empty `.npmignore` file to override it. +Like `git`, `npm` looks for `.npmignore` and `.gitignore` files in all subdirectories of your package, not only the root directory. + +`.npmignore` files follow the [same pattern rules](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#_ignoring) as `.gitignore` files: + +* Blank lines or lines starting with `#` are ignored. +* Standard glob patterns work. +* You can end patterns with a forward slash `/` to specify a directory. +* You can negate a pattern by starting it with an exclamation point `!`. + +By default, some paths and files are ignored, so there's no need to add them to `.npmignore` explicitly. +Some examples are: + +* `.*.swp` +* `._*` +* `.DS_Store` +* `.git` +* `.gitignore` +* `.hg` +* `.npmignore` +* `.npmrc` +* `.lock-wscript` +* `.svn` +* `.wafpickle-*` +* `config.gypi` +* `CVS` +* `npm-debug.log` + +Additionally, everything in `node_modules` is ignored, except for bundled dependencies. +npm automatically handles this for you, so don't bother adding `node_modules` to `.npmignore`. + +The following paths and files are never ignored, so adding them to `.npmignore` is pointless: + +* `package.json` +* `README` (and its variants) +* `LICENSE` / `LICENCE` + +If, given the structure of your project, you find `.npmignore` to be a maintenance headache, you might instead try populating the `files` property of `package.json`, which is an array of file or directory names that should be included in your package. +Sometimes manually picking which items to allow is easier to manage than building a block list. + +See [`package.json`](/configuring-npm/package-json) for more info on what can and can't be ignored. + +#### Testing whether your `.npmignore` or `files` config works + +If you want to double check that your package will include only the files you intend it to when published, you can run the `npm pack` command locally which will generate a tarball in the working directory, the same way it does for publishing. + +### Link Packages + +`npm link` is designed to install a development package and see the changes in real time without having to keep re-installing it. +(You do need to either re-link or `npm rebuild -g` to update compiled packages, of course.) + +More info at [`npm link`](/commands/npm-link). + +### Before Publishing: Make Sure Your Package Installs and Works + +**This is important.** + +If you cannot install it locally, you'll have problems trying to publish it. +Or, worse yet, you'll be able to publish it, but you'll be publishing a broken or pointless package. +So don't do that. + +In the root of your package, do this: + +```bash +npm install . -g +``` + +That'll show you that it's working. +If you'd rather just create a symlink package that points to your working directory, then do this: + +```bash +npm link +``` + +Use `npm ls -g` to see if it's there. + +To test a local install, go into some other folder, and then do: + +```bash +cd ../some-other-folder +npm install ../my-package +``` + +to install it locally into the node_modules folder in that other place. + +Then go into the node-repl, and try using require("my-thing") to bring in your module's main module. + +### Create a User Account + +Create a user with the adduser command. +It works like this: + +```bash +npm adduser +``` + +and then follow the prompts. + +This is documented better in [npm adduser](/commands/npm-adduser). + +### Publish your Package + +This part's easy. +In the root of your folder, do this: + +```bash +npm publish +``` + +You can give publish a url to a tarball, or a filename of a tarball, or a path to a folder. + +Note that pretty much **everything in that folder will be exposed** by default. +So, if you have secret stuff in there, use a `.npmignore` file to list out the globs to ignore, or publish from a fresh checkout. + +### Brag about it + +Send emails, write blogs, blab in IRC. + +Tell the world how easy it is to install your program! + +### See also + +* [npm](/commands/npm) +* [npm init](/commands/npm-init) +* [package.json](/configuring-npm/package-json) +* [npm scripts](/using-npm/scripts) +* [npm publish](/commands/npm-publish) +* [npm adduser](/commands/npm-adduser) +* [npm registry](/using-npm/registry) diff --git a/docs/lib/content/using-npm/logging.md b/docs/lib/content/using-npm/logging.md new file mode 100644 index 0000000000000..d5fca42f595c2 --- /dev/null +++ b/docs/lib/content/using-npm/logging.md @@ -0,0 +1,99 @@ +--- +title: Logging +section: 7 +description: Why, What & How We Log +--- + +### Description + +The `npm` CLI has various mechanisms for showing different levels of information back to end-users for certain commands, configurations & environments. + +### Setting Log File Location + +All logs are written to a debug log, with the path to that file printed if the execution of a command fails. + +The default location of the logs directory is a directory named `_logs` inside the npm cache. +This can be changed with the `logs-dir` config option. + +For example, if you wanted to write all your logs to the current working directory, you could run: `npm install --logs-dir=.`. +This is especially helpful in debugging a specific `npm` issue as you can run a command multiple times with different config values and then diff all the log files. + +Log files will be removed from the `logs-dir` when the number of log files exceeds `logs-max`, with the oldest logs being deleted first. + +To turn off logs completely set `--logs-max=0`. + +### Setting Log Levels + +#### `loglevel` + +`loglevel` is a global argument/config that can be set to determine the type of information to be displayed. + +The default value of `loglevel` is `"notice"` but there are several levels/types of logs available, including: + +- `"silent"` +- `"error"` +- `"warn"` +- `"notice"` +- `"http"` +- `"info"` +- `"verbose"` +- `"silly"` + +All logs pertaining to a level preceding the current setting will be shown. + +##### Aliases + +The log levels listed above have various corresponding aliases, including: + +- `-d`: `--loglevel info` +- `--dd`: `--loglevel verbose` +- `--verbose`: `--loglevel verbose` +- `--ddd`: `--loglevel silly` +- `-q`: `--loglevel warn` +- `--quiet`: `--loglevel warn` +- `-s`: `--loglevel silent` +- `--silent`: `--loglevel silent` + +#### `foreground-scripts` + +The `npm` CLI began hiding the output of lifecycle scripts for `npm install` as of `v7`. +Notably, this means you will not see logs/output from packages that may be using "install scripts" to display information back to you or from your own project's scripts defined in `package.json`. +If you'd like to change this behavior & log this output you can set `foreground-scripts` to `true`. + +### Timing Information + +The [`--timing` config](/using-npm/config#timing) can be set which does a few things: + +1. Always shows the full path to the debug log regardless of command exit status +1. Write timing information to a process specific timing file in the cache or `logs-dir` +1. Output timing information to the terminal + +This file contains a `timers` object where the keys are an identifier for the portion of the process being timed and the value is the number of milliseconds it took to complete. + +Sometimes it is helpful to get timing information without outputting anything to the terminal. +For example, the performance might be affected by writing to the terminal. +In this case you can use +`--timing --silent` which will still write the timing file, but not output anything to the terminal while running. + +### Registry Response Headers + +#### `npm-notice` + +The `npm` CLI reads from & logs any `npm-notice` headers that are returned from the configured registry. +This mechanism can be used by third-party registries to provide useful information when network-dependent requests occur. + +This header is not cached, and will not be logged if the request is served from the cache. + +### Logs and Sensitive Information + +The `npm` CLI makes a best effort to redact the following from terminal output and log files: + +- Passwords inside basic auth URLs +- npm tokens + +However, this behavior should not be relied on to keep all possible sensitive information redacted. +If you are concerned about secrets in your log file or terminal output, you can use `--loglevel=silent` and `--logs-max=0` to ensure no logs are written to your terminal or filesystem. + +### See also + +* [config](/using-npm/config) diff --git a/docs/lib/content/using-npm/orgs.md b/docs/lib/content/using-npm/orgs.md new file mode 100644 index 0000000000000..8faf939d0b5e8 --- /dev/null +++ b/docs/lib/content/using-npm/orgs.md @@ -0,0 +1,98 @@ +--- +title: orgs +section: 7 +description: Working with Teams & Orgs +--- + +### Description + +There are three levels of org users: + +1. Super admin, controls billing & adding people to the org. +2. Team admin, manages team membership & package access. +3. Developer, works on packages they are given access to. + +The super admin is the only person who can add users to the org because it impacts the monthly bill. +The super admin will use the website to manage membership. +Every org has a `developers` team that all users are automatically added to. + +The team admin is the person who manages team creation, team membership, and package access for teams. +The team admin grants package access to teams, not individuals. + +The developer will be able to access packages based on the teams they are on. +Access is either read-write or read-only. + +There are two main commands: + +1. `npm team` see [npm team](/commands/npm-team) for more details +2. `npm access` see [npm access](/commands/npm-access) for more details + +### Team Admins create teams + +* Check who you’ve added to your org: + +```bash +npm team ls <org>:developers +``` + +* Each org is automatically given a `developers` team, so you can see the whole list of team members in your org. +This team automatically gets read-write access to all packages, but you can change that with the `access` command. + +* Create a new team: + +```bash +npm team create <org:team> +``` + +* Add members to that team: + +```bash +npm team add <org:team> <user> +``` + +### Publish a package and adjust package access + +* In package directory, run + +```bash +npm init --scope=<org> +``` +to scope it for your org & publish as usual + +* Grant access: + +```bash +npm access grant <read-only|read-write> <org:team> [<package>] +``` + +* Revoke access: + +```bash +npm access revoke <org:team> [<package>] +``` + +### Monitor your package access + +* See what org packages a team member can access: + +```bash +npm access list packages <org> <user> +``` + +* See packages available to a specific team: + +```bash +npm access list packages <org:team> +``` + +* Check which teams are collaborating on a package: + +```bash +npm access list collaborators <pkg> +``` + +### See also + +* [npm team](/commands/npm-team) +* [npm access](/commands/npm-access) +* [npm scope](/using-npm/scope) diff --git a/docs/lib/content/using-npm/package-spec.md b/docs/lib/content/using-npm/package-spec.md new file mode 100644 index 0000000000000..d5c319fa43c9c --- /dev/null +++ b/docs/lib/content/using-npm/package-spec.md @@ -0,0 +1,93 @@ +--- +title: package-spec +section: 7 +description: Package name specifier +--- + + +### Description + +Commands like `npm install` and the dependency sections in the `package.json` use a package name specifier. +This can be many different things that all refer to a "package". Examples include a package name, git url, tarball, or local directory. +These will generally be referred to as `<package-spec>` in the help output for the npm commands that use this package name specifier. + +### Package name + +* `[<@scope>/]<pkg>` +* `[<@scope>/]<pkg>@<tag>` +* `[<@scope>/]<pkg>@<version>` +* `[<@scope>/]<pkg>@<version range>` + +Refers to a package by name, with or without a scope, and optionally tag, version, or version range. +This is typically used in combination with the [registry](/using-npm/config#registry) config to refer to a package in a registry. + +Examples: +* `npm` +* `@npmcli/arborist` +* `@npmcli/arborist@latest` +* `npm@6.13.1` +* `npm@^4.0.0` + +### Aliases + +* `<alias>@npm:<name>` + +Primarily used by commands like `npm install` and in the dependency sections in the `package.json`, this refers to a package by an alias. +The `<alias>` is the name of the package as it is reified in the `node_modules` folder, and the `<name>` refers to a package name as found in the configured registry. + +See `Package name` above for more info on referring to a package by name, and [registry](/using-npm/config#registry) for configuring which registry is used when referring to a package by name. + +Examples: +* `semver@npm:@npmcli/semver-with-patch` +* `semver@npm:semver@7.2.2` +* `semver@npm:semver@legacy` + +### Folders + +* `<folder>` + +This refers to a package on the local filesystem. +Specifically this is a folder with a `package.json` file in it. +This *should* always be prefixed with a `/` or `./` (or your OS equivalent) to reduce confusion. +npm currently will parse a string with more than one `/` in it as a folder, but this is legacy behavior that may be removed in a future version. + +Examples: + +* `./my-package` +* `/opt/npm/my-package` + +### Tarballs + +* `<tarball file>` +* `<tarball url>` + +Examples: + +* `./my-package.tgz` +* `https://registry.npmjs.org/semver/-/semver-1.0.0.tgz` + +Refers to a package in a tarball format, either on the local filesystem or remotely via url. +This is the format that packages exist in when uploaded to a registry. + +### git urls + +* `<git:// url>` +* `<github username>/<github project>` + +Refers to a package in a git repo. +This can be a full git url, git shorthand, or a username/package on GitHub. +You can specify a git tag, branch, or other git ref by appending `#ref`. + +Examples: + +* `https://github.com/npm/cli.git` +* `git@github.com:npm/cli.git` +* `git+ssh://git@github.com/npm/cli#v6.0.0` +* `github:npm/cli#HEAD` +* `npm/cli#c12ea07` + +### See also + +* [npm-package-arg](https://npm.im/npm-package-arg) +* [scope](/using-npm/scope) +* [config](/using-npm/config) diff --git a/docs/lib/content/using-npm/registry.md b/docs/lib/content/using-npm/registry.md new file mode 100644 index 0000000000000..a707b97ac5a9b --- /dev/null +++ b/docs/lib/content/using-npm/registry.md @@ -0,0 +1,61 @@ +--- +title: registry +section: 7 +description: The JavaScript Package Registry +--- + +### Description + +To resolve packages by name and version, npm talks to a registry website that implements the CommonJS Package Registry specification for reading package info. + +npm is configured to use the **npm public registry** at +<https://registry.npmjs.org> by default. +Use of the npm public registry is subject to terms of use available at <https://docs.npmjs.com/policies/terms>. + +You can configure npm to use any compatible registry you like, and even run your own registry. +Use of someone else's registry may be governed by their terms of use. + +npm's package registry implementation supports several write APIs as well, to allow for publishing packages and managing user account information. + +The registry URL used is determined by the scope of the package (see [`scope`](/using-npm/scope). +If no scope is specified, the default registry is used, which is supplied by the [`registry` config](/using-npm/config#registry) parameter. +See [`npm config`](/commands/npm-config), [`npmrc`](/configuring-npm/npmrc), and [`config`](/using-npm/config) for more on managing npm's configuration. +Authentication configuration such as auth tokens and certificates are configured specifically scoped to an individual registry. +See [Auth Related Configuration](/configuring-npm/npmrc#auth-related-configuration) + +When the default registry is used in a package-lock or shrinkwrap it has the special meaning of "the currently configured registry". If you create a lock file while using the default registry you can switch to another registry and npm will install packages from the new registry, but if you create a lock file while using a custom registry packages will be installed from that registry even after you change to another registry. + +### Does npm send any information about me back to the registry? + +Yes. + +When making requests of the registry npm adds two headers with information about your environment: + +* `Npm-Scope` – If your project is scoped, this header will contain its scope. +In the future npm hopes to build registry features that use this information to allow you to customize your experience for your organization. +* `Npm-In-CI` – Set to "true" if npm believes this install is running in a continuous integration environment, "false" otherwise. +This is detected by looking for the following environment variables: `CI`, `TDDIUM`, + `JENKINS_URL`, `bamboo.buildKey`. +If you'd like to learn more you may find the [original PR](https://github.com/npm/npm-registry-client/pull/129) interesting. + This is used to gather better metrics on how npm is used by humans, versus build farms. + +The npm registry does not try to correlate the information in these headers with any authenticated accounts that may be used in the same requests. + +### How can I prevent my package from being published in the official registry? + +Set `"private": true` in your `package.json` to prevent it from being published at all, or +`"publishConfig":{"registry":"http://my-internal-registry.local"}` +to force it to be published only to your internal/private registry. + +See [`package.json`](/configuring-npm/package-json) for more info on what goes in the package.json file. + +### Where can I find my (and others') published packages? + +<https://www.npmjs.com/> + +### See also + +* [npm config](/commands/npm-config) +* [config](/using-npm/config) +* [npmrc](/configuring-npm/npmrc) +* [npm developers](/using-npm/developers) diff --git a/docs/lib/content/using-npm/removal.md b/docs/lib/content/using-npm/removal.md new file mode 100644 index 0000000000000..9b431aaf7f38a --- /dev/null +++ b/docs/lib/content/using-npm/removal.md @@ -0,0 +1,55 @@ +--- +title: removal +section: 7 +description: Cleaning the Slate +--- + +### Synopsis + +So sad to see you go. + +```bash +sudo npm uninstall npm -g +``` + +Or, if that fails, please proceed to more severe uninstalling methods. + +### More Severe Uninstalling + +Usually, the above instructions are sufficient. +That will remove npm, but leave behind anything you've installed. + +If that doesn't work, or if you require more drastic measures, continue reading. + +Note that this is only necessary for globally-installed packages. +Local installs are completely contained within a project's `node_modules` folder. +Delete that folder, and everything is gone unless a package's install script is particularly ill-behaved. + +This assumes that you installed node and npm in the default place. +If you configured node with a different `--prefix`, or installed npm with a different prefix setting, then adjust the paths accordingly, replacing +`/usr/local` with your install prefix. + +To remove everything npm-related manually: + +```bash +rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/npm* +``` + +If you installed things *with* npm, then your best bet is to uninstall them with npm first, and then install them again once you have a proper install. +This can help find any symlinks that are lying around: + +```bash +ls -laF /usr/local/{lib/node{,/.npm},bin,share/man} | grep npm +``` + +Prior to version 0.3, npm used shim files for executables and node modules. +To track those down, you can do the following: + +```bash +find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ; +``` + +### See also + +* [npm uninstall](/commands/npm-uninstall) +* [npm prune](/commands/npm-prune) diff --git a/docs/lib/content/using-npm/scope.md b/docs/lib/content/using-npm/scope.md new file mode 100644 index 0000000000000..ed069752b63ad --- /dev/null +++ b/docs/lib/content/using-npm/scope.md @@ -0,0 +1,123 @@ +--- +title: scope +section: 7 +description: Scoped packages +--- + +### Description + +All npm packages have a name. +Some package names also have a scope. +A scope follows the usual rules for package names (URL-safe characters, no leading dots or underscores). +When used in package names, scopes are preceded by an `@` symbol and followed by a slash, e.g. + +```bash +@somescope/somepackagename +``` + +Scopes are a way of grouping related packages together, and also affect a few things about the way npm treats the package. + +Each npm user/organization has their own scope, and only you can add packages in your scope. +This means you don't have to worry about someone taking your package name ahead of you. +Thus it is also a good way to signal official packages for organizations. + +Scoped packages can be published and installed as of `npm@2` and are supported by the primary npm registry. +Unscoped packages can depend on scoped packages and vice versa. +The npm client is backwards-compatible with unscoped registries, so it can be used to work with scoped and unscoped registries at the same time. + +### Installing scoped packages + +Scoped packages are installed to a sub-folder of the regular installation folder, e.g. if your other packages are installed in `node_modules/packagename`, scoped modules will be installed in `node_modules/@myorg/packagename`. +The scope folder (`@myorg`) is simply the name of the scope preceded by an `@` symbol, and can contain any number of scoped packages. + +A scoped package is installed by referencing it by name, preceded by an +`@` symbol, in `npm install`: + +```bash +npm install @myorg/mypackage +``` + +Or in `package.json`: + +```json +"dependencies": { + "@myorg/mypackage": "^1.3.0" +} +``` + +Note that if the `@` symbol is omitted, in either case, npm will instead attempt to install from GitHub; see [`npm install`](/commands/npm-install). + +### Requiring scoped packages + +Because scoped packages are installed into a scope folder, you have to include the name of the scope when requiring them in your code, e.g. + +```javascript +require('@myorg/mypackage') +``` + +There is nothing special about the way Node treats scope folders. +This simply requires the `mypackage` module in the folder named `@myorg`. + +### Publishing scoped packages + +Scoped packages can be published from the CLI as of `npm@2` and can be published to any registry that supports them, including the primary npm registry. + +(As of 2015-04-19, and with npm 2.0 or better, the primary npm registry +**does** support scoped packages.) + +If you wish, you may associate a scope with a registry; see below. + +#### Publishing public scoped packages to the primary npm registry + +Publishing to a scope, you have two options: + +- Publishing to your user scope (example: `@username/module`) +- Publishing to an organization scope (example: `@org/module`) + +If publishing a public module to an organization scope, you must first either create an organization with the name of the scope that you'd like to publish to or be added to an existing organization with the appropriate permissions. +For example, if you'd like to publish to `@org`, you would need to create the `org` organization on npmjs.com prior to trying to publish. + +Scoped packages are not public by default. +You will need to specify +`--access public` with the initial `npm publish` command. +This will publish the package and set access to `public` as if you had run `npm access public` after publishing. +You do not need to do this when publishing new versions of an existing scoped package. + +#### Publishing private scoped packages to the npm registry + +To publish a private scoped package to the npm registry, you must have an [npm Private Modules](https://docs.npmjs.com/private-modules/intro) account. + +You can then publish the module with `npm publish` or `npm publish +--access restricted`, and it will be present in the npm registry, with restricted access. +You can then change the access permissions, if desired, with `npm access` or on the npmjs.com website. + +### Associating a scope with a registry + +Scopes can be associated with a separate registry. +This allows you to seamlessly use a mix of packages from the primary npm registry and one or more private registries, such as [GitHub Packages](https://github.com/features/packages) or the open source [Verdaccio](https://verdaccio.org) project. + +You can associate a scope with a registry at login, e.g. + +```bash +npm login --registry=http://reg.example.com --scope=@myco +``` + +Scopes have a many-to-one relationship with registries: one registry can host multiple scopes, but a scope only ever points to one registry. + +You can also associate a scope with a registry using `npm config`: + +```bash +npm config set @myco:registry=http://reg.example.com +``` + +Once a scope is associated with a registry, any `npm install` for a package with that scope will request packages from that registry instead. +Any +`npm publish` for a package name that contains the scope will be published to +that registry instead. + +### See also + +* [npm install](/commands/npm-install) +* [npm publish](/commands/npm-publish) +* [npm access](/commands/npm-access) +* [npm registry](/using-npm/registry) diff --git a/docs/lib/content/using-npm/scripts.md b/docs/lib/content/using-npm/scripts.md new file mode 100644 index 0000000000000..1613d803ee3e9 --- /dev/null +++ b/docs/lib/content/using-npm/scripts.md @@ -0,0 +1,370 @@ +--- +title: scripts +section: 7 +description: How npm handles the "scripts" field +--- + +### Description + +The `"scripts"` property of your `package.json` file supports a number of built-in scripts and their preset life cycle events as well as arbitrary scripts. +These all can be executed by running `npm run <stage>`. +*Pre* and *post* commands with matching names will be run for those as well (e.g. +`premyscript`, +`myscript`, `postmyscript`). +Scripts from dependencies can be run with `npm explore <pkg> -- npm run <stage>`. + +### Pre & Post Scripts + +To create "pre" or "post" scripts for any scripts defined in the +`"scripts"` section of the `package.json`, simply create another script +*with a matching name* and add "pre" or "post" to the beginning of them. + +```json +{ + "scripts": { + "precompress": "{{ executes BEFORE the `compress` script }}", + "compress": "{{ run command to compress files }}", + "postcompress": "{{ executes AFTER `compress` script }}" + } +} +``` + +In this example `npm run compress` would execute these scripts as described. + +### Life Cycle Scripts + +There are some special life cycle scripts that happen only in certain situations. +These scripts happen in addition to the `pre<event>`, `post<event>`, and +`<event>` scripts. + +* `prepare`, `prepublish`, `prepublishOnly`, `prepack`, `postpack`, `dependencies` + +**prepare** (since `npm@4.0.0`) +* Runs BEFORE the package is packed, i.e. +during `npm publish` and `npm pack` +* Runs on local `npm install` without package arguments (runs with flags like `--production` or `--omit=dev`, but does not run when installing specific packages like `npm install express`) +* Runs AFTER `prepublishOnly` and `prepack`, but BEFORE `postpack` +* Runs for a package if it's being installed as a link through `npm install <folder>` + +* NOTE: If a package being installed through git contains a `prepare` script, its `dependencies` and `devDependencies` will be installed, and the prepare script will be run, before the package is packaged and installed. + +* As of `npm@7` these scripts run in the background. + To see the output, run with: `--foreground-scripts`. + +* **In workspaces, prepare scripts run concurrently** across all packages. If you have interdependent packages where one must build before another, consider using `--foreground-scripts` (which can be set in `.npmrc` with `foreground-scripts=true`) to run scripts sequentially, or structure your build differently. + +**prepublish** (DEPRECATED) +* Does not run during `npm publish`, but does run during `npm ci` and `npm install`. +See below for more info. + +**prepublishOnly** +* Runs BEFORE the package is prepared and packed, ONLY on `npm publish`. + +**prepack** +* Runs BEFORE a tarball is packed (on "`npm pack`", "`npm publish`", and when installing a git dependency). +* NOTE: "`npm run pack`" is NOT the same as "`npm pack`". "`npm run pack`" is an arbitrary user defined script name, whereas, "`npm pack`" is a CLI defined command. + +**postpack** +* Runs AFTER the tarball has been generated but before it is moved to its final destination (if at all, publish does not save the tarball locally) + +**dependencies** +* Runs AFTER any operations that modify the `node_modules` directory IF changes occurred. +* Does NOT run in global mode + +#### Prepare and Prepublish + +**Deprecation Note: prepublish** + +Since `npm@1.1.71`, the npm CLI has run the `prepublish` script for both `npm publish` and `npm install`, because it's a convenient way to prepare a package for use (some common use cases are described in the section below). +It has also turned out to be, in practice, [very confusing](https://github.com/npm/npm/issues/10074). +As of `npm@4.0.0`, a new event has been introduced, `prepare`, that preserves this existing behavior. +A _new_ event, `prepublishOnly` has been added as a transitional strategy to allow users to avoid the confusing behavior of existing npm versions and only run on `npm publish` (for instance, running the tests one last time to ensure they're in good shape). + +See <https://github.com/npm/npm/issues/10074> for a much lengthier justification, with further reading, for this change. + +**Use Cases** + +Use a `prepare` script to perform build tasks that are platform-independent and need to run before your package is used. +This includes tasks such as: + +* Compiling TypeScript or other source code into JavaScript. +* Creating minified versions of JavaScript source code. +* Fetching remote resources that your package will use. + +Running these build tasks in the `prepare` script ensures they happen once, in a single place, reducing complexity and variability. +Additionally, this means that: + +* You can depend on build tools as `devDependencies`, and thus your users don't need to have them installed. +* You don't need to include minifiers in your package, reducing the size for your users. +* You don't need to rely on your users having `curl` or `wget` or other system tools on the target machines. + +#### Dependencies + +The `dependencies` script is run any time an `npm` command causes changes to the `node_modules` directory. +It is run AFTER the changes have been applied and the `package.json` and `package-lock.json` files have been updated. + +### Life Cycle Operation Order + +#### [`npm cache add`](/commands/npm-cache) + +* `prepare` + +#### [`npm ci`](/commands/npm-ci) + +* `preinstall` +* `install` +* `postinstall` +* `prepublish` +* `preprepare` +* `prepare` +* `postprepare` + +These all run after the actual installation of modules into + `node_modules`, in order, with no internal actions happening in between + +#### [`npm diff`](/commands/npm-diff) + +* `prepare` + +#### [`npm install`](/commands/npm-install) + +These also run when you run `npm install -g <pkg-name>` + +* `preinstall` +* `install` +* `postinstall` +* `prepublish` +* `preprepare` +* `prepare` +* `postprepare` + +If there is a `binding.gyp` file in the root of your package and you haven't defined your own `install` or `preinstall` scripts, npm will default the `install` command to compile using node-gyp via `node-gyp rebuild` + +These are run from the scripts of `<pkg-name>` + +#### [`npm pack`](/commands/npm-pack) + +* `prepack` +* `prepare` +* `postpack` + +#### [`npm publish`](/commands/npm-publish) + +* `prepublishOnly` +* `prepack` +* `prepare` +* `postpack` +* `publish` +* `postpublish` + +#### [`npm rebuild`](/commands/npm-rebuild) + +* `preinstall` +* `install` +* `postinstall` +* `prepare` + +`prepare` is only run if the current directory is a symlink (e.g. +with linked packages) + +#### [`npm restart`](/commands/npm-restart) + +If there is a `restart` script defined, these events are run; otherwise, +`stop` and `start` are both run if present, including their `pre` and `post` iterations) + +* `prerestart` +* `restart` +* `postrestart` + +#### [`npm run <user defined>`](/commands/npm-run) + +* `pre<user-defined>` +* `<user-defined>` +* `post<user-defined>` + +#### [`npm start`](/commands/npm-start) + +* `prestart` +* `start` +* `poststart` + +If there is a `server.js` file in the root of your package, then npm will default the `start` command to `node server.js`. +`prestart` and `poststart` will still run in this case. + +#### [`npm stop`](/commands/npm-stop) + +* `prestop` +* `stop` +* `poststop` + +#### [`npm test`](/commands/npm-test) + +* `pretest` +* `test` +* `posttest` + +#### [`npm version`](/commands/npm-version) + +* `preversion` +* `version` +* `postversion` + +#### A Note on a lack of [`npm uninstall`](/commands/npm-uninstall) scripts + +While npm v6 had `uninstall` lifecycle scripts, npm v7 does not. +Removal of a package can happen for a wide variety of reasons, and there's no clear way to currently give the script enough context to be useful. + + +Reasons for a package removal include: + +* a user directly uninstalled this package +* a user uninstalled a dependent package and so this dependency is being uninstalled +* a user uninstalled a dependent package but another package also depends on this version +* this version has been merged as a duplicate with another version +* etc. + +Due to the lack of necessary context, `uninstall` lifecycle scripts are not implemented and will not function. + +### Working Directory for Scripts + +Scripts are always run from the root of the package folder, regardless of what the current working directory is when `npm` is invoked. +This means your scripts can reliably assume they are running in the package root. + +If you want your script to behave differently based on the directory you were in when you ran `npm`, you can use the `INIT_CWD` environment variable, which holds the full path you were in when you ran `npm run`. + +#### Historical Behavior in Older npm Versions + +For npm v6 and earlier, scripts were generally run from the root of the package, but there were rare cases and bugs in older versions where this was not guaranteed. +If your package must support very old npm versions, you may wish to add a safeguard in your scripts (for example, by checking process.cwd()). + +For more details, see: +- [npm v7 release notes](https://github.com/npm/cli/releases/tag/v7.0.0) +- [Discussion about script working directory reliability in npm v6 and earlier](https://github.com/npm/npm/issues/12356) + +### User + +When npm is run as root, scripts are always run with the effective uid and gid of the working directory owner. + +### Environment + +Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of the process. + +#### path + +If you depend on modules that define executable scripts, like test suites, then those executables will be added to the `PATH` for executing the scripts. +So, if your package.json has this: + +```json +{ + "name" : "foo", + "dependencies" : { + "bar" : "0.1.x" + }, + "scripts": { + "start" : "bar ./test" + } +} +``` + +then you could run `npm start` to execute the `bar` script, which is exported into the `node_modules/.bin` directory on `npm install`. + +#### package.json vars + +npm sets the following environment variables from the package.json: + +* `npm_package_name` - The package name +* `npm_package_version` - The package version +* `npm_package_bin_*` - Each executable defined in the bin field +* `npm_package_engines_*` - Each engine defined in the engines field +* `npm_package_config_*` - Each config value defined in the config field +* `npm_package_json` - The full path to the package.json file + +Additionally, for install scripts (`preinstall`, `install`, `postinstall`), npm sets these environment variables: + +* `npm_package_resolved` - The resolved URL for the package +* `npm_package_integrity` - The integrity hash for the package +* `npm_package_optional` - Set to `"true"` if the package is optional +* `npm_package_dev` - Set to `"true"` if the package is a dev dependency +* `npm_package_peer` - Set to `"true"` if the package is a peer dependency +* `npm_package_dev_optional` - Set to `"true"` if the package is both dev and optional + +For example, if you had `{"name":"foo", "version":"1.2.5"}` in your package.json file, then your package scripts would have the `npm_package_name` environment variable set to "foo", and the `npm_package_version` set to "1.2.5". You can access these variables in your code with `process.env.npm_package_name` and `process.env.npm_package_version`. + +**Note:** In npm 7 and later, most package.json fields are no longer provided as environment variables. Scripts that need access to other package.json fields should read the package.json file directly. The `npm_package_json` environment variable provides the path to the file for this purpose. + +See [`package.json`](/configuring-npm/package-json) for more on package configs. + +#### current lifecycle event + +Lastly, the `npm_lifecycle_event` environment variable is set to whichever stage of the cycle is being executed. +So, you could have a single script used for different parts of the process which switches based on what's currently happening. + +Objects are flattened following this format, so if you had +`{"scripts":{"install":"foo.js"}}` in your package.json, then you'd see this in the script: + +```bash +process.env.npm_package_scripts_install === "foo.js" +``` + +### Examples + +For example, if your package.json contains this: + +```json +{ + "scripts" : { + "prepare" : "scripts/build.js", + "test" : "scripts/test.js" + } +} +``` + +then `scripts/build.js` will be called for the prepare stage of the lifecycle, and you can check the +`npm_lifecycle_event` environment variable if your script needs to behave differently in different contexts. + +If you want to run build commands, you can do so. +This works just fine: + +```json +{ + "scripts" : { + "prepare" : "npm run build", + "build" : "tsc", + "test" : "jest" + } +} +``` + +### Exiting + +Scripts are run by passing the line as a script argument to `/bin/sh` on POSIX systems or `cmd.exe` on Windows. +You can control which shell is used by setting the [`script-shell`](/using-npm/config#script-shell) configuration option. + +If the script exits with a code other than 0, then this will abort the process. + +Note that these script files don't have to be Node.js or even JavaScript programs. +They just have to be some kind of executable file. + +### Best Practices + +* Don't exit with a non-zero error code unless you *really* mean it. + If the failure is minor or only will prevent some optional features, then it's better to just print a warning and exit successfully. +* Try not to use scripts to do what npm can do for you. +Read through [`package.json`](/configuring-npm/package-json) to see all the things that you can specify and enable by simply describing your package appropriately. +In general, this will lead to a more robust and consistent state. +* Inspect the env to determine where to put things. +For instance, if the `NPM_CONFIG_BINROOT` environment variable is set to `/home/user/bin`, then don't try to install executables into `/usr/local/bin`. +The user probably set it up that way for a reason. +* Don't prefix your script commands with "sudo". If root permissions are required for some reason, then it'll fail with that error, and the user will sudo the npm command in question. +* Don't use `install`. +Use a `.gyp` file for compilation, and `prepare` for anything else. +You should almost never have to explicitly set a preinstall or install script. +If you are doing this, please consider if there is another option. +The only valid use of `install` or `preinstall` scripts is for compilation which must be done on the target architecture. + +### See Also + +* [npm run](/commands/npm-run) +* [package.json](/configuring-npm/package-json) +* [npm developers](/using-npm/developers) +* [npm install](/commands/npm-install) diff --git a/docs/lib/content/using-npm/workspaces.md b/docs/lib/content/using-npm/workspaces.md new file mode 100644 index 0000000000000..91d0f99745a25 --- /dev/null +++ b/docs/lib/content/using-npm/workspaces.md @@ -0,0 +1,218 @@ +--- +title: workspaces +section: 7 +description: Working with workspaces +--- + +### Description + +**Workspaces** is a generic term that refers to the set of features in the npm cli that provides support for managing multiple packages from your local file system from within a singular top-level, root package. + +This set of features makes up for a much more streamlined workflow handling linked packages from the local file system. +It automates the linking process as part of `npm install` and removes the need to manually use `npm link` in order to add references to packages that should be symlinked into the current `node_modules` folder. + +We also refer to these packages being auto-symlinked during `npm install` as a single **workspace**, meaning it's a nested package within the current local file system that is explicitly defined in the [`package.json`](/configuring-npm/package-json#workspaces) +`workspaces` configuration. + +### Defining workspaces + +Workspaces are usually defined via the `workspaces` property of the [`package.json`](/configuring-npm/package-json#workspaces) file, e.g: + +```json +{ + "name": "my-workspaces-powered-project", + "workspaces": [ + "packages/a" + ] +} +``` + +Given the above `package.json` example living at a current working directory `.` that contains a folder named `packages/a` that itself contains a `package.json` inside it, defining a Node.js package, e.g: + +``` +. ++-- package.json +`-- packages + +-- a + | `-- package.json +``` + +The expected result once running `npm install` in this current working directory `.` is that the folder `packages/a` will get symlinked to the `node_modules` folder of the current working dir. + +Below is a post `npm install` example, given that same previous example structure of files and folders: + +``` +. ++-- node_modules +| `-- a -> ../packages/a ++-- package-lock.json ++-- package.json +`-- packages + +-- a + | `-- package.json +``` + +### Getting started with workspaces + +You may automate the required steps to define a new workspace using [npm init](/commands/npm-init). +For example in a project that already has a `package.json` defined you can run: + +``` +npm init -w ./packages/a +``` + +This command will create the missing folders and a new `package.json` file (if needed) while also making sure to properly configure the +`"workspaces"` property of your root project `package.json`. + +### Adding dependencies to a workspace + +It's possible to directly add/remove/update dependencies of your workspaces using the [`workspace` config](/using-npm/config#workspace). + +For example, assuming the following structure: + +``` +. ++-- package.json +`-- packages + +-- a + | `-- package.json + `-- b + `-- package.json +``` + +If you want to add a dependency named `abbrev` from the registry as a dependency of your workspace **a**, you may use the workspace config to tell the npm installer that package should be added as a dependency of the provided workspace: + +``` +npm install abbrev -w a +``` + +**Adding a workspace as a dependency of another workspace:** + +If you want to add workspace **b** as a dependency of workspace **a**, you can use the workspace protocol in the dependency specifier: + +``` +npm install b@workspace:* -w a +``` + +This will add an entry to workspace **a**'s `package.json` like: + +```json +{ + "dependencies": { + "b": "workspace:*" + } +} +``` + +The `workspace:` protocol tells npm to link to the local workspace rather than fetching from the registry. The `*` version means it will use whatever version is defined in workspace **b**'s `package.json`. + +Note: other installing commands such as `uninstall`, `ci`, etc will also respect the provided `workspace` configuration. + +### Using workspaces + +Given the [specifics of how Node.js handles module resolution](https://nodejs.org/dist/latest-v14.x/docs/api/modules.html#modules_all_together) it's possible to consume any defined workspace by its declared `package.json` `name`. +Continuing from the example defined above, let's also create a Node.js script that will require the workspace `a` example module, e.g: + +``` +// ./packages/a/index.js +module.exports = 'a' + +// ./lib/index.js +const moduleA = require('a') +console.log(moduleA) // -> a +``` + +When running it with: + +`node lib/index.js` + +This demonstrates how the nature of `node_modules` resolution allows for +**workspaces** to enable a portable workflow for requiring each **workspace** in such a way that is also easy to [publish](/commands/npm-publish) these nested workspaces to be consumed elsewhere. + +### Running commands in the context of workspaces + +You can use the `workspace` configuration option to run commands in the context of a configured workspace. +Additionally, if your current directory is in a workspace, the `workspace` configuration is implicitly set, and `prefix` is set to the root workspace. + +Following is a quick example on how to use the `npm run` command in the context of nested workspaces. +For a project containing multiple workspaces, e.g: + +``` +. ++-- package.json +`-- packages + +-- a + | `-- package.json + `-- b + `-- package.json +``` + +By running a command using the `workspace` option, it's possible to run the given command in the context of that specific workspace. +e.g: + +``` +npm run test --workspace=a +``` + +You could also run the command within the workspace. + +``` +cd packages/a && npm run test +``` + +Either will run the `test` script defined within the +`./packages/a/package.json` file. + +Please note that you can also specify this argument multiple times in the command-line in order to target multiple workspaces, e.g: + +``` +npm run test --workspace=a --workspace=b +``` + +Or run the command for each workspace within the 'packages' folder: +``` +npm run test --workspace=packages +``` + +It's also possible to use the `workspaces` (plural) configuration option to enable the same behavior but running that command in the context of **all** configured workspaces. +e.g: + +``` +npm run test --workspaces +``` + +Will run the `test` script in both `./packages/a` and `./packages/b`. + +Commands will be run in each workspace in the order they appear in your `package.json` + +``` +{ + "workspaces": [ "packages/a", "packages/b" ] +} +``` + +Order of run is different with: + +``` +{ + "workspaces": [ "packages/b", "packages/a" ] +} +``` + +### Ignoring missing scripts + +It is not required for all of the workspaces to implement scripts run with the `npm run` command. + +By running the command with the `--if-present` flag, npm will ignore workspaces missing target script. + +``` +npm run test --workspaces --if-present +``` + +### See also + +* [npm install](/commands/npm-install) +* [npm publish](/commands/npm-publish) +* [npm run](/commands/npm-run) +* [config](/using-npm/config) + diff --git a/docs/lib/index.js b/docs/lib/index.js new file mode 100644 index 0000000000000..5e40f48882cad --- /dev/null +++ b/docs/lib/index.js @@ -0,0 +1,189 @@ +const localeCompare = require('@isaacs/string-locale-compare')('en') +const { join, basename, resolve } = require('path') +const transformHTML = require('./transform-html.js') +const { version } = require('../../lib/npm.js') +const { aliases } = require('../../lib/utils/cmd-list') +const { shorthands, definitions } = require('@npmcli/config/lib/definitions') + +const DOC_EXT = '.md' + +const TAGS = { + CONFIG: '<!-- AUTOGENERATED CONFIG DESCRIPTIONS -->', + USAGE: '<!-- AUTOGENERATED USAGE DESCRIPTIONS -->', + SHORTHANDS: '<!-- AUTOGENERATED CONFIG SHORTHANDS -->', +} + +const assertPlaceholder = (src, path, placeholder) => { + if (!src.includes(placeholder)) { + throw new Error( + `Cannot replace ${placeholder} in ${path} due to missing placeholder` + ) + } + return placeholder +} + +const getCommandByDoc = (docFile, docExt) => { + // Grab the command name from the *.md filename + // NOTE: We cannot use the name property command file because in the case of + // `npx` the file being used is `lib/commands/exec.js` + const name = basename(docFile, docExt).replace('npm-', '') + + if (name === 'npm') { + return { + name, + params: null, + usage: 'npm', + } + } + + // special case for `npx`: + // `npx` is not technically a command in and of itself, + // so it just needs the usage of npm exec + const srcName = name === 'npx' ? 'exec' : name + const { params, usage = [''], workspaces } = require(`../../lib/commands/${srcName}`) + const usagePrefix = name === 'npx' ? 'npx' : `npm ${name}` + if (params) { + for (const param of params) { + if (definitions[param].exclusive) { + for (const e of definitions[param].exclusive) { + if (!params.includes(e)) { + params.splice(params.indexOf(param) + 1, 0, e) + } + } + } + } + } + + return { + name, + workspaces, + params: name === 'npx' ? null : params, + usage: usage.map(u => `${usagePrefix} ${u}`.trim()).join('\n'), + } +} + +const replaceVersion = (src) => src.replace(/@VERSION@/g, version) + +const replaceUsage = (src, { path }) => { + const replacer = assertPlaceholder(src, path, TAGS.USAGE) + const { usage, name, workspaces } = getCommandByDoc(path, DOC_EXT) + + const synopsis = ['```bash', usage] + + const cmdAliases = Object.keys(aliases).reduce((p, c) => { + if (aliases[c] === name) { + p.push(c) + } + return p + }, []) + + if (cmdAliases.length === 1) { + synopsis.push('', `alias: ${cmdAliases[0]}`) + } else if (cmdAliases.length > 1) { + synopsis.push('', `aliases: ${cmdAliases.join(', ')}`) + } + + synopsis.push('```') + + if (!workspaces) { + synopsis.push('', 'Note: This command is unaware of workspaces.') + } + + return src.replace(replacer, synopsis.join('\n')) +} + +const replaceParams = (src, { path }) => { + const { params } = getCommandByDoc(path, DOC_EXT) + const replacer = params && assertPlaceholder(src, path, TAGS.CONFIG) + + if (!params) { + return src + } + + const paramsConfig = params.map((n) => definitions[n].describe()) + + return src.replace(replacer, paramsConfig.join('\n\n')) +} + +const replaceConfig = (src, { path }) => { + const replacer = assertPlaceholder(src, path, TAGS.CONFIG) + + // sort not-deprecated ones to the top + /* istanbul ignore next - typically already sorted in the definitions file, + * but this is here so that our help doc will stay consistent if we decide + * to move them around. */ + const sort = ([keya, { deprecated: depa }], [keyb, { deprecated: depb }]) => { + return depa && !depb ? 1 + : !depa && depb ? -1 + : localeCompare(keya, keyb) + } + + const allConfig = Object.entries(definitions).sort(sort) + .map(([, def]) => def.describe()) + .join('\n\n') + + return src.replace(replacer, allConfig) +} + +const replaceShorthands = (src, { path }) => { + const replacer = assertPlaceholder(src, path, TAGS.SHORTHANDS) + + const sh = Object.entries(shorthands) + .sort(([shorta, expansiona], [shortb, expansionb]) => + // sort by what they're short FOR + localeCompare(expansiona.join(' '), expansionb.join(' ')) || localeCompare(shorta, shortb) + ) + .map(([short, expansion]) => { + // XXX: this is incorrect. we have multicharacter flags like `-iwr` that + // can only be set with a single dash + const dash = short.length === 1 ? '-' : '--' + return `* \`${dash}${short}\`: \`${expansion.join(' ')}\`` + }) + + return src.replace(replacer, sh.join('\n')) +} + +const replaceHelpLinks = (src) => { + // replaces markdown links with equivalent-ish npm help commands + return src.replace( + /\[`?([\w\s-]+)`?\]\(\/(?:commands|configuring-npm|using-npm)\/(?:[\w\s-]+)\)/g, + (_, p1) => { + const term = p1.replace(/npm\s/g, '').replace(/\s+/g, ' ').trim() + const help = `npm help ${term.includes(' ') ? `"${term}"` : term}` + return help + } + ) +} + +const transformMan = (src, { data, unified, remarkParse, remarkMan }) => unified() + .use(remarkParse) + .use(remarkMan, { version: `NPM@${version}` }) + .processSync(`# ${data.title}(${data.section}) - ${data.description}\n\n${src}`) + .toString() + +const manPath = (name, { data }) => join(`man${data.section}`, `${name}.${data.section}`) + +const transformMd = (src, { frontmatter }) => ['---', frontmatter, '---', '', src].join('\n') + +module.exports = { + DOC_EXT, + TAGS, + paths: { + content: resolve(__dirname, 'content'), + nav: resolve(__dirname, 'content', 'nav.yml'), + template: resolve(__dirname, 'template.html'), + man: resolve(__dirname, '..', '..', 'man'), + html: resolve(__dirname, '..', 'output'), + md: resolve(__dirname, '..', 'content'), + }, + usage: replaceUsage, + params: replaceParams, + config: replaceConfig, + shorthands: replaceShorthands, + version: replaceVersion, + helpLinks: replaceHelpLinks, + man: transformMan, + manPath: manPath, + md: transformMd, + html: transformHTML, +} diff --git a/docs/lib/npm.js b/docs/lib/npm.js deleted file mode 100644 index fb801a17bea46..0000000000000 --- a/docs/lib/npm.js +++ /dev/null @@ -1,14 +0,0 @@ -const { definitions, shorthands, describeAll } = require('../../lib/utils/config/index.js') -const { aliases } = require('../../lib/utils/cmd-list') -const Npm = require('../../lib/npm.js') - -// These are all the npm internals depended on by the docs scripts. If these change -// the associated targets should also be updated in the Makefile. - -module.exports = { - definitions, - shorthands, - describeAll, - aliases, - version: Npm.version, -} diff --git a/docs/lib/template.html b/docs/lib/template.html index be3bafd61aa05..622dc327046ee 100644 --- a/docs/lib/template.html +++ b/docs/lib/template.html @@ -115,6 +115,11 @@ line-height: 1; } +header.title .version { + font-size: 0.8em; + color: #666666; +} + footer#edit { border-top: solid 1px #e1e4e8; margin: 3em 0 4em 0; @@ -138,7 +143,10 @@ <section id="content"> <header class="title"> -<h1>{{ title }}</h1> +<h1> + <span>{{ title }}</span> + <span class="version">@{{ version }}</span> +</h1> <span class="description">{{ description }}</span> </header> diff --git a/docs/lib/transform-html.js b/docs/lib/transform-html.js new file mode 100644 index 0000000000000..dc3dd4930d05d --- /dev/null +++ b/docs/lib/transform-html.js @@ -0,0 +1,161 @@ +const jsdom = require('jsdom') +const { version } = require('../../package.json') + +function transformHTML ( + src, + { path, template, data, unified, remarkParse, remarkGfm, remarkRehype, rehypeStringify } +) { + const content = unified() + .use(remarkParse) + .use(remarkGfm, { + singleTilde: false, + }) + .use(remarkRehype) + .use(rehypeStringify) + .processSync(src) + .toString() + + // Inject this data into the template, using a mustache-like + // replacement scheme. + const html = template.replace(/{{\s*([\w.]+)\s*}}/g, (token, key) => { + switch (key) { + case 'content': + return `<div id="_content">${content}</div>` + case 'url_path': + return encodeURI(path) + + case 'toc': + return '<div id="_table_of_contents"></div>' + + case 'title': + case 'section': + case 'description': + return data[key] + + case 'config.github_repo': + case 'config.github_branch': + case 'config.github_path': + return data[key.replace(/^config\./, '')] + + case 'version': + return version + + default: + throw new Error(`warning: unknown token '${token}' in ${path}`) + } + }) + + const dom = new jsdom.JSDOM(html) + const document = dom.window.document + + // Rewrite relative URLs in links and image sources to be relative to + // this file; this is for supporting `file://` links. HTML pages need + // suffix appended. + const links = [ + { tag: 'a', attr: 'href', suffix: '.html' }, + { tag: 'img', attr: 'src' }, + ] + + for (const linktype of links) { + for (const tag of document.querySelectorAll(linktype.tag)) { + let url = tag.getAttribute(linktype.attr) + + if (url.startsWith('/')) { + const childDepth = path.split('/').length - 1 + const prefix = childDepth > 0 ? '../'.repeat(childDepth) : './' + + url = url.replace(/^\//, prefix) + + if (linktype.suffix) { + url += linktype.suffix + } + + tag.setAttribute(linktype.attr, url) + } + } + } + + // Give headers a unique id so that they can be linked within the doc + const headerIds = [] + for (const header of document.querySelectorAll('h1, h2, h3, h4, h5, h6')) { + const headerText = header.textContent + .replace(/[A-Z]/g, x => x.toLowerCase()) + .replace(/ /g, '-') + .replace(/[^a-z0-9-]/g, '') + let headerId = headerText + let headerIncrement = 1 + + while (document.getElementById(headerId) !== null) { + headerId = headerText + ++headerIncrement + } + + headerIds.push(headerId) + header.setAttribute('id', headerId) + } + + // Walk the dom and build a table of contents + const tocEl = document.getElementById('_table_of_contents') + if (tocEl) { + const toc = generateTableOfContents(document) + if (toc) { + tocEl.appendChild(toc) + } + } + + return dom.serialize() +} + +function generateTableOfContents (document) { + const headers = walkHeaders(document.getElementById('_content')) + + // The nesting depth of headers are not necessarily the header level. + // (eg, h1 > h3 > h5 is a depth of three even though there's an h5.) + const hierarchy = [] + for (const header of headers) { + const level = headerLevel(header) + + while (hierarchy.length && hierarchy[hierarchy.length - 1].headerLevel > level) { + hierarchy.pop() + } + + if (!hierarchy.length || hierarchy[hierarchy.length - 1].headerLevel < level) { + const newList = document.createElement('ul') + newList.headerLevel = level + + if (hierarchy.length) { + hierarchy[hierarchy.length - 1].appendChild(newList) + } + + hierarchy.push(newList) + } + + const element = document.createElement('li') + + const link = document.createElement('a') + link.setAttribute('href', `#${header.getAttribute('id')}`) + link.innerHTML = header.innerHTML + element.appendChild(link) + + hierarchy[hierarchy.length - 1].appendChild(element) + } + + return hierarchy[0] +} + +function walkHeaders (element, headers = []) { + for (const child of element.childNodes) { + if (headerLevel(child)) { + headers.push(child) + } + + walkHeaders(child, headers) + } + return headers +} + +function headerLevel (node) { + const level = node.tagName ? node.tagName.match(/^[Hh]([123456])$/) : null + return level ? level[1] : 0 +} + +module.exports = transformHTML diff --git a/docs/package.json b/docs/package.json index ba913b1ea6844..7787ef241940b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,65 +1,67 @@ { - "name": "docs", + "name": "@npmcli/docs", "description": "The npm cli documentation", "version": "1.0.0", "private": true, + "main": "lib/index.js", "scripts": { - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "snap": "tap", "test": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "build": "node bin/build.js", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "docs" }, "devDependencies": { - "@mdx-js/mdx": "^1.6.22", - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/fs": "^2.1.0", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.5.0", - "cmark-gfm": "^0.9.0", - "jsdom": "^18.1.0", - "marked-man": "^0.7.0", - "tap": "^16.0.1", - "which": "^2.0.2", - "yaml": "^1.10.0" + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "front-matter": "^4.0.2", + "ignore-walk": "^8.0.0", + "jsdom": "27.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-man": "^9.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "semver": "^7.3.8", + "tap": "^16.3.8", + "unified": "^11.0.5", + "yaml": "^2.2.1" }, "author": "GitHub Inc.", "license": "ISC", "files": [ "bin/", - "lib/", - "content/", - "nav.yml" + "lib/" ], "engines": { - "node": ">=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "tap": { - "statements": 81, - "branches": 72, - "functions": 75, - "lines": 81 + "timeout": 600, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "distPaths": [ - "bin/", - "lib/", - "content/", - "nav.yml" - ], - "ciVersions": [ - "16" - ], - "version": "3.5.0" + "ciVersions": "latest", + "version": "4.25.1", + "content": "../scripts/template-oss/index.js", + "workspaceRepo": { + "add": { + ".github/workflows/ci-{{ pkgNameFs }}.yml": "ci-npmcli-docs-yml.hbs" + } + } } } diff --git a/docs/test/index.js b/docs/test/index.js index 57524327bfcbf..be537e68b2a18 100644 --- a/docs/test/index.js +++ b/docs/test/index.js @@ -1,37 +1,111 @@ const t = require('tap') -const spawn = require('@npmcli/promise-spawn') -const fs = require('@npmcli/fs') -const { resolve, join } = require('path') -const which = require('which').sync +const { join } = require('path') +const walk = require('ignore-walk') +const { paths: { content: CONTENT_DIR, nav: NAV, template: TEMPLATE } } = require('../lib/index.js') -const cwd = resolve(__dirname, '..') -const output = join(cwd, 'output') +const testBuildDocs = async (t, { verify, ...opts } = {}) => { + const mockedBuild = require('../lib/build.js') -const rmOutput = () => fs.rm(output, { recursive: true, force: true }).catch(() => {}) + const fixtures = { + man: {}, + html: {}, + md: {}, + ...opts, + } -const spawnNpm = (cmd, ...args) => { - // remove npm config when spawning so config set by test commands don't interfere - const env = Object.entries(process.env) - .filter(([k]) => k.toLowerCase() !== 'npm_config_ignore_scripts') + const root = t.testdir(fixtures) - return spawn(which(cmd), args, { - env: Object.fromEntries(env), - stdioString: true, - cwd, - }) + const paths = { + content: fixtures.content ? join(root, 'content') : CONTENT_DIR, + template: fixtures.template ? join(root, 'template') : TEMPLATE, + nav: fixtures.nav ? join(root, 'nav') : NAV, + man: join(root, 'man'), + html: join(root, 'html'), + md: join(root, 'md'), + } + + return { + results: await mockedBuild({ ...paths, verify }), + root, + ...paths, + } } -t.before(() => spawnNpm('npm', 'rebuild', 'cmark-gfm')) -t.beforeEach(() => rmOutput()) +t.test('builds and verifies the real docs', async (t) => { + const { man, html, md, results } = await testBuildDocs(t, { verify: true }) + + const allFiles = (await Promise.all([ + walk({ path: man }).then(r => r.length), + walk({ path: html }).then(r => r.length), + walk({ path: md }).then(r => r.length), + ])).reduce((a, b) => a + b, 0) + + t.equal(allFiles, results.length) +}) -t.test('docs', async (t) => { - t.rejects(() => fs.stat(output)) - const docs = await spawnNpm('node', join('bin', 'dockhand')) - t.equal(docs.code, 0) - t.ok((await fs.stat(output)).isDirectory()) +t.test('fails on mismatched nav', async t => { + await t.rejects(() => testBuildDocs(t, { + content: { 'test.md': '' }, + nav: '- url: /test2', + }), 'Documentation navigation (nav.yml) does not match filesystem') }) -t.test('files used by documention repo', async (t) => { - t.ok((await fs.stat(join(cwd, 'content'))).isDirectory()) - t.ok((await fs.stat(join(cwd, 'nav.yml'))).isFile()) +t.test('missing placeholders', async t => { + t.test('command', async t => { + await t.rejects(testBuildDocs(t, { + content: { + commands: { 'npm-access.md': '<!-- AUTOGENERATED USAGE DESCRIPTIONS -->' }, + }, + }), /npm-access\.md/) + await t.rejects(testBuildDocs(t, { + content: { + commands: { 'npm-access.md': '<!-- AUTOGENERATED CONFIG DESCRIPTIONS -->' }, + }, + }), /npm-access\.md/) + }) + + t.test('definitions', async t => { + await t.rejects(testBuildDocs(t, { + content: { + 'using-npm': { 'config.md': '<!-- AUTOGENERATED CONFIG SHORTHANDS -->' }, + }, + }), /config\.md/) + await t.rejects(testBuildDocs(t, { + content: { + 'using-npm': { 'config.md': '<!-- AUTOGENERATED CONFIG DESCRIPTIONS -->' }, + }, + }), /config\.md/) + }) +}) + +t.test('html', async t => { + // these don't happen anywhere in the docs so test this for coverage + // but we test for coverage + t.test('files can link to root pages', async t => { + await testBuildDocs(t, { + content: { 'test.md': '[Test](/test)' }, + nav: '- url: /test', + }) + }) + + t.test('succeeds with empty content', async t => { + await testBuildDocs(t, { + content: { 'test.md': '' }, + nav: '- url: /test', + template: '{{ content }}', + }) + }) + + t.test('fails on missing vars in template', async t => { + await t.rejects(() => testBuildDocs(t, { + template: '{{ hello }}', + }), /\{\{ hello \}\}/) + }) + + t.test('rewrites img src', async t => { + await testBuildDocs(t, { + content: { 'test.md': '![](/src)' }, + nav: '- url: /test', + }) + }) }) diff --git a/lib/arborist-cmd.js b/lib/arborist-cmd.js index 5007fbd9244d2..f0167887b0699 100644 --- a/lib/arborist-cmd.js +++ b/lib/arborist-cmd.js @@ -1,8 +1,9 @@ +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 @@ -15,10 +16,36 @@ class ArboristCmd extends BaseCommand { 'install-links', ] + static workspaces = true static ignoreImplicitWorkspace = false + static checkDevEngines = true + + constructor (npm) { + super(npm) + + const { config } = this.npm + + // when location isn't set and global isn't true check for a package.json at + // the localPrefix and set the location to project if found + const locationProject = config.get('location') === 'project' || ( + config.isDefault('location') + // this is different then `npm.global` which falls back to checking + // location which we do not want to use here + && !config.get('global') + && npm.localPackage + ) + + // if audit is not set and we are in global mode and location is not project + // and we assume its not a project related context, then we set audit=false + if (config.isDefault('audit') && (this.npm.global || !locationProject)) { + config.set('audit', false) + } else if (this.npm.global && config.get('audit')) { + log.warn('config', 'includes both --global and --audit, which is currently unsupported.') + } + } - async execWorkspaces (args, filters) { - await this.setWorkspaces(filters) + async execWorkspaces (args) { + await this.setWorkspaces() return this.exec(args) } } diff --git a/lib/auth/legacy.js b/lib/auth/legacy.js deleted file mode 100644 index 9aed12f3926fb..0000000000000 --- a/lib/auth/legacy.js +++ /dev/null @@ -1,100 +0,0 @@ -const profile = require('npm-profile') -const log = require('../utils/log-shim') -const openUrlPrompt = require('../utils/open-url-prompt.js') -const read = require('../utils/read-user-info.js') - -const loginPrompter = async (creds) => { - creds.username = await read.username('Username:', creds.username) - creds.password = await read.password('Password:', creds.password) - creds.email = await read.email('Email: (this IS public) ', creds.email) - - return creds -} - -const login = async (npm, opts) => { - let res - - const requestOTP = async () => { - const otp = await read.otp( - 'Enter one-time password: ' - ) - - return profile.loginCouch( - opts.creds.username, - opts.creds.password, - { ...opts, otp } - ) - } - - const addNewUser = async () => { - let newUser - - try { - newUser = await profile.adduserCouch( - opts.creds.username, - opts.creds.email, - opts.creds.password, - opts - ) - } catch (err) { - if (err.code === 'EOTP') { - newUser = await requestOTP() - } else { - throw err - } - } - - return newUser - } - - const openerPromise = (url, emitter) => - openUrlPrompt( - npm, - url, - 'Authenticate your account at', - 'Press ENTER to open in the browser...', - emitter - ) - - try { - res = await profile.login(openerPromise, loginPrompter, opts) - } catch (err) { - const needsMoreInfo = !(opts && - opts.creds && - opts.creds.username && - opts.creds.password && - opts.creds.email) - if (err.code === 'EOTP') { - res = await requestOTP() - } else if (needsMoreInfo) { - throw err - } else { - // TODO: maybe this needs to check for err.code === 'E400' instead? - res = await addNewUser() - } - } - - const newCreds = {} - if (res && res.token) { - newCreds.token = res.token - } else { - newCreds.username = opts.creds.username - newCreds.password = opts.creds.password - newCreds.email = opts.creds.email - newCreds.alwaysAuth = opts.creds.alwaysAuth - } - - const usermsg = opts.creds.username ? ` user ${opts.creds.username}` : '' - const scopeMessage = opts.scope ? ` to scope ${opts.scope}` : '' - const userout = opts.creds.username ? ` as ${opts.creds.username}` : '' - const message = `Logged in${userout}${scopeMessage} on ${opts.registry}.` - - log.info('login', `Authorized${usermsg}`) - - return { - message, - newCreds, - } -} - -module.exports = login diff --git a/lib/auth/oauth.js b/lib/auth/oauth.js deleted file mode 100644 index 99c2ca0ca04b7..0000000000000 --- a/lib/auth/oauth.js +++ /dev/null @@ -1,8 +0,0 @@ -const sso = require('./sso.js') - -const login = (npm, opts) => { - npm.config.set('sso-type', 'oauth') - return sso(npm, opts) -} - -module.exports = login diff --git a/lib/auth/saml.js b/lib/auth/saml.js deleted file mode 100644 index 3dd31ca013f52..0000000000000 --- a/lib/auth/saml.js +++ /dev/null @@ -1,8 +0,0 @@ -const sso = require('./sso.js') - -const login = (npm, opts) => { - npm.config.set('sso-type', 'saml') - return sso(npm, opts) -} - -module.exports = login diff --git a/lib/auth/sso.js b/lib/auth/sso.js deleted file mode 100644 index 621ead5d21b65..0000000000000 --- a/lib/auth/sso.js +++ /dev/null @@ -1,81 +0,0 @@ -// XXX: To date, npm Enterprise Legacy is the only system that ever -// implemented support for this type of login. A better way to do -// SSO is to use the WebLogin type of login supported by the npm-login -// module. This more forward-looking login style is, ironically, -// supported by the '--auth-type=legacy' type of login. -// When and if npm Enterprise Legacy is no longer supported by the npm -// CLI, we can remove this, and fold the lib/auth/legacy.js back into -// lib/adduser.js - -const profile = require('npm-profile') -const npmFetch = require('npm-registry-fetch') -const log = require('../utils/log-shim') -const openUrl = require('../utils/open-url.js') -const otplease = require('../utils/otplease.js') - -const pollForSession = ({ registry, token, opts }) => { - log.info('adduser', 'Polling for validated SSO session') - return npmFetch.json( - '/-/whoami', { ...opts, registry, forceAuth: { token } } - ).then( - ({ username }) => username, - err => { - if (err.code === 'E401') { - return sleep(opts.ssoPollFrequency).then(() => { - return pollForSession({ registry, token, opts }) - }) - } else { - throw err - } - } - ) -} - -function sleep (time) { - return new Promise((resolve) => setTimeout(resolve, time)) -} - -const login = async (npm, { creds, registry, scope }) => { - const opts = { ...npm.flatOptions, creds, registry, scope } - const { ssoType } = opts - - if (!ssoType) { - throw new Error('Missing option: sso-type') - } - - // We're reusing the legacy login endpoint, so we need some dummy - // stuff here to pass validation. They're never used. - const auth = { - username: 'npm_' + ssoType + '_auth_dummy_user', - password: 'placeholder', - email: 'support@npmjs.com', - authType: ssoType, - } - - const { token, sso } = await otplease(npm, opts, - opts => profile.loginCouch(auth.username, auth.password, opts) - ) - - if (!token) { - throw new Error('no SSO token returned') - } - if (!sso) { - throw new Error('no SSO URL returned by services') - } - - await openUrl(npm, sso, 'to complete your login please visit') - - const username = await pollForSession({ registry, token, opts }) - - log.info('adduser', `Authorized user ${username}`) - - const scopeMessage = scope ? ' to scope ' + scope : '' - const message = `Logged in as ${username}${scopeMessage} on ${registry}.` - - return { - message, - newCreds: { token }, - } -} - -module.exports = login diff --git a/lib/base-cmd.js b/lib/base-cmd.js new file mode 100644 index 0000000000000..3e6c4758cbd58 --- /dev/null +++ b/lib/base-cmd.js @@ -0,0 +1,214 @@ +const { log } = require('proc-log') + +class BaseCommand { + // these defaults can be overridden by individual commands + static workspaces = false + static ignoreImplicitWorkspace = true + static checkDevEngines = false + + // these should always be overridden by individual commands + static name = null + static description = null + static params = null + + // this is a static so that we can read from it without instantiating a command + // which would require loading the config + static get describeUsage () { + const { 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 + + const fullUsage = [ + `${description}`, + '', + 'Usage:', + ...usage.map(u => `npm ${name} ${u}`.trim()), + ] + + if (params) { + let results = '' + let line = '' + for (const param of params) { + /* istanbul ignore next */ + if (seenExclusive.has(param)) { + continue + } + const { exclusive } = definitions[param] + let paramUsage = `${definitions[param].usage}` + if (exclusive) { + const exclusiveParams = [paramUsage] + seenExclusive.add(param) + for (const e of exclusive) { + seenExclusive.add(e) + exclusiveParams.push(definitions[e].usage) + } + paramUsage = `${exclusiveParams.join('|')}` + } + paramUsage = `[${paramUsage}]` + if (line.length + paramUsage.length > wrapWidth) { + results = [results, line].filter(Boolean).join('\n') + line = '' + } + line = [line, paramUsage].filter(Boolean).join(' ') + } + fullUsage.push('') + fullUsage.push('Options:') + fullUsage.push([results, line].filter(Boolean).join('\n')) + } + + const aliases = Object.entries(cmdAliases).reduce((p, [k, v]) => { + return p.concat(v === name ? k : []) + }, []) + + if (aliases.length) { + const plural = aliases.length === 1 ? '' : 'es' + fullUsage.push('') + fullUsage.push(`alias${plural}: ${aliases.join(', ')}`) + } + + fullUsage.push('') + fullUsage.push(`Run "npm help ${name}" for more info`) + + return fullUsage.join('\n') + } + + constructor (npm) { + this.npm = npm + + const { config } = this.npm + + if (!this.constructor.skipConfigValidation) { + config.validate() + } + + if (config.get('workspaces') === false && config.get('workspace').length) { + throw new Error('Cannot use --no-workspaces and --workspace at the same time') + } + } + + get name () { + return this.constructor.name + } + + get description () { + return this.constructor.description + } + + get params () { + return this.constructor.params + } + + get usage () { + return this.constructor.describeUsage + } + + usageError (prefix = '') { + if (prefix) { + prefix += '\n\n' + } + return Object.assign(new Error(`\n${prefix}${this.usage}`), { + code: 'EUSAGE', + }) + } + + // Compare the number of entries with what was expected + checkExpected (entries) { + if (!this.npm.config.isDefault('expect-results')) { + const expected = this.npm.config.get('expect-results') + if (!!entries !== !!expected) { + log.warn(this.name, `Expected ${expected ? '' : 'no '}results, got ${entries}`) + process.exitCode = 1 + } + } else if (!this.npm.config.isDefault('expect-result-count')) { + const expected = this.npm.config.get('expect-result-count') + if (expected !== entries) { + log.warn(this.name, `Expected ${expected} result${expected === 1 ? '' : 's'}, got ${entries}`) + process.exitCode = 1 + } + } + } + + // Checks the devEngines entry in the package.json at this.localPrefix + async checkDevEngines () { + const force = this.npm.flatOptions.force + + const { devEngines } = await require('@npmcli/package-json') + .normalize(this.npm.config.localPrefix) + .then(p => p.content) + .catch(() => ({})) + + if (typeof devEngines === 'undefined') { + return + } + + const { checkDevEngines, currentEnv } = require('npm-install-checks') + const current = currentEnv.devEngines({ + nodeVersion: this.npm.nodeVersion, + npmVersion: this.npm.version, + }) + + const failures = checkDevEngines(devEngines, current) + const warnings = failures.filter(f => f.isWarn) + const errors = failures.filter(f => f.isError) + + const genMsg = (failure, i = 0) => { + return [...new Set([ + // eslint-disable-next-line + i === 0 ? 'The developer of this package has specified the following through devEngines' : '', + `${failure.message}`, + `${failure.errors.map(e => e.message).join('\n')}`, + ])].filter(v => v).join('\n') + } + + [...warnings, ...(force ? errors : [])].forEach((failure, i) => { + const message = genMsg(failure, i) + log.warn('EBADDEVENGINES', message) + log.warn('EBADDEVENGINES', { + current: failure.current, + required: failure.required, + }) + }) + + if (force) { + return + } + + if (errors.length) { + const failure = errors[0] + const message = genMsg(failure) + throw Object.assign(new Error(message), { + engine: failure.engine, + code: 'EBADDEVENGINES', + current: failure.current, + required: failure.required, + }) + } + } + + async setWorkspaces () { + const { relative } = require('node:path') + + const includeWorkspaceRoot = this.isArboristCmd + ? false + : this.npm.config.get('include-workspace-root') + + const prefixInsideCwd = relative(this.npm.localPrefix, process.cwd()).startsWith('..') + const relativeFrom = prefixInsideCwd ? this.npm.localPrefix : process.cwd() + + const filters = this.npm.config.get('workspace') + const getWorkspaces = require('./utils/get-workspaces.js') + const ws = await getWorkspaces(filters, { + path: this.npm.localPrefix, + includeWorkspaceRoot, + relativeFrom, + }) + + this.workspaces = ws + this.workspaceNames = [...ws.keys()] + this.workspacePaths = [...ws.values()] + } +} + +module.exports = BaseCommand diff --git a/lib/base-command.js b/lib/base-command.js deleted file mode 100644 index 3ab800adbfd98..0000000000000 --- a/lib/base-command.js +++ /dev/null @@ -1,118 +0,0 @@ -// Base class for npm commands - -const { relative } = require('path') - -const ConfigDefinitions = require('./utils/config/definitions.js') -const getWorkspaces = require('./workspaces/get-workspaces.js') - -const cmdAliases = require('./utils/cmd-list').aliases - -class BaseCommand { - constructor (npm) { - this.wrapWidth = 80 - this.npm = npm - } - - get name () { - return this.constructor.name - } - - get description () { - return this.constructor.description - } - - get ignoreImplicitWorkspace () { - return this.constructor.ignoreImplicitWorkspace - } - - get usage () { - const usage = [ - `${this.constructor.description}`, - '', - 'Usage:', - ] - - if (!this.constructor.usage) { - usage.push(`npm ${this.constructor.name}`) - } else { - usage.push(...this.constructor.usage.map(u => `npm ${this.constructor.name} ${u}`)) - } - - if (this.constructor.params) { - usage.push('') - usage.push('Options:') - usage.push(this.wrappedParams) - } - - const aliases = Object.keys(cmdAliases).reduce((p, c) => { - if (cmdAliases[c] === this.constructor.name) { - p.push(c) - } - return p - }, []) - - if (aliases.length === 1) { - usage.push('') - usage.push(`alias: ${aliases.join(', ')}`) - } else if (aliases.length > 1) { - usage.push('') - usage.push(`aliases: ${aliases.join(', ')}`) - } - - usage.push('') - usage.push(`Run "npm help ${this.constructor.name}" for more info`) - - return usage.join('\n') - } - - get wrappedParams () { - let results = '' - let line = '' - - for (const param of this.constructor.params) { - const usage = `[${ConfigDefinitions[param].usage}]` - if (line.length && line.length + usage.length > this.wrapWidth) { - results = [results, line].filter(Boolean).join('\n') - line = '' - } - line = [line, usage].filter(Boolean).join(' ') - } - results = [results, line].filter(Boolean).join('\n') - return results - } - - usageError (prefix = '') { - if (prefix) { - prefix += '\n\n' - } - return Object.assign(new Error(`\n${prefix}${this.usage}`), { - code: 'EUSAGE', - }) - } - - async execWorkspaces (args, filters) { - throw Object.assign(new Error('This command does not support workspaces.'), { - code: 'ENOWORKSPACES', - }) - } - - async setWorkspaces (filters) { - if (this.isArboristCmd) { - this.includeWorkspaceRoot = false - } - - const relativeFrom = relative(this.npm.localPrefix, process.cwd()).startsWith('..') - ? this.npm.localPrefix - : process.cwd() - - const ws = await getWorkspaces(filters, { - path: this.npm.localPrefix, - includeWorkspaceRoot: this.includeWorkspaceRoot, - relativeFrom, - }) - this.workspaces = ws - this.workspaceNames = [...ws.keys()] - this.workspacePaths = [...ws.values()] - } -} -module.exports = BaseCommand diff --git a/lib/cli.js b/lib/cli.js index 7b87b94452ead..00b4fc0bd7fb7 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,91 +1,12 @@ -// Separated out for easier unit testing -module.exports = async process => { - // set it here so that regardless of what happens later, we don't - // leak any private CLI configs to other programs - process.title = 'npm' - - // We used to differentiate between known broken and unsupported - // versions of node and attempt to only log unsupported but still run. - // After we dropped node 10 support, we can use new features - // (like static, private, etc) which will only give vague syntax errors, - // so now both broken and unsupported use console, but only broken - // will process.exit. It is important to now perform *both* of these - // checks as early as possible so the user gets the error message. - const semver = require('semver') - const supported = require('../package.json').engines.node - const knownBroken = '<12.5.0' - - const nodejsVersion = process.version.replace(/-.*$/, '') - /* eslint-disable no-console */ - if (semver.satisfies(nodejsVersion, knownBroken)) { - console.error('ERROR: npm is known not to run on Node.js ' + process.version) - console.error("You'll need to upgrade to a newer Node.js version in order to use this") - console.error('version of npm. You can find the latest version at https://nodejs.org/') - process.exit(1) - } - if (!semver.satisfies(nodejsVersion, supported)) { - console.error('npm does not support Node.js ' + process.version) - console.error('You should probably upgrade to a newer version of node as we') - console.error("can't make any promises that npm will work with this version.") - console.error('You can find the latest version at https://nodejs.org/') +try { + const { enableCompileCache } = require('node:module') + /* istanbul ignore next */ + if (enableCompileCache) { + enableCompileCache() } - /* eslint-enable no-console */ +} catch (e) { /* istanbul ignore next */ } - const exitHandler = require('./utils/exit-handler.js') - process.on('uncaughtException', exitHandler) - process.on('unhandledRejection', exitHandler) - - const Npm = require('./npm.js') - const npm = new Npm() - exitHandler.setNpm(npm) - - // if npm is called as "npmg" or "npm_g", then - // run in global mode. - if (process.argv[1][process.argv[1].length - 1] === 'g') { - process.argv.splice(1, 1, 'npm', '-g') - } +const validateEngines = require('./cli/validate-engines.js') +const cliEntry = require('node:path').resolve(__dirname, 'cli/entry.js') - const log = require('./utils/log-shim.js') - // only log node and npm paths in argv initially since argv can contain - // sensitive info. a cleaned version will be logged later - log.verbose('cli', process.argv.slice(0, 2).join(' ')) - log.info('using', 'npm@%s', npm.version) - log.info('using', 'node@%s', process.version) - - let cmd - // now actually fire up npm and run the command. - // this is how to use npm programmatically: - try { - await npm.load() - if (npm.config.get('version', 'cli')) { - npm.output(npm.version) - return exitHandler() - } - - // npm --versions=cli - if (npm.config.get('versions', 'cli')) { - npm.argv = ['version'] - npm.config.set('usage', false, 'cli') - } - - cmd = npm.argv.shift() - if (!cmd) { - npm.output(await npm.usage) - process.exitCode = 1 - return exitHandler() - } - - await npm.exec(cmd, npm.argv) - return exitHandler() - } catch (err) { - if (err.code === 'EUNKNOWNCOMMAND') { - const didYouMean = require('./utils/did-you-mean.js') - const suggestions = await didYouMean(npm, npm.localPrefix, cmd) - npm.output(`Unknown command: "${cmd}"${suggestions}\n`) - npm.output('To see a list of supported npm commands, run:\n npm help') - process.exitCode = 1 - return exitHandler() - } - return exitHandler(err) - } -} +module.exports = (process) => validateEngines(process, () => require(cliEntry)) diff --git a/lib/cli/entry.js b/lib/cli/entry.js new file mode 100644 index 0000000000000..a068d22c55cbf --- /dev/null +++ b/lib/cli/entry.js @@ -0,0 +1,72 @@ +// Separated out for easier unit testing +module.exports = async (process, validateEngines) => { + // set it here so that regardless of what happens later, we don't + // leak any private CLI configs to other programs + process.title = 'npm' + + // Patch the global fs module here at the app level + require('graceful-fs').gracefulify(require('node:fs')) + + const satisfies = require('semver/functions/satisfies') + const ExitHandler = require('./exit-handler.js') + const exitHandler = new ExitHandler({ process }) + 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, 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) + + // At this point we've required a few files and can be pretty sure we don't contain invalid syntax for this version of node. It's possible a lazy require would, but that's unlikely enough that it's not worth catching anymore and we attach the more important exit handlers. + validateEngines.off() + exitHandler.registerUncaughtHandlers() + + // It is now safe to log a warning if they are using a version of node that is not going to fail on syntax errors but is still unsupported and untested and might not work reliably. This is safe to use the logger now which we want since this will show up in the error log too. + if (!satisfies(validateEngines.node, validateEngines.engines)) { + log.warn('cli', validateEngines.unsupportedMessage) + } + + // Now actually fire up npm and run the command. + // This is how to use npm programmatically: + try { + const { exec, command, args } = await npm.load() + + if (!exec) { + return exitHandler.exit() + } + + if (!command) { + output.standard(npm.usage) + process.exitCode = 1 + return exitHandler.exit() + } + + // 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 don't 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.exit() + } catch (err) { + return exitHandler.exit(err) + } +} diff --git a/lib/cli/exit-handler.js b/lib/cli/exit-handler.js new file mode 100644 index 0000000000000..f4fbcd9d834f1 --- /dev/null +++ b/lib/cli/exit-handler.js @@ -0,0 +1,174 @@ +const { log, output, META } = require('proc-log') +const { errorMessage, getExitCodeFromError } = require('../utils/error-message.js') + +class ExitHandler { + #npm = null + #process = null + #exited = false + #exitErrorMessage = false + + #noNpmError = false + + get #hasNpm () { + return !!this.#npm + } + + get #loaded () { + return !!this.#npm?.loaded + } + + get #showExitErrorMessage () { + if (!this.#loaded) { + return false + } + if (!this.#exited) { + return true + } + return this.#exitErrorMessage + } + + get #notLoadedOrExited () { + return !this.#loaded && !this.#exited + } + + setNpm (npm) { + this.#npm = npm + } + + constructor ({ process }) { + this.#process = process + this.#process.on('exit', this.#handleProcessExitAndReset) + } + + registerUncaughtHandlers () { + this.#process.on('uncaughtException', this.#handleExit) + this.#process.on('unhandledRejection', this.#handleExit) + } + + exit (err) { + this.#handleExit(err) + } + + #handleProcessExitAndReset = (code) => { + this.#handleProcessExit(code) + + // Reset all the state. This is only relevant for tests since + // in reality the process fully exits here. + this.#process.off('exit', this.#handleProcessExitAndReset) + this.#process.off('uncaughtException', this.#handleExit) + this.#process.off('unhandledRejection', this.#handleExit) + if (this.#loaded) { + this.#npm.unload() + } + this.#npm = null + this.#exited = false + this.#exitErrorMessage = false + } + + #handleProcessExit (code) { + const numCode = Number(code) || 0 + // Always exit w/ a non-zero code if exit handler was not called + const exitCode = this.#exited ? numCode : (numCode || 1) + this.#process.exitCode = exitCode + + if (this.#notLoadedOrExited) { + // Exit handler was not called and npm was not loaded so we have to log something + this.#logConsoleError(new Error(`Process exited unexpectedly with code: ${exitCode}`)) + return + } + + if (this.#logNoNpmError()) { + return + } + + const os = require('node:os') + log.verbose('cwd', this.#process.cwd()) + log.verbose('os', `${os.type()} ${os.release()}`) + log.verbose('node', this.#process.version) + log.verbose('npm ', `v${this.#npm.version}`) + + // only show the notification if it finished + if (typeof this.#npm.updateNotification === 'string') { + log.notice('', this.#npm.updateNotification, { [META]: true, force: true }) + } + + if (!this.#exited) { + log.error('', 'Exit handler never called!') + log.error('', 'This is an error with npm itself. Please report this error at:') + log.error('', ' <https://github.com/npm/cli/issues>') + if (this.#npm.silent) { + output.error('') + } + } + + log.verbose('exit', exitCode) + + if (exitCode) { + log.verbose('code', exitCode) + } else { + log.info('ok') + } + + if (this.#showExitErrorMessage) { + log.error('', this.#npm.exitErrorMessage()) + } + } + + #logConsoleError (err) { + // Run our error message formatters on all errors even if we + // have no npm or an unloaded npm. This will clean the error + // and possible return a formatted message about EACCESS or something. + const { summary, detail } = errorMessage(err, this.#npm) + const formatted = [...new Set([...summary, ...detail].flat().filter(Boolean))].join('\n') + // If we didn't get anything from the formatted message then just display the full stack + // eslint-disable-next-line no-console + console.error(formatted === err.message ? err.stack : formatted) + } + + #logNoNpmError (err) { + if (this.#hasNpm) { + return false + } + // Make sure we only log this error once + if (!this.#noNpmError) { + this.#noNpmError = true + this.#logConsoleError( + new Error(`Exit prior to setting npm in exit handler`, err ? { cause: err } : {}) + ) + } + return true + } + + #handleExit = (err) => { + this.#exited = true + + // No npm at all + if (this.#logNoNpmError(err)) { + return this.#process.exit(this.#process.exitCode || getExitCodeFromError(err) || 1) + } + + // npm was never loaded but we still might have a config loading error or + // something similar that we can run through the error message formatter + // to give the user a clue as to what happened.s + if (!this.#loaded) { + this.#logConsoleError(new Error('Exit prior to config file resolving', { cause: err })) + return this.#process.exit(this.#process.exitCode || getExitCodeFromError(err) || 1) + } + + this.#exitErrorMessage = err?.suppressError === true ? false : !!err + + // Prefer the exit code of the error, then the current process exit code, + // then set it to 1 if we still have an error. Otherwise, we call process.exit + // with undefined so that it can determine the final exit code + const exitCode = err?.exitCode ?? this.#process.exitCode ?? (err ? 1 : undefined) + + // explicitly call process.exit now so we don't hang on things like the + // update notifier, also flush stdout/err beforehand because process.exit doesn't + // wait for that to happen. + this.#process.stderr.write('', () => this.#process.stdout.write('', () => { + this.#process.exit(exitCode) + })) + } +} + +module.exports = ExitHandler diff --git a/lib/cli/update-notifier.js b/lib/cli/update-notifier.js new file mode 100644 index 0000000000000..20a2290026893 --- /dev/null +++ b/lib/cli/update-notifier.js @@ -0,0 +1,120 @@ +// print a banner telling the user to upgrade npm to latest +// but not in CI, and not if we're doing that already. +// Check daily for betas, and weekly otherwise. + +const ciInfo = require('ci-info') +const gt = require('semver/functions/gt') +const gte = require('semver/functions/gte') +const parse = require('semver/functions/parse') +const { stat, writeFile } = require('node:fs/promises') +const { resolve } = require('node:path') + +// update check frequency +const DAILY = 1000 * 60 * 60 * 24 +const WEEKLY = DAILY * 7 + +// don't put it in the _cacache folder, just in npm's cache +const lastCheckedFile = npm => + resolve(npm.flatOptions.cache, '../_update-notifier-last-checked') + +// Actual check for updates. This is a separate function so that we only load +// this if we are doing the actual update +const updateCheck = async (npm, spec, version, current) => { + const pacote = require('pacote') + + const mani = await pacote.manifest(`npm@${spec}`, { + // always prefer latest, even if doing --tag=whatever on the cmd + defaultTag: 'latest', + ...npm.flatOptions, + cache: false, + }).catch(() => null) + + // if pacote failed, give up + if (!mani) { + return null + } + + const latest = mani.version + + // if the current version is *greater* than latest, we're on a 'next' + // and should get the updates from that release train. + // Note that this isn't another http request over the network, because + // the packument will be cached by pacote from previous request. + if (gt(version, latest) && spec === '*') { + return updateNotifier(npm, `^${version}`) + } + + // if we already have something >= the desired spec, then we're done + if (gte(version, latest)) { + return null + } + + const chalk = npm.logChalk + + // ok! notify the user about this update they should get. + // The message is saved for printing at process exit so it will not get + // lost in any other messages being printed as part of the command. + const update = parse(mani.version) + const type = update.major !== current.major ? 'major' + : update.minor !== current.minor ? 'minor' + : update.patch !== current.patch ? 'patch' + : 'prerelease' + const typec = type === 'major' ? 'red' + : type === 'minor' ? 'yellow' + : 'cyan' + const cmd = `npm install -g npm@${latest}` + 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 +} + +const updateNotifier = async (npm, spec = '*') => { + // if we're on a prerelease train, then updates are coming fast + // check for a new one daily. otherwise, weekly. + const { version } = npm + const current = parse(version) + + // if we're on a beta train, always get the next beta + if (current.prerelease.length) { + spec = `^${version}` + } + + // while on a beta train, get updates daily + const duration = current.prerelease.length ? DAILY : WEEKLY + + const t = new Date(Date.now() - duration) + // if we don't have a file, then definitely check it. + const st = await stat(lastCheckedFile(npm)).catch(() => ({ mtime: t - 1 })) + + // if we've already checked within the specified duration, don't check again + if (!(t > st.mtime)) { + return null + } + + // intentional. do not await this. it's a best-effort update. if this + // fails, it's ok. might be using /dev/null as the cache or something weird + // like that. + writeFile(lastCheckedFile(npm), '').catch(() => {}) + + return updateCheck(npm, spec, version, current) +} + +module.exports = npm => { + if ( + // opted out + !npm.config.get('update-notifier') + // global npm update + || (npm.flatOptions.global && + ['install', 'update'].includes(npm.command) && + npm.argv.some(arg => /^npm(@|$)/.test(arg))) + // CI + || ciInfo.isCI + ) { + return Promise.resolve(null) + } + + return updateNotifier(npm) +} diff --git a/lib/cli/validate-engines.js b/lib/cli/validate-engines.js new file mode 100644 index 0000000000000..971cc6bb51867 --- /dev/null +++ b/lib/cli/validate-engines.js @@ -0,0 +1,47 @@ +// This is separate to indicate that it should contain code we expect to work in +// all versions of node >= 6. This is a best effort to catch syntax errors to +// give users a good error message if they are using a node version that doesn't +// allow syntax we are using such as private properties, etc. This file is +// linted with ecmaVersion=6 so we don't use invalid syntax, which is set in the +// .eslintrc.local.json file + +const { engines: { node: engines }, version } = require('../../package.json') +const npm = `v${version}` + +module.exports = (process, getCli) => { + const node = process.version + + const unsupportedMessage = `npm ${npm} does not support Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` + + const brokenMessage = `ERROR: npm ${npm} is known not to run on Node.js ${node}. This version of npm supports the following node versions: \`${engines}\`. You can find the latest version at https://nodejs.org/.` + + // coverage ignored because this is only hit in very unsupported node versions + // and it's a best effort attempt to show something nice in those cases + /* istanbul ignore next */ + const syntaxErrorHandler = (err) => { + if (err instanceof SyntaxError) { + // eslint-disable-next-line no-console + console.error(`${brokenMessage}\n\nERROR:`) + // eslint-disable-next-line no-console + console.error(err) + return process.exit(1) + } + throw err + } + + process.on('uncaughtException', syntaxErrorHandler) + process.on('unhandledRejection', syntaxErrorHandler) + + // require this only after setting up the error handlers + const cli = getCli() + return cli(process, { + node, + npm, + engines, + unsupportedMessage, + off: () => { + process.off('uncaughtException', syntaxErrorHandler) + process.off('unhandledRejection', syntaxErrorHandler) + }, + }) +} diff --git a/lib/commands/access.js b/lib/commands/access.js index 0a80da8ddd006..d0faf394f0966 100644 --- a/lib/commands/access.js +++ b/lib/commands/access.js @@ -1,209 +1,223 @@ -const path = require('path') - -const libaccess = require('libnpmaccess') -const readPackageJson = require('read-package-json-fast') - -const otplease = require('../utils/otplease.js') +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/auth.js') const getIdentity = require('../utils/get-identity.js') -const BaseCommand = require('../base-command.js') +const BaseCommand = require('../base-cmd.js') -const subcommands = [ - 'public', - 'restricted', +const commands = [ + 'get', 'grant', + 'list', 'revoke', - 'ls-packages', - 'ls-collaborators', - 'edit', - '2fa-required', - '2fa-not-required', + 'set', +] + +const setCommands = [ + 'status=public', + 'status=private', + 'mfa=none', + 'mfa=publish', + 'mfa=automation', + '2fa=none', + '2fa=publish', + '2fa=automation', ] class Access extends BaseCommand { static description = 'Set access level on published packages' static name = 'access' static params = [ - 'registry', + 'json', 'otp', + 'registry', ] - static ignoreImplicitWorkspace = true - static usage = [ - 'public [<package>]', - 'restricted [<package>]', + 'list packages [<user>|<scope>|<scope:team>] [<package>]', + 'list collaborators [<package> [<user>]]', + 'get status [<package>]', + 'set status=public|private [<package>]', + 'set mfa=none|publish|automation [<package>]', 'grant <read-only|read-write> <scope:team> [<package>]', 'revoke <scope:team> [<package>]', - '2fa-required [<package>]', - '2fa-not-required [<package>]', - 'ls-packages [<user>|<scope>|<scope:team>]', - 'ls-collaborators [<package> [<user>]]', - 'edit [<package>]', ] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { - return subcommands + return commands } - switch (argv[2]) { - case 'grant': - if (argv.length === 3) { + if (argv.length === 3) { + switch (argv[2]) { + case 'grant': return ['read-only', 'read-write'] - } else { + case 'revoke': return [] - } - - case 'public': - case 'restricted': - case 'ls-packages': - case 'ls-collaborators': - case 'edit': - case '2fa-required': - case '2fa-not-required': - case 'revoke': - return [] - default: - throw new Error(argv[2] + ' not recognized') + case 'list': + case 'ls': + return ['packages', 'collaborators'] + case 'get': + return ['status'] + case 'set': + return setCommands + default: + throw new Error(argv[2] + ' not recognized') + } } } - async exec ([cmd, ...args]) { + async exec ([cmd, subcmd, ...args]) { if (!cmd) { - throw this.usageError('Subcommand is required.') + throw this.usageError() } - - if (!subcommands.includes(cmd) || !this[cmd]) { - throw this.usageError(`${cmd} is not a recognized subcommand.`) + if (!commands.includes(cmd)) { + throw this.usageError(`${cmd} is not a valid access command`) } - - return this[cmd](args, { - ...this.npm.flatOptions, - }) - } - - public ([pkg], opts) { - return this.modifyPackage(pkg, opts, libaccess.public) - } - - restricted ([pkg], opts) { - return this.modifyPackage(pkg, opts, libaccess.restricted) - } - - async grant ([perms, scopeteam, pkg], opts) { - if (!perms || (perms !== 'read-only' && perms !== 'read-write')) { - throw this.usageError('First argument must be either `read-only` or `read-write`.') - } - - if (!scopeteam) { - throw this.usageError('`<scope:team>` argument is required.') - } - - const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || [] - - if (!scope && !team) { - throw this.usageError( - 'Second argument used incorrect format.\n' + - 'Example: @example:developers' - ) - } - - return this.modifyPackage(pkg, opts, (pkgName, opts) => - libaccess.grant(pkgName, scopeteam, perms, opts), false) - } - - async revoke ([scopeteam, pkg], opts) { - if (!scopeteam) { - throw this.usageError('`<scope:team>` argument is required.') + // All commands take at least one more parameter so we can do this check up front + if (!subcmd) { + throw this.usageError() } - const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || [] - - if (!scope || !team) { - throw this.usageError( - 'First argument used incorrect format.\n' + - 'Example: @example:developers' - ) + switch (cmd) { + case 'grant': + if (!['read-only', 'read-write'].includes(subcmd)) { + throw this.usageError('grant must be either `read-only` or `read-write`') + } + if (!args[0]) { + throw this.usageError('`<scope:team>` argument is required') + } + return this.#grant(subcmd, args[0], args[1]) + case 'revoke': + return this.#revoke(subcmd, args[0]) + case 'list': + case 'ls': + if (subcmd === 'packages') { + return this.#listPackages(args[0], args[1]) + } + if (subcmd === 'collaborators') { + return this.#listCollaborators(args[0], args[1]) + } + throw this.usageError(`list ${subcmd} is not a valid access command`) + case 'get': + if (subcmd !== 'status') { + throw this.usageError(`get ${subcmd} is not a valid access command`) + } + return this.#getStatus(args[0]) + case 'set': + if (!setCommands.includes(subcmd)) { + throw this.usageError(`set ${subcmd} is not a valid access command`) + } + return this.#set(subcmd, args[0]) } - - return this.modifyPackage(pkg, opts, (pkgName, opts) => - libaccess.revoke(pkgName, scopeteam, opts)) } - get ['2fa-required'] () { - return this.tfaRequired - } - - tfaRequired ([pkg], opts) { - return this.modifyPackage(pkg, opts, libaccess.tfaRequired, false) - } - - get ['2fa-not-required'] () { - return this.tfaNotRequired - } - - tfaNotRequired ([pkg], opts) { - return this.modifyPackage(pkg, opts, libaccess.tfaNotRequired, false) + async #grant (permissions, scope, pkg) { + await otplease(this.npm, this.npm.flatOptions, async (opts) => { + await libnpmaccess.setPermissions(scope, pkg, permissions, opts) + }) } - get ['ls-packages'] () { - return this.lsPackages + async #revoke (scope, pkg) { + await otplease(this.npm, this.npm.flatOptions, async (opts) => { + await libnpmaccess.removePermissions(scope, pkg, opts) + }) } - async lsPackages ([owner], opts) { + async #listPackages (owner, pkg) { if (!owner) { - owner = await getIdentity(this.npm, opts) + owner = await getIdentity(this.npm, this.npm.flatOptions) } - - const pkgs = await libaccess.lsPackages(owner, opts) - - // TODO - print these out nicely (breaking change) - this.npm.output(JSON.stringify(pkgs, null, 2)) + const pkgs = await libnpmaccess.getPackages(owner, this.npm.flatOptions) + this.#output(pkgs, pkg) } - get ['ls-collaborators'] () { - return this.lsCollaborators + async #listCollaborators (pkg, user) { + const pkgName = await this.#getPackage(pkg, false) + const collabs = await libnpmaccess.getCollaborators(pkgName, this.npm.flatOptions) + this.#output(collabs, user) } - async lsCollaborators ([pkg, usr], opts) { - const pkgName = await this.getPackage(pkg, false) - const collabs = await libaccess.lsCollaborators(pkgName, usr, opts) + async #getStatus (pkg) { + const pkgName = await this.#getPackage(pkg, false) + const visibility = await libnpmaccess.getVisibility(pkgName, this.npm.flatOptions) + this.#output({ [pkgName]: visibility.public ? 'public' : 'private' }) + } - // TODO - print these out nicely (breaking change) - this.npm.output(JSON.stringify(collabs, null, 2)) + async #set (subcmd, pkg) { + const [subkey, subval] = subcmd.split('=') + switch (subkey) { + case 'mfa': + case '2fa': + return this.#setMfa(pkg, subval) + case 'status': + return this.#setStatus(pkg, subval) + } } - async edit () { - throw new Error('edit subcommand is not implemented yet') + async #setMfa (pkg, level) { + const pkgName = await this.#getPackage(pkg, false) + await otplease(this.npm, this.npm.flatOptions, (opts) => { + return libnpmaccess.setMfa(pkgName, level, opts) + }) } - modifyPackage (pkg, opts, fn, requireScope = true) { - return this.getPackage(pkg, requireScope) - .then(pkgName => otplease(this.npm, opts, opts => fn(pkgName, opts))) + async #setStatus (pkg, status) { + // only scoped packages can have their access changed + const pkgName = await this.#getPackage(pkg, true) + if (status === 'private') { + status = 'restricted' + } + await otplease(this.npm, this.npm.flatOptions, (opts) => { + return libnpmaccess.setAccess(pkgName, status, opts) + }) + return this.#getStatus(pkgName) } - async getPackage (name, requireScope) { - if (name && name.trim()) { - return name.trim() - } else { + async #getPackage (name, requireScope) { + if (!name) { try { - const pkg = await readPackageJson(path.resolve(this.npm.prefix, 'package.json')) - name = pkg.name + const { content } = await pkgJson.normalize(this.npm.prefix) + name = content.name } catch (err) { if (err.code === 'ENOENT') { - throw new Error( - 'no package name passed to command and no package.json found' - ) + throw Object.assign(new Error('no package name given and no package.json found'), { + code: 'ENOENT', + }) } else { throw err } } + } + + const spec = npa(name) + if (requireScope && !spec.scope) { + throw this.usageError('This command is only available for scoped packages.') + } + return name + } - if (requireScope && !name.match(/^@[^/]+\/.*$/)) { - throw this.usageError('This command is only available for scoped packages.') - } else { - return name + #output (items, limiter) { + const outputs = {} + const lookup = { + __proto__: null, + read: 'read-only', + write: 'read-write', + } + for (const item in items) { + const val = items[item] + outputs[item] = lookup[val] || val + } + if (this.npm.config.get('json')) { + output.buffer(outputs) + } else { + for (const item of Object.keys(outputs).sort(localeCompare)) { + if (!limiter || limiter === item) { + output.standard(`${item}: ${outputs[item]}`) + } } } } diff --git a/lib/commands/adduser.js b/lib/commands/adduser.js index 2853269ef3dee..cf64e7a7e7438 100644 --- a/lib/commands/adduser.js +++ b/lib/commands/adduser.js @@ -1,14 +1,7 @@ -const log = require('../utils/log-shim.js') -const replaceInfo = require('../utils/replace-info.js') -const BaseCommand = require('../base-command.js') -const authTypes = { - legacy: require('../auth/legacy.js'), - web: require('../auth/legacy.js'), - webauthn: require('../auth/legacy.js'), - oauth: require('../auth/oauth.js'), - saml: require('../auth/saml.js'), - sso: require('../auth/sso.js'), -} +const { log, output } = require('proc-log') +const { redactLog: replaceInfo } = require('@npmcli/redact') +const auth = require('../utils/auth.js') +const BaseCommand = require('../base-cmd.js') class AddUser extends BaseCommand { static description = 'Add a registry user account' @@ -19,66 +12,39 @@ class AddUser extends BaseCommand { 'auth-type', ] - static ignoreImplicitWorkspace = true - - async exec (args) { - const { scope } = this.npm.flatOptions - const registry = this.getRegistry(this.npm.flatOptions) - const auth = this.getAuthType(this.npm.flatOptions) - const creds = this.npm.config.getCredentialsByURI(registry) - - log.disableProgress() + async exec () { + const scope = this.npm.config.get('scope') + let registry = this.npm.config.get('registry') - log.warn('adduser', - '`adduser` will be split into `login` and `register` in a future version.' - + ' `adduser` will become an alias of `register`.' - + ' `login` (currently an alias) will become its own command.') - log.notice('', `Log in on ${replaceInfo(registry)}`) - - const { message, newCreds } = await auth(this.npm, { - ...this.npm.flatOptions, - creds, - registry, - scope, - }) - - await this.updateConfig({ - newCreds, - registry, - scope, - }) - - this.npm.output(message) - } - - getRegistry ({ scope, registry }) { if (scope) { const scopedRegistry = this.npm.config.get(`${scope}:registry`) const cliRegistry = this.npm.config.get('registry', 'cli') if (scopedRegistry && !cliRegistry) { - return scopedRegistry + registry = scopedRegistry } } - return registry - } - getAuthType ({ authType }) { - const type = authTypes[authType] + const creds = this.npm.config.getCredentialsByURI(registry) - if (!type) { - throw new Error('no such auth module') - } + log.notice('', `Log in on ${replaceInfo(registry)}`) - return type - } + const { message, newCreds } = await auth.adduser(this.npm, { + ...this.npm.flatOptions, + creds, + registry, + }) - async updateConfig ({ newCreds, registry, scope }) { this.npm.config.delete('_token', 'user') // prevent legacy pollution this.npm.config.setCredentialsByURI(registry, newCreds) + if (scope) { this.npm.config.set(scope + ':registry', registry, 'user') } + await this.npm.config.save('user') + + output.standard(message) } } + module.exports = AddUser diff --git a/lib/commands/audit.js b/lib/commands/audit.js index 779bc22fc6aaf..97d0729da9618 100644 --- a/lib/commands/audit.js +++ b/lib/commands/audit.js @@ -1,336 +1,9 @@ -const Arborist = require('@npmcli/arborist') -const auditReport = 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 npmAuditReport = require('npm-audit-report') 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.verifiedCount = 0 - this.output = [] - 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') - } - - await Promise.all([...registries].map(registry => this.setKeys({ registry }))) - - 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 where 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) { - this.exitCode = 1 - } - - if (this.npm.config.get('json')) { - this.appendOutput(JSON.stringify({ - invalid: this.makeJSON(invalid), - missing: this.makeJSON(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.appendOutput(`${timing}\n`) - - if (this.verifiedCount) { - const verifiedBold = this.npm.chalk.bold('verified') - const msg = this.verifiedCount === 1 ? - `${this.verifiedCount} package has a ${verifiedBold} registry signature\n` : - `${this.verifiedCount} packages have ${verifiedBold} registry signatures\n` - this.appendOutput(msg) - } - - if (missing.length) { - const missingClr = this.npm.chalk.bold(this.npm.chalk.red('missing')) - const msg = missing.length === 1 ? - `package has a ${missingClr} registry signature` : - `packages have ${missingClr} registry signatures` - this.appendOutput( - `${missing.length} ${msg} but the registry is ` + - `providing signing keys:\n` - ) - this.appendOutput(this.humanOutput(missing)) - } - - if (invalid.length) { - const invalidClr = this.npm.chalk.bold(this.npm.chalk.red('invalid')) - const msg = invalid.length === 1 ? - `${invalid.length} package has an ${invalidClr} registry signature:\n` : - `${invalid.length} packages have ${invalidClr} registry signatures:\n` - this.appendOutput( - `${missing.length ? '\n' : ''}${msg}` - ) - this.appendOutput(this.humanOutput(invalid)) - const tamperMsg = invalid.length === 1 ? - `\nSomeone might have tampered with this package since it was ` + - `published on the registry!\n` : - `\nSomeone might have tampered with these packages since they where ` + - `published on the registry!\n` - this.appendOutput(tamperMsg) - } - } - - appendOutput (...args) { - this.output.push(...args.flat()) - } - - report () { - return { report: this.output.join('\n'), exitCode: this.exitCode } - } - - 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 }) { - const keys = await fetch.json('/-/npm/v1/keys', { - ...this.npm.flatOptions, - registry, - }).then(({ keys }) => keys.map((key) => ({ - ...key, - pemkey: `-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`, - }))).catch(err => { - if (err.code === 'E404') { - 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 (_) { - } - 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, - _resolved: resolved, - } = await pacote.manifest(`${name}@${version}`, { - verifySignatures: true, - ...this.buildRegistryConfig(registry), - ...this.npm.flatOptions, - }) - const signatures = _signatures || [] - return { - integrity, - signatures, - resolved, - } - } - - 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, 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.verifiedCount += 1 - } else if (keys.length) { - this.missing.push({ - name, - version, - location, - resolved, - integrity, - registry, - }) - } - } catch (e) { - if (e.code === 'EINTEGRITYSIGNATURE') { - const { signature, keyid, integrity, resolved } = e - this.invalid.push({ - name, - type, - version, - resolved, - location, - integrity, - registry, - signature, - keyid, - }) - } else { - throw e - } - } - } - - humanOutput (list) { - return list.map(v => - `${this.npm.chalk.red(`${v.name}@${v.version}`)} (${v.registry})` - ).join('\n') - } - - makeJSON (deps) { - return deps.map(d => ({ - name: d.name, - version: d.version, - location: d.location, - resolved: d.resolved, - integrity: d.integrity, - signature: d.signature, - keyid: d.keyid, - })) - } -} +const VerifySignatures = require('../utils/verify-signatures.js') class Audit extends ArboristWorkspaceCmd { static description = 'Run a security audit' @@ -341,7 +14,9 @@ class Audit extends ArboristWorkspaceCmd { 'force', 'json', 'package-lock-only', + 'package-lock', 'omit', + 'include', 'foreground-scripts', 'ignore-scripts', ...super.params, @@ -349,15 +24,16 @@ class Audit extends ArboristWorkspaceCmd { static usage = ['[fix|signatures]'] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { - return ['fix'] + return ['fix', 'signatures'] } switch (argv[2]) { case 'fix': + case 'signatures': return [] default: throw Object.assign(new Error(argv[2] + ' not recognized'), { @@ -375,7 +51,12 @@ class Audit extends ArboristWorkspaceCmd { } async auditAdvisories (args) { + const fix = args[0] === 'fix' + if (this.npm.config.get('package-lock') === false && fix) { + throw this.usageError('fix cannot be used without a package-lock') + } const reporter = this.npm.config.get('json') ? 'json' : 'detail' + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, audit: true, @@ -385,16 +66,18 @@ class Audit extends ArboristWorkspaceCmd { } const arb = new Arborist(opts) - const fix = args[0] === 'fix' await arb.audit({ fix }) if (fix) { await reifyFinish(this.npm, arb) } else { // will throw if there's an error, because this is an audit command auditError(this.npm, arb.auditReport) - const result = auditReport(arb.auditReport, opts) + const result = npmAuditReport(arb.auditReport, { + ...opts, + chalk: this.npm.chalk, + }) process.exitCode = process.exitCode || result.exitCode - this.npm.output(result.report) + output.standard(result.report) } } @@ -407,7 +90,8 @@ class Audit extends ArboristWorkspaceCmd { ) } - log.verbose('loading installed dependencies') + log.verbose('audit', 'loading installed dependencies') + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, path: this.npm.prefix, @@ -431,9 +115,6 @@ class Audit extends ArboristWorkspaceCmd { const verify = new VerifySignatures(tree, filterSet, this.npm, { ...opts }) await verify.run() - const result = verify.report() - process.exitCode = process.exitCode || result.exitCode - this.npm.output(result.report) } } diff --git a/lib/commands/bin.js b/lib/commands/bin.js deleted file mode 100644 index 9ba3cb4003241..0000000000000 --- a/lib/commands/bin.js +++ /dev/null @@ -1,23 +0,0 @@ -const log = require('../utils/log-shim.js') -const BaseCommand = require('../base-command.js') -// TODO this may not be needed at all. Ignoring because our tests normalize -// process.env.path already -/* istanbul ignore next */ -const path = process.env.path || process.env.Path || process.env.PATH -const { delimiter } = require('path') - -class Bin extends BaseCommand { - static description = 'Display npm bin folder' - static name = 'bin' - static params = ['global'] - static ignoreImplicitWorkspace = true - - async exec (args) { - const b = this.npm.bin - this.npm.output(b) - if (this.npm.global && !path.split(delimiter).includes(b)) { - log.error('bin', '(not in PATH env variable)') - } - } -} -module.exports = Bin diff --git a/lib/commands/birthday.js b/lib/commands/birthday.js deleted file mode 100644 index cdd6db6286905..0000000000000 --- a/lib/commands/birthday.js +++ /dev/null @@ -1,17 +0,0 @@ -const BaseCommand = require('../base-command.js') -const log = require('../utils/log-shim') - -class Birthday extends BaseCommand { - static name = 'birthday' - static description = 'Birthday, deprecated' - static ignoreImplicitWorkspace = true - static isShellout = true - - async exec () { - this.npm.config.set('yes', true) - log.warn('birthday', 'birthday is deprecated and will be removed in a future release') - return this.npm.exec('exec', ['@npmcli/npm-birthday']) - } -} - -module.exports = Birthday diff --git a/lib/commands/bugs.js b/lib/commands/bugs.js index 17cbd96649b87..44926afbc9a0a 100644 --- a/lib/commands/bugs.js +++ b/lib/commands/bugs.js @@ -21,8 +21,9 @@ class Bugs extends PackageUrlCmd { // try to get it from the repo, if possible const info = this.hostedFromMani(mani) - if (info) { - return info.bugs() + const infoUrl = info?.bugs() + if (infoUrl) { + return infoUrl } // just send them to the website, hopefully that has some info! diff --git a/lib/commands/cache.js b/lib/commands/cache.js index bc52889c0006f..7aaf3564cb9fc 100644 --- a/lib/commands/cache.js +++ b/lib/commands/cache.js @@ -1,17 +1,17 @@ +const fs = require('node:fs/promises') +const { join } = require('node:path') const cacache = require('cacache') -const { promisify } = require('util') const pacote = require('pacote') -const path = require('path') -const rimraf = promisify(require('rimraf')) const semver = require('semver') -const BaseCommand = require('../base-command.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 PkgJson = require('@npmcli/package-json') +const abbrev = require('abbrev') +const BaseCommand = require('../base-cmd.js') const searchCachePackage = async (path, parsed, cacheKeys) => { - /* eslint-disable-next-line max-len */ const searchMFH = new RegExp(`^make-fetch-happen:request-cache:.*(?<!/[@a-zA-Z]+)/${parsed.name}/-/(${parsed.name}[^/]+.tgz)$`) const searchPack = new RegExp(`^make-fetch-happen:request-cache:.*/${parsed.escapedName}$`) const results = new Set() @@ -39,7 +39,7 @@ const searchCachePackage = async (path, parsed, cacheKeys) => { try { details = await cacache.get(path, key) packument = jsonParse(details.data) - } catch (_) { + } catch { // if we couldn't parse the packument, abort continue } @@ -64,7 +64,7 @@ const searchCachePackage = async (path, parsed, cacheKeys) => { } class Cache extends BaseCommand { - static description = 'Manipulates packages cache' + static description = 'Manipulates packages and npx cache' static name = 'cache' static params = ['cache'] static usage = [ @@ -72,14 +72,15 @@ class Cache extends BaseCommand { 'clean [<key>]', 'ls [<name>@<version>]', 'verify', + 'npx ls', + 'npx rm [<key>...]', + 'npx info <key>...', ] - static ignoreImplicitWorkspace = true - - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { - return ['add', 'clean', 'verify', 'ls', 'delete'] + return ['add', 'clean', 'verify', 'ls', 'npx'] } // TODO - eventually... @@ -88,7 +89,6 @@ class Cache extends BaseCommand { case 'clean': case 'add': case 'ls': - case 'delete': return [] } } @@ -104,14 +104,31 @@ class Cache extends BaseCommand { return await this.verify() case 'ls': return await this.ls(args) + case 'npx': + return await this.npx(args) default: throw this.usageError() } } - // npm cache clean [pkg]* + // npm cache npx + async npx ([cmd, ...keys]) { + switch (cmd) { + case 'ls': + return await this.npxLs(keys) + case 'rm': + return await this.npxRm(keys) + case 'info': + return await this.npxInfo(keys) + default: + throw this.usageError() + } + } + + // npm cache clean [spec]* async clean (args) { - const cachePath = path.join(this.npm.cache, '_cacache') + // this is a derived value + const cachePath = this.npm.flatOptions.cache if (args.length === 0) { if (!this.npm.config.get('force')) { throw new Error(`As of npm@5, the npm cache self-heals from corruption issues @@ -129,17 +146,17 @@ class Cache extends BaseCommand { If you're sure you want to delete the entire cache, rerun this command with --force.`) } - return rimraf(cachePath) + return fs.rm(cachePath, { recursive: true, force: true }) } for (const key of args) { let entry try { entry = await cacache.get(cachePath, key) - } catch (err) { - log.warn(`Not Found: ${key}`) + } catch { + log.warn('cache', `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) @@ -156,43 +173,50 @@ class Cache extends BaseCommand { throw this.usageError('First argument to `add` is required') } - return Promise.all(args.map(spec => { + await Promise.all(args.map(async spec => { log.silly('cache add', 'spec', spec) // we ask pacote for the thing, and then just throw the data // away so that it tee-pipes it into the cache like it does // for a normal request. - return pacote.tarball.stream(spec, stream => { + await pacote.tarball.stream(spec, stream => { stream.resume() return stream.promise() - }, this.npm.flatOptions) + }, { ...this.npm.flatOptions, _isRoot: true }) + + await pacote.manifest(spec, { + ...this.npm.flatOptions, + fullMetadata: true, + _isRoot: true, + }) })) } async verify () { - const cache = path.join(this.npm.cache, '_cacache') - const prefix = cache.indexOf(process.env.HOME) === 0 - ? `~${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)`) + // this is a derived value + const cachePath = this.npm.flatOptions.cache + const prefix = cachePath.indexOf(process.env.HOME) === 0 + ? `~${cachePath.slice(process.env.HOME.length)}` + : cachePath + const stats = await cacache.verify(cachePath) + 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 <spec> ...] + // npm cache ls [<spec> ...] async ls (specs) { - const cachePath = path.join(this.npm.cache, '_cacache') + // This is a derived value + const { cache: cachePath } = this.npm.flatOptions const cacheKeys = Object.keys(await cacache.ls(cachePath)) if (specs.length > 0) { // get results for each package spec specified @@ -207,10 +231,140 @@ 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)) + } + + async #npxCache (keys = []) { + // This is a derived value + const { npxCache } = this.npm.flatOptions + let dirs + try { + dirs = await fs.readdir(npxCache, { encoding: 'utf-8' }) + } catch { + output.standard('npx cache does not exist') + return + } + const cache = {} + const { default: pMap } = await import('p-map') + await pMap(dirs, async e => { + const pkgPath = join(npxCache, e) + cache[e] = { + hash: e, + path: pkgPath, + valid: false, + } + try { + const pkgJson = await PkgJson.load(pkgPath) + cache[e].package = pkgJson.content + cache[e].valid = true + } catch { + // Defaults to not valid already + } + }, { concurrency: 20 }) + if (!keys.length) { + return cache + } + const result = {} + const abbrevs = abbrev(Object.keys(cache)) + for (const key of keys) { + if (!abbrevs[key]) { + throw this.usageError(`Invalid npx key ${key}`) + } + result[abbrevs[key]] = cache[abbrevs[key]] + } + return result + } + + async npxLs () { + const cache = await this.#npxCache() + for (const key in cache) { + const { hash, valid, package: pkg } = cache[key] + let result = `${hash}:` + if (!valid) { + result = `${result} (empty/invalid)` + } else if (pkg?._npx) { + result = `${result} ${pkg._npx.packages.join(', ')}` + } else { + result = `${result} (unknown)` + } + output.standard(result) + } + } + + async npxRm (keys) { + if (!keys.length) { + if (!this.npm.config.get('force')) { + throw this.usageError('Please use --force to remove entire npx cache') + } + const { npxCache } = this.npm.flatOptions + if (!this.npm.config.get('dry-run')) { + return fs.rm(npxCache, { recursive: true, force: true }) + } + } + + const cache = await this.#npxCache(keys) + for (const key in cache) { + const { path: cachePath } = cache[key] + output.standard(`Removing npx key at ${cachePath}`) + if (!this.npm.config.get('dry-run')) { + await fs.rm(cachePath, { recursive: true }) + } + } + } + + async npxInfo (keys) { + const chalk = this.npm.chalk + if (!keys.length) { + throw this.usageError() + } + const cache = await this.#npxCache(keys) + const Arborist = require('@npmcli/arborist') + for (const key in cache) { + const { hash, path, package: pkg } = cache[key] + let valid = cache[key].valid + const results = [] + try { + if (valid) { + const arb = new Arborist({ path }) + const tree = await arb.loadVirtual() + if (pkg._npx) { + results.push('packages:') + for (const p of pkg._npx.packages) { + const parsed = npa(p) + if (parsed.type === 'directory') { + // in the tree the spec is relative, even if the dependency spec is absolute, so we can't find it by name or spec. + results.push(`- ${chalk.cyan(p)}`) + } else { + results.push(`- ${chalk.cyan(p)} (${chalk.blue(tree.children.get(parsed.name).pkgid)})`) + } + } + } else { + results.push('packages: (unknown)') + results.push(`dependencies:`) + for (const dep in pkg.dependencies) { + const child = tree.children.get(dep) + if (child.isLink) { + results.push(`- ${chalk.cyan(child.realpath)}`) + } else { + results.push(`- ${chalk.cyan(child.pkgid)}`) + } + } + } + } + } catch (ex) { + valid = false + } + const v = valid ? chalk.green('valid') : chalk.red('invalid') + output.standard(`${v} npx cache entry with key ${chalk.blue(hash)}`) + output.standard(`location: ${chalk.blue(path)}`) + if (valid) { + output.standard(results.join('\n')) + } + output.standard('') + } } } diff --git a/lib/commands/ci.js b/lib/commands/ci.js index 0adf203a9856e..7480e645a4e0d 100644 --- a/lib/commands/ci.js +++ b/lib/commands/ci.js @@ -1,21 +1,33 @@ -const util = require('util') -const Arborist = require('@npmcli/arborist') -const rimraf = util.promisify(require('rimraf')) const reifyFinish = require('../utils/reify-finish.js') const runScript = require('@npmcli/run-script') -const fs = require('fs') -const readdir = util.promisify(fs.readdir) -const log = require('../utils/log-shim.js') +const fs = require('node:fs/promises') +const path = require('node:path') +const { log, time } = require('proc-log') const validateLockfile = require('../utils/validate-lockfile.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') -const Install = require('./install.js') +const getWorkspaces = require('../utils/get-workspaces.js') class CI extends ArboristWorkspaceCmd { static description = 'Clean install a project' static name = 'ci' - static params = Install.params + // These are in the order they will show up in when running "-h" + static params = [ + 'install-strategy', + 'legacy-bundling', + 'global-style', + 'omit', + 'include', + 'strict-peer-deps', + 'foreground-scripts', + 'ignore-scripts', + 'allow-git', + 'audit', + 'bin-links', + 'fund', + 'dry-run', + ...super.params, + ] async exec () { if (this.npm.global) { @@ -25,6 +37,7 @@ class CI extends ArboristWorkspaceCmd { } const where = this.npm.prefix + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, packageLock: true, // npm ci should never skip lock files @@ -64,14 +77,26 @@ class CI extends ArboristWorkspaceCmd { ) } - // Only remove node_modules after we've successfully loaded the virtual - // tree and validated the lockfile - await this.npm.time('npm-ci:rm', async () => { - const path = `${where}/node_modules` - // get the list of entries so we can skip the glob for performance - const entries = await readdir(path, null).catch(er => []) - return Promise.all(entries.map(f => rimraf(`${path}/${f}`, { glob: false }))) - }) + const dryRun = this.npm.config.get('dry-run') + if (!dryRun) { + const workspacePaths = await getWorkspaces([], { + path: this.npm.localPrefix, + includeWorkspaceRoot: true, + }) + + // Only remove node_modules after we've successfully loaded the virtual + // tree and validated the lockfile + await time.start('npm-ci:rm', async () => { + return await Promise.all([...workspacePaths.values()].map(async modulePath => { + const fullPath = path.join(modulePath, 'node_modules') + // get the list of entries so we can skip the glob for performance + const entries = await fs.readdir(fullPath, null).catch(() => []) + return Promise.all(entries.map(folder => { + return fs.rm(path.join(fullPath, folder), { force: true, recursive: true }) + })) + })) + }) + } await arb.reify(opts) @@ -94,8 +119,6 @@ class CI extends ArboristWorkspaceCmd { args: [], scriptShell, stdio: 'inherit', - stdioString: true, - banner: !this.npm.silent, event, }) } diff --git a/lib/commands/completion.js b/lib/commands/completion.js index c24fb050dcb34..ae459aaaf31ce 100644 --- a/lib/commands/completion.js +++ b/lib/commands/completion.js @@ -4,7 +4,7 @@ // zsh or bash when calling a function for completion, based on the cursor // position and the command line thus far. These are: // COMP_CWORD: the index of the "word" in the command line being completed -// COMP_LINE: the full command line thusfar as a string +// COMP_LINE: the full command line thus far as a string // COMP_POINT: the cursor index at the point of triggering completion // // We parse the command line with nopt, like npm does, and then create an @@ -27,42 +27,33 @@ // 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('@npmcli/fs') +const fs = require('node:fs/promises') const nopt = require('nopt') +const { resolve } = require('node: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 { 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 { definitions, shorthands } = require('../utils/config/index.js') -const { aliases, cmdList, plumbing } = require('../utils/cmd-list.js') -const aliasNames = Object.keys(aliases) -const fullList = cmdList.concat(aliasNames).filter(c => !plumbing.includes(c)) const configNames = Object.keys(definitions) const shorthandNames = Object.keys(shorthands) const allConfs = configNames.concat(shorthandNames) -const { isWindowsShell } = require('../utils/is-windows.js') -const fileExists = async (file) => { - try { - const stat = await fs.stat(file) - return stat.isFile() - } catch { - return false - } -} - -const BaseCommand = require('../base-command.js') class Completion extends BaseCommand { static description = 'Tab Completion for npm' static name = 'completion' - static ignoreImplicitWorkspace = false // completion for the completion command - async completion (opts) { + static async completion (opts) { if (opts.w > 2) { return } - const { resolve } = require('path') const [bashExists, zshExists] = await Promise.all([ fileExists(resolve(process.env.HOME, '.bashrc')), fileExists(resolve(process.env.HOME, '.zshrc')), @@ -87,13 +78,11 @@ class Completion extends BaseCommand { }) } - const { COMP_CWORD, COMP_LINE, COMP_POINT } = process.env + const { COMP_CWORD, COMP_LINE, COMP_POINT, COMP_FISH } = process.env // if the COMP_* isn't in the env, then just dump the script. - if (COMP_CWORD === undefined || - COMP_LINE === undefined || - COMP_POINT === undefined) { - return dumpScript() + if (COMP_CWORD === undefined || COMP_LINE === undefined || COMP_POINT === undefined) { + return dumpScript(resolve(this.npm.npmRoot, 'lib', 'utils', 'completion.sh')) } // ok we're actually looking at the envs and outputting the suggestions @@ -119,6 +108,7 @@ class Completion extends BaseCommand { partialWords.push(partialWord) const opts = { + isFish: COMP_FISH === 'true', words, w, word, @@ -150,9 +140,9 @@ class Completion extends BaseCommand { // take a little shortcut and use npm's arg parsing logic. // don't have to worry about the last arg being implicitly // boolean'ed, since the last block will catch that. - const types = Object.entries(definitions).reduce((types, [key, def]) => { - types[key] = def.type - return types + const types = Object.entries(definitions).reduce((acc, [key, def]) => { + acc[key] = def.type + return acc }, {}) const parsed = opts.conf = nopt(types, shorthands, partialWords.slice(0, -1), 0) @@ -167,10 +157,14 @@ class Completion extends BaseCommand { // at this point, if words[1] is some kind of npm command, // then complete on it. // otherwise, do nothing - const impl = await this.npm.cmd(cmd) - if (impl.completion) { - const comps = await impl.completion(opts) - return this.wrap(opts, comps) + try { + const { completion } = Npm.cmd(cmd) + if (completion) { + const comps = await completion(opts, this.npm) + return this.wrap(opts, comps) + } + } catch { + // it wasn't a valid command, so do nothing } } @@ -191,15 +185,12 @@ class Completion extends BaseCommand { } if (compls.length > 0) { - this.npm.output(compls.join('\n')) + output.standard(compls.join('\n')) } } } -const dumpScript = async () => { - const { resolve } = require('path') - const p = resolve(__dirname, '..', 'utils', 'completion.sh') - +const dumpScript = async (p) => { const d = (await fs.readFile(p, 'utf8')).replace(/^#!.*?\n/, '') await new Promise((res, rej) => { let done = false @@ -257,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 => { @@ -274,18 +265,19 @@ 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 matches = fullList.filter(c => c.startsWith(opts.partialWord)) +const cmdCompl = (opts) => { + const allCommands = commands.concat(Object.keys(aliases)) + const matches = allCommands.filter(c => c.startsWith(opts.partialWord)) if (!matches.length) { return matches } - const derefs = new Set([...matches.map(c => npm.deref(c))]) + const derefs = new Set([...matches.map(c => deref(c))]) if (derefs.size === 1) { return [...derefs] } - return fullList + return allCommands } module.exports = Completion diff --git a/lib/commands/config.js b/lib/commands/config.js index 96dd4abcaf4af..ce26a46b877da 100644 --- a/lib/commands/config.js +++ b/lib/commands/config.js @@ -1,18 +1,31 @@ -// don't expand so that we only assemble the set of defaults when needed -const configDefs = require('../utils/config/index.js') - -const mkdirp = require('mkdirp-infer-owner') -const { dirname, resolve } = require('path') -const { promisify } = require('util') -const fs = require('fs') -const readFile = promisify(fs.readFile) -const writeFile = promisify(fs.writeFile) -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 rpj = require('read-package-json-fast') -const log = require('../utils/log-shim.js') +const pkgJson = require('@npmcli/package-json') +const { defaults, definitions, nerfDarts, proxyEnv } = require('@npmcli/config/lib/definitions') +const { log, output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') +const { redact } = require('@npmcli/redact') + +// These are the config values to swap with "protected". It does not catch +// every single sensitive thing a user may put in the npmrc file but it gets +// the common ones. This is distinct from nerfDarts because that is used to +// validate valid configs during "npm config set", and folks may have old +// invalid entries lying around in a config file that we still want to protect +// when running "npm config list" +// This is a more general list of values to consider protected. You cannot +// "npm config get" them, and they will not display during "npm config list" +const protected = [ + 'auth', + 'authToken', + 'certfile', + 'email', + 'keyfile', + 'password', + 'username', +] // take an array of `[key, value, k2=v2, k3, v3, ...]` and turn into // { key: value, k2: v2, k3: v3 } @@ -29,19 +42,35 @@ const keyValues = args => { return kv } -const publicVar = k => { +const isProtected = (k) => { // _password if (k.startsWith('_')) { - return false + return true + } + if (protected.includes(k)) { + return true } // //localhost:8080/:_password - if (k.startsWith('//') && k.includes(':_')) { - return false + if (k.startsWith('//')) { + if (k.includes(':_')) { + return true + } + // //registry:_authToken or //registry:authToken + for (const p of protected) { + if (k.endsWith(`:${p}`) || k.endsWith(`:_${p}`)) { + return true + } + } } - return true + return false } -const BaseCommand = require('../base-command.js') +// Private fields are either protected or they can redacted info +const isPrivate = (k, v) => isProtected(k) || redact(v) !== v + +const displayVar = (k, v) => + `${k} = ${isProtected(k, v) ? '(protected)' : JSON.stringify(redact(v))}` + class Config extends BaseCommand { static description = 'Manage the npm configuration files' static name = 'config' @@ -51,6 +80,7 @@ class Config extends BaseCommand { 'delete <key> [<key> ...]', 'list [--json]', 'edit', + 'fix', ] static params = [ @@ -63,14 +93,16 @@ class Config extends BaseCommand { static ignoreImplicitWorkspace = false - async completion (opts) { + static skipConfigValidation = true + + static async completion (opts) { const argv = opts.conf.argv.remain if (argv[1] !== 'config') { argv.unshift('config') } if (argv.length === 2) { - const cmds = ['get', 'set', 'delete', 'ls', 'rm', 'edit'] + const cmds = ['get', 'set', 'delete', 'ls', 'rm', 'edit', 'fix'] if (opts.partialWord !== 'l') { cmds.push('list') } @@ -81,7 +113,7 @@ class Config extends BaseCommand { const action = argv[2] switch (action) { case 'set': - // todo: complete with valid values, if possible. + // TODO: complete with valid values, if possible. if (argv.length > 3) { return [] } @@ -91,47 +123,41 @@ class Config extends BaseCommand { case 'get': case 'delete': case 'rm': - return Object.keys(configDefs.definitions) + return Object.keys(definitions) case 'edit': case 'list': case 'ls': + case 'fix': default: return [] } } - async execWorkspaces (args, filters) { - log.warn('config', 'This command does not support workspaces.') - return this.exec(args) - } - 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 - 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() } } @@ -143,7 +169,23 @@ class Config extends BaseCommand { const where = this.npm.flatOptions.location for (const [key, val] of Object.entries(keyValues(args))) { log.info('config', 'set %j %j', key, val) - this.npm.config.set(key, val || '', where) + const baseKey = key.split(':').pop() + if (!this.npm.config.definitions[baseKey] && !nerfDarts.includes(baseKey)) { + throw new Error(`\`${baseKey}\` is not a valid npm option`) + } + const deprecated = this.npm.config.definitions[baseKey]?.deprecated + if (deprecated) { + throw new Error( + `The \`${baseKey}\` option is deprecated, and cannot be set in this way${deprecated}` + ) + } + + if (val === '') { + this.npm.config.delete(key, where) + } else { + this.npm.config.set(key, val, where) + } + if (!this.npm.config.validate(where)) { log.warn('config', 'omitting invalid config values') } @@ -159,14 +201,15 @@ class Config extends BaseCommand { const out = [] for (const key of keys) { - if (!publicVar(key)) { + const val = this.npm.config.get(key) + if (isPrivate(key, val)) { throw new Error(`The ${key} option is protected, and cannot be retrieved in this way`) } const pref = keys.length > 1 ? `${key}=` : '' - out.push(pref + this.npm.config.get(key)) + out.push(pref + val) } - this.npm.output(out.join('\n')) + output.standard(out.join('\n')) } async del (keys) { @@ -182,6 +225,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 @@ -193,7 +237,7 @@ class Config extends BaseCommand { const data = ( await readFile(file, 'utf8').catch(() => '') ).replace(/\r\n/g, '\n') - const entries = Object.entries(configDefs.defaults) + const entries = Object.entries(defaults) const defData = entries.reduce((str, [key, val]) => { const obj = { [key]: val } const i = ini.stringify(obj) @@ -224,20 +268,63 @@ ${data.split('\n').sort(localeCompare).join('\n').trim()} ${defData} `.split('\n').join(EOL) - await mkdirp(dirname(file)) + await mkdir(dirname(file), { recursive: true }) await writeFile(file, tmpData, 'utf8') - await new Promise((resolve, reject) => { + await new Promise((res, rej) => { const [bin, ...args] = e.split(/\s+/) const editor = spawn(bin, [...args, file], { stdio: 'inherit' }) editor.on('exit', (code) => { if (code) { - return reject(new Error(`editor process exited with code: ${code}`)) + return rej(new Error(`editor process exited with code: ${code}`)) } - return resolve() + return res() }) }) } + async fix () { + let problems + + try { + this.npm.config.validate() + return // if validate doesn't throw we have nothing to do + } catch (err) { + // coverage skipped because we don't need to test rethrowing errors + // istanbul ignore next + if (err.code !== 'ERR_INVALID_AUTH') { + throw err + } + + problems = err.problems + } + + if (!this.npm.config.isDefault('location')) { + problems = problems.filter((problem) => { + return problem.where === this.npm.config.get('location') + }) + } + + this.npm.config.repair(problems) + const locations = [] + + 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 + if (action === 'rename') { + // we keep track of which configs were modified here so we know what to save later + locations.push(where) + return `~ \`${from}\` renamed to \`${to}\` in ${where} config` + } else if (action === 'delete') { + locations.push(where) + return `- \`${key}\` deleted from ${where} config` + } + }).join('\n') + output.standard(summary) + + return await Promise.all(locations.map((location) => this.npm.config.save(location))) + } + async list () { const msg = [] // long does not have a flattener @@ -247,23 +334,39 @@ ${defData} continue } - const keys = Object.keys(data).sort(localeCompare) - if (!keys.length) { + const entries = Object.entries(data).sort(([a], [b]) => localeCompare(a, b)) + if (!entries.length) { continue } msg.push(`; "${where}" config from ${source}`, '') - for (const k of keys) { - const v = publicVar(k) ? JSON.stringify(data[k]) : '(protected)' + for (const [k, v] of entries) { + const display = displayVar(k, v) const src = this.npm.config.find(k) - const overridden = src !== where - msg.push((overridden ? '; ' : '') + - `${k} = ${v} ${overridden ? `; overridden by ${src}` : ''}`) + msg.push(src === where ? display : `; ${display} ; overridden by ${src}`) + msg.push() } msg.push('') } if (!long) { + const envVars = [] + + const foundEnvVars = new Set() + for (const key of Object.keys(process.env)) { + const lowerKey = key.toLowerCase() + if (proxyEnv.includes(lowerKey) && !foundEnvVars.has(lowerKey)) { + foundEnvVars.add(lowerKey) + envVars.push(`; ${key} = ${JSON.stringify(process.env[key])}`) + } + } + + if (envVars.length > 0) { + msg.push('; environment-related config', '') + msg.push(...envVars) + msg.push('') + } + msg.push( `; node bin location = ${process.execPath}`, `; node version = ${process.version}`, @@ -277,34 +380,38 @@ ${defData} } if (!this.npm.global) { - const pkgPath = resolve(this.npm.prefix, 'package.json') - const pkg = await rpj(pkgPath).catch(() => ({})) + const { content } = await pkgJson.normalize(this.npm.prefix).catch(() => ({ content: {} })) - if (pkg.publishConfig) { + if (content.publishConfig) { + for (const key in content.publishConfig) { + this.npm.config.checkUnknown('publishConfig', key) + } + const pkgPath = resolve(this.npm.prefix, 'package.json') msg.push(`; "publishConfig" from ${pkgPath}`) msg.push('; This set of config values will be used at publish-time.', '') - const pkgKeys = Object.keys(pkg.publishConfig).sort(localeCompare) - for (const k of pkgKeys) { - const v = publicVar(k) ? JSON.stringify(pkg.publishConfig[k]) : '(protected)' - msg.push(`${k} = ${v}`) + const entries = Object.entries(content.publishConfig) + .sort(([a], [b]) => localeCompare(a, b)) + for (const [k, value] of entries) { + msg.push(displayVar(k, value)) } msg.push('') } } - this.npm.output(msg.join('\n').trim()) + output.standard(msg.join('\n').trim()) } async listJson () { const publicConf = {} for (const key in this.npm.config.list[0]) { - if (!publicVar(key)) { + const value = this.npm.config.get(key) + if (isPrivate(key, value)) { continue } - publicConf[key] = this.npm.config.get(key) + publicConf[key] = value } - this.npm.output(JSON.stringify(publicConf, null, 2)) + output.buffer(publicConf) } } diff --git a/lib/commands/dedupe.js b/lib/commands/dedupe.js index 2cc44b2a9fb2f..3b7365c2011d3 100644 --- a/lib/commands/dedupe.js +++ b/lib/commands/dedupe.js @@ -1,19 +1,20 @@ -// dedupe duplicated packages, or find them in the tree -const Arborist = require('@npmcli/arborist') 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' static params = [ - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'strict-peer-deps', 'package-lock', 'omit', + 'include', 'ignore-scripts', + 'allow-git', 'audit', 'bin-links', 'fund', @@ -21,7 +22,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' @@ -30,6 +31,7 @@ class Dedupe extends ArboristWorkspaceCmd { const dryRun = this.npm.config.get('dry-run') const where = this.npm.prefix + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, path: where, diff --git a/lib/commands/deprecate.js b/lib/commands/deprecate.js index 068bfdbcec717..d8d33ad9b9d03 100644 --- a/lib/commands/deprecate.js +++ b/lib/commands/deprecate.js @@ -1,10 +1,11 @@ -const fetch = require('npm-registry-fetch') -const otplease = require('../utils/otplease.js') +const npmFetch = require('npm-registry-fetch') +const { otplease } = require('../utils/auth.js') const npa = require('npm-package-arg') +const { log } = require('proc-log') 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' @@ -13,20 +14,21 @@ class Deprecate extends BaseCommand { static params = [ 'registry', 'otp', + 'dry-run', ] - static ignoreImplicitWorkspace = false + static ignoreImplicitWorkspace = true - async completion (opts) { + static async completion (opts, npm) { if (opts.conf.argv.remain.length > 1) { return [] } - const username = await getIdentity(this.npm, this.npm.flatOptions) - const packages = await libaccess.lsPackages(username, this.npm.flatOptions) + const username = await getIdentity(npm, npm.flatOptions) + const packages = await libaccess.getPackages(username, npm.flatOptions) return Object.keys(packages) .filter((name) => - packages[name] === 'read-write' && + packages[name] === 'write' && (opts.conf.argv.remain.length === 0 || name.startsWith(opts.conf.argv.remain[0]))) } @@ -39,34 +41,45 @@ class Deprecate extends BaseCommand { // fetch the data and make sure it exists. const p = npa(pkg) - // npa makes the default spec "latest", but for deprecation - // "*" is the appropriate default. - const spec = p.rawSpec === '' ? '*' : p.fetchSpec + const spec = p.rawSpec === '*' ? '*' : p.fetchSpec if (semver.validRange(spec, true) === null) { throw new Error(`invalid version range: ${spec}`) } const uri = '/' + p.escapedName - const packument = await fetch.json(uri, { + const packument = await npmFetch.json(uri, { ...this.npm.flatOptions, spec: p, query: { write: true }, }) - Object.keys(packument.versions) + const versions = Object.keys(packument.versions) .filter(v => semver.satisfies(v, spec, { includePrerelease: true })) - .forEach(v => { - packument.versions[v].deprecated = msg - }) - return otplease(this.npm, this.npm.flatOptions, opts => fetch(uri, { - ...opts, - spec: p, - method: 'PUT', - body: packument, - ignoreBody: true, - })) + const dryRun = this.npm.config.get('dry-run') + + if (versions.length) { + for (const v of versions) { + packument.versions[v].deprecated = msg + if (msg) { + log.notice(`deprecating ${packument.name}@${v} with message "${msg}"`) + } else { + log.notice(`undeprecating ${packument.name}@${v}`) + } + } + if (!dryRun) { + return otplease(this.npm, this.npm.flatOptions, opts => npmFetch(uri, { + ...opts, + spec: p, + method: 'PUT', + body: packument, + ignoreBody: true, + })) + } + } else { + log.warn('deprecate', 'No version found for', p.rawSpec) + } } } diff --git a/lib/commands/diff.js b/lib/commands/diff.js index bbd6fae6680ca..d104218b3d7ef 100644 --- a/lib/commands/diff.js +++ b/lib/commands/diff.js @@ -1,13 +1,12 @@ -const { resolve } = require('path') +const { resolve } = require('node:path') const semver = require('semver') const libnpmdiff = require('libnpmdiff') const npa = require('npm-package-arg') -const Arborist = require('@npmcli/arborist') const pacote = require('pacote') const pickManifest = require('npm-pick-manifest') -const log = require('../utils/log-shim') -const readPackage = require('read-package-json-fast') -const BaseCommand = require('../base-command.js') +const { log, output } = require('proc-log') +const pkgJson = require('@npmcli/package-json') +const BaseCommand = require('../base-cmd.js') class Diff extends BaseCommand { static description = 'The registry diff command' @@ -32,6 +31,7 @@ class Diff extends BaseCommand { 'include-workspace-root', ] + static workspaces = true static ignoreImplicitWorkspace = false async exec (args) { @@ -64,11 +64,11 @@ class Diff extends BaseCommand { diffFiles: args, where: this.top, }) - return this.npm.output(res) + return output.standard(res) } - async execWorkspaces (args, filters) { - await this.setWorkspaces(filters) + async execWorkspaces (args) { + await this.setWorkspaces() for (const workspacePath of this.workspacePaths) { this.top = workspacePath this.prefix = workspacePath @@ -78,12 +78,12 @@ 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 pkg = await readPackage(resolve(this.prefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.prefix) name = pkg.name - } catch (e) { + } catch { log.verbose('diff', 'could not read project dir package.json') } @@ -103,10 +103,10 @@ 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')}`, + `file:${this.prefix}`, ] } @@ -115,9 +115,9 @@ class Diff extends BaseCommand { let noPackageJson let pkgName try { - const pkg = await readPackage(resolve(this.prefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.prefix) pkgName = pkg.name - } catch (e) { + } catch { log.verbose('diff', 'could not read project dir package.json') noPackageJson = true } @@ -134,7 +134,7 @@ class Diff extends BaseCommand { } return [ `${pkgName}@${a}`, - `file:${this.prefix.replace(/#/g, '%23')}`, + `file:${this.prefix}`, ] } @@ -145,6 +145,7 @@ class Diff extends BaseCommand { if (spec.registry) { let actualTree let node + const Arborist = require('@npmcli/arborist') try { const opts = { ...this.npm.flatOptions, @@ -155,7 +156,7 @@ class Diff extends BaseCommand { node = actualTree && actualTree.inventory.query('name', spec.name) .values().next().value - } catch (e) { + } catch { log.verbose('diff', 'failed to load actual install tree') } @@ -165,7 +166,7 @@ class Diff extends BaseCommand { } return [ `${spec.name}@${spec.fetchSpec}`, - `file:${this.prefix.replace(/#/g, '%23')}`, + `file:${this.prefix}`, ] } @@ -178,14 +179,14 @@ class Diff extends BaseCommand { } } - const aSpec = `file:${node.realpath.replace(/#/g, '%23')}` + const aSpec = `file:${node.realpath}` - // finds what version of the package to compare against, if a exact - // version or tag was passed than it should use that, otherwise + // finds what version of the package to compare against, if an exact + // version or tag was passed than it should use that; otherwise, // work from the top of the arborist tree to find the original semver // range declared in the package that depends on the package. let bSpec - if (spec.rawSpec) { + if (spec.rawSpec !== '*') { bSpec = spec.rawSpec } else { const bTargetVersion = @@ -197,6 +198,7 @@ class Diff extends BaseCommand { const packument = await pacote.packument(spec, { ...this.npm.flatOptions, preferOnline: true, + _isRoot: true, }) bSpec = pickManifest( packument, @@ -211,8 +213,8 @@ class Diff extends BaseCommand { ] } else if (spec.type === 'directory') { return [ - `file:${spec.fetchSpec.replace(/#/g, '%23')}`, - `file:${this.prefix.replace(/#/g, '%23')}`, + `file:${spec.fetchSpec}`, + `file:${this.prefix}`, ] } else { throw this.usageError(`Spec type ${spec.type} not supported.`) @@ -227,9 +229,9 @@ class Diff extends BaseCommand { if (semverA && semverB) { let pkgName try { - const pkg = await readPackage(resolve(this.prefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.prefix) pkgName = pkg.name - } catch (e) { + } catch { log.verbose('diff', 'could not read project dir package.json') } @@ -256,6 +258,7 @@ class Diff extends BaseCommand { async findVersionsByPackageName (specs) { let actualTree + const Arborist = require('@npmcli/arborist') try { const opts = { ...this.npm.flatOptions, @@ -263,13 +266,13 @@ class Diff extends BaseCommand { } const arb = new Arborist(opts) actualTree = await arb.loadActual(opts) - } catch (e) { + } catch { log.verbose('diff', 'failed to load actual install tree') } return specs.map(i => { const spec = npa(i) - if (spec.rawSpec) { + if (spec.rawSpec !== '*') { return i } @@ -279,7 +282,7 @@ class Diff extends BaseCommand { const res = !node || !node.package || !node.package.version ? spec.fetchSpec - : `file:${node.realpath.replace(/#/g, '%23')}` + : `file:${node.realpath}` return `${spec.name}@${res}` }) diff --git a/lib/commands/dist-tag.js b/lib/commands/dist-tag.js index 8052e4f7e4e38..655ec0d17539e 100644 --- a/lib/commands/dist-tag.js +++ b/lib/commands/dist-tag.js @@ -1,11 +1,10 @@ const npa = require('npm-package-arg') -const path = require('path') -const regFetch = require('npm-registry-fetch') +const npmFetch = require('npm-registry-fetch') const semver = require('semver') -const log = require('../utils/log-shim') -const otplease = require('../utils/otplease.js') -const readPackage = require('read-package-json-fast') -const BaseCommand = require('../base-command.js') +const { log, output } = require('proc-log') +const { otplease } = require('../utils/auth.js') +const pkgJson = require('@npmcli/package-json') +const BaseCommand = require('../base-cmd.js') class DistTag extends BaseCommand { static description = 'Modify package distribution tags' @@ -17,9 +16,10 @@ class DistTag extends BaseCommand { 'ls [<package-spec>]', ] + static workspaces = true static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { return ['add', 'rm', 'ls'] @@ -57,14 +57,14 @@ class DistTag extends BaseCommand { } } - async execWorkspaces ([cmdName, pkg, tag], filters) { + async execWorkspaces ([cmdName, pkg, tag]) { // cmdName is some form of list // pkg is one of: // - unset // - . // - .@version if (['ls', 'l', 'sl', 'list'].includes(cmdName) && (!pkg || pkg === '.' || /^\.@/.test(pkg))) { - return this.listWorkspaces(filters) + return this.listWorkspaces() } // pkg is unset @@ -73,12 +73,12 @@ class DistTag extends BaseCommand { // - . // - .@version if (!pkg && (!cmdName || cmdName === '.' || /^\.@/.test(cmdName))) { - return this.listWorkspaces(filters) + return this.listWorkspaces() } // anything else is just a regular dist-tag command - // so we fallback to the non-workspaces implementation - log.warn('Ignoring workspaces for specified package') + // so we fall back to the non-workspaces implementation + log.warn('dist-tag', 'Ignoring workspaces for specified package') return this.exec([cmdName, pkg, tag]) } @@ -89,6 +89,9 @@ class DistTag extends BaseCommand { log.verbose('dist-tag add', defaultTag, 'to', spec.name + '@' + version) + // make sure new spec with tag is valid, this will throw if invalid + npa(`${spec.name}@${defaultTag}`) + if (!spec.name || !version || !defaultTag) { throw this.usageError('must provide a spec with a name and version, and a tag to add') } @@ -116,8 +119,8 @@ class DistTag extends BaseCommand { }, spec, } - await otplease(this.npm, reqOpts, reqOpts => regFetch(url, reqOpts)) - this.npm.output(`+${t}: ${spec.name}@${version}`) + await otplease(this.npm, reqOpts, o => npmFetch(url, o)) + output.standard(`+${t}: ${spec.name}@${version}`) } async remove (spec, tag, opts) { @@ -142,8 +145,8 @@ class DistTag extends BaseCommand { method: 'DELETE', spec, } - await otplease(this.npm, reqOpts, reqOpts => regFetch(url, reqOpts)) - this.npm.output(`-${tag}: ${spec.name}@${version}`) + await otplease(this.npm, reqOpts, o => npmFetch(url, o)) + output.standard(`-${tag}: ${spec.name}@${version}`) } async list (spec, opts) { @@ -151,7 +154,7 @@ class DistTag extends BaseCommand { if (this.npm.global) { throw this.usageError() } - const { name } = await readPackage(path.resolve(this.npm.prefix, 'package.json')) + const { content: { name } } = await pkgJson.normalize(this.npm.prefix) if (!name) { throw this.usageError() } @@ -164,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) @@ -172,14 +175,14 @@ class DistTag extends BaseCommand { } } - async listWorkspaces (filters) { - await this.setWorkspaces(filters) + async listWorkspaces () { + await this.setWorkspaces() for (const name of this.workspaceNames) { try { - this.npm.output(`${name}:`) + output.standard(`${name}:`) await this.list(npa(name), this.npm.flatOptions) - } catch (err) { + } catch { // set the exitCode directly, but ignore the error // since it will have already been logged by this.list() process.exitCode = 1 @@ -188,7 +191,7 @@ class DistTag extends BaseCommand { } async fetchTags (spec, opts) { - const data = await regFetch.json( + const data = await npmFetch.json( `/-/package/${spec.escapedName}/dist-tags`, { ...opts, 'prefer-online': true, spec } ) @@ -202,4 +205,5 @@ class DistTag extends BaseCommand { return data } } + module.exports = DistTag diff --git a/lib/commands/docs.js b/lib/commands/docs.js index 5d20215b56a07..2259b49f79617 100644 --- a/lib/commands/docs.js +++ b/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/lib/commands/doctor.js b/lib/commands/doctor.js index f5bee1eb83f6c..a537478bee3fe 100644 --- a/lib/commands/doctor.js +++ b/lib/commands/doctor.js @@ -1,22 +1,15 @@ const cacache = require('cacache') -const fs = require('fs') -const fetch = require('make-fetch-happen') -const table = require('text-table') +const { access, lstat, readdir, constants: { R_OK, W_OK, X_OK } } = require('node:fs/promises') +const npmFetch = require('make-fetch-happen') const which = require('which') const pacote = require('pacote') -const { resolve } = require('path') +const { resolve } = require('node:path') const semver = require('semver') -const { promisify } = require('util') -const log = require('../utils/log-shim.js') -const ansiTrim = require('../utils/ansi-trim.js') +const { log, output } = require('proc-log') const ping = require('../utils/ping.js') -const { - registry: { default: defaultRegistry }, -} = require('../utils/config/definitions.js') -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 { defaults } = require('@npmcli/config/lib/definitions') +const BaseCommand = require('../base-cmd.js') + const maskLabel = mask => { const label = [] if (mask & R_OK) { @@ -34,102 +27,116 @@ const maskLabel = mask => { return label.join(', ') } -const BaseCommand = require('../base-command.js') +const subcommands = [ + { + // 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: 'Checking npm version', + cmd: 'getLatestNpmVersion', + }, { + groups: ['versions'], + title: 'Checking node version', + cmd: 'getLatestNodejsVersion', + }, { + groups: ['registry'], + title: 'Checking configured npm registry', + cmd: 'checkNpmRegistry', + }, { + groups: ['environment'], + title: 'Checking for git executable in PATH', + cmd: 'getGitPath', + }, { + groups: ['environment'], + title: 'Checking for global bin folder in PATH', + cmd: 'getBinPath', + }, { + groups: ['permissions', 'cache'], + title: 'Checking permissions on cached files (this may take awhile)', + cmd: 'checkCachePermission', + windows: false, + }, { + groups: ['permissions'], + title: 'Checking permissions on local node_modules (this may take awhile)', + cmd: 'checkLocalModulesPermission', + windows: false, + }, { + groups: ['permissions'], + title: 'Checking permissions on global node_modules (this may take awhile)', + cmd: 'checkGlobalModulesPermission', + windows: false, + }, { + groups: ['permissions'], + title: 'Checking permissions on local bin folder', + cmd: 'checkLocalBinPermission', + windows: false, + }, { + groups: ['permissions'], + title: 'Checking permissions on global bin folder', + cmd: 'checkGlobalBinPermission', + windows: false, + }, { + groups: ['cache'], + title: 'Verifying cache contents (this may take awhile)', + cmd: 'verifyCachedFiles', + windows: false, + }, + // TODO: + // group === 'dependencies'? + // - ensure arborist.loadActual() runs without errors and no invalid edges + // - ensure package-lock.json matches loadActual() + // - verify loadActual without hidden lock file matches hidden lockfile + // group === '???' + // - verify all local packages have bins linked + // What is the fix for these? +] + class Doctor extends BaseCommand { - static description = 'Check your npm environment' + 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 && value !== 'ping') + .join('] [')}]`] - async exec (args) { - log.info('Running checkup') - - // each message is [title, ok, message] - const messages = [] - - const actions = [ - ['npm ping', 'checkPing', []], - ['npm -v', 'getLatestNpmVersion', []], - ['node -v', 'getLatestNodejsVersion', []], - ['npm config get registry', 'checkNpmRegistry', []], - ['which git', 'getGitPath', []], - ...(process.platform === 'win32' - ? [] - : [ - [ - 'Perms check on cached files', - 'checkFilesPermission', - [this.npm.cache, true, R_OK], - ], [ - 'Perms check on local node_modules', - 'checkFilesPermission', - [this.npm.localDir, true, R_OK | W_OK, true], - ], [ - 'Perms check on global node_modules', - 'checkFilesPermission', - [this.npm.globalDir, false, R_OK], - ], [ - 'Perms check on local bin folder', - 'checkFilesPermission', - [this.npm.localBin, false, R_OK | W_OK | X_OK, true], - ], [ - 'Perms check on global bin folder', - 'checkFilesPermission', - [this.npm.globalBin, false, X_OK], - ], - ]), - [ - 'Verify cache contents', - 'verifyCachedFiles', - [this.npm.flatOptions.cache], - ], - // TODO: - // - ensure arborist.loadActual() runs without errors and no invalid edges - // - ensure package-lock.json matches loadActual() - // - verify loadActual without hidden lock file matches hidden lockfile - // - verify all local packages have bins linked - ] - - // Do the actual work - for (const [msg, fn, args] of actions) { - const line = [msg] - try { - line.push(true, await this[fn](...args)) - } catch (er) { - line.push(false, er) - } - messages.push(line) - } + static subcommands = subcommands - const outHead = ['Check', 'Value', 'Recommendation/Notes'].map(h => this.npm.chalk.underline(h)) + async exec (args) { + log.info('doctor', 'Running checkup') let allOk = true - const outBody = messages.map(item => { - if (!item[1]) { + + const actions = this.actions(args) + + const chalk = this.npm.chalk + for (const { title, cmd } of actions) { + this.output(title) + // TODO when we have an in progress indicator that could go here + let result + try { + result = await this[cmd]() + this.output(`${chalk.green('Ok')}${result ? `\n${result}` : ''}\n`) + } catch (err) { 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') + this.output(`${chalk.red('Not ok')}\n${chalk.cyan(err)}\n`) } - return item - }) - const outTable = [outHead, ...outBody] - const tableOpts = { - stringLength: s => ansiTrim(s).length, } - if (!this.npm.silent) { - this.npm.output(table(outTable, tableOpts)) - } if (!allOk) { - throw new Error('Some problems found. See above for recommendations.') + if (this.npm.silent) { + throw new Error('Some problems found. Check logs or disable silent mode for recommendations.') + } else { + throw new Error('Some problems found. See above for recommendations.') + } } } 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 '' @@ -139,23 +146,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}` } } @@ -164,60 +164,78 @@ 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 npmFetch(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 () { + 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`) + } + return this.npm.globalBin + } + + async checkCachePermission () { + return this.checkFilesPermission(this.npm.cache, true, R_OK) + } + + async checkLocalModulesPermission () { + return this.checkFilesPermission(this.npm.localDir, true, R_OK | W_OK, true) + } + + async checkGlobalModulesPermission () { + return this.checkFilesPermission(this.npm.globalDir, false, R_OK) + } + + async checkLocalBinPermission () { + return this.checkFilesPermission(this.npm.localBin, false, R_OK | W_OK | X_OK, true) + } + + async checkGlobalBinPermission () { + return this.checkFilesPermission(this.npm.globalBin, false, X_OK) } 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 } @@ -227,17 +245,17 @@ class Doctor extends BaseCommand { try { await access(f, mask) - } catch (er) { + } catch { 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) { @@ -246,7 +264,6 @@ class Doctor extends BaseCommand { } } } finally { - tracker.finish() if (!ok) { throw ( `Check the permissions of files in ${root}` + @@ -259,59 +276,71 @@ 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 "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 () { - if (this.npm.flatOptions.registry !== defaultRegistry) { - throw `Try \`npm config set registry=${defaultRegistry}\`` + if (this.npm.flatOptions.registry !== defaults.registry) { + throw `Try \`npm config set registry=${defaults.registry}\`` } else { - return `using default registry (${defaultRegistry})` + return `using default registry (${defaults.registry})` } } + + output (...args) { + // TODO display layer should do this + if (!this.npm.silent) { + output.standard(...args) + } + } + + actions (params) { + return this.constructor.subcommands.filter(subcmd => { + if (process.platform === 'win32' && subcmd.windows === false) { + return false + } + if (params.length) { + return params.some(param => subcmd.groups.includes(param)) + } + return true + }) + } } module.exports = Doctor diff --git a/lib/commands/edit.js b/lib/commands/edit.js index 0256f4f3a6f01..b2c2ec8d2a39a 100644 --- a/lib/commands/edit.js +++ b/lib/commands/edit.js @@ -1,34 +1,31 @@ -// npm edit <pkg> -// open the package folder in the $EDITOR +const { resolve } = require('node:path') +const { lstat } = require('node:fs/promises') +const cp = require('node:child_process') +const completion = require('../utils/installed-shallow.js') +const BaseCommand = require('../base-cmd.js') -const { resolve } = require('path') -const fs = require('graceful-fs') -const cp = require('child_process') -const completion = require('../utils/completion/installed-shallow.js') -const BaseCommand = require('../base-command.js') +const splitPackageNames = (path) => path.split('/') +// combine scoped parts + .reduce((parts, part) => { + if (parts.length === 0) { + return [part] + } -const splitPackageNames = (path) => { - return 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 <pkg> +// open the package folder in the $EDITOR class Edit extends BaseCommand { static description = 'Edit an installed package' static name = 'edit' @@ -38,8 +35,8 @@ class Edit extends BaseCommand { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + return completion(npm, opts) } async exec (args) { @@ -50,22 +47,18 @@ class Edit extends BaseCommand { const path = splitPackageNames(args[0]) const dir = resolve(this.npm.dir, path) - // graceful-fs does not promisify - await new Promise((resolve, reject) => { - fs.lstat(dir, (err) => { - if (err) { - return reject(err) + await lstat(dir) + await new Promise((res, rej) => { + 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, ...args] = this.npm.config.get('editor').split(/\s+/) - const editor = cp.spawn(bin, [...args, dir], { stdio: 'inherit' }) - editor.on('exit', (code) => { - if (code) { - return reject(new Error(`editor process exited with code: ${code}`)) - } - this.npm.exec('rebuild', [dir]).catch(reject).then(resolve) - }) + await this.npm.exec('rebuild', [dir]).then(res).catch(rej) }) }) } } + module.exports = Edit diff --git a/lib/commands/exec.js b/lib/commands/exec.js index ddbb5f7cf9d79..c91222ffe3230 100644 --- a/lib/commands/exec.js +++ b/lib/commands/exec.js @@ -1,6 +1,6 @@ -const path = require('path') +const { resolve } = require('node: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' @@ -20,32 +20,59 @@ class Exec extends BaseCommand { '--package=foo -c \'<cmd> [args...]\'', ] + static workspaces = true static ignoreImplicitWorkspace = false static isShellout = true - async exec (_args, { locationMsg, runPath } = {}) { - // This is where libnpmexec will look for locally installed packages - const localPrefix = this.npm.localPrefix + async exec (args) { + return this.callExec(args) + } + + async execWorkspaces (args) { + await this.setWorkspaces() + + for (const [name, path] of this.workspaces) { + const locationMsg = + `in workspace ${this.npm.chalk.green(name)} at location:\n${this.npm.chalk.dim(path)}` + await this.callExec(args, { name, locationMsg, runPath: path }) + } + } + + async callExec (args, { name, locationMsg, runPath } = {}) { + let localBin = this.npm.localBin + let pkgPath = this.npm.localPrefix // This is where libnpmexec will actually run the scripts from if (!runPath) { runPath = process.cwd() + } else { + // We have to consider if the workspace has its own separate versions + // libnpmexec will walk up to localDir after looking here + localBin = resolve(this.npm.localDir, name, 'node_modules', '.bin') + // We also need to look for `bin` entries in the workspace package.json + // libnpmexec will NOT look in the project root for the bin entry + pkgPath = runPath } - const args = [..._args] const call = this.npm.config.get('call') + let globalPath const { flatOptions, - localBin, globalBin, 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') + // --prefix sets both of these to the same thing, meaning the global prefix + // is invalid (i.e. no lib/node_modules). This is not a trivial thing to + // untangle and fix so we work around it here. + if (this.npm.localPrefix !== this.npm.globalPrefix) { + globalPath = resolve(globalDir, '..') + } - if (call && _args.length) { + if (call && args.length) { throw this.usageError() } @@ -54,30 +81,30 @@ class Exec extends BaseCommand { // we explicitly set packageLockOnly to false because if it's true // when we try to install a missing package, we won't actually install it packageLockOnly: false, - args, + // what the user asked to run args[0] is run by default + args: [...args], // copy args so they don't get mutated + // specify a custom command to be run instead of args[0] call, + chalk, + // where to look for bins globally, if a file matches call or args[0] it is called + globalBin, + // where to look for packages globally, if a package matches call or args[0] it is called + globalPath, + // where to look for bins locally, if a file matches call or args[0] it is called localBin, locationMsg, - globalBin, - globalPath: path.resolve(globalDir, '..'), - output, + // packages that need to be installed packages, - path: localPrefix, + // path where node_modules is + path: this.npm.localPrefix, + // where to look for package.json#bin entries first + pkgPath, + // cwd to run from runPath, scriptShell, yes, }) } - - async execWorkspaces (args, filters) { - await this.setWorkspaces(filters) - - for (const [name, path] of this.workspaces) { - const locationMsg = - `in workspace ${this.npm.chalk.green(name)} at location:\n${this.npm.chalk.dim(path)}` - await this.exec(args, { locationMsg, runPath: path }) - } - } } module.exports = Exec diff --git a/lib/commands/explain.js b/lib/commands/explain.js index c0ef04548a4ed..5f37ba9925f41 100644 --- a/lib/commands/explain.js +++ b/lib/commands/explain.js @@ -1,10 +1,9 @@ const { explainNode } = require('../utils/explain-dep.js') -const completion = require('../utils/completion/installed-deep.js') -const Arborist = require('@npmcli/arborist') const npa = require('npm-package-arg') const semver = require('semver') -const { relative, resolve } = require('path') +const { relative, resolve } = require('node:path') const validName = require('validate-npm-package-name') +const { output } = require('proc-log') const ArboristWorkspaceCmd = require('../arborist-cmd.js') class Explain extends ArboristWorkspaceCmd { @@ -20,8 +19,9 @@ class Explain extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + const completion = require('../utils/installed-deep.js') + return completion(npm, opts) } async exec (args) { @@ -29,6 +29,7 @@ class Explain extends ArboristWorkspaceCmd { throw this.usageError() } + const Arborist = require('@npmcli/arborist') const arb = new Arborist({ path: this.npm.prefix, ...this.npm.flatOptions }) const tree = await arb.loadActual() @@ -59,7 +60,7 @@ class Explain extends ArboristWorkspaceCmd { const expls = [] for (const node of nodes) { - const { extraneous, dev, optional, devOptional, peer, inBundle } = node + const { extraneous, dev, optional, devOptional, peer, inBundle, overridden } = node const expl = node.explain() if (extraneous) { expl.extraneous = true @@ -69,15 +70,16 @@ class Explain extends ArboristWorkspaceCmd { expl.devOptional = devOptional expl.peer = peer expl.bundled = inBundle + expl.overridden = overridden } expls.push(expl) } if (this.npm.flatOptions.json) { - this.npm.output(JSON.stringify(expls, null, 2)) + output.buffer(expls) } else { - this.npm.output(expls.map(expl => { - return explainNode(expl, Infinity, this.npm.color) + output.standard(expls.map(expl => { + return explainNode(expl, Infinity, this.npm.chalk) }).join('\n\n')) } } @@ -90,7 +92,7 @@ class Explain extends ArboristWorkspaceCmd { } // if it's a location, get that node - const maybeLoc = arg.replace(/\\/g, '/').replace(/\/+$/, '') + const maybeLoc = arg.replace(/\\/g, '/').replace(/(?<!\/)\/+$/, '') const nodeByLoc = tree.inventory.get(maybeLoc) if (nodeByLoc) { return [nodeByLoc] @@ -98,7 +100,7 @@ class Explain extends ArboristWorkspaceCmd { // maybe a path to a node_modules folder const maybePath = relative(this.npm.prefix, resolve(maybeLoc)) - .replace(/\\/g, '/').replace(/\/+$/, '') + .replace(/\\/g, '/').replace(/(?<!\/)\/+$/, '') const nodeByPath = tree.inventory.get(maybePath) if (nodeByPath) { return [nodeByPath] @@ -107,7 +109,7 @@ class Explain extends ArboristWorkspaceCmd { // otherwise, try to select all matching nodes try { return this.getNodesByVersion(tree, arg) - } catch (er) { + } catch { return [] } } @@ -124,4 +126,5 @@ class Explain extends ArboristWorkspaceCmd { }) } } + module.exports = Explain diff --git a/lib/commands/explore.js b/lib/commands/explore.js index 5b97673b90eaa..184af2bdc5a16 100644 --- a/lib/commands/explore.js +++ b/lib/commands/explore.js @@ -1,13 +1,12 @@ -// npm explore <pkg>[@<version>] -// open a subshell to the package folder. - -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const runScript = require('@npmcli/run-script') -const { join, resolve, relative } = require('path') -const log = require('../utils/log-shim.js') -const completion = require('../utils/completion/installed-shallow.js') -const BaseCommand = require('../base-command.js') +const { join, relative } = require('node:path') +const { log, output } = require('proc-log') +const completion = require('../utils/installed-shallow.js') +const BaseCommand = require('../base-cmd.js') +// npm explore <pkg>[@<version>] +// open a subshell to the package folder. class Explore extends BaseCommand { static description = 'Browse an installed package' static name = 'explore' @@ -17,8 +16,8 @@ class Explore extends BaseCommand { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + return completion(npm, opts) } async exec (args) { @@ -38,7 +37,7 @@ class Explore extends BaseCommand { // the set of arguments, or the shell config, and let @npmcli/run-script // handle all the escaping and PATH setup stuff. - const pkg = await rpj(resolve(path, 'package.json')).catch(er => { + const { content: pkg } = await pkgJson.normalize(path).catch(er => { log.error('explore', `It doesn't look like ${pkgname} is installed.`) throw er }) @@ -50,31 +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, - stdioString: true, - 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/lib/commands/find-dupes.js b/lib/commands/find-dupes.js index a9de2410ec0d7..735ac7c4a7ed0 100644 --- a/lib/commands/find-dupes.js +++ b/lib/commands/find-dupes.js @@ -1,15 +1,17 @@ -// 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' static params = [ - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'strict-peer-deps', 'package-lock', 'omit', + 'include', 'ignore-scripts', 'audit', 'bin-links', @@ -17,9 +19,10 @@ class FindDupes extends ArboristWorkspaceCmd { ...super.params, ] - async exec (args, cb) { + async exec () { this.npm.config.set('dry-run', true) return this.npm.exec('dedupe', []) } } + module.exports = FindDupes diff --git a/lib/commands/fund.js b/lib/commands/fund.js index 9690cbc32e079..8c194dac80b49 100644 --- a/lib/commands/fund.js +++ b/lib/commands/fund.js @@ -1,14 +1,11 @@ const archy = require('archy') -const Arborist = require('@npmcli/arborist') -const chalk = require('chalk') 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') - -const completion = require('../utils/completion/installed-deep.js') -const openUrl = require('../utils/open-url.js') +const { openUrl } = require('../utils/open-url.js') const ArboristWorkspaceCmd = require('../arborist-cmd.js') const getPrintableName = ({ name, version }) => { @@ -16,42 +13,57 @@ const getPrintableName = ({ name, version }) => { return `${name}${printableVersion}` } +const errCode = (msg, code) => Object.assign(new Error(msg), { code }) + class Fund extends ArboristWorkspaceCmd { static description = 'Retrieve funding information' static name = 'fund' static params = ['json', 'browser', 'unicode', 'workspace', 'which'] static usage = ['[<package-spec>]'] + // XXX: maybe worth making this generic for all commands? + usageMessage (paramsObj = {}) { + let msg = `\`npm ${this.constructor.name}` + const params = Object.entries(paramsObj) + if (params.length) { + msg += ` ${this.constructor.usage}` + } + for (const [key, value] of params) { + msg += ` --${key}=${value}` + } + return `${msg}\`` + } + // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + const completion = require('../utils/installed-deep.js') + return completion(npm, opts) } async exec (args) { const spec = args[0] - const numberArg = this.npm.config.get('which') - - const fundingSourceNumber = numberArg && parseInt(numberArg, 10) - const badFundingSourceNumber = - numberArg !== null && (String(fundingSourceNumber) !== numberArg || fundingSourceNumber < 1) - - if (badFundingSourceNumber) { - const err = new Error( - '`npm fund [<@scope>/]<pkg> [--which=fundingSourceNumber]` must be given a positive integer' - ) - err.code = 'EFUNDNUMBER' - throw err + let fundingSourceNumber = this.npm.config.get('which') + if (fundingSourceNumber != null) { + fundingSourceNumber = parseInt(fundingSourceNumber, 10) + if (isNaN(fundingSourceNumber) || fundingSourceNumber < 1) { + throw errCode( + `${this.usageMessage({ which: 'fundingSourceNumber' })} must be given a positive integer`, + 'EFUNDNUMBER' + ) + } } if (this.npm.global) { - const err = new Error('`npm fund` does not support global packages') - err.code = 'EFUNDGLOBAL' - throw err + throw errCode( + `${this.usageMessage()} does not support global packages`, + 'EFUNDGLOBAL' + ) } const where = this.npm.prefix + const Arborist = require('@npmcli/arborist') const arb = new Arborist({ ...this.npm.flatOptions, path: where }) const tree = await arb.loadActual() @@ -68,22 +80,18 @@ class Fund extends ArboristWorkspaceCmd { // TODO: add !workspacesEnabled option handling to libnpmfund const fundingInfo = getFundingInfo(tree, { ...this.flatOptions, + Arborist, workspaces: this.workspaceNames, }) if (this.npm.config.get('json')) { - this.npm.output(this.printJSON(fundingInfo)) + output.buffer(fundingInfo) } else { - this.npm.output(this.printHuman(fundingInfo)) + output.standard(this.printHuman(fundingInfo)) } } - printJSON (fundingInfo) { - return JSON.stringify(fundingInfo, null, 2) - } - printHuman (fundingInfo) { - const color = this.npm.color const unicode = this.npm.config.get('unicode') const seenUrls = new Map() @@ -98,26 +106,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: color ? chalk.bgBlack.white(url) : 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 }, @@ -141,11 +148,12 @@ class Fund extends ArboristWorkspaceCmd { }) const res = tree(result) - return color ? chalk.reset(res) : res + return res } async openFundingUrl ({ path, tree, spec, fundingSourceNumber }) { const arg = npa(spec, path) + const retrievePackageMetadata = () => { if (arg.type === 'directory') { if (tree.path === arg.fetchSpec) { @@ -178,32 +186,36 @@ class Fund extends ArboristWorkspaceCmd { const validSources = [].concat(normalizeFunding(funding)).filter(isValidFunding) - const matchesValidSource = - validSources.length === 1 || - (fundingSourceNumber > 0 && fundingSourceNumber <= validSources.length) - - if (matchesValidSource) { - const index = fundingSourceNumber ? fundingSourceNumber - 1 : 0 - const { type, url } = validSources[index] - const typePrefix = type ? `${type} funding` : 'Funding' - const msg = `${typePrefix} available at the following URL` - return openUrl(this.npm, url, msg) - } else if (validSources.length && !(fundingSourceNumber >= 1)) { - validSources.forEach(({ type, url }, i) => { - const typePrefix = type ? `${type} funding` : 'Funding' - const msg = `${typePrefix} available at the following URL` - this.npm.output(`${i + 1}: ${msg}: ${url}`) - }) - this.npm.output( - /* eslint-disable-next-line max-len */ - 'Run `npm fund [<@scope>/]<pkg> --which=1`, for example, to open the first funding URL listed in that package' - ) - } else { - const noFundingError = new Error(`No valid funding method available for: ${spec}`) - noFundingError.code = 'ENOFUND' + if (!validSources.length) { + throw errCode(`No valid funding method available for: ${spec}`, 'ENOFUND') + } + + const fundSource = fundingSourceNumber + ? validSources[fundingSourceNumber - 1] + : validSources.length === 1 ? validSources[0] + : null + + if (fundSource) { + return openUrl(this.npm, ...this.urlMessage(fundSource)) + } - throw noFundingError + const ambiguousUrlMsg = [ + ...validSources.map((s, i) => `${i + 1}: ${this.urlMessage(s).reverse().join(': ')}`), + `Run ${this.usageMessage({ which: '1' })}` + + ', for example, to open the first funding URL listed in that package', + ] + if (fundingSourceNumber) { + ambiguousUrlMsg.unshift(`--which=${fundingSourceNumber} is not a valid index`) } + output.standard(ambiguousUrlMsg.join('\n')) + } + + urlMessage (source) { + const { type, url } = source + const typePrefix = type ? `${type} funding` : 'Funding' + const message = `${typePrefix} available at the following URL` + return [url, message] } } + module.exports = Fund diff --git a/lib/commands/get.js b/lib/commands/get.js index 5e92e85a66382..4191f2c973e7d 100644 --- a/lib/commands/get.js +++ b/lib/commands/get.js @@ -1,20 +1,23 @@ -const BaseCommand = require('../base-command.js') +const Npm = require('../npm.js') +const BaseCommand = require('../base-cmd.js') class Get extends BaseCommand { static description = 'Get a value from the npm configuration' static name = 'get' static usage = ['[<key> ...] (See `npm config`)'] + static params = ['long'] static ignoreImplicitWorkspace = false // TODO /* istanbul ignore next */ - async completion (opts) { - const config = await this.npm.cmd('config') - return config.completion(opts) + static async completion (opts) { + const Config = Npm.cmd('config') + return Config.completion(opts) } async exec (args) { return this.npm.exec('config', ['get'].concat(args)) } } + module.exports = Get diff --git a/lib/commands/help-search.js b/lib/commands/help-search.js index 488189bbbc5cd..f5f6ec05cfa59 100644 --- a/lib/commands/help-search.js +++ b/lib/commands/help-search.js @@ -1,10 +1,8 @@ -const fs = require('fs') -const path = require('path') -const chalk = require('chalk') -const { promisify } = require('util') -const glob = promisify(require('glob')) -const readFile = promisify(fs.readFile) -const BaseCommand = require('../base-command.js') +const { readFile } = require('node:fs/promises') +const path = require('node:path') +const { glob } = require('glob') +const { output } = require('proc-log') +const BaseCommand = require('../base-cmd.js') const globify = pattern => pattern.split('\\').join('/') @@ -13,22 +11,23 @@ class HelpSearch extends BaseCommand { static name = 'help-search' static usage = ['<text>'] static params = ['long'] - static ignoreImplicitWorkspace = true async exec (args) { if (!args.length) { throw this.usageError() } - const docPath = path.resolve(__dirname, '..', '..', 'docs/content') - const files = await glob(`${globify(docPath)}/*/*.md`) + const docPath = path.resolve(this.npm.npmRoot, 'docs/content') + let files = await glob(`${globify(docPath)}/*/*.md`) + // 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) } } @@ -41,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() @@ -142,7 +141,7 @@ class HelpSearch extends BaseCommand { formatResults (args, results) { const cols = Math.min(process.stdout.columns || Infinity, 80) + 1 - const out = results.map(res => { + const formattedOutput = results.map(res => { const out = [res.cmd] const r = Object.keys(res.hits) .map(k => `${k}:${res.hits[k]}`) @@ -164,23 +163,18 @@ class HelpSearch extends BaseCommand { return } - if (!this.npm.color) { - out.push(line + '\n') - return - } - const hilitLine = [] + const highlightLine = [] for (const arg of args) { const finder = line.toLowerCase().split(arg.toLowerCase()) let p = 0 for (const f of finder) { - hilitLine.push(line.slice(p, p + f.length)) + highlightLine.push(line.slice(p, p + f.length)) const word = line.slice(p + f.length, p + f.length + arg.length) - const hilit = chalk.bgBlack.red(word) - hilitLine.push(hilit) + highlightLine.push(this.npm.chalk.blue(word)) p += f.length + arg.length } } - out.push(hilitLine.join('') + '\n') + out.push(highlightLine.join('') + '\n') }) return out.join('') @@ -189,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' + - out + '\n' + + formattedOutput + '\n' + '—'.repeat(cols - 1) + '\n' + '(run with -l or --long to see more context)' - : out + : formattedOutput return finalOut.trim() } } + module.exports = HelpSearch diff --git a/lib/commands/help.js b/lib/commands/help.js index e7d6395a1b01a..6eca85b4b0fe0 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -1,33 +1,41 @@ -const { spawn } = require('child_process') -const path = require('path') -const openUrl = require('../utils/open-url.js') -const { promisify } = require('util') -const glob = promisify(require('glob')) +const spawn = require('@npmcli/promise-spawn') +const path = require('node:path') +const { openUrl } = require('../utils/open-url.js') +const { glob } = require('glob') +const { output, input } = 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 -// seemlessly continue supporting it +// seamlessly continue supporting it const manNumberRegex = /\.(\d+)(\.[^/\\]*)?$/ -// Searches for the "npm-" prefix in page names, to prefer those. -const manNpmPrefixRegex = /\/npm-/ +// hardcoded names for man sections +// XXX: these are used in the docs workspace and should be exported +// from npm so section names can changed more easily +const manSectionNames = { + 1: 'commands', + 5: 'configuring-npm', + 7: 'using-npm', +} class Help extends BaseCommand { static description = 'Get help on npm' static name = 'help' static usage = ['<term> [<terms..>]'] static params = ['viewer'] - static ignoreImplicitWorkspace = true - async completion (opts) { + static async completion (opts, npm) { if (opts.conf.argv.remain.length > 2) { return [] } - const g = path.resolve(__dirname, '../../man/man[0-9]/*.[0-9]') - const files = await glob(globify(g)) + const g = path.resolve(npm.npmRoot, 'man/man[0-9]/*.[0-9]') + let files = await glob(globify(g)) + // preserve glob@8 behavior + files = files.sort((a, b) => a.localeCompare(b, 'en')) return Object.keys(files.reduce(function (acc, file) { file = path.basename(file).replace(/\.[0-9]+$/, '') @@ -40,13 +48,10 @@ class Help extends BaseCommand { async exec (args) { // By default we search all of our man subdirectories, but if the user has // asked for a specific one we limit the search to just there - let manSearch = 'man*' - if (/^\d+$/.test(args[0])) { - manSearch = `man${args.shift()}` - } + const manSearch = /^\d+$/.test(args[0]) ? `man${args.shift()}` : 'man*' if (!args.length) { - return this.npm.output(await this.npm.usage) + return output.standard(this.npm.usage) } // npm help foo bar baz: search topics @@ -54,48 +59,24 @@ class Help extends BaseCommand { return this.helpSearch(args) } - let section = this.npm.deref(args[0]) || args[0] - - // support `npm help package.json` - section = section.replace('.json', '-json') + // `npm help package.json` + const arg = (deref(args[0]) || args[0]).replace('.json', '-json') - const manroot = path.resolve(__dirname, '..', '..', 'man') // find either section.n or npm-section.n - const f = `${manroot}/${manSearch}/?(npm-)${section}.[0-9]*` - let mans = await glob(globify(f)) - mans = mans.sort((a, b) => { - // Prefer the page with an npm prefix, if there's only one. - const aHasPrefix = manNpmPrefixRegex.test(a) - const bHasPrefix = manNpmPrefixRegex.test(b) - if (aHasPrefix !== bHasPrefix) { - return aHasPrefix ? -1 : 1 - } + const f = globify(path.resolve(this.npm.npmRoot, `man/${manSearch}/?(npm-)${arg}.[0-9]*`)) + const [man] = await glob(f).then(r => r.sort((a, b) => { // Because the glob is (subtly) different from manNumberRegex, // we can't rely on it passing. - const aManNumberMatch = a.match(manNumberRegex) - const bManNumberMatch = b.match(manNumberRegex) - if (aManNumberMatch) { - if (!bManNumberMatch) { - return -1 - } - // man number sort first so that 1 aka commands are preferred - if (aManNumberMatch[1] !== bManNumberMatch[1]) { - return aManNumberMatch[1] - bManNumberMatch[1] - } - } else if (bManNumberMatch) { - return 1 + const aManNumberMatch = a.match(manNumberRegex)?.[1] || 999 + const bManNumberMatch = b.match(manNumberRegex)?.[1] || 999 + if (aManNumberMatch !== bManNumberMatch) { + return aManNumberMatch - bManNumberMatch } - return localeCompare(a, b) - }) - const man = mans[0] + })) - if (man) { - await this.viewMan(man) - } else { - return this.helpSearch(args) - } + return man ? this.viewMan(man) : this.helpSearch(args) } helpSearch (args) { @@ -103,62 +84,34 @@ class Help extends BaseCommand { } async viewMan (man) { - const env = {} - Object.keys(process.env).forEach(function (i) { - env[i] = process.env[i] - }) const viewer = this.npm.config.get('viewer') - const opts = { - env, - stdio: 'inherit', + if (viewer === 'browser') { + return openUrl(this.npm, this.htmlMan(man), 'help available at the following URL', true) } - let bin = 'man' - const args = [] - switch (viewer) { - case 'woman': - bin = 'emacsclient' - args.push('-e', `(woman-find-file '${man}')`) - break - - case 'browser': - await openUrl(this.npm, this.htmlMan(man), 'help available at the following URL', true) - return - - default: - args.push(man) - break + let args = ['man', [man]] + if (viewer === 'woman') { + args = ['emacsclient', ['-e', `(woman-find-file '${man}')`]] } - const proc = spawn(bin, args, opts) - return new Promise((resolve, reject) => { - proc.on('exit', (code) => { - if (code) { - return reject(new Error(`help process exited with code: ${code}`)) - } - - return resolve() - }) - }) + try { + await input.start(() => spawn(...args, { stdio: 'inherit' })) + } catch (err) { + if (err.code) { + throw new Error(`help process exited with code: ${err.code}`) + } else { + throw err + } + } } // Returns the path to the html version of the man page htmlMan (man) { - let sect = man.match(manNumberRegex)[1] + const sect = manSectionNames[man.match(manNumberRegex)[1]] const f = path.basename(man).replace(manNumberRegex, '') - switch (sect) { - case '1': - sect = 'commands' - break - case '5': - sect = 'configuring-npm' - break - case '7': - sect = 'using-npm' - break - } - return 'file:///' + path.resolve(__dirname, '..', '..', 'docs', 'output', sect, f + '.html') + return 'file:///' + path.resolve(this.npm.npmRoot, `docs/output/${sect}/${f}.html`) } } + module.exports = Help diff --git a/lib/commands/hook.js b/lib/commands/hook.js deleted file mode 100644 index bb3a34b8d2d1b..0000000000000 --- a/lib/commands/hook.js +++ /dev/null @@ -1,138 +0,0 @@ -const hookApi = require('libnpmhook') -const otplease = require('../utils/otplease.js') -const relativeDate = require('tiny-relative-date') -const Table = require('cli-table3') - -const BaseCommand = require('../base-command.js') -class Hook extends BaseCommand { - static description = 'Manage registry hooks' - static name = 'hook' - static params = [ - 'registry', - 'otp', - ] - - static usage = [ - 'add <pkg> <url> <secret> [--type=<type>]', - 'ls [pkg]', - 'rm <id>', - 'update <id> <url> <secret>', - ] - - static ignoreImplicitWorkspace = true - - async exec (args) { - return otplease(this.npm, { - ...this.npm.flatOptions, - }, (opts) => { - switch (args[0]) { - case 'add': - return this.add(args[1], args[2], args[3], opts) - case 'ls': - return this.ls(args[1], opts) - case 'rm': - return this.rm(args[1], opts) - case 'update': - case 'up': - return this.update(args[1], args[2], args[3], opts) - default: - throw this.usageError() - } - }) - } - - 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)) - } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) - } else if (!this.npm.silent) { - this.npm.output(`+ ${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)) - } else if (opts.parseable) { - this.npm.output(Object.keys(hooks[0]).join('\t')) - hooks.forEach(hook => { - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) - }) - } else if (!hooks.length) { - this.npm.output("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.`) - } - - const table = new Table({ head: ['id', 'target', 'endpoint'] }) - hooks.forEach((hook) => { - table.push([ - { rowSpan: 2, content: hook.id }, - this.hookName(hook), - hook.endpoint, - ]) - if (hook.last_delivery) { - table.push([ - { - colSpan: 1, - content: `triggered ${relativeDate(hook.last_delivery)}`, - }, - hook.response_code, - ]) - } else { - table.push([{ colSpan: 2, content: 'never triggered' }]) - } - }) - 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)) - } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(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}`) - } - } - - 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)) - } else if (opts.parseable) { - this.npm.output(Object.keys(hook).join('\t')) - this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t')) - } else if (!this.npm.silent) { - this.npm.output(`+ ${this.hookName(hook)} ${ - opts.unicode ? ' ➜ ' : ' -> ' - } ${hook.endpoint}`) - } - } - - hookName (hook) { - let target = hook.name - if (hook.type === 'scope') { - target = '@' + target - } - if (hook.type === 'owner') { - target = '~' + target - } - return target - } -} -module.exports = Hook diff --git a/lib/commands/init.js b/lib/commands/init.js index 039f08e06059e..290c8ea78ccda 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -1,20 +1,27 @@ -const fs = require('fs') -const { relative, resolve } = require('path') -const mkdirp = require('mkdirp-infer-owner') +const { statSync } = require('node:fs') +const { relative, resolve } = require('node:path') +const { mkdir } = require('node:fs/promises') const initJson = require('init-package-json') const npa = require('npm-package-arg') -const rpj = require('read-package-json-fast') const libexec = require('libnpmexec') const mapWorkspaces = require('@npmcli/map-workspaces') const PackageJson = require('@npmcli/package-json') -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 BaseCommand = require('../base-command.js') +const posixPath = p => p.split('\\').join('/') class Init extends BaseCommand { static description = 'Create a package.json file' static params = [ + 'init-author-name', + 'init-author-url', + 'init-license', + 'init-module', + 'init-type', + 'init-version', + 'init-private', 'yes', 'force', 'scope', @@ -26,23 +33,24 @@ class Init extends BaseCommand { static name = 'init' static usage = [ - '<package-spec> (same as `npx <package-spec>)', + '<package-spec> (same as `npx create-<package-spec>`)', '<@scope> (same as `npx <@scope>/create`)', ] + static workspaces = true static ignoreImplicitWorkspace = false async exec (args) { // npm exec style if (args.length) { - return (await this.execCreate({ args, path: process.cwd() })) + return await this.execCreate(args) } // no args, uses classic init-package-json boilerplate await this.template() } - async execWorkspaces (args, filters) { + async execWorkspaces (args) { // if the root package is uninitiated, take care of it first if (this.npm.flatOptions.includeWorkspaceRoot) { await this.exec(args) @@ -51,7 +59,16 @@ class Init extends BaseCommand { // reads package.json for the top-level folder first, by doing this we // ensure the command throw if no package.json is found before trying // to create a workspace package.json file or its folders - const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')) + const { content: pkg } = await PackageJson.normalize(this.npm.localPrefix).catch(err => { + if (err.code === 'ENOENT') { + log.warn('init', 'Missing package.json. Try with `--include-workspace-root`.') + } + throw err + }) + + // these are workspaces that are being created, so we can't use + // this.setWorkspaces() + const filters = this.npm.config.get('workspace') const wPath = filterArg => resolve(this.npm.localPrefix, filterArg) const workspacesPaths = [] @@ -59,10 +76,10 @@ class Init extends BaseCommand { if (args.length) { for (const filterArg of filters) { const path = wPath(filterArg) - await mkdirp(path) + await mkdir(path, { recursive: true }) workspacesPaths.push(path) - await this.execCreate({ args, path }) - await this.setWorkspace({ pkg, workspacePath: path }) + await this.execCreate(args, path) + await this.setWorkspace(pkg, path) } return } @@ -70,17 +87,17 @@ class Init extends BaseCommand { // no args, uses classic init-package-json boilerplate for (const filterArg of filters) { const path = wPath(filterArg) - await mkdirp(path) + await mkdir(path, { recursive: true }) workspacesPaths.push(path) await this.template(path) - await this.setWorkspace({ pkg, workspacePath: path }) + await this.setWorkspace(pkg, path) } // reify packages once all workspaces have been initialized await this.update(workspacesPaths) } - async execCreate ({ args, path }) { + async execCreate (args, runPath = process.cwd()) { const [initerName, ...otherArgs] = args let packageName = initerName @@ -95,42 +112,42 @@ class Init extends BaseCommand { const req = npa(initerName) if (req.type === 'git' && req.hosted) { const { user, project } = req.hosted - packageName = initerName - .replace(user + '/' + project, user + '/create-' + project) + packageName = initerName.replace(`${user}/${project}`, `${user}/create-${project}`) } else if (req.registry) { - packageName = req.name.replace(/^(@[^/]+\/)?/, '$1create-') - if (req.rawSpec) { - packageName += '@' + req.rawSpec - } + packageName = `${req.name.replace(/^(@[^/]+\/)?/, '$1create-')}@${req.rawSpec}` } else { throw Object.assign(new Error( 'Unrecognized initializer: ' + initerName + '\nFor more package binary executing power check out `npx`:' + - '\nhttps://www.npmjs.com/package/npx' + '\nhttps://docs.npmjs.com/cli/commands/npx' ), { code: 'EUNSUPPORTED' }) } } const newArgs = [packageName, ...otherArgs] - const { color } = this.npm.flatOptions const { flatOptions, localBin, globalBin, + chalk, } = this.npm - const output = this.npm.output.bind(this.npm) - const runPath = path const scriptShell = this.npm.config.get('script-shell') || undefined const yes = this.npm.config.get('yes') + // only send the init-private flag if it is set + const opts = { ...flatOptions } + if (this.npm.config.isDefault('init-private')) { + delete opts.initPrivate + } + await libexec({ - ...flatOptions, + ...opts, args: newArgs, - color, localBin, globalBin, output, - path, + chalk, + path: this.npm.localPrefix, runPath, scriptShell, yes, @@ -138,12 +155,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.', '', @@ -157,27 +171,21 @@ class Init extends BaseCommand { ].join('\n')) } - // XXX promisify init-package-json - await new Promise((res, rej) => { - initJson(path, initFile, this.npm.config, (er, data) => { - log.resume() - log.enableProgress() - log.silly('package data', data) - if (er && er.message === 'canceled') { - log.warn('init', 'canceled') - return res() - } - if (er) { - rej(er) - } else { - log.info('init', 'written successfully') - res(data) - } - }) - }) + try { + const data = await input.read(() => initJson(path, initFile, this.npm.config)) + log.silly('package data', data) + return data + } catch (er) { + if (er.message === 'canceled') { + output.flush() + log.warn('init', 'canceled') + } else { + throw er + } + } } - async setWorkspace ({ pkg, workspacePath }) { + async setWorkspace (pkg, workspacePath) { const workspaces = await mapWorkspaces({ cwd: this.npm.localPrefix, pkg }) // skip setting workspace if current package.json glob already satisfies it @@ -192,8 +200,8 @@ 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')) - } catch (err) { + statSync(resolve(workspacePath, 'package.json')) + } catch { return } @@ -202,7 +210,7 @@ class Init extends BaseCommand { pkgJson.update({ workspaces: [ ...(pkgJson.content.workspaces || []), - relative(this.npm.localPrefix, workspacePath), + posixPath(relative(this.npm.localPrefix, workspacePath)), ], }) @@ -213,9 +221,7 @@ class Init extends BaseCommand { // translate workspaces paths into an array containing workspaces names const workspaces = [] for (const path of workspacesPaths) { - const pkgPath = resolve(path, 'package.json') - const { name } = await rpj(pkgPath) - .catch(() => ({})) + const { content: { name } } = await PackageJson.normalize(path).catch(() => ({ content: {} })) if (name) { workspaces.push(name) diff --git a/lib/commands/install-ci-test.js b/lib/commands/install-ci-test.js index 9977a2edc5641..4b9dd269f8c74 100644 --- a/lib/commands/install-ci-test.js +++ b/lib/commands/install-ci-test.js @@ -1,15 +1,15 @@ -// 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' - async exec (args, cb) { + async exec (args) { await this.npm.exec('ci', args) return this.npm.exec('test', []) } } + module.exports = InstallCITest diff --git a/lib/commands/install-test.js b/lib/commands/install-test.js index 191d70909f9e7..e21ca7c929c55 100644 --- a/lib/commands/install-test.js +++ b/lib/commands/install-test.js @@ -1,15 +1,15 @@ -// 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' - async exec (args, cb) { + async exec (args) { await this.npm.exec('install', args) return this.npm.exec('test', []) } } + module.exports = InstallTest diff --git a/lib/commands/install.js b/lib/commands/install.js index ecc0727a2ef7c..707848a43d48f 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -1,42 +1,48 @@ -/* 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 Arborist = require('@npmcli/arborist') +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' // These are in the order they will show up in when running "-h" + // If adding to this list, consider adding also to ci.js static params = [ 'save', 'save-exact', 'global', - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'omit', + 'include', 'strict-peer-deps', + 'prefer-dedupe', 'package-lock', + 'package-lock-only', 'foreground-scripts', 'ignore-scripts', + 'allow-git', 'audit', + 'before', 'bin-links', 'fund', 'dry-run', + 'cpu', + 'os', + 'libc', ...super.params, ] static usage = ['[<package-spec> ...]'] - async completion (opts) { + static async completion (opts) { const { partialWord } = opts // install can complete to a folder with a package.json, or any package. // if it has a slash, then it's gotta be a folder @@ -64,7 +70,7 @@ class Install extends ArboristWorkspaceCmd { const contents = await readdir(join(partialPath, sibling)) const result = (contents.indexOf('package.json') !== -1) return result - } catch (er) { + } catch { return false } } @@ -82,7 +88,7 @@ class Install extends ArboristWorkspaceCmd { } // no matches return [] - } catch (er) { + } catch { return [] // invalid dir: no matching } } @@ -111,7 +117,6 @@ class Install extends ArboristWorkspaceCmd { if (forced) { log.warn( 'install', - /* eslint-disable-next-line max-len */ `Forcing global npm install with incompatible version ${npmManifest.version} into node ${process.version}` ) } else { @@ -124,7 +129,7 @@ class Install extends ArboristWorkspaceCmd { args = args.filter(a => resolve(a) !== this.npm.prefix) // `npm i -g` => "install this package globally" - if (where === globalTop && !args.length) { + if (isGlobalInstall && !args.length) { args = ['.'] } @@ -134,6 +139,7 @@ class Install extends ArboristWorkspaceCmd { throw this.usageError() } + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, auditLevel: null, @@ -160,8 +166,6 @@ class Install extends ArboristWorkspaceCmd { args: [], scriptShell, stdio: 'inherit', - stdioString: true, - banner: !this.npm.silent, event, }) } @@ -169,4 +173,5 @@ class Install extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Install diff --git a/lib/commands/link.js b/lib/commands/link.js index 7bce73ed2bb6f..e36e5bededcba 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -1,16 +1,11 @@ -const fs = require('fs') -const util = require('util') -const readdir = util.promisify(fs.readdir) -const { resolve } = require('path') - -const Arborist = require('@npmcli/arborist') +const { readdir } = require('node:fs/promises') +const { resolve } = require('node:path') const npa = require('npm-package-arg') -const rpj = require('read-package-json-fast') +const pkgJson = require('@npmcli/package-json') const semver = require('semver') - const reifyFinish = require('../utils/reify-finish.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Link extends ArboristWorkspaceCmd { static description = 'Symlink a package folder' static name = 'link' @@ -22,12 +17,15 @@ class Link extends ArboristWorkspaceCmd { 'save', 'save-exact', 'global', - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'strict-peer-deps', 'package-lock', 'omit', + 'include', 'ignore-scripts', + 'allow-git', 'audit', 'bin-links', 'fund', @@ -35,8 +33,8 @@ class Link extends ArboristWorkspaceCmd { ...super.params, ] - async completion (opts) { - const dir = this.npm.globalDir + static async completion (opts, npm) { + const dir = npm.globalDir const files = await readdir(dir) return files.filter(f => !/^[._-]/.test(f)) } @@ -51,6 +49,8 @@ class Link extends ArboristWorkspaceCmd { { code: 'ELINKGLOBAL' } ) } + // install-links is implicitly false when running `npm link` + this.npm.config.set('install-links', false) // link with no args: symlink the folder to the global location // link with package arg: symlink the global to the local @@ -64,8 +64,10 @@ class Link extends ArboristWorkspaceCmd { // load current packages from the global space, // and then add symlinks installs locally const globalTop = resolve(this.npm.globalDir, '..') + const Arborist = require('@npmcli/arborist') const globalOpts = { ...this.npm.flatOptions, + Arborist, path: globalTop, global: true, prune: false, @@ -92,24 +94,25 @@ class Link extends ArboristWorkspaceCmd { const names = [] for (const a of args) { const arg = npa(a) - names.push( - arg.type === 'directory' - ? (await rpj(resolve(arg.fetchSpec, 'package.json'))).name - : arg.name - ) + if (arg.type === 'directory') { + const { content } = await pkgJson.normalize(arg.fetchSpec) + names.push(content.name) + } else { + names.push(arg.name) + } } // npm link should not save=true by default unless you're // using any of --save-dev or other types const save = Boolean( - this.npm.config.find('save') !== 'default' || + (this.npm.config.find('save') !== 'default' && + this.npm.config.get('save')) || this.npm.config.get('save-optional') || this.npm.config.get('save-peer') || this.npm.config.get('save-dev') || this.npm.config.get('save-prod') ) - // create a new arborist instance for the local prefix and // reify all the pending names as symlinks there const localArb = new Arborist({ @@ -122,7 +125,7 @@ class Link extends ArboristWorkspaceCmd { ...this.npm.flatOptions, prune: false, path: this.npm.prefix, - add: names.map(l => `file:${resolve(globalTop, 'node_modules', l).replace(/#/g, '%23')}`), + add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`), save, workspaces: this.workspaceNames, }) @@ -133,10 +136,12 @@ class Link extends ArboristWorkspaceCmd { async linkPkg () { const wsp = this.workspacePaths const paths = wsp && wsp.length ? wsp : [this.npm.prefix] - const add = paths.map(path => `file:${path.replace(/#/g, '%23')}`) + const add = paths.map(path => `file:${path}`) const globalTop = resolve(this.npm.globalDir, '..') + const Arborist = require('@npmcli/arborist') const arb = new Arborist({ ...this.npm.flatOptions, + Arborist, path: globalTop, global: true, }) @@ -181,4 +186,5 @@ class Link extends ArboristWorkspaceCmd { return missing } } + module.exports = Link diff --git a/lib/commands/login.js b/lib/commands/login.js new file mode 100644 index 0000000000000..630abf9ac8e04 --- /dev/null +++ b/lib/commands/login.js @@ -0,0 +1,50 @@ +const { log, output } = require('proc-log') +const { redactLog: replaceInfo } = require('@npmcli/redact') +const auth = require('../utils/auth.js') +const BaseCommand = require('../base-cmd.js') + +class Login extends BaseCommand { + static description = 'Login to a registry user account' + static name = 'login' + static params = [ + 'registry', + 'scope', + 'auth-type', + ] + + async exec () { + const scope = this.npm.config.get('scope') + let registry = this.npm.config.get('registry') + + if (scope) { + const scopedRegistry = this.npm.config.get(`${scope}:registry`) + const cliRegistry = this.npm.config.get('registry', 'cli') + if (scopedRegistry && !cliRegistry) { + registry = scopedRegistry + } + } + + const creds = this.npm.config.getCredentialsByURI(registry) + + log.notice('', `Log in on ${replaceInfo(registry)}`) + + const { message, newCreds } = await auth.login(this.npm, { + ...this.npm.flatOptions, + creds, + registry, + }) + + this.npm.config.delete('_token', 'user') // prevent legacy pollution + this.npm.config.setCredentialsByURI(registry, newCreds) + + if (scope) { + this.npm.config.set(scope + ':registry', registry, 'user') + } + + await this.npm.config.save('user') + + output.standard(message) + } +} + +module.exports = Login diff --git a/lib/commands/logout.js b/lib/commands/logout.js index 7c2a7f0b2f830..dc5a0dfda0e98 100644 --- a/lib/commands/logout.js +++ b/lib/commands/logout.js @@ -1,7 +1,7 @@ -const getAuth = require('npm-registry-fetch/lib/auth.js') const npmFetch = require('npm-registry-fetch') -const log = require('../utils/log-shim') -const BaseCommand = require('../base-command.js') +const { getAuth } = npmFetch +const { log } = require('proc-log') +const BaseCommand = require('../base-cmd.js') class Logout extends BaseCommand { static description = 'Log out of the registry' @@ -11,9 +11,7 @@ class Logout extends BaseCommand { 'scope', ] - static ignoreImplicitWorkspace = true - - 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' @@ -21,10 +19,14 @@ class Logout extends BaseCommand { const auth = getAuth(reg, this.npm.flatOptions) + const level = this.npm.config.find(`${auth.regKey}:${auth.authKey}`) + + // find the config level and only delete from there if (auth.token) { log.verbose('logout', `clearing token for ${reg}`) await npmFetch(`/-/user/token/${encodeURIComponent(auth.token)}`, { ...this.npm.flatOptions, + registry: reg, method: 'DELETE', ignoreBody: true, }) @@ -36,12 +38,13 @@ class Logout extends BaseCommand { } if (scope) { - this.npm.config.delete(regRef, 'user') + this.npm.config.delete(regRef, level) } - this.npm.config.clearCredentialsByURI(reg) + this.npm.config.clearCredentialsByURI(reg, level) - await this.npm.config.save('user') + await this.npm.config.save(level) } } + module.exports = Logout diff --git a/lib/commands/ls.js b/lib/commands/ls.js index 073ca0c6992e8..bc8beb007e809 100644 --- a/lib/commands/ls.js +++ b/lib/commands/ls.js @@ -1,14 +1,12 @@ -const { resolve, relative, sep } = require('path') -const relativePrefix = `.${sep}` -const { EOL } = require('os') - +const { resolve, relative, sep } = require('node:path') const archy = require('archy') -const chalk = require('chalk') -const Arborist = require('@npmcli/arborist') 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 completion = require('../utils/completion/installed-deep.js') +const relativePrefix = `.${sep}` const _depth = Symbol('depth') const _dedupe = Symbol('dedupe') @@ -21,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' @@ -36,6 +32,7 @@ class LS extends ArboristWorkspaceCmd { 'global', 'depth', 'omit', + 'include', 'link', 'package-lock-only', 'unicode', @@ -44,13 +41,14 @@ class LS extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + const completion = require('../utils/installed-deep.js') + return completion(npm, opts) } async exec (args) { const all = this.npm.config.get('all') - const color = this.npm.color + const chalk = this.npm.chalk const depth = this.npm.config.get('depth') const global = this.npm.global const json = this.npm.config.get('json') @@ -64,6 +62,8 @@ class LS extends ArboristWorkspaceCmd { const path = global ? resolve(this.npm.globalDir, '..') : this.npm.prefix + const Arborist = require('@npmcli/arborist') + const arb = new Arborist({ global, ...this.npm.flatOptions, @@ -157,7 +157,7 @@ class LS extends ArboristWorkspaceCmd { ? getJsonOutputItem(node, { global, long }) : parseable ? null - : getHumanOutputItem(node, { args, color, global, long }) + : getHumanOutputItem(node, { args, chalk, global, long }) // loop through list of node problems to add them to global list if (node[_include]) { @@ -177,13 +177,14 @@ class LS extends ArboristWorkspaceCmd { const [rootError] = tree.errors.filter(e => e.code === 'EJSONPARSE' && e.path === resolve(path, 'package.json')) - this.npm.output( - json - ? jsonOutput({ path, problems, result, rootError, seenItems }) - : parseable - ? parseableOutput({ seenNodes, global, long }) - : humanOutput({ color, result, seenItems, unicode }) - ) + if (json) { + output.buffer(jsonOutput({ path, problems, result, rootError, seenItems })) + } else { + output.standard(parseable + ? parseableOutput({ seenNodes, global, long }) + : humanOutput({ chalk, result, seenItems, unicode }) + ) + } // if filtering items, should exit with error code on no results if (result && !result[_include] && args.length) { @@ -202,7 +203,7 @@ class LS extends ArboristWorkspaceCmd { if (shouldThrow) { throw Object.assign( - new Error([...problems].join(EOL)), + new Error([...problems].join('\n')), { code: 'ELSPROBLEMS' } ) } @@ -221,6 +222,7 @@ class LS extends ArboristWorkspaceCmd { return tree } } + module.exports = LS const isGitNode = (node) => { @@ -231,7 +233,7 @@ const isGitNode = (node) => { try { const { type } = npa(node.resolved) return type === 'git' || type === 'hosted' - } catch (err) { + } catch { return false } } @@ -280,9 +282,9 @@ const augmentItemWithIncludeMetadata = (node, item) => { return item } -const getHumanOutputItem = (node, { args, color, global, long }) => { +const getHumanOutputItem = (node, { args, chalk, global, long }) => { const { pkgid, path } = node - const workspacePkgId = color ? chalk.green(pkgid) : pkgid + const workspacePkgId = chalk.blueBright(pkgid) let printable = node.isWorkspace ? workspacePkgId : pkgid // special formatting for top-level package name @@ -291,15 +293,16 @@ const getHumanOutputItem = (node, { args, color, global, long }) => { if (hasNoPackageJson || global) { printable = path } else { - printable += `${long ? EOL : ' '}${path}` + printable += `${long ? '\n' : ' '}${path}` } } - const highlightDepName = - color && args.length && node[_filteredBy] + // 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,28 +313,33 @@ const getHumanOutputItem = (node, { args, color, global, long }) => { const label = ( node[_missing] - ? (color ? missingColor(missingMsg) : missingMsg) + ' ' + ? missingColor(missingMsg) + ' ' : '' ) + - `${highlightDepName ? chalk.yellow.bgBlack(printable) : printable}` + + `${highlightDepName ? chalk.yellow(printable) : printable}` + ( node[_dedupe] - ? ' ' + (color ? chalk.gray('deduped') : 'deduped') + ? ' ' + chalk.dim('deduped') : '' ) + ( invalid - ? ' ' + (color ? chalk.red.bgBlack(invalid) : invalid) + ? ' ' + chalk.red(invalid) : '' ) + ( isExtraneous(node, { global }) - ? ' ' + (color ? chalk.green.bgBlack('extraneous') : 'extraneous') + ? ' ' + chalk.red('extraneous') + : '' + ) + + ( + node.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: [] }) } @@ -347,6 +355,13 @@ const getJsonOutputItem = (node, { global, long }) => { item.resolved = node.resolved } + // if the node is the project root, do not add the overridden flag. the project root can't be + // overridden anyway, and if we add the flag it causes undesirable behavior when `npm ls --json` + // is ran in an empty directory since we end up printing an object with only an overridden prop + if (!node.isProjectRoot) { + item.overridden = node.overridden + } + item[_name] = node.name // special formatting for top-level package name @@ -390,7 +405,7 @@ const getJsonOutputItem = (node, { global, long }) => { return augmentItemWithIncludeMetadata(node, item) } -const filterByEdgesTypes = ({ link, omit = [] }) => (edge) => { +const filterByEdgesTypes = ({ link, omit }) => (edge) => { for (const omitType of omit) { if (edge[omitType]) { return false @@ -494,7 +509,7 @@ const augmentNodesWithMetadata = ({ const sortAlphabetically = ({ pkgid: a }, { pkgid: b }) => localeCompare(a, b) -const humanOutput = ({ color, result, seenItems, unicode }) => { +const humanOutput = ({ chalk, result, seenItems, unicode }) => { // we need to traverse the entire tree in order to determine which items // should be included (since a nested transitive included dep will make it // so that all its ancestors should be displayed) @@ -510,7 +525,7 @@ const humanOutput = ({ color, result, seenItems, unicode }) => { } const archyOutput = archy(result, '', { unicode }) - return color ? chalk.reset(archyOutput) : archyOutput + return chalk.reset(archyOutput) } const jsonOutput = ({ path, problems, result, rootError, seenItems }) => { @@ -542,7 +557,7 @@ const jsonOutput = ({ path, problems, result, rootError, seenItems }) => { } } - return JSON.stringify(result, null, 2) + return result } const parseableOutput = ({ global, long, seenNodes }) => { @@ -555,8 +570,9 @@ const parseableOutput = ({ global, long, seenNodes }) => { out += node.path !== node.realpath ? `:${node.realpath}` : '' out += isExtraneous(node, { global }) ? ':EXTRANEOUS' : '' out += node[_invalid] ? ':INVALID' : '' + out += node.overridden ? ':OVERRIDDEN' : '' } - out += EOL + out += '\n' } } return out.trim() diff --git a/lib/commands/org.js b/lib/commands/org.js index 599b4b9c8758a..3daf9e550fb72 100644 --- a/lib/commands/org.js +++ b/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 { otplease } = require('../utils/auth.js') +const BaseCommand = require('../base-cmd.js') +const { output } = require('proc-log') class Org extends BaseCommand { static description = 'Manage orgs' @@ -13,9 +13,8 @@ class Org extends BaseCommand { ] static params = ['registry', 'otp', 'json', 'parseable'] - static ignoreImplicitWorkspace = true - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain if (argv.length === 2) { return ['set', 'rm', 'ls'] @@ -32,7 +31,7 @@ class Org extends BaseCommand { } } - async exec ([cmd, orgname, username, role], cb) { + async exec ([cmd, orgname, username, role]) { return otplease(this.npm, { ...this.npm.flatOptions, }, opts => { @@ -50,7 +49,7 @@ class Org extends BaseCommand { }) } - set (org, user, role, opts) { + async set (org, user, role, opts) { role = role || 'developer' if (!org) { throw new Error('First argument `orgname` is required.') @@ -62,32 +61,30 @@ class Org extends BaseCommand { if (!['owner', 'admin', 'developer'].find(x => x === role)) { throw new Error( - /* eslint-disable-next-line max-len */ 'Third argument `role` must be one of `owner`, `admin`, or `developer`, with `developer` being the default value if omitted.' ) } - return liborg.set(org, user, role, opts).then(memDeets => { - if (opts.json) { - this.npm.output(JSON.stringify(memDeets, null, 2)) - } else if (opts.parseable) { - this.npm.output(['org', 'orgsize', 'user', 'role'].join('\t')) - this.npm.output( - [memDeets.org.name, memDeets.org.size, memDeets.user, memDeets.role].join('\t') - ) - } else if (!this.npm.silent) { - this.npm.output( - `Added ${memDeets.user} as ${memDeets.role} to ${memDeets.org.name}. You now have ${ + const memDeets = await liborg.set(org, user, role, opts) + if (opts.json) { + output.standard(JSON.stringify(memDeets, null, 2)) + } else if (opts.parseable) { + 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) { + 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.` - ) - } + ) + } - return memDeets - }) + return memDeets } - rm (org, user, opts) { + async rm (org, user, opts) { if (!org) { throw new Error('First argument `orgname` is required.') } @@ -96,68 +93,58 @@ class Org extends BaseCommand { throw new Error('Second argument `username` is required.') } - return liborg - .rm(org, user, opts) - .then(() => { - return liborg.ls(org, opts) - }) - .then(roster => { - user = user.replace(/^[~@]?/, '') - org = org.replace(/^[~@]?/, '') - const userCount = Object.keys(roster).length - if (opts.json) { - this.npm.output( - JSON.stringify({ - user, - org, - userCount, - deleted: true, - }) - ) - } else if (opts.parseable) { - this.npm.output(['user', 'org', 'userCount', 'deleted'].join('\t')) - this.npm.output([user, org, userCount, true].join('\t')) - } else if (!this.npm.silent) { - this.npm.output( - `Successfully removed ${user} from ${org}. You now have ${userCount} member${ - userCount === 1 ? '' : 's' - } in this org.` - ) - } + await liborg.rm(org, user, opts) + const roster = await liborg.ls(org, opts) + user = user.replace(/^[~@]?/, '') + org = org.replace(/^[~@]?/, '') + const userCount = Object.keys(roster).length + if (opts.json) { + output.buffer({ + user, + org, + userCount, + deleted: true, }) + } else if (opts.parseable) { + output.standard(['user', 'org', 'userCount', 'deleted'].join('\t')) + output.standard([user, org, userCount, true].join('\t')) + } else if (!this.npm.silent) { + output.standard( + `Successfully removed ${user} from ${org}. You now have ${userCount} member${ + userCount === 1 ? '' : 's' + } in this org.` + ) + } } - ls (org, user, opts) { + async ls (org, user, opts) { if (!org) { throw new Error('First argument `orgname` is required.') } - return liborg.ls(org, opts).then(roster => { - if (user) { - const newRoster = {} - if (roster[user]) { - newRoster[user] = roster[user] - } - - roster = newRoster + let roster = await liborg.ls(org, opts) + if (user) { + const newRoster = {} + if (roster[user]) { + newRoster[user] = roster[user] } - if (opts.json) { - this.npm.output(JSON.stringify(roster, null, 2)) - } else if (opts.parseable) { - this.npm.output(['user', 'role'].join('\t')) - Object.keys(roster).forEach(user => { - this.npm.output([user, roster[user]].join('\t')) - }) - } else if (!this.npm.silent) { - const table = new Table({ head: ['user', 'role'] }) - Object.keys(roster) - .sort() - .forEach(user => { - table.push([user, roster[user]]) - }) - this.npm.output(table.toString()) + + roster = newRoster + } + if (opts.json) { + output.buffer(roster) + } else if (opts.parseable) { + output.standard(['user', 'role'].join('\t')) + Object.keys(roster).forEach(u => { + output.standard([u, roster[u]].join('\t')) + }) + } else if (!this.npm.silent) { + 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/lib/commands/outdated.js b/lib/commands/outdated.js index 042b776f71e0d..6c2d4cdcd9581 100644 --- a/lib/commands/outdated.js +++ b/lib/commands/outdated.js @@ -1,16 +1,23 @@ -const os = require('os') -const path = require('path') +const { resolve } = require('node:path') +const { stripVTControlCharacters } = require('node:util') const pacote = require('pacote') const table = require('text-table') -const chalk = require('chalk') 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') -const Arborist = require('@npmcli/arborist') +const safeNpa = (spec) => { + try { + return npa(spec) + } catch { + return null + } +} -const ansiTrim = require('../utils/ansi-trim.js') -const ArboristWorkspaceCmd = require('../arborist-cmd.js') +// This string is load bearing and is shared with Arborist +const MISSING = 'MISSING' class Outdated extends ArboristWorkspaceCmd { static description = 'Check for outdated packages' @@ -23,184 +30,134 @@ class Outdated extends ArboristWorkspaceCmd { 'parseable', 'global', 'workspace', + 'before', ] - async exec (args) { - const global = path.resolve(this.npm.globalDir, '..') - const where = this.npm.global - ? global - : this.npm.prefix + #tree + #list = [] + #edges = new Set() + #filterSet + async exec (args) { + const Arborist = require('@npmcli/arborist') const arb = new Arborist({ ...this.npm.flatOptions, - path: where, + path: this.npm.global ? resolve(this.npm.globalDir, '..') : this.npm.prefix, }) - - this.edges = new Set() - this.list = [] - this.tree = await arb.loadActual() - - if (this.workspaceNames && this.workspaceNames.length) { - this.filterSet = - arb.workspaceDependencySet( - this.tree, - this.workspaceNames, - this.npm.flatOptions.includeWorkspaceRoot - ) + this.#tree = await arb.loadActual() + + if (this.workspaceNames?.length) { + this.#filterSet = arb.workspaceDependencySet( + this.#tree, + this.workspaceNames, + this.npm.flatOptions.includeWorkspaceRoot + ) } else if (!this.npm.flatOptions.workspacesEnabled) { - this.filterSet = - arb.excludeWorkspacesDependencySet(this.tree) + this.#filterSet = arb.excludeWorkspacesDependencySet(this.#tree) } - if (args.length !== 0) { - // specific deps - for (let i = 0; i < args.length; i++) { - const nodes = this.tree.inventory.query('name', args[i]) - this.getEdges(nodes, 'edgesIn') + if (args.length) { + for (const arg of args) { + // specific deps + this.#getEdges(this.#tree.inventory.query('name', arg), 'edgesIn') } } else { if (this.npm.config.get('all')) { // all deps in tree - const nodes = this.tree.inventory.values() - this.getEdges(nodes, 'edgesOut') + this.#getEdges(this.#tree.inventory.values(), 'edgesOut') } // top-level deps - this.getEdges() + this.#getEdges() } - await Promise.all(Array.from(this.edges).map((edge) => { - return this.getOutdatedInfo(edge) - })) + await Promise.all([...this.#edges].map((e) => this.#getOutdatedInfo(e))) - // sorts list alphabetically - const outdated = this.list.sort((a, b) => localeCompare(a.name, b.name)) + // sorts list alphabetically by name and then dependent + const outdated = this.#list + .sort((a, b) => localeCompare(a.name, b.name) || localeCompare(a.dependent, b.dependent)) - if (outdated.length > 0) { + if (outdated.length) { process.exitCode = 1 } - // return if no outdated packages - if (outdated.length === 0 && !this.npm.config.get('json')) { + if (this.npm.config.get('json')) { + output.buffer(this.#json(outdated)) return } - // display results - if (this.npm.config.get('json')) { - this.npm.output(this.makeJSON(outdated)) - } else if (this.npm.config.get('parseable')) { - this.npm.output(this.makeParseable(outdated)) - } else { - const outList = outdated.map(x => this.makePretty(x)) - const outHead = ['Package', - 'Current', - 'Wanted', - 'Latest', - 'Location', - 'Depended by', - ] - - if (this.npm.config.get('long')) { - outHead.push('Package Type', 'Homepage') - } - const outTable = [outHead].concat(outList) + const res = this.npm.config.get('parseable') + ? this.#parseable(outdated) + : this.#pretty(outdated) - if (this.npm.color) { - outTable[0] = outTable[0].map(heading => chalk.underline(heading)) - } - - const tableOpts = { - align: ['l', 'r', 'r', 'r', 'l'], - stringLength: s => ansiTrim(s).length, - } - this.npm.output(table(outTable, tableOpts)) + if (res) { + output.standard(res) } } - getEdges (nodes, type) { + #getEdges (nodes, type) { // when no nodes are provided then it should only read direct deps // from the root node and its workspaces direct dependencies if (!nodes) { - this.getEdgesOut(this.tree) - this.getWorkspacesEdges() + this.#getEdgesOut(this.#tree) + this.#getWorkspacesEdges() return } for (const node of nodes) { - type === 'edgesOut' - ? this.getEdgesOut(node) - : this.getEdgesIn(node) + if (type === 'edgesOut') { + this.#getEdgesOut(node) + } else { + this.#getEdgesIn(node) + } } } - getEdgesIn (node) { + #getEdgesIn (node) { for (const edge of node.edgesIn) { - this.trackEdge(edge) + this.#trackEdge(edge) } } - getEdgesOut (node) { + #getEdgesOut (node) { // TODO: normalize usage of edges and avoid looping through nodes here - if (this.npm.global) { - for (const child of node.children.values()) { - this.trackEdge(child) - } - } else { - for (const edge of node.edgesOut.values()) { - this.trackEdge(edge) - } + const edges = this.npm.global ? node.children.values() : node.edgesOut.values() + for (const edge of edges) { + this.#trackEdge(edge) } } - trackEdge (edge) { - const filteredOut = - edge.from - && this.filterSet - && this.filterSet.size > 0 - && !this.filterSet.has(edge.from.target) - - if (filteredOut) { + #trackEdge (edge) { + if (edge.from && this.#filterSet?.size > 0 && !this.#filterSet.has(edge.from.target)) { return } - - this.edges.add(edge) + this.#edges.add(edge) } - getWorkspacesEdges (node) { + #getWorkspacesEdges () { if (this.npm.global) { return } - for (const edge of this.tree.edgesOut.values()) { - const workspace = edge - && edge.to - && edge.to.target - && edge.to.target.isWorkspace - - if (workspace) { - this.getEdgesOut(edge.to.target) + for (const edge of this.#tree.edgesOut.values()) { + if (edge?.to?.target?.isWorkspace) { + this.#getEdgesOut(edge.to.target) } } } - async getPackument (spec) { - const packument = await pacote.packument(spec, { + async #getPackument (spec) { + return pacote.packument(spec, { ...this.npm.flatOptions, fullMetadata: this.npm.config.get('long'), preferOnline: true, }) - return packument } - async getOutdatedInfo (edge) { - let alias = false - try { - alias = npa(edge.spec).subSpec - } catch (err) { - } + async #getOutdatedInfo (edge) { + const alias = safeNpa(edge.spec)?.subSpec const spec = npa(alias ? alias.name : edge.name) const node = edge.to || edge - const { path, location } = node - const { version: current } = node.package || {} + const { path, location, package: { version: current } = {} } = node const type = edge.optional ? 'optionalDependencies' : edge.peer ? 'peerDependencies' @@ -215,34 +172,22 @@ class Outdated extends ArboristWorkspaceCmd { // deps different from prod not currently // on disk are not included in the output - if (edge.error === 'MISSING' && type !== 'dependencies') { + if (edge.error === MISSING && type !== 'dependencies') { return } + // if it's not a range, version, or tag, skip it + if (!safeNpa(`${edge.name}@${edge.spec}`)?.registry) { + return null + } + try { - const packument = await this.getPackument(spec) + const packument = await this.#getPackument(spec) const expected = alias ? alias.fetchSpec : edge.spec - // if it's not a range, version, or tag, skip it - try { - if (!npa(`${edge.name}@${edge.spec}`).registry) { - return null - } - } catch (err) { - return null - } const wanted = pickManifest(packument, expected, this.npm.flatOptions) const latest = pickManifest(packument, '*', this.npm.flatOptions) - - if ( - !current || - current !== wanted.version || - wanted.version !== latest.version - ) { - const dependent = edge.from ? - this.maybeWorkspaceName(edge.from) - : 'global' - - this.list.push({ + if (!current || current !== wanted.version || wanted.version !== latest.version) { + this.#list.push({ name: alias ? edge.spec.replace('npm', edge.name) : edge.name, path, type, @@ -250,125 +195,95 @@ class Outdated extends ArboristWorkspaceCmd { location, wanted: wanted.version, latest: latest.version, - dependent, + workspaceDependent: edge.from?.isWorkspace ? edge.from.pkgid : null, + dependedByLocation: edge.from?.name + ? edge.from?.location + : 'global', + dependent: edge.from?.name ?? 'global', homepage: packument.homepage, }) } } catch (err) { // silently catch and ignore ETARGET, E403 & // E404 errors, deps are just skipped - if (!( - err.code === 'ETARGET' || - err.code === 'E403' || - err.code === 'E404') - ) { + if (!['ETARGET', 'E404', 'E404'].includes(err.code)) { throw err } } } - maybeWorkspaceName (node) { - if (!node.isWorkspace) { - return node.name - } - - const humanOutput = - !this.npm.config.get('json') && !this.npm.config.get('parseable') - - const workspaceName = - humanOutput - ? node.pkgid - : node.name - - return this.npm.color && humanOutput - ? chalk.green(workspaceName) - : workspaceName - } - // formatting functions - makePretty (dep) { - const { - current = 'MISSING', - location = '-', - homepage = '', - name, - wanted, - latest, - type, - dependent, - } = dep - - const columns = [name, current, wanted, latest, location, dependent] - - if (this.npm.config.get('long')) { - columns[6] = type - columns[7] = homepage - } - if (this.npm.color) { - columns[0] = chalk[current === wanted ? 'yellow' : 'red'](columns[0]) // current - columns[2] = chalk.green(columns[2]) // wanted - columns[3] = chalk.magenta(columns[3]) // latest + #pretty (list) { + if (!list.length) { + return } - return columns + const long = this.npm.config.get('long') + const { bold, yellow, red, cyan, blue } = this.npm.chalk + + return table([ + [ + 'Package', + 'Current', + 'Wanted', + 'Latest', + 'Location', + 'Depended by', + ...long ? ['Package Type', 'Homepage', 'Depended By Location'] : [], + ].map(h => bold.underline(h)), + ...list.map((d) => [ + d.current === d.wanted ? yellow(d.name) : red(d.name), + d.current ?? 'MISSING', + cyan(d.wanted), + blue(d.latest), + d.location ?? '-', + d.workspaceDependent ? blue(d.workspaceDependent) : d.dependent, + ...long ? [d.type, blue(d.homepage ?? ''), d.dependedByLocation] : [], + ]), + ], { + align: ['l', 'r', 'r', 'r', 'l'], + stringLength: s => stripVTControlCharacters(s).length, + }) } // --parseable creates output like this: // <fullpath>:<name@wanted>:<name@installed>:<name@latest>:<dependedby> - makeParseable (list) { - return list.map(dep => { - const { - name, - current, - wanted, - latest, - path, - dependent, - type, - homepage, - } = dep - const out = [ - path, - name + '@' + wanted, - current ? (name + '@' + current) : 'MISSING', - name + '@' + latest, - dependent, - ] - if (this.npm.config.get('long')) { - out.push(type, homepage) - } - - return out.join(':') - }).join(os.EOL) + #parseable (list) { + return list.map(d => [ + d.path, + `${d.name}@${d.wanted}`, + d.current ? `${d.name}@${d.current}` : 'MISSING', + `${d.name}@${d.latest}`, + d.dependent, + ...this.npm.config.get('long') ? [d.type, d.homepage, d.dependedByLocation] : [], + ].join(':')).join('\n') } - makeJSON (list) { - const out = {} - list.forEach(dep => { - const { - name, - current, - wanted, - latest, - path, - type, - dependent, - homepage, - } = dep - out[name] = { - current, - wanted, - latest, - dependent, - location: path, + #json (list) { + // TODO(BREAKING_CHANGE): this should just return an array. It's a list and + // turing it into an object with keys is lossy since multiple items in the + // list could have the same key. For now we hack that by only changing + // top level values into arrays if they have multiple outdated items + return list.reduce((acc, d) => { + const dep = { + current: d.current, + wanted: d.wanted, + latest: d.latest, + dependent: d.dependent, + location: d.path, + ...this.npm.config.get('long') ? { + type: d.type, + homepage: d.homepage, + dependedByLocation: d.dependedByLocation } : {}, } - if (this.npm.config.get('long')) { - out[name].type = type - out[name].homepage = homepage - } - }) - return JSON.stringify(out, null, 2) + acc[d.name] = acc[d.name] + // If this item already has an outdated dep then we turn it into an array + ? (Array.isArray(acc[d.name]) ? acc[d.name] : [acc[d.name]]).concat(dep) + : dep + return acc + }, {}) } } + module.exports = Outdated diff --git a/lib/commands/owner.js b/lib/commands/owner.js index 824b64e044ecf..d53c1c97b77fc 100644 --- a/lib/commands/owner.js +++ b/lib/commands/owner.js @@ -1,16 +1,16 @@ const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') const pacote = require('pacote') -const log = require('../utils/log-shim') -const otplease = require('../utils/otplease.js') -const readPackageJsonFast = require('read-package-json-fast') -const BaseCommand = require('../base-command.js') -const { resolve } = require('path') +const { log, output } = require('proc-log') +const { otplease } = require('../utils/auth.js') +const pkgJson = require('@npmcli/package-json') +const BaseCommand = require('../base-cmd.js') +const { redact } = require('@npmcli/redact') -const readJson = async (pkg) => { +const readJson = async (path) => { try { - const json = await readPackageJsonFast(pkg) - return json + const { content } = await pkgJson.normalize(path) + return content } catch { return {} } @@ -32,9 +32,10 @@ class Owner extends BaseCommand { 'ls <package-spec>', ] + static workspaces = true static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts, npm) { const argv = opts.conf.argv.remain if (argv.length > 3) { return [] @@ -50,18 +51,19 @@ class Owner extends BaseCommand { // reaches registry in order to autocomplete rm if (argv[2] === 'rm') { - if (this.npm.global) { + if (npm.global) { return [] } - const { name } = await readJson(resolve(this.npm.prefix, 'package.json')) + const { name } = await readJson(npm.prefix) if (!name) { return [] } const spec = npa(name) const data = await pacote.packument(spec, { - ...this.npm.flatOptions, + ...npm.flatOptions, fullMetadata: true, + _isRoot: true, }) if (data && data.maintainers && data.maintainers.length) { return data.maintainers.map(m => m.name) @@ -82,8 +84,8 @@ class Owner extends BaseCommand { } } - async execWorkspaces ([action, ...args], filters) { - await this.setWorkspaces(filters) + async execWorkspaces ([action, ...args]) { + await this.setWorkspaces() // ls pkg or owner add/rm package if ((action === 'ls' && args.length > 0) || args.length > 1) { const implicitWorkspaces = this.npm.config.get('workspace', 'default') @@ -111,15 +113,21 @@ class Owner extends BaseCommand { const spec = npa(pkg) try { - const packumentOpts = { ...this.npm.flatOptions, fullMetadata: true, preferOnline: true } + const packumentOpts = { + ...this.npm.flatOptions, + fullMetadata: + true, + preferOnline: true, + _isRoot: 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", pkg) + log.error('owner ls', "Couldn't get owner data", redact(pkg)) throw err } } @@ -129,7 +137,7 @@ class Owner extends BaseCommand { if (this.npm.global) { throw this.usageError() } - const { name } = await readJson(resolve(prefix, 'package.json')) + const { name } = await readJson(prefix) if (!name) { throw this.usageError() } @@ -165,6 +173,7 @@ class Owner extends BaseCommand { ...this.npm.flatOptions, fullMetadata: true, preferOnline: true, + _isRoot: true, }) const owners = data.maintainers || [] @@ -215,9 +224,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/lib/commands/pack.js b/lib/commands/pack.js index c6a74804642f6..fdde78f6afe23 100644 --- a/lib/commands/pack.js +++ b/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' @@ -15,9 +15,11 @@ class Pack extends BaseCommand { 'workspace', 'workspaces', 'include-workspace-root', + 'ignore-scripts', ] static usage = ['<package-spec>'] + static workspaces = true static ignoreImplicitWorkspace = false async exec (args) { @@ -28,12 +30,17 @@ class Pack extends BaseCommand { const unicode = this.npm.config.get('unicode') const json = this.npm.config.get('json') + const Arborist = require('@npmcli/arborist') // Get the manifests and filenames first so we can bail early on manifest // errors before making any tarballs const manifests = [] for (const arg of args) { const spec = npa(arg) - const manifest = await pacote.manifest(spec, this.npm.flatOptions) + const manifest = await pacote.manifest(spec, { + ...this.npm.flatOptions, + Arborist, + _isRoot: true, + }) if (!manifest._id) { throw new Error('Invalid package, must have name and version') } @@ -46,25 +53,26 @@ class Pack extends BaseCommand { for (const { arg, manifest } of manifests) { const tarballData = await libpack(arg, { ...this.npm.flatOptions, + foregroundScripts: this.npm.config.isDefault('foreground-scripts') + ? true + : this.npm.config.get('foreground-scripts'), prefix: this.npm.localPrefix, workspaces: this.workspacePaths, }) - const pkgContents = await getContents(manifest, tarballData) - tarballs.push(pkgContents) - } - - if (json) { - this.npm.output(JSON.stringify(tarballs, null, 2)) - return + tarballs.push(await getContents(manifest, tarballData)) } - for (const tar of tarballs) { - logTar(tar, { unicode }) - this.npm.output(tar.filename.replace(/^@/, '').replace(/\//, '-')) + for (const [index, tar] of Object.entries(tarballs)) { + // XXX(BREAKING_CHANGE): publish outputs a json object with package + // names as keys. Pack should do the same here instead of an array + logTar(tar, { unicode, json, key: index }) + if (!json) { + output.standard(tar.filename.replace(/^@/, '').replace(/\//, '-')) + } } } - async execWorkspaces (args, filters) { + async execWorkspaces (args) { // If they either ask for nothing, or explicitly include '.' in the args, // we effectively translate that into each workspace requested @@ -75,8 +83,9 @@ class Pack extends BaseCommand { return this.exec(args) } - await this.setWorkspaces(filters) + await this.setWorkspaces() return this.exec([...this.workspacePaths, ...args.filter(a => a !== '.')]) } } + module.exports = Pack diff --git a/lib/commands/ping.js b/lib/commands/ping.js index 22039214689a9..3388ba1aa378e 100644 --- a/lib/commands/ping.js +++ b/lib/commands/ping.js @@ -1,28 +1,30 @@ -const log = require('../utils/log-shim') +const { redact } = require('@npmcli/redact') +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' - static ignoreImplicitWorkspace = true - async exec (args) { - log.notice('PING', this.npm.config.get('registry')) + async exec () { + const cleanRegistry = redact(this.npm.config.get('registry')) + log.notice('PING', cleanRegistry) const start = Date.now() const details = await pingUtil({ ...this.npm.flatOptions }) const time = Date.now() - start log.notice('PONG', `${time}ms`) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ - registry: this.npm.config.get('registry'), + output.buffer({ + 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/lib/commands/pkg.js b/lib/commands/pkg.js index 5fac9bfb54683..5a236f6e62270 100644 --- a/lib/commands/pkg.js +++ b/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 { @@ -11,6 +12,7 @@ class Pkg extends BaseCommand { 'delete <key> [<key> ...]', 'set [<array>[<index>].<key>=<value> ...]', 'set [<array>[].<key>=<value> ...]', + 'fix', ] static params = [ @@ -20,15 +22,10 @@ class Pkg extends BaseCommand { 'workspaces', ] + static workspaces = true static ignoreImplicitWorkspace = false - async exec (args, { prefix } = {}) { - if (!prefix) { - this.prefix = this.npm.localPrefix - } else { - this.prefix = prefix - } - + async exec (args, { path = this.npm.localPrefix, workspace } = {}) { if (this.npm.global) { throw Object.assign( new Error(`There's no package.json file to manage on global mode`), @@ -39,56 +36,50 @@ class Pkg extends BaseCommand { const [cmd, ..._args] = args switch (cmd) { case 'get': - return this.get(_args) + return this.get(_args, { path, workspace }) case 'set': - return this.set(_args) + return this.set(_args, { path, workspace }).then(p => p.save()) case 'delete': - return this.delete(_args) + return this.delete(_args, { path, workspace }).then(p => p.save()) + case 'fix': + return PackageJson.fix(path).then(p => p.save()) default: throw this.usageError() } } - async execWorkspaces (args, filters) { - await this.setWorkspaces(filters) - const result = {} - for (const [workspaceName, workspacePath] of this.workspaces.entries()) { - this.prefix = workspacePath - result[workspaceName] = await this.exec(args, { prefix: workspacePath }) + async execWorkspaces (args) { + await this.setWorkspaces() + for (const [workspace, path] of this.workspaces.entries()) { + await this.exec(args, { path, workspace }) } - // 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)) } - async get (args) { - const pkgJson = await PackageJson.load(this.prefix) - - const { content } = pkgJson - let result = !args.length && content + async get (args, { path, workspace }) { + this.npm.config.set('json', true) + const pkgJson = await PackageJson.load(path) - if (!result) { - const q = new Queryable(content) - result = q.query(args) + let result = pkgJson.content - // in case there's only a single result from the query - // just prints that one element to stdout - if (Object.keys(result).length === 1) { + if (args.length) { + result = new Queryable(result).query(args) + // in case there's only a single argument and a single result from the query + // just prints that one element to stdout. + // TODO(BREAKING_CHANGE): much like other places where we unwrap single + // item arrays this should go away. it makes the behavior unknown for users + // who don't already know the shape of the data. + if (Object.keys(result).length === 1 && args.length === 1) { result = result[args] } } - // only outputs if not running with workspaces config, - // in case you're retrieving info for workspaces the pkgWorkspaces - // will handle the output to make sure it get keyed by ws name - if (!this.workspaces) { - this.npm.output(JSON.stringify(result, null, 2)) - } - - return result + // The display layer is responsible for calling JSON.stringify on the result + // TODO: https://github.com/npm/cli/issues/5508 a raw mode has been requested similar + // to jq -r. If that was added then this method should no longer set `json:true` all the time + output.buffer(workspace ? { [workspace]: result } : result) } - async set (args) { + async set (args, { path }) { const setError = () => this.usageError('npm pkg set expects a key=value pair of args.') @@ -98,7 +89,7 @@ class Pkg extends BaseCommand { const force = this.npm.config.get('force') const json = this.npm.config.get('json') - const pkgJson = await PackageJson.load(this.prefix) + const pkgJson = await PackageJson.load(path) const q = new Queryable(pkgJson.content) for (const arg of args) { const [key, ...rest] = arg.split('=') @@ -110,11 +101,10 @@ class Pkg extends BaseCommand { q.set(key, json ? JSON.parse(value) : value, { force }) } - pkgJson.update(q.toJSON()) - await pkgJson.save() + return pkgJson.update(q.toJSON()) } - async delete (args) { + async delete (args, { path }) { const setError = () => this.usageError('npm pkg delete expects key args.') @@ -122,7 +112,7 @@ class Pkg extends BaseCommand { throw setError() } - const pkgJson = await PackageJson.load(this.prefix) + const pkgJson = await PackageJson.load(path) const q = new Queryable(pkgJson.content) for (const key of args) { if (!key) { @@ -132,8 +122,7 @@ class Pkg extends BaseCommand { q.delete(key) } - pkgJson.update(q.toJSON()) - await pkgJson.save() + return pkgJson.update(q.toJSON()) } } diff --git a/lib/commands/prefix.js b/lib/commands/prefix.js index dd0e34c3d3bd9..907ed5af2c179 100644 --- a/lib/commands/prefix.js +++ b/lib/commands/prefix.js @@ -1,14 +1,14 @@ -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' static name = 'prefix' static params = ['global'] - static usage = ['[-g]'] - static ignoreImplicitWorkspace = true - async exec (args) { - return this.npm.output(this.npm.prefix) + async exec () { + return output.standard(this.npm.prefix) } } + module.exports = Prefix diff --git a/lib/commands/profile.js b/lib/commands/profile.js index 27060cf73a650..2e11f93788f99 100644 --- a/lib/commands/profile.js +++ b/lib/commands/profile.js @@ -1,14 +1,11 @@ -const inspect = require('util').inspect -const { URL } = require('url') -const chalk = require('chalk') -const log = require('../utils/log-shim.js') -const npmProfile = require('npm-profile') +const { inspect } = require('node:util') +const { URL } = require('node:url') +const { log, output } = require('proc-log') +const { get, set, createToken } = 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 { otplease } = require('../utils/auth.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)) @@ -36,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' @@ -54,9 +50,7 @@ class Profile extends BaseCommand { 'otp', ] - static ignoreImplicitWorkspace = true - - async completion (opts) { + static async completion (opts) { var argv = opts.conf.argv.remain if (!argv[2]) { @@ -83,8 +77,6 @@ class Profile extends BaseCommand { throw this.usageError() } - log.gauge.show('profile') - const [subcmd, ...opts] = args switch (subcmd) { @@ -109,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 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.buffer(info) return } @@ -150,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({ [chalk.bold(key)]: cleaned[key] }) + for (const [key, value] of Object.entries(cleaned)) { + output.standard(`${key}: ${value}`) } - - this.npm.output(table.toString()) } } } @@ -212,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 get(conf) const newUser = {} for (const key of writableProfileKeys) { @@ -221,20 +208,22 @@ class Profile extends BaseCommand { newUser[prop] = value - const result = await otplease(this.npm, conf, conf => npmProfile.set(newUser, conf)) + const result = await otplease(this.npm, conf, c => set(newUser, c)) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ [prop]: result[prop] }, null, 2)) + output.buffer({ [prop]: result[prop] }) } 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) } } async enable2fa (args) { + const conf = { ...this.npm.flatOptions } + if (args.length > 1) { throw new Error('npm profile enable-2fa [auth-and-writes|auth-only]') } @@ -257,9 +246,16 @@ class Profile extends BaseCommand { ) } + const userInfo = await get(conf) + + if (!userInfo?.tfa?.pending && userInfo?.tfa?.mode === mode) { + output.standard('Two factor authentication is already enabled and set to ' + mode) + return + } + const info = { tfa: { - mode: mode, + mode, }, } @@ -286,7 +282,7 @@ class Profile extends BaseCommand { if (auth.basic) { log.info('profile', 'Updating authentication to bearer token') - const result = await npmProfile.createToken( + const result = await createToken( auth.basic.password, false, [], { ...this.npm.flatOptions } ) @@ -309,32 +305,16 @@ class Profile extends BaseCommand { const password = await readUserInfo.password() info.tfa.password = password - log.info('profile', 'Determine if tfa is pending') - const userInfo = await pulseTillDone.withPromise( - 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) - ) - } else if (userInfo && userInfo.tfa) { - if (!conf.otp) { - conf.otp = await readUserInfo.otp( - 'Enter one-time password: ' - ) - } + await set({ tfa: { password, mode: 'disable' } }, conf) } log.info('profile', 'Setting two-factor authentication to ' + mode) - const challenge = await pulseTillDone.withPromise( - npmProfile.set(info, conf) - ) + const challenge = await otplease(this.npm, conf, o => set(info, o)) - if (challenge.tfa === null) { - this.npm.output('Two factor authentication mode changed to: ' + mode) + if (challenge.tfa && challenge.tfa.mode) { + output.standard('Two factor authentication mode changed to: ' + mode) return } @@ -351,7 +331,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 ) @@ -360,51 +340,44 @@ class Profile extends BaseCommand { log.info('profile', 'Finalizing two-factor authentication') - const result = await npmProfile.set({ tfa: [interactiveOTP] }, conf) + const result = await 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) { - const conf = { ...this.npm.flatOptions } - const info = await pulseTillDone.withPromise(npmProfile.get(conf)) + async disable2fa () { + const opts = { ...this.npm.flatOptions } + const info = await get(opts) if (!info.tfa || info.tfa.pending) { - this.npm.output('Two factor authentication not enabled.') + output.standard('Two factor authentication not enabled.') return } const password = await readUserInfo.password() - if (!conf.otp) { - const msg = 'Enter one-time password: ' - conf.otp = await readUserInfo.otp(msg) - } - log.info('profile', 'disabling tfa') - - await pulseTillDone.withPromise(npmProfile.set({ - tfa: { password: password, mode: 'disable' }, - }, conf)) + await otplease(this.npm, opts, o => set({ tfa: { password: password, mode: 'disable' } }, o)) if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify({ tfa: false }, null, 2)) + output.buffer({ tfa: false }) } 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/lib/commands/prune.js b/lib/commands/prune.js index ee2c30553f1c5..1bcf8a9576316 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -1,13 +1,13 @@ -// prune extraneous packages -const Arborist = require('@npmcli/arborist') 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' static params = [ 'omit', + 'include', 'dry-run', 'json', 'foreground-scripts', @@ -19,6 +19,7 @@ class Prune extends ArboristWorkspaceCmd { async exec () { const where = this.npm.prefix + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, path: where, @@ -29,4 +30,5 @@ class Prune extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Prune diff --git a/lib/commands/publish.js b/lib/commands/publish.js index 3d17866a684a4..3c8cbfb825129 100644 --- a/lib/commands/publish.js +++ b/lib/commands/publish.js @@ -1,5 +1,4 @@ -const util = require('util') -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,23 +6,18 @@ const runScript = require('@npmcli/run-script') const pacote = require('pacote') const npa = require('npm-package-arg') const npmFetch = require('npm-registry-fetch') -const replaceInfo = require('../utils/replace-info.js') - -const otplease = require('../utils/otplease.js') +const { redactLog: replaceInfo } = require('@npmcli/redact') +const { otplease } = require('../utils/auth.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('../utils/config/flatten.js') +const { flatten } = require('@npmcli/config/lib/definitions') +const pkgJson = require('@npmcli/package-json') +const BaseCommand = require('../base-cmd.js') +const { oidc } = require('../../lib/utils/oidc.js') -// this is the only case in the CLI where we want to use the old full slow -// 'read-package-json' module, because we want to pull in all the defaults and -// metadata, like git sha's and default scripts and all that. -const readJson = util.promisify(require('read-package-json')) - -const BaseCommand = require('../base-command.js') class Publish extends BaseCommand { static description = 'Publish a package' static name = 'publish' @@ -35,9 +29,11 @@ class Publish extends BaseCommand { 'workspace', 'workspaces', 'include-workspace-root', + 'provenance', ] static usage = ['<package-spec>'] + static workspaces = true static ignoreImplicitWorkspace = false async exec (args) { @@ -48,6 +44,30 @@ class Publish extends BaseCommand { throw this.usageError() } + await this.#publish(args) + } + + async execWorkspaces (args) { + const useWorkspaces = args.length === 0 || args.includes('.') + if (!useWorkspaces) { + log.warn('Ignoring workspaces for specified package(s)') + return this.exec(args) + } + await this.setWorkspaces() + + for (const [name, workspace] of this.workspaces.entries()) { + try { + await this.#publish([workspace], { workspace: name }) + } catch (err) { + if (err.code !== 'EPRIVATE') { + throw err + } + log.warn('publish', `Skipping workspace ${this.npm.chalk.cyan(name)}, marked as ${this.npm.chalk.bold('private')}`) + } + } + } + + async #publish (args, { workspace } = {}) { log.verbose('publish', replaceInfo(args)) const unicode = this.npm.config.get('unicode') @@ -62,12 +82,11 @@ 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. const spec = npa(args[0]) - let manifest = await this.getManifest(spec, opts) + let manifest = await this.#getManifest(spec, opts) // only run scripts for directory type publishes if (spec.type === 'directory' && !ignoreScripts) { @@ -76,35 +95,64 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) } // we pass dryRun: true to libnpmpack so it doesn't write the file to disk const tarballData = await pack(spec, { ...opts, + foregroundScripts: this.npm.config.isDefault('foreground-scripts') + ? true + : this.npm.config.get('foreground-scripts'), dryRun: true, prefix: this.npm.localPrefix, workspaces: this.workspacePaths, }) const pkgContents = await getContents(manifest, tarballData) + const logPkg = () => logTar(pkgContents, { unicode, json, key: workspace }) // The purpose of re-reading the manifest is in case it changed, // so that we send the latest and greatest thing to the registry // note that publishConfig might have changed as well! - manifest = await this.getManifest(spec, opts) + manifest = await this.#getManifest(spec, opts, true) + const force = this.npm.config.get('force') + const isDefaultTag = this.npm.config.isDefault('tag') && !manifest.publishConfig?.tag + + if (!force) { + const isPreRelease = Boolean(semver.parse(manifest.version).prerelease.length) + if (isPreRelease && isDefaultTag) { + throw new Error('You must specify a tag using --tag when publishing a prerelease version.') + } + } - // JSON already has the package contents + // If we are not in JSON mode then we show the user the contents of the tarball + // before it is published so they can see it while their otp is pending if (!json) { - logTar(pkgContents, { unicode }) + logPkg() } const resolved = npa.resolve(manifest.name, manifest.version) + + // make sure tag is valid, this will throw if invalid + npa(`${manifest.name}@${defaultTag}`) + const registry = npmFetch.pickRegistry(resolved, opts) + + await oidc({ packageName: manifest.name, registry, opts, config: this.npm.config }) + const creds = this.npm.config.getCredentialsByURI(registry) const noCreds = !(creds.token || creds.username || creds.certfile && creds.keyfile) const outputRegistry = replaceInfo(registry) + // if a workspace package is marked private then we skip it + if (workspace && manifest.private) { + throw Object.assign( + new Error(`This package has been marked as private + Remove the 'private' field from the package.json to publish it.`), + { code: 'EPRIVATE' } + ) + } + if (noCreds) { const msg = `This command requires you to be logged in to ${outputRegistry}` if (dryRun) { @@ -114,10 +162,36 @@ class Publish extends BaseCommand { } } - log.notice('', `Publishing to ${outputRegistry}${dryRun ? ' (dry-run)' : ''}`) + if (!force) { + const { highestVersion, versions } = await this.#registryVersions(resolved, registry) + /* eslint-disable-next-line max-len */ + const highestVersionIsGreater = !!highestVersion && semver.gte(highestVersion, manifest.version) + + if (versions.includes(manifest.version)) { + throw new Error(`You cannot publish over the previously published versions: ${manifest.version}.`) + } + + if (highestVersionIsGreater && isDefaultTag) { + throw new Error(`Cannot implicitly apply the "latest" tag because previously published version ${highestVersion} is higher than the new version ${manifest.version}. You must specify a tag using --tag.`) + } + } + + const access = opts.access === null ? 'default' : opts.access + let msg = `Publishing to ${outputRegistry} with tag ${defaultTag} and ${access} access` + if (dryRun) { + msg = `${msg} (dry-run)` + } + + log.notice('', msg) if (!dryRun) { - await otplease(this.npm, opts, opts => libpub(manifest, tarballData, opts)) + await otplease(this.npm, opts, o => libpub(manifest, tarballData, o)) + } + + // In json mode we don't log until the publish has completed as this will + // add it to the output only if completes successfully + if (json) { + logPkg() } if (spec.type === 'directory' && !ignoreScripts) { @@ -126,7 +200,6 @@ class Publish extends BaseCommand { path: spec.fetchSpec, stdio: 'inherit', pkg: manifest, - banner: !silent, }) await runScript({ @@ -134,69 +207,57 @@ 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)) - } else if (!silent) { - this.npm.output(`+ ${pkgContents.id}`) - } + if (!json && !silent) { + output.standard(`+ ${pkgContents.id}`) } - - return pkgContents } - async execWorkspaces (args, filters) { - // Suppresses JSON output in publish() so we can handle it here - this.suppressOutput = true - - const results = {} - const json = this.npm.config.get('json') - const { silent } = this.npm - await this.setWorkspaces(filters) - - for (const [name, workspace] of this.workspaces.entries()) { - let pkgContents - try { - pkgContents = await this.exec([workspace]) - } catch (err) { - if (err.code === 'EPRIVATE') { - log.warn( - 'publish', - `Skipping workspace ${ - this.npm.chalk.green(name) - }, marked as ${ - this.npm.chalk.bold('private') - }` - ) - continue - } - throw err - } - // 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}`) - } else { - results[name] = pkgContents + async #registryVersions (spec, registry) { + try { + const packument = await pacote.packument(spec, { + ...this.npm.flatOptions, + preferOnline: true, + registry, + _isRoot: true, + }) + if (typeof packument?.versions === 'undefined') { + return { versions: [], highestVersion: null } } - } - - if (!silent && json) { - this.npm.output(JSON.stringify(results, null, 2)) + const ordered = Object.keys(packument?.versions) + .flatMap(v => { + const s = new semver.SemVer(v) + if ((s.prerelease.length > 0) || packument.versions[v].deprecated) { + return [] + } + return s + }) + .sort((a, b) => b.compare(a)) + const highestVersion = ordered.length >= 1 ? ordered[0].version : null + const versions = ordered.map(v => v.version) + return { versions, highestVersion } + } catch (e) { + return { versions: [], highestVersion: null } } } // if it's a directory, read it from the file system // otherwise, get the full metadata from whatever it is // XXX can't pacote read the manifest from a directory? - async getManifest (spec, opts) { + async #getManifest (spec, opts, logWarnings = false) { let manifest if (spec.type === 'directory') { - manifest = await readJson(`${spec.fetchSpec}/package.json`) + const changes = [] + const pkg = await pkgJson.fix(spec.fetchSpec, { changes }) + if (changes.length && logWarnings) { + log.warn('publish', 'npm auto-corrected some errors in your package.json when publishing. Please run "npm pkg fix" to address these errors.') + log.warn('publish', `errors corrected:\n${changes.join('\n')}`) + } + // Prepare is the special function for publishing, different than normalize + const { content } = await pkg.prepare() + manifest = content } else { manifest = await pacote.manifest(spec, { ...opts, @@ -205,9 +266,20 @@ class Publish extends BaseCommand { }) } if (manifest.publishConfig) { - flatten(manifest.publishConfig, opts) + const cliFlags = this.npm.config.data.get('cli').raw + // Filter out properties set in CLI flags to prioritize them over + // corresponding `publishConfig` settings + const filteredPublishConfig = Object.fromEntries( + Object.entries(manifest.publishConfig).filter(([key]) => !(key in cliFlags))) + if (logWarnings) { + for (const key in filteredPublishConfig) { + this.npm.config.checkUnknown('publishConfig', key) + } + } + flatten(filteredPublishConfig, opts) } return manifest } } + module.exports = Publish diff --git a/lib/commands/query.js b/lib/commands/query.js index 371fddef9b440..5e70e25f32e62 100644 --- a/lib/commands/query.js +++ b/lib/commands/query.js @@ -1,8 +1,6 @@ -'use strict' - -const { resolve } = require('path') -const Arborist = require('@npmcli/arborist') -const BaseCommand = require('../base-command.js') +const { resolve } = require('node:path') +const BaseCommand = require('../base-cmd.js') +const { log, output } = require('proc-log') class QuerySelectorItem { constructor (node) { @@ -20,6 +18,8 @@ class QuerySelectorItem { this.dev = node.target.dev this.inBundle = node.target.inBundle this.deduped = this.from.length > 1 + this.overridden = node.overridden + this.queryContext = node.queryContext for (const edge of node.target.edgesIn) { this.from.push(edge.from.location) } @@ -39,6 +39,7 @@ class Query extends BaseCommand { static name = 'query' static usage = ['<selector>'] + static workspaces = true static ignoreImplicitWorkspace = false static params = [ @@ -46,56 +47,90 @@ class Query extends BaseCommand { 'workspace', 'workspaces', 'include-workspace-root', + 'package-lock-only', + 'expect-results', ] - get parsedResponse () { - return JSON.stringify(this.#response, null, 2) + constructor (...args) { + super(...args) + this.npm.config.set('json', true) } async exec (args) { - // one dir up from wherever node_modules lives - const where = resolve(this.npm.dir, '..') - const opts = { + const packageLockOnly = this.npm.config.get('package-lock-only') + const Arborist = require('@npmcli/arborist') + const arb = new Arborist({ ...this.npm.flatOptions, - path: where, + // one dir up from wherever node_modules lives + path: resolve(this.npm.dir, '..'), + forceActual: !packageLockOnly, + }) + let tree + if (packageLockOnly) { + try { + tree = await arb.loadVirtual() + } catch (err) { + log.verbose('loadVirtual', err.stack) + throw this.usageError( + 'A package lock or shrinkwrap file is required in package-lock-only mode' + ) + } + } else { + tree = await arb.loadActual() } - const arb = new Arborist(opts) - const tree = await arb.loadActual(opts) - const items = await tree.querySelectorAll(args[0]) - this.buildResponse(items) - - this.npm.output(this.parsedResponse) + await this.#queryTree(tree, args[0]) + this.#output() } - async execWorkspaces (args, filters) { - await this.setWorkspaces(filters) - const opts = { + async execWorkspaces (args) { + await this.setWorkspaces() + const packageLockOnly = this.npm.config.get('package-lock-only') + const Arborist = require('@npmcli/arborist') + const arb = new Arborist({ ...this.npm.flatOptions, path: this.npm.prefix, + forceActual: !packageLockOnly, + }) + let tree + if (packageLockOnly) { + try { + tree = await arb.loadVirtual() + } catch (err) { + log.verbose('loadVirtual', err.stack) + throw this.usageError( + 'A package lock or shrinkwrap file is required in package-lock-only mode' + ) + } + } else { + tree = await arb.loadActual() } - const arb = new Arborist(opts) - const tree = await arb.loadActual(opts) - for (const workspacePath of this.workspacePaths) { - let items - if (workspacePath === tree.root.path) { - // include-workspace-root - items = await tree.querySelectorAll(args[0]) - } else { - const [workspace] = await tree.querySelectorAll(`.workspace:path(${workspacePath})`) - items = await workspace.target.querySelectorAll(args[0]) + for (const path of this.workspacePaths) { + const wsTree = path === tree.root.path + ? tree // --includes-workspace-root + : await tree.querySelectorAll(`.workspace:path(${path})`).then(r => r[0]?.target) + if (wsTree) { + await this.#queryTree(wsTree, args[0]) } - this.buildResponse(items) } - this.npm.output(this.parsedResponse) + this.#output() + } + + #output () { + this.checkExpected(this.#response.length) + output.buffer(this.#response) } // builds a normalized inventory - buildResponse (items) { + async #queryTree (tree, arg) { + const items = await tree.querySelectorAll(arg, this.npm.flatOptions) for (const node of items) { - if (!this.#seen.has(node.target.location)) { + const { location } = node.target + if (!location || !this.#seen.has(location)) { const item = new QuerySelectorItem(node) this.#response.push(item) - this.#seen.add(item.location) + if (location) { + this.#seen.add(item.location) + } } } } diff --git a/lib/commands/rebuild.js b/lib/commands/rebuild.js index d06313ce483a9..1c19836106e06 100644 --- a/lib/commands/rebuild.js +++ b/lib/commands/rebuild.js @@ -1,10 +1,9 @@ -const { resolve } = require('path') -const Arborist = require('@npmcli/arborist') +const { resolve } = require('node:path') +const { output } = require('proc-log') const npa = require('npm-package-arg') const semver = require('semver') -const completion = require('../utils/completion/installed-deep.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Rebuild extends ArboristWorkspaceCmd { static description = 'Rebuild a package' static name = 'rebuild' @@ -20,13 +19,15 @@ class Rebuild extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + const completion = require('../utils/installed-deep.js') + return completion(npm, opts) } async exec (args) { const globalTop = resolve(this.npm.globalDir, '..') const where = this.npm.global ? globalTop : this.npm.prefix + const Arborist = require('@npmcli/arborist') const arb = new Arborist({ ...this.npm.flatOptions, path: where, @@ -39,7 +40,7 @@ class Rebuild extends ArboristWorkspaceCmd { const tree = await arb.loadActual() const specs = args.map(arg => { const spec = npa(arg) - if (spec.type === 'tag' && spec.rawSpec === '') { + if (spec.rawSpec === '*') { return spec } @@ -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/lib/commands/repo.js b/lib/commands/repo.js index b89b74c0bf1ba..0bfb2cf962c9b 100644 --- a/lib/commands/repo.js +++ b/lib/commands/repo.js @@ -1,6 +1,6 @@ -const { URL } = require('url') - +const { URL } = require('node: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 => { @@ -48,7 +49,7 @@ const unknownHostedUrl = url => { const proto = /(git\+)http:$/.test(protocol) ? 'http:' : 'https:' const path = pathname.replace(/\.git$/, '') return `${proto}//${hostname}${path}` - } catch (e) { + } catch { return null } } diff --git a/lib/commands/restart.js b/lib/commands/restart.js index 575928b2202cc..52b9b20757e29 100644 --- a/lib/commands/restart.js +++ b/lib/commands/restart.js @@ -1,6 +1,6 @@ const LifecycleCmd = require('../lifecycle-cmd.js') -// This ends up calling run-script(['restart', ...args]) +// This ends up calling run(['restart', ...args]) class Restart extends LifecycleCmd { static description = 'Restart a package' static name = 'restart' @@ -8,7 +8,6 @@ class Restart extends LifecycleCmd { 'ignore-scripts', 'script-shell', ] - - static ignoreImplicitWorkspace = false } + module.exports = Restart diff --git a/lib/commands/root.js b/lib/commands/root.js index b814034def5ab..180f4c4ed0720 100644 --- a/lib/commands/root.js +++ b/lib/commands/root.js @@ -1,12 +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'] - static ignoreImplicitWorkspace = true async exec () { - this.npm.output(this.npm.dir) + output.standard(this.npm.dir) } } + module.exports = Root diff --git a/lib/commands/run-script.js b/lib/commands/run-script.js deleted file mode 100644 index 8507dbe79a90e..0000000000000 --- a/lib/commands/run-script.js +++ /dev/null @@ -1,269 +0,0 @@ -const { resolve } = require('path') -const chalk = require('chalk') -const runScript = require('@npmcli/run-script') -const { isServerPackage } = runScript -const rpj = require('read-package-json-fast') -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 nocolor = { - reset: s => s, - bold: s => s, - dim: s => s, - blue: s => s, - green: s => s, -} - -const BaseCommand = require('../base-command.js') -class RunScript extends BaseCommand { - static description = 'Run arbitrary package scripts' - static params = [ - 'workspace', - 'workspaces', - 'include-workspace-root', - 'if-present', - 'ignore-scripts', - 'foreground-scripts', - 'script-shell', - ] - - static name = 'run-script' - static usage = ['<command> [-- <args>]'] - static ignoreImplicitWorkspace = false - static isShellout = true - - async completion (opts) { - const argv = opts.conf.argv.remain - if (argv.length === 2) { - // find the script name - const json = resolve(this.npm.localPrefix, 'package.json') - const { scripts = {} } = await rpj(json).catch(er => ({})) - return Object.keys(scripts) - } - } - - async exec (args) { - if (args.length) { - return this.run(args) - } else { - return this.list(args) - } - } - - async execWorkspaces (args, filters) { - if (args.length) { - return this.runWorkspaces(args, filters) - } else { - return this.listWorkspaces(args, filters) - } - } - - 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 - - pkg = pkg || (await rpj(`${path}/package.json`)) - const { scripts = {} } = pkg - - if (event === 'restart' && !scripts.restart) { - scripts.restart = 'npm stop --if-present && npm start' - } else if (event === 'env' && !scripts.env) { - scripts.env = isWindowsShell ? 'SET' : 'env' - } - - pkg.scripts = scripts - - if ( - !Object.prototype.hasOwnProperty.call(scripts, event) && - !(event === 'start' && (await isServerPackage(path))) - ) { - if (this.npm.config.get('if-present')) { - return - } - - const suggestions = await didYouMean(this.npm, path, event) - throw new Error( - `Missing script: "${event}"${suggestions}\n\nTo see a list of scripts, run:\n npm run` - ) - } - - // positional args only added to the main event, not pre/post - const events = [[event, args]] - if (!this.npm.config.get('ignore-scripts')) { - if (scripts[`pre${event}`]) { - events.unshift([`pre${event}`, []]) - } - - if (scripts[`post${event}`]) { - events.push([`post${event}`, []]) - } - } - - const opts = { - path, - args, - scriptShell, - stdio: 'inherit', - stdioString: true, - pkg, - banner: !this.npm.silent, - } - - for (const [event, args] of events) { - await runScript({ - ...opts, - event, - args, - }) - } - } - - async list (args, path) { - path = path || this.npm.localPrefix - const { scripts, name, _id } = await rpj(`${path}/package.json`) - const pkgid = _id || name - const color = this.npm.color - - if (!scripts) { - return [] - } - - const allScripts = Object.keys(scripts) - if (this.npm.silent) { - return allScripts - } - - if (this.npm.config.get('json')) { - this.npm.output(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}`) - } - - return allScripts - } - - const indent = '\n ' - const prefix = ' ' - const cmds = [] - const runScripts = [] - for (const script of allScripts) { - const list = cmdList.includes(script) ? cmds : runScripts - list.push(script) - } - const colorize = color ? chalk : nocolor - - if (cmds.length) { - this.npm.output( - `${colorize.reset(colorize.bold('Lifecycle scripts'))} included in ${colorize.green( - pkgid - )}:` - ) - } - - for (const script of cmds) { - this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) - } - - if (!cmds.length && runScripts.length) { - this.npm.output( - `${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')}\`:`) - } - - for (const script of runScripts) { - this.npm.output(prefix + script + indent + colorize.dim(scripts[script])) - } - - this.npm.output('') - return allScripts - } - - async runWorkspaces (args, filters) { - const res = [] - await this.setWorkspaces(filters) - - for (const workspacePath of this.workspacePaths) { - const pkg = await rpj(`${workspacePath}/package.json`) - const runResult = await this.run(args, { - path: workspacePath, - pkg, - }).catch(err => { - log.error(`Lifecycle script \`${args[0]}\` failed with error:`) - log.error(err) - log.error(` in workspace: ${pkg._id || pkg.name}`) - log.error(` at location: ${workspacePath}`) - - const scriptMissing = err.message.startsWith('Missing script') - - // avoids exiting with error code in case there's scripts missing - // in some workspaces since other scripts might have succeeded - if (!scriptMissing) { - process.exitCode = 1 - } - - return scriptMissing - }) - res.push(runResult) - } - - // in case **all** tests are missing, then it should exit with error code - if (res.every(Boolean)) { - throw new Error(`Missing script: ${args[0]}`) - } - } - - async listWorkspaces (args, filters) { - await this.setWorkspaces(filters) - - if (this.npm.silent) { - return - } - - if (this.npm.config.get('json')) { - const res = {} - for (const workspacePath of this.workspacePaths) { - const { scripts, name } = await rpj(`${workspacePath}/package.json`) - res[name] = { ...scripts } - } - this.npm.output(JSON.stringify(res, null, 2)) - return - } - - if (this.npm.config.get('parseable')) { - for (const workspacePath of this.workspacePaths) { - const { scripts, name } = await rpj(`${workspacePath}/package.json`) - for (const [script, cmd] of Object.entries(scripts || {})) { - this.npm.output(`${name}:${script}:${cmd}`) - } - } - return - } - - for (const workspacePath of this.workspacePaths) { - await this.list(args, workspacePath) - } - } -} - -module.exports = RunScript diff --git a/lib/commands/run.js b/lib/commands/run.js new file mode 100644 index 0000000000000..d89cb4d93bb7f --- /dev/null +++ b/lib/commands/run.js @@ -0,0 +1,222 @@ +const { output } = require('proc-log') +const pkgJson = require('@npmcli/package-json') +const BaseCommand = require('../base-cmd.js') +const { getError } = require('../utils/error-message.js') +const { outputError } = require('../utils/output-error.js') + +class RunScript extends BaseCommand { + static description = 'Run arbitrary package scripts' + static params = [ + 'workspace', + 'workspaces', + 'include-workspace-root', + 'if-present', + 'ignore-scripts', + 'foreground-scripts', + 'script-shell', + ] + + static name = 'run' + static usage = ['<command> [-- <args>]'] + static workspaces = true + static ignoreImplicitWorkspace = false + static isShellout = true + static checkDevEngines = true + + static async completion (opts, npm) { + const argv = opts.conf.argv.remain + if (argv.length === 2) { + const workspacePrefixes = npm.config.get('workspace', 'default') + const localPrefix = workspacePrefixes.length + ? workspacePrefixes[0] + : npm.localPrefix + const { content: { scripts = {} } } = await pkgJson.normalize(localPrefix) + .catch(() => ({ content: {} })) + if (opts.isFish) { + return Object.keys(scripts).map(s => `${s}\t${scripts[s].slice(0, 30)}`) + } + return Object.keys(scripts) + } + } + + async exec (args) { + if (args.length) { + await this.#run(args, { path: this.npm.localPrefix }) + } else { + await this.#list(this.npm.localPrefix) + } + } + + async execWorkspaces (args) { + await this.setWorkspaces() + + const ws = [...this.workspaces.entries()] + for (const [workspace, path] of ws) { + const last = path === ws.at(-1)[1] + + if (!args.length) { + const newline = await this.#list(path, { workspace }) + if (newline && !last) { + output.standard('') + } + continue + } + + const pkg = await pkgJson.normalize(path).then(p => p.content) + try { + await this.#run(args, { path, pkg, workspace }) + } catch (e) { + const err = getError(e, { npm: this.npm, command: null }) + outputError({ + ...err, + error: [ + ['', `Lifecycle script \`${args[0]}\` failed with error:`], + ...err.error, + ['workspace', pkg._id || pkg.name], + ['location', path], + ], + }) + process.exitCode = err.exitCode + if (!last) { + output.error('') + } + } + } + } + + async #run ([event, ...args], { path, pkg, workspace }) { + const runScript = require('@npmcli/run-script') + + pkg ??= await pkgJson.normalize(path).then(p => p.content) + + const { scripts = {} } = pkg + + 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' + } + + pkg.scripts = scripts + + if ( + !Object.prototype.hasOwnProperty.call(scripts, event) && + !(event === 'start' && (await runScript.isServerPackage(path))) + ) { + if (this.npm.config.get('if-present')) { + return + } + + const suggestions = require('../utils/did-you-mean.js')(pkg, event) + const wsArg = workspace && path !== this.npm.localPrefix + ? ` --workspace=${pkg._id || pkg.name}` + : '' + throw new Error([ + `Missing script: "${event}"${suggestions}\n`, + 'To see a list of scripts, run:', + ` npm run${wsArg}`, + ].join('\n')) + } + + // positional args only added to the main event, not pre/post + const events = [[event, args]] + if (!this.npm.config.get('ignore-scripts')) { + if (scripts[`pre${event}`]) { + events.unshift([`pre${event}`, []]) + } + + if (scripts[`post${event}`]) { + events.push([`post${event}`, []]) + } + } + + for (const [ev, evArgs] of events) { + await runScript({ + args: evArgs, + event: ev, + nodeGyp: this.npm.config.get('node-gyp'), + path, + pkg, + // || undefined is because runScript will be unhappy with the default null value + scriptShell: this.npm.config.get('script-shell') || undefined, + stdio: 'inherit', + }) + } + } + + async #list (path, { workspace } = {}) { + const { scripts = {}, name, _id } = await pkgJson.normalize(path).then(p => p.content) + const scriptEntries = Object.entries(scripts) + + if (this.npm.silent) { + return + } + + if (this.npm.config.get('json')) { + output.buffer(workspace ? { [workspace]: scripts } : scripts) + return + } + + if (!scriptEntries.length) { + return + } + + if (this.npm.config.get('parseable')) { + output.standard(scriptEntries + .map((s) => (workspace ? [workspace, ...s] : s).join(':')) + .join('\n') + .trim()) + return + } + + const cmdList = [ + 'prepare', 'prepublishOnly', + 'prepack', 'postpack', + 'dependencies', + '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 [cmds, runScripts] = scriptEntries.reduce((acc, s) => { + acc[cmdList.includes(s[0]) ? 0 : 1].push(s) + return acc + }, [[], []]) + + const { reset, bold, cyan, dim, blue } = this.npm.chalk + const pkgId = `in ${cyan(_id || name)}` + const title = (t) => reset(bold(t)) + + if (cmds.length) { + output.standard(`${title('Lifecycle scripts')} included ${pkgId}:`) + for (const [k, v] of cmds) { + output.standard(` ${k}`) + output.standard(` ${dim(v)}`) + } + } + + if (runScripts.length) { + const via = `via \`${blue('npm run')}\`:` + if (!cmds.length) { + output.standard(`${title('Scripts')} available ${pkgId} ${via}`) + } else { + output.standard(`available ${via}`) + } + for (const [k, v] of runScripts) { + output.standard(` ${k}`) + output.standard(` ${dim(v)}`) + } + } + + // Return true to indicate that something was output for this path + // that should be separated from others + return true + } +} + +module.exports = RunScript diff --git a/lib/commands/sbom.js b/lib/commands/sbom.js new file mode 100644 index 0000000000000..98452d646dfe8 --- /dev/null +++ b/lib/commands/sbom.js @@ -0,0 +1,132 @@ +const localeCompare = require('@isaacs/string-locale-compare')('en') +const BaseCommand = require('../base-cmd.js') +const { log, output, META } = require('proc-log') +const { cyclonedxOutput } = require('../utils/sbom-cyclonedx.js') +const { spdxOutput } = require('../utils/sbom-spdx.js') + +const SBOM_FORMATS = ['cyclonedx', 'spdx'] + +class SBOM extends BaseCommand { + #response = {} // response is the sbom response + + static description = 'Generate a Software Bill of Materials (SBOM)' + static name = 'sbom' + static workspaces = true + + static params = [ + 'omit', + 'package-lock-only', + 'sbom-format', + 'sbom-type', + 'workspace', + 'workspaces', + ] + + async exec () { + const sbomFormat = this.npm.config.get('sbom-format') + const packageLockOnly = this.npm.config.get('package-lock-only') + + if (!sbomFormat) { + throw this.usageError(`Must specify --sbom-format flag with one of: ${SBOM_FORMATS.join(', ')}.`) + } + + const opts = { + ...this.npm.flatOptions, + path: this.npm.prefix, + forceActual: true, + } + const Arborist = require('@npmcli/arborist') + const arb = new Arborist(opts) + + const tree = packageLockOnly ? await arb.loadVirtual(opts).catch(() => { + throw this.usageError('A package lock or shrinkwrap file is required in package-lock-only mode') + }) : await arb.loadActual(opts) + + // Collect the list of selected workspaces in the project + const wsNodes = this.workspaceNames?.length + ? arb.workspaceNodes(tree, this.workspaceNames) + : null + + // Build the selector and query the tree for the list of nodes + const selector = this.#buildSelector({ wsNodes }) + log.info('sbom', `Using dependency selector: ${selector}`) + const items = await tree.querySelectorAll(selector) + + const errors = items.flatMap(node => detectErrors(node)) + if (errors.length) { + throw Object.assign(new Error([...new Set(errors)].join('\n')), { + code: 'ESBOMPROBLEMS', + }) + } + + // Populate the response with the list of unique nodes (sorted by location) + this.#buildResponse(items.sort((a, b) => localeCompare(a.location, b.location))) + + // TODO(BREAKING_CHANGE): all sbom output is in json mode but setting it before + // any of the errors will cause those to be thrown in json mode. + this.npm.config.set('json', true) + output.standard(JSON.stringify(this.#response, null, 2), { [META]: true, redact: false }) + } + + async execWorkspaces (args) { + await this.setWorkspaces() + return this.exec(args) + } + + // Build the selector from all of the specified filter options + #buildSelector ({ wsNodes }) { + let selector + const omit = this.npm.flatOptions.omit + const workspacesEnabled = this.npm.flatOptions.workspacesEnabled + + // If omit is specified, omit all nodes and their children which match the + // specified selectors + const omits = omit.reduce((acc, o) => `${acc}:not(.${o})`, '') + + if (!workspacesEnabled) { + // If workspaces are disabled, omit all workspace nodes and their children + selector = `:root > :not(.workspace)${omits},:root > :not(.workspace) *${omits},:extraneous` + } else if (wsNodes && wsNodes.length > 0) { + // If one or more workspaces are selected, select only those workspaces and their children + selector = wsNodes.map(ws => `#${ws.name},#${ws.name} *${omits}`).join(',') + } else { + selector = `:root *${omits},:extraneous` + } + + // Always include the root node + return `:root,${selector}` + } + + // builds a normalized inventory + #buildResponse (items) { + const sbomFormat = this.npm.config.get('sbom-format') + const packageType = this.npm.config.get('sbom-type') + const packageLockOnly = this.npm.config.get('package-lock-only') + + this.#response = sbomFormat === 'cyclonedx' + ? cyclonedxOutput({ npm: this.npm, nodes: items, packageType, packageLockOnly }) + : spdxOutput({ npm: this.npm, nodes: items, packageType }) + } +} + +const detectErrors = (node) => { + const errors = [] + + // Look for missing dependencies (that are NOT optional), or invalid dependencies + for (const edge of node.edgesOut.values()) { + if (edge.missing && !(edge.type === 'optional' || edge.type === 'peerOptional')) { + errors.push(`missing: ${edge.name}@${edge.spec}, required by ${edge.from.pkgid}`) + } + + if (edge.invalid) { + /* istanbul ignore next */ + const spec = edge.spec || '*' + const from = edge.from.pkgid + errors.push(`invalid: ${edge.to.pkgid}, ${spec} required by ${from}`) + } + } + + return errors +} + +module.exports = SBOM diff --git a/lib/commands/search.js b/lib/commands/search.js index 8751e9e7d22fd..8b6c01e3930d8 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,47 +1,18 @@ -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', 'description', + 'searchlimit', 'searchopts', 'searchexclude', 'registry', @@ -50,14 +21,13 @@ class Search extends BaseCommand { 'offline', ] - static usage = ['[search terms ...]'] - static ignoreImplicitWorkspace = true + static usage = ['<search term> [<search term> ...]'] 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,27 +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 { - 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. + // Grab a configured output stream that will spit out packages in the desired format. 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 ) @@ -96,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/lib/commands/set-script.js b/lib/commands/set-script.js deleted file mode 100644 index a085f72a31428..0000000000000 --- a/lib/commands/set-script.js +++ /dev/null @@ -1,96 +0,0 @@ -const { resolve } = require('path') -const rpj = require('read-package-json-fast') -const PackageJson = require('@npmcli/package-json') -const log = require('../utils/log-shim') - -const BaseCommand = require('../base-command.js') -class SetScript extends BaseCommand { - static description = 'Set tasks in the scripts section of package.json, deprecated' - static params = ['workspace', 'workspaces', 'include-workspace-root'] - static name = 'set-script' - static usage = ['[<script>] [<command>]'] - static ignoreImplicitWorkspace = false - - async completion (opts) { - const argv = opts.conf.argv.remain - if (argv.length === 2) { - // find the script name - const json = resolve(this.npm.localPrefix, 'package.json') - const { scripts = {} } = await rpj(json).catch(er => ({})) - return Object.keys(scripts) - } - } - - validate (args) { - if (process.env.npm_lifecycle_event === 'postinstall') { - throw new Error('Scripts can’t set from the postinstall script') - } - - // Parse arguments - if (args.length !== 2) { - throw new Error(`Expected 2 arguments: got ${args.length}`) - } - } - - async exec (args) { - this.validate(args) - log.warn('set-script', - 'set-script is deprecated, use `npm pkg set scripts.scriptname="cmd" instead.') - const warn = await this.doSetScript(this.npm.localPrefix, args[0], args[1]) - if (warn) { - log.warn('set-script', `Script "${args[0]}" was overwritten`) - } - } - - async execWorkspaces (args, filters) { - this.validate(args) - await this.setWorkspaces(filters) - - for (const [name, path] of this.workspaces) { - try { - const warn = await this.doSetScript(path, args[0], args[1]) - if (warn) { - log.warn('set-script', `Script "${args[0]}" was overwritten`) - log.warn(` in workspace: ${name}`) - log.warn(` at location: ${path}`) - } - } catch (err) { - log.error('set-script', err.message) - log.error(` in workspace: ${name}`) - log.error(` at location: ${path}`) - process.exitCode = 1 - } - } - } - - // returns a Boolean that will be true if - // the requested script was overwritten - // and false if it was set as a new script - async doSetScript (path, name, value) { - let warn = false - - const pkgJson = await PackageJson.load(path) - const { scripts } = pkgJson.content - - const overwriting = - scripts - && scripts[name] - && scripts[name] !== value - - if (overwriting) { - warn = true - } - - pkgJson.update({ - scripts: { - ...scripts, - [name]: value, - }, - }) - - await pkgJson.save() - - return warn - } -} -module.exports = SetScript diff --git a/lib/commands/set.js b/lib/commands/set.js index b650026a599a9..2e61762ba9dcd 100644 --- a/lib/commands/set.js +++ b/lib/commands/set.js @@ -1,15 +1,18 @@ -const BaseCommand = require('../base-command.js') +const Npm = require('../npm.js') +const BaseCommand = require('../base-cmd.js') class Set extends BaseCommand { static description = 'Set a value in the npm configuration' static name = 'set' static usage = ['<key>=<value> [<key>=<value> ...] (See `npm config`)'] + static params = ['global', 'location'] static ignoreImplicitWorkspace = false // TODO /* istanbul ignore next */ - async completion (opts) { - return this.npm.cmd('config').completion(opts) + static async completion (opts) { + const Config = Npm.cmd('config') + return Config.completion(opts) } async exec (args) { @@ -19,4 +22,5 @@ class Set extends BaseCommand { return this.npm.exec('config', ['set'].concat(args)) } } + module.exports = Set diff --git a/lib/commands/shrinkwrap.js b/lib/commands/shrinkwrap.js index a240f039356e7..86215c18e62dd 100644 --- a/lib/commands/shrinkwrap.js +++ b/lib/commands/shrinkwrap.js @@ -1,8 +1,8 @@ -const { resolve, basename } = require('path') -const { unlink } = require('fs').promises -const Arborist = require('@npmcli/arborist') -const log = require('../utils/log-shim') -const BaseCommand = require('../base-command.js') +const { resolve, basename } = require('node:path') +const { unlink } = require('node: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' @@ -21,6 +21,7 @@ class Shrinkwrap extends BaseCommand { throw er } + const Arborist = require('@npmcli/arborist') const path = this.npm.prefix const sw = resolve(path, 'npm-shrinkwrap.json') const arb = new Arborist({ ...this.npm.flatOptions, path }) @@ -68,4 +69,5 @@ class Shrinkwrap extends BaseCommand { } } } + module.exports = Shrinkwrap diff --git a/lib/commands/star.js b/lib/commands/star.js index 20039bf893811..7d1be1d389730 100644 --- a/lib/commands/star.js +++ b/lib/commands/star.js @@ -1,9 +1,9 @@ -const fetch = require('npm-registry-fetch') +const npmFetch = 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' @@ -32,7 +32,7 @@ class Star extends BaseCommand { const username = await getIdentity(this.npm, this.npm.flatOptions) for (const pkg of pkgs) { - const fullData = await fetch.json(pkg.escapedName, { + const fullData = await npmFetch.json(pkg.escapedName, { ...this.npm.flatOptions, spec: pkg, query: { write: true }, @@ -55,17 +55,18 @@ class Star extends BaseCommand { log.verbose('unstar', 'unstarring', body) } - const data = await fetch.json(pkg.escapedName, { + const data = await npmFetch.json(pkg.escapedName, { ...this.npm.flatOptions, spec: pkg, method: 'PUT', body, }) - this.npm.output(show + ' ' + pkg.name) + output.standard(show + ' ' + pkg.name) log.verbose('star', data) return data } } } + module.exports = Star diff --git a/lib/commands/stars.js b/lib/commands/stars.js index 4214134eb5871..d059d01250900 100644 --- a/lib/commands/stars.js +++ b/lib/commands/stars.js @@ -1,8 +1,8 @@ -const fetch = require('npm-registry-fetch') -const log = require('../utils/log-shim') +const npmFetch = require('npm-registry-fetch') +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' @@ -16,7 +16,7 @@ class Stars extends BaseCommand { user = await getIdentity(this.npm, this.npm.flatOptions) } - const { rows } = await fetch.json('/-/_view/starredByUser', { + const { rows } = await npmFetch.json('/-/_view/starredByUser', { ...this.npm.flatOptions, query: { key: `"${user}"` }, }) @@ -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/lib/commands/start.js b/lib/commands/start.js index d84ad23ebafa6..54818c5be4da6 100644 --- a/lib/commands/start.js +++ b/lib/commands/start.js @@ -1,6 +1,6 @@ const LifecycleCmd = require('../lifecycle-cmd.js') -// This ends up calling run-script(['start', ...args]) +// This ends up calling run(['start', ...args]) class Start extends LifecycleCmd { static description = 'Start a package' static name = 'start' @@ -8,7 +8,6 @@ class Start extends LifecycleCmd { 'ignore-scripts', 'script-shell', ] - - static ignoreImplicitWorkspace = false } + module.exports = Start diff --git a/lib/commands/stop.js b/lib/commands/stop.js index db497675a694b..e6e9c9afca1dd 100644 --- a/lib/commands/stop.js +++ b/lib/commands/stop.js @@ -1,6 +1,6 @@ const LifecycleCmd = require('../lifecycle-cmd.js') -// This ends up calling run-script(['stop', ...args]) +// This ends up calling run(['stop', ...args]) class Stop extends LifecycleCmd { static description = 'Stop a package' static name = 'stop' @@ -8,7 +8,6 @@ class Stop extends LifecycleCmd { 'ignore-scripts', 'script-shell', ] - - static ignoreImplicitWorkspace = false } + module.exports = Stop diff --git a/lib/commands/team.js b/lib/commands/team.js index 2d4fc663715e4..089e917909d10 100644 --- a/lib/commands/team.js +++ b/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/auth.js') -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' @@ -24,7 +24,7 @@ class Team extends BaseCommand { static ignoreImplicitWorkspace = false - async completion (opts) { + static async completion (opts) { const { conf: { argv: { remain: argv } } } = opts const subcommands = ['create', 'destroy', 'add', 'rm', 'ls'] @@ -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.buffer({ 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.buffer({ 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.buffer({ 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.buffer({ 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.buffer(users) } 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.buffer(teams) } 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/lib/commands/test.js b/lib/commands/test.js index 43be934894dd7..7dbff0b0b69c2 100644 --- a/lib/commands/test.js +++ b/lib/commands/test.js @@ -1,6 +1,6 @@ const LifecycleCmd = require('../lifecycle-cmd.js') -// This ends up calling run-script(['test', ...args]) +// This ends up calling run(['test', ...args]) class Test extends LifecycleCmd { static description = 'Test a package' static name = 'test' @@ -8,7 +8,6 @@ class Test extends LifecycleCmd { 'ignore-scripts', 'script-shell', ] - - static ignoreImplicitWorkspace = false } + module.exports = Test diff --git a/lib/commands/token.js b/lib/commands/token.js index cf3b8cbee53a4..b248d6a789a1f 100644 --- a/lib/commands/token.js +++ b/lib/commands/token.js @@ -1,22 +1,40 @@ -const Table = require('cli-table3') -const chalk = require('chalk') -const { v4: isCidrV4, v6: isCidrV6 } = require('is-cidr') -const log = require('../utils/log-shim.js') -const profile = require('npm-profile') - -const otplease = require('../utils/otplease.js') -const pulseTillDone = require('../utils/pulse-till-done.js') +const { log, output, META } = require('proc-log') +const fetch = require('npm-registry-fetch') +const { otplease } = require('../utils/auth.js') const readUserInfo = require('../utils/read-user-info.js') +const BaseCommand = require('../base-cmd.js') + +async function paginate (href, opts, items = []) { + while (href) { + const result = await fetch.json(href, opts) + items = items.concat(result.objects) + href = result.urls.next + } + return items +} -const BaseCommand = require('../base-command.js') class Token extends BaseCommand { static description = 'Manage your authentication tokens' static name = 'token' - static usage = ['list', 'revoke <id|token>', 'create [--read-only] [--cidr=list]'] - static params = ['read-only', 'cidr', 'registry', 'otp'] - static ignoreImplicitWorkspace = true + static usage = ['list', 'revoke <id|token>', 'create'] + static params = ['name', + 'token-description', + 'expires', + 'packages', + 'packages-all', + 'scopes', + 'orgs', + 'packages-and-scopes-permission', + 'orgs-permission', + 'cidr', + 'bypass-2fa', + 'password', + 'registry', + 'otp', + 'read-only', + ] - async completion (opts) { + static async completion (opts) { const argv = opts.conf.argv.remain const subcommands = ['list', 'revoke', 'create'] if (argv.length === 2) { @@ -30,8 +48,7 @@ class Token extends BaseCommand { throw new Error(argv[2] + ' not recognized') } - async exec (args, cb) { - log.gauge.show('token') + async exec (args) { if (args.length === 0) { return this.list() } @@ -39,10 +56,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)) @@ -52,16 +69,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 paginate('/-/npm/v1/tokens', this.npm.flatOptions) + if (json) { + output.buffer(tokens) 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, @@ -74,21 +93,15 @@ 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 created = String(token.created).slice(0, 10) + output.standard(`${chalk.blue('Token')} ${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) { @@ -96,18 +109,17 @@ class Token extends BaseCommand { throw this.usageError('`<tokenKey>` 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)) - args.forEach(id => { + log.info('token', `removing ${toRemove.length} tokens`) + const tokens = await paginate('/-/npm/v1/tokens', this.npm.flatOptions) + for (const id of args) { const matches = tokens.filter(token => token.key.indexOf(id) === 0) if (matches.length === 1) { toRemove.push(matches[0].key) } else if (matches.length > 1) { throw new Error( - /* eslint-disable-next-line max-len */ `Token ID "${id}" was ambiguous, a new token may have been created since you last ran \`npm token list\`.` ) } else { @@ -118,84 +130,114 @@ class Token extends BaseCommand { toRemove.push(id) } - }) - await Promise.all( - toRemove.map(key => { - return otplease(this.npm, conf, conf => { - return profile.removeToken(key, conf) + } + for (const tokenKey of toRemove) { + await otplease(this.npm, this.npm.flatOptions, opts => + fetch(`/-/npm/v1/tokens/token/${tokenKey}`, { + ...opts, + method: 'DELETE', + ignoreBody: true, }) - }) - ) - if (conf.json) { - this.npm.output(JSON.stringify(toRemove)) - } else if (conf.parseable) { - this.npm.output(toRemove.join('\t')) + ) + } + if (json) { + output.buffer(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 - - return readUserInfo - .password() - .then(password => { - const validCIDR = this.validateCIDRList(cidr) - log.info('token', 'creating') - return pulseTillDone.withPromise( - otplease(this.npm, conf, conf => { - return profile.createToken(password, readonly, validCIDR, conf) - }) - ) - }) - .then(result => { - 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])) - } else { - const table = new Table() - for (const k of Object.keys(result)) { - table.push({ [chalk.bold(k)]: String(result[k]) }) - } - this.npm.output(table.toString()) - } - }) - } + async create () { + const json = this.npm.config.get('json') + const parseable = this.npm.config.get('parseable') + const cidr = this.npm.config.get('cidr') + const name = this.npm.config.get('name') + const tokenDescription = this.npm.config.get('token-description') + const expires = this.npm.config.get('expires') + const packages = this.npm.config.get('packages') + const packagesAll = this.npm.config.get('packages-all') + const scopes = this.npm.config.get('scopes') + const orgs = this.npm.config.get('orgs') + const packagesAndScopesPermission = this.npm.config.get('packages-and-scopes-permission') + const orgsPermission = this.npm.config.get('orgs-permission') + const bypassTwoFactor = this.npm.config.get('bypass-2fa') + let password = this.npm.config.get('password') - 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, - }, - } - } 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 = {} + const validCIDR = await this.validateCIDRList(cidr) + + /* istanbul ignore if - skip testing read input */ + if (!password) { + password = await readUserInfo.password() } - if (conf.otp) { - conf.auth.otp = conf.otp + const tokenData = { + name: name, + password: password, + } + + if (tokenDescription) { + tokenData.description = tokenDescription + } + + if (packages?.length > 0) { + tokenData.packages = packages + } + if (packagesAll) { + tokenData.packages_all = true + } + if (scopes?.length > 0) { + tokenData.scopes = scopes + } + if (orgs?.length > 0) { + tokenData.orgs = orgs + } + + if (packagesAndScopesPermission) { + tokenData.packages_and_scopes_permission = packagesAndScopesPermission + } + if (orgsPermission) { + tokenData.orgs_permission = orgsPermission + } + + // Add expiration in days + if (expires) { + tokenData.expires = parseInt(expires, 10) + } + + // Add optional fields + if (validCIDR?.length > 0) { + tokenData.cidr_whitelist = validCIDR + } + if (bypassTwoFactor) { + tokenData.bypass_2fa = true + } + + log.info('token', 'creating') + const result = await otplease(this.npm, this.npm.flatOptions, opts => + fetch.json('/-/npm/v1/tokens', { + ...opts, + method: 'POST', + body: tokenData, + }) + ) + delete result.key + delete result.updated + if (json) { + output.buffer(result) + } else if (parseable) { + Object.keys(result).forEach(k => output.standard(k + '\t' + result[k])) + } else { + const chalk = this.npm.chalk + output.standard(`Created token ${result.token}`, { [META]: true, redact: false }) + if (result.cidr_whitelist?.length) { + output.standard(`with IP whitelist: ${chalk.green(result.cidr_whitelist.join(','))}`) + } + if (result.expires) { + output.standard(`expires: ${result.expires}`) + } } - return conf } invalidCIDRError (msg) { @@ -203,7 +245,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) { @@ -215,26 +256,26 @@ class Token extends BaseCommand { break } } - byId[token.id] = token } - return byId } - validateCIDRList (cidrs) { - const maybeList = cidrs ? (Array.isArray(cidrs) ? cidrs : [cidrs]) : [] + async validateCIDRList (cidrs) { + const { v4: isCidrV4, v6: isCidrV6 } = await import('is-cidr') + const maybeList = [].concat(cidrs).filter(Boolean) const list = maybeList.length === 1 ? maybeList[0].split(/,\s*/) : maybeList 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/lib/commands/undeprecate.js b/lib/commands/undeprecate.js new file mode 100644 index 0000000000000..79ce66bbe5600 --- /dev/null +++ b/lib/commands/undeprecate.js @@ -0,0 +1,13 @@ +const Deprecate = require('./deprecate.js') + +class Undeprecate extends Deprecate { + static description = 'Undeprecate a version of a package' + static name = 'undeprecate' + static usage = ['<package-spec>'] + + async exec ([pkg]) { + return super.exec([pkg, '']) + } +} + +module.exports = Undeprecate diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index e4a193cc5ca4e..f9baebe3bc2e2 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -1,38 +1,30 @@ -const { resolve } = require('path') -const Arborist = require('@npmcli/arborist') -const rpj = require('read-package-json-fast') - +const { resolve } = require('node: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' - static params = ['save', ...super.params] + static params = ['save', 'global', ...super.params] static usage = ['[<@scope>/]<pkg>...'] static ignoreImplicitWorkspace = false // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + return completion(npm, opts) } async exec (args) { - // the /path/to/node_modules/.. - const path = this.npm.global - ? resolve(this.npm.globalDir, '..') - : this.npm.localPrefix - if (!args.length) { if (!this.npm.global) { throw new Error('Must provide a package name to remove') } else { - let pkg - try { - pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')) + const { content: pkg } = await pkgJson.normalize(this.npm.localPrefix) + args.push(pkg.name) } catch (er) { if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') { throw er @@ -40,11 +32,15 @@ class Uninstall extends ArboristWorkspaceCmd { throw this.usageError() } } - - args.push(pkg.name) } } + // the /path/to/node_modules/.. + const path = this.npm.global + ? resolve(this.npm.globalDir, '..') + : this.npm.localPrefix + + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, path, @@ -56,4 +52,5 @@ class Uninstall extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Uninstall diff --git a/lib/commands/unpublish.js b/lib/commands/unpublish.js index 0e5ef3dc5e91d..73d9d03804558 100644 --- a/lib/commands/unpublish.js +++ b/lib/commands/unpublish.js @@ -1,52 +1,54 @@ const libaccess = require('libnpmaccess') const libunpub = require('libnpmpublish').unpublish const npa = require('npm-package-arg') -const npmFetch = require('npm-registry-fetch') -const path = require('path') -const util = require('util') -const readJson = util.promisify(require('read-package-json')) - -const flatten = require('../utils/config/flatten.js') +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 { otplease } = require('../utils/auth.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' static params = ['dry-run', 'force', 'workspace', 'workspaces'] static usage = ['[<package-spec>]'] + static workspaces = true static ignoreImplicitWorkspace = false - async getKeysOfVersions (name, opts) { - const pkgUri = npa(name).escapedName - const json = await npmFetch.json(`${pkgUri}?write=true`, opts) - return Object.keys(json.versions) + static async getKeysOfVersions (name, opts) { + const packument = await pacote.packument(name, { + ...opts, + spec: name, + query: { write: true }, + _isRoot: true, + }) + return Object.keys(packument.versions) } - async completion (args) { + static async completion (args, npm) { const { partialWord, conf } = args if (conf.argv.remain.length >= 3) { return [] } - const opts = { ...this.npm.flatOptions } - const username = await getIdentity(this.npm, { ...opts }).catch(() => null) + const opts = { ...npm.flatOptions } + const username = await getIdentity(npm, { ...opts }).catch(() => null) if (!username) { return [] } - const access = await libaccess.lsPackages(username, opts) + const access = await libaccess.getPackages(username, opts) // do a bit of filtering at this point, so that we don't need // to fetch versions for more than one thing, but also don't // accidentally unpublish a whole project - let pkgs = Object.keys(access || {}) + let pkgs = Object.keys(access) if (!partialWord || !pkgs.length) { return pkgs } @@ -57,7 +59,7 @@ class Unpublish extends BaseCommand { return pkgs } - const versions = await this.getKeysOfVersions(pkgs[0], opts) + const versions = await Unpublish.getKeysOfVersions(pkgs[0], opts) if (!versions.length) { return pkgs } else { @@ -65,20 +67,35 @@ class Unpublish extends BaseCommand { } } - async exec (args) { + async exec (args, { localPrefix } = {}) { if (args.length > 1) { throw this.usageError() } - let spec = args.length && npa(args[0]) + // workspace mode + if (!localPrefix) { + localPrefix = this.npm.localPrefix + } + const force = this.npm.config.get('force') const { silent } = this.npm const dryRun = this.npm.config.get('dry-run') + let spec + if (args.length) { + spec = npa(args[0]) + if (spec.type !== 'version' && spec.rawSpec !== '*') { + throw this.usageError( + 'Can only unpublish a single version, or the entire project.\n' + + 'Tags and ranges are not supported.' + ) + } + } + log.silly('unpublish', 'args[0]', args[0]) log.silly('unpublish', 'spec', spec) - if ((!spec || !spec.rawSpec) && !force) { + if (spec?.rawSpec === '*' && !force) { throw this.usageError( 'Refusing to delete entire project.\n' + 'Run with --force to do this.' @@ -87,70 +104,77 @@ class Unpublish extends BaseCommand { const opts = { ...this.npm.flatOptions } - let pkgName - let pkgVersion let manifest - let manifestErr try { - const pkgJson = path.join(this.npm.localPrefix, 'package.json') - manifest = await readJson(pkgJson) + const { content } = await pkgJson.prepare(localPrefix) + manifest = content } catch (err) { - manifestErr = err - } - if (spec) { - // If cwd has a package.json with a name that matches the package being - // unpublished, load up the publishConfig - if (manifest && manifest.name === spec.name && manifest.publishConfig) { - flatten(manifest.publishConfig, opts) - } - const versions = await this.getKeysOfVersions(spec.name, opts) - if (versions.length === 1 && !force) { - throw this.usageError(LAST_REMAINING_VERSION_ERROR) - } - pkgName = spec.name - pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : '' - } else { - if (manifestErr) { - if (manifestErr.code === 'ENOENT' || manifestErr.code === 'ENOTDIR') { + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') { + if (!spec) { + // We needed a local package.json to figure out what package to + // unpublish throw this.usageError() - } else { - throw manifestErr } + } else { + // folks should know if ANY local package.json had a parsing error. + // They may be relying on `publishConfig` to be loading and we don't + // want to ignore errors in that case. + throw err } + } + let pkgVersion // for cli output + if (spec) { + pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : '' + } else { + spec = npa.resolve(manifest.name, manifest.version) log.verbose('unpublish', manifest) + pkgVersion = manifest.version ? `@${manifest.version}` : '' + if (!manifest.version && !force) { + throw this.usageError( + 'Refusing to delete entire project.\n' + + 'Run with --force to do this.' + ) + } + } - spec = npa.resolve(manifest.name, manifest.version) - if (manifest.publishConfig) { - flatten(manifest.publishConfig, opts) + // If localPrefix has a package.json with a name that matches the package + // being unpublished, load up the publishConfig + if (manifest?.name === spec.name && manifest.publishConfig) { + const cliFlags = this.npm.config.data.get('cli').raw + // Filter out properties set in CLI flags to prioritize them over + // corresponding `publishConfig` settings + const filteredPublishConfig = Object.fromEntries( + Object.entries(manifest.publishConfig).filter(([key]) => !(key in cliFlags))) + for (const key in filteredPublishConfig) { + this.npm.config.checkUnknown('publishConfig', key) } + flatten(filteredPublishConfig, opts) + } - pkgName = manifest.name - pkgVersion = manifest.version ? `@${manifest.version}` : '' + const versions = await Unpublish.getKeysOfVersions(spec.name, opts) + if (versions.length === 1 && spec.rawSpec === versions[0] && !force) { + throw this.usageError(LAST_REMAINING_VERSION_ERROR) + } + if (versions.length === 1) { + pkgVersion = '' } if (!dryRun) { - await otplease(this.npm, opts, opts => libunpub(spec, opts)) + await otplease(this.npm, opts, o => libunpub(spec, o)) } if (!silent) { - this.npm.output(`- ${pkgName}${pkgVersion}`) + output.standard(`- ${spec.name}${pkgVersion}`) } } - async execWorkspaces (args, filters) { - await this.setWorkspaces(filters) - - const force = this.npm.config.get('force') - if (!force) { - throw this.usageError( - 'Refusing to delete entire project(s).\n' + - 'Run with --force to do this.' - ) - } + async execWorkspaces (args) { + await this.setWorkspaces() - for (const name of this.workspaceNames) { - await this.exec([name]) + for (const path of this.workspacePaths) { + await this.exec(args, { localPrefix: path }) } } } + module.exports = Unpublish diff --git a/lib/commands/unstar.js b/lib/commands/unstar.js index cbcb73636c638..c72966866669a 100644 --- a/lib/commands/unstar.js +++ b/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/lib/commands/update.js b/lib/commands/update.js index ca80d61537e70..0d2fc324d9245 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -1,12 +1,8 @@ -const path = require('path') - -const Arborist = require('@npmcli/arborist') -const log = require('../utils/log-shim.js') - +const path = require('node:path') +const { log } = require('proc-log') const reifyFinish = require('../utils/reify-finish.js') -const completion = require('../utils/completion/installed-deep.js') - const ArboristWorkspaceCmd = require('../arborist-cmd.js') + class Update extends ArboristWorkspaceCmd { static description = 'Update packages' static name = 'update' @@ -14,14 +10,17 @@ class Update extends ArboristWorkspaceCmd { static params = [ 'save', 'global', - 'global-style', + 'install-strategy', 'legacy-bundling', + 'global-style', 'omit', + 'include', 'strict-peer-deps', 'package-lock', 'foreground-scripts', 'ignore-scripts', 'audit', + 'before', 'bin-links', 'fund', 'dry-run', @@ -32,16 +31,15 @@ class Update extends ArboristWorkspaceCmd { // TODO /* istanbul ignore next */ - async completion (opts) { - return completion(this.npm, opts) + static async completion (opts, npm) { + const completion = require('../utils/installed-deep.js') + return completion(npm, opts) } async exec (args) { const update = args.length === 0 ? true : args const global = path.resolve(this.npm.globalDir, '..') - const where = this.npm.global - ? global - : this.npm.prefix + const where = this.npm.global ? global : this.npm.prefix // In the context of `npm update` the save // config value should default to `false` @@ -54,6 +52,7 @@ class Update extends ArboristWorkspaceCmd { 'https://github.com/npm/rfcs/blob/latest/implemented/0019-remove-update-depth-option.md') } + const Arborist = require('@npmcli/arborist') const opts = { ...this.npm.flatOptions, path: where, @@ -66,4 +65,5 @@ class Update extends ArboristWorkspaceCmd { await reifyFinish(this.npm, arb) } } + module.exports = Update diff --git a/lib/commands/version.js b/lib/commands/version.js index ab59fff5a308c..fe70322fd7cb9 100644 --- a/lib/commands/version.js +++ b/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' @@ -16,18 +13,20 @@ class Version extends BaseCommand { 'json', 'preid', 'sign-git-tag', + 'save', 'workspace', 'workspaces', 'workspaces-update', 'include-workspace-root', + 'ignore-scripts', ] + static workspaces = true static ignoreImplicitWorkspace = false - /* eslint-disable-next-line max-len */ static usage = ['[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]'] - async completion (opts) { + static async completion (opts) { const { conf: { argv: { remain }, @@ -60,41 +59,55 @@ class Version extends BaseCommand { } } - async execWorkspaces (args, filters) { + async execWorkspaces (args) { switch (args.length) { case 0: - return this.listWorkspaces(filters) + return this.listWorkspaces() case 1: - return this.changeWorkspaces(args, filters) + return this.changeWorkspaces(args) default: throw this.usageError() } } 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, filters) { + async changeWorkspaces (args) { + const updateWorkspaces = require('../utils/update-workspaces.js') + const libnpmversion = require('libnpmversion') const prefix = this.npm.config.get('tag-version-prefix') - await this.setWorkspaces(filters) + 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 = {}) { @@ -114,15 +127,15 @@ class Version extends BaseCommand { } if (this.npm.config.get('json')) { - this.npm.output(JSON.stringify(results, null, 2)) + output.buffer(results) } else { - this.npm.output(results) + output.standard(results) } } - async listWorkspaces (filters) { + async listWorkspaces () { const results = {} - await this.setWorkspaces(filters) + await this.setWorkspaces() for (const path of this.workspacePaths) { const pj = resolve(path, 'package.json') // setWorkspaces has already parsed package.json so we know it won't error @@ -134,22 +147,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/lib/commands/view.js b/lib/commands/view.js index 3b8524ad3fc0d..dd563cb2d52b9 100644 --- a/lib/commands/view.js +++ b/lib/commands/view.js @@ -1,26 +1,21 @@ -/* eslint-disable no-console */ -// XXX: remove console.log later - -// npm view [pkg [pkg ...]] - -const chalk = require('chalk') const columns = require('cli-columns') -const fs = require('fs') +const { readFile } = require('node:fs/promises') const jsonParse = require('json-parse-even-better-errors') -const log = require('../utils/log-shim.js') +const { log, output, META } = require('proc-log') const npa = require('npm-package-arg') -const { resolve } = require('path') +const { resolve } = require('node: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('node:util') const { packument } = require('pacote') +const Queryable = require('../utils/queryable.js') +const BaseCommand = require('../base-cmd.js') +const { getError } = require('../utils/error-message.js') +const { jsonError, outputError } = require('../utils/output-error.js') -const readFile = promisify(fs.readFile) -const readJson = async file => jsonParse(await readFile(file, 'utf8')) +const readJson = file => readFile(file, 'utf8').then(jsonParse) -const Queryable = require('../utils/queryable.js') -const BaseCommand = require('../base-command.js') class View extends BaseCommand { static description = 'View registry info' static name = 'view' @@ -31,11 +26,11 @@ class View extends BaseCommand { 'include-workspace-root', ] + static workspaces = true static ignoreImplicitWorkspace = false - static usage = ['[<package-spec>] [<field>[.subfield]...]'] - async completion (opts) { + static async completion (opts, npm) { if (opts.conf.argv.remain.length <= 2) { // There used to be registry completion here, but it stopped // making sense somewhere around 50,000 packages on the registry @@ -43,52 +38,22 @@ class View extends BaseCommand { } // have the package, get the fields const config = { - ...this.npm.flatOptions, + ...npm.flatOptions, fullMetadata: true, preferOnline: true, + _isRoot: true, } const spec = npa(opts.conf.argv.remain[2]) const pckmnt = await packument(spec, config) - const defaultTag = this.npm.config.get('tag') + const defaultTag = npm.config.get('tag') const dv = pckmnt.versions[pckmnt['dist-tags'][defaultTag]] pckmnt.versions = Object.keys(pckmnt.versions).sort(semver.compareLoose) - return getFields(pckmnt).concat(getFields(dv)) - - function getFields (d, f, pref) { - f = f || [] - pref = pref || [] - Object.keys(d).forEach((k) => { - if (k.charAt(0) === '_' || k.indexOf('.') !== -1) { - return - } - const p = pref.concat(k).join('.') - f.push(p) - if (Array.isArray(d[k])) { - d[k].forEach((val, i) => { - const pi = p + '[' + i + ']' - if (val && typeof val === 'object') { - getFields(val, f, [p]) - } else { - f.push(pi) - } - }) - return - } - if (typeof d[k] === 'object') { - getFields(d[k], f, [p]) - } - }) - return f - } + return getCompletionFields(pckmnt).concat(getCompletionFields(dv)) } async exec (args) { - if (!args.length) { - args = ['.'] - } - let pkg = args.shift() - const local = /^\.@/.test(pkg) || pkg === '.' + let { pkg, local, rest } = parseArgs(args) if (local) { if (this.npm.global) { @@ -103,387 +68,376 @@ class View extends BaseCommand { pkg = `${manifest.name}${pkg.slice(1)}` } - let wholePackument = false - if (!args.length) { - args = [''] - wholePackument = true + await this.#viewPackage(pkg, rest) + } + + async execWorkspaces (args) { + const { pkg, local, rest } = parseArgs(args) + + if (!local) { + log.warn('Ignoring workspaces for specified package(s)') + return this.exec([pkg, ...rest]) } - const [pckmnt, data] = await this.getData(pkg, args) - if (!this.npm.config.get('json') && wholePackument) { - // pretty view (entire packument) - data.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''])) - } else { - // JSON formatted output (JSON or specific attributes from packument) - let reducedData = data.reduce(reducer, {}) - if (wholePackument) { - // No attributes - 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 json = this.npm.config.get('json') + await this.setWorkspaces() - const msg = await this.jsonData(reducedData, pckmnt._id) - if (msg !== '') { - console.log(msg) + for (const name of this.workspaceNames) { + try { + await this.#viewPackage(`${name}${pkg.slice(1)}`, rest, { workspace: true }) + } catch (e) { + const err = getError(e, { npm: this.npm, command: this }) + if (err.code !== 'E404') { + throw e + } + if (json) { + output.buffer({ [META]: true, jsonError: { [name]: jsonError(err, this.npm) } }) + } else { + outputError(err) + } + process.exitCode = err.exitCode } } } - async execWorkspaces (args, filters) { - if (!args.length) { - args = ['.'] + async #viewPackage (name, args, { workspace } = {}) { + const wholePackument = !args.length + const json = this.npm.config.get('json') + + // If we are viewing many packages and outputting individual fields then + // output the name before doing any async activity + if (!json && !wholePackument && workspace) { + output.standard(`${name}:`) } - const pkg = args.shift() + const [pckmnt, data] = await this.#getData(name, args, wholePackument) - const local = /^\.@/.test(pkg) || pkg === '.' - if (!local) { - log.warn('Ignoring workspaces for specified package(s)') - return this.exec([pkg, ...args]) - } - let wholePackument = false - if (!args.length) { - wholePackument = true - args = [''] // getData relies on this - } - const results = {} - await this.setWorkspaces(filters) - for (const name of this.workspaceNames) { - const wsPkg = `${name}${pkg.slice(1)}` - const [pckmnt, data] = await this.getData(wsPkg, args) - - let reducedData = data.reduce(reducer, {}) - if (wholePackument) { - // No attributes - reducedData = cleanBlanks(reducedData) - log.silly('view', reducedData) + if (!json && wholePackument) { + // pretty view (entire packument) + for (const v of data) { + output.standard(this.#prettyView(pckmnt, Object.values(v)[0][Queryable.ALL])) } + return + } - if (!this.npm.config.get('json')) { - if (wholePackument) { - data.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]][''])) - } else { - console.log(`${name}:`) - const msg = await this.jsonData(reducedData, pckmnt._id) - if (msg !== '') { - console.log(msg) - } - } + const res = this.#packageOutput(cleanData(data, wholePackument), pckmnt._id) + if (res) { + if (json) { + output.buffer(workspace ? { [name]: res } : res) } else { - const msg = await this.jsonData(reducedData, pckmnt._id) - if (msg !== '') { - results[name] = JSON.parse(msg) - } + output.standard(res) } } - if (Object.keys(results).length > 0) { - console.log(JSON.stringify(results, null, 2)) - } } - async getData (pkg, args) { - const opts = { + async #getData (pkg, args) { + const spec = npa(pkg) + + const pckmnt = await packument(spec, { ...this.npm.flatOptions, preferOnline: true, fullMetadata: true, - } - - const spec = npa(pkg) + _isRoot: true, + }) // get the data about this package let version = this.npm.config.get('tag') // rawSpec is the git url if this is from git - if (spec.type !== 'git' && spec.type !== 'directory' && spec.rawSpec) { + if (spec.type !== 'git' && spec.type !== 'directory' && spec.rawSpec !== '*') { version = spec.rawSpec } - const pckmnt = await packument(spec, opts) - - if (pckmnt['dist-tags'] && pckmnt['dist-tags'][version]) { + if (pckmnt['dist-tags']?.[version]) { version = pckmnt['dist-tags'][version] } - if (pckmnt.time && pckmnt.time.unpublished) { + + if (pckmnt.time?.unpublished) { const u = pckmnt.time.unpublished - const er = new Error(`Unpublished on ${u.time}`) - er.statusCode = 404 - er.code = 'E404' - er.pkgid = pckmnt._id - throw er + throw Object.assign(new Error(`Unpublished on ${u.time}`), { + statusCode: 404, + code: 'E404', + pkgid: pckmnt._id, + }) } - const data = [] const versions = pckmnt.versions || {} - pckmnt.versions = Object.keys(versions).sort(semver.compareLoose) + pckmnt.versions = Object.keys(versions).filter(v => { + if (semver.valid(v)) { + return true + } + log.info('view', `Ignoring invalid version: ${v}`) + return false + }).sort(semver.compareLoose) // remove readme unless we asked for it if (args.indexOf('readme') === -1) { delete pckmnt.readme } - Object.keys(versions).forEach((v) => { - if (semver.satisfies(v, version, true)) { - args.forEach(arg => { - // remove readme unless we asked for it - if (args.indexOf('readme') !== -1) { - delete versions[v].readme - } - - data.push(showFields(pckmnt, versions[v], arg)) + const data = Object.entries(versions) + .filter(([v]) => semver.satisfies(v, version, true)) + .flatMap(([, v]) => { + // remove readme unless we asked for it + if (args.indexOf('readme') !== -1) { + delete v.readme + } + return showFields({ + data: pckmnt, + version: v, + fields: args, + json: this.npm.config.get('json'), }) - } - }) + }) // No data has been pushed because no data is matching the specified version - if (data.length === 0 && version !== 'latest') { - const er = new Error(`No match found for version ${version}`) - er.statusCode = 404 - er.code = 'E404' - er.pkgid = `${pckmnt._id}@${version}` - throw er - } - - if ( - !this.npm.config.get('json') && - args.length === 1 && - args[0] === '' - ) { - pckmnt.version = version + if (!data.length && version !== 'latest') { + throw Object.assign(new Error(`No match found for version ${version}`), { + statusCode: 404, + code: 'E404', + pkgid: `${pckmnt._id}@${version}`, + }) } return [pckmnt, data] } - async jsonData (data, name) { + #packageOutput (data, name) { + const json = this.npm.config.get('json') const versions = Object.keys(data) - let msg = '' - let msgJson = [] const includeVersions = versions.length > 1 + let includeFields - const json = this.npm.config.get('json') + const res = versions.flatMap((v) => { + const fields = Object.entries(data[v]) - versions.forEach((v) => { - const fields = Object.keys(data[v]) - includeFields = includeFields || (fields.length > 1) - if (json) { - msgJson.push({}) - } - fields.forEach((f) => { - let d = cleanup(data[v][f]) - if (fields.length === 1 && json) { - msgJson[msgJson.length - 1][f] = d + includeFields ||= (fields.length > 1) + + const msg = json ? {} : [] + + for (let [f, d] of fields) { + d = cleanup(d) + + if (json) { + msg[f] = d + continue } if (includeVersions || includeFields || typeof d !== 'string') { - if (json) { - msgJson[msgJson.length - 1][f] = d - } else { - d = inspect(d, { - showHidden: false, - depth: 5, - colors: this.npm.color, - maxArrayLength: null, - }) - } - } else if (typeof d === 'string' && json) { - d = JSON.stringify(d) + d = inspect(d, { + showHidden: false, + depth: 5, + colors: this.npm.color, + maxArrayLength: null, + }) } - if (!json) { - if (f && includeFields) { - f += ' = ' - } - msg += (includeVersions ? name + '@' + v + ' ' : '') + - (includeFields ? f : '') + d + '\n' + if (f && includeFields) { + f += ' = ' } - }) + + msg.push(`${includeVersions ? `${name}@${v} ` : ''}${includeFields ? f : ''}${d}`) + } + + return msg }) if (json) { - if (msgJson.length && Object.keys(msgJson[0]).length === 1) { - const k = Object.keys(msgJson[0])[0] - msgJson = msgJson.map(m => m[k]) + // TODO(BREAKING_CHANGE): all unwrapping should be removed. Users should know + // based on their arguments if they can expect an array or an object. And this + // unwrapping can break that assumption. Eg `npm view abbrev@^2` should always + // return an array, but currently since there is only one version matching `^2` + // this will return a single object instead. + const first = Object.keys(res[0] || {}) + const jsonRes = first.length === 1 ? res.map(m => m[first[0]]) : res + if (jsonRes.length === 0) { + return } - if (msgJson.length === 1) { - msg = JSON.stringify(msgJson[0], null, 2) + '\n' - } else if (msgJson.length > 1) { - msg = JSON.stringify(msgJson, null, 2) + '\n' + if (jsonRes.length === 1) { + return jsonRes[0] } + return jsonRes } - return msg.trim() + return res.join('\n').trim() } - prettyView (packument, manifest) { + #prettyView (packu, manifest) { // More modern, pretty printing of default view const unicode = this.npm.config.get('unicode') - const tags = [] + const chalk = this.npm.chalk + const deps = Object.entries(manifest.dependencies || {}).map(([k, dep]) => + `${chalk.blue(k)}: ${dep}` + ) - Object.keys(packument['dist-tags']).forEach((t) => { - const version = packument['dist-tags'][t] - tags.push(`${chalk.bold.green(t)}: ${version}`) - }) - const unpackedSize = manifest.dist.unpackedSize && - formatBytes(manifest.dist.unpackedSize, true) + // Sort dist-tags by publish time when available, then by tag name, keeping `latest` at the top of the list. + const distTags = Object.entries(packu['dist-tags']) + .sort(([aTag, aVer], [bTag, bVer]) => { + const timeMap = packu.time || {} + const aTime = aTag === 'latest' ? Infinity : Date.parse(timeMap[aVer] || 0) + const bTime = bTag === 'latest' ? Infinity : Date.parse(timeMap[bVer] || 0) + if (aTime === bTime) { + return aTag > bTag ? -1 : 1 + } + return aTime > bTime ? -1 : 1 + }) + .map(([k, t]) => `${chalk.blue(k)}: ${t}`) + + 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(packument.versions.length + ''), - description: manifest.description, - deprecated: manifest.deprecated, - keywords: packument.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: !packument.time ? undefined - : chalk.yellow(relativeDate(packument.time[manifest.version])), - maintainers: (packument.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') + + const res = [] + + res.push('') + res.push([ + 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 && res.push(manifest.description) + if (site) { + res.push(chalk.blue(site)) } - console.log('') - console.log( - 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 && res.push( + `\n${chalk.redBright('DEPRECATED')}${unicode ? ' ⚠️ ' : '!!'} - ${manifest.deprecated}` ) - info.description && console.log(info.description) - if (info.repo || info.site) { - info.site && console.log(chalk.cyan(info.site)) - } - const warningSign = unicode ? ' ⚠️ ' : '!!' - info.deprecated && console.log( - `\n${chalk.bold.red('DEPRECATED')}${ - warningSign - } - ${info.deprecated}` - ) + if (packu.keywords?.length) { + res.push(`\nkeywords: ${ + packu.keywords.map(k => chalk.cyan(k)).join(', ') + }`) + } - if (info.keywords.length) { - console.log('') - console.log('keywords:', chalk.yellow(info.keywords.join(', '))) + if (bins.length) { + res.push(`\nbin: ${chalk.cyan(bins.join(', '))}`) } - if (info.bins.length) { - console.log('') - console.log('bin:', chalk.yellow(info.bins.join(', '))) + res.push('\ndist') + res.push(`.tarball: ${chalk.blue(manifest.dist.tarball)}`) + res.push(`.shasum: ${chalk.green(manifest.dist.shasum)}`) + if (manifest.dist.integrity) { + res.push(`.integrity: ${chalk.green(manifest.dist.integrity)}`) + } + if (manifest.dist.unpackedSize) { + res.push(`.unpackedSize: ${chalk.blue(formatBytes(manifest.dist.unpackedSize, true))}`) } - console.log('') - console.log('dist') - console.log('.tarball:', info.tarball) - console.log('.shasum:', info.shasum) - info.integrity && console.log('.integrity:', info.integrity) - info.unpackedSize && console.log('.unpackedSize:', info.unpackedSize) - - const maxDeps = 24 - if (info.deps.length) { - console.log('') - console.log('dependencies:') - console.log(columns(info.deps.slice(0, maxDeps), { padding: 1 })) - if (info.deps.length > maxDeps) { - console.log(`(...and ${info.deps.length - maxDeps} more.)`) + if (deps.length) { + const maxDeps = 24 + res.push('\ndependencies:') + res.push(columns(deps.slice(0, maxDeps), { padding: 1 })) + if (deps.length > maxDeps) { + res.push(chalk.dim(`(...and ${deps.length - maxDeps} more.)`)) } } - if (info.maintainers && info.maintainers.length) { - console.log('') - console.log('maintainers:') - info.maintainers.forEach((u) => console.log('-', u)) + if (packu.maintainers?.length) { + res.push('\nmaintainers:') + packu.maintainers.forEach(u => + res.push(`- ${unparsePerson({ + name: chalk.blue(u.name), + email: chalk.dim(u.email) })}`) + ) } - console.log('') - console.log('dist-tags:') - console.log(columns(info.tags)) + res.push('\ndist-tags:') + const maxTags = 12 + res.push(columns(distTags.slice(0, maxTags), { padding: 1, sort: false })) + if (distTags.length > maxTags) { + res.push(chalk.dim(`(...and ${distTags.length - maxTags} more.)`)) + } - 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?.[manifest.version]) { + publishInfo += ` ${chalk.cyan(relativeDate(packu.time[manifest.version]))}` } - if (info.publisher) { - publishInfo += ` by ${info.publisher}` + if (publisher) { + publishInfo += ` by ${publisher}` } - console.log('') - console.log(publishInfo) + res.push('') + res.push(publishInfo) } + + return res.join('\n') } } + module.exports = View -function cleanBlanks (obj) { - const clean = {} - Object.keys(obj).forEach((version) => { - clean[version] = obj[version][''] - }) - return clean +function parseArgs (args) { + if (!args.length) { + args = ['.'] + } + + const pkg = args.shift() + + return { + pkg, + local: /^\.@/.test(pkg) || pkg === '.', + rest: args, + } } -// takes an array of objects and merges them into one object -function reducer (acc, cur) { - if (cur) { - Object.keys(cur).forEach((v) => { - acc[v] = acc[v] || {} - Object.keys(cur[v]).forEach((t) => { - acc[v][t] = cur[v][t] +function cleanData (obj, wholePackument) { + // JSON formatted output (JSON or specific attributes from packument) + const data = obj.reduce((acc, cur) => { + if (cur) { + Object.entries(cur).forEach(([k, v]) => { + acc[k] ||= {} + Object.keys(v).forEach((t) => { + acc[k][t] = cur[k][t] + }) }) - }) + } + return acc + }, {}) + + if (wholePackument) { + const cleaned = Object.entries(data).reduce((acc, [k, v]) => { + acc[k] = v[Queryable.ALL] + return acc + }, {}) + log.silly('view', cleaned) + return cleaned } - return acc + return data } // return whatever was printed -function showFields (data, version, fields) { - const o = {} - ;[data, version].forEach((s) => { - Object.keys(s).forEach((k) => { - o[k] = s[k] +function showFields ({ data, version, fields, json }) { + const o = [data, version].reduce((acc, s) => { + Object.entries(s).forEach(([k, v]) => { + acc[k] = v }) - }) + return acc + }, {}) const queryable = new Queryable(o) - const s = queryable.query(fields) - const res = { [version.version]: s } - if (s) { - return res + if (!fields.length) { + return { [version.version]: queryable.query(Queryable.ALL) } } + + return fields.map((field) => { + const s = queryable.query(field, { unwrapSingleItemArrays: !json }) + if (s) { + return { [version.version]: s } + } + }) } function cleanup (data) { @@ -496,19 +450,43 @@ function cleanup (data) { } const keys = Object.keys(data) - if (keys.length <= 3 && - data.name && - (keys.length === 1 || - (keys.length === 3 && data.email && data.url) || - (keys.length === 2 && (data.email || data.url)))) { + + if (keys.length <= 3 && data.name && ( + (keys.length === 1) || + (keys.length === 3 && data.email && data.url) || + (keys.length === 2 && (data.email || data.url)) || + data.trustedPublisher + )) { data = unparsePerson(data) } return data } -function unparsePerson (d) { - return d.name + - (d.email ? ' <' + d.email + '>' : '') + - (d.url ? ' (' + d.url + ')' : '') +const unparsePerson = (d) => + `${d.name}${d.email ? ` <${d.email}>` : ''}${d.url ? ` (${d.url})` : ''}` + +function getCompletionFields (d, f = [], pref = []) { + Object.entries(d).forEach(([k, v]) => { + if (k.charAt(0) === '_' || k.indexOf('.') !== -1) { + return + } + const p = pref.concat(k).join('.') + f.push(p) + if (Array.isArray(v)) { + v.forEach((val, i) => { + const pi = p + '[' + i + ']' + if (val && typeof val === 'object') { + getCompletionFields(val, f, [p]) + } else { + f.push(pi) + } + }) + return + } + if (typeof v === 'object') { + getCompletionFields(v, f, [p]) + } + }) + return f } diff --git a/lib/commands/whoami.js b/lib/commands/whoami.js index 4497f9b3a542d..6b6e93ce7f885 100644 --- a/lib/commands/whoami.js +++ b/lib/commands/whoami.js @@ -1,17 +1,20 @@ +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'] - static ignoreImplicitWorkspace = true - async exec (args) { + async exec () { const username = await getIdentity(this.npm, { ...this.npm.flatOptions }) - this.npm.output( - this.npm.config.get('json') ? JSON.stringify(username) : username - ) + if (this.npm.config.get('json')) { + output.buffer(username) + } else { + output.standard(username) + } } } + module.exports = Whoami diff --git a/lib/lifecycle-cmd.js b/lib/lifecycle-cmd.js index 41633a4ba389c..eb3cc1c9beed7 100644 --- a/lib/lifecycle-cmd.js +++ b/lib/lifecycle-cmd.js @@ -1,17 +1,20 @@ +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 = ['[-- <args>]'] static isShellout = true + static workspaces = true + static ignoreImplicitWorkspace = false - async exec (args, cb) { - return this.npm.exec('run-script', [this.constructor.name, ...args]) + async exec (args) { + return this.npm.exec('run', [this.constructor.name, ...args]) } - async execWorkspaces (args, filters, cb) { - return this.npm.exec('run-script', [this.constructor.name, ...args]) + async execWorkspaces (args) { + return this.npm.exec('run', [this.constructor.name, ...args]) } } + module.exports = LifecycleCmd diff --git a/lib/npm.js b/lib/npm.js index 66111cab89a84..c635f3e05a7b3 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -1,194 +1,259 @@ -const EventEmitter = require('events') -const { resolve, dirname, join } = require('path') +const { resolve, dirname, join } = require('node:path') const Config = require('@npmcli/config') -const chalk = require('chalk') const which = require('which') -const fs = require('@npmcli/fs') - -// Patch the global fs module here at the app level -require('graceful-fs').gracefulify(require('fs')) - -const { definitions, flatten, shorthands } = require('./utils/config/index.js') +const fs = require('node:fs/promises') +const { definitions, flatten, nerfDarts, 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 replaceInfo = require('./utils/replace-info.js') -const updateNotifier = require('./utils/update-notifier.js') +const { log, time, output, META } = require('proc-log') +const { redactLog: replaceInfo } = require('@npmcli/redact') const pkg = require('../package.json') -const cmdList = require('./utils/cmd-list.js') - -let warnedNonDashArg = false -const _load = Symbol('_load') +const { deref } = require('./utils/cmd-list.js') +const { jsonError, outputError } = require('./utils/output-error.js') -class Npm extends EventEmitter { +class Npm { static get version () { return pkg.version } - command = null + static cmd (c) { + const command = deref(c) + 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 = [] - #loadPromise = null - #tmpFolder = null + #command = null + #runId = new Date().toISOString().replace(/[.:]/g, '_') #title = 'npm' #argvClean = [] - #chalk = null + #npmRoot = null + #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) - }, - }) - - config = new Config({ - npmPath: dirname(__dirname), - definitions, - flatten, - shorthands, - }) + #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 + // it is ok to add stuff here, but we should not rely on it more than + // necessary. XXX: make these options not necessary by refactoring @npmcli/config + // - npmRoot: this is where npm looks for docs files and the builtin config + // - argv: this allows tests to extend argv in the same way the argv would + // be passed in via a CLI arg. + // - excludeNpmCwd: this is a hack to get @npmcli/config to stop walking up + // dirs to set a local prefix when it encounters the `npmRoot`. this + // 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 ({ + 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, + definitions, + flatten, + nerfDarts, + shorthands, + argv: [...process.argv, ...argv], + excludeNpmCwd, + }) + } - get version () { - return this.constructor.version + async load () { + let err + try { + return await time.start('npm:load', () => this.#load()) + } catch (e) { + err = e + } + return this.#handleError(err) } - deref (c) { - if (!c) { - return + async #load () { + 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()) { + log.verbose('node symlink', node) + process.execPath = node + this.config.execPath = node + } + }) + + 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] } - if (c.match(/[A-Z]/)) { - c = c.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) + + // 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 don't create any caches/logfiles/timers etc + if (this.config.get('version', 'cli')) { + output.standard(this.version) + return { exec: false } } - if (cmdList.plumbing.indexOf(c) !== -1) { - return c + + // 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 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 time.start('npm:load:mkdirplogs', () => + fs.mkdir(this.#logsDir, { recursive: true }) + .catch((e) => log.verbose('logfile', `could not create logs-dir: ${e}`))) } - // first deref the abbrev, if there is one - // then resolve any aliases - // so `npm install-cl` will resolve to `install-clean` then to `ci` - let a = cmdList.abbrevs[c] - while (cmdList.aliases[a]) { - a = cmdList.aliases[a] + + // 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. + // 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 + // Secrets are mostly in configs, so title is set using only the positional args + // 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 + // safer the config should create a sanitized version of the argv as it + // has the full context of what each option contains. + this.#argvClean = replaceInfo(cooked) + log.verbose('title', this.title) + log.verbose('argv', this.#argvClean.map(JSON.stringify).join(' ')) + }) + + // 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({ + command, + 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'), + }) + + 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 a + + return { exec: true, command: commandArg, args: this.argv } } - // Get an instantiated npm command - // npm.command is already taken as the currently running command, a refactor - // would be needed to change this - async cmd (cmd) { - await this.load() - const command = this.deref(cmd) - if (!command) { - throw Object.assign(new Error(`Unknown command ${cmd}`), { - code: 'EUNKNOWNCOMMAND', - }) + async exec (cmd, args = this.argv) { + if (!this.#command) { + let err + try { + await this.#exec(cmd, args) + } catch (e) { + err = e + } + return this.#handleError(err) + } else { + return this.#exec(cmd, args) } - const Impl = require(`./commands/${command}.js`) - const impl = new Impl(this) - return impl } // Call an npm command - async exec (cmd, args) { - const command = await this.cmd(cmd) - const timeEnd = this.time(`command:${cmd}`) + async #exec (cmd, args) { + const Command = this.constructor.cmd(cmd) + const command = new Command(this) // since 'test', 'start', 'stop', etc. commands re-enter this function - // to call the run-script command, we need to only set it one time. - if (!this.command) { - process.env.npm_command = command.name - this.command = command.name - this.commandInstance = command + // to call the run command, we need to only set it one time. + if (!this.#command) { + this.#command = command + process.env.npm_command = this.command } - // 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 - 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 (!warnedNonDashArg) { - args - .filter(arg => /^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(arg)) - .forEach(arg => { - warnedNonDashArg = true - log.error( - 'arg', - 'Argument starts with non-ascii dash, this is probably invalid:', - arg - ) - }) + if (this.config.get('usage')) { + return output.standard(command.usage) } - const workspacesEnabled = this.config.get('workspaces') + let execWorkspaces = false + const hasWsConfig = this.config.get('workspaces') || this.config.get('workspace').length // if cwd is a workspace, the default is set to [that workspace] - const implicitWorkspace = this.config.get('workspace', 'default').length > 0 - const workspacesFilters = this.config.get('workspace') - const includeWorkspaceRoot = this.config.get('include-workspace-root') - // only call execWorkspaces when we have workspaces explicitly set - // or when it is implicit and not in our ignore list - const hasWorkspaceFilters = workspacesFilters.length > 0 - const invalidWorkspaceConfig = workspacesEnabled === false && hasWorkspaceFilters - + const implicitWs = this.config.get('workspace', 'default').length // (-ws || -w foo) && (cwd is not a workspace || command is not ignoring implicit workspaces) - const filterByWorkspaces = (workspacesEnabled || hasWorkspaceFilters) && - (!implicitWorkspace || !command.ignoreImplicitWorkspace) - // normally this would go in the constructor, but our tests don't - // actually use a real npm object so this.npm.config isn't always - // populated. this is the compromise until we can make that a reality - // and then move this into the constructor. - command.workspaces = workspacesEnabled - command.workspacePaths = null - // normally this would be evaluated in base-command#setWorkspaces, see - // above for explanation - command.includeWorkspaceRoot = includeWorkspaceRoot - - let execPromise = Promise.resolve() - if (this.config.get('usage')) { - this.output(command.usage) - } else if (invalidWorkspaceConfig) { - execPromise = Promise.reject( - new Error('Can not use --no-workspaces and --workspace at the same time')) - } else if (filterByWorkspaces) { + if (hasWsConfig && (!implicitWs || !Command.ignoreImplicitWorkspace)) { if (this.global) { - execPromise = Promise.reject(new Error('Workspaces not supported for global packages')) - } else { - execPromise = command.execWorkspaces(args, workspacesFilters) + throw new Error('Workspaces not supported for global packages') } - } else { - execPromise = command.exec(args) + if (!Command.workspaces) { + throw Object.assign(new Error('This command does not support workspaces.'), { + code: 'ENOWORKSPACES', + }) + } + execWorkspaces = true } - return execPromise.finally(timeEnd) - } - - async load () { - if (!this.#loadPromise) { - this.#loadPromise = this.time('npm:load', () => this[_load]().catch(er => er).then((er) => { - this.loadErr = er - if (!er) { - if (this.config.get('force')) { - log.warn('using --force', 'Recommended protections disabled.') - } - } else { - throw er - } - })) + if (command.checkDevEngines && !this.global) { + await command.checkDevEngines() } - return this.#loadPromise - } - get loaded () { - return this.config.loaded + return time.start(`command:${cmd}`, () => + execWorkspaces ? command.execWorkspaces(args) : command.exec(args)) } // This gets called at the end of the exit handler and @@ -200,116 +265,101 @@ class Npm extends EventEmitter { this.#logFile.off() } - time (name, fn) { - return this.#timers.time(name, fn) - } - - writeTimingFile () { - this.#timers.writeFile({ + finish (err) { + // Finish all our timer work, this will write the file if requested, end timers, etc + this.#timers.finish({ + id: this.#runId, command: this.#argvClean, - // We used to only ever report a single log file - // so to be backwards compatible report the last logfile - // XXX: remove this in npm 9 or just keep it forever - logfile: this.logFiles[this.logFiles.length - 1], logfiles: this.logFiles, version: this.version, }) - } - get title () { - return this.#title + output.flush({ + [META]: true, + // json can be set during a command so we send the + // final value of it to the display layer here + json: this.loaded && this.config.get('json'), + jsonError: jsonError(err, this), + }) } - set title (t) { - process.title = t - this.#title = t + exitErrorMessage () { + if (this.logFiles.length) { + return `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 + return `Log files were not written due to the config logs-max=${logsMax}` + } + + // could be an error writing to the directory + return `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' } - async [_load] () { - const node = this.time('npm:load:whichnode', () => { - try { - return which.sync(process.argv[0]) - } catch {} // TODO should we throw here? - }) + async #handleError (err) { + if (err) { + // Get the local package if it exists for a more helpful error message + const localPkg = await require('@npmcli/package-json') + .normalize(this.localPrefix) + .then(p => p.content) + .catch(() => null) + Object.assign(err, this.#getError(err, { pkg: localPkg })) + } + + this.finish(err) - if (node && node.toUpperCase() !== process.execPath.toUpperCase()) { - log.verbose('node symlink', node) - process.execPath = node - this.config.execPath = node + if (err) { + throw err } + } - await this.time('npm:load:configload', () => this.config.load()) + #getError (rawErr, opts) { + const { files = [], ...error } = require('./utils/error-message.js').getError(rawErr, { + npm: this, + command: this.#command, + ...opts, + }) - // 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', () => - fs.mkdir(this.cache, { recursive: true, owner: 'inherit' }) - .catch((e) => log.verbose('cache', `could not create cache: ${e}`))) + const { writeFileSync } = require('node:fs') + for (const [file, content] of files) { + const filePath = `${this.logPath}${file}` + const fileContent = `'Log files:\n${this.logFiles.join('\n')}\n\n${content.trim()}\n` + try { + writeFileSync(filePath, fileContent) + error.detail.push(['', `\n\nFor a full report see:\n${filePath}`]) + } catch (fileErr) { + log.warn('', `Could not write error message to ${file} due to ${fileErr}`) + } + } - // its ok if this fails. user might have specified an invalid dir - // which we will tell them about at the end - await this.time('npm:load:mkdirplogs', () => - fs.mkdir(this.logsDir, { recursive: true, owner: 'inherit' }) - .catch((e) => log.verbose('logfile', `could not create logs-dir: ${e}`))) + outputError(error) - // 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', () => { - 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() - // 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 - // safer the config should create a sanitized version of the argv as it - // has the full context of what each option contains. - this.#argvClean = replaceInfo(cooked) - log.verbose('title', this.title) - log.verbose('argv', this.#argvClean.map(JSON.stringify).join(' ')) - }) + return error + } - this.time('npm:load:display', () => { - this.#display.load({ - // Use logColor since that is based on stderr - color: this.logColor, - 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' - }) + get title () { + return this.#title + } - this.time('npm:load:logFile', () => { - this.#logFile.load({ - dir: this.logsDir, - logsMax: this.config.get('logs-max'), - }) - log.verbose('logfile', this.#logFile.files[0] || 'no logfile created') - }) + get loaded () { + return this.config.loaded + } - this.time('npm:load:timers', () => - this.#timers.load({ - dir: this.config.get('timing') ? this.timingDir : null, - }) - ) + get version () { + return this.constructor.version + } - this.time('npm:load:configScope', () => { - const configScope = this.config.get('scope') - if (configScope && !/^@/.test(configScope)) { - this.config.set('scope', `@${configScope}`, this.config.find('scope')) - } - }) + get command () { + return this.#command?.name } get flatOptions () { const { flat } = this.config + flat.nodeVersion = process.version + flat.npmVersion = pkg.version if (this.command) { flat.npmCommand = this.command } @@ -323,23 +373,24 @@ class Npm extends EventEmitter { return this.flatOptions.color } + get logColor () { + return this.flatOptions.logColor + } + + get noColorChalk () { + return this.#display.chalk.noColor + } + get chalk () { - if (!this.#chalk) { - let level = chalk.level - if (!this.color) { - level = 0 - } - this.#chalk = new chalk.Instance({ level }) - } - return this.#chalk + return this.#display.chalk.stdout } - get global () { - return this.config.get('global') || this.config.get('location') === 'global' + get logChalk () { + return this.#display.chalk.stderr } - get logColor () { - return this.flatOptions.logColor + get global () { + return this.config.get('global') || this.config.get('location') === 'global' } get silent () { @@ -350,14 +401,6 @@ class Npm extends EventEmitter { return 2 } - get unfinishedTimers () { - return this.#timers.unfinished - } - - get finishedTimers () { - return this.#timers.finished - } - get started () { return this.#timers.started } @@ -366,41 +409,32 @@ class Npm extends EventEmitter { return this.#logFile.files } - get logsDir () { + get #logsDir () { return this.config.get('logs-dir') || join(this.cache, '_logs') } - get timingFile () { - return this.#timers.file + get logPath () { + return resolve(this.#logsDir, `${this.#runId}-`) } - get timingDir () { - // XXX(npm9): make this always in logs-dir - return this.config.get('logs-dir') || this.cache + get npmRoot () { + return this.#npmRoot } get cache () { 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 } get globalDir () { @@ -434,37 +468,9 @@ class Npm extends EventEmitter { return this.global ? this.globalPrefix : this.localPrefix } - set prefix (r) { - const k = this.global ? 'globalPrefix' : 'localPrefix' - this[k] = r - } - get usage () { return usage(this) } - - // XXX add logging to see if we actually use this - get tmp () { - if (!this.#tmpFolder) { - const rand = require('crypto').randomBytes(4).toString('hex') - this.#tmpFolder = `npm-${process.pid}-${rand}` - } - return resolve(this.config.get('tmp'), this.#tmpFolder) - } - - // output to stdout in a progress bar compatible way - output (...msg) { - log.clearProgress() - // eslint-disable-next-line no-console - console.log(...msg) - log.showProgress() - } - - outputError (...msg) { - log.clearProgress() - // eslint-disable-next-line no-console - console.error(...msg) - log.showProgress() - } } + module.exports = Npm diff --git a/lib/package-url-cmd.js b/lib/package-url-cmd.js index 4254dde4517ba..26c61b521ae60 100644 --- a/lib/package-url-cmd.js +++ b/lib/package-url-cmd.js @@ -1,14 +1,10 @@ -// 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('proc-log') +const BaseCommand = require('./base-cmd.js') -const openUrl = require('./utils/open-url.js') -const log = require('./utils/log-shim') - -const BaseCommand = require('./base-command.js') +// Base command for opening urls from a package manifest (bugs, docs, repo) class PackageUrlCommand extends BaseCommand { - static ignoreImplicitWorkspace = false static params = [ 'browser', 'registry', @@ -17,6 +13,8 @@ class PackageUrlCommand extends BaseCommand { 'include-workspace-root', ] + static workspaces = true + static ignoreImplicitWorkspace = false static usage = ['[<pkgname> [<pkgname> ...]]'] async exec (args) { @@ -25,12 +23,12 @@ class PackageUrlCommand extends BaseCommand { } for (const arg of args) { - // XXX It is very odd that `where` is how pacote knows to look anywhere - // other than the cwd. + // XXX It is very odd that `where` is how pacote knows to look anywhere other than the cwd. const opts = { ...this.npm.flatOptions, where: this.npm.localPrefix, fullMetadata: true, + _isRoot: true, } const mani = await pacote.manifest(arg, opts) const url = this.getUrl(arg, mani) @@ -39,11 +37,11 @@ class PackageUrlCommand extends BaseCommand { } } - async execWorkspaces (args, filters) { + async execWorkspaces (args) { if (args && args.length) { return this.exec(args) } - await this.setWorkspaces(filters) + await this.setWorkspaces() return this.exec(this.workspacePaths) } @@ -51,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 @@ -61,4 +60,5 @@ class PackageUrlCommand extends BaseCommand { return (rurl && hostedGitInfo.fromUrl(rurl.replace(/^git\+/, ''))) || null } } + module.exports = PackageUrlCommand diff --git a/lib/utils/ansi-trim.js b/lib/utils/ansi-trim.js deleted file mode 100644 index e35a1baf63335..0000000000000 --- a/lib/utils/ansi-trim.js +++ /dev/null @@ -1,3 +0,0 @@ -const r = new RegExp('\x1b(?:\\[(?:\\d+[ABCDEFGJKSTm]|\\d+;\\d+[Hfm]|' + - '\\d+;\\d+;\\d+m|6n|s|u|\\?25[lh])|\\w)', 'g') -module.exports = str => str.replace(r, '') diff --git a/lib/utils/audit-error.js b/lib/utils/audit-error.js index 7feccc739b6a9..c56ec9ba86f18 100644 --- a/lib/utils/audit-error.js +++ b/lib/utils/audit-error.js @@ -1,4 +1,5 @@ -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 // this is called by the audit command, and by the reify-output util @@ -21,16 +22,16 @@ 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.buffer({ message: error.message, method: error.method, - uri: error.uri, + uri: replaceInfo(error.uri), headers: error.headers, statusCode: error.statusCode, body, - }, null, 2)) + }) } else { - npm.output(body) + output.standard(body) } throw 'audit endpoint returned an error' diff --git a/lib/utils/auth.js b/lib/utils/auth.js new file mode 100644 index 0000000000000..a617ab9430b2a --- /dev/null +++ b/lib/utils/auth.js @@ -0,0 +1,109 @@ +const { webAuthOpener, adduserWeb, loginWeb, loginCouch, adduserCouch } = require('npm-profile') +const { log } = require('proc-log') +const { createOpener } = require('../utils/open-url.js') +const read = require('../utils/read-user-info.js') + +const otplease = async (npm, opts, fn) => { + try { + return await fn(opts) + } catch (err) { + if (!process.stdin.isTTY || !process.stdout.isTTY) { + throw err + } + + // web otp + if (err.code === 'EOTP' && err.body?.authUrl && err.body?.doneUrl) { + const { token: otp } = await webAuthOpener( + createOpener(npm, 'Authenticate your account at'), + err.body.authUrl, + err.body.doneUrl, + opts + ) + return await fn({ ...opts, otp }) + } + + // classic otp + if (err.code === 'EOTP' || (err.code === 'E401' && /one-time pass/.test(err.body))) { + const otp = await read.otp('This operation requires a one-time password.\nEnter OTP:') + return await fn({ ...opts, otp }) + } + + throw err + } +} + +const adduser = async (npm, { creds, ...opts }) => { + const authType = npm.config.get('auth-type') + let res + if (authType === 'web') { + try { + res = await adduserWeb(createOpener(npm, 'Create your account at'), opts) + } catch (err) { + if (err.code === 'ENYI') { + log.verbose('web add user not supported, trying couch') + } else { + throw err + } + } + } + + // auth type !== web or ENYI error w/ web adduser + if (!res) { + const username = await read.username('Username:', creds.username) + const password = await read.password('Password:', creds.password) + const email = await read.email('Email (this will be public):', creds.email) + // npm registry quirk: If you "add" an existing user with their current + // password, it's effectively a login, and if that account has otp you'll + // be prompted for it. + res = await otplease(npm, opts, (reqOpts) => adduserCouch(username, email, password, reqOpts)) + } + + // We don't know the username if it was a web login, all we can reliably log is scope and registry + const message = `Logged in${opts.scope ? ` to scope ${opts.scope}` : ''} on ${opts.registry}.` + + log.info('adduser', message) + + return { + message, + newCreds: { token: res.token }, + } +} + +const login = async (npm, { creds, ...opts }) => { + const authType = npm.config.get('auth-type') + let res + if (authType === 'web') { + try { + res = await loginWeb(createOpener(npm, 'Login at'), opts) + } catch (err) { + if (err.code === 'ENYI') { + log.verbose('web login not supported, trying couch') + } else { + throw err + } + } + } + + // auth type !== web or ENYI error w/ web login + if (!res) { + const username = await read.username('Username:', creds.username) + const password = await read.password('Password:', creds.password) + res = await otplease(npm, opts, (reqOpts) => loginCouch(username, password, reqOpts)) + } + + // We don't know the username if it was a web login, all we can reliably log is scope and registry + const message = `Logged in${opts.scope ? ` to scope ${opts.scope}` : ''} on ${opts.registry}.` + + log.info('login', message) + + return { + message, + newCreds: { token: res.token }, + } +} + +module.exports = { + adduser, + login, + otplease, +} diff --git a/lib/utils/cmd-list.js b/lib/utils/cmd-list.js index 38439542a21f9..61f64f77678e2 100644 --- a/lib/utils/cmd-list.js +++ b/lib/utils/cmd-list.js @@ -1,80 +1,11 @@ const abbrev = require('abbrev') -// plumbing should not have any aliases -const aliases = { - - // aliases - login: 'adduser', - author: 'owner', - home: 'docs', - issues: 'bugs', - info: 'view', - show: 'view', - find: 'search', - add: 'install', - unlink: 'uninstall', - remove: 'uninstall', - rm: 'uninstall', - r: 'uninstall', - - // short names for common things - un: 'uninstall', - rb: 'rebuild', - list: 'ls', - ln: 'link', - create: 'init', - i: 'install', - it: 'install-test', - cit: 'install-ci-test', - up: 'update', - c: 'config', - s: 'search', - se: 'search', - tst: 'test', - t: 'test', - ddp: 'dedupe', - v: 'view', - run: 'run-script', - 'clean-install': 'ci', - 'clean-install-test': 'cit', - x: 'exec', - why: 'explain', - la: 'll', - verison: 'version', - ic: 'ci', - - // typos - innit: 'init', - // manually abbrev so that install-test doesn't make insta stop working - in: 'install', - ins: 'install', - inst: 'install', - insta: 'install', - instal: 'install', - isnt: 'install', - isnta: 'install', - isntal: 'install', - isntall: 'install', - 'install-clean': 'ci', - 'isntall-clean': 'ci', - hlep: 'help', - 'dist-tags': 'dist-tag', - upgrade: 'update', - udpate: 'update', - rum: 'run-script', - sit: 'cit', - urn: 'run-script', - ogr: 'org', - 'add-user': 'adduser', -} - -// these are filenames in . -// Keep these sorted so that lib/utils/npm-usage.js outputs in order -const cmdList = [ +// These correspond to filenames in lib/commands +// Please keep this list sorted alphabetically +const commands = [ 'access', 'adduser', 'audit', - 'bin', 'bugs', 'cache', 'ci', @@ -94,14 +25,14 @@ const cmdList = [ 'fund', 'get', 'help', - 'hook', + 'help-search', 'init', 'install', 'install-ci-test', 'install-test', 'link', 'll', - 'login', // This is an alias for `adduser` but it can be confusing + 'login', 'logout', 'ls', 'org', @@ -119,10 +50,10 @@ const cmdList = [ 'repo', 'restart', 'root', - 'run-script', + 'run', + 'sbom', 'search', 'set', - 'set-script', 'shrinkwrap', 'star', 'stars', @@ -131,6 +62,7 @@ const cmdList = [ 'team', 'test', 'token', + 'undeprecate', 'uninstall', 'unpublish', 'unstar', @@ -140,12 +72,107 @@ const cmdList = [ 'whoami', ] -const plumbing = ['birthday', 'help-search'] -const abbrevs = abbrev(cmdList.concat(Object.keys(aliases))) +// These must resolve to an entry in commands +const aliases = { + + // aliases + author: 'owner', + home: 'docs', + issues: 'bugs', + info: 'view', + show: 'view', + find: 'search', + add: 'install', + unlink: 'uninstall', + remove: 'uninstall', + rm: 'uninstall', + r: 'uninstall', + + // short names for common things + un: 'uninstall', + rb: 'rebuild', + list: 'ls', + ln: 'link', + create: 'init', + i: 'install', + it: 'install-test', + cit: 'install-ci-test', + up: 'update', + c: 'config', + s: 'search', + se: 'search', + tst: 'test', + t: 'test', + ddp: 'dedupe', + v: 'view', + 'run-script': 'run', + 'clean-install': 'ci', + 'clean-install-test': 'install-ci-test', + x: 'exec', + why: 'explain', + la: 'll', + verison: 'version', + ic: 'ci', + + // typos + innit: 'init', + // manually abbrev so that install-test doesn't make insta stop working + in: 'install', + ins: 'install', + inst: 'install', + insta: 'install', + instal: 'install', + isnt: 'install', + isnta: 'install', + isntal: 'install', + isntall: 'install', + 'install-clean': 'ci', + 'isntall-clean': 'ci', + hlep: 'help', + 'dist-tags': 'dist-tag', + upgrade: 'update', + udpate: 'update', + rum: 'run', + sit: 'install-ci-test', + urn: 'run', + ogr: 'org', + 'add-user': 'adduser', +} + +const deref = (c) => { + if (!c) { + return + } + + // Translate camelCase to snake-case (i.e. installTest to install-test) + if (c.match(/[A-Z]/)) { + c = c.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) + } + + // if they asked for something exactly we are done + if (commands.includes(c)) { + return c + } + + // if they asked for a direct alias + if (aliases[c]) { + return aliases[c] + } + + const abbrevs = abbrev(commands.concat(Object.keys(aliases))) + + // first deref the abbrev, if there is one + // then resolve any aliases + // so `npm install-cl` will resolve to `install-clean` then to `ci` + let a = abbrevs[c] + while (aliases[a]) { + a = aliases[a] + } + return a +} module.exports = { - abbrevs, aliases, - cmdList, - plumbing, + commands, + deref, } diff --git a/lib/utils/completion.fish b/lib/utils/completion.fish new file mode 100644 index 0000000000000..5e274ad77e5fd --- /dev/null +++ b/lib/utils/completion.fish @@ -0,0 +1,40 @@ +# npm completions for Fish shell +# This script is a work in progress and does not fall under the normal semver contract as the rest of npm. + +# __fish_npm_needs_command taken from: +# https://stackoverflow.com/questions/16657803/creating-autocomplete-script-with-sub-commands +function __fish_npm_needs_command + set -l cmd (commandline -opc) + + if test (count $cmd) -eq 1 + return 0 + end + + return 1 +end + +# Taken from https://github.com/fish-shell/fish-shell/blob/HEAD/share/completions/npm.fish +function __fish_complete_npm -d "Complete the commandline using npm's 'completion' tool" + # tell npm we are fish shell + set -lx COMP_FISH true + if command -sq npm + # npm completion is bash-centric, so we need to translate fish's "commandline" stuff to bash's $COMP_* stuff + # COMP_LINE is an array with the words in the commandline + set -lx COMP_LINE (commandline -opc) + # COMP_CWORD is the index of the current word in COMP_LINE + # bash starts arrays with 0, so subtract 1 + set -lx COMP_CWORD (math (count $COMP_LINE) - 1) + # COMP_POINT is the index of point/cursor when the commandline is viewed as a string + set -lx COMP_POINT (commandline -C) + # If the cursor is after the last word, the empty token will disappear in the expansion + # Readd it + if test (commandline -ct) = "" + set COMP_CWORD (math $COMP_CWORD + 1) + set COMP_LINE $COMP_LINE "" + end + command npm completion -- $COMP_LINE 2>/dev/null + end +end + +# flush out what ships with fish +complete -e npm diff --git a/lib/utils/completion/installed-deep.js b/lib/utils/completion/installed-deep.js deleted file mode 100644 index 7098d81fe7b49..0000000000000 --- a/lib/utils/completion/installed-deep.js +++ /dev/null @@ -1,45 +0,0 @@ -const { resolve } = require('path') -const Arborist = require('@npmcli/arborist') -const localeCompare = require('@isaacs/string-locale-compare')('en') - -const installedDeep = async (npm) => { - const { - depth, - global, - prefix, - workspacesEnabled, - } = npm.flatOptions - - const getValues = (tree) => - [...tree.inventory.values()] - .filter(i => i.location !== '' && !i.isRoot) - .map(i => { - return i - }) - .filter(i => (i.depth - 1) <= depth) - .sort((a, b) => (a.depth - b.depth) || localeCompare(a.name, b.name)) - - const res = new Set() - const gArb = new Arborist({ - global: true, - path: resolve(npm.globalDir, '..'), - workspacesEnabled, - }) - const gTree = await gArb.loadActual({ global: true }) - - for (const node of getValues(gTree)) { - res.add(global ? node.name : [node.name, '-g']) - } - - if (!global) { - const arb = new Arborist({ global: false, path: prefix, workspacesEnabled }) - const tree = await arb.loadActual() - for (const node of getValues(tree)) { - res.add(node.name) - } - } - - return [...res] -} - -module.exports = installedDeep diff --git a/lib/utils/completion/installed-shallow.js b/lib/utils/completion/installed-shallow.js deleted file mode 100644 index 686c95e63245e..0000000000000 --- a/lib/utils/completion/installed-shallow.js +++ /dev/null @@ -1,17 +0,0 @@ -const { promisify } = require('util') -const readdir = promisify(require('readdir-scoped-modules')) - -const installedShallow = async (npm, opts) => { - const names = global => readdir(global ? npm.globalDir : npm.localDir) - const { conf: { argv: { remain } } } = opts - if (remain.length > 3) { - return null - } - - const { global } = npm.flatOptions - const locals = global ? [] : await names(false) - const globals = (await names(true)).map(n => global ? n : `${n} -g`) - return [...locals, ...globals] -} - -module.exports = installedShallow diff --git a/lib/utils/config/definition.js b/lib/utils/config/definition.js deleted file mode 100644 index f88d8334cf01f..0000000000000 --- a/lib/utils/config/definition.js +++ /dev/null @@ -1,251 +0,0 @@ -// class that describes a config key we know about -// this keeps us from defining a config key and not -// providing a default, description, etc. -// -// TODO: some kind of categorization system, so we can -// say "these are for registry access", "these are for -// version resolution" etc. - -const required = ['type', 'description', 'default', 'key'] - -const allowed = [ - 'default', - 'defaultDescription', - 'deprecated', - 'description', - 'flatten', - 'hint', - 'key', - 'short', - 'type', - 'typeDescription', - 'usage', - 'envExport', -] - -const { - typeDefs: { - semver: { type: semver }, - Umask: { type: Umask }, - url: { type: url }, - path: { type: path }, - }, -} = require('@npmcli/config') - -class Definition { - constructor (key, def) { - this.key = key - // if it's set falsey, don't export it, otherwise we do by default - this.envExport = true - Object.assign(this, def) - this.validate() - if (!this.defaultDescription) { - this.defaultDescription = describeValue(this.default) - } - if (!this.typeDescription) { - this.typeDescription = describeType(this.type) - } - // hint is only used for non-boolean values - if (!this.hint) { - if (this.type === Number) { - this.hint = '<number>' - } else { - this.hint = `<${this.key}>` - } - } - if (!this.usage) { - this.usage = describeUsage(this) - } - } - - validate () { - for (const req of required) { - if (!Object.prototype.hasOwnProperty.call(this, req)) { - throw new Error(`config lacks ${req}: ${this.key}`) - } - } - if (!this.key) { - throw new Error(`config lacks key: ${this.key}`) - } - for (const field of Object.keys(this)) { - if (!allowed.includes(field)) { - throw new Error(`config defines unknown field ${field}: ${this.key}`) - } - } - } - - // a textual description of this config, suitable for help output - describe () { - const description = unindent(this.description) - const noEnvExport = this.envExport - ? '' - : ` -This value is not exported to the environment for child processes. -` - const deprecated = !this.deprecated ? '' : `* DEPRECATED: ${unindent(this.deprecated)}\n` - return wrapAll(`#### \`${this.key}\` - -* Default: ${unindent(this.defaultDescription)} -* Type: ${unindent(this.typeDescription)} -${deprecated} -${description} -${noEnvExport}`) - } -} - -const describeUsage = def => { - let key = '' - - // Single type - if (!Array.isArray(def.type)) { - if (def.short) { - key = `-${def.short}|` - } - - if (def.type === Boolean && def.default !== false) { - key = `${key}--no-${def.key}` - } else { - key = `${key}--${def.key}` - } - - if (def.type !== Boolean) { - key = `${key} ${def.hint}` - } - - return key - } - - key = `--${def.key}` - if (def.short) { - key = `-${def.short}|--${def.key}` - } - - // Multiple types - let types = def.type - const multiple = types.includes(Array) - const bool = types.includes(Boolean) - - // null type means optional and doesn't currently affect usage output since - // all non-optional params have defaults so we render everything as optional - types = types.filter(t => t !== null && t !== Array && t !== Boolean) - - if (!types.length) { - return key - } - - let description - if (!types.some(t => typeof t !== 'string')) { - // Specific values, use specifics given - description = `<${types.filter(d => d).join('|')}>` - } else { - // Generic values, use hint - description = def.hint - } - - if (bool) { - // Currently none of our multi-type configs with boolean values default to - // false so all their hints should show `--no-`, if we ever add ones that - // default to false we can branch the logic here - key = `--no-${def.key}|${key}` - } - - const usage = `${key} ${description}` - if (multiple) { - return `${usage} [${usage} ...]` - } else { - return usage - } -} - -const describeType = type => { - if (Array.isArray(type)) { - const descriptions = type.filter(t => t !== Array).map(t => describeType(t)) - - // [a] => "a" - // [a, b] => "a or b" - // [a, b, c] => "a, b, or c" - // [a, Array] => "a (can be set multiple times)" - // [a, Array, b] => "a or b (can be set multiple times)" - const last = descriptions.length > 1 ? [descriptions.pop()] : [] - const oxford = descriptions.length > 1 ? ', or ' : ' or ' - const words = [descriptions.join(', ')].concat(last).join(oxford) - const multiple = type.includes(Array) ? ' (can be set multiple times)' : '' - return `${words}${multiple}` - } - - // Note: these are not quite the same as the description printed - // when validation fails. In that case, we want to give the user - // a bit more information to help them figure out what's wrong. - switch (type) { - case String: - return 'String' - case Number: - return 'Number' - case Umask: - return 'Octal numeric string in range 0000..0777 (0..511)' - case Boolean: - return 'Boolean' - case Date: - return 'Date' - case path: - return 'Path' - case semver: - return 'SemVer string' - case url: - return 'URL' - default: - return describeValue(type) - } -} - -// if it's a string, quote it. otherwise, just cast to string. -const describeValue = val => (typeof val === 'string' ? JSON.stringify(val) : String(val)) - -const unindent = s => { - // get the first \n followed by a bunch of spaces, and pluck off - // that many spaces from the start of every line. - const match = s.match(/\n +/) - return !match ? s.trim() : s.split(match[0]).join('\n').trim() -} - -const wrap = s => { - const cols = Math.min(Math.max(20, process.stdout.columns) || 80, 80) - 5 - return unindent(s) - .split(/[ \n]+/) - .reduce((left, right) => { - const last = left.split('\n').pop() - const join = last.length && last.length + right.length > cols ? '\n' : ' ' - return left + join + right - }) -} - -const wrapAll = s => { - let inCodeBlock = false - return s - .split('\n\n') - .map(block => { - if (inCodeBlock || block.startsWith('```')) { - inCodeBlock = !block.endsWith('```') - return block - } - - if (block.charAt(0) === '*') { - return ( - '* ' + - block - .slice(1) - .trim() - .split('\n* ') - .map(li => { - return wrap(li).replace(/\n/g, '\n ') - }) - .join('\n* ') - ) - } else { - return wrap(block) - } - }) - .join('\n\n') -} - -module.exports = Definition diff --git a/lib/utils/config/definitions.js b/lib/utils/config/definitions.js deleted file mode 100644 index a132c8456b0fa..0000000000000 --- a/lib/utils/config/definitions.js +++ /dev/null @@ -1,2369 +0,0 @@ -const definitions = {} -module.exports = definitions - -const Definition = require('./definition.js') - -const log = require('../log-shim') -const { version: npmVersion } = require('../../../package.json') -const ciDetect = require('@npmcli/ci-detect') -const ciName = ciDetect() -const querystring = require('querystring') -const { isWindows } = require('../is-windows.js') -const { join } = require('path') - -// used by cafile flattening to flatOptions.ca -const fs = require('fs') -const maybeReadFile = file => { - try { - return fs.readFileSync(file, 'utf8') - } catch (er) { - if (er.code !== 'ENOENT') { - throw er - } - return null - } -} - -const buildOmitList = obj => { - const include = obj.include || [] - const omit = obj.omit || [] - - const only = obj.only - if (/^prod(uction)?$/.test(only) || obj.production) { - omit.push('dev') - } else if (obj.production === false) { - include.push('dev') - } - - if (/^dev/.test(obj.also)) { - include.push('dev') - } - - if (obj.dev) { - include.push('dev') - } - - if (obj.optional === false) { - omit.push('optional') - } else if (obj.optional === true) { - include.push('optional') - } - - obj.omit = [...new Set(omit)].filter(type => !include.includes(type)) - obj.include = [...new Set(include)] - - if (obj.omit.includes('dev')) { - process.env.NODE_ENV = 'production' - } - - return obj.omit -} - -const editor = process.env.EDITOR || - process.env.VISUAL || - (isWindows ? 'notepad.exe' : 'vi') - -const shell = isWindows ? process.env.ComSpec || 'cmd' - : process.env.SHELL || 'sh' - -const { tmpdir, networkInterfaces } = require('os') -const getLocalAddresses = () => { - try { - return Object.values(networkInterfaces()).map( - int => int.map(({ address }) => address) - ).reduce((set, addrs) => set.concat(addrs), [null]) - } catch (e) { - return [null] - } -} - -const unicode = /UTF-?8$/i.test( - process.env.LC_ALL || - process.env.LC_CTYPE || - process.env.LANG -) - -// use LOCALAPPDATA on Windows, if set -// https://github.com/npm/cli/pull/899 -const cacheRoot = (isWindows && process.env.LOCALAPPDATA) || '~' -const cacheExtra = isWindows ? 'npm-cache' : '.npm' -const cache = `${cacheRoot}/${cacheExtra}` - -const Config = require('@npmcli/config') - -// TODO: refactor these type definitions so that they are less -// weird to pull out of the config module. -// TODO: use better type definition/validation API, nopt's is so weird. -const { - typeDefs: { - semver: { type: semver }, - Umask: { type: Umask }, - url: { type: url }, - path: { type: path }, - }, -} = Config - -const define = (key, def) => { - /* istanbul ignore if - this should never happen, prevents mistakes below */ - if (definitions[key]) { - throw new Error(`defining key more than once: ${key}`) - } - definitions[key] = new Definition(key, def) -} - -// basic flattening function, just copy it over camelCase -const flatten = (key, obj, flatOptions) => { - const camel = key.replace(/-([a-z])/g, (_0, _1) => _1.toUpperCase()) - flatOptions[camel] = obj[key] -} - -// TODO: -// Instead of having each definition provide a flatten method, -// provide the (?list of?) flat option field(s?) that it impacts. -// When that config is set, we mark the relevant flatOption fields -// dirty. Then, a getter for that field defines how we actually -// set it. -// -// So, `save-dev`, `save-optional`, `save-prod`, et al would indicate -// that they affect the `saveType` flat option. Then the config.flat -// object has a `get saveType () { ... }` that looks at the "real" -// config settings from files etc and returns the appropriate value. -// -// Getters will also (maybe?) give us a hook to audit flat option -// usage, so we can document and group these more appropriately. -// -// This will be a problem with cases where we currently do: -// const opts = { ...npm.flatOptions, foo: 'bar' }, but we can maybe -// instead do `npm.config.set('foo', 'bar')` prior to passing the -// config object down where it needs to go. -// -// This way, when we go hunting for "where does saveType come from anyway!?" -// while fixing some Arborist bug, we won't have to hunt through too -// many places. - -// Define all config keys we know about - -define('_auth', { - default: null, - type: [null, String], - description: ` - A basic-auth string to use when authenticating against the npm registry. - This will ONLY be used to authenticate against the npm registry. For other - registries you will need to scope it like "//other-registry.tld/:_auth" - - Warning: This should generally not be set via a command-line option. It - is safer to use a registry-provided authentication bearer token stored in - the ~/.npmrc file by running \`npm login\`. - `, - flatten, -}) - -define('access', { - default: null, - defaultDescription: ` - 'restricted' for scoped packages, 'public' for unscoped packages - `, - type: [null, 'restricted', 'public'], - description: ` - When publishing scoped packages, the access level defaults to - \`restricted\`. If you want your scoped package to be publicly viewable - (and installable) set \`--access=public\`. The only valid values for - \`access\` are \`public\` and \`restricted\`. Unscoped packages _always_ - have an access level of \`public\`. - - Note: Using the \`--access\` flag on the \`npm publish\` command will only - set the package access level on the initial publish of the package. Any - subsequent \`npm publish\` commands using the \`--access\` flag will not - have an effect to the access level. To make changes to the access level - after the initial publish use \`npm access\`. - `, - flatten, -}) - -define('all', { - default: false, - type: Boolean, - short: 'a', - description: ` - When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show - all outdated or installed packages, rather than only those directly - depended upon by the current project. - `, - flatten, -}) - -define('allow-same-version', { - default: false, - type: Boolean, - description: ` - Prevents throwing an error when \`npm version\` is used to set the new - version to the same value as the current version. - `, - flatten, -}) - -define('also', { - default: null, - type: [null, 'dev', 'development'], - description: ` - When set to \`dev\` or \`development\`, this is an alias for - \`--include=dev\`. - `, - deprecated: 'Please use --include=dev instead.', - flatten (key, obj, flatOptions) { - definitions.omit.flatten('omit', obj, flatOptions) - }, -}) - -define('audit', { - default: true, - type: Boolean, - description: ` - When "true" submit audit reports alongside the current npm command to the - default registry and all registries configured for scopes. See the - documentation for [\`npm audit\`](/commands/npm-audit) for details on what - is submitted. - `, - flatten, -}) - -define('audit-level', { - default: null, - type: [null, 'info', 'low', 'moderate', 'high', 'critical', 'none'], - description: ` - The minimum level of vulnerability for \`npm audit\` to exit with - a non-zero exit code. - `, - flatten, -}) - -define('auth-type', { - default: 'legacy', - type: ['legacy', 'web', 'sso', 'saml', 'oauth', 'webauthn'], - // deprecation in description rather than field, because not every value - // is deprecated - description: ` - NOTE: auth-type values "sso", "saml", "oauth", and "webauthn" will be - removed in a future version. - - What authentication strategy to use with \`login\`. - `, - flatten (key, obj, flatOptions) { - flatOptions.authType = obj[key] - if (obj[key] === 'sso') { - // no need to deprecate saml/oauth here, as sso-type will be set by these in - // lib/auth/ and is deprecated already - log.warn('config', - '--auth-type=sso is will be removed in a future version.') - } - }, -}) - -define('before', { - default: null, - type: [null, Date], - description: ` - If passed to \`npm install\`, will rebuild the npm tree such that only - versions that were available **on or before** the \`--before\` time get - installed. If there's no versions available for the current set of - direct dependencies, the command will error. - - If the requested version is a \`dist-tag\` and the given tag does not - pass the \`--before\` filter, the most recent version less than or equal - to that tag will be used. For example, \`foo@latest\` might install - \`foo@1.2\` even though \`latest\` is \`2.0\`. - `, - flatten, -}) - -define('bin-links', { - default: true, - type: Boolean, - description: ` - Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package - executables. - - Set to false to have it not do this. This can be used to work around the - fact that some file systems don't support symlinks, even on ostensibly - Unix systems. - `, - flatten, -}) - -define('browser', { - default: null, - defaultDescription: ` - OS X: \`"open"\`, Windows: \`"start"\`, Others: \`"xdg-open"\` - `, - type: [null, Boolean, String], - description: ` - The browser that is called by npm commands to open websites. - - Set to \`false\` to suppress browser behavior and instead print urls to - terminal. - - Set to \`true\` to use default system URL opener. - `, - flatten, -}) - -define('ca', { - default: null, - type: [null, String, Array], - description: ` - The Certificate Authority signing certificate that is trusted for SSL - connections to the registry. Values should be in PEM format (Windows - calls it "Base-64 encoded X.509 (.CER)") with newlines replaced by the - string "\\n". For example: - - \`\`\`ini - ca="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----" - \`\`\` - - Set to \`null\` to only allow "known" registrars, or to a specific CA - cert to trust only that specific signing authority. - - Multiple CAs can be trusted by specifying an array of certificates: - - \`\`\`ini - ca[]="..." - ca[]="..." - \`\`\` - - See also the \`strict-ssl\` config. - `, - flatten, -}) - -define('cache', { - default: cache, - defaultDescription: ` - Windows: \`%LocalAppData%\\npm-cache\`, Posix: \`~/.npm\` - `, - type: path, - description: ` - The location of npm's cache directory. See [\`npm - cache\`](/commands/npm-cache) - `, - flatten (key, obj, flatOptions) { - flatOptions.cache = join(obj.cache, '_cacache') - flatOptions.npxCache = join(obj.cache, '_npx') - }, -}) - -define('cache-max', { - default: Infinity, - type: Number, - description: ` - \`--cache-max=0\` is an alias for \`--prefer-online\` - `, - deprecated: ` - This option has been deprecated in favor of \`--prefer-online\` - `, - flatten (key, obj, flatOptions) { - if (obj[key] <= 0) { - flatOptions.preferOnline = true - } - }, -}) - -define('cache-min', { - default: 0, - type: Number, - description: ` - \`--cache-min=9999 (or bigger)\` is an alias for \`--prefer-offline\`. - `, - deprecated: ` - This option has been deprecated in favor of \`--prefer-offline\`. - `, - flatten (key, obj, flatOptions) { - if (obj[key] >= 9999) { - flatOptions.preferOffline = true - } - }, -}) - -define('cafile', { - default: null, - type: path, - description: ` - A path to a file containing one or multiple Certificate Authority signing - certificates. Similar to the \`ca\` setting, but allows for multiple - CA's, as well as for the CA information to be stored in a file on disk. - `, - flatten (key, obj, flatOptions) { - // always set to null in defaults - if (!obj.cafile) { - return - } - - const raw = maybeReadFile(obj.cafile) - if (!raw) { - return - } - - const delim = '-----END CERTIFICATE-----' - flatOptions.ca = raw.replace(/\r\n/g, '\n').split(delim) - .filter(section => section.trim()) - .map(section => section.trimLeft() + delim) - }, -}) - -define('call', { - default: '', - type: String, - short: 'c', - description: ` - Optional companion option for \`npm exec\`, \`npx\` that allows for - specifying a custom command to be run along with the installed packages. - - \`\`\`bash - npm exec --package yo --package generator-node --call "yo node" - \`\`\` - `, - flatten, -}) - -define('cert', { - default: null, - type: [null, String], - description: ` - A client certificate to pass when accessing the registry. Values should - be in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with - newlines replaced by the string "\\n". For example: - - \`\`\`ini - cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----" - \`\`\` - - It is _not_ the path to a certificate file, though you can set a registry-scoped - "certfile" path like "//other-registry.tld/:certfile=/path/to/cert.pem". - `, - flatten, -}) - -define('ci-name', { - default: ciName || null, - defaultDescription: ` - The name of the current CI system, or \`null\` when not on a known CI - platform. - `, - type: [null, String], - description: ` - The name of a continuous integration system. If not set explicitly, npm - will detect the current CI environment using the - [\`@npmcli/ci-detect\`](http://npm.im/@npmcli/ci-detect) module. - `, - flatten, -}) - -define('cidr', { - default: null, - type: [null, String, Array], - description: ` - This is a list of CIDR address to be used when configuring limited access - tokens with the \`npm token create\` command. - `, - flatten, -}) - -// This should never be directly used, the flattened value is the derived value -// and is sent to other modules, and is also exposed as `npm.color` for use -// inside npm itself. -define('color', { - default: !process.env.NO_COLOR || process.env.NO_COLOR === '0', - usage: '--color|--no-color|--color always', - defaultDescription: ` - true unless the NO_COLOR environ is set to something other than '0' - `, - type: ['always', Boolean], - description: ` - If false, never shows colors. If \`"always"\` then always shows colors. - If true, then only prints color codes for tty file descriptors. - `, - flatten (key, obj, flatOptions) { - flatOptions.color = !obj.color ? false - : obj.color === 'always' ? true - : !!process.stdout.isTTY - flatOptions.logColor = !obj.color ? false - : obj.color === 'always' ? true - : !!process.stderr.isTTY - }, -}) - -define('commit-hooks', { - default: true, - type: Boolean, - description: ` - Run git commit hooks when using the \`npm version\` command. - `, - flatten, -}) - -define('depth', { - default: null, - defaultDescription: ` - \`Infinity\` if \`--all\` is set, otherwise \`1\` - `, - type: [null, Number], - description: ` - The depth to go when recursing packages for \`npm ls\`. - - If not set, \`npm ls\` will show only the immediate dependencies of the - root project. If \`--all\` is set, then npm will show all dependencies - by default. - `, - flatten, -}) - -define('description', { - default: true, - type: Boolean, - usage: '--no-description', - description: ` - Show the description in \`npm search\` - `, - flatten (key, obj, flatOptions) { - flatOptions.search = flatOptions.search || { limit: 20 } - flatOptions.search[key] = obj[key] - }, -}) - -define('dev', { - default: false, - type: Boolean, - description: ` - Alias for \`--include=dev\`. - `, - deprecated: 'Please use --include=dev instead.', - flatten (key, obj, flatOptions) { - definitions.omit.flatten('omit', obj, flatOptions) - }, -}) - -define('diff', { - default: [], - hint: '<package-spec>', - type: [String, Array], - description: ` - Define arguments to compare in \`npm diff\`. - `, - flatten, -}) - -define('diff-ignore-all-space', { - default: false, - type: Boolean, - description: ` - Ignore whitespace when comparing lines in \`npm diff\`. - `, - flatten, -}) - -define('diff-name-only', { - default: false, - type: Boolean, - description: ` - Prints only filenames when using \`npm diff\`. - `, - flatten, -}) - -define('diff-no-prefix', { - default: false, - type: Boolean, - description: ` - Do not show any source or destination prefix in \`npm diff\` output. - - Note: this causes \`npm diff\` to ignore the \`--diff-src-prefix\` and - \`--diff-dst-prefix\` configs. - `, - flatten, -}) - -define('diff-dst-prefix', { - default: 'b/', - hint: '<path>', - type: String, - description: ` - Destination prefix to be used in \`npm diff\` output. - `, - flatten, -}) - -define('diff-src-prefix', { - default: 'a/', - hint: '<path>', - type: String, - description: ` - Source prefix to be used in \`npm diff\` output. - `, - flatten, -}) - -define('diff-text', { - default: false, - type: Boolean, - description: ` - Treat all files as text in \`npm diff\`. - `, - flatten, -}) - -define('diff-unified', { - default: 3, - type: Number, - description: ` - The number of lines of context to print in \`npm diff\`. - `, - flatten, -}) - -define('dry-run', { - default: false, - type: Boolean, - description: ` - Indicates that you don't want npm to make any changes and that it should - only report what it would have done. This can be passed into any of the - commands that modify your local installation, eg, \`install\`, - \`update\`, \`dedupe\`, \`uninstall\`, as well as \`pack\` and - \`publish\`. - - Note: This is NOT honored by other network related commands, eg - \`dist-tags\`, \`owner\`, etc. - `, - flatten, -}) - -define('editor', { - default: editor, - defaultDescription: ` - The EDITOR or VISUAL environment variables, or 'notepad.exe' on Windows, - or 'vim' on Unix systems - `, - type: String, - description: ` - The command to run for \`npm edit\` and \`npm config edit\`. - `, - flatten, -}) - -define('engine-strict', { - default: false, - type: Boolean, - description: ` - If set to true, then npm will stubbornly refuse to install (or even - consider installing) any package that claims to not be compatible with - the current Node.js version. - - This can be overridden by setting the \`--force\` flag. - `, - flatten, -}) - -define('fetch-retries', { - default: 2, - type: Number, - description: ` - The "retries" config for the \`retry\` module to use when fetching - packages from the registry. - - npm will retry idempotent read requests to the registry in the case - of network failures or 5xx HTTP errors. - `, - flatten (key, obj, flatOptions) { - flatOptions.retry = flatOptions.retry || {} - flatOptions.retry.retries = obj[key] - }, -}) - -define('fetch-retry-factor', { - default: 10, - type: Number, - description: ` - The "factor" config for the \`retry\` module to use when fetching - packages. - `, - flatten (key, obj, flatOptions) { - flatOptions.retry = flatOptions.retry || {} - flatOptions.retry.factor = obj[key] - }, -}) - -define('fetch-retry-maxtimeout', { - default: 60000, - defaultDescription: '60000 (1 minute)', - type: Number, - description: ` - The "maxTimeout" config for the \`retry\` module to use when fetching - packages. - `, - flatten (key, obj, flatOptions) { - flatOptions.retry = flatOptions.retry || {} - flatOptions.retry.maxTimeout = obj[key] - }, -}) - -define('fetch-retry-mintimeout', { - default: 10000, - defaultDescription: '10000 (10 seconds)', - type: Number, - description: ` - The "minTimeout" config for the \`retry\` module to use when fetching - packages. - `, - flatten (key, obj, flatOptions) { - flatOptions.retry = flatOptions.retry || {} - flatOptions.retry.minTimeout = obj[key] - }, -}) - -define('fetch-timeout', { - default: 5 * 60 * 1000, - defaultDescription: `${5 * 60 * 1000} (5 minutes)`, - type: Number, - description: ` - The maximum amount of time to wait for HTTP requests to complete. - `, - flatten (key, obj, flatOptions) { - flatOptions.timeout = obj[key] - }, -}) - -define('force', { - default: false, - type: Boolean, - short: 'f', - description: ` - Removes various protections against unfortunate side effects, common - mistakes, unnecessary performance degradation, and malicious input. - - * Allow clobbering non-npm files in global installs. - * Allow the \`npm version\` command to work on an unclean git repository. - * Allow deleting the cache folder with \`npm cache clean\`. - * Allow installing packages that have an \`engines\` declaration - requiring a different version of npm. - * Allow installing packages that have an \`engines\` declaration - requiring a different version of \`node\`, even if \`--engine-strict\` - is enabled. - * Allow \`npm audit fix\` to install modules outside your stated - dependency range (including SemVer-major changes). - * Allow unpublishing all versions of a published package. - * Allow conflicting peerDependencies to be installed in the root project. - * Implicitly set \`--yes\` during \`npm init\`. - * Allow clobbering existing values in \`npm pkg\` - * Allow unpublishing of entire packages (not just a single version). - - If you don't have a clear idea of what you want to do, it is strongly - recommended that you do not use this option! - `, - flatten, -}) - -define('foreground-scripts', { - default: false, - type: Boolean, - description: ` - Run all build scripts (ie, \`preinstall\`, \`install\`, and - \`postinstall\`) scripts for installed packages in the foreground - process, sharing standard input, output, and error with the main npm - process. - - Note that this will generally make installs run slower, and be much - noisier, but can be useful for debugging. - `, - flatten, -}) - -define('format-package-lock', { - default: true, - type: Boolean, - description: ` - Format \`package-lock.json\` or \`npm-shrinkwrap.json\` as a human - readable file. - `, - flatten, -}) - -define('fund', { - default: true, - type: Boolean, - description: ` - When "true" displays the message at the end of each \`npm install\` - acknowledging the number of dependencies looking for funding. - See [\`npm fund\`](/commands/npm-fund) for details. - `, - flatten, -}) - -define('git', { - default: 'git', - type: String, - description: ` - The command to use for git commands. If git is installed on the - computer, but is not in the \`PATH\`, then set this to the full path to - the git binary. - `, - flatten, -}) - -define('git-tag-version', { - default: true, - type: Boolean, - description: ` - Tag the commit when using the \`npm version\` command. Setting this to - false results in no commit being made at all. - `, - flatten, -}) - -define('global', { - default: false, - type: Boolean, - short: 'g', - description: ` - Operates in "global" mode, so that packages are installed into the - \`prefix\` folder instead of the current working directory. See - [folders](/configuring-npm/folders) for more on the differences in - behavior. - - * packages are installed into the \`{prefix}/lib/node_modules\` folder, - instead of the current working directory. - * bin files are linked to \`{prefix}/bin\` - * man pages are linked to \`{prefix}/share/man\` - `, - flatten: (key, obj, flatOptions) => { - flatten(key, obj, flatOptions) - if (flatOptions.global) { - flatOptions.location = 'global' - } - }, -}) - -define('global-style', { - default: false, - type: Boolean, - description: ` - Causes npm to install the package into your local \`node_modules\` folder - with the same layout it uses with the global \`node_modules\` folder. - Only your direct dependencies will show in \`node_modules\` and - everything they depend on will be flattened in their \`node_modules\` - folders. This obviously will eliminate some deduping. If used with - \`legacy-bundling\`, \`legacy-bundling\` will be preferred. - `, - flatten, -}) - -// the globalconfig has its default defined outside of this module -define('globalconfig', { - type: path, - default: '', - defaultDescription: ` - The global --prefix setting plus 'etc/npmrc'. For example, - '/usr/local/etc/npmrc' - `, - description: ` - The config file to read for global config options. - `, - flatten, -}) - -define('heading', { - default: 'npm', - type: String, - description: ` - The string that starts all the debugging log output. - `, - flatten, -}) - -define('https-proxy', { - default: null, - type: [null, url], - description: ` - A proxy to use for outgoing https requests. If the \`HTTPS_PROXY\` or - \`https_proxy\` or \`HTTP_PROXY\` or \`http_proxy\` environment variables - are set, proxy settings will be honored by the underlying - \`make-fetch-happen\` library. - `, - flatten, -}) - -define('if-present', { - default: false, - type: Boolean, - envExport: false, - description: ` - If true, npm will not exit with an error code when \`run-script\` is - invoked for a script that isn't defined in the \`scripts\` section of - \`package.json\`. This option can be used when it's desirable to - optionally run a script when it's present and fail if the script fails. - This is useful, for example, when running scripts that may only apply for - some builds in an otherwise generic CI setup. - `, - flatten, -}) - -define('ignore-scripts', { - default: false, - type: Boolean, - description: ` - If true, npm does not run scripts specified in package.json files. - - Note that commands explicitly intended to run a particular script, such - as \`npm start\`, \`npm stop\`, \`npm restart\`, \`npm test\`, and \`npm - run-script\` will still run their intended script if \`ignore-scripts\` is - set, but they will *not* run any pre- or post-scripts. - `, - flatten, -}) - -define('include', { - default: [], - type: [Array, 'prod', 'dev', 'optional', 'peer'], - description: ` - Option that allows for defining which types of dependencies to install. - - This is the inverse of \`--omit=<type>\`. - - Dependency types specified in \`--include\` will not be omitted, - regardless of the order in which omit/include are specified on the - command-line. - `, - flatten (key, obj, flatOptions) { - // just call the omit flattener, it reads from obj.include - definitions.omit.flatten('omit', obj, flatOptions) - }, -}) - -define('include-staged', { - default: false, - type: Boolean, - description: ` - Allow installing "staged" published packages, as defined by [npm RFC PR - #92](https://github.com/npm/rfcs/pull/92). - - This is experimental, and not implemented by the npm public registry. - `, - flatten, -}) - -define('include-workspace-root', { - default: false, - type: Boolean, - envExport: false, - description: ` - Include the workspace root when workspaces are enabled for a command. - - When false, specifying individual workspaces via the \`workspace\` config, - or all workspaces via the \`workspaces\` flag, will cause npm to operate only - on the specified workspaces, and not on the root project. - `, - flatten, -}) - -define('init-author-email', { - default: '', - type: String, - description: ` - The value \`npm init\` should use by default for the package author's - email. - `, -}) - -define('init-author-name', { - default: '', - type: String, - description: ` - The value \`npm init\` should use by default for the package author's name. - `, -}) - -define('init-author-url', { - default: '', - type: ['', url], - description: ` - The value \`npm init\` should use by default for the package author's homepage. - `, -}) - -define('init-license', { - default: 'ISC', - type: String, - description: ` - The value \`npm init\` should use by default for the package license. - `, -}) - -define('init-module', { - default: '~/.npm-init.js', - type: path, - description: ` - A module that will be loaded by the \`npm init\` command. See the - documentation for the - [init-package-json](https://github.com/npm/init-package-json) module for - more information, or [npm init](/commands/npm-init). - `, -}) - -define('init-version', { - default: '1.0.0', - type: semver, - description: ` - The value that \`npm init\` should use by default for the package - version number, if not already set in package.json. - `, -}) - -// these "aliases" are historically supported in .npmrc files, unfortunately -// They should be removed in a future npm version. -define('init.author.email', { - default: '', - type: String, - deprecated: ` - Use \`--init-author-email\` instead.`, - description: ` - Alias for \`--init-author-email\` - `, -}) - -define('init.author.name', { - default: '', - type: String, - deprecated: ` - Use \`--init-author-name\` instead. - `, - description: ` - Alias for \`--init-author-name\` - `, -}) - -define('init.author.url', { - default: '', - type: ['', url], - deprecated: ` - Use \`--init-author-url\` instead. - `, - description: ` - Alias for \`--init-author-url\` - `, -}) - -define('init.license', { - default: 'ISC', - type: String, - deprecated: ` - Use \`--init-license\` instead. - `, - description: ` - Alias for \`--init-license\` - `, -}) - -define('init.module', { - default: '~/.npm-init.js', - type: path, - deprecated: ` - Use \`--init-module\` instead. - `, - description: ` - Alias for \`--init-module\` - `, -}) - -define('init.version', { - default: '1.0.0', - type: semver, - deprecated: ` - Use \`--init-version\` instead. - `, - description: ` - Alias for \`--init-version\` - `, -}) - -define('install-links', { - default: false, - type: Boolean, - description: ` - When set file: protocol dependencies that exist outside of the project root - will be packed and installed as regular dependencies instead of creating a - symlink. This option has no effect on workspaces. - `, - flatten, -}) - -define('json', { - default: false, - type: Boolean, - description: ` - Whether or not to output JSON data, rather than the normal output. - - * In \`npm pkg set\` it enables parsing set values with JSON.parse() - before saving them to your \`package.json\`. - - Not supported by all npm commands. - `, - flatten, -}) - -define('key', { - default: null, - type: [null, String], - description: ` - A client key to pass when accessing the registry. Values should be in - PEM format with newlines replaced by the string "\\n". For example: - - \`\`\`ini - key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----" - \`\`\` - - It is _not_ the path to a key file, though you can set a registry-scoped - "keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem". - `, - flatten, -}) - -define('legacy-bundling', { - default: false, - type: Boolean, - description: ` - Causes npm to install the package such that versions of npm prior to 1.4, - such as the one included with node 0.8, can install the package. This - eliminates all automatic deduping. If used with \`global-style\` this - option will be preferred. - `, - flatten, -}) - -define('legacy-peer-deps', { - default: false, - type: Boolean, - description: ` - Causes npm to completely ignore \`peerDependencies\` when building a - package tree, as in npm versions 3 through 6. - - If a package cannot be installed because of overly strict - \`peerDependencies\` that collide, it provides a way to move forward - resolving the situation. - - This differs from \`--omit=peer\`, in that \`--omit=peer\` will avoid - unpacking \`peerDependencies\` on disk, but will still design a tree such - that \`peerDependencies\` _could_ be unpacked in a correct place. - - Use of \`legacy-peer-deps\` is not recommended, as it will not enforce - the \`peerDependencies\` contract that meta-dependencies may rely on. - `, - flatten, -}) - -define('link', { - default: false, - type: Boolean, - description: ` - Used with \`npm ls\`, limiting output to only those packages that are - linked. - `, -}) - -define('local-address', { - default: null, - type: getLocalAddresses(), - typeDescription: 'IP Address', - description: ` - The IP address of the local interface to use when making connections to - the npm registry. Must be IPv4 in versions of Node prior to 0.12. - `, - flatten, -}) - -define('location', { - default: 'user', - short: 'L', - type: [ - 'global', - 'user', - 'project', - ], - defaultDescription: ` - "user" unless \`--global\` is passed, which will also set this value to "global" - `, - description: ` - When passed to \`npm config\` this refers to which config file to use. - - When set to "global" mode, packages are installed into the \`prefix\` folder - instead of the current working directory. See - [folders](/configuring-npm/folders) for more on the differences in behavior. - - * packages are installed into the \`{prefix}/lib/node_modules\` folder, - instead of the current working directory. - * bin files are linked to \`{prefix}/bin\` - * man pages are linked to \`{prefix}/share/man\` - `, - flatten: (key, obj, flatOptions) => { - flatten(key, obj, flatOptions) - if (flatOptions.global) { - flatOptions.location = 'global' - } - if (obj.location === 'global') { - flatOptions.global = true - } - }, -}) - -define('lockfile-version', { - default: null, - type: [null, 1, 2, 3, '1', '2', '3'], - defaultDescription: ` - Version 2 if no lockfile or current lockfile version less than or equal to - 2, otherwise maintain current lockfile version - `, - description: ` - Set the lockfile format version to be used in package-lock.json and - npm-shrinkwrap-json files. Possible options are: - - 1: The lockfile version used by npm versions 5 and 6. Lacks some data that - is used during the install, resulting in slower and possibly less - deterministic installs. Prevents lockfile churn when interoperating with - older npm versions. - - 2: The default lockfile version used by npm version 7. Includes both the - version 1 lockfile data and version 3 lockfile data, for maximum - determinism and interoperability, at the expense of more bytes on disk. - - 3: Only the new lockfile information introduced in npm version 7. Smaller - on disk than lockfile version 2, but not interoperable with older npm - versions. Ideal if all users are on npm version 7 and higher. - `, - flatten: (key, obj, flatOptions) => { - flatOptions.lockfileVersion = obj[key] && parseInt(obj[key], 10) - }, -}) - -define('loglevel', { - default: 'notice', - type: [ - 'silent', - 'error', - 'warn', - 'notice', - 'http', - 'timing', - 'info', - 'verbose', - 'silly', - ], - description: ` - What level of logs to report. All logs are written to a debug log, - with the path to that file printed if the execution of a command fails. - - Any logs of a higher level than the setting are shown. The default is - "notice". - - See also the \`foreground-scripts\` config. - `, - flatten (key, obj, flatOptions) { - flatOptions.silent = obj[key] === 'silent' - }, -}) - -define('logs-dir', { - default: null, - type: [null, path], - defaultDescription: ` - A directory named \`_logs\` inside the cache -`, - description: ` - The location of npm's log directory. See [\`npm - logging\`](/using-npm/logging) for more information. - `, -}) - -define('logs-max', { - default: 10, - type: Number, - description: ` - The maximum number of log files to store. - - If set to 0, no log files will be written for the current run. - `, -}) - -define('long', { - default: false, - type: Boolean, - short: 'l', - description: ` - Show extended information in \`ls\`, \`search\`, and \`help-search\`. - `, -}) - -define('maxsockets', { - default: 15, - type: Number, - description: ` - The maximum number of connections to use per origin (protocol/host/port - combination). - `, - flatten (key, obj, flatOptions) { - flatOptions.maxSockets = obj[key] - }, -}) - -define('message', { - default: '%s', - type: String, - short: 'm', - description: ` - Commit message which is used by \`npm version\` when creating version commit. - - Any "%s" in the message will be replaced with the version number. - `, - flatten, -}) - -define('node-options', { - default: null, - type: [null, String], - description: ` - Options to pass through to Node.js via the \`NODE_OPTIONS\` environment - variable. This does not impact how npm itself is executed but it does - impact how lifecycle scripts are called. - `, -}) - -define('node-version', { - default: process.version, - defaultDescription: 'Node.js `process.version` value', - type: semver, - description: ` - The node version to use when checking a package's \`engines\` setting. - `, - flatten, -}) - -define('noproxy', { - default: '', - defaultDescription: ` - The value of the NO_PROXY environment variable - `, - type: [String, Array], - description: ` - Domain extensions that should bypass any proxies. - - Also accepts a comma-delimited string. - `, - flatten (key, obj, flatOptions) { - if (Array.isArray(obj[key])) { - flatOptions.noProxy = obj[key].join(',') - } else { - flatOptions.noProxy = obj[key] - } - }, -}) - -define('npm-version', { - default: npmVersion, - defaultDescription: 'Output of `npm --version`', - type: semver, - description: ` - The npm version to use when checking a package's \`engines\` setting. - `, - flatten, -}) - -define('offline', { - default: false, - type: Boolean, - description: ` - Force offline mode: no network requests will be done during install. To allow - the CLI to fill in missing cache data, see \`--prefer-offline\`. - `, - flatten, -}) - -define('omit', { - default: process.env.NODE_ENV === 'production' ? ['dev'] : [], - defaultDescription: ` - 'dev' if the \`NODE_ENV\` environment variable is set to 'production', - otherwise empty. - `, - type: [Array, 'dev', 'optional', 'peer'], - description: ` - Dependency types to omit from the installation tree on disk. - - Note that these dependencies _are_ still resolved and added to the - \`package-lock.json\` or \`npm-shrinkwrap.json\` file. They are just - not physically installed on disk. - - If a package type appears in both the \`--include\` and \`--omit\` - lists, then it will be included. - - If the resulting omit list includes \`'dev'\`, then the \`NODE_ENV\` - environment variable will be set to \`'production'\` for all lifecycle - scripts. - `, - flatten (key, obj, flatOptions) { - flatOptions.omit = buildOmitList(obj) - }, -}) - -define('omit-lockfile-registry-resolved', { - default: false, - type: Boolean, - description: ` - This option causes npm to create lock files without a \`resolved\` key for - registry dependencies. Subsequent installs will need to resolve tarball - endpoints with the configured registry, likely resulting in a longer install - time. - `, - flatten, -}) - -define('only', { - default: null, - type: [null, 'prod', 'production'], - deprecated: ` - Use \`--omit=dev\` to omit dev dependencies from the install. - `, - description: ` - When set to \`prod\` or \`production\`, this is an alias for - \`--omit=dev\`. - `, - flatten (key, obj, flatOptions) { - definitions.omit.flatten('omit', obj, flatOptions) - }, -}) - -define('optional', { - default: null, - type: [null, Boolean], - deprecated: ` - Use \`--omit=optional\` to exclude optional dependencies, or - \`--include=optional\` to include them. - - Default value does install optional deps unless otherwise omitted. - `, - description: ` - Alias for --include=optional or --omit=optional - `, - flatten (key, obj, flatOptions) { - definitions.omit.flatten('omit', obj, flatOptions) - }, -}) - -define('otp', { - default: null, - type: [null, String], - description: ` - This is a one-time password from a two-factor authenticator. It's needed - when publishing or changing package permissions with \`npm access\`. - - If not set, and a registry response fails with a challenge for a one-time - password, npm will prompt on the command line for one. - `, - flatten, -}) - -define('package', { - default: [], - hint: '<package-spec>', - type: [String, Array], - description: ` - The package or packages to install for [\`npm exec\`](/commands/npm-exec) - `, - flatten, -}) - -define('package-lock', { - default: true, - type: Boolean, - description: ` - If set to false, then ignore \`package-lock.json\` files when installing. - This will also prevent _writing_ \`package-lock.json\` if \`save\` is - true. - - This configuration does not affect \`npm ci\`. - `, - flatten: (key, obj, flatOptions) => { - flatten(key, obj, flatOptions) - if (flatOptions.packageLockOnly) { - flatOptions.packageLock = true - } - }, -}) - -define('package-lock-only', { - default: false, - type: Boolean, - description: ` - If set to true, the current operation will only use the \`package-lock.json\`, - ignoring \`node_modules\`. - - For \`update\` this means only the \`package-lock.json\` will be updated, - instead of checking \`node_modules\` and downloading dependencies. - - For \`list\` this means the output will be based on the tree described by the - \`package-lock.json\`, rather than the contents of \`node_modules\`. - `, - flatten: (key, obj, flatOptions) => { - flatten(key, obj, flatOptions) - if (flatOptions.packageLockOnly) { - flatOptions.packageLock = true - } - }, -}) - -define('pack-destination', { - default: '.', - type: String, - description: ` - Directory in which \`npm pack\` will save tarballs. - `, - flatten, -}) - -define('parseable', { - default: false, - type: Boolean, - short: 'p', - description: ` - Output parseable results from commands that write to standard output. For - \`npm search\`, this will be tab-separated table format. - `, - flatten, -}) - -define('prefer-offline', { - default: false, - type: Boolean, - description: ` - If true, staleness checks for cached data will be bypassed, but missing - data will be requested from the server. To force full offline mode, use - \`--offline\`. - `, - flatten, -}) - -define('prefer-online', { - default: false, - type: Boolean, - description: ` - If true, staleness checks for cached data will be forced, making the CLI - look for updates immediately even for fresh package data. - `, - flatten, -}) - -// `prefix` has its default defined outside of this module -define('prefix', { - type: path, - short: 'C', - default: '', - defaultDescription: ` - In global mode, the folder where the node executable is installed. In - local mode, the nearest parent folder containing either a package.json - file or a node_modules folder. - `, - description: ` - The location to install global items. If set on the command line, then - it forces non-global commands to run in the specified folder. - `, -}) - -define('preid', { - default: '', - hint: 'prerelease-id', - type: String, - description: ` - The "prerelease identifier" to use as a prefix for the "prerelease" part - of a semver. Like the \`rc\` in \`1.2.0-rc.8\`. - `, - flatten, -}) - -define('production', { - default: null, - type: [null, Boolean], - deprecated: 'Use `--omit=dev` instead.', - description: 'Alias for `--omit=dev`', - flatten (key, obj, flatOptions) { - definitions.omit.flatten('omit', obj, flatOptions) - }, -}) - -define('progress', { - default: !ciName, - defaultDescription: ` - \`true\` unless running in a known CI system - `, - type: Boolean, - description: ` - When set to \`true\`, npm will display a progress bar during time - intensive operations, if \`process.stderr\` is a TTY. - - Set to \`false\` to suppress the progress bar. - `, - flatten (key, obj, flatOptions) { - flatOptions.progress = !obj.progress ? false - : !!process.stderr.isTTY && process.env.TERM !== 'dumb' - }, -}) - -define('proxy', { - default: null, - type: [null, false, url], // allow proxy to be disabled explicitly - description: ` - A proxy to use for outgoing http requests. If the \`HTTP_PROXY\` or - \`http_proxy\` environment variables are set, proxy settings will be - honored by the underlying \`request\` library. - `, - flatten, -}) - -define('read-only', { - default: false, - type: Boolean, - description: ` - This is used to mark a token as unable to publish when configuring - limited access tokens with the \`npm token create\` command. - `, - flatten, -}) - -define('rebuild-bundle', { - default: true, - type: Boolean, - description: ` - Rebuild bundled dependencies after installation. - `, - flatten, -}) - -define('registry', { - default: 'https://registry.npmjs.org/', - type: url, - description: ` - The base URL of the npm registry. - `, - flatten, -}) - -define('replace-registry-host', { - default: 'npmjs', - hint: '<npmjs|never|always> | hostname', - type: ['npmjs', 'never', 'always', String], - description: ` - Defines behavior for replacing the registry host in a lockfile with the - configured registry. - - The default behavior is to replace package dist URLs from the default - registry (https://registry.npmjs.org) to the configured registry. If set to - "never", then use the registry value. If set to "always", then replace the - registry host with the configured host every time. - - You may also specify a bare hostname (e.g., "registry.npmjs.org"). - `, - flatten, -}) - -define('save', { - default: true, - defaultDescription: `\`true\` unless when using \`npm update\` where it - defaults to \`false\``, - usage: '-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle', - type: Boolean, - short: 'S', - description: ` - Save installed packages to a \`package.json\` file as dependencies. - - When used with the \`npm rm\` command, removes the dependency from - \`package.json\`. - - Will also prevent writing to \`package-lock.json\` if set to \`false\`. - `, - flatten, -}) - -define('save-bundle', { - default: false, - type: Boolean, - short: 'B', - description: ` - If a package would be saved at install time by the use of \`--save\`, - \`--save-dev\`, or \`--save-optional\`, then also put it in the - \`bundleDependencies\` list. - - Ignored if \`--save-peer\` is set, since peerDependencies cannot be bundled. - `, - flatten (key, obj, flatOptions) { - // XXX update arborist to just ignore it if resulting saveType is peer - // otherwise this won't have the expected effect: - // - // npm config set save-peer true - // npm i foo --save-bundle --save-prod <-- should bundle - flatOptions.saveBundle = obj['save-bundle'] && !obj['save-peer'] - }, -}) - -// XXX: We should really deprecate all these `--save-blah` switches -// in favor of a single `--save-type` option. The unfortunate shortcut -// we took for `--save-peer --save-optional` being `--save-type=peerOptional` -// makes this tricky, and likely a breaking change. - -define('save-dev', { - default: false, - type: Boolean, - short: 'D', - description: ` - Save installed packages to a package.json file as \`devDependencies\`. - `, - flatten (key, obj, flatOptions) { - if (!obj[key]) { - if (flatOptions.saveType === 'dev') { - delete flatOptions.saveType - } - return - } - - flatOptions.saveType = 'dev' - }, -}) - -define('save-exact', { - default: false, - type: Boolean, - short: 'E', - description: ` - Dependencies saved to package.json will be configured with an exact - version rather than using npm's default semver range operator. - `, - flatten (key, obj, flatOptions) { - // just call the save-prefix flattener, it reads from obj['save-exact'] - definitions['save-prefix'].flatten('save-prefix', obj, flatOptions) - }, -}) - -define('save-optional', { - default: false, - type: Boolean, - short: 'O', - description: ` - Save installed packages to a package.json file as - \`optionalDependencies\`. - `, - flatten (key, obj, flatOptions) { - if (!obj[key]) { - if (flatOptions.saveType === 'optional') { - delete flatOptions.saveType - } else if (flatOptions.saveType === 'peerOptional') { - flatOptions.saveType = 'peer' - } - return - } - - if (flatOptions.saveType === 'peerOptional') { - return - } - - if (flatOptions.saveType === 'peer') { - flatOptions.saveType = 'peerOptional' - } else { - flatOptions.saveType = 'optional' - } - }, -}) - -define('save-peer', { - default: false, - type: Boolean, - description: ` - Save installed packages to a package.json file as \`peerDependencies\` - `, - flatten (key, obj, flatOptions) { - if (!obj[key]) { - if (flatOptions.saveType === 'peer') { - delete flatOptions.saveType - } else if (flatOptions.saveType === 'peerOptional') { - flatOptions.saveType = 'optional' - } - return - } - - if (flatOptions.saveType === 'peerOptional') { - return - } - - if (flatOptions.saveType === 'optional') { - flatOptions.saveType = 'peerOptional' - } else { - flatOptions.saveType = 'peer' - } - }, -}) - -define('save-prefix', { - default: '^', - type: String, - description: ` - Configure how versions of packages installed to a package.json file via - \`--save\` or \`--save-dev\` get prefixed. - - For example if a package has version \`1.2.3\`, by default its version is - set to \`^1.2.3\` which allows minor upgrades for that package, but after - \`npm config set save-prefix='~'\` it would be set to \`~1.2.3\` which - only allows patch upgrades. - `, - flatten (key, obj, flatOptions) { - flatOptions.savePrefix = obj['save-exact'] ? '' : obj['save-prefix'] - obj['save-prefix'] = flatOptions.savePrefix - }, -}) - -define('save-prod', { - default: false, - type: Boolean, - short: 'P', - description: ` - Save installed packages into \`dependencies\` specifically. This is - useful if a package already exists in \`devDependencies\` or - \`optionalDependencies\`, but you want to move it to be a non-optional - production dependency. - - This is the default behavior if \`--save\` is true, and neither - \`--save-dev\` or \`--save-optional\` are true. - `, - flatten (key, obj, flatOptions) { - if (!obj[key]) { - if (flatOptions.saveType === 'prod') { - delete flatOptions.saveType - } - return - } - - flatOptions.saveType = 'prod' - }, -}) - -define('scope', { - default: '', - defaultDescription: ` - the scope of the current project, if any, or "" - `, - type: String, - hint: '<@scope>', - description: ` - Associate an operation with a scope for a scoped registry. - - Useful when logging in to or out of a private registry: - - \`\`\` - # log in, linking the scope to the custom registry - npm login --scope=@mycorp --registry=https://registry.mycorp.com - - # log out, removing the link and the auth token - npm logout --scope=@mycorp - \`\`\` - - This will cause \`@mycorp\` to be mapped to the registry for future - installation of packages specified according to the pattern - \`@mycorp/package\`. - - This will also cause \`npm init\` to create a scoped package. - - \`\`\` - # accept all defaults, and create a package named "@foo/whatever", - # instead of just named "whatever" - npm init --scope=@foo --yes - \`\`\` - `, - flatten (key, obj, flatOptions) { - const value = obj[key] - const scope = value && !/^@/.test(value) ? `@${value}` : value - flatOptions.scope = scope - // projectScope is kept for compatibility with npm-registry-fetch - flatOptions.projectScope = scope - }, -}) - -define('script-shell', { - default: null, - defaultDescription: ` - '/bin/sh' on POSIX systems, 'cmd.exe' on Windows - `, - type: [null, String], - description: ` - The shell to use for scripts run with the \`npm exec\`, - \`npm run\` and \`npm init <package-spec>\` commands. - `, - flatten (key, obj, flatOptions) { - flatOptions.scriptShell = obj[key] || undefined - }, -}) - -define('searchexclude', { - default: '', - type: String, - description: ` - Space-separated options that limit the results from search. - `, - flatten (key, obj, flatOptions) { - flatOptions.search = flatOptions.search || { limit: 20 } - flatOptions.search.exclude = obj[key].toLowerCase() - }, -}) - -define('searchlimit', { - default: 20, - type: Number, - description: ` - Number of items to limit search results to. Will not apply at all to - legacy searches. - `, - flatten (key, obj, flatOptions) { - flatOptions.search = flatOptions.search || {} - flatOptions.search.limit = obj[key] - }, -}) - -define('searchopts', { - default: '', - type: String, - description: ` - Space-separated options that are always passed to search. - `, - flatten (key, obj, flatOptions) { - flatOptions.search = flatOptions.search || { limit: 20 } - flatOptions.search.opts = querystring.parse(obj[key]) - }, -}) - -define('searchstaleness', { - default: 15 * 60, - type: Number, - description: ` - The age of the cache, in seconds, before another registry request is made - if using legacy search endpoint. - `, - flatten (key, obj, flatOptions) { - flatOptions.search = flatOptions.search || { limit: 20 } - flatOptions.search.staleness = obj[key] - }, -}) - -define('shell', { - default: shell, - defaultDescription: ` - SHELL environment variable, or "bash" on Posix, or "cmd.exe" on Windows - `, - type: String, - description: ` - The shell to run for the \`npm explore\` command. - `, - flatten, -}) - -define('shrinkwrap', { - default: true, - type: Boolean, - deprecated: ` - Use the --package-lock setting instead. - `, - description: ` - Alias for --package-lock - `, - flatten (key, obj, flatOptions) { - obj['package-lock'] = obj.shrinkwrap - definitions['package-lock'].flatten('package-lock', obj, flatOptions) - }, -}) - -define('sign-git-commit', { - default: false, - type: Boolean, - description: ` - If set to true, then the \`npm version\` command will commit the new - package version using \`-S\` to add a signature. - - Note that git requires you to have set up GPG keys in your git configs - for this to work properly. - `, - flatten, -}) - -define('sign-git-tag', { - default: false, - type: Boolean, - description: ` - If set to true, then the \`npm version\` command will tag the version - using \`-s\` to add a signature. - - Note that git requires you to have set up GPG keys in your git configs - for this to work properly. - `, - flatten, -}) - -define('sso-poll-frequency', { - default: 500, - type: Number, - deprecated: ` - The --auth-type method of SSO/SAML/OAuth will be removed in a future - version of npm in favor of web-based login. - `, - description: ` - When used with SSO-enabled \`auth-type\`s, configures how regularly the - registry should be polled while the user is completing authentication. - `, - flatten, -}) - -define('sso-type', { - default: 'oauth', - type: [null, 'oauth', 'saml'], - deprecated: ` - The --auth-type method of SSO/SAML/OAuth will be removed in a future - version of npm in favor of web-based login. - `, - description: ` - If \`--auth-type=sso\`, the type of SSO type to use. - `, - flatten, -}) - -define('strict-peer-deps', { - default: false, - type: Boolean, - description: ` - If set to \`true\`, and \`--legacy-peer-deps\` is not set, then _any_ - conflicting \`peerDependencies\` will be treated as an install failure, - even if npm could reasonably guess the appropriate resolution based on - non-peer dependency relationships. - - By default, conflicting \`peerDependencies\` deep in the dependency graph - will be resolved using the nearest non-peer dependency specification, - even if doing so will result in some packages receiving a peer dependency - outside the range set in their package's \`peerDependencies\` object. - - When such and override is performed, a warning is printed, explaining the - conflict and the packages involved. If \`--strict-peer-deps\` is set, - then this warning is treated as a failure. - `, - flatten, -}) - -define('strict-ssl', { - default: true, - type: Boolean, - description: ` - Whether or not to do SSL key validation when making requests to the - registry via https. - - See also the \`ca\` config. - `, - flatten (key, obj, flatOptions) { - flatOptions.strictSSL = obj[key] - }, -}) - -define('tag', { - default: 'latest', - type: String, - description: ` - If you ask npm to install a package and don't tell it a specific version, - then it will install the specified tag. - - Also the tag that is added to the package@version specified by the \`npm - tag\` command, if no explicit tag is given. - - When used by the \`npm diff\` command, this is the tag used to fetch the - tarball that will be compared with the local files by default. - `, - flatten (key, obj, flatOptions) { - flatOptions.defaultTag = obj[key] - }, -}) - -define('tag-version-prefix', { - default: 'v', - type: String, - description: ` - If set, alters the prefix used when tagging a new version when performing - a version increment using \`npm-version\`. To remove the prefix - altogether, set it to the empty string: \`""\`. - - Because other tools may rely on the convention that npm version tags look - like \`v1.0.0\`, _only use this property if it is absolutely necessary_. - In particular, use care when overriding this setting for public packages. - `, - flatten, -}) - -define('timing', { - default: false, - type: Boolean, - description: ` - If true, writes a debug log to \`logs-dir\` and timing information - to \`_timing.json\` in the cache, even if the command completes - successfully. \`_timing.json\` is a newline delimited list of JSON - objects. - - You can quickly view it with this [json](https://npm.im/json) command - line: \`npm exec -- json -g < ~/.npm/_timing.json\`. - `, -}) - -define('tmp', { - default: tmpdir(), - defaultDescription: ` - The value returned by the Node.js \`os.tmpdir()\` method - <https://nodejs.org/api/os.html#os_os_tmpdir> - `, - type: path, - deprecated: ` - This setting is no longer used. npm stores temporary files in a special - location in the cache, and they are managed by - [\`cacache\`](http://npm.im/cacache). - `, - description: ` - Historically, the location where temporary files were stored. No longer - relevant. - `, -}) - -define('umask', { - default: 0, - type: Umask, - description: ` - The "umask" value to use when setting the file creation mode on files and - folders. - - Folders and executables are given a mode which is \`0o777\` masked - against this value. Other files are given a mode which is \`0o666\` - masked against this value. - - Note that the underlying system will _also_ apply its own umask value to - files and folders that are created, and npm does not circumvent this, but - rather adds the \`--umask\` config to it. - - Thus, the effective default umask value on most POSIX systems is 0o22, - meaning that folders and executables are created with a mode of 0o755 and - other files are created with a mode of 0o644. - `, - flatten, -}) - -define('unicode', { - default: unicode, - defaultDescription: ` - false on windows, true on mac/unix systems with a unicode locale, as - defined by the \`LC_ALL\`, \`LC_CTYPE\`, or \`LANG\` environment variables. - `, - type: Boolean, - description: ` - When set to true, npm uses unicode characters in the tree output. When - false, it uses ascii characters instead of unicode glyphs. - `, -}) - -define('update-notifier', { - default: true, - type: Boolean, - description: ` - Set to false to suppress the update notification when using an older - version of npm than the latest. - `, -}) - -define('usage', { - default: false, - type: Boolean, - short: ['?', 'H', 'h'], - description: ` - Show short usage output about the command specified. - `, -}) - -define('user-agent', { - default: 'npm/{npm-version} ' + - 'node/{node-version} ' + - '{platform} ' + - '{arch} ' + - 'workspaces/{workspaces} ' + - '{ci}', - type: String, - description: ` - Sets the User-Agent request header. The following fields are replaced - with their actual counterparts: - - * \`{npm-version}\` - The npm version in use - * \`{node-version}\` - The Node.js version in use - * \`{platform}\` - The value of \`process.platform\` - * \`{arch}\` - The value of \`process.arch\` - * \`{workspaces}\` - Set to \`true\` if the \`workspaces\` or \`workspace\` - options are set. - * \`{ci}\` - The value of the \`ci-name\` config, if set, prefixed with - \`ci/\`, or an empty string if \`ci-name\` is empty. - `, - flatten (key, obj, flatOptions) { - const value = obj[key] - const ciName = obj['ci-name'] - let inWorkspaces = false - if (obj.workspaces || obj.workspace && obj.workspace.length) { - inWorkspaces = true - } - flatOptions.userAgent = - value.replace(/\{node-version\}/gi, obj['node-version']) - .replace(/\{npm-version\}/gi, obj['npm-version']) - .replace(/\{platform\}/gi, process.platform) - .replace(/\{arch\}/gi, process.arch) - .replace(/\{workspaces\}/gi, inWorkspaces) - .replace(/\{ci\}/gi, ciName ? `ci/${ciName}` : '') - .trim() - - // We can't clobber the original or else subsequent flattening will fail - // (i.e. when we change the underlying config values) - // obj[key] = flatOptions.userAgent - - // user-agent is a unique kind of config item that gets set from a template - // and ends up translated. Because of this, the normal "should we set this - // to process.env also doesn't work - process.env.npm_config_user_agent = flatOptions.userAgent - }, -}) - -define('userconfig', { - default: '~/.npmrc', - type: path, - description: ` - The location of user-level configuration settings. - - This may be overridden by the \`npm_config_userconfig\` environment - variable or the \`--userconfig\` command line option, but may _not_ - be overridden by settings in the \`globalconfig\` file. - `, -}) - -define('version', { - default: false, - type: Boolean, - short: 'v', - description: ` - If true, output the npm version and exit successfully. - - Only relevant when specified explicitly on the command line. - `, -}) - -define('versions', { - default: false, - type: Boolean, - description: ` - If true, output the npm version as well as node's \`process.versions\` - map and the version in the current working directory's \`package.json\` - file if one exists, and exit successfully. - - Only relevant when specified explicitly on the command line. - `, -}) - -define('viewer', { - default: isWindows ? 'browser' : 'man', - defaultDescription: ` - "man" on Posix, "browser" on Windows - `, - type: String, - description: ` - The program to use to view help content. - - Set to \`"browser"\` to view html help content in the default web browser. - `, -}) - -define('which', { - default: null, - hint: '<fundingSourceNumber>', - type: [null, Number], - description: ` - If there are multiple funding sources, which 1-indexed source URL to open. - `, -}) - -define('workspace', { - default: [], - type: [String, Array], - hint: '<workspace-name>', - short: 'w', - envExport: false, - description: ` - Enable running a command in the context of the configured workspaces of the - current project while filtering by running only the workspaces defined by - this configuration option. - - Valid values for the \`workspace\` config are either: - - * Workspace names - * Path to a workspace directory - * Path to a parent workspace directory (will result in selecting all - workspaces within that folder) - - When set for the \`npm init\` command, this may be set to the folder of - a workspace which does not yet exist, to create the folder and set it - up as a brand new workspace within the project. - `, - flatten: (key, obj, flatOptions) => { - definitions['user-agent'].flatten('user-agent', obj, flatOptions) - }, -}) - -define('workspaces', { - default: null, - type: [null, Boolean], - short: 'ws', - envExport: false, - description: ` - Set to true to run the command in the context of **all** configured - workspaces. - - Explicitly setting this to false will cause commands like \`install\` to - ignore workspaces altogether. - When not set explicitly: - - - Commands that operate on the \`node_modules\` tree (install, update, - etc.) will link workspaces into the \`node_modules\` folder. - - Commands that do other things (test, exec, publish, etc.) will operate - on the root project, _unless_ one or more workspaces are specified in - the \`workspace\` config. - `, - flatten: (key, obj, flatOptions) => { - definitions['user-agent'].flatten('user-agent', obj, flatOptions) - - // TODO: this is a derived value, and should be reworked when we have a - // pattern for derived value - - // workspacesEnabled is true whether workspaces is null or true - // commands contextually work with workspaces or not regardless of - // configuration, so we need an option specifically to disable workspaces - flatOptions.workspacesEnabled = obj[key] !== false - }, -}) - -define('workspaces-update', { - default: true, - type: Boolean, - description: ` - If set to true, the npm cli will run an update after operations that may - possibly change the workspaces installed to the \`node_modules\` folder. - `, - flatten, -}) - -define('yes', { - default: null, - type: [null, Boolean], - short: 'y', - description: ` - Automatically answer "yes" to any prompts that npm might print on - the command line. - `, -}) diff --git a/lib/utils/config/describe-all.js b/lib/utils/config/describe-all.js deleted file mode 100644 index 39f8d5fe4d453..0000000000000 --- a/lib/utils/config/describe-all.js +++ /dev/null @@ -1,20 +0,0 @@ -const definitions = require('./definitions.js') -const localeCompare = require('@isaacs/string-locale-compare')('en') -const describeAll = () => { - // sort not-deprecated ones to the top - /* istanbul ignore next - typically already sorted in the definitions file, - * but this is here so that our help doc will stay consistent if we decide - * to move them around. */ - const sort = ([keya, { deprecated: depa }], [keyb, { deprecated: depb }]) => { - return depa && !depb ? 1 - : !depa && depb ? -1 - : localeCompare(keya, keyb) - } - return Object.entries(definitions).sort(sort) - .map(([key, def]) => def.describe()) - .join( - '\n\n<!-- automatically generated, do not edit manually -->\n' + - '<!-- see lib/utils/config/definitions.js -->\n\n' - ) -} -module.exports = describeAll diff --git a/lib/utils/config/flatten.js b/lib/utils/config/flatten.js deleted file mode 100644 index 588d05bf0d77d..0000000000000 --- a/lib/utils/config/flatten.js +++ /dev/null @@ -1,33 +0,0 @@ -// use the defined flattening function, and copy over any scoped -// registries and registry-specific "nerfdart" configs verbatim -// -// TODO: make these getters so that we only have to make dirty -// the thing that changed, and then flatten the fields that -// could have changed when a config.set is called. -// -// TODO: move nerfdart auth stuff into a nested object that -// is only passed along to paths that end up calling npm-registry-fetch. -const definitions = require('./definitions.js') -const flatten = (obj, flat = {}) => { - for (const [key, val] of Object.entries(obj)) { - const def = definitions[key] - if (def && def.flatten) { - def.flatten(key, obj, flat) - } else if (/@.*:registry$/i.test(key) || /^\/\//.test(key)) { - flat[key] = val - } - } - - // XXX make this the bin/npm-cli.js file explicitly instead - // otherwise using npm programmatically is a bit of a pain. - flat.npmBin = require.main ? require.main.filename - : /* istanbul ignore next - not configurable property */ undefined - flat.nodeBin = process.env.NODE || process.execPath - - // XXX should this be sha512? is it even relevant? - flat.hashAlgorithm = 'sha1' - - return flat -} - -module.exports = flatten diff --git a/lib/utils/config/index.js b/lib/utils/config/index.js deleted file mode 100644 index b0ad24d7ee12f..0000000000000 --- a/lib/utils/config/index.js +++ /dev/null @@ -1,55 +0,0 @@ -const flatten = require('./flatten.js') -const definitions = require('./definitions.js') -const describeAll = require('./describe-all.js') - -// aliases where they get expanded into a completely different thing -// these are NOT supported in the environment or npmrc files, only -// expanded on the CLI. -// TODO: when we switch off of nopt, use an arg parser that supports -// more reasonable aliasing and short opts right in the definitions set. -const shorthands = { - 'enjoy-by': ['--before'], - d: ['--loglevel', 'info'], - dd: ['--loglevel', 'verbose'], - ddd: ['--loglevel', 'silly'], - quiet: ['--loglevel', 'warn'], - q: ['--loglevel', 'warn'], - s: ['--loglevel', 'silent'], - silent: ['--loglevel', 'silent'], - verbose: ['--loglevel', 'verbose'], - desc: ['--description'], - help: ['--usage'], - local: ['--no-global'], - n: ['--no-yes'], - no: ['--no-yes'], - porcelain: ['--parseable'], - readonly: ['--read-only'], - reg: ['--registry'], - iwr: ['--include-workspace-root'], -} - -for (const [key, { short }] of Object.entries(definitions)) { - if (!short) { - continue - } - // can be either an array or string - for (const s of [].concat(short)) { - shorthands[s] = [`--${key}`] - } -} - -module.exports = { - get defaults () { - // NB: 'default' is a reserved word - return Object.entries(definitions).map(([key, { default: def }]) => { - return [key, def] - }).reduce((defaults, [key, def]) => { - defaults[key] = def - return defaults - }, {}) - }, - definitions, - flatten, - shorthands, - describeAll, -} diff --git a/lib/utils/did-you-mean.js b/lib/utils/did-you-mean.js index b859abaaf5d23..deec803c9b710 100644 --- a/lib/utils/did-you-mean.js +++ b/lib/utils/did-you-mean.js @@ -1,40 +1,33 @@ +const Npm = require('../npm') const { distance } = require('fastest-levenshtein') -const readJson = require('read-package-json-fast') -const { cmdList } = require('./cmd-list.js') +const { commands } = require('./cmd-list.js') -const didYouMean = async (npm, path, scmd) => { - // const cmd = await npm.cmd(str) - const close = cmdList.filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && scmd !== cmd) - let best = [] - for (const str of close) { - const cmd = await npm.cmd(str) - best.push(` npm ${str} # ${cmd.description}`) - } - // We would already be suggesting this in `npm x` so omit them here - const runScripts = ['stop', 'start', 'test', 'restart'] - try { - const { bin, scripts } = await readJson(`${path}/package.json`) - best = best.concat( - Object.keys(scripts || {}) - .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && !runScripts.includes(cmd)) - .map(str => ` npm run ${str} # run the "${str}" package script`), - Object.keys(bin || {}) - .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4) - /* eslint-disable-next-line max-len */ - .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) - ) - } catch (_) { - // gracefully ignore not being in a folder w/ a package.json - } +const runScripts = ['stop', 'start', 'test', 'restart'] + +const isClose = (scmd, cmd) => distance(scmd, cmd) < scmd.length * 0.4 + +const didYouMean = (pkg, scmd) => { + const { scripts = {}, bin = {} } = pkg || {} + + const best = [ + ...commands + .filter(cmd => isClose(scmd, cmd) && scmd !== cmd) + .map(str => [str, Npm.cmd(str).description]), + ...Object.keys(scripts) + // We would already be suggesting this in `npm x` so omit them here + .filter(cmd => isClose(scmd, cmd) && !runScripts.includes(cmd)) + .map(str => [`run ${str}`, `run the "${str}" package script`]), + ...Object.keys(bin) + .filter(cmd => isClose(scmd, cmd)) + .map(str => [`exec ${str}`, `run the "${str}" command from either this or a remote npm package`]), + ] if (best.length === 0) { 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 `\n\nDid you mean ${best.length === 1 ? 'this' : 'one of these'}?\n` + + best.slice(0, 3).map(([msg, comment]) => ` npm ${msg} # ${comment}`).join('\n') } + module.exports = didYouMean diff --git a/lib/utils/display.js b/lib/utils/display.js index a19f72297e838..dff16ceebef6f 100644 --- a/lib/utils/display.js +++ b/lib/utils/display.js @@ -1,118 +1,552 @@ -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 _logHandler = Symbol('logHandler') -const _eresolveWarn = Symbol('eresolveWarn') -const _log = Symbol('log') -const _npmlog = Symbol('npmlog') +// 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 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 +} + +// This is the key that is returned to the user for errors +const ERROR_KEY = 'error' +// This is the key producers use to indicate that there is a json error that should be merged into the finished output +const JSON_ERROR_KEY = 'jsonError' + +const isPlainObject = (v) => v && typeof v === 'object' && !Array.isArray(v) + +const getArrayOrObject = (items) => { + if (items.length) { + const foundNonObject = items.find(o => !isPlainObject(o)) + // Non-objects and arrays cant be merged, so just return the first item + if (foundNonObject) { + return foundNonObject + } + // We use objects with 0,1,2,etc keys to merge array + if (items.every((o, i) => Object.hasOwn(o, i))) { + return Object.assign([], ...items) + } + } + // Otherwise its an object with all object items merged together + return Object.assign({}, ...items.filter(o => isPlainObject(o))) +} + +const getJsonBuffer = ({ [JSON_ERROR_KEY]: metaError }, buffer) => { + const items = [] + // meta also contains the meta object passed to flush + const errors = metaError ? [metaError] : [] + // index 1 is the meta, 2 is the logged argument + for (const [, { [JSON_ERROR_KEY]: error }, obj] of buffer) { + if (obj) { + items.push(obj) + } + if (error) { + errors.push(error) + } + } + + if (!items.length && !errors.length) { + return null + } + + const res = getArrayOrObject(items) + + // This skips any error checking since we can only set an error property on an object that can be stringified + // XXX(BREAKING_CHANGE): remove this in favor of always returning an object with result and error keys + if (isPlainObject(res) && errors.length) { + // This is not ideal. + // JSON output has always been keyed at the root with an `error` key, so we cant change that without it being a breaking change. At the same time some commands output arbitrary keys at the top level of the output, such as package names. + // So the output could already have the same key. The choice here is to overwrite it with our error since that is (probably?) more important. + // XXX(BREAKING_CHANGE): all json output should be keyed under well known keys, eg `result` and `error` + if (res[ERROR_KEY]) { + log.warn('', `overwriting existing ${ERROR_KEY} on json output`) + } + res[ERROR_KEY] = getArrayOrObject(errors) + } + + return res +} + +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) +} class Display { - constructor () { - // pause by default until config is loaded - this.on() - log.pause() + #logState = { + buffering: true, + buffer: [], + } + + #outputState = { + buffering: true, + buffer: [], } - on () { - process.on('log', this[_logHandler]) + // colors + #noColorChalk + #stdoutChalk + #stdoutColor + #stderrChalk + #stderrColor + #logColors + + // progress + #progress + + // options + #command + #levelIndex + #timing + #json + #heading + #silent + + // display streams + #stdout + #stderr + + #seenNotices = new Set() + + 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, - timing, - loglevel, - unicode, - progress, - silent, - heading = 'npm', - } = config + process.off('log', this.#logHandler) + this.#logState.buffer.length = 0 + process.off('output', this.#outputHandler) + this.#outputState.buffer.length = 0 + process.off('input', this.#inputHandler) + this.#progress.off() + this.#seenNotices.clear() + } - // XXX: decouple timing from loglevel - if (timing && loglevel === 'notice') { - log.level = 'timing' - } else { - log.level = loglevel + get chalk () { + return { + noColor: this.#noColorChalk, + stdout: this.#stdoutChalk, + stderr: this.#stderrChalk, } + } + + async load ({ + command, + heading, + json, + loglevel, + progress, + stderrColor, + stdoutColor, + timing, + unicode, + }) { + 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, + 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 - log.heading = heading + // 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 - if (color) { - log.enableColor() - } else { - log.disableColor() + 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) => { + this.#json = typeof meta.json === 'boolean' ? meta.json : this.#json + switch (level) { + case output.KEYS.flush: { + this.#outputState.buffering = false + if (this.#json) { + const json = getJsonBuffer(meta, this.#outputState.buffer) + if (json) { + this.#writeOutput(output.KEYS.standard, meta, JSON.stringify(json, 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 { + // XXX: Check if the argument looks like a run-script banner. This should 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 don't 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 } + }) + + #inputHandler = withMeta((level, meta, ...args) => { + switch (level) { + case input.KEYS.start: + log.pause() + this.#outputState.buffering = true + this.#progress.off() + break - // if it's silent, don't show progress - if (progress && !silent) { - log.enableProgress() - } else { - log.disableProgress() + case input.KEYS.end: { + log.resume() + // For silent prompts (like password), add newline to preserve output + if (meta?.silent) { + output.standard('') + } + 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 + + // Use sequential input management to avoid race condition which causes issues with spinner and adding newlines. + input.start() + + return p() + .then((result) => { + // If user hits enter, process end event and return input. + input.end({ [META]: true, silent: meta?.silent }) + res(result) + return result + }) + .catch((error) => { + // If user hits ctrl+c, add newline to preserve output. + output.standard('') + input.end() + rej(error) + }) + } } + }) - // 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, meta, ...args) + break - log (...args) { - this[_logHandler](...args) + case output.KEYS.error: + this.#write(this.#stderr, meta, ...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, + ] + const writeOpts = { prefix } + // notice logs typically come from `npm-notice` headers in responses. Some of them have 2fa login links so we skip redaction. + if (level === 'notice') { + writeOpts.redact = false + // Deduplicate notices within a single command execution, unless in verbose mode + if (this.#levelIndex < LEVEL_OPTIONS.verbose.index) { + const noticeKey = JSON.stringify([title, ...args]) + if (this.#seenNotices.has(noticeKey)) { + return + } + this.#seenNotices.add(noticeKey) + } + } + this.#write(this.#stderr, writeOpts, ...args) + } } +} - // 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) +class Progress { + // Taken from https://github.com/sindresorhus/cli-spinners + // MIT License + // Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) + static dots = { duration: 80, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] } + static lines = { duration: 130, frames: ['-', '\\', '|', '/'] } + + #enabled = false + #frameIndex = 0 + #interval + #lastUpdate = 0 + #spinner + #stream + // Initial timeout to wait to start rendering + #timeout + #rendered = false + + // We are rendering if 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 + // Wait 200 ms so we don't render the spinner for short durations + this.#timeout = setTimeout(() => { + this.#timeout = null + this.#render() + }, 200) + // Make sure this timeout does not keep the process open + this.#timeout.unref() + } + + 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(true) + } + + // If we are currently 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 (resuming) { + 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, resuming) + if (!this.#interval) { + this.#interval = setInterval(() => this.#renderFrame(true), this.#spinner.duration) + // Make sure this timeout does not keep the process open + this.#interval.unref() + } + this.#interval.refresh() + } + + #renderFrame (next, resuming) { + if (next) { + this.#lastUpdate = Date.now() + this.#frameIndex++ + if (this.#frameIndex >= this.#spinner.frames.length) { + this.#frameIndex = 0 + } + } + if (!resuming) { + this.#clearSpinner() + } + this.#stream.write(this.#spinner.frames[this.#frameIndex]) + this.#rendered = true } - // 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, log.useColor(), 2)) - // Return true to short circuit other log in chain - return true + #clearSpinner () { + if (!this.#rendered) { + return } + // Move to the start of the line and clear the rest of the line + this.#stream.cursorTo(0) + this.#stream.clearLine(1) + this.#rendered = false } } diff --git a/lib/utils/error-message.js b/lib/utils/error-message.js index adf10a56f6d66..9faf4c339b1a5 100644 --- a/lib/utils/error-message.js +++ b/lib/utils/error-message.js @@ -1,202 +1,195 @@ -const { format } = require('util') -const { resolve } = require('path') -const nameValidator = require('validate-npm-package-name') -const replaceInfo = require('./replace-info.js') -const { report } = require('./explain-eresolve.js') -const log = require('./log-shim') - -module.exports = (er, npm) => { - const short = [] +const { format } = require('node:util') +const { resolve } = require('node:path') +const { redactLog: replaceInfo } = require('@npmcli/redact') +const { log } = require('proc-log') + +const errorMessage = (er, npm) => { + const summary = [] const detail = [] + const files = [] + let json - if (er.message) { - er.message = replaceInfo(er.message) - } - if (er.stack) { - er.stack = replaceInfo(er.stack) - } + er.message &&= replaceInfo(er.message) + er.stack &&= replaceInfo(er.stack) switch (er.code) { - case 'ERESOLVE': - short.push(['ERESOLVE', er.message]) + case 'ERESOLVE': { + const { report } = require('./explain-eresolve.js') + summary.push(['ERESOLVE', er.message]) detail.push(['', '']) // XXX(display): error messages are logged so we use the logColor since that is based // on stderr. This should be handled solely by the display layer so it could also be // printed to stdout if necessary. - detail.push(['', report(er, !!npm.logColor, resolve(npm.cache, 'eresolve-report.txt'))]) + const { explanation, file } = report(er, npm.logChalk, npm.noColorChalk) + detail.push(['', explanation]) + files.push(['eresolve-report.txt', file]) break + } case 'ENOLOCK': { const cmd = npm.command || '' - short.push([cmd, 'This command requires an existing lockfile.']) + summary.push([cmd, 'This command requires an existing lockfile.']) detail.push([cmd, 'Try creating one first with: npm i --package-lock-only']) detail.push([cmd, `Original error: ${er.message}`]) break } case 'ENOAUDIT': - short.push(['audit', er.message]) + summary.push(['audit', er.message]) break case 'ECONNREFUSED': - short.push(['', er]) - detail.push([ + summary.push(['', er]) + detail.push(['', [ '', - [ - '\nIf you are behind a proxy, please make sure that the', - "'proxy' config is set properly. See: 'npm help config'", - ].join('\n'), - ]) + 'If you are behind a proxy, please make sure that the', + "'proxy' config is set properly. See: 'npm help config'", + ].join('\n')]) break case 'EACCES': case 'EPERM': { const isCachePath = - typeof er.path === 'string' && - npm.config.loaded && - er.path.startsWith(npm.config.get('cache')) + typeof er.path === 'string' && npm.loaded && er.path.startsWith(npm.config.get('cache')) const isCacheDest = - typeof er.dest === 'string' && - npm.config.loaded && - er.dest.startsWith(npm.config.get('cache')) - - const { isWindows } = require('./is-windows.js') + typeof er.dest === 'string' && npm.loaded && er.dest.startsWith(npm.config.get('cache')) - 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([ + summary.push(['', [ '', - [ - '', - 'Your cache folder contains root-owned files, due to a bug in', - 'previous versions of npm which has since been addressed.', - '', - 'To permanently fix this problem, please run:', - ` sudo chown -R ${process.getuid()}:${process.getgid()} ${JSON.stringify( - npm.config.get('cache') - )}`, - ].join('\n'), - ]) + 'Your cache folder contains root-owned files, due to a bug in', + 'previous versions of npm which has since been addressed.', + '', + 'To permanently fix this problem, please run:', + ` sudo chown -R ${process.getuid()}:${process.getgid()} "${npm.config.get('cache')}"`, + ].join('\n')]) } else { - short.push(['', er]) - detail.push([ + summary.push(['', er]) + detail.push(['', [ '', - [ - '\nThe operation was rejected by your operating system.', - isWindows - /* 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.' - /* eslint-disable-next-line max-len */ - : 'It is likely you do not have the permissions to access this file as the current user', - '\nIf you believe this might be a permissions issue, please double-check the', - 'permissions of the file and its containing directories, or try running', - 'the command again as root/Administrator.', - ].join('\n'), - ]) + 'The operation was rejected by your operating system.', + ...process.platform === 'win32' ? [ + "It's possible that the file was already in use (by a text editor or antivirus),", + 'or that you lack permissions to access it.', + ] : [ + 'It is likely you do not have the permissions to access this file as the current user', + ], + '', + 'If you believe this might be a permissions issue, please double-check the', + 'permissions of the file and its containing directories, or try running', + 'the command again as root/Administrator.', + ].join('\n')]) } break } + case 'EALLOWGIT': + summary.push(['', er.message]) + detail.push(['', `Refusing to fetch "${er.package}"`]) + break + case 'ENOGIT': - short.push(['', er.message]) - detail.push([ + summary.push(['', er.message]) + detail.push(['', [ '', - ['', 'Failed using git.', 'Please check if you have git installed and in your PATH.'].join( - '\n' - ), - ]) + 'Failed using git.', + 'Please check if you have git installed and in your PATH.', + ].join('\n')]) break case 'EJSONPARSE': // Check whether we ran into a conflict in our own package.json if (er.path === resolve(npm.prefix, 'package.json')) { const { isDiff } = require('parse-conflict-json') - const txt = require('fs').readFileSync(er.path, 'utf8').replace(/\r\n/g, '\n') + const txt = require('node:fs').readFileSync(er.path, 'utf8').replace(/\r\n/g, '\n') if (isDiff(txt)) { - detail.push([ + detail.push(['', [ + 'Merge conflict detected in your package.json.', '', - [ - 'Merge conflict detected in your package.json.', - '', - 'Please resolve the package.json conflict and retry.', - ].join('\n'), - ]) + 'Please resolve the package.json conflict and retry.', + ].join('\n')]) break } } - short.push(['JSON.parse', er.message]) - detail.push([ - 'JSON.parse', - [ - 'Failed to parse JSON data.', - 'Note: package.json must be actual JSON, not just JavaScript.', - ].join('\n'), - ]) + summary.push(['JSON.parse', er.message]) + detail.push(['JSON.parse', [ + 'Failed to parse JSON data.', + 'Note: package.json must be actual JSON, not just JavaScript.', + ].join('\n')]) break case 'EOTP': case 'E401': // E401 is for places where we accidentally neglect OTP stuff if (er.code === 'EOTP' || /one-time pass/.test(er.message)) { - short.push(['', 'This operation requires a one-time password from your authenticator.']) - detail.push([ - '', - [ + const authUrl = er.body?.authUrl + const doneUrl = er.body?.doneUrl + if (authUrl && doneUrl) { + json = { authUrl, doneUrl } + summary.push(['', 'This operation requires a one-time password.']) + detail.push(['', `Open this URL in your browser to authenticate:`]) + detail.push(['', ` ${authUrl}`]) + detail.push(['', '']) + detail.push(['', `After authenticating, your token can be retrieved from:`]) + detail.push(['', ` ${doneUrl}`]) + } else { + summary.push(['', 'This operation requires a one-time password from your authenticator.']) + detail.push(['', [ 'You can provide a one-time password by passing --otp=<code> to the command you ran.', 'If you already provided a one-time password then it is likely that you either typoed', 'it, or it timed out. Please try again.', - ].join('\n'), - ]) + ].join('\n')]) + } } else { // npm ERR! code E401 // npm ERR! Unable to authenticate, need: Basic - const auth = - !er.headers || !er.headers['www-authenticate'] - ? [] - : er.headers['www-authenticate'].map(au => au.split(/[,\s]+/))[0] + const auth = !er.headers || !er.headers['www-authenticate'] + ? [] + : er.headers['www-authenticate'].map(au => au.split(/[,\s]+/))[0] if (auth.includes('Bearer')) { - short.push([ - '', + summary.push(['', 'Unable to authenticate, your authentication token seems to be invalid.', ]) - detail.push([ - '', - ['To correct this please trying logging in again with:', ' npm login'].join('\n'), - ]) + detail.push(['', [ + 'To correct this please try logging in again with:', + ' npm login', + ].join('\n')]) } else if (auth.includes('Basic')) { - short.push(['', 'Incorrect or missing password.']) - detail.push([ + summary.push(['', 'Incorrect or missing password.']) + detail.push(['', [ + 'If you were trying to login, change your password, create an', + 'authentication token or enable two-factor authentication then', + 'that means you likely typed your password in incorrectly.', + 'Please try again, or recover your password at:', + ' https://www.npmjs.com/forgot', '', - [ - 'If you were trying to login, change your password, create an', - 'authentication token or enable two-factor authentication then', - 'that means you likely typed your password in incorrectly.', - 'Please try again, or recover your password at:', - ' https://www.npmjs.com/forgot', - '', - 'If you were doing some other operation then your saved credentials are', - 'probably out of date. To correct this please try logging in again with:', - ' npm login', - ].join('\n'), - ]) + 'If you were doing some other operation then your saved credentials are', + 'probably out of date. To correct this please try logging in again with:', + ' npm login', + ].join('\n')]) } else { - short.push(['', er.message || er]) + summary.push(['', er.message || er]) } } break case 'E404': // There's no need to have 404 in the message as well. - short.push(['404', er.message.replace(/^404\s+/, '')]) + summary.push(['404', er.message.replace(/^404\s+/, '')]) if (er.pkgid && er.pkgid !== '-') { const pkg = er.pkgid.replace(/(?!^)@.*$/, '') detail.push(['404', '']) - detail.push(['404', '', `'${replaceInfo(er.pkgid)}' is not in this registry.`]) + detail.push([ + '404', + '', + `The requested resource '${replaceInfo(er.pkgid)}' could not be found or you do not have permission to access it.`, + ]) + const nameValidator = require('validate-npm-package-name') const valResult = nameValidator(pkg) if (!valResult.validForNewPackages) { @@ -206,71 +199,84 @@ module.exports = (er, npm) => { errorsArray.forEach((item, idx) => detail.push(['404', ' ' + (idx + 1) + '. ' + item])) } - detail.push(['404', '\nNote that you can also install from a']) + detail.push(['404', '']) + detail.push(['404', 'Note that you can also install from a']) detail.push(['404', 'tarball, folder, http url, or git url.']) } break case 'EPUBLISHCONFLICT': - short.push(['publish fail', 'Cannot publish over existing version.']) + summary.push(['publish fail', 'Cannot publish over existing version.']) detail.push(['publish fail', "Update the 'version' field in package.json and try again."]) detail.push(['publish fail', '']) detail.push(['publish fail', 'To automatically increment version numbers, see:']) - detail.push(['publish fail', ' npm help version']) + detail.push(['publish fail', ' npm help version']) break case 'EISGIT': - short.push(['git', er.message]) - short.push(['git', ' ' + er.path]) - detail.push([ - 'git', - ['Refusing to remove it. Update manually,', 'or move it out of the way first.'].join('\n'), - ]) + summary.push(['git', er.message]) + summary.push(['git', ` ${er.path}`]) + detail.push(['git', [ + 'Refusing to remove it. Update manually,', + 'or move it out of the way first.', + ].join('\n')]) + break + + case 'EBADDEVENGINES': { + const { current, required } = er + summary.push(['EBADDEVENGINES', er.message]) + detail.push(['EBADDEVENGINES', { current, required }]) break + } case 'EBADPLATFORM': { - const validOs = - er.required && er.required.os && er.required.os.join - ? er.required.os.join(',') - : er.required.os - const validArch = - er.required && er.required.cpu && er.required.cpu.join - ? er.required.cpu.join(',') - : er.required.cpu - const expected = { os: validOs, arch: validArch } - const actual = { os: process.platform, arch: process.arch } - short.push([ - 'notsup', - [ - format( - 'Unsupported platform for %s: wanted %j (current: %j)', - er.pkgid, - expected, - actual - ), - ].join('\n'), - ]) - detail.push([ - 'notsup', - [ - 'Valid OS: ' + validOs, - 'Valid Arch: ' + validArch, - 'Actual OS: ' + process.platform, - 'Actual Arch: ' + process.arch, - ].join('\n'), - ]) + const actual = er.current + const expected = { ...er.required } + const checkedKeys = [] + for (const key in expected) { + if (Array.isArray(expected[key]) && expected[key].length > 0) { + expected[key] = expected[key].join(',') + checkedKeys.push(key) + } else if (expected[key] === undefined || + Array.isArray(expected[key]) && expected[key].length === 0) { + delete expected[key] + delete actual[key] + } else { + checkedKeys.push(key) + } + } + + const longestKey = Math.max(...checkedKeys.map((key) => key.length)) + const detailEntry = [] + for (const key of checkedKeys) { + const padding = key.length === longestKey + ? 1 + : 1 + (longestKey - key.length) + + // padding + 1 because 'actual' is longer than 'valid' + detailEntry.push(`Valid ${key}:${' '.repeat(padding + 1)}${expected[key]}`) + detailEntry.push(`Actual ${key}:${' '.repeat(padding)}${actual[key]}`) + } + + summary.push(['notsup', format( + 'Unsupported platform for %s: wanted %j (current: %j)', + er.pkgid, + expected, + actual + )]) + detail.push(['notsup', detailEntry.join('\n')]) break } case 'EEXIST': - short.push(['', er.message]) - short.push(['', 'File exists: ' + (er.dest || er.path)]) + summary.push(['', er.message]) + summary.push(['', 'File exists: ' + (er.dest || er.path)]) detail.push(['', 'Remove the existing file and try again, or run npm']) detail.push(['', 'with --force to overwrite files recklessly.']) break case 'ENEEDAUTH': - short.push(['need auth', er.message]) + summary.push(['need auth', er.message]) detail.push(['need auth', 'You need to authorize this machine using `npm adduser`']) break @@ -279,124 +285,187 @@ module.exports = (er, npm) => { case 'ETIMEDOUT': case 'ERR_SOCKET_TIMEOUT': case 'EAI_FAIL': - short.push(['network', er.message]) - detail.push([ - 'network', - [ - 'This is a problem related to network connectivity.', - 'In most cases you are behind a proxy or have bad network settings.', - '\nIf you are behind a proxy, please make sure that the', - "'proxy' config is set properly. See: 'npm help config'", - ].join('\n'), - ]) + summary.push(['network', er.message]) + detail.push(['network', [ + 'This is a problem related to network connectivity.', + 'In most cases you are behind a proxy or have bad network settings.', + '', + 'If you are behind a proxy, please make sure that the', + "'proxy' config is set properly. See: 'npm help config'", + ].join('\n')]) break case 'ETARGET': - short.push(['notarget', er.message]) - detail.push([ - 'notarget', - [ - 'In most cases you or one of your dependencies are requesting', - "a package version that doesn't exist.", - ].join('\n'), - ]) + summary.push(['notarget', er.message]) + detail.push(['notarget', [ + 'In most cases you or one of your dependencies are requesting', + "a package version that doesn't exist.", + ].join('\n')]) break case 'E403': - short.push(['403', er.message]) - detail.push([ - '403', - [ - 'In most cases, you or one of your dependencies are requesting', - 'a package version that is forbidden by your security policy, or', - 'on a server you do not have access to.', - ].join('\n'), - ]) + summary.push(['403', er.message]) + detail.push(['403', [ + 'In most cases, you or one of your dependencies are requesting', + 'a package version that is forbidden by your security policy, or', + 'on a server you do not have access to.', + ].join('\n')]) break case 'EBADENGINE': - short.push(['engine', er.message]) - short.push(['engine', 'Not compatible with your version of node/npm: ' + er.pkgid]) - detail.push([ - 'notsup', - [ - 'Not compatible with your version of node/npm: ' + er.pkgid, - 'Required: ' + JSON.stringify(er.required), - 'Actual: ' + - JSON.stringify({ - npm: npm.version, - node: npm.config.loaded ? npm.config.get('node-version') : process.version, - }), - ].join('\n'), - ]) + summary.push(['engine', er.message]) + summary.push(['engine', 'Not compatible with your version of node/npm: ' + er.pkgid]) + detail.push(['notsup', [ + 'Not compatible with your version of node/npm: ' + er.pkgid, + 'Required: ' + JSON.stringify(er.required), + 'Actual: ' + + JSON.stringify({ node: process.version, npm: npm.version }), + ].join('\n')]) break case 'ENOSPC': - short.push(['nospc', er.message]) - detail.push([ - 'nospc', - [ - 'There appears to be insufficient space on your system to finish.', - 'Clear up some disk space and try again.', - ].join('\n'), - ]) + summary.push(['nospc', er.message]) + detail.push(['nospc', [ + 'There appears to be insufficient space on your system to finish.', + 'Clear up some disk space and try again.', + ].join('\n')]) break case 'EROFS': - short.push(['rofs', er.message]) - detail.push([ - 'rofs', - [ - 'Often virtualized file systems, or other file systems', - "that don't support symlinks, give this error.", - ].join('\n'), - ]) + summary.push(['rofs', er.message]) + detail.push(['rofs', [ + 'Often virtualized file systems, or other file systems', + "that don't support symlinks, give this error.", + ].join('\n')]) break case 'ENOENT': - short.push(['enoent', er.message]) - detail.push([ - 'enoent', - [ - 'This is related to npm not being able to find a file.', - er.file ? "\nCheck if the file '" + er.file + "' is present." : '', - ].join('\n'), - ]) + summary.push(['enoent', er.message]) + detail.push(['enoent', [ + 'This is related to npm not being able to find a file.', + er.file ? `\nCheck if the file '${er.file}' is present.` : '', + ].join('\n')]) break case 'EMISSINGARG': case 'EUNKNOWNTYPE': case 'EINVALIDTYPE': case 'ETOOMANYARGS': - short.push(['typeerror', er.stack]) - detail.push([ - 'typeerror', - [ - 'This is an error with npm itself. Please report this error at:', - ' https://github.com/npm/cli/issues', - ].join('\n'), - ]) + summary.push(['typeerror', er.stack]) + detail.push(['typeerror', [ + 'This is an error with npm itself. Please report this error at:', + ' https://github.com/npm/cli/issues', + ].join('\n')]) break default: - short.push(['', er.message || er]) + summary.push(['', er.message || er]) + if (er.cause) { + detail.push(['cause', er.cause.message]) + } if (er.signal) { detail.push(['signal', er.signal]) } - if (er.cmd && Array.isArray(er.args)) { detail.push(['command', ...[er.cmd, ...er.args.map(replaceInfo)]]) } - if (er.stdout) { detail.push(['', er.stdout.trim()]) } - if (er.stderr) { detail.push(['', er.stderr.trim()]) } - break } - return { summary: short, detail: detail } + + return { + summary, + detail, + files, + json, + } +} + +const getExitCodeFromError = (err) => { + if (typeof err?.errno === 'number') { + return err.errno + } else if (typeof err?.code === 'number') { + return err.code + } +} + +const getError = (err, { npm, command, pkg }) => { + // if we got a command that just shells out to something else, then it + // will presumably print its own errors and exit with a proper status + // code if there's a problem. If we got an error with a code=0, then... + // something else went wrong along the way, so maybe an npm problem? + if (command?.constructor?.isShellout && typeof err.code === 'number' && err.code) { + return { + exitCode: err.code, + suppressError: true, + } + } + + // XXX: we should stop throwing strings + if (typeof err === 'string') { + return { + exitCode: 1, + suppressError: true, + summary: [['', err]], + } + } + + // XXX: we should stop throwing other non-errors + if (!(err instanceof Error)) { + return { + exitCode: 1, + suppressError: true, + summary: [['weird error', err]], + } + } + + if (err.code === 'EUNKNOWNCOMMAND') { + const suggestions = require('./did-you-mean.js')(pkg, err.command) + return { + exitCode: 1, + suppressError: true, + standard: [ + `Unknown command: "${err.command}"`, + suggestions, + 'To see a list of supported npm commands, run:', + ' npm help', + ], + } + } + + // Anything after this is not suppressed and get more logged information + + // add a code to the error if it doesnt have one and mutate some properties + // so they have redacted information + err.code ??= err.message.match(/^(?:Error: )?(E[A-Z]+)/)?.[1] + // this mutates the error and redacts stack/message + const { summary, detail, files, json } = errorMessage(err, npm) + + return { + err, + code: err.code, + exitCode: getExitCodeFromError(err) || 1, + suppressError: false, + summary, + detail, + files, + json, + verbose: ['type', 'stack', 'statusCode', 'pkgid'] + .filter(k => err[k]) + .map(k => [k, replaceInfo(err[k])]), + error: ['code', 'syscall', 'file', 'path', 'dest', 'errno'] + .filter(k => err[k]) + .map(k => [k, err[k]]), + } +} + +module.exports = { + getExitCodeFromError, + errorMessage, + getError, } diff --git a/lib/utils/exit-handler.js b/lib/utils/exit-handler.js deleted file mode 100644 index d8ae9994dfecc..0000000000000 --- a/lib/utils/exit-handler.js +++ /dev/null @@ -1,224 +0,0 @@ -const os = require('os') - -const log = require('./log-shim.js') -const errorMessage = require('./error-message.js') -const replaceInfo = require('./replace-info.js') - -const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n') -const indent = (val) => Array.isArray(val) ? val.map(v => indent(v)) : ` ${val}` - -let npm = null // set by the cli -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 hasNpm = !!npm - const hasLoadedNpm = hasNpm && npm.config.loaded - - // Unfinished timers can be read before config load - if (hasNpm) { - for (const [name, timer] of npm.unfinishedTimers) { - log.verbose('unfinished npm timer', name, timer) - } - } - - if (!code) { - log.info('ok') - } else { - log.verbose('code', 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('', ' <https://github.com/npm/cli/issues>') - 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:', indent(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:', ...indent(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')) - } - - // This removes any listeners npm setup, mostly for tests to avoid max listener warnings - npm.unload() - } - - // these are needed for the tests to have a clean slate in each test case - exitHandlerCalled = false - showLogFileError = false -}) - -const exitHandler = err => { - exitHandlerCalled = true - - log.disableProgress() - - const hasNpm = !!npm - const hasLoadedNpm = hasNpm && npm.config.loaded - - if (!hasNpm) { - err = err || new Error('Exit prior to setting npm in exit handler') - // eslint-disable-next-line no-console - console.error(err.stack || err.message) - return process.exit(1) - } - - if (!hasLoadedNpm) { - err = err || new Error('Exit prior to config file resolving.') - // 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 - } - - let exitCode - let noLogMessage - - if (err) { - exitCode = 1 - // if we got a command that just shells out to something else, then it - // will presumably print its own errors and exit with a proper status - // code if there's a problem. If we got an error with a code=0, then... - // something else went wrong along the way, so maybe an npm problem? - const isShellout = npm.commandInstance && npm.commandInstance.constructor.isShellout - const quietShellout = isShellout && typeof err.code === 'number' && err.code - if (quietShellout) { - exitCode = err.code - noLogMessage = true - } else if (typeof err === 'string') { - // XXX: we should stop throwing strings - log.error('', err) - noLogMessage = true - } else if (!(err instanceof Error)) { - log.error('weird error', err) - noLogMessage = true - } else { - if (!err.code) { - const matchErrorCode = err.message.match(/^(?:Error: )?(E[A-Z]+)/) - err.code = matchErrorCode && matchErrorCode[1] - } - - for (const k of ['type', 'stack', 'statusCode', 'pkgid']) { - const v = err[k] - if (v) { - log.verbose(k, replaceInfo(v)) - } - } - - log.verbose('cwd', process.cwd()) - log.verbose('', os.type() + ' ' + os.release()) - log.verbose('node', process.version) - log.verbose('npm ', 'v' + npm.version) - - for (const k of ['code', 'syscall', 'file', 'path', 'dest', 'errno']) { - const v = err[k] - if (v) { - log.error(k, v) - } - } - - const msg = errorMessage(err, npm) - for (const errline of [...msg.summary, ...msg.detail]) { - log.error(...errline) - } - - if (hasLoadedNpm && npm.config.get('json')) { - const error = { - error: { - code: err.code, - summary: messageText(msg.summary), - detail: messageText(msg.detail), - }, - } - npm.outputError(JSON.stringify(error, null, 2)) - } - - if (typeof err.errno === 'number') { - exitCode = err.errno - } else if (typeof err.code === 'number') { - exitCode = err.code - } - } - } - - log.verbose('exit', exitCode || 0) - - showLogFileError = (hasLoadedNpm && npm.silent) || noLogMessage - ? false - : !!exitCode - - // explicitly call process.exit now so we don't hang on things like the - // update notifier, also flush stdout/err beforehand because process.exit doesn't - // wait for that to happen. - let flushed = 0 - const flush = [process.stderr, process.stdout] - const exit = () => ++flushed === flush.length && process.exit(exitCode) - flush.forEach((f) => f.write('', exit)) -} - -module.exports = exitHandler -module.exports.setNpm = n => (npm = n) diff --git a/lib/utils/explain-dep.js b/lib/utils/explain-dep.js index 107f68549ef1d..4e9e93454e8a2 100644 --- a/lib/utils/explain-dep.js +++ b/lib/utils/explain-dep.js @@ -1,94 +1,57 @@ -const chalk = require('chalk') -const nocolor = { - bold: s => s, - dim: s => s, - red: s => s, - yellow: s => s, - cyan: s => s, - magenta: s => s, - blue: s => s, - green: s => s, -} - -const { relative } = require('path') - -const explainNode = (node, depth, color) => - printNode(node, color) + - explainDependents(node, depth, color) + - explainLinksIn(node, depth, color) - -const colorType = (type, color) => { - const { red, yellow, cyan, magenta, blue, green } = color ? chalk : nocolor - const style = type === 'extraneous' ? red - : type === 'dev' ? yellow - : type === 'optional' ? cyan - : type === 'peer' ? magenta - : type === 'bundled' ? blue - : type === 'workspace' ? green +const { relative } = require('node:path') + +const explainNode = (node, depth, chalk) => + printNode(node, chalk) + + explainDependents(node, depth, chalk) + + explainLinksIn(node, depth, chalk) + +const colorType = (type, chalk) => { + 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, color) => { - const { - name, - version, - location, - extraneous, - dev, - optional, - peer, - bundled, - isWorkspace, - } = node - const { bold, dim, green } = color ? chalk : nocolor +const printNode = (node, chalk) => { const extra = [] - if (extraneous) { - extra.push(' ' + bold(colorType('extraneous', color))) - } - - if (dev) { - extra.push(' ' + bold(colorType('dev', color))) - } - - if (optional) { - extra.push(' ' + bold(colorType('optional', color))) - } - - if (peer) { - extra.push(' ' + bold(colorType('peer', color))) - } - if (bundled) { - extra.push(' ' + bold(colorType('bundled', color))) + 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, color) => { +const explainLinksIn = ({ linksIn }, depth, chalk) => { if (!linksIn || !linksIn.length || depth <= 0) { return '' } - const messages = linksIn.map(link => explainNode(link, depth - 1, color)) + const messages = linksIn.map(link => explainNode(link, depth - 1, chalk)) const str = '\n' + messages.join('\n') return str.split('\n').join('\n ') } -const explainDependents = ({ name, dependents }, depth, color) => { +const explainDependents = ({ dependents }, depth, chalk) => { if (!dependents || !dependents.length || depth <= 0) { return '' } const max = Math.ceil(depth / 2) const messages = dependents.slice(0, max) - .map(edge => explainEdge(edge, depth, color)) + .map(edge => explainEdge(edge, depth, chalk)) // show just the names of the first 5 deps that overflowed the list if (dependents.length > max) { @@ -96,13 +59,13 @@ const explainDependents = ({ name, dependents }, depth, color) => { const maxLen = 50 const showNames = [] for (let i = max; i < dependents.length; i++) { - const { from: { name = 'the root project' } } = dependents[i] - len += name.length + const { from: { name: depName = 'the root project' } } = dependents[i] + len += depName.length if (len >= maxLen && i < dependents.length - 1) { showNames.push('...') break } - showNames.push(name) + showNames.push(depName) } const show = `(${showNames.join(', ')})` messages.push(`${dependents.length - max} more ${show}`) @@ -112,26 +75,29 @@ const explainDependents = ({ name, dependents }, depth, color) => { return str.split('\n').join('\n ') } -const explainEdge = ({ name, type, bundled, from, spec }, depth, color) => { - const { bold } = color ? chalk : nocolor - const dep = type === 'workspace' - ? bold(relative(from.location, spec.slice('file:'.length))) - : `${bold(name)}@"${bold(spec)}"` - const fromMsg = ` from ${explainFrom(from, depth, color)}` +const explainEdge = ({ name, type, bundled, from, spec, rawSpec, overridden }, depth, chalk) => { + let dep = type === 'workspace' + ? chalk.bold(relative(from.location, spec.slice('file:'.length))) + : `${name}@"${spec}"` + if (overridden) { + dep = `${colorType('overridden', chalk)} ${dep} (was "${rawSpec}")` + } + + const fromMsg = ` from ${explainFrom(from, depth, chalk)}` - return (type === 'prod' ? '' : `${colorType(type, color)} `) + - (bundled ? `${colorType('bundled', color)} ` : '') + + return (type === 'prod' ? '' : `${colorType(type, chalk)} `) + + (bundled ? `${colorType('bundled', chalk)} ` : '') + `${dep}${fromMsg}` } -const explainFrom = (from, depth, color) => { +const explainFrom = (from, depth, chalk) => { if (!from.name && !from.version) { return 'the root project' } - return printNode(from, color) + - explainDependents(from, depth - 1, color) + - explainLinksIn(from, depth - 1, color) + return printNode(from, chalk) + + explainDependents(from, depth - 1, chalk) + + explainLinksIn(from, depth - 1, chalk) } module.exports = { explainNode, printNode, explainEdge } diff --git a/lib/utils/explain-eresolve.js b/lib/utils/explain-eresolve.js index 7f6a10869c73c..f3c6ae23a479d 100644 --- a/lib/utils/explain-eresolve.js +++ b/lib/utils/explain-eresolve.js @@ -1,14 +1,13 @@ // this is called when an ERESOLVE error is caught in the exit-handler, // or when there's a log.warn('eresolve', msg, explanation), to turn it // into a human-intelligible explanation of what's wrong and how to fix. -const { writeFileSync } = require('fs') const { explainEdge, explainNode, printNode } = require('./explain-dep.js') // expl is an explanation object that comes from Arborist. It looks like: // Depth is how far we want to want to descend into the object making a report. // The full report (ie, depth=Infinity) is always written to the cache folder // at ${cache}/eresolve-report.txt along with full json. -const explain = (expl, color, depth) => { +const explain = (expl, chalk, depth) => { const { edge, dep, current, peerConflict, currentEdge } = expl const out = [] @@ -16,28 +15,28 @@ const explain = (expl, color, depth) => { current && current.whileInstalling || edge && edge.from && edge.from.whileInstalling if (whileInstalling) { - out.push('While resolving: ' + printNode(whileInstalling, color)) + out.push('While resolving: ' + printNode(whileInstalling, chalk)) } // it "should" be impossible for an ERESOLVE explanation to lack both // current and currentEdge, but better to have a less helpful error // than a crashing failure. if (current) { - out.push('Found: ' + explainNode(current, depth, color)) + out.push('Found: ' + explainNode(current, depth, chalk)) } else if (peerConflict && peerConflict.current) { - out.push('Found: ' + explainNode(peerConflict.current, depth, color)) + out.push('Found: ' + explainNode(peerConflict.current, depth, chalk)) } else if (currentEdge) { - out.push('Found: ' + explainEdge(currentEdge, depth, color)) + out.push('Found: ' + explainEdge(currentEdge, depth, chalk)) } else /* istanbul ignore else - should always have one */ if (edge) { - out.push('Found: ' + explainEdge(edge, depth, color)) + out.push('Found: ' + explainEdge(edge, depth, chalk)) } out.push('\nCould not resolve dependency:\n' + - explainEdge(edge, depth, color)) + explainEdge(edge, depth, chalk)) if (peerConflict) { const heading = '\nConflicting peer dependency:' - const pc = explainNode(peerConflict.peer, depth, color) + const pc = explainNode(peerConflict.peer, depth, chalk) out.push(heading + ' ' + pc) } @@ -45,27 +44,25 @@ const explain = (expl, color, depth) => { } // generate a full verbose report and tell the user how to fix it -const report = (expl, color, fullReport) => { - const orNoStrict = expl.strictPeerDeps ? '--no-strict-peer-deps, ' : '' - const fix = `Fix the upstream dependency conflict, or retry -this command with ${orNoStrict}--force, or --legacy-peer-deps -to accept an incorrect (and potentially broken) dependency resolution.` - - writeFileSync(fullReport, `# npm resolution error report - -${new Date().toISOString()} - -${explain(expl, false, Infinity)} +const report = (expl, chalk, noColorChalk) => { + const flags = [ + expl.strictPeerDeps ? '--no-strict-peer-deps' : '', + '--force', + '--legacy-peer-deps', + ].filter(Boolean) -${fix} + const or = (arr) => arr.length <= 2 + ? arr.join(' or ') : + arr.map((v, i, l) => i + 1 === l.length ? `or ${v}` : v).join(', ') -Raw JSON explanation object: - -${JSON.stringify(expl, null, 2)} -`, 'utf8') + const fix = `Fix the upstream dependency conflict, or retry +this command with ${or(flags)} +to accept an incorrect (and potentially broken) dependency resolution.` - return explain(expl, color, 4) + - `\n\n${fix}\n\nSee ${fullReport} for a full report.` + return { + explanation: `${explain(expl, chalk, 4)}\n\n${fix}`, + file: `# npm resolution error report\n\n${explain(expl, noColorChalk, Infinity)}\n\n${fix}`, + } } module.exports = { diff --git a/lib/utils/format-bytes.js b/lib/utils/format-bytes.js index d293001df5524..b5c53484825eb 100644 --- a/lib/utils/format-bytes.js +++ b/lib/utils/format-bytes.js @@ -13,12 +13,12 @@ const formatBytes = (bytes, space = true) => { return `${bytes}${spacer}B` } - if (bytes < 1000000) { + if (bytes < 999950) { // kB return `${(bytes / 1000).toFixed(1)}${spacer}kB` } - if (bytes < 1000000000) { + if (bytes < 999950000) { // MB return `${(bytes / 1000000).toFixed(1)}${spacer}MB` } diff --git a/lib/utils/format-search-stream.js b/lib/utils/format-search-stream.js index 2a2dadd5c3434..6d4e20a2d6340 100644 --- a/lib/utils/format-search-stream.js +++ b/lib/utils/format-search-stream.js @@ -1,5 +1,5 @@ -const Minipass = require('minipass') -const columnify = require('columnify') +const { stripVTControlCharacters: strip } = require('node:util') +const { Minipass } = require('minipass') // This module consumes package data in the following format: // @@ -15,14 +15,48 @@ const columnify = require('columnify') // The returned stream will format this package data // into a byte stream of formatted, displayable output. +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() : new TextOutputStream(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 @@ -40,121 +74,100 @@ class JSONOutputStream extends Minipass { } class TextOutputStream extends Minipass { + #args + #chalk + #exclude + #parseable + constructor (opts) { super() - this._opts = opts - this._line = 0 + // Consider a search for "cowboys" and "boy". If we highlight "boys" first the "cowboys" string will no longer string match because of the ansi highlighting added to "boys". If we highlight "boy" second then the ansi reset at the end will make the highlighting only on "cowboy" with a normal "s". Neither is perfect but at least the first option doesn't do partial highlighting. So, we sort strings smaller to larger + this.#args = opts.args + .map(s => s.toLowerCase()) + .filter(Boolean) + .sort((a, b) => a.length - b.length) + this.#chalk = opts.npm.chalk + this.#exclude = opts.exclude + this.#parseable = opts.parseable } - write (pkg) { - return super.write(prettify(pkg, ++this._line, this._opts)) - } -} - -function prettify (data, num, opts) { - var truncate = !opts.long - - var pkg = normalizePackage(data, opts) - - var columns = ['name', 'description', 'author', 'date', 'version', 'keywords'] - - if (opts.parseable) { - return columns.map(function (col) { - return pkg[col] && ('' + pkg[col]).replace(/\t/g, ' ') - }).join('\t') - } - - // 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: num <= 1, - columnSplitter: ' | ', - truncate: truncate, - 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 }, - }, + write (data) { + if (!filter(data, this.#exclude)) { + return + } + // Normalize + const pkg = { + 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(strip) + } else if (typeof data.keywords === 'string') { + pkg.keywords = strip(data.keywords.replace(/[,\s]+/, ' ')).split(' ') } - ).split('\n').map(line => line.slice(0, maxWidth)).join('\n') - - if (opts.color) { - output = highlightSearchTerms(output, opts.args) - } - - return output -} - -var colors = [31, 33, 32, 36, 34, 35] -var cl = colors.length - -function addColorMarker (str, arg, i) { - var m = i % cl + 1 - var markStart = String.fromCharCode(m) - var markEnd = String.fromCharCode(0) - if (arg.charAt(0) === '/') { - return str.replace( - new RegExp(arg.slice(1, -1), 'gi'), - bit => markStart + bit + markEnd - ) - } + 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) + } - // just a normal string, do the split/map thing - var pieces = str.toLowerCase().split(arg.toLowerCase()) - var p = 0 - - return pieces.map(function (piece) { - piece = str.slice(p, p + piece.length) - var mark = markStart + - str.slice(p + piece.length, p + piece.length + arg.length) + - markEnd - p += piece.length + arg.length - return piece + mark - }).join('') -} + const keywords = pkg.keywords.map(k => { + if (this.#args.includes(k)) { + return this.#chalk.cyan(k) + } else { + return k + } + }).join(' ') + + const description = this.#highlight(pkg.description) + let name + if (this.#args.includes(pkg.name)) { + name = this.#chalk.cyan(pkg.name) + } else { + name = this.#highlight(pkg.name) + name = this.#chalk.blue(name) + } -function colorize (line) { - for (var i = 0; i < cl; i++) { - var m = i + 1 - var color = '\u001B[' + colors[i] + 'm' - line = line.split(String.fromCharCode(m)).join(color) + if (description.length) { + output = `${name}\n${description}\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` + } + output += `${this.#chalk.blue(`https://npm.im/${pkg.name}`)}\n` + return super.write(output) } - var uncolor = '\u001B[0m' - return line.split('\u0000').join(uncolor) -} - -function highlightSearchTerms (str, terms) { - terms.forEach(function (arg, i) { - str = addColorMarker(str, arg, i) - }) - return colorize(str).trim() -} - -function normalizePackage (data, opts) { - return { - name: data.name, - description: data.description, - author: data.maintainers.map((m) => `=${m.username}`).join(' '), - keywords: Array.isArray(data.keywords) - ? data.keywords.join(' ') - : typeof data.keywords === 'string' - ? data.keywords.replace(/[,\s]+/, ' ') - : '', - version: data.version, - date: (data.date && - (data.date.toISOString() // remove time - .split('T').join(' ') - .replace(/:[0-9]{2}\.[0-9]{3}Z$/, '')) - .slice(0, -5)) || - 'prehistoric', + #highlight (input) { + let output = input + for (const arg of this.#args) { + let i = output.toLowerCase().indexOf(arg) + while (i > -1) { + const highlit = this.#chalk.cyan(output.slice(i, i + arg.length)) + output = [ + output.slice(0, i), + highlit, + output.slice(i + arg.length), + ].join('') + i = output.toLowerCase().indexOf(arg, i + highlit.length) + } + } + return output } } diff --git a/lib/utils/format.js b/lib/utils/format.js new file mode 100644 index 0000000000000..3161abd7ea4de --- /dev/null +++ b/lib/utils/format.js @@ -0,0 +1,56 @@ +// All logging goes through here, both to console and log files + +const { formatWithOptions: baseFormatWithOptions } = require('node:util') +const { redactLog } = require('@npmcli/redact') + +// 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', redact = true, ...options }, ...args) => { + const prefix = prefixes.filter(p => p != null).join(' ') + let formatted = STRIP_C01(baseFormatWithOptions(options, ...args)) + if (redact) { + formatted = redactLog(formatted) + } + // 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/lib/utils/get-identity.js b/lib/utils/get-identity.js index 41d882473ab7b..d8f59da14247a 100644 --- a/lib/utils/get-identity.js +++ b/lib/utils/get-identity.js @@ -12,7 +12,9 @@ module.exports = async (npm, opts) => { // No username, but we have other credentials; fetch the username from registry if (creds.token || creds.certfile && creds.keyfile) { const registryData = await npmFetch.json('/-/whoami', { ...opts }) - return registryData.username + if (typeof registryData?.username === 'string') { + return registryData.username + } } // At this point, even if they have a credentials object, it doesn't have a diff --git a/lib/utils/get-workspaces.js b/lib/utils/get-workspaces.js new file mode 100644 index 0000000000000..48c26779bb137 --- /dev/null +++ b/lib/utils/get-workspaces.js @@ -0,0 +1,54 @@ +const { resolve, relative } = require('node:path') +const mapWorkspaces = require('@npmcli/map-workspaces') +const { minimatch } = require('minimatch') +const pkgJson = require('@npmcli/package-json') + +// minimatch wants forward slashes only for glob patterns +const globify = pattern => pattern.split('\\').join('/') + +// Returns an Map of paths to workspaces indexed by workspace name +// { foo => '/path/to/foo' } +const getWorkspaces = async (filters, { path, includeWorkspaceRoot, relativeFrom }) => { + // TODO we need a better error to be bubbled up here if this call fails + const { content: pkg } = await pkgJson.normalize(path) + const workspaces = await mapWorkspaces({ cwd: path, pkg }) + let res = new Map() + if (includeWorkspaceRoot) { + res.set(pkg.name, path) + } + + if (!filters.length) { + res = new Map([...res, ...workspaces]) + } + + for (const filterArg of filters) { + for (const [workspaceName, workspacePath] of workspaces.entries()) { + let relativePath = relative(relativeFrom, workspacePath) + if (filterArg.startsWith('./')) { + relativePath = `./${relativePath}` + } + const relativeFilter = relative(path, filterArg) + if (filterArg === workspaceName + || resolve(relativeFrom, filterArg) === workspacePath + || minimatch(relativePath, `${globify(relativeFilter)}/*`) + || minimatch(relativePath, `${globify(filterArg)}/*`) + ) { + res.set(workspaceName, workspacePath) + } + } + } + + if (!res.size) { + let msg = '!' + if (filters.length) { + msg = `:\n ${filters.reduce( + (acc, filterArg) => `${acc} --workspace=${filterArg}`, '')}` + } + + throw new Error(`No workspaces found${msg}`) + } + + return res +} + +module.exports = getWorkspaces diff --git a/lib/utils/installed-deep.js b/lib/utils/installed-deep.js new file mode 100644 index 0000000000000..3c56c5d036f25 --- /dev/null +++ b/lib/utils/installed-deep.js @@ -0,0 +1,45 @@ +const { resolve } = require('node:path') +const localeCompare = require('@isaacs/string-locale-compare')('en') + +const installedDeep = async (npm) => { + const Arborist = require('@npmcli/arborist') + const { + depth, + global, + prefix, + workspacesEnabled, + } = npm.flatOptions + + const getValues = (tree) => + [...tree.inventory.values()] + .filter(i => i.location !== '' && !i.isRoot) + .map(i => { + return i + }) + .filter(i => (i.depth - 1) <= depth) + .sort((a, b) => (a.depth - b.depth) || localeCompare(a.name, b.name)) + + const res = new Set() + const gArb = new Arborist({ + global: true, + path: resolve(npm.globalDir, '..'), + workspacesEnabled, + }) + const gTree = await gArb.loadActual({ global: true }) + + for (const node of getValues(gTree)) { + res.add(global ? node.name : [node.name, '-g']) + } + + if (!global) { + const arb = new Arborist({ global: false, path: prefix, workspacesEnabled }) + const tree = await arb.loadActual() + for (const node of getValues(tree)) { + res.add(node.name) + } + } + + return [...res] +} + +module.exports = installedDeep diff --git a/lib/utils/installed-shallow.js b/lib/utils/installed-shallow.js new file mode 100644 index 0000000000000..d59318fe78541 --- /dev/null +++ b/lib/utils/installed-shallow.js @@ -0,0 +1,19 @@ +const { readdirScoped } = require('@npmcli/fs') + +const installedShallow = async (npm, opts) => { + const names = async global => { + const paths = await readdirScoped(global ? npm.globalDir : npm.localDir) + return paths.map(p => p.replace(/\\/g, '/')) + } + const { conf: { argv: { remain } } } = opts + if (remain.length > 3) { + return null + } + + const { global } = npm.flatOptions + const locals = global ? [] : await names(false) + const globals = (await names(true)).map(n => global ? n : `${n} -g`) + return [...locals, ...globals] +} + +module.exports = installedShallow diff --git a/lib/utils/is-windows.js b/lib/utils/is-windows.js index 57f6599b6ae19..63c5671d8400e 100644 --- a/lib/utils/is-windows.js +++ b/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/lib/utils/log-file.js b/lib/utils/log-file.js index d62329c8551e2..c7c1d754009a3 100644 --- a/lib/utils/log-file.js +++ b/lib/utils/log-file.js @@ -1,32 +1,16 @@ -const os = require('os') -const path = require('path') -const { format, promisify } = require('util') -const rimraf = promisify(require('rimraf')) -const glob = promisify(require('glob')) -const MiniPass = require('minipass') +const os = require('node:os') +const { join, dirname, basename } = require('node:path') const fsMiniPass = require('fs-minipass') -const fs = require('@npmcli/fs') -const log = require('./log-shim') +const fs = require('node:fs/promises') +const { log } = require('proc-log') +const { formatWithOptions } = require('./format') const padZero = (n, length) => n.toString().padStart(length.toString().length, '0') -const globify = pattern => pattern.split('\\').join('/') - -const _logHandler = Symbol('logHandler') -const _formatLogItem = Symbol('formatLogItem') -const _getLogFilePath = Symbol('getLogFilePath') -const _openLogFile = Symbol('openLogFile') -const _cleanLogs = Symbol('cleanlogs') -const _endStream = Symbol('endStream') -const _isBuffered = Symbol('isBuffered') class LogFiles { - // If we write multiple log files we want them all to have the same - // identifier for sorting and matching purposes - #logId = null - - // 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 @@ -41,97 +25,87 @@ class LogFiles { #fileLogCount = 0 #totalLogCount = 0 - #dir = null + #path = null #logsMax = null #files = [] + #timing = false constructor ({ maxLogsPerFile = 50_000, maxFilesPerProcess = 5, } = {}) { - this.#logId = LogFiles.logId(new Date()) this.#MAX_LOGS_PER_FILE = maxLogsPerFile this.#MAX_FILES_PER_PROCESS = maxFilesPerProcess this.on() } - static logId (d) { - return d.toISOString().replace(/[.:]/g, '_') - } - - static format (count, level, title, ...args) { - let prefix = `${count} ${level}` - if (title) { - prefix += ` ${title}` - } - - return format(...args) - .split(/\r?\n/) - .reduce((lines, line) => - lines += prefix + (line ? ' ' : '') + line + os.EOL, - '' - ) - } - on () { - this.#logStream = new MiniPass() - process.on('log', this[_logHandler]) + process.on('log', this.#logHandler) } off () { - process.off('log', this[_logHandler]) - this[_endStream]() + process.off('log', this.#logHandler) + this.#endStream() } - load ({ dir, logsMax = Infinity } = {}) { + load ({ command, path, logsMax = Infinity, timing } = {}) { + if (['completion'].includes(command)) { + return + } + // dir is user configurable and is required to exist so // this can error if the dir is missing or not configured correctly - this.#dir = dir + this.#path = path this.#logsMax = logsMax + this.#timing = timing // Log stream has already ended if (!this.#logStream) { return } - log.verbose('logfile', `logs-max:${logsMax} dir:${dir}`) + 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]() + 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) + return this.#cleanLogs() } get files () { return this.#files } - get [_isBuffered] () { - return this.#logStream instanceof MiniPass + get #isBuffered () { + return Array.isArray(this.#logStream) } - [_endStream] (output) { - if (this.#logStream) { + #endStream (output) { + if (this.#logStream && !this.#isBuffered) { this.#logStream.end(output) this.#logStream = null } } - [_logHandler] = (level, ...args) => { + #logHandler = (level, ...args) => { // Ignore pause and resume events since we // write everything to the log file if (level === 'pause' || level === 'resume') { @@ -143,41 +117,50 @@ class LogFiles { return } - const logOutput = this[_formatLogItem](level, ...args) - - if (this[_isBuffered]) { - // Cant do anything but buffer the output if we dont + if (this.#isBuffered) { + // Cant do anything but buffer the output if we don't // 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 } // Open a new log file if we've written too many logs to this one if (this.#fileLogCount >= this.#MAX_LOGS_PER_FILE) { // Write last chunk to the file and close it - this[_endStream](logOutput) + this.#endStream(logOutput) if (this.#files.length >= this.#MAX_FILES_PER_PROCESS) { // but if its way too many then we just stop listening this.off() } else { // otherwise we are ready for a new file for the next event - this.#logStream = this[_openLogFile]() + this.#logStream = this.#openLogFile() } } else { this.#logStream.write(logOutput) } } - [_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 = '') { - return path.resolve(this.#dir, `${this.#logId}-debug-${count}.log`) + #getLogFilePath (count = '') { + return `${this.#path}debug-${count}.log` } - [_openLogFile] () { + #openLogFile () { // Count in filename will be 0 indexed const count = this.#files.length @@ -186,16 +169,12 @@ class LogFiles { // We never want to write files ending in `-9.log` and `-10.log` because // log file cleaning is done by deleting the oldest so in this example // `-10.log` would be deleted next - const f = this[_getLogFilePath](padZero(count, this.#MAX_FILES_PER_PROCESS)) + const f = this.#getLogFilePath(padZero(count, this.#MAX_FILES_PER_PROCESS)) // Some effort was made to make the async, but we need to write logs // during process.on('exit') which has to be synchronous. So in order // to never drop log messages, it is easiest to make it sync all the time // and this was measured to be about 1.5% slower for 40k lines of output - const logStream = fs.withOwnerSync( - f, - () => new fsMiniPass.WriteStreamSync(f, { flags: 'a' }), - { owner: 'inherit' } - ) + const logStream = new fsMiniPass.WriteStreamSync(f, { flags: 'a' }) if (count > 0) { // Reset file log count if we are opening // after our first file @@ -210,7 +189,7 @@ class LogFiles { } } - async [_cleanLogs] () { + async #cleanLogs () { // module to clean out the old log files // this is a best-effort attempt. if a rm fails, we just // log a message about it and move on. We do return a @@ -218,18 +197,42 @@ class LogFiles { // just for the benefit of testing this function properly. try { - const logPath = this[_getLogFilePath]() - const logGlob = path.join(path.dirname(logPath), path.basename(logPath) + const logPath = this.#getLogFilePath() + const patternFileName = basename(logPath) // tell glob to only match digits - .replace(/\d/g, '[0123456789]') + .replace(/\d/g, 'd') // Handle the old (prior to 8.2.0) log file names which did not have a // counter suffix - .replace(/-\.log$/, '*.log') - ) + .replace('-.log', '') - // Always ignore the currently written files - const files = await glob(globify(logGlob), { ignore: this.#files.map(globify), silent: true }) - const toDelete = files.length - this.#logsMax + let files = await fs.readdir( + dirname(logPath), { + withFileTypes: true, + encoding: 'utf-8', + }) + files = files.sort((a, b) => basename(a.name).localeCompare(basename(b.name), 'en')) + + const logFiles = [] + + for (const file of files) { + if (!file.isFile()) { + continue + } + + const genericFileName = file.name.replace(/\d/g, 'd') + const filePath = join(dirname(logPath), basename(file.name)) + + // Always ignore the currently written files + if ( + genericFileName.includes(patternFileName) + && genericFileName.endsWith('.log') + && !this.#files.includes(filePath) + ) { + logFiles.push(filePath) + } + } + + const toDelete = logFiles.length - this.#logsMax if (toDelete <= 0) { return @@ -237,15 +240,18 @@ class LogFiles { log.silly('logfile', `start cleaning logs, removing ${toDelete} files`) - for (const file of files.slice(0, toDelete)) { + for (const file of logFiles.slice(0, toDelete)) { try { - await rimraf(file, { glob: false }) + await fs.rm(file, { force: true }) } catch (e) { log.silly('logfile', 'error removing log file', file, e) } } } catch (e) { - log.warn('logfile', 'error cleaning log files', e) + // Disable cleanup failure warnings when log writing is disabled + if (this.#logsMax > 0) { + log.verbose('logfile', 'error cleaning log files', e) + } } finally { log.silly('logfile', 'done cleaning log files') } diff --git a/lib/utils/log-shim.js b/lib/utils/log-shim.js deleted file mode 100644 index 9d5a36d967413..0000000000000 --- a/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/lib/utils/npm-usage.js b/lib/utils/npm-usage.js index 431995ecf0bae..1bd790ca601bc 100644 --- a/lib/utils/npm-usage.js +++ b/lib/utils/npm-usage.js @@ -1,10 +1,17 @@ -const { dirname } = require('path') -const { cmdList } = require('./cmd-list') -const localeCompare = require('@isaacs/string-locale-compare')('en') +const { commands } = require('./cmd-list') + +const COL_MAX = 60 +const COL_MIN = 24 +const COL_GUTTER = 16 +const INDENT = 4 + +const indent = (repeat = INDENT) => ' '.repeat(repeat) +const indentNewline = (repeat) => `\n${indent(repeat)}` + +module.exports = (npm) => { + const browser = npm.config.get('viewer') === 'browser' ? ' (in a browser)' : '' + const allCommands = npm.config.get('long') ? cmdUsages(npm.constructor) : cmdNames() -module.exports = async (npm) => { - const usesBrowser = npm.config.get('viewer') === 'browser' - ? ' (in a browser)' : '' return `npm <command> Usage: @@ -15,37 +22,30 @@ npm test run this project's tests npm run <foo> run the script named <foo> npm <command> -h quick help on <command> npm -l display usage info for all commands -npm help <term> search for help on <term>${usesBrowser} -npm help npm more involved overview${usesBrowser} +npm help <term> search for help on <term>${browser} +npm help npm more involved overview${browser} All commands: -${await allCommands(npm)} +${allCommands} Specify configs in the ini-formatted file: - ${npm.config.get('userconfig')} +${indent() + npm.config.get('userconfig')} or on the command line via: npm <command> --key=value More configuration info: npm help config Configuration fields: npm help 7 config -npm@${npm.version} ${dirname(dirname(__dirname))}` -} - -const allCommands = async (npm) => { - if (npm.config.get('long')) { - return usages(npm) - } - return ('\n ' + wrap(cmdList)) +npm@${npm.version} ${npm.npmRoot}` } -const wrap = (arr) => { +const cmdNames = () => { const out = [''] - const line = !process.stdout.columns ? 60 - : Math.min(60, Math.max(process.stdout.columns - 16, 24)) + const line = !process.stdout.columns ? COL_MAX + : Math.min(COL_MAX, Math.max(process.stdout.columns - COL_GUTTER, COL_MIN)) let l = 0 - for (const c of arr) { + for (const c of commands) { if (out[l].length + c.length + 2 < line) { out[l] += ', ' + c } else { @@ -53,20 +53,22 @@ const wrap = (arr) => { out[l] = c } } - return out.join('\n ').slice(2) + + return indentNewline() + out.join(indentNewline()).slice(2) } -const usages = async (npm) => { +const cmdUsages = (Npm) => { // return a string of <command>: <usage> let maxLen = 0 const set = [] - for (const c of cmdList) { - const cmd = await npm.cmd(c) - set.push([c, cmd.usage]) + for (const c of commands) { + set.push([c, Npm.cmd(c).describeUsage.split('\n')]) maxLen = Math.max(maxLen, c.length) } - return set.sort(([a], [b]) => localeCompare(a, b)) - .map(([c, usage]) => `\n ${c}${' '.repeat(maxLen - c.length + 1)}${ - (usage.split('\n').join('\n' + ' '.repeat(maxLen + 5)))}`) - .join('\n') + + return set.map(([name, usageLines]) => { + const gutter = indent(maxLen - name.length + 1) + const usage = usageLines.join(indentNewline(INDENT + maxLen + 1)) + return indentNewline() + name + gutter + usage + }).join('\n') } diff --git a/lib/utils/oidc.js b/lib/utils/oidc.js new file mode 100644 index 0000000000000..24524f4b4bf72 --- /dev/null +++ b/lib/utils/oidc.js @@ -0,0 +1,176 @@ +const { log } = require('proc-log') +const npmFetch = require('npm-registry-fetch') +const ciInfo = require('ci-info') +const fetch = require('make-fetch-happen') +const npa = require('npm-package-arg') +const libaccess = require('libnpmaccess') + +/** + * Handles OpenID Connect (OIDC) token retrieval and exchange for CI environments. + * + * This function is designed to work in Continuous Integration (CI) environments such as GitHub Actions + * and GitLab. It retrieves an OIDC token from the CI environment, exchanges it for an npm token, and + * sets the token in the provided configuration for authentication with the npm registry. + * + * This function is intended to never throw, as it mutates the state of the `opts` and `config` objects on success. + * OIDC is always an optional feature, and the function should not throw if OIDC is not configured by the registry. + * + * @see https://github.com/watson/ci-info for CI environment detection. + * @see https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect for GitHub Actions OIDC. + */ +async function oidc ({ packageName, registry, opts, config }) { + /* + * This code should never run when people try to publish locally on their machines. + * It is designed to execute only in Continuous Integration (CI) environments. + */ + + try { + if (!( + /** @see https://github.com/watson/ci-info/blob/v4.2.0/vendors.json#L152 */ + ciInfo.GITHUB_ACTIONS || + /** @see https://github.com/watson/ci-info/blob/v4.2.0/vendors.json#L161C13-L161C22 */ + ciInfo.GITLAB + )) { + return undefined + } + + /** + * Check if the environment variable `NPM_ID_TOKEN` is set. + * In GitLab CI, the ID token is provided via an environment variable, + * with `NPM_ID_TOKEN` serving as a predefined default. For consistency, + * all supported CI environments are expected to support this variable. + * In contrast, GitHub Actions uses a request-based approach to retrieve the ID token. + * The presence of this token within GitHub Actions will override the request-based approach. + * This variable follows the prefix/suffix convention from sigstore (e.g., `SIGSTORE_ID_TOKEN`). + * @see https://docs.sigstore.dev/cosign/signing/overview/ + */ + let idToken = process.env.NPM_ID_TOKEN + + if (!idToken && ciInfo.GITHUB_ACTIONS) { + /** + * GitHub Actions provides these environment variables: + * - `ACTIONS_ID_TOKEN_REQUEST_URL`: The URL to request the ID token. + * - `ACTIONS_ID_TOKEN_REQUEST_TOKEN`: The token to authenticate the request. + * Only when a workflow has the following permissions: + * ``` + * permissions: + * id-token: write + * ``` + * @see https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-cloud-providers#adding-permissions-settings + */ + if (!( + process.env.ACTIONS_ID_TOKEN_REQUEST_URL && + process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN + )) { + log.silly('oidc', 'Skipped because incorrect permissions for id-token within GitHub workflow') + return undefined + } + + /** + * The specification for an audience is `npm:registry.npmjs.org`, + * where "registry.npmjs.org" can be any supported registry. + */ + const audience = `npm:${new URL(registry).hostname}` + const url = new URL(process.env.ACTIONS_ID_TOKEN_REQUEST_URL) + url.searchParams.append('audience', audience) + const startTime = Date.now() + const response = await fetch(url.href, { + retry: opts.retry, + headers: { + Accept: 'application/json', + Authorization: `Bearer ${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}`, + }, + }) + + const elapsedTime = Date.now() - startTime + + log.http( + 'fetch', + `GET ${url.href} ${response.status} ${elapsedTime}ms` + ) + + const json = await response.json() + + if (!response.ok) { + log.verbose('oidc', `Failed to fetch id_token from GitHub: received an invalid response`) + return undefined + } + + if (!json.value) { + log.verbose('oidc', `Failed to fetch id_token from GitHub: missing value`) + return undefined + } + + idToken = json.value + } + + if (!idToken) { + log.silly('oidc', 'Skipped because no id_token available') + return undefined + } + + const parsedRegistry = new URL(registry) + const regKey = `//${parsedRegistry.host}${parsedRegistry.pathname}` + const authTokenKey = `${regKey}:_authToken` + + const escapedPackageName = npa(packageName).escapedName + let response + try { + response = await npmFetch.json(new URL(`/-/npm/v1/oidc/token/exchange/package/${escapedPackageName}`, registry), { + ...opts, + [authTokenKey]: idToken, // Use the idToken as the auth token for the request + method: 'POST', + }) + } catch (error) { + log.verbose('oidc', `Failed token exchange request with body message: ${error?.body?.message || 'Unknown error'}`) + return undefined + } + + if (!response?.token) { + log.verbose('oidc', 'Failed because token exchange was missing the token in the response body') + return undefined + } + + /* + * The "opts" object is a clone of npm.flatOptions and is passed through the `publish` command, + * eventually reaching `otplease`. To ensure the token is accessible during the publishing process, + * it must be directly attached to the `opts` object. + * Additionally, the token is required by the "live" configuration or getters within `config`. + */ + opts[authTokenKey] = response.token + config.set(authTokenKey, response.token, 'user') + log.verbose('oidc', `Successfully retrieved and set token`) + + try { + const isDefaultProvenance = config.isDefault('provenance') + if (isDefaultProvenance) { + const [headerB64, payloadB64] = idToken.split('.') + if (headerB64 && payloadB64) { + const payloadJson = Buffer.from(payloadB64, 'base64').toString('utf8') + const payload = JSON.parse(payloadJson) + if ( + (ciInfo.GITHUB_ACTIONS && payload.repository_visibility === 'public') || + // only set provenance for gitlab if the repo is public and SIGSTORE_ID_TOKEN is available + (ciInfo.GITLAB && payload.project_visibility === 'public' && process.env.SIGSTORE_ID_TOKEN) + ) { + const visibility = await libaccess.getVisibility(packageName, opts) + if (visibility?.public) { + log.verbose('oidc', `Enabling provenance`) + opts.provenance = true + config.set('provenance', true, 'user') + } + } + } + } + } catch (error) { + log.verbose('oidc', `Failed to set provenance with message: ${error?.message || 'Unknown error'}`) + } + } catch (error) { + log.verbose('oidc', `Failure with message: ${error?.message || 'Unknown error'}`) + } + return undefined +} + +module.exports = { + oidc, +} diff --git a/lib/utils/open-url-prompt.js b/lib/utils/open-url-prompt.js deleted file mode 100644 index 290040e5d14aa..0000000000000 --- a/lib/utils/open-url-prompt.js +++ /dev/null @@ -1,78 +0,0 @@ -const readline = require('readline') -const opener = require('opener') - -function print (npm, title, url) { - const json = npm.config.get('json') - - const message = json ? JSON.stringify({ title, url }) : `${title}:\n${url}` - - npm.output(message) -} - -// Prompt to open URL in browser if possible -const promptOpen = async (npm, url, title, prompt, emitter) => { - const browser = npm.config.get('browser') - const isInteractive = process.stdin.isTTY === true && process.stdout.isTTY === true - - try { - if (!/^https?:$/.test(new URL(url).protocol)) { - throw new Error() - } - } catch (_) { - throw new Error('Invalid URL: ' + url) - } - - print(npm, title, url) - - if (browser === false || !isInteractive) { - return - } - - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - }) - - const tryOpen = await new Promise(resolve => { - rl.on('SIGINT', () => { - rl.close() - resolve('SIGINT') - }) - - rl.question(prompt, () => { - resolve(true) - }) - - if (emitter && emitter.addListener) { - emitter.addListener('abort', () => { - rl.close() - - // clear the prompt line - npm.output('') - - resolve(false) - }) - } - }) - - if (tryOpen === 'SIGINT') { - throw new Error('canceled') - } - - if (!tryOpen) { - return - } - - const command = browser === true ? null : browser - await new Promise((resolve, reject) => { - opener(url, { command }, err => { - if (err) { - return reject(err) - } - - return resolve() - }) - }) -} - -module.exports = promptOpen diff --git a/lib/utils/open-url.js b/lib/utils/open-url.js index eed2449dcce51..9aa04b1382277 100644 --- a/lib/utils/open-url.js +++ b/lib/utils/open-url.js @@ -1,54 +1,99 @@ -const opener = require('opener') +const { open } = require('@npmcli/promise-spawn') +const { output, input, META } = require('proc-log') +const { URL } = require('node:url') +const readline = require('node:readline/promises') +const { once } = require('node:events') -const { URL } = require('url') +const assertValidUrl = (url) => { + try { + if (!/^https?:$/.test(new URL(url).protocol)) { + throw new Error() + } + } catch { + throw new Error('Invalid URL: ' + url) + } +} + +const outputMsg = (json, title, url) => { + if (json) { + output.buffer({ title, url }) + } else { + // These urls are sometimes specifically login urls so we have to turn off redaction to standard output + output.standard(`${title}:\n${url}`, { [META]: true, redact: false }) + } +} // attempt to open URL in web-browser, print address otherwise: -const open = async (npm, url, errMsg, isFile) => { +const openUrl = async (npm, url, title, isFile) => { url = encodeURI(url) const browser = npm.config.get('browser') - - function printAlternateMsg () { - const json = npm.config.get('json') - const alternateMsg = json - ? JSON.stringify({ - title: errMsg, - url, - }, null, 2) - : `${errMsg}:\n ${url}\n` - - npm.output(alternateMsg) - } + const json = npm.config.get('json') if (browser === false) { - printAlternateMsg() + outputMsg(json, title, url) return } // We pass this in as true from the help command so we know we don't have to // check the protocol if (!isFile) { - try { - if (!/^https?:$/.test(new URL(url).protocol)) { - throw new Error() - } - } catch (_) { - throw new Error('Invalid URL: ' + url) + assertValidUrl(url) + } + + try { + await input.start(() => open(url, { + command: browser === true ? null : browser, + })) + } catch (err) { + if (err.code !== 127) { + throw err } + outputMsg(json, title, url) } +} - const command = browser === true ? null : browser - await new Promise((resolve, reject) => { - opener(url, { command }, (err) => { - if (err) { - if (err.code === 'ENOENT') { - printAlternateMsg() - } else { - return reject(err) - } - } - return resolve() - }) +// Prompt to open URL in browser if possible +const openUrlPrompt = async (npm, url, title, prompt, { signal }) => { + const browser = npm.config.get('browser') + const json = npm.config.get('json') + + assertValidUrl(url) + outputMsg(json, title, url) + + if (browser === false || !process.stdin.isTTY || !process.stdout.isTTY) { + return + } + + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, }) + + try { + await input.read(() => Promise.race([ + rl.question(prompt, { signal }), + once(rl, 'error'), + once(rl, 'SIGINT').then(() => { + throw new Error('canceled') + }), + ])) + rl.close() + await openUrl(npm, url, 'Browser unavailable. Please open the URL manually') + } catch (err) { + rl.close() + if (err.name !== 'AbortError') { + throw err + } + } } -module.exports = open +// Rearrange arguments and return a function that takes the two arguments +// returned from the npm-profile methods that take an opener +const createOpener = (npm, title, prompt = 'Press ENTER to open in the browser...') => + (url, opts) => openUrlPrompt(npm, url, title, prompt, opts) + +module.exports = { + openUrl, + openUrlPrompt, + createOpener, +} diff --git a/lib/utils/otplease.js b/lib/utils/otplease.js deleted file mode 100644 index 0e20e7a797ae0..0000000000000 --- a/lib/utils/otplease.js +++ /dev/null @@ -1,46 +0,0 @@ -async function otplease (npm, opts, fn) { - try { - return await fn(opts) - } catch (err) { - if (!process.stdin.isTTY || !process.stdout.isTTY) { - throw err - } - - if (isWebOTP(err)) { - const webAuth = require('./web-auth') - const openUrlPrompt = require('./open-url-prompt') - - const openerPromise = (url, emitter) => - openUrlPrompt( - npm, - url, - 'Authenticate your account at', - 'Press ENTER to open in the browser...', - emitter - ) - const otp = await webAuth(openerPromise, err.body.authUrl, err.body.doneUrl, opts) - return await fn({ ...opts, otp }) - } - - if (isClassicOTP(err)) { - const readUserInfo = require('./read-user-info.js') - const otp = await readUserInfo.otp('This operation requires a one-time password.\nEnter OTP:') - return await fn({ ...opts, otp }) - } - - throw err - } -} - -function isWebOTP (err) { - if (!err.code === 'EOTP' || !err.body) { - return false - } - return err.body.authUrl && err.body.doneUrl -} - -function isClassicOTP (err) { - return err.code === 'EOTP' || (err.code === 'E401' && /one-time pass/.test(err.body)) -} - -module.exports = otplease diff --git a/lib/utils/output-error.js b/lib/utils/output-error.js new file mode 100644 index 0000000000000..07a86c9718b90 --- /dev/null +++ b/lib/utils/output-error.js @@ -0,0 +1,30 @@ +const { log, output } = require('proc-log') + +const outputError = ({ standard = [], verbose = [], error = [], summary = [], detail = [] }) => { + for (const line of standard) { + // Each output line is just a single string + output.standard(line) + } + for (const line of verbose) { + log.verbose(...line) + } + for (const line of [...error, ...summary, ...detail]) { + log.error(...line) + } +} + +const jsonError = (error, npm) => { + if (error && npm?.loaded && npm?.config.get('json')) { + return { + code: error.code, + summary: (error.summary || []).map(l => l.slice(1).join(' ')).join('\n').trim(), + detail: (error.detail || []).map(l => l.slice(1).join(' ')).join('\n').trim(), + ...error.json, + } + } +} + +module.exports = { + outputError, + jsonError, +} diff --git a/lib/utils/ping.js b/lib/utils/ping.js index 00956d0c1630c..3d47ca1ecaf54 100644 --- a/lib/utils/ping.js +++ b/lib/utils/ping.js @@ -1,7 +1,7 @@ // ping the npm registry // used by the ping and doctor commands -const fetch = require('npm-registry-fetch') +const npmFetch = require('npm-registry-fetch') module.exports = async (flatOptions) => { - const res = await fetch('/-/ping?write=true', flatOptions) + const res = await npmFetch('/-/ping', { ...flatOptions, cache: false }) return res.json().catch(() => ({})) } diff --git a/lib/utils/pulse-till-done.js b/lib/utils/pulse-till-done.js deleted file mode 100644 index 2229414147483..0000000000000 --- a/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/lib/utils/queryable.js b/lib/utils/queryable.js index ceb06bdccd103..7e51194eaf1fc 100644 --- a/lib/utils/queryable.js +++ b/lib/utils/queryable.js @@ -1,11 +1,10 @@ -const util = require('util') -const _data = Symbol('data') +const util = require('node:util') const _delete = Symbol('delete') const _append = Symbol('append') const sqBracketsMatcher = str => str.match(/(.+)\[([^\]]+)\]\.?(.*)$/) -// replaces any occurence of an empty-brackets (e.g: []) with a special +// replaces any occurrence of an empty-brackets (e.g: []) with a special // Symbol(append) to represent it, this is going to be useful for the setter // method that will push values to the end of the array when finding these const replaceAppendSymbols = str => { @@ -30,7 +29,7 @@ const parseKeys = key => { const preSqBracketPortion = index[1] // we want to have a `new String` wrapper here in order to differentiate - // between multiple occurences of the same string, e.g: + // between multiple occurrences of the same string, e.g: // foo.bar[foo.bar] should split into { foo: { bar: { 'foo.bar': {} } } /* eslint-disable-next-line no-new-wrappers */ const foundKey = new String(index[2]) @@ -42,7 +41,7 @@ const parseKeys = key => { sqBracketItems.add(foundKey) // returns an array that contains either dot-separate items (that will - // be splitted appart during the next step OR the fully parsed keys + // be split apart during the next step OR the fully parsed keys // read from square brackets, e.g: // foo.bar[1.0.0].a.b -> ['foo.bar', '1.0.0', 'a.b'] return [ @@ -84,7 +83,7 @@ const parseKeys = key => { return res } -const getter = ({ data, key }) => { +const getter = ({ data, key }, { unwrapSingleItemArrays = true } = {}) => { // keys are a list in which each entry represents the name of // a property that should be walked through the object in order to // return the final found value @@ -102,7 +101,7 @@ const getter = ({ data, key }) => { // extra logic to take into account printing array, along with its // special syntax in which using a dot-sep property name after an - // arry will expand it's results, e.g: + // array will expand it's results, e.g: // arr.name -> arr[0].name=value, arr[1].name=value, ... const maybeIndex = Number(k) if (Array.isArray(_data) && !Number.isInteger(maybeIndex)) { @@ -112,13 +111,9 @@ const getter = ({ data, key }) => { }, {}) return _data } else { - // if can't find any more values, it means it's just over - // and there's nothing to return - if (!_data[k]) { + if (!Object.hasOwn(_data, k)) { return undefined } - - // otherwise sets the next value _data = _data[k] } @@ -127,7 +122,7 @@ const getter = ({ data, key }) => { // these are some legacy expectations from // the old API consumed by lib/view.js - if (Array.isArray(_data) && _data.length <= 1) { + if (unwrapSingleItemArrays && Array.isArray(_data) && _data.length <= 1) { _data = _data[0] } @@ -143,12 +138,14 @@ const setter = ({ data, key, value, force }) => { const keys = parseKeys(key) const setKeys = (_data, _key) => { // handles array indexes, converting valid integers to numbers, - // note that occurences of Symbol(append) will throw, + // note that occurrences of Symbol(append) will throw, // so we just ignore these for now let maybeIndex = Number.NaN try { maybeIndex = Number(_key) - } catch (err) {} + } catch { + // leave it NaN + } if (!Number.isNaN(maybeIndex)) { _key = maybeIndex } @@ -209,7 +206,7 @@ const setter = ({ data, key, value, force }) => { } // sets items from the parsed array of keys as objects, recurses to - // setKeys in case there are still items to be handled, otherwise it + // setKeys in case there are still items to be handled; otherwise, it // just sets the original value set by the user if (keys.length) { _data[_key] = setKeys(next(), keys.shift()) @@ -234,6 +231,10 @@ const setter = ({ data, key, value, force }) => { } class Queryable { + static ALL = '' + + #data = null + constructor (obj) { if (!obj || typeof obj !== 'object') { throw Object.assign(new Error('Queryable needs an object to query properties from.'), { @@ -241,22 +242,22 @@ class Queryable { }) } - this[_data] = obj + this.#data = obj } - query (queries) { + query (queries, opts) { // this ugly interface here is meant to be a compatibility layer // with the legacy API lib/view.js is consuming, if at some point // we refactor that command then we can revisit making this nicer - if (queries === '') { - return { '': this[_data] } + if (queries === Queryable.ALL) { + return { [Queryable.ALL]: this.#data } } const q = query => getter({ - data: this[_data], + data: this.#data, key: query, - }) + }, opts) if (Array.isArray(queries)) { let res = {} @@ -269,7 +270,7 @@ class Queryable { } } - // return the value for a single query if found, otherwise returns undefined + // return the value for a single query if found; otherwise, returns undefined get (query) { const obj = this.query(query) if (obj) { @@ -281,7 +282,7 @@ class Queryable { // and assigns `value` to the last property of the query chain set (query, value, { force } = {}) { setter({ - data: this[_data], + data: this.#data, key: query, value, force, @@ -291,14 +292,14 @@ class Queryable { // deletes the value of the property found at `query` delete (query) { setter({ - data: this[_data], + data: this.#data, key: query, value: _delete, }) } toJSON () { - return this[_data] + return this.#data } [util.inspect.custom] () { diff --git a/lib/utils/read-user-info.js b/lib/utils/read-user-info.js index ac24396c6abb9..9b89f9e4382b1 100644 --- a/lib/utils/read-user-info.js +++ b/lib/utils/read-user-info.js @@ -1,12 +1,6 @@ -const { promisify } = require('util') -const readAsync = promisify(require('read')) +const { read: _read } = require('read') const userValidate = require('npm-user-validate') -const log = require('./log-shim.js') - -exports.otp = readOTP -exports.password = readPassword -exports.username = readUsername -exports.email = readEmail +const { log, input, META } = require('proc-log') const otpPrompt = `This command requires a one-time password (OTP) from your authenticator app. Enter one below. You can also pass one on the command line by appending --otp=123456. @@ -15,12 +9,11 @@ https://docs.npmjs.com/getting-started/using-two-factor-authentication Enter OTP: ` const passwordPrompt = 'npm password: ' const usernamePrompt = 'npm username: ' -const emailPrompt = 'email (this IS public): ' +const emailPrompt = 'email (this will be public): ' -function read (opts) { - log.clearProgress() - return readAsync(opts).finally(() => log.showProgress()) -} +// Pass options through so we can differentiate between regular and silent prompts +const read = (options) => + input.read(() => _read(options), { [META]: true, silent: options?.silent }) function readOTP (msg = otpPrompt, otp, isRetry) { if (isRetry && otp && /^[\d ]+$|^[A-Fa-f0-9]{64,64}$/.test(otp)) { @@ -28,7 +21,7 @@ function readOTP (msg = otpPrompt, otp, isRetry) { } return read({ prompt: msg, default: otp || '' }) - .then((otp) => readOTP(msg, otp, true)) + .then((rOtp) => readOTP(msg, rOtp, true)) } function readPassword (msg = passwordPrompt, password, isRetry) { @@ -37,7 +30,7 @@ function readPassword (msg = passwordPrompt, password, isRetry) { } return read({ prompt: msg, silent: true, default: password || '' }) - .then((password) => readPassword(msg, password, true)) + .then((rPassword) => readPassword(msg, rPassword, true)) } function readUsername (msg = usernamePrompt, username, isRetry) { @@ -51,7 +44,7 @@ function readUsername (msg = usernamePrompt, username, isRetry) { } return read({ prompt: msg, default: username || '' }) - .then((username) => readUsername(msg, username, true)) + .then((rUsername) => readUsername(msg, rUsername, true)) } function readEmail (msg = emailPrompt, email, isRetry) { @@ -67,3 +60,10 @@ function readEmail (msg = emailPrompt, email, isRetry) { return read({ prompt: msg, default: email || '' }) .then((username) => readEmail(msg, username, true)) } + +module.exports = { + otp: readOTP, + password: readPassword, + username: readUsername, + email: readEmail, +} diff --git a/lib/utils/reify-finish.js b/lib/utils/reify-finish.js index 9b43abcb7610a..410c19730cdf4 100644 --- a/lib/utils/reify-finish.js +++ b/lib/utils/reify-finish.js @@ -1,7 +1,7 @@ const reifyOutput = require('./reify-output.js') const ini = require('ini') -const { writeFile } = require('fs').promises -const { resolve } = require('path') +const { writeFile } = require('node:fs/promises') +const { resolve } = require('node:path') const reifyFinish = async (npm, arb) => { await saveBuiltinConfig(npm, arb) diff --git a/lib/utils/reify-output.js b/lib/utils/reify-output.js index b5c3a593b8db0..f4a8442e9427f 100644 --- a/lib/utils/reify-output.js +++ b/lib/utils/reify-output.js @@ -9,10 +9,10 @@ // 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 auditReport = require('npm-audit-report') +const npmAuditReport = require('npm-audit-report') const { readTree: getFundingInfo } = require('libnpmfund') const auditError = require('./audit-error.js') @@ -33,26 +33,66 @@ const reifyOutput = (npm, arb) => { } const summary = { + add: [], added: 0, - removed: 0, - changed: 0, + // audit gets added later audited: auditReport && !auditReport.error ? actualTree.inventory.size : 0, + change: [], + changed: 0, funding: 0, + remove: [], + removed: 0, } if (diff) { + 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': + if (showDiff) { + output.standard(`${chalk.blue('remove')} ${d.actual.name} ${d.actual.package.version}`) + } summary.removed++ + summary.remove.push({ + name: d.actual.name, + version: d.actual.package.version, + path: d.actual.path, + }) break case 'ADD': - actualTree.inventory.has(d.ideal) && summary.added++ + if (showDiff) { + output.standard(`${chalk.green('add')} ${d.ideal.name} ${d.ideal.package.version}`) + } + if (actualTree.inventory.has(d.ideal)) { + summary.added++ + summary.add.push({ + name: d.ideal.name, + version: d.ideal.package.version, + path: d.ideal.path, + }) + } break case 'CHANGE': + if (showDiff) { + output.standard(`${chalk.cyan('change')} ${d.actual.name} ${d.actual.package.version} => ${d.ideal.package.version}`) + } summary.changed++ + summary.change.push({ + from: { + name: d.actual.name, + version: d.actual.package.version, + path: d.actual.path, + }, + to: { + name: d.ideal.name, + version: d.ideal.package.version, + path: d.ideal.path, + }, + }) break default: return @@ -76,7 +116,7 @@ const reifyOutput = (npm, arb) => { summary.audit = npm.command === 'audit' ? auditReport : auditReport.toJSON().metadata } - npm.output(JSON.stringify(summary, 0, 2)) + output.buffer(summary) } else { packagesChangedMessage(npm, summary) packagesFundingMessage(npm, summary) @@ -95,7 +135,7 @@ const printAuditReport = (npm, report) => { if (!res || !res.report) { return } - npm.output(`\n${res.report}`) + output.standard(`\n${res.report}`) } const getAuditReport = (npm, report) => { @@ -112,10 +152,11 @@ const getAuditReport = (npm, report) => { const defaultAuditLevel = npm.command !== 'audit' ? 'none' : 'low' const auditLevel = npm.flatOptions.auditLevel || defaultAuditLevel - const res = auditReport(report, { + const res = npmAuditReport(report, { reporter, ...npm.flatOptions, auditLevel, + chalk: npm.chalk, }) if (npm.command === 'audit') { process.exitCode = process.exitCode || res.exitCode @@ -166,7 +207,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 }) => { @@ -174,11 +215,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/lib/utils/replace-info.js b/lib/utils/replace-info.js deleted file mode 100644 index b9ce61935ffb7..0000000000000 --- a/lib/utils/replace-info.js +++ /dev/null @@ -1,31 +0,0 @@ -const { cleanUrl } = require('npm-registry-fetch') -const isString = (v) => typeof v === 'string' - -// split on \s|= similar to how nopt parses options -const splitAndReplace = (str) => { - // stateful regex, don't move out of this scope - const splitChars = /[\s=]/g - - let match = null - let result = '' - let index = 0 - while (match = splitChars.exec(str)) { - result += cleanUrl(str.slice(index, match.index)) + match[0] - index = splitChars.lastIndex - } - - return result + cleanUrl(str.slice(index)) -} - -// replaces auth info in an array of arguments or in a strings -function replaceInfo (arg) { - if (isString(arg)) { - return splitAndReplace(arg) - } else if (Array.isArray(arg)) { - return arg.map((a) => isString(a) ? splitAndReplace(a) : a) - } - - return arg -} - -module.exports = replaceInfo diff --git a/lib/utils/sbom-cyclonedx.js b/lib/utils/sbom-cyclonedx.js new file mode 100644 index 0000000000000..0cd170fbbcbee --- /dev/null +++ b/lib/utils/sbom-cyclonedx.js @@ -0,0 +1,198 @@ +const crypto = require('node:crypto') +const parseLicense = require('spdx-expression-parse') +const PackageJson = require('@npmcli/package-json') +const npa = require('npm-package-arg') +const ssri = require('ssri') + +const CYCLONEDX_SCHEMA = 'http://cyclonedx.org/schema/bom-1.5.schema.json' +const CYCLONEDX_FORMAT = 'CycloneDX' +const CYCLONEDX_SCHEMA_VERSION = '1.5' + +const PROP_BUNDLED = 'cdx:npm:package:bundled' +const PROP_DEVELOPMENT = 'cdx:npm:package:development' +const PROP_EXTRANEOUS = 'cdx:npm:package:extraneous' +const PROP_PRIVATE = 'cdx:npm:package:private' + +const REF_VCS = 'vcs' +const REF_WEBSITE = 'website' +const REF_ISSUE_TRACKER = 'issue-tracker' +const REF_DISTRIBUTION = 'distribution' + +const ALGO_MAP = { + sha1: 'SHA-1', + sha256: 'SHA-256', + sha384: 'SHA-384', + sha512: 'SHA-512', +} + +const cyclonedxOutput = ({ npm, nodes, packageType, packageLockOnly }) => { + const rootNode = nodes.find(node => node.isRoot) + const childNodes = nodes.filter(node => !node.isRoot && !node.isLink) + const uuid = crypto.randomUUID() + + // Create list of child nodes w/ unique IDs + const childNodeMap = new Map() + for (const item of childNodes) { + const id = toCyclonedxID(item) + if (!childNodeMap.has(id)) { + childNodeMap.set(id, item) + } + } + const uniqueChildNodes = Array.from(childNodeMap.values()) + + const deps = [rootNode, ...uniqueChildNodes] + .map(node => toCyclonedxDependency(node, nodes)) + + const bom = { + $schema: CYCLONEDX_SCHEMA, + bomFormat: CYCLONEDX_FORMAT, + specVersion: CYCLONEDX_SCHEMA_VERSION, + serialNumber: `urn:uuid:${uuid}`, + version: 1, + metadata: { + timestamp: new Date().toISOString(), + lifecycles: [ + { phase: packageLockOnly ? 'pre-build' : 'build' }, + ], + tools: [ + { + vendor: 'npm', + name: 'cli', + version: npm.version, + }, + ], + component: toCyclonedxItem(rootNode, { packageType }), + }, + components: uniqueChildNodes.map(toCyclonedxItem), + dependencies: deps, + } + + return bom +} + +const toCyclonedxItem = (node, { packageType }) => { + packageType = packageType || 'library' + + // Calculate purl from package spec + let spec = npa(node.pkgid) + spec = (spec.type === 'alias') ? spec.subSpec : spec + const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${node.resolved}` : '') + + if (node.package) { + const toNormalize = new PackageJson() + toNormalize.fromContent(node.package).normalize({ steps: ['normalizeData'] }) + node.package = toNormalize.content + } + + let parsedLicense + try { + let license = node.package?.license + if (license) { + if (typeof license === 'object') { + license = license.type + } + } + + parsedLicense = parseLicense(license) + } catch { + parsedLicense = null + } + + const component = { + 'bom-ref': toCyclonedxID(node), + type: packageType, + name: node.name, + version: node.version, + scope: (node.optional || node.devOptional) ? 'optional' : 'required', + author: (typeof node.package?.author === 'object') + ? node.package.author.name + : (node.package?.author || undefined), + description: node.package?.description || undefined, + purl: purl, + properties: [], + externalReferences: [], + } + + if (node.integrity) { + const integrity = ssri.parse(node.integrity, { single: true }) + component.hashes = [{ + alg: ALGO_MAP[integrity.algorithm] || /* istanbul ignore next */ 'SHA-512', + content: integrity.hexDigest(), + }] + } + + if (node.dev === true) { + component.properties.push(prop(PROP_DEVELOPMENT)) + } + + if (node.package?.private === true) { + component.properties.push(prop(PROP_PRIVATE)) + } + + if (node.extraneous === true) { + component.properties.push(prop(PROP_EXTRANEOUS)) + } + + if (node.inBundle === true) { + component.properties.push(prop(PROP_BUNDLED)) + } + + if (!node.isLink && node.resolved) { + component.externalReferences.push(extRef(REF_DISTRIBUTION, node.resolved)) + } + + if (node.package?.repository?.url) { + component.externalReferences.push(extRef(REF_VCS, node.package.repository.url)) + } + + if (node.package?.homepage) { + component.externalReferences.push(extRef(REF_WEBSITE, node.package.homepage)) + } + + if (node.package?.bugs?.url) { + component.externalReferences.push(extRef(REF_ISSUE_TRACKER, node.package.bugs.url)) + } + + // If license is a single SPDX license, use the license field + if (parsedLicense?.license) { + component.licenses = [{ license: { id: parsedLicense.license } }] + // If license is a conjunction, use the expression field + } else if (parsedLicense?.conjunction) { + component.licenses = [{ expression: node.package.license }] + } + + return component +} + +const toCyclonedxDependency = (node, nodes) => { + return { + ref: toCyclonedxID(node), + dependsOn: [...node.edgesOut.values()] + // Filter out edges that are linking to nodes not in the list + .filter(edge => nodes.find(n => n === edge.to)) + .map(edge => toCyclonedxID(edge.to)) + .filter(id => id), + } +} + +const toCyclonedxID = (node) => `${node.packageName}@${node.version}` + +const prop = (name) => ({ name, value: 'true' }) + +const extRef = (type, url) => ({ type, url }) + +const isGitNode = (node) => { + if (!node.resolved) { + return + } + + try { + const { type } = npa(node.resolved) + return type === 'git' || type === 'hosted' + } catch { + /* istanbul ignore next */ + return false + } +} + +module.exports = { cyclonedxOutput } diff --git a/lib/utils/sbom-spdx.js b/lib/utils/sbom-spdx.js new file mode 100644 index 0000000000000..074a6f57f98bf --- /dev/null +++ b/lib/utils/sbom-spdx.js @@ -0,0 +1,194 @@ + +const crypto = require('node:crypto') +const PackageJson = require('@npmcli/package-json') +const npa = require('npm-package-arg') +const ssri = require('ssri') + +const SPDX_SCHEMA_VERSION = 'SPDX-2.3' +const SPDX_DATA_LICENSE = 'CC0-1.0' +const SPDX_IDENTIFER = 'SPDXRef-DOCUMENT' + +const NO_ASSERTION = 'NOASSERTION' + +const REL_DESCRIBES = 'DESCRIBES' +const REL_PREREQ = 'PREREQUISITE_FOR' +const REL_OPTIONAL = 'OPTIONAL_DEPENDENCY_OF' +const REL_DEV = 'DEV_DEPENDENCY_OF' +const REL_DEP = 'DEPENDENCY_OF' + +const REF_CAT_PACKAGE_MANAGER = 'PACKAGE-MANAGER' +const REF_TYPE_PURL = 'purl' + +const spdxOutput = ({ npm, nodes, packageType }) => { + const rootNode = nodes.find(node => node.isRoot) + const childNodes = nodes.filter(node => !node.isRoot && !node.isLink) + const rootID = rootNode.pkgid + const uuid = crypto.randomUUID() + const ns = `http://spdx.org/spdxdocs/${npa(rootID).escapedName}-${rootNode.version}-${uuid}` + + // Create list of child nodes w/ unique IDs + const childNodeMap = new Map() + for (const item of childNodes) { + const id = toSpdxID(item) + if (!childNodeMap.has(id)) { + childNodeMap.set(id, item) + } + } + const uniqueChildNodes = Array.from(childNodeMap.values()) + + const relationships = [] + const seen = new Set() + for (let node of nodes) { + if (node.isLink) { + node = node.target + } + + if (seen.has(node)) { + continue + } + seen.add(node) + + const rels = [...node.edgesOut.values()] + // Filter out edges that are linking to nodes not in the list + .filter(edge => nodes.find(n => n === edge.to)) + .map(edge => toSpdxRelationship(node, edge)) + .filter(rel => rel) + + relationships.push(...rels) + } + + const extraRelationships = nodes.filter(node => node.extraneous) + .map(node => toSpdxRelationship(rootNode, { to: node, type: 'optional' })) + + relationships.push(...extraRelationships) + + const bom = { + spdxVersion: SPDX_SCHEMA_VERSION, + dataLicense: SPDX_DATA_LICENSE, + SPDXID: SPDX_IDENTIFER, + name: rootID, + documentNamespace: ns, + creationInfo: { + created: new Date().toISOString(), + creators: [ + `Tool: npm/cli-${npm.version}`, + ], + }, + documentDescribes: [toSpdxID(rootNode)], + packages: [toSpdxItem(rootNode, { packageType }), ...uniqueChildNodes.map(toSpdxItem)], + relationships: [ + { + spdxElementId: SPDX_IDENTIFER, + relatedSpdxElement: toSpdxID(rootNode), + relationshipType: REL_DESCRIBES, + }, + ...relationships, + ], + } + + return bom +} + +const toSpdxItem = (node, { packageType }) => { + const toNormalize = new PackageJson() + toNormalize.fromContent(node.package).normalize({ steps: ['normalizeData'] }) + node.package = toNormalize.content + + // Calculate purl from package spec + let spec = npa(node.pkgid) + spec = (spec.type === 'alias') ? spec.subSpec : spec + const purl = npa.toPurl(spec) + (isGitNode(node) ? `?vcs_url=${node.resolved}` : '') + + /* For workspace nodes, use the location from their linkNode */ + let location = node.location + if (node.isWorkspace && node.linksIn.size > 0) { + location = node.linksIn.values().next().value.location + } + + let license = node.package?.license + if (license) { + if (typeof license === 'object') { + license = license.type + } + } + + const pkg = { + name: node.packageName, + SPDXID: toSpdxID(node), + versionInfo: node.version, + packageFileName: location, + description: node.package?.description || undefined, + primaryPackagePurpose: packageType ? packageType.toUpperCase() : undefined, + downloadLocation: (node.isLink ? undefined : node.resolved) || NO_ASSERTION, + filesAnalyzed: false, + homepage: node.package?.homepage || NO_ASSERTION, + licenseDeclared: license || NO_ASSERTION, + externalRefs: [ + { + referenceCategory: REF_CAT_PACKAGE_MANAGER, + referenceType: REF_TYPE_PURL, + referenceLocator: purl, + }, + ], + } + + if (node.integrity) { + const integrity = ssri.parse(node.integrity, { single: true }) + pkg.checksums = [{ + algorithm: integrity.algorithm.toUpperCase(), + checksumValue: integrity.hexDigest(), + }] + } + return pkg +} + +const toSpdxRelationship = (node, edge) => { + let type + switch (edge.type) { + case 'peer': + type = REL_PREREQ + break + case 'optional': + type = REL_OPTIONAL + break + case 'dev': + type = REL_DEV + break + default: + type = REL_DEP + } + + return { + spdxElementId: toSpdxID(edge.to), + relatedSpdxElement: toSpdxID(node), + relationshipType: type, + } +} + +const toSpdxID = (node) => { + let name = node.packageName + + // Strip leading @ for scoped packages + name = name.replace(/^@/, '') + + // Replace slashes with dots + name = name.replace(/\//g, '.') + + return `SPDXRef-Package-${name}-${node.version}` +} + +const isGitNode = (node) => { + if (!node.resolved) { + return + } + + try { + const { type } = npa(node.resolved) + return type === 'git' || type === 'hosted' + } catch { + /* istanbul ignore next */ + return false + } +} + +module.exports = { spdxOutput } diff --git a/lib/utils/tar.js b/lib/utils/tar.js index 0a74ce8c44434..a744dca313257 100644 --- a/lib/utils/tar.js +++ b/lib/utils/tar.js @@ -1,71 +1,48 @@ const tar = require('tar') const ssri = require('ssri') -const log = require('./log-shim') +const { log, output } = 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, }) -const logTar = (tarball, opts = {}) => { - const { unicode = false } = opts +const logTar = (tarball, { unicode = false, json, key } = {}) => { + if (json) { + output.buffer(key == null ? tarball : { [key]: tarball }) + return + } 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}`) + 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('', '') } @@ -81,7 +58,7 @@ const getContents = async (manifest, tarball) => { totalEntries++ totalEntrySize += entry.size const p = entry.path - if (p.startsWith('package/node_modules/')) { + if (p.startsWith('package/node_modules/') && p !== 'package/node_modules/') { const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1] bundled.add(name) } @@ -94,7 +71,7 @@ const getContents = async (manifest, tarball) => { }) stream.end(tarball) - const integrity = await ssri.fromData(tarball, { + const integrity = ssri.fromData(tarball, { algorithms: ['sha1', 'sha512'], }) @@ -120,7 +97,9 @@ const getContents = async (manifest, tarball) => { unpackedSize: totalEntrySize, shasum, integrity: ssri.parse(integrity.sha512[0]), - filename: `${manifest.name}-${manifest.version}.tgz`, + // @scope/packagename.tgz => scope-packagename.tgz + // we can safely use these global replace rules due to npm package naming rules + filename: `${manifest.name.replace('@', '').replace('/', '-')}-${manifest.version}.tgz`, files: uppers.concat(others), entryCount: totalEntries, bundled: Array.from(bundled), diff --git a/lib/utils/timers.js b/lib/utils/timers.js index 3336c3b519259..16a255961fee3 100644 --- a/lib/utils/timers.js +++ b/lib/utils/timers.js @@ -1,126 +1,87 @@ -const EE = require('events') -const { resolve } = require('path') -const fs = require('@npmcli/fs') -const log = require('./log-shim') +const EE = require('node:events') +const fs = require('node:fs') +const { log, time } = require('proc-log') -const _timeListener = Symbol('timeListener') -const _timeEndListener = Symbol('timeEndListener') -const _init = Symbol('init') +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 ({ dir } = {}) { - if (dir) { - this.file = resolve(dir, '_timing.json') + finish (metadata) { + time.end(INITIAL_TIMER) + + for (const [name, timer] of this.#unfinished) { + log.silly('unfinished npm timer', name, timer) } - } - writeFile (fileData) { - 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 = { - ...fileData, - ...this.#finished, - // add any unfinished timers with their relative start/end - unfinished: [...this.#unfinished.entries()].reduce((acc, [name, start]) => { - acc[name] = [start - globalStart, globalEnd - globalStart] - return acc - }, {}), - } - // we append line delimited json to this file...forever - // XXX: should we also write a process specific timing file? - // with similar rules to the debug log (max files, etc) - fs.withOwnerSync( - this.file, - () => fs.appendFileSync(this.file, JSON.stringify(content) + '\n'), - { owner: 'inherit' } - ) + 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/lib/utils/update-notifier.js b/lib/utils/update-notifier.js deleted file mode 100644 index 75e944407ffbd..0000000000000 --- a/lib/utils/update-notifier.js +++ /dev/null @@ -1,134 +0,0 @@ -// print a banner telling the user to upgrade npm to latest -// but not in CI, and not if we're doing that already. -// Check daily for betas, and weekly otherwise. - -const pacote = require('pacote') -const ciDetect = require('@npmcli/ci-detect') -const semver = require('semver') -const chalk = require('chalk') -const { promisify } = require('util') -const stat = promisify(require('fs').stat) -const writeFile = promisify(require('fs').writeFile) -const { resolve } = require('path') - -const SKIP = Symbol('SKIP') - -const isGlobalNpmUpdate = npm => { - return npm.flatOptions.global && - ['install', 'update'].includes(npm.command) && - npm.argv.some(arg => /^npm(@|$)/.test(arg)) -} - -// update check frequency -const DAILY = 1000 * 60 * 60 * 24 -const WEEKLY = DAILY * 7 - -// don't put it in the _cacache folder, just in npm's cache -const lastCheckedFile = npm => - resolve(npm.flatOptions.cache, '../_update-notifier-last-checked') - -const checkTimeout = async (npm, duration) => { - const t = new Date(Date.now() - duration) - const f = lastCheckedFile(npm) - // if we don't have a file, then definitely check it. - const st = await stat(f).catch(() => ({ mtime: t - 1 })) - return t > st.mtime -} - -const updateNotifier = async (npm, spec = 'latest') => { - // never check for updates in CI, when updating npm already, or opted out - if (!npm.config.get('update-notifier') || - isGlobalNpmUpdate(npm) || - ciDetect()) { - return SKIP - } - - // if we're on a prerelease train, then updates are coming fast - // check for a new one daily. otherwise, weekly. - const { version } = npm - const current = semver.parse(version) - - // if we're on a beta train, always get the next beta - if (current.prerelease.length) { - spec = `^${version}` - } - - // while on a beta train, get updates daily - const duration = spec !== 'latest' ? DAILY : WEEKLY - - // if we've already checked within the specified duration, don't check again - if (!(await checkTimeout(npm, duration))) { - return null - } - - // if they're currently using a prerelease, nudge to the next prerelease - // otherwise, nudge to latest. - const useColor = npm.logColor - - const mani = await pacote.manifest(`npm@${spec}`, { - // always prefer latest, even if doing --tag=whatever on the cmd - defaultTag: 'latest', - ...npm.flatOptions, - }).catch(() => null) - - // if pacote failed, give up - if (!mani) { - return null - } - - const latest = mani.version - - // if the current version is *greater* than latest, we're on a 'next' - // and should get the updates from that release train. - // Note that this isn't another http request over the network, because - // the packument will be cached by pacote from previous request. - if (semver.gt(version, latest) && spec === 'latest') { - return updateNotifier(npm, `^${version}`) - } - - // if we already have something >= the desired spec, then we're done - if (semver.gte(version, latest)) { - return null - } - - // ok! notify the user about this update they should get. - // The message is saved for printing at process exit so it will not get - // lost in any other messages being printed as part of the command. - const update = semver.parse(mani.version) - const type = update.major !== current.major ? 'major' - : update.minor !== current.minor ? 'minor' - : update.patch !== current.patch ? 'patch' - : 'prerelease' - const typec = !useColor ? type - : type === 'major' ? chalk.red(type) - : type === 'minor' ? chalk.yellow(type) - : chalk.green(type) - const oldc = !useColor ? current : chalk.red(current) - const latestc = !useColor ? latest : chalk.green(latest) - const changelog = `https://github.com/npm/cli/releases/tag/v${latest}` - const changelogc = !useColor ? `<${changelog}>` : chalk.cyan(changelog) - 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` - - return message -} - -// only update the notification timeout if we actually finished checking -module.exports = async npm => { - const notification = await updateNotifier(npm) - - // dont write the file if we skipped checking altogether - if (notification === SKIP) { - return null - } - - // intentional. do not await this. it's a best-effort update. if this - // fails, it's ok. might be using /dev/null as the cache or something weird - // like that. - writeFile(lastCheckedFile(npm), '').catch(() => {}) - return notification -} diff --git a/lib/workspaces/update-workspaces.js b/lib/utils/update-workspaces.js similarity index 88% rename from lib/workspaces/update-workspaces.js rename to lib/utils/update-workspaces.js index 4cba1245ac2e5..892f366e9980a 100644 --- a/lib/workspaces/update-workspaces.js +++ b/lib/utils/update-workspaces.js @@ -1,6 +1,5 @@ 'use strict' -const Arborist = require('@npmcli/arborist') const reifyFinish = require('../utils/reify-finish.js') async function updateWorkspaces ({ @@ -22,7 +21,7 @@ async function updateWorkspaces ({ ? false : config.get('save') - // runs a minimalistic reify update, targetting only the workspaces + // runs a minimalistic reify update, targeting only the workspaces // that had version updates and skipping fund/audit/save const opts = { ...flatOptions, @@ -31,6 +30,7 @@ async function updateWorkspaces ({ path: localPrefix, save, } + const Arborist = require('@npmcli/arborist') const arb = new Arborist(opts) await arb.reify({ ...opts, update: workspaces }) diff --git a/lib/utils/verify-signatures.js b/lib/utils/verify-signatures.js new file mode 100644 index 0000000000000..baadb2b1227d9 --- /dev/null +++ b/lib/utils/verify-signatures.js @@ -0,0 +1,377 @@ +const npmFetch = require('npm-registry-fetch') +const localeCompare = require('@isaacs/string-locale-compare')('en') +const npa = require('npm-package-arg') +const pacote = require('pacote') +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() + const { default: pMap } = await import('p-map') + + // 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.buffer({ invalid, missing }) + 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) { + output.standard(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`) + } else { + output.standard(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`) + } + output.standard('') + } + + if (this.verifiedAttestationCount) { + if (this.verifiedAttestationCount === 1) { + output.standard(`${this.verifiedAttestationCount} package has a ${verifiedBold} attestation`) + } else { + output.standard(`${this.verifiedAttestationCount} packages have ${verifiedBold} attestations`) + } + output.standard('') + } + + if (missing.length) { + const missingClr = this.npm.chalk.redBright('missing') + if (missing.length === 1) { + output.standard(`1 package has a ${missingClr} registry signature but the registry is providing signing keys:`) + } else { + 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 { + 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 { + 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) { + output.standard(`Someone might have tampered with this package since it was published on the registry!`) + } else { + 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, fall back to registry keys API + if (!keys) { + log.warn(`Fetching verification keys using TUF failed. Fetching directly from ${registry}.`) + keys = await npmFetch.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 npmFetch.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 an installed version, e.g. optional 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/lib/utils/web-auth.js b/lib/utils/web-auth.js deleted file mode 100644 index ce551687098fc..0000000000000 --- a/lib/utils/web-auth.js +++ /dev/null @@ -1,20 +0,0 @@ -const EventEmitter = require('events') -const { webAuthCheckLogin } = require('npm-profile') - -async function webAuth (opener, initialUrl, doneUrl, opts) { - const doneEmitter = new EventEmitter() - - const openPromise = opener(initialUrl, doneEmitter) - const webAuthCheckPromise = webAuthCheckLogin(doneUrl, { ...opts, cache: false }) - .then(authResult => { - // cancel open prompt if it's present - doneEmitter.emit('abort') - - return authResult.token - }) - - await openPromise - return await webAuthCheckPromise -} - -module.exports = webAuth diff --git a/lib/workspaces/get-workspaces.js b/lib/workspaces/get-workspaces.js deleted file mode 100644 index 373af1d689cc3..0000000000000 --- a/lib/workspaces/get-workspaces.js +++ /dev/null @@ -1,54 +0,0 @@ -const { resolve, relative } = require('path') -const mapWorkspaces = require('@npmcli/map-workspaces') -const minimatch = require('minimatch') -const rpj = require('read-package-json-fast') - -// minimatch wants forward slashes only for glob patterns -const globify = pattern => pattern.split('\\').join('/') - -// Returns an Map of paths to workspaces indexed by workspace name -// { foo => '/path/to/foo' } -const getWorkspaces = async (filters, { path, includeWorkspaceRoot, relativeFrom }) => { - // TODO we need a better error to be bubbled up here if this rpj call fails - const pkg = await rpj(resolve(path, 'package.json')) - const workspaces = await mapWorkspaces({ cwd: path, pkg }) - let res = new Map() - if (includeWorkspaceRoot) { - res.set(pkg.name, path) - } - - if (!filters.length) { - res = new Map([...res, ...workspaces]) - } - - for (const filterArg of filters) { - for (const [workspaceName, workspacePath] of workspaces.entries()) { - let relativePath = relative(relativeFrom, workspacePath) - if (filterArg.startsWith('./')) { - relativePath = `./${relativePath}` - } - const relativeFilter = relative(path, filterArg) - if (filterArg === workspaceName - || resolve(relativeFrom, filterArg) === workspacePath - || minimatch(relativePath, `${globify(relativeFilter)}/*`) - || minimatch(relativePath, `${globify(filterArg)}/*`) - ) { - res.set(workspaceName, workspacePath) - } - } - } - - if (!res.size) { - let msg = '!' - if (filters.length) { - msg = `:\n ${filters.reduce( - (res, filterArg) => `${res} --workspace=${filterArg}`, '')}` - } - - throw new Error(`No workspaces found${msg}`) - } - - return res -} - -module.exports = getWorkspaces diff --git a/make.bat b/make.bat deleted file mode 100644 index d82d893c0802d..0000000000000 --- a/make.bat +++ /dev/null @@ -1,3 +0,0 @@ -:: The tests run "make -s mandocs" in the postsnap script, -:: so this file gives windows something that'll exit -:: successfully, without having to install make. diff --git a/mock-globals/.eslintrc.js b/mock-globals/.eslintrc.js new file mode 100644 index 0000000000000..f21d26eccec7d --- /dev/null +++ b/mock-globals/.eslintrc.js @@ -0,0 +1,20 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +'use strict' + +const { readdirSync: readdir } = require('fs') + +const localConfigs = readdir(__dirname) + .filter((file) => file.startsWith('.eslintrc.local.')) + .map((file) => `./${file}`) + +module.exports = { + root: true, + ignorePatterns: [ + 'tap-testdir*/', + ], + extends: [ + '@npmcli', + ...localConfigs, + ], +} diff --git a/mock-globals/.gitignore b/mock-globals/.gitignore new file mode 100644 index 0000000000000..08e5141aa731c --- /dev/null +++ b/mock-globals/.gitignore @@ -0,0 +1,23 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +# ignore everything in the root +/* + +!**/.gitignore +!/.eslint.config.js +!/.eslintrc.js +!/.eslintrc.local.* +!/.git-blame-ignore-revs +!/.gitignore +!/bin/ +!/CHANGELOG* +!/docs/ +!/lib/ +!/LICENSE* +!/map.js +!/package.json +!/README* +!/scripts/ +!/tap-snapshots/ +!/test/ +tap-testdir*/ diff --git a/mock-globals/lib/index.js b/mock-globals/lib/index.js new file mode 100644 index 0000000000000..ddbc58c2ed40d --- /dev/null +++ b/mock-globals/lib/index.js @@ -0,0 +1,236 @@ +// An initial implementation for a feature that will hopefully exist in tap +// https://github.com/tapjs/node-tap/issues/789 +// This file is only used in tests but it is still tested itself. +// Hopefully it can be removed for a feature in tap in the future + +const sep = '.' +const escapeSep = '"' +const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k) +const opd = (o, k) => Object.getOwnPropertyDescriptor(o, k) +const po = (o) => Object.getPrototypeOf(o) +const pojo = (o) => Object.prototype.toString.call(o) === '[object Object]' +const last = (arr) => arr[arr.length - 1] +const dupes = (arr) => arr.filter((k, i) => arr.indexOf(k) !== i) +const dupesStartsWith = (arr) => arr.filter((k1) => arr.some((k2) => k2.startsWith(k1 + sep))) + +const splitLastSep = (str) => { + let escaped = false + for (let i = str.length - 1; i >= 0; i--) { + const c = str[i] + const cp = str[i + 1] + const cn = str[i - 1] + if (!escaped && c === escapeSep && (cp == null || cp === sep)) { + escaped = true + continue + } + if (escaped && c === escapeSep && cn === sep) { + escaped = false + continue + } + if (!escaped && c === sep) { + return [ + str.slice(0, i), + str.slice(i + 1).replace(new RegExp(`^${escapeSep}(.*)${escapeSep}$`), '$1'), + ] + } + } + return [str] +} + +// A weird getter that can look up keys on nested objects but also +// match keys with dots in their names, eg { 'process.env': { TERM: 'a' } } +// can be looked up with the key 'process.env.TERM' +const get = (obj, key, childKey = '') => { + if (has(obj, key)) { + return childKey ? get(obj[key], childKey) : obj[key] + } + const split = splitLastSep(key) + if (split.length === 2) { + const [parentKey, prefix] = split + return get( + obj, + parentKey, + prefix + (childKey && sep + childKey) + ) + } +} + +// Map an object to an array of nested keys separated by dots +// { a: 1, b: { c: 2, d: [1] } } => ['a', 'b.c', 'b.d'] +const getKeys = (values, p = '', acc = []) => + Object.entries(values).reduce((memo, [k, value]) => { + const key = p ? [p, k].join(sep) : k + return pojo(value) ? getKeys(value, key, memo) : memo.concat(key) + }, acc) + +// Walk prototype chain to get first available descriptor. This is necessary +// to get the current property descriptor for things like `process.on`. +// Since `opd(process, 'on') === undefined` but if you +// walk up the prototype chain you get the original descriptor +// `opd(po(po(process)), 'on') === { value, ... }` +const protoDescriptor = (obj, key) => { + let descriptor + // i always wanted to assign variables in a while loop's condition + // i thought it would feel better than this + while (!(descriptor = opd(obj, key))) { + if (!(obj = po(obj))) { + break + } + } + return descriptor +} + +// Path can be different cases across platform so get the original case +// of the path before anything is changed +// XXX: other special cases to handle? +const specialCaseKeys = (() => { + const originalKeys = { + PATH: process.env.PATH ? 'PATH' : process.env.Path ? 'Path' : 'path', + } + return (key) => { + switch (key.toLowerCase()) { + case 'process.env.path': + return originalKeys.PATH + } + } +})() + +const _setGlobal = Symbol('setGlobal') +const _nextDescriptor = Symbol('nextDescriptor') + +class DescriptorStack { + #stack = [] + #global = null + #valueKey = null + #defaultDescriptor = { configurable: true, writable: true, enumerable: true } + #delete = () => ({ DELETE: true }) + #isDelete = (o) => o && o.DELETE === true + + constructor (key) { + const keys = splitLastSep(key) + this.#global = keys.length === 1 ? global : get(global, keys[0]) + this.#valueKey = specialCaseKeys(key) || last(keys) + // If the global object doesnt return a descriptor for the key + // then we mark it for deletion on teardown + this.#stack = [ + protoDescriptor(this.#global, this.#valueKey) || this.#delete(), + ] + } + + add (value) { + // This must be a unique object so we can find it later via indexOf + // That's why delete/nextDescriptor create new objects + const nextDescriptor = this[_nextDescriptor](value) + this.#stack.push(this[_setGlobal](nextDescriptor)) + + return () => { + const index = this.#stack.indexOf(nextDescriptor) + // If the stack doesnt contain the descriptor anymore + // than do nothing. This keeps the reset function idempotent + if (index > -1) { + // Resetting removes a descriptor from the stack + this.#stack.splice(index, 1) + // But we always reset to what is now the most recent in case + // resets are being called manually out of order + this[_setGlobal](last(this.#stack)) + } + } + } + + reset () { + // Everything could be reset manually so only + // teardown if we have an initial descriptor left + // and then delete the rest of the stack + if (this.#stack.length) { + this[_setGlobal](this.#stack[0]) + this.#stack.length = 0 + } + } + + [_setGlobal] (d) { + if (this.#isDelete(d)) { + delete this.#global[this.#valueKey] + } else { + Object.defineProperty(this.#global, this.#valueKey, d) + } + return d + } + + [_nextDescriptor] (value) { + if (value === undefined) { + return this.#delete() + } + const d = last(this.#stack) + return { + // If the previous descriptor was one to delete the property + // then use the default descriptor as the base + ...(this.#isDelete(d) ? this.#defaultDescriptor : d), + ...(d && d.get ? { get: () => value } : { value }), + } + } +} + +class MockGlobals { + #descriptors = {} + + register (globals, { replace = false } = {}) { + // Replace means don't merge in object values but replace them instead + // so we only get top level keys instead of walking the obj + const keys = replace ? Object.keys(globals) : getKeys(globals) + + // An error state where due to object mode there are multiple global + // values to be set with the same key + const duplicates = dupes(keys) + if (duplicates.length) { + throw new Error(`mockGlobals was called with duplicate keys: ${duplicates}`) + } + + // Another error where when in replace mode overlapping keys are set like + // process and process.stdout which would cause unexpected behavior + const overlapping = dupesStartsWith(keys) + if (overlapping.length) { + const message = overlapping + .map((k) => `${k} -> ${keys.filter((kk) => kk.startsWith(k + sep))}`) + throw new Error(`mockGlobals was called with overlapping keys: ${message}`) + } + + // Set each property passed in and return fns to reset them + // Return an object with each path as a key for manually resetting in each test + return keys.reduce((acc, key) => { + const desc = this.#descriptors[key] || (this.#descriptors[key] = new DescriptorStack(key)) + acc[key] = desc.add(get(globals, key)) + return acc + }, {}) + } + + teardown (key) { + if (!key) { + Object.values(this.#descriptors).forEach((d) => d.reset()) + return + } + this.#descriptors[key].reset() + } +} + +// Each test has one instance of MockGlobals so it can be called multiple times per test +// Its a weak map so that it can be garbage collected along with the tap tests without +// needing to explicitly call cache.delete +const cache = new WeakMap() + +module.exports = (t, globals, options) => { + let instance = cache.get(t) + if (!instance) { + instance = cache.set(t, new MockGlobals()).get(t) + // Teardown only needs to be initialized once. The instance + // will keep track of its own state during the test + t.teardown(() => instance.teardown()) + } + + return { + // Reset contains only the functions to reset the globals + // set by this function call + reset: instance.register(globals, options), + // Teardown will reset across all calls tied to this test + teardown: () => instance.teardown(), + } +} diff --git a/mock-globals/package.json b/mock-globals/package.json new file mode 100644 index 0000000000000..98d849aba496e --- /dev/null +++ b/mock-globals/package.json @@ -0,0 +1,56 @@ +{ + "name": "@npmcli/mock-globals", + "version": "1.0.0", + "description": "", + "main": "lib/index.js", + "private": true, + "scripts": { + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/cli.git", + "directory": "mock-globals" + }, + "keywords": [], + "author": "GitHub Inc.", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/cli/issues" + }, + "homepage": "https://github.com/npm/cli#readme", + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.25.1", + "content": "../scripts/template-oss/index.js" + }, + "tap": { + "branches": 89, + "functions": 97, + "lines": 97, + "statements": 97, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "devDependencies": { + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" + } +} diff --git a/mock-globals/test/index.js b/mock-globals/test/index.js new file mode 100644 index 0000000000000..e926b4d26fa29 --- /dev/null +++ b/mock-globals/test/index.js @@ -0,0 +1,331 @@ +const t = require('tap') +const mockGlobals = require('..') + +/* eslint-disable no-console */ +const originals = { + platform: process.platform, + error: console.error, + stderrOn: process.stderr.on, + stderrWrite: process.stderr.write, + shell: process.env.SHELL, + home: process.env.HOME, + argv: process.argv, + env: process.env, + setInterval, +} + +t.test('console', async t => { + await t.test('mocks', async (t) => { + const errors = [] + mockGlobals(t, { + 'console.error': (...args) => errors.push(...args), + }) + + console.error(1) + console.error(2) + console.error(3) + t.strictSame(errors, [1, 2, 3], 'i got my errors') + }) + + t.equal(console.error, originals.error) +}) +/* eslint-enable no-console */ + +t.test('platform', async (t) => { + t.equal(process.platform, originals.platform) + + await t.test('posix', async (t) => { + mockGlobals(t, { 'process.platform': 'posix' }) + t.equal(process.platform, 'posix') + + await t.test('win32 --> woo', async (t) => { + mockGlobals(t, { 'process.platform': 'win32' }) + t.equal(process.platform, 'win32') + + mockGlobals(t, { 'process.platform': 'woo' }) + t.equal(process.platform, 'woo') + }) + + t.equal(process.platform, 'posix') + }) + + t.equal(process.platform, originals.platform) +}) + +t.test('manual reset', async t => { + let errorHandler, data + + const { reset } = mockGlobals(t, { + 'process.stderr.on': (__, handler) => { + errorHandler = handler + reset['process.stderr.on']() + }, + 'process.stderr.write': (chunk, callback) => { + data = chunk + process.nextTick(() => { + errorHandler({ errno: 'EPIPE' }) + callback() + }) + reset['process.stderr.write']() + }, + }) + + await new Promise((res, rej) => { + process.stderr.on('error', er => er.errno === 'EPIPE' ? res() : rej(er)) + process.stderr.write('hey', res) + }) + + t.equal(process.stderr.on, originals.stderrOn) + t.equal(process.stderr.write, originals.stderrWrite) + t.equal(data, 'hey', 'handles EPIPE errors') + t.ok(errorHandler) +}) + +t.test('reset called multiple times', async (t) => { + await t.test('single reset', async t => { + const { reset } = mockGlobals(t, { 'process.platform': 'z' }) + t.equal(process.platform, 'z') + + reset['process.platform']() + t.equal(process.platform, originals.platform) + + reset['process.platform']() + reset['process.platform']() + reset['process.platform']() + t.equal(process.platform, originals.platform) + }) + + t.equal(process.platform, originals.platform) +}) + +t.test('object mode', async t => { + await t.test('mocks', async t => { + const home = t.testdir() + + mockGlobals(t, { + process: { + stderr: { + on: '1', + }, + env: { + HOME: home, + }, + }, + }) + + t.equal(process.stderr.on, '1') + t.equal(process.env.HOME, home) + }) + + t.equal(process.env.HOME, originals.home) + t.equal(process.stderr.write, originals.stderrWrite) +}) + +t.test('mixed object/string mode', async t => { + await t.test('mocks', async t => { + const home = t.testdir() + + mockGlobals(t, { + 'process.env': { + HOME: home, + TEST: '1', + }, + }) + + t.equal(process.env.HOME, home) + t.equal(process.env.TEST, '1') + }) + + t.equal(process.env.HOME, originals.home) + t.equal(process.env.TEST, undefined) +}) + +t.test('conflicting mixed object/string mode', async t => { + await t.test('same key', async t => { + t.throws( + () => mockGlobals(t, { + process: { + env: { + HOME: '1', + TEST: '1', + NODE_ENV: '1', + }, + stderr: { + write: '1', + }, + }, + 'process.env.HOME': '1', + 'process.stderr.write': '1', + }), + /process.env.HOME,process.stderr.write/ + ) + }) + + await t.test('partial overwrite with replace', async t => { + t.throws( + () => mockGlobals(t, { + process: { + env: { + HOME: '1', + TEST: '1', + NODE_ENV: '1', + }, + stderr: { + write: '1', + }, + }, + 'process.env.HOME': '1', + 'process.stderr.write': '1', + }, { replace: true }), + /process -> process.env.HOME,process.stderr.write/ + ) + }) +}) + +t.test('falsy values', async t => { + await t.test('undefined deletes', async t => { + mockGlobals(t, { 'process.platform': undefined }) + t.notOk(Object.prototype.hasOwnProperty.call(process, 'platform')) + t.equal(process.platform, undefined) + }) + + await t.test('null', async t => { + mockGlobals(t, { 'process.platform': null }) + t.ok(Object.prototype.hasOwnProperty.call(process, 'platform')) + t.equal(process.platform, null) + }) + + t.equal(process.platform, originals.platform) +}) + +t.test('date', async t => { + await t.test('mocks', async t => { + mockGlobals(t, { + 'Date.now': () => 100, + 'Date.prototype.toISOString': () => 'DDD', + }) + t.equal(Date.now(), 100) + t.equal(new Date().toISOString(), 'DDD') + }) + + t.ok(Date.now() > 100) + t.ok(new Date().toISOString().includes('T')) +}) + +t.test('argv', async t => { + await t.test('argv', async t => { + mockGlobals(t, { 'process.argv': ['node', 'woo'] }) + t.strictSame(process.argv, ['node', 'woo']) + }) + + t.strictSame(process.argv, originals.argv) +}) + +t.test('replace', async (t) => { + await t.test('env', async t => { + mockGlobals(t, { 'process.env': { HOME: '1' } }, { replace: true }) + t.strictSame(process.env, { HOME: '1' }) + t.equal(Object.keys(process.env).length, 1) + }) + + await t.test('setInterval', async t => { + mockGlobals(t, { setInterval: 0 }, { replace: true }) + t.strictSame(setInterval, 0) + }) + + t.strictSame(setInterval, originals.setInterval) + t.strictSame(process.env, originals.env) +}) + +t.test('dot key', async t => { + const dotKey = 'this.is.a.single.key' + mockGlobals(t, { + [`process.env."${dotKey}"`]: 'value', + }) + t.strictSame(process.env[dotKey], 'value') +}) + +t.test('multiple mocks and resets', async (t) => { + const initial = 'a' + const platforms = ['b', 'c', 'd', 'e', 'f', 'g'] + + await t.test('first in, first out', async t => { + mockGlobals(t, { 'process.platform': initial }) + t.equal(process.platform, initial) + + await t.test('platforms', async (t) => { + const resets = platforms.map((platform) => { + const { reset } = mockGlobals(t, { 'process.platform': platform }) + t.equal(process.platform, platform) + return reset['process.platform'] + }).reverse() + + ;[...platforms.reverse()].forEach((platform, index) => { + const reset = resets[index] + const nextPlatform = index === platforms.length - 1 ? initial : platforms[index + 1] + t.equal(process.platform, platform) + reset() + t.equal(process.platform, nextPlatform, 'first reset') + reset() + reset() + t.equal(process.platform, nextPlatform, 'multiple resets are idempotent') + }) + }) + + t.equal(process.platform, initial) + }) + + await t.test('last in,first out', async t => { + mockGlobals(t, { 'process.platform': initial }) + t.equal(process.platform, initial) + + await t.test('platforms', async (t) => { + const resets = platforms.map((platform) => { + const { reset } = mockGlobals(t, { 'process.platform': platform }) + t.equal(process.platform, platform) + return reset['process.platform'] + }) + + resets.forEach((reset, index) => { + // Calling a reset out of order removes it from the stack + // but does not change the descriptor so it should still be the + // last in descriptor until there are none left + const lastPlatform = platforms[platforms.length - 1] + const nextPlatform = index === platforms.length - 1 ? initial : lastPlatform + t.equal(process.platform, lastPlatform) + reset() + t.equal(process.platform, nextPlatform, 'multiple resets are idempotent') + reset() + reset() + t.equal(process.platform, nextPlatform, 'multiple resets are idempotent') + }) + }) + + t.equal(process.platform, initial) + }) + + t.test('reset all', async (t) => { + const { teardown } = mockGlobals(t, { 'process.platform': initial }) + + await t.test('platforms', async (t) => { + const resets = platforms.map((p) => { + const { teardown: nestedTeardown, reset } = mockGlobals(t, { 'process.platform': p }) + t.equal(process.platform, p) + return [ + reset['process.platform'], + nestedTeardown, + ] + }) + + resets.forEach(r => r[1]()) + t.equal(process.platform, initial, 'teardown goes to initial value') + + resets.forEach((r) => r[0]()) + t.equal(process.platform, initial, 'calling resets after teardown does nothing') + }) + + t.equal(process.platform, initial) + teardown() + t.equal(process.platform, originals.platform) + }) +}) diff --git a/mock-registry/.eslintrc.js b/mock-registry/.eslintrc.js new file mode 100644 index 0000000000000..f21d26eccec7d --- /dev/null +++ b/mock-registry/.eslintrc.js @@ -0,0 +1,20 @@ +/* This file is automatically added by @npmcli/template-oss. Do not edit. */ + +'use strict' + +const { readdirSync: readdir } = require('fs') + +const localConfigs = readdir(__dirname) + .filter((file) => file.startsWith('.eslintrc.local.')) + .map((file) => `./${file}`) + +module.exports = { + root: true, + ignorePatterns: [ + 'tap-testdir*/', + ], + extends: [ + '@npmcli', + ...localConfigs, + ], +} diff --git a/mock-registry/.eslintrc.local.json b/mock-registry/.eslintrc.local.json new file mode 100644 index 0000000000000..2f2f707c490b9 --- /dev/null +++ b/mock-registry/.eslintrc.local.json @@ -0,0 +1,5 @@ +{ + "rules": { + "import/no-extraneous-dependencies": "off" + } +} diff --git a/mock-registry/.gitignore b/mock-registry/.gitignore new file mode 100644 index 0000000000000..08e5141aa731c --- /dev/null +++ b/mock-registry/.gitignore @@ -0,0 +1,23 @@ +# This file is automatically added by @npmcli/template-oss. Do not edit. + +# ignore everything in the root +/* + +!**/.gitignore +!/.eslint.config.js +!/.eslintrc.js +!/.eslintrc.local.* +!/.git-blame-ignore-revs +!/.gitignore +!/bin/ +!/CHANGELOG* +!/docs/ +!/lib/ +!/LICENSE* +!/map.js +!/package.json +!/README* +!/scripts/ +!/tap-snapshots/ +!/test/ +tap-testdir*/ diff --git a/mock-registry/lib/index.js b/mock-registry/lib/index.js new file mode 100644 index 0000000000000..9b14cd46d8937 --- /dev/null +++ b/mock-registry/lib/index.js @@ -0,0 +1,653 @@ +const Arborist = require('@npmcli/arborist') +const Nock = require('nock') +const npa = require('npm-package-arg') +const pacote = require('pacote') +const path = require('node:path') +const stringify = require('json-stringify-safe') + +const { createReadStream } = require('node:fs') +const fs = require('node:fs/promises') + +const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + +const logReq = (req, ...keys) => { + const obj = JSON.parse(stringify(req)) + const res = {} + for (const [k, v] of Object.entries(obj)) { + if (!keys.includes(k)) { + res[k] = v + } + } + return stringify(res, null, 2) +} + +// helper to convert old audit results to new bulk results +// TODO eventually convert the fixture files themselves +const auditToBulk = audit => { + const bulk = {} + for (const advisory in audit.advisories) { + const { + id, + url, + title, + severity = 'high', + /* eslint-disable-next-line camelcase */ + vulnerable_versions = '*', + module_name: name, + } = audit.advisories[advisory] + bulk[name] = bulk[name] || [] + /* eslint-disable-next-line camelcase */ + bulk[name].push({ id, url, title, severity, vulnerable_versions }) + } + return bulk +} + +class MockRegistry { + #tap + #nock + #registry + #authorization + #basic + #debug + #strict + + constructor (opts) { + if (!opts.registry) { + throw new Error('mock registry requires a registry value') + } + this.#registry = new URL(opts.registry) + this.#authorization = opts.authorization + this.#basic = opts.basic + this.#debug = opts.debug + this.#strict = opts.strict + // Required for this.package + this.#tap = opts.tap + if (this.#tap) { + this.startNock() + } + } + + static tnock (t, host, opts, { debug = false, strict = false } = {}) { + const noMatch = (req) => { + if (debug) { + /* eslint-disable-next-line no-console */ + console.error('NO MATCH', t.name, req.options ? req.options : req.path) + } + if (strict) { + // There are network requests that get caught regardless of error code. + // Turning on strict mode requires that those requests get explicitly + // mocked with a 404, 500, etc. + // XXX: this is opt-in currently because it breaks some existing CLI + // tests. We should work towards making this the default for all tests. + t.comment(logReq(req, 'interceptors', 'socket', 'response', '_events')) + const protocol = req?.options?.protocol || 'http:' + const hostname = req?.options?.hostname || req?.hostname || 'localhost' + const p = req?.path || '/' + const url = new URL(p, `${protocol}//${hostname}`).toString() + t.fail(`Unmatched request: ${req.method} ${url}`) + } + } + + Nock.emitter.on('no match', noMatch) + Nock.disableNetConnect() + const server = Nock(host, opts) + + if (strict) { + // this requires that mocks not be shared between sub tests but it helps + // find mistakes quicker instead of waiting for the entire test to end + t.afterEach((t) => { + t.strictSame(server.pendingMocks(), [], 'no pending mocks after each') + }) + } + + t.teardown(() => { + Nock.enableNetConnect() + server.done() + Nock.emitter.off('no match', noMatch) + Nock.cleanAll() + }) + + return server + } + + get origin () { + return this.#registry.origin + } + + get pathname () { + if (this.#registry.pathname.endsWith('/')) { + return this.#registry.pathname.slice(0, -1) + } + return this.#registry.pathname + } + + get nock () { + return this.#nock + } + + set nock (nock) { + this.#nock = nock + } + + startNock () { + if (this.nock) { + return + } + + if (!this.#tap) { + throw new Error('cannot mock packages without a tap fixture') + } + + const reqheaders = {} + if (this.#authorization) { + reqheaders.authorization = `Bearer ${this.#authorization}` + } + if (this.#basic) { + reqheaders.authorization = `Basic ${this.#basic}` + } + + this.nock = MockRegistry.tnock( + this.#tap, + this.origin, + { reqheaders }, + { debug: this.#debug, strict: this.#strict } + ) + } + + fullPath (uri) { + return `${this.pathname}${uri}` + } + + search ({ responseCode = 200, results = [], error }) { + // the flags, score, and searchScore parts of the response are never used + // by npm, only package is used + const response = results.map(p => ({ package: p })) + this.nock = this.nock.get(this.fullPath(`/-/v1/search`)).query(true) + if (error) { + this.nock = this.nock.replyWithError(error) + } else { + this.nock = this.nock.reply(responseCode, { objects: response }) + } + return this.nock + } + + whoami ({ username, body, responseCode = 200, times = 1 }) { + if (username) { + this.nock = this.nock.get(this.fullPath('/-/whoami')).times(times) + .reply(responseCode, { username }) + } else { + this.nock = this.nock.get(this.fullPath('/-/whoami')).times(times) + .reply(responseCode, body) + } + } + + setAccess ({ spec, body = {} }) { + this.nock = this.nock.post( + this.fullPath(`/-/package/${npa(spec).escapedName}/access`), + body + ).reply(200) + } + + getVisibility ({ spec, visibility, responseCode = 200 }) { + this.nock = this.nock.get( + this.fullPath(`/-/package/${npa(spec).escapedName}/visibility`)) + .reply(responseCode, visibility) + } + + setPermissions ({ spec, team, permissions }) { + if (team.startsWith('@')) { + team = team.slice(1) + } + const [scope, teamName] = team.split(':') + this.nock = this.nock.put( + this.fullPath(`/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`), + { package: spec, permissions } + ).reply(200) + } + + removePermissions ({ spec, team }) { + if (team.startsWith('@')) { + team = team.slice(1) + } + const [scope, teamName] = team.split(':') + this.nock = this.nock.delete( + this.fullPath(`/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`), + { package: spec } + ).reply(200) + } + + couchuser ({ username, body, responseCode = 200 }) { + if (body) { + this.nock = this.nock.get( + this.fullPath(`/-/user/org.couchdb.user:${encodeURIComponent(username)}`) + ).reply(responseCode, body) + } else { + this.nock = this.nock.get( + this.fullPath(`/-/user/org.couchdb.user:${encodeURIComponent(username)}`) + ).reply(responseCode, { _id: `org.couchdb.user:${username}`, email: '', name: username }) + } + } + + couchadduser ({ username, email, password, token = 'npm_default-test-token' }) { + this.nock = this.nock.put(this.fullPath(`/-/user/org.couchdb.user:${username}`), body => { + this.#tap.match(body, { + _id: `org.couchdb.user:${username}`, + name: username, + email, // Sole difference from couchlogin + password, + type: 'user', + roles: [], + }) + if (!body.date) { + return false + } + return true + }).reply(201, { + id: 'org.couchdb.user:undefined', + rev: '_we_dont_use_revs_any_more', + token, + }) + } + + couchlogin ({ username, password, token = 'npm_default-test-token' }) { + this.nock = this.nock.put(this.fullPath(`/-/user/org.couchdb.user:${username}`), body => { + this.#tap.match(body, { + _id: `org.couchdb.user:${username}`, + name: username, + password, + type: 'user', + roles: [], + }) + if (!body.date) { + return false + } + return true + }).reply(201, { + id: 'org.couchdb.user:undefined', + rev: '_we_dont_use_revs_any_more', + token, + }) + } + + webadduser ({ token = 'npm_default-test-token' }) { + const doneUrl = new URL('/npm-cli-test/done', this.origin).href + const loginUrl = new URL('/npm-cli-test/login', this.origin).href + this.nock = this.nock + .post(this.fullPath('/-/v1/login'), body => { + this.#tap.ok(body.create) // Sole difference from weblogin + return true + }) + .reply(200, { doneUrl, loginUrl }) + .get('/npm-cli-test/done') + .reply(200, { token }) + } + + weblogin ({ token = 'npm_default-test-token' }) { + const doneUrl = new URL('/npm-cli-test/done', this.origin).href + const loginUrl = new URL('/npm-cli-test/login/cli/00000000-0000-0000-0000-000000000000', this.origin).href + this.nock = this.nock + .post(this.fullPath('/-/v1/login'), () => { + return true + }) + .reply(200, { doneUrl, loginUrl }) + .get('/npm-cli-test/done') + .reply(200, { token }) + } + + logout (token) { + this.nock = this.nock.delete(this.fullPath(`/-/user/token/${encodeURIComponent(token)}`)) + .reply(200, { ok: true }) + } + + // team can be a team or a username + getPackages ({ user, team, packages = {}, times = 1, responseCode = 200 }) { + let uri + if (user) { + uri = `/-/user/${user}/package` + } else { + if (team.startsWith('@')) { + team = team.slice(1) + } + const [scope, teamName] = team.split(':').map(encodeURIComponent) + if (teamName) { + uri = `/-/team/${scope}/${teamName}/package` + } else { + uri = `/-/org/${scope}/package` + } + } + this.nock = this.nock.get(this.fullPath(uri)).times(times).reply(responseCode, packages) + } + + getCollaborators ({ spec, collaborators = {} }) { + this.nock = this.nock.get(this.fullPath(`/-/package/${npa(spec).escapedName}/collaborators`) + ).reply(200, collaborators) + } + + advisory (advisory = {}) { + const id = advisory.id || parseInt(Math.random() * 1000000) + return { + id, + url: `https://github.com/advisories/GHSA-${id}`, + title: `Test advisory ${id}`, + severity: 'high', + vulnerable_versions: '*', + cwe: [ + 'cwe-0', + ], + cvss: { + score: 0, + }, + ...advisory, + } + } + + star (manifest, users) { + const spec = npa(manifest.name) + this.nock = this.nock.put(this.fullPath(`/${spec.escapedName}`), { + _id: manifest._id, + _rev: manifest._rev, + users, + }).reply(200, { ...manifest, users }) + } + + ping ({ body = {}, responseCode = 200 } = {}) { + this.nock = this.nock.get(this.fullPath('/-/ping')).reply(responseCode, body) + } + + // full unpublish of an entire package + unpublish ({ manifest }) { + let nock = this.nock + const spec = npa(manifest.name) + nock = nock.delete(this.fullPath(`/${spec.escapedName}/-rev/${manifest._rev}`)).reply(201) + return nock + } + + publish (name, { + packageJson, access, noGet, noPut, putCode, manifest, packuments, token, + } = {}) { + if (!noGet) { + // this getPackage call is used to get the latest semver version before publish + if (manifest) { + this.getPackage(name, { code: 200, resp: manifest }) + } else if (packuments) { + this.getPackage(name, { code: 200, resp: this.manifest({ name, packuments }) }) + } else { + // assumes the package does not exist yet and will 404 x2 from pacote.manifest + this.getPackage(name, { times: 2, code: 404 }) + } + } + if (!noPut) { + this.putPackage(name, { code: putCode, packageJson, access, token }) + } + } + + getPackage (name, { times = 1, code = 200, query, resp = {} }) { + let nock = this.nock + nock = nock.get(`/${npa(name).escapedName}`).times(times) + if (query) { + nock = nock.query(query) + } + if (code === 404) { + nock = nock.reply(code, { error: 'Not found' }) + } else { + nock = nock.reply(code, resp) + } + this.nock = nock + } + + putPackage (name, { code = 200, resp = {}, token, ...putPackagePayload }) { + let n = this.nock.put(`/${npa(name).escapedName}`, body => { + return this.#tap.match(body, this.putPackagePayload({ name, ...putPackagePayload })) + }) + if (token) { + n = n.matchHeader('authorization', `Bearer ${token}`) + } + n.reply(code, resp) + } + + putPackagePayload (opts) { + const pkg = opts.packageJson + const name = opts.name || pkg?.name + const registry = opts.registry || pkg?.publishConfig?.registry || 'https://registry.npmjs.org' + const access = opts.access || null + + const nameProperties = !name ? {} : { + _id: name, + name: name, + } + + const packageProperties = !pkg ? {} : { + 'dist-tags': { latest: pkg.version }, + versions: { + [pkg.version]: { + _id: `${pkg.name}@${pkg.version}`, + dist: { + shasum: /\.*/, + tarball: + `http://${new URL(registry).host}/${pkg.name}/-/${pkg.name}-${pkg.version}.tgz`, + }, + ...pkg, + }, + }, + _attachments: { + [`${pkg.name}-${pkg.version}.tgz`]: {}, + }, + } + + return { + access, + ...nameProperties, + ...packageProperties, + } + } + + getTokens (tokens) { + return this.nock.get(this.fullPath('/-/npm/v1/tokens')) + .reply(200, { + objects: tokens, + urls: {}, + total: tokens.length, + userHasOldFormatToken: false, + }) + } + + // The server has rules for what resultData correlates with what tokenData but we don't need to be 100% in sync with that, we just need to be able to pass all of the possible tokenData attributes, and be able to accept all of the possible resultData attributes + createToken (tokenData, resultData = {}) { + return this.nock.post(this.fullPath('/-/npm/v1/tokens'), tokenData) + .reply(201, { + id: `0xdeadbeef`, + key: 'n3wk3y', + token: 'n3wt0k3n', + created: new Date(), + updated: new Date(), + access: 'read-only', + name: tokenData.name, + password: tokenData.password, + ...resultData, + }) + } + + revokeToken (token) { + return this.nock.delete( + this.fullPath(`/-/npm/v1/tokens/token/${token}`) + ).reply(200) + } + + async package ({ manifest, times = 1, query, tarballs }) { + let nock = this.nock + const spec = npa(manifest.name) + nock = nock.get(this.fullPath(`/${spec.escapedName}`)).times(times) + if (query) { + nock = nock.query(query) + } + nock = nock.reply(200, manifest) + if (tarballs) { + for (const [version, tarball] of Object.entries(tarballs)) { + const m = manifest.versions[version] + nock = await this.tarball({ manifest: m, tarball }) + } + } + this.nock = nock + } + + async tarball ({ manifest, tarball }) { + const nock = this.nock + const dist = new URL(manifest.dist.tarball) + const tar = await pacote.tarball(tarball, { Arborist }) + nock.get(this.fullPath(dist.pathname)).reply(200, tar) + return nock + } + + // either pass in packuments if you need to set specific attributes besides version, + // or an array of versions + // the last packument in the packuments or versions array will be tagged latest + manifest ({ name = 'test-package', users, packuments, versions } = {}) { + packuments = this.packuments(versions || packuments, name) + const latest = packuments.slice(-1)[0] + const manifest = { + _id: `${name}@${latest.version}`, + _rev: '00-testdeadbeef', + name, + description: 'test package mock manifest', + dependencies: {}, + versions: {}, + time: {}, + 'dist-tags': { latest: latest.version }, + ...latest, + } + if (users) { + manifest.users = users + } + for (const packument of packuments) { + const unscoped = name.includes('/') ? name.split('/')[1] : name + manifest.versions[packument.version] = { + _id: `${name}@${packument.version}`, + name, + description: 'test package mock manifest', + dependencies: {}, + dist: { + /* eslint-disable-next-line max-len */ + tarball: `${this.origin}${this.fullPath(`/${name}/-/${unscoped}-${packument.version}.tgz`)}`, + }, + maintainers: [], + ...packument, + } + manifest.time[packument.version] = new Date() + } + + return manifest + } + + packuments (packuments = ['1.0.0'], name) { + return packuments.map(p => this.packument(p, name)) + } + + // Generate packument from shorthand + packument (packument, name = 'test-package') { + if (!packument.version) { + packument = { version: packument } + } + return { + name, + version: '1.0.0', + description: 'mocked test package', + dependencies: {}, + ...packument, + } + } + + // bulk advisory audit endpoint + audit ({ responseCode = 200, results = {}, convert = false, times = 1 } = {}) { + this.nock = this.nock + .post(this.fullPath('/-/npm/v1/security/advisories/bulk')) + .times(times) + .reply( + responseCode, + convert ? auditToBulk(results) : results + ) + } + + // Used in Arborist to mock the registry from fixture data on disk + // Will eat up all GET requests to the entire registry, so it probably doesn't work with the other GET routes very well. + mocks ({ dir }) { + const exists = (p) => fs.stat(p).then((s) => s).catch(() => false) + this.nock = this.nock.get(/.*/).reply(async function () { + const { headers, path: url } = this.req + const isCorgi = headers.accept.includes('application/vnd.npm.install-v1+json') + const encodedUrl = url.replace(/@/g, '').replace(/%2f/gi, '/') + const f = path.join(dir, 'registry-mocks', 'content', encodedUrl) + let file = f + let contentType = 'application/octet-stream' + if (isCorgi && await exists(`${f}.min.json`)) { + file = `${f}.min.json` + contentType = corgiDoc + } else if (await exists(`${f}.json`)) { + file = `${f}.json` + contentType = 'application/json' + } else if (await exists(`${f}/index.json`)) { + file = `${f}index.json` + contentType = 'application/json' + } + const stats = await exists(file) + if (stats) { + const body = createReadStream(file) + body.pause() + return [200, body, { 'content-type': contentType, 'content-length': stats.size }] + } + return [404, { error: 'not found' }] + }).persist() + } + + /** + * this is a simpler convenience method for creating mockable registry with + * tarballs for specific versions + */ + async setup (packages) { + const format = Object.keys(packages).map(v => { + const [name, version] = v.split('@') + return { name, version } + }).reduce((acc, inc) => { + const exists = acc.find(pkg => pkg.name === inc.name) + if (exists) { + exists.tarballs = { + ...exists.tarballs, + [inc.version]: packages[`${inc.name}@${inc.version}`], + } + } else { + acc.push({ name: inc.name, + tarballs: { + [inc.version]: packages[`${inc.name}@${inc.version}`], + }, + }) + } + return acc + }, []) + const registry = this + for (const pkg of format) { + const { name, tarballs } = pkg + const versions = Object.keys(tarballs) + const manifest = await registry.manifest({ name, versions }) + + for (const version of versions) { + const tarballPath = pkg.tarballs[version] + if (!tarballPath) { + throw new Error(`Tarball path not provided for version ${version}`) + } + + await registry.tarball({ + manifest: manifest.versions[version], + tarball: tarballPath, + }) + } + } + } + + mockOidcTokenExchange ({ packageName, idToken, statusCode = 200, body } = {}) { + const encodedPackageName = npa(packageName).escapedName + this.nock.post(this.fullPath(`/-/npm/v1/oidc/token/exchange/package/${encodedPackageName}`)) + .matchHeader('authorization', `Bearer ${idToken}`) + .reply(statusCode, body || {}) + } +} + +module.exports = MockRegistry diff --git a/mock-registry/lib/provenance.js b/mock-registry/lib/provenance.js new file mode 100644 index 0000000000000..371bd56dcc930 --- /dev/null +++ b/mock-registry/lib/provenance.js @@ -0,0 +1,98 @@ +const mockGlobals = require('@npmcli/mock-globals') +const nock = require('nock') + +const sigstoreIdToken = () => { + return `.${Buffer.from(JSON.stringify({ + iss: 'https://oauth2.sigstore.dev/auth', + email: 'foo@bar.com', + email_verified: true, + })) + .toString('base64')}.` +} + +const mockProvenance = (t, { + oidcURL, + requestToken, + workflowPath, + repository, + serverUrl, + ref, + sha, + runID, + runAttempt, + runnerEnv, +}) => { + const idToken = sigstoreIdToken() + + mockGlobals(t, { + 'process.env': { + CI: true, + GITHUB_ACTIONS: true, + ACTIONS_ID_TOKEN_REQUEST_URL: oidcURL, + ACTIONS_ID_TOKEN_REQUEST_TOKEN: requestToken, + GITHUB_WORKFLOW_REF: `${repository}/${workflowPath}@${ref}`, + GITHUB_REPOSITORY: repository, + GITHUB_SERVER_URL: serverUrl, + GITHUB_REF: ref, + GITHUB_SHA: sha, + GITHUB_RUN_ID: runID, + GITHUB_RUN_ATTEMPT: runAttempt, + RUNNER_ENVIRONMENT: runnerEnv, + }, + }) + + const url = new URL(oidcURL) + nock(url.origin) + .get(url.pathname) + .query({ audience: 'sigstore' }) + .matchHeader('authorization', `Bearer ${requestToken}`) + .matchHeader('accept', 'application/json') + .reply(200, { value: idToken }) + + const leafCertificate = `-----BEGIN CERTIFICATE-----\nabc\n-----END CERTIFICATE-----\n` + + // Mock the Fulcio signing certificate endpoint + nock('https://fulcio.sigstore.dev') + .post('/api/v2/signingCert') + .reply(200, { + signedCertificateEmbeddedSct: { + chain: { + certificates: [ + leafCertificate, + `-----BEGIN CERTIFICATE-----\nxyz\n-----END CERTIFICATE-----\n`, + ], + }, + }, + }) + + nock('https://rekor.sigstore.dev') + .post('/api/v1/log/entries') + .reply(201, { + '69e5a0c1663ee4452674a5c9d5050d866c2ee31e2faaf79913aea7cc27293cf6': { + body: Buffer.from(JSON.stringify({ + kind: 'hashedrekord', + apiVersion: '0.0.1', + spec: { + signature: { + content: 'ABC123', + publicKey: { content: Buffer.from(leafCertificate).toString('base64') }, + }, + }, + })).toString( + 'base64' + ), + integratedTime: 1654015743, + logID: + 'c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d', + logIndex: 2513258, + verification: { + signedEntryTimestamp: 'MEUCIQD6CD7ZNLUipFoxzmSL/L8Ewic4SRkXN77UjfJZ7d/wAAIgatokSuX9Rg0iWxAgSfHMtcsagtDCQalU5IvXdQ+yLEA=', + }, + }, + }) +} + +module.exports = { + mockProvenance, + sigstoreIdToken, +} diff --git a/mock-registry/package.json b/mock-registry/package.json new file mode 100644 index 0000000000000..94d3baeb27c49 --- /dev/null +++ b/mock-registry/package.json @@ -0,0 +1,58 @@ +{ + "name": "@npmcli/mock-registry", + "version": "1.0.0", + "description": "", + "main": "lib/index.js", + "private": true, + "scripts": { + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/cli.git", + "directory": "mock-registry" + }, + "keywords": [], + "author": "GitHub Inc.", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/cli/issues" + }, + "homepage": "https://github.com/npm/cli#readme", + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.25.1", + "content": "../scripts/template-oss/index.js" + }, + "tap": { + "no-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "devDependencies": { + "@npmcli/arborist": "^9.1.2", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "json-stringify-safe": "^5.0.1", + "nock": "^13.3.3", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "tap": "^16.3.8" + } +} diff --git a/mock-registry/test/index.js b/mock-registry/test/index.js new file mode 100644 index 0000000000000..45f9bc16d0dc3 --- /dev/null +++ b/mock-registry/test/index.js @@ -0,0 +1,8 @@ +const t = require('tap') +const MockRegistry = require('..') + +t.test('it works', async t => { + t.ok(new MockRegistry({ + registry: 'http://registry.npmjs.org/', + })) +}) diff --git a/node_modules/.gitignore b/node_modules/.gitignore index aa43a2716ee15..bea846f692dad 100644 --- a/node_modules/.gitignore +++ b/node_modules/.gitignore @@ -1,10 +1,188 @@ -# Automatically generated to ignore dev deps -/.package-lock.json +# Automatically generated to ignore everything except bundled deps +# Ignore everything by default except this file +/* +!/.gitignore +# Allow all bundled deps +!/@isaacs/ +/@isaacs/* +!/@isaacs/balanced-match +!/@isaacs/brace-expansion +!/@isaacs/fs-minipass +!/@isaacs/string-locale-compare +!/@npmcli/ +/@npmcli/* +!/@npmcli/agent +!/@npmcli/fs +!/@npmcli/git +!/@npmcli/installed-package-contents +!/@npmcli/map-workspaces +!/@npmcli/metavuln-calculator +!/@npmcli/name-from-folder +!/@npmcli/node-gyp +!/@npmcli/package-json +!/@npmcli/promise-spawn +!/@npmcli/query +!/@npmcli/redact +!/@npmcli/run-script +!/@sigstore/ +/@sigstore/* +!/@sigstore/bundle +!/@sigstore/core +!/@sigstore/protobuf-specs +!/@sigstore/sign +!/@sigstore/tuf +!/@sigstore/verify +!/@tufjs/ +/@tufjs/* +!/@tufjs/canonical-json +!/@tufjs/models +!/abbrev +!/agent-base +!/ansi-regex +!/aproba +!/archy +!/bin-links +!/binary-extensions +!/cacache +!/chalk +!/chownr +!/ci-info +!/cidr-regex +!/cli-columns +!/cmd-shim +!/common-ancestor-path +!/cssesc +!/debug +!/diff +!/emoji-regex +!/encoding +!/env-paths +!/err-code +!/exponential-backoff +!/fastest-levenshtein +!/fs-minipass +!/glob +!/graceful-fs +!/hosted-git-info +!/http-cache-semantics +!/http-proxy-agent +!/https-proxy-agent +!/iconv-lite +!/ignore-walk +!/imurmurhash +!/ini +!/init-package-json +!/ip-address +!/ip-regex +!/is-cidr +!/is-fullwidth-code-point +!/isexe +!/json-parse-even-better-errors +!/json-stringify-nice +!/jsonparse +!/just-diff-apply +!/just-diff +!/lru-cache +!/make-fetch-happen +!/minimatch +!/minipass-collect +!/minipass-fetch +!/minipass-flush +!/minipass-flush/node_modules/ +/minipass-flush/node_modules/* +!/minipass-flush/node_modules/minipass +!/minipass-pipeline +!/minipass-pipeline/node_modules/ +/minipass-pipeline/node_modules/* +!/minipass-pipeline/node_modules/minipass +!/minipass-sized +!/minipass +!/minizlib +!/ms +!/mute-stream +!/negotiator +!/node-gyp +!/nopt +!/npm-audit-report +!/npm-bundled +!/npm-install-checks +!/npm-normalize-package-bin +!/npm-package-arg +!/npm-packlist +!/npm-pick-manifest +!/npm-profile +!/npm-registry-fetch +!/npm-user-validate +!/p-map +!/pacote +!/parse-conflict-json +!/path-scurry +!/postcss-selector-parser +!/proc-log +!/proggy +!/promise-all-reject-late +!/promise-call-limit +!/promise-retry +!/promzard +!/qrcode-terminal +!/read-cmd-shim +!/read +!/retry +!/safer-buffer +!/semver +!/signal-exit +!/sigstore +!/smart-buffer +!/socks-proxy-agent +!/socks +!/spdx-correct +!/spdx-correct/node_modules/ +/spdx-correct/node_modules/* +!/spdx-correct/node_modules/spdx-expression-parse +!/spdx-exceptions +!/spdx-expression-parse +!/spdx-license-ids +!/ssri +!/string-width +!/strip-ansi +!/supports-color +!/tar +!/tar/node_modules/ +/tar/node_modules/* +!/tar/node_modules/yallist +!/text-table +!/tiny-relative-date +!/tinyglobby +!/tinyglobby/node_modules/ +/tinyglobby/node_modules/* +!/tinyglobby/node_modules/fdir +!/tinyglobby/node_modules/picomatch +!/treeverse +!/tuf-js +!/unique-filename +!/unique-slug +!/util-deprecate +!/validate-npm-package-license +!/validate-npm-package-license/node_modules/ +/validate-npm-package-license/node_modules/* +!/validate-npm-package-license/node_modules/spdx-expression-parse +!/validate-npm-package-name +!/walk-up-path +!/which +!/write-file-atomic +!/yallist +# Always ignore some specific patterns within any allowed package +.bin/ +.cache/ package-lock.json CHANGELOG* changelog* +ChangeLog* +Changelog* README* readme* +ReadMe* +Readme* __pycache__ .editorconfig .idea/ @@ -24,419 +202,7 @@ __pycache__ .babelrc* .nyc_output .gitkeep - -/@babel/code-frame -/@babel/core -/@babel/generator -/@babel/helper-environment-visitor -/@babel/helper-function-name -/@babel/helper-get-function-arity -/@babel/helper-hoist-variables -/@babel/helper-module-imports -/@babel/helper-module-transforms -/@babel/helper-plugin-utils -/@babel/helper-simple-access -/@babel/helper-split-export-declaration -/@babel/helper-validator-identifier -/@babel/helpers -/@babel/highlight -/@babel/parser -/@babel/plugin-proposal-object-rest-spread -/@babel/plugin-syntax-jsx -/@babel/plugin-syntax-object-rest-spread -/@babel/plugin-transform-parameters -/@babel/template -/@babel/traverse -/@babel/types -/@blueoak/list -/@eslint/eslintrc -/@humanwhocodes/config-array -/@humanwhocodes/object-schema -/@istanbuljs/load-nyc-config -/@istanbuljs/schema -/@mdx-js/mdx -/@mdx-js/util -/@npmcli/eslint-config -/@npmcli/template-oss -/@types/hast -/@types/mdast -/@types/parse5 -/@types/unist -/abab -/acorn -/acorn-globals -/acorn-jsx -/acorn-walk -/ajv -/anymatch -/append-transform -/arg -/argparse -/array-find-index -/asn1 -/assert-plus -/async-hook-domain -/asynckit -/aws-sign2 -/aws4 -/babel-plugin-apply-mdx-type-prop -/babel-plugin-extract-import-names -/bail -/base64-js -/bcrypt-pbkdf -/benchmark -/bind-obj-methods -/bindings -/bl -/braces -/browser-process-hrtime -/buffer -/buffer-from -/caching-transform -/call-bind -/caller -/callsites -/camelcase -/camelcase-css -/caseless -/ccount -/character-entities -/character-entities-legacy -/character-reference-invalid -/chokidar -/cliui -/cmark-gfm -/code-point-at -/collapse-white-space -/combined-stream -/comma-separated-tokens -/commondir -/convert-source-map -/core-util-is -/correct-license-metadata -/coveralls -/cross-spawn -/cssom -/cssstyle -/dashdash -/data-urls -/decamelize -/decimal.js -/decompress-response -/deep-extend -/deep-is -/default-require-extensions -/define-properties -/delayed-stream -/detab -/detect-libc -/docopt -/docs -/doctrine -/domexception -/ecc-jsbn -/end-of-stream -/es-abstract -/es-to-primitive -/es6-error -/escape-string-regexp -/escodegen -/eslint -/eslint-plugin-es -/eslint-plugin-node -/eslint-scope -/eslint-utils -/eslint-visitor-keys -/espree -/esprima -/esquery -/esrecurse -/estraverse -/esutils -/events-to-array -/expand-template -/extend -/extsprintf -/fast-deep-equal -/fast-json-stable-stringify -/fast-levenshtein -/file-entry-cache -/file-uri-to-path -/fill-range -/find-cache-dir -/findit -/flat-cache -/flatted -/flow-parser -/flow-remove-types -/foreground-child -/forever-agent -/form-data -/fromentries -/fs-access -/fs-constants -/fs-exists-cached -/fsevents -/function-loop -/functional-red-black-tree -/gensync -/get-caller-file -/get-intrinsic -/get-package-type -/get-symbol-description -/getpass -/github-from-package -/glob-parent -/globals -/handlebars -/har-schema -/har-validator -/has-bigints -/has-symbols -/has-tostringtag -/hasha -/hast-to-hyperscript -/hast-util-from-parse5 -/hast-util-parse-selector -/hast-util-raw -/hast-util-to-parse5 -/hastscript -/html-encoding-sniffer -/html-escaper -/html-void-elements -/http-signature -/ieee754 -/ignore -/import-fresh -/inline-style-parser -/internal-slot -/is-alphabetical -/is-alphanumerical -/is-bigint -/is-binary-path -/is-boolean-object -/is-buffer -/is-callable -/is-date-object -/is-decimal -/is-extglob -/is-glob -/is-hexadecimal -/is-negative-zero -/is-number -/is-number-object -/is-plain-obj -/is-potential-custom-element-name -/is-regex -/is-shared-array-buffer -/is-stream -/is-string -/is-symbol -/is-typedarray -/is-weakref -/is-whitespace-character -/is-windows -/is-word-character -/isarray -/isstream -/istanbul-lib-coverage -/istanbul-lib-hook -/istanbul-lib-instrument -/istanbul-lib-processinfo -/istanbul-lib-report -/istanbul-lib-source-maps -/istanbul-reports -/jackspeak -/js-tokens -/js-yaml -/jsbn -/jsdom -/jsesc -/json-parse-errback -/json-schema -/json-schema-traverse -/json-stable-stringify-without-jsonify -/json-stringify-safe -/json5 -/jsprim -/lcov-parse -/levn -/libtap -/licensee -/lodash -/lodash.clonedeep -/lodash.flattendeep -/lodash.merge -/lodash.uniq -/log-driver -/make-dir -/make-error -/markdown-escapes -/marked -/marked-man -/mdast-squeeze-paragraphs -/mdast-util-definitions -/mdast-util-to-hast -/mdurl -/mime-db -/mime-types -/mimic-response -/minify-registry-metadata -/minimist -/mkdirp-classic -/napi-build-utils -/natural-compare -/neo-async -/nock -/node-abi -/node-addon-api -/node-modules-regexp -/node-preload -/normalize-path -/npm-license-corrections -/null-check -/number-is-nan -/nwsapi -/nyc -/oauth-sign -/object-assign -/object-inspect -/object-keys -/object.assign -/object.getownpropertydescriptors -/optionator -/own-or -/own-or-env -/package-hash -/parent-module -/parse-entities -/parse5 -/path-key -/path-parse -/performance-now -/picomatch -/pirates -/platform -/prebuild-install -/prelude-ls -/process-nextick-args -/process-on-spawn -/propagate -/property-information -/psl -/pump -/punycode -/qs -/queue-microtask -/rc -/read-package-tree -/readdirp -/regexpp -/release-zalgo -/remark-footnotes -/remark-mdx -/remark-parse -/remark-squeeze-paragraphs -/repeat-string -/request -/require-directory -/require-inject -/require-main-filename -/resolve -/resolve-from -/run-parallel -/saxes -/shebang-command -/shebang-regex -/side-channel -/simple-concat -/simple-get -/smoke-tests -/source-map -/source-map-support -/space-separated-tokens -/spawk -/spawn-wrap -/spdx-compare -/spdx-expression-validate -/spdx-osi -/spdx-ranges -/spdx-whitelisted -/sprintf-js -/sshpk -/stack-utils -/state-toggle -/string.prototype.trimend -/string.prototype.trimstart -/strip-json-comments -/style-to-object -/supports-preserve-symlinks-flag -/symbol-tree -/tap -/tap-mocha-reporter -/tap-parser -/tap-yaml -/tar-fs -/tar-stream -/tcompare -/test-exclude -/to-fast-properties -/to-regex-range -/tough-cookie -/tr46 -/trim -/trim-trailing-lines -/trivial-deferred -/trough -/ts-node -/tunnel-agent -/tweetnacl -/type-check -/type-fest -/typescript -/uglify-js -/unbox-primitive -/unherit -/unicode-length -/unified -/unist-builder -/unist-util-generated -/unist-util-is -/unist-util-position -/unist-util-remove -/unist-util-remove-position -/unist-util-stringify-position -/unist-util-visit -/unist-util-visit-parents -/universalify -/uri-js -/util-promisify -/uuid -/v8-compile-cache -/verror -/vfile -/vfile-location -/vfile-message -/vlq -/w3c-hr-time -/w3c-xmlserializer -/web-namespaces -/webidl-conversions -/whatwg-encoding -/whatwg-mimetype -/whatwg-url -/which-boxed-primitive -/which-module -/word-wrap -/wordwrap -/wrap-ansi -/ws -/xml-name-validator -/xmlchars -/xtend -/y18n -/yaml -/yargs -/yargs-parser -/yn -/zwitch +*.map +*.ts +*.png +*.jpg diff --git a/node_modules/@colors/colors/LICENSE b/node_modules/@colors/colors/LICENSE deleted file mode 100644 index 6b86056199d2a..0000000000000 --- a/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@gmail.com> (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/node_modules/@colors/colors/examples/normal-usage.js b/node_modules/@colors/colors/examples/normal-usage.js deleted file mode 100644 index a4bfe7b7be633..0000000000000 --- a/node_modules/@colors/colors/examples/normal-usage.js +++ /dev/null @@ -1,83 +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/node_modules/@colors/colors/examples/safe-string.js b/node_modules/@colors/colors/examples/safe-string.js deleted file mode 100644 index fc664745705f3..0000000000000 --- a/node_modules/@colors/colors/examples/safe-string.js +++ /dev/null @@ -1,80 +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/node_modules/@colors/colors/index.d.ts b/node_modules/@colors/colors/index.d.ts deleted file mode 100644 index df3f2e6afc945..0000000000000 --- a/node_modules/@colors/colors/index.d.ts +++ /dev/null @@ -1,136 +0,0 @@ -// Type definitions for @colors/colors 1.4+ -// Project: https://github.com/Marak/colors.js -// Definitions by: Bart van der Schoor <https://github.com/Bartvds>, Staffan Eketorp <https://github.com/staeke> -// Definitions: https://github.com/DABH/colors.js - -export interface Color { - (text: string): string; - - strip: Color; - stripColors: Color; - - black: Color; - red: Color; - green: Color; - yellow: Color; - blue: Color; - magenta: Color; - cyan: Color; - white: Color; - gray: Color; - grey: Color; - - bgBlack: Color; - bgRed: Color; - bgGreen: Color; - bgYellow: Color; - bgBlue: Color; - bgMagenta: Color; - bgCyan: Color; - bgWhite: Color; - - reset: Color; - bold: Color; - dim: Color; - italic: Color; - underline: Color; - inverse: Color; - hidden: Color; - strikethrough: Color; - - rainbow: Color; - zebra: Color; - america: Color; - trap: Color; - random: Color; - zalgo: Color; -} - -export function enable(): void; -export function disable(): void; -export function setTheme(theme: any): void; - -export let enabled: boolean; - -export const strip: Color; -export const stripColors: Color; - -export const black: Color; -export const red: Color; -export const green: Color; -export const yellow: Color; -export const blue: Color; -export const magenta: Color; -export const cyan: Color; -export const white: Color; -export const gray: Color; -export const grey: Color; - -export const bgBlack: Color; -export const bgRed: Color; -export const bgGreen: Color; -export const bgYellow: Color; -export const bgBlue: Color; -export const bgMagenta: Color; -export const bgCyan: Color; -export const bgWhite: Color; - -export const reset: Color; -export const bold: Color; -export const dim: Color; -export const italic: Color; -export const underline: Color; -export const inverse: Color; -export const hidden: Color; -export const strikethrough: Color; - -export const rainbow: Color; -export const zebra: Color; -export const america: Color; -export const trap: Color; -export const random: Color; -export const zalgo: Color; - -declare global { - interface String { - strip: string; - stripColors: string; - - black: string; - red: string; - green: string; - yellow: string; - blue: string; - magenta: string; - cyan: string; - white: string; - gray: string; - grey: string; - - bgBlack: string; - bgRed: string; - bgGreen: string; - bgYellow: string; - bgBlue: string; - bgMagenta: string; - bgCyan: string; - bgWhite: string; - - reset: string; - // @ts-ignore - bold: string; - dim: string; - italic: string; - underline: string; - inverse: string; - hidden: string; - strikethrough: string; - - rainbow: string; - zebra: string; - america: string; - trap: string; - random: string; - zalgo: string; - } -} diff --git a/node_modules/@colors/colors/lib/colors.js b/node_modules/@colors/colors/lib/colors.js deleted file mode 100644 index d9fb08762fde5..0000000000000 --- a/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@gmail.com> (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/node_modules/@colors/colors/lib/custom/trap.js b/node_modules/@colors/colors/lib/custom/trap.js deleted file mode 100644 index fbccf88dede0b..0000000000000 --- a/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/node_modules/@colors/colors/lib/custom/zalgo.js b/node_modules/@colors/colors/lib/custom/zalgo.js deleted file mode 100644 index 0ef2b01195635..0000000000000 --- a/node_modules/@colors/colors/lib/custom/zalgo.js +++ /dev/null @@ -1,110 +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/node_modules/@colors/colors/lib/extendStringPrototype.js b/node_modules/@colors/colors/lib/extendStringPrototype.js deleted file mode 100644 index 46fd386a915a6..0000000000000 --- a/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/node_modules/@colors/colors/lib/index.js b/node_modules/@colors/colors/lib/index.js deleted file mode 100644 index 9df5ab7df3077..0000000000000 --- a/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/node_modules/@colors/colors/lib/maps/america.js b/node_modules/@colors/colors/lib/maps/america.js deleted file mode 100644 index dc96903328989..0000000000000 --- a/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/node_modules/@colors/colors/lib/maps/rainbow.js b/node_modules/@colors/colors/lib/maps/rainbow.js deleted file mode 100644 index 2b00ac0ac998e..0000000000000 --- a/node_modules/@colors/colors/lib/maps/rainbow.js +++ /dev/null @@ -1,12 +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/node_modules/@colors/colors/lib/maps/random.js b/node_modules/@colors/colors/lib/maps/random.js deleted file mode 100644 index 3d82a39ec0fab..0000000000000 --- a/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/node_modules/@colors/colors/lib/maps/zebra.js b/node_modules/@colors/colors/lib/maps/zebra.js deleted file mode 100644 index fa73623544a82..0000000000000 --- a/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/node_modules/@colors/colors/lib/styles.js b/node_modules/@colors/colors/lib/styles.js deleted file mode 100644 index 011dafd8c28f7..0000000000000 --- a/node_modules/@colors/colors/lib/styles.js +++ /dev/null @@ -1,95 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/@colors/colors/lib/system/has-flag.js b/node_modules/@colors/colors/lib/system/has-flag.js deleted file mode 100644 index a347dd4d7a697..0000000000000 --- a/node_modules/@colors/colors/lib/system/has-flag.js +++ /dev/null @@ -1,35 +0,0 @@ -/* -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/@colors/colors/lib/system/supports-colors.js b/node_modules/@colors/colors/lib/system/supports-colors.js deleted file mode 100644 index f1f9c8ff3da28..0000000000000 --- a/node_modules/@colors/colors/lib/system/supports-colors.js +++ /dev/null @@ -1,151 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/@colors/colors/package.json b/node_modules/@colors/colors/package.json deleted file mode 100644 index cb87f20953886..0000000000000 --- a/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/node_modules/@colors/colors/safe.d.ts b/node_modules/@colors/colors/safe.d.ts deleted file mode 100644 index 2bafc27984e0e..0000000000000 --- a/node_modules/@colors/colors/safe.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -// Type definitions for Colors.js 1.2 -// Project: https://github.com/Marak/colors.js -// Definitions by: Bart van der Schoor <https://github.com/Bartvds>, Staffan Eketorp <https://github.com/staeke> -// Definitions: https://github.com/Marak/colors.js - -export const enabled: boolean; -export function enable(): void; -export function disable(): void; -export function setTheme(theme: any): void; - -export function strip(str: string): string; -export function stripColors(str: string): string; - -export function black(str: string): string; -export function red(str: string): string; -export function green(str: string): string; -export function yellow(str: string): string; -export function blue(str: string): string; -export function magenta(str: string): string; -export function cyan(str: string): string; -export function white(str: string): string; -export function gray(str: string): string; -export function grey(str: string): string; - -export function bgBlack(str: string): string; -export function bgRed(str: string): string; -export function bgGreen(str: string): string; -export function bgYellow(str: string): string; -export function bgBlue(str: string): string; -export function bgMagenta(str: string): string; -export function bgCyan(str: string): string; -export function bgWhite(str: string): string; - -export function reset(str: string): string; -export function bold(str: string): string; -export function dim(str: string): string; -export function italic(str: string): string; -export function underline(str: string): string; -export function inverse(str: string): string; -export function hidden(str: string): string; -export function strikethrough(str: string): string; - -export function rainbow(str: string): string; -export function zebra(str: string): string; -export function america(str: string): string; -export function trap(str: string): string; -export function random(str: string): string; -export function zalgo(str: string): string; diff --git a/node_modules/@colors/colors/safe.js b/node_modules/@colors/colors/safe.js deleted file mode 100644 index a013d54246485..0000000000000 --- a/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/node_modules/@colors/colors/themes/generic-logging.js b/node_modules/@colors/colors/themes/generic-logging.js deleted file mode 100644 index 63adfe4ac31f9..0000000000000 --- a/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/node_modules/@gar/promisify/LICENSE.md b/node_modules/@gar/promisify/LICENSE.md deleted file mode 100644 index 64f773240bed1..0000000000000 --- a/node_modules/@gar/promisify/LICENSE.md +++ /dev/null @@ -1,10 +0,0 @@ -The MIT License (MIT) - -Copyright © 2020-2022 Michael Garvin - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/node_modules/@gar/promisify/index.js b/node_modules/@gar/promisify/index.js deleted file mode 100644 index d0be95f6fec61..0000000000000 --- a/node_modules/@gar/promisify/index.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict' - -const { promisify } = require('util') - -const handler = { - get: function (target, prop, receiver) { - if (typeof target[prop] !== 'function') { - return target[prop] - } - if (target[prop][promisify.custom]) { - return function () { - return Reflect.get(target, prop, receiver)[promisify.custom].apply(target, arguments) - } - } - return function () { - return new Promise((resolve, reject) => { - Reflect.get(target, prop, receiver).apply(target, [...arguments, function (err, result) { - if (err) { - return reject(err) - } - resolve(result) - }]) - }) - } - } -} - -module.exports = function (thingToPromisify) { - if (typeof thingToPromisify === 'function') { - return promisify(thingToPromisify) - } - if (typeof thingToPromisify === 'object') { - return new Proxy(thingToPromisify, handler) - } - throw new TypeError('Can only promisify functions or objects') -} diff --git a/node_modules/@gar/promisify/package.json b/node_modules/@gar/promisify/package.json deleted file mode 100644 index d0ce69b2f7c0e..0000000000000 --- a/node_modules/@gar/promisify/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@gar/promisify", - "version": "1.1.3", - "description": "Promisify an entire class or object", - "main": "index.js", - "repository": { - "type": "git", - "url": "https://github.com/wraithgar/gar-promisify.git" - }, - "scripts": { - "lint": "standard", - "lint:fix": "standard --fix", - "test": "lab -a @hapi/code -t 100", - "posttest": "npm run lint" - }, - "files": [ - "index.js" - ], - "keywords": [ - "promisify", - "all", - "class", - "object" - ], - "author": "Gar <gar+npm@danger.computer>", - "license": "MIT", - "devDependencies": { - "@hapi/code": "^8.0.1", - "@hapi/lab": "^24.1.0", - "standard": "^16.0.3" - } -} diff --git a/node_modules/@isaacs/balanced-match/LICENSE.md b/node_modules/@isaacs/balanced-match/LICENSE.md new file mode 100644 index 0000000000000..61ece8cc92afb --- /dev/null +++ b/node_modules/@isaacs/balanced-match/LICENSE.md @@ -0,0 +1,23 @@ +(MIT) + +Original code Copyright Julian Gruber <julian@juliangruber.com> + +Port to TypeScript Copyright Isaac Z. Schlueter <i@izs.me> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@isaacs/balanced-match/dist/commonjs/index.js b/node_modules/@isaacs/balanced-match/dist/commonjs/index.js new file mode 100644 index 0000000000000..0c9014bac1531 --- /dev/null +++ b/node_modules/@isaacs/balanced-match/dist/commonjs/index.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.range = exports.balanced = void 0; +const balanced = (a, b, str) => { + const ma = a instanceof RegExp ? maybeMatch(a, str) : a; + const mb = b instanceof RegExp ? maybeMatch(b, str) : b; + const r = ma !== null && mb != null && (0, exports.range)(ma, mb, str); + return (r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + ma.length, r[1]), + post: str.slice(r[1] + mb.length), + }); +}; +exports.balanced = balanced; +const maybeMatch = (reg, str) => { + const m = str.match(reg); + return m ? m[0] : null; +}; +const range = (a, b, str) => { + let begs, beg, left, right = undefined, result; + let ai = str.indexOf(a); + let bi = str.indexOf(b, ai + 1); + let i = ai; + if (ai >= 0 && bi > 0) { + if (a === b) { + return [ai, bi]; + } + begs = []; + left = str.length; + while (i >= 0 && !result) { + if (i === ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } + else if (begs.length === 1) { + const r = begs.pop(); + if (r !== undefined) + result = [r, bi]; + } + else { + beg = begs.pop(); + if (beg !== undefined && beg < left) { + left = beg; + right = bi; + } + bi = str.indexOf(b, i + 1); + } + i = ai < bi && ai >= 0 ? ai : bi; + } + if (begs.length && right !== undefined) { + result = [left, right]; + } + } + return result; +}; +exports.range = range; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@isaacs/balanced-match/dist/commonjs/package.json b/node_modules/@isaacs/balanced-match/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/@isaacs/balanced-match/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/@isaacs/balanced-match/dist/esm/index.js b/node_modules/@isaacs/balanced-match/dist/esm/index.js new file mode 100644 index 0000000000000..fe81200f9d676 --- /dev/null +++ b/node_modules/@isaacs/balanced-match/dist/esm/index.js @@ -0,0 +1,54 @@ +export const balanced = (a, b, str) => { + const ma = a instanceof RegExp ? maybeMatch(a, str) : a; + const mb = b instanceof RegExp ? maybeMatch(b, str) : b; + const r = ma !== null && mb != null && range(ma, mb, str); + return (r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + ma.length, r[1]), + post: str.slice(r[1] + mb.length), + }); +}; +const maybeMatch = (reg, str) => { + const m = str.match(reg); + return m ? m[0] : null; +}; +export const range = (a, b, str) => { + let begs, beg, left, right = undefined, result; + let ai = str.indexOf(a); + let bi = str.indexOf(b, ai + 1); + let i = ai; + if (ai >= 0 && bi > 0) { + if (a === b) { + return [ai, bi]; + } + begs = []; + left = str.length; + while (i >= 0 && !result) { + if (i === ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } + else if (begs.length === 1) { + const r = begs.pop(); + if (r !== undefined) + result = [r, bi]; + } + else { + beg = begs.pop(); + if (beg !== undefined && beg < left) { + left = beg; + right = bi; + } + bi = str.indexOf(b, i + 1); + } + i = ai < bi && ai >= 0 ? ai : bi; + } + if (begs.length && right !== undefined) { + result = [left, right]; + } + } + return result; +}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@isaacs/balanced-match/dist/esm/package.json b/node_modules/@isaacs/balanced-match/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/@isaacs/balanced-match/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/@isaacs/balanced-match/package.json b/node_modules/@isaacs/balanced-match/package.json new file mode 100644 index 0000000000000..49296e6af443c --- /dev/null +++ b/node_modules/@isaacs/balanced-match/package.json @@ -0,0 +1,79 @@ +{ + "name": "@isaacs/balanced-match", + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "version": "4.0.1", + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "git://github.com/isaacs/balanced-match.git" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "type": "module", + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --loglevel warn", + "benchmark": "node benchmark/index.js", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" + }, + "prettier": { + "semi": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "devDependencies": { + "@types/brace-expansion": "^1.1.2", + "@types/node": "^24.0.0", + "mkdirp": "^3.0.1", + "prettier": "^3.3.2", + "tap": "^21.1.0", + "tshy": "^3.0.2", + "typedoc": "^0.28.5" + }, + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "engines": { + "node": "20 || >=22" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" +} diff --git a/node_modules/@isaacs/brace-expansion/LICENSE b/node_modules/@isaacs/brace-expansion/LICENSE new file mode 100644 index 0000000000000..46e7b75c91ced --- /dev/null +++ b/node_modules/@isaacs/brace-expansion/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright Julian Gruber <julian@juliangruber.com> + +TypeScript port Copyright Isaac Z. Schlueter <i@izs.me> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js b/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js new file mode 100644 index 0000000000000..fafdb4b9bf5c4 --- /dev/null +++ b/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js @@ -0,0 +1,199 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EXPANSION_MAX = void 0; +exports.expand = expand; +const balanced_match_1 = require("@isaacs/balanced-match"); +const escSlash = '\0SLASH' + Math.random() + '\0'; +const escOpen = '\0OPEN' + Math.random() + '\0'; +const escClose = '\0CLOSE' + Math.random() + '\0'; +const escComma = '\0COMMA' + Math.random() + '\0'; +const escPeriod = '\0PERIOD' + Math.random() + '\0'; +const escSlashPattern = new RegExp(escSlash, 'g'); +const escOpenPattern = new RegExp(escOpen, 'g'); +const escClosePattern = new RegExp(escClose, 'g'); +const escCommaPattern = new RegExp(escComma, 'g'); +const escPeriodPattern = new RegExp(escPeriod, 'g'); +const slashPattern = /\\\\/g; +const openPattern = /\\{/g; +const closePattern = /\\}/g; +const commaPattern = /\\,/g; +const periodPattern = /\\./g; +exports.EXPANSION_MAX = 100_000; +function numeric(str) { + return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0); +} +function escapeBraces(str) { + return str + .replace(slashPattern, escSlash) + .replace(openPattern, escOpen) + .replace(closePattern, escClose) + .replace(commaPattern, escComma) + .replace(periodPattern, escPeriod); +} +function unescapeBraces(str) { + return str + .replace(escSlashPattern, '\\') + .replace(escOpenPattern, '{') + .replace(escClosePattern, '}') + .replace(escCommaPattern, ',') + .replace(escPeriodPattern, '.'); +} +/** + * Basically just str.split(","), but handling cases + * where we have nested braced sections, which should be + * treated as individual members, like {a,{b,c},d} + */ +function parseCommaParts(str) { + if (!str) { + return ['']; + } + const parts = []; + const m = (0, balanced_match_1.balanced)('{', '}', str); + if (!m) { + return str.split(','); + } + const { pre, body, post } = m; + const p = pre.split(','); + p[p.length - 1] += '{' + body + '}'; + const postParts = parseCommaParts(post); + if (post.length) { + ; + p[p.length - 1] += postParts.shift(); + p.push.apply(p, postParts); + } + parts.push.apply(parts, p); + return parts; +} +function expand(str, options = {}) { + if (!str) { + return []; + } + const { max = exports.EXPANSION_MAX } = options; + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.slice(0, 2) === '{}') { + str = '\\{\\}' + str.slice(2); + } + return expand_(escapeBraces(str), max, true).map(unescapeBraces); +} +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} +function expand_(str, max, isTop) { + /** @type {string[]} */ + const expansions = []; + const m = (0, balanced_match_1.balanced)('{', '}', str); + if (!m) + return [str]; + // no need to expand pre, since it is guaranteed to be free of brace-sets + const pre = m.pre; + const post = m.post.length ? expand_(m.post, max, false) : ['']; + if (/\$$/.test(m.pre)) { + for (let k = 0; k < post.length && k < max; k++) { + const expansion = pre + '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } + } + else { + const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + const isSequence = isNumericSequence || isAlphaSequence; + const isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,(?!,).*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand_(str, max, true); + } + return [str]; + } + let n; + if (isSequence) { + n = m.body.split(/\.\./); + } + else { + n = parseCommaParts(m.body); + if (n.length === 1 && n[0] !== undefined) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand_(n[0], max, false).map(embrace); + //XXX is this necessary? Can't seem to hit it in tests. + /* c8 ignore start */ + if (n.length === 1) { + return post.map(p => m.pre + n[0] + p); + } + /* c8 ignore stop */ + } + } + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + let N; + if (isSequence && n[0] !== undefined && n[1] !== undefined) { + const x = numeric(n[0]); + const y = numeric(n[1]); + const width = Math.max(n[0].length, n[1].length); + let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1; + let test = lte; + const reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + const pad = n.some(isPadded); + N = []; + for (let i = x; test(i, y); i += incr) { + let c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') { + c = ''; + } + } + else { + c = String(i); + if (pad) { + const need = width - c.length; + if (need > 0) { + const z = new Array(need + 1).join('0'); + if (i < 0) { + c = '-' + z + c.slice(1); + } + else { + c = z + c; + } + } + } + } + N.push(c); + } + } + else { + N = []; + for (let j = 0; j < n.length; j++) { + N.push.apply(N, expand_(n[j], max, false)); + } + } + for (let j = 0; j < N.length; j++) { + for (let k = 0; k < post.length && expansions.length < max; k++) { + const expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) { + expansions.push(expansion); + } + } + } + } + return expansions; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@isaacs/brace-expansion/dist/commonjs/package.json b/node_modules/@isaacs/brace-expansion/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/@isaacs/brace-expansion/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/@isaacs/brace-expansion/dist/esm/index.js b/node_modules/@isaacs/brace-expansion/dist/esm/index.js new file mode 100644 index 0000000000000..5c67f519e594a --- /dev/null +++ b/node_modules/@isaacs/brace-expansion/dist/esm/index.js @@ -0,0 +1,195 @@ +import { balanced } from '@isaacs/balanced-match'; +const escSlash = '\0SLASH' + Math.random() + '\0'; +const escOpen = '\0OPEN' + Math.random() + '\0'; +const escClose = '\0CLOSE' + Math.random() + '\0'; +const escComma = '\0COMMA' + Math.random() + '\0'; +const escPeriod = '\0PERIOD' + Math.random() + '\0'; +const escSlashPattern = new RegExp(escSlash, 'g'); +const escOpenPattern = new RegExp(escOpen, 'g'); +const escClosePattern = new RegExp(escClose, 'g'); +const escCommaPattern = new RegExp(escComma, 'g'); +const escPeriodPattern = new RegExp(escPeriod, 'g'); +const slashPattern = /\\\\/g; +const openPattern = /\\{/g; +const closePattern = /\\}/g; +const commaPattern = /\\,/g; +const periodPattern = /\\./g; +export const EXPANSION_MAX = 100_000; +function numeric(str) { + return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0); +} +function escapeBraces(str) { + return str + .replace(slashPattern, escSlash) + .replace(openPattern, escOpen) + .replace(closePattern, escClose) + .replace(commaPattern, escComma) + .replace(periodPattern, escPeriod); +} +function unescapeBraces(str) { + return str + .replace(escSlashPattern, '\\') + .replace(escOpenPattern, '{') + .replace(escClosePattern, '}') + .replace(escCommaPattern, ',') + .replace(escPeriodPattern, '.'); +} +/** + * Basically just str.split(","), but handling cases + * where we have nested braced sections, which should be + * treated as individual members, like {a,{b,c},d} + */ +function parseCommaParts(str) { + if (!str) { + return ['']; + } + const parts = []; + const m = balanced('{', '}', str); + if (!m) { + return str.split(','); + } + const { pre, body, post } = m; + const p = pre.split(','); + p[p.length - 1] += '{' + body + '}'; + const postParts = parseCommaParts(post); + if (post.length) { + ; + p[p.length - 1] += postParts.shift(); + p.push.apply(p, postParts); + } + parts.push.apply(parts, p); + return parts; +} +export function expand(str, options = {}) { + if (!str) { + return []; + } + const { max = EXPANSION_MAX } = options; + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.slice(0, 2) === '{}') { + str = '\\{\\}' + str.slice(2); + } + return expand_(escapeBraces(str), max, true).map(unescapeBraces); +} +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} +function expand_(str, max, isTop) { + /** @type {string[]} */ + const expansions = []; + const m = balanced('{', '}', str); + if (!m) + return [str]; + // no need to expand pre, since it is guaranteed to be free of brace-sets + const pre = m.pre; + const post = m.post.length ? expand_(m.post, max, false) : ['']; + if (/\$$/.test(m.pre)) { + for (let k = 0; k < post.length && k < max; k++) { + const expansion = pre + '{' + m.body + '}' + post[k]; + expansions.push(expansion); + } + } + else { + const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + const isSequence = isNumericSequence || isAlphaSequence; + const isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,(?!,).*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand_(str, max, true); + } + return [str]; + } + let n; + if (isSequence) { + n = m.body.split(/\.\./); + } + else { + n = parseCommaParts(m.body); + if (n.length === 1 && n[0] !== undefined) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand_(n[0], max, false).map(embrace); + //XXX is this necessary? Can't seem to hit it in tests. + /* c8 ignore start */ + if (n.length === 1) { + return post.map(p => m.pre + n[0] + p); + } + /* c8 ignore stop */ + } + } + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + let N; + if (isSequence && n[0] !== undefined && n[1] !== undefined) { + const x = numeric(n[0]); + const y = numeric(n[1]); + const width = Math.max(n[0].length, n[1].length); + let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1; + let test = lte; + const reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + const pad = n.some(isPadded); + N = []; + for (let i = x; test(i, y); i += incr) { + let c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') { + c = ''; + } + } + else { + c = String(i); + if (pad) { + const need = width - c.length; + if (need > 0) { + const z = new Array(need + 1).join('0'); + if (i < 0) { + c = '-' + z + c.slice(1); + } + else { + c = z + c; + } + } + } + } + N.push(c); + } + } + else { + N = []; + for (let j = 0; j < n.length; j++) { + N.push.apply(N, expand_(n[j], max, false)); + } + } + for (let j = 0; j < N.length; j++) { + for (let k = 0; k < post.length && expansions.length < max; k++) { + const expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) { + expansions.push(expansion); + } + } + } + } + return expansions; +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@isaacs/brace-expansion/dist/esm/package.json b/node_modules/@isaacs/brace-expansion/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/@isaacs/brace-expansion/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/@isaacs/brace-expansion/package.json b/node_modules/@isaacs/brace-expansion/package.json new file mode 100644 index 0000000000000..0356a292d6247 --- /dev/null +++ b/node_modules/@isaacs/brace-expansion/package.json @@ -0,0 +1,60 @@ +{ + "name": "@isaacs/brace-expansion", + "description": "Brace expansion as known from sh/bash", + "version": "5.0.1", + "files": [ + "dist" + ], + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "type": "module", + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write .", + "benchmark": "node benchmark/index.js", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" + }, + "devDependencies": { + "@types/brace-expansion": "^1.1.2", + "@types/node": "^24.0.0", + "mkdirp": "^3.0.1", + "prettier": "^3.3.2", + "tap": "^21.5.0", + "tshy": "^3.0.2", + "typedoc": "^0.28.5" + }, + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "license": "MIT", + "engines": { + "node": "20 || >=22" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" +} diff --git a/node_modules/chownr/LICENSE b/node_modules/@isaacs/fs-minipass/LICENSE similarity index 100% rename from node_modules/chownr/LICENSE rename to node_modules/@isaacs/fs-minipass/LICENSE diff --git a/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js b/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js new file mode 100644 index 0000000000000..2b3178c5263b4 --- /dev/null +++ b/node_modules/@isaacs/fs-minipass/dist/commonjs/index.js @@ -0,0 +1,430 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WriteStreamSync = exports.WriteStream = exports.ReadStreamSync = exports.ReadStream = void 0; +const events_1 = __importDefault(require("events")); +const fs_1 = __importDefault(require("fs")); +const minipass_1 = require("minipass"); +const writev = fs_1.default.writev; +const _autoClose = Symbol('_autoClose'); +const _close = Symbol('_close'); +const _ended = Symbol('_ended'); +const _fd = Symbol('_fd'); +const _finished = Symbol('_finished'); +const _flags = Symbol('_flags'); +const _flush = Symbol('_flush'); +const _handleChunk = Symbol('_handleChunk'); +const _makeBuf = Symbol('_makeBuf'); +const _mode = Symbol('_mode'); +const _needDrain = Symbol('_needDrain'); +const _onerror = Symbol('_onerror'); +const _onopen = Symbol('_onopen'); +const _onread = Symbol('_onread'); +const _onwrite = Symbol('_onwrite'); +const _open = Symbol('_open'); +const _path = Symbol('_path'); +const _pos = Symbol('_pos'); +const _queue = Symbol('_queue'); +const _read = Symbol('_read'); +const _readSize = Symbol('_readSize'); +const _reading = Symbol('_reading'); +const _remain = Symbol('_remain'); +const _size = Symbol('_size'); +const _write = Symbol('_write'); +const _writing = Symbol('_writing'); +const _defaultFlag = Symbol('_defaultFlag'); +const _errored = Symbol('_errored'); +class ReadStream extends minipass_1.Minipass { + [_errored] = false; + [_fd]; + [_path]; + [_readSize]; + [_reading] = false; + [_size]; + [_remain]; + [_autoClose]; + constructor(path, opt) { + opt = opt || {}; + super(opt); + this.readable = true; + this.writable = false; + if (typeof path !== 'string') { + throw new TypeError('path must be a string'); + } + this[_errored] = false; + this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined; + this[_path] = path; + this[_readSize] = opt.readSize || 16 * 1024 * 1024; + this[_reading] = false; + this[_size] = typeof opt.size === 'number' ? opt.size : Infinity; + this[_remain] = this[_size]; + this[_autoClose] = + typeof opt.autoClose === 'boolean' ? opt.autoClose : true; + if (typeof this[_fd] === 'number') { + this[_read](); + } + else { + this[_open](); + } + } + get fd() { + return this[_fd]; + } + get path() { + return this[_path]; + } + //@ts-ignore + write() { + throw new TypeError('this is a readable stream'); + } + //@ts-ignore + end() { + throw new TypeError('this is a readable stream'); + } + [_open]() { + fs_1.default.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd)); + } + [_onopen](er, fd) { + if (er) { + this[_onerror](er); + } + else { + this[_fd] = fd; + this.emit('open', fd); + this[_read](); + } + } + [_makeBuf]() { + return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain])); + } + [_read]() { + if (!this[_reading]) { + this[_reading] = true; + const buf = this[_makeBuf](); + /* c8 ignore start */ + if (buf.length === 0) { + return process.nextTick(() => this[_onread](null, 0, buf)); + } + /* c8 ignore stop */ + fs_1.default.read(this[_fd], buf, 0, buf.length, null, (er, br, b) => this[_onread](er, br, b)); + } + } + [_onread](er, br, buf) { + this[_reading] = false; + if (er) { + this[_onerror](er); + } + else if (this[_handleChunk](br, buf)) { + this[_read](); + } + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs_1.default.close(fd, er => er ? this.emit('error', er) : this.emit('close')); + } + } + [_onerror](er) { + this[_reading] = true; + this[_close](); + this.emit('error', er); + } + [_handleChunk](br, buf) { + let ret = false; + // no effect if infinite + this[_remain] -= br; + if (br > 0) { + ret = super.write(br < buf.length ? buf.subarray(0, br) : buf); + } + if (br === 0 || this[_remain] <= 0) { + ret = false; + this[_close](); + super.end(); + } + return ret; + } + emit(ev, ...args) { + switch (ev) { + case 'prefinish': + case 'finish': + return false; + case 'drain': + if (typeof this[_fd] === 'number') { + this[_read](); + } + return false; + case 'error': + if (this[_errored]) { + return false; + } + this[_errored] = true; + return super.emit(ev, ...args); + default: + return super.emit(ev, ...args); + } + } +} +exports.ReadStream = ReadStream; +class ReadStreamSync extends ReadStream { + [_open]() { + let threw = true; + try { + this[_onopen](null, fs_1.default.openSync(this[_path], 'r')); + threw = false; + } + finally { + if (threw) { + this[_close](); + } + } + } + [_read]() { + let threw = true; + try { + if (!this[_reading]) { + this[_reading] = true; + do { + const buf = this[_makeBuf](); + /* c8 ignore start */ + const br = buf.length === 0 + ? 0 + : fs_1.default.readSync(this[_fd], buf, 0, buf.length, null); + /* c8 ignore stop */ + if (!this[_handleChunk](br, buf)) { + break; + } + } while (true); + this[_reading] = false; + } + threw = false; + } + finally { + if (threw) { + this[_close](); + } + } + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs_1.default.closeSync(fd); + this.emit('close'); + } + } +} +exports.ReadStreamSync = ReadStreamSync; +class WriteStream extends events_1.default { + readable = false; + writable = true; + [_errored] = false; + [_writing] = false; + [_ended] = false; + [_queue] = []; + [_needDrain] = false; + [_path]; + [_mode]; + [_autoClose]; + [_fd]; + [_defaultFlag]; + [_flags]; + [_finished] = false; + [_pos]; + constructor(path, opt) { + opt = opt || {}; + super(opt); + this[_path] = path; + this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined; + this[_mode] = opt.mode === undefined ? 0o666 : opt.mode; + this[_pos] = typeof opt.start === 'number' ? opt.start : undefined; + this[_autoClose] = + typeof opt.autoClose === 'boolean' ? opt.autoClose : true; + // truncating makes no sense when writing into the middle + const defaultFlag = this[_pos] !== undefined ? 'r+' : 'w'; + this[_defaultFlag] = opt.flags === undefined; + this[_flags] = opt.flags === undefined ? defaultFlag : opt.flags; + if (this[_fd] === undefined) { + this[_open](); + } + } + emit(ev, ...args) { + if (ev === 'error') { + if (this[_errored]) { + return false; + } + this[_errored] = true; + } + return super.emit(ev, ...args); + } + get fd() { + return this[_fd]; + } + get path() { + return this[_path]; + } + [_onerror](er) { + this[_close](); + this[_writing] = true; + this.emit('error', er); + } + [_open]() { + fs_1.default.open(this[_path], this[_flags], this[_mode], (er, fd) => this[_onopen](er, fd)); + } + [_onopen](er, fd) { + if (this[_defaultFlag] && + this[_flags] === 'r+' && + er && + er.code === 'ENOENT') { + this[_flags] = 'w'; + this[_open](); + } + else if (er) { + this[_onerror](er); + } + else { + this[_fd] = fd; + this.emit('open', fd); + if (!this[_writing]) { + this[_flush](); + } + } + } + end(buf, enc) { + if (buf) { + //@ts-ignore + this.write(buf, enc); + } + this[_ended] = true; + // synthetic after-write logic, where drain/finish live + if (!this[_writing] && + !this[_queue].length && + typeof this[_fd] === 'number') { + this[_onwrite](null, 0); + } + return this; + } + write(buf, enc) { + if (typeof buf === 'string') { + buf = Buffer.from(buf, enc); + } + if (this[_ended]) { + this.emit('error', new Error('write() after end()')); + return false; + } + if (this[_fd] === undefined || this[_writing] || this[_queue].length) { + this[_queue].push(buf); + this[_needDrain] = true; + return false; + } + this[_writing] = true; + this[_write](buf); + return true; + } + [_write](buf) { + fs_1.default.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => this[_onwrite](er, bw)); + } + [_onwrite](er, bw) { + if (er) { + this[_onerror](er); + } + else { + if (this[_pos] !== undefined && typeof bw === 'number') { + this[_pos] += bw; + } + if (this[_queue].length) { + this[_flush](); + } + else { + this[_writing] = false; + if (this[_ended] && !this[_finished]) { + this[_finished] = true; + this[_close](); + this.emit('finish'); + } + else if (this[_needDrain]) { + this[_needDrain] = false; + this.emit('drain'); + } + } + } + } + [_flush]() { + if (this[_queue].length === 0) { + if (this[_ended]) { + this[_onwrite](null, 0); + } + } + else if (this[_queue].length === 1) { + this[_write](this[_queue].pop()); + } + else { + const iovec = this[_queue]; + this[_queue] = []; + writev(this[_fd], iovec, this[_pos], (er, bw) => this[_onwrite](er, bw)); + } + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs_1.default.close(fd, er => er ? this.emit('error', er) : this.emit('close')); + } + } +} +exports.WriteStream = WriteStream; +class WriteStreamSync extends WriteStream { + [_open]() { + let fd; + // only wrap in a try{} block if we know we'll retry, to avoid + // the rethrow obscuring the error's source frame in most cases. + if (this[_defaultFlag] && this[_flags] === 'r+') { + try { + fd = fs_1.default.openSync(this[_path], this[_flags], this[_mode]); + } + catch (er) { + if (er?.code === 'ENOENT') { + this[_flags] = 'w'; + return this[_open](); + } + else { + throw er; + } + } + } + else { + fd = fs_1.default.openSync(this[_path], this[_flags], this[_mode]); + } + this[_onopen](null, fd); + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs_1.default.closeSync(fd); + this.emit('close'); + } + } + [_write](buf) { + // throw the original, but try to close if it fails + let threw = true; + try { + this[_onwrite](null, fs_1.default.writeSync(this[_fd], buf, 0, buf.length, this[_pos])); + threw = false; + } + finally { + if (threw) { + try { + this[_close](); + } + catch { + // ok error + } + } + } + } +} +exports.WriteStreamSync = WriteStreamSync; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@isaacs/fs-minipass/dist/commonjs/package.json b/node_modules/@isaacs/fs-minipass/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/@isaacs/fs-minipass/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/@isaacs/fs-minipass/dist/esm/index.js b/node_modules/@isaacs/fs-minipass/dist/esm/index.js new file mode 100644 index 0000000000000..287a0f614dcc6 --- /dev/null +++ b/node_modules/@isaacs/fs-minipass/dist/esm/index.js @@ -0,0 +1,420 @@ +import EE from 'events'; +import fs from 'fs'; +import { Minipass } from 'minipass'; +const writev = fs.writev; +const _autoClose = Symbol('_autoClose'); +const _close = Symbol('_close'); +const _ended = Symbol('_ended'); +const _fd = Symbol('_fd'); +const _finished = Symbol('_finished'); +const _flags = Symbol('_flags'); +const _flush = Symbol('_flush'); +const _handleChunk = Symbol('_handleChunk'); +const _makeBuf = Symbol('_makeBuf'); +const _mode = Symbol('_mode'); +const _needDrain = Symbol('_needDrain'); +const _onerror = Symbol('_onerror'); +const _onopen = Symbol('_onopen'); +const _onread = Symbol('_onread'); +const _onwrite = Symbol('_onwrite'); +const _open = Symbol('_open'); +const _path = Symbol('_path'); +const _pos = Symbol('_pos'); +const _queue = Symbol('_queue'); +const _read = Symbol('_read'); +const _readSize = Symbol('_readSize'); +const _reading = Symbol('_reading'); +const _remain = Symbol('_remain'); +const _size = Symbol('_size'); +const _write = Symbol('_write'); +const _writing = Symbol('_writing'); +const _defaultFlag = Symbol('_defaultFlag'); +const _errored = Symbol('_errored'); +export class ReadStream extends Minipass { + [_errored] = false; + [_fd]; + [_path]; + [_readSize]; + [_reading] = false; + [_size]; + [_remain]; + [_autoClose]; + constructor(path, opt) { + opt = opt || {}; + super(opt); + this.readable = true; + this.writable = false; + if (typeof path !== 'string') { + throw new TypeError('path must be a string'); + } + this[_errored] = false; + this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined; + this[_path] = path; + this[_readSize] = opt.readSize || 16 * 1024 * 1024; + this[_reading] = false; + this[_size] = typeof opt.size === 'number' ? opt.size : Infinity; + this[_remain] = this[_size]; + this[_autoClose] = + typeof opt.autoClose === 'boolean' ? opt.autoClose : true; + if (typeof this[_fd] === 'number') { + this[_read](); + } + else { + this[_open](); + } + } + get fd() { + return this[_fd]; + } + get path() { + return this[_path]; + } + //@ts-ignore + write() { + throw new TypeError('this is a readable stream'); + } + //@ts-ignore + end() { + throw new TypeError('this is a readable stream'); + } + [_open]() { + fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd)); + } + [_onopen](er, fd) { + if (er) { + this[_onerror](er); + } + else { + this[_fd] = fd; + this.emit('open', fd); + this[_read](); + } + } + [_makeBuf]() { + return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain])); + } + [_read]() { + if (!this[_reading]) { + this[_reading] = true; + const buf = this[_makeBuf](); + /* c8 ignore start */ + if (buf.length === 0) { + return process.nextTick(() => this[_onread](null, 0, buf)); + } + /* c8 ignore stop */ + fs.read(this[_fd], buf, 0, buf.length, null, (er, br, b) => this[_onread](er, br, b)); + } + } + [_onread](er, br, buf) { + this[_reading] = false; + if (er) { + this[_onerror](er); + } + else if (this[_handleChunk](br, buf)) { + this[_read](); + } + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs.close(fd, er => er ? this.emit('error', er) : this.emit('close')); + } + } + [_onerror](er) { + this[_reading] = true; + this[_close](); + this.emit('error', er); + } + [_handleChunk](br, buf) { + let ret = false; + // no effect if infinite + this[_remain] -= br; + if (br > 0) { + ret = super.write(br < buf.length ? buf.subarray(0, br) : buf); + } + if (br === 0 || this[_remain] <= 0) { + ret = false; + this[_close](); + super.end(); + } + return ret; + } + emit(ev, ...args) { + switch (ev) { + case 'prefinish': + case 'finish': + return false; + case 'drain': + if (typeof this[_fd] === 'number') { + this[_read](); + } + return false; + case 'error': + if (this[_errored]) { + return false; + } + this[_errored] = true; + return super.emit(ev, ...args); + default: + return super.emit(ev, ...args); + } + } +} +export class ReadStreamSync extends ReadStream { + [_open]() { + let threw = true; + try { + this[_onopen](null, fs.openSync(this[_path], 'r')); + threw = false; + } + finally { + if (threw) { + this[_close](); + } + } + } + [_read]() { + let threw = true; + try { + if (!this[_reading]) { + this[_reading] = true; + do { + const buf = this[_makeBuf](); + /* c8 ignore start */ + const br = buf.length === 0 + ? 0 + : fs.readSync(this[_fd], buf, 0, buf.length, null); + /* c8 ignore stop */ + if (!this[_handleChunk](br, buf)) { + break; + } + } while (true); + this[_reading] = false; + } + threw = false; + } + finally { + if (threw) { + this[_close](); + } + } + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs.closeSync(fd); + this.emit('close'); + } + } +} +export class WriteStream extends EE { + readable = false; + writable = true; + [_errored] = false; + [_writing] = false; + [_ended] = false; + [_queue] = []; + [_needDrain] = false; + [_path]; + [_mode]; + [_autoClose]; + [_fd]; + [_defaultFlag]; + [_flags]; + [_finished] = false; + [_pos]; + constructor(path, opt) { + opt = opt || {}; + super(opt); + this[_path] = path; + this[_fd] = typeof opt.fd === 'number' ? opt.fd : undefined; + this[_mode] = opt.mode === undefined ? 0o666 : opt.mode; + this[_pos] = typeof opt.start === 'number' ? opt.start : undefined; + this[_autoClose] = + typeof opt.autoClose === 'boolean' ? opt.autoClose : true; + // truncating makes no sense when writing into the middle + const defaultFlag = this[_pos] !== undefined ? 'r+' : 'w'; + this[_defaultFlag] = opt.flags === undefined; + this[_flags] = opt.flags === undefined ? defaultFlag : opt.flags; + if (this[_fd] === undefined) { + this[_open](); + } + } + emit(ev, ...args) { + if (ev === 'error') { + if (this[_errored]) { + return false; + } + this[_errored] = true; + } + return super.emit(ev, ...args); + } + get fd() { + return this[_fd]; + } + get path() { + return this[_path]; + } + [_onerror](er) { + this[_close](); + this[_writing] = true; + this.emit('error', er); + } + [_open]() { + fs.open(this[_path], this[_flags], this[_mode], (er, fd) => this[_onopen](er, fd)); + } + [_onopen](er, fd) { + if (this[_defaultFlag] && + this[_flags] === 'r+' && + er && + er.code === 'ENOENT') { + this[_flags] = 'w'; + this[_open](); + } + else if (er) { + this[_onerror](er); + } + else { + this[_fd] = fd; + this.emit('open', fd); + if (!this[_writing]) { + this[_flush](); + } + } + } + end(buf, enc) { + if (buf) { + //@ts-ignore + this.write(buf, enc); + } + this[_ended] = true; + // synthetic after-write logic, where drain/finish live + if (!this[_writing] && + !this[_queue].length && + typeof this[_fd] === 'number') { + this[_onwrite](null, 0); + } + return this; + } + write(buf, enc) { + if (typeof buf === 'string') { + buf = Buffer.from(buf, enc); + } + if (this[_ended]) { + this.emit('error', new Error('write() after end()')); + return false; + } + if (this[_fd] === undefined || this[_writing] || this[_queue].length) { + this[_queue].push(buf); + this[_needDrain] = true; + return false; + } + this[_writing] = true; + this[_write](buf); + return true; + } + [_write](buf) { + fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => this[_onwrite](er, bw)); + } + [_onwrite](er, bw) { + if (er) { + this[_onerror](er); + } + else { + if (this[_pos] !== undefined && typeof bw === 'number') { + this[_pos] += bw; + } + if (this[_queue].length) { + this[_flush](); + } + else { + this[_writing] = false; + if (this[_ended] && !this[_finished]) { + this[_finished] = true; + this[_close](); + this.emit('finish'); + } + else if (this[_needDrain]) { + this[_needDrain] = false; + this.emit('drain'); + } + } + } + } + [_flush]() { + if (this[_queue].length === 0) { + if (this[_ended]) { + this[_onwrite](null, 0); + } + } + else if (this[_queue].length === 1) { + this[_write](this[_queue].pop()); + } + else { + const iovec = this[_queue]; + this[_queue] = []; + writev(this[_fd], iovec, this[_pos], (er, bw) => this[_onwrite](er, bw)); + } + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs.close(fd, er => er ? this.emit('error', er) : this.emit('close')); + } + } +} +export class WriteStreamSync extends WriteStream { + [_open]() { + let fd; + // only wrap in a try{} block if we know we'll retry, to avoid + // the rethrow obscuring the error's source frame in most cases. + if (this[_defaultFlag] && this[_flags] === 'r+') { + try { + fd = fs.openSync(this[_path], this[_flags], this[_mode]); + } + catch (er) { + if (er?.code === 'ENOENT') { + this[_flags] = 'w'; + return this[_open](); + } + else { + throw er; + } + } + } + else { + fd = fs.openSync(this[_path], this[_flags], this[_mode]); + } + this[_onopen](null, fd); + } + [_close]() { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd]; + this[_fd] = undefined; + fs.closeSync(fd); + this.emit('close'); + } + } + [_write](buf) { + // throw the original, but try to close if it fails + let threw = true; + try { + this[_onwrite](null, fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos])); + threw = false; + } + finally { + if (threw) { + try { + this[_close](); + } + catch { + // ok error + } + } + } + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@isaacs/fs-minipass/dist/esm/package.json b/node_modules/@isaacs/fs-minipass/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/@isaacs/fs-minipass/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/@isaacs/fs-minipass/package.json b/node_modules/@isaacs/fs-minipass/package.json new file mode 100644 index 0000000000000..cc4576c4afe77 --- /dev/null +++ b/node_modules/@isaacs/fs-minipass/package.json @@ -0,0 +1,72 @@ +{ + "name": "@isaacs/fs-minipass", + "version": "4.0.1", + "main": "./dist/commonjs/index.js", + "scripts": { + "prepare": "tshy", + "pretest": "npm run prepare", + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" + }, + "keywords": [], + "author": "Isaac Z. Schlueter", + "license": "ISC", + "repository": { + "type": "git", + "url": "https://github.com/npm/fs-minipass.git" + }, + "description": "fs read and write streams based on minipass", + "dependencies": { + "minipass": "^7.0.4" + }, + "devDependencies": { + "@types/node": "^20.11.30", + "mutate-fs": "^2.1.1", + "prettier": "^3.2.5", + "tap": "^18.7.1", + "tshy": "^1.12.0", + "typedoc": "^0.25.12" + }, + "files": [ + "dist" + ], + "engines": { + "node": ">=18.0.0" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "types": "./dist/commonjs/index.d.ts", + "type": "module", + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + } +} diff --git a/node_modules/@npmcli/agent/lib/agents.js b/node_modules/@npmcli/agent/lib/agents.js new file mode 100644 index 0000000000000..c541b93001517 --- /dev/null +++ b/node_modules/@npmcli/agent/lib/agents.js @@ -0,0 +1,206 @@ +'use strict' + +const net = require('net') +const tls = require('tls') +const { once } = require('events') +const timers = require('timers/promises') +const { normalizeOptions, cacheOptions } = require('./options') +const { getProxy, getProxyAgent, proxyCache } = require('./proxy.js') +const Errors = require('./errors.js') +const { Agent: AgentBase } = require('agent-base') + +module.exports = class Agent extends AgentBase { + #options + #timeouts + #proxy + #noProxy + #ProxyAgent + + constructor (options = {}) { + const { timeouts, proxy, noProxy, ...normalizedOptions } = normalizeOptions(options) + + super(normalizedOptions) + + this.#options = normalizedOptions + this.#timeouts = timeouts + + if (proxy) { + this.#proxy = new URL(proxy) + this.#noProxy = noProxy + this.#ProxyAgent = getProxyAgent(proxy) + } + } + + get proxy () { + return this.#proxy ? { url: this.#proxy } : {} + } + + #getProxy (options) { + if (!this.#proxy) { + return + } + + const proxy = getProxy(`${options.protocol}//${options.host}:${options.port}`, { + proxy: this.#proxy, + noProxy: this.#noProxy, + }) + + if (!proxy) { + return + } + + const cacheKey = cacheOptions({ + ...options, + ...this.#options, + timeouts: this.#timeouts, + proxy, + }) + + if (proxyCache.has(cacheKey)) { + return proxyCache.get(cacheKey) + } + + let ProxyAgent = this.#ProxyAgent + if (Array.isArray(ProxyAgent)) { + ProxyAgent = this.isSecureEndpoint(options) ? ProxyAgent[1] : ProxyAgent[0] + } + + const proxyAgent = new ProxyAgent(proxy, { + ...this.#options, + socketOptions: { family: this.#options.family }, + }) + proxyCache.set(cacheKey, proxyAgent) + + return proxyAgent + } + + // takes an array of promises and races them against the connection timeout + // which will throw the necessary error if it is hit. This will return the + // result of the promise race. + async #timeoutConnection ({ promises, options, timeout }, ac = new AbortController()) { + if (timeout) { + const connectionTimeout = timers.setTimeout(timeout, null, { signal: ac.signal }) + .then(() => { + throw new Errors.ConnectionTimeoutError(`${options.host}:${options.port}`) + }).catch((err) => { + if (err.name === 'AbortError') { + return + } + throw err + }) + promises.push(connectionTimeout) + } + + let result + try { + result = await Promise.race(promises) + ac.abort() + } catch (err) { + ac.abort() + throw err + } + return result + } + + async connect (request, options) { + // if the connection does not have its own lookup function + // set, then use the one from our options + options.lookup ??= this.#options.lookup + + let socket + let timeout = this.#timeouts.connection + const isSecureEndpoint = this.isSecureEndpoint(options) + + const proxy = this.#getProxy(options) + if (proxy) { + // some of the proxies will wait for the socket to fully connect before + // returning so we have to await this while also racing it against the + // connection timeout. + const start = Date.now() + socket = await this.#timeoutConnection({ + options, + timeout, + promises: [proxy.connect(request, options)], + }) + // see how much time proxy.connect took and subtract it from + // the timeout + if (timeout) { + timeout = timeout - (Date.now() - start) + } + } else { + socket = (isSecureEndpoint ? tls : net).connect(options) + } + + socket.setKeepAlive(this.keepAlive, this.keepAliveMsecs) + socket.setNoDelay(this.keepAlive) + + const abortController = new AbortController() + const { signal } = abortController + + const connectPromise = socket[isSecureEndpoint ? 'secureConnecting' : 'connecting'] + ? once(socket, isSecureEndpoint ? 'secureConnect' : 'connect', { signal }) + : Promise.resolve() + + await this.#timeoutConnection({ + options, + timeout, + promises: [ + connectPromise, + once(socket, 'error', { signal }).then((err) => { + throw err[0] + }), + ], + }, abortController) + + if (this.#timeouts.idle) { + socket.setTimeout(this.#timeouts.idle, () => { + socket.destroy(new Errors.IdleTimeoutError(`${options.host}:${options.port}`)) + }) + } + + return socket + } + + addRequest (request, options) { + const proxy = this.#getProxy(options) + // it would be better to call proxy.addRequest here but this causes the + // http-proxy-agent to call its super.addRequest which causes the request + // to be added to the agent twice. since we only support 3 agents + // currently (see the required agents in proxy.js) we have manually + // checked that the only public methods we need to call are called in the + // next block. this could change in the future and presumably we would get + // failing tests until we have properly called the necessary methods on + // each of our proxy agents + if (proxy?.setRequestProps) { + proxy.setRequestProps(request, options) + } + + request.setHeader('connection', this.keepAlive ? 'keep-alive' : 'close') + + if (this.#timeouts.response) { + let responseTimeout + request.once('finish', () => { + setTimeout(() => { + request.destroy(new Errors.ResponseTimeoutError(request, this.#proxy)) + }, this.#timeouts.response) + }) + request.once('response', () => { + clearTimeout(responseTimeout) + }) + } + + if (this.#timeouts.transfer) { + let transferTimeout + request.once('response', (res) => { + setTimeout(() => { + res.destroy(new Errors.TransferTimeoutError(request, this.#proxy)) + }, this.#timeouts.transfer) + res.once('close', () => { + clearTimeout(transferTimeout) + }) + }) + } + + return super.addRequest(request, options) + } +} diff --git a/node_modules/@npmcli/agent/lib/dns.js b/node_modules/@npmcli/agent/lib/dns.js new file mode 100644 index 0000000000000..3c6946c566d73 --- /dev/null +++ b/node_modules/@npmcli/agent/lib/dns.js @@ -0,0 +1,53 @@ +'use strict' + +const { LRUCache } = require('lru-cache') +const dns = require('dns') + +// this is a factory so that each request can have its own opts (i.e. ttl) +// while still sharing the cache across all requests +const cache = new LRUCache({ max: 50 }) + +const getOptions = ({ + family = 0, + hints = dns.ADDRCONFIG, + all = false, + verbatim = undefined, + ttl = 5 * 60 * 1000, + lookup = dns.lookup, +}) => ({ + // hints and lookup are returned since both are top level properties to (net|tls).connect + hints, + lookup: (hostname, ...args) => { + const callback = args.pop() // callback is always last arg + const lookupOptions = args[0] ?? {} + + const options = { + family, + hints, + all, + verbatim, + ...(typeof lookupOptions === 'number' ? { family: lookupOptions } : lookupOptions), + } + + const key = JSON.stringify({ hostname, ...options }) + + if (cache.has(key)) { + const cached = cache.get(key) + return process.nextTick(callback, null, ...cached) + } + + lookup(hostname, options, (err, ...result) => { + if (err) { + return callback(err) + } + + cache.set(key, result, { ttl }) + return callback(null, ...result) + }) + }, +}) + +module.exports = { + cache, + getOptions, +} diff --git a/node_modules/@npmcli/agent/lib/errors.js b/node_modules/@npmcli/agent/lib/errors.js new file mode 100644 index 0000000000000..70475aec8eb35 --- /dev/null +++ b/node_modules/@npmcli/agent/lib/errors.js @@ -0,0 +1,61 @@ +'use strict' + +class InvalidProxyProtocolError extends Error { + constructor (url) { + super(`Invalid protocol \`${url.protocol}\` connecting to proxy \`${url.host}\``) + this.code = 'EINVALIDPROXY' + this.proxy = url + } +} + +class ConnectionTimeoutError extends Error { + constructor (host) { + super(`Timeout connecting to host \`${host}\``) + this.code = 'ECONNECTIONTIMEOUT' + this.host = host + } +} + +class IdleTimeoutError extends Error { + constructor (host) { + super(`Idle timeout reached for host \`${host}\``) + this.code = 'EIDLETIMEOUT' + this.host = host + } +} + +class ResponseTimeoutError extends Error { + constructor (request, proxy) { + let msg = 'Response timeout ' + if (proxy) { + msg += `from proxy \`${proxy.host}\` ` + } + msg += `connecting to host \`${request.host}\`` + super(msg) + this.code = 'ERESPONSETIMEOUT' + this.proxy = proxy + this.request = request + } +} + +class TransferTimeoutError extends Error { + constructor (request, proxy) { + let msg = 'Transfer timeout ' + if (proxy) { + msg += `from proxy \`${proxy.host}\` ` + } + msg += `for \`${request.host}\`` + super(msg) + this.code = 'ETRANSFERTIMEOUT' + this.proxy = proxy + this.request = request + } +} + +module.exports = { + InvalidProxyProtocolError, + ConnectionTimeoutError, + IdleTimeoutError, + ResponseTimeoutError, + TransferTimeoutError, +} diff --git a/node_modules/@npmcli/agent/lib/index.js b/node_modules/@npmcli/agent/lib/index.js new file mode 100644 index 0000000000000..b33d6eaef07a2 --- /dev/null +++ b/node_modules/@npmcli/agent/lib/index.js @@ -0,0 +1,56 @@ +'use strict' + +const { LRUCache } = require('lru-cache') +const { normalizeOptions, cacheOptions } = require('./options') +const { getProxy, proxyCache } = require('./proxy.js') +const dns = require('./dns.js') +const Agent = require('./agents.js') + +const agentCache = new LRUCache({ max: 20 }) + +const getAgent = (url, { agent, proxy, noProxy, ...options } = {}) => { + // false has meaning so this can't be a simple truthiness check + if (agent != null) { + return agent + } + + url = new URL(url) + + const proxyForUrl = getProxy(url, { proxy, noProxy }) + const normalizedOptions = { + ...normalizeOptions(options), + proxy: proxyForUrl, + } + + const cacheKey = cacheOptions({ + ...normalizedOptions, + secureEndpoint: url.protocol === 'https:', + }) + + if (agentCache.has(cacheKey)) { + return agentCache.get(cacheKey) + } + + const newAgent = new Agent(normalizedOptions) + agentCache.set(cacheKey, newAgent) + + return newAgent +} + +module.exports = { + getAgent, + Agent, + // these are exported for backwards compatability + HttpAgent: Agent, + HttpsAgent: Agent, + cache: { + proxy: proxyCache, + agent: agentCache, + dns: dns.cache, + clear: () => { + proxyCache.clear() + agentCache.clear() + dns.cache.clear() + }, + }, +} diff --git a/node_modules/@npmcli/agent/lib/options.js b/node_modules/@npmcli/agent/lib/options.js new file mode 100644 index 0000000000000..0bf53f725f084 --- /dev/null +++ b/node_modules/@npmcli/agent/lib/options.js @@ -0,0 +1,86 @@ +'use strict' + +const dns = require('./dns') + +const normalizeOptions = (opts) => { + const family = parseInt(opts.family ?? '0', 10) + const keepAlive = opts.keepAlive ?? true + + const normalized = { + // nodejs http agent options. these are all the defaults + // but kept here to increase the likelihood of cache hits + // https://nodejs.org/api/http.html#new-agentoptions + keepAliveMsecs: keepAlive ? 1000 : undefined, + maxSockets: opts.maxSockets ?? 15, + maxTotalSockets: Infinity, + maxFreeSockets: keepAlive ? 256 : undefined, + scheduling: 'fifo', + // then spread the rest of the options + ...opts, + // we already set these to their defaults that we want + family, + keepAlive, + // our custom timeout options + timeouts: { + // the standard timeout option is mapped to our idle timeout + // and then deleted below + idle: opts.timeout ?? 0, + connection: 0, + response: 0, + transfer: 0, + ...opts.timeouts, + }, + // get the dns options that go at the top level of socket connection + ...dns.getOptions({ family, ...opts.dns }), + } + + // remove timeout since we already used it to set our own idle timeout + delete normalized.timeout + + return normalized +} + +const createKey = (obj) => { + let key = '' + const sorted = Object.entries(obj).sort((a, b) => a[0] - b[0]) + for (let [k, v] of sorted) { + if (v == null) { + v = 'null' + } else if (v instanceof URL) { + v = v.toString() + } else if (typeof v === 'object') { + v = createKey(v) + } + key += `${k}:${v}:` + } + return key +} + +const cacheOptions = ({ secureEndpoint, ...options }) => createKey({ + secureEndpoint: !!secureEndpoint, + // socket connect options + family: options.family, + hints: options.hints, + localAddress: options.localAddress, + // tls specific connect options + strictSsl: secureEndpoint ? !!options.rejectUnauthorized : false, + ca: secureEndpoint ? options.ca : null, + cert: secureEndpoint ? options.cert : null, + key: secureEndpoint ? options.key : null, + // http agent options + keepAlive: options.keepAlive, + keepAliveMsecs: options.keepAliveMsecs, + maxSockets: options.maxSockets, + maxTotalSockets: options.maxTotalSockets, + maxFreeSockets: options.maxFreeSockets, + scheduling: options.scheduling, + // timeout options + timeouts: options.timeouts, + // proxy + proxy: options.proxy, +}) + +module.exports = { + normalizeOptions, + cacheOptions, +} diff --git a/node_modules/@npmcli/agent/lib/proxy.js b/node_modules/@npmcli/agent/lib/proxy.js new file mode 100644 index 0000000000000..6272e929e57bc --- /dev/null +++ b/node_modules/@npmcli/agent/lib/proxy.js @@ -0,0 +1,88 @@ +'use strict' + +const { HttpProxyAgent } = require('http-proxy-agent') +const { HttpsProxyAgent } = require('https-proxy-agent') +const { SocksProxyAgent } = require('socks-proxy-agent') +const { LRUCache } = require('lru-cache') +const { InvalidProxyProtocolError } = require('./errors.js') + +const PROXY_CACHE = new LRUCache({ max: 20 }) + +const SOCKS_PROTOCOLS = new Set(SocksProxyAgent.protocols) + +const PROXY_ENV_KEYS = new Set(['https_proxy', 'http_proxy', 'proxy', 'no_proxy']) + +const PROXY_ENV = Object.entries(process.env).reduce((acc, [key, value]) => { + key = key.toLowerCase() + if (PROXY_ENV_KEYS.has(key)) { + acc[key] = value + } + return acc +}, {}) + +const getProxyAgent = (url) => { + url = new URL(url) + + const protocol = url.protocol.slice(0, -1) + if (SOCKS_PROTOCOLS.has(protocol)) { + return SocksProxyAgent + } + if (protocol === 'https' || protocol === 'http') { + return [HttpProxyAgent, HttpsProxyAgent] + } + + throw new InvalidProxyProtocolError(url) +} + +const isNoProxy = (url, noProxy) => { + if (typeof noProxy === 'string') { + noProxy = noProxy.split(',').map((p) => p.trim()).filter(Boolean) + } + + if (!noProxy || !noProxy.length) { + return false + } + + const hostSegments = url.hostname.split('.').reverse() + + return noProxy.some((no) => { + const noSegments = no.split('.').filter(Boolean).reverse() + if (!noSegments.length) { + return false + } + + for (let i = 0; i < noSegments.length; i++) { + if (hostSegments[i] !== noSegments[i]) { + return false + } + } + + return true + }) +} + +const getProxy = (url, { proxy, noProxy }) => { + url = new URL(url) + + if (!proxy) { + proxy = url.protocol === 'https:' + ? PROXY_ENV.https_proxy + : PROXY_ENV.https_proxy || PROXY_ENV.http_proxy || PROXY_ENV.proxy + } + + if (!noProxy) { + noProxy = PROXY_ENV.no_proxy + } + + if (!proxy || isNoProxy(url, noProxy)) { + return null + } + + return new URL(proxy) +} + +module.exports = { + getProxyAgent, + getProxy, + proxyCache: PROXY_CACHE, +} diff --git a/node_modules/@npmcli/agent/package.json b/node_modules/@npmcli/agent/package.json new file mode 100644 index 0000000000000..67670a0c1c484 --- /dev/null +++ b/node_modules/@npmcli/agent/package.json @@ -0,0 +1,60 @@ +{ + "name": "@npmcli/agent", + "version": "4.0.0", + "description": "the http/https agent used by the npm cli", + "main": "lib/index.js", + "scripts": { + "gencerts": "bash scripts/create-cert.sh", + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "author": "GitHub Inc.", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/agent/issues" + }, + "homepage": "https://github.com/npm/agent#readme", + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.25.0", + "publish": "true" + }, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "devDependencies": { + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.25.0", + "minipass-fetch": "^4.0.1", + "nock": "^14.0.3", + "socksv5": "^0.0.6", + "tap": "^16.3.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/agent.git" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + } +} diff --git a/node_modules/@npmcli/arborist b/node_modules/@npmcli/arborist deleted file mode 120000 index a2d3e8bbf4641..0000000000000 --- a/node_modules/@npmcli/arborist +++ /dev/null @@ -1 +0,0 @@ -../../workspaces/arborist \ No newline at end of file diff --git a/node_modules/@npmcli/ci-detect/lib/index.js b/node_modules/@npmcli/ci-detect/lib/index.js deleted file mode 100644 index 8be8fe2e6d03b..0000000000000 --- a/node_modules/@npmcli/ci-detect/lib/index.js +++ /dev/null @@ -1,51 +0,0 @@ -module.exports = () => - process.env.GERRIT_PROJECT ? 'gerrit' - : process.env.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI ? 'azure-pipelines' - : process.env.BITRISE_IO ? 'bitrise' - : process.env.BUDDY_WORKSPACE_ID ? 'buddy' - : process.env.BUILDKITE ? 'buildkite' - : process.env.CIRRUS_CI ? 'cirrus' - : process.env.GITLAB_CI ? 'gitlab' - : process.env.APPVEYOR ? 'appveyor' - : process.env.CIRCLECI ? 'circle-ci' - : process.env.SEMAPHORE ? 'semaphore' - : process.env.DRONE ? 'drone' - : process.env.DSARI ? 'dsari' - : process.env.GITHUB_ACTION ? 'github-actions' - : process.env.TDDIUM ? 'tddium' - : process.env.SCREWDRIVER ? 'screwdriver' - : process.env.STRIDER ? 'strider' - : process.env.TASKCLUSTER_ROOT_URL ? 'taskcluster' - : process.env.JENKINS_URL ? 'jenkins' - : process.env['bamboo.buildKey'] ? 'bamboo' - : process.env.GO_PIPELINE_NAME ? 'gocd' - : process.env.HUDSON_URL ? 'hudson' - : process.env.WERCKER ? 'wercker' - : process.env.NETLIFY ? 'netlify' - : process.env.NOW_GITHUB_DEPLOYMENT ? 'now-github' - : process.env.GITLAB_DEPLOYMENT ? 'now-gitlab' - : process.env.BITBUCKET_DEPLOYMENT ? 'now-bitbucket' - : process.env.BITBUCKET_BUILD_NUMBER ? 'bitbucket-pipelines' - : process.env.NOW_BUILDER ? 'now' - : process.env.VERCEL_GITHUB_DEPLOYMENT ? 'vercel-github' - : process.env.VERCEL_GITLAB_DEPLOYMENT ? 'vercel-gitlab' - : process.env.VERCEL_BITBUCKET_DEPLOYMENT ? 'vercel-bitbucket' - : process.env.VERCEL_URL ? 'vercel' - : process.env.MAGNUM ? 'magnum' - : process.env.NEVERCODE ? 'nevercode' - : process.env.RENDER ? 'render' - : process.env.SAIL_CI ? 'sail' - : process.env.SHIPPABLE ? 'shippable' - : process.env.TEAMCITY_VERSION ? 'teamcity' - // codeship and a few others - : process.env.CI_NAME ? process.env.CI_NAME - // heroku doesn't set envs other than node in a heroku-specific location - : /\/\.heroku\/node\/bin\/node$/.test(process.env.NODE || '') ? 'heroku' - // test travis after the others, since several CI systems mimic it - : process.env.TRAVIS ? 'travis-ci' - // aws CodeBuild/CodePipeline - : process.env.CODEBUILD_SRC_DIR ? 'aws-codebuild' - : process.env.CI === 'true' || process.env.CI === '1' ? 'custom' - // Google Cloud Build - it sets almost nothing - : process.env.BUILDER_OUTPUT ? 'builder' - : false diff --git a/node_modules/@npmcli/ci-detect/package.json b/node_modules/@npmcli/ci-detect/package.json deleted file mode 100644 index c1cf9dc889371..0000000000000 --- a/node_modules/@npmcli/ci-detect/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@npmcli/ci-detect", - "version": "2.0.0", - "description": "Detect what kind of CI environment the program is in", - "author": "GitHub Inc.", - "license": "ISC", - "main": "./lib", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint '**/*.js'", - "postlint": "npm-template-check", - "template-copy": "npm-template-copy --force", - "lintfix": "npm run lint -- --fix", - "snap": "tap", - "posttest": "npm run lint" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "@npmcli/template-oss": "^2.7.1", - "tap": "^15.1.6" - }, - "files": [ - "bin", - "lib" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/npm/ci-detect.git" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - }, - "templateOSS": { - "version": "2.7.1" - } -} diff --git a/node_modules/@npmcli/config/LICENSE b/node_modules/@npmcli/config/LICENSE deleted file mode 100644 index 19cec97b18468..0000000000000 --- a/node_modules/@npmcli/config/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) npm, Inc. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@npmcli/config/lib/env-replace.js b/node_modules/@npmcli/config/lib/env-replace.js deleted file mode 100644 index c851f6e4d1501..0000000000000 --- a/node_modules/@npmcli/config/lib/env-replace.js +++ /dev/null @@ -1,14 +0,0 @@ -// replace any ${ENV} values with the appropriate environ. - -const envExpr = /(?<!\\)(\\*)\$\{([^${}]+)\}/g - -module.exports = (f, env) => f.replace(envExpr, (orig, esc, name) => { - const val = env[name] !== undefined ? env[name] : `$\{${name}}` - - // consume the escape chars that are relevant. - if (esc.length % 2) { - return orig.slice((esc.length + 1) / 2) - } - - return (esc.slice(esc.length / 2)) + val -}) diff --git a/node_modules/@npmcli/config/lib/index.js b/node_modules/@npmcli/config/lib/index.js deleted file mode 100644 index 8c2b181ca9c61..0000000000000 --- a/node_modules/@npmcli/config/lib/index.js +++ /dev/null @@ -1,909 +0,0 @@ -// TODO: set the scope config from package.json or explicit cli config -const walkUp = require('walk-up-path') -const ini = require('ini') -const nopt = require('nopt') -const mkdirp = require('mkdirp-infer-owner') -const mapWorkspaces = require('@npmcli/map-workspaces') -const rpj = require('read-package-json-fast') -const log = require('proc-log') - -/* istanbul ignore next */ -const myUid = process.getuid && process.getuid() -/* istanbul ignore next */ -const myGid = process.getgid && process.getgid() - -const { resolve, dirname, join } = require('path') -const { homedir } = require('os') -const { promisify } = require('util') -const fs = require('fs') -const readFile = promisify(fs.readFile) -const writeFile = promisify(fs.writeFile) -const chmod = promisify(fs.chmod) -const chown = promisify(fs.chown) -const unlink = promisify(fs.unlink) -const stat = promisify(fs.stat) - -const hasOwnProperty = (obj, key) => - Object.prototype.hasOwnProperty.call(obj, key) - -// define a custom getter, but turn into a normal prop -// if we set it. otherwise it can't be set on child objects -const settableGetter = (obj, key, get) => { - Object.defineProperty(obj, key, { - get, - set (value) { - Object.defineProperty(obj, key, { - value, - configurable: true, - writable: true, - enumerable: true, - }) - }, - configurable: true, - enumerable: true, - }) -} - -const typeDefs = require('./type-defs.js') -const nerfDart = require('./nerf-dart.js') -const envReplace = require('./env-replace.js') -const parseField = require('./parse-field.js') -const typeDescription = require('./type-description.js') -const setEnvs = require('./set-envs.js') - -// types that can be saved back to -const confFileTypes = new Set([ - 'global', - 'user', - 'project', -]) - -const confTypes = new Set([ - 'default', - 'builtin', - ...confFileTypes, - 'env', - 'cli', -]) - -const _loaded = Symbol('loaded') -const _get = Symbol('get') -const _find = Symbol('find') -const _loadObject = Symbol('loadObject') -const _loadFile = Symbol('loadFile') -const _checkDeprecated = Symbol('checkDeprecated') -const _flatten = Symbol('flatten') -const _flatOptions = Symbol('flatOptions') - -class Config { - static get typeDefs () { - return typeDefs - } - - constructor ({ - definitions, - shorthands, - flatten, - npmPath, - - // options just to override in tests, mostly - env = process.env, - argv = process.argv, - platform = process.platform, - execPath = process.execPath, - cwd = process.cwd(), - }) { - // turn the definitions into nopt's weirdo syntax - this.definitions = definitions - const types = {} - const defaults = {} - this.deprecated = {} - for (const [key, def] of Object.entries(definitions)) { - defaults[key] = def.default - types[key] = def.type - if (def.deprecated) { - this.deprecated[key] = def.deprecated.trim().replace(/\n +/, '\n') - } - } - - // populated the first time we flatten the object - this[_flatOptions] = null - this[_flatten] = flatten - this.types = types - this.shorthands = shorthands - this.defaults = defaults - - this.npmPath = npmPath - this.argv = argv - this.env = env - this.execPath = execPath - this.platform = platform - this.cwd = cwd - - // set when we load configs - this.globalPrefix = null - this.localPrefix = null - - // defaults to env.HOME, but will always be *something* - this.home = null - - // set up the prototype chain of config objects - const wheres = [...confTypes] - this.data = new Map() - let parent = null - for (const where of wheres) { - this.data.set(where, parent = new ConfigData(parent)) - } - - this.data.set = () => { - throw new Error('cannot change internal config data structure') - } - this.data.delete = () => { - throw new Error('cannot change internal config data structure') - } - - this.sources = new Map([]) - - this.list = [] - for (const { data } of this.data.values()) { - this.list.unshift(data) - } - Object.freeze(this.list) - - this[_loaded] = false - } - - get loaded () { - return this[_loaded] - } - - get prefix () { - return this[_get]('global') ? this.globalPrefix : this.localPrefix - } - - // return the location where key is found. - find (key) { - if (!this.loaded) { - throw new Error('call config.load() before reading values') - } - return this[_find](key) - } - - [_find] (key) { - // have to look in reverse order - const entries = [...this.data.entries()] - for (let i = entries.length - 1; i > -1; i--) { - const [where, { data }] = entries[i] - if (hasOwnProperty(data, key)) { - return where - } - } - return null - } - - get (key, where) { - if (!this.loaded) { - throw new Error('call config.load() before reading values') - } - return this[_get](key, where) - } - - // we need to get values sometimes, so use this internal one to do so - // while in the process of loading. - [_get] (key, where = null) { - if (where !== null && !confTypes.has(where)) { - throw new Error('invalid config location param: ' + where) - } - const { data } = this.data.get(where || 'cli') - return where === null || hasOwnProperty(data, key) ? data[key] : undefined - } - - set (key, val, where = 'cli') { - if (!this.loaded) { - throw new Error('call config.load() before setting values') - } - if (!confTypes.has(where)) { - throw new Error('invalid config location param: ' + where) - } - this[_checkDeprecated](key) - const { data } = this.data.get(where) - data[key] = val - - // this is now dirty, the next call to this.valid will have to check it - this.data.get(where)[_valid] = null - - // the flat options are invalidated, regenerate next time they're needed - this[_flatOptions] = null - } - - get flat () { - if (this[_flatOptions]) { - return this[_flatOptions] - } - - // create the object for flat options passed to deps - process.emit('time', 'config:load:flatten') - this[_flatOptions] = {} - // walk from least priority to highest - for (const { data } of this.data.values()) { - this[_flatten](data, this[_flatOptions]) - } - process.emit('timeEnd', 'config:load:flatten') - - return this[_flatOptions] - } - - delete (key, where = 'cli') { - if (!this.loaded) { - throw new Error('call config.load() before deleting values') - } - if (!confTypes.has(where)) { - throw new Error('invalid config location param: ' + where) - } - delete this.data.get(where).data[key] - } - - async load () { - if (this.loaded) { - 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') - - // warn if anything is not valid - process.emit('time', 'config:load:validate') - this.validate() - process.emit('timeEnd', 'config:load:validate') - - // set this before calling setEnvs, so that we don't have to share - // symbols, as that module also does a bunch of get operations - this[_loaded] = true - - process.emit('time', 'config:load:credentials') - const reg = this.get('registry') - const creds = this.getCredentialsByURI(reg) - // ignore this error because a failed set will strip out anything that - // might be a security hazard, which was the intention. - try { - this.setCredentialsByURI(reg, creds) - } catch (_) {} - process.emit('timeEnd', 'config:load:credentials') - - // 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 () { - this.loadGlobalPrefix() - this.loadHome() - - this[_loadObject]({ - ...this.defaults, - prefix: this.globalPrefix, - }, 'default', 'default values') - - const { data } = this.data.get('default') - - // the metrics-registry defaults to the current resolved value of - // the registry, unless overridden somewhere else. - settableGetter(data, 'metrics-registry', () => this[_get]('registry')) - - // if the prefix is set on cli, env, or userconfig, then we need to - // default the globalconfig file to that location, instead of the default - // global prefix. It's weird that `npm get globalconfig --prefix=/foo` - // returns `/foo/etc/npmrc`, but better to not change it at this point. - settableGetter(data, 'globalconfig', () => - resolve(this[_get]('prefix'), 'etc/npmrc')) - } - - loadHome () { - if (this.env.HOME) { - return this.home = this.env.HOME - } - this.home = homedir() - } - - loadGlobalPrefix () { - if (this.globalPrefix) { - throw new Error('cannot load default global prefix more than once') - } - - if (this.env.PREFIX) { - this.globalPrefix = this.env.PREFIX - } else if (this.platform === 'win32') { - // c:\node\node.exe --> prefix=c:\node\ - this.globalPrefix = dirname(this.execPath) - } else { - // /usr/local/bin/node --> prefix=/usr/local - this.globalPrefix = dirname(dirname(this.execPath)) - - // destdir only is respected on Unix - if (this.env.DESTDIR) { - this.globalPrefix = join(this.env.DESTDIR, this.globalPrefix) - } - } - } - - loadEnv () { - const conf = Object.create(null) - for (const [envKey, envVal] of Object.entries(this.env)) { - if (!/^npm_config_/i.test(envKey) || envVal === '') { - continue - } - const key = envKey.slice('npm_config_'.length) - .replace(/(?!^)_/g, '-') // don't replace _ at the start of the key - .toLowerCase() - conf[key] = envVal - } - this[_loadObject](conf, 'env', 'environment') - } - - loadCLI () { - nopt.invalidHandler = (k, val, type) => - this.invalidHandler(k, val, type, 'command line options', 'cli') - const conf = nopt(this.types, this.shorthands, this.argv) - nopt.invalidHandler = null - this.parsedArgv = conf.argv - delete conf.argv - this[_loadObject](conf, 'cli', 'command line options') - } - - get valid () { - for (const [where, { valid }] of this.data.entries()) { - if (valid === false || valid === null && !this.validate(where)) { - return false - } - } - return true - } - - validate (where) { - if (!where) { - let valid = true - for (const [entryWhere] of this.data.entries()) { - // no need to validate our defaults, we know they're fine - // cli was already validated when parsed the first time - if (entryWhere === 'default' || entryWhere === 'builtin' || entryWhere === 'cli') { - continue - } - const ret = this.validate(entryWhere) - valid = valid && ret - } - return valid - } else { - const obj = this.data.get(where) - obj[_valid] = true - - nopt.invalidHandler = (k, val, type) => - this.invalidHandler(k, val, type, obj.source, where) - - nopt.clean(obj.data, this.types, this.typeDefs) - - nopt.invalidHandler = null - return obj[_valid] - } - } - - // Returns true if the value is coming directly from the source defined - // in default definitions, if the current value for the key config is - // coming from any other different source, returns false - isDefault (key) { - const [defaultType, ...types] = [...confTypes] - const defaultData = this.data.get(defaultType).data - - return hasOwnProperty(defaultData, key) - && types.every(type => { - const typeData = this.data.get(type).data - return !hasOwnProperty(typeData, key) - }) - } - - invalidHandler (k, val, type, source, where) { - log.warn( - 'invalid config', - k + '=' + JSON.stringify(val), - `set in ${source}` - ) - this.data.get(where)[_valid] = false - - if (Array.isArray(type)) { - if (type.includes(typeDefs.url.type)) { - type = typeDefs.url.type - } else { - /* istanbul ignore if - no actual configs matching this, but - * path types SHOULD be handled this way, like URLs, for the - * same reason */ - if (type.includes(typeDefs.path.type)) { - type = typeDefs.path.type - } - } - } - - const typeDesc = typeDescription(type) - const oneOrMore = typeDesc.indexOf(Array) !== -1 - const mustBe = typeDesc - .filter(m => m !== undefined && m !== Array) - const oneOf = mustBe.length === 1 && oneOrMore ? ' one or more' - : mustBe.length > 1 && oneOrMore ? ' one or more of:' - : mustBe.length > 1 ? ' one of:' - : '' - const msg = 'Must be' + oneOf - const desc = mustBe.length === 1 ? mustBe[0] - : mustBe.filter(m => m !== Array) - .map(n => typeof n === 'string' ? n : JSON.stringify(n)) - .join(', ') - log.warn('invalid config', msg, desc) - } - - [_loadObject] (obj, where, source, er = null) { - const conf = this.data.get(where) - if (conf.source) { - const m = `double-loading "${where}" configs from ${source}, ` + - `previously loaded from ${conf.source}` - throw new Error(m) - } - - if (this.sources.has(source)) { - const m = `double-loading config "${source}" as "${where}", ` + - `previously loaded as "${this.sources.get(source)}"` - throw new Error(m) - } - - conf.source = source - this.sources.set(source, where) - if (er) { - conf.loadError = er - if (er.code !== 'ENOENT') { - log.verbose('config', `error loading ${where} config`, er) - } - } else { - conf.raw = obj - for (const [key, value] of Object.entries(obj)) { - const k = envReplace(key, this.env) - const v = this.parseField(value, k) - if (where !== 'default') { - this[_checkDeprecated](k, where, obj, [key, value]) - } - conf.data[k] = v - } - } - } - - [_checkDeprecated] (key, where, obj, kv) { - // XXX(npm9+) make this throw an error - if (this.deprecated[key]) { - log.warn('config', key, this.deprecated[key]) - } - } - - // Parse a field, coercing it to the best type available. - parseField (f, key, listElement = false) { - return parseField(f, key, this, listElement) - } - - async [_loadFile] (file, type) { - process.emit('time', 'config:load:file:' + file) - // only catch the error from readFile, not from the loadObject call - await readFile(file, 'utf8').then( - data => this[_loadObject](ini.parse(data), type, file), - er => this[_loadObject](null, type, file, er) - ) - process.emit('timeEnd', 'config:load:file:' + file) - } - - loadBuiltinConfig () { - return this[_loadFile](resolve(this.npmPath, 'npmrc'), 'builtin') - } - - async loadProjectConfig () { - // the localPrefix can be set by the CLI config, but otherwise is - // found by walking up the folder tree. either way, we load it before - // we return to make sure localPrefix is set - await this.loadLocalPrefix() - - if (this[_get]('global') === true || this[_get]('location') === 'global') { - this.data.get('project').source = '(global mode enabled, ignored)' - this.sources.set(this.data.get('project').source, 'project') - return - } - - const projectFile = resolve(this.localPrefix, '.npmrc') - // if we're in the ~ directory, and there happens to be a node_modules - // folder (which is not TOO uncommon, it turns out), then we can end - // up loading the "project" config where the "userconfig" will be, - // which causes some calamaties. So, we only load project config if - // it doesn't match what the userconfig will be. - if (projectFile !== this[_get]('userconfig')) { - return this[_loadFile](projectFile, 'project') - } else { - this.data.get('project').source = '(same as "user" config, ignored)' - this.sources.set(this.data.get('project').source, 'project') - } - } - - async loadLocalPrefix () { - const cliPrefix = this[_get]('prefix', 'cli') - if (cliPrefix) { - this.localPrefix = cliPrefix - return - } - - const cliWorkspaces = this[_get]('workspaces', 'cli') - const isGlobal = this[_get]('global') || this[_get]('location') === 'global' - - for (const p of walkUp(this.cwd)) { - const hasNodeModules = await stat(resolve(p, 'node_modules')) - .then((st) => st.isDirectory()) - .catch(() => false) - - const hasPackageJson = await stat(resolve(p, 'package.json')) - .then((st) => st.isFile()) - .catch(() => false) - - if (!this.localPrefix && (hasNodeModules || hasPackageJson)) { - this.localPrefix = p - - // if workspaces are disabled, or we're in global mode, return now - if (cliWorkspaces === false || isGlobal) { - return - } - - // otherwise, continue the loop - continue - } - - if (this.localPrefix && hasPackageJson) { - // if we already set localPrefix but this dir has a package.json - // then we need to see if `p` is a workspace root by reading its package.json - // however, if reading it fails then we should just move on - const pkg = await rpj(resolve(p, 'package.json')).catch(() => false) - if (!pkg) { - continue - } - - const workspaces = await mapWorkspaces({ cwd: p, pkg }) - for (const w of workspaces.values()) { - if (w === this.localPrefix) { - // see if there's a .npmrc file in the workspace, if so log a warning - const hasNpmrc = await stat(resolve(this.localPrefix, '.npmrc')) - .then((st) => st.isFile()) - .catch(() => false) - - if (hasNpmrc) { - log.warn(`ignoring workspace config at ${this.localPrefix}/.npmrc`) - } - - // set the workspace in the default layer, which allows it to be overridden easily - const { data } = this.data.get('default') - data.workspace = [this.localPrefix] - this.localPrefix = p - log.info(`found workspace root at ${this.localPrefix}`) - // we found a root, so we return now - return - } - } - } - } - - if (!this.localPrefix) { - this.localPrefix = this.cwd - } - } - - loadUserConfig () { - return this[_loadFile](this[_get]('userconfig'), 'user') - } - - loadGlobalConfig () { - return this[_loadFile](this[_get]('globalconfig'), 'global') - } - - async save (where) { - if (!this.loaded) { - throw new Error('call config.load() before saving') - } - if (!confFileTypes.has(where)) { - throw new Error('invalid config location param: ' + where) - } - const conf = this.data.get(where) - conf[_raw] = { ...conf.data } - conf[_loadError] = null - - // upgrade auth configs to more secure variants before saving - if (where === 'user') { - const reg = this.get('registry') - const creds = this.getCredentialsByURI(reg) - // we ignore this error because the failed set already removed - // anything that might be a security hazard, and it won't be - // saved back to the .npmrc file, so we're good. - try { - this.setCredentialsByURI(reg, creds) - } catch (_) {} - } - - const iniData = ini.stringify(conf.data).trim() + '\n' - if (!iniData.trim()) { - // ignore the unlink error (eg, if file doesn't exist) - await unlink(conf.source).catch(er => {}) - return - } - const dir = dirname(conf.source) - await mkdirp(dir) - await writeFile(conf.source, iniData, 'utf8') - // don't leave a root-owned config file lying around - /* istanbul ignore if - this is best-effort and a pita to test */ - if (myUid === 0) { - const st = await stat(dir).catch(() => null) - if (st && (st.uid !== myUid || st.gid !== myGid)) { - await chown(conf.source, st.uid, st.gid).catch(() => {}) - } - } - const mode = where === 'user' ? 0o600 : 0o666 - await chmod(conf.source, mode) - } - - clearCredentialsByURI (uri) { - const nerfed = nerfDart(uri) - const def = nerfDart(this.get('registry')) - if (def === nerfed) { - // do not delete email, that shouldn't be nerfed any more. - // just delete the nerfed copy, if one exists. - this.delete(`-authtoken`, 'user') - this.delete(`_authToken`, 'user') - this.delete(`_authtoken`, 'user') - this.delete(`_auth`, 'user') - this.delete(`_password`, 'user') - this.delete(`username`, 'user') - } - this.delete(`${nerfed}:-authtoken`, 'user') - this.delete(`${nerfed}:_authtoken`, 'user') - this.delete(`${nerfed}:_authToken`, 'user') - this.delete(`${nerfed}:_auth`, 'user') - this.delete(`${nerfed}:_password`, 'user') - this.delete(`${nerfed}:username`, 'user') - this.delete(`${nerfed}:email`, 'user') - this.delete(`${nerfed}:certfile`, 'user') - this.delete(`${nerfed}:keyfile`, 'user') - } - - setCredentialsByURI (uri, { token, username, password, email, certfile, keyfile }) { - const nerfed = nerfDart(uri) - const def = nerfDart(this.get('registry')) - - if (def === nerfed) { - // remove old style auth info not limited to a single registry - this.delete('_password', 'user') - this.delete('username', 'user') - this.delete('_auth', 'user') - this.delete('_authtoken', 'user') - this.delete('-authtoken', 'user') - this.delete('_authToken', 'user') - } - - // email used to be nerfed always. if we're using the default - // registry, de-nerf it. - if (nerfed === def) { - email = email || - this.get('email', 'user') || - this.get(`${nerfed}:email`, 'user') - if (email) { - this.set('email', 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. - this.delete(`${nerfed}:always-auth`, 'user') - - this.delete(`${nerfed}:-authtoken`, 'user') - this.delete(`${nerfed}:_authtoken`, 'user') - this.delete(`${nerfed}:email`, 'user') - if (certfile && keyfile) { - this.set(`${nerfed}:certfile`, certfile, 'user') - this.set(`${nerfed}:keyfile`, keyfile, 'user') - // cert/key may be used in conjunction with other credentials, thus no `else` - } - if (token) { - this.set(`${nerfed}:_authToken`, token, 'user') - this.delete(`${nerfed}:_password`, 'user') - this.delete(`${nerfed}:username`, 'user') - } else if (username || password) { - if (!username) { - throw new Error('must include username') - } - if (!password) { - throw new Error('must include password') - } - this.delete(`${nerfed}:_authToken`, 'user') - this.set(`${nerfed}:username`, username, 'user') - // note: not encrypted, no idea why we bothered to do this, but oh well - // protects against shoulder-hacks if password is memorable, I guess? - const encoded = Buffer.from(password, 'utf8').toString('base64') - this.set(`${nerfed}:_password`, encoded, 'user') - } else if (!certfile || !keyfile) { - throw new Error('No credentials to set.') - } - } - - // this has to be a bit more complicated to support legacy data of all forms - getCredentialsByURI (uri) { - const nerfed = nerfDart(uri) - const creds = {} - - const email = this.get(`${nerfed}:email`) || this.get('email') - if (email) { - creds.email = email - } - - const certfileReg = this.get(`${nerfed}:certfile`) - const keyfileReg = this.get(`${nerfed}:keyfile`) - if (certfileReg && keyfileReg) { - creds.certfile = certfileReg - creds.keyfile = keyfileReg - // cert/key may be used in conjunction with other credentials, thus no `return` - } - - const tokenReg = this.get(`${nerfed}:_authToken`) || - this.get(`${nerfed}:_authtoken`) || - this.get(`${nerfed}:-authtoken`) || - nerfed === nerfDart(this.get('registry')) && this.get('_authToken') - - if (tokenReg) { - creds.token = tokenReg - return creds - } - - const userReg = this.get(`${nerfed}:username`) - const passReg = this.get(`${nerfed}:_password`) - if (userReg && passReg) { - creds.username = userReg - creds.password = Buffer.from(passReg, 'base64').toString('utf8') - const auth = `${creds.username}:${creds.password}` - creds.auth = Buffer.from(auth, 'utf8').toString('base64') - return creds - } - - const authReg = this.get(`${nerfed}:_auth`) - if (authReg) { - const authDecode = Buffer.from(authReg, 'base64').toString('utf8') - const authSplit = authDecode.split(':') - creds.username = authSplit.shift() - creds.password = authSplit.join(':') - creds.auth = authReg - return creds - } - - // at this point, we can only use the values if the URI is the - // default registry. - const defaultNerf = nerfDart(this.get('registry')) - if (nerfed !== defaultNerf) { - return creds - } - - const userDef = this.get('username') - const passDef = this.get('_password') - if (userDef && passDef) { - creds.username = userDef - creds.password = Buffer.from(passDef, 'base64').toString('utf8') - const auth = `${creds.username}:${creds.password}` - creds.auth = Buffer.from(auth, 'utf8').toString('base64') - return creds - } - - // Handle the old-style _auth=<base64> style for the default - // registry, if set. - const auth = this.get('_auth') - if (!auth) { - return creds - } - - const authDecode = Buffer.from(auth, 'base64').toString('utf8') - const authSplit = authDecode.split(':') - creds.username = authSplit.shift() - creds.password = authSplit.join(':') - creds.auth = auth - return creds - } - - // set up the environment object we have with npm_config_* environs - // for all configs that are different from their default values, and - // set EDITOR and HOME. - setEnvs () { - setEnvs(this) - } -} - -const _data = Symbol('data') -const _raw = Symbol('raw') -const _loadError = Symbol('loadError') -const _source = Symbol('source') -const _valid = Symbol('valid') -class ConfigData { - constructor (parent) { - this[_data] = Object.create(parent && parent.data) - this[_source] = null - this[_loadError] = null - this[_raw] = null - this[_valid] = true - } - - get data () { - return this[_data] - } - - get valid () { - return this[_valid] - } - - set source (s) { - if (this[_source]) { - throw new Error('cannot set ConfigData source more than once') - } - this[_source] = s - } - - get source () { - return this[_source] - } - - set loadError (e) { - if (this[_loadError] || this[_raw]) { - throw new Error('cannot set ConfigData loadError after load') - } - this[_loadError] = e - } - - get loadError () { - return this[_loadError] - } - - set raw (r) { - if (this[_raw] || this[_loadError]) { - throw new Error('cannot set ConfigData raw after load') - } - this[_raw] = r - } - - get raw () { - return this[_raw] - } -} - -module.exports = Config diff --git a/node_modules/@npmcli/config/lib/nerf-dart.js b/node_modules/@npmcli/config/lib/nerf-dart.js deleted file mode 100644 index d6ae4aa2aa7e2..0000000000000 --- a/node_modules/@npmcli/config/lib/nerf-dart.js +++ /dev/null @@ -1,18 +0,0 @@ -const { URL } = require('url') - -/** - * Maps a URL to an identifier. - * - * Name courtesy schiffertronix media LLC, a New Jersey corporation - * - * @param {String} uri The URL to be nerfed. - * - * @returns {String} A nerfed URL. - */ -module.exports = (url) => { - const parsed = new URL(url) - const from = `${parsed.protocol}//${parsed.host}${parsed.pathname}` - const rel = new URL('.', from) - const res = `//${rel.host}${rel.pathname}` - return res -} diff --git a/node_modules/@npmcli/config/lib/parse-field.js b/node_modules/@npmcli/config/lib/parse-field.js deleted file mode 100644 index 0c905bf23cb10..0000000000000 --- a/node_modules/@npmcli/config/lib/parse-field.js +++ /dev/null @@ -1,81 +0,0 @@ -// Parse a field, coercing it to the best type available. -const typeDefs = require('./type-defs.js') -const envReplace = require('./env-replace.js') -const { resolve } = require('path') - -const { parse: umaskParse } = require('./umask.js') - -const parseField = (f, key, opts, listElement = false) => { - if (typeof f !== 'string' && !Array.isArray(f)) { - return f - } - - const { platform, types, home, env } = opts - - // type can be array or a single thing. coerce to array. - const typeList = new Set([].concat(types[key])) - const isPath = typeList.has(typeDefs.path.type) - const isBool = typeList.has(typeDefs.Boolean.type) - const isString = isPath || typeList.has(typeDefs.String.type) - const isUmask = typeList.has(typeDefs.Umask.type) - const isNumber = typeList.has(typeDefs.Number.type) - const isList = !listElement && typeList.has(Array) - - if (Array.isArray(f)) { - return !isList ? f : f.map(field => parseField(field, key, opts, true)) - } - - // now we know it's a string - f = f.trim() - - // list types get put in the environment separated by double-\n - // usually a single \n would suffice, but ca/cert configs can contain - // line breaks and multiple entries. - if (isList) { - return parseField(f.split('\n\n'), key, opts) - } - - // --foo is like --foo=true for boolean types - if (isBool && !isString && f === '') { - return true - } - - // string types can be the string 'true', 'false', etc. - // otherwise, parse these values out - if (!isString && !isPath && !isNumber) { - switch (f) { - case 'true': return true - case 'false': return false - case 'null': return null - case 'undefined': return undefined - } - } - - f = envReplace(f, env) - - if (isPath) { - const homePattern = platform === 'win32' ? /^~(\/|\\)/ : /^~\// - if (homePattern.test(f) && home) { - f = resolve(home, f.slice(2)) - } else { - f = resolve(f) - } - } - - if (isUmask) { - try { - return umaskParse(f) - } catch (er) { - // let it warn later when we validate - return f - } - } - - if (isNumber && !isNaN(f)) { - f = +f - } - - return f -} - -module.exports = parseField diff --git a/node_modules/@npmcli/config/lib/set-envs.js b/node_modules/@npmcli/config/lib/set-envs.js deleted file mode 100644 index 0f5781aaf3395..0000000000000 --- a/node_modules/@npmcli/config/lib/set-envs.js +++ /dev/null @@ -1,111 +0,0 @@ -// Set environment variables for any non-default configs, -// so that they're already there when we run lifecycle scripts. -// -// See https://github.com/npm/rfcs/pull/90 - -// Return the env key if this is a thing that belongs in the env. -// Ie, if the key isn't a @scope, //nerf.dart, or _private, -// and the value is a string or array. Otherwise return false. -const envKey = (key, val) => { - return !/^[/@_]/.test(key) && - (typeof envVal(val) === 'string') && - `npm_config_${key.replace(/-/g, '_').toLowerCase()}` -} - -const envVal = val => Array.isArray(val) ? val.map(v => envVal(v)).join('\n\n') - : val === null || val === undefined || val === false ? '' - : typeof val === 'object' ? null - : String(val) - -const sameConfigValue = (def, val) => - !Array.isArray(val) || !Array.isArray(def) ? def === val - : sameArrayValue(def, val) - -const sameArrayValue = (def, val) => { - if (def.length !== val.length) { - return false - } - - for (let i = 0; i < def.length; i++) { - /* istanbul ignore next - there are no array configs where the default - * is not an empty array, so this loop is a no-op, but it's the correct - * thing to do if we ever DO add a config like that. */ - if (def[i] !== val[i]) { - return false - } - } - return true -} - -const setEnv = (env, rawKey, rawVal) => { - const val = envVal(rawVal) - const key = envKey(rawKey, val) - if (key && val !== null) { - env[key] = val - } -} - -const setEnvs = (config) => { - // This ensures that all npm config values that are not the defaults are - // shared appropriately with child processes, without false positives. - const { - env, - defaults, - definitions, - list: [cliConf, envConf], - } = config - - env.INIT_CWD = process.cwd() - - // if the key is deprecated, skip it always. - // if the key is the default value, - // if the environ is NOT the default value, - // set the environ - // else skip it, it's fine - // if the key is NOT the default value, - // if the env is setting it, then leave it (already set) - // otherwise, set the env - const cliSet = new Set(Object.keys(cliConf)) - const envSet = new Set(Object.keys(envConf)) - for (const key in cliConf) { - const { deprecated, envExport = true } = definitions[key] || {} - if (deprecated || envExport === false) { - continue - } - - if (sameConfigValue(defaults[key], cliConf[key])) { - // config is the default, if the env thought different, then we - // have to set it BACK to the default in the environment. - if (!sameConfigValue(envConf[key], cliConf[key])) { - setEnv(env, key, cliConf[key]) - } - } else { - // config is not the default. if the env wasn't the one to set - // it that way, then we have to put it in the env - if (!(envSet.has(key) && !cliSet.has(key))) { - setEnv(env, key, cliConf[key]) - } - } - } - - // also set some other common nice envs that we want to rely on - env.HOME = config.home - env.npm_config_global_prefix = config.globalPrefix - env.npm_config_local_prefix = config.localPrefix - if (cliConf.editor) { - env.EDITOR = cliConf.editor - } - - // note: this doesn't afect the *current* node process, of course, since - // it's already started, but it does affect the options passed to scripts. - if (cliConf['node-options']) { - env.NODE_OPTIONS = cliConf['node-options'] - } - - if (require.main && require.main.filename) { - env.npm_execpath = require.main.filename - } - env.NODE = env.npm_node_execpath = config.execPath -} - -module.exports = setEnvs diff --git a/node_modules/@npmcli/config/lib/type-defs.js b/node_modules/@npmcli/config/lib/type-defs.js deleted file mode 100644 index 20a827c3d164e..0000000000000 --- a/node_modules/@npmcli/config/lib/type-defs.js +++ /dev/null @@ -1,59 +0,0 @@ -const nopt = require('nopt') - -const { Umask, validate: validateUmask } = require('./umask.js') - -const semver = require('semver') -const validateSemver = (data, k, val) => { - const valid = semver.valid(val) - if (!valid) { - return false - } - data[k] = valid -} - -const noptValidatePath = nopt.typeDefs.path.validate -const validatePath = (data, k, val) => { - if (typeof val !== 'string') { - return false - } - return noptValidatePath(data, k, val) -} - -// add descriptions so we can validate more usefully -module.exports = { - ...nopt.typeDefs, - semver: { - type: semver, - validate: validateSemver, - description: 'full valid SemVer string', - }, - Umask: { - type: Umask, - validate: validateUmask, - description: 'octal number in range 0o000..0o777 (0..511)', - }, - url: { - ...nopt.typeDefs.url, - description: 'full url with "http://"', - }, - path: { - ...nopt.typeDefs.path, - validate: validatePath, - description: 'valid filesystem path', - }, - Number: { - ...nopt.typeDefs.Number, - description: 'numeric value', - }, - Boolean: { - ...nopt.typeDefs.Boolean, - description: 'boolean value (true or false)', - }, - Date: { - ...nopt.typeDefs.Date, - description: 'valid Date string', - }, -} - -// TODO: make nopt less of a global beast so this kludge isn't necessary -nopt.typeDefs = module.exports diff --git a/node_modules/@npmcli/config/lib/umask.js b/node_modules/@npmcli/config/lib/umask.js deleted file mode 100644 index 195fad2386702..0000000000000 --- a/node_modules/@npmcli/config/lib/umask.js +++ /dev/null @@ -1,31 +0,0 @@ -class Umask {} -const parse = val => { - if (typeof val === 'string') { - if (/^0o?[0-7]+$/.test(val)) { - return parseInt(val.replace(/^0o?/, ''), 8) - } else if (/^[1-9][0-9]*$/.test(val)) { - return parseInt(val, 10) - } else { - throw new Error(`invalid umask value: ${val}`) - } - } - if (typeof val !== 'number') { - throw new Error(`invalid umask value: ${val}`) - } - val = Math.floor(val) - if (val < 0 || val > 511) { - throw new Error(`invalid umask value: ${val}`) - } - return val -} - -const validate = (data, k, val) => { - try { - data[k] = parse(val) - return true - } catch (er) { - return false - } -} - -module.exports = { Umask, parse, validate } diff --git a/node_modules/@npmcli/config/package.json b/node_modules/@npmcli/config/package.json deleted file mode 100644 index 2f561c12233dc..0000000000000 --- a/node_modules/@npmcli/config/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@npmcli/config", - "version": "4.2.0", - "files": [ - "bin/", - "lib/" - ], - "main": "lib/index.js", - "description": "Configuration management for the npm cli", - "repository": { - "type": "git", - "url": "https://github.com/npm/config.git" - }, - "author": "GitHub Inc.", - "license": "ISC", - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", - "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" - }, - "tap": { - "check-coverage": true, - "coverage-map": "map.js" - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "tap": "^16.0.1" - }, - "dependencies": { - "@npmcli/map-workspaces": "^2.0.2", - "ini": "^3.0.0", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^5.0.0", - "proc-log": "^2.0.0", - "read-package-json-fast": "^2.0.3", - "semver": "^7.3.5", - "walk-up-path": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" - } -} diff --git a/node_modules/@npmcli/disparity-colors/LICENSE b/node_modules/@npmcli/disparity-colors/LICENSE deleted file mode 100644 index dedcd7d2f9dae..0000000000000 --- a/node_modules/@npmcli/disparity-colors/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) npm Inc. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@npmcli/disparity-colors/lib/index.js b/node_modules/@npmcli/disparity-colors/lib/index.js deleted file mode 100644 index 3d2aa56be9253..0000000000000 --- a/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/node_modules/@npmcli/disparity-colors/package.json b/node_modules/@npmcli/disparity-colors/package.json deleted file mode 100644 index 2b45920a7e783..0000000000000 --- a/node_modules/@npmcli/disparity-colors/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "@npmcli/disparity-colors", - "version": "2.0.0", - "main": "lib/index.js", - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.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", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "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": "3.2.2" - } -} diff --git a/node_modules/@npmcli/fs/lib/common/owner-sync.js b/node_modules/@npmcli/fs/lib/common/owner-sync.js deleted file mode 100644 index 8fa18d5121eff..0000000000000 --- a/node_modules/@npmcli/fs/lib/common/owner-sync.js +++ /dev/null @@ -1,92 +0,0 @@ -const { dirname, resolve } = require('path') -const url = require('url') - -const fs = require('../fs.js') - -// given a path, find the owner of the nearest parent -const find = (path) => { - // if we have no getuid, permissions are irrelevant on this platform - if (!process.getuid) { - return {} - } - - // fs methods accept URL objects with a scheme of file: so we need to unwrap - // those into an actual path string before we can resolve it - const resolved = path != null && path.href && path.origin - ? resolve(url.fileURLToPath(path)) - : resolve(path) - - let stat - - try { - stat = fs.lstatSync(resolved) - } finally { - // if we got a stat, return its contents - if (stat) { - return { uid: stat.uid, gid: stat.gid } - } - - // try the parent directory - if (resolved !== dirname(resolved)) { - return find(dirname(resolved)) - } - - // no more parents, never got a stat, just return an empty object - return {} - } -} - -// given a path, uid, and gid update the ownership of the path if necessary -const update = (path, uid, gid) => { - // nothing to update, just exit - if (uid === undefined && gid === undefined) { - return - } - - try { - // see if the permissions are already the same, if they are we don't - // need to do anything, so return early - const stat = fs.statSync(path) - if (uid === stat.uid && gid === stat.gid) { - return - } - } catch (err) {} - - try { - fs.chownSync(path, uid, gid) - } catch (err) {} -} - -// accepts a `path` and the `owner` property of an options object and normalizes -// it into an object with numerical `uid` and `gid` -const validate = (path, input) => { - let uid - let gid - - if (typeof input === 'string' || typeof input === 'number') { - uid = input - gid = input - } else if (input && typeof input === 'object') { - uid = input.uid - gid = input.gid - } - - if (uid === 'inherit' || gid === 'inherit') { - const owner = find(path) - if (uid === 'inherit') { - uid = owner.uid - } - - if (gid === 'inherit') { - gid = owner.gid - } - } - - return { uid, gid } -} - -module.exports = { - find, - update, - validate, -} diff --git a/node_modules/@npmcli/fs/lib/common/owner.js b/node_modules/@npmcli/fs/lib/common/owner.js deleted file mode 100644 index 3fe167cfc30aa..0000000000000 --- a/node_modules/@npmcli/fs/lib/common/owner.js +++ /dev/null @@ -1,92 +0,0 @@ -const { dirname, resolve } = require('path') -const url = require('url') - -const fs = require('../fs.js') - -// given a path, find the owner of the nearest parent -const find = async (path) => { - // if we have no getuid, permissions are irrelevant on this platform - if (!process.getuid) { - return {} - } - - // fs methods accept URL objects with a scheme of file: so we need to unwrap - // those into an actual path string before we can resolve it - const resolved = path != null && path.href && path.origin - ? resolve(url.fileURLToPath(path)) - : resolve(path) - - let stat - - try { - stat = await fs.lstat(resolved) - } finally { - // if we got a stat, return its contents - if (stat) { - return { uid: stat.uid, gid: stat.gid } - } - - // try the parent directory - if (resolved !== dirname(resolved)) { - return find(dirname(resolved)) - } - - // no more parents, never got a stat, just return an empty object - return {} - } -} - -// given a path, uid, and gid update the ownership of the path if necessary -const update = async (path, uid, gid) => { - // nothing to update, just exit - if (uid === undefined && gid === undefined) { - return - } - - try { - // see if the permissions are already the same, if they are we don't - // need to do anything, so return early - const stat = await fs.stat(path) - if (uid === stat.uid && gid === stat.gid) { - return - } - } catch (err) {} - - try { - await fs.chown(path, uid, gid) - } catch (err) {} -} - -// accepts a `path` and the `owner` property of an options object and normalizes -// it into an object with numerical `uid` and `gid` -const validate = async (path, input) => { - let uid - let gid - - if (typeof input === 'string' || typeof input === 'number') { - uid = input - gid = input - } else if (input && typeof input === 'object') { - uid = input.uid - gid = input.gid - } - - if (uid === 'inherit' || gid === 'inherit') { - const owner = await find(path) - if (uid === 'inherit') { - uid = owner.uid - } - - if (gid === 'inherit') { - gid = owner.gid - } - } - - return { uid, gid } -} - -module.exports = { - find, - update, - validate, -} diff --git a/node_modules/@npmcli/fs/lib/copy-file.js b/node_modules/@npmcli/fs/lib/copy-file.js deleted file mode 100644 index 8888266d627f0..0000000000000 --- a/node_modules/@npmcli/fs/lib/copy-file.js +++ /dev/null @@ -1,16 +0,0 @@ -const fs = require('./fs.js') -const getOptions = require('./common/get-options.js') -const withOwner = require('./with-owner.js') - -const copyFile = async (src, dest, opts) => { - const options = getOptions(opts, { - copy: ['mode'], - wrap: 'mode', - }) - - // the node core method as of 16.5.0 does not support the mode being in an - // object, so we have to pass the mode value directly - return withOwner(dest, () => fs.copyFile(src, dest, options.mode), opts) -} - -module.exports = copyFile diff --git a/node_modules/@npmcli/fs/lib/errors.js b/node_modules/@npmcli/fs/lib/cp/errors.js similarity index 100% rename from node_modules/@npmcli/fs/lib/errors.js rename to node_modules/@npmcli/fs/lib/cp/errors.js diff --git a/node_modules/@npmcli/fs/lib/cp/index.js b/node_modules/@npmcli/fs/lib/cp/index.js index 5da4739bdd528..972ce7aa12abe 100644 --- a/node_modules/@npmcli/fs/lib/cp/index.js +++ b/node_modules/@npmcli/fs/lib/cp/index.js @@ -1,4 +1,4 @@ -const fs = require('../fs.js') +const fs = require('fs/promises') const getOptions = require('../common/get-options.js') const node = require('../common/node.js') const polyfill = require('./polyfill.js') diff --git a/node_modules/@npmcli/fs/lib/cp/polyfill.js b/node_modules/@npmcli/fs/lib/cp/polyfill.js index f83ccbf57ecc9..80eb10de97191 100644 --- a/node_modules/@npmcli/fs/lib/cp/polyfill.js +++ b/node_modules/@npmcli/fs/lib/cp/polyfill.js @@ -23,7 +23,7 @@ const { ERR_FS_CP_UNKNOWN, ERR_FS_EISDIR, ERR_INVALID_ARG_TYPE, -} = require('../errors.js') +} = require('./errors.js') const { constants: { errno: { @@ -45,7 +45,7 @@ const { symlink, unlink, utimes, -} = require('../fs.js') +} = require('fs/promises') const { dirname, isAbsolute, diff --git a/node_modules/@npmcli/fs/lib/fs.js b/node_modules/@npmcli/fs/lib/fs.js deleted file mode 100644 index 457da10eed03e..0000000000000 --- a/node_modules/@npmcli/fs/lib/fs.js +++ /dev/null @@ -1,14 +0,0 @@ -const fs = require('fs') -const promisify = require('@gar/promisify') - -const isLower = (s) => s === s.toLowerCase() && s !== s.toUpperCase() - -const fsSync = Object.fromEntries(Object.entries(fs).filter(([k, v]) => - typeof v === 'function' && (k.endsWith('Sync') || !isLower(k[0])) -)) - -// this module returns the core fs async fns wrapped in a proxy that promisifies -// method calls within the getter. we keep it in a separate module so that the -// overridden methods have a consistent way to get to promisified fs methods -// without creating a circular dependency. the ctors and sync methods are kept untouched -module.exports = { ...promisify(fs), ...fsSync } diff --git a/node_modules/@npmcli/fs/lib/index.js b/node_modules/@npmcli/fs/lib/index.js index 3a98648eca9a1..81c746304cc42 100644 --- a/node_modules/@npmcli/fs/lib/index.js +++ b/node_modules/@npmcli/fs/lib/index.js @@ -1,12 +1,13 @@ +'use strict' + +const cp = require('./cp/index.js') +const withTempDir = require('./with-temp-dir.js') +const readdirScoped = require('./readdir-scoped.js') +const moveFile = require('./move-file.js') + module.exports = { - ...require('./fs.js'), - copyFile: require('./copy-file.js'), - cp: require('./cp/index.js'), - mkdir: require('./mkdir.js'), - mkdtemp: require('./mkdtemp.js'), - rm: require('./rm/index.js'), - withTempDir: require('./with-temp-dir.js'), - withOwner: require('./with-owner.js'), - withOwnerSync: require('./with-owner-sync.js'), - writeFile: require('./write-file.js'), + cp, + withTempDir, + readdirScoped, + moveFile, } diff --git a/node_modules/@npmcli/fs/lib/mkdir.js b/node_modules/@npmcli/fs/lib/mkdir.js deleted file mode 100644 index 098d8d0a09ae3..0000000000000 --- a/node_modules/@npmcli/fs/lib/mkdir.js +++ /dev/null @@ -1,19 +0,0 @@ -const fs = require('./fs.js') -const getOptions = require('./common/get-options.js') -const withOwner = require('./with-owner.js') - -// extends mkdir with the ability to specify an owner of the new dir -const mkdir = async (path, opts) => { - const options = getOptions(opts, { - copy: ['mode', 'recursive'], - wrap: 'mode', - }) - - return withOwner( - path, - () => fs.mkdir(path, options), - opts - ) -} - -module.exports = mkdir diff --git a/node_modules/@npmcli/fs/lib/mkdtemp.js b/node_modules/@npmcli/fs/lib/mkdtemp.js deleted file mode 100644 index 60b12a788de90..0000000000000 --- a/node_modules/@npmcli/fs/lib/mkdtemp.js +++ /dev/null @@ -1,23 +0,0 @@ -const { dirname, sep } = require('path') - -const fs = require('./fs.js') -const getOptions = require('./common/get-options.js') -const withOwner = require('./with-owner.js') - -const mkdtemp = async (prefix, opts) => { - const options = getOptions(opts, { - copy: ['encoding'], - wrap: 'encoding', - }) - - // mkdtemp relies on the trailing path separator to indicate if it should - // create a directory inside of the prefix. if that's the case then the root - // we infer ownership from is the prefix itself, otherwise it's the dirname - // /tmp -> /tmpABCDEF, infers from / - // /tmp/ -> /tmp/ABCDEF, infers from /tmp - const root = prefix.endsWith(sep) ? prefix : dirname(prefix) - - return withOwner(root, () => fs.mkdtemp(prefix, options), opts) -} - -module.exports = mkdtemp diff --git a/node_modules/@npmcli/fs/lib/move-file.js b/node_modules/@npmcli/fs/lib/move-file.js new file mode 100644 index 0000000000000..d56e06d384659 --- /dev/null +++ b/node_modules/@npmcli/fs/lib/move-file.js @@ -0,0 +1,78 @@ +const { dirname, join, resolve, relative, isAbsolute } = require('path') +const fs = require('fs/promises') + +const pathExists = async path => { + try { + await fs.access(path) + return true + } catch (er) { + return er.code !== 'ENOENT' + } +} + +const moveFile = async (source, destination, options = {}, root = true, symlinks = []) => { + if (!source || !destination) { + throw new TypeError('`source` and `destination` file required') + } + + options = { + overwrite: true, + ...options, + } + + if (!options.overwrite && await pathExists(destination)) { + throw new Error(`The destination file exists: ${destination}`) + } + + await fs.mkdir(dirname(destination), { recursive: true }) + + try { + await fs.rename(source, destination) + } catch (error) { + if (error.code === 'EXDEV' || error.code === 'EPERM') { + const sourceStat = await fs.lstat(source) + if (sourceStat.isDirectory()) { + const files = await fs.readdir(source) + await Promise.all(files.map((file) => + moveFile(join(source, file), join(destination, file), options, false, symlinks) + )) + } else if (sourceStat.isSymbolicLink()) { + symlinks.push({ source, destination }) + } else { + await fs.copyFile(source, destination) + } + } else { + throw error + } + } + + if (root) { + await Promise.all(symlinks.map(async ({ source: symSource, destination: symDestination }) => { + let target = await fs.readlink(symSource) + // junction symlinks in windows will be absolute paths, so we need to + // make sure they point to the symlink destination + if (isAbsolute(target)) { + target = resolve(symDestination, relative(symSource, target)) + } + // try to determine what the actual file is so we can create the correct + // type of symlink in windows + let targetStat = 'file' + try { + targetStat = await fs.stat(resolve(dirname(symSource), target)) + if (targetStat.isDirectory()) { + targetStat = 'junction' + } + } catch { + // targetStat remains 'file' + } + await fs.symlink( + target, + symDestination, + targetStat + ) + })) + await fs.rm(source, { recursive: true, force: true }) + } +} + +module.exports = moveFile diff --git a/node_modules/@npmcli/fs/lib/readdir-scoped.js b/node_modules/@npmcli/fs/lib/readdir-scoped.js new file mode 100644 index 0000000000000..cd601dfbe7486 --- /dev/null +++ b/node_modules/@npmcli/fs/lib/readdir-scoped.js @@ -0,0 +1,20 @@ +const { readdir } = require('fs/promises') +const { join } = require('path') + +const readdirScoped = async (dir) => { + const results = [] + + for (const item of await readdir(dir)) { + if (item.startsWith('@')) { + for (const scopedItem of await readdir(join(dir, item))) { + results.push(join(item, scopedItem)) + } + } else { + results.push(item) + } + } + + return results +} + +module.exports = readdirScoped diff --git a/node_modules/@npmcli/fs/lib/rm/index.js b/node_modules/@npmcli/fs/lib/rm/index.js deleted file mode 100644 index cb81fbdf8cc47..0000000000000 --- a/node_modules/@npmcli/fs/lib/rm/index.js +++ /dev/null @@ -1,22 +0,0 @@ -const fs = require('../fs.js') -const getOptions = require('../common/get-options.js') -const node = require('../common/node.js') -const polyfill = require('./polyfill.js') - -// node 14.14.0 added fs.rm, which allows both the force and recursive options -const useNative = node.satisfies('>=14.14.0') - -const rm = async (path, opts) => { - const options = getOptions(opts, { - copy: ['retryDelay', 'maxRetries', 'recursive', 'force'], - }) - - // the polyfill is tested separately from this module, no need to hack - // process.version to try to trigger it just for coverage - // istanbul ignore next - return useNative - ? fs.rm(path, options) - : polyfill(path, options) -} - -module.exports = rm diff --git a/node_modules/@npmcli/fs/lib/rm/polyfill.js b/node_modules/@npmcli/fs/lib/rm/polyfill.js deleted file mode 100644 index a25c17483b001..0000000000000 --- a/node_modules/@npmcli/fs/lib/rm/polyfill.js +++ /dev/null @@ -1,239 +0,0 @@ -// this file is a modified version of the code in node core >=14.14.0 -// which is, in turn, a modified version of the rimraf module on npm -// node core changes: -// - Use of the assert module has been replaced with core's error system. -// - All code related to the glob dependency has been removed. -// - Bring your own custom fs module is not currently supported. -// - Some basic code cleanup. -// changes here: -// - remove all callback related code -// - drop sync support -// - change assertions back to non-internal methods (see options.js) -// - throws ENOTDIR when rmdir gets an ENOENT for a path that exists in Windows -const errnos = require('os').constants.errno -const { join } = require('path') -const fs = require('../fs.js') - -// error codes that mean we need to remove contents -const notEmptyCodes = new Set([ - 'ENOTEMPTY', - 'EEXIST', - 'EPERM', -]) - -// error codes we can retry later -const retryCodes = new Set([ - 'EBUSY', - 'EMFILE', - 'ENFILE', - 'ENOTEMPTY', - 'EPERM', -]) - -const isWindows = process.platform === 'win32' - -const defaultOptions = { - retryDelay: 100, - maxRetries: 0, - recursive: false, - force: false, -} - -// this is drastically simplified, but should be roughly equivalent to what -// node core throws -class ERR_FS_EISDIR extends Error { - constructor (path) { - super() - this.info = { - code: 'EISDIR', - message: 'is a directory', - path, - syscall: 'rm', - errno: errnos.EISDIR, - } - this.name = 'SystemError' - this.code = 'ERR_FS_EISDIR' - this.errno = errnos.EISDIR - this.syscall = 'rm' - this.path = path - this.message = `Path is a directory: ${this.syscall} returned ` + - `${this.info.code} (is a directory) ${path}` - } - - toString () { - return `${this.name} [${this.code}]: ${this.message}` - } -} - -class ENOTDIR extends Error { - constructor (path) { - super() - this.name = 'Error' - this.code = 'ENOTDIR' - this.errno = errnos.ENOTDIR - this.syscall = 'rmdir' - this.path = path - this.message = `not a directory, ${this.syscall} '${this.path}'` - } - - toString () { - return `${this.name}: ${this.code}: ${this.message}` - } -} - -// force is passed separately here because we respect it for the first entry -// into rimraf only, any further calls that are spawned as a result (i.e. to -// delete content within the target) will ignore ENOENT errors -const rimraf = async (path, options, isTop = false) => { - const force = isTop ? options.force : true - const stat = await fs.lstat(path) - .catch((err) => { - // we only ignore ENOENT if we're forcing this call - if (err.code === 'ENOENT' && force) { - return - } - - if (isWindows && err.code === 'EPERM') { - return fixEPERM(path, options, err, isTop) - } - - throw err - }) - - // no stat object here means either lstat threw an ENOENT, or lstat threw - // an EPERM and the fixPERM function took care of things. either way, we're - // already done, so return early - if (!stat) { - return - } - - if (stat.isDirectory()) { - return rmdir(path, options, null, isTop) - } - - return fs.unlink(path) - .catch((err) => { - if (err.code === 'ENOENT' && force) { - return - } - - if (err.code === 'EISDIR') { - return rmdir(path, options, err, isTop) - } - - if (err.code === 'EPERM') { - // in windows, we handle this through fixEPERM which will also try to - // delete things again. everywhere else since deleting the target as a - // file didn't work we go ahead and try to delete it as a directory - return isWindows - ? fixEPERM(path, options, err, isTop) - : rmdir(path, options, err, isTop) - } - - throw err - }) -} - -const fixEPERM = async (path, options, originalErr, isTop) => { - const force = isTop ? options.force : true - const targetMissing = await fs.chmod(path, 0o666) - .catch((err) => { - if (err.code === 'ENOENT' && force) { - return true - } - - throw originalErr - }) - - // got an ENOENT above, return now. no file = no problem - if (targetMissing) { - return - } - - // this function does its own lstat rather than calling rimraf again to avoid - // infinite recursion for a repeating EPERM - const stat = await fs.lstat(path) - .catch((err) => { - if (err.code === 'ENOENT' && force) { - return - } - - throw originalErr - }) - - if (!stat) { - return - } - - if (stat.isDirectory()) { - return rmdir(path, options, originalErr, isTop) - } - - return fs.unlink(path) -} - -const rmdir = async (path, options, originalErr, isTop) => { - if (!options.recursive && isTop) { - throw originalErr || new ERR_FS_EISDIR(path) - } - const force = isTop ? options.force : true - - return fs.rmdir(path) - .catch(async (err) => { - // in Windows, calling rmdir on a file path will fail with ENOENT rather - // than ENOTDIR. to determine if that's what happened, we have to do - // another lstat on the path. if the path isn't actually gone, we throw - // away the ENOENT and replace it with our own ENOTDIR - if (isWindows && err.code === 'ENOENT') { - const stillExists = await fs.lstat(path).then(() => true, () => false) - if (stillExists) { - err = new ENOTDIR(path) - } - } - - // not there, not a problem - if (err.code === 'ENOENT' && force) { - return - } - - // we may not have originalErr if lstat tells us our target is a - // directory but that changes before we actually remove it, so - // only throw it here if it's set - if (originalErr && err.code === 'ENOTDIR') { - throw originalErr - } - - // the directory isn't empty, remove the contents and try again - if (notEmptyCodes.has(err.code)) { - const files = await fs.readdir(path) - await Promise.all(files.map((file) => { - const target = join(path, file) - return rimraf(target, options) - })) - return fs.rmdir(path) - } - - throw err - }) -} - -const rm = async (path, opts) => { - const options = { ...defaultOptions, ...opts } - let retries = 0 - - const errHandler = async (err) => { - if (retryCodes.has(err.code) && ++retries < options.maxRetries) { - const delay = retries * options.retryDelay - await promiseTimeout(delay) - return rimraf(path, options, true).catch(errHandler) - } - - throw err - } - - return rimraf(path, options, true).catch(errHandler) -} - -const promiseTimeout = (ms) => new Promise((r) => setTimeout(r, ms)) - -module.exports = rm diff --git a/node_modules/@npmcli/fs/lib/with-owner-sync.js b/node_modules/@npmcli/fs/lib/with-owner-sync.js deleted file mode 100644 index 3597d1c810475..0000000000000 --- a/node_modules/@npmcli/fs/lib/with-owner-sync.js +++ /dev/null @@ -1,21 +0,0 @@ -const getOptions = require('./common/get-options.js') -const owner = require('./common/owner-sync.js') - -const withOwnerSync = (path, fn, opts) => { - const options = getOptions(opts, { - copy: ['owner'], - }) - - const { uid, gid } = owner.validate(path, options.owner) - - const result = fn({ uid, gid }) - - owner.update(path, uid, gid) - if (typeof result === 'string') { - owner.update(result, uid, gid) - } - - return result -} - -module.exports = withOwnerSync diff --git a/node_modules/@npmcli/fs/lib/with-owner.js b/node_modules/@npmcli/fs/lib/with-owner.js deleted file mode 100644 index a679102883dbb..0000000000000 --- a/node_modules/@npmcli/fs/lib/with-owner.js +++ /dev/null @@ -1,21 +0,0 @@ -const getOptions = require('./common/get-options.js') -const owner = require('./common/owner.js') - -const withOwner = async (path, fn, opts) => { - const options = getOptions(opts, { - copy: ['owner'], - }) - - const { uid, gid } = await owner.validate(path, options.owner) - - const result = await fn({ uid, gid }) - - await Promise.all([ - owner.update(path, uid, gid), - typeof result === 'string' ? owner.update(result, uid, gid) : null, - ]) - - return result -} - -module.exports = withOwner diff --git a/node_modules/@npmcli/fs/lib/with-temp-dir.js b/node_modules/@npmcli/fs/lib/with-temp-dir.js index ad08e6ee6e6d6..0738ac4f29e1b 100644 --- a/node_modules/@npmcli/fs/lib/with-temp-dir.js +++ b/node_modules/@npmcli/fs/lib/with-temp-dir.js @@ -1,9 +1,7 @@ const { join, sep } = require('path') const getOptions = require('./common/get-options.js') -const mkdir = require('./mkdir.js') -const mkdtemp = require('./mkdtemp.js') -const rm = require('./rm/index.js') +const { mkdir, mkdtemp, rm } = require('fs/promises') // create a temp directory, ensure its permissions match its parent, then call // the supplied function passing it the path to the directory. clean up after @@ -12,10 +10,10 @@ const withTempDir = async (root, fn, opts) => { const options = getOptions(opts, { copy: ['tmpPrefix'], }) - // create the directory, and fix its ownership - await mkdir(root, { recursive: true, owner: 'inherit' }) + // create the directory + await mkdir(root, { recursive: true }) - const target = await mkdtemp(join(`${root}${sep}`, options.tmpPrefix || ''), { owner: 'inherit' }) + const target = await mkdtemp(join(`${root}${sep}`, options.tmpPrefix || '')) let err let result @@ -27,7 +25,9 @@ const withTempDir = async (root, fn, opts) => { try { await rm(target, { force: true, recursive: true }) - } catch {} + } catch { + // ignore errors + } if (err) { throw err diff --git a/node_modules/@npmcli/fs/lib/write-file.js b/node_modules/@npmcli/fs/lib/write-file.js deleted file mode 100644 index ff900571a1f28..0000000000000 --- a/node_modules/@npmcli/fs/lib/write-file.js +++ /dev/null @@ -1,14 +0,0 @@ -const fs = require('./fs.js') -const getOptions = require('./common/get-options.js') -const withOwner = require('./with-owner.js') - -const writeFile = async (file, data, opts) => { - const options = getOptions(opts, { - copy: ['encoding', 'mode', 'flag', 'signal'], - wrap: 'encoding', - }) - - return withOwner(file, () => fs.writeFile(file, data, options), opts) -} - -module.exports = writeFile diff --git a/node_modules/@npmcli/fs/package.json b/node_modules/@npmcli/fs/package.json index 9e18028218d1a..0b64301d6579e 100644 --- a/node_modules/@npmcli/fs/package.json +++ b/node_modules/@npmcli/fs/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/fs", - "version": "2.1.1", + "version": "5.0.0", "description": "filesystem utilities for the npm cli", "main": "lib/index.js", "files": [ @@ -8,22 +8,20 @@ "lib/" ], "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "snap": "tap", "test": "tap", "npmclilint": "npmcli-lint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/fs.git" + "url": "git+https://github.com/npm/fs.git" }, "keywords": [ "npm", @@ -32,19 +30,25 @@ "author": "GitHub Inc.", "license": "ISC", "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "dependencies": { - "@gar/promisify": "^1.1.3", "semver": "^7.3.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@npmcli/git/lib/clone.js b/node_modules/@npmcli/git/lib/clone.js index 3f165dd70e380..e25a4d1426821 100644 --- a/node_modules/@npmcli/git/lib/clone.js +++ b/node_modules/@npmcli/git/lib/clone.js @@ -27,8 +27,7 @@ const spawn = require('./spawn.js') const { isWindows } = require('./utils.js') const pickManifest = require('npm-pick-manifest') -const fs = require('fs') -const mkdirp = require('mkdirp') +const fs = require('fs/promises') module.exports = (repo, ref = 'HEAD', target = null, opts = {}) => getRevs(repo, opts).then(revs => clone( @@ -93,7 +92,7 @@ const other = (repo, revDoc, target, opts) => { .concat(shallow ? ['--depth=1'] : []) const git = (args) => spawn(args, { ...opts, cwd: target }) - return mkdirp(target) + return fs.mkdir(target, { recursive: true }) .then(() => git(['init'])) .then(() => isWindows(opts) ? git(['config', '--local', '--add', 'core.longpaths', 'true']) @@ -141,19 +140,21 @@ const plain = (repo, revDoc, target, opts) => { return spawn(args, opts).then(() => revDoc.sha) } -const updateSubmodules = (target, opts) => new Promise(resolve => - fs.stat(target + '/.gitmodules', er => { - if (er) { - return resolve(null) - } - return resolve(spawn([ - 'submodule', - 'update', - '-q', - '--init', - '--recursive', - ], { ...opts, cwd: target })) - })) +const updateSubmodules = async (target, opts) => { + const hasSubmodules = await fs.stat(`${target}/.gitmodules`) + .then(() => true) + .catch(() => false) + if (!hasSubmodules) { + return null + } + return spawn([ + 'submodule', + 'update', + '-q', + '--init', + '--recursive', + ], { ...opts, cwd: target }) +} const unresolved = (repo, ref, target, opts) => { // can't do this one shallowly, because the ref isn't advertised @@ -161,7 +162,7 @@ const unresolved = (repo, ref, target, opts) => { const lp = isWindows(opts) ? ['--config', 'core.longpaths=true'] : [] const cloneArgs = ['clone', '--mirror', '-q', repo, target + '/.git'] const git = (args) => spawn(args, { ...opts, cwd: target }) - return mkdirp(target) + return fs.mkdir(target, { recursive: true }) .then(() => git(cloneArgs.concat(lp))) .then(() => git(['init'])) .then(() => git(['checkout', ref])) diff --git a/node_modules/@npmcli/git/lib/errors.js b/node_modules/@npmcli/git/lib/errors.js index 7aeac4762866f..3ceaa45811669 100644 --- a/node_modules/@npmcli/git/lib/errors.js +++ b/node_modules/@npmcli/git/lib/errors.js @@ -8,7 +8,7 @@ class GitError extends Error { } class GitConnectionError extends GitError { - constructor (message) { + constructor () { super('A git connection error occurred') } @@ -18,13 +18,13 @@ class GitConnectionError extends GitError { } class GitPathspecError extends GitError { - constructor (message) { + constructor () { super('The git reference could not be found') } } class GitUnknownError extends GitError { - constructor (message) { + constructor () { super('An unknown git error occurred') } } diff --git a/node_modules/@npmcli/git/lib/find.js b/node_modules/@npmcli/git/lib/find.js index d58f01dbcc16f..34bd310b88e5d 100644 --- a/node_modules/@npmcli/git/lib/find.js +++ b/node_modules/@npmcli/git/lib/find.js @@ -1,15 +1,15 @@ const is = require('./is.js') const { dirname } = require('path') -module.exports = async ({ cwd = process.cwd() } = {}) => { - if (await is({ cwd })) { - return cwd - } - while (cwd !== dirname(cwd)) { - cwd = dirname(cwd) +module.exports = async ({ cwd = process.cwd(), root } = {}) => { + while (true) { if (await is({ cwd })) { return cwd } + const next = dirname(cwd) + if (cwd === root || cwd === next) { + return null + } + cwd = next } - return null } diff --git a/node_modules/@npmcli/git/lib/is.js b/node_modules/@npmcli/git/lib/is.js index e2542f2157727..f5a0e8754f10d 100644 --- a/node_modules/@npmcli/git/lib/is.js +++ b/node_modules/@npmcli/git/lib/is.js @@ -1,6 +1,4 @@ // not an airtight indicator, but a good gut-check to even bother trying -const { promisify } = require('util') -const fs = require('fs') -const stat = promisify(fs.stat) +const { stat } = require('fs/promises') module.exports = ({ cwd = process.cwd() } = {}) => stat(cwd + '/.git').then(() => true, () => false) diff --git a/node_modules/@npmcli/git/lib/opts.js b/node_modules/@npmcli/git/lib/opts.js index 3119af16e0cf1..1e80e9efe4989 100644 --- a/node_modules/@npmcli/git/lib/opts.js +++ b/node_modules/@npmcli/git/lib/opts.js @@ -1,12 +1,57 @@ +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') +const ini = require('ini') + +const gitConfigPath = path.join(os.homedir(), '.gitconfig') + +let cachedConfig = null + +// Function to load and cache the git config +const loadGitConfig = () => { + if (cachedConfig === null) { + try { + cachedConfig = {} + if (fs.existsSync(gitConfigPath)) { + const configContent = fs.readFileSync(gitConfigPath, 'utf-8') + cachedConfig = ini.parse(configContent) + } + } catch (error) { + cachedConfig = {} + } + } + return cachedConfig +} + +const checkGitConfigs = () => { + const config = loadGitConfig() + return { + sshCommandSetInConfig: config?.core?.sshCommand !== undefined, + askPassSetInConfig: config?.core?.askpass !== undefined, + } +} + +const sshCommandSetInEnv = process.env.GIT_SSH_COMMAND !== undefined +const askPassSetInEnv = process.env.GIT_ASKPASS !== undefined +const { sshCommandSetInConfig, askPassSetInConfig } = checkGitConfigs() + // Values we want to set if they're not already defined by the end user // This defaults to accepting new ssh host key fingerprints -const gitEnv = { - GIT_ASKPASS: 'echo', - GIT_SSH_COMMAND: 'ssh -oStrictHostKeyChecking=accept-new', +const finalGitEnv = { + ...(askPassSetInEnv || askPassSetInConfig ? {} : { + GIT_ASKPASS: 'echo', + }), + ...(sshCommandSetInEnv || sshCommandSetInConfig ? {} : { + GIT_SSH_COMMAND: 'ssh -oStrictHostKeyChecking=accept-new', + }), } + module.exports = (opts = {}) => ({ stdioString: true, ...opts, shell: false, - env: opts.env || { ...gitEnv, ...process.env }, + env: opts.env || { ...finalGitEnv, ...process.env }, }) + +// Export the loadGitConfig function for testing +module.exports.loadGitConfig = loadGitConfig diff --git a/node_modules/@npmcli/git/lib/revs.js b/node_modules/@npmcli/git/lib/revs.js index ee72370d5b7ec..ebcc848fa3458 100644 --- a/node_modules/@npmcli/git/lib/revs.js +++ b/node_modules/@npmcli/git/lib/revs.js @@ -1,14 +1,12 @@ -const pinflight = require('promise-inflight') const spawn = require('./spawn.js') -const LRU = require('lru-cache') +const { LRUCache } = require('lru-cache') +const linesToRevs = require('./lines-to-revs.js') -const revsCache = new LRU({ +const revsCache = new LRUCache({ max: 100, ttl: 5 * 60 * 1000, }) -const linesToRevs = require('./lines-to-revs.js') - module.exports = async (repo, opts = {}) => { if (!opts.noGitRevCache) { const cached = revsCache.get(repo) @@ -17,12 +15,8 @@ module.exports = async (repo, opts = {}) => { } } - return pinflight(`ls-remote:${repo}`, () => - spawn(['ls-remote', repo], opts) - .then(({ stdout }) => linesToRevs(stdout.trim().split('\n'))) - .then(revs => { - revsCache.set(repo, revs) - return revs - }) - ) + const { stdout } = await spawn(['ls-remote', repo], opts) + const revs = linesToRevs(stdout.trim().split('\n')) + revsCache.set(repo, revs) + return revs } diff --git a/node_modules/@npmcli/git/lib/spawn.js b/node_modules/@npmcli/git/lib/spawn.js index 7098d7b872942..03c1cbde21547 100644 --- a/node_modules/@npmcli/git/lib/spawn.js +++ b/node_modules/@npmcli/git/lib/spawn.js @@ -1,11 +1,11 @@ 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 whichGit = require('./which.js') const makeOpts = require('./opts.js') module.exports = (gitArgs, opts = {}) => { + const whichGit = require('./which.js') const gitPath = whichGit(opts) if (gitPath instanceof Error) { diff --git a/node_modules/@npmcli/git/lib/which.js b/node_modules/@npmcli/git/lib/which.js index a2f690e1bce80..dc2a1ad212166 100644 --- a/node_modules/@npmcli/git/lib/which.js +++ b/node_modules/@npmcli/git/lib/which.js @@ -3,7 +3,9 @@ const which = require('which') let gitPath try { gitPath = which.sync('git') -} catch (e) {} +} catch { + // ignore errors +} module.exports = (opts = {}) => { if (opts.git) { diff --git a/node_modules/@npmcli/git/package.json b/node_modules/@npmcli/git/package.json index 08525ae99e8ec..78d077513dd81 100644 --- a/node_modules/@npmcli/git/package.json +++ b/node_modules/@npmcli/git/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/git", - "version": "3.0.1", + "version": "7.0.1", "main": "lib/index.js", "files": [ "bin/", @@ -9,49 +9,50 @@ "description": "a util for spawning git from npm CLI contexts", "repository": { "type": "git", - "url": "https://github.com/npm/git.git" + "url": "git+https://github.com/npm/git.git" }, "author": "GitHub Inc.", "license": "ISC", "scripts": { - "lint": "eslint \"**/*.js\"", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "preversion": "npm test", + "lint": "npm run eslint", "snap": "tap", "test": "tap", "posttest": "npm run lint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "template-oss-apply": "template-oss-apply --force" + "lintfix": "npm run eslint -- --fix", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true, - "coverage-map": "map.js" + "timeout": 600, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.24.1", + "npm-package-arg": "^13.0.0", "slash": "^3.0.0", "tap": "^16.0.1" }, "dependencies": { - "@npmcli/promise-spawn": "^3.0.0", - "lru-cache": "^7.4.4", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^7.0.0", - "proc-log": "^2.0.0", - "promise-inflight": "^1.0.1", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^2.0.2" + "which": "^6.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "windowsCI": false, - "version": "3.2.2" + "version": "4.24.1", + "publish": true } } diff --git a/node_modules/@npmcli/installed-package-contents/bin/index.js b/node_modules/@npmcli/installed-package-contents/bin/index.js new file mode 100755 index 0000000000000..7b83b23bf168c --- /dev/null +++ b/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 <path> [-d<n> --depth=<n>] + +Lists the files installed for a package specified by <path>. + +Options: + -d<n> --depth=<n> 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/node_modules/@npmcli/installed-package-contents/index.js b/node_modules/@npmcli/installed-package-contents/index.js deleted file mode 100755 index 30427fe28c108..0000000000000 --- a/node_modules/@npmcli/installed-package-contents/index.js +++ /dev/null @@ -1,237 +0,0 @@ -// 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 -// - if depth >= maxDepth, add PATH to result, and finish -// - readdir(PATH, with file types) -// - add all FILEs in PATH to result -// - if PARENT: -// - if depth < maxDepth, add GET CONTENTS of all DIRs in PATH -// - else, add all DIRs in PATH -// - if no parent -// - if no bundled deps, -// - if depth < maxDepth, add GET CONTENTS of DIRs in path except -// node_modules -// - else, add all DIRs in path other than node_modules -// - if has bundled deps, -// - get list of bundled deps -// - 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 normalizePackageBin = require('npm-normalize-package-bin') - -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) - -// 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 - return pkg - }) - - -const pkgContents = async ({ - path, - depth, - currentDepth = 0, - pkg = null, - result = null, - packageJsonCache = null, -}) => { - if (!result) - result = new Set() - - if (!packageJsonCache) - packageJsonCache = new Map() - - if (pkg === true) { - return rpj({ path: path + '/package.json', packageJsonCache }) - .then(pkg => pkgContents({ - path, - depth, - currentDepth, - pkg, - result, - packageJsonCache, - })) - } - - if (pkg) { - // add all bins to result if they exist - if (pkg.bin) { - const dir = dirname(path) - const base = basename(path) - const scope = basename(dir) - const nm = /^@.+/.test(scope) ? dirname(dir) : dir - - const binFiles = [] - Object.keys(pkg.bin).forEach(b => { - const base = resolve(nm, '.bin', b) - binFiles.push(base, base + '.cmd', base + '.ps1') - }) - - const bins = await Promise.all( - binFiles.map(b => stat(b).then(() => b).catch((er) => null)) - ) - bins.filter(b => b).forEach(b => result.add(b)) - } - } - - if (currentDepth >= depth) { - result.add(path) - return result - } - - // we'll need bundle list later, so get that now in parallel - const [dirEntries, bundleDeps] = await Promise.all([ - readdir(path, { withFileTypes: true }), - currentDepth === 0 && pkg && pkg.bundleDependencies - ? bundled({ path, packageJsonCache }) : null, - ]).catch(() => []) - - // not a thing, probably a missing folder - if (!dirEntries) - return result - - // empty folder, just add the folder itself to the result - if (!dirEntries.length && !bundleDeps && currentDepth !== 0) { - result.add(path) - return result - } - - 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) { - result.add(p) - continue - } - - if (currentDepth !== 0 || entry.name !== 'node_modules') { - if (currentDepth < depth - 1) { - recursePromises.push(pkgContents({ - path: p, - packageJsonCache, - depth, - currentDepth: currentDepth + 1, - result, - })) - } else { - result.add(p) - } - continue - } - } - - if (bundleDeps) { - // bundle deps are all folders - // we always recurse to get pkg bins, but if currentDepth is too high, - // it'll return early before walking their contents. - recursePromises.push(...bundleDeps.map(dep => { - const p = resolve(path, 'node_modules', dep) - return pkgContents({ - path: p, - packageJsonCache, - pkg: true, - depth, - currentDepth: currentDepth + 1, - result, - }) - })) - } - - if (recursePromises.length) - await Promise.all(recursePromises) - - return result -} - -module.exports = ({path, depth = 1, packageJsonCache}) => pkgContents({ - path: resolve(path), - depth, - pkg: true, - packageJsonCache, -}).then(results => [...results]) - - -if (require.main === module) { - const options = { path: null, depth: 1 } - const usage = `Usage: - installed-package-contents <path> [-d<n> --depth=<n>] - -Lists the files installed for a package specified by <path>. - -Options: - -d<n> --depth=<n> 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/node_modules/@npmcli/installed-package-contents/lib/index.js b/node_modules/@npmcli/installed-package-contents/lib/index.js new file mode 100644 index 0000000000000..ab1486cd01d00 --- /dev/null +++ b/node_modules/@npmcli/installed-package-contents/lib/index.js @@ -0,0 +1,181 @@ +// 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 +// - if depth >= maxDepth, add PATH to result, and finish +// - readdir(PATH, with file types) +// - add all FILEs in PATH to result +// - if PARENT: +// - if depth < maxDepth, add GET CONTENTS of all DIRs in PATH +// - else, add all DIRs in PATH +// - if no parent +// - if no bundled deps, +// - if depth < maxDepth, add GET CONTENTS of DIRs in path except +// node_modules +// - else, add all DIRs in path other than node_modules +// - if has bundled deps, +// - get list of bundled deps +// - add GET CONTENTS of bundled deps, PACKAGE=true, depth + 1 + +const bundled = require('npm-bundled') +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)) + : readFile(path).then(json => { + const pkg = normalizePackageBin(JSON.parse(json)) + packageJsonCache.set(path, pkg) + return pkg + }).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 + return pkg + }) + +const pkgContents = async ({ + path, + depth = 1, + currentDepth = 0, + pkg = null, + result = null, + packageJsonCache = null, +}) => { + if (!result) { + result = new Set() + } + + if (!packageJsonCache) { + packageJsonCache = new Map() + } + + if (pkg === true) { + return rpj({ path: path + '/package.json', packageJsonCache }) + .then(p => pkgContents({ + path, + depth, + currentDepth, + pkg: p, + result, + packageJsonCache, + })) + } + + if (pkg) { + // add all bins to result if they exist + if (pkg.bin) { + const dir = dirname(path) + const scope = basename(dir) + const nm = /^@.+/.test(scope) ? dirname(dir) : dir + + const binFiles = [] + Object.keys(pkg.bin).forEach(b => { + const base = resolve(nm, '.bin', b) + binFiles.push(base, base + '.cmd', base + '.ps1') + }) + + const bins = await Promise.all( + binFiles.map(b => stat(b).then(() => b).catch(() => null)) + ) + bins.filter(b => b).forEach(b => result.add(b)) + } + } + + if (currentDepth >= depth) { + result.add(path) + return result + } + + // we'll need bundle list later, so get that now in parallel + const [dirEntries, bundleDeps] = await Promise.all([ + readdir(path, { withFileTypes: true }), + currentDepth === 0 && pkg && pkg.bundleDependencies + ? bundled({ path, packageJsonCache }) : null, + ]).catch(() => []) + + // not a thing, probably a missing folder + if (!dirEntries) { + return result + } + + // empty folder, just add the folder itself to the result + if (!dirEntries.length && !bundleDeps && currentDepth !== 0) { + result.add(path) + return result + } + + const recursePromises = [] + + for (const entry of dirEntries) { + const p = resolve(path, entry.name) + if (entry.isDirectory() === false) { + result.add(p) + continue + } + + if (currentDepth !== 0 || entry.name !== 'node_modules') { + if (currentDepth < depth - 1) { + recursePromises.push(pkgContents({ + path: p, + packageJsonCache, + depth, + currentDepth: currentDepth + 1, + result, + })) + } else { + result.add(p) + } + continue + } + } + + if (bundleDeps) { + // bundle deps are all folders + // we always recurse to get pkg bins, but if currentDepth is too high, + // it'll return early before walking their contents. + recursePromises.push(...bundleDeps.map(dep => { + const p = resolve(path, 'node_modules', dep) + return pkgContents({ + path: p, + packageJsonCache, + pkg: true, + depth, + currentDepth: currentDepth + 1, + result, + }) + })) + } + + if (recursePromises.length) { + await Promise.all(recursePromises) + } + + return result +} + +module.exports = ({ path, ...opts }) => pkgContents({ + path: resolve(path), + ...opts, + pkg: true, +}).then(results => [...results]) diff --git a/node_modules/@npmcli/installed-package-contents/package.json b/node_modules/@npmcli/installed-package-contents/package.json index 13916308f99db..599b285fb467d 100644 --- a/node_modules/@npmcli/installed-package-contents/package.json +++ b/node_modules/@npmcli/installed-package-contents/package.json @@ -1,37 +1,52 @@ { "name": "@npmcli/installed-package-contents", - "version": "1.0.7", + "version": "4.0.0", "description": "Get the list of files installed in a package in node_modules, including bundled dependencies", - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", - "main": "index.js", + "author": "GitHub Inc.", + "main": "lib/index.js", "bin": { - "installed-package-contents": "index.js" + "installed-package-contents": "bin/index.js" }, "license": "ISC", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true, - "color": true + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { - "require-inject": "^1.4.4", - "tap": "^14.11.0" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, "dependencies": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/installed-package-contents.git" }, - "repository": "git+https://github.com/npm/installed-package-contents", "files": [ - "index.js" + "bin/", + "lib/" ], "engines": { - "node": ">= 10" + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@npmcli/map-workspaces/lib/index.js b/node_modules/@npmcli/map-workspaces/lib/index.js index 3ac545e9c15c4..f38b8cd33b74f 100644 --- a/node_modules/@npmcli/map-workspaces/lib/index.js +++ b/node_modules/@npmcli/map-workspaces/lib/index.js @@ -1,29 +1,53 @@ -const { promisify } = require('util') const path = require('path') const getName = require('@npmcli/name-from-folder') -const minimatch = require('minimatch') -const rpj = require('read-package-json-fast') -const glob = require('glob') -const pGlob = promisify(glob) - -function appendNegatedPatterns (patterns) { - const results = [] - for (let pattern of patterns) { +const { minimatch } = require('minimatch') +const pkgJson = require('@npmcli/package-json') +const { glob } = require('glob') + +function appendNegatedPatterns (allPatterns) { + const patterns = [] + const negatedPatterns = [] + for (let pattern of allPatterns) { const excl = pattern.match(/^!+/) if (excl) { - pattern = pattern.substr(excl[0].length) + pattern = pattern.slice(excl[0].length) } - // strip off any / from the start of the pattern. /foo => foo - pattern = pattern.replace(/^\/+/, '') + // strip off any / or ./ from the start of the pattern. /foo => foo + pattern = pattern.replace(/^\.?\/+/, '') // an odd number of ! means a negated pattern. !!foo ==> foo const negate = excl && excl[0].length % 2 === 1 - results.push({ pattern, negate }) + if (negate) { + negatedPatterns.push(pattern) + } else { + // remove negated patterns that appeared before this pattern to avoid + // ignoring paths that were matched afterwards + // e.g: ['packages/**', '!packages/b/**', 'packages/b/a'] + // in the above list, the last pattern overrides the negated pattern + // right before it. In effect, the above list would become: + // ['packages/**', 'packages/b/a'] + // The order matters here which is why we must do it inside the loop + // as opposed to doing it all together at the end. + for (let i = 0; i < negatedPatterns.length; ++i) { + const negatedPattern = negatedPatterns[i] + if (minimatch(pattern, negatedPattern)) { + negatedPatterns.splice(i, 1) + } + } + patterns.push(pattern) + } } - return results + // use the negated patterns to eagerly remove all the patterns that + // can be removed to avoid unnecessary crawling + for (const negated of negatedPatterns) { + for (const pattern of minimatch.match(patterns, negated)) { + patterns.splice(patterns.indexOf(pattern), 1) + } + } + return { patterns, negatedPatterns } } function getPatterns (workspaces) { @@ -43,15 +67,7 @@ function getPatterns (workspaces) { } function getPackageName (pkg, pathname) { - const { name } = pkg - return name || getName(pathname) -} - -function pkgPathmame (opts) { - return (...args) => { - const cwd = opts.cwd ? opts.cwd : process.cwd() - return path.join.apply(null, [cwd, ...args]) - } + return pkg.name || getName(pathname) } // make sure glob pattern only matches folders @@ -77,64 +93,66 @@ async function mapWorkspaces (opts = {}) { code: 'EMAPWORKSPACESPKG', }) } + if (!opts.cwd) { + opts.cwd = process.cwd() + } const { workspaces = [] } = opts.pkg - const patterns = getPatterns(workspaces) + const { patterns, negatedPatterns } = getPatterns(workspaces) const results = new Map() - const seen = new Map() - if (!patterns.length) { + if (!patterns.length && !negatedPatterns.length) { return results } + const seen = new Map() const getGlobOpts = () => ({ ...opts, ignore: [ ...opts.ignore || [], - ...['**/node_modules/**'], + '**/node_modules/**', + // just ignore the negated patterns to avoid unnecessary crawling + ...negatedPatterns, ], }) - const getPackagePathname = pkgPathmame(opts) - - for (const item of patterns) { - const matches = await pGlob(getGlobPattern(item.pattern), getGlobOpts()) - - for (const match of matches) { - let pkg - const packageJsonPathname = getPackagePathname(match, 'package.json') - const packagePathname = path.dirname(packageJsonPathname) + let matches = await glob(patterns.map((p) => getGlobPattern(p)), getGlobOpts()) + // preserves glob@8 behavior + matches = matches.sort((a, b) => a.localeCompare(b, 'en')) + + // we must preserve the order of results according to the given list of + // workspace patterns + const orderedMatches = [] + for (const pattern of patterns) { + orderedMatches.push(...matches.filter((m) => { + return minimatch(m, pattern, { partial: true, windowsPathsNoEscape: true }) + })) + } - try { - pkg = await rpj(packageJsonPathname) - } catch (err) { - if (err.code === 'ENOENT') { - continue - } else { - throw err - } + for (const match of orderedMatches) { + let pkg + try { + pkg = await pkgJson.normalize(path.join(opts.cwd, match)) + } catch (err) { + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') { + continue + } else { + throw err } + } - const name = getPackageName(pkg, packagePathname) + const name = getPackageName(pkg.content, pkg.path) - let seenPackagePathnames = seen.get(name) - if (!seenPackagePathnames) { - seenPackagePathnames = new Set() - seen.set(name, seenPackagePathnames) - } - if (item.negate) { - seenPackagePathnames.delete(packagePathname) - } else { - seenPackagePathnames.add(packagePathname) - } + let seenPackagePathnames = seen.get(name) + if (!seenPackagePathnames) { + seenPackagePathnames = new Set() + seen.set(name, seenPackagePathnames) } + seenPackagePathnames.add(pkg.path) } const errorMessageArray = ['must not have multiple workspaces with the same name'] for (const [packageName, seenPackagePathnames] of seen) { - if (seenPackagePathnames.size === 0) { - continue - } if (seenPackagePathnames.size > 1) { addDuplicateErrorMessages(errorMessageArray, packageName, seenPackagePathnames) } else { @@ -172,35 +190,32 @@ mapWorkspaces.virtual = function (opts = {}) { code: 'EMAPWORKSPACESLOCKFILE', }) } + if (!opts.cwd) { + opts.cwd = process.cwd() + } const { packages = {} } = opts.lockfile const { workspaces = [] } = packages[''] || {} // uses a pathname-keyed map in order to negate the exact items const results = new Map() - const patterns = getPatterns(workspaces) - if (!patterns.length) { + const { patterns, negatedPatterns } = getPatterns(workspaces) + if (!patterns.length && !negatedPatterns.length) { return results } - patterns.push({ pattern: '**/node_modules/**', negate: true }) + negatedPatterns.push('**/node_modules/**') - const getPackagePathname = pkgPathmame(opts) - - for (const packageKey of Object.keys(packages)) { - if (packageKey === '') { - continue + const packageKeys = Object.keys(packages) + for (const pattern of negatedPatterns) { + for (const packageKey of minimatch.match(packageKeys, pattern)) { + packageKeys.splice(packageKeys.indexOf(packageKey), 1) } + } - for (const item of patterns) { - if (minimatch(packageKey, item.pattern)) { - const packagePathname = getPackagePathname(packageKey) - const name = getPackageName(packages[packageKey], packagePathname) - - if (item.negate) { - results.delete(packagePathname) - } else { - results.set(packagePathname, name) - } - } + for (const pattern of patterns) { + for (const packageKey of minimatch.match(packageKeys, pattern)) { + const packagePathname = path.join(opts.cwd, packageKey) + const name = getPackageName(packages[packageKey], packagePathname) + results.set(packagePathname, name) } } diff --git a/node_modules/@npmcli/map-workspaces/package.json b/node_modules/@npmcli/map-workspaces/package.json index 3025081e5529b..84de7b989b4c4 100644 --- a/node_modules/@npmcli/map-workspaces/package.json +++ b/node_modules/@npmcli/map-workspaces/package.json @@ -1,18 +1,18 @@ { "name": "@npmcli/map-workspaces", - "version": "2.0.3", + "version": "5.0.3", "main": "lib/index.js", "files": [ "bin/", "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "description": "Retrieves a name:pathname Map for a given workspaces config", "repository": { "type": "git", - "url": "https://github.com/npm/map-workspaces.git" + "url": "git+https://github.com/npm/map-workspaces.git" }, "keywords": [ "npm", @@ -25,34 +25,37 @@ "author": "GitHub Inc.", "license": "ISC", "scripts": { - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "pretest": "npm run lint", "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.4.1", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", "tap": "^16.0.1" }, "dependencies": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^2.0.3" + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.4.1" + "version": "4.28.0", + "publish": "true" } } diff --git a/node_modules/@npmcli/metavuln-calculator/lib/advisory.js b/node_modules/@npmcli/metavuln-calculator/lib/advisory.js index 1f479a90dd999..1f4554963d7e4 100644 --- a/node_modules/@npmcli/metavuln-calculator/lib/advisory.js +++ b/node_modules/@npmcli/metavuln-calculator/lib/advisory.js @@ -106,7 +106,7 @@ class Advisory { this[_packument] = packument - const pakuVersions = Object.keys(packument.versions) + const pakuVersions = Object.keys(packument.versions || {}) const allVersions = new Set([...pakuVersions, ...this.versions]) const versionsAdded = [] const versionsRemoved = [] @@ -242,7 +242,7 @@ class Advisory { // check the dependency of this version on the vulnerable dep // if we got a version that's not in the packument, fall back on // the spec provided, if possible. - const mani = this[_packument].versions[version] || { + const mani = this[_packument]?.versions?.[version] || { dependencies: { [this.dependency]: spec, }, @@ -292,7 +292,7 @@ class Advisory { [_testSpec] (spec) { for (const v of this.versions) { - const satisfies = semver.satisfies(v, spec) + const satisfies = semver.satisfies(v, spec, semverOpt) if (!satisfies) { continue } diff --git a/node_modules/@npmcli/metavuln-calculator/lib/index.js b/node_modules/@npmcli/metavuln-calculator/lib/index.js index 668f55942c506..971409b5bad44 100644 --- a/node_modules/@npmcli/metavuln-calculator/lib/index.js +++ b/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,9 +105,9 @@ 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) => { + .catch(() => { // presumably not something from the registry. // an empty packument will have an effective range of * return { @@ -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/node_modules/@npmcli/metavuln-calculator/package.json b/node_modules/@npmcli/metavuln-calculator/package.json index 2e7209ffc7da0..02b13bc8e8219 100644 --- a/node_modules/@npmcli/metavuln-calculator/package.json +++ b/node_modules/@npmcli/metavuln-calculator/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/metavuln-calculator", - "version": "3.1.1", + "version": "9.0.3", "main": "lib/index.js", "files": [ "bin/", @@ -9,7 +9,7 @@ "description": "Calculate meta-vulnerabilities from package security advisories", "repository": { "type": "git", - "url": "https://github.com/npm/metavuln-calculator.git" + "url": "git+https://github.com/npm/metavuln-calculator.git" }, "author": "GitHub Inc.", "license": "ISC", @@ -18,36 +18,45 @@ "posttest": "npm run lint", "snap": "tap", "postsnap": "npm run lint", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "eslint": "eslint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" }, "tap": { "check-coverage": true, - "coverage-map": "map.js" + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "require-inject": "^1.4.4", "tap": "^16.0.1" }, "dependencies": { - "cacache": "^16.0.0", - "json-parse-even-better-errors": "^2.3.1", - "pacote": "^13.0.3", + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.27.1", + "publish": "true", + "ciVersions": [ + "16.14.0", + "16.x", + "18.0.0", + "18.x" + ] } } diff --git a/node_modules/@npmcli/move-file/LICENSE.md b/node_modules/@npmcli/move-file/LICENSE.md deleted file mode 100644 index 072bf20840acd..0000000000000 --- a/node_modules/@npmcli/move-file/LICENSE.md +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) -Copyright (c) npm, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@npmcli/move-file/lib/index.js b/node_modules/@npmcli/move-file/lib/index.js deleted file mode 100644 index ecc55f0171da5..0000000000000 --- a/node_modules/@npmcli/move-file/lib/index.js +++ /dev/null @@ -1,175 +0,0 @@ -const { dirname, join, resolve, relative, isAbsolute } = require('path') -const rimraf_ = require('rimraf') -const { promisify } = require('util') -const { - access: access_, - accessSync, - copyFile: copyFile_, - copyFileSync, - readdir: readdir_, - readdirSync, - rename: rename_, - renameSync, - stat: stat_, - statSync, - lstat: lstat_, - lstatSync, - symlink: symlink_, - symlinkSync, - readlink: readlink_, - readlinkSync, -} = require('fs') - -const access = promisify(access_) -const copyFile = promisify(copyFile_) -const readdir = promisify(readdir_) -const rename = promisify(rename_) -const stat = promisify(stat_) -const lstat = promisify(lstat_) -const symlink = promisify(symlink_) -const readlink = promisify(readlink_) -const rimraf = promisify(rimraf_) -const rimrafSync = rimraf_.sync - -const mkdirp = require('mkdirp') - -const pathExists = async path => { - try { - await access(path) - return true - } catch (er) { - return er.code !== 'ENOENT' - } -} - -const pathExistsSync = path => { - try { - accessSync(path) - return true - } catch (er) { - return er.code !== 'ENOENT' - } -} - -const moveFile = async (source, destination, options = {}, root = true, symlinks = []) => { - if (!source || !destination) { - throw new TypeError('`source` and `destination` file required') - } - - options = { - overwrite: true, - ...options, - } - - if (!options.overwrite && await pathExists(destination)) { - throw new Error(`The destination file exists: ${destination}`) - } - - await mkdirp(dirname(destination)) - - try { - await rename(source, destination) - } catch (error) { - if (error.code === 'EXDEV' || error.code === 'EPERM') { - const sourceStat = await lstat(source) - if (sourceStat.isDirectory()) { - const files = await readdir(source) - await Promise.all(files.map((file) => - moveFile(join(source, file), join(destination, file), options, false, symlinks) - )) - } else if (sourceStat.isSymbolicLink()) { - symlinks.push({ source, destination }) - } else { - await copyFile(source, destination) - } - } else { - throw error - } - } - - if (root) { - await Promise.all(symlinks.map(async ({ source: symSource, destination: symDestination }) => { - let target = await readlink(symSource) - // junction symlinks in windows will be absolute paths, so we need to - // make sure they point to the symlink destination - if (isAbsolute(target)) { - target = resolve(symDestination, relative(symSource, target)) - } - // try to determine what the actual file is so we can create the correct - // type of symlink in windows - let targetStat - try { - targetStat = await stat(resolve(dirname(symSource), target)) - } catch (err) {} - await symlink( - target, - symDestination, - targetStat && targetStat.isDirectory() ? 'junction' : 'file' - ) - })) - await rimraf(source) - } -} - -const moveFileSync = (source, destination, options = {}, root = true, symlinks = []) => { - if (!source || !destination) { - throw new TypeError('`source` and `destination` file required') - } - - options = { - overwrite: true, - ...options, - } - - if (!options.overwrite && pathExistsSync(destination)) { - throw new Error(`The destination file exists: ${destination}`) - } - - mkdirp.sync(dirname(destination)) - - try { - renameSync(source, destination) - } catch (error) { - if (error.code === 'EXDEV' || error.code === 'EPERM') { - const sourceStat = lstatSync(source) - if (sourceStat.isDirectory()) { - const files = readdirSync(source) - for (const file of files) { - moveFileSync(join(source, file), join(destination, file), options, false, symlinks) - } - } else if (sourceStat.isSymbolicLink()) { - symlinks.push({ source, destination }) - } else { - copyFileSync(source, destination) - } - } else { - throw error - } - } - - if (root) { - for (const { source: symSource, destination: symDestination } of symlinks) { - let target = readlinkSync(symSource) - // junction symlinks in windows will be absolute paths, so we need to - // make sure they point to the symlink destination - if (isAbsolute(target)) { - target = resolve(symDestination, relative(symSource, target)) - } - // try to determine what the actual file is so we can create the correct - // type of symlink in windows - let targetStat - try { - targetStat = statSync(resolve(dirname(symSource), target)) - } catch (err) {} - symlinkSync( - target, - symDestination, - targetStat && targetStat.isDirectory() ? 'junction' : 'file' - ) - } - rimrafSync(source) - } -} - -module.exports = moveFile -module.exports.sync = moveFileSync diff --git a/node_modules/@npmcli/move-file/package.json b/node_modules/@npmcli/move-file/package.json deleted file mode 100644 index 1b1d377b0c7b2..0000000000000 --- a/node_modules/@npmcli/move-file/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@npmcli/move-file", - "version": "2.0.0", - "files": [ - "bin/", - "lib/" - ], - "main": "lib/index.js", - "description": "move a file (fork of move-file)", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "tap": "^16.0.1" - }, - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", - "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint" - }, - "repository": { - "type": "git", - "url": "https://github.com/npm/move-file.git" - }, - "tap": { - "check-coverage": true - }, - "license": "MIT", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "author": "GitHub Inc.", - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" - } -} diff --git a/node_modules/@npmcli/name-from-folder/index.js b/node_modules/@npmcli/name-from-folder/lib/index.js similarity index 100% rename from node_modules/@npmcli/name-from-folder/index.js rename to node_modules/@npmcli/name-from-folder/lib/index.js diff --git a/node_modules/@npmcli/name-from-folder/package.json b/node_modules/@npmcli/name-from-folder/package.json index 9569b4e66e90c..503667521565d 100644 --- a/node_modules/@npmcli/name-from-folder/package.json +++ b/node_modules/@npmcli/name-from-folder/package.json @@ -1,27 +1,45 @@ { "name": "@npmcli/name-from-folder", - "version": "1.0.1", + "version": "4.0.0", "files": [ - "index.js" + "bin/", + "lib/" ], + "main": "lib/index.js", "description": "Get the package name from a folder path", "repository": { "type": "git", - "url": "git+https://github.com/npm/name-from-folder" + "url": "git+https://github.com/npm/name-from-folder.git" }, - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", + "author": "GitHub Inc.", "license": "ISC", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { - "tap": "^14.10.7" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.2" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@npmcli/node-gyp/LICENSE b/node_modules/@npmcli/node-gyp/LICENSE new file mode 100644 index 0000000000000..3609cabca4535 --- /dev/null +++ b/node_modules/@npmcli/node-gyp/LICENSE @@ -0,0 +1,7 @@ +ISC License: + +Copyright (c) 2023 by 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 copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/@npmcli/node-gyp/package.json b/node_modules/@npmcli/node-gyp/package.json index 04eeec8ff808c..a34dc6be61751 100644 --- a/node_modules/@npmcli/node-gyp/package.json +++ b/node_modules/@npmcli/node-gyp/package.json @@ -1,22 +1,20 @@ { "name": "@npmcli/node-gyp", - "version": "2.0.0", + "version": "5.0.0", "description": "Tools for dealing with node-gyp packages", "scripts": { "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/node-gyp.git" + "url": "git+https://github.com/npm/node-gyp.git" }, "keywords": [ "npm", @@ -31,15 +29,22 @@ "author": "GitHub Inc.", "license": "ISC", "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@npmcli/package-json/lib/index.js b/node_modules/@npmcli/package-json/lib/index.js index e98308f3d3b84..adcbac67eabba 100644 --- a/node_modules/@npmcli/package-json/lib/index.js +++ b/node_modules/@npmcli/package-json/lib/index.js @@ -1,17 +1,13 @@ -const fs = require('fs') -const promisify = require('util').promisify -const readFile = promisify(fs.readFile) -const writeFile = promisify(fs.writeFile) -const { resolve } = require('path') +const { readFile, writeFile } = require('node:fs/promises') +const { resolve } = require('node:path') +const parseJSON = require('json-parse-even-better-errors') + const updateDeps = require('./update-dependencies.js') const updateScripts = require('./update-scripts.js') const updateWorkspaces = require('./update-workspaces.js') - -const parseJSON = require('json-parse-even-better-errors') - -const _filename = Symbol('filename') -const _manifest = Symbol('manifest') -const _readFileContent = Symbol('readFileContent') +const { normalize, syncNormalize } = require('./normalize.js') +const { read, parse } = require('./read-package.js') +const { packageSort } = require('./sort.js') // a list of handy specialized helper functions that take // care of special cases that are handled by the npm cli @@ -29,80 +25,271 @@ const knownKeys = new Set([ ]) class PackageJson { - static async load (path) { - return await new PackageJson(path).load() - } + // npm pkg fix + static fixSteps = Object.freeze([ + 'binRefs', + 'bundleDependencies', + 'fixName', + 'fixVersionField', + 'fixRepositoryField', + 'fixDependencies', + 'devDependencies', + 'scriptpath', + ]) + + static normalizeSteps = Object.freeze([ + '_id', + '_attributes', + 'bundledDependencies', + 'bundleDependencies', + 'optionalDedupe', + 'scripts', + 'funding', + 'bin', + 'binDir', + ]) + + static prepareSteps = Object.freeze([ + '_id', + '_attributes', + 'bundledDependencies', + 'bundleDependencies', + 'bundleDependenciesDeleteFalse', + 'gypfile', + 'serverjs', + 'scriptpath', + 'authors', + 'readme', + 'mans', + 'binDir', + 'gitHead', + 'fillTypes', + 'normalizeData', + 'binRefs', + ]) - constructor (path) { - this[_filename] = resolve(path, 'package.json') - this[_manifest] = {} - this[_readFileContent] = '' + // create a new empty package.json, so we can save at the given path even + // though we didn't start from a parsed file + static async create (path, opts = {}) { + const p = new PackageJson() + await p.create(path) + if (opts.data) { + return p.update(opts.data) + } + return p } - async load () { + // Loads a package.json at given path and JSON parses + static async load (path, opts = {}) { + const p = new PackageJson() + // Avoid try/catch if we aren't going to create + if (!opts.create) { + return p.load(path) + } + try { - this[_readFileContent] = - await readFile(this[_filename], 'utf8') + return await p.load(path) } catch (err) { - throw new Error('package.json not found') + if (!err.message.startsWith('Could not read package.json')) { + throw err + } + return await p.create(path) } + } + + // npm pkg fix + static async fix (path, opts) { + const p = new PackageJson() + await p.load(path, true) + return p.fix(opts) + } + + // read-package-json compatible behavior + static async prepare (path, opts) { + const p = new PackageJson() + await p.load(path, true) + return p.prepare(opts) + } + + // read-package-json-fast compatible behavior + static async normalize (path, opts) { + const p = new PackageJson() + await p.load(path) + return p.normalize(opts) + } + + #path + #manifest + #readFileContent = '' + #canSave = true + // Load content from given path + async load (path, parseIndex) { + this.#path = path + let parseErr try { - this[_manifest] = - parseJSON(this[_readFileContent]) + this.#readFileContent = await read(this.filename) } catch (err) { - throw new Error(`Invalid package.json: ${err}`) + if (!parseIndex) { + throw err + } + parseErr = err + } + + if (parseErr) { + const indexFile = resolve(this.path, 'index.js') + let indexFileContent + try { + indexFileContent = await readFile(indexFile, 'utf8') + } catch (err) { + throw parseErr + } + try { + this.fromComment(indexFileContent) + } catch (err) { + throw parseErr + } + // This wasn't a package.json so prevent saving + this.#canSave = false + return this + } + + return this.fromJSON(this.#readFileContent) + } + + // Load data from a JSON string/buffer + fromJSON (data) { + this.#manifest = parse(data) + return this + } + + // Manually set data from an existing object + fromContent (data) { + if (!data || typeof data !== 'object') { + throw new Error('Content data must be an object') } + this.#manifest = data + this.#canSave = false + return this + } + + // Load data from a comment + // /**package { "name": "foo", "version": "1.2.3", ... } **/ + fromComment (data) { + data = data.split(/^\/\*\*package(?:\s|$)/m) + + if (data.length < 2) { + throw new Error('File has no package in comments') + } + data = data[1] + data = data.split(/\*\*\/$/m) + + if (data.length < 2) { + throw new Error('File has no package in comments') + } + data = data[0] + data = data.replace(/^\s*\*/mg, '') + this.#manifest = parseJSON(data) return this } get content () { - return this[_manifest] + return this.#manifest + } + + get path () { + return this.#path + } + + get filename () { + if (this.path) { + return resolve(this.path, 'package.json') + } + return undefined } + create (path) { + this.#path = path + this.#manifest = {} + return this + } + + // This should be the ONLY way to set content in the manifest update (content) { - // validates both current manifest and content param - const invalidContent = - typeof this[_manifest] !== 'object' - || typeof content !== 'object' - if (invalidContent) { - throw Object.assign( - new Error(`Can't update invalid package.json data`), - { code: 'EPACKAGEJSONUPDATE' } - ) + if (!this.content) { + throw new Error('Can not update without content. Please `load` or `create`') } for (const step of knownSteps) { - this[_manifest] = step({ content, originalContent: this[_manifest] }) + this.#manifest = step({ content, originalContent: this.content }) } - // unknown properties will just be overwitten + // unknown properties will just be overwritten for (const [key, value] of Object.entries(content)) { if (!knownKeys.has(key)) { - this[_manifest][key] = value + this.content[key] = value } } return this } - async save () { + async save ({ sort } = {}) { + if (!this.#canSave) { + throw new Error('No package.json to save to') + } const { [Symbol.for('indent')]: indent, [Symbol.for('newline')]: newline, - } = this[_manifest] + ...rest + } = this.content const format = indent === undefined ? ' ' : indent const eol = newline === undefined ? '\n' : newline + + const content = sort ? packageSort(rest) : rest + const fileContent = `${ - JSON.stringify(this[_manifest], null, format) + JSON.stringify(content, null, format) }\n` .replace(/\n/g, eol) - if (fileContent.trim() !== this[_readFileContent].trim()) { - return await writeFile(this[_filename], fileContent) + if (fileContent.trim() !== this.#readFileContent.trim()) { + const written = await writeFile(this.filename, fileContent) + this.#readFileContent = fileContent + return written + } + } + + // steps is NOT overrideable here because this is a legacy function that's not being used in new places + syncNormalize (opts = {}) { + opts.steps = this.constructor.normalizeSteps.filter(s => s !== '_attributes') + syncNormalize(this, opts) + return this + } + + async normalize (opts = {}) { + if (!opts.steps) { + opts.steps = this.constructor.normalizeSteps } + await normalize(this, opts) + return this + } + + async prepare (opts = {}) { + if (!opts.steps) { + opts.steps = this.constructor.prepareSteps + } + await normalize(this, opts) + return this + } + + async fix (opts = {}) { + // This one is not overridable + opts.steps = this.constructor.fixSteps + await normalize(this, opts) + return this } } diff --git a/node_modules/@npmcli/package-json/lib/normalize-data.js b/node_modules/@npmcli/package-json/lib/normalize-data.js new file mode 100644 index 0000000000000..1c1a36984c5e9 --- /dev/null +++ b/node_modules/@npmcli/package-json/lib/normalize-data.js @@ -0,0 +1,254 @@ +// Originally normalize-package-data + +const { URL } = require('node:url') +const hostedGitInfo = require('hosted-git-info') +const validateLicense = require('validate-npm-package-license') + +const typos = { + dependancies: 'dependencies', + dependecies: 'dependencies', + depdenencies: 'dependencies', + devEependencies: 'devDependencies', + depends: 'dependencies', + 'dev-dependencies': 'devDependencies', + devDependences: 'devDependencies', + devDepenencies: 'devDependencies', + devdependencies: 'devDependencies', + repostitory: 'repository', + repo: 'repository', + prefereGlobal: 'preferGlobal', + hompage: 'homepage', + hampage: 'homepage', + autohr: 'author', + autor: 'author', + contributers: 'contributors', + publicationConfig: 'publishConfig', + script: 'scripts', +} + +const isEmail = str => str.includes('@') && (str.indexOf('@') < str.lastIndexOf('.')) + +// Extracts description from contents of a readme file in markdown format +function extractDescription (description) { + // the first block of text before the first heading that isn't the first line heading + const lines = description.trim().split('\n') + let start = 0 + // skip initial empty lines and lines that start with # + while (lines[start]?.trim().match(/^(#|$)/)) { + start++ + } + let end = start + 1 + // keep going till we get to the end or an empty line + while (end < lines.length && lines[end].trim()) { + end++ + } + return lines.slice(start, end).join(' ').trim() +} + +function stringifyPerson (person) { + if (typeof person !== 'string') { + const name = person.name || '' + const u = person.url || person.web + const wrappedUrl = u ? (' (' + u + ')') : '' + const e = person.email || person.mail + const wrappedEmail = e ? (' <' + e + '>') : '' + person = name + wrappedEmail + wrappedUrl + } + const matchedName = person.match(/^([^(<]+)/) + const matchedUrl = person.match(/\(([^()]+)\)/) + const matchedEmail = person.match(/<([^<>]+)>/) + const parsed = {} + if (matchedName?.[0].trim()) { + parsed.name = matchedName[0].trim() + } + if (matchedEmail) { + parsed.email = matchedEmail[1] + } + if (matchedUrl) { + parsed.url = matchedUrl[1] + } + return parsed +} + +function normalizeData (data, changes) { + // fixDescriptionField + if (data.description && typeof data.description !== 'string') { + changes?.push(`'description' field should be a string`) + delete data.description + } + if (data.readme && !data.description && data.readme !== 'ERROR: No README data found!') { + data.description = extractDescription(data.readme) + } + if (data.description === undefined) { + delete data.description + } + if (!data.description) { + changes?.push('No description') + } + + // fixModulesField + if (data.modules) { + changes?.push(`modules field is deprecated`) + delete data.modules + } + + // fixFilesField + const files = data.files + if (files && !Array.isArray(files)) { + changes?.push(`Invalid 'files' member`) + delete data.files + } else if (data.files) { + data.files = data.files.filter(function (file) { + if (!file || typeof file !== 'string') { + changes?.push(`Invalid filename in 'files' list: ${file}`) + return false + } else { + return true + } + }) + } + + // fixManField + if (data.man && typeof data.man === 'string') { + data.man = [data.man] + } + + // fixBugsField + if (!data.bugs && data.repository?.url) { + const hosted = hostedGitInfo.fromUrl(data.repository.url) + if (hosted && hosted.bugs()) { + data.bugs = { url: hosted.bugs() } + } + } else if (data.bugs) { + if (typeof data.bugs === 'string') { + if (isEmail(data.bugs)) { + data.bugs = { email: data.bugs } + } else if (URL.canParse(data.bugs)) { + data.bugs = { url: data.bugs } + } else { + changes?.push(`Bug string field must be url, email, or {email,url}`) + } + } else { + for (const k in data.bugs) { + if (['web', 'name'].includes(k)) { + changes?.push(`bugs['${k}'] should probably be bugs['url'].`) + data.bugs.url = data.bugs[k] + delete data.bugs[k] + } + } + const oldBugs = data.bugs + data.bugs = {} + if (oldBugs.url) { + if (URL.canParse(oldBugs.url)) { + data.bugs.url = oldBugs.url + } else { + changes?.push('bugs.url field must be a string url. Deleted.') + } + } + if (oldBugs.email) { + if (typeof (oldBugs.email) === 'string' && isEmail(oldBugs.email)) { + data.bugs.email = oldBugs.email + } else { + changes?.push('bugs.email field must be a string email. Deleted.') + } + } + } + if (!data.bugs.email && !data.bugs.url) { + delete data.bugs + changes?.push('Normalized value of bugs field is an empty object. Deleted.') + } + } + // fixKeywordsField + if (typeof data.keywords === 'string') { + data.keywords = data.keywords.split(/,\s+/) + } + if (data.keywords && !Array.isArray(data.keywords)) { + delete data.keywords + changes?.push(`keywords should be an array of strings`) + } else if (data.keywords) { + data.keywords = data.keywords.filter(function (kw) { + if (typeof kw !== 'string' || !kw) { + changes?.push(`keywords should be an array of strings`) + return false + } else { + return true + } + }) + } + // fixBundleDependenciesField + const bdd = 'bundledDependencies' + const bd = 'bundleDependencies' + if (data[bdd] && !data[bd]) { + data[bd] = data[bdd] + delete data[bdd] + } + if (data[bd] && !Array.isArray(data[bd])) { + changes?.push(`Invalid 'bundleDependencies' list. Must be array of package names`) + delete data[bd] + } else if (data[bd]) { + data[bd] = data[bd].filter(function (filtered) { + if (!filtered || typeof filtered !== 'string') { + changes?.push(`Invalid bundleDependencies member: ${filtered}`) + return false + } else { + if (!data.dependencies) { + data.dependencies = {} + } + if (!Object.prototype.hasOwnProperty.call(data.dependencies, filtered)) { + changes?.push(`Non-dependency in bundleDependencies: ${filtered}`) + data.dependencies[filtered] = '*' + } + return true + } + }) + } + // fixHomepageField + if (!data.homepage && data.repository && data.repository.url) { + const hosted = hostedGitInfo.fromUrl(data.repository.url) + if (hosted) { + data.homepage = hosted.docs() + } + } + if (data.homepage) { + if (typeof data.homepage !== 'string') { + changes?.push('homepage field must be a string url. Deleted.') + delete data.homepage + } else { + if (!URL.canParse(data.homepage)) { + data.homepage = 'http://' + data.homepage + } + } + } + // fixReadmeField + if (!data.readme) { + changes?.push('No README data') + data.readme = 'ERROR: No README data found!' + } + // fixLicenseField + const license = data.license || data.licence + if (!license) { + changes?.push('No license field.') + } else if (typeof (license) !== 'string' || license.length < 1 || license.trim() === '') { + changes?.push('license should be a valid SPDX license expression') + } else if (!validateLicense(license).validForNewPackages) { + changes?.push('license should be a valid SPDX license expression') + } + // fixPeople + if (data.author) { + data.author = stringifyPerson(data.author) + } + ['maintainers', 'contributors'].forEach(function (set) { + if (!Array.isArray(data[set])) { + return + } + data[set] = data[set].map(stringifyPerson) + }) + // fixTypos + for (const d in typos) { + if (Object.prototype.hasOwnProperty.call(data, d)) { + changes?.push(`${d} should probably be ${typos[d]}.`) + } + } +} + +module.exports = { normalizeData } diff --git a/node_modules/@npmcli/package-json/lib/normalize.js b/node_modules/@npmcli/package-json/lib/normalize.js new file mode 100644 index 0000000000000..0388220ccefed --- /dev/null +++ b/node_modules/@npmcli/package-json/lib/normalize.js @@ -0,0 +1,614 @@ +const valid = require('semver/functions/valid') +const clean = require('semver/functions/clean') +const fs = require('node:fs/promises') +const path = require('node:path') +const { log } = require('proc-log') +const moduleBuiltin = require('node:module') + +/** + * @type {import('hosted-git-info')} + */ +let _hostedGitInfo +function lazyHostedGitInfo () { + if (!_hostedGitInfo) { + _hostedGitInfo = require('hosted-git-info') + } + return _hostedGitInfo +} + +/** + * @type {import('glob').glob} + */ +let _glob +function lazyLoadGlob () { + if (!_glob) { + _glob = require('glob').glob + } + return _glob +} + +// used to be npm-normalize-package-bin +function normalizePackageBin (pkg, changes) { + if (pkg.bin) { + if (typeof pkg.bin === 'string' && pkg.name) { + changes?.push('"bin" was converted to an object') + pkg.bin = { [pkg.name]: pkg.bin } + } else if (Array.isArray(pkg.bin)) { + changes?.push('"bin" was converted to an object') + pkg.bin = pkg.bin.reduce((acc, k) => { + acc[path.basename(k)] = k + return acc + }, {}) + } + if (typeof pkg.bin === 'object') { + for (const binKey in pkg.bin) { + if (typeof pkg.bin[binKey] !== 'string') { + delete pkg.bin[binKey] + changes?.push(`removed invalid "bin[${binKey}]"`) + continue + } + const base = path.basename(secureAndUnixifyPath(binKey)) + if (!base) { + delete pkg.bin[binKey] + changes?.push(`removed invalid "bin[${binKey}]"`) + continue + } + + const binTarget = secureAndUnixifyPath(pkg.bin[binKey]) + + if (!binTarget) { + delete pkg.bin[binKey] + changes?.push(`removed invalid "bin[${binKey}]"`) + continue + } + + if (base !== binKey) { + delete pkg.bin[binKey] + changes?.push(`"bin[${binKey}]" was renamed to "bin[${base}]"`) + } + if (binTarget !== pkg.bin[binKey]) { + changes?.push(`"bin[${base}]" script name ${binTarget} was invalid and removed`) + } + pkg.bin[base] = binTarget + } + + if (Object.keys(pkg.bin).length === 0) { + changes?.push('empty "bin" was removed') + delete pkg.bin + } + + return pkg + } + } + delete pkg.bin +} + +function normalizePackageMan (pkg, changes) { + if (pkg.man) { + const mans = [] + for (const man of (Array.isArray(pkg.man) ? pkg.man : [pkg.man])) { + if (typeof man !== 'string') { + changes?.push(`removed invalid "man [${man}]"`) + } else { + mans.push(secureAndUnixifyPath(man)) + } + } + + if (!mans.length) { + changes?.push('empty "man" was removed') + } else { + pkg.man = mans + return pkg + } + } + delete pkg.man +} + +function isCorrectlyEncodedName (spec) { + return !spec.match(/[/@\s+%:]/) && + spec === encodeURIComponent(spec) +} + +function isValidScopedPackageName (spec) { + if (spec.charAt(0) !== '@') { + return false + } + + const rest = spec.slice(1).split('/') + if (rest.length !== 2) { + return false + } + + return rest[0] && rest[1] && + rest[0] === encodeURIComponent(rest[0]) && + rest[1] === encodeURIComponent(rest[1]) +} + +function unixifyPath (ref) { + return ref.replace(/\\|:/g, '/') +} + +function secureAndUnixifyPath (ref) { + const secured = unixifyPath(path.join('.', path.join('/', unixifyPath(ref)))) + return secured.startsWith('./') ? '' : secured +} + +// Only steps that can be ran synchronously. There are some object constructors (i.e. Aborist Node) that need synchronous normalization so here we are. +function syncSteps (pkg, { strict, steps, changes, allowLegacyCase }) { + const data = pkg.content + const pkgId = `${data.name ?? ''}@${data.version ?? ''}` + + // name and version are load bearing so we have to clean them up first + if (steps.includes('fixName') || steps.includes('fixNameField') || steps.includes('normalizeData')) { + if (!data.name && !strict) { + changes?.push('Missing "name" field was set to an empty string') + data.name = '' + } else { + if (typeof data.name !== 'string') { + throw new Error('name field must be a string.') + } + if (!strict) { + const name = data.name.trim() + if (data.name !== name) { + changes?.push(`Whitespace was trimmed from "name"`) + data.name = name + } + } + + if (data.name.startsWith('.') || + !(isValidScopedPackageName(data.name) || isCorrectlyEncodedName(data.name)) || + (strict && (!allowLegacyCase) && data.name !== data.name.toLowerCase()) || + data.name.toLowerCase() === 'node_modules' || + data.name.toLowerCase() === 'favicon.ico') { + throw new Error('Invalid name: ' + JSON.stringify(data.name)) + } + } + } + + if (steps.includes('fixName')) { + // Check for conflicts with builtin modules + if (moduleBuiltin.builtinModules.includes(data.name)) { + log.warn('package-json', pkgId, `Package name "${data.name}" conflicts with a Node.js built-in module name`) + } + } + + if (steps.includes('fixVersionField') || steps.includes('normalizeData')) { + // allow "loose" semver 1.0 versions in non-strict mode + // enforce strict semver 2.0 compliance in strict mode + const loose = !strict + if (!data.version) { + data.version = '' + } else { + if (!valid(data.version, loose)) { + throw new Error(`Invalid version: "${data.version}"`) + } + const version = clean(data.version, loose) + if (version !== data.version) { + changes?.push(`"version" was cleaned and set to "${version}"`) + data.version = version + } + } + } + + // remove attributes that start with "_" + if (steps.includes('_attributes')) { + for (const key in data) { + if (key.startsWith('_')) { + changes?.push(`"${key}" was removed`) + delete pkg.content[key] + } + } + } + + // build the "_id" attribute + if (steps.includes('_id')) { + if (data.name && data.version) { + changes?.push(`"_id" was set to ${pkgId}`) + data._id = pkgId + } + } + + // fix bundledDependencies typo + if (steps.includes('bundledDependencies')) { + if (data.bundleDependencies === undefined && data.bundledDependencies !== undefined) { + data.bundleDependencies = data.bundledDependencies + changes?.push(`Deleted incorrect "bundledDependencies"`) + } + delete data.bundledDependencies + } + + // expand "bundleDependencies: true or translate from object" + if (steps.includes('bundleDependencies')) { + const bd = data.bundleDependencies + if (bd === false && !steps.includes('bundleDependenciesDeleteFalse')) { + changes?.push(`"bundleDependencies" was changed from "false" to "[]"`) + data.bundleDependencies = [] + } else if (bd === true) { + changes?.push(`"bundleDependencies" was auto-populated from "dependencies"`) + data.bundleDependencies = Object.keys(data.dependencies || {}) + } else if (bd && typeof bd === 'object') { + if (!Array.isArray(bd)) { + changes?.push(`"bundleDependencies" was changed from an object to an array`) + data.bundleDependencies = Object.keys(bd) + } + } else if ('bundleDependencies' in data) { + changes?.push(`"bundleDependencies" was removed`) + delete data.bundleDependencies + } + } + + // it was once common practice to list deps both in optionalDependencies and + // in dependencies, to support npm versions that did not know about + // optionalDependencies. This is no longer a relevant need, so duplicating + // the deps in two places is unnecessary and excessive. + if (steps.includes('optionalDedupe')) { + if (data.dependencies && + data.optionalDependencies && typeof data.optionalDependencies === 'object') { + for (const name in data.optionalDependencies) { + changes?.push(`optionalDependencies."${name}" was removed`) + delete data.dependencies[name] + } + if (!Object.keys(data.dependencies).length) { + changes?.push(`Empty "optionalDependencies" was removed`) + delete data.dependencies + } + } + } + + // strip "node_modules/.bin" from scripts entries + // remove invalid scripts entries (non-strings) + if ((steps.includes('scripts') || steps.includes('scriptpath')) && data.scripts !== undefined) { + const spre = /^(\.[/\\])?node_modules[/\\].bin[\\/]/ + if (typeof data.scripts === 'object') { + for (const name in data.scripts) { + if (typeof data.scripts[name] !== 'string') { + delete data.scripts[name] + changes?.push(`Invalid scripts."${name}" was removed`) + } else if (steps.includes('scriptpath') && spre.test(data.scripts[name])) { + data.scripts[name] = data.scripts[name].replace(spre, '') + changes?.push(`scripts entry "${name}" was fixed to remove node_modules/.bin reference`) + } + } + } else { + changes?.push(`Removed invalid "scripts"`) + delete data.scripts + } + } + + if (steps.includes('funding')) { + if (data.funding && typeof data.funding === 'string') { + data.funding = { url: data.funding } + changes?.push(`"funding" was changed to an object with a url attribute`) + } + } + + // "normalizeData" from "read-package-json", which was just a call through to + // "normalize-package-data". We only call the "fixer" functions because + // outside of that it was also clobbering _id (which we already conditionally + // do) and also adding the gypfile script (which we also already + // conditionally do) + + // Some steps are isolated so we can do a limited subset of these in `fix` + if (steps.includes('fixRepositoryField') || steps.includes('normalizeData')) { + if (data.repositories) { + changes?.push(`"repository" was set to the first entry in "repositories" (${data.repository})`) + data.repository = data.repositories[0] + } + if (data.repository) { + if (typeof data.repository === 'string') { + changes?.push('"repository" was changed from a string to an object') + data.repository = { + type: 'git', + url: data.repository, + } + } + if (data.repository.url) { + const hosted = lazyHostedGitInfo().fromUrl(data.repository.url) + let r + if (hosted) { + if (hosted.getDefaultRepresentation() === 'shortcut') { + r = hosted.https() + } else { + r = hosted.toString() + } + if (r !== data.repository.url) { + changes?.push(`"repository.url" was normalized to "${r}"`) + data.repository.url = r + } + } + } + } + } + + if (steps.includes('fixDependencies') || steps.includes('normalizeData')) { + // peerDependencies? + // devDependencies is meaningless here, it's ignored on an installed package + for (const type of ['dependencies', 'devDependencies', 'optionalDependencies']) { + if (data[type]) { + let secondWarning = true + if (typeof data[type] === 'string') { + changes?.push(`"${type}" was converted from a string into an object`) + data[type] = data[type].trim().split(/[\n\r\s\t ,]+/) + secondWarning = false + } + if (Array.isArray(data[type])) { + if (secondWarning) { + changes?.push(`"${type}" was converted from an array into an object`) + } + const o = {} + for (const d of data[type]) { + if (typeof d === 'string') { + const dep = d.trim().split(/(:?[@\s><=])/) + const dn = dep.shift() + const dv = dep.join('').replace(/^@/, '').trim() + o[dn] = dv + } + } + data[type] = o + } + } + } + // normalize-package-data used to put optional dependencies BACK into + // dependencies here, we no longer do this + + for (const deps of ['dependencies', 'devDependencies']) { + if (deps in data) { + if (!data[deps] || typeof data[deps] !== 'object') { + changes?.push(`Removed invalid "${deps}"`) + delete data[deps] + } else { + for (const d in data[deps]) { + const r = data[deps][d] + if (typeof r !== 'string') { + changes?.push(`Removed invalid "${deps}.${d}"`) + delete data[deps][d] + } + const hosted = lazyHostedGitInfo().fromUrl(data[deps][d])?.toString() + if (hosted && hosted !== data[deps][d]) { + changes?.push(`Normalized git reference to "${deps}.${d}"`) + data[deps][d] = hosted.toString() + } + } + } + } + } + } + + // TODO some of this is duplicated in other steps here, a future breaking change may be able to remove the duplicates involved in this step + if (steps.includes('normalizeData')) { + const { normalizeData } = require('./normalize-data.js') + normalizeData(data, changes) + } +} + +// Steps that require await, distinct from sync-steps.js +async function asyncSteps (pkg, { steps, root, changes }) { + const data = pkg.content + const scripts = data.scripts || {} + const pkgId = `${data.name ?? ''}@${data.version ?? ''}` + + // add "install" attribute if any "*.gyp" files exist + if (steps.includes('gypfile')) { + if (!scripts.install && !scripts.preinstall && data.gypfile !== false) { + const files = await lazyLoadGlob()('*.gyp', { cwd: pkg.path }) + if (files.length) { + scripts.install = 'node-gyp rebuild' + data.scripts = scripts + data.gypfile = true + changes?.push(`"scripts.install" was set to "node-gyp rebuild"`) + changes?.push(`"gypfile" was set to "true"`) + } + } + } + + // add "start" attribute if "server.js" exists + if (steps.includes('serverjs') && !scripts.start) { + try { + await fs.access(path.join(pkg.path, 'server.js')) + scripts.start = 'node server.js' + data.scripts = scripts + changes?.push('"scripts.start" was set to "node server.js"') + } catch { + // do nothing + } + } + + // populate "authors" attribute + if (steps.includes('authors') && !data.contributors) { + try { + const authorData = await fs.readFile(path.join(pkg.path, 'AUTHORS'), 'utf8') + const authors = authorData.split(/\r?\n/g) + .map(line => line.replace(/^\s*#.*$/, '').trim()) + .filter(line => line) + data.contributors = authors + changes?.push('"contributors" was auto-populated with the contents of the "AUTHORS" file') + } catch { + // do nothing + } + } + + // populate "readme" attribute + if (steps.includes('readme') && !data.readme) { + const mdre = /\.m?a?r?k?d?o?w?n?$/i + const files = await lazyLoadGlob()('{README,README.*}', { + cwd: pkg.path, + nocase: true, + mark: true, + }) + let readmeFile + for (const file of files) { + // don't accept directories. + if (!file.endsWith(path.sep)) { + if (file.match(mdre)) { + readmeFile = file + break + } + if (file.endsWith('README')) { + readmeFile = file + } + } + } + if (readmeFile) { + const readmeData = await fs.readFile(path.join(pkg.path, readmeFile), 'utf8') + data.readme = readmeData + data.readmeFilename = readmeFile + changes?.push(`"readme" was set to the contents of ${readmeFile}`) + changes?.push(`"readmeFilename" was set to ${readmeFile}`) + } + if (!data.readme) { + data.readme = 'ERROR: No README data found!' + } + } + + // expand directories.man + if (steps.includes('mans')) { + if (data.directories?.man && !data.man) { + const manDir = secureAndUnixifyPath(data.directories.man) + const cwd = path.resolve(pkg.path, manDir) + const files = await lazyLoadGlob()('**/*.[0-9]', { cwd }) + data.man = files.map(man => + path.relative(pkg.path, path.join(cwd, man)).split(path.sep).join('/') + ) + } + normalizePackageMan(data, changes) + } + + // expand "directories.bin" + if (steps.includes('binDir') && data.directories?.bin && !data.bin && pkg.path) { + const binPath = secureAndUnixifyPath(data.directories.bin) + const bins = await lazyLoadGlob()('**', { cwd: path.resolve(pkg.path, binPath) }) + data.bin = bins.reduce((acc, binFile) => { + if (binFile && !binFile.startsWith('.')) { + const binName = path.basename(binFile) + // binPath is already cleaned and unixified, no need to path.join here. + acc[binName] = `${binPath}/${secureAndUnixifyPath(binFile)}` + } + return acc + }, {}) + } else if (steps.includes('bin') || steps.includes('binDir') || steps.includes('binRefs')) { + normalizePackageBin(data, changes) + } + + // populate "gitHead" attribute + if (steps.includes('gitHead') && !data.gitHead) { + const git = require('@npmcli/git') + const gitRoot = await git.find({ cwd: pkg.path, root }) + let head + if (gitRoot) { + try { + head = await fs.readFile(path.resolve(gitRoot, '.git/HEAD'), 'utf8') + } catch (err) { + // do nothing + } + } + let headData + if (head) { + if (head.startsWith('ref: ')) { + const headRef = head.replace(/^ref: /, '').trim() + const headFile = path.resolve(gitRoot, '.git', headRef) + try { + headData = await fs.readFile(headFile, 'utf8') + headData = headData.replace(/^ref: /, '').trim() + } catch (err) { + // do nothing + } + if (!headData) { + const packFile = path.resolve(gitRoot, '.git/packed-refs') + try { + let refs = await fs.readFile(packFile, 'utf8') + if (refs) { + refs = refs.split('\n') + for (let i = 0; i < refs.length; i++) { + const match = refs[i].match(/^([0-9a-f]{40}) (.+)$/) + if (match && match[2].trim() === headRef) { + headData = match[1] + break + } + } + } + } catch { + // do nothing + } + } + } else { + headData = head.trim() + } + } + if (headData) { + data.gitHead = headData + } + } + + // populate "types" attribute + if (steps.includes('fillTypes')) { + const index = data.main || 'index.js' + + if (typeof index !== 'string') { + throw 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') { + // } + // } + const extless = path.join(path.dirname(index), path.basename(index, path.extname(index))) + const dts = `./${extless}.d.ts` + const hasDTSFields = 'types' in data || 'typings' in data + if (!hasDTSFields) { + try { + await fs.access(path.join(pkg.path, dts)) + data.types = dts.split(path.sep).join('/') + } catch { + // do nothing + } + } + } + + // 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. + if (steps.includes('binRefs') && data.bin instanceof Object) { + for (const key in data.bin) { + try { + await fs.access(path.resolve(pkg.path, data.bin[key])) + } catch { + log.warn('package-json', pkgId, `No bin file found at ${data.bin[key]}`) + // XXX: should a future breaking change delete bin entries that cannot be accessed? + } + } + } +} + +// We don't want the `changes` array in here by default because this is a hot path for parsing packuments during install. The calling method passes it in if it wants to track changes. +async function normalize (pkg, opts) { + if (!pkg.content) { + throw new Error('Can not normalize without content') + } + await asyncSteps(pkg, opts) + // the normalizeData part of this needs to be the last thing ran, so sync comes second + syncSteps(pkg, opts) +} + +function syncNormalize (pkg, opts) { + syncSteps(pkg, opts) +} + +module.exports = { normalize, syncNormalize } diff --git a/node_modules/@npmcli/package-json/lib/read-package.js b/node_modules/@npmcli/package-json/lib/read-package.js new file mode 100644 index 0000000000000..d6c86ce388e6c --- /dev/null +++ b/node_modules/@npmcli/package-json/lib/read-package.js @@ -0,0 +1,39 @@ +// This is JUST the code needed to open a package.json file and parse it. +// It's isolated out so that code needing to parse a package.json file can do so in the same way as this module does, without needing to require the whole module, or needing to require the underlying parsing library. + +const { readFile } = require('fs/promises') +const parseJSON = require('json-parse-even-better-errors') + +async function read (filename) { + try { + const data = await readFile(filename, 'utf8') + return data + } catch (err) { + err.message = `Could not read package.json: ${err}` + throw err + } +} + +function parse (data) { + try { + const content = parseJSON(data) + return content + } catch (err) { + err.message = `Invalid package.json: ${err}` + throw err + } +} + +// This is what most external libs will use. +// PackageJson will call read and parse separately +async function readPackage (filename) { + const data = await read(filename) + const content = parse(data) + return content +} + +module.exports = { + read, + parse, + readPackage, +} diff --git a/node_modules/@npmcli/package-json/lib/sort.js b/node_modules/@npmcli/package-json/lib/sort.js new file mode 100644 index 0000000000000..0bd0d5199da58 --- /dev/null +++ b/node_modules/@npmcli/package-json/lib/sort.js @@ -0,0 +1,101 @@ +/** + * arbitrary sort order for package.json largely pulled from: + * https://github.com/keithamus/sort-package-json/blob/main/defaultRules.md + * + * cross checked with: + * https://github.com/npm/types/blob/main/types/index.d.ts#L104 + * https://docs.npmjs.com/cli/configuring-npm/package-json + */ +function packageSort (json) { + const { + name, + version, + private: isPrivate, + description, + keywords, + homepage, + bugs, + repository, + funding, + license, + author, + maintainers, + contributors, + type, + imports, + exports, + main, + browser, + types, + bin, + man, + directories, + files, + workspaces, + scripts, + config, + dependencies, + devDependencies, + peerDependencies, + peerDependenciesMeta, + optionalDependencies, + bundledDependencies, + bundleDependencies, + engines, + os, + cpu, + publishConfig, + devEngines, + licenses, + overrides, + ...rest + } = json + + return { + ...(typeof name !== 'undefined' ? { name } : {}), + ...(typeof version !== 'undefined' ? { version } : {}), + ...(typeof isPrivate !== 'undefined' ? { private: isPrivate } : {}), + ...(typeof description !== 'undefined' ? { description } : {}), + ...(typeof keywords !== 'undefined' ? { keywords } : {}), + ...(typeof homepage !== 'undefined' ? { homepage } : {}), + ...(typeof bugs !== 'undefined' ? { bugs } : {}), + ...(typeof repository !== 'undefined' ? { repository } : {}), + ...(typeof funding !== 'undefined' ? { funding } : {}), + ...(typeof license !== 'undefined' ? { license } : {}), + ...(typeof author !== 'undefined' ? { author } : {}), + ...(typeof maintainers !== 'undefined' ? { maintainers } : {}), + ...(typeof contributors !== 'undefined' ? { contributors } : {}), + ...(typeof type !== 'undefined' ? { type } : {}), + ...(typeof imports !== 'undefined' ? { imports } : {}), + ...(typeof exports !== 'undefined' ? { exports } : {}), + ...(typeof main !== 'undefined' ? { main } : {}), + ...(typeof browser !== 'undefined' ? { browser } : {}), + ...(typeof types !== 'undefined' ? { types } : {}), + ...(typeof bin !== 'undefined' ? { bin } : {}), + ...(typeof man !== 'undefined' ? { man } : {}), + ...(typeof directories !== 'undefined' ? { directories } : {}), + ...(typeof files !== 'undefined' ? { files } : {}), + ...(typeof workspaces !== 'undefined' ? { workspaces } : {}), + ...(typeof scripts !== 'undefined' ? { scripts } : {}), + ...(typeof config !== 'undefined' ? { config } : {}), + ...(typeof dependencies !== 'undefined' ? { dependencies } : {}), + ...(typeof devDependencies !== 'undefined' ? { devDependencies } : {}), + ...(typeof peerDependencies !== 'undefined' ? { peerDependencies } : {}), + ...(typeof peerDependenciesMeta !== 'undefined' ? { peerDependenciesMeta } : {}), + ...(typeof optionalDependencies !== 'undefined' ? { optionalDependencies } : {}), + ...(typeof bundledDependencies !== 'undefined' ? { bundledDependencies } : {}), + ...(typeof bundleDependencies !== 'undefined' ? { bundleDependencies } : {}), + ...(typeof engines !== 'undefined' ? { engines } : {}), + ...(typeof os !== 'undefined' ? { os } : {}), + ...(typeof cpu !== 'undefined' ? { cpu } : {}), + ...(typeof publishConfig !== 'undefined' ? { publishConfig } : {}), + ...(typeof devEngines !== 'undefined' ? { devEngines } : {}), + ...(typeof licenses !== 'undefined' ? { licenses } : {}), + ...(typeof overrides !== 'undefined' ? { overrides } : {}), + ...rest, + } +} + +module.exports = { + packageSort, +} diff --git a/node_modules/@npmcli/package-json/package.json b/node_modules/@npmcli/package-json/package.json index d2c4b9da9db62..31aa68a6654dc 100644 --- a/node_modules/@npmcli/package-json/package.json +++ b/node_modules/@npmcli/package-json/package.json @@ -1,48 +1,59 @@ { "name": "@npmcli/package-json", - "version": "2.0.0", + "version": "7.0.4", "description": "Programmatic API to update package.json", + "keywords": [ + "npm", + "oss" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/npm/package-json.git" + }, + "license": "ISC", + "author": "GitHub Inc.", "main": "lib/index.js", "files": [ "bin/", "lib/" ], "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "snap": "tap", "test": "tap", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force" - }, - "keywords": [ - "npm", - "oss" - ], - "author": "GitHub Inc.", - "license": "ISC", - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "tap": "^16.0.1" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "dependencies": { - "json-parse-even-better-errors": "^2.3.1" + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" }, - "repository": { - "type": "git", - "url": "https://github.com/npm/package-json.git" + "devDependencies": { + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", + "tap": "^16.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.28.0", + "publish": "true" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@npmcli/promise-spawn/lib/escape.js b/node_modules/@npmcli/promise-spawn/lib/escape.js new file mode 100644 index 0000000000000..5fab00210f26c --- /dev/null +++ b/node_modules/@npmcli/promise-spawn/lib/escape.js @@ -0,0 +1,67 @@ +'use strict' + +// this code adapted from: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ +const cmd = (input, doubleEscape) => { + if (!input.length) { + return '""' + } + + let result + if (!/[ \t\n\v"]/.test(input)) { + result = input + } else { + result = '"' + for (let i = 0; i <= input.length; ++i) { + let slashCount = 0 + while (input[i] === '\\') { + ++i + ++slashCount + } + + if (i === input.length) { + result += '\\'.repeat(slashCount * 2) + break + } + + if (input[i] === '"') { + result += '\\'.repeat(slashCount * 2 + 1) + result += input[i] + } else { + result += '\\'.repeat(slashCount) + result += input[i] + } + } + result += '"' + } + + // and finally, prefix shell meta chars with a ^ + result = result.replace(/[ !%^&()<>|"]/g, '^$&') + if (doubleEscape) { + result = result.replace(/[ !%^&()<>|"]/g, '^$&') + } + + return result +} + +const sh = (input) => { + if (!input.length) { + return `''` + } + + if (!/[\t\n\r "#$&'()*;<>?\\`|~]/.test(input)) { + return input + } + + // replace single quotes with '\'' and wrap the whole result in a fresh set of quotes + const result = `'${input.replace(/'/g, `'\\''`)}'` + // if the input string already had single quotes around it, clean those up + .replace(/^(?:'')+(?!$)/, '') + .replace(/\\'''/g, `\\'`) + + return result +} + +module.exports = { + cmd, + sh, +} diff --git a/node_modules/@npmcli/promise-spawn/lib/index.js b/node_modules/@npmcli/promise-spawn/lib/index.js index 84ddc83d10bab..1faf62c9157df 100644 --- a/node_modules/@npmcli/promise-spawn/lib/index.js +++ b/node_modules/@npmcli/promise-spawn/lib/index.js @@ -1,75 +1,218 @@ +'use strict' + const { spawn } = require('child_process') -const inferOwner = require('infer-owner') +const os = require('os') +const which = require('which') -const isPipe = (stdio = 'pipe', fd) => - stdio === 'pipe' || stdio === null ? true - : Array.isArray(stdio) ? isPipe(stdio[fd], fd) - : false +const escape = require('./escape.js') // 'extra' object is for decorating the error a bit more const promiseSpawn = (cmd, args, opts = {}, extra = {}) => { - const cwd = opts.cwd || process.cwd() - const isRoot = process.getuid && process.getuid() === 0 - const { uid, gid } = isRoot ? inferOwner.sync(cwd) : {} - return promiseSpawnUid(cmd, args, { - ...opts, - cwd, - uid, - gid, - }, extra) -} + if (opts.shell) { + return spawnWithShell(cmd, args, opts, extra) + } + + let resolve, reject + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve + reject = _reject + }) + + // Create error here so we have a more useful stack trace when rejecting + const closeError = new Error('command failed') -const stdioResult = (stdout, stderr, { stdioString, stdio }) => - stdioString ? { - stdout: isPipe(stdio, 1) ? Buffer.concat(stdout).toString() : null, - stderr: isPipe(stdio, 2) ? Buffer.concat(stderr).toString() : null, + const stdout = [] + const stderr = [] + + const getResult = (result) => ({ + cmd, + args, + ...result, + ...stdioResult(stdout, stderr, opts), + ...extra, + }) + const rejectWithOpts = (er, erOpts) => { + const resultError = getResult(erOpts) + reject(Object.assign(er, resultError)) } - : { - stdout: isPipe(stdio, 1) ? Buffer.concat(stdout) : null, - stderr: isPipe(stdio, 2) ? Buffer.concat(stderr) : null, + + const proc = spawn(cmd, args, opts) + promise.stdin = proc.stdin + promise.process = proc + + proc.on('error', rejectWithOpts) + + if (proc.stdout) { + proc.stdout.on('data', c => stdout.push(c)) + proc.stdout.on('error', rejectWithOpts) } -const promiseSpawnUid = (cmd, args, opts, extra) => { - let proc - const p = new Promise((res, rej) => { - proc = spawn(cmd, args, opts) - const stdout = [] - const stderr = [] - const reject = er => rej(Object.assign(er, { - cmd, - args, - ...stdioResult(stdout, stderr, opts), - ...extra, - })) - proc.on('error', reject) - if (proc.stdout) { - proc.stdout.on('data', c => stdout.push(c)).on('error', reject) - proc.stdout.on('error', er => reject(er)) - } - if (proc.stderr) { - proc.stderr.on('data', c => stderr.push(c)).on('error', reject) - proc.stderr.on('error', er => reject(er)) + if (proc.stderr) { + proc.stderr.on('data', c => stderr.push(c)) + proc.stderr.on('error', rejectWithOpts) + } + + proc.on('close', (code, signal) => { + if (code || signal) { + rejectWithOpts(closeError, { code, signal }) + } else { + resolve(getResult({ code, signal })) } - proc.on('close', (code, signal) => { - const result = { - cmd, - args, - code, - signal, - ...stdioResult(stdout, stderr, opts), - ...extra, + }) + + return promise +} + +const spawnWithShell = (cmd, args, opts, extra) => { + let command = opts.shell + // if shell is set to true, we use a platform default. we can't let the core + // spawn method decide this for us because we need to know what shell is in use + // ahead of time so that we can escape arguments properly. we don't need coverage here. + if (command === true) { + // istanbul ignore next + command = process.platform === 'win32' ? (process.env.ComSpec || 'cmd.exe') : 'sh' + } + + const options = { ...opts, shell: false } + const realArgs = [] + let script = cmd + + // first, determine if we're in windows because if we are we need to know if we're + // running an .exe or a .cmd/.bat since the latter requires extra escaping + const isCmd = /(?:^|\\)cmd(?:\.exe)?$/i.test(command) + if (isCmd) { + let doubleEscape = false + + // find the actual command we're running + let initialCmd = '' + let insideQuotes = false + for (let i = 0; i < cmd.length; ++i) { + const char = cmd.charAt(i) + if (char === ' ' && !insideQuotes) { + break } - if (code || signal) { - rej(Object.assign(new Error('command failed'), result)) - } else { - res(result) + + initialCmd += char + if (char === '"' || char === "'") { + insideQuotes = !insideQuotes } - }) - }) + } + + let pathToInitial + try { + pathToInitial = which.sync(initialCmd, { + path: (options.env && findInObject(options.env, 'PATH')) || process.env.PATH, + pathext: (options.env && findInObject(options.env, 'PATHEXT')) || process.env.PATHEXT, + }).toLowerCase() + } catch (err) { + pathToInitial = initialCmd.toLowerCase() + } + + doubleEscape = pathToInitial.endsWith('.cmd') || pathToInitial.endsWith('.bat') + for (const arg of args) { + script += ` ${escape.cmd(arg, doubleEscape)}` + } + realArgs.push('/d', '/s', '/c', script) + options.windowsVerbatimArguments = true + } else { + for (const arg of args) { + script += ` ${escape.sh(arg)}` + } + realArgs.push('-c', script) + } + + return promiseSpawn(command, realArgs, options, extra) +} + +// open a file with the default application as defined by the user's OS +const open = (_args, opts = {}, extra = {}) => { + const options = { ...opts, shell: true } + const args = [].concat(_args) + + let platform = process.platform + // process.platform === 'linux' may actually indicate WSL, if that's the case + // open the argument with sensible-browser which is pre-installed + // In WSL, set the default browser using, for example, + // export BROWSER="/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" + // or + // export BROWSER="/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" + // To permanently set the default browser, add the appropriate entry to your shell's + // RC file, e.g. .bashrc or .zshrc. + if (platform === 'linux' && os.release().toLowerCase().includes('microsoft')) { + platform = 'wsl' + if (!process.env.BROWSER) { + return Promise.reject( + new Error('Set the BROWSER environment variable to your desired browser.')) + } + } + + let command = options.command + if (!command) { + if (platform === 'win32') { + // spawnWithShell does not do the additional os.release() check, so we + // have to force the shell here to make sure we treat WSL as windows. + options.shell = process.env.ComSpec + // also, the start command accepts a title so to make sure that we don't + // accidentally interpret the first arg as the title, we stick an empty + // string immediately after the start command + command = 'start ""' + } else if (platform === 'wsl') { + command = 'sensible-browser' + } else if (platform === 'darwin') { + command = 'open' + } else { + command = 'xdg-open' + } + } + + return spawnWithShell(command, args, options, extra) +} +promiseSpawn.open = open + +const isPipe = (stdio = 'pipe', fd) => { + if (stdio === 'pipe' || stdio === null) { + return true + } + + if (Array.isArray(stdio)) { + return isPipe(stdio[fd], fd) + } + + return false +} + +const stdioResult = (stdout, stderr, { stdioString = true, stdio }) => { + const result = { + stdout: null, + stderr: null, + } + + // stdio is [stdin, stdout, stderr] + if (isPipe(stdio, 1)) { + result.stdout = Buffer.concat(stdout) + if (stdioString) { + result.stdout = result.stdout.toString().trim() + } + } - p.stdin = proc.stdin - p.process = proc - return p + if (isPipe(stdio, 2)) { + result.stderr = Buffer.concat(stderr) + if (stdioString) { + result.stderr = result.stderr.toString().trim() + } + } + + return result +} + +// case insensitive lookup in an object +const findInObject = (obj, key) => { + key = key.toLowerCase() + for (const objKey of Object.keys(obj).sort()) { + if (objKey.toLowerCase() === key) { + return obj[objKey] + } + } } module.exports = promiseSpawn diff --git a/node_modules/@npmcli/promise-spawn/package.json b/node_modules/@npmcli/promise-spawn/package.json index 4521b56d50560..f00ee324355c8 100644 --- a/node_modules/@npmcli/promise-spawn/package.json +++ b/node_modules/@npmcli/promise-spawn/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/promise-spawn", - "version": "3.0.0", + "version": "9.0.1", "files": [ "bin/", "lib/" @@ -9,40 +9,43 @@ "description": "spawn processes the way the npm cli likes to do", "repository": { "type": "git", - "url": "https://github.com/npm/promise-spawn.git" + "url": "git+https://github.com/npm/promise-spawn.git" }, "author": "GitHub Inc.", "license": "ISC", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "minipass": "^3.1.1", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", + "spawk": "^1.7.1", "tap": "^16.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.28.0", + "publish": true }, "dependencies": { - "infer-owner": "^1.0.4" + "which": "^6.0.0" } } diff --git a/node_modules/@npmcli/query/lib/index.js b/node_modules/@npmcli/query/lib/index.js index 36a8c700caae1..db7dc345a8c75 100644 --- a/node_modules/@npmcli/query/lib/index.js +++ b/node_modules/@npmcli/query/lib/index.js @@ -1,8 +1,6 @@ 'use strict' -const npa = require('npm-package-arg') const parser = require('postcss-selector-parser') -const semver = require('semver') const arrayDelimiter = Symbol('arrayDelimiter') @@ -12,37 +10,6 @@ const escapeSlashes = str => const unescapeSlashes = str => str.replace(/\\\//g, '/') -const fixupIds = astNode => { - const { name, rawSpec: part } = npa(astNode.value) - const versionParts = [{ astNode, part }] - let currentAstNode = astNode.next() - - if (!part) { - return - } - - while (currentAstNode) { - versionParts.push({ astNode: currentAstNode, part: String(currentAstNode) }) - currentAstNode = currentAstNode.next() - } - - let version - let length = versionParts.length - while (!version && length) { - version = - semver.valid( - versionParts.slice(0, length).reduce((res, i) => `${res}${i.part}`, '') - ) - length-- - } - - astNode.value = `${name}@${version}` - - for (let i = 1; i <= length; i++) { - versionParts[i].astNode.remove() - } -} - // recursively fixes up any :attr pseudo-class found const fixupAttr = astNode => { const properties = [] @@ -118,11 +85,65 @@ const fixupNestedPseudo = astNode => { transformAst(newRootNode) } +// :semver(<version|range|selector>, [version|range|selector], [function]) +// note: the first or second parameter must be a static version or range const fixupSemverSpecs = astNode => { - const children = astNode.nodes[0].nodes - const value = children.reduce((res, i) => `${res}${String(i)}`, '') + // if we have three nodes, the last is the semver function to use, pull that out first + if (astNode.nodes.length === 3) { + const funcNode = astNode.nodes.pop().nodes[0] + if (funcNode.type === 'tag') { + astNode.semverFunc = funcNode.value + } else if (funcNode.type === 'string') { + // a string is always in some type of quotes, we don't want those so slice them off + astNode.semverFunc = funcNode.value.slice(1, -1) + } else { + // anything that isn't a tag or a string isn't a function name + throw Object.assign( + new Error('`:semver` pseudo-class expects a function name as last value'), + { code: 'ESEMVERFUNC' } + ) + } + } + + // now if we have 1 node, it's a static value + // istanbul ignore else + if (astNode.nodes.length === 1) { + const semverNode = astNode.nodes.pop() + astNode.semverValue = semverNode.nodes.reduce((res, next) => `${res}${String(next)}`, '') + } else if (astNode.nodes.length === 2) { + // and if we have two nodes, one of them is a static value and we need to determine which it is + for (let i = 0; i < astNode.nodes.length; ++i) { + const type = astNode.nodes[i].nodes[0].type + // the type of the first child may be combinator for ranges, such as >14 + if (type === 'tag' || type === 'combinator') { + const semverNode = astNode.nodes.splice(i, 1)[0] + astNode.semverValue = semverNode.nodes.reduce((res, next) => `${res}${String(next)}`, '') + astNode.semverPosition = i + break + } + } + + if (typeof astNode.semverValue === 'undefined') { + throw Object.assign( + new Error('`:semver` pseudo-class expects a static value in the first or second position'), + { code: 'ESEMVERVALUE' } + ) + } + } + + // if we got here, the last remaining child should be attribute selector + if (astNode.nodes.length === 1) { + fixupAttr(astNode) + } else { + // if we don't have a selector, we default to `[version]` + astNode.attributeMatcher = { + insensitive: false, + attribute: 'version', + qualifiedAttribute: 'version', + } + astNode.lookupProperties = [] + } - astNode.semverValue = value astNode.nodes.length = 0 } @@ -138,6 +159,53 @@ const fixupPaths = astNode => { astNode.nodes.length = 0 } +const fixupOutdated = astNode => { + if (astNode.nodes.length) { + astNode.outdatedKind = String(astNode.nodes[0]) + astNode.nodes.length = 0 + } +} + +const fixupVuln = astNode => { + const vulns = [] + if (astNode.nodes.length) { + for (const selector of astNode.nodes) { + const vuln = {} + for (const node of selector.nodes) { + if (node.type !== 'attribute') { + throw Object.assign( + new Error(':vuln pseudo-class only accepts attribute matchers or "cwe" tag'), + { code: 'EQUERYATTR' } + ) + } + if (!['severity', 'cwe'].includes(node._attribute)) { + throw Object.assign( + new Error(':vuln pseudo-class only matches "severity" and "cwe" attributes'), + { code: 'EQUERYATTR' } + ) + } + if (!node.operator) { + node.operator = '=' + node.value = '*' + } + if (node.operator !== '=') { + throw Object.assign( + new Error(':vuln pseudo-class attribute selector only accepts "=" operator', node), + { code: 'EQUERYATTR' } + ) + } + if (!vuln[node._attribute]) { + vuln[node._attribute] = [] + } + vuln[node._attribute].push(node._value) + } + vulns.push(vuln) + } + astNode.vulns = vulns + astNode.nodes.length = 0 + } +} + // a few of the supported ast nodes need to be tweaked in order to properly be // interpreted as proper arborist query selectors, namely semver ranges from // both ids and :semver pseudo-class selectors need to be translated from what @@ -149,10 +217,6 @@ const fixupPaths = astNode => { // of the parsed ast from the query and modifying the parsed nodes accordingly const transformAst = selector => { selector.walk((nextAstNode) => { - if (nextAstNode.type === 'id') { - fixupIds(nextAstNode) - } - switch (nextAstNode.value) { case ':attr': return fixupAttr(nextAstNode) @@ -166,6 +230,10 @@ const transformAst = selector => { return fixupSemverSpecs(nextAstNode) case ':type': return fixupTypes(nextAstNode) + case ':outdated': + return fixupOutdated(nextAstNode) + case ':vuln': + return fixupVuln(nextAstNode) } }) } diff --git a/node_modules/@npmcli/query/package.json b/node_modules/@npmcli/query/package.json index 0c9247e0bb23b..0cb533eb819b6 100644 --- a/node_modules/@npmcli/query/package.json +++ b/node_modules/@npmcli/query/package.json @@ -1,19 +1,17 @@ { "name": "@npmcli/query", - "version": "1.1.1", + "version": "5.0.0", "description": "npm query parser and tools", "main": "lib/index.js", "scripts": { "test": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "contributors": [ { @@ -38,24 +36,29 @@ "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.27.1", + "publish": true }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.2.0" }, "dependencies": { - "npm-package-arg": "^9.1.0", - "postcss-selector-parser": "^6.0.10", - "semver": "^7.3.7" + "postcss-selector-parser": "^7.0.0" }, "repository": { "type": "git", - "url": "https://github.com/npm/query.git" + "url": "git+https://github.com/npm/query.git" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@npmcli/redact/LICENSE b/node_modules/@npmcli/redact/LICENSE new file mode 100644 index 0000000000000..c21644115c85d --- /dev/null +++ b/node_modules/@npmcli/redact/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 npm + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@npmcli/redact/lib/deep-map.js b/node_modules/@npmcli/redact/lib/deep-map.js new file mode 100644 index 0000000000000..c14857c2c01b1 --- /dev/null +++ b/node_modules/@npmcli/redact/lib/deep-map.js @@ -0,0 +1,71 @@ +const { serializeError } = require('./error') + +const deepMap = (input, handler = v => v, path = ['$'], seen = new Set([input])) => { + // this is in an effort to maintain bole's error logging behavior + if (path.join('.') === '$' && input instanceof Error) { + return deepMap({ err: serializeError(input) }, handler, path, seen) + } + if (input instanceof Error) { + return deepMap(serializeError(input), handler, path, seen) + } + // allows for non-node js environments, sush as workers + if (typeof Buffer !== 'undefined' && input instanceof Buffer) { + return `[unable to log instanceof buffer]` + } + if (input instanceof Uint8Array) { + return `[unable to log instanceof Uint8Array]` + } + + 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 = {} + + 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/node_modules/@npmcli/redact/lib/error.js b/node_modules/@npmcli/redact/lib/error.js new file mode 100644 index 0000000000000..e374b3902a285 --- /dev/null +++ b/node_modules/@npmcli/redact/lib/error.js @@ -0,0 +1,28 @@ +/** takes an error object and serializes it to a plan object */ +function serializeError (input) { + if (!(input instanceof Error)) { + if (typeof input === 'string') { + const error = new Error(`attempted to serialize a non-error, string String, "${input}"`) + return serializeError(error) + } + const error = new Error(`attempted to serialize a non-error, ${typeof input} ${input?.constructor?.name}`) + return serializeError(error) + } + // different error objects store status code differently + // AxiosError uses `status`, other services use `statusCode` + const statusCode = input.statusCode ?? input.status + // CAUTION: what we serialize here gets add to the size of logs + return { + errorType: input.errorType ?? input.constructor.name, + ...(input.message ? { message: input.message } : {}), + ...(input.stack ? { stack: input.stack } : {}), + // think of this as error code + ...(input.code ? { code: input.code } : {}), + // think of this as http status code + ...(statusCode ? { statusCode } : {}), + } +} + +module.exports = { + serializeError, +} diff --git a/node_modules/@npmcli/redact/lib/index.js b/node_modules/@npmcli/redact/lib/index.js new file mode 100644 index 0000000000000..9b10c7f6a0081 --- /dev/null +++ b/node_modules/@npmcli/redact/lib/index.js @@ -0,0 +1,44 @@ +const matchers = require('./matchers') +const { redactUrlPassword } = require('./utils') + +const REPLACE = '***' + +const redact = (value) => { + if (typeof value !== 'string' || !value) { + return value + } + 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 +const splitAndRedact = (str) => { + // stateful regex, don't move out of this scope + const splitChars = /[\s=]/g + + let match = null + let result = '' + let index = 0 + while (match = splitChars.exec(str)) { + result += redact(str.slice(index, match.index)) + match[0] + index = splitChars.lastIndex + } + + return result + redact(str.slice(index)) +} + +// replaces auth info in an array of arguments or in a strings +const redactLog = (arg) => { + if (typeof arg === 'string') { + return splitAndRedact(arg) + } else if (Array.isArray(arg)) { + return arg.map((a) => typeof a === 'string' ? splitAndRedact(a) : a) + } + return arg +} + +module.exports = { + redact, + redactLog, +} diff --git a/node_modules/@npmcli/redact/lib/matchers.js b/node_modules/@npmcli/redact/lib/matchers.js new file mode 100644 index 0000000000000..854ba8e1cbda1 --- /dev/null +++ b/node_modules/@npmcli/redact/lib/matchers.js @@ -0,0 +1,88 @@ +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 DEEP_HEADER_COOKIE = { + type: TYPE_PATH, + predicate: ({ path }) => path.endsWith('.headers.cookie'), + replacement: '[REDACTED_HEADER_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, + DEEP_HEADER_COOKIE, + REWRITE_REQUEST, + REWRITE_RESPONSE, +} diff --git a/node_modules/@npmcli/redact/lib/server.js b/node_modules/@npmcli/redact/lib/server.js new file mode 100644 index 0000000000000..555e37dcc1f54 --- /dev/null +++ b/node_modules/@npmcli/redact/lib/server.js @@ -0,0 +1,59 @@ +const { + AUTH_HEADER, + JSON_WEB_TOKEN, + NPM_SECRET, + DEEP_HEADER_AUTHORIZATION, + DEEP_HEADER_SET_COOKIE, + REWRITE_REQUEST, + REWRITE_RESPONSE, + DEEP_HEADER_COOKIE, +} = require('./matchers') + +const { + redactUrlMatcher, + redactUrlPasswordMatcher, + redactMatchers, +} = require('./utils') + +const { serializeError } = require('./error') + +const { deepMap } = require('./deep-map') + +const _redact = redactMatchers( + NPM_SECRET, + AUTH_HEADER, + JSON_WEB_TOKEN, + DEEP_HEADER_AUTHORIZATION, + DEEP_HEADER_SET_COOKIE, + DEEP_HEADER_COOKIE, + REWRITE_REQUEST, + REWRITE_RESPONSE, + redactUrlMatcher( + redactUrlPasswordMatcher() + ) +) + +const redact = (input) => deepMap(input, (value, path) => _redact(value, { path })) + +/** takes an error returns new error keeping some custom properties */ +function redactError (input) { + const { message, ...data } = serializeError(input) + const output = new Error(redact(message)) + return Object.assign(output, redact(data)) +} + +/** runs a function within try / catch and throws error wrapped in redactError */ +function redactThrow (func) { + if (typeof func !== 'function') { + throw new Error('redactThrow expects a function') + } + return async (...args) => { + try { + return await func(...args) + } catch (error) { + throw redactError(error) + } + } +} + +module.exports = { redact, redactError, redactThrow } diff --git a/node_modules/@npmcli/redact/lib/utils.js b/node_modules/@npmcli/redact/lib/utils.js new file mode 100644 index 0000000000000..8395ab25fc373 --- /dev/null +++ b/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/node_modules/@npmcli/redact/package.json b/node_modules/@npmcli/redact/package.json new file mode 100644 index 0000000000000..53d0edf50b73d --- /dev/null +++ b/node_modules/@npmcli/redact/package.json @@ -0,0 +1,52 @@ +{ + "name": "@npmcli/redact", + "version": "4.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": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "keywords": [], + "author": "GitHub Inc.", + "license": "ISC", + "files": [ + "bin/", + "lib/" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/npm/redact.git" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ], + "timeout": 120 + }, + "devDependencies": { + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.10" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/@npmcli/run-script/lib/escape.js b/node_modules/@npmcli/run-script/lib/escape.js deleted file mode 100644 index 303100d337eb7..0000000000000 --- a/node_modules/@npmcli/run-script/lib/escape.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict' - -// eslint-disable-next-line max-len -// this code adapted from: https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ -const cmd = (input, doubleEscape) => { - if (!input.length) { - return '""' - } - - let result - if (!/[ \t\n\v"]/.test(input)) { - result = input - } else { - result = '"' - for (let i = 0; i <= input.length; ++i) { - let slashCount = 0 - while (input[i] === '\\') { - ++i - ++slashCount - } - - if (i === input.length) { - result += '\\'.repeat(slashCount * 2) - break - } - - if (input[i] === '"') { - result += '\\'.repeat(slashCount * 2 + 1) - result += input[i] - } else { - result += '\\'.repeat(slashCount) - result += input[i] - } - } - result += '"' - } - - // and finally, prefix shell meta chars with a ^ - result = result.replace(/[ !^&()<>|"]/g, '^$&') - if (doubleEscape) { - result = result.replace(/[ !^&()<>|"]/g, '^$&') - } - - // except for % which is escaped with another %, and only once - result = result.replace(/%/g, '%%') - - return result -} - -const sh = (input) => { - if (!input.length) { - return `''` - } - - if (!/[\t\n\r "#$&'()*;<>?\\`|~]/.test(input)) { - return input - } - - // replace single quotes with '\'' and wrap the whole result in a fresh set of quotes - const result = `'${input.replace(/'/g, `'\\''`)}'` - // if the input string already had single quotes around it, clean those up - .replace(/^(?:'')+(?!$)/, '') - .replace(/\\'''/g, `\\'`) - - return result -} - -// disabling the no-control-regex rule for this line as we very specifically _do_ want to -// replace those characters if they somehow exist at this point, which is highly unlikely -// eslint-disable-next-line no-control-regex -const filename = (input) => input.replace(/[<>:"/\\|?*\x00-\x1F]/g, '') - -module.exports = { - cmd, - sh, - filename, -} diff --git a/node_modules/@npmcli/run-script/lib/is-server-package.js b/node_modules/@npmcli/run-script/lib/is-server-package.js index d168623247527..c36c40d4898d5 100644 --- a/node_modules/@npmcli/run-script/lib/is-server-package.js +++ b/node_modules/@npmcli/run-script/lib/is-server-package.js @@ -1,7 +1,6 @@ -const util = require('util') -const fs = require('fs') -const { stat } = fs.promises || { stat: util.promisify(fs.stat) } -const { resolve } = require('path') +const { stat } = require('node:fs/promises') +const { resolve } = require('node:path') + module.exports = async path => { try { const st = await stat(resolve(path, 'server.js')) diff --git a/node_modules/@npmcli/run-script/lib/is-windows.js b/node_modules/@npmcli/run-script/lib/is-windows.js deleted file mode 100644 index 651917e6ad27a..0000000000000 --- a/node_modules/@npmcli/run-script/lib/is-windows.js +++ /dev/null @@ -1,2 +0,0 @@ -const platform = process.env.__FAKE_TESTING_PLATFORM__ || process.platform -module.exports = platform === 'win32' diff --git a/node_modules/@npmcli/run-script/lib/make-spawn-args.js b/node_modules/@npmcli/run-script/lib/make-spawn-args.js index 7725fd976c893..1c9f02c062f72 100644 --- a/node_modules/@npmcli/run-script/lib/make-spawn-args.js +++ b/node_modules/@npmcli/run-script/lib/make-spawn-args.js @@ -1,33 +1,34 @@ /* eslint camelcase: "off" */ -const isWindows = require('./is-windows.js') const setPATH = require('./set-path.js') -const { unlinkSync: unlink, writeFileSync: writeFile } = require('fs') -const { tmpdir } = require('os') const { resolve } = require('path') -const which = require('which') -const npm_config_node_gyp = require.resolve('node-gyp/bin/node-gyp.js') -const escape = require('./escape.js') -const { randomBytes } = require('crypto') -const translateWinPathToPosix = (path) => { - return path - .replace(/^([A-z]):/, '/$1') - .replace(/\\/g, '/') -} +let npm_config_node_gyp const makeSpawnArgs = options => { const { + args, + binPaths, + cmd, + env, event, + nodeGyp, path, - scriptShell = isWindows ? process.env.ComSpec || 'cmd' : 'sh', - binPaths, - env = {}, + scriptShell = true, stdio, - cmd, - args = [], - stdioString = false, + stdioString, } = options + if (nodeGyp) { + // npm already pulled this from env and passes it in to options + npm_config_node_gyp = nodeGyp + } else if (env.npm_config_node_gyp) { + // legacy mode for standalone user + npm_config_node_gyp = env.npm_config_node_gyp + } else { + // default + npm_config_node_gyp = require.resolve('node-gyp/bin/node-gyp.js') + } + const spawnEnv = setPATH(path, binPaths, { // we need to at least save the PATH environment var ...process.env, @@ -38,75 +39,15 @@ const makeSpawnArgs = options => { npm_config_node_gyp, }) - const fileName = escape.filename(`${event}-${randomBytes(4).toString('hex')}`) - let scriptFile - let script = '' - - const isCmd = /(?:^|\\)cmd(?:\.exe)?$/i.test(scriptShell) - if (isCmd) { - let initialCmd = '' - let insideQuotes = false - for (let i = 0; i < cmd.length; ++i) { - const char = cmd.charAt(i) - if (char === ' ' && !insideQuotes) { - break - } - - initialCmd += char - if (char === '"' || char === "'") { - insideQuotes = !insideQuotes - } - } - - let pathToInitial - try { - pathToInitial = which.sync(initialCmd, { - path: spawnEnv.path, - pathext: spawnEnv.pathext, - }).toLowerCase() - } catch (err) { - pathToInitial = initialCmd.toLowerCase() - } - - const doubleEscape = pathToInitial.endsWith('.cmd') || pathToInitial.endsWith('.bat') - - scriptFile = resolve(tmpdir(), `${fileName}.cmd`) - script += '@echo off\n' - script += cmd - if (args.length) { - script += ` ${args.map((arg) => escape.cmd(arg, doubleEscape)).join(' ')}` - } - } else { - scriptFile = resolve(tmpdir(), `${fileName}.sh`) - script = cmd - if (args.length) { - script += ` ${args.map((arg) => escape.sh(arg)).join(' ')}` - } - } - - writeFile(scriptFile, script) - const spawnArgs = isCmd - ? ['/d', '/s', '/c', escape.cmd(scriptFile)] - : [isWindows ? translateWinPathToPosix(scriptFile) : scriptFile] - const spawnOpts = { env: spawnEnv, stdioString, stdio, cwd: path, - ...(isCmd ? { windowsVerbatimArguments: true } : {}), - } - - const cleanup = () => { - // delete the script, this is just a best effort - try { - unlink(scriptFile) - } catch (err) { - // ignore errors - } + shell: scriptShell, } - return [scriptShell, spawnArgs, spawnOpts, cleanup] + return [cmd, args, spawnOpts] } module.exports = makeSpawnArgs diff --git a/node_modules/@npmcli/run-script/lib/package-envs.js b/node_modules/@npmcli/run-script/lib/package-envs.js index 6b538e50247fd..612f850fb076c 100644 --- a/node_modules/@npmcli/run-script/lib/package-envs.js +++ b/node_modules/@npmcli/run-script/lib/package-envs.js @@ -1,26 +1,29 @@ -// https://github.com/npm/rfcs/pull/183 - -const envVal = val => Array.isArray(val) ? val.map(v => envVal(v)).join('\n\n') - : val === null || val === false ? '' - : String(val) - -const packageEnvs = (env, vals, prefix) => { +const packageEnvs = (vals, prefix, env = {}) => { for (const [key, val] of Object.entries(vals)) { if (val === undefined) { continue - } else if (val && !Array.isArray(val) && typeof val === 'object') { - packageEnvs(env, val, `${prefix}${key}_`) + } else if (val === null || val === false) { + env[`${prefix}${key}`] = '' + } else if (Array.isArray(val)) { + val.forEach((item, index) => { + packageEnvs({ [`${key}_${index}`]: item }, `${prefix}`, env) + }) + } else if (typeof val === 'object') { + packageEnvs(val, `${prefix}${key}_`, env) } else { - env[`${prefix}${key}`] = envVal(val) + env[`${prefix}${key}`] = String(val) } } return env } -module.exports = (env, pkg) => packageEnvs({ ...env }, { - name: pkg.name, - version: pkg.version, - config: pkg.config, - engines: pkg.engines, - bin: pkg.bin, -}, 'npm_package_') +// https://github.com/npm/rfcs/pull/183 defines which fields we put into the environment +module.exports = pkg => { + return packageEnvs({ + name: pkg.name, + version: pkg.version, + config: pkg.config, + engines: pkg.engines, + bin: pkg.bin, + }, 'npm_package_') +} diff --git a/node_modules/@npmcli/run-script/lib/run-script-pkg.js b/node_modules/@npmcli/run-script/lib/run-script-pkg.js index ec6ef31e50ab0..161caebb98d97 100644 --- a/node_modules/@npmcli/run-script/lib/run-script-pkg.js +++ b/node_modules/@npmcli/run-script/lib/run-script-pkg.js @@ -5,26 +5,21 @@ 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) => - `\n> ${id ? id + ' ' : ''}${event}\n> ${cmd.trim().replace(/\n/g, '\n> ')}\n` - const runScriptPkg = async options => { const { - event, - path, - scriptShell, + args = [], binPaths = false, env = {}, - stdio = 'pipe', + event, + nodeGyp, + path, pkg, - args = [], - stdioString = false, - // note: only used when stdio:inherit - banner = true, + scriptShell, // 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, + stdio = 'pipe', + stdioString, } = options const { scripts = {}, gypfile } = pkg @@ -50,20 +45,34 @@ 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)) + 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, cleanup] = makeSpawnArgs({ + const [spawnShell, spawnArgs, spawnOpts] = makeSpawnArgs({ + args, + binPaths, + cmd, + env: { ...env, ...packageEnvs(pkg) }, event, + nodeGyp, path, scriptShell, - binPaths, - env: packageEnvs(env, pkg), stdio, - cmd, - args, stdioString, }) @@ -84,8 +93,14 @@ const runScriptPkg = async options => { return p.catch(er => { const { signal } = er + // coverage disabled because win32 never emits signals + /* istanbul ignore next */ if (stdio === 'inherit' && signal) { + // by the time we reach here, the child has already exited. we send the + // signal back to ourselves again so that npm will exit with the same + // status as the child process.kill(process.pid, signal) + // just in case we don't die, reject after 500ms // this also keeps the node process open long enough to actually // get the signal, rather than terminating gracefully. @@ -93,7 +108,7 @@ const runScriptPkg = async options => { } else { throw er } - }).finally(cleanup) + }).finally(inputEnd) } module.exports = runScriptPkg diff --git a/node_modules/@npmcli/run-script/lib/run-script.js b/node_modules/@npmcli/run-script/lib/run-script.js index e9d18261a2c1f..b00304c8d6e7f 100644 --- a/node_modules/@npmcli/run-script/lib/run-script.js +++ b/node_modules/@npmcli/run-script/lib/run-script.js @@ -1,14 +1,15 @@ -const rpj = require('read-package-json-fast') +const PackageJson = require('@npmcli/package-json') const runScriptPkg = require('./run-script-pkg.js') const validateOptions = require('./validate-options.js') const isServerPackage = require('./is-server-package.js') -const runScript = options => { +const runScript = async options => { validateOptions(options) - const { pkg, path } = options - return pkg ? runScriptPkg(options) - : rpj(path + '/package.json') - .then(readPackage => runScriptPkg({ ...options, pkg: readPackage })) + if (options.pkg) { + return runScriptPkg(options) + } + const { content: pkg } = await PackageJson.normalize(options.path) + return runScriptPkg({ ...options, pkg }) } module.exports = Object.assign(runScript, { isServerPackage }) diff --git a/node_modules/@npmcli/run-script/lib/signal-manager.js b/node_modules/@npmcli/run-script/lib/signal-manager.js index 7e10f859e0a68..a099a4af2b9be 100644 --- a/node_modules/@npmcli/run-script/lib/signal-manager.js +++ b/node_modules/@npmcli/run-script/lib/signal-manager.js @@ -6,6 +6,9 @@ const forwardedSignals = [ 'SIGTERM', ] +// no-op, this is so receiving the signal doesn't cause us to exit immediately +// instead, we exit after all children have exited when we re-send the signal +// to ourselves. see the catch handler at the bottom of run-script-pkg.js const handleSignal = signal => { for (const proc of runningProcs) { proc.kill(signal) diff --git a/node_modules/@npmcli/run-script/package.json b/node_modules/@npmcli/run-script/package.json index a6629826d29c2..9ddb499084173 100644 --- a/node_modules/@npmcli/run-script/package.json +++ b/node_modules/@npmcli/run-script/package.json @@ -1,35 +1,32 @@ { "name": "@npmcli/run-script", - "version": "4.2.0", + "version": "10.0.3", "description": "Run a lifecycle script for a package (descendant of npm-lifecycle)", "author": "GitHub Inc.", "license": "ISC", "scripts": { "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "eslint": "eslint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "snap": "tap", "posttest": "npm run lint", "template-oss-apply": "template-oss-apply --force" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "minipass": "^3.1.6", - "require-inject": "^1.4.4", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", + "spawk": "^1.8.1", "tap": "^16.0.1" }, "dependencies": { - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/promise-spawn": "^3.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^2.0.3", - "which": "^2.0.2" + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" }, "files": [ "bin/", @@ -38,13 +35,20 @@ "main": "lib/run-script.js", "repository": { "type": "git", - "url": "https://github.com/npm/run-script.git" + "url": "git+https://github.com/npm/run-script.git" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.28.0", + "publish": "true" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/@sigstore/bundle/LICENSE b/node_modules/@sigstore/bundle/LICENSE new file mode 100644 index 0000000000000..e9e7c1679a09d --- /dev/null +++ b/node_modules/@sigstore/bundle/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 The Sigstore Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/@sigstore/bundle/dist/build.js b/node_modules/@sigstore/bundle/dist/build.js new file mode 100644 index 0000000000000..ade736407554c --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/build.js @@ -0,0 +1,100 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toMessageSignatureBundle = toMessageSignatureBundle; +exports.toDSSEBundle = toDSSEBundle; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const bundle_1 = require("./bundle"); +// Message signature bundle - $case: 'messageSignature' +function toMessageSignatureBundle(options) { + return { + mediaType: options.certificateChain + ? bundle_1.BUNDLE_V02_MEDIA_TYPE + : bundle_1.BUNDLE_V03_MEDIA_TYPE, + content: { + $case: 'messageSignature', + messageSignature: { + messageDigest: { + algorithm: protobuf_specs_1.HashAlgorithm.SHA2_256, + digest: options.digest, + }, + signature: options.signature, + }, + }, + verificationMaterial: toVerificationMaterial(options), + }; +} +// DSSE envelope bundle - $case: 'dsseEnvelope' +function toDSSEBundle(options) { + return { + mediaType: options.certificateChain + ? bundle_1.BUNDLE_V02_MEDIA_TYPE + : bundle_1.BUNDLE_V03_MEDIA_TYPE, + content: { + $case: 'dsseEnvelope', + dsseEnvelope: toEnvelope(options), + }, + verificationMaterial: toVerificationMaterial(options), + }; +} +function toEnvelope(options) { + return { + payloadType: options.artifactType, + payload: options.artifact, + signatures: [toSignature(options)], + }; +} +function toSignature(options) { + return { + keyid: options.keyHint || '', + sig: options.signature, + }; +} +// Verification material +function toVerificationMaterial(options) { + return { + content: toKeyContent(options), + tlogEntries: [], + timestampVerificationData: { rfc3161Timestamps: [] }, + }; +} +function toKeyContent(options) { + if (options.certificate) { + if (options.certificateChain) { + return { + $case: 'x509CertificateChain', + x509CertificateChain: { + certificates: [{ rawBytes: options.certificate }], + }, + }; + } + else { + return { + $case: 'certificate', + certificate: { rawBytes: options.certificate }, + }; + } + } + else { + return { + $case: 'publicKey', + publicKey: { + hint: options.keyHint || '', + }, + }; + } +} diff --git a/node_modules/@sigstore/bundle/dist/bundle.js b/node_modules/@sigstore/bundle/dist/bundle.js new file mode 100644 index 0000000000000..eb67a0ddc17bb --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/bundle.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BUNDLE_V03_MEDIA_TYPE = exports.BUNDLE_V03_LEGACY_MEDIA_TYPE = exports.BUNDLE_V02_MEDIA_TYPE = exports.BUNDLE_V01_MEDIA_TYPE = void 0; +exports.isBundleWithCertificateChain = isBundleWithCertificateChain; +exports.isBundleWithPublicKey = isBundleWithPublicKey; +exports.isBundleWithMessageSignature = isBundleWithMessageSignature; +exports.isBundleWithDsseEnvelope = isBundleWithDsseEnvelope; +exports.BUNDLE_V01_MEDIA_TYPE = 'application/vnd.dev.sigstore.bundle+json;version=0.1'; +exports.BUNDLE_V02_MEDIA_TYPE = 'application/vnd.dev.sigstore.bundle+json;version=0.2'; +exports.BUNDLE_V03_LEGACY_MEDIA_TYPE = 'application/vnd.dev.sigstore.bundle+json;version=0.3'; +exports.BUNDLE_V03_MEDIA_TYPE = 'application/vnd.dev.sigstore.bundle.v0.3+json'; +// Type guards for bundle variants. +function isBundleWithCertificateChain(b) { + return b.verificationMaterial.content.$case === 'x509CertificateChain'; +} +function isBundleWithPublicKey(b) { + return b.verificationMaterial.content.$case === 'publicKey'; +} +function isBundleWithMessageSignature(b) { + return b.content.$case === 'messageSignature'; +} +function isBundleWithDsseEnvelope(b) { + return b.content.$case === 'dsseEnvelope'; +} diff --git a/node_modules/@sigstore/bundle/dist/error.js b/node_modules/@sigstore/bundle/dist/error.js new file mode 100644 index 0000000000000..f84295323b812 --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/error.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ValidationError = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +class ValidationError extends Error { + constructor(message, fields) { + super(message); + this.fields = fields; + } +} +exports.ValidationError = ValidationError; diff --git a/node_modules/@sigstore/bundle/dist/index.js b/node_modules/@sigstore/bundle/dist/index.js new file mode 100644 index 0000000000000..1b012acad4d85 --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/index.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isBundleV01 = exports.assertBundleV02 = exports.assertBundleV01 = exports.assertBundleLatest = exports.assertBundle = exports.envelopeToJSON = exports.envelopeFromJSON = exports.bundleToJSON = exports.bundleFromJSON = exports.ValidationError = exports.isBundleWithPublicKey = exports.isBundleWithMessageSignature = exports.isBundleWithDsseEnvelope = exports.isBundleWithCertificateChain = exports.BUNDLE_V03_MEDIA_TYPE = exports.BUNDLE_V03_LEGACY_MEDIA_TYPE = exports.BUNDLE_V02_MEDIA_TYPE = exports.BUNDLE_V01_MEDIA_TYPE = exports.toMessageSignatureBundle = exports.toDSSEBundle = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var build_1 = require("./build"); +Object.defineProperty(exports, "toDSSEBundle", { enumerable: true, get: function () { return build_1.toDSSEBundle; } }); +Object.defineProperty(exports, "toMessageSignatureBundle", { enumerable: true, get: function () { return build_1.toMessageSignatureBundle; } }); +var bundle_1 = require("./bundle"); +Object.defineProperty(exports, "BUNDLE_V01_MEDIA_TYPE", { enumerable: true, get: function () { return bundle_1.BUNDLE_V01_MEDIA_TYPE; } }); +Object.defineProperty(exports, "BUNDLE_V02_MEDIA_TYPE", { enumerable: true, get: function () { return bundle_1.BUNDLE_V02_MEDIA_TYPE; } }); +Object.defineProperty(exports, "BUNDLE_V03_LEGACY_MEDIA_TYPE", { enumerable: true, get: function () { return bundle_1.BUNDLE_V03_LEGACY_MEDIA_TYPE; } }); +Object.defineProperty(exports, "BUNDLE_V03_MEDIA_TYPE", { enumerable: true, get: function () { return bundle_1.BUNDLE_V03_MEDIA_TYPE; } }); +Object.defineProperty(exports, "isBundleWithCertificateChain", { enumerable: true, get: function () { return bundle_1.isBundleWithCertificateChain; } }); +Object.defineProperty(exports, "isBundleWithDsseEnvelope", { enumerable: true, get: function () { return bundle_1.isBundleWithDsseEnvelope; } }); +Object.defineProperty(exports, "isBundleWithMessageSignature", { enumerable: true, get: function () { return bundle_1.isBundleWithMessageSignature; } }); +Object.defineProperty(exports, "isBundleWithPublicKey", { enumerable: true, get: function () { return bundle_1.isBundleWithPublicKey; } }); +var error_1 = require("./error"); +Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return error_1.ValidationError; } }); +var serialized_1 = require("./serialized"); +Object.defineProperty(exports, "bundleFromJSON", { enumerable: true, get: function () { return serialized_1.bundleFromJSON; } }); +Object.defineProperty(exports, "bundleToJSON", { enumerable: true, get: function () { return serialized_1.bundleToJSON; } }); +Object.defineProperty(exports, "envelopeFromJSON", { enumerable: true, get: function () { return serialized_1.envelopeFromJSON; } }); +Object.defineProperty(exports, "envelopeToJSON", { enumerable: true, get: function () { return serialized_1.envelopeToJSON; } }); +var validate_1 = require("./validate"); +Object.defineProperty(exports, "assertBundle", { enumerable: true, get: function () { return validate_1.assertBundle; } }); +Object.defineProperty(exports, "assertBundleLatest", { enumerable: true, get: function () { return validate_1.assertBundleLatest; } }); +Object.defineProperty(exports, "assertBundleV01", { enumerable: true, get: function () { return validate_1.assertBundleV01; } }); +Object.defineProperty(exports, "assertBundleV02", { enumerable: true, get: function () { return validate_1.assertBundleV02; } }); +Object.defineProperty(exports, "isBundleV01", { enumerable: true, get: function () { return validate_1.isBundleV01; } }); diff --git a/node_modules/@sigstore/bundle/dist/serialized.js b/node_modules/@sigstore/bundle/dist/serialized.js new file mode 100644 index 0000000000000..be0d2a2d54d09 --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/serialized.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.envelopeToJSON = exports.envelopeFromJSON = exports.bundleToJSON = exports.bundleFromJSON = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const bundle_1 = require("./bundle"); +const validate_1 = require("./validate"); +const bundleFromJSON = (obj) => { + const bundle = protobuf_specs_1.Bundle.fromJSON(obj); + switch (bundle.mediaType) { + case bundle_1.BUNDLE_V01_MEDIA_TYPE: + (0, validate_1.assertBundleV01)(bundle); + break; + case bundle_1.BUNDLE_V02_MEDIA_TYPE: + (0, validate_1.assertBundleV02)(bundle); + break; + default: + (0, validate_1.assertBundleLatest)(bundle); + break; + } + return bundle; +}; +exports.bundleFromJSON = bundleFromJSON; +const bundleToJSON = (bundle) => { + return protobuf_specs_1.Bundle.toJSON(bundle); +}; +exports.bundleToJSON = bundleToJSON; +const envelopeFromJSON = (obj) => { + return protobuf_specs_1.Envelope.fromJSON(obj); +}; +exports.envelopeFromJSON = envelopeFromJSON; +const envelopeToJSON = (envelope) => { + return protobuf_specs_1.Envelope.toJSON(envelope); +}; +exports.envelopeToJSON = envelopeToJSON; diff --git a/node_modules/@sigstore/bundle/dist/utility.js b/node_modules/@sigstore/bundle/dist/utility.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/utility.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/bundle/dist/validate.js b/node_modules/@sigstore/bundle/dist/validate.js new file mode 100644 index 0000000000000..21b8b5ee293ba --- /dev/null +++ b/node_modules/@sigstore/bundle/dist/validate.js @@ -0,0 +1,199 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.assertBundle = assertBundle; +exports.assertBundleV01 = assertBundleV01; +exports.isBundleV01 = isBundleV01; +exports.assertBundleV02 = assertBundleV02; +exports.assertBundleLatest = assertBundleLatest; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("./error"); +// Performs basic validation of a Sigstore bundle to ensure that all required +// fields are populated. This is not a complete validation of the bundle, but +// rather a check that the bundle is in a valid state to be processed by the +// rest of the code. +function assertBundle(b) { + const invalidValues = validateBundleBase(b); + if (invalidValues.length > 0) { + throw new error_1.ValidationError('invalid bundle', invalidValues); + } +} +// Asserts that the given bundle conforms to the v0.1 bundle format. +function assertBundleV01(b) { + const invalidValues = []; + invalidValues.push(...validateBundleBase(b)); + invalidValues.push(...validateInclusionPromise(b)); + if (invalidValues.length > 0) { + throw new error_1.ValidationError('invalid v0.1 bundle', invalidValues); + } +} +// Type guard to determine if Bundle is a v0.1 bundle. +function isBundleV01(b) { + try { + assertBundleV01(b); + return true; + } + catch (e) { + return false; + } +} +// Asserts that the given bundle conforms to the v0.2 bundle format. +function assertBundleV02(b) { + const invalidValues = []; + invalidValues.push(...validateBundleBase(b)); + invalidValues.push(...validateInclusionProof(b)); + if (invalidValues.length > 0) { + throw new error_1.ValidationError('invalid v0.2 bundle', invalidValues); + } +} +// Asserts that the given bundle conforms to the newest (0.3) bundle format. +function assertBundleLatest(b) { + const invalidValues = []; + invalidValues.push(...validateBundleBase(b)); + invalidValues.push(...validateInclusionProof(b)); + invalidValues.push(...validateNoCertificateChain(b)); + if (invalidValues.length > 0) { + throw new error_1.ValidationError('invalid bundle', invalidValues); + } +} +function validateBundleBase(b) { + const invalidValues = []; + // Media type validation + if (b.mediaType === undefined || + (!b.mediaType.match(/^application\/vnd\.dev\.sigstore\.bundle\+json;version=\d\.\d/) && + !b.mediaType.match(/^application\/vnd\.dev\.sigstore\.bundle\.v\d\.\d\+json/))) { + invalidValues.push('mediaType'); + } + // Content-related validation + if (b.content === undefined) { + invalidValues.push('content'); + } + else { + switch (b.content.$case) { + case 'messageSignature': + if (b.content.messageSignature.messageDigest === undefined) { + invalidValues.push('content.messageSignature.messageDigest'); + } + else { + if (b.content.messageSignature.messageDigest.digest.length === 0) { + invalidValues.push('content.messageSignature.messageDigest.digest'); + } + } + if (b.content.messageSignature.signature.length === 0) { + invalidValues.push('content.messageSignature.signature'); + } + break; + case 'dsseEnvelope': + if (b.content.dsseEnvelope.payload.length === 0) { + invalidValues.push('content.dsseEnvelope.payload'); + } + if (b.content.dsseEnvelope.signatures.length !== 1) { + invalidValues.push('content.dsseEnvelope.signatures'); + } + else { + if (b.content.dsseEnvelope.signatures[0].sig.length === 0) { + invalidValues.push('content.dsseEnvelope.signatures[0].sig'); + } + } + break; + } + } + // Verification material-related validation + if (b.verificationMaterial === undefined) { + invalidValues.push('verificationMaterial'); + } + else { + if (b.verificationMaterial.content === undefined) { + invalidValues.push('verificationMaterial.content'); + } + else { + switch (b.verificationMaterial.content.$case) { + case 'x509CertificateChain': + if (b.verificationMaterial.content.x509CertificateChain.certificates + .length === 0) { + invalidValues.push('verificationMaterial.content.x509CertificateChain.certificates'); + } + b.verificationMaterial.content.x509CertificateChain.certificates.forEach((cert, i) => { + if (cert.rawBytes.length === 0) { + invalidValues.push(`verificationMaterial.content.x509CertificateChain.certificates[${i}].rawBytes`); + } + }); + break; + case 'certificate': + if (b.verificationMaterial.content.certificate.rawBytes.length === 0) { + invalidValues.push('verificationMaterial.content.certificate.rawBytes'); + } + break; + } + } + if (b.verificationMaterial.tlogEntries === undefined) { + invalidValues.push('verificationMaterial.tlogEntries'); + } + else { + if (b.verificationMaterial.tlogEntries.length > 0) { + b.verificationMaterial.tlogEntries.forEach((entry, i) => { + if (entry.logId === undefined) { + invalidValues.push(`verificationMaterial.tlogEntries[${i}].logId`); + } + if (entry.kindVersion === undefined) { + invalidValues.push(`verificationMaterial.tlogEntries[${i}].kindVersion`); + } + }); + } + } + } + return invalidValues; +} +// Necessary for V01 bundles +function validateInclusionPromise(b) { + const invalidValues = []; + if (b.verificationMaterial && + b.verificationMaterial.tlogEntries?.length > 0) { + b.verificationMaterial.tlogEntries.forEach((entry, i) => { + if (entry.inclusionPromise === undefined) { + invalidValues.push(`verificationMaterial.tlogEntries[${i}].inclusionPromise`); + } + }); + } + return invalidValues; +} +// Necessary for V02 and later bundles +function validateInclusionProof(b) { + const invalidValues = []; + if (b.verificationMaterial && + b.verificationMaterial.tlogEntries?.length > 0) { + b.verificationMaterial.tlogEntries.forEach((entry, i) => { + if (entry.inclusionProof === undefined) { + invalidValues.push(`verificationMaterial.tlogEntries[${i}].inclusionProof`); + } + else { + if (entry.inclusionProof.checkpoint === undefined) { + invalidValues.push(`verificationMaterial.tlogEntries[${i}].inclusionProof.checkpoint`); + } + } + }); + } + return invalidValues; +} +// Necessary for V03 and later bundles +function validateNoCertificateChain(b) { + const invalidValues = []; + /* istanbul ignore next */ + if (b.verificationMaterial?.content?.$case === 'x509CertificateChain') { + invalidValues.push('verificationMaterial.content.$case'); + } + return invalidValues; +} diff --git a/node_modules/@sigstore/bundle/package.json b/node_modules/@sigstore/bundle/package.json new file mode 100644 index 0000000000000..03291b2159b79 --- /dev/null +++ b/node_modules/@sigstore/bundle/package.json @@ -0,0 +1,35 @@ +{ + "name": "@sigstore/bundle", + "version": "4.0.0", + "description": "Sigstore bundle type", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "shx rm -rf dist *.tsbuildinfo", + "build": "tsc --build", + "test": "jest" + }, + "files": [ + "dist", + "store" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/sigstore-js.git" + }, + "bugs": { + "url": "https://github.com/sigstore/sigstore-js/issues" + }, + "homepage": "https://github.com/sigstore/sigstore-js/tree/main/packages/bundle#readme", + "publishConfig": { + "provenance": true + }, + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/@sigstore/core/LICENSE b/node_modules/@sigstore/core/LICENSE new file mode 100644 index 0000000000000..e9e7c1679a09d --- /dev/null +++ b/node_modules/@sigstore/core/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 The Sigstore Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/@sigstore/core/dist/asn1/error.js b/node_modules/@sigstore/core/dist/asn1/error.js new file mode 100644 index 0000000000000..17d93b0f7e706 --- /dev/null +++ b/node_modules/@sigstore/core/dist/asn1/error.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ASN1TypeError = exports.ASN1ParseError = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +class ASN1ParseError extends Error { +} +exports.ASN1ParseError = ASN1ParseError; +class ASN1TypeError extends Error { +} +exports.ASN1TypeError = ASN1TypeError; diff --git a/node_modules/@sigstore/core/dist/asn1/index.js b/node_modules/@sigstore/core/dist/asn1/index.js new file mode 100644 index 0000000000000..348b2ea4022e5 --- /dev/null +++ b/node_modules/@sigstore/core/dist/asn1/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ASN1Obj = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var obj_1 = require("./obj"); +Object.defineProperty(exports, "ASN1Obj", { enumerable: true, get: function () { return obj_1.ASN1Obj; } }); diff --git a/node_modules/@sigstore/core/dist/asn1/length.js b/node_modules/@sigstore/core/dist/asn1/length.js new file mode 100644 index 0000000000000..cb7ebf09dbefa --- /dev/null +++ b/node_modules/@sigstore/core/dist/asn1/length.js @@ -0,0 +1,62 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decodeLength = decodeLength; +exports.encodeLength = encodeLength; +const error_1 = require("./error"); +// Decodes the length of a DER-encoded ANS.1 element from the supplied stream. +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-length-and-value-bytes +function decodeLength(stream) { + const buf = stream.getUint8(); + // If the most significant bit is UNSET the length is just the value of the + // byte. + if ((buf & 0x80) === 0x00) { + return buf; + } + // Otherwise, the lower 7 bits of the first byte indicate the number of bytes + // that follow to encode the length. + const byteCount = buf & 0x7f; + // Ensure the encoded length can safely fit in a JS number. + if (byteCount > 6) { + throw new error_1.ASN1ParseError('length exceeds 6 byte limit'); + } + // Iterate over the bytes that encode the length. + let len = 0; + for (let i = 0; i < byteCount; i++) { + len = len * 256 + stream.getUint8(); + } + // This is a valid ASN.1 length encoding, but we don't support it. + if (len === 0) { + throw new error_1.ASN1ParseError('indefinite length encoding not supported'); + } + return len; +} +// Translates the supplied value to a DER-encoded length. +function encodeLength(len) { + if (len < 128) { + return Buffer.from([len]); + } + // Bitwise operations on large numbers are not supported in JS, so we need to + // use BigInts. + let val = BigInt(len); + const bytes = []; + while (val > 0n) { + bytes.unshift(Number(val & 255n)); + val = val >> 8n; + } + return Buffer.from([0x80 | bytes.length, ...bytes]); +} diff --git a/node_modules/@sigstore/core/dist/asn1/obj.js b/node_modules/@sigstore/core/dist/asn1/obj.js new file mode 100644 index 0000000000000..2dc90d6ac9b8d --- /dev/null +++ b/node_modules/@sigstore/core/dist/asn1/obj.js @@ -0,0 +1,155 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ASN1Obj = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const stream_1 = require("../stream"); +const error_1 = require("./error"); +const length_1 = require("./length"); +const parse_1 = require("./parse"); +const tag_1 = require("./tag"); +class ASN1Obj { + tag; + subs; + value; + constructor(tag, value, subs) { + this.tag = tag; + this.value = value; + this.subs = subs; + } + // Constructs an ASN.1 object from a Buffer of DER-encoded bytes. + static parseBuffer(buf) { + return parseStream(new stream_1.ByteStream(buf)); + } + toDER() { + const valueStream = new stream_1.ByteStream(); + if (this.subs.length > 0) { + for (const sub of this.subs) { + valueStream.appendView(sub.toDER()); + } + } + else { + valueStream.appendView(this.value); + } + const value = valueStream.buffer; + // Concat tag/length/value + const obj = new stream_1.ByteStream(); + obj.appendChar(this.tag.toDER()); + obj.appendView((0, length_1.encodeLength)(value.length)); + obj.appendView(value); + return obj.buffer; + } + ///////////////////////////////////////////////////////////////////////////// + // Convenience methods for parsing ASN.1 primitives into JS types + // Returns the ASN.1 object's value as a boolean. Throws an error if the + // object is not a boolean. + toBoolean() { + if (!this.tag.isBoolean()) { + throw new error_1.ASN1TypeError('not a boolean'); + } + return (0, parse_1.parseBoolean)(this.value); + } + // Returns the ASN.1 object's value as a BigInt. Throws an error if the + // object is not an integer. + toInteger() { + if (!this.tag.isInteger()) { + throw new error_1.ASN1TypeError('not an integer'); + } + return (0, parse_1.parseInteger)(this.value); + } + // Returns the ASN.1 object's value as an OID string. Throws an error if the + // object is not an OID. + toOID() { + if (!this.tag.isOID()) { + throw new error_1.ASN1TypeError('not an OID'); + } + return (0, parse_1.parseOID)(this.value); + } + // Returns the ASN.1 object's value as a Date. Throws an error if the object + // is not either a UTCTime or a GeneralizedTime. + toDate() { + switch (true) { + case this.tag.isUTCTime(): + return (0, parse_1.parseTime)(this.value, true); + case this.tag.isGeneralizedTime(): + return (0, parse_1.parseTime)(this.value, false); + default: + throw new error_1.ASN1TypeError('not a date'); + } + } + // Returns the ASN.1 object's value as a number[] where each number is the + // value of a bit in the bit string. Throws an error if the object is not a + // bit string. + toBitString() { + if (!this.tag.isBitString()) { + throw new error_1.ASN1TypeError('not a bit string'); + } + return (0, parse_1.parseBitString)(this.value); + } +} +exports.ASN1Obj = ASN1Obj; +///////////////////////////////////////////////////////////////////////////// +// Internal stream parsing functions +function parseStream(stream) { + // Parse tag, length, and value from stream + const tag = new tag_1.ASN1Tag(stream.getUint8()); + const len = (0, length_1.decodeLength)(stream); + const value = stream.slice(stream.position, len); + const start = stream.position; + let subs = []; + // If the object is constructed, parse its children. Sometimes, children + // are embedded in OCTESTRING objects, so we need to check those + // for children as well. + if (tag.constructed) { + subs = collectSubs(stream, len); + } + else if (tag.isOctetString()) { + // Attempt to parse children of OCTETSTRING objects. If anything fails, + // assume the object is not constructed and treat as primitive. + try { + subs = collectSubs(stream, len); + } + catch (e) { + // Fail silently and treat as primitive + } + } + // If there are no children, move stream cursor to the end of the object + if (subs.length === 0) { + stream.seek(start + len); + } + return new ASN1Obj(tag, value, subs); +} +function collectSubs(stream, len) { + // Calculate end of object content + const end = stream.position + len; + // Make sure there are enough bytes left in the stream. This should never + // happen, cause it'll get caught when the stream is sliced in parseStream. + // Leaving as an extra check just in case. + /* istanbul ignore if */ + if (end > stream.length) { + throw new error_1.ASN1ParseError('invalid length'); + } + // Parse all children + const subs = []; + while (stream.position < end) { + subs.push(parseStream(stream)); + } + // When we're done parsing children, we should be at the end of the object + if (stream.position !== end) { + throw new error_1.ASN1ParseError('invalid length'); + } + return subs; +} diff --git a/node_modules/@sigstore/core/dist/asn1/parse.js b/node_modules/@sigstore/core/dist/asn1/parse.js new file mode 100644 index 0000000000000..7fbb42632c60e --- /dev/null +++ b/node_modules/@sigstore/core/dist/asn1/parse.js @@ -0,0 +1,124 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.parseInteger = parseInteger; +exports.parseStringASCII = parseStringASCII; +exports.parseTime = parseTime; +exports.parseOID = parseOID; +exports.parseBoolean = parseBoolean; +exports.parseBitString = parseBitString; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const RE_TIME_SHORT_YEAR = /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d{3})?Z$/; +const RE_TIME_LONG_YEAR = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d{3})?Z$/; +// Parse a BigInt from the DER-encoded buffer +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-integer +function parseInteger(buf) { + let pos = 0; + const end = buf.length; + let val = buf[pos]; + const neg = val > 0x7f; + // Consume any padding bytes + const pad = neg ? 0xff : 0x00; + while (val == pad && ++pos < end) { + val = buf[pos]; + } + // Calculate remaining bytes to read + const len = end - pos; + if (len === 0) + return BigInt(neg ? -1 : 0); + // Handle two's complement for negative numbers + val = neg ? val - 256 : val; + // Parse remaining bytes + let n = BigInt(val); + for (let i = pos + 1; i < end; ++i) { + n = n * BigInt(256) + BigInt(buf[i]); + } + return n; +} +// Parse an ASCII string from the DER-encoded buffer +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-basic-types#boolean +function parseStringASCII(buf) { + return buf.toString('ascii'); +} +// Parse a Date from the DER-encoded buffer +// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5.1 +function parseTime(buf, shortYear) { + const timeStr = parseStringASCII(buf); + // Parse the time string into matches - captured groups start at index 1 + const m = shortYear + ? RE_TIME_SHORT_YEAR.exec(timeStr) + : RE_TIME_LONG_YEAR.exec(timeStr); + if (!m) { + throw new Error('invalid time'); + } + // Translate dates with a 2-digit year to 4 digits per the spec + if (shortYear) { + let year = Number(m[1]); + year += year >= 50 ? 1900 : 2000; + m[1] = year.toString(); + } + // Translate to ISO8601 format and parse + return new Date(`${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}Z`); +} +// Parse an OID from the DER-encoded buffer +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier +function parseOID(buf) { + let pos = 0; + const end = buf.length; + // Consume first byte which encodes the first two OID components + let n = buf[pos++]; + const first = Math.floor(n / 40); + const second = n % 40; + let oid = `${first}.${second}`; + // Consume remaining bytes + let val = 0; + for (; pos < end; ++pos) { + n = buf[pos]; + val = (val << 7) + (n & 0x7f); + // If the left-most bit is NOT set, then this is the last byte in the + // sequence and we can add the value to the OID and reset the accumulator + if ((n & 0x80) === 0) { + oid += `.${val}`; + val = 0; + } + } + return oid; +} +// Parse a boolean from the DER-encoded buffer +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-basic-types#boolean +function parseBoolean(buf) { + return buf[0] !== 0; +} +// Parse a bit string from the DER-encoded buffer +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-bit-string +function parseBitString(buf) { + // First byte tell us how many unused bits are in the last byte + const unused = buf[0]; + const start = 1; + const end = buf.length; + const bits = []; + for (let i = start; i < end; ++i) { + const byte = buf[i]; + // The skip value is only used for the last byte + const skip = i === end - 1 ? unused : 0; + // Iterate over each bit in the byte (most significant first) + for (let j = 7; j >= skip; --j) { + // Read the bit and add it to the bit string + bits.push((byte >> j) & 0x01); + } + } + return bits; +} diff --git a/node_modules/@sigstore/core/dist/asn1/tag.js b/node_modules/@sigstore/core/dist/asn1/tag.js new file mode 100644 index 0000000000000..ebb4dd562353f --- /dev/null +++ b/node_modules/@sigstore/core/dist/asn1/tag.js @@ -0,0 +1,89 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ASN1Tag = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("./error"); +const UNIVERSAL_TAG = { + BOOLEAN: 0x01, + INTEGER: 0x02, + BIT_STRING: 0x03, + OCTET_STRING: 0x04, + OBJECT_IDENTIFIER: 0x06, + SEQUENCE: 0x10, + SET: 0x11, + PRINTABLE_STRING: 0x13, + UTC_TIME: 0x17, + GENERALIZED_TIME: 0x18, +}; +const TAG_CLASS = { + UNIVERSAL: 0x00, + APPLICATION: 0x01, + CONTEXT_SPECIFIC: 0x02, + PRIVATE: 0x03, +}; +// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-tag-bytes +class ASN1Tag { + number; + constructed; + class; + constructor(enc) { + // Bits 0 through 4 are the tag number + this.number = enc & 0x1f; + // Bit 5 is the constructed bit + this.constructed = (enc & 0x20) === 0x20; + // Bit 6 & 7 are the class + this.class = enc >> 6; + if (this.number === 0x1f) { + throw new error_1.ASN1ParseError('long form tags not supported'); + } + if (this.class === TAG_CLASS.UNIVERSAL && this.number === 0x00) { + throw new error_1.ASN1ParseError('unsupported tag 0x00'); + } + } + isUniversal() { + return this.class === TAG_CLASS.UNIVERSAL; + } + isContextSpecific(num) { + const res = this.class === TAG_CLASS.CONTEXT_SPECIFIC; + return num !== undefined ? res && this.number === num : res; + } + isBoolean() { + return this.isUniversal() && this.number === UNIVERSAL_TAG.BOOLEAN; + } + isInteger() { + return this.isUniversal() && this.number === UNIVERSAL_TAG.INTEGER; + } + isBitString() { + return this.isUniversal() && this.number === UNIVERSAL_TAG.BIT_STRING; + } + isOctetString() { + return this.isUniversal() && this.number === UNIVERSAL_TAG.OCTET_STRING; + } + isOID() { + return (this.isUniversal() && this.number === UNIVERSAL_TAG.OBJECT_IDENTIFIER); + } + isUTCTime() { + return this.isUniversal() && this.number === UNIVERSAL_TAG.UTC_TIME; + } + isGeneralizedTime() { + return this.isUniversal() && this.number === UNIVERSAL_TAG.GENERALIZED_TIME; + } + toDER() { + return this.number | (this.constructed ? 0x20 : 0x00) | (this.class << 6); + } +} +exports.ASN1Tag = ASN1Tag; diff --git a/node_modules/@sigstore/core/dist/crypto.js b/node_modules/@sigstore/core/dist/crypto.js new file mode 100644 index 0000000000000..296b5ba43e86a --- /dev/null +++ b/node_modules/@sigstore/core/dist/crypto.js @@ -0,0 +1,60 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createPublicKey = createPublicKey; +exports.digest = digest; +exports.verify = verify; +exports.bufferEqual = bufferEqual; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const crypto_1 = __importDefault(require("crypto")); +function createPublicKey(key, type = 'spki') { + if (typeof key === 'string') { + return crypto_1.default.createPublicKey(key); + } + else { + return crypto_1.default.createPublicKey({ key, format: 'der', type: type }); + } +} +function digest(algorithm, ...data) { + const hash = crypto_1.default.createHash(algorithm); + for (const d of data) { + hash.update(d); + } + return hash.digest(); +} +function verify(data, key, signature, algorithm) { + // The try/catch is to work around an issue in Node 14.x where verify throws + // an error in some scenarios if the signature is invalid. + try { + return crypto_1.default.verify(algorithm, data, key, signature); + } + catch (e) { + /* istanbul ignore next */ + return false; + } +} +function bufferEqual(a, b) { + try { + return crypto_1.default.timingSafeEqual(a, b); + } + catch { + /* istanbul ignore next */ + return false; + } +} diff --git a/node_modules/@sigstore/core/dist/dsse.js b/node_modules/@sigstore/core/dist/dsse.js new file mode 100644 index 0000000000000..ca7b63630e2ba --- /dev/null +++ b/node_modules/@sigstore/core/dist/dsse.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.preAuthEncoding = preAuthEncoding; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const PAE_PREFIX = 'DSSEv1'; +// DSSE Pre-Authentication Encoding +function preAuthEncoding(payloadType, payload) { + const prefix = [ + PAE_PREFIX, + payloadType.length, + payloadType, + payload.length, + '', + ].join(' '); + return Buffer.concat([Buffer.from(prefix, 'ascii'), payload]); +} diff --git a/node_modules/@sigstore/core/dist/encoding.js b/node_modules/@sigstore/core/dist/encoding.js new file mode 100644 index 0000000000000..7113af66db4c2 --- /dev/null +++ b/node_modules/@sigstore/core/dist/encoding.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.base64Encode = base64Encode; +exports.base64Decode = base64Decode; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const BASE64_ENCODING = 'base64'; +const UTF8_ENCODING = 'utf-8'; +function base64Encode(str) { + return Buffer.from(str, UTF8_ENCODING).toString(BASE64_ENCODING); +} +function base64Decode(str) { + return Buffer.from(str, BASE64_ENCODING).toString(UTF8_ENCODING); +} diff --git a/node_modules/@sigstore/core/dist/index.js b/node_modules/@sigstore/core/dist/index.js new file mode 100644 index 0000000000000..49859d84db756 --- /dev/null +++ b/node_modules/@sigstore/core/dist/index.js @@ -0,0 +1,66 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.X509SCTExtension = exports.X509Certificate = exports.EXTENSION_OID_SCT = exports.ByteStream = exports.RFC3161Timestamp = exports.pem = exports.json = exports.encoding = exports.dsse = exports.crypto = exports.ASN1Obj = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var asn1_1 = require("./asn1"); +Object.defineProperty(exports, "ASN1Obj", { enumerable: true, get: function () { return asn1_1.ASN1Obj; } }); +exports.crypto = __importStar(require("./crypto")); +exports.dsse = __importStar(require("./dsse")); +exports.encoding = __importStar(require("./encoding")); +exports.json = __importStar(require("./json")); +exports.pem = __importStar(require("./pem")); +var rfc3161_1 = require("./rfc3161"); +Object.defineProperty(exports, "RFC3161Timestamp", { enumerable: true, get: function () { return rfc3161_1.RFC3161Timestamp; } }); +var stream_1 = require("./stream"); +Object.defineProperty(exports, "ByteStream", { enumerable: true, get: function () { return stream_1.ByteStream; } }); +var x509_1 = require("./x509"); +Object.defineProperty(exports, "EXTENSION_OID_SCT", { enumerable: true, get: function () { return x509_1.EXTENSION_OID_SCT; } }); +Object.defineProperty(exports, "X509Certificate", { enumerable: true, get: function () { return x509_1.X509Certificate; } }); +Object.defineProperty(exports, "X509SCTExtension", { enumerable: true, get: function () { return x509_1.X509SCTExtension; } }); diff --git a/node_modules/@sigstore/core/dist/json.js b/node_modules/@sigstore/core/dist/json.js new file mode 100644 index 0000000000000..7808d033b98cc --- /dev/null +++ b/node_modules/@sigstore/core/dist/json.js @@ -0,0 +1,60 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.canonicalize = canonicalize; +// JSON canonicalization per https://github.com/cyberphone/json-canonicalization +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function canonicalize(object) { + let buffer = ''; + if (object === null || typeof object !== 'object' || object.toJSON != null) { + // Primitives or toJSONable objects + buffer += JSON.stringify(object); + } + else if (Array.isArray(object)) { + // Array - maintain element order + buffer += '['; + let first = true; + object.forEach((element) => { + if (!first) { + buffer += ','; + } + first = false; + // recursive call + buffer += canonicalize(element); + }); + buffer += ']'; + } + else { + // Object - Sort properties before serializing + buffer += '{'; + let first = true; + Object.keys(object) + .sort() + .forEach((property) => { + if (!first) { + buffer += ','; + } + first = false; + buffer += JSON.stringify(property); + buffer += ':'; + // recursive call + buffer += canonicalize(object[property]); + }); + buffer += '}'; + } + return buffer; +} diff --git a/node_modules/@sigstore/core/dist/oid.js b/node_modules/@sigstore/core/dist/oid.js new file mode 100644 index 0000000000000..4438ac9bdca98 --- /dev/null +++ b/node_modules/@sigstore/core/dist/oid.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SHA2_HASH_ALGOS = exports.RSA_SIGNATURE_ALGOS = exports.ECDSA_SIGNATURE_ALGOS = void 0; +exports.ECDSA_SIGNATURE_ALGOS = { + '1.2.840.10045.4.3.1': 'sha224', + '1.2.840.10045.4.3.2': 'sha256', + '1.2.840.10045.4.3.3': 'sha384', + '1.2.840.10045.4.3.4': 'sha512', +}; +exports.RSA_SIGNATURE_ALGOS = { + '1.2.840.113549.1.1.14': 'sha224', + '1.2.840.113549.1.1.11': 'sha256', + '1.2.840.113549.1.1.12': 'sha384', + '1.2.840.113549.1.1.13': 'sha512', +}; +exports.SHA2_HASH_ALGOS = { + '2.16.840.1.101.3.4.2.1': 'sha256', + '2.16.840.1.101.3.4.2.2': 'sha384', + '2.16.840.1.101.3.4.2.3': 'sha512', +}; diff --git a/node_modules/@sigstore/core/dist/pem.js b/node_modules/@sigstore/core/dist/pem.js new file mode 100644 index 0000000000000..f1241d28d586e --- /dev/null +++ b/node_modules/@sigstore/core/dist/pem.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toDER = toDER; +exports.fromDER = fromDER; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const PEM_HEADER = /-----BEGIN (.*)-----/; +const PEM_FOOTER = /-----END (.*)-----/; +function toDER(certificate) { + let der = ''; + certificate.split('\n').forEach((line) => { + if (line.match(PEM_HEADER) || line.match(PEM_FOOTER)) { + return; + } + der += line; + }); + return Buffer.from(der, 'base64'); +} +// Translates a DER-encoded buffer into a PEM-encoded string. Standard PEM +// encoding dictates that each certificate should have a trailing newline after +// the footer. +function fromDER(certificate, type = 'CERTIFICATE') { + // Base64-encode the certificate. + const der = certificate.toString('base64'); + // Split the certificate into lines of 64 characters. + const lines = der.match(/.{1,64}/g) || ''; + return [`-----BEGIN ${type}-----`, ...lines, `-----END ${type}-----`] + .join('\n') + .concat('\n'); +} diff --git a/node_modules/@sigstore/core/dist/rfc3161/error.js b/node_modules/@sigstore/core/dist/rfc3161/error.js new file mode 100644 index 0000000000000..b9b549b0bb323 --- /dev/null +++ b/node_modules/@sigstore/core/dist/rfc3161/error.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RFC3161TimestampVerificationError = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +class RFC3161TimestampVerificationError extends Error { +} +exports.RFC3161TimestampVerificationError = RFC3161TimestampVerificationError; diff --git a/node_modules/@sigstore/core/dist/rfc3161/index.js b/node_modules/@sigstore/core/dist/rfc3161/index.js new file mode 100644 index 0000000000000..b77ecf1c7d50c --- /dev/null +++ b/node_modules/@sigstore/core/dist/rfc3161/index.js @@ -0,0 +1,20 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RFC3161Timestamp = void 0; +var timestamp_1 = require("./timestamp"); +Object.defineProperty(exports, "RFC3161Timestamp", { enumerable: true, get: function () { return timestamp_1.RFC3161Timestamp; } }); diff --git a/node_modules/@sigstore/core/dist/rfc3161/timestamp.js b/node_modules/@sigstore/core/dist/rfc3161/timestamp.js new file mode 100644 index 0000000000000..a7034526ecbce --- /dev/null +++ b/node_modules/@sigstore/core/dist/rfc3161/timestamp.js @@ -0,0 +1,212 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RFC3161Timestamp = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const asn1_1 = require("../asn1"); +const crypto = __importStar(require("../crypto")); +const oid_1 = require("../oid"); +const error_1 = require("./error"); +const tstinfo_1 = require("./tstinfo"); +const OID_PKCS9_CONTENT_TYPE_SIGNED_DATA = '1.2.840.113549.1.7.2'; +const OID_PKCS9_CONTENT_TYPE_TSTINFO = '1.2.840.113549.1.9.16.1.4'; +const OID_PKCS9_MESSAGE_DIGEST_KEY = '1.2.840.113549.1.9.4'; +class RFC3161Timestamp { + root; + constructor(asn1) { + this.root = asn1; + } + static parse(der) { + const asn1 = asn1_1.ASN1Obj.parseBuffer(der); + return new RFC3161Timestamp(asn1); + } + get status() { + return this.pkiStatusInfoObj.subs[0].toInteger(); + } + get contentType() { + return this.contentTypeObj.toOID(); + } + get eContentType() { + return this.eContentTypeObj.toOID(); + } + get signingTime() { + return this.tstInfo.genTime; + } + get signerIssuer() { + return this.signerSidObj.subs[0].value; + } + get signerSerialNumber() { + return this.signerSidObj.subs[1].value; + } + get signerDigestAlgorithm() { + const oid = this.signerDigestAlgorithmObj.subs[0].toOID(); + return oid_1.SHA2_HASH_ALGOS[oid]; + } + get signatureAlgorithm() { + const oid = this.signatureAlgorithmObj.subs[0].toOID(); + return oid_1.ECDSA_SIGNATURE_ALGOS[oid]; + } + get signatureValue() { + return this.signatureValueObj.value; + } + get tstInfo() { + // Need to unpack tstInfo from an OCTET STRING + return new tstinfo_1.TSTInfo(this.eContentObj.subs[0].subs[0]); + } + verify(data, publicKey) { + if (!this.timeStampTokenObj) { + throw new error_1.RFC3161TimestampVerificationError('timeStampToken is missing'); + } + // Check for expected ContentInfo content type + if (this.contentType !== OID_PKCS9_CONTENT_TYPE_SIGNED_DATA) { + throw new error_1.RFC3161TimestampVerificationError(`incorrect content type: ${this.contentType}`); + } + // Check for expected encapsulated content type + if (this.eContentType !== OID_PKCS9_CONTENT_TYPE_TSTINFO) { + throw new error_1.RFC3161TimestampVerificationError(`incorrect encapsulated content type: ${this.eContentType}`); + } + // Check that the tstInfo references the correct artifact + this.tstInfo.verify(data); + // Check that the signed message digest matches the tstInfo + this.verifyMessageDigest(); + // Check that the signature is valid for the signed attributes + this.verifySignature(publicKey); + } + verifyMessageDigest() { + // Check that the tstInfo matches the signed data + const tstInfoDigest = crypto.digest(this.signerDigestAlgorithm, this.tstInfo.raw); + const expectedDigest = this.messageDigestAttributeObj.subs[1].subs[0].value; + if (!crypto.bufferEqual(tstInfoDigest, expectedDigest)) { + throw new error_1.RFC3161TimestampVerificationError('signed data does not match tstInfo'); + } + } + verifySignature(key) { + // Encode the signed attributes for verification + const signedAttrs = this.signedAttrsObj.toDER(); + signedAttrs[0] = 0x31; // Change context-specific tag to SET + // Check that the signature is valid for the signed attributes + const verified = crypto.verify(signedAttrs, key, this.signatureValue, this.signatureAlgorithm); + if (!verified) { + throw new error_1.RFC3161TimestampVerificationError('signature verification failed'); + } + } + // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2 + get pkiStatusInfoObj() { + // pkiStatusInfo is the first element of the timestamp response sequence + return this.root.subs[0]; + } + // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2 + get timeStampTokenObj() { + // timeStampToken is the first element of the timestamp response sequence + return this.root.subs[1]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-3 + get contentTypeObj() { + return this.timeStampTokenObj.subs[0]; + } + // https://www.rfc-editor.org/rfc/rfc5652#section-3 + get signedDataObj() { + const obj = this.timeStampTokenObj.subs.find((sub) => sub.tag.isContextSpecific(0x00)); + return obj.subs[0]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.1 + get encapContentInfoObj() { + return this.signedDataObj.subs[2]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.1 + get signerInfosObj() { + // SignerInfos is the last element of the signed data sequence + const sd = this.signedDataObj; + return sd.subs[sd.subs.length - 1]; + } + // https://www.rfc-editor.org/rfc/rfc5652#section-5.1 + get signerInfoObj() { + // Only supporting one signer + return this.signerInfosObj.subs[0]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.2 + get eContentTypeObj() { + return this.encapContentInfoObj.subs[0]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.2 + get eContentObj() { + return this.encapContentInfoObj.subs[1]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 + get signedAttrsObj() { + const signedAttrs = this.signerInfoObj.subs.find((sub) => sub.tag.isContextSpecific(0x00)); + return signedAttrs; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 + get messageDigestAttributeObj() { + const messageDigest = this.signedAttrsObj.subs.find((sub) => sub.subs[0].tag.isOID() && + sub.subs[0].toOID() === OID_PKCS9_MESSAGE_DIGEST_KEY); + return messageDigest; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 + get signerSidObj() { + return this.signerInfoObj.subs[1]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 + get signerDigestAlgorithmObj() { + // Signature is the 2nd element of the signerInfoObj object + return this.signerInfoObj.subs[2]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 + get signatureAlgorithmObj() { + // Signature is the 4th element of the signerInfoObj object + return this.signerInfoObj.subs[4]; + } + // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3 + get signatureValueObj() { + // Signature is the 6th element of the signerInfoObj object + return this.signerInfoObj.subs[5]; + } +} +exports.RFC3161Timestamp = RFC3161Timestamp; diff --git a/node_modules/@sigstore/core/dist/rfc3161/tstinfo.js b/node_modules/@sigstore/core/dist/rfc3161/tstinfo.js new file mode 100644 index 0000000000000..91213529b6605 --- /dev/null +++ b/node_modules/@sigstore/core/dist/rfc3161/tstinfo.js @@ -0,0 +1,72 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TSTInfo = void 0; +const crypto = __importStar(require("../crypto")); +const oid_1 = require("../oid"); +const error_1 = require("./error"); +class TSTInfo { + root; + constructor(asn1) { + this.root = asn1; + } + get version() { + return this.root.subs[0].toInteger(); + } + get genTime() { + return this.root.subs[4].toDate(); + } + get messageImprintHashAlgorithm() { + const oid = this.messageImprintObj.subs[0].subs[0].toOID(); + return oid_1.SHA2_HASH_ALGOS[oid]; + } + get messageImprintHashedMessage() { + return this.messageImprintObj.subs[1].value; + } + get raw() { + return this.root.toDER(); + } + verify(data) { + const digest = crypto.digest(this.messageImprintHashAlgorithm, data); + if (!crypto.bufferEqual(digest, this.messageImprintHashedMessage)) { + throw new error_1.RFC3161TimestampVerificationError('message imprint does not match artifact'); + } + } + // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2 + get messageImprintObj() { + return this.root.subs[2]; + } +} +exports.TSTInfo = TSTInfo; diff --git a/node_modules/@sigstore/core/dist/stream.js b/node_modules/@sigstore/core/dist/stream.js new file mode 100644 index 0000000000000..c69b3097a2dd2 --- /dev/null +++ b/node_modules/@sigstore/core/dist/stream.js @@ -0,0 +1,117 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ByteStream = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +class StreamError extends Error { +} +class ByteStream { + static BLOCK_SIZE = 1024; + buf; + view; + start = 0; + constructor(buffer) { + if (buffer) { + this.buf = buffer; + this.view = Buffer.from(buffer); + } + else { + this.buf = Buffer.alloc(0); + this.view = Buffer.from(this.buf); + } + } + get buffer() { + return this.view.subarray(0, this.start); + } + get length() { + return this.view.byteLength; + } + get position() { + return this.start; + } + seek(position) { + this.start = position; + } + // Returns a Buffer containing the specified number of bytes starting at the + // given start position. + slice(start, len) { + const end = start + len; + if (end > this.length) { + throw new StreamError('request past end of buffer'); + } + return this.view.subarray(start, end); + } + appendChar(char) { + this.ensureCapacity(1); + this.view[this.start] = char; + this.start += 1; + } + appendUint16(num) { + this.ensureCapacity(2); + const value = new Uint16Array([num]); + const view = new Uint8Array(value.buffer); + this.view[this.start] = view[1]; + this.view[this.start + 1] = view[0]; + this.start += 2; + } + appendUint24(num) { + this.ensureCapacity(3); + const value = new Uint32Array([num]); + const view = new Uint8Array(value.buffer); + this.view[this.start] = view[2]; + this.view[this.start + 1] = view[1]; + this.view[this.start + 2] = view[0]; + this.start += 3; + } + appendView(view) { + this.ensureCapacity(view.length); + this.view.set(view, this.start); + this.start += view.length; + } + getBlock(size) { + if (size <= 0) { + return Buffer.alloc(0); + } + if (this.start + size > this.view.length) { + throw new Error('request past end of buffer'); + } + const result = this.view.subarray(this.start, this.start + size); + this.start += size; + return result; + } + getUint8() { + return this.getBlock(1)[0]; + } + getUint16() { + const block = this.getBlock(2); + return (block[0] << 8) | block[1]; + } + ensureCapacity(size) { + if (this.start + size > this.view.byteLength) { + const blockSize = ByteStream.BLOCK_SIZE + (size > ByteStream.BLOCK_SIZE ? size : 0); + this.realloc(this.view.byteLength + blockSize); + } + } + realloc(size) { + const newArray = Buffer.alloc(size); + const newView = Buffer.from(newArray); + // Copy the old buffer into the new one + newView.set(this.view); + this.buf = newArray; + this.view = newView; + } +} +exports.ByteStream = ByteStream; diff --git a/node_modules/@sigstore/core/dist/x509/cert.js b/node_modules/@sigstore/core/dist/x509/cert.js new file mode 100644 index 0000000000000..0e1126ba4a298 --- /dev/null +++ b/node_modules/@sigstore/core/dist/x509/cert.js @@ -0,0 +1,245 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.X509Certificate = exports.EXTENSION_OID_SCT = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const asn1_1 = require("../asn1"); +const crypto = __importStar(require("../crypto")); +const oid_1 = require("../oid"); +const pem = __importStar(require("../pem")); +const ext_1 = require("./ext"); +const EXTENSION_OID_SUBJECT_KEY_ID = '2.5.29.14'; +const EXTENSION_OID_KEY_USAGE = '2.5.29.15'; +const EXTENSION_OID_SUBJECT_ALT_NAME = '2.5.29.17'; +const EXTENSION_OID_BASIC_CONSTRAINTS = '2.5.29.19'; +const EXTENSION_OID_AUTHORITY_KEY_ID = '2.5.29.35'; +exports.EXTENSION_OID_SCT = '1.3.6.1.4.1.11129.2.4.2'; +class X509Certificate { + root; + constructor(asn1) { + this.root = asn1; + } + static parse(cert) { + const der = typeof cert === 'string' ? pem.toDER(cert) : cert; + const asn1 = asn1_1.ASN1Obj.parseBuffer(der); + return new X509Certificate(asn1); + } + get tbsCertificate() { + return this.tbsCertificateObj; + } + get version() { + // version number is the first element of the version context specific tag + const ver = this.versionObj.subs[0].toInteger(); + return `v${(ver + BigInt(1)).toString()}`; + } + get serialNumber() { + return this.serialNumberObj.value; + } + get notBefore() { + // notBefore is the first element of the validity sequence + return this.validityObj.subs[0].toDate(); + } + get notAfter() { + // notAfter is the second element of the validity sequence + return this.validityObj.subs[1].toDate(); + } + get issuer() { + return this.issuerObj.value; + } + get subject() { + return this.subjectObj.value; + } + get publicKey() { + return this.subjectPublicKeyInfoObj.toDER(); + } + get signatureAlgorithm() { + const oid = this.signatureAlgorithmObj.subs[0].toOID(); + if (oid_1.RSA_SIGNATURE_ALGOS[oid]) { + return oid_1.RSA_SIGNATURE_ALGOS[oid]; + } + return oid_1.ECDSA_SIGNATURE_ALGOS[oid]; + } + get signatureValue() { + // Signature value is a bit string, so we need to skip the first byte + return this.signatureValueObj.value.subarray(1); + } + get subjectAltName() { + const ext = this.extSubjectAltName; + return ext?.uri || /* istanbul ignore next */ ext?.rfc822Name; + } + get extensions() { + // The extension list is the first (and only) element of the extensions + // context specific tag + /* istanbul ignore next */ + const extSeq = this.extensionsObj?.subs[0]; + /* istanbul ignore next */ + return extSeq?.subs || []; + } + get extKeyUsage() { + const ext = this.findExtension(EXTENSION_OID_KEY_USAGE); + return ext ? new ext_1.X509KeyUsageExtension(ext) : undefined; + } + get extBasicConstraints() { + const ext = this.findExtension(EXTENSION_OID_BASIC_CONSTRAINTS); + return ext ? new ext_1.X509BasicConstraintsExtension(ext) : undefined; + } + get extSubjectAltName() { + const ext = this.findExtension(EXTENSION_OID_SUBJECT_ALT_NAME); + return ext ? new ext_1.X509SubjectAlternativeNameExtension(ext) : undefined; + } + get extAuthorityKeyID() { + const ext = this.findExtension(EXTENSION_OID_AUTHORITY_KEY_ID); + return ext ? new ext_1.X509AuthorityKeyIDExtension(ext) : undefined; + } + get extSubjectKeyID() { + const ext = this.findExtension(EXTENSION_OID_SUBJECT_KEY_ID); + return ext + ? new ext_1.X509SubjectKeyIDExtension(ext) + : /* istanbul ignore next */ undefined; + } + get extSCT() { + const ext = this.findExtension(exports.EXTENSION_OID_SCT); + return ext ? new ext_1.X509SCTExtension(ext) : undefined; + } + get isCA() { + const ca = this.extBasicConstraints?.isCA || false; + // If the KeyUsage extension is present, keyCertSign must be set + /* istanbul ignore else */ + if (this.extKeyUsage) { + return ca && this.extKeyUsage.keyCertSign; + } + // TODO: test coverage for this case + /* istanbul ignore next */ + return ca; + } + extension(oid) { + const ext = this.findExtension(oid); + return ext ? new ext_1.X509Extension(ext) : undefined; + } + verify(issuerCertificate) { + // Use the issuer's public key if provided, otherwise use the subject's + const publicKey = issuerCertificate?.publicKey || this.publicKey; + const key = crypto.createPublicKey(publicKey); + return crypto.verify(this.tbsCertificate.toDER(), key, this.signatureValue, this.signatureAlgorithm); + } + validForDate(date) { + return this.notBefore <= date && date <= this.notAfter; + } + equals(other) { + return this.root.toDER().equals(other.root.toDER()); + } + // Creates a copy of the certificate with a new buffer + clone() { + const der = this.root.toDER(); + const clone = Buffer.alloc(der.length); + der.copy(clone); + return X509Certificate.parse(clone); + } + findExtension(oid) { + // Find the extension with the given OID. The OID will always be the first + // element of the extension sequence + return this.extensions.find((ext) => ext.subs[0].toOID() === oid); + } + ///////////////////////////////////////////////////////////////////////////// + // The following properties use the documented x509 structure to locate the + // desired ASN.1 object + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1 + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.1 + get tbsCertificateObj() { + // tbsCertificate is the first element of the certificate sequence + return this.root.subs[0]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.2 + get signatureAlgorithmObj() { + // signatureAlgorithm is the second element of the certificate sequence + return this.root.subs[1]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.3 + get signatureValueObj() { + // signatureValue is the third element of the certificate sequence + return this.root.subs[2]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.1 + get versionObj() { + // version is the first element of the tbsCertificate sequence + return this.tbsCertificateObj.subs[0]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.2 + get serialNumberObj() { + // serialNumber is the second element of the tbsCertificate sequence + return this.tbsCertificateObj.subs[1]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.4 + get issuerObj() { + // issuer is the fourth element of the tbsCertificate sequence + return this.tbsCertificateObj.subs[3]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5 + get validityObj() { + // version is the fifth element of the tbsCertificate sequence + return this.tbsCertificateObj.subs[4]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.6 + get subjectObj() { + // subject is the sixth element of the tbsCertificate sequence + return this.tbsCertificateObj.subs[5]; + } + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.7 + get subjectPublicKeyInfoObj() { + // subjectPublicKeyInfo is the seventh element of the tbsCertificate sequence + return this.tbsCertificateObj.subs[6]; + } + // Extensions can't be located by index because their position varies. Instead, + // we need to find the extensions context specific tag + // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.9 + get extensionsObj() { + return this.tbsCertificateObj.subs.find((sub) => sub.tag.isContextSpecific(0x03)); + } +} +exports.X509Certificate = X509Certificate; diff --git a/node_modules/@sigstore/core/dist/x509/ext.js b/node_modules/@sigstore/core/dist/x509/ext.js new file mode 100644 index 0000000000000..10f37fe256efe --- /dev/null +++ b/node_modules/@sigstore/core/dist/x509/ext.js @@ -0,0 +1,146 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.X509SCTExtension = exports.X509SubjectKeyIDExtension = exports.X509AuthorityKeyIDExtension = exports.X509SubjectAlternativeNameExtension = exports.X509KeyUsageExtension = exports.X509BasicConstraintsExtension = exports.X509Extension = void 0; +const stream_1 = require("../stream"); +const sct_1 = require("./sct"); +// https://www.rfc-editor.org/rfc/rfc5280#section-4.1 +class X509Extension { + root; + constructor(asn1) { + this.root = asn1; + } + get oid() { + return this.root.subs[0].toOID(); + } + get critical() { + // The critical field is optional and will be the second element of the + // extension sequence if present. Default to false if not present. + return this.root.subs.length === 3 ? this.root.subs[1].toBoolean() : false; + } + get value() { + return this.extnValueObj.value; + } + get valueObj() { + return this.extnValueObj; + } + get extnValueObj() { + // The extnValue field will be the last element of the extension sequence + return this.root.subs[this.root.subs.length - 1]; + } +} +exports.X509Extension = X509Extension; +// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9 +class X509BasicConstraintsExtension extends X509Extension { + get isCA() { + return this.sequence.subs[0]?.toBoolean() ?? false; + } + get pathLenConstraint() { + return this.sequence.subs.length > 1 + ? this.sequence.subs[1].toInteger() + : undefined; + } + // The extnValue field contains a single sequence wrapping the isCA and + // pathLenConstraint. + get sequence() { + return this.extnValueObj.subs[0]; + } +} +exports.X509BasicConstraintsExtension = X509BasicConstraintsExtension; +// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.3 +class X509KeyUsageExtension extends X509Extension { + get digitalSignature() { + return this.bitString[0] === 1; + } + get keyCertSign() { + return this.bitString[5] === 1; + } + get crlSign() { + return this.bitString[6] === 1; + } + // The extnValue field contains a single bit string which is a bit mask + // indicating which key usages are enabled. + get bitString() { + return this.extnValueObj.subs[0].toBitString(); + } +} +exports.X509KeyUsageExtension = X509KeyUsageExtension; +// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.6 +class X509SubjectAlternativeNameExtension extends X509Extension { + get rfc822Name() { + return this.findGeneralName(0x01)?.value.toString('ascii'); + } + get uri() { + return this.findGeneralName(0x06)?.value.toString('ascii'); + } + // Retrieve the value of an otherName with the given OID. + otherName(oid) { + const otherName = this.findGeneralName(0x00); + if (otherName === undefined) { + return undefined; + } + // The otherName is a sequence containing an OID and a value. + // Need to check that the OID matches the one we're looking for. + const otherNameOID = otherName.subs[0].toOID(); + if (otherNameOID !== oid) { + return undefined; + } + // The otherNameValue is a sequence containing the actual value. + const otherNameValue = otherName.subs[1]; + return otherNameValue.subs[0].value.toString('ascii'); + } + findGeneralName(tag) { + return this.generalNames.find((gn) => gn.tag.isContextSpecific(tag)); + } + // The extnValue field contains a sequence of GeneralNames. + get generalNames() { + return this.extnValueObj.subs[0].subs; + } +} +exports.X509SubjectAlternativeNameExtension = X509SubjectAlternativeNameExtension; +// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.1 +class X509AuthorityKeyIDExtension extends X509Extension { + get keyIdentifier() { + return this.findSequenceMember(0x00)?.value; + } + findSequenceMember(tag) { + return this.sequence.subs.find((el) => el.tag.isContextSpecific(tag)); + } + // The extnValue field contains a single sequence wrapping the keyIdentifier + get sequence() { + return this.extnValueObj.subs[0]; + } +} +exports.X509AuthorityKeyIDExtension = X509AuthorityKeyIDExtension; +// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.2 +class X509SubjectKeyIDExtension extends X509Extension { + get keyIdentifier() { + return this.extnValueObj.subs[0].value; + } +} +exports.X509SubjectKeyIDExtension = X509SubjectKeyIDExtension; +// https://www.rfc-editor.org/rfc/rfc6962#section-3.3 +class X509SCTExtension extends X509Extension { + constructor(asn1) { + super(asn1); + } + get signedCertificateTimestamps() { + const buf = this.extnValueObj.subs[0].value; + const stream = new stream_1.ByteStream(buf); + // The overall list length is encoded in the first two bytes -- note this + // is the length of the list in bytes, NOT the number of SCTs in the list + const end = stream.getUint16() + 2; + const sctList = []; + while (stream.position < end) { + // Read the length of the next SCT + const sctLength = stream.getUint16(); + // Slice out the bytes for the next SCT and parse it + const sct = stream.getBlock(sctLength); + sctList.push(sct_1.SignedCertificateTimestamp.parse(sct)); + } + if (stream.position !== end) { + throw new Error('SCT list length does not match actual length'); + } + return sctList; + } +} +exports.X509SCTExtension = X509SCTExtension; diff --git a/node_modules/@sigstore/core/dist/x509/index.js b/node_modules/@sigstore/core/dist/x509/index.js new file mode 100644 index 0000000000000..cdd77e58f37d5 --- /dev/null +++ b/node_modules/@sigstore/core/dist/x509/index.js @@ -0,0 +1,23 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.X509SCTExtension = exports.X509Certificate = exports.EXTENSION_OID_SCT = void 0; +var cert_1 = require("./cert"); +Object.defineProperty(exports, "EXTENSION_OID_SCT", { enumerable: true, get: function () { return cert_1.EXTENSION_OID_SCT; } }); +Object.defineProperty(exports, "X509Certificate", { enumerable: true, get: function () { return cert_1.X509Certificate; } }); +var ext_1 = require("./ext"); +Object.defineProperty(exports, "X509SCTExtension", { enumerable: true, get: function () { return ext_1.X509SCTExtension; } }); diff --git a/node_modules/@sigstore/core/dist/x509/sct.js b/node_modules/@sigstore/core/dist/x509/sct.js new file mode 100644 index 0000000000000..338e3478fd45e --- /dev/null +++ b/node_modules/@sigstore/core/dist/x509/sct.js @@ -0,0 +1,158 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SignedCertificateTimestamp = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const crypto = __importStar(require("../crypto")); +const stream_1 = require("../stream"); +class SignedCertificateTimestamp { + version; + logID; + timestamp; + extensions; + hashAlgorithm; + signatureAlgorithm; + signature; + constructor(options) { + this.version = options.version; + this.logID = options.logID; + this.timestamp = options.timestamp; + this.extensions = options.extensions; + this.hashAlgorithm = options.hashAlgorithm; + this.signatureAlgorithm = options.signatureAlgorithm; + this.signature = options.signature; + } + get datetime() { + return new Date(Number(this.timestamp.readBigInt64BE())); + } + // Returns the hash algorithm used to generate the SCT's signature. + // https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1 + get algorithm() { + switch (this.hashAlgorithm) { + /* istanbul ignore next */ + case 0: + return 'none'; + /* istanbul ignore next */ + case 1: + return 'md5'; + /* istanbul ignore next */ + case 2: + return 'sha1'; + /* istanbul ignore next */ + case 3: + return 'sha224'; + case 4: + return 'sha256'; + /* istanbul ignore next */ + case 5: + return 'sha384'; + /* istanbul ignore next */ + case 6: + return 'sha512'; + /* istanbul ignore next */ + default: + return 'unknown'; + } + } + verify(preCert, key) { + // Assemble the digitally-signed struct (the data over which the signature + // was generated). + // https://www.rfc-editor.org/rfc/rfc6962#section-3.2 + const stream = new stream_1.ByteStream(); + stream.appendChar(this.version); + stream.appendChar(0x00); // SignatureType = certificate_timestamp(0) + stream.appendView(this.timestamp); + stream.appendUint16(0x01); // LogEntryType = precert_entry(1) + stream.appendView(preCert); + stream.appendUint16(this.extensions.byteLength); + /* istanbul ignore next - extensions are very uncommon */ + if (this.extensions.byteLength > 0) { + stream.appendView(this.extensions); + } + return crypto.verify(stream.buffer, key, this.signature, this.algorithm); + } + // Parses a SignedCertificateTimestamp from a buffer. SCTs are encoded using + // TLS encoding which means the fields and lengths of most fields are + // specified as part of the SCT and TLS specs. + // https://www.rfc-editor.org/rfc/rfc6962#section-3.2 + // https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1 + static parse(buf) { + const stream = new stream_1.ByteStream(buf); + // Version - enum { v1(0), (255) } + const version = stream.getUint8(); + // Log ID - struct { opaque key_id[32]; } + const logID = stream.getBlock(32); + // Timestamp - uint64 + const timestamp = stream.getBlock(8); + // Extensions - opaque extensions<0..2^16-1>; + const extenstionLength = stream.getUint16(); + const extensions = stream.getBlock(extenstionLength); + // Hash algo - enum { sha256(4), . . . (255) } + const hashAlgorithm = stream.getUint8(); + // Signature algo - enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } + const signatureAlgorithm = stream.getUint8(); + // Signature - opaque signature<0..2^16-1>; + const sigLength = stream.getUint16(); + const signature = stream.getBlock(sigLength); + // Check that we read the entire buffer + if (stream.position !== buf.length) { + throw new Error('SCT buffer length mismatch'); + } + return new SignedCertificateTimestamp({ + version, + logID, + timestamp, + extensions, + hashAlgorithm, + signatureAlgorithm, + signature, + }); + } +} +exports.SignedCertificateTimestamp = SignedCertificateTimestamp; diff --git a/node_modules/@sigstore/core/package.json b/node_modules/@sigstore/core/package.json new file mode 100644 index 0000000000000..8cd757103e7a1 --- /dev/null +++ b/node_modules/@sigstore/core/package.json @@ -0,0 +1,31 @@ +{ + "name": "@sigstore/core", + "version": "3.1.0", + "description": "Base library for Sigstore", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "shx rm -rf dist *.tsbuildinfo", + "build": "tsc --build", + "test": "jest" + }, + "files": [ + "dist" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/sigstore-js.git" + }, + "bugs": { + "url": "https://github.com/sigstore/sigstore-js/issues" + }, + "homepage": "https://github.com/sigstore/sigstore-js/tree/main/packages/core#readme", + "publishConfig": { + "provenance": true + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/@sigstore/protobuf-specs/LICENSE b/node_modules/@sigstore/protobuf-specs/LICENSE new file mode 100644 index 0000000000000..e9e7c1679a09d --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 The Sigstore Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/envelope.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/envelope.js new file mode 100644 index 0000000000000..5c4f37bfaf3fb --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/envelope.js @@ -0,0 +1,59 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: envelope.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Signature = exports.Envelope = void 0; +exports.Envelope = { + fromJSON(object) { + return { + payload: isSet(object.payload) ? Buffer.from(bytesFromBase64(object.payload)) : Buffer.alloc(0), + payloadType: isSet(object.payloadType) ? globalThis.String(object.payloadType) : "", + signatures: globalThis.Array.isArray(object?.signatures) + ? object.signatures.map((e) => exports.Signature.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.payload.length !== 0) { + obj.payload = base64FromBytes(message.payload); + } + if (message.payloadType !== "") { + obj.payloadType = message.payloadType; + } + if (message.signatures?.length) { + obj.signatures = message.signatures.map((e) => exports.Signature.toJSON(e)); + } + return obj; + }, +}; +exports.Signature = { + fromJSON(object) { + return { + sig: isSet(object.sig) ? Buffer.from(bytesFromBase64(object.sig)) : Buffer.alloc(0), + keyid: isSet(object.keyid) ? globalThis.String(object.keyid) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.sig.length !== 0) { + obj.sig = base64FromBytes(message.sig); + } + if (message.keyid !== "") { + obj.keyid = message.keyid; + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/events.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/events.js new file mode 100644 index 0000000000000..6138fef5672fc --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/events.js @@ -0,0 +1,174 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: events.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CloudEventBatch = exports.CloudEvent_CloudEventAttributeValue = exports.CloudEvent_AttributesEntry = exports.CloudEvent = void 0; +/* eslint-disable */ +const any_1 = require("./google/protobuf/any"); +const timestamp_1 = require("./google/protobuf/timestamp"); +exports.CloudEvent = { + fromJSON(object) { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + source: isSet(object.source) ? globalThis.String(object.source) : "", + specVersion: isSet(object.specVersion) ? globalThis.String(object.specVersion) : "", + type: isSet(object.type) ? globalThis.String(object.type) : "", + attributes: isObject(object.attributes) + ? Object.entries(object.attributes).reduce((acc, [key, value]) => { + acc[key] = exports.CloudEvent_CloudEventAttributeValue.fromJSON(value); + return acc; + }, {}) + : {}, + data: isSet(object.binaryData) + ? { $case: "binaryData", binaryData: Buffer.from(bytesFromBase64(object.binaryData)) } + : isSet(object.textData) + ? { $case: "textData", textData: globalThis.String(object.textData) } + : isSet(object.protoData) + ? { $case: "protoData", protoData: any_1.Any.fromJSON(object.protoData) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.source !== "") { + obj.source = message.source; + } + if (message.specVersion !== "") { + obj.specVersion = message.specVersion; + } + if (message.type !== "") { + obj.type = message.type; + } + if (message.attributes) { + const entries = Object.entries(message.attributes); + if (entries.length > 0) { + obj.attributes = {}; + entries.forEach(([k, v]) => { + obj.attributes[k] = exports.CloudEvent_CloudEventAttributeValue.toJSON(v); + }); + } + } + if (message.data?.$case === "binaryData") { + obj.binaryData = base64FromBytes(message.data.binaryData); + } + else if (message.data?.$case === "textData") { + obj.textData = message.data.textData; + } + else if (message.data?.$case === "protoData") { + obj.protoData = any_1.Any.toJSON(message.data.protoData); + } + return obj; + }, +}; +exports.CloudEvent_AttributesEntry = { + fromJSON(object) { + return { + key: isSet(object.key) ? globalThis.String(object.key) : "", + value: isSet(object.value) ? exports.CloudEvent_CloudEventAttributeValue.fromJSON(object.value) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.key !== "") { + obj.key = message.key; + } + if (message.value !== undefined) { + obj.value = exports.CloudEvent_CloudEventAttributeValue.toJSON(message.value); + } + return obj; + }, +}; +exports.CloudEvent_CloudEventAttributeValue = { + fromJSON(object) { + return { + attr: isSet(object.ceBoolean) + ? { $case: "ceBoolean", ceBoolean: globalThis.Boolean(object.ceBoolean) } + : isSet(object.ceInteger) + ? { $case: "ceInteger", ceInteger: globalThis.Number(object.ceInteger) } + : isSet(object.ceString) + ? { $case: "ceString", ceString: globalThis.String(object.ceString) } + : isSet(object.ceBytes) + ? { $case: "ceBytes", ceBytes: Buffer.from(bytesFromBase64(object.ceBytes)) } + : isSet(object.ceUri) + ? { $case: "ceUri", ceUri: globalThis.String(object.ceUri) } + : isSet(object.ceUriRef) + ? { $case: "ceUriRef", ceUriRef: globalThis.String(object.ceUriRef) } + : isSet(object.ceTimestamp) + ? { $case: "ceTimestamp", ceTimestamp: fromJsonTimestamp(object.ceTimestamp) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.attr?.$case === "ceBoolean") { + obj.ceBoolean = message.attr.ceBoolean; + } + else if (message.attr?.$case === "ceInteger") { + obj.ceInteger = Math.round(message.attr.ceInteger); + } + else if (message.attr?.$case === "ceString") { + obj.ceString = message.attr.ceString; + } + else if (message.attr?.$case === "ceBytes") { + obj.ceBytes = base64FromBytes(message.attr.ceBytes); + } + else if (message.attr?.$case === "ceUri") { + obj.ceUri = message.attr.ceUri; + } + else if (message.attr?.$case === "ceUriRef") { + obj.ceUriRef = message.attr.ceUriRef; + } + else if (message.attr?.$case === "ceTimestamp") { + obj.ceTimestamp = message.attr.ceTimestamp.toISOString(); + } + return obj; + }, +}; +exports.CloudEventBatch = { + fromJSON(object) { + return { + events: globalThis.Array.isArray(object?.events) ? object.events.map((e) => exports.CloudEvent.fromJSON(e)) : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.events?.length) { + obj.events = message.events.map((e) => exports.CloudEvent.toJSON(e)); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function fromTimestamp(t) { + let millis = (globalThis.Number(t.seconds) || 0) * 1_000; + millis += (t.nanos || 0) / 1_000_000; + return new globalThis.Date(millis); +} +function fromJsonTimestamp(o) { + if (o instanceof globalThis.Date) { + return o; + } + else if (typeof o === "string") { + return new globalThis.Date(o); + } + else { + return fromTimestamp(timestamp_1.Timestamp.fromJSON(o)); + } +} +function isObject(value) { + return typeof value === "object" && value !== null; +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/api/field_behavior.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/api/field_behavior.js new file mode 100644 index 0000000000000..b4d9ccc781c2f --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/api/field_behavior.js @@ -0,0 +1,141 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: google/api/field_behavior.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.FieldBehavior = void 0; +exports.fieldBehaviorFromJSON = fieldBehaviorFromJSON; +exports.fieldBehaviorToJSON = fieldBehaviorToJSON; +/* eslint-disable */ +/** + * An indicator of the behavior of a given field (for example, that a field + * is required in requests, or given as output but ignored as input). + * This **does not** change the behavior in protocol buffers itself; it only + * denotes the behavior and may affect how API tooling handles the field. + * + * Note: This enum **may** receive new values in the future. + */ +var FieldBehavior; +(function (FieldBehavior) { + /** FIELD_BEHAVIOR_UNSPECIFIED - Conventional default for enums. Do not use this. */ + FieldBehavior[FieldBehavior["FIELD_BEHAVIOR_UNSPECIFIED"] = 0] = "FIELD_BEHAVIOR_UNSPECIFIED"; + /** + * OPTIONAL - Specifically denotes a field as optional. + * While all fields in protocol buffers are optional, this may be specified + * for emphasis if appropriate. + */ + FieldBehavior[FieldBehavior["OPTIONAL"] = 1] = "OPTIONAL"; + /** + * REQUIRED - Denotes a field as required. + * This indicates that the field **must** be provided as part of the request, + * and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + */ + FieldBehavior[FieldBehavior["REQUIRED"] = 2] = "REQUIRED"; + /** + * OUTPUT_ONLY - Denotes a field as output only. + * This indicates that the field is provided in responses, but including the + * field in a request does nothing (the server *must* ignore it and + * *must not* throw an error as a result of the field's presence). + */ + FieldBehavior[FieldBehavior["OUTPUT_ONLY"] = 3] = "OUTPUT_ONLY"; + /** + * INPUT_ONLY - Denotes a field as input only. + * This indicates that the field is provided in requests, and the + * corresponding field is not included in output. + */ + FieldBehavior[FieldBehavior["INPUT_ONLY"] = 4] = "INPUT_ONLY"; + /** + * IMMUTABLE - Denotes a field as immutable. + * This indicates that the field may be set once in a request to create a + * resource, but may not be changed thereafter. + */ + FieldBehavior[FieldBehavior["IMMUTABLE"] = 5] = "IMMUTABLE"; + /** + * UNORDERED_LIST - Denotes that a (repeated) field is an unordered list. + * This indicates that the service may provide the elements of the list + * in any arbitrary order, rather than the order the user originally + * provided. Additionally, the list's order may or may not be stable. + */ + FieldBehavior[FieldBehavior["UNORDERED_LIST"] = 6] = "UNORDERED_LIST"; + /** + * NON_EMPTY_DEFAULT - Denotes that this field returns a non-empty default value if not set. + * This indicates that if the user provides the empty value in a request, + * a non-empty value will be returned. The user will not be aware of what + * non-empty value to expect. + */ + FieldBehavior[FieldBehavior["NON_EMPTY_DEFAULT"] = 7] = "NON_EMPTY_DEFAULT"; + /** + * IDENTIFIER - Denotes that the field in a resource (a message annotated with + * google.api.resource) is used in the resource name to uniquely identify the + * resource. For AIP-compliant APIs, this should only be applied to the + * `name` field on the resource. + * + * This behavior should not be applied to references to other resources within + * the message. + * + * The identifier field of resources often have different field behavior + * depending on the request it is embedded in (e.g. for Create methods name + * is optional and unused, while for Update methods it is required). Instead + * of method-specific annotations, only `IDENTIFIER` is required. + */ + FieldBehavior[FieldBehavior["IDENTIFIER"] = 8] = "IDENTIFIER"; +})(FieldBehavior || (exports.FieldBehavior = FieldBehavior = {})); +function fieldBehaviorFromJSON(object) { + switch (object) { + case 0: + case "FIELD_BEHAVIOR_UNSPECIFIED": + return FieldBehavior.FIELD_BEHAVIOR_UNSPECIFIED; + case 1: + case "OPTIONAL": + return FieldBehavior.OPTIONAL; + case 2: + case "REQUIRED": + return FieldBehavior.REQUIRED; + case 3: + case "OUTPUT_ONLY": + return FieldBehavior.OUTPUT_ONLY; + case 4: + case "INPUT_ONLY": + return FieldBehavior.INPUT_ONLY; + case 5: + case "IMMUTABLE": + return FieldBehavior.IMMUTABLE; + case 6: + case "UNORDERED_LIST": + return FieldBehavior.UNORDERED_LIST; + case 7: + case "NON_EMPTY_DEFAULT": + return FieldBehavior.NON_EMPTY_DEFAULT; + case 8: + case "IDENTIFIER": + return FieldBehavior.IDENTIFIER; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldBehavior"); + } +} +function fieldBehaviorToJSON(object) { + switch (object) { + case FieldBehavior.FIELD_BEHAVIOR_UNSPECIFIED: + return "FIELD_BEHAVIOR_UNSPECIFIED"; + case FieldBehavior.OPTIONAL: + return "OPTIONAL"; + case FieldBehavior.REQUIRED: + return "REQUIRED"; + case FieldBehavior.OUTPUT_ONLY: + return "OUTPUT_ONLY"; + case FieldBehavior.INPUT_ONLY: + return "INPUT_ONLY"; + case FieldBehavior.IMMUTABLE: + return "IMMUTABLE"; + case FieldBehavior.UNORDERED_LIST: + return "UNORDERED_LIST"; + case FieldBehavior.NON_EMPTY_DEFAULT: + return "NON_EMPTY_DEFAULT"; + case FieldBehavior.IDENTIFIER: + return "IDENTIFIER"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldBehavior"); + } +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/any.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/any.js new file mode 100644 index 0000000000000..f0c8aab773e4c --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/any.js @@ -0,0 +1,35 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: google/protobuf/any.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Any = void 0; +exports.Any = { + fromJSON(object) { + return { + typeUrl: isSet(object.typeUrl) ? globalThis.String(object.typeUrl) : "", + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.typeUrl !== "") { + obj.typeUrl = message.typeUrl; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/descriptor.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/descriptor.js new file mode 100644 index 0000000000000..d6f8ddddf799d --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/descriptor.js @@ -0,0 +1,2042 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: google/protobuf/descriptor.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GeneratedCodeInfo = exports.SourceCodeInfo_Location = exports.SourceCodeInfo = exports.FeatureSetDefaults_FeatureSetEditionDefault = exports.FeatureSetDefaults = exports.FeatureSet = exports.UninterpretedOption_NamePart = exports.UninterpretedOption = exports.MethodOptions = exports.ServiceOptions = exports.EnumValueOptions = exports.EnumOptions = exports.OneofOptions = exports.FieldOptions_FeatureSupport = exports.FieldOptions_EditionDefault = exports.FieldOptions = exports.MessageOptions = exports.FileOptions = exports.MethodDescriptorProto = exports.ServiceDescriptorProto = exports.EnumValueDescriptorProto = exports.EnumDescriptorProto_EnumReservedRange = exports.EnumDescriptorProto = exports.OneofDescriptorProto = exports.FieldDescriptorProto = exports.ExtensionRangeOptions_Declaration = exports.ExtensionRangeOptions = exports.DescriptorProto_ReservedRange = exports.DescriptorProto_ExtensionRange = exports.DescriptorProto = exports.FileDescriptorProto = exports.FileDescriptorSet = exports.GeneratedCodeInfo_Annotation_Semantic = exports.FeatureSet_EnforceNamingStyle = exports.FeatureSet_JsonFormat = exports.FeatureSet_MessageEncoding = exports.FeatureSet_Utf8Validation = exports.FeatureSet_RepeatedFieldEncoding = exports.FeatureSet_EnumType = exports.FeatureSet_FieldPresence = exports.MethodOptions_IdempotencyLevel = exports.FieldOptions_OptionTargetType = exports.FieldOptions_OptionRetention = exports.FieldOptions_JSType = exports.FieldOptions_CType = exports.FileOptions_OptimizeMode = exports.FieldDescriptorProto_Label = exports.FieldDescriptorProto_Type = exports.ExtensionRangeOptions_VerificationState = exports.Edition = void 0; +exports.GeneratedCodeInfo_Annotation = void 0; +exports.editionFromJSON = editionFromJSON; +exports.editionToJSON = editionToJSON; +exports.extensionRangeOptions_VerificationStateFromJSON = extensionRangeOptions_VerificationStateFromJSON; +exports.extensionRangeOptions_VerificationStateToJSON = extensionRangeOptions_VerificationStateToJSON; +exports.fieldDescriptorProto_TypeFromJSON = fieldDescriptorProto_TypeFromJSON; +exports.fieldDescriptorProto_TypeToJSON = fieldDescriptorProto_TypeToJSON; +exports.fieldDescriptorProto_LabelFromJSON = fieldDescriptorProto_LabelFromJSON; +exports.fieldDescriptorProto_LabelToJSON = fieldDescriptorProto_LabelToJSON; +exports.fileOptions_OptimizeModeFromJSON = fileOptions_OptimizeModeFromJSON; +exports.fileOptions_OptimizeModeToJSON = fileOptions_OptimizeModeToJSON; +exports.fieldOptions_CTypeFromJSON = fieldOptions_CTypeFromJSON; +exports.fieldOptions_CTypeToJSON = fieldOptions_CTypeToJSON; +exports.fieldOptions_JSTypeFromJSON = fieldOptions_JSTypeFromJSON; +exports.fieldOptions_JSTypeToJSON = fieldOptions_JSTypeToJSON; +exports.fieldOptions_OptionRetentionFromJSON = fieldOptions_OptionRetentionFromJSON; +exports.fieldOptions_OptionRetentionToJSON = fieldOptions_OptionRetentionToJSON; +exports.fieldOptions_OptionTargetTypeFromJSON = fieldOptions_OptionTargetTypeFromJSON; +exports.fieldOptions_OptionTargetTypeToJSON = fieldOptions_OptionTargetTypeToJSON; +exports.methodOptions_IdempotencyLevelFromJSON = methodOptions_IdempotencyLevelFromJSON; +exports.methodOptions_IdempotencyLevelToJSON = methodOptions_IdempotencyLevelToJSON; +exports.featureSet_FieldPresenceFromJSON = featureSet_FieldPresenceFromJSON; +exports.featureSet_FieldPresenceToJSON = featureSet_FieldPresenceToJSON; +exports.featureSet_EnumTypeFromJSON = featureSet_EnumTypeFromJSON; +exports.featureSet_EnumTypeToJSON = featureSet_EnumTypeToJSON; +exports.featureSet_RepeatedFieldEncodingFromJSON = featureSet_RepeatedFieldEncodingFromJSON; +exports.featureSet_RepeatedFieldEncodingToJSON = featureSet_RepeatedFieldEncodingToJSON; +exports.featureSet_Utf8ValidationFromJSON = featureSet_Utf8ValidationFromJSON; +exports.featureSet_Utf8ValidationToJSON = featureSet_Utf8ValidationToJSON; +exports.featureSet_MessageEncodingFromJSON = featureSet_MessageEncodingFromJSON; +exports.featureSet_MessageEncodingToJSON = featureSet_MessageEncodingToJSON; +exports.featureSet_JsonFormatFromJSON = featureSet_JsonFormatFromJSON; +exports.featureSet_JsonFormatToJSON = featureSet_JsonFormatToJSON; +exports.featureSet_EnforceNamingStyleFromJSON = featureSet_EnforceNamingStyleFromJSON; +exports.featureSet_EnforceNamingStyleToJSON = featureSet_EnforceNamingStyleToJSON; +exports.generatedCodeInfo_Annotation_SemanticFromJSON = generatedCodeInfo_Annotation_SemanticFromJSON; +exports.generatedCodeInfo_Annotation_SemanticToJSON = generatedCodeInfo_Annotation_SemanticToJSON; +/* eslint-disable */ +/** The full set of known editions. */ +var Edition; +(function (Edition) { + /** EDITION_UNKNOWN - A placeholder for an unknown edition value. */ + Edition[Edition["EDITION_UNKNOWN"] = 0] = "EDITION_UNKNOWN"; + /** + * EDITION_LEGACY - A placeholder edition for specifying default behaviors *before* a feature + * was first introduced. This is effectively an "infinite past". + */ + Edition[Edition["EDITION_LEGACY"] = 900] = "EDITION_LEGACY"; + /** + * EDITION_PROTO2 - Legacy syntax "editions". These pre-date editions, but behave much like + * distinct editions. These can't be used to specify the edition of proto + * files, but feature definitions must supply proto2/proto3 defaults for + * backwards compatibility. + */ + Edition[Edition["EDITION_PROTO2"] = 998] = "EDITION_PROTO2"; + Edition[Edition["EDITION_PROTO3"] = 999] = "EDITION_PROTO3"; + /** + * EDITION_2023 - Editions that have been released. The specific values are arbitrary and + * should not be depended on, but they will always be time-ordered for easy + * comparison. + */ + Edition[Edition["EDITION_2023"] = 1000] = "EDITION_2023"; + Edition[Edition["EDITION_2024"] = 1001] = "EDITION_2024"; + /** + * EDITION_1_TEST_ONLY - Placeholder editions for testing feature resolution. These should not be + * used or relied on outside of tests. + */ + Edition[Edition["EDITION_1_TEST_ONLY"] = 1] = "EDITION_1_TEST_ONLY"; + Edition[Edition["EDITION_2_TEST_ONLY"] = 2] = "EDITION_2_TEST_ONLY"; + Edition[Edition["EDITION_99997_TEST_ONLY"] = 99997] = "EDITION_99997_TEST_ONLY"; + Edition[Edition["EDITION_99998_TEST_ONLY"] = 99998] = "EDITION_99998_TEST_ONLY"; + Edition[Edition["EDITION_99999_TEST_ONLY"] = 99999] = "EDITION_99999_TEST_ONLY"; + /** + * EDITION_MAX - Placeholder for specifying unbounded edition support. This should only + * ever be used by plugins that can expect to never require any changes to + * support a new edition. + */ + Edition[Edition["EDITION_MAX"] = 2147483647] = "EDITION_MAX"; +})(Edition || (exports.Edition = Edition = {})); +function editionFromJSON(object) { + switch (object) { + case 0: + case "EDITION_UNKNOWN": + return Edition.EDITION_UNKNOWN; + case 900: + case "EDITION_LEGACY": + return Edition.EDITION_LEGACY; + case 998: + case "EDITION_PROTO2": + return Edition.EDITION_PROTO2; + case 999: + case "EDITION_PROTO3": + return Edition.EDITION_PROTO3; + case 1000: + case "EDITION_2023": + return Edition.EDITION_2023; + case 1001: + case "EDITION_2024": + return Edition.EDITION_2024; + case 1: + case "EDITION_1_TEST_ONLY": + return Edition.EDITION_1_TEST_ONLY; + case 2: + case "EDITION_2_TEST_ONLY": + return Edition.EDITION_2_TEST_ONLY; + case 99997: + case "EDITION_99997_TEST_ONLY": + return Edition.EDITION_99997_TEST_ONLY; + case 99998: + case "EDITION_99998_TEST_ONLY": + return Edition.EDITION_99998_TEST_ONLY; + case 99999: + case "EDITION_99999_TEST_ONLY": + return Edition.EDITION_99999_TEST_ONLY; + case 2147483647: + case "EDITION_MAX": + return Edition.EDITION_MAX; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum Edition"); + } +} +function editionToJSON(object) { + switch (object) { + case Edition.EDITION_UNKNOWN: + return "EDITION_UNKNOWN"; + case Edition.EDITION_LEGACY: + return "EDITION_LEGACY"; + case Edition.EDITION_PROTO2: + return "EDITION_PROTO2"; + case Edition.EDITION_PROTO3: + return "EDITION_PROTO3"; + case Edition.EDITION_2023: + return "EDITION_2023"; + case Edition.EDITION_2024: + return "EDITION_2024"; + case Edition.EDITION_1_TEST_ONLY: + return "EDITION_1_TEST_ONLY"; + case Edition.EDITION_2_TEST_ONLY: + return "EDITION_2_TEST_ONLY"; + case Edition.EDITION_99997_TEST_ONLY: + return "EDITION_99997_TEST_ONLY"; + case Edition.EDITION_99998_TEST_ONLY: + return "EDITION_99998_TEST_ONLY"; + case Edition.EDITION_99999_TEST_ONLY: + return "EDITION_99999_TEST_ONLY"; + case Edition.EDITION_MAX: + return "EDITION_MAX"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum Edition"); + } +} +/** The verification state of the extension range. */ +var ExtensionRangeOptions_VerificationState; +(function (ExtensionRangeOptions_VerificationState) { + /** DECLARATION - All the extensions of the range must be declared. */ + ExtensionRangeOptions_VerificationState[ExtensionRangeOptions_VerificationState["DECLARATION"] = 0] = "DECLARATION"; + ExtensionRangeOptions_VerificationState[ExtensionRangeOptions_VerificationState["UNVERIFIED"] = 1] = "UNVERIFIED"; +})(ExtensionRangeOptions_VerificationState || (exports.ExtensionRangeOptions_VerificationState = ExtensionRangeOptions_VerificationState = {})); +function extensionRangeOptions_VerificationStateFromJSON(object) { + switch (object) { + case 0: + case "DECLARATION": + return ExtensionRangeOptions_VerificationState.DECLARATION; + case 1: + case "UNVERIFIED": + return ExtensionRangeOptions_VerificationState.UNVERIFIED; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum ExtensionRangeOptions_VerificationState"); + } +} +function extensionRangeOptions_VerificationStateToJSON(object) { + switch (object) { + case ExtensionRangeOptions_VerificationState.DECLARATION: + return "DECLARATION"; + case ExtensionRangeOptions_VerificationState.UNVERIFIED: + return "UNVERIFIED"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum ExtensionRangeOptions_VerificationState"); + } +} +var FieldDescriptorProto_Type; +(function (FieldDescriptorProto_Type) { + /** + * TYPE_DOUBLE - 0 is reserved for errors. + * Order is weird for historical reasons. + */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_DOUBLE"] = 1] = "TYPE_DOUBLE"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_FLOAT"] = 2] = "TYPE_FLOAT"; + /** + * TYPE_INT64 - Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + * negative values are likely. + */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_INT64"] = 3] = "TYPE_INT64"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_UINT64"] = 4] = "TYPE_UINT64"; + /** + * TYPE_INT32 - Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + * negative values are likely. + */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_INT32"] = 5] = "TYPE_INT32"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_FIXED64"] = 6] = "TYPE_FIXED64"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_FIXED32"] = 7] = "TYPE_FIXED32"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_BOOL"] = 8] = "TYPE_BOOL"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_STRING"] = 9] = "TYPE_STRING"; + /** + * TYPE_GROUP - Tag-delimited aggregate. + * Group type is deprecated and not supported after google.protobuf. However, Proto3 + * implementations should still be able to parse the group wire format and + * treat group fields as unknown fields. In Editions, the group wire format + * can be enabled via the `message_encoding` feature. + */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_GROUP"] = 10] = "TYPE_GROUP"; + /** TYPE_MESSAGE - Length-delimited aggregate. */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_MESSAGE"] = 11] = "TYPE_MESSAGE"; + /** TYPE_BYTES - New in version 2. */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_BYTES"] = 12] = "TYPE_BYTES"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_UINT32"] = 13] = "TYPE_UINT32"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_ENUM"] = 14] = "TYPE_ENUM"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_SFIXED32"] = 15] = "TYPE_SFIXED32"; + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_SFIXED64"] = 16] = "TYPE_SFIXED64"; + /** TYPE_SINT32 - Uses ZigZag encoding. */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_SINT32"] = 17] = "TYPE_SINT32"; + /** TYPE_SINT64 - Uses ZigZag encoding. */ + FieldDescriptorProto_Type[FieldDescriptorProto_Type["TYPE_SINT64"] = 18] = "TYPE_SINT64"; +})(FieldDescriptorProto_Type || (exports.FieldDescriptorProto_Type = FieldDescriptorProto_Type = {})); +function fieldDescriptorProto_TypeFromJSON(object) { + switch (object) { + case 1: + case "TYPE_DOUBLE": + return FieldDescriptorProto_Type.TYPE_DOUBLE; + case 2: + case "TYPE_FLOAT": + return FieldDescriptorProto_Type.TYPE_FLOAT; + case 3: + case "TYPE_INT64": + return FieldDescriptorProto_Type.TYPE_INT64; + case 4: + case "TYPE_UINT64": + return FieldDescriptorProto_Type.TYPE_UINT64; + case 5: + case "TYPE_INT32": + return FieldDescriptorProto_Type.TYPE_INT32; + case 6: + case "TYPE_FIXED64": + return FieldDescriptorProto_Type.TYPE_FIXED64; + case 7: + case "TYPE_FIXED32": + return FieldDescriptorProto_Type.TYPE_FIXED32; + case 8: + case "TYPE_BOOL": + return FieldDescriptorProto_Type.TYPE_BOOL; + case 9: + case "TYPE_STRING": + return FieldDescriptorProto_Type.TYPE_STRING; + case 10: + case "TYPE_GROUP": + return FieldDescriptorProto_Type.TYPE_GROUP; + case 11: + case "TYPE_MESSAGE": + return FieldDescriptorProto_Type.TYPE_MESSAGE; + case 12: + case "TYPE_BYTES": + return FieldDescriptorProto_Type.TYPE_BYTES; + case 13: + case "TYPE_UINT32": + return FieldDescriptorProto_Type.TYPE_UINT32; + case 14: + case "TYPE_ENUM": + return FieldDescriptorProto_Type.TYPE_ENUM; + case 15: + case "TYPE_SFIXED32": + return FieldDescriptorProto_Type.TYPE_SFIXED32; + case 16: + case "TYPE_SFIXED64": + return FieldDescriptorProto_Type.TYPE_SFIXED64; + case 17: + case "TYPE_SINT32": + return FieldDescriptorProto_Type.TYPE_SINT32; + case 18: + case "TYPE_SINT64": + return FieldDescriptorProto_Type.TYPE_SINT64; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldDescriptorProto_Type"); + } +} +function fieldDescriptorProto_TypeToJSON(object) { + switch (object) { + case FieldDescriptorProto_Type.TYPE_DOUBLE: + return "TYPE_DOUBLE"; + case FieldDescriptorProto_Type.TYPE_FLOAT: + return "TYPE_FLOAT"; + case FieldDescriptorProto_Type.TYPE_INT64: + return "TYPE_INT64"; + case FieldDescriptorProto_Type.TYPE_UINT64: + return "TYPE_UINT64"; + case FieldDescriptorProto_Type.TYPE_INT32: + return "TYPE_INT32"; + case FieldDescriptorProto_Type.TYPE_FIXED64: + return "TYPE_FIXED64"; + case FieldDescriptorProto_Type.TYPE_FIXED32: + return "TYPE_FIXED32"; + case FieldDescriptorProto_Type.TYPE_BOOL: + return "TYPE_BOOL"; + case FieldDescriptorProto_Type.TYPE_STRING: + return "TYPE_STRING"; + case FieldDescriptorProto_Type.TYPE_GROUP: + return "TYPE_GROUP"; + case FieldDescriptorProto_Type.TYPE_MESSAGE: + return "TYPE_MESSAGE"; + case FieldDescriptorProto_Type.TYPE_BYTES: + return "TYPE_BYTES"; + case FieldDescriptorProto_Type.TYPE_UINT32: + return "TYPE_UINT32"; + case FieldDescriptorProto_Type.TYPE_ENUM: + return "TYPE_ENUM"; + case FieldDescriptorProto_Type.TYPE_SFIXED32: + return "TYPE_SFIXED32"; + case FieldDescriptorProto_Type.TYPE_SFIXED64: + return "TYPE_SFIXED64"; + case FieldDescriptorProto_Type.TYPE_SINT32: + return "TYPE_SINT32"; + case FieldDescriptorProto_Type.TYPE_SINT64: + return "TYPE_SINT64"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldDescriptorProto_Type"); + } +} +var FieldDescriptorProto_Label; +(function (FieldDescriptorProto_Label) { + /** LABEL_OPTIONAL - 0 is reserved for errors */ + FieldDescriptorProto_Label[FieldDescriptorProto_Label["LABEL_OPTIONAL"] = 1] = "LABEL_OPTIONAL"; + FieldDescriptorProto_Label[FieldDescriptorProto_Label["LABEL_REPEATED"] = 3] = "LABEL_REPEATED"; + /** + * LABEL_REQUIRED - The required label is only allowed in google.protobuf. In proto3 and Editions + * it's explicitly prohibited. In Editions, the `field_presence` feature + * can be used to get this behavior. + */ + FieldDescriptorProto_Label[FieldDescriptorProto_Label["LABEL_REQUIRED"] = 2] = "LABEL_REQUIRED"; +})(FieldDescriptorProto_Label || (exports.FieldDescriptorProto_Label = FieldDescriptorProto_Label = {})); +function fieldDescriptorProto_LabelFromJSON(object) { + switch (object) { + case 1: + case "LABEL_OPTIONAL": + return FieldDescriptorProto_Label.LABEL_OPTIONAL; + case 3: + case "LABEL_REPEATED": + return FieldDescriptorProto_Label.LABEL_REPEATED; + case 2: + case "LABEL_REQUIRED": + return FieldDescriptorProto_Label.LABEL_REQUIRED; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldDescriptorProto_Label"); + } +} +function fieldDescriptorProto_LabelToJSON(object) { + switch (object) { + case FieldDescriptorProto_Label.LABEL_OPTIONAL: + return "LABEL_OPTIONAL"; + case FieldDescriptorProto_Label.LABEL_REPEATED: + return "LABEL_REPEATED"; + case FieldDescriptorProto_Label.LABEL_REQUIRED: + return "LABEL_REQUIRED"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldDescriptorProto_Label"); + } +} +/** Generated classes can be optimized for speed or code size. */ +var FileOptions_OptimizeMode; +(function (FileOptions_OptimizeMode) { + /** SPEED - Generate complete code for parsing, serialization, */ + FileOptions_OptimizeMode[FileOptions_OptimizeMode["SPEED"] = 1] = "SPEED"; + /** CODE_SIZE - etc. */ + FileOptions_OptimizeMode[FileOptions_OptimizeMode["CODE_SIZE"] = 2] = "CODE_SIZE"; + /** LITE_RUNTIME - Generate code using MessageLite and the lite runtime. */ + FileOptions_OptimizeMode[FileOptions_OptimizeMode["LITE_RUNTIME"] = 3] = "LITE_RUNTIME"; +})(FileOptions_OptimizeMode || (exports.FileOptions_OptimizeMode = FileOptions_OptimizeMode = {})); +function fileOptions_OptimizeModeFromJSON(object) { + switch (object) { + case 1: + case "SPEED": + return FileOptions_OptimizeMode.SPEED; + case 2: + case "CODE_SIZE": + return FileOptions_OptimizeMode.CODE_SIZE; + case 3: + case "LITE_RUNTIME": + return FileOptions_OptimizeMode.LITE_RUNTIME; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FileOptions_OptimizeMode"); + } +} +function fileOptions_OptimizeModeToJSON(object) { + switch (object) { + case FileOptions_OptimizeMode.SPEED: + return "SPEED"; + case FileOptions_OptimizeMode.CODE_SIZE: + return "CODE_SIZE"; + case FileOptions_OptimizeMode.LITE_RUNTIME: + return "LITE_RUNTIME"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FileOptions_OptimizeMode"); + } +} +var FieldOptions_CType; +(function (FieldOptions_CType) { + /** STRING - Default mode. */ + FieldOptions_CType[FieldOptions_CType["STRING"] = 0] = "STRING"; + /** + * CORD - The option [ctype=CORD] may be applied to a non-repeated field of type + * "bytes". It indicates that in C++, the data should be stored in a Cord + * instead of a string. For very large strings, this may reduce memory + * fragmentation. It may also allow better performance when parsing from a + * Cord, or when parsing with aliasing enabled, as the parsed Cord may then + * alias the original buffer. + */ + FieldOptions_CType[FieldOptions_CType["CORD"] = 1] = "CORD"; + FieldOptions_CType[FieldOptions_CType["STRING_PIECE"] = 2] = "STRING_PIECE"; +})(FieldOptions_CType || (exports.FieldOptions_CType = FieldOptions_CType = {})); +function fieldOptions_CTypeFromJSON(object) { + switch (object) { + case 0: + case "STRING": + return FieldOptions_CType.STRING; + case 1: + case "CORD": + return FieldOptions_CType.CORD; + case 2: + case "STRING_PIECE": + return FieldOptions_CType.STRING_PIECE; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_CType"); + } +} +function fieldOptions_CTypeToJSON(object) { + switch (object) { + case FieldOptions_CType.STRING: + return "STRING"; + case FieldOptions_CType.CORD: + return "CORD"; + case FieldOptions_CType.STRING_PIECE: + return "STRING_PIECE"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_CType"); + } +} +var FieldOptions_JSType; +(function (FieldOptions_JSType) { + /** JS_NORMAL - Use the default type. */ + FieldOptions_JSType[FieldOptions_JSType["JS_NORMAL"] = 0] = "JS_NORMAL"; + /** JS_STRING - Use JavaScript strings. */ + FieldOptions_JSType[FieldOptions_JSType["JS_STRING"] = 1] = "JS_STRING"; + /** JS_NUMBER - Use JavaScript numbers. */ + FieldOptions_JSType[FieldOptions_JSType["JS_NUMBER"] = 2] = "JS_NUMBER"; +})(FieldOptions_JSType || (exports.FieldOptions_JSType = FieldOptions_JSType = {})); +function fieldOptions_JSTypeFromJSON(object) { + switch (object) { + case 0: + case "JS_NORMAL": + return FieldOptions_JSType.JS_NORMAL; + case 1: + case "JS_STRING": + return FieldOptions_JSType.JS_STRING; + case 2: + case "JS_NUMBER": + return FieldOptions_JSType.JS_NUMBER; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_JSType"); + } +} +function fieldOptions_JSTypeToJSON(object) { + switch (object) { + case FieldOptions_JSType.JS_NORMAL: + return "JS_NORMAL"; + case FieldOptions_JSType.JS_STRING: + return "JS_STRING"; + case FieldOptions_JSType.JS_NUMBER: + return "JS_NUMBER"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_JSType"); + } +} +/** If set to RETENTION_SOURCE, the option will be omitted from the binary. */ +var FieldOptions_OptionRetention; +(function (FieldOptions_OptionRetention) { + FieldOptions_OptionRetention[FieldOptions_OptionRetention["RETENTION_UNKNOWN"] = 0] = "RETENTION_UNKNOWN"; + FieldOptions_OptionRetention[FieldOptions_OptionRetention["RETENTION_RUNTIME"] = 1] = "RETENTION_RUNTIME"; + FieldOptions_OptionRetention[FieldOptions_OptionRetention["RETENTION_SOURCE"] = 2] = "RETENTION_SOURCE"; +})(FieldOptions_OptionRetention || (exports.FieldOptions_OptionRetention = FieldOptions_OptionRetention = {})); +function fieldOptions_OptionRetentionFromJSON(object) { + switch (object) { + case 0: + case "RETENTION_UNKNOWN": + return FieldOptions_OptionRetention.RETENTION_UNKNOWN; + case 1: + case "RETENTION_RUNTIME": + return FieldOptions_OptionRetention.RETENTION_RUNTIME; + case 2: + case "RETENTION_SOURCE": + return FieldOptions_OptionRetention.RETENTION_SOURCE; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_OptionRetention"); + } +} +function fieldOptions_OptionRetentionToJSON(object) { + switch (object) { + case FieldOptions_OptionRetention.RETENTION_UNKNOWN: + return "RETENTION_UNKNOWN"; + case FieldOptions_OptionRetention.RETENTION_RUNTIME: + return "RETENTION_RUNTIME"; + case FieldOptions_OptionRetention.RETENTION_SOURCE: + return "RETENTION_SOURCE"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_OptionRetention"); + } +} +/** + * This indicates the types of entities that the field may apply to when used + * as an option. If it is unset, then the field may be freely used as an + * option on any kind of entity. + */ +var FieldOptions_OptionTargetType; +(function (FieldOptions_OptionTargetType) { + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_UNKNOWN"] = 0] = "TARGET_TYPE_UNKNOWN"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_FILE"] = 1] = "TARGET_TYPE_FILE"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_EXTENSION_RANGE"] = 2] = "TARGET_TYPE_EXTENSION_RANGE"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_MESSAGE"] = 3] = "TARGET_TYPE_MESSAGE"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_FIELD"] = 4] = "TARGET_TYPE_FIELD"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_ONEOF"] = 5] = "TARGET_TYPE_ONEOF"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_ENUM"] = 6] = "TARGET_TYPE_ENUM"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_ENUM_ENTRY"] = 7] = "TARGET_TYPE_ENUM_ENTRY"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_SERVICE"] = 8] = "TARGET_TYPE_SERVICE"; + FieldOptions_OptionTargetType[FieldOptions_OptionTargetType["TARGET_TYPE_METHOD"] = 9] = "TARGET_TYPE_METHOD"; +})(FieldOptions_OptionTargetType || (exports.FieldOptions_OptionTargetType = FieldOptions_OptionTargetType = {})); +function fieldOptions_OptionTargetTypeFromJSON(object) { + switch (object) { + case 0: + case "TARGET_TYPE_UNKNOWN": + return FieldOptions_OptionTargetType.TARGET_TYPE_UNKNOWN; + case 1: + case "TARGET_TYPE_FILE": + return FieldOptions_OptionTargetType.TARGET_TYPE_FILE; + case 2: + case "TARGET_TYPE_EXTENSION_RANGE": + return FieldOptions_OptionTargetType.TARGET_TYPE_EXTENSION_RANGE; + case 3: + case "TARGET_TYPE_MESSAGE": + return FieldOptions_OptionTargetType.TARGET_TYPE_MESSAGE; + case 4: + case "TARGET_TYPE_FIELD": + return FieldOptions_OptionTargetType.TARGET_TYPE_FIELD; + case 5: + case "TARGET_TYPE_ONEOF": + return FieldOptions_OptionTargetType.TARGET_TYPE_ONEOF; + case 6: + case "TARGET_TYPE_ENUM": + return FieldOptions_OptionTargetType.TARGET_TYPE_ENUM; + case 7: + case "TARGET_TYPE_ENUM_ENTRY": + return FieldOptions_OptionTargetType.TARGET_TYPE_ENUM_ENTRY; + case 8: + case "TARGET_TYPE_SERVICE": + return FieldOptions_OptionTargetType.TARGET_TYPE_SERVICE; + case 9: + case "TARGET_TYPE_METHOD": + return FieldOptions_OptionTargetType.TARGET_TYPE_METHOD; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_OptionTargetType"); + } +} +function fieldOptions_OptionTargetTypeToJSON(object) { + switch (object) { + case FieldOptions_OptionTargetType.TARGET_TYPE_UNKNOWN: + return "TARGET_TYPE_UNKNOWN"; + case FieldOptions_OptionTargetType.TARGET_TYPE_FILE: + return "TARGET_TYPE_FILE"; + case FieldOptions_OptionTargetType.TARGET_TYPE_EXTENSION_RANGE: + return "TARGET_TYPE_EXTENSION_RANGE"; + case FieldOptions_OptionTargetType.TARGET_TYPE_MESSAGE: + return "TARGET_TYPE_MESSAGE"; + case FieldOptions_OptionTargetType.TARGET_TYPE_FIELD: + return "TARGET_TYPE_FIELD"; + case FieldOptions_OptionTargetType.TARGET_TYPE_ONEOF: + return "TARGET_TYPE_ONEOF"; + case FieldOptions_OptionTargetType.TARGET_TYPE_ENUM: + return "TARGET_TYPE_ENUM"; + case FieldOptions_OptionTargetType.TARGET_TYPE_ENUM_ENTRY: + return "TARGET_TYPE_ENUM_ENTRY"; + case FieldOptions_OptionTargetType.TARGET_TYPE_SERVICE: + return "TARGET_TYPE_SERVICE"; + case FieldOptions_OptionTargetType.TARGET_TYPE_METHOD: + return "TARGET_TYPE_METHOD"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FieldOptions_OptionTargetType"); + } +} +/** + * Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + * or neither? HTTP based RPC implementation may choose GET verb for safe + * methods, and PUT verb for idempotent methods instead of the default POST. + */ +var MethodOptions_IdempotencyLevel; +(function (MethodOptions_IdempotencyLevel) { + MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["IDEMPOTENCY_UNKNOWN"] = 0] = "IDEMPOTENCY_UNKNOWN"; + /** NO_SIDE_EFFECTS - implies idempotent */ + MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["NO_SIDE_EFFECTS"] = 1] = "NO_SIDE_EFFECTS"; + /** IDEMPOTENT - idempotent, but may have side effects */ + MethodOptions_IdempotencyLevel[MethodOptions_IdempotencyLevel["IDEMPOTENT"] = 2] = "IDEMPOTENT"; +})(MethodOptions_IdempotencyLevel || (exports.MethodOptions_IdempotencyLevel = MethodOptions_IdempotencyLevel = {})); +function methodOptions_IdempotencyLevelFromJSON(object) { + switch (object) { + case 0: + case "IDEMPOTENCY_UNKNOWN": + return MethodOptions_IdempotencyLevel.IDEMPOTENCY_UNKNOWN; + case 1: + case "NO_SIDE_EFFECTS": + return MethodOptions_IdempotencyLevel.NO_SIDE_EFFECTS; + case 2: + case "IDEMPOTENT": + return MethodOptions_IdempotencyLevel.IDEMPOTENT; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum MethodOptions_IdempotencyLevel"); + } +} +function methodOptions_IdempotencyLevelToJSON(object) { + switch (object) { + case MethodOptions_IdempotencyLevel.IDEMPOTENCY_UNKNOWN: + return "IDEMPOTENCY_UNKNOWN"; + case MethodOptions_IdempotencyLevel.NO_SIDE_EFFECTS: + return "NO_SIDE_EFFECTS"; + case MethodOptions_IdempotencyLevel.IDEMPOTENT: + return "IDEMPOTENT"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum MethodOptions_IdempotencyLevel"); + } +} +var FeatureSet_FieldPresence; +(function (FeatureSet_FieldPresence) { + FeatureSet_FieldPresence[FeatureSet_FieldPresence["FIELD_PRESENCE_UNKNOWN"] = 0] = "FIELD_PRESENCE_UNKNOWN"; + FeatureSet_FieldPresence[FeatureSet_FieldPresence["EXPLICIT"] = 1] = "EXPLICIT"; + FeatureSet_FieldPresence[FeatureSet_FieldPresence["IMPLICIT"] = 2] = "IMPLICIT"; + FeatureSet_FieldPresence[FeatureSet_FieldPresence["LEGACY_REQUIRED"] = 3] = "LEGACY_REQUIRED"; +})(FeatureSet_FieldPresence || (exports.FeatureSet_FieldPresence = FeatureSet_FieldPresence = {})); +function featureSet_FieldPresenceFromJSON(object) { + switch (object) { + case 0: + case "FIELD_PRESENCE_UNKNOWN": + return FeatureSet_FieldPresence.FIELD_PRESENCE_UNKNOWN; + case 1: + case "EXPLICIT": + return FeatureSet_FieldPresence.EXPLICIT; + case 2: + case "IMPLICIT": + return FeatureSet_FieldPresence.IMPLICIT; + case 3: + case "LEGACY_REQUIRED": + return FeatureSet_FieldPresence.LEGACY_REQUIRED; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_FieldPresence"); + } +} +function featureSet_FieldPresenceToJSON(object) { + switch (object) { + case FeatureSet_FieldPresence.FIELD_PRESENCE_UNKNOWN: + return "FIELD_PRESENCE_UNKNOWN"; + case FeatureSet_FieldPresence.EXPLICIT: + return "EXPLICIT"; + case FeatureSet_FieldPresence.IMPLICIT: + return "IMPLICIT"; + case FeatureSet_FieldPresence.LEGACY_REQUIRED: + return "LEGACY_REQUIRED"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_FieldPresence"); + } +} +var FeatureSet_EnumType; +(function (FeatureSet_EnumType) { + FeatureSet_EnumType[FeatureSet_EnumType["ENUM_TYPE_UNKNOWN"] = 0] = "ENUM_TYPE_UNKNOWN"; + FeatureSet_EnumType[FeatureSet_EnumType["OPEN"] = 1] = "OPEN"; + FeatureSet_EnumType[FeatureSet_EnumType["CLOSED"] = 2] = "CLOSED"; +})(FeatureSet_EnumType || (exports.FeatureSet_EnumType = FeatureSet_EnumType = {})); +function featureSet_EnumTypeFromJSON(object) { + switch (object) { + case 0: + case "ENUM_TYPE_UNKNOWN": + return FeatureSet_EnumType.ENUM_TYPE_UNKNOWN; + case 1: + case "OPEN": + return FeatureSet_EnumType.OPEN; + case 2: + case "CLOSED": + return FeatureSet_EnumType.CLOSED; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_EnumType"); + } +} +function featureSet_EnumTypeToJSON(object) { + switch (object) { + case FeatureSet_EnumType.ENUM_TYPE_UNKNOWN: + return "ENUM_TYPE_UNKNOWN"; + case FeatureSet_EnumType.OPEN: + return "OPEN"; + case FeatureSet_EnumType.CLOSED: + return "CLOSED"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_EnumType"); + } +} +var FeatureSet_RepeatedFieldEncoding; +(function (FeatureSet_RepeatedFieldEncoding) { + FeatureSet_RepeatedFieldEncoding[FeatureSet_RepeatedFieldEncoding["REPEATED_FIELD_ENCODING_UNKNOWN"] = 0] = "REPEATED_FIELD_ENCODING_UNKNOWN"; + FeatureSet_RepeatedFieldEncoding[FeatureSet_RepeatedFieldEncoding["PACKED"] = 1] = "PACKED"; + FeatureSet_RepeatedFieldEncoding[FeatureSet_RepeatedFieldEncoding["EXPANDED"] = 2] = "EXPANDED"; +})(FeatureSet_RepeatedFieldEncoding || (exports.FeatureSet_RepeatedFieldEncoding = FeatureSet_RepeatedFieldEncoding = {})); +function featureSet_RepeatedFieldEncodingFromJSON(object) { + switch (object) { + case 0: + case "REPEATED_FIELD_ENCODING_UNKNOWN": + return FeatureSet_RepeatedFieldEncoding.REPEATED_FIELD_ENCODING_UNKNOWN; + case 1: + case "PACKED": + return FeatureSet_RepeatedFieldEncoding.PACKED; + case 2: + case "EXPANDED": + return FeatureSet_RepeatedFieldEncoding.EXPANDED; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_RepeatedFieldEncoding"); + } +} +function featureSet_RepeatedFieldEncodingToJSON(object) { + switch (object) { + case FeatureSet_RepeatedFieldEncoding.REPEATED_FIELD_ENCODING_UNKNOWN: + return "REPEATED_FIELD_ENCODING_UNKNOWN"; + case FeatureSet_RepeatedFieldEncoding.PACKED: + return "PACKED"; + case FeatureSet_RepeatedFieldEncoding.EXPANDED: + return "EXPANDED"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_RepeatedFieldEncoding"); + } +} +var FeatureSet_Utf8Validation; +(function (FeatureSet_Utf8Validation) { + FeatureSet_Utf8Validation[FeatureSet_Utf8Validation["UTF8_VALIDATION_UNKNOWN"] = 0] = "UTF8_VALIDATION_UNKNOWN"; + FeatureSet_Utf8Validation[FeatureSet_Utf8Validation["VERIFY"] = 2] = "VERIFY"; + FeatureSet_Utf8Validation[FeatureSet_Utf8Validation["NONE"] = 3] = "NONE"; +})(FeatureSet_Utf8Validation || (exports.FeatureSet_Utf8Validation = FeatureSet_Utf8Validation = {})); +function featureSet_Utf8ValidationFromJSON(object) { + switch (object) { + case 0: + case "UTF8_VALIDATION_UNKNOWN": + return FeatureSet_Utf8Validation.UTF8_VALIDATION_UNKNOWN; + case 2: + case "VERIFY": + return FeatureSet_Utf8Validation.VERIFY; + case 3: + case "NONE": + return FeatureSet_Utf8Validation.NONE; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_Utf8Validation"); + } +} +function featureSet_Utf8ValidationToJSON(object) { + switch (object) { + case FeatureSet_Utf8Validation.UTF8_VALIDATION_UNKNOWN: + return "UTF8_VALIDATION_UNKNOWN"; + case FeatureSet_Utf8Validation.VERIFY: + return "VERIFY"; + case FeatureSet_Utf8Validation.NONE: + return "NONE"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_Utf8Validation"); + } +} +var FeatureSet_MessageEncoding; +(function (FeatureSet_MessageEncoding) { + FeatureSet_MessageEncoding[FeatureSet_MessageEncoding["MESSAGE_ENCODING_UNKNOWN"] = 0] = "MESSAGE_ENCODING_UNKNOWN"; + FeatureSet_MessageEncoding[FeatureSet_MessageEncoding["LENGTH_PREFIXED"] = 1] = "LENGTH_PREFIXED"; + FeatureSet_MessageEncoding[FeatureSet_MessageEncoding["DELIMITED"] = 2] = "DELIMITED"; +})(FeatureSet_MessageEncoding || (exports.FeatureSet_MessageEncoding = FeatureSet_MessageEncoding = {})); +function featureSet_MessageEncodingFromJSON(object) { + switch (object) { + case 0: + case "MESSAGE_ENCODING_UNKNOWN": + return FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN; + case 1: + case "LENGTH_PREFIXED": + return FeatureSet_MessageEncoding.LENGTH_PREFIXED; + case 2: + case "DELIMITED": + return FeatureSet_MessageEncoding.DELIMITED; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_MessageEncoding"); + } +} +function featureSet_MessageEncodingToJSON(object) { + switch (object) { + case FeatureSet_MessageEncoding.MESSAGE_ENCODING_UNKNOWN: + return "MESSAGE_ENCODING_UNKNOWN"; + case FeatureSet_MessageEncoding.LENGTH_PREFIXED: + return "LENGTH_PREFIXED"; + case FeatureSet_MessageEncoding.DELIMITED: + return "DELIMITED"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_MessageEncoding"); + } +} +var FeatureSet_JsonFormat; +(function (FeatureSet_JsonFormat) { + FeatureSet_JsonFormat[FeatureSet_JsonFormat["JSON_FORMAT_UNKNOWN"] = 0] = "JSON_FORMAT_UNKNOWN"; + FeatureSet_JsonFormat[FeatureSet_JsonFormat["ALLOW"] = 1] = "ALLOW"; + FeatureSet_JsonFormat[FeatureSet_JsonFormat["LEGACY_BEST_EFFORT"] = 2] = "LEGACY_BEST_EFFORT"; +})(FeatureSet_JsonFormat || (exports.FeatureSet_JsonFormat = FeatureSet_JsonFormat = {})); +function featureSet_JsonFormatFromJSON(object) { + switch (object) { + case 0: + case "JSON_FORMAT_UNKNOWN": + return FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN; + case 1: + case "ALLOW": + return FeatureSet_JsonFormat.ALLOW; + case 2: + case "LEGACY_BEST_EFFORT": + return FeatureSet_JsonFormat.LEGACY_BEST_EFFORT; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_JsonFormat"); + } +} +function featureSet_JsonFormatToJSON(object) { + switch (object) { + case FeatureSet_JsonFormat.JSON_FORMAT_UNKNOWN: + return "JSON_FORMAT_UNKNOWN"; + case FeatureSet_JsonFormat.ALLOW: + return "ALLOW"; + case FeatureSet_JsonFormat.LEGACY_BEST_EFFORT: + return "LEGACY_BEST_EFFORT"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_JsonFormat"); + } +} +var FeatureSet_EnforceNamingStyle; +(function (FeatureSet_EnforceNamingStyle) { + FeatureSet_EnforceNamingStyle[FeatureSet_EnforceNamingStyle["ENFORCE_NAMING_STYLE_UNKNOWN"] = 0] = "ENFORCE_NAMING_STYLE_UNKNOWN"; + FeatureSet_EnforceNamingStyle[FeatureSet_EnforceNamingStyle["STYLE2024"] = 1] = "STYLE2024"; + FeatureSet_EnforceNamingStyle[FeatureSet_EnforceNamingStyle["STYLE_LEGACY"] = 2] = "STYLE_LEGACY"; +})(FeatureSet_EnforceNamingStyle || (exports.FeatureSet_EnforceNamingStyle = FeatureSet_EnforceNamingStyle = {})); +function featureSet_EnforceNamingStyleFromJSON(object) { + switch (object) { + case 0: + case "ENFORCE_NAMING_STYLE_UNKNOWN": + return FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN; + case 1: + case "STYLE2024": + return FeatureSet_EnforceNamingStyle.STYLE2024; + case 2: + case "STYLE_LEGACY": + return FeatureSet_EnforceNamingStyle.STYLE_LEGACY; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_EnforceNamingStyle"); + } +} +function featureSet_EnforceNamingStyleToJSON(object) { + switch (object) { + case FeatureSet_EnforceNamingStyle.ENFORCE_NAMING_STYLE_UNKNOWN: + return "ENFORCE_NAMING_STYLE_UNKNOWN"; + case FeatureSet_EnforceNamingStyle.STYLE2024: + return "STYLE2024"; + case FeatureSet_EnforceNamingStyle.STYLE_LEGACY: + return "STYLE_LEGACY"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum FeatureSet_EnforceNamingStyle"); + } +} +/** + * Represents the identified object's effect on the element in the original + * .proto file. + */ +var GeneratedCodeInfo_Annotation_Semantic; +(function (GeneratedCodeInfo_Annotation_Semantic) { + /** NONE - There is no effect or the effect is indescribable. */ + GeneratedCodeInfo_Annotation_Semantic[GeneratedCodeInfo_Annotation_Semantic["NONE"] = 0] = "NONE"; + /** SET - The element is set or otherwise mutated. */ + GeneratedCodeInfo_Annotation_Semantic[GeneratedCodeInfo_Annotation_Semantic["SET"] = 1] = "SET"; + /** ALIAS - An alias to the element is returned. */ + GeneratedCodeInfo_Annotation_Semantic[GeneratedCodeInfo_Annotation_Semantic["ALIAS"] = 2] = "ALIAS"; +})(GeneratedCodeInfo_Annotation_Semantic || (exports.GeneratedCodeInfo_Annotation_Semantic = GeneratedCodeInfo_Annotation_Semantic = {})); +function generatedCodeInfo_Annotation_SemanticFromJSON(object) { + switch (object) { + case 0: + case "NONE": + return GeneratedCodeInfo_Annotation_Semantic.NONE; + case 1: + case "SET": + return GeneratedCodeInfo_Annotation_Semantic.SET; + case 2: + case "ALIAS": + return GeneratedCodeInfo_Annotation_Semantic.ALIAS; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum GeneratedCodeInfo_Annotation_Semantic"); + } +} +function generatedCodeInfo_Annotation_SemanticToJSON(object) { + switch (object) { + case GeneratedCodeInfo_Annotation_Semantic.NONE: + return "NONE"; + case GeneratedCodeInfo_Annotation_Semantic.SET: + return "SET"; + case GeneratedCodeInfo_Annotation_Semantic.ALIAS: + return "ALIAS"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum GeneratedCodeInfo_Annotation_Semantic"); + } +} +exports.FileDescriptorSet = { + fromJSON(object) { + return { + file: globalThis.Array.isArray(object?.file) ? object.file.map((e) => exports.FileDescriptorProto.fromJSON(e)) : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.file?.length) { + obj.file = message.file.map((e) => exports.FileDescriptorProto.toJSON(e)); + } + return obj; + }, +}; +exports.FileDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + package: isSet(object.package) ? globalThis.String(object.package) : "", + dependency: globalThis.Array.isArray(object?.dependency) + ? object.dependency.map((e) => globalThis.String(e)) + : [], + publicDependency: globalThis.Array.isArray(object?.publicDependency) + ? object.publicDependency.map((e) => globalThis.Number(e)) + : [], + weakDependency: globalThis.Array.isArray(object?.weakDependency) + ? object.weakDependency.map((e) => globalThis.Number(e)) + : [], + messageType: globalThis.Array.isArray(object?.messageType) + ? object.messageType.map((e) => exports.DescriptorProto.fromJSON(e)) + : [], + enumType: globalThis.Array.isArray(object?.enumType) + ? object.enumType.map((e) => exports.EnumDescriptorProto.fromJSON(e)) + : [], + service: globalThis.Array.isArray(object?.service) + ? object.service.map((e) => exports.ServiceDescriptorProto.fromJSON(e)) + : [], + extension: globalThis.Array.isArray(object?.extension) + ? object.extension.map((e) => exports.FieldDescriptorProto.fromJSON(e)) + : [], + options: isSet(object.options) ? exports.FileOptions.fromJSON(object.options) : undefined, + sourceCodeInfo: isSet(object.sourceCodeInfo) ? exports.SourceCodeInfo.fromJSON(object.sourceCodeInfo) : undefined, + syntax: isSet(object.syntax) ? globalThis.String(object.syntax) : "", + edition: isSet(object.edition) ? editionFromJSON(object.edition) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.package !== undefined && message.package !== "") { + obj.package = message.package; + } + if (message.dependency?.length) { + obj.dependency = message.dependency; + } + if (message.publicDependency?.length) { + obj.publicDependency = message.publicDependency.map((e) => Math.round(e)); + } + if (message.weakDependency?.length) { + obj.weakDependency = message.weakDependency.map((e) => Math.round(e)); + } + if (message.messageType?.length) { + obj.messageType = message.messageType.map((e) => exports.DescriptorProto.toJSON(e)); + } + if (message.enumType?.length) { + obj.enumType = message.enumType.map((e) => exports.EnumDescriptorProto.toJSON(e)); + } + if (message.service?.length) { + obj.service = message.service.map((e) => exports.ServiceDescriptorProto.toJSON(e)); + } + if (message.extension?.length) { + obj.extension = message.extension.map((e) => exports.FieldDescriptorProto.toJSON(e)); + } + if (message.options !== undefined) { + obj.options = exports.FileOptions.toJSON(message.options); + } + if (message.sourceCodeInfo !== undefined) { + obj.sourceCodeInfo = exports.SourceCodeInfo.toJSON(message.sourceCodeInfo); + } + if (message.syntax !== undefined && message.syntax !== "") { + obj.syntax = message.syntax; + } + if (message.edition !== undefined && message.edition !== 0) { + obj.edition = editionToJSON(message.edition); + } + return obj; + }, +}; +exports.DescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + field: globalThis.Array.isArray(object?.field) + ? object.field.map((e) => exports.FieldDescriptorProto.fromJSON(e)) + : [], + extension: globalThis.Array.isArray(object?.extension) + ? object.extension.map((e) => exports.FieldDescriptorProto.fromJSON(e)) + : [], + nestedType: globalThis.Array.isArray(object?.nestedType) + ? object.nestedType.map((e) => exports.DescriptorProto.fromJSON(e)) + : [], + enumType: globalThis.Array.isArray(object?.enumType) + ? object.enumType.map((e) => exports.EnumDescriptorProto.fromJSON(e)) + : [], + extensionRange: globalThis.Array.isArray(object?.extensionRange) + ? object.extensionRange.map((e) => exports.DescriptorProto_ExtensionRange.fromJSON(e)) + : [], + oneofDecl: globalThis.Array.isArray(object?.oneofDecl) + ? object.oneofDecl.map((e) => exports.OneofDescriptorProto.fromJSON(e)) + : [], + options: isSet(object.options) ? exports.MessageOptions.fromJSON(object.options) : undefined, + reservedRange: globalThis.Array.isArray(object?.reservedRange) + ? object.reservedRange.map((e) => exports.DescriptorProto_ReservedRange.fromJSON(e)) + : [], + reservedName: globalThis.Array.isArray(object?.reservedName) + ? object.reservedName.map((e) => globalThis.String(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.field?.length) { + obj.field = message.field.map((e) => exports.FieldDescriptorProto.toJSON(e)); + } + if (message.extension?.length) { + obj.extension = message.extension.map((e) => exports.FieldDescriptorProto.toJSON(e)); + } + if (message.nestedType?.length) { + obj.nestedType = message.nestedType.map((e) => exports.DescriptorProto.toJSON(e)); + } + if (message.enumType?.length) { + obj.enumType = message.enumType.map((e) => exports.EnumDescriptorProto.toJSON(e)); + } + if (message.extensionRange?.length) { + obj.extensionRange = message.extensionRange.map((e) => exports.DescriptorProto_ExtensionRange.toJSON(e)); + } + if (message.oneofDecl?.length) { + obj.oneofDecl = message.oneofDecl.map((e) => exports.OneofDescriptorProto.toJSON(e)); + } + if (message.options !== undefined) { + obj.options = exports.MessageOptions.toJSON(message.options); + } + if (message.reservedRange?.length) { + obj.reservedRange = message.reservedRange.map((e) => exports.DescriptorProto_ReservedRange.toJSON(e)); + } + if (message.reservedName?.length) { + obj.reservedName = message.reservedName; + } + return obj; + }, +}; +exports.DescriptorProto_ExtensionRange = { + fromJSON(object) { + return { + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + end: isSet(object.end) ? globalThis.Number(object.end) : 0, + options: isSet(object.options) ? exports.ExtensionRangeOptions.fromJSON(object.options) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.start !== undefined && message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.end !== undefined && message.end !== 0) { + obj.end = Math.round(message.end); + } + if (message.options !== undefined) { + obj.options = exports.ExtensionRangeOptions.toJSON(message.options); + } + return obj; + }, +}; +exports.DescriptorProto_ReservedRange = { + fromJSON(object) { + return { + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + end: isSet(object.end) ? globalThis.Number(object.end) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.start !== undefined && message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.end !== undefined && message.end !== 0) { + obj.end = Math.round(message.end); + } + return obj; + }, +}; +exports.ExtensionRangeOptions = { + fromJSON(object) { + return { + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + declaration: globalThis.Array.isArray(object?.declaration) + ? object.declaration.map((e) => exports.ExtensionRangeOptions_Declaration.fromJSON(e)) + : [], + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + verification: isSet(object.verification) + ? extensionRangeOptions_VerificationStateFromJSON(object.verification) + : 1, + }; + }, + toJSON(message) { + const obj = {}; + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + if (message.declaration?.length) { + obj.declaration = message.declaration.map((e) => exports.ExtensionRangeOptions_Declaration.toJSON(e)); + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.verification !== undefined && message.verification !== 1) { + obj.verification = extensionRangeOptions_VerificationStateToJSON(message.verification); + } + return obj; + }, +}; +exports.ExtensionRangeOptions_Declaration = { + fromJSON(object) { + return { + number: isSet(object.number) ? globalThis.Number(object.number) : 0, + fullName: isSet(object.fullName) ? globalThis.String(object.fullName) : "", + type: isSet(object.type) ? globalThis.String(object.type) : "", + reserved: isSet(object.reserved) ? globalThis.Boolean(object.reserved) : false, + repeated: isSet(object.repeated) ? globalThis.Boolean(object.repeated) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.number !== undefined && message.number !== 0) { + obj.number = Math.round(message.number); + } + if (message.fullName !== undefined && message.fullName !== "") { + obj.fullName = message.fullName; + } + if (message.type !== undefined && message.type !== "") { + obj.type = message.type; + } + if (message.reserved !== undefined && message.reserved !== false) { + obj.reserved = message.reserved; + } + if (message.repeated !== undefined && message.repeated !== false) { + obj.repeated = message.repeated; + } + return obj; + }, +}; +exports.FieldDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + number: isSet(object.number) ? globalThis.Number(object.number) : 0, + label: isSet(object.label) ? fieldDescriptorProto_LabelFromJSON(object.label) : 1, + type: isSet(object.type) ? fieldDescriptorProto_TypeFromJSON(object.type) : 1, + typeName: isSet(object.typeName) ? globalThis.String(object.typeName) : "", + extendee: isSet(object.extendee) ? globalThis.String(object.extendee) : "", + defaultValue: isSet(object.defaultValue) ? globalThis.String(object.defaultValue) : "", + oneofIndex: isSet(object.oneofIndex) ? globalThis.Number(object.oneofIndex) : 0, + jsonName: isSet(object.jsonName) ? globalThis.String(object.jsonName) : "", + options: isSet(object.options) ? exports.FieldOptions.fromJSON(object.options) : undefined, + proto3Optional: isSet(object.proto3Optional) ? globalThis.Boolean(object.proto3Optional) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.number !== undefined && message.number !== 0) { + obj.number = Math.round(message.number); + } + if (message.label !== undefined && message.label !== 1) { + obj.label = fieldDescriptorProto_LabelToJSON(message.label); + } + if (message.type !== undefined && message.type !== 1) { + obj.type = fieldDescriptorProto_TypeToJSON(message.type); + } + if (message.typeName !== undefined && message.typeName !== "") { + obj.typeName = message.typeName; + } + if (message.extendee !== undefined && message.extendee !== "") { + obj.extendee = message.extendee; + } + if (message.defaultValue !== undefined && message.defaultValue !== "") { + obj.defaultValue = message.defaultValue; + } + if (message.oneofIndex !== undefined && message.oneofIndex !== 0) { + obj.oneofIndex = Math.round(message.oneofIndex); + } + if (message.jsonName !== undefined && message.jsonName !== "") { + obj.jsonName = message.jsonName; + } + if (message.options !== undefined) { + obj.options = exports.FieldOptions.toJSON(message.options); + } + if (message.proto3Optional !== undefined && message.proto3Optional !== false) { + obj.proto3Optional = message.proto3Optional; + } + return obj; + }, +}; +exports.OneofDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + options: isSet(object.options) ? exports.OneofOptions.fromJSON(object.options) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.options !== undefined) { + obj.options = exports.OneofOptions.toJSON(message.options); + } + return obj; + }, +}; +exports.EnumDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + value: globalThis.Array.isArray(object?.value) + ? object.value.map((e) => exports.EnumValueDescriptorProto.fromJSON(e)) + : [], + options: isSet(object.options) ? exports.EnumOptions.fromJSON(object.options) : undefined, + reservedRange: globalThis.Array.isArray(object?.reservedRange) + ? object.reservedRange.map((e) => exports.EnumDescriptorProto_EnumReservedRange.fromJSON(e)) + : [], + reservedName: globalThis.Array.isArray(object?.reservedName) + ? object.reservedName.map((e) => globalThis.String(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.value?.length) { + obj.value = message.value.map((e) => exports.EnumValueDescriptorProto.toJSON(e)); + } + if (message.options !== undefined) { + obj.options = exports.EnumOptions.toJSON(message.options); + } + if (message.reservedRange?.length) { + obj.reservedRange = message.reservedRange.map((e) => exports.EnumDescriptorProto_EnumReservedRange.toJSON(e)); + } + if (message.reservedName?.length) { + obj.reservedName = message.reservedName; + } + return obj; + }, +}; +exports.EnumDescriptorProto_EnumReservedRange = { + fromJSON(object) { + return { + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + end: isSet(object.end) ? globalThis.Number(object.end) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.start !== undefined && message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.end !== undefined && message.end !== 0) { + obj.end = Math.round(message.end); + } + return obj; + }, +}; +exports.EnumValueDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + number: isSet(object.number) ? globalThis.Number(object.number) : 0, + options: isSet(object.options) ? exports.EnumValueOptions.fromJSON(object.options) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.number !== undefined && message.number !== 0) { + obj.number = Math.round(message.number); + } + if (message.options !== undefined) { + obj.options = exports.EnumValueOptions.toJSON(message.options); + } + return obj; + }, +}; +exports.ServiceDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + method: globalThis.Array.isArray(object?.method) + ? object.method.map((e) => exports.MethodDescriptorProto.fromJSON(e)) + : [], + options: isSet(object.options) ? exports.ServiceOptions.fromJSON(object.options) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.method?.length) { + obj.method = message.method.map((e) => exports.MethodDescriptorProto.toJSON(e)); + } + if (message.options !== undefined) { + obj.options = exports.ServiceOptions.toJSON(message.options); + } + return obj; + }, +}; +exports.MethodDescriptorProto = { + fromJSON(object) { + return { + name: isSet(object.name) ? globalThis.String(object.name) : "", + inputType: isSet(object.inputType) ? globalThis.String(object.inputType) : "", + outputType: isSet(object.outputType) ? globalThis.String(object.outputType) : "", + options: isSet(object.options) ? exports.MethodOptions.fromJSON(object.options) : undefined, + clientStreaming: isSet(object.clientStreaming) ? globalThis.Boolean(object.clientStreaming) : false, + serverStreaming: isSet(object.serverStreaming) ? globalThis.Boolean(object.serverStreaming) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.name !== undefined && message.name !== "") { + obj.name = message.name; + } + if (message.inputType !== undefined && message.inputType !== "") { + obj.inputType = message.inputType; + } + if (message.outputType !== undefined && message.outputType !== "") { + obj.outputType = message.outputType; + } + if (message.options !== undefined) { + obj.options = exports.MethodOptions.toJSON(message.options); + } + if (message.clientStreaming !== undefined && message.clientStreaming !== false) { + obj.clientStreaming = message.clientStreaming; + } + if (message.serverStreaming !== undefined && message.serverStreaming !== false) { + obj.serverStreaming = message.serverStreaming; + } + return obj; + }, +}; +exports.FileOptions = { + fromJSON(object) { + return { + javaPackage: isSet(object.javaPackage) ? globalThis.String(object.javaPackage) : "", + javaOuterClassname: isSet(object.javaOuterClassname) ? globalThis.String(object.javaOuterClassname) : "", + javaMultipleFiles: isSet(object.javaMultipleFiles) ? globalThis.Boolean(object.javaMultipleFiles) : false, + javaGenerateEqualsAndHash: isSet(object.javaGenerateEqualsAndHash) + ? globalThis.Boolean(object.javaGenerateEqualsAndHash) + : false, + javaStringCheckUtf8: isSet(object.javaStringCheckUtf8) ? globalThis.Boolean(object.javaStringCheckUtf8) : false, + optimizeFor: isSet(object.optimizeFor) ? fileOptions_OptimizeModeFromJSON(object.optimizeFor) : 1, + goPackage: isSet(object.goPackage) ? globalThis.String(object.goPackage) : "", + ccGenericServices: isSet(object.ccGenericServices) ? globalThis.Boolean(object.ccGenericServices) : false, + javaGenericServices: isSet(object.javaGenericServices) ? globalThis.Boolean(object.javaGenericServices) : false, + pyGenericServices: isSet(object.pyGenericServices) ? globalThis.Boolean(object.pyGenericServices) : false, + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + ccEnableArenas: isSet(object.ccEnableArenas) ? globalThis.Boolean(object.ccEnableArenas) : true, + objcClassPrefix: isSet(object.objcClassPrefix) ? globalThis.String(object.objcClassPrefix) : "", + csharpNamespace: isSet(object.csharpNamespace) ? globalThis.String(object.csharpNamespace) : "", + swiftPrefix: isSet(object.swiftPrefix) ? globalThis.String(object.swiftPrefix) : "", + phpClassPrefix: isSet(object.phpClassPrefix) ? globalThis.String(object.phpClassPrefix) : "", + phpNamespace: isSet(object.phpNamespace) ? globalThis.String(object.phpNamespace) : "", + phpMetadataNamespace: isSet(object.phpMetadataNamespace) ? globalThis.String(object.phpMetadataNamespace) : "", + rubyPackage: isSet(object.rubyPackage) ? globalThis.String(object.rubyPackage) : "", + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.javaPackage !== undefined && message.javaPackage !== "") { + obj.javaPackage = message.javaPackage; + } + if (message.javaOuterClassname !== undefined && message.javaOuterClassname !== "") { + obj.javaOuterClassname = message.javaOuterClassname; + } + if (message.javaMultipleFiles !== undefined && message.javaMultipleFiles !== false) { + obj.javaMultipleFiles = message.javaMultipleFiles; + } + if (message.javaGenerateEqualsAndHash !== undefined && message.javaGenerateEqualsAndHash !== false) { + obj.javaGenerateEqualsAndHash = message.javaGenerateEqualsAndHash; + } + if (message.javaStringCheckUtf8 !== undefined && message.javaStringCheckUtf8 !== false) { + obj.javaStringCheckUtf8 = message.javaStringCheckUtf8; + } + if (message.optimizeFor !== undefined && message.optimizeFor !== 1) { + obj.optimizeFor = fileOptions_OptimizeModeToJSON(message.optimizeFor); + } + if (message.goPackage !== undefined && message.goPackage !== "") { + obj.goPackage = message.goPackage; + } + if (message.ccGenericServices !== undefined && message.ccGenericServices !== false) { + obj.ccGenericServices = message.ccGenericServices; + } + if (message.javaGenericServices !== undefined && message.javaGenericServices !== false) { + obj.javaGenericServices = message.javaGenericServices; + } + if (message.pyGenericServices !== undefined && message.pyGenericServices !== false) { + obj.pyGenericServices = message.pyGenericServices; + } + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.ccEnableArenas !== undefined && message.ccEnableArenas !== true) { + obj.ccEnableArenas = message.ccEnableArenas; + } + if (message.objcClassPrefix !== undefined && message.objcClassPrefix !== "") { + obj.objcClassPrefix = message.objcClassPrefix; + } + if (message.csharpNamespace !== undefined && message.csharpNamespace !== "") { + obj.csharpNamespace = message.csharpNamespace; + } + if (message.swiftPrefix !== undefined && message.swiftPrefix !== "") { + obj.swiftPrefix = message.swiftPrefix; + } + if (message.phpClassPrefix !== undefined && message.phpClassPrefix !== "") { + obj.phpClassPrefix = message.phpClassPrefix; + } + if (message.phpNamespace !== undefined && message.phpNamespace !== "") { + obj.phpNamespace = message.phpNamespace; + } + if (message.phpMetadataNamespace !== undefined && message.phpMetadataNamespace !== "") { + obj.phpMetadataNamespace = message.phpMetadataNamespace; + } + if (message.rubyPackage !== undefined && message.rubyPackage !== "") { + obj.rubyPackage = message.rubyPackage; + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.MessageOptions = { + fromJSON(object) { + return { + messageSetWireFormat: isSet(object.messageSetWireFormat) + ? globalThis.Boolean(object.messageSetWireFormat) + : false, + noStandardDescriptorAccessor: isSet(object.noStandardDescriptorAccessor) + ? globalThis.Boolean(object.noStandardDescriptorAccessor) + : false, + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + mapEntry: isSet(object.mapEntry) ? globalThis.Boolean(object.mapEntry) : false, + deprecatedLegacyJsonFieldConflicts: isSet(object.deprecatedLegacyJsonFieldConflicts) + ? globalThis.Boolean(object.deprecatedLegacyJsonFieldConflicts) + : false, + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.messageSetWireFormat !== undefined && message.messageSetWireFormat !== false) { + obj.messageSetWireFormat = message.messageSetWireFormat; + } + if (message.noStandardDescriptorAccessor !== undefined && message.noStandardDescriptorAccessor !== false) { + obj.noStandardDescriptorAccessor = message.noStandardDescriptorAccessor; + } + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.mapEntry !== undefined && message.mapEntry !== false) { + obj.mapEntry = message.mapEntry; + } + if (message.deprecatedLegacyJsonFieldConflicts !== undefined && message.deprecatedLegacyJsonFieldConflicts !== false) { + obj.deprecatedLegacyJsonFieldConflicts = message.deprecatedLegacyJsonFieldConflicts; + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.FieldOptions = { + fromJSON(object) { + return { + ctype: isSet(object.ctype) ? fieldOptions_CTypeFromJSON(object.ctype) : 0, + packed: isSet(object.packed) ? globalThis.Boolean(object.packed) : false, + jstype: isSet(object.jstype) ? fieldOptions_JSTypeFromJSON(object.jstype) : 0, + lazy: isSet(object.lazy) ? globalThis.Boolean(object.lazy) : false, + unverifiedLazy: isSet(object.unverifiedLazy) ? globalThis.Boolean(object.unverifiedLazy) : false, + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + weak: isSet(object.weak) ? globalThis.Boolean(object.weak) : false, + debugRedact: isSet(object.debugRedact) ? globalThis.Boolean(object.debugRedact) : false, + retention: isSet(object.retention) ? fieldOptions_OptionRetentionFromJSON(object.retention) : 0, + targets: globalThis.Array.isArray(object?.targets) + ? object.targets.map((e) => fieldOptions_OptionTargetTypeFromJSON(e)) + : [], + editionDefaults: globalThis.Array.isArray(object?.editionDefaults) + ? object.editionDefaults.map((e) => exports.FieldOptions_EditionDefault.fromJSON(e)) + : [], + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + featureSupport: isSet(object.featureSupport) + ? exports.FieldOptions_FeatureSupport.fromJSON(object.featureSupport) + : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.ctype !== undefined && message.ctype !== 0) { + obj.ctype = fieldOptions_CTypeToJSON(message.ctype); + } + if (message.packed !== undefined && message.packed !== false) { + obj.packed = message.packed; + } + if (message.jstype !== undefined && message.jstype !== 0) { + obj.jstype = fieldOptions_JSTypeToJSON(message.jstype); + } + if (message.lazy !== undefined && message.lazy !== false) { + obj.lazy = message.lazy; + } + if (message.unverifiedLazy !== undefined && message.unverifiedLazy !== false) { + obj.unverifiedLazy = message.unverifiedLazy; + } + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.weak !== undefined && message.weak !== false) { + obj.weak = message.weak; + } + if (message.debugRedact !== undefined && message.debugRedact !== false) { + obj.debugRedact = message.debugRedact; + } + if (message.retention !== undefined && message.retention !== 0) { + obj.retention = fieldOptions_OptionRetentionToJSON(message.retention); + } + if (message.targets?.length) { + obj.targets = message.targets.map((e) => fieldOptions_OptionTargetTypeToJSON(e)); + } + if (message.editionDefaults?.length) { + obj.editionDefaults = message.editionDefaults.map((e) => exports.FieldOptions_EditionDefault.toJSON(e)); + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.featureSupport !== undefined) { + obj.featureSupport = exports.FieldOptions_FeatureSupport.toJSON(message.featureSupport); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.FieldOptions_EditionDefault = { + fromJSON(object) { + return { + edition: isSet(object.edition) ? editionFromJSON(object.edition) : 0, + value: isSet(object.value) ? globalThis.String(object.value) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.edition !== undefined && message.edition !== 0) { + obj.edition = editionToJSON(message.edition); + } + if (message.value !== undefined && message.value !== "") { + obj.value = message.value; + } + return obj; + }, +}; +exports.FieldOptions_FeatureSupport = { + fromJSON(object) { + return { + editionIntroduced: isSet(object.editionIntroduced) ? editionFromJSON(object.editionIntroduced) : 0, + editionDeprecated: isSet(object.editionDeprecated) ? editionFromJSON(object.editionDeprecated) : 0, + deprecationWarning: isSet(object.deprecationWarning) ? globalThis.String(object.deprecationWarning) : "", + editionRemoved: isSet(object.editionRemoved) ? editionFromJSON(object.editionRemoved) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.editionIntroduced !== undefined && message.editionIntroduced !== 0) { + obj.editionIntroduced = editionToJSON(message.editionIntroduced); + } + if (message.editionDeprecated !== undefined && message.editionDeprecated !== 0) { + obj.editionDeprecated = editionToJSON(message.editionDeprecated); + } + if (message.deprecationWarning !== undefined && message.deprecationWarning !== "") { + obj.deprecationWarning = message.deprecationWarning; + } + if (message.editionRemoved !== undefined && message.editionRemoved !== 0) { + obj.editionRemoved = editionToJSON(message.editionRemoved); + } + return obj; + }, +}; +exports.OneofOptions = { + fromJSON(object) { + return { + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.EnumOptions = { + fromJSON(object) { + return { + allowAlias: isSet(object.allowAlias) ? globalThis.Boolean(object.allowAlias) : false, + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + deprecatedLegacyJsonFieldConflicts: isSet(object.deprecatedLegacyJsonFieldConflicts) + ? globalThis.Boolean(object.deprecatedLegacyJsonFieldConflicts) + : false, + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.allowAlias !== undefined && message.allowAlias !== false) { + obj.allowAlias = message.allowAlias; + } + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.deprecatedLegacyJsonFieldConflicts !== undefined && message.deprecatedLegacyJsonFieldConflicts !== false) { + obj.deprecatedLegacyJsonFieldConflicts = message.deprecatedLegacyJsonFieldConflicts; + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.EnumValueOptions = { + fromJSON(object) { + return { + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + debugRedact: isSet(object.debugRedact) ? globalThis.Boolean(object.debugRedact) : false, + featureSupport: isSet(object.featureSupport) + ? exports.FieldOptions_FeatureSupport.fromJSON(object.featureSupport) + : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.debugRedact !== undefined && message.debugRedact !== false) { + obj.debugRedact = message.debugRedact; + } + if (message.featureSupport !== undefined) { + obj.featureSupport = exports.FieldOptions_FeatureSupport.toJSON(message.featureSupport); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.ServiceOptions = { + fromJSON(object) { + return { + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.MethodOptions = { + fromJSON(object) { + return { + deprecated: isSet(object.deprecated) ? globalThis.Boolean(object.deprecated) : false, + idempotencyLevel: isSet(object.idempotencyLevel) + ? methodOptions_IdempotencyLevelFromJSON(object.idempotencyLevel) + : 0, + features: isSet(object.features) ? exports.FeatureSet.fromJSON(object.features) : undefined, + uninterpretedOption: globalThis.Array.isArray(object?.uninterpretedOption) + ? object.uninterpretedOption.map((e) => exports.UninterpretedOption.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.deprecated !== undefined && message.deprecated !== false) { + obj.deprecated = message.deprecated; + } + if (message.idempotencyLevel !== undefined && message.idempotencyLevel !== 0) { + obj.idempotencyLevel = methodOptions_IdempotencyLevelToJSON(message.idempotencyLevel); + } + if (message.features !== undefined) { + obj.features = exports.FeatureSet.toJSON(message.features); + } + if (message.uninterpretedOption?.length) { + obj.uninterpretedOption = message.uninterpretedOption.map((e) => exports.UninterpretedOption.toJSON(e)); + } + return obj; + }, +}; +exports.UninterpretedOption = { + fromJSON(object) { + return { + name: globalThis.Array.isArray(object?.name) + ? object.name.map((e) => exports.UninterpretedOption_NamePart.fromJSON(e)) + : [], + identifierValue: isSet(object.identifierValue) ? globalThis.String(object.identifierValue) : "", + positiveIntValue: isSet(object.positiveIntValue) ? globalThis.String(object.positiveIntValue) : "0", + negativeIntValue: isSet(object.negativeIntValue) ? globalThis.String(object.negativeIntValue) : "0", + doubleValue: isSet(object.doubleValue) ? globalThis.Number(object.doubleValue) : 0, + stringValue: isSet(object.stringValue) ? Buffer.from(bytesFromBase64(object.stringValue)) : Buffer.alloc(0), + aggregateValue: isSet(object.aggregateValue) ? globalThis.String(object.aggregateValue) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.name?.length) { + obj.name = message.name.map((e) => exports.UninterpretedOption_NamePart.toJSON(e)); + } + if (message.identifierValue !== undefined && message.identifierValue !== "") { + obj.identifierValue = message.identifierValue; + } + if (message.positiveIntValue !== undefined && message.positiveIntValue !== "0") { + obj.positiveIntValue = message.positiveIntValue; + } + if (message.negativeIntValue !== undefined && message.negativeIntValue !== "0") { + obj.negativeIntValue = message.negativeIntValue; + } + if (message.doubleValue !== undefined && message.doubleValue !== 0) { + obj.doubleValue = message.doubleValue; + } + if (message.stringValue !== undefined && message.stringValue.length !== 0) { + obj.stringValue = base64FromBytes(message.stringValue); + } + if (message.aggregateValue !== undefined && message.aggregateValue !== "") { + obj.aggregateValue = message.aggregateValue; + } + return obj; + }, +}; +exports.UninterpretedOption_NamePart = { + fromJSON(object) { + return { + namePart: isSet(object.namePart) ? globalThis.String(object.namePart) : "", + isExtension: isSet(object.isExtension) ? globalThis.Boolean(object.isExtension) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.namePart !== "") { + obj.namePart = message.namePart; + } + if (message.isExtension !== false) { + obj.isExtension = message.isExtension; + } + return obj; + }, +}; +exports.FeatureSet = { + fromJSON(object) { + return { + fieldPresence: isSet(object.fieldPresence) ? featureSet_FieldPresenceFromJSON(object.fieldPresence) : 0, + enumType: isSet(object.enumType) ? featureSet_EnumTypeFromJSON(object.enumType) : 0, + repeatedFieldEncoding: isSet(object.repeatedFieldEncoding) + ? featureSet_RepeatedFieldEncodingFromJSON(object.repeatedFieldEncoding) + : 0, + utf8Validation: isSet(object.utf8Validation) ? featureSet_Utf8ValidationFromJSON(object.utf8Validation) : 0, + messageEncoding: isSet(object.messageEncoding) ? featureSet_MessageEncodingFromJSON(object.messageEncoding) : 0, + jsonFormat: isSet(object.jsonFormat) ? featureSet_JsonFormatFromJSON(object.jsonFormat) : 0, + enforceNamingStyle: isSet(object.enforceNamingStyle) + ? featureSet_EnforceNamingStyleFromJSON(object.enforceNamingStyle) + : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.fieldPresence !== undefined && message.fieldPresence !== 0) { + obj.fieldPresence = featureSet_FieldPresenceToJSON(message.fieldPresence); + } + if (message.enumType !== undefined && message.enumType !== 0) { + obj.enumType = featureSet_EnumTypeToJSON(message.enumType); + } + if (message.repeatedFieldEncoding !== undefined && message.repeatedFieldEncoding !== 0) { + obj.repeatedFieldEncoding = featureSet_RepeatedFieldEncodingToJSON(message.repeatedFieldEncoding); + } + if (message.utf8Validation !== undefined && message.utf8Validation !== 0) { + obj.utf8Validation = featureSet_Utf8ValidationToJSON(message.utf8Validation); + } + if (message.messageEncoding !== undefined && message.messageEncoding !== 0) { + obj.messageEncoding = featureSet_MessageEncodingToJSON(message.messageEncoding); + } + if (message.jsonFormat !== undefined && message.jsonFormat !== 0) { + obj.jsonFormat = featureSet_JsonFormatToJSON(message.jsonFormat); + } + if (message.enforceNamingStyle !== undefined && message.enforceNamingStyle !== 0) { + obj.enforceNamingStyle = featureSet_EnforceNamingStyleToJSON(message.enforceNamingStyle); + } + return obj; + }, +}; +exports.FeatureSetDefaults = { + fromJSON(object) { + return { + defaults: globalThis.Array.isArray(object?.defaults) + ? object.defaults.map((e) => exports.FeatureSetDefaults_FeatureSetEditionDefault.fromJSON(e)) + : [], + minimumEdition: isSet(object.minimumEdition) ? editionFromJSON(object.minimumEdition) : 0, + maximumEdition: isSet(object.maximumEdition) ? editionFromJSON(object.maximumEdition) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.defaults?.length) { + obj.defaults = message.defaults.map((e) => exports.FeatureSetDefaults_FeatureSetEditionDefault.toJSON(e)); + } + if (message.minimumEdition !== undefined && message.minimumEdition !== 0) { + obj.minimumEdition = editionToJSON(message.minimumEdition); + } + if (message.maximumEdition !== undefined && message.maximumEdition !== 0) { + obj.maximumEdition = editionToJSON(message.maximumEdition); + } + return obj; + }, +}; +exports.FeatureSetDefaults_FeatureSetEditionDefault = { + fromJSON(object) { + return { + edition: isSet(object.edition) ? editionFromJSON(object.edition) : 0, + overridableFeatures: isSet(object.overridableFeatures) + ? exports.FeatureSet.fromJSON(object.overridableFeatures) + : undefined, + fixedFeatures: isSet(object.fixedFeatures) ? exports.FeatureSet.fromJSON(object.fixedFeatures) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.edition !== undefined && message.edition !== 0) { + obj.edition = editionToJSON(message.edition); + } + if (message.overridableFeatures !== undefined) { + obj.overridableFeatures = exports.FeatureSet.toJSON(message.overridableFeatures); + } + if (message.fixedFeatures !== undefined) { + obj.fixedFeatures = exports.FeatureSet.toJSON(message.fixedFeatures); + } + return obj; + }, +}; +exports.SourceCodeInfo = { + fromJSON(object) { + return { + location: globalThis.Array.isArray(object?.location) + ? object.location.map((e) => exports.SourceCodeInfo_Location.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.location?.length) { + obj.location = message.location.map((e) => exports.SourceCodeInfo_Location.toJSON(e)); + } + return obj; + }, +}; +exports.SourceCodeInfo_Location = { + fromJSON(object) { + return { + path: globalThis.Array.isArray(object?.path) + ? object.path.map((e) => globalThis.Number(e)) + : [], + span: globalThis.Array.isArray(object?.span) ? object.span.map((e) => globalThis.Number(e)) : [], + leadingComments: isSet(object.leadingComments) ? globalThis.String(object.leadingComments) : "", + trailingComments: isSet(object.trailingComments) ? globalThis.String(object.trailingComments) : "", + leadingDetachedComments: globalThis.Array.isArray(object?.leadingDetachedComments) + ? object.leadingDetachedComments.map((e) => globalThis.String(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.path?.length) { + obj.path = message.path.map((e) => Math.round(e)); + } + if (message.span?.length) { + obj.span = message.span.map((e) => Math.round(e)); + } + if (message.leadingComments !== undefined && message.leadingComments !== "") { + obj.leadingComments = message.leadingComments; + } + if (message.trailingComments !== undefined && message.trailingComments !== "") { + obj.trailingComments = message.trailingComments; + } + if (message.leadingDetachedComments?.length) { + obj.leadingDetachedComments = message.leadingDetachedComments; + } + return obj; + }, +}; +exports.GeneratedCodeInfo = { + fromJSON(object) { + return { + annotation: globalThis.Array.isArray(object?.annotation) + ? object.annotation.map((e) => exports.GeneratedCodeInfo_Annotation.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.annotation?.length) { + obj.annotation = message.annotation.map((e) => exports.GeneratedCodeInfo_Annotation.toJSON(e)); + } + return obj; + }, +}; +exports.GeneratedCodeInfo_Annotation = { + fromJSON(object) { + return { + path: globalThis.Array.isArray(object?.path) + ? object.path.map((e) => globalThis.Number(e)) + : [], + sourceFile: isSet(object.sourceFile) ? globalThis.String(object.sourceFile) : "", + begin: isSet(object.begin) ? globalThis.Number(object.begin) : 0, + end: isSet(object.end) ? globalThis.Number(object.end) : 0, + semantic: isSet(object.semantic) ? generatedCodeInfo_Annotation_SemanticFromJSON(object.semantic) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.path?.length) { + obj.path = message.path.map((e) => Math.round(e)); + } + if (message.sourceFile !== undefined && message.sourceFile !== "") { + obj.sourceFile = message.sourceFile; + } + if (message.begin !== undefined && message.begin !== 0) { + obj.begin = Math.round(message.begin); + } + if (message.end !== undefined && message.end !== 0) { + obj.end = Math.round(message.end); + } + if (message.semantic !== undefined && message.semantic !== 0) { + obj.semantic = generatedCodeInfo_Annotation_SemanticToJSON(message.semantic); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/timestamp.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/timestamp.js new file mode 100644 index 0000000000000..9d24cbba10de9 --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/google/protobuf/timestamp.js @@ -0,0 +1,29 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: google/protobuf/timestamp.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Timestamp = void 0; +exports.Timestamp = { + fromJSON(object) { + return { + seconds: isSet(object.seconds) ? globalThis.String(object.seconds) : "0", + nanos: isSet(object.nanos) ? globalThis.Number(object.nanos) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.seconds !== "0") { + obj.seconds = message.seconds; + } + if (message.nanos !== 0) { + obj.nanos = Math.round(message.nanos); + } + return obj; + }, +}; +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/dsse.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/dsse.js new file mode 100644 index 0000000000000..abc766bed3b88 --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/dsse.js @@ -0,0 +1,55 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: rekor/v2/dsse.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSSELogEntryV002 = exports.DSSERequestV002 = void 0; +/* eslint-disable */ +const envelope_1 = require("../../envelope"); +const sigstore_common_1 = require("../../sigstore_common"); +const verifier_1 = require("./verifier"); +exports.DSSERequestV002 = { + fromJSON(object) { + return { + envelope: isSet(object.envelope) ? envelope_1.Envelope.fromJSON(object.envelope) : undefined, + verifiers: globalThis.Array.isArray(object?.verifiers) + ? object.verifiers.map((e) => verifier_1.Verifier.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.envelope !== undefined) { + obj.envelope = envelope_1.Envelope.toJSON(message.envelope); + } + if (message.verifiers?.length) { + obj.verifiers = message.verifiers.map((e) => verifier_1.Verifier.toJSON(e)); + } + return obj; + }, +}; +exports.DSSELogEntryV002 = { + fromJSON(object) { + return { + payloadHash: isSet(object.payloadHash) ? sigstore_common_1.HashOutput.fromJSON(object.payloadHash) : undefined, + signatures: globalThis.Array.isArray(object?.signatures) + ? object.signatures.map((e) => verifier_1.Signature.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.payloadHash !== undefined) { + obj.payloadHash = sigstore_common_1.HashOutput.toJSON(message.payloadHash); + } + if (message.signatures?.length) { + obj.signatures = message.signatures.map((e) => verifier_1.Signature.toJSON(e)); + } + return obj; + }, +}; +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/entry.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/entry.js new file mode 100644 index 0000000000000..c5eccb10e0a68 --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/entry.js @@ -0,0 +1,81 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: rekor/v2/entry.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CreateEntryRequest = exports.Spec = exports.Entry = void 0; +/* eslint-disable */ +const dsse_1 = require("./dsse"); +const hashedrekord_1 = require("./hashedrekord"); +exports.Entry = { + fromJSON(object) { + return { + kind: isSet(object.kind) ? globalThis.String(object.kind) : "", + apiVersion: isSet(object.apiVersion) ? globalThis.String(object.apiVersion) : "", + spec: isSet(object.spec) ? exports.Spec.fromJSON(object.spec) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.kind !== "") { + obj.kind = message.kind; + } + if (message.apiVersion !== "") { + obj.apiVersion = message.apiVersion; + } + if (message.spec !== undefined) { + obj.spec = exports.Spec.toJSON(message.spec); + } + return obj; + }, +}; +exports.Spec = { + fromJSON(object) { + return { + spec: isSet(object.hashedRekordV002) + ? { $case: "hashedRekordV002", hashedRekordV002: hashedrekord_1.HashedRekordLogEntryV002.fromJSON(object.hashedRekordV002) } + : isSet(object.dsseV002) + ? { $case: "dsseV002", dsseV002: dsse_1.DSSELogEntryV002.fromJSON(object.dsseV002) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.spec?.$case === "hashedRekordV002") { + obj.hashedRekordV002 = hashedrekord_1.HashedRekordLogEntryV002.toJSON(message.spec.hashedRekordV002); + } + else if (message.spec?.$case === "dsseV002") { + obj.dsseV002 = dsse_1.DSSELogEntryV002.toJSON(message.spec.dsseV002); + } + return obj; + }, +}; +exports.CreateEntryRequest = { + fromJSON(object) { + return { + spec: isSet(object.hashedRekordRequestV002) + ? { + $case: "hashedRekordRequestV002", + hashedRekordRequestV002: hashedrekord_1.HashedRekordRequestV002.fromJSON(object.hashedRekordRequestV002), + } + : isSet(object.dsseRequestV002) + ? { $case: "dsseRequestV002", dsseRequestV002: dsse_1.DSSERequestV002.fromJSON(object.dsseRequestV002) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.spec?.$case === "hashedRekordRequestV002") { + obj.hashedRekordRequestV002 = hashedrekord_1.HashedRekordRequestV002.toJSON(message.spec.hashedRekordRequestV002); + } + else if (message.spec?.$case === "dsseRequestV002") { + obj.dsseRequestV002 = dsse_1.DSSERequestV002.toJSON(message.spec.dsseRequestV002); + } + return obj; + }, +}; +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/hashedrekord.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/hashedrekord.js new file mode 100644 index 0000000000000..d3fd1af2483d1 --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/hashedrekord.js @@ -0,0 +1,56 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: rekor/v2/hashedrekord.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HashedRekordLogEntryV002 = exports.HashedRekordRequestV002 = void 0; +/* eslint-disable */ +const sigstore_common_1 = require("../../sigstore_common"); +const verifier_1 = require("./verifier"); +exports.HashedRekordRequestV002 = { + fromJSON(object) { + return { + digest: isSet(object.digest) ? Buffer.from(bytesFromBase64(object.digest)) : Buffer.alloc(0), + signature: isSet(object.signature) ? verifier_1.Signature.fromJSON(object.signature) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.digest.length !== 0) { + obj.digest = base64FromBytes(message.digest); + } + if (message.signature !== undefined) { + obj.signature = verifier_1.Signature.toJSON(message.signature); + } + return obj; + }, +}; +exports.HashedRekordLogEntryV002 = { + fromJSON(object) { + return { + data: isSet(object.data) ? sigstore_common_1.HashOutput.fromJSON(object.data) : undefined, + signature: isSet(object.signature) ? verifier_1.Signature.fromJSON(object.signature) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.data !== undefined) { + obj.data = sigstore_common_1.HashOutput.toJSON(message.data); + } + if (message.signature !== undefined) { + obj.signature = verifier_1.Signature.toJSON(message.signature); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/verifier.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/verifier.js new file mode 100644 index 0000000000000..c437d5053a3cb --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/rekor/v2/verifier.js @@ -0,0 +1,74 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: rekor/v2/verifier.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Signature = exports.Verifier = exports.PublicKey = void 0; +/* eslint-disable */ +const sigstore_common_1 = require("../../sigstore_common"); +exports.PublicKey = { + fromJSON(object) { + return { rawBytes: isSet(object.rawBytes) ? Buffer.from(bytesFromBase64(object.rawBytes)) : Buffer.alloc(0) }; + }, + toJSON(message) { + const obj = {}; + if (message.rawBytes.length !== 0) { + obj.rawBytes = base64FromBytes(message.rawBytes); + } + return obj; + }, +}; +exports.Verifier = { + fromJSON(object) { + return { + verifier: isSet(object.publicKey) + ? { $case: "publicKey", publicKey: exports.PublicKey.fromJSON(object.publicKey) } + : isSet(object.x509Certificate) + ? { $case: "x509Certificate", x509Certificate: sigstore_common_1.X509Certificate.fromJSON(object.x509Certificate) } + : undefined, + keyDetails: isSet(object.keyDetails) ? (0, sigstore_common_1.publicKeyDetailsFromJSON)(object.keyDetails) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.verifier?.$case === "publicKey") { + obj.publicKey = exports.PublicKey.toJSON(message.verifier.publicKey); + } + else if (message.verifier?.$case === "x509Certificate") { + obj.x509Certificate = sigstore_common_1.X509Certificate.toJSON(message.verifier.x509Certificate); + } + if (message.keyDetails !== 0) { + obj.keyDetails = (0, sigstore_common_1.publicKeyDetailsToJSON)(message.keyDetails); + } + return obj; + }, +}; +exports.Signature = { + fromJSON(object) { + return { + content: isSet(object.content) ? Buffer.from(bytesFromBase64(object.content)) : Buffer.alloc(0), + verifier: isSet(object.verifier) ? exports.Verifier.fromJSON(object.verifier) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.content.length !== 0) { + obj.content = base64FromBytes(message.content); + } + if (message.verifier !== undefined) { + obj.verifier = exports.Verifier.toJSON(message.verifier); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_bundle.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_bundle.js new file mode 100644 index 0000000000000..aed636f00e7cf --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_bundle.js @@ -0,0 +1,103 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: sigstore_bundle.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Bundle = exports.VerificationMaterial = exports.TimestampVerificationData = void 0; +/* eslint-disable */ +const envelope_1 = require("./envelope"); +const sigstore_common_1 = require("./sigstore_common"); +const sigstore_rekor_1 = require("./sigstore_rekor"); +exports.TimestampVerificationData = { + fromJSON(object) { + return { + rfc3161Timestamps: globalThis.Array.isArray(object?.rfc3161Timestamps) + ? object.rfc3161Timestamps.map((e) => sigstore_common_1.RFC3161SignedTimestamp.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.rfc3161Timestamps?.length) { + obj.rfc3161Timestamps = message.rfc3161Timestamps.map((e) => sigstore_common_1.RFC3161SignedTimestamp.toJSON(e)); + } + return obj; + }, +}; +exports.VerificationMaterial = { + fromJSON(object) { + return { + content: isSet(object.publicKey) + ? { $case: "publicKey", publicKey: sigstore_common_1.PublicKeyIdentifier.fromJSON(object.publicKey) } + : isSet(object.x509CertificateChain) + ? { + $case: "x509CertificateChain", + x509CertificateChain: sigstore_common_1.X509CertificateChain.fromJSON(object.x509CertificateChain), + } + : isSet(object.certificate) + ? { $case: "certificate", certificate: sigstore_common_1.X509Certificate.fromJSON(object.certificate) } + : undefined, + tlogEntries: globalThis.Array.isArray(object?.tlogEntries) + ? object.tlogEntries.map((e) => sigstore_rekor_1.TransparencyLogEntry.fromJSON(e)) + : [], + timestampVerificationData: isSet(object.timestampVerificationData) + ? exports.TimestampVerificationData.fromJSON(object.timestampVerificationData) + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.content?.$case === "publicKey") { + obj.publicKey = sigstore_common_1.PublicKeyIdentifier.toJSON(message.content.publicKey); + } + else if (message.content?.$case === "x509CertificateChain") { + obj.x509CertificateChain = sigstore_common_1.X509CertificateChain.toJSON(message.content.x509CertificateChain); + } + else if (message.content?.$case === "certificate") { + obj.certificate = sigstore_common_1.X509Certificate.toJSON(message.content.certificate); + } + if (message.tlogEntries?.length) { + obj.tlogEntries = message.tlogEntries.map((e) => sigstore_rekor_1.TransparencyLogEntry.toJSON(e)); + } + if (message.timestampVerificationData !== undefined) { + obj.timestampVerificationData = exports.TimestampVerificationData.toJSON(message.timestampVerificationData); + } + return obj; + }, +}; +exports.Bundle = { + fromJSON(object) { + return { + mediaType: isSet(object.mediaType) ? globalThis.String(object.mediaType) : "", + verificationMaterial: isSet(object.verificationMaterial) + ? exports.VerificationMaterial.fromJSON(object.verificationMaterial) + : undefined, + content: isSet(object.messageSignature) + ? { $case: "messageSignature", messageSignature: sigstore_common_1.MessageSignature.fromJSON(object.messageSignature) } + : isSet(object.dsseEnvelope) + ? { $case: "dsseEnvelope", dsseEnvelope: envelope_1.Envelope.fromJSON(object.dsseEnvelope) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.mediaType !== "") { + obj.mediaType = message.mediaType; + } + if (message.verificationMaterial !== undefined) { + obj.verificationMaterial = exports.VerificationMaterial.toJSON(message.verificationMaterial); + } + if (message.content?.$case === "messageSignature") { + obj.messageSignature = sigstore_common_1.MessageSignature.toJSON(message.content.messageSignature); + } + else if (message.content?.$case === "dsseEnvelope") { + obj.dsseEnvelope = envelope_1.Envelope.toJSON(message.content.dsseEnvelope); + } + return obj; + }, +}; +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_common.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_common.js new file mode 100644 index 0000000000000..b900516ed3b55 --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_common.js @@ -0,0 +1,596 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: sigstore_common.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TimeRange = exports.X509CertificateChain = exports.SubjectAlternativeName = exports.X509Certificate = exports.DistinguishedName = exports.ObjectIdentifierValuePair = exports.ObjectIdentifier = exports.PublicKeyIdentifier = exports.PublicKey = exports.RFC3161SignedTimestamp = exports.LogId = exports.MessageSignature = exports.HashOutput = exports.SubjectAlternativeNameType = exports.PublicKeyDetails = exports.HashAlgorithm = void 0; +exports.hashAlgorithmFromJSON = hashAlgorithmFromJSON; +exports.hashAlgorithmToJSON = hashAlgorithmToJSON; +exports.publicKeyDetailsFromJSON = publicKeyDetailsFromJSON; +exports.publicKeyDetailsToJSON = publicKeyDetailsToJSON; +exports.subjectAlternativeNameTypeFromJSON = subjectAlternativeNameTypeFromJSON; +exports.subjectAlternativeNameTypeToJSON = subjectAlternativeNameTypeToJSON; +/* eslint-disable */ +const timestamp_1 = require("./google/protobuf/timestamp"); +/** + * Only a subset of the secure hash standard algorithms are supported. + * See <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf> for more + * details. + * UNSPECIFIED SHOULD not be used, primary reason for inclusion is to force + * any proto JSON serialization to emit the used hash algorithm, as default + * option is to *omit* the default value of an enum (which is the first + * value, represented by '0'. + */ +var HashAlgorithm; +(function (HashAlgorithm) { + HashAlgorithm[HashAlgorithm["HASH_ALGORITHM_UNSPECIFIED"] = 0] = "HASH_ALGORITHM_UNSPECIFIED"; + HashAlgorithm[HashAlgorithm["SHA2_256"] = 1] = "SHA2_256"; + HashAlgorithm[HashAlgorithm["SHA2_384"] = 2] = "SHA2_384"; + HashAlgorithm[HashAlgorithm["SHA2_512"] = 3] = "SHA2_512"; + HashAlgorithm[HashAlgorithm["SHA3_256"] = 4] = "SHA3_256"; + HashAlgorithm[HashAlgorithm["SHA3_384"] = 5] = "SHA3_384"; +})(HashAlgorithm || (exports.HashAlgorithm = HashAlgorithm = {})); +function hashAlgorithmFromJSON(object) { + switch (object) { + case 0: + case "HASH_ALGORITHM_UNSPECIFIED": + return HashAlgorithm.HASH_ALGORITHM_UNSPECIFIED; + case 1: + case "SHA2_256": + return HashAlgorithm.SHA2_256; + case 2: + case "SHA2_384": + return HashAlgorithm.SHA2_384; + case 3: + case "SHA2_512": + return HashAlgorithm.SHA2_512; + case 4: + case "SHA3_256": + return HashAlgorithm.SHA3_256; + case 5: + case "SHA3_384": + return HashAlgorithm.SHA3_384; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum HashAlgorithm"); + } +} +function hashAlgorithmToJSON(object) { + switch (object) { + case HashAlgorithm.HASH_ALGORITHM_UNSPECIFIED: + return "HASH_ALGORITHM_UNSPECIFIED"; + case HashAlgorithm.SHA2_256: + return "SHA2_256"; + case HashAlgorithm.SHA2_384: + return "SHA2_384"; + case HashAlgorithm.SHA2_512: + return "SHA2_512"; + case HashAlgorithm.SHA3_256: + return "SHA3_256"; + case HashAlgorithm.SHA3_384: + return "SHA3_384"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum HashAlgorithm"); + } +} +/** + * Details of a specific public key, capturing the the key encoding method, + * and signature algorithm. + * + * PublicKeyDetails captures the public key/hash algorithm combinations + * recommended in the Sigstore ecosystem. + * + * This is modelled as a linear set as we want to provide a small number of + * opinionated options instead of allowing every possible permutation. + * + * Any changes to this enum MUST be reflected in the algorithm registry. + * + * See: <https://github.com/sigstore/architecture-docs/blob/main/algorithm-registry.md> + * + * To avoid the possibility of contradicting formats such as PKCS1 with + * ED25519 the valid permutations are listed as a linear set instead of a + * cartesian set (i.e one combined variable instead of two, one for encoding + * and one for the signature algorithm). + */ +var PublicKeyDetails; +(function (PublicKeyDetails) { + PublicKeyDetails[PublicKeyDetails["PUBLIC_KEY_DETAILS_UNSPECIFIED"] = 0] = "PUBLIC_KEY_DETAILS_UNSPECIFIED"; + /** + * PKCS1_RSA_PKCS1V5 - RSA + * + * @deprecated + */ + PublicKeyDetails[PublicKeyDetails["PKCS1_RSA_PKCS1V5"] = 1] = "PKCS1_RSA_PKCS1V5"; + /** + * PKCS1_RSA_PSS - See RFC8017 + * + * @deprecated + */ + PublicKeyDetails[PublicKeyDetails["PKCS1_RSA_PSS"] = 2] = "PKCS1_RSA_PSS"; + /** @deprecated */ + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PKCS1V5"] = 3] = "PKIX_RSA_PKCS1V5"; + /** @deprecated */ + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PSS"] = 4] = "PKIX_RSA_PSS"; + /** PKIX_RSA_PKCS1V15_2048_SHA256 - RSA public key in PKIX format, PKCS#1v1.5 signature */ + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PKCS1V15_2048_SHA256"] = 9] = "PKIX_RSA_PKCS1V15_2048_SHA256"; + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PKCS1V15_3072_SHA256"] = 10] = "PKIX_RSA_PKCS1V15_3072_SHA256"; + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PKCS1V15_4096_SHA256"] = 11] = "PKIX_RSA_PKCS1V15_4096_SHA256"; + /** PKIX_RSA_PSS_2048_SHA256 - RSA public key in PKIX format, RSASSA-PSS signature */ + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PSS_2048_SHA256"] = 16] = "PKIX_RSA_PSS_2048_SHA256"; + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PSS_3072_SHA256"] = 17] = "PKIX_RSA_PSS_3072_SHA256"; + PublicKeyDetails[PublicKeyDetails["PKIX_RSA_PSS_4096_SHA256"] = 18] = "PKIX_RSA_PSS_4096_SHA256"; + /** + * PKIX_ECDSA_P256_HMAC_SHA_256 - ECDSA + * + * @deprecated + */ + PublicKeyDetails[PublicKeyDetails["PKIX_ECDSA_P256_HMAC_SHA_256"] = 6] = "PKIX_ECDSA_P256_HMAC_SHA_256"; + /** PKIX_ECDSA_P256_SHA_256 - See NIST FIPS 186-4 */ + PublicKeyDetails[PublicKeyDetails["PKIX_ECDSA_P256_SHA_256"] = 5] = "PKIX_ECDSA_P256_SHA_256"; + PublicKeyDetails[PublicKeyDetails["PKIX_ECDSA_P384_SHA_384"] = 12] = "PKIX_ECDSA_P384_SHA_384"; + PublicKeyDetails[PublicKeyDetails["PKIX_ECDSA_P521_SHA_512"] = 13] = "PKIX_ECDSA_P521_SHA_512"; + /** PKIX_ED25519 - Ed 25519 */ + PublicKeyDetails[PublicKeyDetails["PKIX_ED25519"] = 7] = "PKIX_ED25519"; + PublicKeyDetails[PublicKeyDetails["PKIX_ED25519_PH"] = 8] = "PKIX_ED25519_PH"; + /** + * PKIX_ECDSA_P384_SHA_256 - These algorithms are deprecated and should not be used, but they + * were/are being used by most Sigstore clients implementations. + * + * @deprecated + */ + PublicKeyDetails[PublicKeyDetails["PKIX_ECDSA_P384_SHA_256"] = 19] = "PKIX_ECDSA_P384_SHA_256"; + /** @deprecated */ + PublicKeyDetails[PublicKeyDetails["PKIX_ECDSA_P521_SHA_256"] = 20] = "PKIX_ECDSA_P521_SHA_256"; + /** + * LMS_SHA256 - LMS and LM-OTS + * + * These algorithms are deprecated and should not be used. + * Keys and signatures MAY be used by private Sigstore + * deployments, but will not be supported by the public + * good instance. + * + * USER WARNING: LMS and LM-OTS are both stateful signature schemes. + * Using them correctly requires discretion and careful consideration + * to ensure that individual secret keys are not used more than once. + * In addition, LM-OTS is a single-use scheme, meaning that it + * MUST NOT be used for more than one signature per LM-OTS key. + * If you cannot maintain these invariants, you MUST NOT use these + * schemes. + * + * @deprecated + */ + PublicKeyDetails[PublicKeyDetails["LMS_SHA256"] = 14] = "LMS_SHA256"; + /** @deprecated */ + PublicKeyDetails[PublicKeyDetails["LMOTS_SHA256"] = 15] = "LMOTS_SHA256"; + /** + * ML_DSA_65 - ML-DSA + * + * These ML_DSA_65 and ML-DSA_87 algorithms are the pure variants that + * take data to sign rather than the prehash variants (HashML-DSA), which + * take digests. While considered quantum-resistant, their usage + * involves tradeoffs in that signatures and keys are much larger, and + * this makes deployments more costly. + * + * USER WARNING: ML_DSA_65 and ML_DSA_87 are experimental algorithms. + * In the future they MAY be used by private Sigstore deployments, but + * they are not yet fully functional. This warning will be removed when + * these algorithms are widely supported by Sigstore clients and servers, + * but care should still be taken for production environments. + */ + PublicKeyDetails[PublicKeyDetails["ML_DSA_65"] = 21] = "ML_DSA_65"; + PublicKeyDetails[PublicKeyDetails["ML_DSA_87"] = 22] = "ML_DSA_87"; +})(PublicKeyDetails || (exports.PublicKeyDetails = PublicKeyDetails = {})); +function publicKeyDetailsFromJSON(object) { + switch (object) { + case 0: + case "PUBLIC_KEY_DETAILS_UNSPECIFIED": + return PublicKeyDetails.PUBLIC_KEY_DETAILS_UNSPECIFIED; + case 1: + case "PKCS1_RSA_PKCS1V5": + return PublicKeyDetails.PKCS1_RSA_PKCS1V5; + case 2: + case "PKCS1_RSA_PSS": + return PublicKeyDetails.PKCS1_RSA_PSS; + case 3: + case "PKIX_RSA_PKCS1V5": + return PublicKeyDetails.PKIX_RSA_PKCS1V5; + case 4: + case "PKIX_RSA_PSS": + return PublicKeyDetails.PKIX_RSA_PSS; + case 9: + case "PKIX_RSA_PKCS1V15_2048_SHA256": + return PublicKeyDetails.PKIX_RSA_PKCS1V15_2048_SHA256; + case 10: + case "PKIX_RSA_PKCS1V15_3072_SHA256": + return PublicKeyDetails.PKIX_RSA_PKCS1V15_3072_SHA256; + case 11: + case "PKIX_RSA_PKCS1V15_4096_SHA256": + return PublicKeyDetails.PKIX_RSA_PKCS1V15_4096_SHA256; + case 16: + case "PKIX_RSA_PSS_2048_SHA256": + return PublicKeyDetails.PKIX_RSA_PSS_2048_SHA256; + case 17: + case "PKIX_RSA_PSS_3072_SHA256": + return PublicKeyDetails.PKIX_RSA_PSS_3072_SHA256; + case 18: + case "PKIX_RSA_PSS_4096_SHA256": + return PublicKeyDetails.PKIX_RSA_PSS_4096_SHA256; + case 6: + case "PKIX_ECDSA_P256_HMAC_SHA_256": + return PublicKeyDetails.PKIX_ECDSA_P256_HMAC_SHA_256; + case 5: + case "PKIX_ECDSA_P256_SHA_256": + return PublicKeyDetails.PKIX_ECDSA_P256_SHA_256; + case 12: + case "PKIX_ECDSA_P384_SHA_384": + return PublicKeyDetails.PKIX_ECDSA_P384_SHA_384; + case 13: + case "PKIX_ECDSA_P521_SHA_512": + return PublicKeyDetails.PKIX_ECDSA_P521_SHA_512; + case 7: + case "PKIX_ED25519": + return PublicKeyDetails.PKIX_ED25519; + case 8: + case "PKIX_ED25519_PH": + return PublicKeyDetails.PKIX_ED25519_PH; + case 19: + case "PKIX_ECDSA_P384_SHA_256": + return PublicKeyDetails.PKIX_ECDSA_P384_SHA_256; + case 20: + case "PKIX_ECDSA_P521_SHA_256": + return PublicKeyDetails.PKIX_ECDSA_P521_SHA_256; + case 14: + case "LMS_SHA256": + return PublicKeyDetails.LMS_SHA256; + case 15: + case "LMOTS_SHA256": + return PublicKeyDetails.LMOTS_SHA256; + case 21: + case "ML_DSA_65": + return PublicKeyDetails.ML_DSA_65; + case 22: + case "ML_DSA_87": + return PublicKeyDetails.ML_DSA_87; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum PublicKeyDetails"); + } +} +function publicKeyDetailsToJSON(object) { + switch (object) { + case PublicKeyDetails.PUBLIC_KEY_DETAILS_UNSPECIFIED: + return "PUBLIC_KEY_DETAILS_UNSPECIFIED"; + case PublicKeyDetails.PKCS1_RSA_PKCS1V5: + return "PKCS1_RSA_PKCS1V5"; + case PublicKeyDetails.PKCS1_RSA_PSS: + return "PKCS1_RSA_PSS"; + case PublicKeyDetails.PKIX_RSA_PKCS1V5: + return "PKIX_RSA_PKCS1V5"; + case PublicKeyDetails.PKIX_RSA_PSS: + return "PKIX_RSA_PSS"; + case PublicKeyDetails.PKIX_RSA_PKCS1V15_2048_SHA256: + return "PKIX_RSA_PKCS1V15_2048_SHA256"; + case PublicKeyDetails.PKIX_RSA_PKCS1V15_3072_SHA256: + return "PKIX_RSA_PKCS1V15_3072_SHA256"; + case PublicKeyDetails.PKIX_RSA_PKCS1V15_4096_SHA256: + return "PKIX_RSA_PKCS1V15_4096_SHA256"; + case PublicKeyDetails.PKIX_RSA_PSS_2048_SHA256: + return "PKIX_RSA_PSS_2048_SHA256"; + case PublicKeyDetails.PKIX_RSA_PSS_3072_SHA256: + return "PKIX_RSA_PSS_3072_SHA256"; + case PublicKeyDetails.PKIX_RSA_PSS_4096_SHA256: + return "PKIX_RSA_PSS_4096_SHA256"; + case PublicKeyDetails.PKIX_ECDSA_P256_HMAC_SHA_256: + return "PKIX_ECDSA_P256_HMAC_SHA_256"; + case PublicKeyDetails.PKIX_ECDSA_P256_SHA_256: + return "PKIX_ECDSA_P256_SHA_256"; + case PublicKeyDetails.PKIX_ECDSA_P384_SHA_384: + return "PKIX_ECDSA_P384_SHA_384"; + case PublicKeyDetails.PKIX_ECDSA_P521_SHA_512: + return "PKIX_ECDSA_P521_SHA_512"; + case PublicKeyDetails.PKIX_ED25519: + return "PKIX_ED25519"; + case PublicKeyDetails.PKIX_ED25519_PH: + return "PKIX_ED25519_PH"; + case PublicKeyDetails.PKIX_ECDSA_P384_SHA_256: + return "PKIX_ECDSA_P384_SHA_256"; + case PublicKeyDetails.PKIX_ECDSA_P521_SHA_256: + return "PKIX_ECDSA_P521_SHA_256"; + case PublicKeyDetails.LMS_SHA256: + return "LMS_SHA256"; + case PublicKeyDetails.LMOTS_SHA256: + return "LMOTS_SHA256"; + case PublicKeyDetails.ML_DSA_65: + return "ML_DSA_65"; + case PublicKeyDetails.ML_DSA_87: + return "ML_DSA_87"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum PublicKeyDetails"); + } +} +var SubjectAlternativeNameType; +(function (SubjectAlternativeNameType) { + SubjectAlternativeNameType[SubjectAlternativeNameType["SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED"] = 0] = "SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED"; + SubjectAlternativeNameType[SubjectAlternativeNameType["EMAIL"] = 1] = "EMAIL"; + SubjectAlternativeNameType[SubjectAlternativeNameType["URI"] = 2] = "URI"; + /** + * OTHER_NAME - OID 1.3.6.1.4.1.57264.1.7 + * See https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#1361415726417--othername-san + * for more details. + */ + SubjectAlternativeNameType[SubjectAlternativeNameType["OTHER_NAME"] = 3] = "OTHER_NAME"; +})(SubjectAlternativeNameType || (exports.SubjectAlternativeNameType = SubjectAlternativeNameType = {})); +function subjectAlternativeNameTypeFromJSON(object) { + switch (object) { + case 0: + case "SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED": + return SubjectAlternativeNameType.SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED; + case 1: + case "EMAIL": + return SubjectAlternativeNameType.EMAIL; + case 2: + case "URI": + return SubjectAlternativeNameType.URI; + case 3: + case "OTHER_NAME": + return SubjectAlternativeNameType.OTHER_NAME; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum SubjectAlternativeNameType"); + } +} +function subjectAlternativeNameTypeToJSON(object) { + switch (object) { + case SubjectAlternativeNameType.SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED: + return "SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED"; + case SubjectAlternativeNameType.EMAIL: + return "EMAIL"; + case SubjectAlternativeNameType.URI: + return "URI"; + case SubjectAlternativeNameType.OTHER_NAME: + return "OTHER_NAME"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum SubjectAlternativeNameType"); + } +} +exports.HashOutput = { + fromJSON(object) { + return { + algorithm: isSet(object.algorithm) ? hashAlgorithmFromJSON(object.algorithm) : 0, + digest: isSet(object.digest) ? Buffer.from(bytesFromBase64(object.digest)) : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.algorithm !== 0) { + obj.algorithm = hashAlgorithmToJSON(message.algorithm); + } + if (message.digest.length !== 0) { + obj.digest = base64FromBytes(message.digest); + } + return obj; + }, +}; +exports.MessageSignature = { + fromJSON(object) { + return { + messageDigest: isSet(object.messageDigest) ? exports.HashOutput.fromJSON(object.messageDigest) : undefined, + signature: isSet(object.signature) ? Buffer.from(bytesFromBase64(object.signature)) : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.messageDigest !== undefined) { + obj.messageDigest = exports.HashOutput.toJSON(message.messageDigest); + } + if (message.signature.length !== 0) { + obj.signature = base64FromBytes(message.signature); + } + return obj; + }, +}; +exports.LogId = { + fromJSON(object) { + return { keyId: isSet(object.keyId) ? Buffer.from(bytesFromBase64(object.keyId)) : Buffer.alloc(0) }; + }, + toJSON(message) { + const obj = {}; + if (message.keyId.length !== 0) { + obj.keyId = base64FromBytes(message.keyId); + } + return obj; + }, +}; +exports.RFC3161SignedTimestamp = { + fromJSON(object) { + return { + signedTimestamp: isSet(object.signedTimestamp) + ? Buffer.from(bytesFromBase64(object.signedTimestamp)) + : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.signedTimestamp.length !== 0) { + obj.signedTimestamp = base64FromBytes(message.signedTimestamp); + } + return obj; + }, +}; +exports.PublicKey = { + fromJSON(object) { + return { + rawBytes: isSet(object.rawBytes) ? Buffer.from(bytesFromBase64(object.rawBytes)) : undefined, + keyDetails: isSet(object.keyDetails) ? publicKeyDetailsFromJSON(object.keyDetails) : 0, + validFor: isSet(object.validFor) ? exports.TimeRange.fromJSON(object.validFor) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.rawBytes !== undefined) { + obj.rawBytes = base64FromBytes(message.rawBytes); + } + if (message.keyDetails !== 0) { + obj.keyDetails = publicKeyDetailsToJSON(message.keyDetails); + } + if (message.validFor !== undefined) { + obj.validFor = exports.TimeRange.toJSON(message.validFor); + } + return obj; + }, +}; +exports.PublicKeyIdentifier = { + fromJSON(object) { + return { hint: isSet(object.hint) ? globalThis.String(object.hint) : "" }; + }, + toJSON(message) { + const obj = {}; + if (message.hint !== "") { + obj.hint = message.hint; + } + return obj; + }, +}; +exports.ObjectIdentifier = { + fromJSON(object) { + return { id: globalThis.Array.isArray(object?.id) ? object.id.map((e) => globalThis.Number(e)) : [] }; + }, + toJSON(message) { + const obj = {}; + if (message.id?.length) { + obj.id = message.id.map((e) => Math.round(e)); + } + return obj; + }, +}; +exports.ObjectIdentifierValuePair = { + fromJSON(object) { + return { + oid: isSet(object.oid) ? exports.ObjectIdentifier.fromJSON(object.oid) : undefined, + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.oid !== undefined) { + obj.oid = exports.ObjectIdentifier.toJSON(message.oid); + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, +}; +exports.DistinguishedName = { + fromJSON(object) { + return { + organization: isSet(object.organization) ? globalThis.String(object.organization) : "", + commonName: isSet(object.commonName) ? globalThis.String(object.commonName) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.organization !== "") { + obj.organization = message.organization; + } + if (message.commonName !== "") { + obj.commonName = message.commonName; + } + return obj; + }, +}; +exports.X509Certificate = { + fromJSON(object) { + return { rawBytes: isSet(object.rawBytes) ? Buffer.from(bytesFromBase64(object.rawBytes)) : Buffer.alloc(0) }; + }, + toJSON(message) { + const obj = {}; + if (message.rawBytes.length !== 0) { + obj.rawBytes = base64FromBytes(message.rawBytes); + } + return obj; + }, +}; +exports.SubjectAlternativeName = { + fromJSON(object) { + return { + type: isSet(object.type) ? subjectAlternativeNameTypeFromJSON(object.type) : 0, + identity: isSet(object.regexp) + ? { $case: "regexp", regexp: globalThis.String(object.regexp) } + : isSet(object.value) + ? { $case: "value", value: globalThis.String(object.value) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.type !== 0) { + obj.type = subjectAlternativeNameTypeToJSON(message.type); + } + if (message.identity?.$case === "regexp") { + obj.regexp = message.identity.regexp; + } + else if (message.identity?.$case === "value") { + obj.value = message.identity.value; + } + return obj; + }, +}; +exports.X509CertificateChain = { + fromJSON(object) { + return { + certificates: globalThis.Array.isArray(object?.certificates) + ? object.certificates.map((e) => exports.X509Certificate.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.certificates?.length) { + obj.certificates = message.certificates.map((e) => exports.X509Certificate.toJSON(e)); + } + return obj; + }, +}; +exports.TimeRange = { + fromJSON(object) { + return { + start: isSet(object.start) ? fromJsonTimestamp(object.start) : undefined, + end: isSet(object.end) ? fromJsonTimestamp(object.end) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.start !== undefined) { + obj.start = message.start.toISOString(); + } + if (message.end !== undefined) { + obj.end = message.end.toISOString(); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function fromTimestamp(t) { + let millis = (globalThis.Number(t.seconds) || 0) * 1_000; + millis += (t.nanos || 0) / 1_000_000; + return new globalThis.Date(millis); +} +function fromJsonTimestamp(o) { + if (o instanceof globalThis.Date) { + return o; + } + else if (typeof o === "string") { + return new globalThis.Date(o); + } + else { + return fromTimestamp(timestamp_1.Timestamp.fromJSON(o)); + } +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_rekor.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_rekor.js new file mode 100644 index 0000000000000..fd8ea8384664d --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_rekor.js @@ -0,0 +1,137 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: sigstore_rekor.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TransparencyLogEntry = exports.InclusionPromise = exports.InclusionProof = exports.Checkpoint = exports.KindVersion = void 0; +/* eslint-disable */ +const sigstore_common_1 = require("./sigstore_common"); +exports.KindVersion = { + fromJSON(object) { + return { + kind: isSet(object.kind) ? globalThis.String(object.kind) : "", + version: isSet(object.version) ? globalThis.String(object.version) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.kind !== "") { + obj.kind = message.kind; + } + if (message.version !== "") { + obj.version = message.version; + } + return obj; + }, +}; +exports.Checkpoint = { + fromJSON(object) { + return { envelope: isSet(object.envelope) ? globalThis.String(object.envelope) : "" }; + }, + toJSON(message) { + const obj = {}; + if (message.envelope !== "") { + obj.envelope = message.envelope; + } + return obj; + }, +}; +exports.InclusionProof = { + fromJSON(object) { + return { + logIndex: isSet(object.logIndex) ? globalThis.String(object.logIndex) : "0", + rootHash: isSet(object.rootHash) ? Buffer.from(bytesFromBase64(object.rootHash)) : Buffer.alloc(0), + treeSize: isSet(object.treeSize) ? globalThis.String(object.treeSize) : "0", + hashes: globalThis.Array.isArray(object?.hashes) + ? object.hashes.map((e) => Buffer.from(bytesFromBase64(e))) + : [], + checkpoint: isSet(object.checkpoint) ? exports.Checkpoint.fromJSON(object.checkpoint) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.logIndex !== "0") { + obj.logIndex = message.logIndex; + } + if (message.rootHash.length !== 0) { + obj.rootHash = base64FromBytes(message.rootHash); + } + if (message.treeSize !== "0") { + obj.treeSize = message.treeSize; + } + if (message.hashes?.length) { + obj.hashes = message.hashes.map((e) => base64FromBytes(e)); + } + if (message.checkpoint !== undefined) { + obj.checkpoint = exports.Checkpoint.toJSON(message.checkpoint); + } + return obj; + }, +}; +exports.InclusionPromise = { + fromJSON(object) { + return { + signedEntryTimestamp: isSet(object.signedEntryTimestamp) + ? Buffer.from(bytesFromBase64(object.signedEntryTimestamp)) + : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.signedEntryTimestamp.length !== 0) { + obj.signedEntryTimestamp = base64FromBytes(message.signedEntryTimestamp); + } + return obj; + }, +}; +exports.TransparencyLogEntry = { + fromJSON(object) { + return { + logIndex: isSet(object.logIndex) ? globalThis.String(object.logIndex) : "0", + logId: isSet(object.logId) ? sigstore_common_1.LogId.fromJSON(object.logId) : undefined, + kindVersion: isSet(object.kindVersion) ? exports.KindVersion.fromJSON(object.kindVersion) : undefined, + integratedTime: isSet(object.integratedTime) ? globalThis.String(object.integratedTime) : "0", + inclusionPromise: isSet(object.inclusionPromise) ? exports.InclusionPromise.fromJSON(object.inclusionPromise) : undefined, + inclusionProof: isSet(object.inclusionProof) ? exports.InclusionProof.fromJSON(object.inclusionProof) : undefined, + canonicalizedBody: isSet(object.canonicalizedBody) + ? Buffer.from(bytesFromBase64(object.canonicalizedBody)) + : Buffer.alloc(0), + }; + }, + toJSON(message) { + const obj = {}; + if (message.logIndex !== "0") { + obj.logIndex = message.logIndex; + } + if (message.logId !== undefined) { + obj.logId = sigstore_common_1.LogId.toJSON(message.logId); + } + if (message.kindVersion !== undefined) { + obj.kindVersion = exports.KindVersion.toJSON(message.kindVersion); + } + if (message.integratedTime !== "0") { + obj.integratedTime = message.integratedTime; + } + if (message.inclusionPromise !== undefined) { + obj.inclusionPromise = exports.InclusionPromise.toJSON(message.inclusionPromise); + } + if (message.inclusionProof !== undefined) { + obj.inclusionProof = exports.InclusionProof.toJSON(message.inclusionProof); + } + if (message.canonicalizedBody.length !== 0) { + obj.canonicalizedBody = base64FromBytes(message.canonicalizedBody); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_trustroot.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_trustroot.js new file mode 100644 index 0000000000000..1b5492fb1a77e --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_trustroot.js @@ -0,0 +1,284 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: sigstore_trustroot.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ClientTrustConfig = exports.ServiceConfiguration = exports.Service = exports.SigningConfig = exports.TrustedRoot = exports.CertificateAuthority = exports.TransparencyLogInstance = exports.ServiceSelector = void 0; +exports.serviceSelectorFromJSON = serviceSelectorFromJSON; +exports.serviceSelectorToJSON = serviceSelectorToJSON; +/* eslint-disable */ +const sigstore_common_1 = require("./sigstore_common"); +/** + * ServiceSelector specifies how a client SHOULD select a set of + * Services to connect to. A client SHOULD throw an error if + * the value is SERVICE_SELECTOR_UNDEFINED. + */ +var ServiceSelector; +(function (ServiceSelector) { + ServiceSelector[ServiceSelector["SERVICE_SELECTOR_UNDEFINED"] = 0] = "SERVICE_SELECTOR_UNDEFINED"; + /** + * ALL - Clients SHOULD select all Services based on supported API version + * and validity window. + */ + ServiceSelector[ServiceSelector["ALL"] = 1] = "ALL"; + /** + * ANY - Clients SHOULD select one Service based on supported API version + * and validity window. It is up to the client implementation to + * decide how to select the Service, e.g. random or round-robin. + */ + ServiceSelector[ServiceSelector["ANY"] = 2] = "ANY"; + /** + * EXACT - Clients SHOULD select a specific number of Services based on + * supported API version and validity window, using the provided + * `count`. It is up to the client implementation to decide how to + * select the Service, e.g. random or round-robin. + */ + ServiceSelector[ServiceSelector["EXACT"] = 3] = "EXACT"; +})(ServiceSelector || (exports.ServiceSelector = ServiceSelector = {})); +function serviceSelectorFromJSON(object) { + switch (object) { + case 0: + case "SERVICE_SELECTOR_UNDEFINED": + return ServiceSelector.SERVICE_SELECTOR_UNDEFINED; + case 1: + case "ALL": + return ServiceSelector.ALL; + case 2: + case "ANY": + return ServiceSelector.ANY; + case 3: + case "EXACT": + return ServiceSelector.EXACT; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum ServiceSelector"); + } +} +function serviceSelectorToJSON(object) { + switch (object) { + case ServiceSelector.SERVICE_SELECTOR_UNDEFINED: + return "SERVICE_SELECTOR_UNDEFINED"; + case ServiceSelector.ALL: + return "ALL"; + case ServiceSelector.ANY: + return "ANY"; + case ServiceSelector.EXACT: + return "EXACT"; + default: + throw new globalThis.Error("Unrecognized enum value " + object + " for enum ServiceSelector"); + } +} +exports.TransparencyLogInstance = { + fromJSON(object) { + return { + baseUrl: isSet(object.baseUrl) ? globalThis.String(object.baseUrl) : "", + hashAlgorithm: isSet(object.hashAlgorithm) ? (0, sigstore_common_1.hashAlgorithmFromJSON)(object.hashAlgorithm) : 0, + publicKey: isSet(object.publicKey) ? sigstore_common_1.PublicKey.fromJSON(object.publicKey) : undefined, + logId: isSet(object.logId) ? sigstore_common_1.LogId.fromJSON(object.logId) : undefined, + checkpointKeyId: isSet(object.checkpointKeyId) ? sigstore_common_1.LogId.fromJSON(object.checkpointKeyId) : undefined, + operator: isSet(object.operator) ? globalThis.String(object.operator) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.baseUrl !== "") { + obj.baseUrl = message.baseUrl; + } + if (message.hashAlgorithm !== 0) { + obj.hashAlgorithm = (0, sigstore_common_1.hashAlgorithmToJSON)(message.hashAlgorithm); + } + if (message.publicKey !== undefined) { + obj.publicKey = sigstore_common_1.PublicKey.toJSON(message.publicKey); + } + if (message.logId !== undefined) { + obj.logId = sigstore_common_1.LogId.toJSON(message.logId); + } + if (message.checkpointKeyId !== undefined) { + obj.checkpointKeyId = sigstore_common_1.LogId.toJSON(message.checkpointKeyId); + } + if (message.operator !== "") { + obj.operator = message.operator; + } + return obj; + }, +}; +exports.CertificateAuthority = { + fromJSON(object) { + return { + subject: isSet(object.subject) ? sigstore_common_1.DistinguishedName.fromJSON(object.subject) : undefined, + uri: isSet(object.uri) ? globalThis.String(object.uri) : "", + certChain: isSet(object.certChain) ? sigstore_common_1.X509CertificateChain.fromJSON(object.certChain) : undefined, + validFor: isSet(object.validFor) ? sigstore_common_1.TimeRange.fromJSON(object.validFor) : undefined, + operator: isSet(object.operator) ? globalThis.String(object.operator) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.subject !== undefined) { + obj.subject = sigstore_common_1.DistinguishedName.toJSON(message.subject); + } + if (message.uri !== "") { + obj.uri = message.uri; + } + if (message.certChain !== undefined) { + obj.certChain = sigstore_common_1.X509CertificateChain.toJSON(message.certChain); + } + if (message.validFor !== undefined) { + obj.validFor = sigstore_common_1.TimeRange.toJSON(message.validFor); + } + if (message.operator !== "") { + obj.operator = message.operator; + } + return obj; + }, +}; +exports.TrustedRoot = { + fromJSON(object) { + return { + mediaType: isSet(object.mediaType) ? globalThis.String(object.mediaType) : "", + tlogs: globalThis.Array.isArray(object?.tlogs) + ? object.tlogs.map((e) => exports.TransparencyLogInstance.fromJSON(e)) + : [], + certificateAuthorities: globalThis.Array.isArray(object?.certificateAuthorities) + ? object.certificateAuthorities.map((e) => exports.CertificateAuthority.fromJSON(e)) + : [], + ctlogs: globalThis.Array.isArray(object?.ctlogs) + ? object.ctlogs.map((e) => exports.TransparencyLogInstance.fromJSON(e)) + : [], + timestampAuthorities: globalThis.Array.isArray(object?.timestampAuthorities) + ? object.timestampAuthorities.map((e) => exports.CertificateAuthority.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.mediaType !== "") { + obj.mediaType = message.mediaType; + } + if (message.tlogs?.length) { + obj.tlogs = message.tlogs.map((e) => exports.TransparencyLogInstance.toJSON(e)); + } + if (message.certificateAuthorities?.length) { + obj.certificateAuthorities = message.certificateAuthorities.map((e) => exports.CertificateAuthority.toJSON(e)); + } + if (message.ctlogs?.length) { + obj.ctlogs = message.ctlogs.map((e) => exports.TransparencyLogInstance.toJSON(e)); + } + if (message.timestampAuthorities?.length) { + obj.timestampAuthorities = message.timestampAuthorities.map((e) => exports.CertificateAuthority.toJSON(e)); + } + return obj; + }, +}; +exports.SigningConfig = { + fromJSON(object) { + return { + mediaType: isSet(object.mediaType) ? globalThis.String(object.mediaType) : "", + caUrls: globalThis.Array.isArray(object?.caUrls) ? object.caUrls.map((e) => exports.Service.fromJSON(e)) : [], + oidcUrls: globalThis.Array.isArray(object?.oidcUrls) ? object.oidcUrls.map((e) => exports.Service.fromJSON(e)) : [], + rekorTlogUrls: globalThis.Array.isArray(object?.rekorTlogUrls) + ? object.rekorTlogUrls.map((e) => exports.Service.fromJSON(e)) + : [], + rekorTlogConfig: isSet(object.rekorTlogConfig) + ? exports.ServiceConfiguration.fromJSON(object.rekorTlogConfig) + : undefined, + tsaUrls: globalThis.Array.isArray(object?.tsaUrls) ? object.tsaUrls.map((e) => exports.Service.fromJSON(e)) : [], + tsaConfig: isSet(object.tsaConfig) ? exports.ServiceConfiguration.fromJSON(object.tsaConfig) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.mediaType !== "") { + obj.mediaType = message.mediaType; + } + if (message.caUrls?.length) { + obj.caUrls = message.caUrls.map((e) => exports.Service.toJSON(e)); + } + if (message.oidcUrls?.length) { + obj.oidcUrls = message.oidcUrls.map((e) => exports.Service.toJSON(e)); + } + if (message.rekorTlogUrls?.length) { + obj.rekorTlogUrls = message.rekorTlogUrls.map((e) => exports.Service.toJSON(e)); + } + if (message.rekorTlogConfig !== undefined) { + obj.rekorTlogConfig = exports.ServiceConfiguration.toJSON(message.rekorTlogConfig); + } + if (message.tsaUrls?.length) { + obj.tsaUrls = message.tsaUrls.map((e) => exports.Service.toJSON(e)); + } + if (message.tsaConfig !== undefined) { + obj.tsaConfig = exports.ServiceConfiguration.toJSON(message.tsaConfig); + } + return obj; + }, +}; +exports.Service = { + fromJSON(object) { + return { + url: isSet(object.url) ? globalThis.String(object.url) : "", + majorApiVersion: isSet(object.majorApiVersion) ? globalThis.Number(object.majorApiVersion) : 0, + validFor: isSet(object.validFor) ? sigstore_common_1.TimeRange.fromJSON(object.validFor) : undefined, + operator: isSet(object.operator) ? globalThis.String(object.operator) : "", + }; + }, + toJSON(message) { + const obj = {}; + if (message.url !== "") { + obj.url = message.url; + } + if (message.majorApiVersion !== 0) { + obj.majorApiVersion = Math.round(message.majorApiVersion); + } + if (message.validFor !== undefined) { + obj.validFor = sigstore_common_1.TimeRange.toJSON(message.validFor); + } + if (message.operator !== "") { + obj.operator = message.operator; + } + return obj; + }, +}; +exports.ServiceConfiguration = { + fromJSON(object) { + return { + selector: isSet(object.selector) ? serviceSelectorFromJSON(object.selector) : 0, + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + }; + }, + toJSON(message) { + const obj = {}; + if (message.selector !== 0) { + obj.selector = serviceSelectorToJSON(message.selector); + } + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, +}; +exports.ClientTrustConfig = { + fromJSON(object) { + return { + mediaType: isSet(object.mediaType) ? globalThis.String(object.mediaType) : "", + trustedRoot: isSet(object.trustedRoot) ? exports.TrustedRoot.fromJSON(object.trustedRoot) : undefined, + signingConfig: isSet(object.signingConfig) ? exports.SigningConfig.fromJSON(object.signingConfig) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.mediaType !== "") { + obj.mediaType = message.mediaType; + } + if (message.trustedRoot !== undefined) { + obj.trustedRoot = exports.TrustedRoot.toJSON(message.trustedRoot); + } + if (message.signingConfig !== undefined) { + obj.signingConfig = exports.SigningConfig.toJSON(message.signingConfig); + } + return obj; + }, +}; +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_verification.js b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_verification.js new file mode 100644 index 0000000000000..876fe9cc1db1d --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/__generated__/sigstore_verification.js @@ -0,0 +1,281 @@ +"use strict"; +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.5 +// protoc v6.30.2 +// source: sigstore_verification.proto +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Input = exports.Artifact = exports.ArtifactVerificationOptions_ObserverTimestampOptions = exports.ArtifactVerificationOptions_TlogIntegratedTimestampOptions = exports.ArtifactVerificationOptions_TimestampAuthorityOptions = exports.ArtifactVerificationOptions_CtlogOptions = exports.ArtifactVerificationOptions_TlogOptions = exports.ArtifactVerificationOptions = exports.PublicKeyIdentities = exports.CertificateIdentities = exports.CertificateIdentity = void 0; +/* eslint-disable */ +const sigstore_bundle_1 = require("./sigstore_bundle"); +const sigstore_common_1 = require("./sigstore_common"); +const sigstore_trustroot_1 = require("./sigstore_trustroot"); +exports.CertificateIdentity = { + fromJSON(object) { + return { + issuer: isSet(object.issuer) ? globalThis.String(object.issuer) : "", + san: isSet(object.san) ? sigstore_common_1.SubjectAlternativeName.fromJSON(object.san) : undefined, + oids: globalThis.Array.isArray(object?.oids) + ? object.oids.map((e) => sigstore_common_1.ObjectIdentifierValuePair.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.issuer !== "") { + obj.issuer = message.issuer; + } + if (message.san !== undefined) { + obj.san = sigstore_common_1.SubjectAlternativeName.toJSON(message.san); + } + if (message.oids?.length) { + obj.oids = message.oids.map((e) => sigstore_common_1.ObjectIdentifierValuePair.toJSON(e)); + } + return obj; + }, +}; +exports.CertificateIdentities = { + fromJSON(object) { + return { + identities: globalThis.Array.isArray(object?.identities) + ? object.identities.map((e) => exports.CertificateIdentity.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.identities?.length) { + obj.identities = message.identities.map((e) => exports.CertificateIdentity.toJSON(e)); + } + return obj; + }, +}; +exports.PublicKeyIdentities = { + fromJSON(object) { + return { + publicKeys: globalThis.Array.isArray(object?.publicKeys) + ? object.publicKeys.map((e) => sigstore_common_1.PublicKey.fromJSON(e)) + : [], + }; + }, + toJSON(message) { + const obj = {}; + if (message.publicKeys?.length) { + obj.publicKeys = message.publicKeys.map((e) => sigstore_common_1.PublicKey.toJSON(e)); + } + return obj; + }, +}; +exports.ArtifactVerificationOptions = { + fromJSON(object) { + return { + signers: isSet(object.certificateIdentities) + ? { + $case: "certificateIdentities", + certificateIdentities: exports.CertificateIdentities.fromJSON(object.certificateIdentities), + } + : isSet(object.publicKeys) + ? { $case: "publicKeys", publicKeys: exports.PublicKeyIdentities.fromJSON(object.publicKeys) } + : undefined, + tlogOptions: isSet(object.tlogOptions) + ? exports.ArtifactVerificationOptions_TlogOptions.fromJSON(object.tlogOptions) + : undefined, + ctlogOptions: isSet(object.ctlogOptions) + ? exports.ArtifactVerificationOptions_CtlogOptions.fromJSON(object.ctlogOptions) + : undefined, + tsaOptions: isSet(object.tsaOptions) + ? exports.ArtifactVerificationOptions_TimestampAuthorityOptions.fromJSON(object.tsaOptions) + : undefined, + integratedTsOptions: isSet(object.integratedTsOptions) + ? exports.ArtifactVerificationOptions_TlogIntegratedTimestampOptions.fromJSON(object.integratedTsOptions) + : undefined, + observerOptions: isSet(object.observerOptions) + ? exports.ArtifactVerificationOptions_ObserverTimestampOptions.fromJSON(object.observerOptions) + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.signers?.$case === "certificateIdentities") { + obj.certificateIdentities = exports.CertificateIdentities.toJSON(message.signers.certificateIdentities); + } + else if (message.signers?.$case === "publicKeys") { + obj.publicKeys = exports.PublicKeyIdentities.toJSON(message.signers.publicKeys); + } + if (message.tlogOptions !== undefined) { + obj.tlogOptions = exports.ArtifactVerificationOptions_TlogOptions.toJSON(message.tlogOptions); + } + if (message.ctlogOptions !== undefined) { + obj.ctlogOptions = exports.ArtifactVerificationOptions_CtlogOptions.toJSON(message.ctlogOptions); + } + if (message.tsaOptions !== undefined) { + obj.tsaOptions = exports.ArtifactVerificationOptions_TimestampAuthorityOptions.toJSON(message.tsaOptions); + } + if (message.integratedTsOptions !== undefined) { + obj.integratedTsOptions = exports.ArtifactVerificationOptions_TlogIntegratedTimestampOptions.toJSON(message.integratedTsOptions); + } + if (message.observerOptions !== undefined) { + obj.observerOptions = exports.ArtifactVerificationOptions_ObserverTimestampOptions.toJSON(message.observerOptions); + } + return obj; + }, +}; +exports.ArtifactVerificationOptions_TlogOptions = { + fromJSON(object) { + return { + threshold: isSet(object.threshold) ? globalThis.Number(object.threshold) : 0, + performOnlineVerification: isSet(object.performOnlineVerification) + ? globalThis.Boolean(object.performOnlineVerification) + : false, + disable: isSet(object.disable) ? globalThis.Boolean(object.disable) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.threshold !== 0) { + obj.threshold = Math.round(message.threshold); + } + if (message.performOnlineVerification !== false) { + obj.performOnlineVerification = message.performOnlineVerification; + } + if (message.disable !== false) { + obj.disable = message.disable; + } + return obj; + }, +}; +exports.ArtifactVerificationOptions_CtlogOptions = { + fromJSON(object) { + return { + threshold: isSet(object.threshold) ? globalThis.Number(object.threshold) : 0, + disable: isSet(object.disable) ? globalThis.Boolean(object.disable) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.threshold !== 0) { + obj.threshold = Math.round(message.threshold); + } + if (message.disable !== false) { + obj.disable = message.disable; + } + return obj; + }, +}; +exports.ArtifactVerificationOptions_TimestampAuthorityOptions = { + fromJSON(object) { + return { + threshold: isSet(object.threshold) ? globalThis.Number(object.threshold) : 0, + disable: isSet(object.disable) ? globalThis.Boolean(object.disable) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.threshold !== 0) { + obj.threshold = Math.round(message.threshold); + } + if (message.disable !== false) { + obj.disable = message.disable; + } + return obj; + }, +}; +exports.ArtifactVerificationOptions_TlogIntegratedTimestampOptions = { + fromJSON(object) { + return { + threshold: isSet(object.threshold) ? globalThis.Number(object.threshold) : 0, + disable: isSet(object.disable) ? globalThis.Boolean(object.disable) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.threshold !== 0) { + obj.threshold = Math.round(message.threshold); + } + if (message.disable !== false) { + obj.disable = message.disable; + } + return obj; + }, +}; +exports.ArtifactVerificationOptions_ObserverTimestampOptions = { + fromJSON(object) { + return { + threshold: isSet(object.threshold) ? globalThis.Number(object.threshold) : 0, + disable: isSet(object.disable) ? globalThis.Boolean(object.disable) : false, + }; + }, + toJSON(message) { + const obj = {}; + if (message.threshold !== 0) { + obj.threshold = Math.round(message.threshold); + } + if (message.disable !== false) { + obj.disable = message.disable; + } + return obj; + }, +}; +exports.Artifact = { + fromJSON(object) { + return { + data: isSet(object.artifactUri) + ? { $case: "artifactUri", artifactUri: globalThis.String(object.artifactUri) } + : isSet(object.artifact) + ? { $case: "artifact", artifact: Buffer.from(bytesFromBase64(object.artifact)) } + : isSet(object.artifactDigest) + ? { $case: "artifactDigest", artifactDigest: sigstore_common_1.HashOutput.fromJSON(object.artifactDigest) } + : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.data?.$case === "artifactUri") { + obj.artifactUri = message.data.artifactUri; + } + else if (message.data?.$case === "artifact") { + obj.artifact = base64FromBytes(message.data.artifact); + } + else if (message.data?.$case === "artifactDigest") { + obj.artifactDigest = sigstore_common_1.HashOutput.toJSON(message.data.artifactDigest); + } + return obj; + }, +}; +exports.Input = { + fromJSON(object) { + return { + artifactTrustRoot: isSet(object.artifactTrustRoot) ? sigstore_trustroot_1.TrustedRoot.fromJSON(object.artifactTrustRoot) : undefined, + artifactVerificationOptions: isSet(object.artifactVerificationOptions) + ? exports.ArtifactVerificationOptions.fromJSON(object.artifactVerificationOptions) + : undefined, + bundle: isSet(object.bundle) ? sigstore_bundle_1.Bundle.fromJSON(object.bundle) : undefined, + artifact: isSet(object.artifact) ? exports.Artifact.fromJSON(object.artifact) : undefined, + }; + }, + toJSON(message) { + const obj = {}; + if (message.artifactTrustRoot !== undefined) { + obj.artifactTrustRoot = sigstore_trustroot_1.TrustedRoot.toJSON(message.artifactTrustRoot); + } + if (message.artifactVerificationOptions !== undefined) { + obj.artifactVerificationOptions = exports.ArtifactVerificationOptions.toJSON(message.artifactVerificationOptions); + } + if (message.bundle !== undefined) { + obj.bundle = sigstore_bundle_1.Bundle.toJSON(message.bundle); + } + if (message.artifact !== undefined) { + obj.artifact = exports.Artifact.toJSON(message.artifact); + } + return obj; + }, +}; +function bytesFromBase64(b64) { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} +function base64FromBytes(arr) { + return globalThis.Buffer.from(arr).toString("base64"); +} +function isSet(value) { + return value !== null && value !== undefined; +} diff --git a/node_modules/@sigstore/protobuf-specs/dist/index.js b/node_modules/@sigstore/protobuf-specs/dist/index.js new file mode 100644 index 0000000000000..eafb768c48fca --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/index.js @@ -0,0 +1,37 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +__exportStar(require("./__generated__/envelope"), exports); +__exportStar(require("./__generated__/sigstore_bundle"), exports); +__exportStar(require("./__generated__/sigstore_common"), exports); +__exportStar(require("./__generated__/sigstore_rekor"), exports); +__exportStar(require("./__generated__/sigstore_trustroot"), exports); +__exportStar(require("./__generated__/sigstore_verification"), exports); diff --git a/node_modules/@sigstore/protobuf-specs/dist/rekor/v2/index.js b/node_modules/@sigstore/protobuf-specs/dist/rekor/v2/index.js new file mode 100644 index 0000000000000..10745efc39a1f --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/dist/rekor/v2/index.js @@ -0,0 +1,35 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +__exportStar(require("../../__generated__/rekor/v2/dsse"), exports); +__exportStar(require("../../__generated__/rekor/v2/entry"), exports); +__exportStar(require("../../__generated__/rekor/v2/hashedrekord"), exports); +__exportStar(require("../../__generated__/rekor/v2/verifier"), exports); diff --git a/node_modules/@sigstore/protobuf-specs/package.json b/node_modules/@sigstore/protobuf-specs/package.json new file mode 100644 index 0000000000000..f87b2540fbf98 --- /dev/null +++ b/node_modules/@sigstore/protobuf-specs/package.json @@ -0,0 +1,35 @@ +{ + "name": "@sigstore/protobuf-specs", + "version": "0.5.0", + "description": "code-signing for npm packages", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": "./dist/index.js", + "./rekor/v2": "./dist/rekor/v2/index.js" + }, + "scripts": { + "build": "tsc" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/protobuf-specs.git" + }, + "files": [ + "dist" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/sigstore/protobuf-specs/issues" + }, + "homepage": "https://github.com/sigstore/protobuf-specs#readme", + "devDependencies": { + "@tsconfig/node18": "^18.2.4", + "@types/node": "^18.14.0", + "typescript": "^5.7.2" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } +} diff --git a/node_modules/@sigstore/sign/LICENSE b/node_modules/@sigstore/sign/LICENSE new file mode 100644 index 0000000000000..e9e7c1679a09d --- /dev/null +++ b/node_modules/@sigstore/sign/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 The Sigstore Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/@sigstore/sign/dist/bundler/base.js b/node_modules/@sigstore/sign/dist/bundler/base.js new file mode 100644 index 0000000000000..e231c663fffc1 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/bundler/base.js @@ -0,0 +1,52 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BaseBundleBuilder = void 0; +// BaseBundleBuilder is a base class for BundleBuilder implementations. It +// provides a the basic wokflow for signing and witnessing an artifact. +// Subclasses must implement the `package` method to assemble a valid bundle +// with the generated signature and verification material. +class BaseBundleBuilder { + signer; + witnesses; + constructor(options) { + this.signer = options.signer; + this.witnesses = options.witnesses; + } + // Executes the signing/witnessing process for the given artifact. + async create(artifact) { + const signature = await this.prepare(artifact).then((blob) => this.signer.sign(blob)); + const bundle = await this.package(artifact, signature); + // Invoke all of the witnesses in parallel + const verificationMaterials = await Promise.all(this.witnesses.map((witness) => witness.testify(bundle.content, publicKey(signature.key)))); + // Collect the verification material from all of the witnesses + const tlogEntryList = []; + const timestampList = []; + verificationMaterials.forEach(({ tlogEntries, rfc3161Timestamps }) => { + tlogEntryList.push(...(tlogEntries ?? [])); + timestampList.push(...(rfc3161Timestamps ?? [])); + }); + // Merge the collected verification material into the bundle + bundle.verificationMaterial.tlogEntries = tlogEntryList; + bundle.verificationMaterial.timestampVerificationData = { + rfc3161Timestamps: timestampList, + }; + return bundle; + } + // Override this function to apply any pre-signing transformations to the + // artifact. The returned buffer will be signed by the signer. The default + // implementation simply returns the artifact data. + async prepare(artifact) { + return artifact.data; + } +} +exports.BaseBundleBuilder = BaseBundleBuilder; +// Extracts the public key from a KeyMaterial. Returns either the public key +// or the certificate, depending on the type of key material. +function publicKey(key) { + switch (key.$case) { + case 'publicKey': + return key.publicKey; + case 'x509Certificate': + return key.certificate; + } +} diff --git a/node_modules/@sigstore/sign/dist/bundler/bundle.js b/node_modules/@sigstore/sign/dist/bundler/bundle.js new file mode 100644 index 0000000000000..34b1d12f2b44c --- /dev/null +++ b/node_modules/@sigstore/sign/dist/bundler/bundle.js @@ -0,0 +1,81 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toMessageSignatureBundle = toMessageSignatureBundle; +exports.toDSSEBundle = toDSSEBundle; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const sigstore = __importStar(require("@sigstore/bundle")); +const util_1 = require("../util"); +// Helper functions for assembling the parts of a Sigstore bundle +// Message signature bundle - $case: 'messageSignature' +function toMessageSignatureBundle(artifact, signature) { + const digest = util_1.crypto.digest('sha256', artifact.data); + return sigstore.toMessageSignatureBundle({ + digest, + signature: signature.signature, + certificate: signature.key.$case === 'x509Certificate' + ? util_1.pem.toDER(signature.key.certificate) + : undefined, + keyHint: signature.key.$case === 'publicKey' ? signature.key.hint : undefined, + certificateChain: true, + }); +} +// DSSE envelope bundle - $case: 'dsseEnvelope' +function toDSSEBundle(artifact, signature, certificateChain) { + return sigstore.toDSSEBundle({ + artifact: artifact.data, + artifactType: artifact.type, + signature: signature.signature, + certificate: signature.key.$case === 'x509Certificate' + ? util_1.pem.toDER(signature.key.certificate) + : undefined, + keyHint: signature.key.$case === 'publicKey' ? signature.key.hint : undefined, + certificateChain, + }); +} diff --git a/node_modules/@sigstore/sign/dist/bundler/dsse.js b/node_modules/@sigstore/sign/dist/bundler/dsse.js new file mode 100644 index 0000000000000..95c8d31c29fc3 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/bundler/dsse.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSSEBundleBuilder = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const util_1 = require("../util"); +const base_1 = require("./base"); +const bundle_1 = require("./bundle"); +// BundleBuilder implementation for DSSE wrapped attestations +class DSSEBundleBuilder extends base_1.BaseBundleBuilder { + certificateChain; + constructor(options) { + super(options); + this.certificateChain = options.certificateChain ?? false; + } + // DSSE requires the artifact to be pre-encoded with the payload type + // before the signature is generated. + async prepare(artifact) { + const a = artifactDefaults(artifact); + return util_1.dsse.preAuthEncoding(a.type, a.data); + } + // Packages the artifact and signature into a DSSE bundle + async package(artifact, signature) { + return (0, bundle_1.toDSSEBundle)(artifactDefaults(artifact), signature, this.certificateChain); + } +} +exports.DSSEBundleBuilder = DSSEBundleBuilder; +// Defaults the artifact type to an empty string if not provided +function artifactDefaults(artifact) { + return { + ...artifact, + type: artifact.type ?? '', + }; +} diff --git a/node_modules/@sigstore/sign/dist/bundler/index.js b/node_modules/@sigstore/sign/dist/bundler/index.js new file mode 100644 index 0000000000000..d67c8c324a4f0 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/bundler/index.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MessageSignatureBundleBuilder = exports.DSSEBundleBuilder = void 0; +var dsse_1 = require("./dsse"); +Object.defineProperty(exports, "DSSEBundleBuilder", { enumerable: true, get: function () { return dsse_1.DSSEBundleBuilder; } }); +var message_1 = require("./message"); +Object.defineProperty(exports, "MessageSignatureBundleBuilder", { enumerable: true, get: function () { return message_1.MessageSignatureBundleBuilder; } }); diff --git a/node_modules/@sigstore/sign/dist/bundler/message.js b/node_modules/@sigstore/sign/dist/bundler/message.js new file mode 100644 index 0000000000000..e3991f42bab93 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/bundler/message.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MessageSignatureBundleBuilder = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const base_1 = require("./base"); +const bundle_1 = require("./bundle"); +// BundleBuilder implementation for raw message signatures +class MessageSignatureBundleBuilder extends base_1.BaseBundleBuilder { + constructor(options) { + super(options); + } + async package(artifact, signature) { + return (0, bundle_1.toMessageSignatureBundle)(artifact, signature); + } +} +exports.MessageSignatureBundleBuilder = MessageSignatureBundleBuilder; diff --git a/node_modules/@sigstore/sign/dist/config.js b/node_modules/@sigstore/sign/dist/config.js new file mode 100644 index 0000000000000..dcb2b240cec53 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/config.js @@ -0,0 +1,143 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.bundleBuilderFromSigningConfig = bundleBuilderFromSigningConfig; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const dsse_1 = require("./bundler/dsse"); +const message_1 = require("./bundler/message"); +const signer_1 = require("./signer"); +const witness_1 = require("./witness"); +const MAX_CA_API_VERSION = 1; +const MAX_TLOG_API_VERSION = 2; +const MAX_TSA_API_VERSION = 1; +const DEFAULT_TIMEOUT = 5000; +const DEFAULT_REKORV2_TIMEOUT = 20000; +const DEFAULT_RETRY = { retries: 2 }; +// Creates a BundleBuilder based on the provided SigningConfig +function bundleBuilderFromSigningConfig(options) { + const { signingConfig, identityProvider, bundleType } = options; + const fetchOptions = options.fetchOptions || { + timeout: DEFAULT_TIMEOUT, + retry: DEFAULT_RETRY, + }; + const signer = fulcioSignerFromConfig(signingConfig, identityProvider, fetchOptions); + const witnesses = witnessesFromConfig(signingConfig, fetchOptions); + switch (bundleType) { + case 'messageSignature': + return new message_1.MessageSignatureBundleBuilder({ signer, witnesses }); + case 'dsseEnvelope': + return new dsse_1.DSSEBundleBuilder({ signer, witnesses }); + } +} +function fulcioSignerFromConfig(signingConfig, identityProvider, fetchOptions) { + const service = certAuthorityService(signingConfig); + return new signer_1.FulcioSigner({ + fulcioBaseURL: service.url, + identityProvider: identityProvider, + timeout: fetchOptions.timeout, + retry: fetchOptions.retry, + }); +} +function witnessesFromConfig(signingConfig, fetchOptions) { + const witnesses = []; + if (signingConfig.rekorTlogConfig) { + if (signingConfig.rekorTlogConfig.selector !== protobuf_specs_1.ServiceSelector.ANY) { + throw new Error('Unsupported Rekor TLog selector in signing configuration'); + } + const tlog = tlogService(signingConfig); + witnesses.push(new witness_1.RekorWitness({ + rekorBaseURL: tlog.url, + majorApiVersion: tlog.majorApiVersion, + retry: fetchOptions.retry, + timeout: + // Ensure Rekor V2 has at least a 20 second timeout + tlog.majorApiVersion === 1 + ? fetchOptions.timeout + : Math.min(fetchOptions.timeout || + /* istanbul ignore next */ DEFAULT_TIMEOUT, DEFAULT_REKORV2_TIMEOUT), + })); + } + if (signingConfig.tsaConfig) { + if (signingConfig.tsaConfig.selector !== protobuf_specs_1.ServiceSelector.ANY) { + throw new Error('Unsupported TSA selector in signing configuration'); + } + const tsa = tsaService(signingConfig); + witnesses.push(new witness_1.TSAWitness({ + tsaBaseURL: tsa.url, + retry: fetchOptions.retry, + timeout: fetchOptions.timeout, + })); + } + return witnesses; +} +// Returns the first valid CA service from the signing configuration +function certAuthorityService(signingConfig) { + const compatibleCAs = filterServicesByMaxAPIVersion(signingConfig.caUrls, MAX_CA_API_VERSION); + const sortedCAs = sortServicesByStartDate(compatibleCAs); + if (sortedCAs.length === 0) { + throw new Error('No valid CA services found in signing configuration'); + } + return sortedCAs[0]; +} +// Returns the first valid TLog service from the signing configuration +function tlogService(signingConfig) { + const compatibleTLogs = filterServicesByMaxAPIVersion(signingConfig.rekorTlogUrls, MAX_TLOG_API_VERSION); + const sortedTLogs = sortServicesByStartDate(compatibleTLogs); + if (sortedTLogs.length === 0) { + throw new Error('No valid TLogs found in signing configuration'); + } + return sortedTLogs[0]; +} +// Returns the first valid TSA service from the signing configuration +function tsaService(signingConfig) { + const compatibleTSAs = filterServicesByMaxAPIVersion(signingConfig.tsaUrls, MAX_TSA_API_VERSION); + const sortedTSAs = sortServicesByStartDate(compatibleTSAs); + if (sortedTSAs.length === 0) { + throw new Error('No valid TSAs found in signing configuration'); + } + return sortedTSAs[0]; +} +// Returns the services sorted by start date (most recent first), filtering out +// any services that have an end date in the past +function sortServicesByStartDate(services) { + const now = new Date(); + // Filter out any services that have an end date in the past + const validServices = services.filter((service) => { + // If there's no end date, the service is still valid + if (!service.validFor?.end) { + return true; + } + // Keep services whose end date is in the future or present + return service.validFor.end >= now; + }); + return validServices.sort((a, b) => { + /* istanbul ignore next */ + const aStart = a.validFor?.start?.getTime() ?? 0; + /* istanbul ignore next */ + const bStart = b.validFor?.start?.getTime() ?? 0; + // Sort descending (most recent first) + return bStart - aStart; + }); +} +// Returns a filtered list of services whose major API version is less than or +// equal to the specified version +function filterServicesByMaxAPIVersion(services, apiVersion) { + // Filter out any services with a major API version greater than the specified version + return services.filter((service) => { + return service.majorApiVersion <= apiVersion; + }); +} diff --git a/node_modules/@sigstore/sign/dist/error.js b/node_modules/@sigstore/sign/dist/error.js new file mode 100644 index 0000000000000..125522ac84b0e --- /dev/null +++ b/node_modules/@sigstore/sign/dist/error.js @@ -0,0 +1,41 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.InternalError = void 0; +exports.internalError = internalError; +const error_1 = require("./external/error"); +class InternalError extends Error { + code; + cause; + constructor({ code, message, cause, }) { + super(message); + this.name = this.constructor.name; + this.cause = cause; + this.code = code; + } +} +exports.InternalError = InternalError; +function internalError(err, code, message) { + if (err instanceof error_1.HTTPError) { + message += ` - ${err.message}`; + } + throw new InternalError({ + code: code, + message: message, + cause: err, + }); +} diff --git a/node_modules/@sigstore/sign/dist/external/error.js b/node_modules/@sigstore/sign/dist/external/error.js new file mode 100644 index 0000000000000..fd00afa835da4 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/error.js @@ -0,0 +1,28 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HTTPError = void 0; +class HTTPError extends Error { + statusCode; + location; + constructor({ status, message, location, }) { + super(`(${status}) ${message}`); + this.statusCode = status; + this.location = location; + } +} +exports.HTTPError = HTTPError; diff --git a/node_modules/@sigstore/sign/dist/external/fetch.js b/node_modules/@sigstore/sign/dist/external/fetch.js new file mode 100644 index 0000000000000..116090f3c641e --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/fetch.js @@ -0,0 +1,98 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fetchWithRetry = fetchWithRetry; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const http2_1 = require("http2"); +const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); +const proc_log_1 = require("proc-log"); +const promise_retry_1 = __importDefault(require("promise-retry")); +const util_1 = require("../util"); +const error_1 = require("./error"); +const { HTTP2_HEADER_LOCATION, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_USER_AGENT, HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_REQUEST_TIMEOUT, } = http2_1.constants; +async function fetchWithRetry(url, options) { + return (0, promise_retry_1.default)(async (retry, attemptNum) => { + const method = options.method || 'POST'; + const headers = { + [HTTP2_HEADER_USER_AGENT]: util_1.ua.getUserAgent(), + ...options.headers, + }; + const response = await (0, make_fetch_happen_1.default)(url, { + method, + headers, + body: options.body, + timeout: options.timeout, + retry: false, // We're handling retries ourselves + }).catch((reason) => { + proc_log_1.log.http('fetch', `${method} ${url} attempt ${attemptNum} failed with ${reason}`); + return retry(reason); + }); + if (response.ok) { + return response; + } + else { + const error = await errorFromResponse(response); + proc_log_1.log.http('fetch', `${method} ${url} attempt ${attemptNum} failed with ${response.status}`); + if (retryable(response.status)) { + return retry(error); + } + else { + throw error; + } + } + }, retryOpts(options.retry)); +} +// Translate a Response into an HTTPError instance. This will attempt to parse +// the response body for a message, but will default to the statusText if none +// is found. +const errorFromResponse = async (response) => { + let message = response.statusText; + const location = response.headers.get(HTTP2_HEADER_LOCATION) || undefined; + const contentType = response.headers.get(HTTP2_HEADER_CONTENT_TYPE); + // If response type is JSON, try to parse the body for a message + if (contentType?.includes('application/json')) { + try { + const body = await response.json(); + message = body.message || message; + } + catch (e) { + // ignore + } + } + return new error_1.HTTPError({ + status: response.status, + message: message, + location: location, + }); +}; +// Determine if a status code is retryable. This includes 5xx errors, 408, and +// 429. +const retryable = (status) => [HTTP_STATUS_REQUEST_TIMEOUT, HTTP_STATUS_TOO_MANY_REQUESTS].includes(status) || status >= HTTP_STATUS_INTERNAL_SERVER_ERROR; +// Normalize the retry options to the format expected by promise-retry +const retryOpts = (retry) => { + if (typeof retry === 'boolean') { + return { retries: retry ? 1 : 0 }; + } + else if (typeof retry === 'number') { + return { retries: retry }; + } + else { + return { retries: 0, ...retry }; + } +}; diff --git a/node_modules/@sigstore/sign/dist/external/fulcio.js b/node_modules/@sigstore/sign/dist/external/fulcio.js new file mode 100644 index 0000000000000..20904fc34e454 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/fulcio.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Fulcio = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const fetch_1 = require("./fetch"); +/** + * Fulcio API client. + */ +class Fulcio { + options; + constructor(options) { + this.options = options; + } + async createSigningCertificate(request) { + const { baseURL, retry, timeout } = this.options; + const url = `${baseURL}/api/v2/signingCert`; + const response = await (0, fetch_1.fetchWithRetry)(url, { + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(request), + timeout, + retry, + }); + return response.json(); + } +} +exports.Fulcio = Fulcio; diff --git a/node_modules/@sigstore/sign/dist/external/rekor-v2.js b/node_modules/@sigstore/sign/dist/external/rekor-v2.js new file mode 100644 index 0000000000000..c35cb99c8fac8 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/rekor-v2.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RekorV2 = void 0; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const fetch_1 = require("./fetch"); +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const v2_1 = require("@sigstore/protobuf-specs/rekor/v2"); +/** + * Rekor API client. + */ +class RekorV2 { + options; + constructor(options) { + this.options = options; + } + async createEntry(proposedEntry) { + const { baseURL, timeout, retry } = this.options; + const url = `${baseURL}/api/v2/log/entries`; + const response = await (0, fetch_1.fetchWithRetry)(url, { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + body: JSON.stringify(v2_1.CreateEntryRequest.toJSON(proposedEntry)), + timeout, + retry, + }); + return response.json().then((data) => protobuf_specs_1.TransparencyLogEntry.fromJSON(data)); + } +} +exports.RekorV2 = RekorV2; diff --git a/node_modules/@sigstore/sign/dist/external/rekor.js b/node_modules/@sigstore/sign/dist/external/rekor.js new file mode 100644 index 0000000000000..1a990d5fcea41 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/rekor.js @@ -0,0 +1,81 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Rekor = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const fetch_1 = require("./fetch"); +/** + * Rekor API client. + */ +class Rekor { + options; + constructor(options) { + this.options = options; + } + /** + * Create a new entry in the Rekor log. + * @param propsedEntry {ProposedEntry} Data to create a new entry + * @returns {Promise<Entry>} The created entry + */ + async createEntry(propsedEntry) { + const { baseURL, timeout, retry } = this.options; + const url = `${baseURL}/api/v1/log/entries`; + const response = await (0, fetch_1.fetchWithRetry)(url, { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + body: JSON.stringify(propsedEntry), + timeout, + retry, + }); + const data = await response.json(); + return entryFromResponse(data); + } + /** + * Get an entry from the Rekor log. + * @param uuid {string} The UUID of the entry to retrieve + * @returns {Promise<Entry>} The retrieved entry + */ + async getEntry(uuid) { + const { baseURL, timeout, retry } = this.options; + const url = `${baseURL}/api/v1/log/entries/${uuid}`; + const response = await (0, fetch_1.fetchWithRetry)(url, { + method: 'GET', + headers: { + Accept: 'application/json', + }, + timeout, + retry, + }); + const data = await response.json(); + return entryFromResponse(data); + } +} +exports.Rekor = Rekor; +// Unpack the response from the Rekor API into a more convenient format. +function entryFromResponse(data) { + const entries = Object.entries(data); + if (entries.length != 1) { + throw new Error('Received multiple entries in Rekor response'); + } + // Grab UUID and entry data from the response + const [uuid, entry] = entries[0]; + return { + ...entry, + uuid, + }; +} diff --git a/node_modules/@sigstore/sign/dist/external/tsa.js b/node_modules/@sigstore/sign/dist/external/tsa.js new file mode 100644 index 0000000000000..a15dcc6f3c4f0 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/external/tsa.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TimestampAuthority = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const fetch_1 = require("./fetch"); +class TimestampAuthority { + options; + constructor(options) { + this.options = options; + } + async createTimestamp(request) { + const { baseURL, timeout, retry } = this.options; + // Account for the fact that the TSA URL may already include the full + // path if the client was initalized from a `SigningConfig` service entry + // (which always uses the full URL). + const url = new URL(baseURL).pathname === '/' + ? `${baseURL}/api/v1/timestamp` + : baseURL; + const response = await (0, fetch_1.fetchWithRetry)(url, { + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(request), + timeout, + retry, + }); + return response.buffer(); + } +} +exports.TimestampAuthority = TimestampAuthority; diff --git a/node_modules/@sigstore/sign/dist/identity/ci.js b/node_modules/@sigstore/sign/dist/identity/ci.js new file mode 100644 index 0000000000000..318ef01b68e3e --- /dev/null +++ b/node_modules/@sigstore/sign/dist/identity/ci.js @@ -0,0 +1,74 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CIContextProvider = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); +// Collection of all the CI-specific providers we have implemented +const providers = [getGHAToken, getEnv]; +/** + * CIContextProvider is a composite identity provider which will iterate + * over all of the CI-specific providers and return the token from the first + * one that resolves. + */ +class CIContextProvider { + audience; + /* istanbul ignore next */ + constructor(audience = 'sigstore') { + this.audience = audience; + } + // Invoke all registered ProviderFuncs and return the value of whichever one + // resolves first. + async getToken() { + return Promise.any(providers.map((getToken) => getToken(this.audience))).catch(() => Promise.reject('CI: no tokens available')); + } +} +exports.CIContextProvider = CIContextProvider; +/** + * getGHAToken can retrieve an OIDC token when running in a GitHub Actions + * workflow + */ +async function getGHAToken(audience) { + // Check to see if we're running in GitHub Actions + if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL || + !process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN) { + return Promise.reject('no token available'); + } + // Construct URL to request token w/ appropriate audience + const url = new URL(process.env.ACTIONS_ID_TOKEN_REQUEST_URL); + url.searchParams.append('audience', audience); + const response = await (0, make_fetch_happen_1.default)(url.href, { + retry: 2, + headers: { + Accept: 'application/json', + Authorization: `Bearer ${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}`, + }, + }); + return response.json().then((data) => data.value); +} +/** + * getEnv can retrieve an OIDC token from an environment variable. + * This matches the behavior of https://github.com/sigstore/cosign/tree/main/pkg/providers/envvar + */ +async function getEnv() { + if (!process.env.SIGSTORE_ID_TOKEN) { + return Promise.reject('no token available'); + } + return process.env.SIGSTORE_ID_TOKEN; +} diff --git a/node_modules/@sigstore/sign/dist/identity/index.js b/node_modules/@sigstore/sign/dist/identity/index.js new file mode 100644 index 0000000000000..1c1223b443fab --- /dev/null +++ b/node_modules/@sigstore/sign/dist/identity/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CIContextProvider = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var ci_1 = require("./ci"); +Object.defineProperty(exports, "CIContextProvider", { enumerable: true, get: function () { return ci_1.CIContextProvider; } }); diff --git a/node_modules/@sigstore/sign/dist/identity/provider.js b/node_modules/@sigstore/sign/dist/identity/provider.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/identity/provider.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/sign/dist/index.js b/node_modules/@sigstore/sign/dist/index.js new file mode 100644 index 0000000000000..02fae0589e508 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/index.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TSAWitness = exports.RekorWitness = exports.DEFAULT_REKOR_URL = exports.FulcioSigner = exports.DEFAULT_FULCIO_URL = exports.CIContextProvider = exports.InternalError = exports.bundleBuilderFromSigningConfig = exports.MessageSignatureBundleBuilder = exports.DSSEBundleBuilder = void 0; +var bundler_1 = require("./bundler"); +Object.defineProperty(exports, "DSSEBundleBuilder", { enumerable: true, get: function () { return bundler_1.DSSEBundleBuilder; } }); +Object.defineProperty(exports, "MessageSignatureBundleBuilder", { enumerable: true, get: function () { return bundler_1.MessageSignatureBundleBuilder; } }); +var config_1 = require("./config"); +Object.defineProperty(exports, "bundleBuilderFromSigningConfig", { enumerable: true, get: function () { return config_1.bundleBuilderFromSigningConfig; } }); +var error_1 = require("./error"); +Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return error_1.InternalError; } }); +var identity_1 = require("./identity"); +Object.defineProperty(exports, "CIContextProvider", { enumerable: true, get: function () { return identity_1.CIContextProvider; } }); +var signer_1 = require("./signer"); +Object.defineProperty(exports, "DEFAULT_FULCIO_URL", { enumerable: true, get: function () { return signer_1.DEFAULT_FULCIO_URL; } }); +Object.defineProperty(exports, "FulcioSigner", { enumerable: true, get: function () { return signer_1.FulcioSigner; } }); +var witness_1 = require("./witness"); +Object.defineProperty(exports, "DEFAULT_REKOR_URL", { enumerable: true, get: function () { return witness_1.DEFAULT_REKOR_URL; } }); +Object.defineProperty(exports, "RekorWitness", { enumerable: true, get: function () { return witness_1.RekorWitness; } }); +Object.defineProperty(exports, "TSAWitness", { enumerable: true, get: function () { return witness_1.TSAWitness; } }); diff --git a/node_modules/@sigstore/sign/dist/signer/fulcio/ca.js b/node_modules/@sigstore/sign/dist/signer/fulcio/ca.js new file mode 100644 index 0000000000000..5919631473436 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/signer/fulcio/ca.js @@ -0,0 +1,60 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CAClient = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../../error"); +const fulcio_1 = require("../../external/fulcio"); +class CAClient { + fulcio; + constructor(options) { + this.fulcio = new fulcio_1.Fulcio({ + baseURL: options.fulcioBaseURL, + retry: options.retry, + timeout: options.timeout, + }); + } + async createSigningCertificate(identityToken, publicKey, challenge) { + const request = toCertificateRequest(identityToken, publicKey, challenge); + try { + const resp = await this.fulcio.createSigningCertificate(request); + // Account for the fact that the response may contain either a + // signedCertificateEmbeddedSct or a signedCertificateDetachedSct. + const cert = resp.signedCertificateEmbeddedSct + ? resp.signedCertificateEmbeddedSct + : resp.signedCertificateDetachedSct; + return cert.chain.certificates; + } + catch (err) { + (0, error_1.internalError)(err, 'CA_CREATE_SIGNING_CERTIFICATE_ERROR', 'error creating signing certificate'); + } + } +} +exports.CAClient = CAClient; +function toCertificateRequest(identityToken, publicKey, challenge) { + return { + credentials: { + oidcIdentityToken: identityToken, + }, + publicKeyRequest: { + publicKey: { + algorithm: 'ECDSA', + content: publicKey, + }, + proofOfPossession: challenge.toString('base64'), + }, + }; +} diff --git a/node_modules/@sigstore/sign/dist/signer/fulcio/ephemeral.js b/node_modules/@sigstore/sign/dist/signer/fulcio/ephemeral.js new file mode 100644 index 0000000000000..24b92d9f1f37b --- /dev/null +++ b/node_modules/@sigstore/sign/dist/signer/fulcio/ephemeral.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EphemeralSigner = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const crypto_1 = require("crypto"); +const EC_KEYPAIR_TYPE = 'ec'; +const P256_CURVE = 'P-256'; +// Signer implementation which uses an ephemeral keypair to sign artifacts. +// The private key lives only in memory and is tied to the lifetime of the +// EphemeralSigner instance. +class EphemeralSigner { + keypair; + constructor() { + this.keypair = (0, crypto_1.generateKeyPairSync)(EC_KEYPAIR_TYPE, { + namedCurve: P256_CURVE, + }); + } + async sign(data) { + const signature = (0, crypto_1.sign)('sha256', data, this.keypair.privateKey); + const publicKey = this.keypair.publicKey + .export({ format: 'pem', type: 'spki' }) + .toString('ascii'); + return { + signature: signature, + key: { $case: 'publicKey', publicKey }, + }; + } +} +exports.EphemeralSigner = EphemeralSigner; diff --git a/node_modules/@sigstore/sign/dist/signer/fulcio/index.js b/node_modules/@sigstore/sign/dist/signer/fulcio/index.js new file mode 100644 index 0000000000000..6df16a83af778 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/signer/fulcio/index.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.FulcioSigner = exports.DEFAULT_FULCIO_URL = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../../error"); +const util_1 = require("../../util"); +const ca_1 = require("./ca"); +const ephemeral_1 = require("./ephemeral"); +exports.DEFAULT_FULCIO_URL = 'https://fulcio.sigstore.dev'; +// Signer implementation which can be used to decorate another signer +// with a Fulcio-issued signing certificate for the signer's public key. +// Must be instantiated with an identity provider which can provide a JWT +// which represents the identity to be bound to the signing certificate. +class FulcioSigner { + ca; + identityProvider; + keyHolder; + constructor(options) { + this.ca = new ca_1.CAClient({ + ...options, + fulcioBaseURL: options.fulcioBaseURL || /* istanbul ignore next */ exports.DEFAULT_FULCIO_URL, + }); + this.identityProvider = options.identityProvider; + this.keyHolder = options.keyHolder || new ephemeral_1.EphemeralSigner(); + } + async sign(data) { + // Retrieve identity token from the supplied identity provider + const identityToken = await this.getIdentityToken(); + // Extract challenge claim from OIDC token + let subject; + try { + subject = util_1.oidc.extractJWTSubject(identityToken); + } + catch (err) { + throw new error_1.InternalError({ + code: 'IDENTITY_TOKEN_PARSE_ERROR', + message: `invalid identity token: ${identityToken}`, + cause: err, + }); + } + // Construct challenge value by signing the subject claim + const challenge = await this.keyHolder.sign(Buffer.from(subject)); + if (challenge.key.$case !== 'publicKey') { + throw new error_1.InternalError({ + code: 'CA_CREATE_SIGNING_CERTIFICATE_ERROR', + message: 'unexpected format for signing key', + }); + } + // Create signing certificate + const certificates = await this.ca.createSigningCertificate(identityToken, challenge.key.publicKey, challenge.signature); + // Generate artifact signature + const signature = await this.keyHolder.sign(data); + // Specifically returning only the first certificate in the chain + // as the key. + return { + signature: signature.signature, + key: { + $case: 'x509Certificate', + certificate: certificates[0], + }, + }; + } + async getIdentityToken() { + try { + return await this.identityProvider.getToken(); + } + catch (err) { + throw new error_1.InternalError({ + code: 'IDENTITY_TOKEN_READ_ERROR', + message: 'error retrieving identity token', + cause: err, + }); + } + } +} +exports.FulcioSigner = FulcioSigner; diff --git a/node_modules/@sigstore/sign/dist/signer/index.js b/node_modules/@sigstore/sign/dist/signer/index.js new file mode 100644 index 0000000000000..e2087767b81c1 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/signer/index.js @@ -0,0 +1,22 @@ +"use strict"; +/* istanbul ignore file */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.FulcioSigner = exports.DEFAULT_FULCIO_URL = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var fulcio_1 = require("./fulcio"); +Object.defineProperty(exports, "DEFAULT_FULCIO_URL", { enumerable: true, get: function () { return fulcio_1.DEFAULT_FULCIO_URL; } }); +Object.defineProperty(exports, "FulcioSigner", { enumerable: true, get: function () { return fulcio_1.FulcioSigner; } }); diff --git a/node_modules/@sigstore/sign/dist/signer/signer.js b/node_modules/@sigstore/sign/dist/signer/signer.js new file mode 100644 index 0000000000000..b92c54183375d --- /dev/null +++ b/node_modules/@sigstore/sign/dist/signer/signer.js @@ -0,0 +1,17 @@ +"use strict"; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/sign/dist/types/fetch.js b/node_modules/@sigstore/sign/dist/types/fetch.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/types/fetch.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/sign/dist/util/index.js b/node_modules/@sigstore/sign/dist/util/index.js new file mode 100644 index 0000000000000..436630cfbbf19 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/util/index.js @@ -0,0 +1,59 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ua = exports.oidc = exports.pem = exports.json = exports.encoding = exports.dsse = exports.crypto = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var core_1 = require("@sigstore/core"); +Object.defineProperty(exports, "crypto", { enumerable: true, get: function () { return core_1.crypto; } }); +Object.defineProperty(exports, "dsse", { enumerable: true, get: function () { return core_1.dsse; } }); +Object.defineProperty(exports, "encoding", { enumerable: true, get: function () { return core_1.encoding; } }); +Object.defineProperty(exports, "json", { enumerable: true, get: function () { return core_1.json; } }); +Object.defineProperty(exports, "pem", { enumerable: true, get: function () { return core_1.pem; } }); +exports.oidc = __importStar(require("./oidc")); +exports.ua = __importStar(require("./ua")); diff --git a/node_modules/@sigstore/sign/dist/util/oidc.js b/node_modules/@sigstore/sign/dist/util/oidc.js new file mode 100644 index 0000000000000..a9a3b10d3f61a --- /dev/null +++ b/node_modules/@sigstore/sign/dist/util/oidc.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.extractJWTSubject = extractJWTSubject; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +function extractJWTSubject(jwt) { + const parts = jwt.split('.', 3); + const payload = JSON.parse(core_1.encoding.base64Decode(parts[1])); + if (payload.email) { + if (!payload.email_verified) { + throw new Error('JWT email not verified by issuer'); + } + return payload.email; + } + if (payload.sub) { + return payload.sub; + } + else { + throw new Error('JWT subject not found'); + } +} diff --git a/node_modules/@sigstore/sign/dist/util/ua.js b/node_modules/@sigstore/sign/dist/util/ua.js new file mode 100644 index 0000000000000..b15ff2070fb9f --- /dev/null +++ b/node_modules/@sigstore/sign/dist/util/ua.js @@ -0,0 +1,32 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getUserAgent = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const os_1 = __importDefault(require("os")); +// Format User-Agent: <product> / <product-version> (<platform>) +// source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent +const getUserAgent = () => { + const packageVersion = require('../../package.json').version; + const nodeVersion = process.version; + const platformName = os_1.default.platform(); + const archName = os_1.default.arch(); + return `sigstore-js/${packageVersion} (Node ${nodeVersion}) (${platformName}/${archName})`; +}; +exports.getUserAgent = getUserAgent; diff --git a/node_modules/@sigstore/sign/dist/witness/index.js b/node_modules/@sigstore/sign/dist/witness/index.js new file mode 100644 index 0000000000000..72677c399caa7 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/index.js @@ -0,0 +1,24 @@ +"use strict"; +/* istanbul ignore file */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TSAWitness = exports.RekorWitness = exports.DEFAULT_REKOR_URL = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var tlog_1 = require("./tlog"); +Object.defineProperty(exports, "DEFAULT_REKOR_URL", { enumerable: true, get: function () { return tlog_1.DEFAULT_REKOR_URL; } }); +Object.defineProperty(exports, "RekorWitness", { enumerable: true, get: function () { return tlog_1.RekorWitness; } }); +var tsa_1 = require("./tsa"); +Object.defineProperty(exports, "TSAWitness", { enumerable: true, get: function () { return tsa_1.TSAWitness; } }); diff --git a/node_modules/@sigstore/sign/dist/witness/tlog/client.js b/node_modules/@sigstore/sign/dist/witness/tlog/client.js new file mode 100644 index 0000000000000..8d13c45124e0b --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/tlog/client.js @@ -0,0 +1,92 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TLogV2Client = exports.TLogClient = void 0; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../../error"); +const error_2 = require("../../external/error"); +const rekor_1 = require("../../external/rekor"); +const rekor_v2_1 = require("../../external/rekor-v2"); +class TLogClient { + rekor; + fetchOnConflict; + constructor(options) { + this.fetchOnConflict = options.fetchOnConflict ?? false; + this.rekor = new rekor_1.Rekor({ + baseURL: options.rekorBaseURL, + retry: options.retry, + timeout: options.timeout, + }); + } + async createEntry(proposedEntry) { + let entry; + try { + entry = await this.rekor.createEntry(proposedEntry); + } + catch (err) { + // If the entry already exists, fetch it (if enabled) + if (entryExistsError(err) && this.fetchOnConflict) { + // Grab the UUID of the existing entry from the location header + /* istanbul ignore next */ + const uuid = err.location.split('/').pop() || ''; + try { + entry = await this.rekor.getEntry(uuid); + } + catch (err) { + (0, error_1.internalError)(err, 'TLOG_FETCH_ENTRY_ERROR', 'error fetching tlog entry'); + } + } + else { + (0, error_1.internalError)(err, 'TLOG_CREATE_ENTRY_ERROR', 'error creating tlog entry'); + } + } + return entry; + } +} +exports.TLogClient = TLogClient; +function entryExistsError(value) { + return (value instanceof error_2.HTTPError && + value.statusCode === 409 && + value.location !== undefined); +} +class TLogV2Client { + rekor; + constructor(options) { + this.rekor = new rekor_v2_1.RekorV2({ + baseURL: options.rekorBaseURL, + retry: options.retry, + timeout: options.timeout, + }); + } + async createEntry(createEntryRequest) { + let entry; + try { + entry = await this.rekor.createEntry(createEntryRequest); + } + catch (err) { + (0, error_1.internalError)(err, 'TLOG_CREATE_ENTRY_ERROR', 'error creating tlog entry'); + } + if (entry.logId === undefined || entry.kindVersion === undefined) { + (0, error_1.internalError)(new Error('invalid tlog entry'), 'TLOG_CREATE_ENTRY_ERROR', 'error creating tlog entry'); + } + return { + ...entry, + logId: entry.logId, + kindVersion: entry.kindVersion, + }; + } +} +exports.TLogV2Client = TLogV2Client; diff --git a/node_modules/@sigstore/sign/dist/witness/tlog/entry.js b/node_modules/@sigstore/sign/dist/witness/tlog/entry.js new file mode 100644 index 0000000000000..0563406b5d875 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/tlog/entry.js @@ -0,0 +1,197 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toProposedEntry = toProposedEntry; +exports.toCreateEntryRequest = toCreateEntryRequest; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const bundle_1 = require("@sigstore/bundle"); +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const util_1 = require("../../util"); +const SHA256_ALGORITHM = 'sha256'; +function toProposedEntry(content, publicKey, +// TODO: Remove this parameter once have completely switched to 'dsse' entries +entryType = 'dsse') { + switch (content.$case) { + case 'dsseEnvelope': + // TODO: Remove this conditional once have completely ditched "intoto" entries + if (entryType === 'intoto') { + return toProposedIntotoEntry(content.dsseEnvelope, publicKey); + } + return toProposedDSSEEntry(content.dsseEnvelope, publicKey); + case 'messageSignature': + return toProposedHashedRekordEntry(content.messageSignature, publicKey); + } +} +// Returns a properly formatted Rekor "hashedrekord" entry for the given digest +// and signature +function toProposedHashedRekordEntry(messageSignature, publicKey) { + const hexDigest = messageSignature.messageDigest.digest.toString('hex'); + const b64Signature = messageSignature.signature.toString('base64'); + const b64Key = util_1.encoding.base64Encode(publicKey); + return { + apiVersion: '0.0.1', + kind: 'hashedrekord', + spec: { + data: { + hash: { + algorithm: SHA256_ALGORITHM, + value: hexDigest, + }, + }, + signature: { + content: b64Signature, + publicKey: { + content: b64Key, + }, + }, + }, + }; +} +// Returns a properly formatted Rekor "dsse" entry for the given DSSE envelope +// and signature +function toProposedDSSEEntry(envelope, publicKey) { + const envelopeJSON = JSON.stringify((0, bundle_1.envelopeToJSON)(envelope)); + const encodedKey = util_1.encoding.base64Encode(publicKey); + return { + apiVersion: '0.0.1', + kind: 'dsse', + spec: { + proposedContent: { + envelope: envelopeJSON, + verifiers: [encodedKey], + }, + }, + }; +} +// Returns a properly formatted Rekor "intoto" entry for the given DSSE +// envelope and signature +function toProposedIntotoEntry(envelope, publicKey) { + // Calculate the value for the payloadHash field in the Rekor entry + const payloadHash = util_1.crypto + .digest(SHA256_ALGORITHM, envelope.payload) + .toString('hex'); + // Calculate the value for the hash field in the Rekor entry + const envelopeHash = calculateDSSEHash(envelope, publicKey); + // Collect values for re-creating the DSSE envelope. + // Double-encode payload and signature cause that's what Rekor expects + const payload = util_1.encoding.base64Encode(envelope.payload.toString('base64')); + const sig = util_1.encoding.base64Encode(envelope.signatures[0].sig.toString('base64')); + const keyid = envelope.signatures[0].keyid; + const encodedKey = util_1.encoding.base64Encode(publicKey); + // Create the envelope portion of the entry. Note the inclusion of the + // publicKey in the signature struct is not a standard part of a DSSE + // envelope, but is required by Rekor. + const dsse = { + payloadType: envelope.payloadType, + payload: payload, + signatures: [{ sig, publicKey: encodedKey }], + }; + // If the keyid is an empty string, Rekor seems to remove it altogether. We + // need to do the same here so that we can properly recreate the entry for + // verification. + if (keyid.length > 0) { + dsse.signatures[0].keyid = keyid; + } + return { + apiVersion: '0.0.2', + kind: 'intoto', + spec: { + content: { + envelope: dsse, + hash: { algorithm: SHA256_ALGORITHM, value: envelopeHash }, + payloadHash: { algorithm: SHA256_ALGORITHM, value: payloadHash }, + }, + }, + }; +} +// Calculates the hash of a DSSE envelope for inclusion in a Rekor entry. +// There is no standard way to do this, so the scheme we're using as as +// follows: +// * payload is base64 encoded +// * signature is base64 encoded (only the first signature is used) +// * keyid is included ONLY if it is NOT an empty string +// * The resulting JSON is canonicalized and hashed to a hex string +function calculateDSSEHash(envelope, publicKey) { + const dsse = { + payloadType: envelope.payloadType, + payload: envelope.payload.toString('base64'), + signatures: [ + { sig: envelope.signatures[0].sig.toString('base64'), publicKey }, + ], + }; + // If the keyid is an empty string, Rekor seems to remove it altogether. + if (envelope.signatures[0].keyid.length > 0) { + dsse.signatures[0].keyid = envelope.signatures[0].keyid; + } + return util_1.crypto + .digest(SHA256_ALGORITHM, util_1.json.canonicalize(dsse)) + .toString('hex'); +} +function toCreateEntryRequest(content, publicKey) { + switch (content.$case) { + case 'dsseEnvelope': + return toCreateEntryRequestDSSE(content.dsseEnvelope, publicKey); + case 'messageSignature': + return toCreateEntryRequestMessageSignature(content.messageSignature, publicKey); + } +} +function toCreateEntryRequestDSSE(envelope, publicKey) { + return { + spec: { + $case: 'dsseRequestV002', + dsseRequestV002: { + envelope: envelope, + verifiers: [ + { + // TODO: We need to add support of passing the key details in the + // signature bundle. For now we're hardcoding the key details here. + keyDetails: protobuf_specs_1.PublicKeyDetails.PKIX_ECDSA_P256_SHA_256, + verifier: { + $case: 'x509Certificate', + x509Certificate: { + rawBytes: util_1.pem.toDER(publicKey), + }, + }, + }, + ], + }, + }, + }; +} +function toCreateEntryRequestMessageSignature(messageSignature, publicKey) { + return { + spec: { + $case: 'hashedRekordRequestV002', + hashedRekordRequestV002: { + digest: messageSignature.messageDigest.digest, + signature: { + content: messageSignature.signature, + verifier: { + // TODO: We need to add support of passing the key details in the + // signature bundle. For now we're hardcoding the key details here. + keyDetails: protobuf_specs_1.PublicKeyDetails.PKIX_ECDSA_P256_SHA_256, + verifier: { + $case: 'x509Certificate', + x509Certificate: { + rawBytes: util_1.pem.toDER(publicKey), + }, + }, + }, + }, + }, + }, + }; +} diff --git a/node_modules/@sigstore/sign/dist/witness/tlog/index.js b/node_modules/@sigstore/sign/dist/witness/tlog/index.js new file mode 100644 index 0000000000000..5a2e71a1c2911 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/tlog/index.js @@ -0,0 +1,97 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RekorWitness = exports.DEFAULT_REKOR_URL = void 0; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const util_1 = require("../../util"); +const client_1 = require("./client"); +const entry_1 = require("./entry"); +exports.DEFAULT_REKOR_URL = 'https://rekor.sigstore.dev'; +class RekorWitness { + tlogV1; + tlogV2; + entryType; + majorApiVersion; + constructor(options) { + this.entryType = options.entryType; + this.majorApiVersion = options.majorApiVersion || 1; + this.tlogV1 = new client_1.TLogClient({ + ...options, + rekorBaseURL: options.rekorBaseURL || /* istanbul ignore next */ exports.DEFAULT_REKOR_URL, + }); + this.tlogV2 = new client_1.TLogV2Client({ + ...options, + rekorBaseURL: options.rekorBaseURL || /* istanbul ignore next */ exports.DEFAULT_REKOR_URL, + }); + } + async testify(content, publicKey) { + let tlogEntry; + if (this.majorApiVersion === 2) { + const request = (0, entry_1.toCreateEntryRequest)(content, publicKey); + tlogEntry = await this.tlogV2.createEntry(request); + } + else { + const proposedEntry = (0, entry_1.toProposedEntry)(content, publicKey, this.entryType); + const entry = await this.tlogV1.createEntry(proposedEntry); + tlogEntry = toTransparencyLogEntry(entry); + } + return { tlogEntries: [tlogEntry] }; + } +} +exports.RekorWitness = RekorWitness; +function toTransparencyLogEntry(entry) { + const logID = Buffer.from(entry.logID, 'hex'); + // Parse entry body so we can extract the kind and version. + const bodyJSON = util_1.encoding.base64Decode(entry.body); + const entryBody = JSON.parse(bodyJSON); + const promise = entry?.verification?.signedEntryTimestamp + ? inclusionPromise(entry.verification.signedEntryTimestamp) + : undefined; + const proof = entry?.verification?.inclusionProof + ? inclusionProof(entry.verification.inclusionProof) + : undefined; + const tlogEntry = { + logIndex: entry.logIndex.toString(), + logId: { + keyId: logID, + }, + integratedTime: entry.integratedTime.toString(), + kindVersion: { + kind: entryBody.kind, + version: entryBody.apiVersion, + }, + inclusionPromise: promise, + inclusionProof: proof, + canonicalizedBody: Buffer.from(entry.body, 'base64'), + }; + return tlogEntry; +} +function inclusionPromise(promise) { + return { + signedEntryTimestamp: Buffer.from(promise, 'base64'), + }; +} +function inclusionProof(proof) { + return { + logIndex: proof.logIndex.toString(), + treeSize: proof.treeSize.toString(), + rootHash: Buffer.from(proof.rootHash, 'hex'), + hashes: proof.hashes.map((h) => Buffer.from(h, 'hex')), + checkpoint: { + envelope: proof.checkpoint, + }, + }; +} diff --git a/node_modules/@sigstore/sign/dist/witness/tsa/client.js b/node_modules/@sigstore/sign/dist/witness/tsa/client.js new file mode 100644 index 0000000000000..97bfb5b883e3a --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/tsa/client.js @@ -0,0 +1,47 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TSAClient = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../../error"); +const tsa_1 = require("../../external/tsa"); +const util_1 = require("../../util"); +const SHA256_ALGORITHM = 'sha256'; +class TSAClient { + tsa; + constructor(options) { + this.tsa = new tsa_1.TimestampAuthority({ + baseURL: options.tsaBaseURL, + retry: options.retry, + timeout: options.timeout, + }); + } + async createTimestamp(signature) { + const request = { + artifactHash: util_1.crypto + .digest(SHA256_ALGORITHM, signature) + .toString('base64'), + hashAlgorithm: SHA256_ALGORITHM, + }; + try { + return await this.tsa.createTimestamp(request); + } + catch (err) { + (0, error_1.internalError)(err, 'TSA_CREATE_TIMESTAMP_ERROR', 'error creating timestamp'); + } + } +} +exports.TSAClient = TSAClient; diff --git a/node_modules/@sigstore/sign/dist/witness/tsa/index.js b/node_modules/@sigstore/sign/dist/witness/tsa/index.js new file mode 100644 index 0000000000000..07a34b46cf113 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/tsa/index.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TSAWitness = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const client_1 = require("./client"); +class TSAWitness { + tsa; + constructor(options) { + this.tsa = new client_1.TSAClient({ + tsaBaseURL: options.tsaBaseURL, + retry: options.retry, + timeout: options.timeout, + }); + } + async testify(content) { + const signature = extractSignature(content); + const timestamp = await this.tsa.createTimestamp(signature); + return { + rfc3161Timestamps: [{ signedTimestamp: timestamp }], + }; + } +} +exports.TSAWitness = TSAWitness; +function extractSignature(content) { + switch (content.$case) { + case 'dsseEnvelope': + return content.dsseEnvelope.signatures[0].sig; + case 'messageSignature': + return content.messageSignature.signature; + } +} diff --git a/node_modules/@sigstore/sign/dist/witness/witness.js b/node_modules/@sigstore/sign/dist/witness/witness.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@sigstore/sign/dist/witness/witness.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/sign/package.json b/node_modules/@sigstore/sign/package.json new file mode 100644 index 0000000000000..0f844a8735a89 --- /dev/null +++ b/node_modules/@sigstore/sign/package.json @@ -0,0 +1,46 @@ +{ + "name": "@sigstore/sign", + "version": "4.1.0", + "description": "Sigstore signing library", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "shx rm -rf dist *.tsbuildinfo", + "build": "tsc --build", + "test": "jest" + }, + "files": [ + "dist" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/sigstore-js.git" + }, + "bugs": { + "url": "https://github.com/sigstore/sigstore-js/issues" + }, + "homepage": "https://github.com/sigstore/sigstore-js/tree/main/packages/sign#readme", + "publishConfig": { + "provenance": true + }, + "devDependencies": { + "@sigstore/jest": "^0.0.0", + "@sigstore/mock": "^0.11.0", + "@sigstore/rekor-types": "^4.0.0", + "@types/make-fetch-happen": "^10.0.4", + "@types/promise-retry": "^1.1.6" + }, + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.3", + "proc-log": "^6.1.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/@sigstore/tuf/LICENSE b/node_modules/@sigstore/tuf/LICENSE new file mode 100644 index 0000000000000..e9e7c1679a09d --- /dev/null +++ b/node_modules/@sigstore/tuf/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 The Sigstore Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/@sigstore/tuf/dist/appdata.js b/node_modules/@sigstore/tuf/dist/appdata.js new file mode 100644 index 0000000000000..06a8143e70da2 --- /dev/null +++ b/node_modules/@sigstore/tuf/dist/appdata.js @@ -0,0 +1,43 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.appDataPath = appDataPath; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const os_1 = __importDefault(require("os")); +const path_1 = __importDefault(require("path")); +function appDataPath(name) { + const homedir = os_1.default.homedir(); + switch (process.platform) { + /* istanbul ignore next */ + case 'darwin': { + const appSupport = path_1.default.join(homedir, 'Library', 'Application Support'); + return path_1.default.join(appSupport, name); + } + /* istanbul ignore next */ + case 'win32': { + const localAppData = process.env.LOCALAPPDATA || path_1.default.join(homedir, 'AppData', 'Local'); + return path_1.default.join(localAppData, name, 'Data'); + } + /* istanbul ignore next */ + default: { + const localData = process.env.XDG_DATA_HOME || path_1.default.join(homedir, '.local', 'share'); + return path_1.default.join(localData, name); + } + } +} diff --git a/node_modules/@sigstore/tuf/dist/client.js b/node_modules/@sigstore/tuf/dist/client.js new file mode 100644 index 0000000000000..a170af40a0a28 --- /dev/null +++ b/node_modules/@sigstore/tuf/dist/client.js @@ -0,0 +1,116 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TUFClient = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const tuf_js_1 = require("tuf-js"); +const _1 = require("."); +const package_json_1 = require("../package.json"); +const target_1 = require("./target"); +const TARGETS_DIR_NAME = 'targets'; +class TUFClient { + updater; + constructor(options) { + const url = new URL(options.mirrorURL); + const repoName = encodeURIComponent(url.host + url.pathname.replace(/\/$/, '')); + const cachePath = path_1.default.join(options.cachePath, repoName); + initTufCache(cachePath); + seedCache({ + cachePath, + mirrorURL: options.mirrorURL, + tufRootPath: options.rootPath, + forceInit: options.forceInit, + }); + this.updater = initClient({ + mirrorURL: options.mirrorURL, + cachePath, + forceCache: options.forceCache, + retry: options.retry, + timeout: options.timeout, + }); + } + async refresh() { + return this.updater.refresh(); + } + getTarget(targetName) { + return (0, target_1.readTarget)(this.updater, targetName); + } +} +exports.TUFClient = TUFClient; +// Initializes the TUF cache directory structure including the initial +// root.json file. If the cache directory does not exist, it will be +// created. If the targets directory does not exist, it will be created. +// If the root.json file does not exist, it will be copied from the +// rootPath argument. +function initTufCache(cachePath) { + const targetsPath = path_1.default.join(cachePath, TARGETS_DIR_NAME); + if (!fs_1.default.existsSync(cachePath)) { + fs_1.default.mkdirSync(cachePath, { recursive: true }); + } + /* istanbul ignore else */ + if (!fs_1.default.existsSync(targetsPath)) { + fs_1.default.mkdirSync(targetsPath); + } +} +// Populates the TUF cache with the initial root.json file. If the root.json +// file does not exist (or we're forcing re-initialization), copy it from either +// the rootPath argument or from one of the repo seeds. +function seedCache({ cachePath, mirrorURL, tufRootPath, forceInit, }) { + const cachedRootPath = path_1.default.join(cachePath, 'root.json'); + // If the root.json file does not exist (or we're forcing re-initialization), + // populate it either from the supplied rootPath or from one of the repo seeds. + /* istanbul ignore else */ + if (!fs_1.default.existsSync(cachedRootPath) || forceInit) { + if (tufRootPath) { + fs_1.default.copyFileSync(tufRootPath, cachedRootPath); + } + else { + const seeds = require('../seeds.json'); + const repoSeed = seeds[mirrorURL]; + if (!repoSeed) { + throw new _1.TUFError({ + code: 'TUF_INIT_CACHE_ERROR', + message: `No root.json found for mirror: ${mirrorURL}`, + }); + } + fs_1.default.writeFileSync(cachedRootPath, Buffer.from(repoSeed['root.json'], 'base64')); + // Copy any seed targets into the cache + Object.entries(repoSeed.targets).forEach(([targetName, target]) => { + fs_1.default.writeFileSync(path_1.default.join(cachePath, TARGETS_DIR_NAME, targetName), Buffer.from(target, 'base64')); + }); + } + } +} +function initClient(options) { + const config = { + fetchTimeout: options.timeout, + fetchRetry: options.retry, + userAgent: `${encodeURIComponent(package_json_1.name)}/${package_json_1.version}`, + }; + return new tuf_js_1.Updater({ + metadataBaseUrl: options.mirrorURL, + targetBaseUrl: `${options.mirrorURL}/targets`, + metadataDir: options.cachePath, + targetDir: path_1.default.join(options.cachePath, TARGETS_DIR_NAME), + forceCache: options.forceCache, + config, + }); +} diff --git a/node_modules/@sigstore/tuf/dist/error.js b/node_modules/@sigstore/tuf/dist/error.js new file mode 100644 index 0000000000000..fd1f7100166cf --- /dev/null +++ b/node_modules/@sigstore/tuf/dist/error.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TUFError = void 0; +class TUFError extends Error { + code; + cause; + constructor({ code, message, cause, }) { + super(message); + this.code = code; + this.cause = cause; + this.name = this.constructor.name; + } +} +exports.TUFError = TUFError; diff --git a/node_modules/@sigstore/tuf/dist/index.js b/node_modules/@sigstore/tuf/dist/index.js new file mode 100644 index 0000000000000..2af5de93ec5d2 --- /dev/null +++ b/node_modules/@sigstore/tuf/dist/index.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TUFError = exports.DEFAULT_MIRROR_URL = void 0; +exports.getTrustedRoot = getTrustedRoot; +exports.initTUF = initTUF; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const appdata_1 = require("./appdata"); +const client_1 = require("./client"); +exports.DEFAULT_MIRROR_URL = 'https://tuf-repo-cdn.sigstore.dev'; +const DEFAULT_CACHE_DIR = 'sigstore-js'; +const DEFAULT_RETRY = { retries: 2 }; +const DEFAULT_TIMEOUT = 5000; +const TRUSTED_ROOT_TARGET = 'trusted_root.json'; +async function getTrustedRoot( +/* istanbul ignore next */ +options = {}) { + const client = createClient(options); + const trustedRoot = await client.getTarget(TRUSTED_ROOT_TARGET); + return protobuf_specs_1.TrustedRoot.fromJSON(JSON.parse(trustedRoot)); +} +async function initTUF( +/* istanbul ignore next */ +options = {}) { + const client = createClient(options); + return client.refresh().then(() => client); +} +// Create a TUF client with default options +function createClient(options) { + /* istanbul ignore next */ + return new client_1.TUFClient({ + cachePath: options.cachePath || (0, appdata_1.appDataPath)(DEFAULT_CACHE_DIR), + rootPath: options.rootPath, + mirrorURL: options.mirrorURL || exports.DEFAULT_MIRROR_URL, + retry: options.retry ?? DEFAULT_RETRY, + timeout: options.timeout ?? DEFAULT_TIMEOUT, + forceCache: options.forceCache ?? false, + forceInit: options.forceInit ?? options.force ?? false, + }); +} +var error_1 = require("./error"); +Object.defineProperty(exports, "TUFError", { enumerable: true, get: function () { return error_1.TUFError; } }); diff --git a/node_modules/@sigstore/tuf/dist/target.js b/node_modules/@sigstore/tuf/dist/target.js new file mode 100644 index 0000000000000..5c6675bdfbf5f --- /dev/null +++ b/node_modules/@sigstore/tuf/dist/target.js @@ -0,0 +1,79 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.readTarget = readTarget; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const fs_1 = __importDefault(require("fs")); +const error_1 = require("./error"); +// Downloads and returns the specified target from the provided TUF Updater. +async function readTarget(tuf, targetPath) { + const path = await getTargetPath(tuf, targetPath); + return new Promise((resolve, reject) => { + fs_1.default.readFile(path, 'utf-8', (err, data) => { + if (err) { + reject(new error_1.TUFError({ + code: 'TUF_READ_TARGET_ERROR', + message: `error reading target ${path}`, + cause: err, + })); + } + else { + resolve(data); + } + }); + }); +} +// Returns the local path to the specified target. If the target is not yet +// cached locally, the provided TUF Updater will be used to download and +// cache the target. +async function getTargetPath(tuf, target) { + let targetInfo; + try { + targetInfo = await tuf.getTargetInfo(target); + } + catch (err) { + throw new error_1.TUFError({ + code: 'TUF_REFRESH_METADATA_ERROR', + message: 'error refreshing TUF metadata', + cause: err, + }); + } + if (!targetInfo) { + throw new error_1.TUFError({ + code: 'TUF_FIND_TARGET_ERROR', + message: `target ${target} not found`, + }); + } + let path = await tuf.findCachedTarget(targetInfo); + // An empty path here means the target has not been cached locally, or is + // out of date. In either case, we need to download it. + if (!path) { + try { + path = await tuf.downloadTarget(targetInfo); + } + catch (err) { + throw new error_1.TUFError({ + code: 'TUF_DOWNLOAD_TARGET_ERROR', + message: `error downloading target ${path}`, + cause: err, + }); + } + } + return path; +} diff --git a/node_modules/@sigstore/tuf/package.json b/node_modules/@sigstore/tuf/package.json new file mode 100644 index 0000000000000..a782796c45ed6 --- /dev/null +++ b/node_modules/@sigstore/tuf/package.json @@ -0,0 +1,41 @@ +{ + "name": "@sigstore/tuf", + "version": "4.0.1", + "description": "Client for the Sigstore TUF repository", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "shx rm -rf dist *.tsbuildinfo", + "build": "tsc --build", + "test": "jest" + }, + "files": [ + "dist", + "seeds.json" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/sigstore-js.git" + }, + "bugs": { + "url": "https://github.com/sigstore/sigstore-js/issues" + }, + "homepage": "https://github.com/sigstore/sigstore-js/tree/main/packages/tuf#readme", + "publishConfig": { + "provenance": true + }, + "devDependencies": { + "@sigstore/jest": "^0.0.0", + "@tufjs/repo-mock": "^4.0.0", + "@types/make-fetch-happen": "^10.0.4" + }, + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/@sigstore/tuf/seeds.json b/node_modules/@sigstore/tuf/seeds.json new file mode 100644 index 0000000000000..54cb71f29ef0c --- /dev/null +++ b/node_modules/@sigstore/tuf/seeds.json @@ -0,0 +1 @@ +{"https://tuf-repo-cdn.sigstore.dev":{"root.json":"ewogInNpZ25hdHVyZXMiOiBbCiAgewogICAia2V5aWQiOiAiNmYyNjAwODlkNTkyM2RhZjIwMTY2Y2E2NTdjNTQzYWY2MTgzNDZhYjk3MTg4NGE5OTk2MmIwMTk4OGJiZTBjMyIsCiAgICJzaWciOiAiIgogIH0sCiAgewogICAia2V5aWQiOiAiZTcxYTU0ZDU0MzgzNWJhODZhZGFkOTQ2MDM3OWM3NjQxZmI4NzI2ZDE2NGVhNzY2ODAxYTFjNTIyYWJhN2VhMiIsCiAgICJzaWciOiAiMzA0NTAyMjEwMGJiZGRkNDY0ZjgwNjZjZWI4OGJhNzg3Mzc1YzEyY2Q2MzMwNjgwZTA4YzI5MTA3MDNlNjUzOGM3MWNjNzlhZDIwMjIwNTE5MGIwNmU0NTM3ZmU5NjFiM2VmODFmZTY4ZWRjZDAwODljMTlmOTE5YWZlZDQyM2I5YWFmZDcwMDY0MTE1MyIKICB9LAogIHsKICAgImtleWlkIjogIjIyZjRjYWVjNmQ4ZTZmOTU1NWFmNjZiM2Q0YzNjYjA2YTNiYjIzZmRjN2UzOWM5MTZjNjFmNDYyZTZmNTJiMDYiLAogICAic2lnIjogIjMwNDQwMjIwNjkzMDZjZDUyNTdmNzMyYTc0MGMxYWZlNjBhOGU0MzNjNWRlNThlYWZlYWRiZTk5YzMzNmM5YzcxZDE5OGNmODAyMjAwZDc3Mzk1M2FlN2RiYzQ4ZDNlNWJhZDlhNmY2NGJhZmZmMTk2YjdlMmFkNGE1MmExOTUxOTM2N2Q0N2RjMDQyIgogIH0sCiAgewogICAia2V5aWQiOiAiNjE2NDM4MzgxMjViNDQwYjQwZGI2OTQyZjVjYjVhMzFjMGRjMDQzNjgzMTZlYjJhYWE1OGI5NTkwNGE1ODIyMiIsCiAgICJzaWciOiAiMzA0NDAyMjA0ZDIxYTJlYzgwZGY2NmU2MWY2ZmUyOTEyOTUxZGM0N2RmODM2MDM2ZjhjMGFiMTA4MTZkMzc1ZTcxZGJmNzllMDIyMDU0N2FkY2UxYWZkZjA0ZTY3OTRlZmEyMDNkZDUyNjRjNmY3ZTBlZjc4ZTU3ZmU5MzRiMGQyNmNiOTk0ZWVjNzYiCiAgfSwKICB7CiAgICJrZXlpZCI6ICJhNjg3ZTViZjRmYWI4MmIwZWU1OGQ0NmUwNWM5NTM1MTQ1YTJjOWFmYjQ1OGY0M2Q0MmI0NWNhMGZkY2UyYTcwIiwKICAgInNpZyI6ICIzMDQ1MDIyMDYwODI2NDk2NTU3MTQ0ZWIxNjQ5ODkzZWQ1ZjZmNGVhNTQ1MzZmZWIwY2E4MmY4Yjg5YWU2NDFiZTM5NzQzZTUwMjIxMDBhZDcxMThiNWU5ZDQ4MzczMjYyMDZlNDEyZmM2ZGEyOTk5OTI1ZDExMDMyOGE3YzE2NmIwNmM2MjQzMzZjOTNmIgogIH0sCiAgewogICAia2V5aWQiOiAiMTgzZTY0ZjM3NjcwZGMxM2NhMGQyODk5NWEzMDUzZjM3NDA5NTRkZGNlNDQzMjFhNDFlNDY1MzRjZjQ0ZTYzMiIsCiAgICJzaWciOiAiMzA0NjAyMjEwMGQ4MTc5NDM5YzJlNzNlYjBjMTczM2FiZWU3ZmFmODMyZGNhZWE3MjYzZWRjYjQ5MTk4OTFjM2EyNDdmMDU5MjMwMjIxMDBlMWE0MzdlMDc5N2U4MDNmOWI3MmRjOWQyZDkyMTU1YjBhMjI3MGMyNGVmZGQ1ZjRiM2E1ZDhmMGIwZjQzMWE3IgogIH0KIF0sCiAic2lnbmVkIjogewogICJfdHlwZSI6ICJyb290IiwKICAiY29uc2lzdGVudF9zbmFwc2hvdCI6IHRydWUsCiAgImV4cGlyZXMiOiAiMjAyNi0wMS0yMlQxMzowNTo1OVoiLAogICJrZXlzIjogewogICAiMGM4NzQzMmMzYmYwOWZkOTkxODlmZGMzMmZhNWVhZWRmNGU0YTVmYWM3YmFiNzNmYTA0YTJlMGZjNjRhZjZmNSI6IHsKICAgICJrZXlpZF9oYXNoX2FsZ29yaXRobXMiOiBbCiAgICAgInNoYTI1NiIsCiAgICAgInNoYTUxMiIKICAgIF0sCiAgICAia2V5dHlwZSI6ICJlY2RzYSIsCiAgICAia2V5dmFsIjogewogICAgICJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRVdSaUdyNStqKzNKNVNzSCtadHI1bkUySDJ3TzdcbkJWK25PM3M5M2dMY2ExOHFUT3pIWTFvV3lBR0R5a01Tc0dUVUJTdDlEK0FuMEtmS3NEMm1mU000MlE9PVxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tXG4iCiAgICB9LAogICAgInNjaGVtZSI6ICJlY2RzYS1zaGEyLW5pc3RwMjU2IiwKICAgICJ4LXR1Zi1vbi1jaS1vbmxpbmUtdXJpIjogImdjcGttczpwcm9qZWN0cy9zaWdzdG9yZS1yb290LXNpZ25pbmcvbG9jYXRpb25zL2dsb2JhbC9rZXlSaW5ncy9yb290L2NyeXB0b0tleXMvdGltZXN0YW1wL2NyeXB0b0tleVZlcnNpb25zLzEiCiAgIH0sCiAgICIxODNlNjRmMzc2NzBkYzEzY2EwZDI4OTk1YTMwNTNmMzc0MDk1NGRkY2U0NDMyMWE0MWU0NjUzNGNmNDRlNjMyIjogewogICAgImtleXR5cGUiOiAiZWNkc2EiLAogICAgImtleXZhbCI6IHsKICAgICAicHVibGljIjogIi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVNeHBQT0pDSVo1b3RHNDEwNmZHSnNlRVFpM1Y5XG5wa01ZUTR1eVY5VGoxTTdXSFhJeUxHK2prZnZ1RzBnbFExSlpiUlpaQlYzZ0FSNHNvamRHSElTZW93PT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLVxuIgogICAgfSwKICAgICJzY2hlbWUiOiAiZWNkc2Etc2hhMi1uaXN0cDI1NiIsCiAgICAieC10dWYtb24tY2kta2V5b3duZXIiOiAiQGxhbmNlIgogICB9LAogICAiMjJmNGNhZWM2ZDhlNmY5NTU1YWY2NmIzZDRjM2NiMDZhM2JiMjNmZGM3ZTM5YzkxNmM2MWY0NjJlNmY1MmIwNiI6IHsKICAgICJrZXlpZF9oYXNoX2FsZ29yaXRobXMiOiBbCiAgICAgInNoYTI1NiIsCiAgICAgInNoYTUxMiIKICAgIF0sCiAgICAia2V5dHlwZSI6ICJlY2RzYSIsCiAgICAia2V5dmFsIjogewogICAgICJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRXpCelZPbUhDUG9qTVZMU0kzNjRXaWlWOE5QckRcbjZJZ1J4Vmxpc2t6L3YreTNKRVI1bWNWR2NPTmxpRGNXTUM1SjJsZkhtalBOUGhiNEg3eG04THpmU0E9PVxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tXG4iCiAgICB9LAogICAgInNjaGVtZSI6ICJlY2RzYS1zaGEyLW5pc3RwMjU2IiwKICAgICJ4LXR1Zi1vbi1jaS1rZXlvd25lciI6ICJAc2FudGlhZ290b3JyZXMiCiAgIH0sCiAgICI2MTY0MzgzODEyNWI0NDBiNDBkYjY5NDJmNWNiNWEzMWMwZGMwNDM2ODMxNmViMmFhYTU4Yjk1OTA0YTU4MjIyIjogewogICAgImtleWlkX2hhc2hfYWxnb3JpdGhtcyI6IFsKICAgICAic2hhMjU2IiwKICAgICAic2hhNTEyIgogICAgXSwKICAgICJrZXl0eXBlIjogImVjZHNhIiwKICAgICJrZXl2YWwiOiB7CiAgICAgInB1YmxpYyI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFaW5pa1NzQVFtWWtOZUg1ZVlxL0NuSXpMYWFjT1xueGxTYWF3UURPd3FLeS90Q3F4cTV4eFBTSmMyMUs0V0loczlHeU9rS2Z6dWVZM0dJTHpjTUpaNGNXdz09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS1cbiIKICAgIH0sCiAgICAic2NoZW1lIjogImVjZHNhLXNoYTItbmlzdHAyNTYiLAogICAgIngtdHVmLW9uLWNpLWtleW93bmVyIjogIkBib2JjYWxsYXdheSIKICAgfSwKICAgImE2ODdlNWJmNGZhYjgyYjBlZTU4ZDQ2ZTA1Yzk1MzUxNDVhMmM5YWZiNDU4ZjQzZDQyYjQ1Y2EwZmRjZTJhNzAiOiB7CiAgICAia2V5aWRfaGFzaF9hbGdvcml0aG1zIjogWwogICAgICJzaGEyNTYiLAogICAgICJzaGE1MTIiCiAgICBdLAogICAgImtleXR5cGUiOiAiZWNkc2EiLAogICAgImtleXZhbCI6IHsKICAgICAicHVibGljIjogIi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUwZ2hyaDkyTHcxWXIzaWRHVjVXcUN0TURCOEN4XG4rRDhoZEM0dzJaTE5JcGxWUm9WR0xza1lhM2doZU15T2ppSjhrUGkxNWFRMi8vN1Arb2o3VXZKUEd3PT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLVxuIgogICAgfSwKICAgICJzY2hlbWUiOiAiZWNkc2Etc2hhMi1uaXN0cDI1NiIsCiAgICAieC10dWYtb24tY2kta2V5b3duZXIiOiAiQGpvc2h1YWdsIgogICB9LAogICAiZTcxYTU0ZDU0MzgzNWJhODZhZGFkOTQ2MDM3OWM3NjQxZmI4NzI2ZDE2NGVhNzY2ODAxYTFjNTIyYWJhN2VhMiI6IHsKICAgICJrZXlpZF9oYXNoX2FsZ29yaXRobXMiOiBbCiAgICAgInNoYTI1NiIsCiAgICAgInNoYTUxMiIKICAgIF0sCiAgICAia2V5dHlwZSI6ICJlY2RzYSIsCiAgICAia2V5dmFsIjogewogICAgICJwdWJsaWMiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUVYc3ozU1pYRmI4ak1WNDJqNnBKbHlqYmpSOEtcbk4zQndvY2V4cTZMTUliNXFzV0tPUXZMTjE2TlVlZkxjNEhzd09vdW1Sc1ZWYWFqU3BRUzZmb2JrUnc9PVxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tXG4iCiAgICB9LAogICAgInNjaGVtZSI6ICJlY2RzYS1zaGEyLW5pc3RwMjU2IiwKICAgICJ4LXR1Zi1vbi1jaS1rZXlvd25lciI6ICJAbW5tNjc4IgogICB9CiAgfSwKICAicm9sZXMiOiB7CiAgICJyb290IjogewogICAgImtleWlkcyI6IFsKICAgICAiZTcxYTU0ZDU0MzgzNWJhODZhZGFkOTQ2MDM3OWM3NjQxZmI4NzI2ZDE2NGVhNzY2ODAxYTFjNTIyYWJhN2VhMiIsCiAgICAgIjIyZjRjYWVjNmQ4ZTZmOTU1NWFmNjZiM2Q0YzNjYjA2YTNiYjIzZmRjN2UzOWM5MTZjNjFmNDYyZTZmNTJiMDYiLAogICAgICI2MTY0MzgzODEyNWI0NDBiNDBkYjY5NDJmNWNiNWEzMWMwZGMwNDM2ODMxNmViMmFhYTU4Yjk1OTA0YTU4MjIyIiwKICAgICAiYTY4N2U1YmY0ZmFiODJiMGVlNThkNDZlMDVjOTUzNTE0NWEyYzlhZmI0NThmNDNkNDJiNDVjYTBmZGNlMmE3MCIsCiAgICAgIjE4M2U2NGYzNzY3MGRjMTNjYTBkMjg5OTVhMzA1M2YzNzQwOTU0ZGRjZTQ0MzIxYTQxZTQ2NTM0Y2Y0NGU2MzIiCiAgICBdLAogICAgInRocmVzaG9sZCI6IDMKICAgfSwKICAgInNuYXBzaG90IjogewogICAgImtleWlkcyI6IFsKICAgICAiMGM4NzQzMmMzYmYwOWZkOTkxODlmZGMzMmZhNWVhZWRmNGU0YTVmYWM3YmFiNzNmYTA0YTJlMGZjNjRhZjZmNSIKICAgIF0sCiAgICAidGhyZXNob2xkIjogMSwKICAgICJ4LXR1Zi1vbi1jaS1leHBpcnktcGVyaW9kIjogMzY1MCwKICAgICJ4LXR1Zi1vbi1jaS1zaWduaW5nLXBlcmlvZCI6IDM2NQogICB9LAogICAidGFyZ2V0cyI6IHsKICAgICJrZXlpZHMiOiBbCiAgICAgImU3MWE1NGQ1NDM4MzViYTg2YWRhZDk0NjAzNzljNzY0MWZiODcyNmQxNjRlYTc2NjgwMWExYzUyMmFiYTdlYTIiLAogICAgICIyMmY0Y2FlYzZkOGU2Zjk1NTVhZjY2YjNkNGMzY2IwNmEzYmIyM2ZkYzdlMzljOTE2YzYxZjQ2MmU2ZjUyYjA2IiwKICAgICAiNjE2NDM4MzgxMjViNDQwYjQwZGI2OTQyZjVjYjVhMzFjMGRjMDQzNjgzMTZlYjJhYWE1OGI5NTkwNGE1ODIyMiIsCiAgICAgImE2ODdlNWJmNGZhYjgyYjBlZTU4ZDQ2ZTA1Yzk1MzUxNDVhMmM5YWZiNDU4ZjQzZDQyYjQ1Y2EwZmRjZTJhNzAiLAogICAgICIxODNlNjRmMzc2NzBkYzEzY2EwZDI4OTk1YTMwNTNmMzc0MDk1NGRkY2U0NDMyMWE0MWU0NjUzNGNmNDRlNjMyIgogICAgXSwKICAgICJ0aHJlc2hvbGQiOiAzCiAgIH0sCiAgICJ0aW1lc3RhbXAiOiB7CiAgICAia2V5aWRzIjogWwogICAgICIwYzg3NDMyYzNiZjA5ZmQ5OTE4OWZkYzMyZmE1ZWFlZGY0ZTRhNWZhYzdiYWI3M2ZhMDRhMmUwZmM2NGFmNmY1IgogICAgXSwKICAgICJ0aHJlc2hvbGQiOiAxLAogICAgIngtdHVmLW9uLWNpLWV4cGlyeS1wZXJpb2QiOiA3LAogICAgIngtdHVmLW9uLWNpLXNpZ25pbmctcGVyaW9kIjogNgogICB9CiAgfSwKICAic3BlY192ZXJzaW9uIjogIjEuMCIsCiAgInZlcnNpb24iOiAxMywKICAieC10dWYtb24tY2ktZXhwaXJ5LXBlcmlvZCI6IDE5NywKICAieC10dWYtb24tY2ktc2lnbmluZy1wZXJpb2QiOiA0NgogfQp9","targets":{"trusted_root.json":"ewogICJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLmRldi5zaWdzdG9yZS50cnVzdGVkcm9vdCtqc29uO3ZlcnNpb249MC4xIiwKICAidGxvZ3MiOiBbCiAgICB7CiAgICAgICJiYXNlVXJsIjogImh0dHBzOi8vcmVrb3Iuc2lnc3RvcmUuZGV2IiwKICAgICAgImhhc2hBbGdvcml0aG0iOiAiU0hBMl8yNTYiLAogICAgICAicHVibGljS2V5IjogewogICAgICAgICJyYXdCeXRlcyI6ICJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUyRzJZKzJ0YWJkVFY1QmNHaUJJeDBhOWZBRndya0JibUxTR3RrczRMM3FYNnlZWTB6dWZCbmhDOFVyL2l5NTVHaFdQLzlBL2JZMkxoQzMwTTkrUll0dz09IiwKICAgICAgICAia2V5RGV0YWlscyI6ICJQS0lYX0VDRFNBX1AyNTZfU0hBXzI1NiIsCiAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgInN0YXJ0IjogIjIwMjEtMDEtMTJUMTE6NTM6MjdaIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImxvZ0lkIjogewogICAgICAgICJrZXlJZCI6ICJ3Tkk5YXRRR2x6K1ZXZk82TFJ5Z0g0UVVmWS84VzRSRndpVDVpNVdSZ0IwPSIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImJhc2VVcmwiOiAiaHR0cHM6Ly9sb2cyMDI1LTEucmVrb3Iuc2lnc3RvcmUuZGV2IiwKICAgICAgImhhc2hBbGdvcml0aG0iOiAiU0hBMl8yNTYiLAogICAgICAicHVibGljS2V5IjogewogICAgICAgICJyYXdCeXRlcyI6ICJNQ293QlFZREsyVndBeUVBdDhybHAxa25Hd2pmYmNYQVlQWUFrbjBYaUx6MXg4TzR0MFlrRWhpZTI0ND0iLAogICAgICAgICJrZXlEZXRhaWxzIjogIlBLSVhfRUQyNTUxOSIsCiAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgInN0YXJ0IjogIjIwMjUtMDktMjNUMDA6MDA6MDBaIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImxvZ0lkIjogewogICAgICAgICJrZXlJZCI6ICJ6eEdaRlZ2ZDBGRW1qUjhXckZ3TWRjQUo5dnRhWS9RWGY0NFkxd1VlUDZBPSIKICAgICAgfQogICAgfQogIF0sCiAgImNlcnRpZmljYXRlQXV0aG9yaXRpZXMiOiBbCiAgICB7CiAgICAgICJzdWJqZWN0IjogewogICAgICAgICJvcmdhbml6YXRpb24iOiAic2lnc3RvcmUuZGV2IiwKICAgICAgICAiY29tbW9uTmFtZSI6ICJzaWdzdG9yZSIKICAgICAgfSwKICAgICAgInVyaSI6ICJodHRwczovL2Z1bGNpby5zaWdzdG9yZS5kZXYiLAogICAgICAiY2VydENoYWluIjogewogICAgICAgICJjZXJ0aWZpY2F0ZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJyYXdCeXRlcyI6ICJNSUlCK0RDQ0FYNmdBd0lCQWdJVE5Wa0Rab0Npb2ZQRHN5N2RmbTZnZUxidWh6QUtCZ2dxaGtqT1BRUURBekFxTVJVd0V3WURWUVFLRXd4emFXZHpkRzl5WlM1a1pYWXhFVEFQQmdOVkJBTVRDSE5wWjNOMGIzSmxNQjRYRFRJeE1ETXdOekF6TWpBeU9Wb1hEVE14TURJeU16QXpNakF5T1Zvd0tqRVZNQk1HQTFVRUNoTU1jMmxuYzNSdmNtVXVaR1YyTVJFd0R3WURWUVFERXdoemFXZHpkRzl5WlRCMk1CQUdCeXFHU000OUFnRUdCU3VCQkFBaUEySUFCTFN5QTdJaTVrK3BOTzhaRVdZMHlsZW1XRG93T2tOYTNrTCtHWkU1WjVHV2VoTDkvQTliUk5BM1JicnNaNWkwSmNhc3RhUkw3U3A1ZnAvakQ1ZHhxYy9VZFRWbmx2UzE2YW4rMllmc3dlL1F1TG9sUlVDcmNPRTIrMmlBNSt0emQ2Tm1NR1F3RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUV3SFFZRFZSME9CQllFRk1qRkhRQkJtaVFwTWxFazZ3MnVTdTFLQnRQc01COEdBMVVkSXdRWU1CYUFGTWpGSFFCQm1pUXBNbEVrNncydVN1MUtCdFBzTUFvR0NDcUdTTTQ5QkFNREEyZ0FNR1VDTUg4bGlXSmZNdWk2dlhYQmhqRGdZNE13c2xtTi9USnhWZS84M1dyRm9td21OZjA1NnkxWDQ4RjljNG0zYTNvelhBSXhBS2pSYXk1L2FqL2pzS0tHSWttUWF0akk4dXVwSHIvK0N4RnZhSldtcFlxTmtMREdSVSs5b3J6aDVoSTJScmN1YVE9PSIKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0sCiAgICAgICJ2YWxpZEZvciI6IHsKICAgICAgICAic3RhcnQiOiAiMjAyMS0wMy0wN1QwMzoyMDoyOVoiLAogICAgICAgICJlbmQiOiAiMjAyMi0xMi0zMVQyMzo1OTo1OS45OTlaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAic3ViamVjdCI6IHsKICAgICAgICAib3JnYW5pemF0aW9uIjogInNpZ3N0b3JlLmRldiIsCiAgICAgICAgImNvbW1vbk5hbWUiOiAic2lnc3RvcmUiCiAgICAgIH0sCiAgICAgICJ1cmkiOiAiaHR0cHM6Ly9mdWxjaW8uc2lnc3RvcmUuZGV2IiwKICAgICAgImNlcnRDaGFpbiI6IHsKICAgICAgICAiY2VydGlmaWNhdGVzIjogWwogICAgICAgICAgewogICAgICAgICAgICAicmF3Qnl0ZXMiOiAiTUlJQ0dqQ0NBYUdnQXdJQkFnSVVBTG5WaVZmblUwYnJKYXNtUmtIcm4vVW5mYVF3Q2dZSUtvWkl6ajBFQXdNd0tqRVZNQk1HQTFVRUNoTU1jMmxuYzNSdmNtVXVaR1YyTVJFd0R3WURWUVFERXdoemFXZHpkRzl5WlRBZUZ3MHlNakEwTVRNeU1EQTJNVFZhRncwek1URXdNRFV4TXpVMk5UaGFNRGN4RlRBVEJnTlZCQW9UREhOcFozTjBiM0psTG1SbGRqRWVNQndHQTFVRUF4TVZjMmxuYzNSdmNtVXRhVzUwWlhKdFpXUnBZWFJsTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUU4UlZTL3lzSCtOT3Z1RFp5UEladGlsZ1VGOU5sYXJZcEFkOUhQMXZCQkgxVTVDVjc3TFNTN3MwWmlING5FN0h2N3B0UzZMdnZSL1NUazc5OExWZ016TGxKNEhlSWZGM3RIU2FleExjWXBTQVNyMWtTME4vUmdCSnovOWpXQ2lYbm8zc3dlVEFPQmdOVkhROEJBZjhFQkFNQ0FRWXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd013RWdZRFZSMFRBUUgvQkFnd0JnRUIvd0lCQURBZEJnTlZIUTRFRmdRVTM5UHB6MVlrRVpiNXFOanBLRldpeGk0WVpEOHdId1lEVlIwakJCZ3dGb0FVV01BZVg1RkZwV2FwZXN5UW9aTWkwQ3JGeGZvd0NnWUlLb1pJemowRUF3TURad0F3WkFJd1BDc1FLNERZaVpZRFBJYURpNUhGS25meFh4NkFTU1ZtRVJmc3luWUJpWDJYNlNKUm5aVTg0LzlEWmRuRnZ2eG1BakJPdDZRcEJsYzRKLzBEeHZrVENxcGNsdnppTDZCQ0NQbmpkbElCM1B1M0J4c1BteWdVWTdJaTJ6YmRDZGxpaW93PSIKICAgICAgICAgIH0sCiAgICAgICAgICB7CiAgICAgICAgICAgICJyYXdCeXRlcyI6ICJNSUlCOXpDQ0FYeWdBd0lCQWdJVUFMWk5BUEZkeEhQd2plRGxvRHd5WUNoQU8vNHdDZ1lJS29aSXpqMEVBd013S2pFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUkV3RHdZRFZRUURFd2h6YVdkemRHOXlaVEFlRncweU1URXdNRGN4TXpVMk5UbGFGdzB6TVRFd01EVXhNelUyTlRoYU1Db3hGVEFUQmdOVkJBb1RESE5wWjNOMGIzSmxMbVJsZGpFUk1BOEdBMVVFQXhNSWMybG5jM1J2Y21Vd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVQ3WGVGVDRyYjNQUUd3UzRJYWp0TGszL09sbnBnYW5nYUJjbFlwc1lCcjVpKzR5bkIwN2NlYjNMUDBPSU9aZHhleFg2OWM1aVZ1eUpSUStIejA1eWkrVUYzdUJXQWxIcGlTNXNoMCtIMkdIRTdTWHJrMUVDNW0xVHIxOUw5Z2c5MmpZekJoTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlJZd0I1ZmtVV2xacWw2ekpDaGt5TFFLc1hGK2pBZkJnTlZIU01FR0RBV2dCUll3QjVma1VXbFpxbDZ6SkNoa3lMUUtzWEYrakFLQmdncWhrak9QUVFEQXdOcEFEQm1BakVBajFuSGVYWnArMTNOV0JOYStFRHNEUDhHMVdXZzF0Q01XUC9XSFBxcGFWbzBqaHN3ZU5GWmdTczBlRTd3WUk0cUFqRUEyV0I5b3Q5OHNJa29GM3ZaWWRkMy9WdFdCNWI5VE5NZWE3SXgvc3RKNVRmY0xMZUFCTEU0Qk5KT3NRNHZuQkhKIgogICAgICAgICAgfQogICAgICAgIF0KICAgICAgfSwKICAgICAgInZhbGlkRm9yIjogewogICAgICAgICJzdGFydCI6ICIyMDIyLTA0LTEzVDIwOjA2OjE1WiIKICAgICAgfQogICAgfQogIF0sCiAgImN0bG9ncyI6IFsKICAgIHsKICAgICAgImJhc2VVcmwiOiAiaHR0cHM6Ly9jdGZlLnNpZ3N0b3JlLmRldi90ZXN0IiwKICAgICAgImhhc2hBbGdvcml0aG0iOiAiU0hBMl8yNTYiLAogICAgICAicHVibGljS2V5IjogewogICAgICAgICJyYXdCeXRlcyI6ICJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUViZndSK1JKdWRYc2NnUkJScEtYMVhGRHkzUHl1ZER4ei9TZm5SaTFmVDhla3BmQmQyTzF1b3o3anIzWjhuS3p4QTY5RVVRK2VGQ0ZJM3pldWJQV1U3dz09IiwKICAgICAgICAia2V5RGV0YWlscyI6ICJQS0lYX0VDRFNBX1AyNTZfU0hBXzI1NiIsCiAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgInN0YXJ0IjogIjIwMjEtMDMtMTRUMDA6MDA6MDBaIiwKICAgICAgICAgICJlbmQiOiAiMjAyMi0xMC0zMVQyMzo1OTo1OS45OTlaIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImxvZ0lkIjogewogICAgICAgICJrZXlJZCI6ICJDR0NTOENoUy8yaEYwZEZySjRTY1JXY1lyQlk5d3pqU2JlYThJZ1kyYjNJPSIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImJhc2VVcmwiOiAiaHR0cHM6Ly9jdGZlLnNpZ3N0b3JlLmRldi8yMDIyIiwKICAgICAgImhhc2hBbGdvcml0aG0iOiAiU0hBMl8yNTYiLAogICAgICAicHVibGljS2V5IjogewogICAgICAgICJyYXdCeXRlcyI6ICJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVpUFNsRmkwQ21GVGZFakNVcUY5SHVDRWNZWE5LQWFZYWxJSm1CWjh5eWV6UGpUcWh4cktCcE1uYW9jVnRMSkJJMWVNM3VYblF6UUdBSmRKNGdzOUZ5dz09IiwKICAgICAgICAia2V5RGV0YWlscyI6ICJQS0lYX0VDRFNBX1AyNTZfU0hBXzI1NiIsCiAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgInN0YXJ0IjogIjIwMjItMTAtMjBUMDA6MDA6MDBaIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImxvZ0lkIjogewogICAgICAgICJrZXlJZCI6ICIzVDB3YXNiSEVUSmpHUjRjbVdjM0FxSktYcmplUEszL2g0cHlnQzhwN280PSIKICAgICAgfQogICAgfQogIF0sCiAgInRpbWVzdGFtcEF1dGhvcml0aWVzIjogWwogICAgewogICAgICAic3ViamVjdCI6IHsKICAgICAgICAib3JnYW5pemF0aW9uIjogInNpZ3N0b3JlLmRldiIsCiAgICAgICAgImNvbW1vbk5hbWUiOiAic2lnc3RvcmUtdHNhLXNlbGZzaWduZWQiCiAgICAgIH0sCiAgICAgICJ1cmkiOiAiaHR0cHM6Ly90aW1lc3RhbXAuc2lnc3RvcmUuZGV2L2FwaS92MS90aW1lc3RhbXAiLAogICAgICAiY2VydENoYWluIjogewogICAgICAgICJjZXJ0aWZpY2F0ZXMiOiBbCiAgICAgICAgICB7CiAgICAgICAgICAgICJyYXdCeXRlcyI6ICJNSUlDRURDQ0FaYWdBd0lCQWdJVU9oTlVMd3lRWWU2OHdVTXZ5NHFPaXlvaml3d3dDZ1lJS29aSXpqMEVBd013T1RFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNU0F3SGdZRFZRUURFeGR6YVdkemRHOXlaUzEwYzJFdGMyVnNabk5wWjI1bFpEQWVGdzB5TlRBME1EZ3dOalU1TkROYUZ3MHpOVEEwTURZd05qVTVORE5hTUM0eEZUQVRCZ05WQkFvVERITnBaM04wYjNKbExtUmxkakVWTUJNR0ExVUVBeE1NYzJsbmMzUnZjbVV0ZEhOaE1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFNHJhMlo4aEtOaWcyVDlrRmpDQVRvR0czMGpreStXUXYzQnpMK21LdmgxU0tOUi9Vd3V3c2ZOQ2c0c3J5b1lBZDhFNmlzb3ZWQTNNNGFvTmRtOVFEaTUwWjhuVEV5dnFnZkRQdFRJd1hJdGZpVy9BRmYxVjd1d2tia0FvajB4eGNvMm93YURBT0JnTlZIUThCQWY4RUJBTUNCNEF3SFFZRFZSME9CQllFRkluOWVVT0h6OUJsUnNNQ1JzY3NjMXQ5dE9zRE1COEdBMVVkSXdRWU1CYUFGSmpzQWU5L3UxSC8xSlVlYjRxSW1GTUhpYzYvTUJZR0ExVWRKUUVCL3dRTU1Bb0dDQ3NHQVFVRkJ3TUlNQW9HQ0NxR1NNNDlCQU1EQTJnQU1HVUNNRHRwc1YvNkthTzBxeUYvVU1zWDJhU1VYS1FGZG9HVHB0UUdjMGZ0cTFjc3VsSFBHRzZkc215TU5kM0pCK0czRVFJeEFPYWp2QmNqcEptS2I0TnYrMlRhb2o4VWM1K2I2aWg2RlhDQ0tyYVNxdXBlMDd6cXN3TWNYSlRlMWNFeHZIdnZsdz09IgogICAgICAgICAgfSwKICAgICAgICAgIHsKICAgICAgICAgICAgInJhd0J5dGVzIjogIk1JSUI5ekNDQVh5Z0F3SUJBZ0lVVjdmMEdMRE9vRXpJaDhMWFNXODBPSmlVcDE0d0NnWUlLb1pJemowRUF3TXdPVEVWTUJNR0ExVUVDaE1NYzJsbmMzUnZjbVV1WkdWMk1TQXdIZ1lEVlFRREV4ZHphV2R6ZEc5eVpTMTBjMkV0YzJWc1puTnBaMjVsWkRBZUZ3MHlOVEEwTURnd05qVTVORE5hRncwek5UQTBNRFl3TmpVNU5ETmFNRGt4RlRBVEJnTlZCQW9UREhOcFozTjBiM0psTG1SbGRqRWdNQjRHQTFVRUF4TVhjMmxuYzNSdmNtVXRkSE5oTFhObGJHWnphV2R1WldRd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVFVUU50ZlJUL291M1lBVGE2d0Iva0tUZTcwY2ZKd3lSSUJvdk1udDhSY0pwaC9DT0U4MnV5UzZGbXBwTExMMVZCUEdjUGZwUVBZSk5Yeld3aThpY3doS1E2Vy9RZTJoM29lYkJiMkZIcHdOSkRxbytUTWFDL3RkZmt2L0VsSkI3MmpSVEJETUE0R0ExVWREd0VCL3dRRUF3SUJCakFTQmdOVkhSTUJBZjhFQ0RBR0FRSC9BZ0VBTUIwR0ExVWREZ1FXQkJTWTdBSHZmN3RSLzlTVkhtK0tpSmhUQjRuT3Z6QUtCZ2dxaGtqT1BRUURBd05wQURCbUFqRUF3R0VHcmZHWlIxY2VuMVI4L0RUVk1JOTQzTHNzWm1KUnREcC9pN1NmR0htR1JQNmdSYnVqOXZPSzNiNjdaMFFRQWpFQXVUMkg2NzNMUUVhSFRjeVFTWnJrcDRtWDdXd2ttRitzVmJrWVk1bVhOK1JNSDEzS1VFSEhPcUFTYWVtWVdLL0UiCiAgICAgICAgICB9CiAgICAgICAgXQogICAgICB9LAogICAgICAidmFsaWRGb3IiOiB7CiAgICAgICAgInN0YXJ0IjogIjIwMjUtMDctMDRUMDA6MDA6MDBaIgogICAgICB9CiAgICB9CiAgXQp9Cg==","registry.npmjs.org%2Fkeys.json":"ewogICAgImtleXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAia2V5SWQiOiAiU0hBMjU2OmpsM2J3c3d1ODBQampva0NnaDBvMnc1YzJVNExoUUFFNTdnajljejFrekEiLAogICAgICAgICAgICAia2V5VXNhZ2UiOiAibnBtOnNpZ25hdHVyZXMiLAogICAgICAgICAgICAicHVibGljS2V5IjogewogICAgICAgICAgICAgICAgInJhd0J5dGVzIjogIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRTFPbGIzek1BRkZ4WEtIaUlrUU81Y0ozWWhsNWk2VVBwK0lodXRlQkpidUhjQTVVb2dLbzBFV3RsV3dXNktTYUtvVE5FWUw3SmxDUWlWbmtoQmt0VWdnPT0iLAogICAgICAgICAgICAgICAgImtleURldGFpbHMiOiAiUEtJWF9FQ0RTQV9QMjU2X1NIQV8yNTYiLAogICAgICAgICAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgICAgICAgICAgICJzdGFydCI6ICIxOTk5LTAxLTAxVDAwOjAwOjAwLjAwMFoiLAogICAgICAgICAgICAgICAgICAgICJlbmQiOiAiMjAyNS0wMS0yOVQwMDowMDowMC4wMDBaIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgICJrZXlJZCI6ICJTSEEyNTY6amwzYndzd3U4MFBqam9rQ2doMG8ydzVjMlU0TGhRQUU1N2dqOWN6MWt6QSIsCiAgICAgICAgICAgICJrZXlVc2FnZSI6ICJucG06YXR0ZXN0YXRpb25zIiwKICAgICAgICAgICAgInB1YmxpY0tleSI6IHsKICAgICAgICAgICAgICAgICJyYXdCeXRlcyI6ICJNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUxT2xiM3pNQUZGeFhLSGlJa1FPNWNKM1lobDVpNlVQcCtJaHV0ZUJKYnVIY0E1VW9nS28wRVd0bFd3VzZLU2FLb1RORVlMN0psQ1FpVm5raEJrdFVnZz09IiwKICAgICAgICAgICAgICAgICJrZXlEZXRhaWxzIjogIlBLSVhfRUNEU0FfUDI1Nl9TSEFfMjU2IiwKICAgICAgICAgICAgICAgICJ2YWxpZEZvciI6IHsKICAgICAgICAgICAgICAgICAgICAic3RhcnQiOiAiMjAyMi0xMi0wMVQwMDowMDowMC4wMDBaIiwKICAgICAgICAgICAgICAgICAgICAiZW5kIjogIjIwMjUtMDEtMjlUMDA6MDA6MDAuMDAwWiIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICAia2V5SWQiOiAiU0hBMjU2OkRoUTh3UjVBUEJ2RkhMRi8rVGMrQVl2UE9kVHBjSURxT2h4c0JIUndDN1UiLAogICAgICAgICAgICAia2V5VXNhZ2UiOiAibnBtOnNpZ25hdHVyZXMiLAogICAgICAgICAgICAicHVibGljS2V5IjogewogICAgICAgICAgICAgICAgInJhd0J5dGVzIjogIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRVk2WWE3VysrN2FVUHp2TVRyZXpINlljeDNjK0hPS1lDY05HeWJKWlNDSnEvZmQ3UWE4dXVBS3RkSWtVUXRRaUVLRVJoQW1FNWxNTUpoUDhPa0RPYTJnPT0iLAogICAgICAgICAgICAgICAgImtleURldGFpbHMiOiAiUEtJWF9FQ0RTQV9QMjU2X1NIQV8yNTYiLAogICAgICAgICAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgICAgICAgICAgICJzdGFydCI6ICIyMDI1LTAxLTEzVDAwOjAwOjAwLjAwMFoiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgImtleUlkIjogIlNIQTI1NjpEaFE4d1I1QVBCdkZITEYvK1RjK0FZdlBPZFRwY0lEcU9oeHNCSFJ3QzdVIiwKICAgICAgICAgICAgImtleVVzYWdlIjogIm5wbTphdHRlc3RhdGlvbnMiLAogICAgICAgICAgICAicHVibGljS2V5IjogewogICAgICAgICAgICAgICAgInJhd0J5dGVzIjogIk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRVk2WWE3VysrN2FVUHp2TVRyZXpINlljeDNjK0hPS1lDY05HeWJKWlNDSnEvZmQ3UWE4dXVBS3RkSWtVUXRRaUVLRVJoQW1FNWxNTUpoUDhPa0RPYTJnPT0iLAogICAgICAgICAgICAgICAgImtleURldGFpbHMiOiAiUEtJWF9FQ0RTQV9QMjU2X1NIQV8yNTYiLAogICAgICAgICAgICAgICAgInZhbGlkRm9yIjogewogICAgICAgICAgICAgICAgICAgICJzdGFydCI6ICIyMDI1LTAxLTEzVDAwOjAwOjAwLjAwMFoiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICBdCn0K"}}} diff --git a/node_modules/@sigstore/verify/dist/bundle/dsse.js b/node_modules/@sigstore/verify/dist/bundle/dsse.js new file mode 100644 index 0000000000000..7ee255401b177 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/bundle/dsse.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSSESignatureContent = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +class DSSESignatureContent { + env; + constructor(env) { + this.env = env; + } + compareDigest(digest) { + return core_1.crypto.bufferEqual(digest, core_1.crypto.digest('sha256', this.env.payload)); + } + compareSignature(signature) { + return core_1.crypto.bufferEqual(signature, this.signature); + } + verifySignature(key) { + return core_1.crypto.verify(this.preAuthEncoding, key, this.signature); + } + get signature() { + return this.env.signatures.length > 0 + ? this.env.signatures[0].sig + : Buffer.from(''); + } + // DSSE Pre-Authentication Encoding + get preAuthEncoding() { + return core_1.dsse.preAuthEncoding(this.env.payloadType, this.env.payload); + } +} +exports.DSSESignatureContent = DSSESignatureContent; diff --git a/node_modules/@sigstore/verify/dist/bundle/index.js b/node_modules/@sigstore/verify/dist/bundle/index.js new file mode 100644 index 0000000000000..cba2a65704c95 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/bundle/index.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toSignedEntity = toSignedEntity; +exports.signatureContent = signatureContent; +const core_1 = require("@sigstore/core"); +const dsse_1 = require("./dsse"); +const message_1 = require("./message"); +function toSignedEntity(bundle, artifact) { + const { tlogEntries, timestampVerificationData } = bundle.verificationMaterial; + const timestamps = []; + for (const entry of tlogEntries) { + if (entry.integratedTime && entry.integratedTime !== '0') { + timestamps.push({ + $case: 'transparency-log', + tlogEntry: entry, + }); + } + } + for (const ts of timestampVerificationData?.rfc3161Timestamps ?? []) { + timestamps.push({ + $case: 'timestamp-authority', + timestamp: core_1.RFC3161Timestamp.parse(Buffer.from(ts.signedTimestamp)), + }); + } + return { + signature: signatureContent(bundle, artifact), + key: key(bundle), + tlogEntries, + timestamps, + }; +} +function signatureContent(bundle, artifact) { + switch (bundle.content.$case) { + case 'dsseEnvelope': + return new dsse_1.DSSESignatureContent(bundle.content.dsseEnvelope); + case 'messageSignature': + return new message_1.MessageSignatureContent(bundle.content.messageSignature, artifact); + } +} +function key(bundle) { + switch (bundle.verificationMaterial.content.$case) { + case 'publicKey': + return { + $case: 'public-key', + hint: bundle.verificationMaterial.content.publicKey.hint, + }; + case 'x509CertificateChain': + return { + $case: 'certificate', + certificate: core_1.X509Certificate.parse(Buffer.from(bundle.verificationMaterial.content.x509CertificateChain + .certificates[0].rawBytes)), + }; + case 'certificate': + return { + $case: 'certificate', + certificate: core_1.X509Certificate.parse(Buffer.from(bundle.verificationMaterial.content.certificate.rawBytes)), + }; + } +} diff --git a/node_modules/@sigstore/verify/dist/bundle/message.js b/node_modules/@sigstore/verify/dist/bundle/message.js new file mode 100644 index 0000000000000..13cb5c27a02ac --- /dev/null +++ b/node_modules/@sigstore/verify/dist/bundle/message.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MessageSignatureContent = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +// Map from the Sigstore protobuf HashAlgorithm enum to +// the string values used by the Node.js crypto module. +const HASH_ALGORITHM_MAP = { + [protobuf_specs_1.HashAlgorithm.HASH_ALGORITHM_UNSPECIFIED]: 'sha256', + [protobuf_specs_1.HashAlgorithm.SHA2_256]: 'sha256', + [protobuf_specs_1.HashAlgorithm.SHA2_384]: 'sha384', + [protobuf_specs_1.HashAlgorithm.SHA2_512]: 'sha512', + [protobuf_specs_1.HashAlgorithm.SHA3_256]: 'sha3-256', + [protobuf_specs_1.HashAlgorithm.SHA3_384]: 'sha3-384', +}; +class MessageSignatureContent { + signature; + messageDigest; + artifact; + hashAlgorithm; + constructor(messageSignature, artifact) { + this.signature = messageSignature.signature; + this.messageDigest = messageSignature.messageDigest.digest; + this.artifact = artifact; + this.hashAlgorithm = + HASH_ALGORITHM_MAP[messageSignature.messageDigest.algorithm] ?? + /* istanbul ignore next */ 'sha256'; + } + compareSignature(signature) { + return core_1.crypto.bufferEqual(signature, this.signature); + } + compareDigest(digest) { + return core_1.crypto.bufferEqual(digest, this.messageDigest); + } + verifySignature(key) { + return core_1.crypto.verify(this.artifact, key, this.signature, this.hashAlgorithm); + } +} +exports.MessageSignatureContent = MessageSignatureContent; diff --git a/node_modules/@sigstore/verify/dist/error.js b/node_modules/@sigstore/verify/dist/error.js new file mode 100644 index 0000000000000..e6d72c2335618 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/error.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PolicyError = exports.VerificationError = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +class BaseError extends Error { + code; + cause; /* eslint-disable-line @typescript-eslint/no-explicit-any */ + constructor({ code, message, cause, }) { + super(message); + this.code = code; + this.cause = cause; + this.name = this.constructor.name; + } +} +class VerificationError extends BaseError { +} +exports.VerificationError = VerificationError; +class PolicyError extends BaseError { +} +exports.PolicyError = PolicyError; diff --git a/node_modules/@sigstore/verify/dist/index.js b/node_modules/@sigstore/verify/dist/index.js new file mode 100644 index 0000000000000..3222876fcd68b --- /dev/null +++ b/node_modules/@sigstore/verify/dist/index.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Verifier = exports.toTrustMaterial = exports.VerificationError = exports.PolicyError = exports.toSignedEntity = void 0; +/* istanbul ignore file */ +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var bundle_1 = require("./bundle"); +Object.defineProperty(exports, "toSignedEntity", { enumerable: true, get: function () { return bundle_1.toSignedEntity; } }); +var error_1 = require("./error"); +Object.defineProperty(exports, "PolicyError", { enumerable: true, get: function () { return error_1.PolicyError; } }); +Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return error_1.VerificationError; } }); +var trust_1 = require("./trust"); +Object.defineProperty(exports, "toTrustMaterial", { enumerable: true, get: function () { return trust_1.toTrustMaterial; } }); +var verifier_1 = require("./verifier"); +Object.defineProperty(exports, "Verifier", { enumerable: true, get: function () { return verifier_1.Verifier; } }); diff --git a/node_modules/@sigstore/verify/dist/key/certificate.js b/node_modules/@sigstore/verify/dist/key/certificate.js new file mode 100644 index 0000000000000..a5611c6824bda --- /dev/null +++ b/node_modules/@sigstore/verify/dist/key/certificate.js @@ -0,0 +1,216 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CertificateChainVerifier = void 0; +exports.verifyCertificateChain = verifyCertificateChain; +const error_1 = require("../error"); +const trust_1 = require("../trust"); +function verifyCertificateChain(timestamp, leaf, certificateAuthorities) { + // Filter list of trusted CAs to those which are valid for the given + // timestamp + const cas = (0, trust_1.filterCertAuthorities)(certificateAuthorities, timestamp); + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + let error; + for (const ca of cas) { + try { + const verifier = new CertificateChainVerifier({ + trustedCerts: ca.certChain, + untrustedCert: leaf, + timestamp, + }); + return verifier.verify(); + } + catch (err) { + error = err; + } + } + // If we failed to verify the certificate chain for all of the trusted + // CAs, throw the last error we encountered. + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'Failed to verify certificate chain', + cause: error, + }); +} +class CertificateChainVerifier { + untrustedCert; + trustedCerts; + localCerts; + timestamp; + constructor(opts) { + this.untrustedCert = opts.untrustedCert; + this.trustedCerts = opts.trustedCerts; + this.localCerts = dedupeCertificates([ + ...opts.trustedCerts, + opts.untrustedCert, + ]); + this.timestamp = opts.timestamp; + } + verify() { + // Construct certificate path from leaf to root + const certificatePath = this.sort(); + // Perform validation checks on each certificate in the path + this.checkPath(certificatePath); + const validForDate = certificatePath.every((cert) => cert.validForDate(this.timestamp)); + if (!validForDate) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'certificate is not valid or expired at the specified date', + }); + } + // Return verified certificate path + return certificatePath; + } + sort() { + const leafCert = this.untrustedCert; + // Construct all possible paths from the leaf + let paths = this.buildPaths(leafCert); + // Filter for paths which contain a trusted certificate + paths = paths.filter((path) => path.some((cert) => this.trustedCerts.includes(cert))); + if (paths.length === 0) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'no trusted certificate path found', + }); + } + // Find the shortest of possible paths + /* istanbul ignore next */ + const path = paths.reduce((prev, curr) => prev.length < curr.length ? prev : curr); + // Construct chain from shortest path + // Removes the last certificate in the path, which will be a second copy + // of the root certificate given that the root is self-signed. + return [leafCert, ...path].slice(0, -1); + } + // Recursively build all possible paths from the leaf to the root + buildPaths(certificate) { + const paths = []; + const issuers = this.findIssuer(certificate); + if (issuers.length === 0) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'no valid certificate path found', + }); + } + for (let i = 0; i < issuers.length; i++) { + const issuer = issuers[i]; + // Base case - issuer is self + if (issuer.equals(certificate)) { + paths.push([certificate]); + continue; + } + // Recursively build path for the issuer + const subPaths = this.buildPaths(issuer); + // Construct paths by appending the issuer to each subpath + for (let j = 0; j < subPaths.length; j++) { + paths.push([issuer, ...subPaths[j]]); + } + } + return paths; + } + // Return all possible issuers for the given certificate + findIssuer(certificate) { + let issuers = []; + let keyIdentifier; + // Exit early if the certificate is self-signed + if (certificate.subject.equals(certificate.issuer)) { + if (certificate.verify()) { + return [certificate]; + } + } + // If the certificate has an authority key identifier, use that + // to find the issuer + if (certificate.extAuthorityKeyID) { + keyIdentifier = certificate.extAuthorityKeyID.keyIdentifier; + // TODO: Add support for authorityCertIssuer/authorityCertSerialNumber + // though Fulcio doesn't appear to use these + } + // Find possible issuers by comparing the authorityKeyID/subjectKeyID + // or issuer/subject. Potential issuers are added to the result array. + this.localCerts.forEach((possibleIssuer) => { + if (keyIdentifier) { + /* istanbul ignore else */ + if (possibleIssuer.extSubjectKeyID) { + if (possibleIssuer.extSubjectKeyID.keyIdentifier.equals(keyIdentifier)) { + issuers.push(possibleIssuer); + } + return; + } + } + // Fallback to comparing certificate issuer and subject if + // subjectKey/authorityKey extensions are not present + if (possibleIssuer.subject.equals(certificate.issuer)) { + issuers.push(possibleIssuer); + } + }); + // Remove any issuers which fail to verify the certificate + issuers = issuers.filter((issuer) => { + try { + return certificate.verify(issuer); + } + catch (ex) { + /* istanbul ignore next - should never error */ + return false; + } + }); + return issuers; + } + checkPath(path) { + /* istanbul ignore if */ + if (path.length < 1) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'certificate chain must contain at least one certificate', + }); + } + // Ensure that all certificates beyond the leaf are CAs + const validCAs = path.slice(1).every((cert) => cert.isCA); + if (!validCAs) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'intermediate certificate is not a CA', + }); + } + // Certificate's issuer must match the subject of the next certificate + // in the chain + for (let i = path.length - 2; i >= 0; i--) { + /* istanbul ignore if */ + if (!path[i].issuer.equals(path[i + 1].subject)) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'incorrect certificate name chaining', + }); + } + } + // Check pathlength constraints + for (let i = 0; i < path.length; i++) { + const cert = path[i]; + // If the certificate is a CA, check the path length + if (cert.extBasicConstraints?.isCA) { + const pathLength = cert.extBasicConstraints.pathLenConstraint; + // The path length, if set, indicates how many intermediate + // certificates (NOT including the leaf) are allowed to follow. The + // pathLength constraint of any intermediate CA certificate MUST be + // greater than or equal to it's own depth in the chain (with an + // adjustment for the leaf certificate) + if (pathLength !== undefined && pathLength < i - 1) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'path length constraint exceeded', + }); + } + } + } + } +} +exports.CertificateChainVerifier = CertificateChainVerifier; +// Remove duplicate certificates from the array +function dedupeCertificates(certs) { + for (let i = 0; i < certs.length; i++) { + for (let j = i + 1; j < certs.length; j++) { + if (certs[i].equals(certs[j])) { + certs.splice(j, 1); + j--; + } + } + } + return certs; +} diff --git a/node_modules/@sigstore/verify/dist/key/index.js b/node_modules/@sigstore/verify/dist/key/index.js new file mode 100644 index 0000000000000..c966ccb1e925e --- /dev/null +++ b/node_modules/@sigstore/verify/dist/key/index.js @@ -0,0 +1,67 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyPublicKey = verifyPublicKey; +exports.verifyCertificate = verifyCertificate; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const error_1 = require("../error"); +const certificate_1 = require("./certificate"); +const sct_1 = require("./sct"); +const OID_FULCIO_ISSUER_V1 = '1.3.6.1.4.1.57264.1.1'; +const OID_FULCIO_ISSUER_V2 = '1.3.6.1.4.1.57264.1.8'; +function verifyPublicKey(hint, timestamps, trustMaterial) { + const key = trustMaterial.publicKey(hint); + timestamps.forEach((timestamp) => { + if (!key.validFor(timestamp)) { + throw new error_1.VerificationError({ + code: 'PUBLIC_KEY_ERROR', + message: `Public key is not valid for timestamp: ${timestamp.toISOString()}`, + }); + } + }); + return { key: key.publicKey }; +} +function verifyCertificate(leaf, timestamps, trustMaterial) { + // Check that leaf certificate chains to a trusted CA + let path = []; + timestamps.forEach((timestamp) => { + path = (0, certificate_1.verifyCertificateChain)(timestamp, leaf, trustMaterial.certificateAuthorities); + }); + return { + scts: (0, sct_1.verifySCTs)(path[0], path[1], trustMaterial.ctlogs), + signer: getSigner(path[0]), + }; +} +function getSigner(cert) { + let issuer; + const issuerExtension = cert.extension(OID_FULCIO_ISSUER_V2); + /* istanbul ignore next */ + if (issuerExtension) { + issuer = issuerExtension.valueObj.subs?.[0]?.value.toString('ascii'); + } + else { + issuer = cert.extension(OID_FULCIO_ISSUER_V1)?.value.toString('ascii'); + } + const identity = { + extensions: { issuer }, + subjectAlternativeName: cert.subjectAltName, + }; + return { + key: core_1.crypto.createPublicKey(cert.publicKey), + identity, + }; +} diff --git a/node_modules/@sigstore/verify/dist/key/sct.js b/node_modules/@sigstore/verify/dist/key/sct.js new file mode 100644 index 0000000000000..8eca48738096e --- /dev/null +++ b/node_modules/@sigstore/verify/dist/key/sct.js @@ -0,0 +1,78 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifySCTs = verifySCTs; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const error_1 = require("../error"); +const trust_1 = require("../trust"); +function verifySCTs(cert, issuer, ctlogs) { + let extSCT; + // Verifying the SCT requires that we remove the SCT extension and + // re-encode the TBS structure to DER -- this value is part of the data + // over which the signature is calculated. Since this is a destructive action + // we create a copy of the certificate so we can remove the SCT extension + // without affecting the original certificate. + const clone = cert.clone(); + // Intentionally not using the findExtension method here because we want to + // remove the the SCT extension from the certificate before calculating the + // PreCert structure + for (let i = 0; i < clone.extensions.length; i++) { + const ext = clone.extensions[i]; + if (ext.subs[0].toOID() === core_1.EXTENSION_OID_SCT) { + extSCT = new core_1.X509SCTExtension(ext); + // Remove the extension from the certificate + clone.extensions.splice(i, 1); + break; + } + } + // No SCT extension found to verify + if (!extSCT) { + return []; + } + // Found an SCT extension but it has no SCTs + /* istanbul ignore if -- too difficult to fabricate test case for this */ + if (extSCT.signedCertificateTimestamps.length === 0) { + return []; + } + // Construct the PreCert structure + // https://www.rfc-editor.org/rfc/rfc6962#section-3.2 + const preCert = new core_1.ByteStream(); + // Calculate hash of the issuer's public key + const issuerId = core_1.crypto.digest('sha256', issuer.publicKey); + preCert.appendView(issuerId); + // Re-encodes the certificate to DER after removing the SCT extension + const tbs = clone.tbsCertificate.toDER(); + preCert.appendUint24(tbs.length); + preCert.appendView(tbs); + // Calculate and return the verification results for each SCT + return extSCT.signedCertificateTimestamps.map((sct) => { + // Find the ctlog instance that corresponds to the SCT's logID + const validCTLogs = (0, trust_1.filterTLogAuthorities)(ctlogs, { + logID: sct.logID, + targetDate: sct.datetime, + }); + // See if the SCT is valid for any of the CT logs + const verified = validCTLogs.some((log) => sct.verify(preCert.buffer, log.publicKey)); + if (!verified) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'SCT verification failed', + }); + } + return sct.logID; + }); +} diff --git a/node_modules/@sigstore/verify/dist/policy.js b/node_modules/@sigstore/verify/dist/policy.js new file mode 100644 index 0000000000000..f5960cf047b84 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/policy.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifySubjectAlternativeName = verifySubjectAlternativeName; +exports.verifyExtensions = verifyExtensions; +const error_1 = require("./error"); +function verifySubjectAlternativeName(policyIdentity, signerIdentity) { + if (signerIdentity === undefined || !signerIdentity.match(policyIdentity)) { + throw new error_1.PolicyError({ + code: 'UNTRUSTED_SIGNER_ERROR', + message: `certificate identity error - expected ${policyIdentity}, got ${signerIdentity}`, + }); + } +} +function verifyExtensions(policyExtensions, signerExtensions = {}) { + let key; + for (key in policyExtensions) { + if (signerExtensions[key] !== policyExtensions[key]) { + throw new error_1.PolicyError({ + code: 'UNTRUSTED_SIGNER_ERROR', + message: `invalid certificate extension - expected ${key}=${policyExtensions[key]}, got ${key}=${signerExtensions[key]}`, + }); + } + } +} diff --git a/node_modules/@sigstore/verify/dist/shared.types.js b/node_modules/@sigstore/verify/dist/shared.types.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/shared.types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/verify/dist/timestamp/index.js b/node_modules/@sigstore/verify/dist/timestamp/index.js new file mode 100644 index 0000000000000..03a51083e1082 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/timestamp/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getTSATimestamp = getTSATimestamp; +exports.getTLogTimestamp = getTLogTimestamp; +const tsa_1 = require("./tsa"); +function getTSATimestamp(timestamp, data, timestampAuthorities) { + (0, tsa_1.verifyRFC3161Timestamp)(timestamp, data, timestampAuthorities); + return { + type: 'timestamp-authority', + logID: timestamp.signerSerialNumber, + timestamp: timestamp.signingTime, + }; +} +function getTLogTimestamp(entry) { + return { + type: 'transparency-log', + logID: entry.logId.keyId, + timestamp: new Date(Number(entry.integratedTime) * 1000), + }; +} diff --git a/node_modules/@sigstore/verify/dist/timestamp/tsa.js b/node_modules/@sigstore/verify/dist/timestamp/tsa.js new file mode 100644 index 0000000000000..0da4a3de8247f --- /dev/null +++ b/node_modules/@sigstore/verify/dist/timestamp/tsa.js @@ -0,0 +1,63 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyRFC3161Timestamp = verifyRFC3161Timestamp; +const core_1 = require("@sigstore/core"); +const error_1 = require("../error"); +const certificate_1 = require("../key/certificate"); +const trust_1 = require("../trust"); +function verifyRFC3161Timestamp(timestamp, data, timestampAuthorities) { + const signingTime = timestamp.signingTime; + // Filter for CAs which were valid at the time of signing + timestampAuthorities = (0, trust_1.filterCertAuthorities)(timestampAuthorities, signingTime); + // Filter for CAs which match serial and issuer embedded in the timestamp + timestampAuthorities = filterCAsBySerialAndIssuer(timestampAuthorities, { + serialNumber: timestamp.signerSerialNumber, + issuer: timestamp.signerIssuer, + }); + // Check that we can verify the timestamp with AT LEAST ONE of the remaining + // CAs + const verified = timestampAuthorities.some((ca) => { + try { + verifyTimestampForCA(timestamp, data, ca); + return true; + } + catch (e) { + return false; + } + }); + if (!verified) { + throw new error_1.VerificationError({ + code: 'TIMESTAMP_ERROR', + message: 'timestamp could not be verified', + }); + } +} +function verifyTimestampForCA(timestamp, data, ca) { + const [leaf, ...cas] = ca.certChain; + const signingKey = core_1.crypto.createPublicKey(leaf.publicKey); + const signingTime = timestamp.signingTime; + // Verify the certificate chain for the provided CA + try { + new certificate_1.CertificateChainVerifier({ + untrustedCert: leaf, + trustedCerts: cas, + timestamp: signingTime, + }).verify(); + } + catch (e) { + throw new error_1.VerificationError({ + code: 'TIMESTAMP_ERROR', + message: 'invalid certificate chain', + }); + } + // Check that the signing certificate's key can be used to verify the + // timestamp signature. + timestamp.verify(data, signingKey); +} +// Filters the list of CAs to those which have a leaf signing certificate which +// matches the given serial number and issuer. +function filterCAsBySerialAndIssuer(timestampAuthorities, criteria) { + return timestampAuthorities.filter((ca) => ca.certChain.length > 0 && + core_1.crypto.bufferEqual(ca.certChain[0].serialNumber, criteria.serialNumber) && + core_1.crypto.bufferEqual(ca.certChain[0].issuer, criteria.issuer)); +} diff --git a/node_modules/@sigstore/verify/dist/tlog/checkpoint.js b/node_modules/@sigstore/verify/dist/tlog/checkpoint.js new file mode 100644 index 0000000000000..220c5639b4c38 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/checkpoint.js @@ -0,0 +1,154 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LogCheckpoint = void 0; +exports.verifyCheckpoint = verifyCheckpoint; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const error_1 = require("../error"); +// Separator between the note and the signatures in a checkpoint +const CHECKPOINT_SEPARATOR = '\n\n'; +// Checkpoint signatures are of the following form: +// "– <identity> <key_hint+signature_bytes>\n" +// where: +// - the prefix is an emdash (U+2014). +// - <identity> gives a human-readable representation of the signing ID. +// - <key_hint+signature_bytes> is the first 4 bytes of the SHA256 hash of the +// associated public key followed by the signature bytes. +const SIGNATURE_REGEX = /\u2014 (\S+) (\S+)\n/g; +// Verifies the checkpoint value in the given tlog entry. There are two steps +// to the verification: +// 1. Verify that all signatures in the checkpoint can be verified against a +// trusted public key +// 2. Verify that the root hash in the checkpoint matches the root hash in the +// inclusion proof +// See: https://github.com/transparency-dev/formats/blob/main/log/README.md +function verifyCheckpoint(entry, tlogs) { + const inclusionProof = entry.inclusionProof; + const signedNote = SignedNote.fromString(inclusionProof.checkpoint.envelope); + const checkpoint = LogCheckpoint.fromString(signedNote.note); + // Verify that the signatures in the checkpoint are all valid + if (!verifySignedNote(signedNote, tlogs)) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'invalid checkpoint signature', + }); + } + return checkpoint; +} +// Verifies the signatures in the SignedNote. For each signature, the +// corresponding transparency log is looked up by the key hint and the +// signature is verified against the public key in the transparency log. +// Throws an error if any of the signatures are invalid. +function verifySignedNote(signedNote, tlogs) { + const data = Buffer.from(signedNote.note, 'utf-8'); + return signedNote.signatures.some((signature) => { + // Find the transparency log instance with the matching key hint + const tlog = tlogs.find((tlog) => core_1.crypto.bufferEqual(tlog.logID.subarray(0, 4), signature.keyHint) && + tlog.baseURL.match(signature.name) // Match the name to the base URL of the tlog + ); + if (!tlog) { + return false; + } + return core_1.crypto.verify(data, tlog.publicKey, signature.signature); + }); +} +// SignedNote represents a signed note from a transparency log checkpoint. Consists +// of a body (or note) and one more signatures calculated over the body. See +// https://github.com/transparency-dev/formats/blob/main/log/README.md#signed-envelope +class SignedNote { + note; + signatures; + constructor(note, signatures) { + this.note = note; + this.signatures = signatures; + } + // Deserialize a SignedNote from a string + static fromString(envelope) { + if (!envelope.includes(CHECKPOINT_SEPARATOR)) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'missing checkpoint separator', + }); + } + // Split the note into the header and the data portions at the separator + const split = envelope.indexOf(CHECKPOINT_SEPARATOR); + const header = envelope.slice(0, split + 1); + const data = envelope.slice(split + CHECKPOINT_SEPARATOR.length); + // Find all the signature lines in the data portion + const matches = data.matchAll(SIGNATURE_REGEX); + // Parse each of the matched signature lines into the name and signature. + // The first four bytes of the signature are the key hint (should match the + // first four bytes of the log ID), and the rest is the signature itself. + const signatures = Array.from(matches, (match) => { + const [, name, signature] = match; + const sigBytes = Buffer.from(signature, 'base64'); + if (sigBytes.length < 5) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'malformed checkpoint signature', + }); + } + return { + name, + keyHint: sigBytes.subarray(0, 4), + signature: sigBytes.subarray(4), + }; + }); + if (signatures.length === 0) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'no signatures found in checkpoint', + }); + } + return new SignedNote(header, signatures); + } +} +// LogCheckpoint represents a transparency log checkpoint. Consists of the +// following: +// - origin: the name of the transparency log +// - logSize: the size of the log at the time of the checkpoint +// - logHash: the root hash of the log at the time of the checkpoint +// - rest: the rest of the checkpoint body, which is a list of log entries +// See: +// https://github.com/transparency-dev/formats/blob/main/log/README.md#checkpoint-body +class LogCheckpoint { + origin; + logSize; + logHash; + rest; + constructor(origin, logSize, logHash, rest) { + this.origin = origin; + this.logSize = logSize; + this.logHash = logHash; + this.rest = rest; + } + static fromString(note) { + const lines = note.trimEnd().split('\n'); + if (lines.length < 3) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'too few lines in checkpoint header', + }); + } + const origin = lines[0]; + const logSize = BigInt(lines[1]); + const rootHash = Buffer.from(lines[2], 'base64'); + const rest = lines.slice(3); + return new LogCheckpoint(origin, logSize, rootHash, rest); + } +} +exports.LogCheckpoint = LogCheckpoint; diff --git a/node_modules/@sigstore/verify/dist/tlog/dsse.js b/node_modules/@sigstore/verify/dist/tlog/dsse.js new file mode 100644 index 0000000000000..e438459dac80d --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/dsse.js @@ -0,0 +1,106 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DSSE_API_VERSION_V1 = void 0; +exports.verifyDSSETLogBody = verifyDSSETLogBody; +exports.verifyDSSETLogBodyV2 = verifyDSSETLogBodyV2; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../error"); +exports.DSSE_API_VERSION_V1 = '0.0.1'; +// Compare the given dsse tlog entry to the given bundle +function verifyDSSETLogBody(tlogEntry, content) { + switch (tlogEntry.apiVersion) { + case exports.DSSE_API_VERSION_V1: + return verifyDSSE001TLogBody(tlogEntry, content); + default: + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `unsupported dsse version: ${tlogEntry.apiVersion}`, + }); + } +} +// Compare the given dsse tlog entry to the given bundle. This function is +// specifically for Rekor V2 entries. +function verifyDSSETLogBodyV2(tlogEntry, content) { + const spec = tlogEntry.spec?.spec; + if (!spec) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `missing dsse spec`, + }); + } + switch (spec.$case) { + case 'dsseV002': + return verifyDSSE002TLogBody(spec.dsseV002, content); + default: + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `unsupported version: ${spec.$case}`, + }); + } +} +// Compare the given dsse v0.0.1 tlog entry to the given DSSE envelope. +function verifyDSSE001TLogBody(tlogEntry, content) { + // Ensure the bundle's DSSE only contains a single signature + if (tlogEntry.spec.signatures?.length !== 1) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'signature count mismatch', + }); + } + const tlogSig = tlogEntry.spec.signatures[0].signature; + // Ensure that the signature in the bundle's DSSE matches tlog entry + if (!content.compareSignature(Buffer.from(tlogSig, 'base64'))) + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'tlog entry signature mismatch', + }); + // Ensure the digest of the bundle's DSSE payload matches the digest in the + // tlog entry + const tlogHash = tlogEntry.spec.payloadHash?.value || ''; + if (!content.compareDigest(Buffer.from(tlogHash, 'hex'))) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'DSSE payload hash mismatch', + }); + } +} +// Compare the given dsse v0.0.2 tlog entry to the given DSSE envelope. +function verifyDSSE002TLogBody(spec, content) { + // Ensure the bundle's DSSE only contains a single signature + if (spec.signatures?.length !== 1) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'signature count mismatch', + }); + } + const tlogSig = spec.signatures[0].content; + // Ensure that the signature in the bundle's DSSE matches tlog entry + if (!content.compareSignature(tlogSig)) + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'tlog entry signature mismatch', + }); + // Ensure the digest of the bundle's DSSE payload matches the digest in the + // tlog entry + const tlogHash = spec.payloadHash?.digest || Buffer.from(''); + if (!content.compareDigest(tlogHash)) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'DSSE payload hash mismatch', + }); + } +} diff --git a/node_modules/@sigstore/verify/dist/tlog/hashedrekord.js b/node_modules/@sigstore/verify/dist/tlog/hashedrekord.js new file mode 100644 index 0000000000000..97dfcc9edc305 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/hashedrekord.js @@ -0,0 +1,94 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HASHEDREKORD_API_VERSION_V1 = void 0; +exports.verifyHashedRekordTLogBody = verifyHashedRekordTLogBody; +exports.verifyHashedRekordTLogBodyV2 = verifyHashedRekordTLogBodyV2; +/* +Copyright 2025 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../error"); +exports.HASHEDREKORD_API_VERSION_V1 = '0.0.1'; +// Compare the given hashedrekord tlog entry to the given bundle +function verifyHashedRekordTLogBody(tlogEntry, content) { + switch (tlogEntry.apiVersion) { + case exports.HASHEDREKORD_API_VERSION_V1: + return verifyHashedrekord001TLogBody(tlogEntry, content); + default: + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `unsupported hashedrekord version: ${tlogEntry.apiVersion}`, + }); + } +} +// Compare the given hashedrekor tlog entry to the given bundle. This function is +// specifically for Rekor V2 entries. +function verifyHashedRekordTLogBodyV2(tlogEntry, content) { + const spec = tlogEntry.spec?.spec; + if (!spec) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `missing dsse spec`, + }); + } + switch (spec.$case) { + case 'hashedRekordV002': + return verifyHashedrekord002TLogBody(spec.hashedRekordV002, content); + default: + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `unsupported version: ${spec.$case}`, + }); + } +} +// Compare the given hashedrekord v0.0.1 tlog entry to the given message +// signature +function verifyHashedrekord001TLogBody(tlogEntry, content) { + // Ensure that the bundles message signature matches the tlog entry + const tlogSig = tlogEntry.spec.signature.content || ''; + if (!content.compareSignature(Buffer.from(tlogSig, 'base64'))) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'signature mismatch', + }); + } + // Ensure that the bundle's message digest matches the tlog entry + const tlogDigest = tlogEntry.spec.data.hash?.value || ''; + if (!content.compareDigest(Buffer.from(tlogDigest, 'hex'))) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'digest mismatch', + }); + } +} +// Compare the given hashedrekord v0.0.2 tlog entry to the given message +// signature +function verifyHashedrekord002TLogBody(spec, content) { + // Ensure that the bundles message signature matches the tlog entry + const tlogSig = spec.signature?.content || Buffer.from(''); + if (!content.compareSignature(tlogSig)) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'signature mismatch', + }); + } + // Ensure that the bundle's message digest matches the tlog entry + const tlogHash = spec.data?.digest || Buffer.from(''); + if (!content.compareDigest(tlogHash)) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'digest mismatch', + }); + } +} diff --git a/node_modules/@sigstore/verify/dist/tlog/index.js b/node_modules/@sigstore/verify/dist/tlog/index.js new file mode 100644 index 0000000000000..6c244fa37e908 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/index.js @@ -0,0 +1,92 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyTLogBody = verifyTLogBody; +exports.verifyTLogInclusion = verifyTLogInclusion; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const v2_1 = require("@sigstore/protobuf-specs/rekor/v2"); +const error_1 = require("../error"); +const dsse_1 = require("./dsse"); +const hashedrekord_1 = require("./hashedrekord"); +const intoto_1 = require("./intoto"); +const checkpoint_1 = require("./checkpoint"); +const merkle_1 = require("./merkle"); +const set_1 = require("./set"); +// Verifies that the given tlog entry matches the supplied signature content. +function verifyTLogBody(entry, sigContent) { + const { kind, version } = entry.kindVersion; + const body = JSON.parse(entry.canonicalizedBody.toString('utf8')); + // validate body + if (kind !== body.kind || version !== body.apiVersion) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `kind/version mismatch - expected: ${kind}/${version}, received: ${body.kind}/${body.apiVersion}`, + }); + } + switch (kind) { + case 'dsse': + // Rekor V1 and V2 use incompatible types so we need to branch here based on version + if (version == dsse_1.DSSE_API_VERSION_V1) { + return (0, dsse_1.verifyDSSETLogBody)(body, sigContent); + } + else { + const entryRekorV2 = v2_1.Entry.fromJSON(body); + return (0, dsse_1.verifyDSSETLogBodyV2)(entryRekorV2, sigContent); + } + case 'intoto': + return (0, intoto_1.verifyIntotoTLogBody)(body, sigContent); + case 'hashedrekord': + // Rekor V1 and V2 use incompatible types so we need to branch here based on version + if (version == hashedrekord_1.HASHEDREKORD_API_VERSION_V1) { + return (0, hashedrekord_1.verifyHashedRekordTLogBody)(body, sigContent); + } + else { + const entryRekorV2 = v2_1.Entry.fromJSON(body); + return (0, hashedrekord_1.verifyHashedRekordTLogBodyV2)(entryRekorV2, sigContent); + } + /* istanbul ignore next */ + default: + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `unsupported kind: ${kind}`, + }); + } +} +function verifyTLogInclusion(entry, tlogAuthorities) { + let inclusionVerified = false; + if (isTLogEntryWithInclusionPromise(entry)) { + (0, set_1.verifyTLogSET)(entry, tlogAuthorities); + inclusionVerified = true; + } + if (isTLogEntryWithInclusionProof(entry)) { + const checkpoint = (0, checkpoint_1.verifyCheckpoint)(entry, tlogAuthorities); + (0, merkle_1.verifyMerkleInclusion)(entry, checkpoint); + inclusionVerified = true; + } + if (!inclusionVerified) { + throw new error_1.VerificationError({ + code: 'TLOG_MISSING_INCLUSION_ERROR', + message: 'inclusion could not be verified', + }); + } + return; +} +function isTLogEntryWithInclusionPromise(entry) { + return entry.inclusionPromise !== undefined; +} +function isTLogEntryWithInclusionProof(entry) { + return entry.inclusionProof !== undefined; +} diff --git a/node_modules/@sigstore/verify/dist/tlog/intoto.js b/node_modules/@sigstore/verify/dist/tlog/intoto.js new file mode 100644 index 0000000000000..9096ae9418cc3 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/intoto.js @@ -0,0 +1,62 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyIntotoTLogBody = verifyIntotoTLogBody; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const error_1 = require("../error"); +// Compare the given intoto tlog entry to the given bundle +function verifyIntotoTLogBody(tlogEntry, content) { + switch (tlogEntry.apiVersion) { + case '0.0.2': + return verifyIntoto002TLogBody(tlogEntry, content); + default: + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: `unsupported intoto version: ${tlogEntry.apiVersion}`, + }); + } +} +// Compare the given intoto v0.0.2 tlog entry to the given DSSE envelope. +function verifyIntoto002TLogBody(tlogEntry, content) { + // Ensure the bundle's DSSE contains a single signature + if (tlogEntry.spec.content.envelope.signatures?.length !== 1) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'signature count mismatch', + }); + } + // Signature is double-base64-encoded in the tlog entry + const tlogSig = base64Decode(tlogEntry.spec.content.envelope.signatures[0].sig); + // Ensure that the signature in the bundle's DSSE matches tlog entry + if (!content.compareSignature(Buffer.from(tlogSig, 'base64'))) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'tlog entry signature mismatch', + }); + } + // Ensure the digest of the bundle's DSSE payload matches the digest in the + // tlog entry + const tlogHash = tlogEntry.spec.content.payloadHash?.value || ''; + if (!content.compareDigest(Buffer.from(tlogHash, 'hex'))) { + throw new error_1.VerificationError({ + code: 'TLOG_BODY_ERROR', + message: 'DSSE payload hash mismatch', + }); + } +} +function base64Decode(str) { + return Buffer.from(str, 'base64').toString('utf-8'); +} diff --git a/node_modules/@sigstore/verify/dist/tlog/merkle.js b/node_modules/@sigstore/verify/dist/tlog/merkle.js new file mode 100644 index 0000000000000..fbebeffd1ba7b --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/merkle.js @@ -0,0 +1,104 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyMerkleInclusion = verifyMerkleInclusion; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const error_1 = require("../error"); +const RFC6962_LEAF_HASH_PREFIX = Buffer.from([0x00]); +const RFC6962_NODE_HASH_PREFIX = Buffer.from([0x01]); +function verifyMerkleInclusion(entry, checkpoint) { + const inclusionProof = entry.inclusionProof; + const logIndex = BigInt(inclusionProof.logIndex); + const treeSize = BigInt(checkpoint.logSize); + if (logIndex < 0n || logIndex >= treeSize) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: `invalid index: ${logIndex}`, + }); + } + // Figure out which subset of hashes corresponds to the inner and border + // nodes + const { inner, border } = decompInclProof(logIndex, treeSize); + if (inclusionProof.hashes.length !== inner + border) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'invalid hash count', + }); + } + const innerHashes = inclusionProof.hashes.slice(0, inner); + const borderHashes = inclusionProof.hashes.slice(inner); + // The entry's hash is the leaf hash + const leafHash = hashLeaf(entry.canonicalizedBody); + // Chain the hashes belonging to the inner and border portions + const calculatedHash = chainBorderRight(chainInner(leafHash, innerHashes, logIndex), borderHashes); + // Calculated hash should match the root hash in the inclusion proof + if (!core_1.crypto.bufferEqual(calculatedHash, checkpoint.logHash)) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROOF_ERROR', + message: 'calculated root hash does not match inclusion proof', + }); + } +} +// Breaks down inclusion proof for a leaf at the specified index in a tree of +// the specified size. The split point is where paths to the index leaf and +// the (size - 1) leaf diverge. Returns lengths of the bottom and upper proof +// parts. +function decompInclProof(index, size) { + const inner = innerProofSize(index, size); + const border = onesCount(index >> BigInt(inner)); + return { inner, border }; +} +// Computes a subtree hash for a node on or below the tree's right border. +// Assumes the provided proof hashes are ordered from lower to higher levels +// and seed is the initial hash of the node specified by the index. +function chainInner(seed, hashes, index) { + return hashes.reduce((acc, h, i) => { + if ((index >> BigInt(i)) & BigInt(1)) { + return hashChildren(h, acc); + } + else { + return hashChildren(acc, h); + } + }, seed); +} +// Computes a subtree hash for nodes along the tree's right border. +function chainBorderRight(seed, hashes) { + return hashes.reduce((acc, h) => hashChildren(h, acc), seed); +} +function innerProofSize(index, size) { + return bitLength(index ^ (size - BigInt(1))); +} +// Counts the number of ones in the binary representation of the given number. +// https://en.wikipedia.org/wiki/Hamming_weight +function onesCount(num) { + return num.toString(2).split('1').length - 1; +} +// Returns the number of bits necessary to represent an integer in binary. +function bitLength(n) { + if (n === 0n) { + return 0; + } + return n.toString(2).length; +} +// Hashing logic according to RFC6962. +// https://datatracker.ietf.org/doc/html/rfc6962#section-2 +function hashChildren(left, right) { + return core_1.crypto.digest('sha256', RFC6962_NODE_HASH_PREFIX, left, right); +} +function hashLeaf(leaf) { + return core_1.crypto.digest('sha256', RFC6962_LEAF_HASH_PREFIX, leaf); +} diff --git a/node_modules/@sigstore/verify/dist/tlog/set.js b/node_modules/@sigstore/verify/dist/tlog/set.js new file mode 100644 index 0000000000000..5d3f47bb88746 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/tlog/set.js @@ -0,0 +1,60 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyTLogSET = verifyTLogSET; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const error_1 = require("../error"); +const trust_1 = require("../trust"); +// Verifies the SET for the given entry against the list of trusted +// transparency logs. Returns true if the SET can be verified against at least +// one of the trusted logs; otherwise, returns false. +function verifyTLogSET(entry, tlogs) { + // Filter the list of tlog instances to only those which might be able to + // verify the SET + const validTLogs = (0, trust_1.filterTLogAuthorities)(tlogs, { + logID: entry.logId.keyId, + targetDate: new Date(Number(entry.integratedTime) * 1000), + }); + // Check to see if we can verify the SET against any of the valid tlogs + const verified = validTLogs.some((tlog) => { + // Re-create the original Rekor verification payload + const payload = toVerificationPayload(entry); + // Canonicalize the payload and turn into a buffer for verification + const data = Buffer.from(core_1.json.canonicalize(payload), 'utf8'); + // Extract the SET from the tlog entry + const signature = entry.inclusionPromise.signedEntryTimestamp; + return core_1.crypto.verify(data, tlog.publicKey, signature); + }); + if (!verified) { + throw new error_1.VerificationError({ + code: 'TLOG_INCLUSION_PROMISE_ERROR', + message: 'inclusion promise could not be verified', + }); + } +} +// Returns a properly formatted "VerificationPayload" for one of the +// transaction log entires in the given bundle which can be used for SET +// verification. +function toVerificationPayload(entry) { + const { integratedTime, logIndex, logId, canonicalizedBody } = entry; + return { + body: canonicalizedBody.toString('base64'), + integratedTime: Number(integratedTime), + logIndex: Number(logIndex), + logID: logId.keyId.toString('hex'), + }; +} diff --git a/node_modules/@sigstore/verify/dist/trust/filter.js b/node_modules/@sigstore/verify/dist/trust/filter.js new file mode 100644 index 0000000000000..98bd25cd70e59 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/trust/filter.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.filterCertAuthorities = filterCertAuthorities; +exports.filterTLogAuthorities = filterTLogAuthorities; +function filterCertAuthorities(certAuthorities, timestamp) { + return certAuthorities.filter((ca) => { + return ca.validFor.start <= timestamp && ca.validFor.end >= timestamp; + }); +} +// Filter the list of tlog instances to only those which match the given log +// ID and have public keys which are valid for the given integrated time. +function filterTLogAuthorities(tlogAuthorities, criteria) { + return tlogAuthorities.filter((tlog) => { + // If we're filtering by log ID and the log IDs don't match, we can't use + // this tlog + if (criteria.logID && !tlog.logID.equals(criteria.logID)) { + return false; + } + // Check that the integrated time is within the validFor range + return (tlog.validFor.start <= criteria.targetDate && + criteria.targetDate <= tlog.validFor.end); + }); +} diff --git a/node_modules/@sigstore/verify/dist/trust/index.js b/node_modules/@sigstore/verify/dist/trust/index.js new file mode 100644 index 0000000000000..2823f5f7d4b93 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/trust/index.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.filterTLogAuthorities = exports.filterCertAuthorities = void 0; +exports.toTrustMaterial = toTrustMaterial; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const protobuf_specs_1 = require("@sigstore/protobuf-specs"); +const error_1 = require("../error"); +const BEGINNING_OF_TIME = new Date(0); +const END_OF_TIME = new Date(8640000000000000); +var filter_1 = require("./filter"); +Object.defineProperty(exports, "filterCertAuthorities", { enumerable: true, get: function () { return filter_1.filterCertAuthorities; } }); +Object.defineProperty(exports, "filterTLogAuthorities", { enumerable: true, get: function () { return filter_1.filterTLogAuthorities; } }); +function toTrustMaterial(root, keys) { + const keyFinder = typeof keys === 'function' ? keys : keyLocator(keys); + return { + certificateAuthorities: root.certificateAuthorities.map(createCertAuthority), + timestampAuthorities: root.timestampAuthorities.map(createCertAuthority), + tlogs: root.tlogs.map(createTLogAuthority), + ctlogs: root.ctlogs.map(createTLogAuthority), + publicKey: keyFinder, + }; +} +function createTLogAuthority(tlogInstance) { + const keyDetails = tlogInstance.publicKey.keyDetails; + const keyType = keyDetails === protobuf_specs_1.PublicKeyDetails.PKCS1_RSA_PKCS1V5 || + keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V5 || + keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V15_2048_SHA256 || + keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V15_3072_SHA256 || + keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V15_4096_SHA256 + ? 'pkcs1' + : 'spki'; + /* istanbul ignore next */ + return { + baseURL: tlogInstance.baseUrl, + logID: tlogInstance.checkpointKeyId + ? tlogInstance.checkpointKeyId.keyId + : tlogInstance.logId.keyId, + publicKey: core_1.crypto.createPublicKey(tlogInstance.publicKey.rawBytes, keyType), + validFor: { + start: tlogInstance.publicKey.validFor?.start || BEGINNING_OF_TIME, + end: tlogInstance.publicKey.validFor?.end || END_OF_TIME, + }, + }; +} +function createCertAuthority(ca) { + /* istanbul ignore next */ + return { + certChain: ca.certChain.certificates.map((cert) => { + return core_1.X509Certificate.parse(Buffer.from(cert.rawBytes)); + }), + validFor: { + start: ca.validFor?.start || BEGINNING_OF_TIME, + end: ca.validFor?.end || END_OF_TIME, + }, + }; +} +function keyLocator(keys) { + return (hint) => { + const key = (keys || {})[hint]; + if (!key) { + throw new error_1.VerificationError({ + code: 'PUBLIC_KEY_ERROR', + message: `key not found: ${hint}`, + }); + } + return { + publicKey: core_1.crypto.createPublicKey(key.rawBytes), + validFor: (date) => { + /* istanbul ignore next */ + return ((key.validFor?.start || BEGINNING_OF_TIME) <= date && + (key.validFor?.end || END_OF_TIME) >= date); + }, + }; + }; +} diff --git a/node_modules/@sigstore/verify/dist/trust/trust.types.js b/node_modules/@sigstore/verify/dist/trust/trust.types.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@sigstore/verify/dist/trust/trust.types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@sigstore/verify/dist/verifier.js b/node_modules/@sigstore/verify/dist/verifier.js new file mode 100644 index 0000000000000..5751087ff178d --- /dev/null +++ b/node_modules/@sigstore/verify/dist/verifier.js @@ -0,0 +1,150 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Verifier = void 0; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const util_1 = require("util"); +const error_1 = require("./error"); +const key_1 = require("./key"); +const policy_1 = require("./policy"); +const timestamp_1 = require("./timestamp"); +const tlog_1 = require("./tlog"); +class Verifier { + trustMaterial; + options; + constructor(trustMaterial, options = {}) { + this.trustMaterial = trustMaterial; + this.options = { + ctlogThreshold: options.ctlogThreshold ?? 1, + tlogThreshold: options.tlogThreshold ?? 1, + timestampThreshold: options.timestampThreshold ?? options.tsaThreshold ?? 1, + tsaThreshold: 0, + }; + } + verify(entity, policy) { + const timestamps = this.verifyTimestamps(entity); + const signer = this.verifySigningKey(entity, timestamps); + this.verifyTLogs(entity); + this.verifySignature(entity, signer); + if (policy) { + this.verifyPolicy(policy, signer.identity || {}); + } + return signer; + } + // Checks that all of the timestamps in the entity are valid and returns them + verifyTimestamps(entity) { + let timestampCount = 0; + const timestamps = entity.timestamps.map((timestamp) => { + switch (timestamp.$case) { + case 'timestamp-authority': + timestampCount++; + return (0, timestamp_1.getTSATimestamp)(timestamp.timestamp, entity.signature.signature, this.trustMaterial.timestampAuthorities); + case 'transparency-log': + timestampCount++; + return (0, timestamp_1.getTLogTimestamp)(timestamp.tlogEntry); + } + }); + // Check for duplicate timestamps + if (containsDupes(timestamps)) { + throw new error_1.VerificationError({ + code: 'TIMESTAMP_ERROR', + message: 'duplicate timestamp', + }); + } + if (timestampCount < this.options.timestampThreshold) { + throw new error_1.VerificationError({ + code: 'TIMESTAMP_ERROR', + message: `expected ${this.options.timestampThreshold} timestamps, got ${timestampCount}`, + }); + } + return timestamps.map((t) => t.timestamp); + } + // Checks that the signing key is valid for all of the the supplied timestamps + // and returns the signer. + verifySigningKey({ key }, timestamps) { + switch (key.$case) { + case 'public-key': { + return (0, key_1.verifyPublicKey)(key.hint, timestamps, this.trustMaterial); + } + case 'certificate': { + const result = (0, key_1.verifyCertificate)(key.certificate, timestamps, this.trustMaterial); + /* istanbul ignore next - no fixture */ + if (containsDupes(result.scts)) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: 'duplicate SCT', + }); + } + if (result.scts.length < this.options.ctlogThreshold) { + throw new error_1.VerificationError({ + code: 'CERTIFICATE_ERROR', + message: `expected ${this.options.ctlogThreshold} SCTs, got ${result.scts.length}`, + }); + } + return result.signer; + } + } + } + // Checks that the tlog entries are valid for the supplied content + verifyTLogs({ signature: content, tlogEntries }) { + let tlogCount = 0; + tlogEntries.forEach((entry) => { + tlogCount++; + (0, tlog_1.verifyTLogInclusion)(entry, this.trustMaterial.tlogs); + (0, tlog_1.verifyTLogBody)(entry, content); + }); + if (tlogCount < this.options.tlogThreshold) { + throw new error_1.VerificationError({ + code: 'TLOG_ERROR', + message: `expected ${this.options.tlogThreshold} tlog entries, got ${tlogCount}`, + }); + } + } + // Checks that the signature is valid for the supplied content + verifySignature(entity, signer) { + if (!entity.signature.verifySignature(signer.key)) { + throw new error_1.VerificationError({ + code: 'SIGNATURE_ERROR', + message: 'signature verification failed', + }); + } + } + verifyPolicy(policy, identity) { + // Check the subject alternative name of the signer matches the policy + /* istanbul ignore else */ + if (policy.subjectAlternativeName) { + (0, policy_1.verifySubjectAlternativeName)(policy.subjectAlternativeName, identity.subjectAlternativeName); + } + // Check that the extensions of the signer match the policy + /* istanbul ignore else */ + if (policy.extensions) { + (0, policy_1.verifyExtensions)(policy.extensions, identity.extensions); + } + } +} +exports.Verifier = Verifier; +// Checks for duplicate items in the array. Objects are compared using +// deep equality. +function containsDupes(arr) { + for (let i = 0; i < arr.length; i++) { + for (let j = i + 1; j < arr.length; j++) { + if ((0, util_1.isDeepStrictEqual)(arr[i], arr[j])) { + return true; + } + } + } + return false; +} diff --git a/node_modules/@sigstore/verify/package.json b/node_modules/@sigstore/verify/package.json new file mode 100644 index 0000000000000..79826a80bddeb --- /dev/null +++ b/node_modules/@sigstore/verify/package.json @@ -0,0 +1,36 @@ +{ + "name": "@sigstore/verify", + "version": "3.1.0", + "description": "Verification of Sigstore signatures", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "shx rm -rf dist *.tsbuildinfo", + "build": "tsc --build", + "test": "jest" + }, + "files": [ + "dist" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/sigstore-js.git" + }, + "bugs": { + "url": "https://github.com/sigstore/sigstore-js/issues" + }, + "homepage": "https://github.com/sigstore/sigstore-js/tree/main/packages/verify#readme", + "publishConfig": { + "provenance": true + }, + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/@tootallnate/once/LICENSE b/node_modules/@tootallnate/once/LICENSE deleted file mode 100644 index c4c56a2a53b2f..0000000000000 --- a/node_modules/@tootallnate/once/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Nathan Rajlich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/@tootallnate/once/dist/index.d.ts b/node_modules/@tootallnate/once/dist/index.d.ts deleted file mode 100644 index 93d02a9a348b5..0000000000000 --- a/node_modules/@tootallnate/once/dist/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/// <reference types="node" /> -import { EventEmitter } from 'events'; -import { EventNames, EventListenerParameters, AbortSignal } from './types'; -export interface OnceOptions { - signal?: AbortSignal; -} -export default function once<Emitter extends EventEmitter, Event extends EventNames<Emitter>>(emitter: Emitter, name: Event, { signal }?: OnceOptions): Promise<EventListenerParameters<Emitter, Event>>; diff --git a/node_modules/@tootallnate/once/dist/index.js b/node_modules/@tootallnate/once/dist/index.js deleted file mode 100644 index ca6385b1b82f8..0000000000000 --- a/node_modules/@tootallnate/once/dist/index.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -function once(emitter, name, { signal } = {}) { - return new Promise((resolve, reject) => { - function cleanup() { - signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', cleanup); - emitter.removeListener(name, onEvent); - emitter.removeListener('error', onError); - } - function onEvent(...args) { - cleanup(); - resolve(args); - } - function onError(err) { - cleanup(); - reject(err); - } - signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', cleanup); - emitter.on(name, onEvent); - emitter.on('error', onError); - }); -} -exports.default = once; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/@tootallnate/once/dist/index.js.map b/node_modules/@tootallnate/once/dist/index.js.map deleted file mode 100644 index 61708ca07f1b0..0000000000000 --- a/node_modules/@tootallnate/once/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAOA,SAAwB,IAAI,CAI3B,OAAgB,EAChB,IAAW,EACX,EAAE,MAAM,KAAkB,EAAE;IAE5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,SAAS,OAAO;YACf,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACtC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,SAAS,OAAO,CAAC,GAAG,IAAW;YAC9B,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,IAA+C,CAAC,CAAC;QAC1D,CAAC;QACD,SAAS,OAAO,CAAC,GAAU;YAC1B,OAAO,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;QACD,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACJ,CAAC;AA1BD,uBA0BC"} \ No newline at end of file diff --git a/node_modules/@tootallnate/once/dist/overloaded-parameters.d.ts b/node_modules/@tootallnate/once/dist/overloaded-parameters.d.ts deleted file mode 100644 index eb2bbc6c6275e..0000000000000 --- a/node_modules/@tootallnate/once/dist/overloaded-parameters.d.ts +++ /dev/null @@ -1,231 +0,0 @@ -export declare type OverloadedParameters<T> = T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; - (...args: infer A15): any; - (...args: infer A16): any; - (...args: infer A17): any; - (...args: infer A18): any; - (...args: infer A19): any; - (...args: infer A20): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 | A17 | A18 | A19 | A20 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; - (...args: infer A15): any; - (...args: infer A16): any; - (...args: infer A17): any; - (...args: infer A18): any; - (...args: infer A19): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 | A17 | A18 | A19 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; - (...args: infer A15): any; - (...args: infer A16): any; - (...args: infer A17): any; - (...args: infer A18): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 | A17 | A18 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; - (...args: infer A15): any; - (...args: infer A16): any; - (...args: infer A17): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 | A17 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; - (...args: infer A15): any; - (...args: infer A16): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 | A16 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; - (...args: infer A15): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 | A15 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; - (...args: infer A14): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 | A14 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; - (...args: infer A13): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 | A13 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; - (...args: infer A12): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 | A12 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; - (...args: infer A11): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 | A11 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; - (...args: infer A10): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 | A10 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; - (...args: infer A9): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 | A9 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; - (...args: infer A8): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 | A8 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; - (...args: infer A7): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 | A7 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; - (...args: infer A6): any; -} ? A1 | A2 | A3 | A4 | A5 | A6 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; - (...args: infer A5): any; -} ? A1 | A2 | A3 | A4 | A5 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; - (...args: infer A4): any; -} ? A1 | A2 | A3 | A4 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; - (...args: infer A3): any; -} ? A1 | A2 | A3 : T extends { - (...args: infer A1): any; - (...args: infer A2): any; -} ? A1 | A2 : T extends { - (...args: infer A1): any; -} ? A1 : any; diff --git a/node_modules/@tootallnate/once/dist/overloaded-parameters.js b/node_modules/@tootallnate/once/dist/overloaded-parameters.js deleted file mode 100644 index 207186d9e7cca..0000000000000 --- a/node_modules/@tootallnate/once/dist/overloaded-parameters.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -//# sourceMappingURL=overloaded-parameters.js.map \ No newline at end of file diff --git a/node_modules/@tootallnate/once/dist/overloaded-parameters.js.map b/node_modules/@tootallnate/once/dist/overloaded-parameters.js.map deleted file mode 100644 index 863f146d625f6..0000000000000 --- a/node_modules/@tootallnate/once/dist/overloaded-parameters.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"overloaded-parameters.js","sourceRoot":"","sources":["../src/overloaded-parameters.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/node_modules/@tootallnate/once/dist/types.d.ts b/node_modules/@tootallnate/once/dist/types.d.ts deleted file mode 100644 index 58be8284ab8d3..0000000000000 --- a/node_modules/@tootallnate/once/dist/types.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/// <reference types="node" /> -import { EventEmitter } from 'events'; -import { OverloadedParameters } from './overloaded-parameters'; -export declare type FirstParameter<T> = T extends [infer R, ...any[]] ? R : never; -export declare type EventListener<F, T extends string | symbol> = F extends [ - T, - infer R, - ...any[] -] ? R : never; -export declare type EventParameters<Emitter extends EventEmitter> = OverloadedParameters<Emitter['on']>; -export declare type EventNames<Emitter extends EventEmitter> = FirstParameter<EventParameters<Emitter>>; -export declare type EventListenerParameters<Emitter extends EventEmitter, Event extends EventNames<Emitter>> = WithDefault<Parameters<EventListener<EventParameters<Emitter>, Event>>, unknown[]>; -export declare type WithDefault<T, D> = [T] extends [never] ? D : T; -export interface AbortSignal { - addEventListener: (name: string, listener: (...args: any[]) => any) => void; - removeEventListener: (name: string, listener: (...args: any[]) => any) => void; -} diff --git a/node_modules/@tootallnate/once/dist/types.js b/node_modules/@tootallnate/once/dist/types.js deleted file mode 100644 index 11e638d1ee44a..0000000000000 --- a/node_modules/@tootallnate/once/dist/types.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/node_modules/@tootallnate/once/dist/types.js.map b/node_modules/@tootallnate/once/dist/types.js.map deleted file mode 100644 index c768b79002615..0000000000000 --- a/node_modules/@tootallnate/once/dist/types.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/node_modules/@tootallnate/once/package.json b/node_modules/@tootallnate/once/package.json deleted file mode 100644 index 69ce947d9c310..0000000000000 --- a/node_modules/@tootallnate/once/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@tootallnate/once", - "version": "2.0.0", - "description": "Creates a Promise that waits for a single event", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "files": [ - "dist" - ], - "scripts": { - "prebuild": "rimraf dist", - "build": "tsc", - "test": "jest", - "prepublishOnly": "npm run build" - }, - "repository": { - "type": "git", - "url": "git://github.com/TooTallNate/once.git" - }, - "keywords": [], - "author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)", - "license": "MIT", - "bugs": { - "url": "https://github.com/TooTallNate/once/issues" - }, - "devDependencies": { - "@types/jest": "^27.0.2", - "@types/node": "^12.12.11", - "abort-controller": "^3.0.0", - "jest": "^27.2.1", - "rimraf": "^3.0.0", - "ts-jest": "^27.0.5", - "typescript": "^4.4.3" - }, - "engines": { - "node": ">= 10" - }, - "jest": { - "preset": "ts-jest", - "globals": { - "ts-jest": { - "diagnostics": false, - "isolatedModules": true - } - }, - "verbose": false, - "testEnvironment": "node", - "testMatch": [ - "<rootDir>/test/**/*.test.ts" - ] - } -} diff --git a/node_modules/@tufjs/canonical-json/LICENSE b/node_modules/@tufjs/canonical-json/LICENSE new file mode 100644 index 0000000000000..420700f5d3765 --- /dev/null +++ b/node_modules/@tufjs/canonical-json/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 GitHub and the TUF Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tufjs/canonical-json/lib/index.js b/node_modules/@tufjs/canonical-json/lib/index.js new file mode 100644 index 0000000000000..d480696de1f6c --- /dev/null +++ b/node_modules/@tufjs/canonical-json/lib/index.js @@ -0,0 +1,64 @@ +const COMMA = ','; +const COLON = ':'; +const LEFT_SQUARE_BRACKET = '['; +const RIGHT_SQUARE_BRACKET = ']'; +const LEFT_CURLY_BRACKET = '{'; +const RIGHT_CURLY_BRACKET = '}'; + +// Recursively encodes the supplied object according to the canonical JSON form +// as specified at http://wiki.laptop.org/go/Canonical_JSON. It's a restricted +// dialect of JSON in which keys are lexically sorted, floats are not allowed, +// and only double quotes and backslashes are escaped. +function canonicalize(object) { + const buffer = []; + if (typeof object === 'string') { + buffer.push(canonicalizeString(object)); + } else if (typeof object === 'boolean') { + buffer.push(JSON.stringify(object)); + } else if (Number.isInteger(object)) { + buffer.push(JSON.stringify(object)); + } else if (object === null) { + buffer.push(JSON.stringify(object)); + } else if (Array.isArray(object)) { + buffer.push(LEFT_SQUARE_BRACKET); + let first = true; + object.forEach((element) => { + if (!first) { + buffer.push(COMMA); + } + first = false; + buffer.push(canonicalize(element)); + }); + buffer.push(RIGHT_SQUARE_BRACKET); + } else if (typeof object === 'object') { + buffer.push(LEFT_CURLY_BRACKET); + let first = true; + Object.keys(object) + .sort() + .forEach((property) => { + if (!first) { + buffer.push(COMMA); + } + first = false; + buffer.push(canonicalizeString(property)); + buffer.push(COLON); + buffer.push(canonicalize(object[property])); + }); + buffer.push(RIGHT_CURLY_BRACKET); + } else { + throw new TypeError('cannot encode ' + object.toString()); + } + + return buffer.join(''); +} + +// String canonicalization consists of escaping backslash (\) and double +// quote (") characters and wrapping the resulting string in double quotes. +function canonicalizeString(string) { + const escapedString = string.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); + return '"' + escapedString + '"'; +} + +module.exports = { + canonicalize, +}; diff --git a/node_modules/@tufjs/canonical-json/package.json b/node_modules/@tufjs/canonical-json/package.json new file mode 100644 index 0000000000000..886c0c3969225 --- /dev/null +++ b/node_modules/@tufjs/canonical-json/package.json @@ -0,0 +1,35 @@ +{ + "name": "@tufjs/canonical-json", + "version": "2.0.0", + "description": "OLPC JSON canonicalization", + "main": "lib/index.js", + "typings": "lib/index.d.ts", + "license": "MIT", + "keywords": [ + "json", + "canonical", + "canonicalize", + "canonicalization", + "crypto", + "signature", + "olpc" + ], + "author": "bdehamer@github.com", + "repository": { + "type": "git", + "url": "git+https://github.com/theupdateframework/tuf-js.git" + }, + "homepage": "https://github.com/theupdateframework/tuf-js/tree/main/packages/canonical-json#readme", + "bugs": { + "url": "https://github.com/theupdateframework/tuf-js/issues" + }, + "files": [ + "lib/" + ], + "scripts": { + "test": "jest" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } +} diff --git a/node_modules/@tufjs/models/LICENSE b/node_modules/@tufjs/models/LICENSE new file mode 100644 index 0000000000000..420700f5d3765 --- /dev/null +++ b/node_modules/@tufjs/models/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 GitHub and the TUF Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@tufjs/models/dist/base.js b/node_modules/@tufjs/models/dist/base.js new file mode 100644 index 0000000000000..14f0024f8091a --- /dev/null +++ b/node_modules/@tufjs/models/dist/base.js @@ -0,0 +1,96 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Signed = exports.MetadataKind = void 0; +exports.isMetadataKind = isMetadataKind; +const util_1 = __importDefault(require("util")); +const error_1 = require("./error"); +const utils_1 = require("./utils"); +const SPECIFICATION_VERSION = ['1', '0', '31']; +var MetadataKind; +(function (MetadataKind) { + MetadataKind["Root"] = "root"; + MetadataKind["Timestamp"] = "timestamp"; + MetadataKind["Snapshot"] = "snapshot"; + MetadataKind["Targets"] = "targets"; +})(MetadataKind || (exports.MetadataKind = MetadataKind = {})); +function isMetadataKind(value) { + return (typeof value === 'string' && + Object.values(MetadataKind).includes(value)); +} +/*** + * A base class for the signed part of TUF metadata. + * + * Objects with base class Signed are usually included in a ``Metadata`` object + * on the signed attribute. This class provides attributes and methods that + * are common for all TUF metadata types (roles). + */ +class Signed { + specVersion; + expires; + version; + unrecognizedFields; + constructor(options) { + this.specVersion = options.specVersion || SPECIFICATION_VERSION.join('.'); + const specList = this.specVersion.split('.'); + if (!(specList.length === 2 || specList.length === 3) || + !specList.every((item) => isNumeric(item))) { + throw new error_1.ValueError('Failed to parse specVersion'); + } + // major version must match + if (specList[0] != SPECIFICATION_VERSION[0]) { + throw new error_1.ValueError('Unsupported specVersion'); + } + this.expires = options.expires; + this.version = options.version; + this.unrecognizedFields = options.unrecognizedFields || {}; + } + equals(other) { + if (!(other instanceof Signed)) { + return false; + } + return (this.specVersion === other.specVersion && + this.expires === other.expires && + this.version === other.version && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields)); + } + isExpired(referenceTime) { + if (!referenceTime) { + referenceTime = new Date(); + } + return referenceTime >= new Date(this.expires); + } + static commonFieldsFromJSON(data) { + const { spec_version, expires, version, ...rest } = data; + if (!utils_1.guard.isDefined(spec_version)) { + throw new error_1.ValueError('spec_version is not defined'); + } + else if (typeof spec_version !== 'string') { + throw new TypeError('spec_version must be a string'); + } + if (!utils_1.guard.isDefined(expires)) { + throw new error_1.ValueError('expires is not defined'); + } + else if (!(typeof expires === 'string')) { + throw new TypeError('expires must be a string'); + } + if (!utils_1.guard.isDefined(version)) { + throw new error_1.ValueError('version is not defined'); + } + else if (!(typeof version === 'number')) { + throw new TypeError('version must be a number'); + } + return { + specVersion: spec_version, + expires, + version, + unrecognizedFields: rest, + }; + } +} +exports.Signed = Signed; +function isNumeric(str) { + return !isNaN(Number(str)); +} diff --git a/node_modules/@tufjs/models/dist/delegations.js b/node_modules/@tufjs/models/dist/delegations.js new file mode 100644 index 0000000000000..9ad8bf05f1c6b --- /dev/null +++ b/node_modules/@tufjs/models/dist/delegations.js @@ -0,0 +1,119 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Delegations = void 0; +const util_1 = __importDefault(require("util")); +const error_1 = require("./error"); +const key_1 = require("./key"); +const role_1 = require("./role"); +const utils_1 = require("./utils"); +/** + * A container object storing information about all delegations. + * + * Targets roles that are trusted to provide signed metadata files + * describing targets with designated pathnames and/or further delegations. + */ +class Delegations { + keys; + roles; + unrecognizedFields; + succinctRoles; + constructor(options) { + this.keys = options.keys; + this.unrecognizedFields = options.unrecognizedFields || {}; + if (options.roles) { + if (Object.keys(options.roles).some((roleName) => role_1.TOP_LEVEL_ROLE_NAMES.includes(roleName))) { + throw new error_1.ValueError('Delegated role name conflicts with top-level role name'); + } + } + this.succinctRoles = options.succinctRoles; + this.roles = options.roles; + } + equals(other) { + if (!(other instanceof Delegations)) { + return false; + } + return (util_1.default.isDeepStrictEqual(this.keys, other.keys) && + util_1.default.isDeepStrictEqual(this.roles, other.roles) && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields) && + util_1.default.isDeepStrictEqual(this.succinctRoles, other.succinctRoles)); + } + *rolesForTarget(targetPath) { + if (this.roles) { + for (const role of Object.values(this.roles)) { + if (role.isDelegatedPath(targetPath)) { + yield { role: role.name, terminating: role.terminating }; + } + } + } + else if (this.succinctRoles) { + yield { + role: this.succinctRoles.getRoleForTarget(targetPath), + terminating: true, + }; + } + } + toJSON() { + const json = { + keys: keysToJSON(this.keys), + ...this.unrecognizedFields, + }; + if (this.roles) { + json.roles = rolesToJSON(this.roles); + } + else if (this.succinctRoles) { + json.succinct_roles = this.succinctRoles.toJSON(); + } + return json; + } + static fromJSON(data) { + const { keys, roles, succinct_roles, ...unrecognizedFields } = data; + let succinctRoles; + if (utils_1.guard.isObject(succinct_roles)) { + succinctRoles = role_1.SuccinctRoles.fromJSON(succinct_roles); + } + return new Delegations({ + keys: keysFromJSON(keys), + roles: rolesFromJSON(roles), + unrecognizedFields, + succinctRoles, + }); + } +} +exports.Delegations = Delegations; +function keysToJSON(keys) { + return Object.entries(keys).reduce((acc, [keyId, key]) => ({ + ...acc, + [keyId]: key.toJSON(), + }), {}); +} +function rolesToJSON(roles) { + return Object.values(roles).map((role) => role.toJSON()); +} +function keysFromJSON(data) { + if (!utils_1.guard.isObjectRecord(data)) { + throw new TypeError('keys is malformed'); + } + return Object.entries(data).reduce((acc, [keyID, keyData]) => ({ + ...acc, + [keyID]: key_1.Key.fromJSON(keyID, keyData), + }), {}); +} +function rolesFromJSON(data) { + let roleMap; + if (utils_1.guard.isDefined(data)) { + if (!utils_1.guard.isObjectArray(data)) { + throw new TypeError('roles is malformed'); + } + roleMap = data.reduce((acc, role) => { + const delegatedRole = role_1.DelegatedRole.fromJSON(role); + return { + ...acc, + [delegatedRole.name]: delegatedRole, + }; + }, {}); + } + return roleMap; +} diff --git a/node_modules/@tufjs/models/dist/error.js b/node_modules/@tufjs/models/dist/error.js new file mode 100644 index 0000000000000..ba80698747ba0 --- /dev/null +++ b/node_modules/@tufjs/models/dist/error.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UnsupportedAlgorithmError = exports.CryptoError = exports.LengthOrHashMismatchError = exports.UnsignedMetadataError = exports.RepositoryError = exports.ValueError = void 0; +// An error about insufficient values +class ValueError extends Error { +} +exports.ValueError = ValueError; +// An error with a repository's state, such as a missing file. +// It covers all exceptions that come from the repository side when +// looking from the perspective of users of metadata API or ngclient. +class RepositoryError extends Error { +} +exports.RepositoryError = RepositoryError; +// An error about metadata object with insufficient threshold of signatures. +class UnsignedMetadataError extends RepositoryError { +} +exports.UnsignedMetadataError = UnsignedMetadataError; +// An error while checking the length and hash values of an object. +class LengthOrHashMismatchError extends RepositoryError { +} +exports.LengthOrHashMismatchError = LengthOrHashMismatchError; +class CryptoError extends Error { +} +exports.CryptoError = CryptoError; +class UnsupportedAlgorithmError extends CryptoError { +} +exports.UnsupportedAlgorithmError = UnsupportedAlgorithmError; diff --git a/node_modules/@tufjs/models/dist/file.js b/node_modules/@tufjs/models/dist/file.js new file mode 100644 index 0000000000000..c8cdcb1c40271 --- /dev/null +++ b/node_modules/@tufjs/models/dist/file.js @@ -0,0 +1,191 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TargetFile = exports.MetaFile = void 0; +const crypto_1 = __importDefault(require("crypto")); +const util_1 = __importDefault(require("util")); +const error_1 = require("./error"); +const utils_1 = require("./utils"); +// A container with information about a particular metadata file. +// +// This class is used for Timestamp and Snapshot metadata. +class MetaFile { + version; + length; + hashes; + unrecognizedFields; + constructor(opts) { + if (opts.version <= 0) { + throw new error_1.ValueError('Metafile version must be at least 1'); + } + if (opts.length !== undefined) { + validateLength(opts.length); + } + this.version = opts.version; + this.length = opts.length; + this.hashes = opts.hashes; + this.unrecognizedFields = opts.unrecognizedFields || {}; + } + equals(other) { + if (!(other instanceof MetaFile)) { + return false; + } + return (this.version === other.version && + this.length === other.length && + util_1.default.isDeepStrictEqual(this.hashes, other.hashes) && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields)); + } + verify(data) { + // Verifies that the given data matches the expected length. + if (this.length !== undefined) { + if (data.length !== this.length) { + throw new error_1.LengthOrHashMismatchError(`Expected length ${this.length} but got ${data.length}`); + } + } + // Verifies that the given data matches the supplied hashes. + if (this.hashes) { + Object.entries(this.hashes).forEach(([key, value]) => { + let hash; + try { + hash = crypto_1.default.createHash(key); + } + catch (e) { + throw new error_1.LengthOrHashMismatchError(`Hash algorithm ${key} not supported`); + } + const observedHash = hash.update(data).digest('hex'); + if (observedHash !== value) { + throw new error_1.LengthOrHashMismatchError(`Expected hash ${value} but got ${observedHash}`); + } + }); + } + } + toJSON() { + const json = { + version: this.version, + ...this.unrecognizedFields, + }; + if (this.length !== undefined) { + json.length = this.length; + } + if (this.hashes) { + json.hashes = this.hashes; + } + return json; + } + static fromJSON(data) { + const { version, length, hashes, ...rest } = data; + if (typeof version !== 'number') { + throw new TypeError('version must be a number'); + } + if (utils_1.guard.isDefined(length) && typeof length !== 'number') { + throw new TypeError('length must be a number'); + } + if (utils_1.guard.isDefined(hashes) && !utils_1.guard.isStringRecord(hashes)) { + throw new TypeError('hashes must be string keys and values'); + } + return new MetaFile({ + version, + length, + hashes, + unrecognizedFields: rest, + }); + } +} +exports.MetaFile = MetaFile; +// Container for info about a particular target file. +// +// This class is used for Target metadata. +class TargetFile { + length; + path; + hashes; + unrecognizedFields; + constructor(opts) { + validateLength(opts.length); + this.length = opts.length; + this.path = opts.path; + this.hashes = opts.hashes; + this.unrecognizedFields = opts.unrecognizedFields || {}; + } + get custom() { + const custom = this.unrecognizedFields['custom']; + if (!custom || Array.isArray(custom) || !(typeof custom === 'object')) { + return {}; + } + return custom; + } + equals(other) { + if (!(other instanceof TargetFile)) { + return false; + } + return (this.length === other.length && + this.path === other.path && + util_1.default.isDeepStrictEqual(this.hashes, other.hashes) && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields)); + } + async verify(stream) { + let observedLength = 0; + // Create a digest for each hash algorithm + const digests = Object.keys(this.hashes).reduce((acc, key) => { + try { + acc[key] = crypto_1.default.createHash(key); + } + catch (e) { + throw new error_1.LengthOrHashMismatchError(`Hash algorithm ${key} not supported`); + } + return acc; + }, {}); + // Read stream chunk by chunk + for await (const chunk of stream) { + // Keep running tally of stream length + observedLength += chunk.length; + // Append chunk to each digest + Object.values(digests).forEach((digest) => { + digest.update(chunk); + }); + } + // Verify length matches expected value + if (observedLength !== this.length) { + throw new error_1.LengthOrHashMismatchError(`Expected length ${this.length} but got ${observedLength}`); + } + // Verify each digest matches expected value + Object.entries(digests).forEach(([key, value]) => { + const expected = this.hashes[key]; + const actual = value.digest('hex'); + if (actual !== expected) { + throw new error_1.LengthOrHashMismatchError(`Expected hash ${expected} but got ${actual}`); + } + }); + } + toJSON() { + return { + length: this.length, + hashes: this.hashes, + ...this.unrecognizedFields, + }; + } + static fromJSON(path, data) { + const { length, hashes, ...rest } = data; + if (typeof length !== 'number') { + throw new TypeError('length must be a number'); + } + if (!utils_1.guard.isStringRecord(hashes)) { + throw new TypeError('hashes must have string keys and values'); + } + return new TargetFile({ + length, + path, + hashes, + unrecognizedFields: rest, + }); + } +} +exports.TargetFile = TargetFile; +// Check that supplied length if valid +function validateLength(length) { + if (length < 0) { + throw new error_1.ValueError('Length must be at least 0'); + } +} diff --git a/node_modules/@tufjs/models/dist/index.js b/node_modules/@tufjs/models/dist/index.js new file mode 100644 index 0000000000000..a4dc783659f04 --- /dev/null +++ b/node_modules/@tufjs/models/dist/index.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Timestamp = exports.Targets = exports.Snapshot = exports.Signature = exports.Root = exports.Metadata = exports.Key = exports.TargetFile = exports.MetaFile = exports.ValueError = exports.MetadataKind = void 0; +var base_1 = require("./base"); +Object.defineProperty(exports, "MetadataKind", { enumerable: true, get: function () { return base_1.MetadataKind; } }); +var error_1 = require("./error"); +Object.defineProperty(exports, "ValueError", { enumerable: true, get: function () { return error_1.ValueError; } }); +var file_1 = require("./file"); +Object.defineProperty(exports, "MetaFile", { enumerable: true, get: function () { return file_1.MetaFile; } }); +Object.defineProperty(exports, "TargetFile", { enumerable: true, get: function () { return file_1.TargetFile; } }); +var key_1 = require("./key"); +Object.defineProperty(exports, "Key", { enumerable: true, get: function () { return key_1.Key; } }); +var metadata_1 = require("./metadata"); +Object.defineProperty(exports, "Metadata", { enumerable: true, get: function () { return metadata_1.Metadata; } }); +var root_1 = require("./root"); +Object.defineProperty(exports, "Root", { enumerable: true, get: function () { return root_1.Root; } }); +var signature_1 = require("./signature"); +Object.defineProperty(exports, "Signature", { enumerable: true, get: function () { return signature_1.Signature; } }); +var snapshot_1 = require("./snapshot"); +Object.defineProperty(exports, "Snapshot", { enumerable: true, get: function () { return snapshot_1.Snapshot; } }); +var targets_1 = require("./targets"); +Object.defineProperty(exports, "Targets", { enumerable: true, get: function () { return targets_1.Targets; } }); +var timestamp_1 = require("./timestamp"); +Object.defineProperty(exports, "Timestamp", { enumerable: true, get: function () { return timestamp_1.Timestamp; } }); diff --git a/node_modules/@tufjs/models/dist/key.js b/node_modules/@tufjs/models/dist/key.js new file mode 100644 index 0000000000000..10bf2f4b66fc0 --- /dev/null +++ b/node_modules/@tufjs/models/dist/key.js @@ -0,0 +1,90 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Key = void 0; +const util_1 = __importDefault(require("util")); +const error_1 = require("./error"); +const utils_1 = require("./utils"); +const key_1 = require("./utils/key"); +// A container class representing the public portion of a Key. +class Key { + keyID; + keyType; + scheme; + keyVal; + unrecognizedFields; + constructor(options) { + const { keyID, keyType, scheme, keyVal, unrecognizedFields } = options; + this.keyID = keyID; + this.keyType = keyType; + this.scheme = scheme; + this.keyVal = keyVal; + this.unrecognizedFields = unrecognizedFields || {}; + } + // Verifies the that the metadata.signatures contains a signature made with + // this key and is correctly signed. + verifySignature(metadata) { + const signature = metadata.signatures[this.keyID]; + if (!signature) + throw new error_1.UnsignedMetadataError('no signature for key found in metadata'); + if (!this.keyVal.public) + throw new error_1.UnsignedMetadataError('no public key found'); + const publicKey = (0, key_1.getPublicKey)({ + keyType: this.keyType, + scheme: this.scheme, + keyVal: this.keyVal.public, + }); + const signedData = metadata.signed.toJSON(); + try { + if (!utils_1.crypto.verifySignature(signedData, publicKey, signature.sig)) { + throw new error_1.UnsignedMetadataError(`failed to verify ${this.keyID} signature`); + } + } + catch (error) { + if (error instanceof error_1.UnsignedMetadataError) { + throw error; + } + throw new error_1.UnsignedMetadataError(`failed to verify ${this.keyID} signature`); + } + } + equals(other) { + if (!(other instanceof Key)) { + return false; + } + return (this.keyID === other.keyID && + this.keyType === other.keyType && + this.scheme === other.scheme && + util_1.default.isDeepStrictEqual(this.keyVal, other.keyVal) && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields)); + } + toJSON() { + return { + keytype: this.keyType, + scheme: this.scheme, + keyval: this.keyVal, + ...this.unrecognizedFields, + }; + } + static fromJSON(keyID, data) { + const { keytype, scheme, keyval, ...rest } = data; + if (typeof keytype !== 'string') { + throw new TypeError('keytype must be a string'); + } + if (typeof scheme !== 'string') { + throw new TypeError('scheme must be a string'); + } + if (!utils_1.guard.isStringRecord(keyval)) { + throw new TypeError('keyval must be a string record'); + } + return new Key({ + keyID, + keyType: keytype, + scheme, + keyVal: keyval, + unrecognizedFields: rest, + }); + } +} +exports.Key = Key; diff --git a/node_modules/@tufjs/models/dist/metadata.js b/node_modules/@tufjs/models/dist/metadata.js new file mode 100644 index 0000000000000..1ae4b6829c0c7 --- /dev/null +++ b/node_modules/@tufjs/models/dist/metadata.js @@ -0,0 +1,165 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Metadata = void 0; +const canonical_json_1 = require("@tufjs/canonical-json"); +const util_1 = __importDefault(require("util")); +const base_1 = require("./base"); +const error_1 = require("./error"); +const root_1 = require("./root"); +const signature_1 = require("./signature"); +const snapshot_1 = require("./snapshot"); +const targets_1 = require("./targets"); +const timestamp_1 = require("./timestamp"); +const utils_1 = require("./utils"); +/*** + * A container for signed TUF metadata. + * + * Provides methods to convert to and from json, read and write to and + * from JSON and to create and verify metadata signatures. + * + * ``Metadata[T]`` is a generic container type where T can be any one type of + * [``Root``, ``Timestamp``, ``Snapshot``, ``Targets``]. The purpose of this + * is to allow static type checking of the signed attribute in code using + * Metadata:: + * + * root_md = Metadata[Root].fromJSON("root.json") + * # root_md type is now Metadata[Root]. This means signed and its + * # attributes like consistent_snapshot are now statically typed and the + * # types can be verified by static type checkers and shown by IDEs + * + * Using a type constraint is not required but not doing so means T is not a + * specific type so static typing cannot happen. Note that the type constraint + * ``[Root]`` is not validated at runtime (as pure annotations are not available + * then). + * + * Apart from ``expires`` all of the arguments to the inner constructors have + * reasonable default values for new metadata. + */ +class Metadata { + signed; + signatures; + unrecognizedFields; + constructor(signed, signatures, unrecognizedFields) { + this.signed = signed; + this.signatures = signatures || {}; + this.unrecognizedFields = unrecognizedFields || {}; + } + sign(signer, append = true) { + const bytes = Buffer.from((0, canonical_json_1.canonicalize)(this.signed.toJSON())); + const signature = signer(bytes); + if (!append) { + this.signatures = {}; + } + this.signatures[signature.keyID] = signature; + } + verifyDelegate(delegatedRole, delegatedMetadata) { + let role; + let keys = {}; + switch (this.signed.type) { + case base_1.MetadataKind.Root: + keys = this.signed.keys; + role = this.signed.roles[delegatedRole]; + break; + case base_1.MetadataKind.Targets: + if (!this.signed.delegations) { + throw new error_1.ValueError(`No delegations found for ${delegatedRole}`); + } + keys = this.signed.delegations.keys; + if (this.signed.delegations.roles) { + role = this.signed.delegations.roles[delegatedRole]; + } + else if (this.signed.delegations.succinctRoles) { + if (this.signed.delegations.succinctRoles.isDelegatedRole(delegatedRole)) { + role = this.signed.delegations.succinctRoles; + } + } + break; + default: + throw new TypeError('invalid metadata type'); + } + if (!role) { + throw new error_1.ValueError(`no delegation found for ${delegatedRole}`); + } + const signingKeys = new Set(); + role.keyIDs.forEach((keyID) => { + const key = keys[keyID]; + // If we dont' have the key, continue checking other keys + if (!key) { + return; + } + try { + key.verifySignature(delegatedMetadata); + signingKeys.add(key.keyID); + } + catch (error) { + // continue + } + }); + if (signingKeys.size < role.threshold) { + throw new error_1.UnsignedMetadataError(`${delegatedRole} was signed by ${signingKeys.size}/${role.threshold} keys`); + } + } + equals(other) { + if (!(other instanceof Metadata)) { + return false; + } + return ( + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + this.signed.equals(other.signed) && + util_1.default.isDeepStrictEqual(this.signatures, other.signatures) && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields)); + } + toJSON() { + const signatures = Object.values(this.signatures).map((signature) => { + return signature.toJSON(); + }); + return { + signatures, + signed: this.signed.toJSON(), + ...this.unrecognizedFields, + }; + } + static fromJSON(type, data) { + const { signed, signatures, ...rest } = data; + if (!utils_1.guard.isDefined(signed) || !utils_1.guard.isObject(signed)) { + throw new TypeError('signed is not defined'); + } + if (type !== signed._type) { + throw new error_1.ValueError(`expected '${type}', got ${signed['_type']}`); + } + if (!utils_1.guard.isObjectArray(signatures)) { + throw new TypeError('signatures is not an array'); + } + let signedObj; + switch (type) { + case base_1.MetadataKind.Root: + signedObj = root_1.Root.fromJSON(signed); + break; + case base_1.MetadataKind.Timestamp: + signedObj = timestamp_1.Timestamp.fromJSON(signed); + break; + case base_1.MetadataKind.Snapshot: + signedObj = snapshot_1.Snapshot.fromJSON(signed); + break; + case base_1.MetadataKind.Targets: + signedObj = targets_1.Targets.fromJSON(signed); + break; + default: + throw new TypeError('invalid metadata type'); + } + const sigMap = {}; + // Ensure that each signature is unique + signatures.forEach((sigData) => { + const sig = signature_1.Signature.fromJSON(sigData); + if (sigMap[sig.keyID]) { + throw new error_1.ValueError(`multiple signatures found for keyid: ${sig.keyID}`); + } + sigMap[sig.keyID] = sig; + }); + return new Metadata(signedObj, sigMap, rest); + } +} +exports.Metadata = Metadata; diff --git a/node_modules/@tufjs/models/dist/role.js b/node_modules/@tufjs/models/dist/role.js new file mode 100644 index 0000000000000..6c049e17c8dab --- /dev/null +++ b/node_modules/@tufjs/models/dist/role.js @@ -0,0 +1,310 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SuccinctRoles = exports.DelegatedRole = exports.Role = exports.TOP_LEVEL_ROLE_NAMES = void 0; +const crypto_1 = __importDefault(require("crypto")); +const minimatch_1 = require("minimatch"); +const util_1 = __importDefault(require("util")); +const error_1 = require("./error"); +const utils_1 = require("./utils"); +exports.TOP_LEVEL_ROLE_NAMES = [ + 'root', + 'targets', + 'snapshot', + 'timestamp', +]; +/** + * Container that defines which keys are required to sign roles metadata. + * + * Role defines how many keys are required to successfully sign the roles + * metadata, and which keys are accepted. + */ +class Role { + keyIDs; + threshold; + unrecognizedFields; + constructor(options) { + const { keyIDs, threshold, unrecognizedFields } = options; + if (hasDuplicates(keyIDs)) { + throw new error_1.ValueError('duplicate key IDs found'); + } + if (threshold < 1) { + throw new error_1.ValueError('threshold must be at least 1'); + } + this.keyIDs = keyIDs; + this.threshold = threshold; + this.unrecognizedFields = unrecognizedFields || {}; + } + equals(other) { + if (!(other instanceof Role)) { + return false; + } + return (this.threshold === other.threshold && + util_1.default.isDeepStrictEqual(this.keyIDs, other.keyIDs) && + util_1.default.isDeepStrictEqual(this.unrecognizedFields, other.unrecognizedFields)); + } + toJSON() { + return { + keyids: this.keyIDs, + threshold: this.threshold, + ...this.unrecognizedFields, + }; + } + static fromJSON(data) { + const { keyids, threshold, ...rest } = data; + if (!utils_1.guard.isStringArray(keyids)) { + throw new TypeError('keyids must be an array'); + } + if (typeof threshold !== 'number') { + throw new TypeError('threshold must be a number'); + } + return new Role({ + keyIDs: keyids, + threshold, + unrecognizedFields: rest, + }); + } +} +exports.Role = Role; +function hasDuplicates(array) { + return new Set(array).size !== array.length; +} +/** + * A container with information about a delegated role. + * + * A delegation can happen in two ways: + * - ``paths`` is set: delegates targets matching any path pattern in ``paths`` + * - ``pathHashPrefixes`` is set: delegates targets whose target path hash + * starts with any of the prefixes in ``pathHashPrefixes`` + * + * ``paths`` and ``pathHashPrefixes`` are mutually exclusive: both cannot be + * set, at least one of them must be set. + */ +class DelegatedRole extends Role { + name; + terminating; + paths; + pathHashPrefixes; + constructor(opts) { + super(opts); + const { name, terminating, paths, pathHashPrefixes } = opts; + this.name = name; + this.terminating = terminating; + if (opts.paths && opts.pathHashPrefixes) { + throw new error_1.ValueError('paths and pathHashPrefixes are mutually exclusive'); + } + this.paths = paths; + this.pathHashPrefixes = pathHashPrefixes; + } + equals(other) { + if (!(other instanceof DelegatedRole)) { + return false; + } + return (super.equals(other) && + this.name === other.name && + this.terminating === other.terminating && + util_1.default.isDeepStrictEqual(this.paths, other.paths) && + util_1.default.isDeepStrictEqual(this.pathHashPrefixes, other.pathHashPrefixes)); + } + isDelegatedPath(targetFilepath) { + if (this.paths) { + return this.paths.some((pathPattern) => isTargetInPathPattern(targetFilepath, pathPattern)); + } + if (this.pathHashPrefixes) { + const hasher = crypto_1.default.createHash('sha256'); + const pathHash = hasher.update(targetFilepath).digest('hex'); + return this.pathHashPrefixes.some((pathHashPrefix) => pathHash.startsWith(pathHashPrefix)); + } + return false; + } + toJSON() { + const json = { + ...super.toJSON(), + name: this.name, + terminating: this.terminating, + }; + if (this.paths) { + json.paths = this.paths; + } + if (this.pathHashPrefixes) { + json.path_hash_prefixes = this.pathHashPrefixes; + } + return json; + } + static fromJSON(data) { + const { keyids, threshold, name, terminating, paths, path_hash_prefixes, ...rest } = data; + if (!utils_1.guard.isStringArray(keyids)) { + throw new TypeError('keyids must be an array of strings'); + } + if (typeof threshold !== 'number') { + throw new TypeError('threshold must be a number'); + } + if (typeof name !== 'string') { + throw new TypeError('name must be a string'); + } + if (typeof terminating !== 'boolean') { + throw new TypeError('terminating must be a boolean'); + } + if (utils_1.guard.isDefined(paths) && !utils_1.guard.isStringArray(paths)) { + throw new TypeError('paths must be an array of strings'); + } + if (utils_1.guard.isDefined(path_hash_prefixes) && + !utils_1.guard.isStringArray(path_hash_prefixes)) { + throw new TypeError('path_hash_prefixes must be an array of strings'); + } + return new DelegatedRole({ + keyIDs: keyids, + threshold, + name, + terminating, + paths, + pathHashPrefixes: path_hash_prefixes, + unrecognizedFields: rest, + }); + } +} +exports.DelegatedRole = DelegatedRole; +// JS version of Ruby's Array#zip +const zip = (a, b) => a.map((k, i) => [k, b[i]]); +function isTargetInPathPattern(target, pattern) { + const targetParts = target.split('/'); + const patternParts = pattern.split('/'); + if (patternParts.length != targetParts.length) { + return false; + } + return zip(targetParts, patternParts).every(([targetPart, patternPart]) => (0, minimatch_1.minimatch)(targetPart, patternPart)); +} +/** + * Succinctly defines a hash bin delegation graph. + * + * A ``SuccinctRoles`` object describes a delegation graph that covers all + * targets, distributing them uniformly over the delegated roles (i.e. bins) + * in the graph. + * + * The total number of bins is 2 to the power of the passed ``bit_length``. + * + * Bin names are the concatenation of the passed ``name_prefix`` and a + * zero-padded hex representation of the bin index separated by a hyphen. + * + * The passed ``keyids`` and ``threshold`` is used for each bin, and each bin + * is 'terminating'. + * + * For details: https://github.com/theupdateframework/taps/blob/master/tap15.md + */ +class SuccinctRoles extends Role { + bitLength; + namePrefix; + numberOfBins; + suffixLen; + constructor(opts) { + super(opts); + const { bitLength, namePrefix } = opts; + if (bitLength <= 0 || bitLength > 32) { + throw new error_1.ValueError('bitLength must be between 1 and 32'); + } + this.bitLength = bitLength; + this.namePrefix = namePrefix; + // Calculate the suffix_len value based on the total number of bins in + // hex. If bit_length = 10 then number_of_bins = 1024 or bin names will + // have a suffix between "000" and "3ff" in hex and suffix_len will be 3 + // meaning the third bin will have a suffix of "003". + this.numberOfBins = Math.pow(2, bitLength); + // suffix_len is calculated based on "number_of_bins - 1" as the name + // of the last bin contains the number "number_of_bins -1" as a suffix. + this.suffixLen = (this.numberOfBins - 1).toString(16).length; + } + equals(other) { + if (!(other instanceof SuccinctRoles)) { + return false; + } + return (super.equals(other) && + this.bitLength === other.bitLength && + this.namePrefix === other.namePrefix); + } + /*** + * Calculates the name of the delegated role responsible for 'target_filepath'. + * + * The target at path ''target_filepath' is assigned to a bin by casting + * the left-most 'bit_length' of bits of the file path hash digest to + * int, using it as bin index between 0 and '2**bit_length - 1'. + * + * Args: + * target_filepath: URL path to a target file, relative to a base + * targets URL. + */ + getRoleForTarget(targetFilepath) { + const hasher = crypto_1.default.createHash('sha256'); + const hasherBuffer = hasher.update(targetFilepath).digest(); + // can't ever need more than 4 bytes (32 bits). + const hashBytes = hasherBuffer.subarray(0, 4); + // Right shift hash bytes, so that we only have the leftmost + // bit_length bits that we care about. + const shiftValue = 32 - this.bitLength; + const binNumber = hashBytes.readUInt32BE() >>> shiftValue; + // Add zero padding if necessary and cast to hex the suffix. + const suffix = binNumber.toString(16).padStart(this.suffixLen, '0'); + return `${this.namePrefix}-${suffix}`; + } + *getRoles() { + for (let i = 0; i < this.numberOfBins; i++) { + const suffix = i.toString(16).padStart(this.suffixLen, '0'); + yield `${this.namePrefix}-${suffix}`; + } + } + /*** + * Determines whether the given ``role_name`` is in one of + * the delegated roles that ``SuccinctRoles`` represents. + * + * Args: + * role_name: The name of the role to check against. + */ + isDelegatedRole(roleName) { + const desiredPrefix = this.namePrefix + '-'; + if (!roleName.startsWith(desiredPrefix)) { + return false; + } + const suffix = roleName.slice(desiredPrefix.length, roleName.length); + if (suffix.length != this.suffixLen) { + return false; + } + // make sure the suffix is a hex string + if (!suffix.match(/^[0-9a-fA-F]+$/)) { + return false; + } + const num = parseInt(suffix, 16); + return 0 <= num && num < this.numberOfBins; + } + toJSON() { + const json = { + ...super.toJSON(), + bit_length: this.bitLength, + name_prefix: this.namePrefix, + }; + return json; + } + static fromJSON(data) { + const { keyids, threshold, bit_length, name_prefix, ...rest } = data; + if (!utils_1.guard.isStringArray(keyids)) { + throw new TypeError('keyids must be an array of strings'); + } + if (typeof threshold !== 'number') { + throw new TypeError('threshold must be a number'); + } + if (typeof bit_length !== 'number') { + throw new TypeError('bit_length must be a number'); + } + if (typeof name_prefix !== 'string') { + throw new TypeError('name_prefix must be a string'); + } + return new SuccinctRoles({ + keyIDs: keyids, + threshold, + bitLength: bit_length, + namePrefix: name_prefix, + unrecognizedFields: rest, + }); + } +} +exports.SuccinctRoles = SuccinctRoles; diff --git a/node_modules/@tufjs/models/dist/root.js b/node_modules/@tufjs/models/dist/root.js new file mode 100644 index 0000000000000..76d4e4039980e --- /dev/null +++ b/node_modules/@tufjs/models/dist/root.js @@ -0,0 +1,119 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Root = void 0; +const util_1 = __importDefault(require("util")); +const base_1 = require("./base"); +const error_1 = require("./error"); +const key_1 = require("./key"); +const role_1 = require("./role"); +const utils_1 = require("./utils"); +/** + * A container for the signed part of root metadata. + * + * The top-level role and metadata file signed by the root keys. + * This role specifies trusted keys for all other top-level roles, which may further delegate trust. + */ +class Root extends base_1.Signed { + type = base_1.MetadataKind.Root; + keys; + roles; + consistentSnapshot; + constructor(options) { + super(options); + this.keys = options.keys || {}; + this.consistentSnapshot = options.consistentSnapshot ?? true; + if (!options.roles) { + this.roles = role_1.TOP_LEVEL_ROLE_NAMES.reduce((acc, role) => ({ + ...acc, + [role]: new role_1.Role({ keyIDs: [], threshold: 1 }), + }), {}); + } + else { + const roleNames = new Set(Object.keys(options.roles)); + if (!role_1.TOP_LEVEL_ROLE_NAMES.every((role) => roleNames.has(role))) { + throw new error_1.ValueError('missing top-level role'); + } + this.roles = options.roles; + } + } + addKey(key, role) { + if (!this.roles[role]) { + throw new error_1.ValueError(`role ${role} does not exist`); + } + if (!this.roles[role].keyIDs.includes(key.keyID)) { + this.roles[role].keyIDs.push(key.keyID); + } + this.keys[key.keyID] = key; + } + equals(other) { + if (!(other instanceof Root)) { + return false; + } + return (super.equals(other) && + this.consistentSnapshot === other.consistentSnapshot && + util_1.default.isDeepStrictEqual(this.keys, other.keys) && + util_1.default.isDeepStrictEqual(this.roles, other.roles)); + } + toJSON() { + return { + _type: this.type, + spec_version: this.specVersion, + version: this.version, + expires: this.expires, + keys: keysToJSON(this.keys), + roles: rolesToJSON(this.roles), + consistent_snapshot: this.consistentSnapshot, + ...this.unrecognizedFields, + }; + } + static fromJSON(data) { + const { unrecognizedFields, ...commonFields } = base_1.Signed.commonFieldsFromJSON(data); + const { keys, roles, consistent_snapshot, ...rest } = unrecognizedFields; + if (typeof consistent_snapshot !== 'boolean') { + throw new TypeError('consistent_snapshot must be a boolean'); + } + return new Root({ + ...commonFields, + keys: keysFromJSON(keys), + roles: rolesFromJSON(roles), + consistentSnapshot: consistent_snapshot, + unrecognizedFields: rest, + }); + } +} +exports.Root = Root; +function keysToJSON(keys) { + return Object.entries(keys).reduce((acc, [keyID, key]) => ({ ...acc, [keyID]: key.toJSON() }), {}); +} +function rolesToJSON(roles) { + return Object.entries(roles).reduce((acc, [roleName, role]) => ({ ...acc, [roleName]: role.toJSON() }), {}); +} +function keysFromJSON(data) { + let keys; + if (utils_1.guard.isDefined(data)) { + if (!utils_1.guard.isObjectRecord(data)) { + throw new TypeError('keys must be an object'); + } + keys = Object.entries(data).reduce((acc, [keyID, keyData]) => ({ + ...acc, + [keyID]: key_1.Key.fromJSON(keyID, keyData), + }), {}); + } + return keys; +} +function rolesFromJSON(data) { + let roles; + if (utils_1.guard.isDefined(data)) { + if (!utils_1.guard.isObjectRecord(data)) { + throw new TypeError('roles must be an object'); + } + roles = Object.entries(data).reduce((acc, [roleName, roleData]) => ({ + ...acc, + [roleName]: role_1.Role.fromJSON(roleData), + }), {}); + } + return roles; +} diff --git a/node_modules/@tufjs/models/dist/signature.js b/node_modules/@tufjs/models/dist/signature.js new file mode 100644 index 0000000000000..43c0bfe58c483 --- /dev/null +++ b/node_modules/@tufjs/models/dist/signature.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Signature = void 0; +/** + * A container class containing information about a signature. + * + * Contains a signature and the keyid uniquely identifying the key used + * to generate the signature. + * + * Provide a `fromJSON` method to create a Signature from a JSON object. + */ +class Signature { + keyID; + sig; + constructor(options) { + const { keyID, sig } = options; + this.keyID = keyID; + this.sig = sig; + } + toJSON() { + return { + keyid: this.keyID, + sig: this.sig, + }; + } + static fromJSON(data) { + const { keyid, sig } = data; + if (typeof keyid !== 'string') { + throw new TypeError('keyid must be a string'); + } + if (typeof sig !== 'string') { + throw new TypeError('sig must be a string'); + } + return new Signature({ + keyID: keyid, + sig: sig, + }); + } +} +exports.Signature = Signature; diff --git a/node_modules/@tufjs/models/dist/snapshot.js b/node_modules/@tufjs/models/dist/snapshot.js new file mode 100644 index 0000000000000..bc9983c12e669 --- /dev/null +++ b/node_modules/@tufjs/models/dist/snapshot.js @@ -0,0 +1,72 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Snapshot = void 0; +const util_1 = __importDefault(require("util")); +const base_1 = require("./base"); +const file_1 = require("./file"); +const utils_1 = require("./utils"); +/** + * A container for the signed part of snapshot metadata. + * + * Snapshot contains information about all target Metadata files. + * A top-level role that specifies the latest versions of all targets metadata files, + * and hence the latest versions of all targets (including any dependencies between them) on the repository. + */ +class Snapshot extends base_1.Signed { + type = base_1.MetadataKind.Snapshot; + meta; + constructor(opts) { + super(opts); + this.meta = opts.meta || { 'targets.json': new file_1.MetaFile({ version: 1 }) }; + } + equals(other) { + if (!(other instanceof Snapshot)) { + return false; + } + return super.equals(other) && util_1.default.isDeepStrictEqual(this.meta, other.meta); + } + toJSON() { + return { + _type: this.type, + meta: metaToJSON(this.meta), + spec_version: this.specVersion, + version: this.version, + expires: this.expires, + ...this.unrecognizedFields, + }; + } + static fromJSON(data) { + const { unrecognizedFields, ...commonFields } = base_1.Signed.commonFieldsFromJSON(data); + const { meta, ...rest } = unrecognizedFields; + return new Snapshot({ + ...commonFields, + meta: metaFromJSON(meta), + unrecognizedFields: rest, + }); + } +} +exports.Snapshot = Snapshot; +function metaToJSON(meta) { + return Object.entries(meta).reduce((acc, [path, metadata]) => ({ + ...acc, + [path]: metadata.toJSON(), + }), {}); +} +function metaFromJSON(data) { + let meta; + if (utils_1.guard.isDefined(data)) { + if (!utils_1.guard.isObjectRecord(data)) { + throw new TypeError('meta field is malformed'); + } + else { + meta = Object.entries(data).reduce((acc, [path, metadata]) => ({ + ...acc, + [path]: file_1.MetaFile.fromJSON(metadata), + }), {}); + } + } + return meta; +} diff --git a/node_modules/@tufjs/models/dist/targets.js b/node_modules/@tufjs/models/dist/targets.js new file mode 100644 index 0000000000000..e509722f94758 --- /dev/null +++ b/node_modules/@tufjs/models/dist/targets.js @@ -0,0 +1,94 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Targets = void 0; +const util_1 = __importDefault(require("util")); +const base_1 = require("./base"); +const delegations_1 = require("./delegations"); +const file_1 = require("./file"); +const utils_1 = require("./utils"); +// Container for the signed part of targets metadata. +// +// Targets contains verifying information about target files and also delegates +// responsible to other Targets roles. +class Targets extends base_1.Signed { + type = base_1.MetadataKind.Targets; + targets; + delegations; + constructor(options) { + super(options); + this.targets = options.targets || {}; + this.delegations = options.delegations; + } + addTarget(target) { + this.targets[target.path] = target; + } + equals(other) { + if (!(other instanceof Targets)) { + return false; + } + return (super.equals(other) && + util_1.default.isDeepStrictEqual(this.targets, other.targets) && + util_1.default.isDeepStrictEqual(this.delegations, other.delegations)); + } + toJSON() { + const json = { + _type: this.type, + spec_version: this.specVersion, + version: this.version, + expires: this.expires, + targets: targetsToJSON(this.targets), + ...this.unrecognizedFields, + }; + if (this.delegations) { + json.delegations = this.delegations.toJSON(); + } + return json; + } + static fromJSON(data) { + const { unrecognizedFields, ...commonFields } = base_1.Signed.commonFieldsFromJSON(data); + const { targets, delegations, ...rest } = unrecognizedFields; + return new Targets({ + ...commonFields, + targets: targetsFromJSON(targets), + delegations: delegationsFromJSON(delegations), + unrecognizedFields: rest, + }); + } +} +exports.Targets = Targets; +function targetsToJSON(targets) { + return Object.entries(targets).reduce((acc, [path, target]) => ({ + ...acc, + [path]: target.toJSON(), + }), {}); +} +function targetsFromJSON(data) { + let targets; + if (utils_1.guard.isDefined(data)) { + if (!utils_1.guard.isObjectRecord(data)) { + throw new TypeError('targets must be an object'); + } + else { + targets = Object.entries(data).reduce((acc, [path, target]) => ({ + ...acc, + [path]: file_1.TargetFile.fromJSON(path, target), + }), {}); + } + } + return targets; +} +function delegationsFromJSON(data) { + let delegations; + if (utils_1.guard.isDefined(data)) { + if (!utils_1.guard.isObject(data)) { + throw new TypeError('delegations must be an object'); + } + else { + delegations = delegations_1.Delegations.fromJSON(data); + } + } + return delegations; +} diff --git a/node_modules/@tufjs/models/dist/timestamp.js b/node_modules/@tufjs/models/dist/timestamp.js new file mode 100644 index 0000000000000..d454b308f27e1 --- /dev/null +++ b/node_modules/@tufjs/models/dist/timestamp.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Timestamp = void 0; +const base_1 = require("./base"); +const file_1 = require("./file"); +const utils_1 = require("./utils"); +/** + * A container for the signed part of timestamp metadata. + * + * A top-level that specifies the latest version of the snapshot role metadata file, + * and hence the latest versions of all metadata and targets on the repository. + */ +class Timestamp extends base_1.Signed { + type = base_1.MetadataKind.Timestamp; + snapshotMeta; + constructor(options) { + super(options); + this.snapshotMeta = options.snapshotMeta || new file_1.MetaFile({ version: 1 }); + } + equals(other) { + if (!(other instanceof Timestamp)) { + return false; + } + return super.equals(other) && this.snapshotMeta.equals(other.snapshotMeta); + } + toJSON() { + return { + _type: this.type, + spec_version: this.specVersion, + version: this.version, + expires: this.expires, + meta: { 'snapshot.json': this.snapshotMeta.toJSON() }, + ...this.unrecognizedFields, + }; + } + static fromJSON(data) { + const { unrecognizedFields, ...commonFields } = base_1.Signed.commonFieldsFromJSON(data); + const { meta, ...rest } = unrecognizedFields; + return new Timestamp({ + ...commonFields, + snapshotMeta: snapshotMetaFromJSON(meta), + unrecognizedFields: rest, + }); + } +} +exports.Timestamp = Timestamp; +function snapshotMetaFromJSON(data) { + let snapshotMeta; + if (utils_1.guard.isDefined(data)) { + const snapshotData = data['snapshot.json']; + if (!utils_1.guard.isDefined(snapshotData) || !utils_1.guard.isObject(snapshotData)) { + throw new TypeError('missing snapshot.json in meta'); + } + else { + snapshotMeta = file_1.MetaFile.fromJSON(snapshotData); + } + } + return snapshotMeta; +} diff --git a/node_modules/@tufjs/models/dist/utils/guard.js b/node_modules/@tufjs/models/dist/utils/guard.js new file mode 100644 index 0000000000000..911e8475986bb --- /dev/null +++ b/node_modules/@tufjs/models/dist/utils/guard.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isDefined = isDefined; +exports.isObject = isObject; +exports.isStringArray = isStringArray; +exports.isObjectArray = isObjectArray; +exports.isStringRecord = isStringRecord; +exports.isObjectRecord = isObjectRecord; +function isDefined(val) { + return val !== undefined; +} +function isObject(value) { + return typeof value === 'object' && value !== null; +} +function isStringArray(value) { + return Array.isArray(value) && value.every((v) => typeof v === 'string'); +} +function isObjectArray(value) { + return Array.isArray(value) && value.every(isObject); +} +function isStringRecord(value) { + return (typeof value === 'object' && + value !== null && + Object.keys(value).every((k) => typeof k === 'string') && + Object.values(value).every((v) => typeof v === 'string')); +} +function isObjectRecord(value) { + return (typeof value === 'object' && + value !== null && + Object.keys(value).every((k) => typeof k === 'string') && + Object.values(value).every((v) => typeof v === 'object' && v !== null)); +} diff --git a/node_modules/@tufjs/models/dist/utils/index.js b/node_modules/@tufjs/models/dist/utils/index.js new file mode 100644 index 0000000000000..395cccc36cf92 --- /dev/null +++ b/node_modules/@tufjs/models/dist/utils/index.js @@ -0,0 +1,38 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.crypto = exports.guard = void 0; +exports.guard = __importStar(require("./guard")); +exports.crypto = __importStar(require("./verify")); diff --git a/node_modules/@tufjs/models/dist/utils/key.js b/node_modules/@tufjs/models/dist/utils/key.js new file mode 100644 index 0000000000000..3c3ec07f1425a --- /dev/null +++ b/node_modules/@tufjs/models/dist/utils/key.js @@ -0,0 +1,142 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getPublicKey = getPublicKey; +const crypto_1 = __importDefault(require("crypto")); +const error_1 = require("../error"); +const oid_1 = require("./oid"); +const ASN1_TAG_SEQUENCE = 0x30; +const ANS1_TAG_BIT_STRING = 0x03; +const NULL_BYTE = 0x00; +const OID_EDDSA = '1.3.101.112'; +const OID_EC_PUBLIC_KEY = '1.2.840.10045.2.1'; +const OID_EC_CURVE_P256V1 = '1.2.840.10045.3.1.7'; +const PEM_HEADER = '-----BEGIN PUBLIC KEY-----'; +function getPublicKey(keyInfo) { + switch (keyInfo.keyType) { + case 'rsa': + return getRSAPublicKey(keyInfo); + case 'ed25519': + return getED25519PublicKey(keyInfo); + case 'ecdsa': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + return getECDCSAPublicKey(keyInfo); + default: + throw new error_1.UnsupportedAlgorithmError(`Unsupported key type: ${keyInfo.keyType}`); + } +} +function getRSAPublicKey(keyInfo) { + // Only support PEM-encoded RSA keys + if (!keyInfo.keyVal.startsWith(PEM_HEADER)) { + throw new error_1.CryptoError('Invalid key format'); + } + const key = crypto_1.default.createPublicKey(keyInfo.keyVal); + switch (keyInfo.scheme) { + case 'rsassa-pss-sha256': + return { + key: key, + padding: crypto_1.default.constants.RSA_PKCS1_PSS_PADDING, + }; + default: + throw new error_1.UnsupportedAlgorithmError(`Unsupported RSA scheme: ${keyInfo.scheme}`); + } +} +function getED25519PublicKey(keyInfo) { + let key; + // If key is already PEM-encoded we can just parse it + if (keyInfo.keyVal.startsWith(PEM_HEADER)) { + key = crypto_1.default.createPublicKey(keyInfo.keyVal); + } + else { + // If key is not PEM-encoded it had better be hex + if (!isHex(keyInfo.keyVal)) { + throw new error_1.CryptoError('Invalid key format'); + } + key = crypto_1.default.createPublicKey({ + key: ed25519.hexToDER(keyInfo.keyVal), + format: 'der', + type: 'spki', + }); + } + return { key }; +} +function getECDCSAPublicKey(keyInfo) { + let key; + // If key is already PEM-encoded we can just parse it + if (keyInfo.keyVal.startsWith(PEM_HEADER)) { + key = crypto_1.default.createPublicKey(keyInfo.keyVal); + } + else { + // If key is not PEM-encoded it had better be hex + if (!isHex(keyInfo.keyVal)) { + throw new error_1.CryptoError('Invalid key format'); + } + key = crypto_1.default.createPublicKey({ + key: ecdsa.hexToDER(keyInfo.keyVal), + format: 'der', + type: 'spki', + }); + } + return { key }; +} +const ed25519 = { + // Translates a hex key into a crypto KeyObject + // https://keygen.sh/blog/how-to-use-hexadecimal-ed25519-keys-in-node/ + hexToDER: (hex) => { + const key = Buffer.from(hex, 'hex'); + const oid = (0, oid_1.encodeOIDString)(OID_EDDSA); + // Create a byte sequence containing the OID and key + const elements = Buffer.concat([ + Buffer.concat([ + Buffer.from([ASN1_TAG_SEQUENCE]), + Buffer.from([oid.length]), + oid, + ]), + Buffer.concat([ + Buffer.from([ANS1_TAG_BIT_STRING]), + Buffer.from([key.length + 1]), + Buffer.from([NULL_BYTE]), + key, + ]), + ]); + // Wrap up by creating a sequence of elements + const der = Buffer.concat([ + Buffer.from([ASN1_TAG_SEQUENCE]), + Buffer.from([elements.length]), + elements, + ]); + return der; + }, +}; +const ecdsa = { + hexToDER: (hex) => { + const key = Buffer.from(hex, 'hex'); + const bitString = Buffer.concat([ + Buffer.from([ANS1_TAG_BIT_STRING]), + Buffer.from([key.length + 1]), + Buffer.from([NULL_BYTE]), + key, + ]); + const oids = Buffer.concat([ + (0, oid_1.encodeOIDString)(OID_EC_PUBLIC_KEY), + (0, oid_1.encodeOIDString)(OID_EC_CURVE_P256V1), + ]); + const oidSequence = Buffer.concat([ + Buffer.from([ASN1_TAG_SEQUENCE]), + Buffer.from([oids.length]), + oids, + ]); + // Wrap up by creating a sequence of elements + const der = Buffer.concat([ + Buffer.from([ASN1_TAG_SEQUENCE]), + Buffer.from([oidSequence.length + bitString.length]), + oidSequence, + bitString, + ]); + return der; + }, +}; +const isHex = (key) => /^[0-9a-fA-F]+$/.test(key); diff --git a/node_modules/@tufjs/models/dist/utils/oid.js b/node_modules/@tufjs/models/dist/utils/oid.js new file mode 100644 index 0000000000000..00b29c3030d1e --- /dev/null +++ b/node_modules/@tufjs/models/dist/utils/oid.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.encodeOIDString = encodeOIDString; +const ANS1_TAG_OID = 0x06; +function encodeOIDString(oid) { + const parts = oid.split('.'); + // The first two subidentifiers are encoded into the first byte + const first = parseInt(parts[0], 10) * 40 + parseInt(parts[1], 10); + const rest = []; + parts.slice(2).forEach((part) => { + const bytes = encodeVariableLengthInteger(parseInt(part, 10)); + rest.push(...bytes); + }); + const der = Buffer.from([first, ...rest]); + return Buffer.from([ANS1_TAG_OID, der.length, ...der]); +} +function encodeVariableLengthInteger(value) { + const bytes = []; + let mask = 0x00; + while (value > 0) { + bytes.unshift((value & 0x7f) | mask); + value >>= 7; + mask = 0x80; + } + return bytes; +} diff --git a/node_modules/@tufjs/models/dist/utils/types.js b/node_modules/@tufjs/models/dist/utils/types.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/@tufjs/models/dist/utils/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@tufjs/models/dist/utils/verify.js b/node_modules/@tufjs/models/dist/utils/verify.js new file mode 100644 index 0000000000000..8232b6f6a97ab --- /dev/null +++ b/node_modules/@tufjs/models/dist/utils/verify.js @@ -0,0 +1,13 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifySignature = void 0; +const canonical_json_1 = require("@tufjs/canonical-json"); +const crypto_1 = __importDefault(require("crypto")); +const verifySignature = (metaDataSignedData, key, signature) => { + const canonicalData = Buffer.from((0, canonical_json_1.canonicalize)(metaDataSignedData)); + return crypto_1.default.verify(undefined, canonicalData, key, Buffer.from(signature, 'hex')); +}; +exports.verifySignature = verifySignature; diff --git a/node_modules/@tufjs/models/package.json b/node_modules/@tufjs/models/package.json new file mode 100644 index 0000000000000..cf4410577d042 --- /dev/null +++ b/node_modules/@tufjs/models/package.json @@ -0,0 +1,37 @@ +{ + "name": "@tufjs/models", + "version": "4.1.0", + "description": "TUF metadata models", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "tsc --build tsconfig.build.json", + "clean": "rm -rf dist && rm tsconfig.build.tsbuildinfo", + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/theupdateframework/tuf-js.git" + }, + "keywords": [ + "tuf", + "security", + "update" + ], + "author": "bdehamer@github.com", + "license": "MIT", + "bugs": { + "url": "https://github.com/theupdateframework/tuf-js/issues" + }, + "homepage": "https://github.com/theupdateframework/tuf-js/tree/main/packages/models#readme", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/abbrev/abbrev.js b/node_modules/abbrev/abbrev.js deleted file mode 100644 index 7b1dc5d67694a..0000000000000 --- a/node_modules/abbrev/abbrev.js +++ /dev/null @@ -1,61 +0,0 @@ -module.exports = exports = abbrev.abbrev = abbrev - -abbrev.monkeyPatch = monkeyPatch - -function monkeyPatch () { - Object.defineProperty(Array.prototype, 'abbrev', { - value: function () { return abbrev(this) }, - enumerable: false, configurable: true, writable: true - }) - - Object.defineProperty(Object.prototype, 'abbrev', { - value: function () { return abbrev(Object.keys(this)) }, - enumerable: false, configurable: true, writable: true - }) -} - -function abbrev (list) { - if (arguments.length !== 1 || !Array.isArray(list)) { - list = Array.prototype.slice.call(arguments, 0) - } - for (var i = 0, l = list.length, args = [] ; i < l ; i ++) { - args[i] = typeof list[i] === "string" ? list[i] : String(list[i]) - } - - // sort them lexicographically, so that they're next to their nearest kin - args = args.sort(lexSort) - - // walk through each, seeing how much it has in common with the next and previous - var abbrevs = {} - , prev = "" - for (var i = 0, l = args.length ; i < l ; i ++) { - var current = args[i] - , next = args[i + 1] || "" - , nextMatches = true - , prevMatches = true - if (current === next) continue - for (var j = 0, cl = current.length ; j < cl ; j ++) { - var curChar = current.charAt(j) - nextMatches = nextMatches && curChar === next.charAt(j) - prevMatches = prevMatches && curChar === prev.charAt(j) - if (!nextMatches && !prevMatches) { - j ++ - break - } - } - prev = current - if (j === cl) { - abbrevs[current] = current - continue - } - for (var a = current.substr(0, j) ; j <= cl ; j ++) { - abbrevs[a] = current - a += current.charAt(j) - } - } - return abbrevs -} - -function lexSort (a, b) { - return a === b ? 0 : a > b ? 1 : -1 -} diff --git a/node_modules/abbrev/lib/index.js b/node_modules/abbrev/lib/index.js new file mode 100644 index 0000000000000..f7bee0c6fc7ad --- /dev/null +++ b/node_modules/abbrev/lib/index.js @@ -0,0 +1,53 @@ +module.exports = abbrev + +function abbrev (...args) { + let list = args + if (args.length === 1 && (Array.isArray(args[0]) || typeof args[0] === 'string')) { + list = [].concat(args[0]) + } + + for (let i = 0, l = list.length; i < l; i++) { + list[i] = typeof list[i] === 'string' ? list[i] : String(list[i]) + } + + // sort them lexicographically, so that they're next to their nearest kin + list = list.sort(lexSort) + + // walk through each, seeing how much it has in common with the next and previous + const abbrevs = {} + let prev = '' + for (let ii = 0, ll = list.length; ii < ll; ii++) { + const current = list[ii] + const next = list[ii + 1] || '' + let nextMatches = true + let prevMatches = true + if (current === next) { + continue + } + let j = 0 + const cl = current.length + for (; j < cl; j++) { + const curChar = current.charAt(j) + nextMatches = nextMatches && curChar === next.charAt(j) + prevMatches = prevMatches && curChar === prev.charAt(j) + if (!nextMatches && !prevMatches) { + j++ + break + } + } + prev = current + if (j === cl) { + abbrevs[current] = current + continue + } + for (let a = current.slice(0, j); j <= cl; j++) { + abbrevs[a] = current + a += current.charAt(j) + } + } + return abbrevs +} + +function lexSort (a, b) { + return a === b ? 0 : a > b ? 1 : -1 +} diff --git a/node_modules/abbrev/package.json b/node_modules/abbrev/package.json index bf4e8015bba9d..f17aaccfa56ad 100644 --- a/node_modules/abbrev/package.json +++ b/node_modules/abbrev/package.json @@ -1,21 +1,41 @@ { "name": "abbrev", - "version": "1.1.1", + "version": "4.0.0", "description": "Like ruby's abbrev module, but in js", - "author": "Isaac Z. Schlueter <i@izs.me>", - "main": "abbrev.js", + "author": "GitHub Inc.", + "main": "lib/index.js", "scripts": { - "test": "tap test.js --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" + "test": "node --test", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "node --test --test-update-snapshots", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "test:cover": "node --test --experimental-test-coverage --test-timeout=3000 --test-coverage-lines=100 --test-coverage-functions=100 --test-coverage-branches=100" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/abbrev-js.git" }, - "repository": "http://github.com/isaacs/abbrev-js", "license": "ISC", "devDependencies": { - "tap": "^10.1" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.26.1" }, "files": [ - "abbrev.js" - ] + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.26.1", + "publish": true, + "testRunner": "node:test", + "latestCiVersion": 24 + } } diff --git a/node_modules/agent-base/LICENSE b/node_modules/agent-base/LICENSE new file mode 100644 index 0000000000000..008728cb51847 --- /dev/null +++ b/node_modules/agent-base/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> + +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. \ No newline at end of file diff --git a/node_modules/agent-base/dist/helpers.js b/node_modules/agent-base/dist/helpers.js new file mode 100644 index 0000000000000..ef3f92022d455 --- /dev/null +++ b/node_modules/agent-base/dist/helpers.js @@ -0,0 +1,66 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.req = exports.json = exports.toBuffer = void 0; +const http = __importStar(require("http")); +const https = __importStar(require("https")); +async function toBuffer(stream) { + let length = 0; + const chunks = []; + for await (const chunk of stream) { + length += chunk.length; + chunks.push(chunk); + } + return Buffer.concat(chunks, length); +} +exports.toBuffer = toBuffer; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +async function json(stream) { + const buf = await toBuffer(stream); + const str = buf.toString('utf8'); + try { + return JSON.parse(str); + } + catch (_err) { + const err = _err; + err.message += ` (input: ${str})`; + throw err; + } +} +exports.json = json; +function req(url, opts = {}) { + const href = typeof url === 'string' ? url : url.href; + const req = (href.startsWith('https:') ? https : http).request(url, opts); + const promise = new Promise((resolve, reject) => { + req + .once('response', resolve) + .once('error', reject) + .end(); + }); + req.then = promise.then.bind(promise); + return req; +} +exports.req = req; +//# sourceMappingURL=helpers.js.map \ No newline at end of file diff --git a/node_modules/agent-base/dist/index.js b/node_modules/agent-base/dist/index.js new file mode 100644 index 0000000000000..57ac85205e8ab --- /dev/null +++ b/node_modules/agent-base/dist/index.js @@ -0,0 +1,178 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Agent = void 0; +const net = __importStar(require("net")); +const http = __importStar(require("http")); +const https_1 = require("https"); +__exportStar(require("./helpers"), exports); +const INTERNAL = Symbol('AgentBaseInternalState'); +class Agent extends http.Agent { + constructor(opts) { + super(opts); + this[INTERNAL] = {}; + } + /** + * Determine whether this is an `http` or `https` request. + */ + isSecureEndpoint(options) { + if (options) { + // First check the `secureEndpoint` property explicitly, since this + // means that a parent `Agent` is "passing through" to this instance. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (typeof options.secureEndpoint === 'boolean') { + return options.secureEndpoint; + } + // If no explicit `secure` endpoint, check if `protocol` property is + // set. This will usually be the case since using a full string URL + // or `URL` instance should be the most common usage. + if (typeof options.protocol === 'string') { + return options.protocol === 'https:'; + } + } + // Finally, if no `protocol` property was set, then fall back to + // checking the stack trace of the current call stack, and try to + // detect the "https" module. + const { stack } = new Error(); + if (typeof stack !== 'string') + return false; + return stack + .split('\n') + .some((l) => l.indexOf('(https.js:') !== -1 || + l.indexOf('node:https:') !== -1); + } + // In order to support async signatures in `connect()` and Node's native + // connection pooling in `http.Agent`, the array of sockets for each origin + // has to be updated synchronously. This is so the length of the array is + // accurate when `addRequest()` is next called. We achieve this by creating a + // fake socket and adding it to `sockets[origin]` and incrementing + // `totalSocketCount`. + incrementSockets(name) { + // If `maxSockets` and `maxTotalSockets` are both Infinity then there is no + // need to create a fake socket because Node.js native connection pooling + // will never be invoked. + if (this.maxSockets === Infinity && this.maxTotalSockets === Infinity) { + return null; + } + // All instances of `sockets` are expected TypeScript errors. The + // alternative is to add it as a private property of this class but that + // will break TypeScript subclassing. + if (!this.sockets[name]) { + // @ts-expect-error `sockets` is readonly in `@types/node` + this.sockets[name] = []; + } + const fakeSocket = new net.Socket({ writable: false }); + this.sockets[name].push(fakeSocket); + // @ts-expect-error `totalSocketCount` isn't defined in `@types/node` + this.totalSocketCount++; + return fakeSocket; + } + decrementSockets(name, socket) { + if (!this.sockets[name] || socket === null) { + return; + } + const sockets = this.sockets[name]; + const index = sockets.indexOf(socket); + if (index !== -1) { + sockets.splice(index, 1); + // @ts-expect-error `totalSocketCount` isn't defined in `@types/node` + this.totalSocketCount--; + if (sockets.length === 0) { + // @ts-expect-error `sockets` is readonly in `@types/node` + delete this.sockets[name]; + } + } + } + // In order to properly update the socket pool, we need to call `getName()` on + // the core `https.Agent` if it is a secureEndpoint. + getName(options) { + const secureEndpoint = this.isSecureEndpoint(options); + if (secureEndpoint) { + // @ts-expect-error `getName()` isn't defined in `@types/node` + return https_1.Agent.prototype.getName.call(this, options); + } + // @ts-expect-error `getName()` isn't defined in `@types/node` + return super.getName(options); + } + createSocket(req, options, cb) { + const connectOpts = { + ...options, + secureEndpoint: this.isSecureEndpoint(options), + }; + const name = this.getName(connectOpts); + const fakeSocket = this.incrementSockets(name); + Promise.resolve() + .then(() => this.connect(req, connectOpts)) + .then((socket) => { + this.decrementSockets(name, fakeSocket); + if (socket instanceof http.Agent) { + try { + // @ts-expect-error `addRequest()` isn't defined in `@types/node` + return socket.addRequest(req, connectOpts); + } + catch (err) { + return cb(err); + } + } + this[INTERNAL].currentSocket = socket; + // @ts-expect-error `createSocket()` isn't defined in `@types/node` + super.createSocket(req, options, cb); + }, (err) => { + this.decrementSockets(name, fakeSocket); + cb(err); + }); + } + createConnection() { + const socket = this[INTERNAL].currentSocket; + this[INTERNAL].currentSocket = undefined; + if (!socket) { + throw new Error('No socket was returned in the `connect()` function'); + } + return socket; + } + get defaultPort() { + return (this[INTERNAL].defaultPort ?? + (this.protocol === 'https:' ? 443 : 80)); + } + set defaultPort(v) { + if (this[INTERNAL]) { + this[INTERNAL].defaultPort = v; + } + } + get protocol() { + return (this[INTERNAL].protocol ?? + (this.isSecureEndpoint() ? 'https:' : 'http:')); + } + set protocol(v) { + if (this[INTERNAL]) { + this[INTERNAL].protocol = v; + } + } +} +exports.Agent = Agent; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/agent-base/dist/src/index.d.ts b/node_modules/agent-base/dist/src/index.d.ts deleted file mode 100644 index bc4ab744c59c8..0000000000000 --- a/node_modules/agent-base/dist/src/index.d.ts +++ /dev/null @@ -1,78 +0,0 @@ -/// <reference types="node" /> -import net from 'net'; -import http from 'http'; -import https from 'https'; -import { Duplex } from 'stream'; -import { EventEmitter } from 'events'; -declare function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent; -declare function createAgent(callback: createAgent.AgentCallback, opts?: createAgent.AgentOptions): createAgent.Agent; -declare namespace createAgent { - interface ClientRequest extends http.ClientRequest { - _last?: boolean; - _hadError?: boolean; - method: string; - } - interface AgentRequestOptions { - host?: string; - path?: string; - port: number; - } - interface HttpRequestOptions extends AgentRequestOptions, Omit<http.RequestOptions, keyof AgentRequestOptions> { - secureEndpoint: false; - } - interface HttpsRequestOptions extends AgentRequestOptions, Omit<https.RequestOptions, keyof AgentRequestOptions> { - secureEndpoint: true; - } - type RequestOptions = HttpRequestOptions | HttpsRequestOptions; - type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent; - type AgentCallbackReturn = Duplex | AgentLike; - type AgentCallbackCallback = (err?: Error | null, socket?: createAgent.AgentCallbackReturn) => void; - type AgentCallbackPromise = (req: createAgent.ClientRequest, opts: createAgent.RequestOptions) => createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>; - type AgentCallback = typeof Agent.prototype.callback; - type AgentOptions = { - timeout?: number; - }; - /** - * Base `http.Agent` implementation. - * No pooling/keep-alive is implemented by default. - * - * @param {Function} callback - * @api public - */ - class Agent extends EventEmitter { - timeout: number | null; - maxFreeSockets: number; - maxTotalSockets: number; - maxSockets: number; - sockets: { - [key: string]: net.Socket[]; - }; - freeSockets: { - [key: string]: net.Socket[]; - }; - requests: { - [key: string]: http.IncomingMessage[]; - }; - options: https.AgentOptions; - private promisifiedCallback?; - private explicitDefaultPort?; - private explicitProtocol?; - constructor(callback?: createAgent.AgentCallback | createAgent.AgentOptions, _opts?: createAgent.AgentOptions); - get defaultPort(): number; - set defaultPort(v: number); - get protocol(): string; - set protocol(v: string); - callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions, fn: createAgent.AgentCallbackCallback): void; - callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions): createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>; - /** - * Called by node-core's "_http_client.js" module when creating - * a new HTTP request with this Agent instance. - * - * @api public - */ - addRequest(req: ClientRequest, _opts: RequestOptions): void; - freeSocket(socket: net.Socket, opts: AgentOptions): void; - destroy(): void; - } -} -export = createAgent; diff --git a/node_modules/agent-base/dist/src/index.js b/node_modules/agent-base/dist/src/index.js deleted file mode 100644 index bfd9e22071e7e..0000000000000 --- a/node_modules/agent-base/dist/src/index.js +++ /dev/null @@ -1,203 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -const events_1 = require("events"); -const debug_1 = __importDefault(require("debug")); -const promisify_1 = __importDefault(require("./promisify")); -const debug = debug_1.default('agent-base'); -function isAgent(v) { - return Boolean(v) && typeof v.addRequest === 'function'; -} -function isSecureEndpoint() { - const { stack } = new Error(); - if (typeof stack !== 'string') - return false; - return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1); -} -function createAgent(callback, opts) { - return new createAgent.Agent(callback, opts); -} -(function (createAgent) { - /** - * Base `http.Agent` implementation. - * No pooling/keep-alive is implemented by default. - * - * @param {Function} callback - * @api public - */ - class Agent extends events_1.EventEmitter { - constructor(callback, _opts) { - super(); - let opts = _opts; - if (typeof callback === 'function') { - this.callback = callback; - } - else if (callback) { - opts = callback; - } - // Timeout for the socket to be returned from the callback - this.timeout = null; - if (opts && typeof opts.timeout === 'number') { - this.timeout = opts.timeout; - } - // These aren't actually used by `agent-base`, but are required - // for the TypeScript definition files in `@types/node` :/ - this.maxFreeSockets = 1; - this.maxSockets = 1; - this.maxTotalSockets = Infinity; - this.sockets = {}; - this.freeSockets = {}; - this.requests = {}; - this.options = {}; - } - get defaultPort() { - if (typeof this.explicitDefaultPort === 'number') { - return this.explicitDefaultPort; - } - return isSecureEndpoint() ? 443 : 80; - } - set defaultPort(v) { - this.explicitDefaultPort = v; - } - get protocol() { - if (typeof this.explicitProtocol === 'string') { - return this.explicitProtocol; - } - return isSecureEndpoint() ? 'https:' : 'http:'; - } - set protocol(v) { - this.explicitProtocol = v; - } - callback(req, opts, fn) { - throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`'); - } - /** - * Called by node-core's "_http_client.js" module when creating - * a new HTTP request with this Agent instance. - * - * @api public - */ - addRequest(req, _opts) { - const opts = Object.assign({}, _opts); - if (typeof opts.secureEndpoint !== 'boolean') { - opts.secureEndpoint = isSecureEndpoint(); - } - if (opts.host == null) { - opts.host = 'localhost'; - } - if (opts.port == null) { - opts.port = opts.secureEndpoint ? 443 : 80; - } - if (opts.protocol == null) { - opts.protocol = opts.secureEndpoint ? 'https:' : 'http:'; - } - if (opts.host && opts.path) { - // If both a `host` and `path` are specified then it's most - // likely the result of a `url.parse()` call... we need to - // remove the `path` portion so that `net.connect()` doesn't - // attempt to open that as a unix socket file. - delete opts.path; - } - delete opts.agent; - delete opts.hostname; - delete opts._defaultAgent; - delete opts.defaultPort; - delete opts.createConnection; - // Hint to use "Connection: close" - // XXX: non-documented `http` module API :( - req._last = true; - req.shouldKeepAlive = false; - let timedOut = false; - let timeoutId = null; - const timeoutMs = opts.timeout || this.timeout; - const onerror = (err) => { - if (req._hadError) - return; - req.emit('error', err); - // For Safety. Some additional errors might fire later on - // and we need to make sure we don't double-fire the error event. - req._hadError = true; - }; - const ontimeout = () => { - timeoutId = null; - timedOut = true; - const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`); - err.code = 'ETIMEOUT'; - onerror(err); - }; - const callbackError = (err) => { - if (timedOut) - return; - if (timeoutId !== null) { - clearTimeout(timeoutId); - timeoutId = null; - } - onerror(err); - }; - const onsocket = (socket) => { - if (timedOut) - return; - if (timeoutId != null) { - clearTimeout(timeoutId); - timeoutId = null; - } - if (isAgent(socket)) { - // `socket` is actually an `http.Agent` instance, so - // relinquish responsibility for this `req` to the Agent - // from here on - debug('Callback returned another Agent instance %o', socket.constructor.name); - socket.addRequest(req, opts); - return; - } - if (socket) { - socket.once('free', () => { - this.freeSocket(socket, opts); - }); - req.onSocket(socket); - return; - } - const err = new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``); - onerror(err); - }; - if (typeof this.callback !== 'function') { - onerror(new Error('`callback` is not defined')); - return; - } - if (!this.promisifiedCallback) { - if (this.callback.length >= 3) { - debug('Converting legacy callback function to promise'); - this.promisifiedCallback = promisify_1.default(this.callback); - } - else { - this.promisifiedCallback = this.callback; - } - } - if (typeof timeoutMs === 'number' && timeoutMs > 0) { - timeoutId = setTimeout(ontimeout, timeoutMs); - } - if ('port' in opts && typeof opts.port !== 'number') { - opts.port = Number(opts.port); - } - try { - debug('Resolving socket for %o request: %o', opts.protocol, `${req.method} ${req.path}`); - Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError); - } - catch (err) { - Promise.reject(err).catch(callbackError); - } - } - freeSocket(socket, opts) { - debug('Freeing socket %o %o', socket.constructor.name, opts); - socket.destroy(); - } - destroy() { - debug('Destroying agent %o', this.constructor.name); - } - } - createAgent.Agent = Agent; - // So that `instanceof` works correctly - createAgent.prototype = createAgent.Agent.prototype; -})(createAgent || (createAgent = {})); -module.exports = createAgent; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/agent-base/dist/src/index.js.map b/node_modules/agent-base/dist/src/index.js.map deleted file mode 100644 index bd118ab6bb1ce..0000000000000 --- a/node_modules/agent-base/dist/src/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAIA,mCAAsC;AACtC,kDAAgC;AAChC,4DAAoC;AAEpC,MAAM,KAAK,GAAG,eAAW,CAAC,YAAY,CAAC,CAAC;AAExC,SAAS,OAAO,CAAC,CAAM;IACtB,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC;AACzD,CAAC;AAED,SAAS,gBAAgB;IACxB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,EAAE,CAAC;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAK,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxG,CAAC;AAOD,SAAS,WAAW,CACnB,QAA+D,EAC/D,IAA+B;IAE/B,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED,WAAU,WAAW;IAmDpB;;;;;;OAMG;IACH,MAAa,KAAM,SAAQ,qBAAY;QAmBtC,YACC,QAA+D,EAC/D,KAAgC;YAEhC,KAAK,EAAE,CAAC;YAER,IAAI,IAAI,GAAG,KAAK,CAAC;YACjB,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;gBACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;aACzB;iBAAM,IAAI,QAAQ,EAAE;gBACpB,IAAI,GAAG,QAAQ,CAAC;aAChB;YAED,0DAA0D;YAC1D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE;gBAC7C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;aAC5B;YAED,+DAA+D;YAC/D,0DAA0D;YAC1D,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;YACpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;YAChC,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,IAAI,WAAW;YACd,IAAI,OAAO,IAAI,CAAC,mBAAmB,KAAK,QAAQ,EAAE;gBACjD,OAAO,IAAI,CAAC,mBAAmB,CAAC;aAChC;YACD,OAAO,gBAAgB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,CAAC;QAED,IAAI,WAAW,CAAC,CAAS;YACxB,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,QAAQ;YACX,IAAI,OAAO,IAAI,CAAC,gBAAgB,KAAK,QAAQ,EAAE;gBAC9C,OAAO,IAAI,CAAC,gBAAgB,CAAC;aAC7B;YACD,OAAO,gBAAgB,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;QAChD,CAAC;QAED,IAAI,QAAQ,CAAC,CAAS;YACrB,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC3B,CAAC;QAaD,QAAQ,CACP,GAA8B,EAC9B,IAA8B,EAC9B,EAAsC;YAKtC,MAAM,IAAI,KAAK,CACd,yFAAyF,CACzF,CAAC;QACH,CAAC;QAED;;;;;WAKG;QACH,UAAU,CAAC,GAAkB,EAAE,KAAqB;YACnD,MAAM,IAAI,qBAAwB,KAAK,CAAE,CAAC;YAE1C,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE;gBAC7C,IAAI,CAAC,cAAc,GAAG,gBAAgB,EAAE,CAAC;aACzC;YAED,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE;gBACtB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;aACxB;YAED,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE;gBACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3C;YAED,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE;gBAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;aACzD;YAED,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;gBAC3B,2DAA2D;gBAC3D,0DAA0D;gBAC1D,4DAA4D;gBAC5D,8CAA8C;gBAC9C,OAAO,IAAI,CAAC,IAAI,CAAC;aACjB;YAED,OAAO,IAAI,CAAC,KAAK,CAAC;YAClB,OAAO,IAAI,CAAC,QAAQ,CAAC;YACrB,OAAO,IAAI,CAAC,aAAa,CAAC;YAC1B,OAAO,IAAI,CAAC,WAAW,CAAC;YACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC;YAE7B,kCAAkC;YAClC,2CAA2C;YAC3C,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;YACjB,GAAG,CAAC,eAAe,GAAG,KAAK,CAAC;YAE5B,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,SAAS,GAAyC,IAAI,CAAC;YAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;YAE/C,MAAM,OAAO,GAAG,CAAC,GAA0B,EAAE,EAAE;gBAC9C,IAAI,GAAG,CAAC,SAAS;oBAAE,OAAO;gBAC1B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACvB,yDAAyD;gBACzD,iEAAiE;gBACjE,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,CAAC,CAAC;YAEF,MAAM,SAAS,GAAG,GAAG,EAAE;gBACtB,SAAS,GAAG,IAAI,CAAC;gBACjB,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,GAAG,GAA0B,IAAI,KAAK,CAC3C,sDAAsD,SAAS,IAAI,CACnE,CAAC;gBACF,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC;YAEF,MAAM,aAAa,GAAG,CAAC,GAA0B,EAAE,EAAE;gBACpD,IAAI,QAAQ;oBAAE,OAAO;gBACrB,IAAI,SAAS,KAAK,IAAI,EAAE;oBACvB,YAAY,CAAC,SAAS,CAAC,CAAC;oBACxB,SAAS,GAAG,IAAI,CAAC;iBACjB;gBACD,OAAO,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC;YAEF,MAAM,QAAQ,GAAG,CAAC,MAA2B,EAAE,EAAE;gBAChD,IAAI,QAAQ;oBAAE,OAAO;gBACrB,IAAI,SAAS,IAAI,IAAI,EAAE;oBACtB,YAAY,CAAC,SAAS,CAAC,CAAC;oBACxB,SAAS,GAAG,IAAI,CAAC;iBACjB;gBAED,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE;oBACpB,oDAAoD;oBACpD,wDAAwD;oBACxD,eAAe;oBACf,KAAK,CACJ,6CAA6C,EAC7C,MAAM,CAAC,WAAW,CAAC,IAAI,CACvB,CAAC;oBACD,MAA4B,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBACpD,OAAO;iBACP;gBAED,IAAI,MAAM,EAAE;oBACX,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;wBACxB,IAAI,CAAC,UAAU,CAAC,MAAoB,EAAE,IAAI,CAAC,CAAC;oBAC7C,CAAC,CAAC,CAAC;oBACH,GAAG,CAAC,QAAQ,CAAC,MAAoB,CAAC,CAAC;oBACnC,OAAO;iBACP;gBAED,MAAM,GAAG,GAAG,IAAI,KAAK,CACpB,qDAAqD,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,CAC/E,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC;YAEF,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE;gBACxC,OAAO,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;gBAChD,OAAO;aACP;YAED,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE;gBAC9B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE;oBAC9B,KAAK,CAAC,gDAAgD,CAAC,CAAC;oBACxD,IAAI,CAAC,mBAAmB,GAAG,mBAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;iBACpD;qBAAM;oBACN,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC;iBACzC;aACD;YAED,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,GAAG,CAAC,EAAE;gBACnD,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;aAC7C;YAED,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;gBACpD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC9B;YAED,IAAI;gBACH,KAAK,CACJ,qCAAqC,EACrC,IAAI,CAAC,QAAQ,EACb,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAC3B,CAAC;gBACF,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACxD,QAAQ,EACR,aAAa,CACb,CAAC;aACF;YAAC,OAAO,GAAG,EAAE;gBACb,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;aACzC;QACF,CAAC;QAED,UAAU,CAAC,MAAkB,EAAE,IAAkB;YAChD,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;QAED,OAAO;YACN,KAAK,CAAC,qBAAqB,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;KACD;IAxPY,iBAAK,QAwPjB,CAAA;IAED,uCAAuC;IACvC,WAAW,CAAC,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC;AACrD,CAAC,EAtTS,WAAW,KAAX,WAAW,QAsTpB;AAED,iBAAS,WAAW,CAAC"} \ No newline at end of file diff --git a/node_modules/agent-base/dist/src/promisify.d.ts b/node_modules/agent-base/dist/src/promisify.d.ts deleted file mode 100644 index 02688696fb4c1..0000000000000 --- a/node_modules/agent-base/dist/src/promisify.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ClientRequest, RequestOptions, AgentCallbackCallback, AgentCallbackPromise } from './index'; -declare type LegacyCallback = (req: ClientRequest, opts: RequestOptions, fn: AgentCallbackCallback) => void; -export default function promisify(fn: LegacyCallback): AgentCallbackPromise; -export {}; diff --git a/node_modules/agent-base/dist/src/promisify.js b/node_modules/agent-base/dist/src/promisify.js deleted file mode 100644 index b2f6132a7beaa..0000000000000 --- a/node_modules/agent-base/dist/src/promisify.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -function promisify(fn) { - return function (req, opts) { - return new Promise((resolve, reject) => { - fn.call(this, req, opts, (err, rtn) => { - if (err) { - reject(err); - } - else { - resolve(rtn); - } - }); - }); - }; -} -exports.default = promisify; -//# sourceMappingURL=promisify.js.map \ No newline at end of file diff --git a/node_modules/agent-base/dist/src/promisify.js.map b/node_modules/agent-base/dist/src/promisify.js.map deleted file mode 100644 index 4bff9bfcfa289..0000000000000 --- a/node_modules/agent-base/dist/src/promisify.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"promisify.js","sourceRoot":"","sources":["../../src/promisify.ts"],"names":[],"mappings":";;AAeA,SAAwB,SAAS,CAAC,EAAkB;IACnD,OAAO,UAAsB,GAAkB,EAAE,IAAoB;QACpE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,EAAE,CAAC,IAAI,CACN,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,CAAC,GAA6B,EAAE,GAAyB,EAAE,EAAE;gBAC5D,IAAI,GAAG,EAAE;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;iBACZ;qBAAM;oBACN,OAAO,CAAC,GAAG,CAAC,CAAC;iBACb;YACF,CAAC,CACD,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC;AAjBD,4BAiBC"} \ No newline at end of file diff --git a/node_modules/agent-base/package.json b/node_modules/agent-base/package.json index fadce3ad99f22..1b4964a83f66f 100644 --- a/node_modules/agent-base/package.json +++ b/node_modules/agent-base/package.json @@ -1,24 +1,16 @@ { "name": "agent-base", - "version": "6.0.2", + "version": "7.1.4", "description": "Turn a function into an `http.Agent` instance", - "main": "dist/src/index", - "typings": "dist/src/index", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "files": [ - "dist/src", - "src" + "dist" ], - "scripts": { - "prebuild": "rimraf dist", - "build": "tsc", - "postbuild": "cpy --parents src test '!**/*.ts' dist", - "test": "mocha --reporter spec dist/test/*.js", - "test-lint": "eslint src --ext .js,.ts", - "prepublishOnly": "npm run build" - }, "repository": { "type": "git", - "url": "git://github.com/TooTallNate/node-agent-base.git" + "url": "https://github.com/TooTallNate/proxy-agents.git", + "directory": "packages/agent-base" }, "keywords": [ "http", @@ -29,36 +21,26 @@ ], "author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)", "license": "MIT", - "bugs": { - "url": "https://github.com/TooTallNate/node-agent-base/issues" - }, - "dependencies": { - "debug": "4" - }, "devDependencies": { - "@types/debug": "4", - "@types/mocha": "^5.2.7", - "@types/node": "^14.0.20", - "@types/semver": "^7.1.0", - "@types/ws": "^6.0.3", - "@typescript-eslint/eslint-plugin": "1.6.0", - "@typescript-eslint/parser": "1.1.0", - "async-listen": "^1.2.0", - "cpy-cli": "^2.0.0", - "eslint": "5.16.0", - "eslint-config-airbnb": "17.1.0", - "eslint-config-prettier": "4.1.0", - "eslint-import-resolver-typescript": "1.1.1", - "eslint-plugin-import": "2.16.0", - "eslint-plugin-jsx-a11y": "6.2.1", - "eslint-plugin-react": "7.12.4", - "mocha": "^6.2.0", - "rimraf": "^3.0.0", - "semver": "^7.1.2", - "typescript": "^3.5.3", - "ws": "^3.0.0" + "@types/debug": "^4.1.7", + "@types/jest": "^29.5.1", + "@types/node": "^14.18.45", + "@types/semver": "^7.3.13", + "@types/ws": "^6.0.4", + "async-listen": "^3.0.0", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "typescript": "^5.0.4", + "ws": "^5.2.4", + "tsconfig": "0.0.0" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" + }, + "scripts": { + "build": "tsc", + "test": "jest --env node --verbose --bail", + "lint": "eslint . --ext .ts", + "pack": "node ../../scripts/pack.mjs" } -} +} \ No newline at end of file diff --git a/node_modules/agent-base/src/index.ts b/node_modules/agent-base/src/index.ts deleted file mode 100644 index a47ccd493f90a..0000000000000 --- a/node_modules/agent-base/src/index.ts +++ /dev/null @@ -1,345 +0,0 @@ -import net from 'net'; -import http from 'http'; -import https from 'https'; -import { Duplex } from 'stream'; -import { EventEmitter } from 'events'; -import createDebug from 'debug'; -import promisify from './promisify'; - -const debug = createDebug('agent-base'); - -function isAgent(v: any): v is createAgent.AgentLike { - return Boolean(v) && typeof v.addRequest === 'function'; -} - -function isSecureEndpoint(): boolean { - const { stack } = new Error(); - if (typeof stack !== 'string') return false; - return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1); -} - -function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent; -function createAgent( - callback: createAgent.AgentCallback, - opts?: createAgent.AgentOptions -): createAgent.Agent; -function createAgent( - callback?: createAgent.AgentCallback | createAgent.AgentOptions, - opts?: createAgent.AgentOptions -) { - return new createAgent.Agent(callback, opts); -} - -namespace createAgent { - export interface ClientRequest extends http.ClientRequest { - _last?: boolean; - _hadError?: boolean; - method: string; - } - - export interface AgentRequestOptions { - host?: string; - path?: string; - // `port` on `http.RequestOptions` can be a string or undefined, - // but `net.TcpNetConnectOpts` expects only a number - port: number; - } - - export interface HttpRequestOptions - extends AgentRequestOptions, - Omit<http.RequestOptions, keyof AgentRequestOptions> { - secureEndpoint: false; - } - - export interface HttpsRequestOptions - extends AgentRequestOptions, - Omit<https.RequestOptions, keyof AgentRequestOptions> { - secureEndpoint: true; - } - - export type RequestOptions = HttpRequestOptions | HttpsRequestOptions; - - export type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent; - - export type AgentCallbackReturn = Duplex | AgentLike; - - export type AgentCallbackCallback = ( - err?: Error | null, - socket?: createAgent.AgentCallbackReturn - ) => void; - - export type AgentCallbackPromise = ( - req: createAgent.ClientRequest, - opts: createAgent.RequestOptions - ) => - | createAgent.AgentCallbackReturn - | Promise<createAgent.AgentCallbackReturn>; - - export type AgentCallback = typeof Agent.prototype.callback; - - export type AgentOptions = { - timeout?: number; - }; - - /** - * Base `http.Agent` implementation. - * No pooling/keep-alive is implemented by default. - * - * @param {Function} callback - * @api public - */ - export class Agent extends EventEmitter { - public timeout: number | null; - public maxFreeSockets: number; - public maxTotalSockets: number; - public maxSockets: number; - public sockets: { - [key: string]: net.Socket[]; - }; - public freeSockets: { - [key: string]: net.Socket[]; - }; - public requests: { - [key: string]: http.IncomingMessage[]; - }; - public options: https.AgentOptions; - private promisifiedCallback?: createAgent.AgentCallbackPromise; - private explicitDefaultPort?: number; - private explicitProtocol?: string; - - constructor( - callback?: createAgent.AgentCallback | createAgent.AgentOptions, - _opts?: createAgent.AgentOptions - ) { - super(); - - let opts = _opts; - if (typeof callback === 'function') { - this.callback = callback; - } else if (callback) { - opts = callback; - } - - // Timeout for the socket to be returned from the callback - this.timeout = null; - if (opts && typeof opts.timeout === 'number') { - this.timeout = opts.timeout; - } - - // These aren't actually used by `agent-base`, but are required - // for the TypeScript definition files in `@types/node` :/ - this.maxFreeSockets = 1; - this.maxSockets = 1; - this.maxTotalSockets = Infinity; - this.sockets = {}; - this.freeSockets = {}; - this.requests = {}; - this.options = {}; - } - - get defaultPort(): number { - if (typeof this.explicitDefaultPort === 'number') { - return this.explicitDefaultPort; - } - return isSecureEndpoint() ? 443 : 80; - } - - set defaultPort(v: number) { - this.explicitDefaultPort = v; - } - - get protocol(): string { - if (typeof this.explicitProtocol === 'string') { - return this.explicitProtocol; - } - return isSecureEndpoint() ? 'https:' : 'http:'; - } - - set protocol(v: string) { - this.explicitProtocol = v; - } - - callback( - req: createAgent.ClientRequest, - opts: createAgent.RequestOptions, - fn: createAgent.AgentCallbackCallback - ): void; - callback( - req: createAgent.ClientRequest, - opts: createAgent.RequestOptions - ): - | createAgent.AgentCallbackReturn - | Promise<createAgent.AgentCallbackReturn>; - callback( - req: createAgent.ClientRequest, - opts: createAgent.AgentOptions, - fn?: createAgent.AgentCallbackCallback - ): - | createAgent.AgentCallbackReturn - | Promise<createAgent.AgentCallbackReturn> - | void { - throw new Error( - '"agent-base" has no default implementation, you must subclass and override `callback()`' - ); - } - - /** - * Called by node-core's "_http_client.js" module when creating - * a new HTTP request with this Agent instance. - * - * @api public - */ - addRequest(req: ClientRequest, _opts: RequestOptions): void { - const opts: RequestOptions = { ..._opts }; - - if (typeof opts.secureEndpoint !== 'boolean') { - opts.secureEndpoint = isSecureEndpoint(); - } - - if (opts.host == null) { - opts.host = 'localhost'; - } - - if (opts.port == null) { - opts.port = opts.secureEndpoint ? 443 : 80; - } - - if (opts.protocol == null) { - opts.protocol = opts.secureEndpoint ? 'https:' : 'http:'; - } - - if (opts.host && opts.path) { - // If both a `host` and `path` are specified then it's most - // likely the result of a `url.parse()` call... we need to - // remove the `path` portion so that `net.connect()` doesn't - // attempt to open that as a unix socket file. - delete opts.path; - } - - delete opts.agent; - delete opts.hostname; - delete opts._defaultAgent; - delete opts.defaultPort; - delete opts.createConnection; - - // Hint to use "Connection: close" - // XXX: non-documented `http` module API :( - req._last = true; - req.shouldKeepAlive = false; - - let timedOut = false; - let timeoutId: ReturnType<typeof setTimeout> | null = null; - const timeoutMs = opts.timeout || this.timeout; - - const onerror = (err: NodeJS.ErrnoException) => { - if (req._hadError) return; - req.emit('error', err); - // For Safety. Some additional errors might fire later on - // and we need to make sure we don't double-fire the error event. - req._hadError = true; - }; - - const ontimeout = () => { - timeoutId = null; - timedOut = true; - const err: NodeJS.ErrnoException = new Error( - `A "socket" was not created for HTTP request before ${timeoutMs}ms` - ); - err.code = 'ETIMEOUT'; - onerror(err); - }; - - const callbackError = (err: NodeJS.ErrnoException) => { - if (timedOut) return; - if (timeoutId !== null) { - clearTimeout(timeoutId); - timeoutId = null; - } - onerror(err); - }; - - const onsocket = (socket: AgentCallbackReturn) => { - if (timedOut) return; - if (timeoutId != null) { - clearTimeout(timeoutId); - timeoutId = null; - } - - if (isAgent(socket)) { - // `socket` is actually an `http.Agent` instance, so - // relinquish responsibility for this `req` to the Agent - // from here on - debug( - 'Callback returned another Agent instance %o', - socket.constructor.name - ); - (socket as createAgent.Agent).addRequest(req, opts); - return; - } - - if (socket) { - socket.once('free', () => { - this.freeSocket(socket as net.Socket, opts); - }); - req.onSocket(socket as net.Socket); - return; - } - - const err = new Error( - `no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\`` - ); - onerror(err); - }; - - if (typeof this.callback !== 'function') { - onerror(new Error('`callback` is not defined')); - return; - } - - if (!this.promisifiedCallback) { - if (this.callback.length >= 3) { - debug('Converting legacy callback function to promise'); - this.promisifiedCallback = promisify(this.callback); - } else { - this.promisifiedCallback = this.callback; - } - } - - if (typeof timeoutMs === 'number' && timeoutMs > 0) { - timeoutId = setTimeout(ontimeout, timeoutMs); - } - - if ('port' in opts && typeof opts.port !== 'number') { - opts.port = Number(opts.port); - } - - try { - debug( - 'Resolving socket for %o request: %o', - opts.protocol, - `${req.method} ${req.path}` - ); - Promise.resolve(this.promisifiedCallback(req, opts)).then( - onsocket, - callbackError - ); - } catch (err) { - Promise.reject(err).catch(callbackError); - } - } - - freeSocket(socket: net.Socket, opts: AgentOptions) { - debug('Freeing socket %o %o', socket.constructor.name, opts); - socket.destroy(); - } - - destroy() { - debug('Destroying agent %o', this.constructor.name); - } - } - - // So that `instanceof` works correctly - createAgent.prototype = createAgent.Agent.prototype; -} - -export = createAgent; diff --git a/node_modules/agent-base/src/promisify.ts b/node_modules/agent-base/src/promisify.ts deleted file mode 100644 index 60cc6627100b8..0000000000000 --- a/node_modules/agent-base/src/promisify.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - Agent, - ClientRequest, - RequestOptions, - AgentCallbackCallback, - AgentCallbackPromise, - AgentCallbackReturn -} from './index'; - -type LegacyCallback = ( - req: ClientRequest, - opts: RequestOptions, - fn: AgentCallbackCallback -) => void; - -export default function promisify(fn: LegacyCallback): AgentCallbackPromise { - return function(this: Agent, req: ClientRequest, opts: RequestOptions) { - return new Promise((resolve, reject) => { - fn.call( - this, - req, - opts, - (err: Error | null | undefined, rtn?: AgentCallbackReturn) => { - if (err) { - reject(err); - } else { - resolve(rtn); - } - } - ); - }); - }; -} diff --git a/node_modules/agentkeepalive/History.md b/node_modules/agentkeepalive/History.md deleted file mode 100644 index 9db6e5576d42b..0000000000000 --- a/node_modules/agentkeepalive/History.md +++ /dev/null @@ -1,248 +0,0 @@ - -4.2.1 / 2022-02-21 -================== - -**fixes** - * [[`8b13b5c`](http://github.com/node-modules/agentkeepalive/commit/8b13b5ca797f4779a0a8d393ad8ecb622cd27987)] - fix: explicitly set `| undefined` in type definitions (#99) (Benoit Lemoine <<lemoine.benoit@gmail.com>>) - -4.2.0 / 2021-12-31 -================== - -**fixes** - * [[`f418c67`](http://github.com/node-modules/agentkeepalive/commit/f418c67a63c061c7261592d4553bc455e0b0d306)] - fix: change `freeSocketTimeout` default value to 4000 (#102) (fengmk2 <<fengmk2@gmail.com>>) - -**others** - * [[`bc2a1ce`](http://github.com/node-modules/agentkeepalive/commit/bc2a1cea0884b4d18b0d244bf00006d9107963df)] - doc(readme): making `timeout`'s default clear (#100) (Aaron <<aaronarinder@gmail.com>>) - -4.1.4 / 2021-02-05 -================== - -**fixes** - * [[`4d04794`](http://github.com/node-modules/agentkeepalive/commit/4d047946b1547b4edff92ea40205aee4f0c8aa46)] - fix(types): correct `Https` constructor argument (#89) (Simen Bekkhus <<sbekkhus91@gmail.com>>) - -4.1.3 / 2020-06-15 -================== - -**fixes** - * [[`4ba9f9c`](http://github.com/node-modules/agentkeepalive/commit/4ba9f9c844f2a6b8037ce56599d25c69ef054d91)] - fix: compatible with node v12.16.3 (#91) (killa <<killa123@126.com>>) - -4.1.2 / 2020-04-25 -================== - -**fixes** - * [[`de66b02`](http://github.com/node-modules/agentkeepalive/commit/de66b0206d064a97129c2c31bcdabd4d64557b91)] - fix: detect http request timeout handler (#88) (fengmk2 <<fengmk2@gmail.com>>) - -4.1.1 / 2020-04-25 -================== - -**fixes** - * [[`bbd20c0`](http://github.com/node-modules/agentkeepalive/commit/bbd20c03b8cf7dfb00b3aad1ada26d4ab90d2d6e)] - fix: definition error (#87) (吖猩 <<whxaxes@qq.com>>) - -**others** - * [[`3b01699`](http://github.com/node-modules/agentkeepalive/commit/3b01699b8e90022d5f56898dd709e4fe7ee7cdaa)] - test: run test on node 12 (#84) (Igor Savin <<iselwin@gmail.com>>) - -4.1.0 / 2019-10-12 -================== - -**features** - * [[`fe33b80`](http://github.com/node-modules/agentkeepalive/commit/fe33b800acc09109388bfe65107550952b6fc7b0)] - feat: Add `reusedSocket` property on client request (#82) (Weijia Wang <<starkwang@126.com>>) - -**others** - * [[`77ba744`](http://github.com/node-modules/agentkeepalive/commit/77ba744667bb6b9e5986a53e5222f62094db12b9)] - docs: fix grammar in readme (#81) (Herrington Darkholme <<2883231+HerringtonDarkholme@users.noreply.github.com>>) - -4.0.2 / 2019-02-19 -================== - -**fixes** - * [[`56d4a9b`](http://github.com/node-modules/agentkeepalive/commit/56d4a9b2a4499ea28943ddb590358d7831a02cb1)] - fix: HttpAgent export = internal (#74) (Andrew Leedham <<AndrewLeedham@outlook.com>>) - -4.0.1 / 2019-02-19 -================== - -**fixes** - * [[`bad1ac0`](http://github.com/node-modules/agentkeepalive/commit/bad1ac0e710fbc486717e14e68c59266d35df6a8)] - fix: HttpsAgent Type Definition (#71) (#72) (Andrew Leedham <<AndrewLeedham@outlook.com>>) - * [[`f48a4a7`](http://github.com/node-modules/agentkeepalive/commit/f48a4a701ea6fbe43781c91e1c0aaad6e328ac7f)] - fix: export interface (#70) (Vinay <<vinaybedre@gmail.com>>) - -**others** - * [[`9124343`](http://github.com/node-modules/agentkeepalive/commit/91243437cfdd324cb97f39dee76746d5e5f4cd72)] - chore: add agent.options.keepAlive instead agent.keepAlive (fengmk2 <<fengmk2@gmail.com>>) - * [[`d177d40`](http://github.com/node-modules/agentkeepalive/commit/d177d40422fe7296990b4e270cf498e3f33c18fa)] - test: add request timeout bigger than agent timeout cases (fengmk2 <<fengmk2@gmail.com>>) - -4.0.0 / 2018-10-23 -================== - -**features** - * [[`5c9f3bb`](http://github.com/node-modules/agentkeepalive/commit/5c9f3bbd60555744edcf777105b148982a1a42b6)] - feat: impl the new Agent extend http.Agent (fengmk2 <<fengmk2@gmail.com>>) - -**others** - * [[`498c8f1`](http://github.com/node-modules/agentkeepalive/commit/498c8f13cf76600d3dd6e1c91cdf2d8292355dff)] - chore: move LICENSE from readme to file (fengmk2 <<fengmk2@gmail.com>>) - * [[`4f39894`](http://github.com/node-modules/agentkeepalive/commit/4f398942ba2f90cf4501239e56ac4e6344931a01)] - bugfix: support agent.options.timeout on https agent (fengmk2 <<fengmk2@gmail.com>>) - -3.5.2 / 2018-10-19 -================== - -**fixes** - * [[`5751fc1`](http://github.com/node-modules/agentkeepalive/commit/5751fc1180ed6544602c681ffbd08ca66a0cb12c)] - fix: sockLen being miscalculated when removing sockets (#60) (Ehden Sinai <<cixel@users.noreply.github.com>>) - -3.5.1 / 2018-07-31 -================== - -**fixes** - * [[`495f1ab`](http://github.com/node-modules/agentkeepalive/commit/495f1ab625d43945d72f68096b97db723d4f0657)] - fix: add the lost npm files (#66) (Henry Zhuang <<zhuanghengfei@gmail.com>>) - -3.5.0 / 2018-07-31 -================== - -**features** - * [[`16f5aea`](http://github.com/node-modules/agentkeepalive/commit/16f5aeadfda57f1c602652f1472a63cc83cd05bf)] - feat: add typing define. (#65) (Henry Zhuang <<zhuanghengfei@gmail.com>>) - -**others** - * [[`28fa062`](http://github.com/node-modules/agentkeepalive/commit/28fa06246fb5103f88ebeeb8563757a9078b8157)] - docs: add "per host" to description of maxFreeSockets (tony-gutierrez <<tony.gutierrez@bluefletch.com>>) - * [[`7df2577`](http://github.com/node-modules/agentkeepalive/commit/7df25774f00a1031ca4daad2878a17e0539072a2)] - test: run test on node 10 (#63) (fengmk2 <<fengmk2@gmail.com>>) - -3.4.1 / 2018-03-08 -================== - -**fixes** - * [[`4d3a3b1`](http://github.com/node-modules/agentkeepalive/commit/4d3a3b1f7b16595febbbd39eeed72b2663549014)] - fix: Handle ipv6 addresses in host-header correctly with TLS (#53) (Mattias Holmlund <<u376@m1.holmlund.se>>) - -**others** - * [[`55a7a5c`](http://github.com/node-modules/agentkeepalive/commit/55a7a5cd33e97f9a8370083dcb041c5552f10ac9)] - test: stop timer after test end (fengmk2 <<fengmk2@gmail.com>>) - -3.4.0 / 2018-02-27 -================== - -**features** - * [[`bc7cadb`](http://github.com/node-modules/agentkeepalive/commit/bc7cadb30ecd2071e2b341ac53ae1a2b8155c43d)] - feat: use socket custom freeSocketKeepAliveTimeout first (#59) (fengmk2 <<fengmk2@gmail.com>>) - -**others** - * [[`138eda8`](http://github.com/node-modules/agentkeepalive/commit/138eda81e10b632aaa87bea0cb66d8667124c4e8)] - doc: fix `keepAliveMsecs` params description (#55) (Hongcai Deng <<admin@dhchouse.com>>) - -3.3.0 / 2017-06-20 -================== - - * feat: add statusChanged getter (#51) - * chore: format License - -3.2.0 / 2017-06-10 -================== - - * feat: add expiring active sockets - * test: add node 8 (#49) - -3.1.0 / 2017-02-20 -================== - - * feat: timeout support humanize ms (#48) - -3.0.0 / 2016-12-20 -================== - - * fix: emit agent socket close event - * test: add remove excess calls to removeSocket - * test: use egg-ci - * test: refactor test with eslint rules - * feat: merge _http_agent.js from 7.2.1 - -2.2.0 / 2016-06-26 -================== - - * feat: Add browser shim (noop) for isomorphic use. (#39) - * chore: add security check badge - -2.1.1 / 2016-04-06 -================== - - * https: fix ssl socket leak when keepalive is used - * chore: remove circle ci image - -2.1.0 / 2016-04-02 -================== - - * fix: opened sockets number overflow maxSockets - -2.0.5 / 2016-03-16 -================== - - * fix: pick _evictSession to httpsAgent - -2.0.4 / 2016-03-13 -================== - - * test: add Circle ci - * test: add appveyor ci build - * refactor: make sure only one error listener - * chore: use codecov - * fix: handle idle socket error - * test: run on more node versions - -2.0.3 / 2015-08-03 -================== - - * fix: add default error handler to avoid Unhandled error event throw - -2.0.2 / 2015-04-25 -================== - - * fix: remove socket from freeSockets on 'timeout' (@pmalouin) - -2.0.1 / 2015-04-19 -================== - - * fix: add timeoutSocketCount to getCurrentStatus() - * feat(getCurrentStatus): add getCurrentStatus - -2.0.0 / 2015-04-01 -================== - - * fix: socket.destroyed always be undefined on 0.10.x - * Make it compatible with node v0.10.x (@lattmann) - -1.2.1 / 2015-03-23 -================== - - * patch from iojs: don't overwrite servername option - * patch commits from joyent/node - * add max sockets test case - * add nagle algorithm delayed link - -1.2.0 / 2014-09-02 -================== - - * allow set keepAliveTimeout = 0 - * support timeout on working socket. fixed #6 - -1.1.0 / 2014-08-28 -================== - - * add some socket counter for deep monitor - -1.0.0 / 2014-08-13 -================== - - * update _http_agent, only support 0.11+, only support node 0.11.0+ - -0.2.2 / 2013-11-19 -================== - - * support node 0.8 and node 0.10 - -0.2.1 / 2013-11-08 -================== - - * fix socket does not timeout bug, it will hang on life, must use 0.2.x on node 0.11 - -0.2.0 / 2013-11-06 -================== - - * use keepalive agent on node 0.11+ impl - -0.1.5 / 2013-06-24 -================== - - * support coveralls - * add node 0.10 test - * add 0.8.22 original https.js - * add original http.js module to diff - * update jscover - * mv pem to fixtures - * add https agent usage diff --git a/node_modules/agentkeepalive/LICENSE b/node_modules/agentkeepalive/LICENSE deleted file mode 100644 index 941258ca703b3..0000000000000 --- a/node_modules/agentkeepalive/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -The MIT License - -Copyright(c) node-modules and other contributors. -Copyright(c) 2012 - 2015 fengmk2 <fengmk2@gmail.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/node_modules/agentkeepalive/browser.js b/node_modules/agentkeepalive/browser.js deleted file mode 100644 index 29c9398aa567f..0000000000000 --- a/node_modules/agentkeepalive/browser.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = noop; -module.exports.HttpsAgent = noop; - -// Noop function for browser since native api's don't use agents. -function noop () {} diff --git a/node_modules/agentkeepalive/index.d.ts b/node_modules/agentkeepalive/index.d.ts deleted file mode 100644 index c2ce7d207a64b..0000000000000 --- a/node_modules/agentkeepalive/index.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as http from 'http'; -import * as https from 'https'; - -interface PlainObject { - [key: string]: any; -} - -declare class HttpAgent extends http.Agent { - constructor(opts?: AgentKeepAlive.HttpOptions); - readonly statusChanged: boolean; - createSocket(req: http.IncomingMessage, options: http.RequestOptions, cb: Function): void; - getCurrentStatus(): AgentKeepAlive.AgentStatus; -} - -interface Constants { - CURRENT_ID: Symbol; - CREATE_ID: Symbol; - INIT_SOCKET: Symbol; - CREATE_HTTPS_CONNECTION: Symbol; - SOCKET_CREATED_TIME: Symbol; - SOCKET_NAME: Symbol; - SOCKET_REQUEST_COUNT: Symbol; - SOCKET_REQUEST_FINISHED_COUNT: Symbol; -} - -declare class AgentKeepAlive extends HttpAgent {} - -declare namespace AgentKeepAlive { - export interface AgentStatus { - createSocketCount: number; - createSocketErrorCount: number; - closeSocketCount: number; - errorSocketCount: number; - timeoutSocketCount: number; - requestCount: number; - freeSockets: PlainObject; - sockets: PlainObject; - requests: PlainObject; - } - - interface CommonHttpOption { - keepAlive?: boolean | undefined; - freeSocketTimeout?: number | undefined; - freeSocketKeepAliveTimeout?: number | undefined; - timeout?: number | undefined; - socketActiveTTL?: number | undefined; - } - - export interface HttpOptions extends http.AgentOptions, CommonHttpOption { } - export interface HttpsOptions extends https.AgentOptions, CommonHttpOption { } - - export class HttpsAgent extends https.Agent { - constructor(opts?: HttpsOptions); - readonly statusChanged: boolean; - createSocket(req: http.IncomingMessage, options: http.RequestOptions, cb: Function): void; - getCurrentStatus(): AgentStatus; - } - - export const constants: Constants; -} - -export = AgentKeepAlive; diff --git a/node_modules/agentkeepalive/index.js b/node_modules/agentkeepalive/index.js deleted file mode 100644 index 6ca1513463724..0000000000000 --- a/node_modules/agentkeepalive/index.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = require('./lib/agent'); -module.exports.HttpsAgent = require('./lib/https_agent'); -module.exports.constants = require('./lib/constants'); diff --git a/node_modules/agentkeepalive/lib/agent.js b/node_modules/agentkeepalive/lib/agent.js deleted file mode 100644 index a7065b5e5d1ad..0000000000000 --- a/node_modules/agentkeepalive/lib/agent.js +++ /dev/null @@ -1,398 +0,0 @@ -'use strict'; - -const OriginalAgent = require('http').Agent; -const ms = require('humanize-ms'); -const debug = require('debug')('agentkeepalive'); -const deprecate = require('depd')('agentkeepalive'); -const { - INIT_SOCKET, - CURRENT_ID, - CREATE_ID, - SOCKET_CREATED_TIME, - SOCKET_NAME, - SOCKET_REQUEST_COUNT, - SOCKET_REQUEST_FINISHED_COUNT, -} = require('./constants'); - -// OriginalAgent come from -// - https://github.com/nodejs/node/blob/v8.12.0/lib/_http_agent.js -// - https://github.com/nodejs/node/blob/v10.12.0/lib/_http_agent.js - -// node <= 10 -let defaultTimeoutListenerCount = 1; -const majorVersion = parseInt(process.version.split('.', 1)[0].substring(1)); -if (majorVersion >= 11 && majorVersion <= 12) { - defaultTimeoutListenerCount = 2; -} else if (majorVersion >= 13) { - defaultTimeoutListenerCount = 3; -} - -class Agent extends OriginalAgent { - constructor(options) { - options = options || {}; - options.keepAlive = options.keepAlive !== false; - // default is keep-alive and 4s free socket timeout - // see https://medium.com/ssense-tech/reduce-networking-errors-in-nodejs-23b4eb9f2d83 - if (options.freeSocketTimeout === undefined) { - options.freeSocketTimeout = 4000; - } - // Legacy API: keepAliveTimeout should be rename to `freeSocketTimeout` - if (options.keepAliveTimeout) { - deprecate('options.keepAliveTimeout is deprecated, please use options.freeSocketTimeout instead'); - options.freeSocketTimeout = options.keepAliveTimeout; - delete options.keepAliveTimeout; - } - // Legacy API: freeSocketKeepAliveTimeout should be rename to `freeSocketTimeout` - if (options.freeSocketKeepAliveTimeout) { - deprecate('options.freeSocketKeepAliveTimeout is deprecated, please use options.freeSocketTimeout instead'); - options.freeSocketTimeout = options.freeSocketKeepAliveTimeout; - delete options.freeSocketKeepAliveTimeout; - } - - // Sets the socket to timeout after timeout milliseconds of inactivity on the socket. - // By default is double free socket timeout. - if (options.timeout === undefined) { - // make sure socket default inactivity timeout >= 8s - options.timeout = Math.max(options.freeSocketTimeout * 2, 8000); - } - - // support humanize format - options.timeout = ms(options.timeout); - options.freeSocketTimeout = ms(options.freeSocketTimeout); - options.socketActiveTTL = options.socketActiveTTL ? ms(options.socketActiveTTL) : 0; - - super(options); - - this[CURRENT_ID] = 0; - - // create socket success counter - this.createSocketCount = 0; - this.createSocketCountLastCheck = 0; - - this.createSocketErrorCount = 0; - this.createSocketErrorCountLastCheck = 0; - - this.closeSocketCount = 0; - this.closeSocketCountLastCheck = 0; - - // socket error event count - this.errorSocketCount = 0; - this.errorSocketCountLastCheck = 0; - - // request finished counter - this.requestCount = 0; - this.requestCountLastCheck = 0; - - // including free socket timeout counter - this.timeoutSocketCount = 0; - this.timeoutSocketCountLastCheck = 0; - - this.on('free', socket => { - // https://github.com/nodejs/node/pull/32000 - // Node.js native agent will check socket timeout eqs agent.options.timeout. - // Use the ttl or freeSocketTimeout to overwrite. - const timeout = this.calcSocketTimeout(socket); - if (timeout > 0 && socket.timeout !== timeout) { - socket.setTimeout(timeout); - } - }); - } - - get freeSocketKeepAliveTimeout() { - deprecate('agent.freeSocketKeepAliveTimeout is deprecated, please use agent.options.freeSocketTimeout instead'); - return this.options.freeSocketTimeout; - } - - get timeout() { - deprecate('agent.timeout is deprecated, please use agent.options.timeout instead'); - return this.options.timeout; - } - - get socketActiveTTL() { - deprecate('agent.socketActiveTTL is deprecated, please use agent.options.socketActiveTTL instead'); - return this.options.socketActiveTTL; - } - - calcSocketTimeout(socket) { - /** - * return <= 0: should free socket - * return > 0: should update socket timeout - * return undefined: not find custom timeout - */ - let freeSocketTimeout = this.options.freeSocketTimeout; - const socketActiveTTL = this.options.socketActiveTTL; - if (socketActiveTTL) { - // check socketActiveTTL - const aliveTime = Date.now() - socket[SOCKET_CREATED_TIME]; - const diff = socketActiveTTL - aliveTime; - if (diff <= 0) { - return diff; - } - if (freeSocketTimeout && diff < freeSocketTimeout) { - freeSocketTimeout = diff; - } - } - // set freeSocketTimeout - if (freeSocketTimeout) { - // set free keepalive timer - // try to use socket custom freeSocketTimeout first, support headers['keep-alive'] - // https://github.com/node-modules/urllib/blob/b76053020923f4d99a1c93cf2e16e0c5ba10bacf/lib/urllib.js#L498 - const customFreeSocketTimeout = socket.freeSocketTimeout || socket.freeSocketKeepAliveTimeout; - return customFreeSocketTimeout || freeSocketTimeout; - } - } - - keepSocketAlive(socket) { - const result = super.keepSocketAlive(socket); - // should not keepAlive, do nothing - if (!result) return result; - - const customTimeout = this.calcSocketTimeout(socket); - if (typeof customTimeout === 'undefined') { - return true; - } - if (customTimeout <= 0) { - debug('%s(requests: %s, finished: %s) free but need to destroy by TTL, request count %s, diff is %s', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], customTimeout); - return false; - } - if (socket.timeout !== customTimeout) { - socket.setTimeout(customTimeout); - } - return true; - } - - // only call on addRequest - reuseSocket(...args) { - // reuseSocket(socket, req) - super.reuseSocket(...args); - const socket = args[0]; - const req = args[1]; - req.reusedSocket = true; - const agentTimeout = this.options.timeout; - if (getSocketTimeout(socket) !== agentTimeout) { - // reset timeout before use - socket.setTimeout(agentTimeout); - debug('%s reset timeout to %sms', socket[SOCKET_NAME], agentTimeout); - } - socket[SOCKET_REQUEST_COUNT]++; - debug('%s(requests: %s, finished: %s) reuse on addRequest, timeout %sms', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], - getSocketTimeout(socket)); - } - - [CREATE_ID]() { - const id = this[CURRENT_ID]++; - if (this[CURRENT_ID] === Number.MAX_SAFE_INTEGER) this[CURRENT_ID] = 0; - return id; - } - - [INIT_SOCKET](socket, options) { - // bugfix here. - // https on node 8, 10 won't set agent.options.timeout by default - // TODO: need to fix on node itself - if (options.timeout) { - const timeout = getSocketTimeout(socket); - if (!timeout) { - socket.setTimeout(options.timeout); - } - } - - if (this.options.keepAlive) { - // Disable Nagle's algorithm: http://blog.caustik.com/2012/04/08/scaling-node-js-to-100k-concurrent-connections/ - // https://fengmk2.com/benchmark/nagle-algorithm-delayed-ack-mock.html - socket.setNoDelay(true); - } - this.createSocketCount++; - if (this.options.socketActiveTTL) { - socket[SOCKET_CREATED_TIME] = Date.now(); - } - // don't show the hole '-----BEGIN CERTIFICATE----' key string - socket[SOCKET_NAME] = `sock[${this[CREATE_ID]()}#${options._agentKey}]`.split('-----BEGIN', 1)[0]; - socket[SOCKET_REQUEST_COUNT] = 1; - socket[SOCKET_REQUEST_FINISHED_COUNT] = 0; - installListeners(this, socket, options); - } - - createConnection(options, oncreate) { - let called = false; - const onNewCreate = (err, socket) => { - if (called) return; - called = true; - - if (err) { - this.createSocketErrorCount++; - return oncreate(err); - } - this[INIT_SOCKET](socket, options); - oncreate(err, socket); - }; - - const newSocket = super.createConnection(options, onNewCreate); - if (newSocket) onNewCreate(null, newSocket); - } - - get statusChanged() { - const changed = this.createSocketCount !== this.createSocketCountLastCheck || - this.createSocketErrorCount !== this.createSocketErrorCountLastCheck || - this.closeSocketCount !== this.closeSocketCountLastCheck || - this.errorSocketCount !== this.errorSocketCountLastCheck || - this.timeoutSocketCount !== this.timeoutSocketCountLastCheck || - this.requestCount !== this.requestCountLastCheck; - if (changed) { - this.createSocketCountLastCheck = this.createSocketCount; - this.createSocketErrorCountLastCheck = this.createSocketErrorCount; - this.closeSocketCountLastCheck = this.closeSocketCount; - this.errorSocketCountLastCheck = this.errorSocketCount; - this.timeoutSocketCountLastCheck = this.timeoutSocketCount; - this.requestCountLastCheck = this.requestCount; - } - return changed; - } - - getCurrentStatus() { - return { - createSocketCount: this.createSocketCount, - createSocketErrorCount: this.createSocketErrorCount, - closeSocketCount: this.closeSocketCount, - errorSocketCount: this.errorSocketCount, - timeoutSocketCount: this.timeoutSocketCount, - requestCount: this.requestCount, - freeSockets: inspect(this.freeSockets), - sockets: inspect(this.sockets), - requests: inspect(this.requests), - }; - } -} - -// node 8 don't has timeout attribute on socket -// https://github.com/nodejs/node/pull/21204/files#diff-e6ef024c3775d787c38487a6309e491dR408 -function getSocketTimeout(socket) { - return socket.timeout || socket._idleTimeout; -} - -function installListeners(agent, socket, options) { - debug('%s create, timeout %sms', socket[SOCKET_NAME], getSocketTimeout(socket)); - - // listener socket events: close, timeout, error, free - function onFree() { - // create and socket.emit('free') logic - // https://github.com/nodejs/node/blob/master/lib/_http_agent.js#L311 - // no req on the socket, it should be the new socket - if (!socket._httpMessage && socket[SOCKET_REQUEST_COUNT] === 1) return; - - socket[SOCKET_REQUEST_FINISHED_COUNT]++; - agent.requestCount++; - debug('%s(requests: %s, finished: %s) free', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT]); - - // should reuse on pedding requests? - const name = agent.getName(options); - if (socket.writable && agent.requests[name] && agent.requests[name].length) { - // will be reuse on agent free listener - socket[SOCKET_REQUEST_COUNT]++; - debug('%s(requests: %s, finished: %s) will be reuse on agent free event', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT]); - } - } - socket.on('free', onFree); - - function onClose(isError) { - debug('%s(requests: %s, finished: %s) close, isError: %s', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], isError); - agent.closeSocketCount++; - } - socket.on('close', onClose); - - // start socket timeout handler - function onTimeout() { - // onTimeout and emitRequestTimeout(_http_client.js) - // https://github.com/nodejs/node/blob/v12.x/lib/_http_client.js#L711 - const listenerCount = socket.listeners('timeout').length; - // node <= 10, default listenerCount is 1, onTimeout - // 11 < node <= 12, default listenerCount is 2, onTimeout and emitRequestTimeout - // node >= 13, default listenerCount is 3, onTimeout, - // onTimeout(https://github.com/nodejs/node/pull/32000/files#diff-5f7fb0850412c6be189faeddea6c5359R333) - // and emitRequestTimeout - const timeout = getSocketTimeout(socket); - const req = socket._httpMessage; - const reqTimeoutListenerCount = req && req.listeners('timeout').length || 0; - debug('%s(requests: %s, finished: %s) timeout after %sms, listeners %s, defaultTimeoutListenerCount %s, hasHttpRequest %s, HttpRequest timeoutListenerCount %s', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], - timeout, listenerCount, defaultTimeoutListenerCount, !!req, reqTimeoutListenerCount); - if (debug.enabled) { - debug('timeout listeners: %s', socket.listeners('timeout').map(f => f.name).join(', ')); - } - agent.timeoutSocketCount++; - const name = agent.getName(options); - if (agent.freeSockets[name] && agent.freeSockets[name].indexOf(socket) !== -1) { - // free socket timeout, destroy quietly - socket.destroy(); - // Remove it from freeSockets list immediately to prevent new requests - // from being sent through this socket. - agent.removeSocket(socket, options); - debug('%s is free, destroy quietly', socket[SOCKET_NAME]); - } else { - // if there is no any request socket timeout handler, - // agent need to handle socket timeout itself. - // - // custom request socket timeout handle logic must follow these rules: - // 1. Destroy socket first - // 2. Must emit socket 'agentRemove' event tell agent remove socket - // from freeSockets list immediately. - // Otherise you may be get 'socket hang up' error when reuse - // free socket and timeout happen in the same time. - if (reqTimeoutListenerCount === 0) { - const error = new Error('Socket timeout'); - error.code = 'ERR_SOCKET_TIMEOUT'; - error.timeout = timeout; - // must manually call socket.end() or socket.destroy() to end the connection. - // https://nodejs.org/dist/latest-v10.x/docs/api/net.html#net_socket_settimeout_timeout_callback - socket.destroy(error); - agent.removeSocket(socket, options); - debug('%s destroy with timeout error', socket[SOCKET_NAME]); - } - } - } - socket.on('timeout', onTimeout); - - function onError(err) { - const listenerCount = socket.listeners('error').length; - debug('%s(requests: %s, finished: %s) error: %s, listenerCount: %s', - socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], - err, listenerCount); - agent.errorSocketCount++; - if (listenerCount === 1) { - // if socket don't contain error event handler, don't catch it, emit it again - debug('%s emit uncaught error event', socket[SOCKET_NAME]); - socket.removeListener('error', onError); - socket.emit('error', err); - } - } - socket.on('error', onError); - - function onRemove() { - debug('%s(requests: %s, finished: %s) agentRemove', - socket[SOCKET_NAME], - socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT]); - // We need this function for cases like HTTP 'upgrade' - // (defined by WebSockets) where we need to remove a socket from the - // pool because it'll be locked up indefinitely - socket.removeListener('close', onClose); - socket.removeListener('error', onError); - socket.removeListener('free', onFree); - socket.removeListener('timeout', onTimeout); - socket.removeListener('agentRemove', onRemove); - } - socket.on('agentRemove', onRemove); -} - -module.exports = Agent; - -function inspect(obj) { - const res = {}; - for (const key in obj) { - res[key] = obj[key].length; - } - return res; -} diff --git a/node_modules/agentkeepalive/lib/constants.js b/node_modules/agentkeepalive/lib/constants.js deleted file mode 100644 index ca7ab97eacd9c..0000000000000 --- a/node_modules/agentkeepalive/lib/constants.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -module.exports = { - // agent - CURRENT_ID: Symbol('agentkeepalive#currentId'), - CREATE_ID: Symbol('agentkeepalive#createId'), - INIT_SOCKET: Symbol('agentkeepalive#initSocket'), - CREATE_HTTPS_CONNECTION: Symbol('agentkeepalive#createHttpsConnection'), - // socket - SOCKET_CREATED_TIME: Symbol('agentkeepalive#socketCreatedTime'), - SOCKET_NAME: Symbol('agentkeepalive#socketName'), - SOCKET_REQUEST_COUNT: Symbol('agentkeepalive#socketRequestCount'), - SOCKET_REQUEST_FINISHED_COUNT: Symbol('agentkeepalive#socketRequestFinishedCount'), -}; diff --git a/node_modules/agentkeepalive/lib/https_agent.js b/node_modules/agentkeepalive/lib/https_agent.js deleted file mode 100644 index 73f529d65e7ff..0000000000000 --- a/node_modules/agentkeepalive/lib/https_agent.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -const OriginalHttpsAgent = require('https').Agent; -const HttpAgent = require('./agent'); -const { - INIT_SOCKET, - CREATE_HTTPS_CONNECTION, -} = require('./constants'); - -class HttpsAgent extends HttpAgent { - constructor(options) { - super(options); - - this.defaultPort = 443; - this.protocol = 'https:'; - this.maxCachedSessions = this.options.maxCachedSessions; - /* istanbul ignore next */ - if (this.maxCachedSessions === undefined) { - this.maxCachedSessions = 100; - } - - this._sessionCache = { - map: {}, - list: [], - }; - } - - createConnection(options) { - const socket = this[CREATE_HTTPS_CONNECTION](options); - this[INIT_SOCKET](socket, options); - return socket; - } -} - -// https://github.com/nodejs/node/blob/master/lib/https.js#L89 -HttpsAgent.prototype[CREATE_HTTPS_CONNECTION] = OriginalHttpsAgent.prototype.createConnection; - -[ - 'getName', - '_getSession', - '_cacheSession', - // https://github.com/nodejs/node/pull/4982 - '_evictSession', -].forEach(function(method) { - /* istanbul ignore next */ - if (typeof OriginalHttpsAgent.prototype[method] === 'function') { - HttpsAgent.prototype[method] = OriginalHttpsAgent.prototype[method]; - } -}); - -module.exports = HttpsAgent; diff --git a/node_modules/agentkeepalive/package.json b/node_modules/agentkeepalive/package.json deleted file mode 100644 index efa561d2c6d6c..0000000000000 --- a/node_modules/agentkeepalive/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "agentkeepalive", - "version": "4.2.1", - "description": "Missing keepalive http.Agent", - "main": "index.js", - "browser": "browser.js", - "files": [ - "index.js", - "index.d.ts", - "browser.js", - "lib" - ], - "scripts": { - "test": "npm run lint && egg-bin test --full-trace", - "test-local": "egg-bin test --full-trace", - "cov": "cross-env DEBUG=agentkeepalive egg-bin cov --full-trace", - "ci": "npm run lint && npm run cov", - "lint": "eslint lib test index.js", - "autod": "autod" - }, - "repository": { - "type": "git", - "url": "git://github.com/node-modules/agentkeepalive.git" - }, - "bugs": { - "url": "https://github.com/node-modules/agentkeepalive/issues" - }, - "keywords": [ - "http", - "https", - "agent", - "keepalive", - "agentkeepalive", - "HttpAgent", - "HttpsAgent" - ], - "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "devDependencies": { - "autod": "^3.0.1", - "coffee": "^5.3.0", - "cross-env": "^6.0.3", - "egg-bin": "^4.9.0", - "egg-ci": "^1.10.0", - "eslint": "^5.7.0", - "eslint-config-egg": "^7.1.0", - "mm": "^2.4.1", - "pedding": "^1.1.0", - "typescript": "^3.8.3" - }, - "engines": { - "node": ">= 8.0.0" - }, - "ci": { - "type": "github", - "os": { - "github": "linux" - }, - "version": "8, 10, 12, 14, 16" - }, - "author": "fengmk2 <fengmk2@gmail.com> (https://fengmk2.com)", - "license": "MIT" -} diff --git a/node_modules/aggregate-error/index.d.ts b/node_modules/aggregate-error/index.d.ts deleted file mode 100644 index 502bf7ad1d0df..0000000000000 --- a/node_modules/aggregate-error/index.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -/** -Create an error from multiple errors. -*/ -declare class AggregateError<T extends Error = Error> extends Error implements Iterable<T> { - readonly name: 'AggregateError'; - - /** - @param errors - If a string, a new `Error` is created with the string as the error message. If a non-Error object, a new `Error` is created with all properties from the object copied over. - @returns An Error that is also an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables) for the individual errors. - - @example - ``` - import AggregateError = require('aggregate-error'); - - const error = new AggregateError([new Error('foo'), 'bar', {message: 'baz'}]); - - throw error; - - // AggregateError: - // Error: foo - // at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:33) - // Error: bar - // at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13) - // Error: baz - // at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13) - // at AggregateError (/Users/sindresorhus/dev/aggregate-error/index.js:19:3) - // at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13) - // at Module._compile (module.js:556:32) - // at Object.Module._extensions..js (module.js:565:10) - // at Module.load (module.js:473:32) - // at tryModuleLoad (module.js:432:12) - // at Function.Module._load (module.js:424:3) - // at Module.runMain (module.js:590:10) - // at run (bootstrap_node.js:394:7) - // at startup (bootstrap_node.js:149:9) - - - for (const individualError of error) { - console.log(individualError); - } - //=> [Error: foo] - //=> [Error: bar] - //=> [Error: baz] - ``` - */ - constructor(errors: ReadonlyArray<T | {[key: string]: any} | string>); - - [Symbol.iterator](): IterableIterator<T>; -} - -export = AggregateError; diff --git a/node_modules/aggregate-error/index.js b/node_modules/aggregate-error/index.js deleted file mode 100644 index ba5bf02211685..0000000000000 --- a/node_modules/aggregate-error/index.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; -const indentString = require('indent-string'); -const cleanStack = require('clean-stack'); - -const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); - -class AggregateError extends Error { - constructor(errors) { - if (!Array.isArray(errors)) { - throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); - } - - errors = [...errors].map(error => { - if (error instanceof Error) { - return error; - } - - if (error !== null && typeof error === 'object') { - // Handle plain error objects with message property and/or possibly other metadata - return Object.assign(new Error(error.message), error); - } - - return new Error(error); - }); - - let message = errors - .map(error => { - // The `stack` property is not standardized, so we can't assume it exists - return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); - }) - .join('\n'); - message = '\n' + indentString(message, 4); - super(message); - - this.name = 'AggregateError'; - - Object.defineProperty(this, '_errors', {value: errors}); - } - - * [Symbol.iterator]() { - for (const error of this._errors) { - yield error; - } - } -} - -module.exports = AggregateError; diff --git a/node_modules/aggregate-error/license b/node_modules/aggregate-error/license deleted file mode 100644 index e7af2f77107d7..0000000000000 --- a/node_modules/aggregate-error/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/aggregate-error/package.json b/node_modules/aggregate-error/package.json deleted file mode 100644 index 74fcc37611e64..0000000000000 --- a/node_modules/aggregate-error/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "aggregate-error", - "version": "3.1.0", - "description": "Create an error from multiple errors", - "license": "MIT", - "repository": "sindresorhus/aggregate-error", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "aggregate", - "error", - "combine", - "multiple", - "many", - "collection", - "iterable", - "iterator" - ], - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "devDependencies": { - "ava": "^2.4.0", - "tsd": "^0.7.1", - "xo": "^0.25.3" - } -} diff --git a/node_modules/aggregate-error/readme.md b/node_modules/aggregate-error/readme.md deleted file mode 100644 index 850de98a8e8f4..0000000000000 --- a/node_modules/aggregate-error/readme.md +++ /dev/null @@ -1,61 +0,0 @@ -# aggregate-error [![Build Status](https://travis-ci.org/sindresorhus/aggregate-error.svg?branch=master)](https://travis-ci.org/sindresorhus/aggregate-error) - -> Create an error from multiple errors - - -## Install - -``` -$ npm install aggregate-error -``` - - -## Usage - -```js -const AggregateError = require('aggregate-error'); - -const error = new AggregateError([new Error('foo'), 'bar', {message: 'baz'}]); - -throw error; -/* -AggregateError: - Error: foo - at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:33) - Error: bar - at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13) - Error: baz - at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13) - at AggregateError (/Users/sindresorhus/dev/aggregate-error/index.js:19:3) - at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13) - at Module._compile (module.js:556:32) - at Object.Module._extensions..js (module.js:565:10) - at Module.load (module.js:473:32) - at tryModuleLoad (module.js:432:12) - at Function.Module._load (module.js:424:3) - at Module.runMain (module.js:590:10) - at run (bootstrap_node.js:394:7) - at startup (bootstrap_node.js:149:9) -*/ - -for (const individualError of error) { - console.log(individualError); -} -//=> [Error: foo] -//=> [Error: bar] -//=> [Error: baz] -``` - - -## API - -### AggregateError(errors) - -Returns an `Error` that is also an [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables) for the individual errors. - -#### errors - -Type: `Array<Error|Object|string>` - -If a string, a new `Error` is created with the string as the error message.<br> -If a non-Error object, a new `Error` is created with all properties from the object copied over. diff --git a/node_modules/ansi-regex/index.d.ts b/node_modules/ansi-regex/index.d.ts deleted file mode 100644 index 2dbf6af2b6f3b..0000000000000 --- a/node_modules/ansi-regex/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -declare namespace ansiRegex { - interface Options { - /** - Match only the first ANSI escape. - - @default false - */ - onlyFirst: boolean; - } -} - -/** -Regular expression for matching ANSI escape codes. - -@example -``` -import ansiRegex = require('ansi-regex'); - -ansiRegex().test('\u001B[4mcake\u001B[0m'); -//=> true - -ansiRegex().test('cake'); -//=> false - -'\u001B[4mcake\u001B[0m'.match(ansiRegex()); -//=> ['\u001B[4m', '\u001B[0m'] - -'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); -//=> ['\u001B[4m'] - -'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex()); -//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007'] -``` -*/ -declare function ansiRegex(options?: ansiRegex.Options): RegExp; - -export = ansiRegex; diff --git a/node_modules/ansi-regex/readme.md b/node_modules/ansi-regex/readme.md deleted file mode 100644 index 4d848bc36f6b8..0000000000000 --- a/node_modules/ansi-regex/readme.md +++ /dev/null @@ -1,78 +0,0 @@ -# ansi-regex - -> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) - - -## Install - -``` -$ npm install ansi-regex -``` - - -## Usage - -```js -const ansiRegex = require('ansi-regex'); - -ansiRegex().test('\u001B[4mcake\u001B[0m'); -//=> true - -ansiRegex().test('cake'); -//=> false - -'\u001B[4mcake\u001B[0m'.match(ansiRegex()); -//=> ['\u001B[4m', '\u001B[0m'] - -'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true})); -//=> ['\u001B[4m'] - -'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex()); -//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007'] -``` - - -## API - -### ansiRegex(options?) - -Returns a regex for matching ANSI escape codes. - -#### options - -Type: `object` - -##### onlyFirst - -Type: `boolean`<br> -Default: `false` *(Matches any ANSI escape codes in a string)* - -Match only the first ANSI escape. - - -## FAQ - -### Why do you test for codes not in the ECMA 48 standard? - -Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them. - -On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out. - - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) - - ---- - -<div align="center"> - <b> - <a href="https://tidelift.com/subscription/pkg/npm-ansi-regex?utm_source=npm-ansi-regex&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> - </b> - <br> - <sub> - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. - </sub> -</div> diff --git a/node_modules/ansi-styles/index.d.ts b/node_modules/ansi-styles/index.d.ts deleted file mode 100644 index 44a907e580f10..0000000000000 --- a/node_modules/ansi-styles/index.d.ts +++ /dev/null @@ -1,345 +0,0 @@ -declare type CSSColor = - | 'aliceblue' - | 'antiquewhite' - | 'aqua' - | 'aquamarine' - | 'azure' - | 'beige' - | 'bisque' - | 'black' - | 'blanchedalmond' - | 'blue' - | 'blueviolet' - | 'brown' - | 'burlywood' - | 'cadetblue' - | 'chartreuse' - | 'chocolate' - | 'coral' - | 'cornflowerblue' - | 'cornsilk' - | 'crimson' - | 'cyan' - | 'darkblue' - | 'darkcyan' - | 'darkgoldenrod' - | 'darkgray' - | 'darkgreen' - | 'darkgrey' - | 'darkkhaki' - | 'darkmagenta' - | 'darkolivegreen' - | 'darkorange' - | 'darkorchid' - | 'darkred' - | 'darksalmon' - | 'darkseagreen' - | 'darkslateblue' - | 'darkslategray' - | 'darkslategrey' - | 'darkturquoise' - | 'darkviolet' - | 'deeppink' - | 'deepskyblue' - | 'dimgray' - | 'dimgrey' - | 'dodgerblue' - | 'firebrick' - | 'floralwhite' - | 'forestgreen' - | 'fuchsia' - | 'gainsboro' - | 'ghostwhite' - | 'gold' - | 'goldenrod' - | 'gray' - | 'green' - | 'greenyellow' - | 'grey' - | 'honeydew' - | 'hotpink' - | 'indianred' - | 'indigo' - | 'ivory' - | 'khaki' - | 'lavender' - | 'lavenderblush' - | 'lawngreen' - | 'lemonchiffon' - | 'lightblue' - | 'lightcoral' - | 'lightcyan' - | 'lightgoldenrodyellow' - | 'lightgray' - | 'lightgreen' - | 'lightgrey' - | 'lightpink' - | 'lightsalmon' - | 'lightseagreen' - | 'lightskyblue' - | 'lightslategray' - | 'lightslategrey' - | 'lightsteelblue' - | 'lightyellow' - | 'lime' - | 'limegreen' - | 'linen' - | 'magenta' - | 'maroon' - | 'mediumaquamarine' - | 'mediumblue' - | 'mediumorchid' - | 'mediumpurple' - | 'mediumseagreen' - | 'mediumslateblue' - | 'mediumspringgreen' - | 'mediumturquoise' - | 'mediumvioletred' - | 'midnightblue' - | 'mintcream' - | 'mistyrose' - | 'moccasin' - | 'navajowhite' - | 'navy' - | 'oldlace' - | 'olive' - | 'olivedrab' - | 'orange' - | 'orangered' - | 'orchid' - | 'palegoldenrod' - | 'palegreen' - | 'paleturquoise' - | 'palevioletred' - | 'papayawhip' - | 'peachpuff' - | 'peru' - | 'pink' - | 'plum' - | 'powderblue' - | 'purple' - | 'rebeccapurple' - | 'red' - | 'rosybrown' - | 'royalblue' - | 'saddlebrown' - | 'salmon' - | 'sandybrown' - | 'seagreen' - | 'seashell' - | 'sienna' - | 'silver' - | 'skyblue' - | 'slateblue' - | 'slategray' - | 'slategrey' - | 'snow' - | 'springgreen' - | 'steelblue' - | 'tan' - | 'teal' - | 'thistle' - | 'tomato' - | 'turquoise' - | 'violet' - | 'wheat' - | 'white' - | 'whitesmoke' - | 'yellow' - | 'yellowgreen'; - -declare namespace ansiStyles { - interface ColorConvert { - /** - The RGB color space. - - @param red - (`0`-`255`) - @param green - (`0`-`255`) - @param blue - (`0`-`255`) - */ - rgb(red: number, green: number, blue: number): string; - - /** - The RGB HEX color space. - - @param hex - A hexadecimal string containing RGB data. - */ - hex(hex: string): string; - - /** - @param keyword - A CSS color name. - */ - keyword(keyword: CSSColor): string; - - /** - The HSL color space. - - @param hue - (`0`-`360`) - @param saturation - (`0`-`100`) - @param lightness - (`0`-`100`) - */ - hsl(hue: number, saturation: number, lightness: number): string; - - /** - The HSV color space. - - @param hue - (`0`-`360`) - @param saturation - (`0`-`100`) - @param value - (`0`-`100`) - */ - hsv(hue: number, saturation: number, value: number): string; - - /** - The HSV color space. - - @param hue - (`0`-`360`) - @param whiteness - (`0`-`100`) - @param blackness - (`0`-`100`) - */ - hwb(hue: number, whiteness: number, blackness: number): string; - - /** - Use a [4-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4-bit) to set text color. - */ - ansi(ansi: number): string; - - /** - Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color. - */ - ansi256(ansi: number): string; - } - - interface CSPair { - /** - The ANSI terminal control sequence for starting this style. - */ - readonly open: string; - - /** - The ANSI terminal control sequence for ending this style. - */ - readonly close: string; - } - - interface ColorBase { - readonly ansi: ColorConvert; - readonly ansi256: ColorConvert; - readonly ansi16m: ColorConvert; - - /** - The ANSI terminal control sequence for ending this color. - */ - readonly close: string; - } - - interface Modifier { - /** - Resets the current color chain. - */ - readonly reset: CSPair; - - /** - Make text bold. - */ - readonly bold: CSPair; - - /** - Emitting only a small amount of light. - */ - readonly dim: CSPair; - - /** - Make text italic. (Not widely supported) - */ - readonly italic: CSPair; - - /** - Make text underline. (Not widely supported) - */ - readonly underline: CSPair; - - /** - Inverse background and foreground colors. - */ - readonly inverse: CSPair; - - /** - Prints the text, but makes it invisible. - */ - readonly hidden: CSPair; - - /** - Puts a horizontal line through the center of the text. (Not widely supported) - */ - readonly strikethrough: CSPair; - } - - interface ForegroundColor { - readonly black: CSPair; - readonly red: CSPair; - readonly green: CSPair; - readonly yellow: CSPair; - readonly blue: CSPair; - readonly cyan: CSPair; - readonly magenta: CSPair; - readonly white: CSPair; - - /** - Alias for `blackBright`. - */ - readonly gray: CSPair; - - /** - Alias for `blackBright`. - */ - readonly grey: CSPair; - - readonly blackBright: CSPair; - readonly redBright: CSPair; - readonly greenBright: CSPair; - readonly yellowBright: CSPair; - readonly blueBright: CSPair; - readonly cyanBright: CSPair; - readonly magentaBright: CSPair; - readonly whiteBright: CSPair; - } - - interface BackgroundColor { - readonly bgBlack: CSPair; - readonly bgRed: CSPair; - readonly bgGreen: CSPair; - readonly bgYellow: CSPair; - readonly bgBlue: CSPair; - readonly bgCyan: CSPair; - readonly bgMagenta: CSPair; - readonly bgWhite: CSPair; - - /** - Alias for `bgBlackBright`. - */ - readonly bgGray: CSPair; - - /** - Alias for `bgBlackBright`. - */ - readonly bgGrey: CSPair; - - readonly bgBlackBright: CSPair; - readonly bgRedBright: CSPair; - readonly bgGreenBright: CSPair; - readonly bgYellowBright: CSPair; - readonly bgBlueBright: CSPair; - readonly bgCyanBright: CSPair; - readonly bgMagentaBright: CSPair; - readonly bgWhiteBright: CSPair; - } -} - -declare const ansiStyles: { - readonly modifier: ansiStyles.Modifier; - readonly color: ansiStyles.ForegroundColor & ansiStyles.ColorBase; - readonly bgColor: ansiStyles.BackgroundColor & ansiStyles.ColorBase; - readonly codes: ReadonlyMap<number, number>; -} & ansiStyles.BackgroundColor & ansiStyles.ForegroundColor & ansiStyles.Modifier; - -export = ansiStyles; diff --git a/node_modules/ansi-styles/index.js b/node_modules/ansi-styles/index.js deleted file mode 100644 index 5d82581a13f99..0000000000000 --- a/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/node_modules/ansi-styles/license b/node_modules/ansi-styles/license deleted file mode 100644 index e7af2f77107d7..0000000000000 --- a/node_modules/ansi-styles/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/ansi-styles/package.json b/node_modules/ansi-styles/package.json deleted file mode 100644 index 75393284d7e47..0000000000000 --- a/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/node_modules/ansi-styles/readme.md b/node_modules/ansi-styles/readme.md deleted file mode 100644 index 24883de808be6..0000000000000 --- a/node_modules/ansi-styles/readme.md +++ /dev/null @@ -1,152 +0,0 @@ -# ansi-styles [![Build Status](https://travis-ci.org/chalk/ansi-styles.svg?branch=master)](https://travis-ci.org/chalk/ansi-styles) - -> [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal - -You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings. - -<img src="screenshot.svg" width="900"> - -## Install - -``` -$ npm install ansi-styles -``` - -## Usage - -```js -const style = require('ansi-styles'); - -console.log(`${style.green.open}Hello world!${style.green.close}`); - - -// Color conversion between 16/256/truecolor -// NOTE: If conversion goes to 16 colors or 256 colors, the original color -// may be degraded to fit that color palette. This means terminals -// that do not support 16 million colors will best-match the -// original color. -console.log(style.bgColor.ansi.hsl(120, 80, 72) + 'Hello world!' + style.bgColor.close); -console.log(style.color.ansi256.rgb(199, 20, 250) + 'Hello world!' + style.color.close); -console.log(style.color.ansi16m.hex('#abcdef') + 'Hello world!' + style.color.close); -``` - -## API - -Each style has an `open` and `close` property. - -## Styles - -### Modifiers - -- `reset` -- `bold` -- `dim` -- `italic` *(Not widely supported)* -- `underline` -- `inverse` -- `hidden` -- `strikethrough` *(Not widely supported)* - -### Colors - -- `black` -- `red` -- `green` -- `yellow` -- `blue` -- `magenta` -- `cyan` -- `white` -- `blackBright` (alias: `gray`, `grey`) -- `redBright` -- `greenBright` -- `yellowBright` -- `blueBright` -- `magentaBright` -- `cyanBright` -- `whiteBright` - -### Background colors - -- `bgBlack` -- `bgRed` -- `bgGreen` -- `bgYellow` -- `bgBlue` -- `bgMagenta` -- `bgCyan` -- `bgWhite` -- `bgBlackBright` (alias: `bgGray`, `bgGrey`) -- `bgRedBright` -- `bgGreenBright` -- `bgYellowBright` -- `bgBlueBright` -- `bgMagentaBright` -- `bgCyanBright` -- `bgWhiteBright` - -## Advanced usage - -By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module. - -- `style.modifier` -- `style.color` -- `style.bgColor` - -###### Example - -```js -console.log(style.color.green.open); -``` - -Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `style.codes`, which returns a `Map` with the open codes as keys and close codes as values. - -###### Example - -```js -console.log(style.codes.get(36)); -//=> 39 -``` - -## [256 / 16 million (TrueColor) support](https://gist.github.com/XVilka/8346728) - -`ansi-styles` uses the [`color-convert`](https://github.com/Qix-/color-convert) package to allow for converting between various colors and ANSI escapes, with support for 256 and 16 million colors. - -The following color spaces from `color-convert` are supported: - -- `rgb` -- `hex` -- `keyword` -- `hsl` -- `hsv` -- `hwb` -- `ansi` -- `ansi256` - -To use these, call the associated conversion function with the intended output, for example: - -```js -style.color.ansi.rgb(100, 200, 15); // RGB to 16 color ansi foreground code -style.bgColor.ansi.rgb(100, 200, 15); // RGB to 16 color ansi background code - -style.color.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code -style.bgColor.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code - -style.color.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color foreground code -style.bgColor.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color background code -``` - -## Related - -- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) - -## For enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of `ansi-styles` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-ansi-styles?utm_source=npm-ansi-styles&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) diff --git a/node_modules/aproba/index.js b/node_modules/aproba/index.js index fd947481ba557..5a58e8126520c 100644 --- a/node_modules/aproba/index.js +++ b/node_modules/aproba/index.js @@ -97,7 +97,7 @@ function moreThanOneError (schema) { } function newException (code, msg) { - const err = new Error(msg) + const err = new TypeError(msg) err.code = code /* istanbul ignore else */ if (Error.captureStackTrace) Error.captureStackTrace(err, validate) diff --git a/node_modules/aproba/package.json b/node_modules/aproba/package.json index d2212d30d8edd..71c7fca58d3c4 100644 --- a/node_modules/aproba/package.json +++ b/node_modules/aproba/package.json @@ -1,6 +1,6 @@ { "name": "aproba", - "version": "2.0.0", + "version": "2.1.0", "description": "A ridiculously light-weight argument validator (now browser friendly)", "main": "index.js", "directories": { diff --git a/node_modules/are-we-there-yet/LICENSE.md b/node_modules/are-we-there-yet/LICENSE.md deleted file mode 100644 index 845be76f64e78..0000000000000 --- a/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/node_modules/are-we-there-yet/lib/index.js b/node_modules/are-we-there-yet/lib/index.js deleted file mode 100644 index 57d8743fdad17..0000000000000 --- a/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/node_modules/are-we-there-yet/lib/tracker-base.js b/node_modules/are-we-there-yet/lib/tracker-base.js deleted file mode 100644 index 6f436875578a7..0000000000000 --- a/node_modules/are-we-there-yet/lib/tracker-base.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' -var EventEmitter = require('events').EventEmitter -var util = require('util') - -var trackerId = 0 -var TrackerBase = module.exports = function (name) { - EventEmitter.call(this) - this.id = ++trackerId - this.name = name -} -util.inherits(TrackerBase, EventEmitter) diff --git a/node_modules/are-we-there-yet/lib/tracker-group.js b/node_modules/are-we-there-yet/lib/tracker-group.js deleted file mode 100644 index 9da13f8a7e116..0000000000000 --- a/node_modules/are-we-there-yet/lib/tracker-group.js +++ /dev/null @@ -1,116 +0,0 @@ -'use strict' -var util = require('util') -var TrackerBase = require('./tracker-base.js') -var Tracker = require('./tracker.js') -var TrackerStream = require('./tracker-stream.js') - -var TrackerGroup = module.exports = function (name) { - TrackerBase.call(this, name) - this.parentGroup = null - this.trackers = [] - this.completion = {} - this.weight = {} - this.totalWeight = 0 - this.finished = false - this.bubbleChange = bubbleChange(this) -} -util.inherits(TrackerGroup, TrackerBase) - -function bubbleChange (trackerGroup) { - return function (name, completed, tracker) { - trackerGroup.completion[tracker.id] = completed - if (trackerGroup.finished) { - return - } - trackerGroup.emit('change', name || trackerGroup.name, trackerGroup.completed(), trackerGroup) - } -} - -TrackerGroup.prototype.nameInTree = function () { - var names = [] - var from = this - while (from) { - names.unshift(from.name) - from = from.parentGroup - } - return names.join('/') -} - -TrackerGroup.prototype.addUnit = function (unit, weight) { - if (unit.addUnit) { - var toTest = this - while (toTest) { - if (unit === toTest) { - throw new Error( - 'Attempted to add tracker group ' + - unit.name + ' to tree that already includes it ' + - this.nameInTree(this)) - } - toTest = toTest.parentGroup - } - unit.parentGroup = this - } - this.weight[unit.id] = weight || 1 - this.totalWeight += this.weight[unit.id] - this.trackers.push(unit) - this.completion[unit.id] = unit.completed() - unit.on('change', this.bubbleChange) - if (!this.finished) { - this.emit('change', unit.name, this.completion[unit.id], unit) - } - return unit -} - -TrackerGroup.prototype.completed = function () { - if (this.trackers.length === 0) { - return 0 - } - var valPerWeight = 1 / this.totalWeight - var completed = 0 - for (var ii = 0; ii < this.trackers.length; ii++) { - var trackerId = this.trackers[ii].id - completed += - valPerWeight * this.weight[trackerId] * this.completion[trackerId] - } - return completed -} - -TrackerGroup.prototype.newGroup = function (name, weight) { - return this.addUnit(new TrackerGroup(name), weight) -} - -TrackerGroup.prototype.newItem = function (name, todo, weight) { - return this.addUnit(new Tracker(name, todo), weight) -} - -TrackerGroup.prototype.newStream = function (name, todo, weight) { - return this.addUnit(new TrackerStream(name, todo), weight) -} - -TrackerGroup.prototype.finish = function () { - this.finished = true - if (!this.trackers.length) { - this.addUnit(new Tracker(), 1, true) - } - for (var ii = 0; ii < this.trackers.length; ii++) { - var tracker = this.trackers[ii] - tracker.finish() - tracker.removeListener('change', this.bubbleChange) - } - this.emit('change', this.name, 1, this) -} - -var buffer = ' ' -TrackerGroup.prototype.debug = function (depth) { - depth = depth || 0 - var indent = depth ? buffer.substr(0, depth) : '' - var output = indent + (this.name || 'top') + ': ' + this.completed() + '\n' - this.trackers.forEach(function (tracker) { - if (tracker instanceof TrackerGroup) { - output += tracker.debug(depth + 1) - } else { - output += indent + ' ' + tracker.name + ': ' + tracker.completed() + '\n' - } - }) - return output -} diff --git a/node_modules/are-we-there-yet/lib/tracker-stream.js b/node_modules/are-we-there-yet/lib/tracker-stream.js deleted file mode 100644 index e1cf85055702a..0000000000000 --- a/node_modules/are-we-there-yet/lib/tracker-stream.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict' -var util = require('util') -var stream = require('readable-stream') -var delegate = require('delegates') -var Tracker = require('./tracker.js') - -var TrackerStream = module.exports = function (name, size, options) { - stream.Transform.call(this, options) - this.tracker = new Tracker(name, size) - this.name = name - this.id = this.tracker.id - this.tracker.on('change', delegateChange(this)) -} -util.inherits(TrackerStream, stream.Transform) - -function delegateChange (trackerStream) { - return function (name, completion, tracker) { - trackerStream.emit('change', name, completion, trackerStream) - } -} - -TrackerStream.prototype._transform = function (data, encoding, cb) { - this.tracker.completeWork(data.length ? data.length : 1) - this.push(data) - cb() -} - -TrackerStream.prototype._flush = function (cb) { - this.tracker.finish() - cb() -} - -delegate(TrackerStream.prototype, 'tracker') - .method('completed') - .method('addWork') - .method('finish') diff --git a/node_modules/are-we-there-yet/lib/tracker.js b/node_modules/are-we-there-yet/lib/tracker.js deleted file mode 100644 index a8f8b3ba01391..0000000000000 --- a/node_modules/are-we-there-yet/lib/tracker.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' -var util = require('util') -var TrackerBase = require('./tracker-base.js') - -var Tracker = module.exports = function (name, todo) { - TrackerBase.call(this, name) - this.workDone = 0 - this.workTodo = todo || 0 -} -util.inherits(Tracker, TrackerBase) - -Tracker.prototype.completed = function () { - return this.workTodo === 0 ? 0 : this.workDone / this.workTodo -} - -Tracker.prototype.addWork = function (work) { - this.workTodo += work - this.emit('change', this.name, this.completed(), this) -} - -Tracker.prototype.completeWork = function (work) { - this.workDone += work - if (this.workDone > this.workTodo) { - this.workDone = this.workTodo - } - this.emit('change', this.name, this.completed(), this) -} - -Tracker.prototype.finish = function () { - this.workTodo = this.workDone = 1 - this.emit('change', this.name, 1, this) -} diff --git a/node_modules/are-we-there-yet/package.json b/node_modules/are-we-there-yet/package.json deleted file mode 100644 index 67c01e9cbc8e4..0000000000000 --- a/node_modules/are-we-there-yet/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "are-we-there-yet", - "version": "3.0.0", - "description": "Keep track of the overall completion of many disparate processes", - "main": "lib/index.js", - "scripts": { - "test": "tap", - "npmclilint": "npmcli-lint", - "lint": "eslint '**/*.js'", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint", - "postsnap": "npm run lintfix --", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "snap": "tap", - "postlint": "npm-template-check", - "template-copy": "npm-template-copy --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": "^2.0.0", - "@npmcli/template-oss": "^2.7.1", - "eslint": "^8.8.0", - "eslint-plugin-node": "^11.1.0", - "tap": "^15.0.9" - }, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "files": [ - "bin", - "lib" - ], - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - }, - "tap": { - "branches": 68, - "statements": 92, - "functions": 86, - "lines": 92 - }, - "templateOSS": { - "version": "2.7.1" - } -} diff --git a/node_modules/asap/CHANGES.md b/node_modules/asap/CHANGES.md deleted file mode 100644 index f105b91956d15..0000000000000 --- a/node_modules/asap/CHANGES.md +++ /dev/null @@ -1,70 +0,0 @@ - -## 2.0.6 - -Version 2.0.4 adds support for React Native by clarifying in package.json that -the browser environment does not support Node.js domains. -Why this is necessary, we leave as an exercise for the user. - -## 2.0.3 - -Version 2.0.3 fixes a bug when adjusting the capacity of the task queue. - -## 2.0.1-2.02 - -Version 2.0.1 fixes a bug in the way redirects were expressed that affected the -function of Browserify, but which Mr would tolerate. - -## 2.0.0 - -Version 2 of ASAP is a full rewrite with a few salient changes. -First, the ASAP source is CommonJS only and designed with [Browserify][] and -[Browserify-compatible][Mr] module loaders in mind. - -[Browserify]: https://github.com/substack/node-browserify -[Mr]: https://github.com/montagejs/mr - -The new version has been refactored in two dimensions. -Support for Node.js and browsers have been separated, using Browserify -redirects and ASAP has been divided into two modules. -The "raw" layer depends on the tasks to catch thrown exceptions and unravel -Node.js domains. - -The full implementation of ASAP is loadable as `require("asap")` in both Node.js -and browsers. - -The raw layer that lacks exception handling overhead is loadable as -`require("asap/raw")`. -The interface is the same for both layers. - -Tasks are no longer required to be functions, but can rather be any object that -implements `task.call()`. -With this feature you can recycle task objects to avoid garbage collector churn -and avoid closures in general. - -The implementation has been rigorously documented so that our successors can -understand the scope of the problem that this module solves and all of its -nuances, ensuring that the next generation of implementations know what details -are essential. - -- [asap.js](https://github.com/kriskowal/asap/blob/master/asap.js) -- [raw.js](https://github.com/kriskowal/asap/blob/master/raw.js) -- [browser-asap.js](https://github.com/kriskowal/asap/blob/master/browser-asap.js) -- [browser-raw.js](https://github.com/kriskowal/asap/blob/master/browser-raw.js) - -The new version has also been rigorously tested across a broad spectrum of -browsers, in both the window and worker context. -The following charts capture the browser test results for the most recent -release. -The first chart shows test results for ASAP running in the main window context. -The second chart shows test results for ASAP running in a web worker context. -Test results are inconclusive (grey) on browsers that do not support web -workers. -These data are captured automatically by [Continuous -Integration][]. - -![Browser Compatibility](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-results-matrix.svg) - -![Compatibility in Web Workers](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-worker-results-matrix.svg) - -[Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md - diff --git a/node_modules/asap/LICENSE.md b/node_modules/asap/LICENSE.md deleted file mode 100644 index ba18c61390db9..0000000000000 --- a/node_modules/asap/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright 2009–2014 Contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. - diff --git a/node_modules/asap/asap.js b/node_modules/asap/asap.js deleted file mode 100644 index f04fcd58fc0b2..0000000000000 --- a/node_modules/asap/asap.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -var rawAsap = require("./raw"); -var freeTasks = []; - -/** - * Calls a task as soon as possible after returning, in its own event, with - * priority over IO events. An exception thrown in a task can be handled by - * `process.on("uncaughtException") or `domain.on("error")`, but will otherwise - * crash the process. If the error is handled, all subsequent tasks will - * resume. - * - * @param {{call}} task A callable object, typically a function that takes no - * arguments. - */ -module.exports = asap; -function asap(task) { - var rawTask; - if (freeTasks.length) { - rawTask = freeTasks.pop(); - } else { - rawTask = new RawTask(); - } - rawTask.task = task; - rawTask.domain = process.domain; - rawAsap(rawTask); -} - -function RawTask() { - this.task = null; - this.domain = null; -} - -RawTask.prototype.call = function () { - if (this.domain) { - this.domain.enter(); - } - var threw = true; - try { - this.task.call(); - threw = false; - // If the task throws an exception (presumably) Node.js restores the - // domain stack for the next event. - if (this.domain) { - this.domain.exit(); - } - } finally { - // We use try/finally and a threw flag to avoid messing up stack traces - // when we catch and release errors. - if (threw) { - // In Node.js, uncaught exceptions are considered fatal errors. - // Re-throw them to interrupt flushing! - // Ensure that flushing continues if an uncaught exception is - // suppressed listening process.on("uncaughtException") or - // domain.on("error"). - rawAsap.requestFlush(); - } - // If the task threw an error, we do not want to exit the domain here. - // Exiting the domain would prevent the domain from catching the error. - this.task = null; - this.domain = null; - freeTasks.push(this); - } -}; - diff --git a/node_modules/asap/browser-asap.js b/node_modules/asap/browser-asap.js deleted file mode 100644 index 805c9824605b0..0000000000000 --- a/node_modules/asap/browser-asap.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict"; - -// rawAsap provides everything we need except exception management. -var rawAsap = require("./raw"); -// RawTasks are recycled to reduce GC churn. -var freeTasks = []; -// We queue errors to ensure they are thrown in right order (FIFO). -// Array-as-queue is good enough here, since we are just dealing with exceptions. -var pendingErrors = []; -var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError); - -function throwFirstError() { - if (pendingErrors.length) { - throw pendingErrors.shift(); - } -} - -/** - * Calls a task as soon as possible after returning, in its own event, with priority - * over other events like animation, reflow, and repaint. An error thrown from an - * event will not interrupt, nor even substantially slow down the processing of - * other events, but will be rather postponed to a lower priority event. - * @param {{call}} task A callable object, typically a function that takes no - * arguments. - */ -module.exports = asap; -function asap(task) { - var rawTask; - if (freeTasks.length) { - rawTask = freeTasks.pop(); - } else { - rawTask = new RawTask(); - } - rawTask.task = task; - rawAsap(rawTask); -} - -// We wrap tasks with recyclable task objects. A task object implements -// `call`, just like a function. -function RawTask() { - this.task = null; -} - -// The sole purpose of wrapping the task is to catch the exception and recycle -// the task object after its single use. -RawTask.prototype.call = function () { - try { - this.task.call(); - } catch (error) { - if (asap.onerror) { - // This hook exists purely for testing purposes. - // Its name will be periodically randomized to break any code that - // depends on its existence. - asap.onerror(error); - } else { - // In a web browser, exceptions are not fatal. However, to avoid - // slowing down the queue of pending tasks, we rethrow the error in a - // lower priority turn. - pendingErrors.push(error); - requestErrorThrow(); - } - } finally { - this.task = null; - freeTasks[freeTasks.length] = this; - } -}; diff --git a/node_modules/asap/browser-raw.js b/node_modules/asap/browser-raw.js deleted file mode 100644 index 9cee7e32eb5d3..0000000000000 --- a/node_modules/asap/browser-raw.js +++ /dev/null @@ -1,223 +0,0 @@ -"use strict"; - -// Use the fastest means possible to execute a task in its own turn, with -// priority over other events including IO, animation, reflow, and redraw -// events in browsers. -// -// An exception thrown by a task will permanently interrupt the processing of -// subsequent tasks. The higher level `asap` function ensures that if an -// exception is thrown by a task, that the task queue will continue flushing as -// soon as possible, but if you use `rawAsap` directly, you are responsible to -// either ensure that no exceptions are thrown from your task, or to manually -// call `rawAsap.requestFlush` if an exception is thrown. -module.exports = rawAsap; -function rawAsap(task) { - if (!queue.length) { - requestFlush(); - flushing = true; - } - // Equivalent to push, but avoids a function call. - queue[queue.length] = task; -} - -var queue = []; -// Once a flush has been requested, no further calls to `requestFlush` are -// necessary until the next `flush` completes. -var flushing = false; -// `requestFlush` is an implementation-specific method that attempts to kick -// off a `flush` event as quickly as possible. `flush` will attempt to exhaust -// the event queue before yielding to the browser's own event loop. -var requestFlush; -// The position of the next task to execute in the task queue. This is -// preserved between calls to `flush` so that it can be resumed if -// a task throws an exception. -var index = 0; -// If a task schedules additional tasks recursively, the task queue can grow -// unbounded. To prevent memory exhaustion, the task queue will periodically -// truncate already-completed tasks. -var capacity = 1024; - -// The flush function processes all tasks that have been scheduled with -// `rawAsap` unless and until one of those tasks throws an exception. -// If a task throws an exception, `flush` ensures that its state will remain -// consistent and will resume where it left off when called again. -// However, `flush` does not make any arrangements to be called again if an -// exception is thrown. -function flush() { - while (index < queue.length) { - var currentIndex = index; - // Advance the index before calling the task. This ensures that we will - // begin flushing on the next task the task throws an error. - index = index + 1; - queue[currentIndex].call(); - // Prevent leaking memory for long chains of recursive calls to `asap`. - // If we call `asap` within tasks scheduled by `asap`, the queue will - // grow, but to avoid an O(n) walk for every task we execute, we don't - // shift tasks off the queue after they have been executed. - // Instead, we periodically shift 1024 tasks off the queue. - if (index > capacity) { - // Manually shift all values starting at the index back to the - // beginning of the queue. - for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { - queue[scan] = queue[scan + index]; - } - queue.length -= index; - index = 0; - } - } - queue.length = 0; - index = 0; - flushing = false; -} - -// `requestFlush` is implemented using a strategy based on data collected from -// every available SauceLabs Selenium web driver worker at time of writing. -// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593 - -// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that -// have WebKitMutationObserver but not un-prefixed MutationObserver. -// Must use `global` or `self` instead of `window` to work in both frames and web -// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop. - -/* globals self */ -var scope = typeof global !== "undefined" ? global : self; -var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver; - -// MutationObservers are desirable because they have high priority and work -// reliably everywhere they are implemented. -// They are implemented in all modern browsers. -// -// - Android 4-4.3 -// - Chrome 26-34 -// - Firefox 14-29 -// - Internet Explorer 11 -// - iPad Safari 6-7.1 -// - iPhone Safari 7-7.1 -// - Safari 6-7 -if (typeof BrowserMutationObserver === "function") { - requestFlush = makeRequestCallFromMutationObserver(flush); - -// MessageChannels are desirable because they give direct access to the HTML -// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera -// 11-12, and in web workers in many engines. -// Although message channels yield to any queued rendering and IO tasks, they -// would be better than imposing the 4ms delay of timers. -// However, they do not work reliably in Internet Explorer or Safari. - -// Internet Explorer 10 is the only browser that has setImmediate but does -// not have MutationObservers. -// Although setImmediate yields to the browser's renderer, it would be -// preferrable to falling back to setTimeout since it does not have -// the minimum 4ms penalty. -// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and -// Desktop to a lesser extent) that renders both setImmediate and -// MessageChannel useless for the purposes of ASAP. -// https://github.com/kriskowal/q/issues/396 - -// Timers are implemented universally. -// We fall back to timers in workers in most engines, and in foreground -// contexts in the following browsers. -// However, note that even this simple case requires nuances to operate in a -// broad spectrum of browsers. -// -// - Firefox 3-13 -// - Internet Explorer 6-9 -// - iPad Safari 4.3 -// - Lynx 2.8.7 -} else { - requestFlush = makeRequestCallFromTimer(flush); -} - -// `requestFlush` requests that the high priority event queue be flushed as -// soon as possible. -// This is useful to prevent an error thrown in a task from stalling the event -// queue if the exception handled by Node.js’s -// `process.on("uncaughtException")` or by a domain. -rawAsap.requestFlush = requestFlush; - -// To request a high priority event, we induce a mutation observer by toggling -// the text of a text node between "1" and "-1". -function makeRequestCallFromMutationObserver(callback) { - var toggle = 1; - var observer = new BrowserMutationObserver(callback); - var node = document.createTextNode(""); - observer.observe(node, {characterData: true}); - return function requestCall() { - toggle = -toggle; - node.data = toggle; - }; -} - -// The message channel technique was discovered by Malte Ubl and was the -// original foundation for this library. -// http://www.nonblocking.io/2011/06/windownexttick.html - -// Safari 6.0.5 (at least) intermittently fails to create message ports on a -// page's first load. Thankfully, this version of Safari supports -// MutationObservers, so we don't need to fall back in that case. - -// function makeRequestCallFromMessageChannel(callback) { -// var channel = new MessageChannel(); -// channel.port1.onmessage = callback; -// return function requestCall() { -// channel.port2.postMessage(0); -// }; -// } - -// For reasons explained above, we are also unable to use `setImmediate` -// under any circumstances. -// Even if we were, there is another bug in Internet Explorer 10. -// It is not sufficient to assign `setImmediate` to `requestFlush` because -// `setImmediate` must be called *by name* and therefore must be wrapped in a -// closure. -// Never forget. - -// function makeRequestCallFromSetImmediate(callback) { -// return function requestCall() { -// setImmediate(callback); -// }; -// } - -// Safari 6.0 has a problem where timers will get lost while the user is -// scrolling. This problem does not impact ASAP because Safari 6.0 supports -// mutation observers, so that implementation is used instead. -// However, if we ever elect to use timers in Safari, the prevalent work-around -// is to add a scroll event listener that calls for a flush. - -// `setTimeout` does not call the passed callback if the delay is less than -// approximately 7 in web workers in Firefox 8 through 18, and sometimes not -// even then. - -function makeRequestCallFromTimer(callback) { - return function requestCall() { - // We dispatch a timeout with a specified delay of 0 for engines that - // can reliably accommodate that request. This will usually be snapped - // to a 4 milisecond delay, but once we're flushing, there's no delay - // between events. - var timeoutHandle = setTimeout(handleTimer, 0); - // However, since this timer gets frequently dropped in Firefox - // workers, we enlist an interval handle that will try to fire - // an event 20 times per second until it succeeds. - var intervalHandle = setInterval(handleTimer, 50); - - function handleTimer() { - // Whichever timer succeeds will cancel both timers and - // execute the callback. - clearTimeout(timeoutHandle); - clearInterval(intervalHandle); - callback(); - } - }; -} - -// This is for `asap.js` only. -// Its name will be periodically randomized to break any code that depends on -// its existence. -rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer; - -// ASAP was originally a nextTick shim included in Q. This was factored out -// into this ASAP package. It was later adapted to RSVP which made further -// amendments. These decisions, particularly to marginalize MessageChannel and -// to capture the MutationObserver implementation in a closure, were integrated -// back into ASAP proper. -// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js diff --git a/node_modules/asap/package.json b/node_modules/asap/package.json deleted file mode 100644 index ae9f303bcd15d..0000000000000 --- a/node_modules/asap/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "asap", - "version": "2.0.6", - "description": "High-priority task queue for Node.js and browsers", - "keywords": [ - "event", - "task", - "queue" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/kriskowal/asap.git" - }, - "main": "./asap.js", - "browser": { - "./asap": "./browser-asap.js", - "./asap.js": "./browser-asap.js", - "./raw": "./browser-raw.js", - "./raw.js": "./browser-raw.js", - "./test/domain.js": "./test/browser-domain.js" - }, - "react-native": { - "domain": false - }, - "files": [ - "raw.js", - "asap.js", - "browser-raw.js", - "browser-asap.js" - ], - "scripts": { - "test": "npm run lint && npm run test-node", - "test-travis": "npm run lint && npm run test-node && npm run test-saucelabs && npm run test-saucelabs-worker", - "test-node": "node test/asap-test.js", - "test-publish": "node scripts/publish-bundle.js test/asap-test.js | pbcopy", - "test-browser": "node scripts/publish-bundle.js test/asap-test.js | xargs opener", - "test-saucelabs": "node scripts/saucelabs.js test/asap-test.js scripts/saucelabs-spot-configurations.json", - "test-saucelabs-all": "node scripts/saucelabs.js test/asap-test.js scripts/saucelabs-all-configurations.json", - "test-saucelabs-worker": "node scripts/saucelabs-worker-test.js scripts/saucelabs-spot-configurations.json", - "test-saucelabs-worker-all": "node scripts/saucelabs-worker-test.js scripts/saucelabs-all-configurations.json", - "lint": "jshint raw.js asap.js browser-raw.js browser-asap.js $(find scripts -name '*.js' | grep -v gauntlet)", - "benchmarks": "node benchmarks" - }, - "devDependencies": { - "events": "^1.0.1", - "jshint": "^2.5.1", - "knox": "^0.8.10", - "mr": "^2.0.5", - "opener": "^1.3.0", - "q": "^2.0.3", - "q-io": "^2.0.3", - "saucelabs": "^0.1.1", - "wd": "^0.2.21", - "weak-map": "^1.0.5", - "benchmark": "^1.0.0" - } -} diff --git a/node_modules/asap/raw.js b/node_modules/asap/raw.js deleted file mode 100644 index ae3b892316842..0000000000000 --- a/node_modules/asap/raw.js +++ /dev/null @@ -1,101 +0,0 @@ -"use strict"; - -var domain; // The domain module is executed on demand -var hasSetImmediate = typeof setImmediate === "function"; - -// Use the fastest means possible to execute a task in its own turn, with -// priority over other events including network IO events in Node.js. -// -// An exception thrown by a task will permanently interrupt the processing of -// subsequent tasks. The higher level `asap` function ensures that if an -// exception is thrown by a task, that the task queue will continue flushing as -// soon as possible, but if you use `rawAsap` directly, you are responsible to -// either ensure that no exceptions are thrown from your task, or to manually -// call `rawAsap.requestFlush` if an exception is thrown. -module.exports = rawAsap; -function rawAsap(task) { - if (!queue.length) { - requestFlush(); - flushing = true; - } - // Avoids a function call - queue[queue.length] = task; -} - -var queue = []; -// Once a flush has been requested, no further calls to `requestFlush` are -// necessary until the next `flush` completes. -var flushing = false; -// The position of the next task to execute in the task queue. This is -// preserved between calls to `flush` so that it can be resumed if -// a task throws an exception. -var index = 0; -// If a task schedules additional tasks recursively, the task queue can grow -// unbounded. To prevent memory excaustion, the task queue will periodically -// truncate already-completed tasks. -var capacity = 1024; - -// The flush function processes all tasks that have been scheduled with -// `rawAsap` unless and until one of those tasks throws an exception. -// If a task throws an exception, `flush` ensures that its state will remain -// consistent and will resume where it left off when called again. -// However, `flush` does not make any arrangements to be called again if an -// exception is thrown. -function flush() { - while (index < queue.length) { - var currentIndex = index; - // Advance the index before calling the task. This ensures that we will - // begin flushing on the next task the task throws an error. - index = index + 1; - queue[currentIndex].call(); - // Prevent leaking memory for long chains of recursive calls to `asap`. - // If we call `asap` within tasks scheduled by `asap`, the queue will - // grow, but to avoid an O(n) walk for every task we execute, we don't - // shift tasks off the queue after they have been executed. - // Instead, we periodically shift 1024 tasks off the queue. - if (index > capacity) { - // Manually shift all values starting at the index back to the - // beginning of the queue. - for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { - queue[scan] = queue[scan + index]; - } - queue.length -= index; - index = 0; - } - } - queue.length = 0; - index = 0; - flushing = false; -} - -rawAsap.requestFlush = requestFlush; -function requestFlush() { - // Ensure flushing is not bound to any domain. - // It is not sufficient to exit the domain, because domains exist on a stack. - // To execute code outside of any domain, the following dance is necessary. - var parentDomain = process.domain; - if (parentDomain) { - if (!domain) { - // Lazy execute the domain module. - // Only employed if the user elects to use domains. - domain = require("domain"); - } - domain.active = process.domain = null; - } - - // `setImmediate` is slower that `process.nextTick`, but `process.nextTick` - // cannot handle recursion. - // `requestFlush` will only be called recursively from `asap.js`, to resume - // flushing after an error is thrown into a domain. - // Conveniently, `setImmediate` was introduced in the same version - // `process.nextTick` started throwing recursion errors. - if (flushing && hasSetImmediate) { - setImmediate(flush); - } else { - process.nextTick(flush); - } - - if (parentDomain) { - domain.active = process.domain = parentDomain; - } -} diff --git a/node_modules/balanced-match/LICENSE.md b/node_modules/balanced-match/LICENSE.md deleted file mode 100644 index 2cdc8e4148cc0..0000000000000 --- a/node_modules/balanced-match/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -(MIT) - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/node_modules/balanced-match/index.js b/node_modules/balanced-match/index.js deleted file mode 100644 index c67a64608df7f..0000000000000 --- a/node_modules/balanced-match/index.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - if(a===b) { - return [ai, bi]; - } - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} diff --git a/node_modules/balanced-match/package.json b/node_modules/balanced-match/package.json deleted file mode 100644 index ce6073e0403b5..0000000000000 --- a/node_modules/balanced-match/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "balanced-match", - "description": "Match balanced character pairs, like \"{\" and \"}\"", - "version": "1.0.2", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/balanced-match.git" - }, - "homepage": "https://github.com/juliangruber/balanced-match", - "main": "index.js", - "scripts": { - "test": "tape test/test.js", - "bench": "matcha test/bench.js" - }, - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "keywords": [ - "match", - "regexp", - "test", - "balanced", - "parse" - ], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/node_modules/bin-links/lib/check-bin.js b/node_modules/bin-links/lib/check-bin.js index 750a34fbbff3a..c5b997bb96355 100644 --- a/node_modules/bin-links/lib/check-bin.js +++ b/node_modules/bin-links/lib/check-bin.js @@ -4,9 +4,7 @@ const isWindows = require('./is-windows.js') const binTarget = require('./bin-target.js') const { resolve, dirname } = require('path') const readCmdShim = require('read-cmd-shim') -const fs = require('fs') -const { promisify } = require('util') -const readlink = promisify(fs.readlink) +const { readlink } = require('fs/promises') const checkBin = async ({ bin, path, top, global, force }) => { // always ok to clobber when forced diff --git a/node_modules/bin-links/lib/fix-bin.js b/node_modules/bin-links/lib/fix-bin.js index d1f513a2cf93d..453bd4f3e95b1 100644 --- a/node_modules/bin-links/lib/fix-bin.js +++ b/node_modules/bin-links/lib/fix-bin.js @@ -1,16 +1,14 @@ // make sure that bins are executable, and that they don't have // windows line-endings on the hashbang line. -const fs = require('fs') -const { promisify } = require('util') +const { + chmod, + open, + readFile, +} = require('fs/promises') const execMode = 0o777 & (~process.umask()) const writeFileAtomic = require('write-file-atomic') -const open = promisify(fs.open) -const close = promisify(fs.close) -const read = promisify(fs.read) -const chmod = promisify(fs.chmod) -const readFile = promisify(fs.readFile) const isWindowsHashBang = buf => buf[0] === '#'.charCodeAt(0) && @@ -19,16 +17,16 @@ const isWindowsHashBang = buf => const isWindowsHashbangFile = file => { const FALSE = () => false - return open(file, 'r').then(fd => { + return open(file, 'r').then(fh => { const buf = Buffer.alloc(2048) - return read(fd, buf, 0, 2048, 0) + return fh.read(buf, 0, 2048, 0) .then( () => { const isWHB = isWindowsHashBang(buf) - return close(fd).then(() => isWHB, () => isWHB) + return fh.close().then(() => isWHB, () => isWHB) }, // don't leak FD if read() fails - () => close(fd).then(FALSE, FALSE) + () => fh.close().then(FALSE, FALSE) ) }, FALSE) } diff --git a/node_modules/bin-links/lib/link-gently.js b/node_modules/bin-links/lib/link-gently.js index 671ce38a586e7..a39d3bced57b1 100644 --- a/node_modules/bin-links/lib/link-gently.js +++ b/node_modules/bin-links/lib/link-gently.js @@ -4,17 +4,23 @@ // if there's a symlink already, pointing into our pkg, remove it first // then create the symlink -const { promisify } = require('util') const { resolve, dirname } = require('path') -const mkdirp = require('mkdirp-infer-owner') -const fs = require('fs') -const symlink = promisify(fs.symlink) -const readlink = promisify(fs.readlink) -const lstat = promisify(fs.lstat) -const throwNonEnoent = er => { - if (er.code !== 'ENOENT') { - throw er +const { lstat, mkdir, readlink, rm, symlink } = require('fs/promises') +const { log } = require('proc-log') +const throwSignificant = er => { + if (er.code === 'ENOENT') { + return } + if (er.code === 'EACCES') { + log.warn('error adding file', er.message) + return + } + throw er +} + +const rmOpts = { + recursive: true, + force: true, } // even in --force mode, we never create a link over a link we've @@ -23,16 +29,12 @@ const throwNonEnoent = er => { // which creates a race condition and nondeterminism. const seen = new Set() -// disable glob in our rimraf calls -const rimraf = promisify(require('rimraf')) -const rm = path => rimraf(path, { glob: false }) - const SKIP = Symbol('skip - missing or already installed') const CLOBBER = Symbol('clobber - ours or in forceful mode') const linkGently = async ({ path, to, from, absFrom, force }) => { if (seen.has(to)) { - return true + return false } seen.add(to) @@ -41,8 +43,8 @@ const linkGently = async ({ path, to, from, absFrom, force }) => { // or at least a warning, but npm has always behaved this // way in the past, so it'd be a breaking change return Promise.all([ - lstat(absFrom).catch(throwNonEnoent), - lstat(to).catch(throwNonEnoent), + lstat(absFrom).catch(throwSignificant), + lstat(to).catch(throwSignificant), ]).then(([stFrom, stTo]) => { // not present in package, skip it if (!stFrom) { @@ -52,7 +54,7 @@ const linkGently = async ({ path, to, from, absFrom, force }) => { // exists! maybe clobber if we can if (stTo) { if (!stTo.isSymbolicLink()) { - return force && rm(to).then(() => CLOBBER) + return force && rm(to, rmOpts).then(() => CLOBBER) } return readlink(to).then(target => { @@ -62,12 +64,14 @@ const linkGently = async ({ path, to, from, absFrom, force }) => { target = resolve(dirname(to), target) if (target.indexOf(path) === 0 || force) { - return rm(to).then(() => CLOBBER) + return rm(to, rmOpts).then(() => CLOBBER) } + // neither skip nor clobber + return false }) } else { // doesn't exist, dir might not either - return mkdirp(dirname(to)) + return mkdir(dirname(to), { recursive: true }) } }) .then(skipOrClobber => { @@ -76,7 +80,7 @@ const linkGently = async ({ path, to, from, absFrom, force }) => { } return symlink(from, to, 'file').catch(er => { if (skipOrClobber === CLOBBER || force) { - return rm(to).then(() => symlink(from, to, 'file')) + return rm(to, rmOpts).then(() => symlink(from, to, 'file')) } throw er }).then(() => true) diff --git a/node_modules/bin-links/lib/link-mans.js b/node_modules/bin-links/lib/link-mans.js index 656e179b6ca54..b6dd214cebdfe 100644 --- a/node_modules/bin-links/lib/link-mans.js +++ b/node_modules/bin-links/lib/link-mans.js @@ -2,22 +2,23 @@ const { dirname, relative, join, resolve, basename } = require('path') const linkGently = require('./link-gently.js') const manTarget = require('./man-target.js') -const linkMans = ({ path, pkg, top, force }) => { +const linkMans = async ({ path, pkg, top, force }) => { const target = manTarget({ path, top }) - if (!target || !pkg.man || !Array.isArray(pkg.man) || !pkg.man.length) { - return Promise.resolve([]) + if (!target || !Array.isArray(pkg?.man) || !pkg.man.length) { + return [] } - // break any links to c:\\blah or /foo/blah or ../blah - // and filter out duplicates - const set = [...new Set(pkg.man.map(man => - man ? join('/', man).replace(/\\|:/g, '/').slice(1) : null) - .filter(man => typeof man === 'string'))] - - return Promise.all(set.map(man => { - const parseMan = man.match(/(.*\.([0-9]+)(\.gz)?)$/) + const links = [] + // `new Set` to filter out duplicates + for (let man of new Set(pkg.man)) { + if (!man || typeof man !== 'string') { + continue + } + // break any links to c:\\blah or /foo/blah or ../blah + man = join('/', man).replace(/\\|:/g, '/').slice(1) + const parseMan = man.match(/\.([0-9]+)(\.gz)?$/) if (!parseMan) { - return Promise.reject(Object.assign(new Error('invalid man entry name\n' + + throw Object.assign(new Error('invalid man entry name\n' + 'Man files must end with a number, ' + 'and optionally a .gz suffix if they are compressed.' ), { @@ -25,28 +26,28 @@ const linkMans = ({ path, pkg, top, force }) => { path, pkgid: pkg._id, man, - })) + }) } - const stem = parseMan[1] - const sxn = parseMan[2] - const base = basename(stem) + const section = parseMan[1] + const base = basename(man) const absFrom = resolve(path, man) /* istanbul ignore if - that unpossible */ if (absFrom.indexOf(path) !== 0) { - return Promise.reject(Object.assign(new Error('invalid man entry'), { + throw Object.assign(new Error('invalid man entry'), { code: 'EBADMAN', path, pkgid: pkg._id, man, - })) + }) } - const to = resolve(target, 'man' + sxn, base) + const to = resolve(target, 'man' + section, base) const from = relative(dirname(to), absFrom) - return linkGently({ from, to, path, absFrom, force }) - })) + links.push(linkGently({ from, to, path, absFrom, force })) + } + return Promise.all(links) } module.exports = linkMans diff --git a/node_modules/bin-links/lib/shim-bin.js b/node_modules/bin-links/lib/shim-bin.js index 70259a49e5b0c..67e2702702f0a 100644 --- a/node_modules/bin-links/lib/shim-bin.js +++ b/node_modules/bin-links/lib/shim-bin.js @@ -1,7 +1,5 @@ -const { promisify } = require('util') const { resolve, dirname } = require('path') -const fs = require('fs') -const lstat = promisify(fs.lstat) +const { lstat } = require('fs/promises') const throwNonEnoent = er => { if (er.code !== 'ENOENT') { throw er @@ -19,7 +17,7 @@ const fixBin = require('./fix-bin.js') // nondeterminism. const seen = new Set() -const failEEXIST = ({ path, to, from }) => +const failEEXIST = ({ to, from }) => Promise.reject(Object.assign(new Error('EEXIST: file already exists'), { path: to, dest: from, @@ -56,12 +54,12 @@ const shimBin = ({ path, to, from, absFrom, force }) => { } if (force) { - return + return false } return Promise.all(shims.map((s, i) => [s, stats[i]]).map(([s, st]) => { if (!st) { - return + return false } return readCmdShim(s) .then(target => { @@ -69,6 +67,7 @@ const shimBin = ({ path, to, from, absFrom, force }) => { if (target.indexOf(resolve(path)) !== 0) { return failEEXIST({ from, to, path }) } + return false }, er => handleReadCmdShimError({ er, from, to })) })) }) diff --git a/node_modules/bin-links/package.json b/node_modules/bin-links/package.json index a86948de153c5..23f52cfc96ec4 100644 --- a/node_modules/bin-links/package.json +++ b/node_modules/bin-links/package.json @@ -1,23 +1,21 @@ { "name": "bin-links", - "version": "3.0.1", + "version": "6.0.0", "description": "JavaScript package binary linker", "main": "./lib/index.js", "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "snap": "tap", "test": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/bin-links.git" + "url": "git+https://github.com/npm/bin-links.git" }, "keywords": [ "npm", @@ -26,35 +24,38 @@ ], "license": "ISC", "dependencies": { - "cmd-shim": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^1.0.0", - "read-cmd-shim": "^3.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^4.0.0" + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "mkdirp": "^1.0.3", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "require-inject": "^1.4.4", - "tap": "^15.0.10" + "tap": "^16.0.1" }, "tap": { "check-coverage": true, - "coverage-map": "map.js" + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "files": [ "bin/", "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "windowsCI": false, - "version": "3.2.2" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/binary-extensions/binary-extensions.json b/node_modules/binary-extensions/binary-extensions.json index 4aab3837893a2..9a57d80cd08fb 100644 --- a/node_modules/binary-extensions/binary-extensions.json +++ b/node_modules/binary-extensions/binary-extensions.json @@ -7,6 +7,9 @@ "a", "aac", "adp", + "afdesign", + "afphoto", + "afpub", "ai", "aif", "aiff", @@ -35,6 +38,7 @@ "cmx", "cpio", "cr2", + "cr3", "cur", "dat", "dcm", diff --git a/node_modules/binary-extensions/binary-extensions.json.d.ts b/node_modules/binary-extensions/binary-extensions.json.d.ts deleted file mode 100644 index 94a248c2bcff7..0000000000000 --- a/node_modules/binary-extensions/binary-extensions.json.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare const binaryExtensionsJson: readonly string[]; - -export = binaryExtensionsJson; diff --git a/node_modules/binary-extensions/index.d.ts b/node_modules/binary-extensions/index.d.ts deleted file mode 100644 index f469ac5fb0fe5..0000000000000 --- a/node_modules/binary-extensions/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** -List of binary file extensions. - -@example -``` -import binaryExtensions = require('binary-extensions'); - -console.log(binaryExtensions); -//=> ['3ds', '3g2', …] -``` -*/ -declare const binaryExtensions: readonly string[]; - -export = binaryExtensions; diff --git a/node_modules/binary-extensions/index.js b/node_modules/binary-extensions/index.js index d46e468867114..6c99c7eb54f17 100644 --- a/node_modules/binary-extensions/index.js +++ b/node_modules/binary-extensions/index.js @@ -1 +1,3 @@ -module.exports = require('./binary-extensions.json'); +import binaryExtensions from './binary-extensions.json' with {type: 'json'}; + +export default binaryExtensions; diff --git a/node_modules/binary-extensions/license b/node_modules/binary-extensions/license index 401b1c731bcd3..5493a1a6e3f9a 100644 --- a/node_modules/binary-extensions/license +++ b/node_modules/binary-extensions/license @@ -1,6 +1,7 @@ MIT License -Copyright (c) 2019 Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com), Paul Miller (https://paulmillr.com) +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) +Copyright (c) Paul Miller (https://paulmillr.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/node_modules/binary-extensions/package.json b/node_modules/binary-extensions/package.json index c4d3641735b91..abe49c2e9a34a 100644 --- a/node_modules/binary-extensions/package.json +++ b/node_modules/binary-extensions/package.json @@ -1,25 +1,32 @@ { "name": "binary-extensions", - "version": "2.2.0", + "version": "3.1.0", "description": "List of binary file extensions", "license": "MIT", "repository": "sindresorhus/binary-extensions", + "funding": "https://github.com/sponsors/sindresorhus", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" + "url": "https://sindresorhus.com" }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": ">=8" + "node": ">=18.20" }, "scripts": { - "test": "xo && ava && tsd" + "//test": "xo && ava && tsd", + "test": "ava && tsd" }, "files": [ "index.js", "index.d.ts", - "binary-extensions.json", - "binary-extensions.json.d.ts" + "binary-extensions.json" ], "keywords": [ "binary", @@ -31,8 +38,8 @@ "array" ], "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" + "ava": "^6.1.2", + "tsd": "^0.31.0", + "xo": "^0.58.0" } } diff --git a/node_modules/binary-extensions/readme.md b/node_modules/binary-extensions/readme.md deleted file mode 100644 index 3e25dd835e08b..0000000000000 --- a/node_modules/binary-extensions/readme.md +++ /dev/null @@ -1,41 +0,0 @@ -# binary-extensions - -> List of binary file extensions - -The list is just a [JSON file](binary-extensions.json) and can be used anywhere. - - -## Install - -``` -$ npm install binary-extensions -``` - - -## Usage - -```js -const binaryExtensions = require('binary-extensions'); - -console.log(binaryExtensions); -//=> ['3ds', '3g2', …] -``` - - -## Related - -- [is-binary-path](https://github.com/sindresorhus/is-binary-path) - Check if a filepath is a binary file -- [text-extensions](https://github.com/sindresorhus/text-extensions) - List of text file extensions - - ---- - -<div align="center"> - <b> - <a href="https://tidelift.com/subscription/pkg/npm-binary-extensions?utm_source=npm-binary-extensions&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> - </b> - <br> - <sub> - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. - </sub> -</div> diff --git a/node_modules/brace-expansion/LICENSE b/node_modules/brace-expansion/LICENSE deleted file mode 100644 index de3226673c387..0000000000000 --- a/node_modules/brace-expansion/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/node_modules/brace-expansion/index.js b/node_modules/brace-expansion/index.js deleted file mode 100644 index 4af9ddee463f4..0000000000000 --- a/node_modules/brace-expansion/index.js +++ /dev/null @@ -1,203 +0,0 @@ -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m) return [str]; - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - if (/\$$/.test(m.pre)) { - for (var k = 0; k < post.length; k++) { - var expansion = pre+ '{' + m.body + '}' + post[k]; - expansions.push(expansion); - } - } else { - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = []; - - for (var j = 0; j < n.length; j++) { - N.push.apply(N, expand(n[j], false)); - } - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - } - - return expansions; -} - diff --git a/node_modules/brace-expansion/package.json b/node_modules/brace-expansion/package.json deleted file mode 100644 index 7097d41e39de5..0000000000000 --- a/node_modules/brace-expansion/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "brace-expansion", - "description": "Brace expansion as known from sh/bash", - "version": "2.0.1", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/brace-expansion.git" - }, - "homepage": "https://github.com/juliangruber/brace-expansion", - "main": "index.js", - "scripts": { - "test": "tape test/*.js", - "gentest": "bash test/generate.sh", - "bench": "matcha test/perf/bench.js" - }, - "dependencies": { - "balanced-match": "^1.0.0" - }, - "devDependencies": { - "@c4312/matcha": "^1.3.1", - "tape": "^4.6.0" - }, - "keywords": [], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/node_modules/builtins/License b/node_modules/builtins/License deleted file mode 100644 index b142e5dc08133..0000000000000 --- a/node_modules/builtins/License +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2015 Julian Gruber <julian@juliangruber.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/node_modules/builtins/Readme.md b/node_modules/builtins/Readme.md deleted file mode 100644 index b1c0007d6f5e4..0000000000000 --- a/node_modules/builtins/Readme.md +++ /dev/null @@ -1,39 +0,0 @@ -# builtins - -[![CI](https://github.com/juliangruber/builtins/actions/workflows/ci.yml/badge.svg)](https://github.com/juliangruber/builtins/actions/workflows/ci.yml) - -List of node.js [builtin modules](http://nodejs.org/api/). - -## Usage - -```js -const builtins = require('builtins') -``` - -Get list of core modules for current Node.js version: - -```js -assert(builtins().includes('http')) -``` - -Get list of core modules for specific Node.js version: - -```js -assert(builtins({ version: '6.0.0' }).includes('http')) -``` - -Get list of core modules present in one or mode Node.js versions: - -```js -assert(builtins({ version: '*' }).includes('worker_threads')) -``` - -Add experimental modules to the list: - -```js -assert(builtins({ experimental: true }).includes('wasi')) -``` - -## License - -MIT diff --git a/node_modules/builtins/index.js b/node_modules/builtins/index.js deleted file mode 100644 index b715278437cbc..0000000000000 --- a/node_modules/builtins/index.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict' - -const semver = require('semver') - -const permanentModules = [ - 'assert', - 'buffer', - 'child_process', - 'cluster', - 'console', - 'constants', - 'crypto', - 'dgram', - 'dns', - 'domain', - 'events', - 'fs', - 'http', - 'https', - 'module', - 'net', - 'os', - 'path', - 'punycode', - 'querystring', - 'readline', - 'repl', - 'stream', - 'string_decoder', - 'sys', - 'timers', - 'tls', - 'tty', - 'url', - 'util', - 'vm', - 'zlib' -] - -const versionLockedModules = { - freelist: '<6.0.0', - v8: '>=1.0.0', - process: '>=1.1.0', - inspector: '>=8.0.0', - async_hooks: '>=8.1.0', - http2: '>=8.4.0', - perf_hooks: '>=8.5.0', - trace_events: '>=10.0.0', - worker_threads: '>=12.0.0', - 'node:test': '>=18.0.0' -} - -const experimentalModules = { - worker_threads: '>=10.5.0', - wasi: '>=12.16.0', - diagnostics_channel: '^14.17.0 || >=15.1.0' -} - -module.exports = ({ version = process.version, experimental = false } = {}) => { - const builtins = [...permanentModules] - - for (const [name, semverRange] of Object.entries(versionLockedModules)) { - if (version === '*' || semver.satisfies(version, semverRange)) { - builtins.push(name) - } - } - - if (experimental) { - for (const [name, semverRange] of Object.entries(experimentalModules)) { - if ( - !builtins.includes(name) && - (version === '*' || semver.satisfies(version, semverRange)) - ) { - builtins.push(name) - } - } - } - - return builtins -} diff --git a/node_modules/builtins/package.json b/node_modules/builtins/package.json deleted file mode 100644 index 1c43660c7483f..0000000000000 --- a/node_modules/builtins/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "builtins", - "version": "5.0.1", - "description": "List of node.js builtin modules", - "repository": "juliangruber/builtins", - "license": "MIT", - "main": "index.js", - "files": [], - "scripts": { - "test": "prettier-standard && standard && node-core-test" - }, - "dependencies": { - "semver": "^7.0.0" - }, - "devDependencies": { - "node-core-test": "^1.4.0", - "prettier-standard": "^15.0.1", - "standard": "^14.3.4" - } -} diff --git a/node_modules/cacache/lib/content/read.js b/node_modules/cacache/lib/content/read.js index 8367ccb205d0b..5f6192c3cec56 100644 --- a/node_modules/cacache/lib/content/read.js +++ b/node_modules/cacache/lib/content/read.js @@ -1,6 +1,6 @@ 'use strict' -const fs = require('@npmcli/fs') +const fs = require('fs/promises') const fsm = require('fs-minipass') const ssri = require('ssri') const contentPath = require('./path') @@ -13,18 +13,20 @@ async function read (cache, integrity, opts = {}) { const { size } = opts const { stat, cpath, sri } = await withContentSri(cache, integrity, async (cpath, sri) => { // get size - const stat = await fs.stat(cpath) + const stat = size ? { size } : await fs.stat(cpath) return { stat, cpath, sri } }) - if (typeof size === 'number' && stat.size !== size) { - throw sizeError(size, stat.size) - } if (stat.size > MAX_SINGLE_READ_SIZE) { return readPipeline(cpath, stat.size, sri, new Pipeline()).concat() } const data = await fs.readFile(cpath, { encoding: null }) + + if (stat.size !== data.length) { + throw sizeError(stat.size, data.length) + } + if (!ssri.checkData(data, sri)) { throw integrityError(sri, cpath) } @@ -46,24 +48,6 @@ const readPipeline = (cpath, size, sri, stream) => { return stream } -module.exports.sync = readSync - -function readSync (cache, integrity, opts = {}) { - const { size } = opts - return withContentSriSync(cache, integrity, (cpath, sri) => { - const data = fs.readFileSync(cpath, { encoding: null }) - if (typeof size === 'number' && size !== data.length) { - throw sizeError(size, data.length) - } - - if (ssri.checkData(data, sri)) { - return data - } - - throw integrityError(sri, cpath) - }) -} - module.exports.stream = readStream module.exports.readStream = readStream @@ -73,35 +57,25 @@ function readStream (cache, integrity, opts = {}) { // Set all this up to run on the stream and then just return the stream Promise.resolve().then(async () => { const { stat, cpath, sri } = await withContentSri(cache, integrity, async (cpath, sri) => { - // just stat to ensure it exists - const stat = await fs.stat(cpath) + // get size + const stat = size ? { size } : await fs.stat(cpath) return { stat, cpath, sri } }) - if (typeof size === 'number' && size !== stat.size) { - return stream.emit('error', sizeError(size, stat.size)) - } - readPipeline(cpath, stat.size, sri, stream) + return readPipeline(cpath, stat.size, sri, stream) }).catch(err => stream.emit('error', err)) return stream } module.exports.copy = copy -module.exports.copy.sync = copySync function copy (cache, integrity, dest) { - return withContentSri(cache, integrity, (cpath, sri) => { + return withContentSri(cache, integrity, (cpath) => { return fs.copyFile(cpath, dest) }) } -function copySync (cache, integrity, dest) { - return withContentSriSync(cache, integrity, (cpath, sri) => { - return fs.copyFileSync(cpath, dest) - }) -} - module.exports.hasContent = hasContent async function hasContent (cache, integrity) { @@ -130,34 +104,6 @@ async function hasContent (cache, integrity) { } } -module.exports.hasContent.sync = hasContentSync - -function hasContentSync (cache, integrity) { - if (!integrity) { - return false - } - - return withContentSriSync(cache, integrity, (cpath, sri) => { - try { - const stat = fs.statSync(cpath) - return { size: stat.size, sri, stat } - } catch (err) { - if (err.code === 'ENOENT') { - return false - } - - if (err.code === 'EPERM') { - /* istanbul ignore else */ - if (process.platform !== 'win32') { - throw err - } else { - return false - } - } - } - }) -} - async function withContentSri (cache, integrity, fn) { const sri = ssri.parse(integrity) // If `integrity` has multiple entries, pick the first digest @@ -201,28 +147,6 @@ async function withContentSri (cache, integrity, fn) { } } -function withContentSriSync (cache, integrity, fn) { - const sri = ssri.parse(integrity) - // If `integrity` has multiple entries, pick the first digest - // with available local data. - const algo = sri.pickAlgorithm() - const digests = sri[algo] - if (digests.length <= 1) { - const cpath = contentPath(cache, digests[0]) - return fn(cpath, digests[0]) - } else { - let lastErr = null - for (const meta of digests) { - try { - return withContentSriSync(cache, meta, fn) - } catch (err) { - lastErr = err - } - } - throw lastErr - } -} - function sizeError (expected, found) { /* eslint-disable-next-line max-len */ const err = new Error(`Bad data size: expected inserted data to be ${expected} bytes, but got ${found} instead`) diff --git a/node_modules/cacache/lib/content/rm.js b/node_modules/cacache/lib/content/rm.js index f7333053b393f..ce58d679e4cb2 100644 --- a/node_modules/cacache/lib/content/rm.js +++ b/node_modules/cacache/lib/content/rm.js @@ -1,10 +1,8 @@ 'use strict' -const util = require('util') - +const fs = require('fs/promises') const contentPath = require('./path') const { hasContent } = require('./read') -const rimraf = util.promisify(require('rimraf')) module.exports = rm @@ -12,7 +10,7 @@ async function rm (cache, integrity) { const content = await hasContent(cache, integrity) // ~pretty~ sure we can't end up with a content lacking sri, but be safe if (content && content.sri) { - await rimraf(contentPath(cache, content.sri)) + await fs.rm(contentPath(cache, content.sri), { recursive: true, force: true }) return true } else { return false diff --git a/node_modules/cacache/lib/content/write.js b/node_modules/cacache/lib/content/write.js index 62388dc81d0fd..e7187abca8788 100644 --- a/node_modules/cacache/lib/content/write.js +++ b/node_modules/cacache/lib/content/write.js @@ -1,28 +1,25 @@ 'use strict' const events = require('events') -const util = require('util') const contentPath = require('./path') -const fixOwner = require('../util/fix-owner') -const fs = require('@npmcli/fs') -const moveFile = require('../util/move-file') -const Minipass = require('minipass') +const fs = require('fs/promises') +const { moveFile } = require('@npmcli/fs') +const { Minipass } = require('minipass') const Pipeline = require('minipass-pipeline') const Flush = require('minipass-flush') const path = require('path') -const rimraf = util.promisify(require('rimraf')) const ssri = require('ssri') const uniqueFilename = require('unique-filename') const fsm = require('fs-minipass') module.exports = write +// Cache of move operations in process so we don't duplicate +const moveOperations = new Map() + async function write (cache, data, opts = {}) { const { algorithms, size, integrity } = opts - if (algorithms && algorithms.length > 1) { - throw new Error('opts.algorithms only supports a single algorithm for now') - } if (typeof size === 'number' && data.length !== size) { throw sizeError(size, data.length) @@ -33,16 +30,19 @@ async function write (cache, data, opts = {}) { throw checksumError(integrity, sri) } - const tmp = await makeTmp(cache, opts) - try { - await fs.writeFile(tmp.target, data, { flag: 'wx' }) - await moveToDestination(tmp, cache, sri, opts) - return { integrity: sri, size: data.length } - } finally { - if (!tmp.moved) { - await rimraf(tmp.target) + for (const algo in sri) { + const tmp = await makeTmp(cache, opts) + const hash = sri[algo].toString() + try { + await fs.writeFile(tmp.target, data, { flag: 'wx' }) + await moveToDestination(tmp, cache, hash, opts) + } finally { + if (!tmp.moved) { + await fs.rm(tmp.target, { recursive: true, force: true }) + } } } + return { integrity: sri, size: data.length } } module.exports.stream = writeStream @@ -67,6 +67,7 @@ class CacacheWriteStream extends Flush { this.cache, this.opts ) + this.handleContentP.catch(error => this.emit('error', error)) } return this.inputStream.write(chunk, encoding, cb) } @@ -80,9 +81,11 @@ class CacacheWriteStream extends Flush { // defer this one tick by rejecting a promise on it. return Promise.reject(e).catch(cb) } + // eslint-disable-next-line promise/catch-or-return this.handleContentP.then( (res) => { res.integrity && this.emit('integrity', res.integrity) + // eslint-disable-next-line promise/always-return res.size !== null && this.emit('size', res.size) cb() }, @@ -109,7 +112,7 @@ async function handleContent (inputStream, cache, opts) { return res } finally { if (!tmp.moved) { - await rimraf(tmp.target) + await fs.rm(tmp.target, { recursive: true, force: true }) } } } @@ -150,21 +153,37 @@ async function pipeToTmp (inputStream, cache, tmpTarget, opts) { async function makeTmp (cache, opts) { const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix) - await fixOwner.mkdirfix(cache, path.dirname(tmpTarget)) + await fs.mkdir(path.dirname(tmpTarget), { recursive: true }) return { target: tmpTarget, moved: false, } } -async function moveToDestination (tmp, cache, sri, opts) { +async function moveToDestination (tmp, cache, sri) { const destination = contentPath(cache, sri) const destDir = path.dirname(destination) - - await fixOwner.mkdirfix(cache, destDir) - await moveFile(tmp.target, destination) - tmp.moved = true - await fixOwner.chownr(cache, destination) + if (moveOperations.has(destination)) { + return moveOperations.get(destination) + } + moveOperations.set( + destination, + fs.mkdir(destDir, { recursive: true }) + .then(async () => { + await moveFile(tmp.target, destination, { overwrite: false }) + tmp.moved = true + return tmp.moved + }) + .catch(err => { + if (!err.message.startsWith('The destination file exists')) { + throw Object.assign(err, { code: 'EEXIST' }) + } + }).finally(() => { + moveOperations.delete(destination) + }) + + ) + return moveOperations.get(destination) } function sizeError (expected, found) { diff --git a/node_modules/cacache/lib/entry-index.js b/node_modules/cacache/lib/entry-index.js index cbfa619099f90..0e09b10818d09 100644 --- a/node_modules/cacache/lib/entry-index.js +++ b/node_modules/cacache/lib/entry-index.js @@ -1,21 +1,25 @@ 'use strict' -const util = require('util') const crypto = require('crypto') -const fs = require('@npmcli/fs') -const Minipass = require('minipass') +const { + appendFile, + mkdir, + readFile, + readdir, + rm, + writeFile, +} = require('fs/promises') +const { Minipass } = require('minipass') const path = require('path') const ssri = require('ssri') const uniqueFilename = require('unique-filename') const contentPath = require('./content/path') -const fixOwner = require('./util/fix-owner') const hashToSegments = require('./util/hash-to-segments') const indexV = require('../package.json')['cache-version'].index -const moveFile = require('@npmcli/move-file') -const _rimraf = require('rimraf') -const rimraf = util.promisify(_rimraf) -rimraf.sync = _rimraf.sync +const { moveFile } = require('@npmcli/fs') + +const lsStreamConcurrency = 5 module.exports.NotFoundError = class NotFoundError extends Error { constructor (cache, key) { @@ -66,7 +70,7 @@ async function compact (cache, key, matchFn, opts = {}) { const setup = async () => { const target = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix) - await fixOwner.mkdirfix(cache, path.dirname(target)) + await mkdir(path.dirname(target), { recursive: true }) return { target, moved: false, @@ -75,24 +79,17 @@ async function compact (cache, key, matchFn, opts = {}) { const teardown = async (tmp) => { if (!tmp.moved) { - return rimraf(tmp.target) + return rm(tmp.target, { recursive: true, force: true }) } } const write = async (tmp) => { - await fs.writeFile(tmp.target, newIndex, { flag: 'wx' }) - await fixOwner.mkdirfix(cache, path.dirname(bucket)) + await writeFile(tmp.target, newIndex, { flag: 'wx' }) + await mkdir(path.dirname(bucket), { recursive: true }) // we use @npmcli/move-file directly here because we // want to overwrite the existing file await moveFile(tmp.target, bucket) tmp.moved = true - try { - await fixOwner.chownr(cache, bucket) - } catch (err) { - if (err.code !== 'ENOENT') { - throw err - } - } } // write the file atomically @@ -114,17 +111,17 @@ async function compact (cache, key, matchFn, opts = {}) { module.exports.insert = insert async function insert (cache, key, integrity, opts = {}) { - const { metadata, size } = opts + const { metadata, size, time } = opts const bucket = bucketPath(cache, key) const entry = { key, integrity: integrity && ssri.stringify(integrity), - time: Date.now(), + time: time || Date.now(), size, metadata, } try { - await fixOwner.mkdirfix(cache, path.dirname(bucket)) + await mkdir(path.dirname(bucket), { recursive: true }) const stringified = JSON.stringify(entry) // NOTE - Cleverness ahoy! // @@ -134,44 +131,13 @@ async function insert (cache, key, integrity, opts = {}) { // // Thanks to @isaacs for the whiteboarding session that ended up with // this. - await fs.appendFile(bucket, `\n${hashEntry(stringified)}\t${stringified}`) - await fixOwner.chownr(cache, bucket) + await appendFile(bucket, `\n${hashEntry(stringified)}\t${stringified}`) } catch (err) { if (err.code === 'ENOENT') { return undefined } throw err - // There's a class of race conditions that happen when things get deleted - // during fixOwner, or between the two mkdirfix/chownr calls. - // - // It's perfectly fine to just not bother in those cases and lie - // that the index entry was written. Because it's a cache. - } - return formatEntry(cache, entry) -} - -module.exports.insert.sync = insertSync - -function insertSync (cache, key, integrity, opts = {}) { - const { metadata, size } = opts - const bucket = bucketPath(cache, key) - const entry = { - key, - integrity: integrity && ssri.stringify(integrity), - time: Date.now(), - size, - metadata, - } - fixOwner.mkdirfix.sync(cache, path.dirname(bucket)) - const stringified = JSON.stringify(entry) - fs.appendFileSync(bucket, `\n${hashEntry(stringified)}\t${stringified}`) - try { - fixOwner.chownr.sync(cache, bucket) - } catch (err) { - if (err.code !== 'ENOENT') { - throw err - } } return formatEntry(cache, entry) } @@ -198,27 +164,6 @@ async function find (cache, key) { } } -module.exports.find.sync = findSync - -function findSync (cache, key) { - const bucket = bucketPath(cache, key) - try { - return bucketEntriesSync(bucket).reduce((latest, next) => { - if (next && next.key === key) { - return formatEntry(cache, next) - } else { - return latest - } - }, null) - } catch (err) { - if (err.code === 'ENOENT') { - return null - } else { - throw err - } - } -} - module.exports.delete = del function del (cache, key, opts = {}) { @@ -227,18 +172,7 @@ function del (cache, key, opts = {}) { } const bucket = bucketPath(cache, key) - return rimraf(bucket) -} - -module.exports.delete.sync = delSync - -function delSync (cache, key, opts = {}) { - if (!opts.removeFully) { - return insertSync(cache, key, null, opts) - } - - const bucket = bucketPath(cache, key) - return rimraf.sync(bucket) + return rm(bucket, { recursive: true, force: true }) } module.exports.lsStream = lsStream @@ -249,16 +183,17 @@ function lsStream (cache) { // Set all this up to run on the stream and then just return the stream Promise.resolve().then(async () => { + const { default: pMap } = await import('p-map') const buckets = await readdirOrEmpty(indexDir) - await Promise.all(buckets.map(async (bucket) => { + await pMap(buckets, async (bucket) => { const bucketPath = path.join(indexDir, bucket) const subbuckets = await readdirOrEmpty(bucketPath) - await Promise.all(subbuckets.map(async (subbucket) => { + await pMap(subbuckets, async (subbucket) => { const subbucketPath = path.join(bucketPath, subbucket) // "/cachename/<bucket 0xFF>/<bucket 0xFF>./*" const subbucketEntries = await readdirOrEmpty(subbucketPath) - await Promise.all(subbucketEntries.map(async (entry) => { + await pMap(subbucketEntries, async (entry) => { const entryPath = path.join(subbucketPath, entry) try { const entries = await bucketEntries(entryPath) @@ -281,10 +216,14 @@ function lsStream (cache) { } throw err } - })) - })) - })) + }, + { concurrency: lsStreamConcurrency }) + }, + { concurrency: lsStreamConcurrency }) + }, + { concurrency: lsStreamConcurrency }) stream.end() + return stream }).catch(err => stream.emit('error', err)) return stream @@ -303,18 +242,11 @@ async function ls (cache) { module.exports.bucketEntries = bucketEntries async function bucketEntries (bucket, filter) { - const data = await fs.readFile(bucket, 'utf8') - return _bucketEntries(data, filter) -} - -module.exports.bucketEntries.sync = bucketEntriesSync - -function bucketEntriesSync (bucket, filter) { - const data = fs.readFileSync(bucket, 'utf8') + const data = await readFile(bucket, 'utf8') return _bucketEntries(data, filter) } -function _bucketEntries (data, filter) { +function _bucketEntries (data) { const entries = [] data.split('\n').forEach((entry) => { if (!entry) { @@ -330,10 +262,11 @@ function _bucketEntries (data, filter) { let obj try { obj = JSON.parse(pieces[1]) - } catch (e) { - // Entry is corrupted! - return + } catch (_) { + // eslint-ignore-next-line no-empty-block } + // coverage disabled here, no need to test with an entry that parses to something falsey + // istanbul ignore else if (obj) { entries.push(obj) } @@ -393,7 +326,7 @@ function formatEntry (cache, entry, keepAll) { } function readdirOrEmpty (dir) { - return fs.readdir(dir).catch((err) => { + return readdir(dir).catch((err) => { if (err.code === 'ENOENT' || err.code === 'ENOTDIR') { return [] } diff --git a/node_modules/cacache/lib/get.js b/node_modules/cacache/lib/get.js index cc9d8f6796647..80ec206c7ecaa 100644 --- a/node_modules/cacache/lib/get.js +++ b/node_modules/cacache/lib/get.js @@ -1,7 +1,7 @@ 'use strict' const Collect = require('minipass-collect') -const Minipass = require('minipass') +const { Minipass } = require('minipass') const Pipeline = require('minipass-pipeline') const index = require('./entry-index') @@ -53,61 +53,6 @@ async function getDataByDigest (cache, key, opts = {}) { } module.exports.byDigest = getDataByDigest -function getDataSync (cache, key, opts = {}) { - const { integrity, memoize, size } = opts - const memoized = memo.get(cache, key, opts) - - if (memoized && memoize !== false) { - return { - metadata: memoized.entry.metadata, - data: memoized.data, - integrity: memoized.entry.integrity, - size: memoized.entry.size, - } - } - const entry = index.find.sync(cache, key, opts) - if (!entry) { - throw new index.NotFoundError(cache, key) - } - const data = read.sync(cache, entry.integrity, { - integrity: integrity, - size: size, - }) - const res = { - metadata: entry.metadata, - data: data, - size: entry.size, - integrity: entry.integrity, - } - if (memoize) { - memo.put(cache, entry, res.data, opts) - } - - return res -} - -module.exports.sync = getDataSync - -function getDataByDigestSync (cache, digest, opts = {}) { - const { integrity, memoize, size } = opts - const memoized = memo.get.byDigest(cache, digest, opts) - - if (memoized && memoize !== false) { - return memoized - } - - const res = read.sync(cache, digest, { - integrity: integrity, - size: size, - }) - if (memoize) { - memo.put.byDigest(cache, digest, res, opts) - } - - return res -} -module.exports.sync.byDigest = getDataByDigestSync - const getMemoizedStream = (memoized) => { const stream = new Minipass() stream.on('newListener', function (ev, cb) { @@ -155,6 +100,7 @@ function getStream (cache, key, opts = {}) { stream.unshift(memoStream) } stream.unshift(src) + return stream }).catch((err) => stream.emit('error', err)) return stream diff --git a/node_modules/cacache/lib/index.js b/node_modules/cacache/lib/index.js index 1c56be68dd8fd..c9b0da5f3a271 100644 --- a/node_modules/cacache/lib/index.js +++ b/node_modules/cacache/lib/index.js @@ -17,15 +17,12 @@ module.exports.ls.stream = index.lsStream module.exports.get = get module.exports.get.byDigest = get.byDigest -module.exports.get.sync = get.sync -module.exports.get.sync.byDigest = get.sync.byDigest module.exports.get.stream = get.stream module.exports.get.stream.byDigest = get.stream.byDigest module.exports.get.copy = get.copy module.exports.get.copy.byDigest = get.copy.byDigest module.exports.get.info = get.info module.exports.get.hasContent = get.hasContent -module.exports.get.hasContent.sync = get.hasContent.sync module.exports.put = put module.exports.put.stream = put.stream diff --git a/node_modules/cacache/lib/memoization.js b/node_modules/cacache/lib/memoization.js index 0ff604a479c9c..2ecc60912e456 100644 --- a/node_modules/cacache/lib/memoization.js +++ b/node_modules/cacache/lib/memoization.js @@ -1,8 +1,8 @@ 'use strict' -const LRU = require('lru-cache') +const { LRUCache } = require('lru-cache') -const MEMOIZED = new LRU({ +const MEMOIZED = new LRUCache({ max: 500, maxSize: 50 * 1024 * 1024, // 50MB ttl: 3 * 60 * 1000, // 3 minutes diff --git a/node_modules/cacache/lib/rm.js b/node_modules/cacache/lib/rm.js index 5f00071770b8d..a94760c7cf243 100644 --- a/node_modules/cacache/lib/rm.js +++ b/node_modules/cacache/lib/rm.js @@ -1,11 +1,10 @@ 'use strict' -const util = require('util') - +const { rm } = require('fs/promises') +const glob = require('./util/glob.js') const index = require('./entry-index') const memo = require('./memoization') const path = require('path') -const rimraf = util.promisify(require('rimraf')) const rmContent = require('./content/rm') module.exports = entry @@ -25,7 +24,8 @@ function content (cache, integrity) { module.exports.all = all -function all (cache) { +async function all (cache) { memo.clearMemoized() - return rimraf(path.join(cache, '*(content-*|index-*)')) + const paths = await glob(path.join(cache, '*(content-*|index-*)'), { silent: true, nosort: true }) + return Promise.all(paths.map((p) => rm(p, { recursive: true, force: true }))) } diff --git a/node_modules/cacache/lib/util/fix-owner.js b/node_modules/cacache/lib/util/fix-owner.js deleted file mode 100644 index 182fcb028f06c..0000000000000 --- a/node_modules/cacache/lib/util/fix-owner.js +++ /dev/null @@ -1,145 +0,0 @@ -'use strict' - -const util = require('util') - -const chownr = util.promisify(require('chownr')) -const mkdirp = require('mkdirp') -const inflight = require('promise-inflight') -const inferOwner = require('infer-owner') - -// Memoize getuid()/getgid() calls. -// patch process.setuid/setgid to invalidate cached value on change -const self = { uid: null, gid: null } -const getSelf = () => { - if (typeof self.uid !== 'number') { - self.uid = process.getuid() - const setuid = process.setuid - process.setuid = (uid) => { - self.uid = null - process.setuid = setuid - return process.setuid(uid) - } - } - if (typeof self.gid !== 'number') { - self.gid = process.getgid() - const setgid = process.setgid - process.setgid = (gid) => { - self.gid = null - process.setgid = setgid - return process.setgid(gid) - } - } -} - -module.exports.chownr = fixOwner - -async function fixOwner (cache, filepath) { - if (!process.getuid) { - // This platform doesn't need ownership fixing - return - } - - getSelf() - if (self.uid !== 0) { - // almost certainly can't chown anyway - return - } - - const { uid, gid } = await inferOwner(cache) - - // No need to override if it's already what we used. - if (self.uid === uid && self.gid === gid) { - return - } - - return inflight('fixOwner: fixing ownership on ' + filepath, () => - chownr( - filepath, - typeof uid === 'number' ? uid : self.uid, - typeof gid === 'number' ? gid : self.gid - ).catch((err) => { - if (err.code === 'ENOENT') { - return null - } - - throw err - }) - ) -} - -module.exports.chownr.sync = fixOwnerSync - -function fixOwnerSync (cache, filepath) { - if (!process.getuid) { - // This platform doesn't need ownership fixing - return - } - const { uid, gid } = inferOwner.sync(cache) - getSelf() - if (self.uid !== 0) { - // almost certainly can't chown anyway - return - } - - if (self.uid === uid && self.gid === gid) { - // No need to override if it's already what we used. - return - } - try { - chownr.sync( - filepath, - typeof uid === 'number' ? uid : self.uid, - typeof gid === 'number' ? gid : self.gid - ) - } catch (err) { - // only catch ENOENT, any other error is a problem. - if (err.code === 'ENOENT') { - return null - } - - throw err - } -} - -module.exports.mkdirfix = mkdirfix - -async function mkdirfix (cache, p, cb) { - // we have to infer the owner _before_ making the directory, even though - // we aren't going to use the results, since the cache itself might not - // exist yet. If we mkdirp it, then our current uid/gid will be assumed - // to be correct if it creates the cache folder in the process. - await inferOwner(cache) - try { - const made = await mkdirp(p) - if (made) { - await fixOwner(cache, made) - return made - } - } catch (err) { - if (err.code === 'EEXIST') { - await fixOwner(cache, p) - return null - } - throw err - } -} - -module.exports.mkdirfix.sync = mkdirfixSync - -function mkdirfixSync (cache, p) { - try { - inferOwner.sync(cache) - const made = mkdirp.sync(p) - if (made) { - fixOwnerSync(cache, made) - return made - } - } catch (err) { - if (err.code === 'EEXIST') { - fixOwnerSync(cache, p) - return null - } else { - throw err - } - } -} diff --git a/node_modules/cacache/lib/util/glob.js b/node_modules/cacache/lib/util/glob.js new file mode 100644 index 0000000000000..8500c1c16a429 --- /dev/null +++ b/node_modules/cacache/lib/util/glob.js @@ -0,0 +1,7 @@ +'use strict' + +const { glob } = require('glob') +const path = require('path') + +const globify = (pattern) => pattern.split(path.win32.sep).join(path.posix.sep) +module.exports = (path, options) => glob(globify(path), options) diff --git a/node_modules/cacache/lib/util/move-file.js b/node_modules/cacache/lib/util/move-file.js deleted file mode 100644 index a0b40413cb56e..0000000000000 --- a/node_modules/cacache/lib/util/move-file.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict' - -const fs = require('@npmcli/fs') -const move = require('@npmcli/move-file') -const pinflight = require('promise-inflight') - -module.exports = moveFile - -async function moveFile (src, dest) { - const isWindows = process.platform === 'win32' - - // This isn't quite an fs.rename -- the assumption is that - // if `dest` already exists, and we get certain errors while - // trying to move it, we should just not bother. - // - // In the case of cache corruption, users will receive an - // EINTEGRITY error elsewhere, and can remove the offending - // content their own way. - // - // Note that, as the name suggests, this strictly only supports file moves. - try { - await fs.link(src, dest) - } catch (err) { - if (isWindows && err.code === 'EPERM') { - // XXX This is a really weird way to handle this situation, as it - // results in the src file being deleted even though the dest - // might not exist. Since we pretty much always write files to - // deterministic locations based on content hash, this is likely - // ok (or at worst, just ends in a future cache miss). But it would - // be worth investigating at some time in the future if this is - // really what we want to do here. - } else if (err.code === 'EEXIST' || err.code === 'EBUSY') { - // file already exists, so whatever - } else { - throw err - } - } - try { - await Promise.all([ - fs.unlink(src), - !isWindows && fs.chmod(dest, '0444'), - ]) - } catch (e) { - return pinflight('cacache-move-file:' + dest, async () => { - await fs.stat(dest).catch((err) => { - if (err.code !== 'ENOENT') { - // Something else is wrong here. Bail bail bail - throw err - } - }) - // file doesn't already exist! let's try a rename -> copy fallback - // only delete if it successfully copies - return move(src, dest) - }) - } -} diff --git a/node_modules/cacache/lib/util/tmp.js b/node_modules/cacache/lib/util/tmp.js index b4437cfcbeed6..0bf5302136ebe 100644 --- a/node_modules/cacache/lib/util/tmp.js +++ b/node_modules/cacache/lib/util/tmp.js @@ -1,8 +1,7 @@ 'use strict' -const fs = require('@npmcli/fs') - -const fixOwner = require('./fix-owner') +const { withTempDir } = require('@npmcli/fs') +const fs = require('fs/promises') const path = require('path') module.exports.mkdir = mktmpdir @@ -23,11 +22,5 @@ function withTmp (cache, opts, cb) { cb = opts opts = {} } - return fs.withTempDir(path.join(cache, 'tmp'), cb, opts) -} - -module.exports.fix = fixtmpdir - -function fixtmpdir (cache) { - return fixOwner(cache, path.join(cache, 'tmp')) + return withTempDir(path.join(cache, 'tmp'), cb, opts) } diff --git a/node_modules/cacache/lib/verify.js b/node_modules/cacache/lib/verify.js index 52692a01d192f..dcff3aa73f317 100644 --- a/node_modules/cacache/lib/verify.js +++ b/node_modules/cacache/lib/verify.js @@ -1,20 +1,20 @@ 'use strict' -const util = require('util') - -const pMap = require('p-map') +const { + mkdir, + readFile, + rm, + stat, + truncate, + writeFile, +} = require('fs/promises') const contentPath = require('./content/path') -const fixOwner = require('./util/fix-owner') -const fs = require('@npmcli/fs') const fsm = require('fs-minipass') -const glob = util.promisify(require('glob')) +const glob = require('./util/glob.js') const index = require('./entry-index') const path = require('path') -const rimraf = util.promisify(require('rimraf')) const ssri = require('ssri') -const globify = pattern => pattern.split('\\').join('/') - const hasOwnProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) @@ -67,19 +67,17 @@ async function verify (cache, opts) { return stats } -async function markStartTime (cache, opts) { +async function markStartTime () { return { startTime: new Date() } } -async function markEndTime (cache, opts) { +async function markEndTime () { return { endTime: new Date() } } async function fixPerms (cache, opts) { opts.log.silly('verify', 'fixing cache permissions') - await fixOwner.mkdirfix(cache, cache) - // TODO - fix file permissions too - await fixOwner.chownr(cache, cache) + await mkdir(cache, { recursive: true }) return null } @@ -90,10 +88,11 @@ async function fixPerms (cache, opts) { // 2. Mark each integrity value as "live" // 3. Read entire filesystem tree in `content-vX/` dir // 4. If content is live, verify its checksum and delete it if it fails -// 5. If content is not marked as live, rimraf it. +// 5. If content is not marked as live, rm it. // async function garbageCollect (cache, opts) { opts.log.silly('verify', 'garbage collecting content') + const { default: pMap } = await import('p-map') const indexStream = index.lsStream(cache) const liveContent = new Set() indexStream.on('data', (entry) => { @@ -101,13 +100,17 @@ async function garbageCollect (cache, opts) { return } - liveContent.add(entry.integrity.toString()) + // integrity is stringified, re-parse it so we can get each hash + const integrity = ssri.parse(entry.integrity) + for (const algo in integrity) { + liveContent.add(integrity[algo].toString()) + } }) await new Promise((resolve, reject) => { indexStream.on('end', resolve).on('error', reject) }) const contentDir = contentPath.contentDir(cache) - const files = await glob(globify(path.join(contentDir, '**')), { + const files = await glob(path.join(contentDir, '**'), { follow: false, nodir: true, nosort: true, @@ -139,8 +142,8 @@ async function garbageCollect (cache, opts) { } else { // No entries refer to this content. We can delete. stats.reclaimedCount++ - const s = await fs.stat(f) - await rimraf(f) + const s = await stat(f) + await rm(f, { recursive: true, force: true }) stats.reclaimedSize += s.size } return stats @@ -153,7 +156,7 @@ async function garbageCollect (cache, opts) { async function verifyContent (filepath, sri) { const contentInfo = {} try { - const { size } = await fs.stat(filepath) + const { size } = await stat(filepath) contentInfo.size = size contentInfo.valid = true await ssri.checkStream(new fsm.ReadStream(filepath), sri) @@ -165,7 +168,7 @@ async function verifyContent (filepath, sri) { throw err } - await rimraf(filepath) + await rm(filepath, { recursive: true, force: true }) contentInfo.valid = false } return contentInfo @@ -173,6 +176,7 @@ async function verifyContent (filepath, sri) { async function rebuildIndex (cache, opts) { opts.log.silly('verify', 'rebuilding index') + const { default: pMap } = await import('p-map') const entries = await index.ls(cache) const stats = { missingContent: 0, @@ -210,17 +214,18 @@ async function rebuildIndex (cache, opts) { return stats } -async function rebuildBucket (cache, bucket, stats, opts) { - await fs.truncate(bucket._path) +async function rebuildBucket (cache, bucket, stats) { + await truncate(bucket._path) // This needs to be serialized because cacache explicitly // lets very racy bucket conflicts clobber each other. for (const entry of bucket) { const content = contentPath(cache, entry.integrity) try { - await fs.stat(content) + await stat(content) await index.insert(cache, entry.key, entry.integrity, { metadata: entry.metadata, size: entry.size, + time: entry.time, }) stats.totalEntries++ } catch (err) { @@ -236,22 +241,18 @@ async function rebuildBucket (cache, bucket, stats, opts) { function cleanTmp (cache, opts) { opts.log.silly('verify', 'cleaning tmp directory') - return rimraf(path.join(cache, 'tmp')) + return rm(path.join(cache, 'tmp'), { recursive: true, force: true }) } -function writeVerifile (cache, opts) { +async function writeVerifile (cache, opts) { const verifile = path.join(cache, '_lastverified') opts.log.silly('verify', 'writing verifile to ' + verifile) - try { - return fs.writeFile(verifile, `${Date.now()}`) - } finally { - fixOwner.chownr.sync(cache, verifile) - } + return writeFile(verifile, `${Date.now()}`) } module.exports.lastRun = lastRun async function lastRun (cache) { - const data = await fs.readFile(path.join(cache, '_lastverified'), { encoding: 'utf8' }) + const data = await readFile(path.join(cache, '_lastverified'), { encoding: 'utf8' }) return new Date(+data) } diff --git a/node_modules/cacache/package.json b/node_modules/cacache/package.json index bb5674dafca81..fb8eb5f66edf9 100644 --- a/node_modules/cacache/package.json +++ b/node_modules/cacache/package.json @@ -1,6 +1,6 @@ { "name": "cacache", - "version": "16.1.1", + "version": "20.0.3", "cache-version": { "content": "2", "index": "5" @@ -12,24 +12,22 @@ "lib/" ], "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "test": "tap", "snap": "tap", "coverage": "tap", "test-docker": "docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "npmclilint": "npmcli-lint", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "postsnap": "npm run lintfix --", "postlint": "template-oss-check", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/cacache.git" + "url": "git+https://github.com/npm/cacache.git" }, "keywords": [ "cache", @@ -48,37 +46,37 @@ ], "license": "ISC", "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^1.1.1" + "p-map": "^7.0.2", + "ssri": "^13.0.0", + "unique-filename": "^5.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^6.0.1", + "@npmcli/template-oss": "4.28.0", "tap": "^16.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "windowsCI": false, - "version": "3.5.0" + "version": "4.28.0", + "publish": "true" }, - "author": "GitHub Inc." + "author": "GitHub Inc.", + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + } } diff --git a/node_modules/chalk/index.d.ts b/node_modules/chalk/index.d.ts deleted file mode 100644 index 9cd88f38beea8..0000000000000 --- a/node_modules/chalk/index.d.ts +++ /dev/null @@ -1,415 +0,0 @@ -/** -Basic foreground colors. - -[More colors here.](https://github.com/chalk/chalk/blob/master/readme.md#256-and-truecolor-color-support) -*/ -declare type ForegroundColor = - | 'black' - | 'red' - | 'green' - | 'yellow' - | 'blue' - | 'magenta' - | 'cyan' - | 'white' - | 'gray' - | 'grey' - | 'blackBright' - | 'redBright' - | 'greenBright' - | 'yellowBright' - | 'blueBright' - | 'magentaBright' - | 'cyanBright' - | 'whiteBright'; - -/** -Basic background colors. - -[More colors here.](https://github.com/chalk/chalk/blob/master/readme.md#256-and-truecolor-color-support) -*/ -declare type BackgroundColor = - | 'bgBlack' - | 'bgRed' - | 'bgGreen' - | 'bgYellow' - | 'bgBlue' - | 'bgMagenta' - | 'bgCyan' - | 'bgWhite' - | 'bgGray' - | 'bgGrey' - | 'bgBlackBright' - | 'bgRedBright' - | 'bgGreenBright' - | 'bgYellowBright' - | 'bgBlueBright' - | 'bgMagentaBright' - | 'bgCyanBright' - | 'bgWhiteBright'; - -/** -Basic colors. - -[More colors here.](https://github.com/chalk/chalk/blob/master/readme.md#256-and-truecolor-color-support) -*/ -declare type Color = ForegroundColor | BackgroundColor; - -declare type Modifiers = - | 'reset' - | 'bold' - | 'dim' - | 'italic' - | 'underline' - | 'inverse' - | 'hidden' - | 'strikethrough' - | 'visible'; - -declare namespace chalk { - /** - Levels: - - `0` - All colors disabled. - - `1` - Basic 16 colors support. - - `2` - ANSI 256 colors support. - - `3` - Truecolor 16 million colors support. - */ - type Level = 0 | 1 | 2 | 3; - - interface Options { - /** - Specify the color support for Chalk. - - By default, color support is automatically detected based on the environment. - - Levels: - - `0` - All colors disabled. - - `1` - Basic 16 colors support. - - `2` - ANSI 256 colors support. - - `3` - Truecolor 16 million colors support. - */ - level?: Level; - } - - /** - Return a new Chalk instance. - */ - type Instance = new (options?: Options) => Chalk; - - /** - Detect whether the terminal supports color. - */ - interface ColorSupport { - /** - The color level used by Chalk. - */ - level: Level; - - /** - Return whether Chalk supports basic 16 colors. - */ - hasBasic: boolean; - - /** - Return whether Chalk supports ANSI 256 colors. - */ - has256: boolean; - - /** - Return whether Chalk supports Truecolor 16 million colors. - */ - has16m: boolean; - } - - interface ChalkFunction { - /** - Use a template string. - - @remarks Template literals are unsupported for nested calls (see [issue #341](https://github.com/chalk/chalk/issues/341)) - - @example - ``` - import chalk = require('chalk'); - - log(chalk` - CPU: {red ${cpu.totalPercent}%} - RAM: {green ${ram.used / ram.total * 100}%} - DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} - `); - ``` - - @example - ``` - import chalk = require('chalk'); - - log(chalk.red.bgBlack`2 + 3 = {bold ${2 + 3}}`) - ``` - */ - (text: TemplateStringsArray, ...placeholders: unknown[]): string; - - (...text: unknown[]): string; - } - - interface Chalk extends ChalkFunction { - /** - Return a new Chalk instance. - */ - Instance: Instance; - - /** - The color support for Chalk. - - By default, color support is automatically detected based on the environment. - - Levels: - - `0` - All colors disabled. - - `1` - Basic 16 colors support. - - `2` - ANSI 256 colors support. - - `3` - Truecolor 16 million colors support. - */ - level: Level; - - /** - Use HEX value to set text color. - - @param color - Hexadecimal value representing the desired color. - - @example - ``` - import chalk = require('chalk'); - - chalk.hex('#DEADED'); - ``` - */ - hex(color: string): Chalk; - - /** - Use keyword color value to set text color. - - @param color - Keyword value representing the desired color. - - @example - ``` - import chalk = require('chalk'); - - chalk.keyword('orange'); - ``` - */ - keyword(color: string): Chalk; - - /** - Use RGB values to set text color. - */ - rgb(red: number, green: number, blue: number): Chalk; - - /** - Use HSL values to set text color. - */ - hsl(hue: number, saturation: number, lightness: number): Chalk; - - /** - Use HSV values to set text color. - */ - hsv(hue: number, saturation: number, value: number): Chalk; - - /** - Use HWB values to set text color. - */ - hwb(hue: number, whiteness: number, blackness: number): Chalk; - - /** - Use a [Select/Set Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters) (SGR) [color code number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) to set text color. - - 30 <= code && code < 38 || 90 <= code && code < 98 - For example, 31 for red, 91 for redBright. - */ - ansi(code: number): Chalk; - - /** - Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color. - */ - ansi256(index: number): Chalk; - - /** - Use HEX value to set background color. - - @param color - Hexadecimal value representing the desired color. - - @example - ``` - import chalk = require('chalk'); - - chalk.bgHex('#DEADED'); - ``` - */ - bgHex(color: string): Chalk; - - /** - Use keyword color value to set background color. - - @param color - Keyword value representing the desired color. - - @example - ``` - import chalk = require('chalk'); - - chalk.bgKeyword('orange'); - ``` - */ - bgKeyword(color: string): Chalk; - - /** - Use RGB values to set background color. - */ - bgRgb(red: number, green: number, blue: number): Chalk; - - /** - Use HSL values to set background color. - */ - bgHsl(hue: number, saturation: number, lightness: number): Chalk; - - /** - Use HSV values to set background color. - */ - bgHsv(hue: number, saturation: number, value: number): Chalk; - - /** - Use HWB values to set background color. - */ - bgHwb(hue: number, whiteness: number, blackness: number): Chalk; - - /** - Use a [Select/Set Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters) (SGR) [color code number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) to set background color. - - 30 <= code && code < 38 || 90 <= code && code < 98 - For example, 31 for red, 91 for redBright. - Use the foreground code, not the background code (for example, not 41, nor 101). - */ - bgAnsi(code: number): Chalk; - - /** - Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color. - */ - bgAnsi256(index: number): Chalk; - - /** - Modifier: Resets the current color chain. - */ - readonly reset: Chalk; - - /** - Modifier: Make text bold. - */ - readonly bold: Chalk; - - /** - Modifier: Emitting only a small amount of light. - */ - readonly dim: Chalk; - - /** - Modifier: Make text italic. (Not widely supported) - */ - readonly italic: Chalk; - - /** - Modifier: Make text underline. (Not widely supported) - */ - readonly underline: Chalk; - - /** - Modifier: Inverse background and foreground colors. - */ - readonly inverse: Chalk; - - /** - Modifier: Prints the text, but makes it invisible. - */ - readonly hidden: Chalk; - - /** - Modifier: Puts a horizontal line through the center of the text. (Not widely supported) - */ - readonly strikethrough: Chalk; - - /** - Modifier: Prints the text only when Chalk has a color support level > 0. - Can be useful for things that are purely cosmetic. - */ - readonly visible: Chalk; - - readonly black: Chalk; - readonly red: Chalk; - readonly green: Chalk; - readonly yellow: Chalk; - readonly blue: Chalk; - readonly magenta: Chalk; - readonly cyan: Chalk; - readonly white: Chalk; - - /* - Alias for `blackBright`. - */ - readonly gray: Chalk; - - /* - Alias for `blackBright`. - */ - readonly grey: Chalk; - - readonly blackBright: Chalk; - readonly redBright: Chalk; - readonly greenBright: Chalk; - readonly yellowBright: Chalk; - readonly blueBright: Chalk; - readonly magentaBright: Chalk; - readonly cyanBright: Chalk; - readonly whiteBright: Chalk; - - readonly bgBlack: Chalk; - readonly bgRed: Chalk; - readonly bgGreen: Chalk; - readonly bgYellow: Chalk; - readonly bgBlue: Chalk; - readonly bgMagenta: Chalk; - readonly bgCyan: Chalk; - readonly bgWhite: Chalk; - - /* - Alias for `bgBlackBright`. - */ - readonly bgGray: Chalk; - - /* - Alias for `bgBlackBright`. - */ - readonly bgGrey: Chalk; - - readonly bgBlackBright: Chalk; - readonly bgRedBright: Chalk; - readonly bgGreenBright: Chalk; - readonly bgYellowBright: Chalk; - readonly bgBlueBright: Chalk; - readonly bgMagentaBright: Chalk; - readonly bgCyanBright: Chalk; - readonly bgWhiteBright: Chalk; - } -} - -/** -Main Chalk object that allows to chain styles together. -Call the last one as a method with a string argument. -Order doesn't matter, and later styles take precedent in case of a conflict. -This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`. -*/ -declare const chalk: chalk.Chalk & chalk.ChalkFunction & { - supportsColor: chalk.ColorSupport | false; - Level: chalk.Level; - Color: Color; - ForegroundColor: ForegroundColor; - BackgroundColor: BackgroundColor; - Modifiers: Modifiers; - stderr: chalk.Chalk & {supportsColor: chalk.ColorSupport | false}; -}; - -export = chalk; diff --git a/node_modules/chalk/license b/node_modules/chalk/license index e7af2f77107d7..fa7ceba3eb4a9 100644 --- a/node_modules/chalk/license +++ b/node_modules/chalk/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/node_modules/chalk/package.json b/node_modules/chalk/package.json index 47c23f29068ca..c9e0dc52ba744 100644 --- a/node_modules/chalk/package.json +++ b/node_modules/chalk/package.json @@ -1,21 +1,32 @@ { "name": "chalk", - "version": "4.1.2", + "version": "5.6.2", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", "funding": "https://github.com/chalk/chalk?sponsor=1", - "main": "source", + "type": "module", + "main": "./source/index.js", + "exports": "./source/index.js", + "imports": { + "#ansi-styles": "./source/vendor/ansi-styles/index.js", + "#supports-color": { + "node": "./source/vendor/supports-color/index.js", + "default": "./source/vendor/supports-color/browser.js" + } + }, + "types": "./source/index.d.ts", + "sideEffects": false, "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "scripts": { - "test": "xo && nyc ava && tsd", + "test": "xo && c8 ava && tsd", "bench": "matcha benchmark.js" }, "files": [ "source", - "index.d.ts" + "!source/index.test-d.ts" ], "keywords": [ "color", @@ -25,7 +36,6 @@ "console", "cli", "string", - "str", "ansi", "style", "styles", @@ -40,29 +50,34 @@ "command-line", "text" ], - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "devDependencies": { - "ava": "^2.4.0", - "coveralls": "^3.0.7", - "execa": "^4.0.0", - "import-fresh": "^3.1.0", + "@types/node": "^16.11.10", + "ava": "^3.15.0", + "c8": "^7.10.0", + "color-convert": "^2.0.1", + "execa": "^6.0.0", + "log-update": "^5.0.0", "matcha": "^0.7.0", - "nyc": "^15.0.0", - "resolve-from": "^5.0.0", - "tsd": "^0.7.4", - "xo": "^0.28.2" + "tsd": "^0.19.0", + "xo": "^0.57.0", + "yoctodelay": "^2.0.0" }, "xo": { "rules": { "unicorn/prefer-string-slice": "off", - "unicorn/prefer-includes": "off", - "@typescript-eslint/member-ordering": "off", - "no-redeclare": "off", - "unicorn/string-content": "off", - "unicorn/better-regex": "off" + "@typescript-eslint/consistent-type-imports": "off", + "@typescript-eslint/consistent-type-exports": "off", + "@typescript-eslint/consistent-type-definitions": "off", + "unicorn/expiring-todo-comments": "off" } + }, + "c8": { + "reporter": [ + "text", + "lcov" + ], + "exclude": [ + "source/vendor" + ] } } diff --git a/node_modules/chalk/readme.md b/node_modules/chalk/readme.md deleted file mode 100644 index a055d21c97ed7..0000000000000 --- a/node_modules/chalk/readme.md +++ /dev/null @@ -1,341 +0,0 @@ -<h1 align="center"> - <br> - <br> - <img width="320" src="media/logo.svg" alt="Chalk"> - <br> - <br> - <br> -</h1> - -> Terminal string styling done right - -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript-ready](https://img.shields.io/npm/types/chalk.svg) [![run on repl.it](https://repl.it/badge/github/chalk/chalk)](https://repl.it/github/chalk/chalk) - -<img src="https://cdn.jsdelivr.net/gh/chalk/ansi-styles@8261697c95bf34b6c7767e2cbe9941a851d59385/screenshot.svg" width="900"> - -<br> - ---- - -<div align="center"> - <p> - <p> - <sup> - Sindre Sorhus' open source work is supported by the community on <a href="https://github.com/sponsors/sindresorhus">GitHub Sponsors</a> and <a href="https://stakes.social/0x44d871aebF0126Bf646753E2C976Aa7e68A66c15">Dev</a> - </sup> - </p> - <sup>Special thanks to:</sup> - <br> - <br> - <a href="https://standardresume.co/tech"> - <img src="https://sindresorhus.com/assets/thanks/standard-resume-logo.svg" width="160"/> - </a> - <br> - <br> - <a href="https://retool.com/?utm_campaign=sindresorhus"> - <img src="https://sindresorhus.com/assets/thanks/retool-logo.svg" width="230"/> - </a> - <br> - <br> - <a href="https://doppler.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=chalk&utm_source=github"> - <div> - <img src="https://dashboard.doppler.com/imgs/logo-long.svg" width="240" alt="Doppler"> - </div> - <b>All your environment variables, in one place</b> - <div> - <span>Stop struggling with scattered API keys, hacking together home-brewed tools,</span> - <br> - <span>and avoiding access controls. Keep your team and servers in sync with Doppler.</span> - </div> - </a> - <br> - <a href="https://uibakery.io/?utm_source=chalk&utm_medium=sponsor&utm_campaign=github"> - <div> - <img src="https://sindresorhus.com/assets/thanks/uibakery-logo.jpg" width="270" alt="UI Bakery"> - </div> - </a> - </p> -</div> - ---- - -<br> - -## Highlights - -- Expressive API -- Highly performant -- Ability to nest styles -- [256/Truecolor color support](#256-and-truecolor-color-support) -- Auto-detects color support -- Doesn't extend `String.prototype` -- Clean and focused -- Actively maintained -- [Used by ~50,000 packages](https://www.npmjs.com/browse/depended/chalk) as of January 1, 2020 - -## Install - -```console -$ npm install chalk -``` - -## Usage - -```js -const chalk = require('chalk'); - -console.log(chalk.blue('Hello world!')); -``` - -Chalk comes with an easy to use composable API where you just chain and nest the styles you want. - -```js -const chalk = require('chalk'); -const log = console.log; - -// Combine styled and normal strings -log(chalk.blue('Hello') + ' World' + chalk.red('!')); - -// Compose multiple styles using the chainable API -log(chalk.blue.bgRed.bold('Hello world!')); - -// Pass in multiple arguments -log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz')); - -// Nest styles -log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!')); - -// Nest styles of the same type even (color, underline, background) -log(chalk.green( - 'I am a green line ' + - chalk.blue.underline.bold('with a blue substring') + - ' that becomes green again!' -)); - -// ES2015 template literal -log(` -CPU: ${chalk.red('90%')} -RAM: ${chalk.green('40%')} -DISK: ${chalk.yellow('70%')} -`); - -// ES2015 tagged template literal -log(chalk` -CPU: {red ${cpu.totalPercent}%} -RAM: {green ${ram.used / ram.total * 100}%} -DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} -`); - -// Use RGB colors in terminal emulators that support it. -log(chalk.keyword('orange')('Yay for orange colored text!')); -log(chalk.rgb(123, 45, 67).underline('Underlined reddish color')); -log(chalk.hex('#DEADED').bold('Bold gray!')); -``` - -Easily define your own themes: - -```js -const chalk = require('chalk'); - -const error = chalk.bold.red; -const warning = chalk.keyword('orange'); - -console.log(error('Error!')); -console.log(warning('Warning!')); -``` - -Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args): - -```js -const name = 'Sindre'; -console.log(chalk.green('Hello %s'), name); -//=> 'Hello Sindre' -``` - -## API - -### chalk.`<style>[.<style>...](string, [string...])` - -Example: `chalk.red.bold.underline('Hello', 'world');` - -Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`. - -Multiple arguments will be separated by space. - -### chalk.level - -Specifies the level of color support. - -Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers. - -If you need to change this in a reusable module, create a new instance: - -```js -const ctx = new chalk.Instance({level: 0}); -``` - -| Level | Description | -| :---: | :--- | -| `0` | All colors disabled | -| `1` | Basic color support (16 colors) | -| `2` | 256 color support | -| `3` | Truecolor support (16 million colors) | - -### chalk.supportsColor - -Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience. - -Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. - -Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. - -### chalk.stderr and chalk.stderr.supportsColor - -`chalk.stderr` contains a separate instance configured with color support detected for `stderr` stream instead of `stdout`. Override rules from `chalk.supportsColor` apply to this too. `chalk.stderr.supportsColor` is exposed for convenience. - -## Styles - -### Modifiers - -- `reset` - Resets the current color chain. -- `bold` - Make text bold. -- `dim` - Emitting only a small amount of light. -- `italic` - Make text italic. *(Not widely supported)* -- `underline` - Make text underline. *(Not widely supported)* -- `inverse`- Inverse background and foreground colors. -- `hidden` - Prints the text, but makes it invisible. -- `strikethrough` - Puts a horizontal line through the center of the text. *(Not widely supported)* -- `visible`- Prints the text only when Chalk has a color level > 0. Can be useful for things that are purely cosmetic. - -### Colors - -- `black` -- `red` -- `green` -- `yellow` -- `blue` -- `magenta` -- `cyan` -- `white` -- `blackBright` (alias: `gray`, `grey`) -- `redBright` -- `greenBright` -- `yellowBright` -- `blueBright` -- `magentaBright` -- `cyanBright` -- `whiteBright` - -### Background colors - -- `bgBlack` -- `bgRed` -- `bgGreen` -- `bgYellow` -- `bgBlue` -- `bgMagenta` -- `bgCyan` -- `bgWhite` -- `bgBlackBright` (alias: `bgGray`, `bgGrey`) -- `bgRedBright` -- `bgGreenBright` -- `bgYellowBright` -- `bgBlueBright` -- `bgMagentaBright` -- `bgCyanBright` -- `bgWhiteBright` - -## Tagged template literal - -Chalk can be used as a [tagged template literal](https://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals). - -```js -const chalk = require('chalk'); - -const miles = 18; -const calculateFeet = miles => miles * 5280; - -console.log(chalk` - There are {bold 5280 feet} in a mile. - In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}. -`); -``` - -Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`). - -Template styles are chained exactly like normal Chalk styles. The following three statements are equivalent: - -```js -console.log(chalk.bold.rgb(10, 100, 200)('Hello!')); -console.log(chalk.bold.rgb(10, 100, 200)`Hello!`); -console.log(chalk`{bold.rgb(10,100,200) Hello!}`); -``` - -Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain spaces between parameters. - -All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped. - -## 256 and Truecolor color support - -Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps. - -Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red). - -Examples: - -- `chalk.hex('#DEADED').underline('Hello, world!')` -- `chalk.keyword('orange')('Some orange text')` -- `chalk.rgb(15, 100, 204).inverse('Hello!')` - -Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `keyword` for foreground colors and `bgKeyword` for background colors). - -- `chalk.bgHex('#DEADED').underline('Hello, world!')` -- `chalk.bgKeyword('orange')('Some orange text')` -- `chalk.bgRgb(15, 100, 204).inverse('Hello!')` - -The following color models can be used: - -- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')` -- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')` -- [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')` -- [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')` -- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')` -- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hwb(32, 0, 50).bold('Orange!')` -- [`ansi`](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) - Example: `chalk.ansi(31).bgAnsi(93)('red on yellowBright')` -- [`ansi256`](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) - Example: `chalk.bgAnsi256(194)('Honeydew, more or less')` - -## Windows - -If you're on Windows, do yourself a favor and use [Windows Terminal](https://github.com/microsoft/terminal) instead of `cmd.exe`. - -## Origin story - -[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative. - -## chalk for enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of chalk and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-chalk?utm_source=npm-chalk&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - -## Related - -- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module -- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal -- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color -- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes -- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream -- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes -- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes -- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes -- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes -- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models -- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal -- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings -- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings -- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) diff --git a/node_modules/chalk/source/index.js b/node_modules/chalk/source/index.js index 75ec66350527a..8bc993da5d622 100644 --- a/node_modules/chalk/source/index.js +++ b/node_modules/chalk/source/index.js @@ -1,19 +1,22 @@ -'use strict'; -const ansiStyles = require('ansi-styles'); -const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color'); -const { +import ansiStyles from '#ansi-styles'; +import supportsColor from '#supports-color'; +import { // eslint-disable-line import/order stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = require('./util'); + stringEncaseCRLFWithFirstIndex, +} from './utilities.js'; -const {isArray} = Array; +const {stdout: stdoutColor, stderr: stderrColor} = supportsColor; + +const GENERATOR = Symbol('GENERATOR'); +const STYLER = Symbol('STYLER'); +const IS_EMPTY = Symbol('IS_EMPTY'); // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ 'ansi', 'ansi', 'ansi256', - 'ansi16m' + 'ansi16m', ]; const styles = Object.create(null); @@ -28,7 +31,7 @@ const applyOptions = (object, options = {}) => { object.level = options.level === undefined ? colorLevel : options.level; }; -class ChalkClass { +export class Chalk { constructor(options) { // eslint-disable-next-line no-constructor-return return chalkFactory(options); @@ -36,69 +39,80 @@ class ChalkClass { } const chalkFactory = options => { - const chalk = {}; + const chalk = (...strings) => strings.join(' '); applyOptions(chalk, options); - chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = () => { - throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); - }; - - chalk.template.Instance = ChalkClass; + Object.setPrototypeOf(chalk, createChalk.prototype); - return chalk.template; + return chalk; }; -function Chalk(options) { +function createChalk(options) { return chalkFactory(options); } +Object.setPrototypeOf(createChalk.prototype, Function.prototype); + for (const [styleName, style] of Object.entries(ansiStyles)) { styles[styleName] = { get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]); Object.defineProperty(this, styleName, {value: builder}); return builder; - } + }, }; } styles.visible = { get() { - const builder = createBuilder(this, this._styler, true); + const builder = createBuilder(this, this[STYLER], true); Object.defineProperty(this, 'visible', {value: builder}); return builder; + }, +}; + +const getModelAnsi = (model, level, type, ...arguments_) => { + if (model === 'rgb') { + if (level === 'ansi16m') { + return ansiStyles[type].ansi16m(...arguments_); + } + + if (level === 'ansi256') { + return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_)); + } + + return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_)); } + + if (model === 'hex') { + return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_)); + } + + return ansiStyles[type][model](...arguments_); }; -const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +const usedModels = ['rgb', 'hex', 'ansi256']; for (const model of usedModels) { styles[model] = { get() { const {level} = this; return function (...arguments_) { - const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); - return createBuilder(this, styler, this._isEmpty); + const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]); + return createBuilder(this, styler, this[IS_EMPTY]); }; - } + }, }; -} -for (const model of usedModels) { const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); styles[bgModel] = { get() { const {level} = this; return function (...arguments_) { - const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); - return createBuilder(this, styler, this._isEmpty); + const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]); + return createBuilder(this, styler, this[IS_EMPTY]); }; - } + }, }; } @@ -107,12 +121,12 @@ const proto = Object.defineProperties(() => {}, { level: { enumerable: true, get() { - return this._generator.level; + return this[GENERATOR].level; }, set(level) { - this._generator.level = level; - } - } + this[GENERATOR].level = level; + }, + }, }); const createStyler = (open, close, parent) => { @@ -131,46 +145,39 @@ const createStyler = (open, close, parent) => { close, openAll, closeAll, - parent + parent, }; }; const createBuilder = (self, _styler, _isEmpty) => { - const builder = (...arguments_) => { - if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { - // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` - return applyStyle(builder, chalkTag(builder, ...arguments_)); - } - - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); - }; + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); // We alter the prototype because we must return a function, but there is // no way to create a function with a different prototype Object.setPrototypeOf(builder, proto); - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; + builder[GENERATOR] = self; + builder[STYLER] = _styler; + builder[IS_EMPTY] = _isEmpty; return builder; }; const applyStyle = (self, string) => { if (self.level <= 0 || !string) { - return self._isEmpty ? '' : string; + return self[IS_EMPTY] ? '' : string; } - let styler = self._styler; + let styler = self[STYLER]; if (styler === undefined) { return string; } const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { + if (string.includes('\u001B')) { while (styler !== undefined) { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code @@ -192,38 +199,27 @@ const applyStyle = (self, string) => { return openAll + string + closeAll; }; -let template; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; - - if (!isArray(firstString) || !isArray(firstString.raw)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } +Object.defineProperties(createChalk.prototype, styles); - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; +const chalk = createChalk(); +export const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0}); - for (let i = 1; i < firstString.length; i++) { - parts.push( - String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); - } +export { + modifierNames, + foregroundColorNames, + backgroundColorNames, + colorNames, - if (template === undefined) { - template = require('./templates'); - } + // TODO: Remove these aliases in the next major version + modifierNames as modifiers, + foregroundColorNames as foregroundColors, + backgroundColorNames as backgroundColors, + colorNames as colors, +} from './vendor/ansi-styles/index.js'; - return template(chalk, parts.join('')); +export { + stdoutColor as supportsColor, + stderrColor as supportsColorStderr, }; -Object.defineProperties(Chalk.prototype, styles); - -const chalk = Chalk(); // eslint-disable-line new-cap -chalk.supportsColor = stdoutColor; -chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap -chalk.stderr.supportsColor = stderrColor; - -module.exports = chalk; +export default chalk; diff --git a/node_modules/chalk/source/templates.js b/node_modules/chalk/source/templates.js deleted file mode 100644 index b130949d646fd..0000000000000 --- a/node_modules/chalk/source/templates.js +++ /dev/null @@ -1,134 +0,0 @@ -'use strict'; -const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; - - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - if (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); - } - - return ESCAPES.get(c) || c; -} - -function parseArguments(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const [styleName, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } - - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } - - return current; -} - -module.exports = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape(escapeCharacter)); - } else if (style) { - const string = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); - } - - return chunks.join(''); -}; diff --git a/node_modules/chalk/source/util.js b/node_modules/chalk/source/util.js deleted file mode 100644 index ca466fd466c07..0000000000000 --- a/node_modules/chalk/source/util.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -const stringReplaceAll = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } - - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -module.exports = { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -}; diff --git a/node_modules/chalk/source/utilities.js b/node_modules/chalk/source/utilities.js new file mode 100644 index 0000000000000..4366dee0d84d7 --- /dev/null +++ b/node_modules/chalk/source/utilities.js @@ -0,0 +1,33 @@ +// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`. +export function stringReplaceAll(string, substring, replacer) { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } + + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; + do { + returnValue += string.slice(endIndex, index) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); + } while (index !== -1); + + returnValue += string.slice(endIndex); + return returnValue; +} + +export function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) { + let endIndex = 0; + let returnValue = ''; + do { + const gotCR = string[index - 1] === '\r'; + returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); + } while (index !== -1); + + returnValue += string.slice(endIndex); + return returnValue; +} diff --git a/node_modules/chalk/source/vendor/ansi-styles/index.js b/node_modules/chalk/source/vendor/ansi-styles/index.js new file mode 100644 index 0000000000000..eaa7bed6cb1ed --- /dev/null +++ b/node_modules/chalk/source/vendor/ansi-styles/index.js @@ -0,0 +1,223 @@ +const ANSI_BACKGROUND_OFFSET = 10; + +const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`; + +const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`; + +const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`; + +const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + overline: [53, 55], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + + // Bright color + blackBright: [90, 39], + gray: [90, 39], // Alias of `blackBright` + grey: [90, 39], // Alias of `blackBright` + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39], + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + + // Bright color + bgBlackBright: [100, 49], + bgGray: [100, 49], // Alias of `bgBlackBright` + bgGrey: [100, 49], // Alias of `bgBlackBright` + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49], + }, +}; + +export const modifierNames = Object.keys(styles.modifier); +export const foregroundColorNames = Object.keys(styles.color); +export const backgroundColorNames = Object.keys(styles.bgColor); +export const colorNames = [...foregroundColorNames, ...backgroundColorNames]; + +function assembleStyles() { + const codes = new Map(); + + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m`, + }; + + group[styleName] = styles[styleName]; + + codes.set(style[0], style[1]); + } + + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false, + }); + } + + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false, + }); + + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; + + styles.color.ansi = wrapAnsi16(); + styles.color.ansi256 = wrapAnsi256(); + styles.color.ansi16m = wrapAnsi16m(); + styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); + styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); + styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); + + // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js + Object.defineProperties(styles, { + rgbToAnsi256: { + value(red, green, blue) { + // We use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (red === green && green === blue) { + if (red < 8) { + return 16; + } + + if (red > 248) { + return 231; + } + + return Math.round(((red - 8) / 247) * 24) + 232; + } + + return 16 + + (36 * Math.round(red / 255 * 5)) + + (6 * Math.round(green / 255 * 5)) + + Math.round(blue / 255 * 5); + }, + enumerable: false, + }, + hexToRgb: { + value(hex) { + const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); + if (!matches) { + return [0, 0, 0]; + } + + let [colorString] = matches; + + if (colorString.length === 3) { + colorString = [...colorString].map(character => character + character).join(''); + } + + const integer = Number.parseInt(colorString, 16); + + return [ + /* eslint-disable no-bitwise */ + (integer >> 16) & 0xFF, + (integer >> 8) & 0xFF, + integer & 0xFF, + /* eslint-enable no-bitwise */ + ]; + }, + enumerable: false, + }, + hexToAnsi256: { + value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)), + enumerable: false, + }, + ansi256ToAnsi: { + value(code) { + if (code < 8) { + return 30 + code; + } + + if (code < 16) { + return 90 + (code - 8); + } + + let red; + let green; + let blue; + + if (code >= 232) { + red = (((code - 232) * 10) + 8) / 255; + green = red; + blue = red; + } else { + code -= 16; + + const remainder = code % 36; + + red = Math.floor(code / 36) / 5; + green = Math.floor(remainder / 6) / 5; + blue = (remainder % 6) / 5; + } + + const value = Math.max(red, green, blue) * 2; + + if (value === 0) { + return 30; + } + + // eslint-disable-next-line no-bitwise + let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red)); + + if (value === 2) { + result += 60; + } + + return result; + }, + enumerable: false, + }, + rgbToAnsi: { + value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)), + enumerable: false, + }, + hexToAnsi: { + value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), + enumerable: false, + }, + }); + + return styles; +} + +const ansiStyles = assembleStyles(); + +export default ansiStyles; diff --git a/node_modules/chalk/source/vendor/supports-color/browser.js b/node_modules/chalk/source/vendor/supports-color/browser.js new file mode 100644 index 0000000000000..fbb6ce0fc9ab9 --- /dev/null +++ b/node_modules/chalk/source/vendor/supports-color/browser.js @@ -0,0 +1,34 @@ +/* eslint-env browser */ + +const level = (() => { + if (!('navigator' in globalThis)) { + return 0; + } + + if (globalThis.navigator.userAgentData) { + const brand = navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium'); + if (brand && brand.version > 93) { + return 3; + } + } + + if (/\b(Chrome|Chromium)\//.test(globalThis.navigator.userAgent)) { + return 1; + } + + return 0; +})(); + +const colorSupport = level !== 0 && { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, +}; + +const supportsColor = { + stdout: colorSupport, + stderr: colorSupport, +}; + +export default supportsColor; diff --git a/node_modules/chalk/source/vendor/supports-color/index.js b/node_modules/chalk/source/vendor/supports-color/index.js new file mode 100644 index 0000000000000..265d7f8581953 --- /dev/null +++ b/node_modules/chalk/source/vendor/supports-color/index.js @@ -0,0 +1,190 @@ +import process from 'node:process'; +import os from 'node:os'; +import tty from 'node:tty'; + +// From: https://github.com/sindresorhus/has-flag/blob/main/index.js +/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) { +function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +} + +const {env} = process; + +let flagForceColor; +if ( + hasFlag('no-color') + || hasFlag('no-colors') + || hasFlag('color=false') + || hasFlag('color=never') +) { + flagForceColor = 0; +} else if ( + hasFlag('color') + || hasFlag('colors') + || hasFlag('color=true') + || hasFlag('color=always') +) { + flagForceColor = 1; +} + +function envForceColor() { + if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + return 1; + } + + if (env.FORCE_COLOR === 'false') { + return 0; + } + + return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + } +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, + }; +} + +function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { + const noFlagForceColor = envForceColor(); + if (noFlagForceColor !== undefined) { + flagForceColor = noFlagForceColor; + } + + const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; + + if (forceColor === 0) { + return 0; + } + + if (sniffFlags) { + if (hasFlag('color=16m') + || hasFlag('color=full') + || hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + } + + // Check for Azure DevOps pipelines. + // Has to be above the `!streamIsTTY` check. + if ('TF_BUILD' in env && 'AGENT_NAME' in env) { + return 1; + } + + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } + + if (process.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 + && Number(osRelease[2]) >= 10_586 + ) { + return Number(osRelease[2]) >= 14_931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) { + return 3; + } + + if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if (env.TERM === 'xterm-kitty') { + return 3; + } + + if (env.TERM === 'xterm-ghostty') { + return 3; + } + + if (env.TERM === 'wezterm') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': { + return version >= 3 ? 3 : 2; + } + + case 'Apple_Terminal': { + return 2; + } + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + return min; +} + +export function createSupportsColor(stream, options = {}) { + const level = _supportsColor(stream, { + streamIsTTY: stream && stream.isTTY, + ...options, + }); + + return translateLevel(level); +} + +const supportsColor = { + stdout: createSupportsColor({isTTY: tty.isatty(1)}), + stderr: createSupportsColor({isTTY: tty.isatty(2)}), +}; + +export default supportsColor; diff --git a/node_modules/chownr/LICENSE.md b/node_modules/chownr/LICENSE.md new file mode 100644 index 0000000000000..881248b6d7f0c --- /dev/null +++ b/node_modules/chownr/LICENSE.md @@ -0,0 +1,63 @@ +All packages under `src/` are licensed according to the terms in +their respective `LICENSE` or `LICENSE.md` files. + +The remainder of this project is licensed under the Blue Oak +Model License, as follows: + +----- + +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/chownr/chownr.js b/node_modules/chownr/chownr.js deleted file mode 100644 index 0d40932169654..0000000000000 --- a/node_modules/chownr/chownr.js +++ /dev/null @@ -1,167 +0,0 @@ -'use strict' -const fs = require('fs') -const path = require('path') - -/* istanbul ignore next */ -const LCHOWN = fs.lchown ? 'lchown' : 'chown' -/* istanbul ignore next */ -const LCHOWNSYNC = fs.lchownSync ? 'lchownSync' : 'chownSync' - -/* istanbul ignore next */ -const needEISDIRHandled = fs.lchown && - !process.version.match(/v1[1-9]+\./) && - !process.version.match(/v10\.[6-9]/) - -const lchownSync = (path, uid, gid) => { - try { - return fs[LCHOWNSYNC](path, uid, gid) - } catch (er) { - if (er.code !== 'ENOENT') - throw er - } -} - -/* istanbul ignore next */ -const chownSync = (path, uid, gid) => { - try { - return fs.chownSync(path, uid, gid) - } catch (er) { - if (er.code !== 'ENOENT') - throw er - } -} - -/* istanbul ignore next */ -const handleEISDIR = - needEISDIRHandled ? (path, uid, gid, cb) => er => { - // Node prior to v10 had a very questionable implementation of - // fs.lchown, which would always try to call fs.open on a directory - // Fall back to fs.chown in those cases. - if (!er || er.code !== 'EISDIR') - cb(er) - else - fs.chown(path, uid, gid, cb) - } - : (_, __, ___, cb) => cb - -/* istanbul ignore next */ -const handleEISDirSync = - needEISDIRHandled ? (path, uid, gid) => { - try { - return lchownSync(path, uid, gid) - } catch (er) { - if (er.code !== 'EISDIR') - throw er - chownSync(path, uid, gid) - } - } - : (path, uid, gid) => lchownSync(path, uid, gid) - -// fs.readdir could only accept an options object as of node v6 -const nodeVersion = process.version -let readdir = (path, options, cb) => fs.readdir(path, options, cb) -let readdirSync = (path, options) => fs.readdirSync(path, options) -/* istanbul ignore next */ -if (/^v4\./.test(nodeVersion)) - readdir = (path, options, cb) => fs.readdir(path, cb) - -const chown = (cpath, uid, gid, cb) => { - fs[LCHOWN](cpath, uid, gid, handleEISDIR(cpath, uid, gid, er => { - // Skip ENOENT error - cb(er && er.code !== 'ENOENT' ? er : null) - })) -} - -const chownrKid = (p, child, uid, gid, cb) => { - if (typeof child === 'string') - return fs.lstat(path.resolve(p, child), (er, stats) => { - // Skip ENOENT error - if (er) - return cb(er.code !== 'ENOENT' ? er : null) - stats.name = child - chownrKid(p, stats, uid, gid, cb) - }) - - if (child.isDirectory()) { - chownr(path.resolve(p, child.name), uid, gid, er => { - if (er) - return cb(er) - const cpath = path.resolve(p, child.name) - chown(cpath, uid, gid, cb) - }) - } else { - const cpath = path.resolve(p, child.name) - chown(cpath, uid, gid, cb) - } -} - - -const chownr = (p, uid, gid, cb) => { - readdir(p, { withFileTypes: true }, (er, children) => { - // any error other than ENOTDIR or ENOTSUP means it's not readable, - // or doesn't exist. give up. - if (er) { - if (er.code === 'ENOENT') - return cb() - else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP') - return cb(er) - } - if (er || !children.length) - return chown(p, uid, gid, cb) - - let len = children.length - let errState = null - const then = er => { - if (errState) - return - if (er) - return cb(errState = er) - if (-- len === 0) - return chown(p, uid, gid, cb) - } - - children.forEach(child => chownrKid(p, child, uid, gid, then)) - }) -} - -const chownrKidSync = (p, child, uid, gid) => { - if (typeof child === 'string') { - try { - const stats = fs.lstatSync(path.resolve(p, child)) - stats.name = child - child = stats - } catch (er) { - if (er.code === 'ENOENT') - return - else - throw er - } - } - - if (child.isDirectory()) - chownrSync(path.resolve(p, child.name), uid, gid) - - handleEISDirSync(path.resolve(p, child.name), uid, gid) -} - -const chownrSync = (p, uid, gid) => { - let children - try { - children = readdirSync(p, { withFileTypes: true }) - } catch (er) { - if (er.code === 'ENOENT') - return - else if (er.code === 'ENOTDIR' || er.code === 'ENOTSUP') - return handleEISDirSync(p, uid, gid) - else - throw er - } - - if (children && children.length) - children.forEach(child => chownrKidSync(p, child, uid, gid)) - - return handleEISDirSync(p, uid, gid) -} - -module.exports = chownr -chownr.sync = chownrSync diff --git a/node_modules/chownr/dist/commonjs/index.js b/node_modules/chownr/dist/commonjs/index.js new file mode 100644 index 0000000000000..6a7b68d5eac26 --- /dev/null +++ b/node_modules/chownr/dist/commonjs/index.js @@ -0,0 +1,93 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.chownrSync = exports.chownr = void 0; +const node_fs_1 = __importDefault(require("node:fs")); +const node_path_1 = __importDefault(require("node:path")); +const lchownSync = (path, uid, gid) => { + try { + return node_fs_1.default.lchownSync(path, uid, gid); + } + catch (er) { + if (er?.code !== 'ENOENT') + throw er; + } +}; +const chown = (cpath, uid, gid, cb) => { + node_fs_1.default.lchown(cpath, uid, gid, er => { + // Skip ENOENT error + cb(er && er?.code !== 'ENOENT' ? er : null); + }); +}; +const chownrKid = (p, child, uid, gid, cb) => { + if (child.isDirectory()) { + (0, exports.chownr)(node_path_1.default.resolve(p, child.name), uid, gid, (er) => { + if (er) + return cb(er); + const cpath = node_path_1.default.resolve(p, child.name); + chown(cpath, uid, gid, cb); + }); + } + else { + const cpath = node_path_1.default.resolve(p, child.name); + chown(cpath, uid, gid, cb); + } +}; +const chownr = (p, uid, gid, cb) => { + node_fs_1.default.readdir(p, { withFileTypes: true }, (er, children) => { + // any error other than ENOTDIR or ENOTSUP means it's not readable, + // or doesn't exist. give up. + if (er) { + if (er.code === 'ENOENT') + return cb(); + else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP') + return cb(er); + } + if (er || !children.length) + return chown(p, uid, gid, cb); + let len = children.length; + let errState = null; + const then = (er) => { + /* c8 ignore start */ + if (errState) + return; + /* c8 ignore stop */ + if (er) + return cb((errState = er)); + if (--len === 0) + return chown(p, uid, gid, cb); + }; + for (const child of children) { + chownrKid(p, child, uid, gid, then); + } + }); +}; +exports.chownr = chownr; +const chownrKidSync = (p, child, uid, gid) => { + if (child.isDirectory()) + (0, exports.chownrSync)(node_path_1.default.resolve(p, child.name), uid, gid); + lchownSync(node_path_1.default.resolve(p, child.name), uid, gid); +}; +const chownrSync = (p, uid, gid) => { + let children; + try { + children = node_fs_1.default.readdirSync(p, { withFileTypes: true }); + } + catch (er) { + const e = er; + if (e?.code === 'ENOENT') + return; + else if (e?.code === 'ENOTDIR' || e?.code === 'ENOTSUP') + return lchownSync(p, uid, gid); + else + throw e; + } + for (const child of children) { + chownrKidSync(p, child, uid, gid); + } + return lchownSync(p, uid, gid); +}; +exports.chownrSync = chownrSync; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/chownr/dist/commonjs/package.json b/node_modules/chownr/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/chownr/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/chownr/dist/esm/index.js b/node_modules/chownr/dist/esm/index.js new file mode 100644 index 0000000000000..5c2815297a67c --- /dev/null +++ b/node_modules/chownr/dist/esm/index.js @@ -0,0 +1,85 @@ +import fs from 'node:fs'; +import path from 'node:path'; +const lchownSync = (path, uid, gid) => { + try { + return fs.lchownSync(path, uid, gid); + } + catch (er) { + if (er?.code !== 'ENOENT') + throw er; + } +}; +const chown = (cpath, uid, gid, cb) => { + fs.lchown(cpath, uid, gid, er => { + // Skip ENOENT error + cb(er && er?.code !== 'ENOENT' ? er : null); + }); +}; +const chownrKid = (p, child, uid, gid, cb) => { + if (child.isDirectory()) { + chownr(path.resolve(p, child.name), uid, gid, (er) => { + if (er) + return cb(er); + const cpath = path.resolve(p, child.name); + chown(cpath, uid, gid, cb); + }); + } + else { + const cpath = path.resolve(p, child.name); + chown(cpath, uid, gid, cb); + } +}; +export const chownr = (p, uid, gid, cb) => { + fs.readdir(p, { withFileTypes: true }, (er, children) => { + // any error other than ENOTDIR or ENOTSUP means it's not readable, + // or doesn't exist. give up. + if (er) { + if (er.code === 'ENOENT') + return cb(); + else if (er.code !== 'ENOTDIR' && er.code !== 'ENOTSUP') + return cb(er); + } + if (er || !children.length) + return chown(p, uid, gid, cb); + let len = children.length; + let errState = null; + const then = (er) => { + /* c8 ignore start */ + if (errState) + return; + /* c8 ignore stop */ + if (er) + return cb((errState = er)); + if (--len === 0) + return chown(p, uid, gid, cb); + }; + for (const child of children) { + chownrKid(p, child, uid, gid, then); + } + }); +}; +const chownrKidSync = (p, child, uid, gid) => { + if (child.isDirectory()) + chownrSync(path.resolve(p, child.name), uid, gid); + lchownSync(path.resolve(p, child.name), uid, gid); +}; +export const chownrSync = (p, uid, gid) => { + let children; + try { + children = fs.readdirSync(p, { withFileTypes: true }); + } + catch (er) { + const e = er; + if (e?.code === 'ENOENT') + return; + else if (e?.code === 'ENOTDIR' || e?.code === 'ENOTSUP') + return lchownSync(p, uid, gid); + else + throw e; + } + for (const child of children) { + chownrKidSync(p, child, uid, gid); + } + return lchownSync(p, uid, gid); +}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/chownr/dist/esm/package.json b/node_modules/chownr/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/chownr/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/chownr/package.json b/node_modules/chownr/package.json index 5b0214ca12e3f..09aa6b2e2e576 100644 --- a/node_modules/chownr/package.json +++ b/node_modules/chownr/package.json @@ -2,31 +2,68 @@ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", "name": "chownr", "description": "like `chown -R`", - "version": "2.0.0", + "version": "3.0.0", "repository": { "type": "git", "url": "git://github.com/isaacs/chownr.git" }, - "main": "chownr.js", "files": [ - "chownr.js" + "dist" ], "devDependencies": { - "mkdirp": "0.3", - "rimraf": "^2.7.1", - "tap": "^14.10.6" - }, - "tap": { - "check-coverage": true + "@types/node": "^20.12.5", + "mkdirp": "^3.0.1", + "prettier": "^3.2.5", + "rimraf": "^5.0.5", + "tap": "^18.7.2", + "tshy": "^1.13.1", + "typedoc": "^0.25.12" }, "scripts": { + "prepare": "tshy", + "pretest": "npm run prepare", "test": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" }, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "type": "module", + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" } } diff --git a/node_modules/ci-info/LICENSE b/node_modules/ci-info/LICENSE new file mode 100644 index 0000000000000..95f61daaaf485 --- /dev/null +++ b/node_modules/ci-info/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Thomas Watson Steen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/ci-info/index.js b/node_modules/ci-info/index.js new file mode 100644 index 0000000000000..38056d9aa8772 --- /dev/null +++ b/node_modules/ci-info/index.js @@ -0,0 +1,104 @@ +'use strict' + +const vendors = require('./vendors.json') + +const env = process.env + +// Used for testing only +Object.defineProperty(exports, '_vendors', { + value: vendors.map(function (v) { + return v.constant + }) +}) + +exports.name = null +exports.isPR = null +exports.id = null + +if (env.CI !== 'false') { + vendors.forEach(function (vendor) { + const envs = Array.isArray(vendor.env) ? vendor.env : [vendor.env] + const isCI = envs.every(function (obj) { + return checkEnv(obj) + }) + + exports[vendor.constant] = isCI + + if (!isCI) { + return + } + + exports.name = vendor.name + exports.isPR = checkPR(vendor) + exports.id = vendor.constant + }) +} + +exports.isCI = !!( + env.CI !== 'false' && // Bypass all checks if CI env is explicitly set to 'false' + (env.BUILD_ID || // Jenkins, Cloudbees + env.BUILD_NUMBER || // Jenkins, TeamCity + env.CI || // Travis CI, CircleCI, Cirrus CI, Gitlab CI, Appveyor, CodeShip, dsari, Cloudflare Pages/Workers + env.CI_APP_ID || // Appflow + env.CI_BUILD_ID || // Appflow + env.CI_BUILD_NUMBER || // Appflow + env.CI_NAME || // Codeship and others + env.CONTINUOUS_INTEGRATION || // Travis CI, Cirrus CI + env.RUN_ID || // TaskCluster, dsari + exports.name || + false) +) + +function checkEnv (obj) { + // "env": "CIRRUS" + if (typeof obj === 'string') return !!env[obj] + + // "env": { "env": "NODE", "includes": "/app/.heroku/node/bin/node" } + if ('env' in obj) { + // Currently there are no other types, uncomment when there are + // if ('includes' in obj) { + return env[obj.env] && env[obj.env].includes(obj.includes) + // } + } + + if ('any' in obj) { + return obj.any.some(function (k) { + return !!env[k] + }) + } + + return Object.keys(obj).every(function (k) { + return env[k] === obj[k] + }) +} + +function checkPR (vendor) { + switch (typeof vendor.pr) { + case 'string': + // "pr": "CIRRUS_PR" + return !!env[vendor.pr] + case 'object': + if ('env' in vendor.pr) { + if ('any' in vendor.pr) { + // "pr": { "env": "CODEBUILD_WEBHOOK_EVENT", "any": ["PULL_REQUEST_CREATED", "PULL_REQUEST_UPDATED"] } + return vendor.pr.any.some(function (key) { + return env[vendor.pr.env] === key + }) + } else { + // "pr": { "env": "BUILDKITE_PULL_REQUEST", "ne": "false" } + return vendor.pr.env in env && env[vendor.pr.env] !== vendor.pr.ne + } + } else if ('any' in vendor.pr) { + // "pr": { "any": ["ghprbPullId", "CHANGE_ID"] } + return vendor.pr.any.some(function (key) { + return !!env[key] + }) + } else { + // "pr": { "DRONE_BUILD_EVENT": "pull_request" } + return checkEnv(vendor.pr) + } + default: + // PR detection not supported for this vendor + return null + } +} diff --git a/node_modules/ci-info/package.json b/node_modules/ci-info/package.json new file mode 100644 index 0000000000000..30b978ab04afa --- /dev/null +++ b/node_modules/ci-info/package.json @@ -0,0 +1,54 @@ +{ + "name": "ci-info", + "version": "4.4.0", + "description": "Get details about the current Continuous Integration environment", + "main": "index.js", + "typings": "index.d.ts", + "type": "commonjs", + "author": "Thomas Watson Steen <w@tson.dk> (https://twitter.com/wa7son)", + "license": "MIT", + "repository": "github:watson/ci-info", + "bugs": "https://github.com/watson/ci-info/issues", + "homepage": "https://github.com/watson/ci-info", + "contributors": [ + { + "name": "Sibiraj", + "url": "https://github.com/sibiraj-s" + } + ], + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "keywords": [ + "ci", + "continuous", + "integration", + "test", + "detect" + ], + "files": [ + "vendors.json", + "index.js", + "index.d.ts", + "CHANGELOG.md" + ], + "scripts": { + "build": "node sort-vendors.js && node create-typings.js", + "lint:fix": "standard --fix", + "test": "standard && node test.js", + "prepare": "husky install || true" + }, + "devDependencies": { + "clear-module": "^4.1.2", + "husky": "^9.1.7", + "publint": "^0.3.12", + "standard": "^17.1.2", + "tape": "^5.9.0" + }, + "engines": { + "node": ">=8" + } +} diff --git a/node_modules/ci-info/vendors.json b/node_modules/ci-info/vendors.json new file mode 100644 index 0000000000000..d697afa927775 --- /dev/null +++ b/node_modules/ci-info/vendors.json @@ -0,0 +1,363 @@ +[ + { + "name": "Agola CI", + "constant": "AGOLA", + "env": "AGOLA_GIT_REF", + "pr": "AGOLA_PULL_REQUEST_ID" + }, + { + "name": "Alpic", + "constant": "ALPIC", + "env": "ALPIC_HOST" + }, + { + "name": "Appcircle", + "constant": "APPCIRCLE", + "env": "AC_APPCIRCLE", + "pr": { + "env": "AC_GIT_PR", + "ne": "false" + } + }, + { + "name": "AppVeyor", + "constant": "APPVEYOR", + "env": "APPVEYOR", + "pr": "APPVEYOR_PULL_REQUEST_NUMBER" + }, + { + "name": "AWS CodeBuild", + "constant": "CODEBUILD", + "env": "CODEBUILD_BUILD_ARN", + "pr": { + "env": "CODEBUILD_WEBHOOK_EVENT", + "any": [ + "PULL_REQUEST_CREATED", + "PULL_REQUEST_UPDATED", + "PULL_REQUEST_REOPENED" + ] + } + }, + { + "name": "Azure Pipelines", + "constant": "AZURE_PIPELINES", + "env": "TF_BUILD", + "pr": { + "BUILD_REASON": "PullRequest" + } + }, + { + "name": "Bamboo", + "constant": "BAMBOO", + "env": "bamboo_planKey" + }, + { + "name": "Bitbucket Pipelines", + "constant": "BITBUCKET", + "env": "BITBUCKET_COMMIT", + "pr": "BITBUCKET_PR_ID" + }, + { + "name": "Bitrise", + "constant": "BITRISE", + "env": "BITRISE_IO", + "pr": "BITRISE_PULL_REQUEST" + }, + { + "name": "Buddy", + "constant": "BUDDY", + "env": "BUDDY_WORKSPACE_ID", + "pr": "BUDDY_EXECUTION_PULL_REQUEST_ID" + }, + { + "name": "Buildkite", + "constant": "BUILDKITE", + "env": "BUILDKITE", + "pr": { + "env": "BUILDKITE_PULL_REQUEST", + "ne": "false" + } + }, + { + "name": "CircleCI", + "constant": "CIRCLE", + "env": "CIRCLECI", + "pr": "CIRCLE_PULL_REQUEST" + }, + { + "name": "Cirrus CI", + "constant": "CIRRUS", + "env": "CIRRUS_CI", + "pr": "CIRRUS_PR" + }, + { + "name": "Cloudflare Pages", + "constant": "CLOUDFLARE_PAGES", + "env": "CF_PAGES" + }, + { + "name": "Cloudflare Workers", + "constant": "CLOUDFLARE_WORKERS", + "env": "WORKERS_CI" + }, + { + "name": "Codefresh", + "constant": "CODEFRESH", + "env": "CF_BUILD_ID", + "pr": { + "any": [ + "CF_PULL_REQUEST_NUMBER", + "CF_PULL_REQUEST_ID" + ] + } + }, + { + "name": "Codemagic", + "constant": "CODEMAGIC", + "env": "CM_BUILD_ID", + "pr": "CM_PULL_REQUEST" + }, + { + "name": "Codeship", + "constant": "CODESHIP", + "env": { + "CI_NAME": "codeship" + } + }, + { + "name": "Drone", + "constant": "DRONE", + "env": "DRONE", + "pr": { + "DRONE_BUILD_EVENT": "pull_request" + } + }, + { + "name": "dsari", + "constant": "DSARI", + "env": "DSARI" + }, + { + "name": "Earthly", + "constant": "EARTHLY", + "env": "EARTHLY_CI" + }, + { + "name": "Expo Application Services", + "constant": "EAS", + "env": "EAS_BUILD" + }, + { + "name": "Gerrit", + "constant": "GERRIT", + "env": "GERRIT_PROJECT" + }, + { + "name": "Gitea Actions", + "constant": "GITEA_ACTIONS", + "env": "GITEA_ACTIONS" + }, + { + "name": "GitHub Actions", + "constant": "GITHUB_ACTIONS", + "env": "GITHUB_ACTIONS", + "pr": { + "GITHUB_EVENT_NAME": "pull_request" + } + }, + { + "name": "GitLab CI", + "constant": "GITLAB", + "env": "GITLAB_CI", + "pr": "CI_MERGE_REQUEST_ID" + }, + { + "name": "GoCD", + "constant": "GOCD", + "env": "GO_PIPELINE_LABEL" + }, + { + "name": "Google Cloud Build", + "constant": "GOOGLE_CLOUD_BUILD", + "env": "BUILDER_OUTPUT" + }, + { + "name": "Harness CI", + "constant": "HARNESS", + "env": "HARNESS_BUILD_ID" + }, + { + "name": "Heroku", + "constant": "HEROKU", + "env": { + "env": "NODE", + "includes": "/app/.heroku/node/bin/node" + } + }, + { + "name": "Hudson", + "constant": "HUDSON", + "env": "HUDSON_URL" + }, + { + "name": "Jenkins", + "constant": "JENKINS", + "env": [ + "JENKINS_URL", + "BUILD_ID" + ], + "pr": { + "any": [ + "ghprbPullId", + "CHANGE_ID" + ] + } + }, + { + "name": "LayerCI", + "constant": "LAYERCI", + "env": "LAYERCI", + "pr": "LAYERCI_PULL_REQUEST" + }, + { + "name": "Magnum CI", + "constant": "MAGNUM", + "env": "MAGNUM" + }, + { + "name": "Netlify CI", + "constant": "NETLIFY", + "env": "NETLIFY", + "pr": { + "env": "PULL_REQUEST", + "ne": "false" + } + }, + { + "name": "Nevercode", + "constant": "NEVERCODE", + "env": "NEVERCODE", + "pr": { + "env": "NEVERCODE_PULL_REQUEST", + "ne": "false" + } + }, + { + "name": "Prow", + "constant": "PROW", + "env": "PROW_JOB_ID" + }, + { + "name": "ReleaseHub", + "constant": "RELEASEHUB", + "env": "RELEASE_BUILD_ID" + }, + { + "name": "Render", + "constant": "RENDER", + "env": "RENDER", + "pr": { + "IS_PULL_REQUEST": "true" + } + }, + { + "name": "Sail CI", + "constant": "SAIL", + "env": "SAILCI", + "pr": "SAIL_PULL_REQUEST_NUMBER" + }, + { + "name": "Screwdriver", + "constant": "SCREWDRIVER", + "env": "SCREWDRIVER", + "pr": { + "env": "SD_PULL_REQUEST", + "ne": "false" + } + }, + { + "name": "Semaphore", + "constant": "SEMAPHORE", + "env": "SEMAPHORE", + "pr": "PULL_REQUEST_NUMBER" + }, + { + "name": "Sourcehut", + "constant": "SOURCEHUT", + "env": { + "CI_NAME": "sourcehut" + } + }, + { + "name": "Strider CD", + "constant": "STRIDER", + "env": "STRIDER" + }, + { + "name": "TaskCluster", + "constant": "TASKCLUSTER", + "env": [ + "TASK_ID", + "RUN_ID" + ] + }, + { + "name": "TeamCity", + "constant": "TEAMCITY", + "env": "TEAMCITY_VERSION" + }, + { + "name": "Travis CI", + "constant": "TRAVIS", + "env": "TRAVIS", + "pr": { + "env": "TRAVIS_PULL_REQUEST", + "ne": "false" + } + }, + { + "name": "Vela", + "constant": "VELA", + "env": "VELA", + "pr": { + "VELA_PULL_REQUEST": "1" + } + }, + { + "name": "Vercel", + "constant": "VERCEL", + "env": { + "any": [ + "NOW_BUILDER", + "VERCEL" + ] + }, + "pr": "VERCEL_GIT_PULL_REQUEST_ID" + }, + { + "name": "Visual Studio App Center", + "constant": "APPCENTER", + "env": "APPCENTER_BUILD_ID" + }, + { + "name": "Woodpecker", + "constant": "WOODPECKER", + "env": { + "CI": "woodpecker" + }, + "pr": { + "CI_BUILD_EVENT": "pull_request" + } + }, + { + "name": "Xcode Cloud", + "constant": "XCODE_CLOUD", + "env": "CI_XCODE_PROJECT", + "pr": "CI_PULL_REQUEST_NUMBER" + }, + { + "name": "Xcode Server", + "constant": "XCODE_SERVER", + "env": "XCS" + } +] diff --git a/node_modules/cidr-regex/dist/index.js b/node_modules/cidr-regex/dist/index.js new file mode 100644 index 0000000000000..2817f65eeb3cb --- /dev/null +++ b/node_modules/cidr-regex/dist/index.js @@ -0,0 +1,15 @@ +import ipRegex from "ip-regex"; +const defaultOpts = { exact: false }; +const v4str = `${ipRegex.v4().source}\\/(3[0-2]|[12]?[0-9])`; +const v6str = `${ipRegex.v6().source}\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])`; +const v4exact = new RegExp(`^${v4str}$`); +const v6exact = new RegExp(`^${v6str}$`); +const v46exact = new RegExp(`(?:^${v4str}$)|(?:^${v6str}$)`); +const cidrRegex = ({ exact } = defaultOpts) => exact ? v46exact : new RegExp(`(?:${v4str})|(?:${v6str})`, "g"); +const v4 = cidrRegex.v4 = ({ exact } = defaultOpts) => exact ? v4exact : new RegExp(v4str, "g"); +const v6 = cidrRegex.v6 = ({ exact } = defaultOpts) => exact ? v6exact : new RegExp(v6str, "g"); +export { + cidrRegex as default, + v4, + v6 +}; diff --git a/node_modules/cidr-regex/index.d.ts b/node_modules/cidr-regex/index.d.ts deleted file mode 100644 index 9099caecc8e2a..0000000000000 --- a/node_modules/cidr-regex/index.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -declare namespace ip { - interface Options { - /** - Only match an exact string. Useful with `RegExp#test()` to check if a string is a CIDR IP address. *(`false` matches any CIDR IP address in a string)* - - @default false - */ - readonly exact?: boolean; - } -} - -declare const ip: { - /** - Regular expression for matching IP addresses in CIDR notation. - - @returns A regex for matching both IPv4 and IPv6 CIDR IP addresses. - - @example - ``` - import cidrRegex = require("cidr-regex"); - - // Contains a CIDR IP address? - cidrRegex().test("foo 192.168.0.1/24"); - //=> true - - // Is a CIDR IP address? - cidrRegex({exact: true}).test("foo 192.168.0.1/24"); - //=> false - - "foo 192.168.0.1/24 bar 1:2:3:4:5:6:7:8/64 baz".match(cidrRegex()); - //=> ["192.168.0.1/24", "1:2:3:4:5:6:7:8/64"] - ``` - */ - (options?: ip.Options): RegExp; - - /** - @returns A regex for matching IPv4 CIDR IP addresses. - */ - v4(options?: ip.Options): RegExp; - - /** - @returns A regex for matching IPv6 CIDR IP addresses. - - @example - ``` - import cidrRegex = require("cidr-regex"); - - cidrRegex.v6({exact: true}).test("1:2:3:4:5:6:7:8/64"); - //=> true - ``` - */ - v6(options?: ip.Options): RegExp; -}; - -export = ip; diff --git a/node_modules/cidr-regex/index.js b/node_modules/cidr-regex/index.js deleted file mode 100644 index 0f12ee10b3c81..0000000000000 --- a/node_modules/cidr-regex/index.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; - -const ipRegex = require("ip-regex"); - -const defaultOpts = {exact: false}; - -const v4str = `${ipRegex.v4().source}\\/(3[0-2]|[12]?[0-9])`; -const v6str = `${ipRegex.v6().source}\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])`; - -// can not precompile the non-exact regexes because global flag makes the regex object stateful -// which would require the user to reset .lastIndex on subsequent calls -const v4exact = new RegExp(`^${v4str}$`); -const v6exact = new RegExp(`^${v6str}$`); -const v46exact = new RegExp(`(?:^${v4str}$)|(?:^${v6str}$)`); - -module.exports = ({exact} = defaultOpts) => exact ? v46exact : new RegExp(`(?:${v4str})|(?:${v6str})`, "g"); -module.exports.v4 = ({exact} = defaultOpts) => exact ? v4exact : new RegExp(v4str, "g"); -module.exports.v6 = ({exact} = defaultOpts) => exact ? v6exact : new RegExp(v6str, "g"); diff --git a/node_modules/cidr-regex/package.json b/node_modules/cidr-regex/package.json index 8ddef4ed96a93..662f89261b01c 100644 --- a/node_modules/cidr-regex/package.json +++ b/node_modules/cidr-regex/package.json @@ -1,6 +1,6 @@ { "name": "cidr-regex", - "version": "3.1.1", + "version": "5.0.1", "description": "Regular expression for matching IP addresses in CIDR notation", "author": "silverwind <me@silverwind.io>", "contributors": [ @@ -8,35 +8,31 @@ ], "repository": "silverwind/cidr-regex", "license": "BSD-2-Clause", - "scripts": { - "test": "make test" - }, - "engines": { - "node": ">=10" - }, + "type": "module", + "sideEffects": false, + "main": "./dist/index.js", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "cidr", - "regex", - "notation", - "cidr notation", - "prefix", - "prefixes", - "ip", - "ip address" + "dist" ], + "engines": { + "node": ">=20" + }, "dependencies": { - "ip-regex": "^4.1.0" + "ip-regex": "5.0.0" }, "devDependencies": { - "eslint": "7.8.1", - "eslint-config-silverwind": "18.0.8", - "jest": "26.4.2", - "tsd": "0.13.1", - "updates": "10.3.6", - "versions": "8.4.3" + "@types/node": "24.5.2", + "eslint": "9.36.0", + "eslint-config-silverwind": "105.1.0", + "typescript": "5.9.2", + "typescript-config-silverwind": "10.0.1", + "updates": "16.7.2", + "versions": "13.1.2", + "vite": "7.1.7", + "vite-config-silverwind": "6.0.2", + "vitest": "3.2.4", + "vitest-config-silverwind": "10.2.0" } } diff --git a/node_modules/clean-stack/index.d.ts b/node_modules/clean-stack/index.d.ts deleted file mode 100644 index ed5899509419c..0000000000000 --- a/node_modules/clean-stack/index.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -declare namespace cleanStack { - interface Options { - /** - Prettify the file paths in the stack: - - `/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15` → `~/dev/clean-stack/unicorn.js:2:15` - - @default false - */ - readonly pretty?: boolean; - } -} - -/** -Clean up error stack traces. Removes the mostly unhelpful internal Node.js entries. - -@param stack - The `stack` property of an `Error`. - -@example -``` -import cleanStack = require('clean-stack'); - -const error = new Error('Missing unicorn'); - -console.log(error.stack); - -// Error: Missing unicorn -// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15) -// at Module._compile (module.js:409:26) -// at Object.Module._extensions..js (module.js:416:10) -// at Module.load (module.js:343:32) -// at Function.Module._load (module.js:300:12) -// at Function.Module.runMain (module.js:441:10) -// at startup (node.js:139:18) - -console.log(cleanStack(error.stack)); - -// Error: Missing unicorn -// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15) -``` -*/ -declare function cleanStack( - stack: string, - options?: cleanStack.Options -): string; - -export = cleanStack; diff --git a/node_modules/clean-stack/index.js b/node_modules/clean-stack/index.js deleted file mode 100644 index 8c1dcc4cd02a2..0000000000000 --- a/node_modules/clean-stack/index.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; -const os = require('os'); - -const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; -const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; -const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); - -module.exports = (stack, options) => { - options = Object.assign({pretty: false}, options); - - return stack.replace(/\\/g, '/') - .split('\n') - .filter(line => { - const pathMatches = line.match(extractPathRegex); - if (pathMatches === null || !pathMatches[1]) { - return true; - } - - const match = pathMatches[1]; - - // Electron - if ( - match.includes('.app/Contents/Resources/electron.asar') || - match.includes('.app/Contents/Resources/default_app.asar') - ) { - return false; - } - - return !pathRegex.test(match); - }) - .filter(line => line.trim() !== '') - .map(line => { - if (options.pretty) { - return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); - } - - return line; - }) - .join('\n'); -}; diff --git a/node_modules/clean-stack/license b/node_modules/clean-stack/license deleted file mode 100644 index e7af2f77107d7..0000000000000 --- a/node_modules/clean-stack/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/clean-stack/package.json b/node_modules/clean-stack/package.json deleted file mode 100644 index 719fdff55e7b6..0000000000000 --- a/node_modules/clean-stack/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "clean-stack", - "version": "2.2.0", - "description": "Clean up error stack traces", - "license": "MIT", - "repository": "sindresorhus/clean-stack", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=6" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "clean", - "stack", - "trace", - "traces", - "error", - "err", - "electron" - ], - "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" - }, - "browser": { - "os": false - } -} diff --git a/node_modules/clean-stack/readme.md b/node_modules/clean-stack/readme.md deleted file mode 100644 index 8d4416046820a..0000000000000 --- a/node_modules/clean-stack/readme.md +++ /dev/null @@ -1,76 +0,0 @@ -# clean-stack [![Build Status](https://travis-ci.org/sindresorhus/clean-stack.svg?branch=master)](https://travis-ci.org/sindresorhus/clean-stack) - -> Clean up error stack traces - -Removes the mostly unhelpful internal Node.js entries. - -Also works in Electron. - - -## Install - -``` -$ npm install clean-stack -``` - - -## Usage - -```js -const cleanStack = require('clean-stack'); - -const error = new Error('Missing unicorn'); - -console.log(error.stack); -/* -Error: Missing unicorn - at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15) - at Module._compile (module.js:409:26) - at Object.Module._extensions..js (module.js:416:10) - at Module.load (module.js:343:32) - at Function.Module._load (module.js:300:12) - at Function.Module.runMain (module.js:441:10) - at startup (node.js:139:18) -*/ - -console.log(cleanStack(error.stack)); -/* -Error: Missing unicorn - at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15) -*/ -``` - - -## API - -### cleanStack(stack, [options]) - -#### stack - -Type: `string` - -The `stack` property of an `Error`. - -#### options - -Type: `Object` - -##### pretty - -Type: `boolean`<br> -Default: `false` - -Prettify the file paths in the stack: - -`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15` → `~/dev/clean-stack/unicorn.js:2:15` - - -## Related - -- [extrack-stack](https://github.com/sindresorhus/extract-stack) - Extract the actual stack of an error -- [stack-utils](https://github.com/tapjs/stack-utils) - Captures and cleans stack traces - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/cli-columns/LICENSE b/node_modules/cli-columns/license similarity index 100% rename from node_modules/cli-columns/LICENSE rename to node_modules/cli-columns/license diff --git a/node_modules/cli-table3/LICENSE b/node_modules/cli-table3/LICENSE deleted file mode 100644 index a09b7de012ac8..0000000000000 --- a/node_modules/cli-table3/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2014 James Talmage <james.talmage@jrtechnical.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/node_modules/cli-table3/index.d.ts b/node_modules/cli-table3/index.d.ts deleted file mode 100644 index 16980f848cc8e..0000000000000 --- a/node_modules/cli-table3/index.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -declare namespace CliTable3 { - type CharName = - "top" | - "top-mid" | - "top-left" | - "top-right" | - "bottom" | - "bottom-mid" | - "bottom-left" | - "bottom-right" | - "left" | - "left-mid" | - "mid" | - "mid-mid" | - "right" | - "right-mid" | - "middle"; - - type HorizontalAlignment = "left" | "center" | "right"; - type VerticalAlignment = "top" | "center" | "bottom"; - - interface TableOptions { - truncate: string; - colWidths: Array<number | null>; - rowHeights: Array<number | null>; - colAligns: HorizontalAlignment[]; - rowAligns: VerticalAlignment[]; - head: string[]; - wordWrap: boolean; - wrapOnWordBoundary: boolean; - } - - interface TableInstanceOptions extends TableOptions { - chars: Record<CharName, string>; - style: { - "padding-left": number; - "padding-right": number; - head: string[]; - border: string[]; - compact: boolean; - }; - } - - interface TableConstructorOptions extends Partial<TableOptions> { - chars?: Partial<Record<CharName, string>>; - style?: Partial<TableInstanceOptions["style"]>; - } - - type CellValue = boolean | number | string | null | undefined; - - interface CellOptions { - content: CellValue; - chars?: Partial<Record<CharName, string>>; - truncate?: string; - colSpan?: number; - rowSpan?: number; - hAlign?: HorizontalAlignment; - vAlign?: VerticalAlignment; - style?: { - "padding-left"?: number; - "padding-right"?: number; - head?: string[]; - border?: string[]; - }; - } - - interface GenericTable<T> extends Array<T> { - options: TableInstanceOptions; - readonly width: number; - } - - type Table = GenericTable<HorizontalTableRow|VerticalTableRow|CrossTableRow>; - type Cell = CellValue | CellOptions; - - type HorizontalTableRow = Cell[]; - - interface VerticalTableRow { - [name: string]: Cell; - } - - interface CrossTableRow { - [name: string]: Cell[]; - } -} - -interface CliTable3 { - new (options?: CliTable3.TableConstructorOptions): CliTable3.Table; - readonly prototype: CliTable3.Table; -} - -declare const CliTable3: CliTable3; - -export = CliTable3; diff --git a/node_modules/cli-table3/index.js b/node_modules/cli-table3/index.js deleted file mode 100644 index b49d920dd3ef6..0000000000000 --- a/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/node_modules/cli-table3/package.json b/node_modules/cli-table3/package.json deleted file mode 100644 index 4e6689621968c..0000000000000 --- a/node_modules/cli-table3/package.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "cli-table3", - "version": "0.6.2", - "description": "Pretty unicode tables for the command line. Based on the original cli-table.", - "main": "index.js", - "types": "index.d.ts", - "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": [ - "<rootDir>/test/**/*.js" - ] - }, - { - "runner": "jest-runner-eslint", - "displayName": "lint", - "testMatch": [ - "<rootDir>/examples/**/*.js", - "<rootDir>/lib/**/*.js", - "<rootDir>/scripts/**/*.js", - "<rootDir>/src/**/*.js", - "<rootDir>/test/**/*.js" - ] - } - ] - }, - "prettier": { - "printWidth": 120, - "tabWidth": 2, - "singleQuote": true, - "trailingComma": "es5" - } -} diff --git a/node_modules/cli-table3/src/cell.js b/node_modules/cli-table3/src/cell.js deleted file mode 100644 index 8f507442bb8fc..0000000000000 --- a/node_modules/cli-table3/src/cell.js +++ /dev/null @@ -1,406 +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) { - if (this.fixedWidth && (tableOptions.wordWrap || tableOptions.textWrap)) { - 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 = true } = tableOptions; - 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/node_modules/cli-table3/src/debug.js b/node_modules/cli-table3/src/debug.js deleted file mode 100644 index 6acfb03032159..0000000000000 --- a/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/node_modules/cli-table3/src/layout-manager.js b/node_modules/cli-table3/src/layout-manager.js deleted file mode 100644 index 3937452274d72..0000000000000 --- a/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/node_modules/cli-table3/src/table.js b/node_modules/cli-table3/src/table.js deleted file mode 100644 index eb4a9bda9a364..0000000000000 --- a/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/node_modules/cli-table3/src/utils.js b/node_modules/cli-table3/src/utils.js deleted file mode 100644 index c922c5b9adb62..0000000000000 --- a/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/node_modules/clone/LICENSE b/node_modules/clone/LICENSE deleted file mode 100644 index cc3c87bc3bfd8..0000000000000 --- a/node_modules/clone/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright © 2011-2015 Paul Vorbach <paul@vorba.ch> - -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/node_modules/clone/clone.iml b/node_modules/clone/clone.iml deleted file mode 100644 index 30de8aee9ba30..0000000000000 --- a/node_modules/clone/clone.iml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="WEB_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$" /> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="library" name="clone node_modules" level="project" /> - </component> -</module> \ No newline at end of file diff --git a/node_modules/clone/clone.js b/node_modules/clone/clone.js deleted file mode 100644 index ba200c2f99288..0000000000000 --- a/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/node_modules/clone/package.json b/node_modules/clone/package.json deleted file mode 100644 index 3ddd242f4a510..0000000000000 --- a/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 <paul@vorba.ch> (http://paul.vorba.ch/)", - "contributors": [ - "Blake Miner <miner.blake@gmail.com> (http://www.blakeminer.com/)", - "Tian You <axqd001@gmail.com> (http://blog.axqd.net/)", - "George Stagas <gstagas@gmail.com> (http://stagas.com/)", - "Tobiasz Cudnik <tobiasz.cudnik@gmail.com> (https://github.com/TobiaszCudnik)", - "Pavel Lang <langpavel@phpskelet.org> (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 <nathan@macinn.es> (http://macinn.es/)", - "Benjamin E. Coe <ben@npmjs.com> (https://twitter.com/benjamincoe)", - "Nathan Zadoks (https://github.com/nathan7)", - "Róbert Oroszi <robert+gh@oroszi.net> (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/node_modules/cmd-shim/lib/index.js b/node_modules/cmd-shim/lib/index.js index 10494e58ad548..c13890aed3263 100644 --- a/node_modules/cmd-shim/lib/index.js +++ b/node_modules/cmd-shim/lib/index.js @@ -8,18 +8,20 @@ // Write a binroot/pkg.bin + ".cmd" file that has this line in it: // @<prog> <args...> %dp0%<target> %* -const { promisify } = require('util') -const fs = require('fs') -const writeFile = promisify(fs.writeFile) -const readFile = promisify(fs.readFile) -const chmod = promisify(fs.chmod) -const stat = promisify(fs.stat) -const unlink = promisify(fs.unlink) +const { + chmod, + mkdir, + readFile, + stat, + unlink, + writeFile, +} = require('fs/promises') const { dirname, relative } = require('path') -const mkdir = require('mkdirp-infer-owner') const toBatchSyntax = require('./to-batch-syntax') -const shebangExpr = /^#!\s*(?:\/usr\/bin\/env\s*((?:[^ \t=]+=[^ \t=]+\s+)*))?([^ \t]+)(.*)$/ +// linting disabled because this regex is really long +// eslint-disable-next-line max-len +const shebangExpr = /^#!\s*(?:\/usr\/bin\/env\s+(?:-S\s+)?((?:[^ \t=]+=[^ \t=]+\s+)*))?([^ \t]+)(.*)$/ const cmdShimIfExists = (from, to) => stat(from).then(() => cmdShim(from, to), () => {}) @@ -42,7 +44,7 @@ const writeShim = (from, to) => // First, check if the bin is a #! of some sort. // If not, then assume it's something that'll be compiled, or some other // sort of script, and just call it directly. - mkdir(dirname(to)) + mkdir(dirname(to), { recursive: true }) .then(() => readFile(from, 'utf8')) .then(data => { const firstLine = data.trim().split(/\r*\n/)[0] @@ -54,7 +56,7 @@ const writeShim = (from, to) => const prog = shebang[2] const args = shebang[3] || '' return writeShim_(from, to, prog, args, vars) - }, er => writeShim_(from, to)) + }, () => writeShim_(from, to)) const writeShim_ = (from, to, prog, args, variables) => { let shTarget = relative(dirname(to), from) @@ -120,7 +122,11 @@ const writeShim_ = (from, to, prog, args, variables) => { // basedir=`dirname "$0"` // // case `uname` in - // *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; + // *CYGWIN*|*MINGW*|*MSYS*) + // if command -v cygpath > /dev/null 2>&1; then + // basedir=`cygpath -w "$basedir"` + // fi + // ;; // esac // // if [ -x "$basedir/node.exe" ]; then @@ -135,7 +141,11 @@ const writeShim_ = (from, to, prog, args, variables) => { + `basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")\n` + '\n' + 'case `uname` in\n' - + ' *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;\n' + + ' *CYGWIN*|*MINGW*|*MSYS*)\n' + + ' if command -v cygpath > /dev/null 2>&1; then\n' + + ' basedir=`cygpath -w "$basedir"`\n' + + ' fi\n' + + ' ;;\n' + 'esac\n' + '\n' diff --git a/node_modules/cmd-shim/package.json b/node_modules/cmd-shim/package.json index 1bcbdc4342ced..0da1978b985d2 100644 --- a/node_modules/cmd-shim/package.json +++ b/node_modules/cmd-shim/package.json @@ -1,32 +1,25 @@ { "name": "cmd-shim", - "version": "5.0.0", + "version": "8.0.0", "description": "Used in npm for command line application support", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", - "posttest": "npm run lint" + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/cmd-shim.git" + "url": "git+https://github.com/npm/cmd-shim.git" }, "license": "ISC", - "dependencies": { - "mkdirp-infer-owner": "^2.0.0" - }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "rimraf": "^3.0.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "files": [ @@ -37,14 +30,19 @@ "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/color-convert/LICENSE b/node_modules/color-convert/LICENSE deleted file mode 100644 index 5b4c386f9269b..0000000000000 --- a/node_modules/color-convert/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2011-2016 Heather Arthur <fayearthur@gmail.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/node_modules/color-convert/conversions.js b/node_modules/color-convert/conversions.js deleted file mode 100644 index 2657f265c9e10..0000000000000 --- a/node_modules/color-convert/conversions.js +++ /dev/null @@ -1,839 +0,0 @@ -/* MIT license */ -/* eslint-disable no-mixed-operators */ -const cssKeywords = require('color-name'); - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -const reverseKeywords = {}; -for (const key of Object.keys(cssKeywords)) { - reverseKeywords[cssKeywords[key]] = key; -} - -const convert = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -module.exports = convert; - -// Hide .channels and .labels properties -for (const model of Object.keys(convert)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - const {channels, labels} = convert[model]; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); -} - -convert.rgb.hsl = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const min = Math.min(r, g, b); - const max = Math.max(r, g, b); - const delta = max - min; - let h; - let s; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - const l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert.rgb.hsv = function (rgb) { - let rdif; - let gdif; - let bdif; - let h; - let s; - - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const v = Math.max(r, g, b); - const diff = v - Math.min(r, g, b); - const diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = 0; - s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert.rgb.hwb = function (rgb) { - const r = rgb[0]; - const g = rgb[1]; - let b = rgb[2]; - const h = convert.rgb.hsl(rgb)[0]; - const w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert.rgb.cmyk = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - - const k = Math.min(1 - r, 1 - g, 1 - b); - const c = (1 - r - k) / (1 - k) || 0; - const m = (1 - g - k) / (1 - k) || 0; - const y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -function comparativeDistance(x, y) { - /* - See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - */ - return ( - ((x[0] - y[0]) ** 2) + - ((x[1] - y[1]) ** 2) + - ((x[2] - y[2]) ** 2) - ); -} - -convert.rgb.keyword = function (rgb) { - const reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } - - let currentClosestDistance = Infinity; - let currentClosestKeyword; - - for (const keyword of Object.keys(cssKeywords)) { - const value = cssKeywords[keyword]; - - // Compute comparative distance - const distance = comparativeDistance(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - - return currentClosestKeyword; -}; - -convert.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; - -convert.rgb.xyz = function (rgb) { - let r = rgb[0] / 255; - let g = rgb[1] / 255; - let b = rgb[2] / 255; - - // Assume sRGB - r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); - g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); - b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - - const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert.rgb.lab = function (rgb) { - const xyz = convert.rgb.xyz(rgb); - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); - - return [l, a, b]; -}; - -convert.hsl.rgb = function (hsl) { - const h = hsl[0] / 360; - const s = hsl[1] / 100; - const l = hsl[2] / 100; - let t2; - let t3; - let val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - const t1 = 2 * l - t2; - - const rgb = [0, 0, 0]; - for (let i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert.hsl.hsv = function (hsl) { - const h = hsl[0]; - let s = hsl[1] / 100; - let l = hsl[2] / 100; - let smin = s; - const lmin = Math.max(l, 0.01); - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - const v = (l + s) / 2; - const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert.hsv.rgb = function (hsv) { - const h = hsv[0] / 60; - const s = hsv[1] / 100; - let v = hsv[2] / 100; - const hi = Math.floor(h) % 6; - - const f = h - Math.floor(h); - const p = 255 * v * (1 - s); - const q = 255 * v * (1 - (s * f)); - const t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert.hsv.hsl = function (hsv) { - const h = hsv[0]; - const s = hsv[1] / 100; - const v = hsv[2] / 100; - const vmin = Math.max(v, 0.01); - let sl; - let l; - - l = (2 - s) * v; - const lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - const h = hwb[0] / 360; - let wh = hwb[1] / 100; - let bl = hwb[2] / 100; - const ratio = wh + bl; - let f; - - // Wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - const i = Math.floor(6 * h); - const v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - const n = wh + f * (v - wh); // Linear interpolation - - let r; - let g; - let b; - /* eslint-disable max-statements-per-line,no-multi-spaces */ - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - /* eslint-enable max-statements-per-line,no-multi-spaces */ - - return [r * 255, g * 255, b * 255]; -}; - -convert.cmyk.rgb = function (cmyk) { - const c = cmyk[0] / 100; - const m = cmyk[1] / 100; - const y = cmyk[2] / 100; - const k = cmyk[3] / 100; - - const r = 1 - Math.min(1, c * (1 - k) + k); - const g = 1 - Math.min(1, m * (1 - k) + k); - const b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert.xyz.rgb = function (xyz) { - const x = xyz[0] / 100; - const y = xyz[1] / 100; - const z = xyz[2] / 100; - let r; - let g; - let b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // Assume sRGB - r = r > 0.0031308 - ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert.xyz.lab = function (xyz) { - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); - - return [l, a, b]; -}; - -convert.lab.xyz = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let x; - let y; - let z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - const y2 = y ** 3; - const x2 = x ** 3; - const z2 = z ** 3; - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert.lab.lch = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let h; - - const hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - const c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert.lch.lab = function (lch) { - const l = lch[0]; - const c = lch[1]; - const h = lch[2]; - - const hr = h / 360 * 2 * Math.PI; - const a = c * Math.cos(hr); - const b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert.rgb.ansi16 = function (args, saturation = null) { - const [r, g, b] = args; - let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - let ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert.hsv.ansi16 = function (args) { - // Optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; - -convert.rgb.ansi256 = function (args) { - const r = args[0]; - const g = args[1]; - const b = args[2]; - - // We use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - const ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert.ansi16.rgb = function (args) { - let color = args % 10; - - // Handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - const mult = (~~(args > 50) + 1) * 0.5; - const r = ((color & 1) * mult) * 255; - const g = (((color >> 1) & 1) * mult) * 255; - const b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert.ansi256.rgb = function (args) { - // Handle greyscale - if (args >= 232) { - const c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - let rem; - const r = Math.floor(args / 36) / 5 * 255; - const g = Math.floor((rem = args % 36) / 6) / 5 * 255; - const b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert.rgb.hex = function (args) { - const integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert.hex.rgb = function (args) { - const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - let colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(char => { - return char + char; - }).join(''); - } - - const integer = parseInt(colorString, 16); - const r = (integer >> 16) & 0xFF; - const g = (integer >> 8) & 0xFF; - const b = integer & 0xFF; - - return [r, g, b]; -}; - -convert.rgb.hcg = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const max = Math.max(Math.max(r, g), b); - const min = Math.min(Math.min(r, g), b); - const chroma = (max - min); - let grayscale; - let hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert.hsl.hcg = function (hsl) { - const s = hsl[1] / 100; - const l = hsl[2] / 100; - - const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); - - let f = 0; - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert.hsv.hcg = function (hsv) { - const s = hsv[1] / 100; - const v = hsv[2] / 100; - - const c = s * v; - let f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert.hcg.rgb = function (hcg) { - const h = hcg[0] / 360; - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - const pure = [0, 0, 0]; - const hi = (h % 1) * 6; - const v = hi % 1; - const w = 1 - v; - let mg = 0; - - /* eslint-disable max-statements-per-line */ - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - /* eslint-enable max-statements-per-line */ - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert.hcg.hsv = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const v = c + g * (1.0 - c); - let f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert.hcg.hsl = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const l = g * (1.0 - c) + 0.5 * c; - let s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert.hcg.hwb = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - const v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert.hwb.hcg = function (hwb) { - const w = hwb[1] / 100; - const b = hwb[2] / 100; - const v = 1 - b; - const c = v - w; - let g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert.gray.hsl = function (args) { - return [0, 0, args[0]]; -}; - -convert.gray.hsv = convert.gray.hsl; - -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert.gray.hex = function (gray) { - const val = Math.round(gray[0] / 100 * 255) & 0xFF; - const integer = (val << 16) + (val << 8) + val; - - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert.rgb.gray = function (rgb) { - const val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; diff --git a/node_modules/color-convert/index.js b/node_modules/color-convert/index.js deleted file mode 100644 index b648e5737be61..0000000000000 --- a/node_modules/color-convert/index.js +++ /dev/null @@ -1,81 +0,0 @@ -const conversions = require('./conversions'); -const route = require('./route'); - -const convert = {}; - -const models = Object.keys(conversions); - -function wrapRaw(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - if (arg0 === undefined || arg0 === null) { - return arg0; - } - - if (arg0.length > 1) { - args = arg0; - } - - return fn(args); - }; - - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - - if (arg0 === undefined || arg0 === null) { - return arg0; - } - - if (arg0.length > 1) { - args = arg0; - } - - const result = fn(args); - - // We're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (let len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models.forEach(fromModel => { - convert[fromModel] = {}; - - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - - const routes = route(fromModel); - const routeModels = Object.keys(routes); - - routeModels.forEach(toModel => { - const fn = routes[toModel]; - - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -module.exports = convert; diff --git a/node_modules/color-convert/package.json b/node_modules/color-convert/package.json deleted file mode 100644 index 6e48000c7c98f..0000000000000 --- a/node_modules/color-convert/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "color-convert", - "description": "Plain color conversion functions", - "version": "2.0.1", - "author": "Heather Arthur <fayearthur@gmail.com>", - "license": "MIT", - "repository": "Qix-/color-convert", - "scripts": { - "pretest": "xo", - "test": "node test/basic.js" - }, - "engines": { - "node": ">=7.0.0" - }, - "keywords": [ - "color", - "colour", - "convert", - "converter", - "conversion", - "rgb", - "hsl", - "hsv", - "hwb", - "cmyk", - "ansi", - "ansi16" - ], - "files": [ - "index.js", - "conversions.js", - "route.js" - ], - "xo": { - "rules": { - "default-case": 0, - "no-inline-comments": 0, - "operator-linebreak": 0 - } - }, - "devDependencies": { - "chalk": "^2.4.2", - "xo": "^0.24.0" - }, - "dependencies": { - "color-name": "~1.1.4" - } -} diff --git a/node_modules/color-convert/route.js b/node_modules/color-convert/route.js deleted file mode 100644 index 1a08521b5a001..0000000000000 --- a/node_modules/color-convert/route.js +++ /dev/null @@ -1,97 +0,0 @@ -const conversions = require('./conversions'); - -/* - This function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph() { - const graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - const models = Object.keys(conversions); - - for (let len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - const graph = buildGraph(); - const queue = [fromModel]; // Unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - const current = queue.pop(); - const adjacents = Object.keys(conversions[current]); - - for (let len = adjacents.length, i = 0; i < len; i++) { - const adjacent = adjacents[i]; - const node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion(toModel, graph) { - const path = [graph[toModel].parent, toModel]; - let fn = conversions[graph[toModel].parent][toModel]; - - let cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -module.exports = function (fromModel) { - const graph = deriveBFS(fromModel); - const conversion = {}; - - const models = Object.keys(graph); - for (let len = models.length, i = 0; i < len; i++) { - const toModel = models[i]; - const node = graph[toModel]; - - if (node.parent === null) { - // No possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion(toModel, graph); - } - - return conversion; -}; - diff --git a/node_modules/color-name/LICENSE b/node_modules/color-name/LICENSE deleted file mode 100644 index c6b10012540c2..0000000000000 --- a/node_modules/color-name/LICENSE +++ /dev/null @@ -1,8 +0,0 @@ -The MIT License (MIT) -Copyright (c) 2015 Dmitry Ivanov - -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. \ No newline at end of file diff --git a/node_modules/color-name/index.js b/node_modules/color-name/index.js deleted file mode 100644 index b7c198a6f3d7c..0000000000000 --- a/node_modules/color-name/index.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict' - -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; diff --git a/node_modules/color-name/package.json b/node_modules/color-name/package.json deleted file mode 100644 index 782dd82878030..0000000000000 --- a/node_modules/color-name/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "color-name", - "version": "1.1.4", - "description": "A list of color names and its values", - "main": "index.js", - "files": [ - "index.js" - ], - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "git@github.com:colorjs/color-name.git" - }, - "keywords": [ - "color-name", - "color", - "color-keyword", - "keyword" - ], - "author": "DY <dfcreative@gmail.com>", - "license": "MIT", - "bugs": { - "url": "https://github.com/colorjs/color-name/issues" - }, - "homepage": "https://github.com/colorjs/color-name" -} diff --git a/node_modules/color-support/LICENSE b/node_modules/color-support/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/color-support/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/color-support/bin.js b/node_modules/color-support/bin.js deleted file mode 100755 index 3c0a967218083..0000000000000 --- a/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/node_modules/color-support/browser.js b/node_modules/color-support/browser.js deleted file mode 100644 index ab5c6631a35b8..0000000000000 --- a/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/node_modules/color-support/index.js b/node_modules/color-support/index.js deleted file mode 100644 index 6b6f3b2819424..0000000000000 --- a/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/node_modules/color-support/package.json b/node_modules/color-support/package.json deleted file mode 100644 index f3e3b77145d6b..0000000000000 --- a/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 <i@izs.me> (http://blog.izs.me/)", - "license": "ISC", - "files": [ - "browser.js", - "index.js", - "bin.js" - ] -} diff --git a/node_modules/columnify/LICENSE b/node_modules/columnify/LICENSE deleted file mode 100644 index ed47678e61c40..0000000000000 --- a/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/node_modules/columnify/Makefile b/node_modules/columnify/Makefile deleted file mode 100644 index 3a67c57a3b1e0..0000000000000 --- a/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/node_modules/columnify/Readme.md b/node_modules/columnify/Readme.md deleted file mode 100644 index d94ab9bc5f128..0000000000000 --- a/node_modules/columnify/Readme.md +++ /dev/null @@ -1,475 +0,0 @@ -# columnify - -[![Columnify Unit Tests](https://github.com/timoxley/columnify/actions/workflows/test.yml/badge.svg)](https://github.com/timoxley/columnify/actions/workflows/test.yml) -[![NPM Version](https://img.shields.io/npm/v/columnify.svg?style=flat)](https://npmjs.org/package/columnify) -[![License](http://img.shields.io/npm/l/columnify.svg?style=flat)](LICENSE) - -Create text-based columns suitable for console output from objects or -arrays of objects. - -Columns are automatically resized to fit the content of the largest -cell. Each cell will be padded with spaces to fill the available space -and ensure column contents are left-aligned. - -Designed to [handle sensible wrapping in npm search results](https://github.com/isaacs/npm/pull/2328). - -`npm search` before & after integrating columnify: - -![npm-tidy-search](https://f.cloud.github.com/assets/43438/1848959/ae02ad04-76a1-11e3-8255-4781debffc26.gif) - -## Installation - -``` -$ npm install columnify -``` - -## Usage - -```javascript -var columnify = require('columnify') -var columns = columnify(data, options) -console.log(columns) -``` - -## Examples - -### Columnify Objects - -Objects are converted to a list of key/value pairs: - -```javascript -var data = { - "commander@0.6.1": 1, - "minimatch@0.2.14": 3, - "mkdirp@0.3.5": 2, - "sigmund@1.0.0": 3 -} - -console.log(columnify(data)) -``` -#### Output: -``` -KEY VALUE -commander@0.6.1 1 -minimatch@0.2.14 3 -mkdirp@0.3.5 2 -sigmund@1.0.0 3 -``` - -### Custom Column Names - -```javascript -var data = { - "commander@0.6.1": 1, - "minimatch@0.2.14": 3, - "mkdirp@0.3.5": 2, - "sigmund@1.0.0": 3 -} - -console.log(columnify(data, {columns: ['MODULE', 'COUNT']})) -``` -#### Output: -``` -MODULE COUNT -commander@0.6.1 1 -minimatch@0.2.14 3 -mkdirp@0.3.5 2 -sigmund@1.0.0 3 -``` - -### Columnify Arrays of Objects - -Column headings are extracted from the keys in supplied objects. - -```javascript -var columnify = require('columnify') - -var columns = columnify([{ - name: 'mod1', - version: '0.0.1' -}, { - name: 'module2', - version: '0.2.0' -}]) - -console.log(columns) -``` -#### Output: -``` -NAME VERSION -mod1 0.0.1 -module2 0.2.0 -``` - -### Filtering & Ordering Columns - -By default, all properties are converted into columns, whether or not -they exist on every object or not. - -To explicitly specify which columns to include, and in which order, -supply a "columns" or "include" array ("include" is just an alias). - -```javascript -var data = [{ - name: 'module1', - description: 'some description', - version: '0.0.1', -}, { - name: 'module2', - description: 'another description', - version: '0.2.0', -}] - -var columns = columnify(data, { - columns: ['name', 'version'] -}) - -console.log(columns) -``` - -#### Output: -``` -NAME VERSION -module1 0.0.1 -module2 0.2.0 -``` - -## Global and Per Column Options -You can set a number of options at a global level (ie. for all columns) or on a per column basis. - -Set options on a per column basis by using the `config` option to specify individual columns: - -```javascript -var columns = columnify(data, { - optionName: optionValue, - config: { - columnName: {optionName: optionValue}, - columnName: {optionName: optionValue}, - } -}) -``` - -### Maximum and Minimum Column Widths -As with all options, you can define the `maxWidth` and `minWidth` globally, or for specified columns. By default, wrapping will happen at word boundaries. Empty cells or those which do not fill the `minWidth` will be padded with spaces. - -```javascript -var columns = columnify([{ - name: 'mod1', - description: 'some description which happens to be far larger than the max', - version: '0.0.1', -}, { - name: 'module-two', - description: 'another description larger than the max', - version: '0.2.0', -}], { - minWidth: 20, - config: { - description: {maxWidth: 30} - } -}) - -console.log(columns) -``` - -#### Output: -``` -NAME DESCRIPTION VERSION -mod1 some description which happens 0.0.1 - to be far larger than the max -module-two another description larger 0.2.0 - than the max -``` - -#### Maximum Line Width - -You can set a hard maximum line width using the `maxLineWidth` option. -Beyond this value data is unceremoniously truncated with no truncation -marker. - -This can either be a number or 'auto' to set the value to the width of -stdout. - -Setting this value to 'auto' prevent TTY-imposed line-wrapping when -lines exceed the screen width. - -#### Truncating Column Cells Instead of Wrapping - -You can disable wrapping and instead truncate content at the maximum -column width by using the `truncate` option. Truncation respects word boundaries. A truncation marker, `…`, will appear next to the last word in any truncated line. - -```javascript -var columns = columnify(data, { - truncate: true, - config: { - description: { - maxWidth: 20 - } - } -}) - -console.log(columns) -``` -#### Output: -``` -NAME DESCRIPTION VERSION -mod1 some description… 0.0.1 -module-two another description… 0.2.0 -``` - - -### Align Right/Center -You can set the alignment of the column data by using the `align` option. - -```js -var data = { - "mocha@1.18.2": 1, - "commander@2.0.0": 1, - "debug@0.8.1": 1 -} - -columnify(data, {config: {value: {align: 'right'}}}) -``` - -#### Output: -``` -KEY VALUE -mocha@1.18.2 1 -commander@2.0.0 1 -debug@0.8.1 1 -``` - -`align: 'center'` works in a similar way. - - -### Padding Character - -Set a character to fill whitespace within columns with the `paddingChr` option. - -```js -var data = { - "shortKey": "veryVeryVeryVeryVeryLongVal", - "veryVeryVeryVeryVeryLongKey": "shortVal" -} - -columnify(data, { paddingChr: '.'}) -``` - -#### Output: -``` -KEY........................ VALUE...................... -shortKey................... veryVeryVeryVeryVeryLongVal -veryVeryVeryVeryVeryLongKey shortVal................... -``` - -### Preserve Existing Newlines - -By default, `columnify` sanitises text by replacing any occurance of 1 or more whitespace characters with a single space. - -`columnify` can be configured to respect existing new line characters using the `preserveNewLines` option. Note this will still collapse all other whitespace. - -```javascript -var data = [{ - name: "glob@3.2.9", - paths: [ - "node_modules/tap/node_modules/glob", - "node_modules/tape/node_modules/glob" - ].join('\n') -}, { - name: "nopt@2.2.1", - paths: [ - "node_modules/tap/node_modules/nopt" - ] -}, { - name: "runforcover@0.0.2", - paths: "node_modules/tap/node_modules/runforcover" -}] - -console.log(columnify(data, {preserveNewLines: true})) -``` -#### Output: -``` -NAME PATHS -glob@3.2.9 node_modules/tap/node_modules/glob - node_modules/tape/node_modules/glob -nopt@2.2.1 node_modules/tap/node_modules/nopt -runforcover@0.0.2 node_modules/tap/node_modules/runforcover -``` - -Compare this with output without `preserveNewLines`: - -```javascript -console.log(columnify(data, {preserveNewLines: false})) -// or just -console.log(columnify(data)) -``` - -``` -NAME PATHS -glob@3.2.9 node_modules/tap/node_modules/glob node_modules/tape/node_modules/glob -nopt@2.2.1 node_modules/tap/node_modules/nopt -runforcover@0.0.2 node_modules/tap/node_modules/runforcover -``` - -### Custom Truncation Marker - -You can change the truncation marker to something other than the default -`…` by using the `truncateMarker` option. - -```javascript -var columns = columnify(data, { - truncate: true, - truncateMarker: '>', - widths: { - description: { - maxWidth: 20 - } - } -}) - -console.log(columns) -``` -#### Output: -``` -NAME DESCRIPTION VERSION -mod1 some description> 0.0.1 -module-two another description> 0.2.0 -``` - -### Custom Column Splitter - -If your columns need some bling, you can split columns with custom -characters by using the `columnSplitter` option. - -```javascript -var columns = columnify(data, { - columnSplitter: ' | ' -}) - -console.log(columns) -``` -#### Output: -``` -NAME | DESCRIPTION | VERSION -mod1 | some description which happens to be far larger than the max | 0.0.1 -module-two | another description larger than the max | 0.2.0 -``` - -### Control Header Display - -Control whether column headers are displayed by using the `showHeaders` option. - -```javascript -var columns = columnify(data, { - showHeaders: false -}) -``` - -This also works well for hiding a single column header, like an `id` column: -```javascript -var columns = columnify(data, { - config: { - id: { showHeaders: false } - } -}) -``` - -### Transforming Column Data and Headers -If you need to modify the presentation of column content or heading content there are two useful options for doing that: `dataTransform` and `headingTransform`. Both of these take a function and need to return a valid string. - -```javascript -var columns = columnify([{ - name: 'mod1', - description: 'SOME DESCRIPTION TEXT.' -}, { - name: 'module-two', - description: 'SOME SLIGHTLY LONGER DESCRIPTION TEXT.' -}], { - dataTransform: function(data) { - return data.toLowerCase() - }, - headingTransform: function(heading) { - return heading.toLowerCase() - }, - config: { - name: { - headingTransform: function(heading) { - heading = "module " + heading - return "*" + heading.toUpperCase() + "*" - } - } - } -}) -``` -#### Output: -``` -*MODULE NAME* description -mod1 some description text. -module-two some slightly longer description text. -``` - - -## Multibyte Character Support - -`columnify` uses [mycoboco/wcwidth.js](https://github.com/mycoboco/wcwidth.js) to calculate length of multibyte characters: - -```javascript -var data = [{ - name: 'module-one', - description: 'some description', - version: '0.0.1', -}, { - name: '这是一个很长的名字的模块', - description: '这真的是一个描述的内容这个描述很长', - version: "0.3.3" -}] - -console.log(columnify(data)) -``` - -#### Without multibyte handling: - -i.e. before columnify added this feature - -``` -NAME DESCRIPTION VERSION -module-one some description 0.0.1 -这是一个很长的名字的模块 这真的是一个描述的内容这个描述很长 0.3.3 -``` - -#### With multibyte handling: - -``` -NAME DESCRIPTION VERSION -module-one some description 0.0.1 -这是一个很长的名字的模块 这真的是一个描述的内容这个描述很长 0.3.3 -``` - -## Contributions - -``` - project : columnify - repo age : 8 years - active : 47 days - commits : 180 - files : 57 - authors : - 123 Tim Oxley 68.3% - 11 Nicholas Hoffman 6.1% - 8 Tim 4.4% - 7 Arjun Mehta 3.9% - 6 Dany 3.3% - 5 Tim Kevin Oxley 2.8% - 5 Wei Gao 2.8% - 4 Matias Singers 2.2% - 3 Michael Kriese 1.7% - 2 sreekanth370 1.1% - 2 Dany Shaanan 1.1% - 1 Tim Malone 0.6% - 1 Seth Miller 0.6% - 1 andyfusniak 0.6% - 1 Isaac Z. Schlueter 0.6% -``` - -## License - -MIT diff --git a/node_modules/columnify/columnify.js b/node_modules/columnify/columnify.js deleted file mode 100644 index dcef9236e1843..0000000000000 --- a/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/node_modules/columnify/index.js b/node_modules/columnify/index.js deleted file mode 100644 index 221269b3e76b7..0000000000000 --- a/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/node_modules/columnify/package.json b/node_modules/columnify/package.json deleted file mode 100644 index 29565407a8cd7..0000000000000 --- a/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/node_modules/columnify/utils.js b/node_modules/columnify/utils.js deleted file mode 100644 index df3e6cc44e856..0000000000000 --- a/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/node_modules/columnify/width.js b/node_modules/columnify/width.js deleted file mode 100644 index a9f5333b40b2f..0000000000000 --- a/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/node_modules/common-ancestor-path/LICENSE b/node_modules/common-ancestor-path/LICENSE deleted file mode 100644 index 05eeeb88c2ef4..0000000000000 --- a/node_modules/common-ancestor-path/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/common-ancestor-path/LICENSE.md b/node_modules/common-ancestor-path/LICENSE.md new file mode 100644 index 0000000000000..c5402b9577a8c --- /dev/null +++ b/node_modules/common-ancestor-path/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/common-ancestor-path/dist/commonjs/index.js b/node_modules/common-ancestor-path/dist/commonjs/index.js new file mode 100644 index 0000000000000..70a3604fb0f3b --- /dev/null +++ b/node_modules/common-ancestor-path/dist/commonjs/index.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.commonAncestorPath = void 0; +const node_path_1 = require("node:path"); +function* commonArrayMembers(a, b) { + const [l, s] = a.length > b.length ? [a, b] : [b, a]; + for (const x of s) { + if (x === l.shift()) + yield x; + else + break; + } +} +const cap = (a, b) => a === b ? a + : !a || !b ? null + : (0, node_path_1.parse)(a).root !== (0, node_path_1.parse)(b).root ? null + : [...commonArrayMembers((0, node_path_1.normalize)(a).split(node_path_1.sep), (0, node_path_1.normalize)(b).split(node_path_1.sep))].join(node_path_1.sep); +const commonAncestorPath = (...paths) => paths.reduce(cap); +exports.commonAncestorPath = commonAncestorPath; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/common-ancestor-path/dist/commonjs/package.json b/node_modules/common-ancestor-path/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/common-ancestor-path/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/common-ancestor-path/dist/esm/index.js b/node_modules/common-ancestor-path/dist/esm/index.js new file mode 100644 index 0000000000000..abb7c92931a61 --- /dev/null +++ b/node_modules/common-ancestor-path/dist/esm/index.js @@ -0,0 +1,16 @@ +import { parse, sep, normalize as norm } from 'node:path'; +function* commonArrayMembers(a, b) { + const [l, s] = a.length > b.length ? [a, b] : [b, a]; + for (const x of s) { + if (x === l.shift()) + yield x; + else + break; + } +} +const cap = (a, b) => a === b ? a + : !a || !b ? null + : parse(a).root !== parse(b).root ? null + : [...commonArrayMembers(norm(a).split(sep), norm(b).split(sep))].join(sep); +export const commonAncestorPath = (...paths) => paths.reduce(cap); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/common-ancestor-path/dist/esm/package.json b/node_modules/common-ancestor-path/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/common-ancestor-path/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/common-ancestor-path/index.js b/node_modules/common-ancestor-path/index.js deleted file mode 100644 index 09ae3178295ad..0000000000000 --- a/node_modules/common-ancestor-path/index.js +++ /dev/null @@ -1,17 +0,0 @@ -const {parse, sep, normalize: norm} = require('path') - -function* commonArrayMembers (a, b) { - const [l, s] = a.length > b.length ? [a, b] : [b, a] - for (const x of s) { - if (x === l.shift()) - yield x - else - break - } -} - -const commonAncestorPath = (a, b) => a === b ? a - : parse(a).root !== parse(b).root ? null - : [...commonArrayMembers(norm(a).split(sep), norm(b).split(sep))].join(sep) - -module.exports = (...paths) => paths.reduce(commonAncestorPath) diff --git a/node_modules/common-ancestor-path/package.json b/node_modules/common-ancestor-path/package.json index 4375d1d0818ac..c98b78300d143 100644 --- a/node_modules/common-ancestor-path/package.json +++ b/node_modules/common-ancestor-path/package.json @@ -1,28 +1,60 @@ { "name": "common-ancestor-path", - "version": "1.0.1", + "version": "2.0.0", "files": [ - "index.js" + "dist" ], "description": "Find the common ancestor of 2 or more paths on Windows or Unix", "repository": { "type": "git", - "url": "git+https://github.com/isaacs/common-ancestor-path" + "url": "git@github.com:isaacs/common-ancestor-path" }, "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", - "license": "ISC", + "license": "BlueOak-1.0.0", "scripts": { - "test": "tap", - "snap": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --log-level warn --cache", + "typedoc": "typedoc" }, "devDependencies": { + "@types/node": "^24.10.1", + "prettier": "^3.6.2", "require-inject": "^1.4.4", - "tap": "^14.10.7" + "tap": "^21.1.6", + "tshy": "^3.1.0", + "typedoc": "^0.28.14" + }, + "type": "module", + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js", + "engines": { + "node": ">= 18" } } diff --git a/node_modules/concat-map/LICENSE b/node_modules/concat-map/LICENSE deleted file mode 100644 index ee27ba4b4412b..0000000000000 --- a/node_modules/concat-map/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -This software is released under the MIT license: - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/concat-map/example/map.js b/node_modules/concat-map/example/map.js deleted file mode 100644 index 33656217b61d8..0000000000000 --- a/node_modules/concat-map/example/map.js +++ /dev/null @@ -1,6 +0,0 @@ -var concatMap = require('../'); -var xs = [ 1, 2, 3, 4, 5, 6 ]; -var ys = concatMap(xs, function (x) { - return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; -}); -console.dir(ys); diff --git a/node_modules/concat-map/index.js b/node_modules/concat-map/index.js deleted file mode 100644 index b29a7812e5055..0000000000000 --- a/node_modules/concat-map/index.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; diff --git a/node_modules/concat-map/package.json b/node_modules/concat-map/package.json deleted file mode 100644 index d3640e6b027b9..0000000000000 --- a/node_modules/concat-map/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name" : "concat-map", - "description" : "concatenative mapdashery", - "version" : "0.0.1", - "repository" : { - "type" : "git", - "url" : "git://github.com/substack/node-concat-map.git" - }, - "main" : "index.js", - "keywords" : [ - "concat", - "concatMap", - "map", - "functional", - "higher-order" - ], - "directories" : { - "example" : "example", - "test" : "test" - }, - "scripts" : { - "test" : "tape test/*.js" - }, - "devDependencies" : { - "tape" : "~2.4.0" - }, - "license" : "MIT", - "author" : { - "name" : "James Halliday", - "email" : "mail@substack.net", - "url" : "http://substack.net" - }, - "testling" : { - "files" : "test/*.js", - "browsers" : { - "ie" : [ 6, 7, 8, 9 ], - "ff" : [ 3.5, 10, 15.0 ], - "chrome" : [ 10, 22 ], - "safari" : [ 5.1 ], - "opera" : [ 12 ] - } - } -} diff --git a/node_modules/concat-map/test/map.js b/node_modules/concat-map/test/map.js deleted file mode 100644 index fdbd7022f6da1..0000000000000 --- a/node_modules/concat-map/test/map.js +++ /dev/null @@ -1,39 +0,0 @@ -var concatMap = require('../'); -var test = require('tape'); - -test('empty or not', function (t) { - var xs = [ 1, 2, 3, 4, 5, 6 ]; - var ixes = []; - var ys = concatMap(xs, function (x, ix) { - ixes.push(ix); - return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; - }); - t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); - t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); - t.end(); -}); - -test('always something', function (t) { - var xs = [ 'a', 'b', 'c', 'd' ]; - var ys = concatMap(xs, function (x) { - return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; - }); - t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); - t.end(); -}); - -test('scalars', function (t) { - var xs = [ 'a', 'b', 'c', 'd' ]; - var ys = concatMap(xs, function (x) { - return x === 'b' ? [ 'B', 'B', 'B' ] : x; - }); - t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); - t.end(); -}); - -test('undefs', function (t) { - var xs = [ 'a', 'b', 'c', 'd' ]; - var ys = concatMap(xs, function () {}); - t.same(ys, [ undefined, undefined, undefined, undefined ]); - t.end(); -}); diff --git a/node_modules/console-control-strings/LICENSE b/node_modules/console-control-strings/LICENSE deleted file mode 100644 index e756052969b78..0000000000000 --- a/node_modules/console-control-strings/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2014, Rebecca Turner <me@re-becca.org> - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/console-control-strings/index.js b/node_modules/console-control-strings/index.js deleted file mode 100644 index bf890348ec6e3..0000000000000 --- a/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/node_modules/console-control-strings/package.json b/node_modules/console-control-strings/package.json deleted file mode 100644 index eb6c62ae2dac7..0000000000000 --- a/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 <me@re-becca.org> (http://re-becca.org/)", - "license": "ISC", - "files": [ - "LICENSE", - "index.js" - ], - "devDependencies": { - "standard": "^7.1.2", - "tap": "^5.7.2" - } -} diff --git a/node_modules/debug/node_modules/ms/index.js b/node_modules/debug/node_modules/ms/index.js deleted file mode 100644 index c4498bcc21258..0000000000000 --- a/node_modules/debug/node_modules/ms/index.js +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var w = d * 7; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ - -module.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isFinite(val)) { - return options.long ? fmtLong(val) : fmtShort(val); - } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'weeks': - case 'week': - case 'w': - return n * w; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtShort(ms) { - var msAbs = Math.abs(ms); - if (msAbs >= d) { - return Math.round(ms / d) + 'd'; - } - if (msAbs >= h) { - return Math.round(ms / h) + 'h'; - } - if (msAbs >= m) { - return Math.round(ms / m) + 'm'; - } - if (msAbs >= s) { - return Math.round(ms / s) + 's'; - } - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtLong(ms) { - var msAbs = Math.abs(ms); - if (msAbs >= d) { - return plural(ms, msAbs, d, 'day'); - } - if (msAbs >= h) { - return plural(ms, msAbs, h, 'hour'); - } - if (msAbs >= m) { - return plural(ms, msAbs, m, 'minute'); - } - if (msAbs >= s) { - return plural(ms, msAbs, s, 'second'); - } - return ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural(ms, msAbs, n, name) { - var isPlural = msAbs >= n * 1.5; - return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); -} diff --git a/node_modules/debug/node_modules/ms/license.md b/node_modules/debug/node_modules/ms/license.md deleted file mode 100644 index 69b61253a3892..0000000000000 --- a/node_modules/debug/node_modules/ms/license.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Zeit, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/debug/node_modules/ms/package.json b/node_modules/debug/node_modules/ms/package.json deleted file mode 100644 index eea666e1fb03d..0000000000000 --- a/node_modules/debug/node_modules/ms/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "ms", - "version": "2.1.2", - "description": "Tiny millisecond conversion utility", - "repository": "zeit/ms", - "main": "./index", - "files": [ - "index.js" - ], - "scripts": { - "precommit": "lint-staged", - "lint": "eslint lib/* bin/*", - "test": "mocha tests.js" - }, - "eslintConfig": { - "extends": "eslint:recommended", - "env": { - "node": true, - "es6": true - } - }, - "lint-staged": { - "*.js": [ - "npm run lint", - "prettier --single-quote --write", - "git add" - ] - }, - "license": "MIT", - "devDependencies": { - "eslint": "4.12.1", - "expect.js": "0.3.1", - "husky": "0.14.3", - "lint-staged": "5.0.0", - "mocha": "4.0.1" - } -} diff --git a/node_modules/debug/node_modules/ms/readme.md b/node_modules/debug/node_modules/ms/readme.md deleted file mode 100644 index 9a1996b17e0de..0000000000000 --- a/node_modules/debug/node_modules/ms/readme.md +++ /dev/null @@ -1,60 +0,0 @@ -# ms - -[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms) -[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/zeit) - -Use this package to easily convert various time formats to milliseconds. - -## Examples - -```js -ms('2 days') // 172800000 -ms('1d') // 86400000 -ms('10h') // 36000000 -ms('2.5 hrs') // 9000000 -ms('2h') // 7200000 -ms('1m') // 60000 -ms('5s') // 5000 -ms('1y') // 31557600000 -ms('100') // 100 -ms('-3 days') // -259200000 -ms('-1h') // -3600000 -ms('-200') // -200 -``` - -### Convert from Milliseconds - -```js -ms(60000) // "1m" -ms(2 * 60000) // "2m" -ms(-3 * 60000) // "-3m" -ms(ms('10 hours')) // "10h" -``` - -### Time Format Written-Out - -```js -ms(60000, { long: true }) // "1 minute" -ms(2 * 60000, { long: true }) // "2 minutes" -ms(-3 * 60000, { long: true }) // "-3 minutes" -ms(ms('10 hours'), { long: true }) // "10 hours" -``` - -## Features - -- Works both in [Node.js](https://nodejs.org) and in the browser -- If a number is supplied to `ms`, a string with a unit is returned -- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`) -- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned - -## Related Packages - -- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time. - -## Caught a Bug? - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device -2. Link the package to the global module directory: `npm link` -3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms! - -As always, you can run the tests using: `npm test` diff --git a/node_modules/debug/package.json b/node_modules/debug/package.json index 3bcdc242fc067..ee8abb523dbe0 100644 --- a/node_modules/debug/package.json +++ b/node_modules/debug/package.json @@ -1,6 +1,6 @@ { "name": "debug", - "version": "4.3.4", + "version": "4.4.3", "repository": { "type": "git", "url": "git://github.com/debug-js/debug.git" @@ -16,7 +16,7 @@ "LICENSE", "README.md" ], - "author": "Josh Junon <josh.junon@protonmail.com>", + "author": "Josh Junon (https://github.com/qix-)", "contributors": [ "TJ Holowaychuk <tj@vision-media.ca>", "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)", @@ -26,24 +26,24 @@ "scripts": { "lint": "xo", "test": "npm run test:node && npm run test:browser && npm run lint", - "test:node": "istanbul cover _mocha -- test.js", + "test:node": "mocha test.js test.node.js", "test:browser": "karma start --single-run", "test:coverage": "cat ./coverage/lcov.info | coveralls" }, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "devDependencies": { "brfs": "^2.0.1", "browserify": "^16.2.3", "coveralls": "^3.0.2", - "istanbul": "^0.4.5", "karma": "^3.1.4", "karma-browserify": "^6.0.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", "mocha": "^5.2.0", "mocha-lcov-reporter": "^1.2.0", + "sinon": "^14.0.0", "xo": "^0.23.0" }, "peerDependenciesMeta": { @@ -55,5 +55,10 @@ "browser": "./src/browser.js", "engines": { "node": ">=6.0" + }, + "xo": { + "rules": { + "import/extensions": "off" + } } } diff --git a/node_modules/debug/src/browser.js b/node_modules/debug/src/browser.js index cd0fc35d1ee11..5993451b82e6b 100644 --- a/node_modules/debug/src/browser.js +++ b/node_modules/debug/src/browser.js @@ -125,14 +125,17 @@ function useColors() { return false; } + let m; + // Is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + // eslint-disable-next-line no-return-assign return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || // Is firebug? http://stackoverflow.com/a/398120/376773 (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || // Is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) || // Double check webkit in userAgent just in case we are in a worker (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } @@ -216,7 +219,7 @@ function save(namespaces) { function load() { let r; try { - r = exports.storage.getItem('debug'); + r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ; } catch (error) { // Swallow // XXX (@Qix-) should we be logging these? diff --git a/node_modules/debug/src/common.js b/node_modules/debug/src/common.js index e3291b20faa1a..141cb578b7722 100644 --- a/node_modules/debug/src/common.js +++ b/node_modules/debug/src/common.js @@ -166,24 +166,62 @@ function setup(env) { createDebug.names = []; createDebug.skips = []; - let i; - const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - const len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) { - // ignore empty strings - continue; + const split = (typeof namespaces === 'string' ? namespaces : '') + .trim() + .replace(/\s+/g, ',') + .split(',') + .filter(Boolean); + + for (const ns of split) { + if (ns[0] === '-') { + createDebug.skips.push(ns.slice(1)); + } else { + createDebug.names.push(ns); } + } + } - namespaces = split[i].replace(/\*/g, '.*?'); - - if (namespaces[0] === '-') { - createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$')); + /** + * Checks if the given string matches a namespace template, honoring + * asterisks as wildcards. + * + * @param {String} search + * @param {String} template + * @return {Boolean} + */ + function matchesTemplate(search, template) { + let searchIndex = 0; + let templateIndex = 0; + let starIndex = -1; + let matchIndex = 0; + + while (searchIndex < search.length) { + if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { + // Match character or proceed with wildcard + if (template[templateIndex] === '*') { + starIndex = templateIndex; + matchIndex = searchIndex; + templateIndex++; // Skip the '*' + } else { + searchIndex++; + templateIndex++; + } + } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition + // Backtrack to the last '*' and try to match more characters + templateIndex = starIndex + 1; + matchIndex++; + searchIndex = matchIndex; } else { - createDebug.names.push(new RegExp('^' + namespaces + '$')); + return false; // No match } } + + // Handle trailing '*' in template + while (templateIndex < template.length && template[templateIndex] === '*') { + templateIndex++; + } + + return templateIndex === template.length; } /** @@ -194,8 +232,8 @@ function setup(env) { */ function disable() { const namespaces = [ - ...createDebug.names.map(toNamespace), - ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) + ...createDebug.names, + ...createDebug.skips.map(namespace => '-' + namespace) ].join(','); createDebug.enable(''); return namespaces; @@ -209,21 +247,14 @@ function setup(env) { * @api public */ function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - - let i; - let len; - - for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name)) { + for (const skip of createDebug.skips) { + if (matchesTemplate(name, skip)) { return false; } } - for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name)) { + for (const ns of createDebug.names) { + if (matchesTemplate(name, ns)) { return true; } } @@ -231,19 +262,6 @@ function setup(env) { return false; } - /** - * Convert regexp to namespace - * - * @param {RegExp} regxep - * @return {String} namespace - * @api private - */ - function toNamespace(regexp) { - return regexp.toString() - .substring(2, regexp.toString().length - 2) - .replace(/\.\*\?$/, '*'); - } - /** * Coerce `val`. * diff --git a/node_modules/debug/src/node.js b/node_modules/debug/src/node.js index 79bc085cb0230..715560a4ca8fb 100644 --- a/node_modules/debug/src/node.js +++ b/node_modules/debug/src/node.js @@ -187,11 +187,11 @@ function getDate() { } /** - * Invokes `util.format()` with the specified arguments and writes to stderr. + * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr. */ function log(...args) { - return process.stderr.write(util.format(...args) + '\n'); + return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n'); } /** diff --git a/node_modules/debuglog/LICENSE b/node_modules/debuglog/LICENSE deleted file mode 100644 index a3187cc10022f..0000000000000 --- a/node_modules/debuglog/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright Joyent, Inc. and other Node contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/node_modules/debuglog/debuglog.js b/node_modules/debuglog/debuglog.js deleted file mode 100644 index 748fd72a1a68f..0000000000000 --- a/node_modules/debuglog/debuglog.js +++ /dev/null @@ -1,22 +0,0 @@ -var util = require('util'); - -module.exports = (util && util.debuglog) || debuglog; - -var debugs = {}; -var debugEnviron = process.env.NODE_DEBUG || ''; - -function debuglog(set) { - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = util.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; diff --git a/node_modules/debuglog/package.json b/node_modules/debuglog/package.json deleted file mode 100644 index e51ecc95f11b5..0000000000000 --- a/node_modules/debuglog/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "debuglog", - "version": "1.0.1", - "description": "backport of util.debuglog from node v0.11", - "license": "MIT", - "main": "debuglog.js", - "repository": { - "type": "git", - "url": "https://github.com/sam-github/node-debuglog.git" - }, - "author": { - "name": "Sam Roberts", - "email": "sam@strongloop.com" - }, - "engines": { - "node": "*" - }, - "browser": { - "util": false - } -} diff --git a/node_modules/defaults/LICENSE b/node_modules/defaults/LICENSE deleted file mode 100644 index d88b072078480..0000000000000 --- a/node_modules/defaults/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -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/node_modules/defaults/index.js b/node_modules/defaults/index.js deleted file mode 100644 index cb7d75c9c6beb..0000000000000 --- a/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/node_modules/defaults/package.json b/node_modules/defaults/package.json deleted file mode 100644 index 854016d56fefd..0000000000000 --- a/node_modules/defaults/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "defaults", - "version": "1.0.3", - "description": "merge single level defaults over a config object", - "main": "index.js", - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/tmpvar/defaults.git" - }, - "keywords": [ - "config", - "defaults" - ], - "author": "Elijah Insua <tmpvar@gmail.com>", - "license": "MIT", - "readmeFilename": "README.md", - "dependencies": { - "clone": "^1.0.2" - }, - "devDependencies": { - "tap": "^2.0.0" - } -} diff --git a/node_modules/defaults/test.js b/node_modules/defaults/test.js deleted file mode 100644 index 60e0ffba8b4aa..0000000000000 --- a/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/node_modules/delegates/History.md b/node_modules/delegates/History.md deleted file mode 100644 index 25959eab67b84..0000000000000 --- a/node_modules/delegates/History.md +++ /dev/null @@ -1,22 +0,0 @@ - -1.0.0 / 2015-12-14 -================== - - * Merge pull request #12 from kasicka/master - * Add license text - -0.1.0 / 2014-10-17 -================== - - * adds `.fluent()` to api - -0.0.3 / 2014-01-13 -================== - - * fix receiver for .method() - -0.0.2 / 2014-01-13 -================== - - * Object.defineProperty() sucks - * Initial commit diff --git a/node_modules/delegates/License b/node_modules/delegates/License deleted file mode 100644 index 60de60addbe7e..0000000000000 --- a/node_modules/delegates/License +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2015 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/delegates/Makefile b/node_modules/delegates/Makefile deleted file mode 100644 index a9dcfd50dbdb2..0000000000000 --- a/node_modules/delegates/Makefile +++ /dev/null @@ -1,8 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec \ - --bail - -.PHONY: test \ No newline at end of file diff --git a/node_modules/delegates/Readme.md b/node_modules/delegates/Readme.md deleted file mode 100644 index ab8cf4ace1593..0000000000000 --- a/node_modules/delegates/Readme.md +++ /dev/null @@ -1,94 +0,0 @@ - -# delegates - - Node method and accessor delegation utilty. - -## Installation - -``` -$ npm install delegates -``` - -## Example - -```js -var delegate = require('delegates'); - -... - -delegate(proto, 'request') - .method('acceptsLanguages') - .method('acceptsEncodings') - .method('acceptsCharsets') - .method('accepts') - .method('is') - .access('querystring') - .access('idempotent') - .access('socket') - .access('length') - .access('query') - .access('search') - .access('status') - .access('method') - .access('path') - .access('body') - .access('host') - .access('url') - .getter('subdomains') - .getter('protocol') - .getter('header') - .getter('stale') - .getter('fresh') - .getter('secure') - .getter('ips') - .getter('ip') -``` - -# API - -## Delegate(proto, prop) - -Creates a delegator instance used to configure using the `prop` on the given -`proto` object. (which is usually a prototype) - -## Delegate#method(name) - -Allows the given method `name` to be accessed on the host. - -## Delegate#getter(name) - -Creates a "getter" for the property with the given `name` on the delegated -object. - -## Delegate#setter(name) - -Creates a "setter" for the property with the given `name` on the delegated -object. - -## Delegate#access(name) - -Creates an "accessor" (ie: both getter *and* setter) for the property with the -given `name` on the delegated object. - -## Delegate#fluent(name) - -A unique type of "accessor" that works for a "fluent" API. When called as a -getter, the method returns the expected value. However, if the method is called -with a value, it will return itself so it can be chained. For example: - -```js -delegate(proto, 'request') - .fluent('query') - -// getter -var q = request.query(); - -// setter (chainable) -request - .query({ a: 1 }) - .query({ b: 2 }); -``` - -# License - - MIT diff --git a/node_modules/delegates/index.js b/node_modules/delegates/index.js deleted file mode 100644 index 17c222d52935c..0000000000000 --- a/node_modules/delegates/index.js +++ /dev/null @@ -1,121 +0,0 @@ - -/** - * Expose `Delegator`. - */ - -module.exports = Delegator; - -/** - * Initialize a delegator. - * - * @param {Object} proto - * @param {String} target - * @api public - */ - -function Delegator(proto, target) { - if (!(this instanceof Delegator)) return new Delegator(proto, target); - this.proto = proto; - this.target = target; - this.methods = []; - this.getters = []; - this.setters = []; - this.fluents = []; -} - -/** - * Delegate method `name`. - * - * @param {String} name - * @return {Delegator} self - * @api public - */ - -Delegator.prototype.method = function(name){ - var proto = this.proto; - var target = this.target; - this.methods.push(name); - - proto[name] = function(){ - return this[target][name].apply(this[target], arguments); - }; - - return this; -}; - -/** - * Delegator accessor `name`. - * - * @param {String} name - * @return {Delegator} self - * @api public - */ - -Delegator.prototype.access = function(name){ - return this.getter(name).setter(name); -}; - -/** - * Delegator getter `name`. - * - * @param {String} name - * @return {Delegator} self - * @api public - */ - -Delegator.prototype.getter = function(name){ - var proto = this.proto; - var target = this.target; - this.getters.push(name); - - proto.__defineGetter__(name, function(){ - return this[target][name]; - }); - - return this; -}; - -/** - * Delegator setter `name`. - * - * @param {String} name - * @return {Delegator} self - * @api public - */ - -Delegator.prototype.setter = function(name){ - var proto = this.proto; - var target = this.target; - this.setters.push(name); - - proto.__defineSetter__(name, function(val){ - return this[target][name] = val; - }); - - return this; -}; - -/** - * Delegator fluent accessor - * - * @param {String} name - * @return {Delegator} self - * @api public - */ - -Delegator.prototype.fluent = function (name) { - var proto = this.proto; - var target = this.target; - this.fluents.push(name); - - proto[name] = function(val){ - if ('undefined' != typeof val) { - this[target][name] = val; - return this; - } else { - return this[target][name]; - } - }; - - return this; -}; diff --git a/node_modules/delegates/package.json b/node_modules/delegates/package.json deleted file mode 100644 index 17240384fd43b..0000000000000 --- a/node_modules/delegates/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "delegates", - "version": "1.0.0", - "repository": "visionmedia/node-delegates", - "description": "delegate methods and accessors to another property", - "keywords": ["delegate", "delegation"], - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "license": "MIT" -} diff --git a/node_modules/delegates/test/index.js b/node_modules/delegates/test/index.js deleted file mode 100644 index 7b6e3d4df19d9..0000000000000 --- a/node_modules/delegates/test/index.js +++ /dev/null @@ -1,94 +0,0 @@ - -var assert = require('assert'); -var delegate = require('..'); - -describe('.method(name)', function(){ - it('should delegate methods', function(){ - var obj = {}; - - obj.request = { - foo: function(bar){ - assert(this == obj.request); - return bar; - } - }; - - delegate(obj, 'request').method('foo'); - - obj.foo('something').should.equal('something'); - }) -}) - -describe('.getter(name)', function(){ - it('should delegate getters', function(){ - var obj = {}; - - obj.request = { - get type() { - return 'text/html'; - } - } - - delegate(obj, 'request').getter('type'); - - obj.type.should.equal('text/html'); - }) -}) - -describe('.setter(name)', function(){ - it('should delegate setters', function(){ - var obj = {}; - - obj.request = { - get type() { - return this._type.toUpperCase(); - }, - - set type(val) { - this._type = val; - } - } - - delegate(obj, 'request').setter('type'); - - obj.type = 'hey'; - obj.request.type.should.equal('HEY'); - }) -}) - -describe('.access(name)', function(){ - it('should delegate getters and setters', function(){ - var obj = {}; - - obj.request = { - get type() { - return this._type.toUpperCase(); - }, - - set type(val) { - this._type = val; - } - } - - delegate(obj, 'request').access('type'); - - obj.type = 'hey'; - obj.type.should.equal('HEY'); - }) -}) - -describe('.fluent(name)', function () { - it('should delegate in a fluent fashion', function () { - var obj = { - settings: { - env: 'development' - } - }; - - delegate(obj, 'settings').fluent('env'); - - obj.env().should.equal('development'); - obj.env('production').should.equal(obj); - obj.settings.env.should.equal('production'); - }) -}) diff --git a/node_modules/depd/History.md b/node_modules/depd/History.md deleted file mode 100644 index 507ecb8de21d5..0000000000000 --- a/node_modules/depd/History.md +++ /dev/null @@ -1,96 +0,0 @@ -1.1.2 / 2018-01-11 -================== - - * perf: remove argument reassignment - * Support Node.js 0.6 to 9.x - -1.1.1 / 2017-07-27 -================== - - * Remove unnecessary `Buffer` loading - * Support Node.js 0.6 to 8.x - -1.1.0 / 2015-09-14 -================== - - * Enable strict mode in more places - * Support io.js 3.x - * Support io.js 2.x - * Support web browser loading - - Requires bundler like Browserify or webpack - -1.0.1 / 2015-04-07 -================== - - * Fix `TypeError`s when under `'use strict'` code - * Fix useless type name on auto-generated messages - * Support io.js 1.x - * Support Node.js 0.12 - -1.0.0 / 2014-09-17 -================== - - * No changes - -0.4.5 / 2014-09-09 -================== - - * Improve call speed to functions using the function wrapper - * Support Node.js 0.6 - -0.4.4 / 2014-07-27 -================== - - * Work-around v8 generating empty stack traces - -0.4.3 / 2014-07-26 -================== - - * Fix exception when global `Error.stackTraceLimit` is too low - -0.4.2 / 2014-07-19 -================== - - * Correct call site for wrapped functions and properties - -0.4.1 / 2014-07-19 -================== - - * Improve automatic message generation for function properties - -0.4.0 / 2014-07-19 -================== - - * Add `TRACE_DEPRECATION` environment variable - * Remove non-standard grey color from color output - * Support `--no-deprecation` argument - * Support `--trace-deprecation` argument - * Support `deprecate.property(fn, prop, message)` - -0.3.0 / 2014-06-16 -================== - - * Add `NO_DEPRECATION` environment variable - -0.2.0 / 2014-06-15 -================== - - * Add `deprecate.property(obj, prop, message)` - * Remove `supports-color` dependency for node.js 0.8 - -0.1.0 / 2014-06-15 -================== - - * Add `deprecate.function(fn, message)` - * Add `process.on('deprecation', fn)` emitter - * Automatically generate message when omitted from `deprecate()` - -0.0.1 / 2014-06-15 -================== - - * Fix warning for dynamic calls at singe call site - -0.0.0 / 2014-06-15 -================== - - * Initial implementation diff --git a/node_modules/depd/LICENSE b/node_modules/depd/LICENSE deleted file mode 100644 index 84441fbb57092..0000000000000 --- a/node_modules/depd/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2014-2017 Douglas Christopher Wilson - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/depd/Readme.md b/node_modules/depd/Readme.md deleted file mode 100644 index 77906702044fe..0000000000000 --- a/node_modules/depd/Readme.md +++ /dev/null @@ -1,280 +0,0 @@ -# depd - -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][npm-url] -[![Node.js Version][node-image]][node-url] -[![Linux Build][travis-image]][travis-url] -[![Windows Build][appveyor-image]][appveyor-url] -[![Coverage Status][coveralls-image]][coveralls-url] - -Deprecate all the things - -> With great modules comes great responsibility; mark things deprecated! - -## Install - -This module is installed directly using `npm`: - -```sh -$ npm install depd -``` - -This module can also be bundled with systems like -[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/), -though by default this module will alter it's API to no longer display or -track deprecations. - -## API - -<!-- eslint-disable no-unused-vars --> - -```js -var deprecate = require('depd')('my-module') -``` - -This library allows you to display deprecation messages to your users. -This library goes above and beyond with deprecation warnings by -introspection of the call stack (but only the bits that it is interested -in). - -Instead of just warning on the first invocation of a deprecated -function and never again, this module will warn on the first invocation -of a deprecated function per unique call site, making it ideal to alert -users of all deprecated uses across the code base, rather than just -whatever happens to execute first. - -The deprecation warnings from this module also include the file and line -information for the call into the module that the deprecated function was -in. - -**NOTE** this library has a similar interface to the `debug` module, and -this module uses the calling file to get the boundary for the call stacks, -so you should always create a new `deprecate` object in each file and not -within some central file. - -### depd(namespace) - -Create a new deprecate function that uses the given namespace name in the -messages and will display the call site prior to the stack entering the -file this function was called from. It is highly suggested you use the -name of your module as the namespace. - -### deprecate(message) - -Call this function from deprecated code to display a deprecation message. -This message will appear once per unique caller site. Caller site is the -first call site in the stack in a different file from the caller of this -function. - -If the message is omitted, a message is generated for you based on the site -of the `deprecate()` call and will display the name of the function called, -similar to the name displayed in a stack trace. - -### deprecate.function(fn, message) - -Call this function to wrap a given function in a deprecation message on any -call to the function. An optional message can be supplied to provide a custom -message. - -### deprecate.property(obj, prop, message) - -Call this function to wrap a given property on object in a deprecation message -on any accessing or setting of the property. An optional message can be supplied -to provide a custom message. - -The method must be called on the object where the property belongs (not -inherited from the prototype). - -If the property is a data descriptor, it will be converted to an accessor -descriptor in order to display the deprecation message. - -### process.on('deprecation', fn) - -This module will allow easy capturing of deprecation errors by emitting the -errors as the type "deprecation" on the global `process`. If there are no -listeners for this type, the errors are written to STDERR as normal, but if -there are any listeners, nothing will be written to STDERR and instead only -emitted. From there, you can write the errors in a different format or to a -logging source. - -The error represents the deprecation and is emitted only once with the same -rules as writing to STDERR. The error has the following properties: - - - `message` - This is the message given by the library - - `name` - This is always `'DeprecationError'` - - `namespace` - This is the namespace the deprecation came from - - `stack` - This is the stack of the call to the deprecated thing - -Example `error.stack` output: - -``` -DeprecationError: my-cool-module deprecated oldfunction - at Object.<anonymous> ([eval]-wrapper:6:22) - at Module._compile (module.js:456:26) - at evalScript (node.js:532:25) - at startup (node.js:80:7) - at node.js:902:3 -``` - -### process.env.NO_DEPRECATION - -As a user of modules that are deprecated, the environment variable `NO_DEPRECATION` -is provided as a quick solution to silencing deprecation warnings from being -output. The format of this is similar to that of `DEBUG`: - -```sh -$ NO_DEPRECATION=my-module,othermod node app.js -``` - -This will suppress deprecations from being output for "my-module" and "othermod". -The value is a list of comma-separated namespaces. To suppress every warning -across all namespaces, use the value `*` for a namespace. - -Providing the argument `--no-deprecation` to the `node` executable will suppress -all deprecations (only available in Node.js 0.8 or higher). - -**NOTE** This will not suppress the deperecations given to any "deprecation" -event listeners, just the output to STDERR. - -### process.env.TRACE_DEPRECATION - -As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION` -is provided as a solution to getting more detailed location information in deprecation -warnings by including the entire stack trace. The format of this is the same as -`NO_DEPRECATION`: - -```sh -$ TRACE_DEPRECATION=my-module,othermod node app.js -``` - -This will include stack traces for deprecations being output for "my-module" and -"othermod". The value is a list of comma-separated namespaces. To trace every -warning across all namespaces, use the value `*` for a namespace. - -Providing the argument `--trace-deprecation` to the `node` executable will trace -all deprecations (only available in Node.js 0.8 or higher). - -**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`. - -## Display - -![message](files/message.png) - -When a user calls a function in your library that you mark deprecated, they -will see the following written to STDERR (in the given colors, similar colors -and layout to the `debug` module): - -``` -bright cyan bright yellow -| | reset cyan -| | | | -▼ ▼ ▼ ▼ -my-cool-module deprecated oldfunction [eval]-wrapper:6:22 -▲ ▲ ▲ ▲ -| | | | -namespace | | location of mycoolmod.oldfunction() call - | deprecation message - the word "deprecated" -``` - -If the user redirects their STDERR to a file or somewhere that does not support -colors, they see (similar layout to the `debug` module): - -``` -Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22 -▲ ▲ ▲ ▲ ▲ -| | | | | -timestamp of message namespace | | location of mycoolmod.oldfunction() call - | deprecation message - the word "deprecated" -``` - -## Examples - -### Deprecating all calls to a function - -This will display a deprecated message about "oldfunction" being deprecated -from "my-module" on STDERR. - -```js -var deprecate = require('depd')('my-cool-module') - -// message automatically derived from function name -// Object.oldfunction -exports.oldfunction = deprecate.function(function oldfunction () { - // all calls to function are deprecated -}) - -// specific message -exports.oldfunction = deprecate.function(function () { - // all calls to function are deprecated -}, 'oldfunction') -``` - -### Conditionally deprecating a function call - -This will display a deprecated message about "weirdfunction" being deprecated -from "my-module" on STDERR when called with less than 2 arguments. - -```js -var deprecate = require('depd')('my-cool-module') - -exports.weirdfunction = function () { - if (arguments.length < 2) { - // calls with 0 or 1 args are deprecated - deprecate('weirdfunction args < 2') - } -} -``` - -When calling `deprecate` as a function, the warning is counted per call site -within your own module, so you can display different deprecations depending -on different situations and the users will still get all the warnings: - -```js -var deprecate = require('depd')('my-cool-module') - -exports.weirdfunction = function () { - if (arguments.length < 2) { - // calls with 0 or 1 args are deprecated - deprecate('weirdfunction args < 2') - } else if (typeof arguments[0] !== 'string') { - // calls with non-string first argument are deprecated - deprecate('weirdfunction non-string first arg') - } -} -``` - -### Deprecating property access - -This will display a deprecated message about "oldprop" being deprecated -from "my-module" on STDERR when accessed. A deprecation will be displayed -when setting the value and when getting the value. - -```js -var deprecate = require('depd')('my-cool-module') - -exports.oldprop = 'something' - -// message automatically derives from property name -deprecate.property(exports, 'oldprop') - -// explicit message -deprecate.property(exports, 'oldprop', 'oldprop >= 0.10') -``` - -## License - -[MIT](LICENSE) - -[npm-version-image]: https://img.shields.io/npm/v/depd.svg -[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg -[npm-url]: https://npmjs.org/package/depd -[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd/master.svg?label=linux -[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd -[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/nodejs-depd/master.svg?label=windows -[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd -[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg -[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master -[node-image]: https://img.shields.io/node/v/depd.svg -[node-url]: https://nodejs.org/en/download/ diff --git a/node_modules/depd/index.js b/node_modules/depd/index.js deleted file mode 100644 index d758d3c8f58a6..0000000000000 --- a/node_modules/depd/index.js +++ /dev/null @@ -1,522 +0,0 @@ -/*! - * depd - * Copyright(c) 2014-2017 Douglas Christopher Wilson - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var callSiteToString = require('./lib/compat').callSiteToString -var eventListenerCount = require('./lib/compat').eventListenerCount -var relative = require('path').relative - -/** - * Module exports. - */ - -module.exports = depd - -/** - * Get the path to base files on. - */ - -var basePath = process.cwd() - -/** - * Determine if namespace is contained in the string. - */ - -function containsNamespace (str, namespace) { - var vals = str.split(/[ ,]+/) - var ns = String(namespace).toLowerCase() - - for (var i = 0; i < vals.length; i++) { - var val = vals[i] - - // namespace contained - if (val && (val === '*' || val.toLowerCase() === ns)) { - return true - } - } - - return false -} - -/** - * Convert a data descriptor to accessor descriptor. - */ - -function convertDataDescriptorToAccessor (obj, prop, message) { - var descriptor = Object.getOwnPropertyDescriptor(obj, prop) - var value = descriptor.value - - descriptor.get = function getter () { return value } - - if (descriptor.writable) { - descriptor.set = function setter (val) { return (value = val) } - } - - delete descriptor.value - delete descriptor.writable - - Object.defineProperty(obj, prop, descriptor) - - return descriptor -} - -/** - * Create arguments string to keep arity. - */ - -function createArgumentsString (arity) { - var str = '' - - for (var i = 0; i < arity; i++) { - str += ', arg' + i - } - - return str.substr(2) -} - -/** - * Create stack string from stack. - */ - -function createStackString (stack) { - var str = this.name + ': ' + this.namespace - - if (this.message) { - str += ' deprecated ' + this.message - } - - for (var i = 0; i < stack.length; i++) { - str += '\n at ' + callSiteToString(stack[i]) - } - - return str -} - -/** - * Create deprecate for namespace in caller. - */ - -function depd (namespace) { - if (!namespace) { - throw new TypeError('argument namespace is required') - } - - var stack = getStack() - var site = callSiteLocation(stack[1]) - var file = site[0] - - function deprecate (message) { - // call to self as log - log.call(deprecate, message) - } - - deprecate._file = file - deprecate._ignored = isignored(namespace) - deprecate._namespace = namespace - deprecate._traced = istraced(namespace) - deprecate._warned = Object.create(null) - - deprecate.function = wrapfunction - deprecate.property = wrapproperty - - return deprecate -} - -/** - * Determine if namespace is ignored. - */ - -function isignored (namespace) { - /* istanbul ignore next: tested in a child processs */ - if (process.noDeprecation) { - // --no-deprecation support - return true - } - - var str = process.env.NO_DEPRECATION || '' - - // namespace ignored - return containsNamespace(str, namespace) -} - -/** - * Determine if namespace is traced. - */ - -function istraced (namespace) { - /* istanbul ignore next: tested in a child processs */ - if (process.traceDeprecation) { - // --trace-deprecation support - return true - } - - var str = process.env.TRACE_DEPRECATION || '' - - // namespace traced - return containsNamespace(str, namespace) -} - -/** - * Display deprecation message. - */ - -function log (message, site) { - var haslisteners = eventListenerCount(process, 'deprecation') !== 0 - - // abort early if no destination - if (!haslisteners && this._ignored) { - return - } - - var caller - var callFile - var callSite - var depSite - var i = 0 - var seen = false - var stack = getStack() - var file = this._file - - if (site) { - // provided site - depSite = site - callSite = callSiteLocation(stack[1]) - callSite.name = depSite.name - file = callSite[0] - } else { - // get call site - i = 2 - depSite = callSiteLocation(stack[i]) - callSite = depSite - } - - // get caller of deprecated thing in relation to file - for (; i < stack.length; i++) { - caller = callSiteLocation(stack[i]) - callFile = caller[0] - - if (callFile === file) { - seen = true - } else if (callFile === this._file) { - file = this._file - } else if (seen) { - break - } - } - - var key = caller - ? depSite.join(':') + '__' + caller.join(':') - : undefined - - if (key !== undefined && key in this._warned) { - // already warned - return - } - - this._warned[key] = true - - // generate automatic message from call site - var msg = message - if (!msg) { - msg = callSite === depSite || !callSite.name - ? defaultMessage(depSite) - : defaultMessage(callSite) - } - - // emit deprecation if listeners exist - if (haslisteners) { - var err = DeprecationError(this._namespace, msg, stack.slice(i)) - process.emit('deprecation', err) - return - } - - // format and write message - var format = process.stderr.isTTY - ? formatColor - : formatPlain - var output = format.call(this, msg, caller, stack.slice(i)) - process.stderr.write(output + '\n', 'utf8') -} - -/** - * Get call site location as array. - */ - -function callSiteLocation (callSite) { - var file = callSite.getFileName() || '<anonymous>' - var line = callSite.getLineNumber() - var colm = callSite.getColumnNumber() - - if (callSite.isEval()) { - file = callSite.getEvalOrigin() + ', ' + file - } - - var site = [file, line, colm] - - site.callSite = callSite - site.name = callSite.getFunctionName() - - return site -} - -/** - * Generate a default message from the site. - */ - -function defaultMessage (site) { - var callSite = site.callSite - var funcName = site.name - - // make useful anonymous name - if (!funcName) { - funcName = '<anonymous@' + formatLocation(site) + '>' - } - - var context = callSite.getThis() - var typeName = context && callSite.getTypeName() - - // ignore useless type name - if (typeName === 'Object') { - typeName = undefined - } - - // make useful type name - if (typeName === 'Function') { - typeName = context.name || typeName - } - - return typeName && callSite.getMethodName() - ? typeName + '.' + funcName - : funcName -} - -/** - * Format deprecation message without color. - */ - -function formatPlain (msg, caller, stack) { - var timestamp = new Date().toUTCString() - - var formatted = timestamp + - ' ' + this._namespace + - ' deprecated ' + msg - - // add stack trace - if (this._traced) { - for (var i = 0; i < stack.length; i++) { - formatted += '\n at ' + callSiteToString(stack[i]) - } - - return formatted - } - - if (caller) { - formatted += ' at ' + formatLocation(caller) - } - - return formatted -} - -/** - * Format deprecation message with color. - */ - -function formatColor (msg, caller, stack) { - var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' + // bold cyan - ' \x1b[33;1mdeprecated\x1b[22;39m' + // bold yellow - ' \x1b[0m' + msg + '\x1b[39m' // reset - - // add stack trace - if (this._traced) { - for (var i = 0; i < stack.length; i++) { - formatted += '\n \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan - } - - return formatted - } - - if (caller) { - formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan - } - - return formatted -} - -/** - * Format call site location. - */ - -function formatLocation (callSite) { - return relative(basePath, callSite[0]) + - ':' + callSite[1] + - ':' + callSite[2] -} - -/** - * Get the stack as array of call sites. - */ - -function getStack () { - var limit = Error.stackTraceLimit - var obj = {} - var prep = Error.prepareStackTrace - - Error.prepareStackTrace = prepareObjectStackTrace - Error.stackTraceLimit = Math.max(10, limit) - - // capture the stack - Error.captureStackTrace(obj) - - // slice this function off the top - var stack = obj.stack.slice(1) - - Error.prepareStackTrace = prep - Error.stackTraceLimit = limit - - return stack -} - -/** - * Capture call site stack from v8. - */ - -function prepareObjectStackTrace (obj, stack) { - return stack -} - -/** - * Return a wrapped function in a deprecation message. - */ - -function wrapfunction (fn, message) { - if (typeof fn !== 'function') { - throw new TypeError('argument fn must be a function') - } - - var args = createArgumentsString(fn.length) - var deprecate = this // eslint-disable-line no-unused-vars - var stack = getStack() - var site = callSiteLocation(stack[1]) - - site.name = fn.name - - // eslint-disable-next-line no-eval - var deprecatedfn = eval('(function (' + args + ') {\n' + - '"use strict"\n' + - 'log.call(deprecate, message, site)\n' + - 'return fn.apply(this, arguments)\n' + - '})') - - return deprecatedfn -} - -/** - * Wrap property in a deprecation message. - */ - -function wrapproperty (obj, prop, message) { - if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { - throw new TypeError('argument obj must be object') - } - - var descriptor = Object.getOwnPropertyDescriptor(obj, prop) - - if (!descriptor) { - throw new TypeError('must call property on owner object') - } - - if (!descriptor.configurable) { - throw new TypeError('property must be configurable') - } - - var deprecate = this - var stack = getStack() - var site = callSiteLocation(stack[1]) - - // set site name - site.name = prop - - // convert data descriptor - if ('value' in descriptor) { - descriptor = convertDataDescriptorToAccessor(obj, prop, message) - } - - var get = descriptor.get - var set = descriptor.set - - // wrap getter - if (typeof get === 'function') { - descriptor.get = function getter () { - log.call(deprecate, message, site) - return get.apply(this, arguments) - } - } - - // wrap setter - if (typeof set === 'function') { - descriptor.set = function setter () { - log.call(deprecate, message, site) - return set.apply(this, arguments) - } - } - - Object.defineProperty(obj, prop, descriptor) -} - -/** - * Create DeprecationError for deprecation - */ - -function DeprecationError (namespace, message, stack) { - var error = new Error() - var stackString - - Object.defineProperty(error, 'constructor', { - value: DeprecationError - }) - - Object.defineProperty(error, 'message', { - configurable: true, - enumerable: false, - value: message, - writable: true - }) - - Object.defineProperty(error, 'name', { - enumerable: false, - configurable: true, - value: 'DeprecationError', - writable: true - }) - - Object.defineProperty(error, 'namespace', { - configurable: true, - enumerable: false, - value: namespace, - writable: true - }) - - Object.defineProperty(error, 'stack', { - configurable: true, - enumerable: false, - get: function () { - if (stackString !== undefined) { - return stackString - } - - // prepare stack trace - return (stackString = createStackString.call(this, stack)) - }, - set: function setter (val) { - stackString = val - } - }) - - return error -} diff --git a/node_modules/depd/lib/browser/index.js b/node_modules/depd/lib/browser/index.js deleted file mode 100644 index 6be45cc20b33f..0000000000000 --- a/node_modules/depd/lib/browser/index.js +++ /dev/null @@ -1,77 +0,0 @@ -/*! - * depd - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module exports. - * @public - */ - -module.exports = depd - -/** - * Create deprecate for namespace in caller. - */ - -function depd (namespace) { - if (!namespace) { - throw new TypeError('argument namespace is required') - } - - function deprecate (message) { - // no-op in browser - } - - deprecate._file = undefined - deprecate._ignored = true - deprecate._namespace = namespace - deprecate._traced = false - deprecate._warned = Object.create(null) - - deprecate.function = wrapfunction - deprecate.property = wrapproperty - - return deprecate -} - -/** - * Return a wrapped function in a deprecation message. - * - * This is a no-op version of the wrapper, which does nothing but call - * validation. - */ - -function wrapfunction (fn, message) { - if (typeof fn !== 'function') { - throw new TypeError('argument fn must be a function') - } - - return fn -} - -/** - * Wrap property in a deprecation message. - * - * This is a no-op version of the wrapper, which does nothing but call - * validation. - */ - -function wrapproperty (obj, prop, message) { - if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) { - throw new TypeError('argument obj must be object') - } - - var descriptor = Object.getOwnPropertyDescriptor(obj, prop) - - if (!descriptor) { - throw new TypeError('must call property on owner object') - } - - if (!descriptor.configurable) { - throw new TypeError('property must be configurable') - } -} diff --git a/node_modules/depd/lib/compat/callsite-tostring.js b/node_modules/depd/lib/compat/callsite-tostring.js deleted file mode 100644 index 73186dc644a36..0000000000000 --- a/node_modules/depd/lib/compat/callsite-tostring.js +++ /dev/null @@ -1,103 +0,0 @@ -/*! - * depd - * Copyright(c) 2014 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module exports. - */ - -module.exports = callSiteToString - -/** - * Format a CallSite file location to a string. - */ - -function callSiteFileLocation (callSite) { - var fileName - var fileLocation = '' - - if (callSite.isNative()) { - fileLocation = 'native' - } else if (callSite.isEval()) { - fileName = callSite.getScriptNameOrSourceURL() - if (!fileName) { - fileLocation = callSite.getEvalOrigin() - } - } else { - fileName = callSite.getFileName() - } - - if (fileName) { - fileLocation += fileName - - var lineNumber = callSite.getLineNumber() - if (lineNumber != null) { - fileLocation += ':' + lineNumber - - var columnNumber = callSite.getColumnNumber() - if (columnNumber) { - fileLocation += ':' + columnNumber - } - } - } - - return fileLocation || 'unknown source' -} - -/** - * Format a CallSite to a string. - */ - -function callSiteToString (callSite) { - var addSuffix = true - var fileLocation = callSiteFileLocation(callSite) - var functionName = callSite.getFunctionName() - var isConstructor = callSite.isConstructor() - var isMethodCall = !(callSite.isToplevel() || isConstructor) - var line = '' - - if (isMethodCall) { - var methodName = callSite.getMethodName() - var typeName = getConstructorName(callSite) - - if (functionName) { - if (typeName && functionName.indexOf(typeName) !== 0) { - line += typeName + '.' - } - - line += functionName - - if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) { - line += ' [as ' + methodName + ']' - } - } else { - line += typeName + '.' + (methodName || '<anonymous>') - } - } else if (isConstructor) { - line += 'new ' + (functionName || '<anonymous>') - } else if (functionName) { - line += functionName - } else { - addSuffix = false - line += fileLocation - } - - if (addSuffix) { - line += ' (' + fileLocation + ')' - } - - return line -} - -/** - * Get constructor name of reviver. - */ - -function getConstructorName (obj) { - var receiver = obj.receiver - return (receiver.constructor && receiver.constructor.name) || null -} diff --git a/node_modules/depd/lib/compat/event-listener-count.js b/node_modules/depd/lib/compat/event-listener-count.js deleted file mode 100644 index 3a8925d136ae6..0000000000000 --- a/node_modules/depd/lib/compat/event-listener-count.js +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * depd - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module exports. - * @public - */ - -module.exports = eventListenerCount - -/** - * Get the count of listeners on an event emitter of a specific type. - */ - -function eventListenerCount (emitter, type) { - return emitter.listeners(type).length -} diff --git a/node_modules/depd/lib/compat/index.js b/node_modules/depd/lib/compat/index.js deleted file mode 100644 index 955b3336b25e7..0000000000000 --- a/node_modules/depd/lib/compat/index.js +++ /dev/null @@ -1,79 +0,0 @@ -/*! - * depd - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var EventEmitter = require('events').EventEmitter - -/** - * Module exports. - * @public - */ - -lazyProperty(module.exports, 'callSiteToString', function callSiteToString () { - var limit = Error.stackTraceLimit - var obj = {} - var prep = Error.prepareStackTrace - - function prepareObjectStackTrace (obj, stack) { - return stack - } - - Error.prepareStackTrace = prepareObjectStackTrace - Error.stackTraceLimit = 2 - - // capture the stack - Error.captureStackTrace(obj) - - // slice the stack - var stack = obj.stack.slice() - - Error.prepareStackTrace = prep - Error.stackTraceLimit = limit - - return stack[0].toString ? toString : require('./callsite-tostring') -}) - -lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount () { - return EventEmitter.listenerCount || require('./event-listener-count') -}) - -/** - * Define a lazy property. - */ - -function lazyProperty (obj, prop, getter) { - function get () { - var val = getter() - - Object.defineProperty(obj, prop, { - configurable: true, - enumerable: true, - value: val - }) - - return val - } - - Object.defineProperty(obj, prop, { - configurable: true, - enumerable: true, - get: get - }) -} - -/** - * Call toString() on the obj - */ - -function toString (obj) { - return obj.toString() -} diff --git a/node_modules/depd/package.json b/node_modules/depd/package.json deleted file mode 100644 index 5e3c863216e40..0000000000000 --- a/node_modules/depd/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "depd", - "description": "Deprecate all the things", - "version": "1.1.2", - "author": "Douglas Christopher Wilson <doug@somethingdoug.com>", - "license": "MIT", - "keywords": [ - "deprecate", - "deprecated" - ], - "repository": "dougwilson/nodejs-depd", - "browser": "lib/browser/index.js", - "devDependencies": { - "benchmark": "2.1.4", - "beautify-benchmark": "0.2.4", - "eslint": "3.19.0", - "eslint-config-standard": "7.1.0", - "eslint-plugin-markdown": "1.0.0-beta.7", - "eslint-plugin-promise": "3.6.0", - "eslint-plugin-standard": "3.0.1", - "istanbul": "0.4.5", - "mocha": "~1.21.5" - }, - "files": [ - "lib/", - "History.md", - "LICENSE", - "index.js", - "Readme.md" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "bench": "node benchmark/index.js", - "lint": "eslint --plugin markdown --ext js,md .", - "test": "mocha --reporter spec --bail test/", - "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --no-exit test/", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/" - } -} diff --git a/node_modules/dezalgo/LICENSE b/node_modules/dezalgo/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/dezalgo/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/dezalgo/dezalgo.js b/node_modules/dezalgo/dezalgo.js deleted file mode 100644 index 04fd3ba78146d..0000000000000 --- a/node_modules/dezalgo/dezalgo.js +++ /dev/null @@ -1,22 +0,0 @@ -var wrappy = require('wrappy') -module.exports = wrappy(dezalgo) - -var asap = require('asap') - -function dezalgo (cb) { - var sync = true - asap(function () { - sync = false - }) - - return function zalgoSafe() { - var args = arguments - var me = this - if (sync) - asap(function() { - cb.apply(me, args) - }) - else - cb.apply(me, args) - } -} diff --git a/node_modules/dezalgo/package.json b/node_modules/dezalgo/package.json deleted file mode 100644 index f8ba8ec2b6b7a..0000000000000 --- a/node_modules/dezalgo/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "dezalgo", - "version": "1.0.4", - "description": "Contain async insanity so that the dark pony lord doesn't eat souls", - "main": "dezalgo.js", - "files": [ - "dezalgo.js" - ], - "directories": { - "test": "test" - }, - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - }, - "devDependencies": { - "tap": "^12.4.0" - }, - "scripts": { - "test": "tap test/*.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/npm/dezalgo" - }, - "keywords": [ - "async", - "zalgo", - "the dark pony", - "he comes", - "asynchrony of all holy and good", - "To invoke the hive mind representing chaos", - "Invoking the feeling of chaos. /Without order", - "The Nezperdian Hive Mind of Chaos, (zalgo………………)", - "He who waits beyond the wall", - "ZALGO", - "HE COMES", - "there used to be some funky unicode keywords here, but it broke the npm website on chrome, so they were removed, sorry" - ], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "license": "ISC", - "bugs": { - "url": "https://github.com/npm/dezalgo/issues" - }, - "homepage": "https://github.com/npm/dezalgo" -} diff --git a/node_modules/diff/CONTRIBUTING.md b/node_modules/diff/CONTRIBUTING.md index c8c4fe6cc225c..203d0245fc634 100644 --- a/node_modules/diff/CONTRIBUTING.md +++ b/node_modules/diff/CONTRIBUTING.md @@ -1,39 +1,28 @@ -# How to Contribute - -## Pull Requests - -We also accept [pull requests][pull-request]! - -Generally we like to see pull requests that - -- Maintain the existing code style -- Are focused on a single change (i.e. avoid large refactoring or style adjustments in untouched code if not the primary goal of the pull request) -- Have [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) -- Have tests -- Don't decrease the current code coverage (see coverage/lcov-report/index.html) - -## Building +## Building and testing ``` -npm install -npm test +yarn +yarn test ``` -The `npm test -- dev` implements watching for tests within Node and `karma start` may be used for manual testing in browsers. +To run tests in a *browser* (for instance to test compatibility with Firefox, with Safari, or with old browser versions), run `yarn karma start`, then open http://localhost:9876/ in the browser you want to test in. Results of the test run will appear in the terminal where `yarn karma start` is running. If you notice any problems, please report them to the GitHub issue tracker at [http://github.com/kpdecker/jsdiff/issues](http://github.com/kpdecker/jsdiff/issues). ## Releasing -JsDiff utilizes the [release yeoman generator][generator-release] to perform most release tasks. +Run a test in Firefox via the procedure above before releasing. -A full release may be completed with the following: +A full release may be completed by first updating the `"version"` property in package.json, then running the following: ``` -yo release -npm publish +yarn clean +yarn build +yarn publish ``` -[generator-release]: https://github.com/walmartlabs/generator-release -[pull-request]: https://github.com/kpdecker/jsdiff/pull/new/master +After releasing, remember to: +* commit the `package.json` change and push it to GitHub +* create a new version tag on GitHub +* update `diff.js` on the `gh-pages` branch to the latest built version from the `dist/` folder. diff --git a/node_modules/diff/LICENSE b/node_modules/diff/LICENSE index 4e7146ed78a2f..2d48b19fcc2e6 100644 --- a/node_modules/diff/LICENSE +++ b/node_modules/diff/LICENSE @@ -1,31 +1,29 @@ -Software License Agreement (BSD License) +BSD 3-Clause License Copyright (c) 2009-2015, Kevin Decker <kpdecker@gmail.com> - All rights reserved. -Redistribution and use of this software in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. -* Neither the name of Kevin Decker nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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/node_modules/diff/dist/diff.js b/node_modules/diff/dist/diff.js index bba91954f4b23..6f416fdf444b4 100644 --- a/node_modules/diff/dist/diff.js +++ b/node_modules/diff/dist/diff.js @@ -1,1582 +1,1741 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = global || self, factory(global.Diff = {})); -}(this, (function (exports) { 'use strict'; - - function Diff() {} - Diff.prototype = { - diff: function diff(oldString, newString) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var callback = options.callback; - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - this.options = options; - var self = this; - - function done(value) { - if (callback) { - setTimeout(function () { - callback(undefined, value); - }, 0); - return true; - } else { - return value; - } - } // Allow subclasses to massage the input prior to running - - - oldString = this.castInput(oldString); - newString = this.castInput(newString); - oldString = this.removeEmpty(this.tokenize(oldString)); - newString = this.removeEmpty(this.tokenize(newString)); - var newLen = newString.length, - oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ - newPos: -1, - components: [] - }]; // Seed editLength = 0, i.e. the content starts with the same values - - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{ - value: this.join(newString), - count: newString.length - }]); - } // Main worker method. checks all permutations of a given edit length for acceptance. - - - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath = void 0; - - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } - - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; - - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - - - if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } - - _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done - - if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { - return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Diff = {})); +})(this, (function (exports) { 'use strict'; + + class Diff { + diff(oldStr, newStr, + // Type below is not accurate/complete - see above for full possibilities - but it compiles + options = {}) { + let callback; + if (typeof options === 'function') { + callback = options; + options = {}; + } + else if ('callback' in options) { + callback = options.callback; + } + // Allow subclasses to massage the input prior to running + const oldString = this.castInput(oldStr, options); + const newString = this.castInput(newStr, options); + const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); + const newTokens = this.removeEmpty(this.tokenize(newString, options)); + return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); } - - editLength++; - } // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - - - if (callback) { - (function exec() { - setTimeout(function () { - // This should not happen, but we want to be safe. - - /* istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); + diffWithOptionsObj(oldTokens, newTokens, options, callback) { + var _a; + const done = (value) => { + value = this.postProcess(value, options); + if (callback) { + setTimeout(function () { callback(value); }, 0); + return undefined; + } + else { + return value; + } + }; + const newLen = newTokens.length, oldLen = oldTokens.length; + let editLength = 1; + let maxEditLength = newLen + oldLen; + if (options.maxEditLength != null) { + maxEditLength = Math.min(maxEditLength, options.maxEditLength); + } + const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; + const abortAfterTimestamp = Date.now() + maxExecutionTime; + const bestPath = [{ oldPos: -1, lastComponent: undefined }]; + // Seed editLength = 0, i.e. the content starts with the same values + let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); + if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { + // Identity per the equality and tokenizer + return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); + } + // Once we hit the right edge of the edit graph on some diagonal k, we can + // definitely reach the end of the edit graph in no more than k edits, so + // there's no point in considering any moves to diagonal k+1 any more (from + // which we're guaranteed to need at least k+1 more edits). + // Similarly, once we've reached the bottom of the edit graph, there's no + // point considering moves to lower diagonals. + // We record this fact by setting minDiagonalToConsider and + // maxDiagonalToConsider to some finite value once we've hit the edge of + // the edit graph. + // This optimization is not faithful to the original algorithm presented in + // Myers's paper, which instead pointlessly extends D-paths off the end of + // the edit graph - see page 7 of Myers's paper which notes this point + // explicitly and illustrates it with a diagram. This has major performance + // implications for some common scenarios. For instance, to compute a diff + // where the new text simply appends d characters on the end of the + // original text of length n, the true Myers algorithm will take O(n+d^2) + // time while this optimization needs only O(n+d) time. + let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; + // Main worker method. checks all permutations of a given edit length for acceptance. + const execEditLength = () => { + for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { + let basePath; + const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; + if (removePath) { + // No one else is going to attempt to use this value, clear it + // @ts-expect-error - perf optimisation. This type-violating value will never be read. + bestPath[diagonalPath - 1] = undefined; + } + let canAdd = false; + if (addPath) { + // what newPos will be after we do an insertion: + const addPathNewPos = addPath.oldPos - diagonalPath; + canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; + } + const canRemove = removePath && removePath.oldPos + 1 < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + // @ts-expect-error - perf optimisation. This type-violating value will never be read. + bestPath[diagonalPath] = undefined; + continue; + } + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the old string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canRemove || (canAdd && removePath.oldPos < addPath.oldPos)) { + basePath = this.addToPath(addPath, true, false, 0, options); + } + else { + basePath = this.addToPath(removePath, false, true, 1, options); + } + newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); + if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { + // If we have hit the end of both strings, then we are done + return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; + } + else { + bestPath[diagonalPath] = basePath; + if (basePath.oldPos + 1 >= oldLen) { + maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); + } + if (newPos + 1 >= newLen) { + minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); + } + } + } + editLength++; + }; + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced, or until the edit length exceeds options.maxEditLength (if given), + // in which case it will return undefined. + if (callback) { + (function exec() { + setTimeout(function () { + if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { + return callback(undefined); + } + if (!execEditLength()) { + exec(); + } + }, 0); + }()); + } + else { + while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { + const ret = execEditLength(); + if (ret) { + return ret; + } + } + } + } + addToPath(path, added, removed, oldPosInc, options) { + const last = path.lastComponent; + if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) { + return { + oldPos: path.oldPos + oldPosInc, + lastComponent: { count: last.count + 1, added: added, removed: removed, previousComponent: last.previousComponent } + }; + } + else { + return { + oldPos: path.oldPos + oldPosInc, + lastComponent: { count: 1, added: added, removed: removed, previousComponent: last } + }; + } + } + extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { + const newLen = newTokens.length, oldLen = oldTokens.length; + let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { + newPos++; + oldPos++; + commonCount++; + if (options.oneChangePerToken) { + basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; + } + } + if (commonCount && !options.oneChangePerToken) { + basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; + } + basePath.oldPos = oldPos; + return newPos; + } + equals(left, right, options) { + if (options.comparator) { + return options.comparator(left, right); + } + else { + return left === right + || (!!options.ignoreCase && left.toLowerCase() === right.toLowerCase()); + } + } + removeEmpty(array) { + const ret = []; + for (let i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } } - - if (!execEditLength()) { - exec(); - } - }, 0); - })(); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - - if (ret) { return ret; - } } - } - }, - pushComponent: function pushComponent(components, added, removed) { - var last = components[components.length - 1]; - - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = { - count: last.count + 1, - added: added, - removed: removed - }; - } else { - components.push({ - count: 1, - added: added, - removed: removed - }); - } - }, - extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, - commonCount = 0; - - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - - if (commonCount) { - basePath.components.push({ - count: commonCount - }); - } - - basePath.newPos = newPos; - return oldPos; - }, - equals: function equals(left, right) { - if (this.options.comparator) { - return this.options.comparator(left, right); - } else { - return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); - } - }, - removeEmpty: function removeEmpty(array) { - var ret = []; - - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + castInput(value, options) { + return value; } - } - - return ret; - }, - castInput: function castInput(value) { - return value; - }, - tokenize: function tokenize(value) { - return value.split(''); - }, - join: function join(chars) { - return chars.join(''); - } - }; - - function buildValues(diff, components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; - - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = value.map(function (value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); - component.value = diff.join(value); - } else { - component.value = diff.join(newString.slice(newPos, newPos + component.count)); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + tokenize(value, options) { + return Array.from(value); + } + join(chars) { + // Assumes ValueT is string, which is the case for most subclasses. + // When it's false, e.g. in diffArrays, this method needs to be overridden (e.g. with a no-op) + // Yes, the casts are verbose and ugly, because this pattern - of having the base class SORT OF + // assume tokens and values are strings, but not completely - is weird and janky. + return chars.join(''); + } + postProcess(changeObjects, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + options) { + return changeObjects; + } + get useLongestToken() { + return false; + } + buildValues(lastComponent, newTokens, oldTokens) { + // First we convert our linked list of components in reverse order to an + // array in the right order: + const components = []; + let nextComponent; + while (lastComponent) { + components.push(lastComponent); + nextComponent = lastComponent.previousComponent; + delete lastComponent.previousComponent; + lastComponent = nextComponent; + } + components.reverse(); + const componentLen = components.length; + let componentPos = 0, newPos = 0, oldPos = 0; + for (; componentPos < componentLen; componentPos++) { + const component = components[componentPos]; + if (!component.removed) { + if (!component.added && this.useLongestToken) { + let value = newTokens.slice(newPos, newPos + component.count); + value = value.map(function (value, i) { + const oldValue = oldTokens[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); + component.value = this.join(value); + } + else { + component.value = this.join(newTokens.slice(newPos, newPos + component.count)); + } + newPos += component.count; + // Common case + if (!component.added) { + oldPos += component.count; + } + } + else { + component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); + oldPos += component.count; + } + } + return components; } - - newPos += component.count; // Common case - - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); - oldPos += component.count; // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } - } - } // Special case handle for when one terminal is ignored (i.e. whitespace). - // For this case we merge the terminal into the prior string and drop the change. - // This is only available for string mode. - - - var lastComponent = components[componentLen - 1]; - - if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { - components[componentLen - 2].value += lastComponent.value; - components.pop(); } - return components; - } - - function clonePath(path) { - return { - newPos: path.newPos, - components: path.components.slice(0) - }; - } - - var characterDiff = new Diff(); - function diffChars(oldStr, newStr, options) { - return characterDiff.diff(oldStr, newStr, options); - } - - function generateOptions(options, defaults) { - if (typeof options === 'function') { - defaults.callback = options; - } else if (options) { - for (var name in options) { - /* istanbul ignore else */ - if (options.hasOwnProperty(name)) { - defaults[name] = options[name]; - } - } + class CharacterDiff extends Diff { } - - return defaults; - } - - // - // Ranges and exceptions: - // Latin-1 Supplement, 0080–00FF - // - U+00D7 × Multiplication sign - // - U+00F7 ÷ Division sign - // Latin Extended-A, 0100–017F - // Latin Extended-B, 0180–024F - // IPA Extensions, 0250–02AF - // Spacing Modifier Letters, 02B0–02FF - // - U+02C7 ˇ ˇ Caron - // - U+02D8 ˘ ˘ Breve - // - U+02D9 ˙ ˙ Dot Above - // - U+02DA ˚ ˚ Ring Above - // - U+02DB ˛ ˛ Ogonek - // - U+02DC ˜ ˜ Small Tilde - // - U+02DD ˝ ˝ Double Acute Accent - // Latin Extended Additional, 1E00–1EFF - - var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; - var reWhitespace = /\S/; - var wordDiff = new Diff(); - - wordDiff.equals = function (left, right) { - if (this.options.ignoreCase) { - left = left.toLowerCase(); - right = right.toLowerCase(); + const characterDiff = new CharacterDiff(); + function diffChars(oldStr, newStr, options) { + return characterDiff.diff(oldStr, newStr, options); } - return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); - }; - - wordDiff.tokenize = function (value) { - // All whitespace symbols except newline group into one token, each newline - in separate token - var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. - - for (var i = 0; i < tokens.length - 1; i++) { - // If we have an empty string in the next field and we have only word chars before and after, merge - if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { - tokens[i] += tokens[i + 2]; - tokens.splice(i + 1, 2); - i--; - } + function longestCommonPrefix(str1, str2) { + let i; + for (i = 0; i < str1.length && i < str2.length; i++) { + if (str1[i] != str2[i]) { + return str1.slice(0, i); + } + } + return str1.slice(0, i); } - - return tokens; - }; - - function diffWords(oldStr, newStr, options) { - options = generateOptions(options, { - ignoreWhitespace: true - }); - return wordDiff.diff(oldStr, newStr, options); - } - function diffWordsWithSpace(oldStr, newStr, options) { - return wordDiff.diff(oldStr, newStr, options); - } - - var lineDiff = new Diff(); - - lineDiff.tokenize = function (value) { - var retLines = [], - linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line - - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } // Merge the content and line separators into single tokens - - - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; - - if (i % 2 && !this.options.newlineIsToken) { - retLines[retLines.length - 1] += line; - } else { - if (this.options.ignoreWhitespace) { - line = line.trim(); + function longestCommonSuffix(str1, str2) { + let i; + // Unlike longestCommonPrefix, we need a special case to handle all scenarios + // where we return the empty string since str1.slice(-0) will return the + // entire string. + if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) { + return ''; } - - retLines.push(line); - } + for (i = 0; i < str1.length && i < str2.length; i++) { + if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) { + return str1.slice(-i); + } + } + return str1.slice(-i); } - - return retLines; - }; - - function diffLines(oldStr, newStr, callback) { - return lineDiff.diff(oldStr, newStr, callback); - } - function diffTrimmedLines(oldStr, newStr, callback) { - var options = generateOptions(callback, { - ignoreWhitespace: true - }); - return lineDiff.diff(oldStr, newStr, options); - } - - var sentenceDiff = new Diff(); - - sentenceDiff.tokenize = function (value) { - return value.split(/(\S.+?[.!?])(?=\s+|$)/); - }; - - function diffSentences(oldStr, newStr, callback) { - return sentenceDiff.diff(oldStr, newStr, callback); - } - - var cssDiff = new Diff(); - - cssDiff.tokenize = function (value) { - return value.split(/([{}:;,]|\s+)/); - }; - - function diffCss(oldStr, newStr, callback) { - return cssDiff.diff(oldStr, newStr, callback); - } - - function _typeof(obj) { - "@babel/helpers - typeof"; - - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; + function replacePrefix(string, oldPrefix, newPrefix) { + if (string.slice(0, oldPrefix.length) != oldPrefix) { + throw Error(`string ${JSON.stringify(string)} doesn't start with prefix ${JSON.stringify(oldPrefix)}; this is a bug`); + } + return newPrefix + string.slice(oldPrefix.length); } - - return _typeof(obj); - } - - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); - } - - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); - } - - function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); - } - - function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); - } - - function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - - return arr2; - } - - function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - - var objectPrototypeToString = Object.prototype.toString; - var jsonDiff = new Diff(); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a - // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - - jsonDiff.useLongestToken = true; - jsonDiff.tokenize = lineDiff.tokenize; - - jsonDiff.castInput = function (value) { - var _this$options = this.options, - undefinedReplacement = _this$options.undefinedReplacement, - _this$options$stringi = _this$options.stringifyReplacer, - stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) { - return typeof v === 'undefined' ? undefinedReplacement : v; - } : _this$options$stringi; - return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' '); - }; - - jsonDiff.equals = function (left, right) { - return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); - }; - - function diffJson(oldObj, newObj, options) { - return jsonDiff.diff(oldObj, newObj, options); - } // This function handles the presence of circular references by bailing out when encountering an - // object that is already on the "stack" of items being processed. Accepts an optional replacer - - function canonicalize(obj, stack, replacementStack, replacer, key) { - stack = stack || []; - replacementStack = replacementStack || []; - - if (replacer) { - obj = replacer(key, obj); + function replaceSuffix(string, oldSuffix, newSuffix) { + if (!oldSuffix) { + return string + newSuffix; + } + if (string.slice(-oldSuffix.length) != oldSuffix) { + throw Error(`string ${JSON.stringify(string)} doesn't end with suffix ${JSON.stringify(oldSuffix)}; this is a bug`); + } + return string.slice(0, -oldSuffix.length) + newSuffix; } - - var i; - - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } + function removePrefix(string, oldPrefix) { + return replacePrefix(string, oldPrefix, ''); } - - var canonicalizedObj; - - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key); - } - - stack.pop(); - replacementStack.pop(); - return canonicalizedObj; + function removeSuffix(string, oldSuffix) { + return replaceSuffix(string, oldSuffix, ''); } - - if (obj && obj.toJSON) { - obj = obj.toJSON(); + function maximumOverlap(string1, string2) { + return string2.slice(0, overlapCount(string1, string2)); } - - if (_typeof(obj) === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - - var sortedKeys = [], - _key; - - for (_key in obj) { - /* istanbul ignore else */ - if (obj.hasOwnProperty(_key)) { - sortedKeys.push(_key); + // Nicked from https://stackoverflow.com/a/60422853/1709587 + function overlapCount(a, b) { + // Deal with cases where the strings differ in length + let startA = 0; + if (a.length > b.length) { + startA = a.length - b.length; } - } - - sortedKeys.sort(); - - for (i = 0; i < sortedKeys.length; i += 1) { - _key = sortedKeys[i]; - canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key); - } - - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; - } - - return canonicalizedObj; - } - - var arrayDiff = new Diff(); - - arrayDiff.tokenize = function (value) { - return value.slice(); - }; - - arrayDiff.join = arrayDiff.removeEmpty = function (value) { - return value; - }; - - function diffArrays(oldArr, newArr, callback) { - return arrayDiff.diff(oldArr, newArr, callback); - } - - function parsePatch(uniDiff) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], - list = [], - i = 0; - - function parseIndex() { - var index = {}; - list.push(index); // Parse diff metadata - - while (i < diffstr.length) { - var line = diffstr[i]; // File header found, end parsing diff metadata - - if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { - break; - } // Diff index - - - var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); - - if (header) { - index.index = header[1]; + let endB = b.length; + if (a.length < b.length) { + endB = a.length; } - - i++; - } // Parse file headers if they are defined. Unified diff requires them, but - // there's no technical issues to have an isolated hunk without file header - - - parseFileHeader(index); - parseFileHeader(index); // Parse hunks - - index.hunks = []; - - while (i < diffstr.length) { - var _line = diffstr[i]; - - if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { - break; - } else if (/^@@/.test(_line)) { - index.hunks.push(parseHunk()); - } else if (_line && options.strict) { - // Ignore unexpected content unless in strict mode - throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); - } else { - i++; - } - } - } // Parses the --- and +++ headers, if none are found, no lines - // are consumed. - - - function parseFileHeader(index) { - var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]); - - if (fileHeader) { - var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; - var data = fileHeader[2].split('\t', 2); - var fileName = data[0].replace(/\\\\/g, '\\'); - - if (/^".*"$/.test(fileName)) { - fileName = fileName.substr(1, fileName.length - 2); - } - - index[keyPrefix + 'FileName'] = fileName; - index[keyPrefix + 'Header'] = (data[1] || '').trim(); - i++; - } - } // Parses a hunk - // This assumes that we are at the start of a hunk. - - - function parseHunk() { - var chunkHeaderIndex = i, - chunkHeaderLine = diffstr[i++], - chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); - var hunk = { - oldStart: +chunkHeader[1], - oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], - newStart: +chunkHeader[3], - newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], - lines: [], - linedelimiters: [] - }; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart += 1; - } - - if (hunk.newLines === 0) { - hunk.newStart += 1; - } - - var addCount = 0, - removeCount = 0; - - for (; i < diffstr.length; i++) { - // Lines starting with '---' could be mistaken for the "remove line" operation - // But they could be the header for the next file. Therefore prune such cases out. - if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { - break; + // Create a back-reference for each index + // that should be followed in case of a mismatch. + // We only need B to make these references: + const map = Array(endB); + let k = 0; // Index that lags behind j + map[0] = 0; + for (let j = 1; j < endB; j++) { + if (b[j] == b[k]) { + map[j] = map[k]; // skip over the same character (optional optimisation) + } + else { + map[j] = k; + } + while (k > 0 && b[j] != b[k]) { + k = map[k]; + } + if (b[j] == b[k]) { + k++; + } } - - var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0]; - - if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { - hunk.lines.push(diffstr[i]); - hunk.linedelimiters.push(delimiters[i] || '\n'); - - if (operation === '+') { - addCount++; - } else if (operation === '-') { - removeCount++; - } else if (operation === ' ') { - addCount++; - removeCount++; - } - } else { - break; - } - } // Handle the empty block count case - - - if (!addCount && hunk.newLines === 1) { - hunk.newLines = 0; - } - - if (!removeCount && hunk.oldLines === 1) { - hunk.oldLines = 0; - } // Perform optional sanity checking - - - if (options.strict) { - if (addCount !== hunk.newLines) { - throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + // Phase 2: use these references while iterating over A + k = 0; + for (let i = startA; i < a.length; i++) { + while (k > 0 && a[i] != b[k]) { + k = map[k]; + } + if (a[i] == b[k]) { + k++; + } } - - if (removeCount !== hunk.oldLines) { - throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + return k; + } + /** + * Returns true if the string consistently uses Windows line endings. + */ + function hasOnlyWinLineEndings(string) { + return string.includes('\r\n') && !string.startsWith('\n') && !string.match(/[^\r]\n/); + } + /** + * Returns true if the string consistently uses Unix line endings. + */ + function hasOnlyUnixLineEndings(string) { + return !string.includes('\r\n') && string.includes('\n'); + } + function trailingWs(string) { + // Yes, this looks overcomplicated and dumb - why not replace the whole function with + // return string.match(/\s*$/)[0] + // you ask? Because: + // 1. the trap described at https://markamery.com/blog/quadratic-time-regexes/ would mean doing + // this would cause this function to take O(n²) time in the worst case (specifically when + // there is a massive run of NON-TRAILING whitespace in `string`), and + // 2. the fix proposed in the same blog post, of using a negative lookbehind, is incompatible + // with old Safari versions that we'd like to not break if possible (see + // https://github.com/kpdecker/jsdiff/pull/550) + // It feels absurd to do this with an explicit loop instead of a regex, but I really can't see a + // better way that doesn't result in broken behaviour. + let i; + for (i = string.length - 1; i >= 0; i--) { + if (!string[i].match(/\s/)) { + break; + } } - } - - return hunk; + return string.substring(i + 1); } - - while (i < diffstr.length) { - parseIndex(); + function leadingWs(string) { + // Thankfully the annoying considerations described in trailingWs don't apply here: + const match = string.match(/^\s*/); + return match ? match[0] : ''; } - return list; - } - - // Iterator that traverses in the range of [min, max], stepping - // by distance from a given start position. I.e. for [0, 4], with - // start of 2, this will iterate 2, 3, 1, 4, 0. - function distanceIterator (start, minLine, maxLine) { - var wantForward = true, - backwardExhausted = false, - forwardExhausted = false, - localOffset = 1; - return function iterator() { - if (wantForward && !forwardExhausted) { - if (backwardExhausted) { - localOffset++; - } else { - wantForward = false; - } // Check if trying to fit beyond text length, and if not, check it fits - // after offset location (or desired location on first iteration) - - - if (start + localOffset <= maxLine) { - return localOffset; + // Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode + // + // Chars/ranges counted as "word" characters by this regex are as follows: + // + // + U+00AD Soft hyphen + // + 00C0–00FF (letters with diacritics from the Latin-1 Supplement), except: + // - U+00D7 × Multiplication sign + // - U+00F7 ÷ Division sign + // + Latin Extended-A, 0100–017F + // + Latin Extended-B, 0180–024F + // + IPA Extensions, 0250–02AF + // + Spacing Modifier Letters, 02B0–02FF, except: + // - U+02C7 ˇ ˇ Caron + // - U+02D8 ˘ ˘ Breve + // - U+02D9 ˙ ˙ Dot Above + // - U+02DA ˚ ˚ Ring Above + // - U+02DB ˛ ˛ Ogonek + // - U+02DC ˜ ˜ Small Tilde + // - U+02DD ˝ ˝ Double Acute Accent + // + Latin Extended Additional, 1E00–1EFF + const extendedWordChars = 'a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}'; + // Each token is one of the following: + // - A punctuation mark plus the surrounding whitespace + // - A word plus the surrounding whitespace + // - Pure whitespace (but only in the special case where the entire text + // is just whitespace) + // + // We have to include surrounding whitespace in the tokens because the two + // alternative approaches produce horribly broken results: + // * If we just discard the whitespace, we can't fully reproduce the original + // text from the sequence of tokens and any attempt to render the diff will + // get the whitespace wrong. + // * If we have separate tokens for whitespace, then in a typical text every + // second token will be a single space character. But this often results in + // the optimal diff between two texts being a perverse one that preserves + // the spaces between words but deletes and reinserts actual common words. + // See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640 + // for an example. + // + // Keeping the surrounding whitespace of course has implications for .equals + // and .join, not just .tokenize. + // This regex does NOT fully implement the tokenization rules described above. + // Instead, it gives runs of whitespace their own "token". The tokenize method + // then handles stitching whitespace tokens onto adjacent word or punctuation + // tokens. + const tokenizeIncludingWhitespace = new RegExp(`[${extendedWordChars}]+|\\s+|[^${extendedWordChars}]`, 'ug'); + class WordDiff extends Diff { + equals(left, right, options) { + if (options.ignoreCase) { + left = left.toLowerCase(); + right = right.toLowerCase(); + } + return left.trim() === right.trim(); } - - forwardExhausted = true; - } - - if (!backwardExhausted) { - if (!forwardExhausted) { - wantForward = true; - } // Check if trying to fit before text beginning, and if not, check it fits - // before offset location - - - if (minLine <= start - localOffset) { - return -localOffset++; + tokenize(value, options = {}) { + let parts; + if (options.intlSegmenter) { + const segmenter = options.intlSegmenter; + if (segmenter.resolvedOptions().granularity != 'word') { + throw new Error('The segmenter passed must have a granularity of "word"'); + } + // We want `parts` to be an array whose elements alternate between being + // pure whitespace and being pure non-whitespace. This is ALMOST what the + // segments returned by a word-based Intl.Segmenter already look like, + // and therefore we can ALMOST get what we want by simply doing... + // parts = Array.from(segmenter.segment(value), segment => segment.segment); + // ... but not QUITE, because there's of one annoying special case: every + // newline character gets its own segment, instead of sharing a segment + // with other surrounding whitespace. We therefore need to manually merge + // consecutive segments of whitespace into a single part: + parts = []; + for (const segmentObj of Array.from(segmenter.segment(value))) { + const segment = segmentObj.segment; + if (parts.length && (/\s/).test(parts[parts.length - 1]) && (/\s/).test(segment)) { + parts[parts.length - 1] += segment; + } + else { + parts.push(segment); + } + } + } + else { + parts = value.match(tokenizeIncludingWhitespace) || []; + } + const tokens = []; + let prevPart = null; + parts.forEach(part => { + if ((/\s/).test(part)) { + if (prevPart == null) { + tokens.push(part); + } + else { + tokens.push(tokens.pop() + part); + } + } + else if (prevPart != null && (/\s/).test(prevPart)) { + if (tokens[tokens.length - 1] == prevPart) { + tokens.push(tokens.pop() + part); + } + else { + tokens.push(prevPart + part); + } + } + else { + tokens.push(part); + } + prevPart = part; + }); + return tokens; + } + join(tokens) { + // Tokens being joined here will always have appeared consecutively in the + // same text, so we can simply strip off the leading whitespace from all the + // tokens except the first (and except any whitespace-only tokens - but such + // a token will always be the first and only token anyway) and then join them + // and the whitespace around words and punctuation will end up correct. + return tokens.map((token, i) => { + if (i == 0) { + return token; + } + else { + return token.replace((/^\s+/), ''); + } + }).join(''); + } + postProcess(changes, options) { + if (!changes || options.oneChangePerToken) { + return changes; + } + let lastKeep = null; + // Change objects representing any insertion or deletion since the last + // "keep" change object. There can be at most one of each. + let insertion = null; + let deletion = null; + changes.forEach(change => { + if (change.added) { + insertion = change; + } + else if (change.removed) { + deletion = change; + } + else { + if (insertion || deletion) { // May be false at start of text + dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change); + } + lastKeep = change; + insertion = null; + deletion = null; + } + }); + if (insertion || deletion) { + dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null); + } + return changes; } - - backwardExhausted = true; - return iterator(); - } // We tried to fit hunk before text beginning and beyond text length, then - // hunk can't fit on the text. Return undefined - - }; - } - - function applyPatch(source, uniDiff) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); } - - if (Array.isArray(uniDiff)) { - if (uniDiff.length > 1) { - throw new Error('applyPatch only works with a single input.'); - } - - uniDiff = uniDiff[0]; - } // Apply the diff to the input - - - var lines = source.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], - hunks = uniDiff.hunks, - compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) { - return line === patchContent; - }, - errorCount = 0, - fuzzFactor = options.fuzzFactor || 0, - minLine = 0, - offset = 0, - removeEOFNL, - addEOFNL; - /** - * Checks if the hunk exactly fits on the provided location - */ - - - function hunkFits(hunk, toPos) { - for (var j = 0; j < hunk.lines.length; j++) { - var line = hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line; - - if (operation === ' ' || operation === '-') { - // Context sanity check - if (!compareLine(toPos + 1, lines[toPos], operation, content)) { - errorCount++; - - if (errorCount > fuzzFactor) { - return false; + const wordDiff = new WordDiff(); + function diffWords(oldStr, newStr, options) { + // This option has never been documented and never will be (it's clearer to + // just call `diffWordsWithSpace` directly if you need that behavior), but + // has existed in jsdiff for a long time, so we retain support for it here + // for the sake of backwards compatibility. + if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) { + return diffWordsWithSpace(oldStr, newStr, options); + } + return wordDiff.diff(oldStr, newStr, options); + } + function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) { + // Before returning, we tidy up the leading and trailing whitespace of the + // change objects to eliminate cases where trailing whitespace in one object + // is repeated as leading whitespace in the next. + // Below are examples of the outcomes we want here to explain the code. + // I=insert, K=keep, D=delete + // 1. diffing 'foo bar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz' + // After cleanup, we want: K:'foo ' D:'bar ' K:'baz' + // + // 2. Diffing 'foo bar baz' vs 'foo qux baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz' + // After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz' + // + // 3. Diffing 'foo\nbar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:'\nbar ' K:' baz' + // After cleanup, we want K'foo' D:'\nbar' K:' baz' + // + // 4. Diffing 'foo baz' vs 'foo\nbar baz' + // Prior to cleanup, we have K:'foo\n' I:'\nbar ' K:' baz' + // After cleanup, we ideally want K'foo' I:'\nbar' K:' baz' + // but don't actually manage this currently (the pre-cleanup change + // objects don't contain enough information to make it possible). + // + // 5. Diffing 'foo bar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz' + // After cleanup, we want K:'foo ' D:' bar ' K:'baz' + // + // Our handling is unavoidably imperfect in the case where there's a single + // indel between keeps and the whitespace has changed. For instance, consider + // diffing 'foo\tbar\nbaz' vs 'foo baz'. Unless we create an extra change + // object to represent the insertion of the space character (which isn't even + // a token), we have no way to avoid losing information about the texts' + // original whitespace in the result we return. Still, we do our best to + // output something that will look sensible if we e.g. print it with + // insertions in green and deletions in red. + // Between two "keep" change objects (or before the first or after the last + // change object), we can have either: + // * A "delete" followed by an "insert" + // * Just an "insert" + // * Just a "delete" + // We handle the three cases separately. + if (deletion && insertion) { + const oldWsPrefix = leadingWs(deletion.value); + const oldWsSuffix = trailingWs(deletion.value); + const newWsPrefix = leadingWs(insertion.value); + const newWsSuffix = trailingWs(insertion.value); + if (startKeep) { + const commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix); + startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix); + deletion.value = removePrefix(deletion.value, commonWsPrefix); + insertion.value = removePrefix(insertion.value, commonWsPrefix); + } + if (endKeep) { + const commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix); + endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix); + deletion.value = removeSuffix(deletion.value, commonWsSuffix); + insertion.value = removeSuffix(insertion.value, commonWsSuffix); } - } - - toPos++; } - } - - return true; - } // Search best fit offsets for each hunk based on the previous ones - - - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i], - maxLine = lines.length - hunk.oldLines, - localOffset = 0, - toPos = offset + hunk.oldStart - 1; - var iterator = distanceIterator(toPos, minLine, maxLine); - - for (; localOffset !== undefined; localOffset = iterator()) { - if (hunkFits(hunk, toPos + localOffset)) { - hunk.offset = offset += localOffset; - break; + else if (insertion) { + // The whitespaces all reflect what was in the new text rather than + // the old, so we essentially have no information about whitespace + // insertion or deletion. We just want to dedupe the whitespace. + // We do that by having each change object keep its trailing + // whitespace and deleting duplicate leading whitespace where + // present. + if (startKeep) { + const ws = leadingWs(insertion.value); + insertion.value = insertion.value.substring(ws.length); + } + if (endKeep) { + const ws = leadingWs(endKeep.value); + endKeep.value = endKeep.value.substring(ws.length); + } + // otherwise we've got a deletion and no insertion + } + else if (startKeep && endKeep) { + const newWsFull = leadingWs(endKeep.value), delWsStart = leadingWs(deletion.value), delWsEnd = trailingWs(deletion.value); + // Any whitespace that comes straight after startKeep in both the old and + // new texts, assign to startKeep and remove from the deletion. + const newWsStart = longestCommonPrefix(newWsFull, delWsStart); + deletion.value = removePrefix(deletion.value, newWsStart); + // Any whitespace that comes straight before endKeep in both the old and + // new texts, and hasn't already been assigned to startKeep, assign to + // endKeep and remove from the deletion. + const newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd); + deletion.value = removeSuffix(deletion.value, newWsEnd); + endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd); + // If there's any whitespace from the new text that HASN'T already been + // assigned, assign it to the start: + startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length)); + } + else if (endKeep) { + // We are at the start of the text. Preserve all the whitespace on + // endKeep, and just remove whitespace from the end of deletion to the + // extent that it overlaps with the start of endKeep. + const endKeepWsPrefix = leadingWs(endKeep.value); + const deletionWsSuffix = trailingWs(deletion.value); + const overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix); + deletion.value = removeSuffix(deletion.value, overlap); + } + else if (startKeep) { + // We are at the END of the text. Preserve all the whitespace on + // startKeep, and just remove whitespace from the start of deletion to + // the extent that it overlaps with the end of startKeep. + const startKeepWsSuffix = trailingWs(startKeep.value); + const deletionWsPrefix = leadingWs(deletion.value); + const overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix); + deletion.value = removePrefix(deletion.value, overlap); } - } - - if (localOffset === undefined) { - return false; - } // Set lower text limit to end of the current hunk, so next ones don't try - // to fit over already patched text - - - minLine = hunk.offset + hunk.oldStart + hunk.oldLines; - } // Apply patch hunks - - - var diffOffset = 0; - - for (var _i = 0; _i < hunks.length; _i++) { - var _hunk = hunks[_i], - _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1; - - diffOffset += _hunk.newLines - _hunk.oldLines; - - for (var j = 0; j < _hunk.lines.length; j++) { - var line = _hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line, - delimiter = _hunk.linedelimiters[j]; - - if (operation === ' ') { - _toPos++; - } else if (operation === '-') { - lines.splice(_toPos, 1); - delimiters.splice(_toPos, 1); - /* istanbul ignore else */ - } else if (operation === '+') { - lines.splice(_toPos, 0, content); - delimiters.splice(_toPos, 0, delimiter); - _toPos++; - } else if (operation === '\\') { - var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; - - if (previousOperation === '+') { - removeEOFNL = true; - } else if (previousOperation === '-') { - addEOFNL = true; - } - } - } - } // Handle EOFNL insertion/removal - - - if (removeEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - delimiters.pop(); - } - } else if (addEOFNL) { - lines.push(''); - delimiters.push('\n'); } - - for (var _k = 0; _k < lines.length - 1; _k++) { - lines[_k] = lines[_k] + delimiters[_k]; + class WordsWithSpaceDiff extends Diff { + tokenize(value) { + // Slightly different to the tokenizeIncludingWhitespace regex used above in + // that this one treats each individual newline as a distinct token, rather + // than merging them into other surrounding whitespace. This was requested + // in https://github.com/kpdecker/jsdiff/issues/180 & + // https://github.com/kpdecker/jsdiff/issues/211 + const regex = new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`, 'ug'); + return value.match(regex) || []; + } } - - return lines.join(''); - } // Wrapper that supports multiple file patches via callbacks. - - function applyPatches(uniDiff, options) { - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); + const wordsWithSpaceDiff = new WordsWithSpaceDiff(); + function diffWordsWithSpace(oldStr, newStr, options) { + return wordsWithSpaceDiff.diff(oldStr, newStr, options); } - var currentIndex = 0; - - function processIndex() { - var index = uniDiff[currentIndex++]; - - if (!index) { - return options.complete(); - } - - options.loadFile(index, function (err, data) { - if (err) { - return options.complete(err); + function generateOptions(options, defaults) { + if (typeof options === 'function') { + defaults.callback = options; } - - var updatedContent = applyPatch(data, index, options); - options.patched(index, updatedContent, function (err) { - if (err) { - return options.complete(err); - } - - processIndex(); - }); - }); + else if (options) { + for (const name in options) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(options, name)) { + defaults[name] = options[name]; + } + } + } + return defaults; } - processIndex(); - } - - function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - if (!options) { - options = {}; + class LineDiff extends Diff { + constructor() { + super(...arguments); + this.tokenize = tokenize; + } + equals(left, right, options) { + // If we're ignoring whitespace, we need to normalise lines by stripping + // whitespace before checking equality. (This has an annoying interaction + // with newlineIsToken that requires special handling: if newlines get their + // own token, then we DON'T want to trim the *newline* tokens down to empty + // strings, since this would cause us to treat whitespace-only line content + // as equal to a separator between lines, which would be weird and + // inconsistent with the documented behavior of the options.) + if (options.ignoreWhitespace) { + if (!options.newlineIsToken || !left.includes('\n')) { + left = left.trim(); + } + if (!options.newlineIsToken || !right.includes('\n')) { + right = right.trim(); + } + } + else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { + if (left.endsWith('\n')) { + left = left.slice(0, -1); + } + if (right.endsWith('\n')) { + right = right.slice(0, -1); + } + } + return super.equals(left, right, options); + } } - - if (typeof options.context === 'undefined') { - options.context = 4; + const lineDiff = new LineDiff(); + function diffLines(oldStr, newStr, options) { + return lineDiff.diff(oldStr, newStr, options); } - - var diff = diffLines(oldStr, newStr, options); - diff.push({ - value: '', - lines: [] - }); // Append an empty value to make cleanup easier - - function contextLines(lines) { - return lines.map(function (entry) { - return ' ' + entry; - }); + function diffTrimmedLines(oldStr, newStr, options) { + options = generateOptions(options, { ignoreWhitespace: true }); + return lineDiff.diff(oldStr, newStr, options); } - - var hunks = []; - var oldRangeStart = 0, - newRangeStart = 0, - curRange = [], - oldLine = 1, - newLine = 1; - - var _loop = function _loop(i) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; - - if (current.added || current.removed) { - var _curRange; - - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; - - if (prev) { - curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } // Output our changes - - - (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) { - return (current.added ? '+' : '-') + entry; - }))); // Track the updated file position - - - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= options.context * 2 && i < diff.length - 2) { - var _curRange2; - - // Overlapping - (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines))); - } else { - var _curRange3; - - // end the range and output - var contextSize = Math.min(lines.length, options.context); - - (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize)))); - - var hunk = { - oldStart: oldRangeStart, - oldLines: oldLine - oldRangeStart + contextSize, - newStart: newRangeStart, - newLines: newLine - newRangeStart + contextSize, - lines: curRange - }; - - if (i >= diff.length - 2 && lines.length <= options.context) { - // EOF is inside this hunk - var oldEOFNewline = /\n$/.test(oldStr); - var newEOFNewline = /\n$/.test(newStr); - var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; - - if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) { - // special case: old has no eol and no trailing context; no-nl can end up before adds - // however, if the old file is empty, do not output the no-nl line - curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); - } - - if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) { - curRange.push('\\ No newline at end of file'); - } + // Exported standalone so it can be used from jsonDiff too. + function tokenize(value, options) { + if (options.stripTrailingCr) { + // remove one \r before \n to match GNU diff's --strip-trailing-cr behavior + value = value.replace(/\r\n/g, '\n'); + } + const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } + // Merge the content and line separators into single tokens + for (let i = 0; i < linesAndNewlines.length; i++) { + const line = linesAndNewlines[i]; + if (i % 2 && !options.newlineIsToken) { + retLines[retLines.length - 1] += line; + } + else { + retLines.push(line); } - - hunks.push(hunk); - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } } - - oldLine += lines.length; - newLine += lines.length; - } - }; - - for (var i = 0; i < diff.length; i++) { - _loop(i); - } - - return { - oldFileName: oldFileName, - newFileName: newFileName, - oldHeader: oldHeader, - newHeader: newHeader, - hunks: hunks - }; - } - function formatPatch(diff) { - var ret = []; - - if (diff.oldFileName == diff.newFileName) { - ret.push('Index: ' + diff.oldFileName); + return retLines; } - ret.push('==================================================================='); - ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); - ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); - - for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart -= 1; - } - - if (hunk.newLines === 0) { - hunk.newStart -= 1; - } - - ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); - ret.push.apply(ret, hunk.lines); + function isSentenceEndPunct(char) { + return char == '.' || char == '!' || char == '?'; } - - return ret.join('\n') + '\n'; - } - function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)); - } - function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { - return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); - } - - function arrayEqual(a, b) { - if (a.length !== b.length) { - return false; + class SentenceDiff extends Diff { + tokenize(value) { + var _a; + // If in future we drop support for environments that don't support lookbehinds, we can replace + // this entire function with: + // return value.split(/(?<=[.!?])(\s+|$)/); + // but until then, for similar reasons to the trailingWs function in string.ts, we are forced + // to do this verbosely "by hand" instead of using a regex. + const result = []; + let tokenStartI = 0; + for (let i = 0; i < value.length; i++) { + if (i == value.length - 1) { + result.push(value.slice(tokenStartI)); + break; + } + if (isSentenceEndPunct(value[i]) && value[i + 1].match(/\s/)) { + // We've hit a sentence break - i.e. a punctuation mark followed by whitespace. + // We now want to push TWO tokens to the result: + // 1. the sentence + result.push(value.slice(tokenStartI, i + 1)); + // 2. the whitespace + i = tokenStartI = i + 1; + while ((_a = value[i + 1]) === null || _a === void 0 ? void 0 : _a.match(/\s/)) { + i++; + } + result.push(value.slice(tokenStartI, i + 1)); + // Then the next token (a sentence) starts on the character after the whitespace. + // (It's okay if this is off the end of the string - then the outer loop will terminate + // here anyway.) + tokenStartI = i + 1; + } + } + return result; + } } - - return arrayStartsWith(a, b); - } - function arrayStartsWith(array, start) { - if (start.length > array.length) { - return false; + const sentenceDiff = new SentenceDiff(); + function diffSentences(oldStr, newStr, options) { + return sentenceDiff.diff(oldStr, newStr, options); } - for (var i = 0; i < start.length; i++) { - if (start[i] !== array[i]) { - return false; - } + class CssDiff extends Diff { + tokenize(value) { + return value.split(/([{}:;,]|\s+)/); + } } - - return true; - } - - function calcLineCount(hunk) { - var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines), - oldLines = _calcOldNewLineCount.oldLines, - newLines = _calcOldNewLineCount.newLines; - - if (oldLines !== undefined) { - hunk.oldLines = oldLines; - } else { - delete hunk.oldLines; + const cssDiff = new CssDiff(); + function diffCss(oldStr, newStr, options) { + return cssDiff.diff(oldStr, newStr, options); } - if (newLines !== undefined) { - hunk.newLines = newLines; - } else { - delete hunk.newLines; + class JsonDiff extends Diff { + constructor() { + super(...arguments); + this.tokenize = tokenize; + } + get useLongestToken() { + // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a + // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: + return true; + } + castInput(value, options) { + const { undefinedReplacement, stringifyReplacer = (k, v) => typeof v === 'undefined' ? undefinedReplacement : v } = options; + return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), null, ' '); + } + equals(left, right, options) { + return super.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'), options); + } } - } - function merge(mine, theirs, base) { - mine = loadPatch(mine, base); - theirs = loadPatch(theirs, base); - var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning. - // Leaving sanity checks on this to the API consumer that may know more about the - // meaning in their own context. - - if (mine.index || theirs.index) { - ret.index = mine.index || theirs.index; + const jsonDiff = new JsonDiff(); + function diffJson(oldStr, newStr, options) { + return jsonDiff.diff(oldStr, newStr, options); } - - if (mine.newFileName || theirs.newFileName) { - if (!fileNameChanged(mine)) { - // No header or no change in ours, use theirs (and ours if theirs does not exist) - ret.oldFileName = theirs.oldFileName || mine.oldFileName; - ret.newFileName = theirs.newFileName || mine.newFileName; - ret.oldHeader = theirs.oldHeader || mine.oldHeader; - ret.newHeader = theirs.newHeader || mine.newHeader; - } else if (!fileNameChanged(theirs)) { - // No header or no change in theirs, use ours - ret.oldFileName = mine.oldFileName; - ret.newFileName = mine.newFileName; - ret.oldHeader = mine.oldHeader; - ret.newHeader = mine.newHeader; - } else { - // Both changed... figure it out - ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName); - ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName); - ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader); - ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader); - } + // This function handles the presence of circular references by bailing out when encountering an + // object that is already on the "stack" of items being processed. Accepts an optional replacer + function canonicalize(obj, stack, replacementStack, replacer, key) { + stack = stack || []; + replacementStack = replacementStack || []; + if (replacer) { + obj = replacer(key === undefined ? '' : key, obj); + } + let i; + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } + let canonicalizedObj; + if ('[object Array]' === Object.prototype.toString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, String(i)); + } + stack.pop(); + replacementStack.pop(); + return canonicalizedObj; + } + if (obj && obj.toJSON) { + obj = obj.toJSON(); + } + if (typeof obj === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + const sortedKeys = []; + let key; + for (key in obj) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(obj, key)) { + sortedKeys.push(key); + } + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key = sortedKeys[i]; + canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack, replacer, key); + } + stack.pop(); + replacementStack.pop(); + } + else { + canonicalizedObj = obj; + } + return canonicalizedObj; } - ret.hunks = []; - var mineIndex = 0, - theirsIndex = 0, - mineOffset = 0, - theirsOffset = 0; - - while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) { - var mineCurrent = mine.hunks[mineIndex] || { - oldStart: Infinity - }, - theirsCurrent = theirs.hunks[theirsIndex] || { - oldStart: Infinity - }; - - if (hunkBefore(mineCurrent, theirsCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(mineCurrent, mineOffset)); - mineIndex++; - theirsOffset += mineCurrent.newLines - mineCurrent.oldLines; - } else if (hunkBefore(theirsCurrent, mineCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset)); - theirsIndex++; - mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines; - } else { - // Overlap, merge as best we can - var mergedHunk = { - oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart), - oldLines: 0, - newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset), - newLines: 0, - lines: [] - }; - mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines); - theirsIndex++; - mineIndex++; - ret.hunks.push(mergedHunk); - } + class ArrayDiff extends Diff { + tokenize(value) { + return value.slice(); + } + join(value) { + return value; + } + removeEmpty(value) { + return value; + } } - - return ret; - } - - function loadPatch(param, base) { - if (typeof param === 'string') { - if (/^@@/m.test(param) || /^Index:/m.test(param)) { - return parsePatch(param)[0]; - } - - if (!base) { - throw new Error('Must provide a base reference or pass in a patch'); - } - - return structuredPatch(undefined, undefined, base, param); + const arrayDiff = new ArrayDiff(); + function diffArrays(oldArr, newArr, options) { + return arrayDiff.diff(oldArr, newArr, options); } - return param; - } - - function fileNameChanged(patch) { - return patch.newFileName && patch.newFileName !== patch.oldFileName; - } - - function selectField(index, mine, theirs) { - if (mine === theirs) { - return mine; - } else { - index.conflict = true; - return { - mine: mine, - theirs: theirs - }; + function unixToWin(patch) { + if (Array.isArray(patch)) { + // It would be cleaner if instead of the line below we could just write + // return patch.map(unixToWin) + // but mysteriously TypeScript (v5.7.3 at the time of writing) does not like this and it will + // refuse to compile, thinking that unixToWin could then return StructuredPatch[][] and the + // result would be incompatible with the overload signatures. + // See bug report at https://github.com/microsoft/TypeScript/issues/61398. + return patch.map(p => unixToWin(p)); + } + return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map(hunk => (Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map((line, i) => { + var _a; + return (line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))) + ? line + : line + '\r'; + }) }))) }); } - } - - function hunkBefore(test, check) { - return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart; - } - - function cloneHunk(hunk, offset) { - return { - oldStart: hunk.oldStart, - oldLines: hunk.oldLines, - newStart: hunk.newStart + offset, - newLines: hunk.newLines, - lines: hunk.lines - }; - } - - function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) { - // This will generally result in a conflicted hunk, but there are cases where the context - // is the only overlap where we can successfully merge the content here. - var mine = { - offset: mineOffset, - lines: mineLines, - index: 0 - }, - their = { - offset: theirOffset, - lines: theirLines, - index: 0 - }; // Handle any leading content - - insertLeading(hunk, mine, their); - insertLeading(hunk, their, mine); // Now in the overlap content. Scan through and select the best changes from each. - - while (mine.index < mine.lines.length && their.index < their.lines.length) { - var mineCurrent = mine.lines[mine.index], - theirCurrent = their.lines[their.index]; - - if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) { - // Both modified ... - mutualChange(hunk, mine, their); - } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') { - var _hunk$lines; - - // Mine inserted - (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine))); - } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') { - var _hunk$lines2; - - // Theirs inserted - (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their))); - } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') { - // Mine removed or edited - removal(hunk, mine, their); - } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') { - // Their removed or edited - removal(hunk, their, mine, true); - } else if (mineCurrent === theirCurrent) { - // Context identity - hunk.lines.push(mineCurrent); - mine.index++; - their.index++; - } else { - // Context mismatch - conflict(hunk, collectChange(mine), collectChange(their)); - } - } // Now push anything that may be remaining - - - insertTrailing(hunk, mine); - insertTrailing(hunk, their); - calcLineCount(hunk); - } - - function mutualChange(hunk, mine, their) { - var myChanges = collectChange(mine), - theirChanges = collectChange(their); - - if (allRemoves(myChanges) && allRemoves(theirChanges)) { - // Special case for remove changes that are supersets of one another - if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) { - var _hunk$lines3; - - (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges)); - - return; - } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) { - var _hunk$lines4; - - (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges)); - - return; - } - } else if (arrayEqual(myChanges, theirChanges)) { - var _hunk$lines5; - - (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges)); - - return; + function winToUnix(patch) { + if (Array.isArray(patch)) { + // (See comment above equivalent line in unixToWin) + return patch.map(p => winToUnix(p)); + } + return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map(hunk => (Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map(line => line.endsWith('\r') ? line.substring(0, line.length - 1) : line) }))) }); } - - conflict(hunk, myChanges, theirChanges); - } - - function removal(hunk, mine, their, swap) { - var myChanges = collectChange(mine), - theirChanges = collectContext(their, myChanges); - - if (theirChanges.merged) { - var _hunk$lines6; - - (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged)); - } else { - conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges); + /** + * Returns true if the patch consistently uses Unix line endings (or only involves one line and has + * no line endings). + */ + function isUnix(patch) { + if (!Array.isArray(patch)) { + patch = [patch]; + } + return !patch.some(index => index.hunks.some(hunk => hunk.lines.some(line => !line.startsWith('\\') && line.endsWith('\r')))); } - } - - function conflict(hunk, mine, their) { - hunk.conflict = true; - hunk.lines.push({ - conflict: true, - mine: mine, - theirs: their - }); - } - - function insertLeading(hunk, insert, their) { - while (insert.offset < their.offset && insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - insert.offset++; + /** + * Returns true if the patch uses Windows line endings and only Windows line endings. + */ + function isWin(patch) { + if (!Array.isArray(patch)) { + patch = [patch]; + } + return patch.some(index => index.hunks.some(hunk => hunk.lines.some(line => line.endsWith('\r')))) + && patch.every(index => index.hunks.every(hunk => hunk.lines.every((line, i) => { var _a; return line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\')); }))); } - } - function insertTrailing(hunk, insert) { - while (insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); + /** + * Parses a patch into structured data, in the same structure returned by `structuredPatch`. + * + * @return a JSON object representation of the a patch, suitable for use with the `applyPatch` method. + */ + function parsePatch(uniDiff) { + const diffstr = uniDiff.split(/\n/), list = []; + let i = 0; + function parseIndex() { + const index = {}; + list.push(index); + // Parse diff metadata + while (i < diffstr.length) { + const line = diffstr[i]; + // File header found, end parsing diff metadata + if ((/^(---|\+\+\+|@@)\s/).test(line)) { + break; + } + // Try to parse the line as a diff header, like + // Index: README.md + // or + // diff -r 9117c6561b0b -r 273ce12ad8f1 .hgignore + // or + // Index: something with multiple words + // and extract the filename (or whatever else is used as an index name) + // from the end (i.e. 'README.md', '.hgignore', or + // 'something with multiple words' in the examples above). + // + // TODO: It seems awkward that we indiscriminately trim off trailing + // whitespace here. Theoretically, couldn't that be meaningful - + // e.g. if the patch represents a diff of a file whose name ends + // with a space? Seems wrong to nuke it. + // But this behaviour has been around since v2.2.1 in 2015, so if + // it's going to change, it should be done cautiously and in a new + // major release, for backwards-compat reasons. + // -- ExplodingCabbage + const headerMatch = (/^(?:Index:|diff(?: -r \w+)+)\s+/).exec(line); + if (headerMatch) { + index.index = line.substring(headerMatch[0].length).trim(); + } + i++; + } + // Parse file headers if they are defined. Unified diff requires them, but + // there's no technical issues to have an isolated hunk without file header + parseFileHeader(index); + parseFileHeader(index); + // Parse hunks + index.hunks = []; + while (i < diffstr.length) { + const line = diffstr[i]; + if ((/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/).test(line)) { + break; + } + else if ((/^@@/).test(line)) { + index.hunks.push(parseHunk()); + } + else if (line) { + throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(line)); + } + else { + i++; + } + } + } + // Parses the --- and +++ headers, if none are found, no lines + // are consumed. + function parseFileHeader(index) { + const fileHeaderMatch = (/^(---|\+\+\+)\s+/).exec(diffstr[i]); + if (fileHeaderMatch) { + const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split('\t', 2), header = (data[1] || '').trim(); + let fileName = data[0].replace(/\\\\/g, '\\'); + if (fileName.startsWith('"') && fileName.endsWith('"')) { + fileName = fileName.substr(1, fileName.length - 2); + } + if (prefix === '---') { + index.oldFileName = fileName; + index.oldHeader = header; + } + else { + index.newFileName = fileName; + index.newHeader = header; + } + i++; + } + } + // Parses a hunk + // This assumes that we are at the start of a hunk. + function parseHunk() { + var _a; + const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); + const hunk = { + oldStart: +chunkHeader[1], + oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], + newStart: +chunkHeader[3], + newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], + lines: [] + }; + // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + if (hunk.oldLines === 0) { + hunk.oldStart += 1; + } + if (hunk.newLines === 0) { + hunk.newStart += 1; + } + let addCount = 0, removeCount = 0; + for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))); i++) { + const operation = (diffstr[i].length == 0 && i != (diffstr.length - 1)) ? ' ' : diffstr[i][0]; + if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { + hunk.lines.push(diffstr[i]); + if (operation === '+') { + addCount++; + } + else if (operation === '-') { + removeCount++; + } + else if (operation === ' ') { + addCount++; + removeCount++; + } + } + else { + throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`); + } + } + // Handle the empty block count case + if (!addCount && hunk.newLines === 1) { + hunk.newLines = 0; + } + if (!removeCount && hunk.oldLines === 1) { + hunk.oldLines = 0; + } + // Perform sanity checking + if (addCount !== hunk.newLines) { + throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + if (removeCount !== hunk.oldLines) { + throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + return hunk; + } + while (i < diffstr.length) { + parseIndex(); + } + return list; } - } - - function collectChange(state) { - var ret = [], - operation = state.lines[state.index][0]; - - while (state.index < state.lines.length) { - var line = state.lines[state.index]; // Group additions that are immediately after subtractions and treat them as one "atomic" modify change. - - if (operation === '-' && line[0] === '+') { - operation = '+'; - } - if (operation === line[0]) { - ret.push(line); - state.index++; - } else { - break; - } + // Iterator that traverses in the range of [min, max], stepping + // by distance from a given start position. I.e. for [0, 4], with + // start of 2, this will iterate 2, 3, 1, 4, 0. + function distanceIterator (start, minLine, maxLine) { + let wantForward = true, backwardExhausted = false, forwardExhausted = false, localOffset = 1; + return function iterator() { + if (wantForward && !forwardExhausted) { + if (backwardExhausted) { + localOffset++; + } + else { + wantForward = false; + } + // Check if trying to fit beyond text length, and if not, check it fits + // after offset location (or desired location on first iteration) + if (start + localOffset <= maxLine) { + return start + localOffset; + } + forwardExhausted = true; + } + if (!backwardExhausted) { + if (!forwardExhausted) { + wantForward = true; + } + // Check if trying to fit before text beginning, and if not, check it fits + // before offset location + if (minLine <= start - localOffset) { + return start - localOffset++; + } + backwardExhausted = true; + return iterator(); + } + // We tried to fit hunk before text beginning and beyond text length, then + // hunk can't fit on the text. Return undefined + return undefined; + }; } - return ret; - } - - function collectContext(state, matchChanges) { - var changes = [], - merged = [], - matchIndex = 0, - contextChanges = false, - conflicted = false; - - while (matchIndex < matchChanges.length && state.index < state.lines.length) { - var change = state.lines[state.index], - match = matchChanges[matchIndex]; // Once we've hit our add, then we are done - - if (match[0] === '+') { - break; - } - - contextChanges = contextChanges || change[0] !== ' '; - merged.push(match); - matchIndex++; // Consume any additions in the other block as a conflict to attempt - // to pull in the remaining context after this - - if (change[0] === '+') { - conflicted = true; - - while (change[0] === '+') { - changes.push(change); - change = state.lines[++state.index]; + /** + * attempts to apply a unified diff patch. + * + * Hunks are applied first to last. + * `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly. + * If that fails, it tries scanning backwards and forwards, one line at a time, to find a place to apply the hunk where the context lines match exactly. + * If that still fails, and `fuzzFactor` is greater than zero, it increments the maximum number of mismatches (missing, extra, or changed context lines) that there can be between the hunk context and a region where we are trying to apply the patch such that the hunk will still be considered to match. + * Regardless of `fuzzFactor`, lines to be deleted in the hunk *must* be present for a hunk to match, and the context lines *immediately* before and after an insertion must match exactly. + * + * Once a hunk is successfully fitted, the process begins again with the next hunk. + * Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks. + * + * If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`. + * + * If a hunk is successfully fitted but not at the line number specified by the hunk header, all subsequent hunks have their target line number adjusted accordingly. + * (e.g. if the first hunk is applied 10 lines below where the hunk header said it should fit, `applyPatch` will *start* looking for somewhere to apply the second hunk 10 lines below where its hunk header says it goes.) + * + * If the patch was applied successfully, returns a string containing the patched text. + * If the patch could not be applied (because some hunks in the patch couldn't be fitted to the text in `source`), `applyPatch` returns false. + * + * @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods. + */ + function applyPatch(source, patch, options = {}) { + let patches; + if (typeof patch === 'string') { + patches = parsePatch(patch); } - } - - if (match.substr(1) === change.substr(1)) { - changes.push(change); - state.index++; - } else { - conflicted = true; - } + else if (Array.isArray(patch)) { + patches = patch; + } + else { + patches = [patch]; + } + if (patches.length > 1) { + throw new Error('applyPatch only works with a single input.'); + } + return applyStructuredPatch(source, patches[0], options); } - - if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) { - conflicted = true; + function applyStructuredPatch(source, patch, options = {}) { + if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) { + if (hasOnlyWinLineEndings(source) && isUnix(patch)) { + patch = unixToWin(patch); + } + else if (hasOnlyUnixLineEndings(source) && isWin(patch)) { + patch = winToUnix(patch); + } + } + // Apply the diff to the input + const lines = source.split('\n'), hunks = patch.hunks, compareLine = options.compareLine || ((lineNumber, line, operation, patchContent) => line === patchContent), fuzzFactor = options.fuzzFactor || 0; + let minLine = 0; + if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) { + throw new Error('fuzzFactor must be a non-negative integer'); + } + // Special case for empty patch. + if (!hunks.length) { + return source; + } + // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change + // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a + // newline that already exists - then we either return false and fail to apply the patch (if + // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0). + // If we do need to remove/add a newline at EOF, this will always be in the final hunk: + let prevLine = '', removeEOFNL = false, addEOFNL = false; + for (let i = 0; i < hunks[hunks.length - 1].lines.length; i++) { + const line = hunks[hunks.length - 1].lines[i]; + if (line[0] == '\\') { + if (prevLine[0] == '+') { + removeEOFNL = true; + } + else if (prevLine[0] == '-') { + addEOFNL = true; + } + } + prevLine = line; + } + if (removeEOFNL) { + if (addEOFNL) { + // This means the final line gets changed but doesn't have a trailing newline in either the + // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if + // fuzzFactor is 0, we simply validate that the source file has no trailing newline. + if (!fuzzFactor && lines[lines.length - 1] == '') { + return false; + } + } + else if (lines[lines.length - 1] == '') { + lines.pop(); + } + else if (!fuzzFactor) { + return false; + } + } + else if (addEOFNL) { + if (lines[lines.length - 1] != '') { + lines.push(''); + } + else if (!fuzzFactor) { + return false; + } + } + /** + * Checks if the hunk can be made to fit at the provided location with at most `maxErrors` + * insertions, substitutions, or deletions, while ensuring also that: + * - lines deleted in the hunk match exactly, and + * - wherever an insertion operation or block of insertion operations appears in the hunk, the + * immediately preceding and following lines of context match exactly + * + * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0]. + * + * If the hunk can be applied, returns an object with properties `oldLineLastI` and + * `replacementLines`. Otherwise, returns null. + */ + function applyHunk(hunkLines, toPos, maxErrors, hunkLinesI = 0, lastContextLineMatched = true, patchedLines = [], patchedLinesLength = 0) { + let nConsecutiveOldContextLines = 0; + let nextContextLineMustMatch = false; + for (; hunkLinesI < hunkLines.length; hunkLinesI++) { + const hunkLine = hunkLines[hunkLinesI], operation = (hunkLine.length > 0 ? hunkLine[0] : ' '), content = (hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine); + if (operation === '-') { + if (compareLine(toPos + 1, lines[toPos], operation, content)) { + toPos++; + nConsecutiveOldContextLines = 0; + } + else { + if (!maxErrors || lines[toPos] == null) { + return null; + } + patchedLines[patchedLinesLength] = lines[toPos]; + return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1); + } + } + if (operation === '+') { + if (!lastContextLineMatched) { + return null; + } + patchedLines[patchedLinesLength] = content; + patchedLinesLength++; + nConsecutiveOldContextLines = 0; + nextContextLineMustMatch = true; + } + if (operation === ' ') { + nConsecutiveOldContextLines++; + patchedLines[patchedLinesLength] = lines[toPos]; + if (compareLine(toPos + 1, lines[toPos], operation, content)) { + patchedLinesLength++; + lastContextLineMatched = true; + nextContextLineMustMatch = false; + toPos++; + } + else { + if (nextContextLineMustMatch || !maxErrors) { + return null; + } + // Consider 3 possibilities in sequence: + // 1. lines contains a *substitution* not included in the patch context, or + // 2. lines contains an *insertion* not included in the patch context, or + // 3. lines contains a *deletion* not included in the patch context + // The first two options are of course only possible if the line from lines is non-null - + // i.e. only option 3 is possible if we've overrun the end of the old file. + return (lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength)); + } + } + } + // Before returning, trim any unmodified context lines off the end of patchedLines and reduce + // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region + // that starts in this hunk's trailing context. + patchedLinesLength -= nConsecutiveOldContextLines; + toPos -= nConsecutiveOldContextLines; + patchedLines.length = patchedLinesLength; + return { + patchedLines, + oldLineLastI: toPos - 1 + }; + } + const resultLines = []; + // Search best fit offsets for each hunk based on the previous ones + let prevHunkOffset = 0; + for (let i = 0; i < hunks.length; i++) { + const hunk = hunks[i]; + let hunkResult; + const maxLine = lines.length - hunk.oldLines + fuzzFactor; + let toPos; + for (let maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) { + toPos = hunk.oldStart + prevHunkOffset - 1; + const iterator = distanceIterator(toPos, minLine, maxLine); + for (; toPos !== undefined; toPos = iterator()) { + hunkResult = applyHunk(hunk.lines, toPos, maxErrors); + if (hunkResult) { + break; + } + } + if (hunkResult) { + break; + } + } + if (!hunkResult) { + return false; + } + // Copy everything from the end of where we applied the last hunk to the start of this hunk + for (let i = minLine; i < toPos; i++) { + resultLines.push(lines[i]); + } + // Add the lines produced by applying the hunk: + for (let i = 0; i < hunkResult.patchedLines.length; i++) { + const line = hunkResult.patchedLines[i]; + resultLines.push(line); + } + // Set lower text limit to end of the current hunk, so next ones don't try + // to fit over already patched text + minLine = hunkResult.oldLineLastI + 1; + // Note the offset between where the patch said the hunk should've applied and where we + // applied it, so we can adjust future hunks accordingly: + prevHunkOffset = toPos + 1 - hunk.oldStart; + } + // Copy over the rest of the lines from the old text + for (let i = minLine; i < lines.length; i++) { + resultLines.push(lines[i]); + } + return resultLines.join('\n'); } - - if (conflicted) { - return changes; + /** + * applies one or more patches. + * + * `patch` may be either an array of structured patch objects, or a string representing a patch in unified diff format (which may patch one or more files). + * + * This method will iterate over the contents of the patch and apply to data provided through callbacks. The general flow for each patch index is: + * + * - `options.loadFile(index, callback)` is called. The caller should then load the contents of the file and then pass that to the `callback(err, data)` callback. Passing an `err` will terminate further patch execution. + * - `options.patched(index, content, callback)` is called once the patch has been applied. `content` will be the return value from `applyPatch`. When it's ready, the caller should call `callback(err)` callback. Passing an `err` will terminate further patch execution. + * + * Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made. + */ + function applyPatches(uniDiff, options) { + const spDiff = typeof uniDiff === 'string' ? parsePatch(uniDiff) : uniDiff; + let currentIndex = 0; + function processIndex() { + const index = spDiff[currentIndex++]; + if (!index) { + return options.complete(); + } + options.loadFile(index, function (err, data) { + if (err) { + return options.complete(err); + } + const updatedContent = applyPatch(data, index, options); + options.patched(index, updatedContent, function (err) { + if (err) { + return options.complete(err); + } + processIndex(); + }); + }); + } + processIndex(); } - while (matchIndex < matchChanges.length) { - merged.push(matchChanges[matchIndex++]); + function reversePatch(structuredPatch) { + if (Array.isArray(structuredPatch)) { + // (See comment in unixToWin for why we need the pointless-looking anonymous function here) + return structuredPatch.map(patch => reversePatch(patch)).reverse(); + } + return Object.assign(Object.assign({}, structuredPatch), { oldFileName: structuredPatch.newFileName, oldHeader: structuredPatch.newHeader, newFileName: structuredPatch.oldFileName, newHeader: structuredPatch.oldHeader, hunks: structuredPatch.hunks.map(hunk => { + return { + oldLines: hunk.newLines, + oldStart: hunk.newStart, + newLines: hunk.oldLines, + newStart: hunk.oldStart, + lines: hunk.lines.map(l => { + if (l.startsWith('-')) { + return `+${l.slice(1)}`; + } + if (l.startsWith('+')) { + return `-${l.slice(1)}`; + } + return l; + }) + }; + }) }); } - return { - merged: merged, - changes: changes + const INCLUDE_HEADERS = { + includeIndex: true, + includeUnderline: true, + includeFileHeaders: true }; - } - - function allRemoves(changes) { - return changes.reduce(function (prev, change) { - return prev && change[0] === '-'; - }, true); - } - - function skipRemoveSuperset(state, removeChanges, delta) { - for (var i = 0; i < delta; i++) { - var changeContent = removeChanges[removeChanges.length - delta + i].substr(1); - - if (state.lines[state.index + i] !== ' ' + changeContent) { - return false; - } + const FILE_HEADERS_ONLY = { + includeIndex: false, + includeUnderline: false, + includeFileHeaders: true + }; + const OMIT_HEADERS = { + includeIndex: false, + includeUnderline: false, + includeFileHeaders: false + }; + function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + let optionsObj; + if (!options) { + optionsObj = {}; + } + else if (typeof options === 'function') { + optionsObj = { callback: options }; + } + else { + optionsObj = options; + } + if (typeof optionsObj.context === 'undefined') { + optionsObj.context = 4; + } + // We copy this into its own variable to placate TypeScript, which thinks + // optionsObj.context might be undefined in the callbacks below. + const context = optionsObj.context; + // @ts-expect-error (runtime check for something that is correctly a static type error) + if (optionsObj.newlineIsToken) { + throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions'); + } + if (!optionsObj.callback) { + return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj)); + } + else { + const { callback } = optionsObj; + diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => { + const patch = diffLinesResultToPatch(diff); + // TypeScript is unhappy without the cast because it does not understand that `patch` may + // be undefined here only if `callback` is StructuredPatchCallbackAbortable: + callback(patch); + } })); + } + function diffLinesResultToPatch(diff) { + // STEP 1: Build up the patch with no "\ No newline at end of file" lines and with the arrays + // of lines containing trailing newline characters. We'll tidy up later... + if (!diff) { + return; + } + diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier + function contextLines(lines) { + return lines.map(function (entry) { return ' ' + entry; }); + } + const hunks = []; + let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1; + for (let i = 0; i < diff.length; i++) { + const current = diff[i], lines = current.lines || splitLines(current.value); + current.lines = lines; + if (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + const prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; + if (prev) { + curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : []; + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } + // Output our changes + for (const line of lines) { + curRange.push((current.added ? '+' : '-') + line); + } + // Track the updated file position + if (current.added) { + newLine += lines.length; + } + else { + oldLine += lines.length; + } + } + else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= context * 2 && i < diff.length - 2) { + // Overlapping + for (const line of contextLines(lines)) { + curRange.push(line); + } + } + else { + // end the range and output + const contextSize = Math.min(lines.length, context); + for (const line of contextLines(lines.slice(0, contextSize))) { + curRange.push(line); + } + const hunk = { + oldStart: oldRangeStart, + oldLines: (oldLine - oldRangeStart + contextSize), + newStart: newRangeStart, + newLines: (newLine - newRangeStart + contextSize), + lines: curRange + }; + hunks.push(hunk); + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } + // Step 2: eliminate the trailing `\n` from each line of each hunk, and, where needed, add + // "\ No newline at end of file". + for (const hunk of hunks) { + for (let i = 0; i < hunk.lines.length; i++) { + if (hunk.lines[i].endsWith('\n')) { + hunk.lines[i] = hunk.lines[i].slice(0, -1); + } + else { + hunk.lines.splice(i + 1, 0, '\\ No newline at end of file'); + i++; // Skip the line we just added, then continue iterating + } + } + } + return { + oldFileName: oldFileName, newFileName: newFileName, + oldHeader: oldHeader, newHeader: newHeader, + hunks: hunks + }; + } } - - state.index += delta; - return true; - } - - function calcOldNewLineCount(lines) { - var oldLines = 0; - var newLines = 0; - lines.forEach(function (line) { - if (typeof line !== 'string') { - var myCount = calcOldNewLineCount(line.mine); - var theirCount = calcOldNewLineCount(line.theirs); - - if (oldLines !== undefined) { - if (myCount.oldLines === theirCount.oldLines) { - oldLines += myCount.oldLines; - } else { - oldLines = undefined; - } + /** + * creates a unified diff patch. + * @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`) + */ + function formatPatch(patch, headerOptions) { + if (!headerOptions) { + headerOptions = INCLUDE_HEADERS; } - - if (newLines !== undefined) { - if (myCount.newLines === theirCount.newLines) { - newLines += myCount.newLines; - } else { - newLines = undefined; - } + if (Array.isArray(patch)) { + if (patch.length > 1 && !headerOptions.includeFileHeaders) { + throw new Error('Cannot omit file headers on a multi-file patch. ' + + '(The result would be unparseable; how would a tool trying to apply ' + + 'the patch know which changes are to which file?)'); + } + return patch.map(p => formatPatch(p, headerOptions)).join('\n'); } - } else { - if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) { - newLines++; + const ret = []; + if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) { + ret.push('Index: ' + patch.oldFileName); } - - if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) { - oldLines++; - } - } - }); - return { - oldLines: oldLines, - newLines: newLines - }; - } - - // See: http://code.google.com/p/google-diff-match-patch/wiki/API - function convertChangesToDMP(changes) { - var ret = [], - change, - operation; - - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); + if (headerOptions.includeUnderline) { + ret.push('==================================================================='); + } + if (headerOptions.includeFileHeaders) { + ret.push('--- ' + patch.oldFileName + (typeof patch.oldHeader === 'undefined' ? '' : '\t' + patch.oldHeader)); + ret.push('+++ ' + patch.newFileName + (typeof patch.newHeader === 'undefined' ? '' : '\t' + patch.newHeader)); + } + for (let i = 0; i < patch.hunks.length; i++) { + const hunk = patch.hunks[i]; + // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + if (hunk.oldLines === 0) { + hunk.oldStart -= 1; + } + if (hunk.newLines === 0) { + hunk.newStart -= 1; + } + ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + + ' +' + hunk.newStart + ',' + hunk.newLines + + ' @@'); + for (const line of hunk.lines) { + ret.push(line); + } + } + return ret.join('\n') + '\n'; } - - return ret; - } - - function convertChangesToXML(changes) { - var ret = []; - - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - - if (change.added) { - ret.push('<ins>'); - } else if (change.removed) { - ret.push('<del>'); - } - - ret.push(escapeHTML(change.value)); - - if (change.added) { - ret.push('</ins>'); - } else if (change.removed) { - ret.push('</del>'); - } + function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + if (typeof options === 'function') { + options = { callback: options }; + } + if (!(options === null || options === void 0 ? void 0 : options.callback)) { + const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); + if (!patchObj) { + return; + } + return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions); + } + else { + const { callback } = options; + structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: patchObj => { + if (!patchObj) { + callback(undefined); + } + else { + callback(formatPatch(patchObj, options.headerOptions)); + } + } })); + } + } + function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { + return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); + } + /** + * Split `text` into an array of lines, including the trailing newline character (where present) + */ + function splitLines(text) { + const hasTrailingNl = text.endsWith('\n'); + const result = text.split('\n').map(line => line + '\n'); + if (hasTrailingNl) { + result.pop(); + } + else { + result.push(result.pop().slice(0, -1)); + } + return result; } - return ret.join(''); - } - - function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(/</g, '<'); - n = n.replace(/>/g, '>'); - n = n.replace(/"/g, '"'); - return n; - } - - exports.Diff = Diff; - exports.applyPatch = applyPatch; - exports.applyPatches = applyPatches; - exports.canonicalize = canonicalize; - exports.convertChangesToDMP = convertChangesToDMP; - exports.convertChangesToXML = convertChangesToXML; - exports.createPatch = createPatch; - exports.createTwoFilesPatch = createTwoFilesPatch; - exports.diffArrays = diffArrays; - exports.diffChars = diffChars; - exports.diffCss = diffCss; - exports.diffJson = diffJson; - exports.diffLines = diffLines; - exports.diffSentences = diffSentences; - exports.diffTrimmedLines = diffTrimmedLines; - exports.diffWords = diffWords; - exports.diffWordsWithSpace = diffWordsWithSpace; - exports.merge = merge; - exports.parsePatch = parsePatch; - exports.structuredPatch = structuredPatch; + /** + * converts a list of change objects to the format returned by Google's [diff-match-patch](https://github.com/google/diff-match-patch) library + */ + function convertChangesToDMP(changes) { + const ret = []; + let change, operation; + for (let i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } + else if (change.removed) { + operation = -1; + } + else { + operation = 0; + } + ret.push([operation, change.value]); + } + return ret; + } - Object.defineProperty(exports, '__esModule', { value: true }); + /** + * converts a list of change objects to a serialized XML format + */ + function convertChangesToXML(changes) { + const ret = []; + for (let i = 0; i < changes.length; i++) { + const change = changes[i]; + if (change.added) { + ret.push('<ins>'); + } + else if (change.removed) { + ret.push('<del>'); + } + ret.push(escapeHTML(change.value)); + if (change.added) { + ret.push('</ins>'); + } + else if (change.removed) { + ret.push('</del>'); + } + } + return ret.join(''); + } + function escapeHTML(s) { + let n = s; + n = n.replace(/&/g, '&'); + n = n.replace(/</g, '<'); + n = n.replace(/>/g, '>'); + n = n.replace(/"/g, '"'); + return n; + } -}))); + exports.Diff = Diff; + exports.FILE_HEADERS_ONLY = FILE_HEADERS_ONLY; + exports.INCLUDE_HEADERS = INCLUDE_HEADERS; + exports.OMIT_HEADERS = OMIT_HEADERS; + exports.applyPatch = applyPatch; + exports.applyPatches = applyPatches; + exports.arrayDiff = arrayDiff; + exports.canonicalize = canonicalize; + exports.characterDiff = characterDiff; + exports.convertChangesToDMP = convertChangesToDMP; + exports.convertChangesToXML = convertChangesToXML; + exports.createPatch = createPatch; + exports.createTwoFilesPatch = createTwoFilesPatch; + exports.cssDiff = cssDiff; + exports.diffArrays = diffArrays; + exports.diffChars = diffChars; + exports.diffCss = diffCss; + exports.diffJson = diffJson; + exports.diffLines = diffLines; + exports.diffSentences = diffSentences; + exports.diffTrimmedLines = diffTrimmedLines; + exports.diffWords = diffWords; + exports.diffWordsWithSpace = diffWordsWithSpace; + exports.formatPatch = formatPatch; + exports.jsonDiff = jsonDiff; + exports.lineDiff = lineDiff; + exports.parsePatch = parsePatch; + exports.reversePatch = reversePatch; + exports.sentenceDiff = sentenceDiff; + exports.structuredPatch = structuredPatch; + exports.wordDiff = wordDiff; + exports.wordsWithSpaceDiff = wordsWithSpaceDiff; + +})); diff --git a/node_modules/diff/dist/diff.min.js b/node_modules/diff/dist/diff.min.js new file mode 100644 index 0000000000000..8ae55324ed93b --- /dev/null +++ b/node_modules/diff/dist/diff.min.js @@ -0,0 +1 @@ +((global,factory)=>{"object"==typeof exports&&"undefined"!=typeof module?factory(exports):"function"==typeof define&&define.amd?define(["exports"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Diff={})})(this,function(exports){class Diff{diff(oldStr,newStr,options={}){let callback;"function"==typeof options?(callback=options,options={}):"callback"in options&&(callback=options.callback);oldStr=this.castInput(oldStr,options),newStr=this.castInput(newStr,options),oldStr=this.removeEmpty(this.tokenize(oldStr,options)),newStr=this.removeEmpty(this.tokenize(newStr,options));return this.diffWithOptionsObj(oldStr,newStr,options,callback)}diffWithOptionsObj(oldTokens,newTokens,options,callback){let _a,done=value=>{if(value=this.postProcess(value,options),!callback)return value;setTimeout(function(){callback(value)},0)},newLen=newTokens.length,oldLen=oldTokens.length,editLength=1,maxEditLength=newLen+oldLen;null!=options.maxEditLength&&(maxEditLength=Math.min(maxEditLength,options.maxEditLength));var maxExecutionTime=null!=(_a=options.timeout)?_a:1/0;let abortAfterTimestamp=Date.now()+maxExecutionTime,bestPath=[{oldPos:-1,lastComponent:void 0}],newPos=this.extractCommon(bestPath[0],newTokens,oldTokens,0,options);if(bestPath[0].oldPos+1>=oldLen&&newPos+1>=newLen)return done(this.buildValues(bestPath[0].lastComponent,newTokens,oldTokens));let minDiagonalToConsider=-1/0,maxDiagonalToConsider=1/0,execEditLength=()=>{for(let diagonalPath=Math.max(minDiagonalToConsider,-editLength);diagonalPath<=Math.min(maxDiagonalToConsider,editLength);diagonalPath+=2){let basePath;var removePath=bestPath[diagonalPath-1],addPath=bestPath[diagonalPath+1];removePath&&(bestPath[diagonalPath-1]=void 0);let canAdd=!1;addPath&&(addPathNewPos=addPath.oldPos-diagonalPath,canAdd=addPath&&0<=addPathNewPos&&addPathNewPos<newLen);var addPathNewPos=removePath&&removePath.oldPos+1<oldLen;if(canAdd||addPathNewPos){if(basePath=!addPathNewPos||canAdd&&removePath.oldPos<addPath.oldPos?this.addToPath(addPath,!0,!1,0,options):this.addToPath(removePath,!1,!0,1,options),newPos=this.extractCommon(basePath,newTokens,oldTokens,diagonalPath,options),basePath.oldPos+1>=oldLen&&newPos+1>=newLen)return done(this.buildValues(basePath.lastComponent,newTokens,oldTokens))||!0;(bestPath[diagonalPath]=basePath).oldPos+1>=oldLen&&(maxDiagonalToConsider=Math.min(maxDiagonalToConsider,diagonalPath-1)),newPos+1>=newLen&&(minDiagonalToConsider=Math.max(minDiagonalToConsider,diagonalPath+1))}else bestPath[diagonalPath]=void 0}editLength++};if(callback)!function exec(){setTimeout(function(){if(editLength>maxEditLength||Date.now()>abortAfterTimestamp)return callback(void 0);execEditLength()||exec()},0)}();else for(;editLength<=maxEditLength&&Date.now()<=abortAfterTimestamp;){var ret=execEditLength();if(ret)return ret}}addToPath(path,added,removed,oldPosInc,options){var last=path.lastComponent;return last&&!options.oneChangePerToken&&last.added===added&&last.removed===removed?{oldPos:path.oldPos+oldPosInc,lastComponent:{count:last.count+1,added:added,removed:removed,previousComponent:last.previousComponent}}:{oldPos:path.oldPos+oldPosInc,lastComponent:{count:1,added:added,removed:removed,previousComponent:last}}}extractCommon(basePath,newTokens,oldTokens,diagonalPath,options){var newLen=newTokens.length,oldLen=oldTokens.length;let oldPos=basePath.oldPos,newPos=oldPos-diagonalPath,commonCount=0;for(;newPos+1<newLen&&oldPos+1<oldLen&&this.equals(oldTokens[oldPos+1],newTokens[newPos+1],options);)newPos++,oldPos++,commonCount++,options.oneChangePerToken&&(basePath.lastComponent={count:1,previousComponent:basePath.lastComponent,added:!1,removed:!1});return commonCount&&!options.oneChangePerToken&&(basePath.lastComponent={count:commonCount,previousComponent:basePath.lastComponent,added:!1,removed:!1}),basePath.oldPos=oldPos,newPos}equals(left,right,options){return options.comparator?options.comparator(left,right):left===right||!!options.ignoreCase&&left.toLowerCase()===right.toLowerCase()}removeEmpty(array){var ret=[];for(let i=0;i<array.length;i++)array[i]&&ret.push(array[i]);return ret}castInput(value,options){return value}tokenize(value,options){return Array.from(value)}join(chars){return chars.join("")}postProcess(changeObjects,options){return changeObjects}get useLongestToken(){return!1}buildValues(lastComponent,newTokens,oldTokens){for(var nextComponent,components=[];lastComponent;)components.push(lastComponent),nextComponent=lastComponent.previousComponent,delete lastComponent.previousComponent,lastComponent=nextComponent;components.reverse();var componentLen=components.length;let componentPos=0,newPos=0,oldPos=0;for(;componentPos<componentLen;componentPos++){var component=components[componentPos];if(component.removed)component.value=this.join(oldTokens.slice(oldPos,oldPos+component.count)),oldPos+=component.count;else{if(!component.added&&this.useLongestToken){let value=newTokens.slice(newPos,newPos+component.count);value=value.map(function(value,i){i=oldTokens[oldPos+i];return i.length>value.length?i:value}),component.value=this.join(value)}else component.value=this.join(newTokens.slice(newPos,newPos+component.count));newPos+=component.count,component.added||(oldPos+=component.count)}}return components}}class CharacterDiff extends Diff{}let characterDiff=new CharacterDiff;function longestCommonPrefix(str1,str2){let i;for(i=0;i<str1.length&&i<str2.length;i++)if(str1[i]!=str2[i])return str1.slice(0,i);return str1.slice(0,i)}function longestCommonSuffix(str1,str2){let i;if(!str1||!str2||str1[str1.length-1]!=str2[str2.length-1])return"";for(i=0;i<str1.length&&i<str2.length;i++)if(str1[str1.length-(i+1)]!=str2[str2.length-(i+1)])return str1.slice(-i);return str1.slice(-i)}function replacePrefix(string,oldPrefix,newPrefix){if(string.slice(0,oldPrefix.length)!=oldPrefix)throw Error(`string ${JSON.stringify(string)} doesn't start with prefix ${JSON.stringify(oldPrefix)}; this is a bug`);return newPrefix+string.slice(oldPrefix.length)}function replaceSuffix(string,oldSuffix,newSuffix){if(!oldSuffix)return string+newSuffix;if(string.slice(-oldSuffix.length)!=oldSuffix)throw Error(`string ${JSON.stringify(string)} doesn't end with suffix ${JSON.stringify(oldSuffix)}; this is a bug`);return string.slice(0,-oldSuffix.length)+newSuffix}function removePrefix(string,oldPrefix){return replacePrefix(string,oldPrefix,"")}function removeSuffix(string,oldSuffix){return replaceSuffix(string,oldSuffix,"")}function maximumOverlap(string1,string2){return string2.slice(0,((a,b)=>{let startA=0,endB=(a.length>b.length&&(startA=a.length-b.length),b.length),map=(a.length<b.length&&(endB=a.length),Array(endB)),k=0;map[0]=0;for(let j=1;j<endB;j++){for(b[j]==b[k]?map[j]=map[k]:map[j]=k;0<k&&b[j]!=b[k];)k=map[k];b[j]==b[k]&&k++}k=0;for(let i=startA;i<a.length;i++){for(;0<k&&a[i]!=b[k];)k=map[k];a[i]==b[k]&&k++}return k})(string1,string2))}function trailingWs(string){let i;for(i=string.length-1;0<=i&&string[i].match(/\s/);i--);return string.substring(i+1)}function leadingWs(string){string=string.match(/^\s*/);return string?string[0]:""}let extendedWordChars="a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}",tokenizeIncludingWhitespace=new RegExp(`[${extendedWordChars}]+|\\s+|[^${extendedWordChars}]`,"ug");class WordDiff extends Diff{equals(left,right,options){return options.ignoreCase&&(left=left.toLowerCase(),right=right.toLowerCase()),left.trim()===right.trim()}tokenize(value,options={}){let parts;if(options.intlSegmenter){var segmentObj,options=options.intlSegmenter;if("word"!=options.resolvedOptions().granularity)throw new Error('The segmenter passed must have a granularity of "word"');parts=[];for(segmentObj of Array.from(options.segment(value))){var segment=segmentObj.segment;parts.length&&/\s/.test(parts[parts.length-1])&&/\s/.test(segment)?parts[parts.length-1]+=segment:parts.push(segment)}}else parts=value.match(tokenizeIncludingWhitespace)||[];let tokens=[],prevPart=null;return parts.forEach(part=>{/\s/.test(part)?null==prevPart?tokens.push(part):tokens.push(tokens.pop()+part):null!=prevPart&&/\s/.test(prevPart)?tokens[tokens.length-1]==prevPart?tokens.push(tokens.pop()+part):tokens.push(prevPart+part):tokens.push(part),prevPart=part}),tokens}join(tokens){return tokens.map((token,i)=>0==i?token:token.replace(/^\s+/,"")).join("")}postProcess(changes,options){if(changes&&!options.oneChangePerToken){let lastKeep=null,insertion=null,deletion=null;changes.forEach(change=>{change.added?insertion=change:deletion=change.removed?change:((insertion||deletion)&&dedupeWhitespaceInChangeObjects(lastKeep,deletion,insertion,change),lastKeep=change,insertion=null)}),(insertion||deletion)&&dedupeWhitespaceInChangeObjects(lastKeep,deletion,insertion,null)}return changes}}let wordDiff=new WordDiff;function dedupeWhitespaceInChangeObjects(startKeep,deletion,insertion,endKeep){if(deletion&&insertion){var oldWsPrefix=leadingWs(deletion.value),oldWsSuffix=trailingWs(deletion.value),newWsPrefix=leadingWs(insertion.value),newWsSuffix=trailingWs(insertion.value);startKeep&&(oldWsPrefix=longestCommonPrefix(oldWsPrefix,newWsPrefix),startKeep.value=replaceSuffix(startKeep.value,newWsPrefix,oldWsPrefix),deletion.value=removePrefix(deletion.value,oldWsPrefix),insertion.value=removePrefix(insertion.value,oldWsPrefix)),endKeep&&(newWsPrefix=longestCommonSuffix(oldWsSuffix,newWsSuffix),endKeep.value=replacePrefix(endKeep.value,newWsSuffix,newWsPrefix),deletion.value=removeSuffix(deletion.value,newWsPrefix),insertion.value=removeSuffix(insertion.value,newWsPrefix))}else if(insertion){if(startKeep&&(oldWsPrefix=leadingWs(insertion.value),insertion.value=insertion.value.substring(oldWsPrefix.length)),endKeep){let ws=leadingWs(endKeep.value);endKeep.value=endKeep.value.substring(ws.length)}}else if(startKeep&&endKeep){oldWsSuffix=leadingWs(endKeep.value),newWsSuffix=leadingWs(deletion.value),newWsPrefix=trailingWs(deletion.value),insertion=longestCommonPrefix(oldWsSuffix,newWsSuffix),oldWsPrefix=(deletion.value=removePrefix(deletion.value,insertion),longestCommonSuffix(removePrefix(oldWsSuffix,insertion),newWsPrefix));deletion.value=removeSuffix(deletion.value,oldWsPrefix),endKeep.value=replacePrefix(endKeep.value,oldWsSuffix,oldWsPrefix),startKeep.value=replaceSuffix(startKeep.value,oldWsSuffix,oldWsSuffix.slice(0,oldWsSuffix.length-oldWsPrefix.length))}else if(endKeep){newWsSuffix=leadingWs(endKeep.value),insertion=maximumOverlap(trailingWs(deletion.value),newWsSuffix);deletion.value=removeSuffix(deletion.value,insertion)}else if(startKeep){let overlap=maximumOverlap(trailingWs(startKeep.value),leadingWs(deletion.value));deletion.value=removePrefix(deletion.value,overlap)}}class WordsWithSpaceDiff extends Diff{tokenize(value){var regex=new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`,"ug");return value.match(regex)||[]}}let wordsWithSpaceDiff=new WordsWithSpaceDiff;function diffWordsWithSpace(oldStr,newStr,options){return wordsWithSpaceDiff.diff(oldStr,newStr,options)}class LineDiff extends Diff{constructor(){super(...arguments),this.tokenize=tokenize}equals(left,right,options){return options.ignoreWhitespace?(options.newlineIsToken&&left.includes("\n")||(left=left.trim()),options.newlineIsToken&&right.includes("\n")||(right=right.trim())):options.ignoreNewlineAtEof&&!options.newlineIsToken&&(left.endsWith("\n")&&(left=left.slice(0,-1)),right.endsWith("\n"))&&(right=right.slice(0,-1)),super.equals(left,right,options)}}let lineDiff=new LineDiff;function diffLines(oldStr,newStr,options){return lineDiff.diff(oldStr,newStr,options)}function tokenize(value,options){var retLines=[],linesAndNewlines=(value=options.stripTrailingCr?value.replace(/\r\n/g,"\n"):value).split(/(\n|\r\n)/);linesAndNewlines[linesAndNewlines.length-1]||linesAndNewlines.pop();for(let i=0;i<linesAndNewlines.length;i++){var line=linesAndNewlines[i];i%2&&!options.newlineIsToken?retLines[retLines.length-1]+=line:retLines.push(line)}return retLines}class SentenceDiff extends Diff{tokenize(value){var _a,char,result=[];let tokenStartI=0;for(let i=0;i<value.length;i++){if(i==value.length-1){result.push(value.slice(tokenStartI));break}if(("."==(char=value[i])||"!"==char||"?"==char)&&value[i+1].match(/\s/)){for(result.push(value.slice(tokenStartI,i+1)),i=tokenStartI=i+1;null!=(_a=value[i+1])&&_a.match(/\s/);)i++;result.push(value.slice(tokenStartI,i+1)),tokenStartI=i+1}}return result}}let sentenceDiff=new SentenceDiff;class CssDiff extends Diff{tokenize(value){return value.split(/([{}:;,]|\s+)/)}}let cssDiff=new CssDiff;class JsonDiff extends Diff{constructor(){super(...arguments),this.tokenize=tokenize}get useLongestToken(){return!0}castInput(value,options){let{undefinedReplacement,stringifyReplacer=(k,v)=>void 0===v?undefinedReplacement:v}=options;return"string"==typeof value?value:JSON.stringify(canonicalize(value,null,null,stringifyReplacer),null," ")}equals(left,right,options){return super.equals(left.replace(/,([\r\n])/g,"$1"),right.replace(/,([\r\n])/g,"$1"),options)}}let jsonDiff=new JsonDiff;function canonicalize(obj,stack,replacementStack,replacer,key){stack=stack||[],replacementStack=replacementStack||[],replacer&&(obj=replacer(void 0===key?"":key,obj));let i;for(i=0;i<stack.length;i+=1)if(stack[i]===obj)return replacementStack[i];let canonicalizedObj;if("[object Array]"===Object.prototype.toString.call(obj)){for(stack.push(obj),canonicalizedObj=new Array(obj.length),replacementStack.push(canonicalizedObj),i=0;i<obj.length;i+=1)canonicalizedObj[i]=canonicalize(obj[i],stack,replacementStack,replacer,String(i));stack.pop(),replacementStack.pop()}else if("object"==typeof(obj=obj&&obj.toJSON?obj.toJSON():obj)&&null!==obj){stack.push(obj),canonicalizedObj={},replacementStack.push(canonicalizedObj);var sortedKeys=[];let key;for(key in obj)Object.prototype.hasOwnProperty.call(obj,key)&&sortedKeys.push(key);for(sortedKeys.sort(),i=0;i<sortedKeys.length;i+=1)key=sortedKeys[i],canonicalizedObj[key]=canonicalize(obj[key],stack,replacementStack,replacer,key);stack.pop(),replacementStack.pop()}else canonicalizedObj=obj;return canonicalizedObj}class ArrayDiff extends Diff{tokenize(value){return value.slice()}join(value){return value}removeEmpty(value){return value}}let arrayDiff=new ArrayDiff;function parsePatch(uniDiff){let diffstr=uniDiff.split(/\n/),list=[],i=0;function parseIndex(){var index={};for(list.push(index);i<diffstr.length;){var line=diffstr[i];if(/^(---|\+\+\+|@@)\s/.test(line))break;var headerMatch=/^(?:Index:|diff(?: -r \w+)+)\s+/.exec(line);headerMatch&&(index.index=line.substring(headerMatch[0].length).trim()),i++}for(parseFileHeader(index),parseFileHeader(index),index.hunks=[];i<diffstr.length;){let line=diffstr[i];if(/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line))break;if(/^@@/.test(line))index.hunks.push((()=>{var chunkHeaderIndex=i,chunkHeaderLine=diffstr[i++],hunk={oldStart:+(chunkHeaderLine=chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/))[1],oldLines:void 0===chunkHeaderLine[2]?1:+chunkHeaderLine[2],newStart:+chunkHeaderLine[3],newLines:void 0===chunkHeaderLine[4]?1:+chunkHeaderLine[4],lines:[]};0===hunk.oldLines&&(hunk.oldStart+=1),0===hunk.newLines&&(hunk.newStart+=1);let addCount=0,removeCount=0;for(;i<diffstr.length&&(removeCount<hunk.oldLines||addCount<hunk.newLines||null!=(_a=diffstr[i])&&_a.startsWith("\\"));i++){var _a=0==diffstr[i].length&&i!=diffstr.length-1?" ":diffstr[i][0];if("+"!==_a&&"-"!==_a&&" "!==_a&&"\\"!==_a)throw new Error(`Hunk at line ${chunkHeaderIndex+1} contained invalid line `+diffstr[i]);hunk.lines.push(diffstr[i]),"+"===_a?addCount++:"-"===_a?removeCount++:" "===_a&&(addCount++,removeCount++)}if(addCount||1!==hunk.newLines||(hunk.newLines=0),removeCount||1!==hunk.oldLines||(hunk.oldLines=0),addCount!==hunk.newLines)throw new Error("Added line count did not match for hunk at line "+(chunkHeaderIndex+1));if(removeCount===hunk.oldLines)return hunk;throw new Error("Removed line count did not match for hunk at line "+(chunkHeaderIndex+1))})());else{if(line)throw new Error("Unknown line "+(i+1)+" "+JSON.stringify(line));i++}}}function parseFileHeader(index){var fileHeaderMatch=/^(---|\+\+\+)\s+/.exec(diffstr[i]);if(fileHeaderMatch){var fileHeaderMatch=fileHeaderMatch[1],data=diffstr[i].substring(3).trim().split("\t",2),header=(data[1]||"").trim();let fileName=data[0].replace(/\\\\/g,"\\");fileName.startsWith('"')&&fileName.endsWith('"')&&(fileName=fileName.substr(1,fileName.length-2)),"---"===fileHeaderMatch?(index.oldFileName=fileName,index.oldHeader=header):(index.newFileName=fileName,index.newHeader=header),i++}}for(;i<diffstr.length;)parseIndex();return list}function applyPatch(source,patch,options={}){let patches;if(1<(patches="string"==typeof patch?parsePatch(patch):Array.isArray(patch)?patch:[patch]).length)throw new Error("applyPatch only works with a single input.");return((source,patch,options={})=>{!options.autoConvertLineEndings&&null!=options.autoConvertLineEndings||((string=>string.includes("\r\n")&&!string.startsWith("\n")&&!string.match(/[^\r]\n/))(source)&&(patch=>!(patch=Array.isArray(patch)?patch:[patch]).some(index=>index.hunks.some(hunk=>hunk.lines.some(line=>!line.startsWith("\\")&&line.endsWith("\r")))))(patch)?patch=function unixToWin(patch){return Array.isArray(patch)?patch.map(p=>unixToWin(p)):Object.assign(Object.assign({},patch),{hunks:patch.hunks.map(hunk=>Object.assign(Object.assign({},hunk),{lines:hunk.lines.map((line,i)=>line.startsWith("\\")||line.endsWith("\r")||null!=(i=hunk.lines[i+1])&&i.startsWith("\\")?line:line+"\r")}))})}(patch):(string=>!string.includes("\r\n")&&string.includes("\n"))(source)&&(patch=>(patch=Array.isArray(patch)?patch:[patch]).some(index=>index.hunks.some(hunk=>hunk.lines.some(line=>line.endsWith("\r"))))&&patch.every(index=>index.hunks.every(hunk=>hunk.lines.every((line,i)=>line.startsWith("\\")||line.endsWith("\r")||(null==(line=hunk.lines[i+1])?void 0:line.startsWith("\\"))))))(patch)&&(patch=function winToUnix(patch){return Array.isArray(patch)?patch.map(p=>winToUnix(p)):Object.assign(Object.assign({},patch),{hunks:patch.hunks.map(hunk=>Object.assign(Object.assign({},hunk),{lines:hunk.lines.map(line=>line.endsWith("\r")?line.substring(0,line.length-1):line)}))})}(patch)));let lines=source.split("\n"),hunks=patch.hunks,compareLine=options.compareLine||((lineNumber,line,operation,patchContent)=>line===patchContent),fuzzFactor=options.fuzzFactor||0,minLine=0;if(fuzzFactor<0||!Number.isInteger(fuzzFactor))throw new Error("fuzzFactor must be a non-negative integer");if(!hunks.length)return source;let prevLine="",removeEOFNL=!1,addEOFNL=!1;for(let i=0;i<hunks[hunks.length-1].lines.length;i++){var line=hunks[hunks.length-1].lines[i];"\\"==line[0]&&("+"==prevLine[0]?removeEOFNL=!0:"-"==prevLine[0]&&(addEOFNL=!0)),prevLine=line}if(removeEOFNL){if(addEOFNL){if(!fuzzFactor&&""==lines[lines.length-1])return!1}else if(""==lines[lines.length-1])lines.pop();else if(!fuzzFactor)return!1}else if(addEOFNL)if(""!=lines[lines.length-1])lines.push("");else if(!fuzzFactor)return!1;let resultLines=[],prevHunkOffset=0;for(let i=0;i<hunks.length;i++){var hunk=hunks[i];let hunkResult;var maxLine=lines.length-hunk.oldLines+fuzzFactor;let toPos;for(let maxErrors=0;maxErrors<=fuzzFactor;maxErrors++){for(var iterator=((start,minLine,maxLine)=>{let wantForward=!0,backwardExhausted=!1,forwardExhausted=!1,localOffset=1;return function iterator(){if(wantForward&&!forwardExhausted){if(backwardExhausted?localOffset++:wantForward=!1,start+localOffset<=maxLine)return start+localOffset;forwardExhausted=!0}if(!backwardExhausted)return forwardExhausted||(wantForward=!0),minLine<=start-localOffset?start-localOffset++:(backwardExhausted=!0,iterator())}})(toPos=hunk.oldStart+prevHunkOffset-1,minLine,maxLine);void 0!==toPos&&!(hunkResult=function applyHunk(hunkLines,toPos,maxErrors,hunkLinesI=0,lastContextLineMatched=!0,patchedLines=[],patchedLinesLength=0){let nConsecutiveOldContextLines=0,nextContextLineMustMatch=!1;for(;hunkLinesI<hunkLines.length;hunkLinesI++){var operation=0<(hunkLine=hunkLines[hunkLinesI]).length?hunkLine[0]:" ",hunkLine=0<hunkLine.length?hunkLine.substr(1):hunkLine;if("-"===operation){if(!compareLine(toPos+1,lines[toPos],operation,hunkLine))return maxErrors&&null!=lines[toPos]?(patchedLines[patchedLinesLength]=lines[toPos],applyHunk(hunkLines,toPos+1,maxErrors-1,hunkLinesI,!1,patchedLines,patchedLinesLength+1)):null;toPos++,nConsecutiveOldContextLines=0}if("+"===operation){if(!lastContextLineMatched)return null;patchedLines[patchedLinesLength]=hunkLine,patchedLinesLength++,nConsecutiveOldContextLines=0,nextContextLineMustMatch=!0}if(" "===operation){if(nConsecutiveOldContextLines++,patchedLines[patchedLinesLength]=lines[toPos],!compareLine(toPos+1,lines[toPos],operation,hunkLine))return nextContextLineMustMatch||!maxErrors?null:lines[toPos]&&(applyHunk(hunkLines,toPos+1,maxErrors-1,hunkLinesI+1,!1,patchedLines,patchedLinesLength+1)||applyHunk(hunkLines,toPos+1,maxErrors-1,hunkLinesI,!1,patchedLines,patchedLinesLength+1))||applyHunk(hunkLines,toPos,maxErrors-1,hunkLinesI+1,!1,patchedLines,patchedLinesLength);patchedLinesLength++,lastContextLineMatched=!0,nextContextLineMustMatch=!1,toPos++}}return patchedLinesLength-=nConsecutiveOldContextLines,toPos-=nConsecutiveOldContextLines,patchedLines.length=patchedLinesLength,{patchedLines:patchedLines,oldLineLastI:toPos-1}}(hunk.lines,toPos,maxErrors));toPos=iterator());if(hunkResult)break}if(!hunkResult)return!1;for(let i=minLine;i<toPos;i++)resultLines.push(lines[i]);for(let i=0;i<hunkResult.patchedLines.length;i++){var line=hunkResult.patchedLines[i];resultLines.push(line)}minLine=hunkResult.oldLineLastI+1,prevHunkOffset=toPos+1-hunk.oldStart}for(let i=minLine;i<lines.length;i++)resultLines.push(lines[i]);return resultLines.join("\n")})(source,patches[0],options)}let INCLUDE_HEADERS={includeIndex:!0,includeUnderline:!0,includeFileHeaders:!0};function structuredPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,options){let optionsObj,context=(void 0===(optionsObj=options?"function"==typeof options?{callback:options}:options:{}).context&&(optionsObj.context=4),optionsObj.context);if(optionsObj.newlineIsToken)throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");if(!optionsObj.callback)return diffLinesResultToPatch(diffLines(oldStr,newStr,optionsObj));{let callback=optionsObj.callback;diffLines(oldStr,newStr,Object.assign(Object.assign({},optionsObj),{callback:diff=>{diff=diffLinesResultToPatch(diff);callback(diff)}}))}function diffLinesResultToPatch(diff){if(diff){diff.push({value:"",lines:[]});var hunks=[];let oldRangeStart=0,newRangeStart=0,curRange=[],oldLine=1,newLine=1;for(let i=0;i<diff.length;i++){var line,current=diff[i],lines=current.lines||(text=>{var hasTrailingNl=text.endsWith("\n"),text=text.split("\n").map(line=>line+"\n");return hasTrailingNl?text.pop():text.push(text.pop().slice(0,-1)),text})(current.value);if(current.lines=lines,current.added||current.removed){oldRangeStart||(prev=diff[i-1],oldRangeStart=oldLine,newRangeStart=newLine,prev&&(curRange=0<context?contextLines(prev.lines.slice(-context)):[],oldRangeStart-=curRange.length,newRangeStart-=curRange.length));for(line of lines)curRange.push((current.added?"+":"-")+line);current.added?newLine+=lines.length:oldLine+=lines.length}else{if(oldRangeStart)if(lines.length<=2*context&&i<diff.length-2)for(let line of contextLines(lines))curRange.push(line);else{var prev=Math.min(lines.length,context);for(let line of contextLines(lines.slice(0,prev)))curRange.push(line);var hunk={oldStart:oldRangeStart,oldLines:oldLine-oldRangeStart+prev,newStart:newRangeStart,newLines:newLine-newRangeStart+prev,lines:curRange};hunks.push(hunk),oldRangeStart=0,newRangeStart=0,curRange=[]}oldLine+=lines.length,newLine+=lines.length}}for(let hunk of hunks)for(let i=0;i<hunk.lines.length;i++)hunk.lines[i].endsWith("\n")?hunk.lines[i]=hunk.lines[i].slice(0,-1):(hunk.lines.splice(i+1,0,"\\ No newline at end of file"),i++);return{oldFileName:oldFileName,newFileName:newFileName,oldHeader:oldHeader,newHeader:newHeader,hunks:hunks};function contextLines(lines){return lines.map(function(entry){return" "+entry})}}}}function formatPatch(patch,headerOptions){if(headerOptions=headerOptions||INCLUDE_HEADERS,Array.isArray(patch)){if(1<patch.length&&!headerOptions.includeFileHeaders)throw new Error("Cannot omit file headers on a multi-file patch. (The result would be unparseable; how would a tool trying to apply the patch know which changes are to which file?)");return patch.map(p=>formatPatch(p,headerOptions)).join("\n")}var ret=[];headerOptions.includeIndex&&patch.oldFileName==patch.newFileName&&ret.push("Index: "+patch.oldFileName),headerOptions.includeUnderline&&ret.push("==================================================================="),headerOptions.includeFileHeaders&&(ret.push("--- "+patch.oldFileName+(void 0===patch.oldHeader?"":"\t"+patch.oldHeader)),ret.push("+++ "+patch.newFileName+(void 0===patch.newHeader?"":"\t"+patch.newHeader)));for(let i=0;i<patch.hunks.length;i++){var line,hunk=patch.hunks[i];0===hunk.oldLines&&--hunk.oldStart,0===hunk.newLines&&--hunk.newStart,ret.push("@@ -"+hunk.oldStart+","+hunk.oldLines+" +"+hunk.newStart+","+hunk.newLines+" @@");for(line of hunk.lines)ret.push(line)}return ret.join("\n")+"\n"}function createTwoFilesPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,options){if(null!=(options="function"==typeof options?{callback:options}:options)&&options.callback){let callback=options.callback;structuredPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,Object.assign(Object.assign({},options),{callback:patchObj=>{patchObj?callback(formatPatch(patchObj,options.headerOptions)):callback(void 0)}}))}else{oldFileName=structuredPatch(oldFileName,newFileName,oldStr,newStr,oldHeader,newHeader,options);if(oldFileName)return formatPatch(oldFileName,null==options?void 0:options.headerOptions)}}exports.Diff=Diff,exports.FILE_HEADERS_ONLY={includeIndex:!1,includeUnderline:!1,includeFileHeaders:!0},exports.INCLUDE_HEADERS=INCLUDE_HEADERS,exports.OMIT_HEADERS={includeIndex:!1,includeUnderline:!1,includeFileHeaders:!1},exports.applyPatch=applyPatch,exports.applyPatches=function(uniDiff,options){let spDiff="string"==typeof uniDiff?parsePatch(uniDiff):uniDiff,currentIndex=0;!function processIndex(){let index=spDiff[currentIndex++];if(!index)return options.complete();options.loadFile(index,function(err,data){if(err)return options.complete(err);err=applyPatch(data,index,options),options.patched(index,err,function(err){if(err)return options.complete(err);processIndex()})})}()},exports.arrayDiff=arrayDiff,exports.canonicalize=canonicalize,exports.characterDiff=characterDiff,exports.convertChangesToDMP=function(changes){var ret=[];let change,operation;for(let i=0;i<changes.length;i++)change=changes[i],operation=change.added?1:change.removed?-1:0,ret.push([operation,change.value]);return ret},exports.convertChangesToXML=function(changes){var ret=[];for(let i=0;i<changes.length;i++){var change=changes[i];change.added?ret.push("<ins>"):change.removed&&ret.push("<del>"),ret.push((s=>{let n=s;return n=(n=(n=(n=n.replace(/&/g,"&")).replace(/</g,"<")).replace(/>/g,">")).replace(/"/g,""")})(change.value)),change.added?ret.push("</ins>"):change.removed&&ret.push("</del>")}return ret.join("")},exports.createPatch=function(fileName,oldStr,newStr,oldHeader,newHeader,options){return createTwoFilesPatch(fileName,fileName,oldStr,newStr,oldHeader,newHeader,options)},exports.createTwoFilesPatch=createTwoFilesPatch,exports.cssDiff=cssDiff,exports.diffArrays=function(oldArr,newArr,options){return arrayDiff.diff(oldArr,newArr,options)},exports.diffChars=function(oldStr,newStr,options){return characterDiff.diff(oldStr,newStr,options)},exports.diffCss=function(oldStr,newStr,options){return cssDiff.diff(oldStr,newStr,options)},exports.diffJson=function(oldStr,newStr,options){return jsonDiff.diff(oldStr,newStr,options)},exports.diffLines=diffLines,exports.diffSentences=function(oldStr,newStr,options){return sentenceDiff.diff(oldStr,newStr,options)},exports.diffTrimmedLines=function(oldStr,newStr,options){return options=((options,defaults)=>{if("function"==typeof options)defaults.callback=options;else if(options)for(var name in options)Object.prototype.hasOwnProperty.call(options,name)&&(defaults[name]=options[name]);return defaults})(options,{ignoreWhitespace:!0}),lineDiff.diff(oldStr,newStr,options)},exports.diffWords=function(oldStr,newStr,options){return null==(null==options?void 0:options.ignoreWhitespace)||options.ignoreWhitespace?wordDiff.diff(oldStr,newStr,options):diffWordsWithSpace(oldStr,newStr,options)},exports.diffWordsWithSpace=diffWordsWithSpace,exports.formatPatch=formatPatch,exports.jsonDiff=jsonDiff,exports.lineDiff=lineDiff,exports.parsePatch=parsePatch,exports.reversePatch=function reversePatch(structuredPatch){return Array.isArray(structuredPatch)?structuredPatch.map(patch=>reversePatch(patch)).reverse():Object.assign(Object.assign({},structuredPatch),{oldFileName:structuredPatch.newFileName,oldHeader:structuredPatch.newHeader,newFileName:structuredPatch.oldFileName,newHeader:structuredPatch.oldHeader,hunks:structuredPatch.hunks.map(hunk=>({oldLines:hunk.newLines,oldStart:hunk.newStart,newLines:hunk.oldLines,newStart:hunk.oldStart,lines:hunk.lines.map(l=>l.startsWith("-")?"+"+l.slice(1):l.startsWith("+")?"-"+l.slice(1):l)}))})},exports.sentenceDiff=sentenceDiff,exports.structuredPatch=structuredPatch,exports.wordDiff=wordDiff,exports.wordsWithSpaceDiff=wordsWithSpaceDiff}); \ No newline at end of file diff --git a/node_modules/diff/eslint.config.mjs b/node_modules/diff/eslint.config.mjs new file mode 100644 index 0000000000000..ea1c73566ea89 --- /dev/null +++ b/node_modules/diff/eslint.config.mjs @@ -0,0 +1,182 @@ +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import globals from "globals"; + +export default tseslint.config( + { + ignores: [ + "**/*", // ignore everything... + "!src/**/", "!src/**/*.ts", // ... except our TypeScript source files... + "!test/**/", "!test/**/*.js", // ... and our tests + ], + }, + eslint.configs.recommended, + tseslint.configs.recommended, + { + files: ['src/**/*.ts'], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + extends: [tseslint.configs.recommendedTypeChecked], + rules: { + // Not sure if these actually serve a purpose, but they provide a way to enforce SOME of what + // would be imposed by having "verbatimModuleSyntax": true in our tsconfig.json without + // actually doing that. + "@typescript-eslint/consistent-type-imports": 2, + "@typescript-eslint/consistent-type-exports": 2, + + // Things from the recommendedTypeChecked shared config that are disabled simply because they + // caused lots of errors in our existing code when tried. Plausibly useful to turn on if + // possible and somebody fancies doing the work: + "@typescript-eslint/no-unsafe-argument": 0, + "@typescript-eslint/no-unsafe-assignment": 0, + "@typescript-eslint/no-unsafe-call": 0, + "@typescript-eslint/no-unsafe-member-access": 0, + "@typescript-eslint/no-unsafe-return": 0, + } + }, + { + languageOptions: { + globals: { + ...globals.browser, + }, + }, + + rules: { + // Possible Errors // + //-----------------// + "comma-dangle": [2, "never"], + "no-console": 1, // Allow for debugging + "no-debugger": 1, // Allow for debugging + "no-extra-parens": [2, "functions"], + "no-extra-semi": 2, + "no-negated-in-lhs": 2, + "no-unreachable": 1, // Optimizer and coverage will handle/highlight this and can be useful for debugging + + // Best Practices // + //----------------// + curly: 2, + "default-case": 1, + "dot-notation": [2, { + allowKeywords: false, + }], + "guard-for-in": 1, + "no-alert": 2, + "no-caller": 2, + "no-div-regex": 1, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-floating-decimal": 2, + "no-implied-eval": 2, + "no-iterator": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-multi-spaces": 2, + "no-multi-str": 1, + "no-native-reassign": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-octal-escape": 2, + "no-process-env": 2, + "no-proto": 2, + "no-return-assign": 2, + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-throw-literal": 2, + "no-unused-expressions": 2, + "no-warning-comments": 1, + radix: 2, + "wrap-iife": 2, + + // Variables // + //-----------// + "no-catch-shadow": 2, + "no-label-var": 2, + "no-undef-init": 2, + + // Node.js // + //---------// + + // Stylistic // + //-----------// + "brace-style": [2, "1tbs", { + allowSingleLine: true, + }], + camelcase: 2, + "comma-spacing": [2, { + before: false, + after: true, + }], + "comma-style": [2, "last"], + "consistent-this": [1, "self"], + "eol-last": 2, + "func-style": [2, "declaration"], + "key-spacing": [2, { + beforeColon: false, + afterColon: true, + }], + "new-cap": 2, + "new-parens": 2, + "no-array-constructor": 2, + "no-lonely-if": 2, + "no-mixed-spaces-and-tabs": 2, + "no-nested-ternary": 1, + "no-new-object": 2, + "no-spaced-func": 2, + "no-trailing-spaces": 2, + "quote-props": [2, "as-needed", { + keywords: true, + }], + quotes: [2, "single", "avoid-escape"], + semi: 2, + "semi-spacing": [2, { + before: false, + after: true, + }], + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, { + anonymous: "never", + named: "never", + }], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "space-unary-ops": 2, + "spaced-comment": [2, "always"], + "wrap-regex": 1, + "no-var": 2, + + // Typescript // + //------------// + "@typescript-eslint/no-explicit-any": 0, // Very strict rule, incompatible with our code + + // We use these intentionally - e.g. + // export interface DiffCssOptions extends CommonDiffOptions {} + // for the options argument to diffCss which currently takes no options beyond the ones + // common to all diffFoo functions. Doing this allows consistency (one options interface per + // diffFoo function) and future-proofs against the API having to change in future if we add a + // non-common option to one of these functions. + "@typescript-eslint/no-empty-object-type": [2, {allowInterfaces: 'with-single-extends'}], + }, + }, + { + files: ['test/**/*.js'], + languageOptions: { + globals: { + ...globals.node, + ...globals.mocha, + }, + }, + rules: { + "no-unused-expressions": 0, // Needs disabling to support Chai `.to.be.undefined` etc syntax + "@typescript-eslint/no-unused-expressions": 0, // (as above) + }, + } +); diff --git a/node_modules/diff/lib/convert/dmp.js b/node_modules/diff/lib/convert/dmp.js deleted file mode 100644 index 91ff40a9120f7..0000000000000 --- a/node_modules/diff/lib/convert/dmp.js +++ /dev/null @@ -1,32 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.convertChangesToDMP = convertChangesToDMP; - -/*istanbul ignore end*/ -// See: http://code.google.com/p/google-diff-match-patch/wiki/API -function convertChangesToDMP(changes) { - var ret = [], - change, - operation; - - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); - } - - return ret; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb252ZXJ0L2RtcC5qcyJdLCJuYW1lcyI6WyJjb252ZXJ0Q2hhbmdlc1RvRE1QIiwiY2hhbmdlcyIsInJldCIsImNoYW5nZSIsIm9wZXJhdGlvbiIsImkiLCJsZW5ndGgiLCJhZGRlZCIsInJlbW92ZWQiLCJwdXNoIiwidmFsdWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQ08sU0FBU0EsbUJBQVQsQ0FBNkJDLE9BQTdCLEVBQXNDO0FBQzNDLE1BQUlDLEdBQUcsR0FBRyxFQUFWO0FBQUEsTUFDSUMsTUFESjtBQUFBLE1BRUlDLFNBRko7O0FBR0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHSixPQUFPLENBQUNLLE1BQTVCLEVBQW9DRCxDQUFDLEVBQXJDLEVBQXlDO0FBQ3ZDRixJQUFBQSxNQUFNLEdBQUdGLE9BQU8sQ0FBQ0ksQ0FBRCxDQUFoQjs7QUFDQSxRQUFJRixNQUFNLENBQUNJLEtBQVgsRUFBa0I7QUFDaEJILE1BQUFBLFNBQVMsR0FBRyxDQUFaO0FBQ0QsS0FGRCxNQUVPLElBQUlELE1BQU0sQ0FBQ0ssT0FBWCxFQUFvQjtBQUN6QkosTUFBQUEsU0FBUyxHQUFHLENBQUMsQ0FBYjtBQUNELEtBRk0sTUFFQTtBQUNMQSxNQUFBQSxTQUFTLEdBQUcsQ0FBWjtBQUNEOztBQUVERixJQUFBQSxHQUFHLENBQUNPLElBQUosQ0FBUyxDQUFDTCxTQUFELEVBQVlELE1BQU0sQ0FBQ08sS0FBbkIsQ0FBVDtBQUNEOztBQUNELFNBQU9SLEdBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8vIFNlZTogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2dvb2dsZS1kaWZmLW1hdGNoLXBhdGNoL3dpa2kvQVBJXG5leHBvcnQgZnVuY3Rpb24gY29udmVydENoYW5nZXNUb0RNUChjaGFuZ2VzKSB7XG4gIGxldCByZXQgPSBbXSxcbiAgICAgIGNoYW5nZSxcbiAgICAgIG9wZXJhdGlvbjtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgY2hhbmdlID0gY2hhbmdlc1tpXTtcbiAgICBpZiAoY2hhbmdlLmFkZGVkKSB7XG4gICAgICBvcGVyYXRpb24gPSAxO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnJlbW92ZWQpIHtcbiAgICAgIG9wZXJhdGlvbiA9IC0xO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcGVyYXRpb24gPSAwO1xuICAgIH1cblxuICAgIHJldC5wdXNoKFtvcGVyYXRpb24sIGNoYW5nZS52YWx1ZV0pO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG4iXX0= diff --git a/node_modules/diff/lib/convert/xml.js b/node_modules/diff/lib/convert/xml.js deleted file mode 100644 index 69ec60c66c81d..0000000000000 --- a/node_modules/diff/lib/convert/xml.js +++ /dev/null @@ -1,42 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.convertChangesToXML = convertChangesToXML; - -/*istanbul ignore end*/ -function convertChangesToXML(changes) { - var ret = []; - - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - - if (change.added) { - ret.push('<ins>'); - } else if (change.removed) { - ret.push('<del>'); - } - - ret.push(escapeHTML(change.value)); - - if (change.added) { - ret.push('</ins>'); - } else if (change.removed) { - ret.push('</del>'); - } - } - - return ret.join(''); -} - -function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(/</g, '<'); - n = n.replace(/>/g, '>'); - n = n.replace(/"/g, '"'); - return n; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb252ZXJ0L3htbC5qcyJdLCJuYW1lcyI6WyJjb252ZXJ0Q2hhbmdlc1RvWE1MIiwiY2hhbmdlcyIsInJldCIsImkiLCJsZW5ndGgiLCJjaGFuZ2UiLCJhZGRlZCIsInB1c2giLCJyZW1vdmVkIiwiZXNjYXBlSFRNTCIsInZhbHVlIiwiam9pbiIsInMiLCJuIiwicmVwbGFjZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQU8sU0FBU0EsbUJBQVQsQ0FBNkJDLE9BQTdCLEVBQXNDO0FBQzNDLE1BQUlDLEdBQUcsR0FBRyxFQUFWOztBQUNBLE9BQUssSUFBSUMsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0YsT0FBTyxDQUFDRyxNQUE1QixFQUFvQ0QsQ0FBQyxFQUFyQyxFQUF5QztBQUN2QyxRQUFJRSxNQUFNLEdBQUdKLE9BQU8sQ0FBQ0UsQ0FBRCxDQUFwQjs7QUFDQSxRQUFJRSxNQUFNLENBQUNDLEtBQVgsRUFBa0I7QUFDaEJKLE1BQUFBLEdBQUcsQ0FBQ0ssSUFBSixDQUFTLE9BQVQ7QUFDRCxLQUZELE1BRU8sSUFBSUYsTUFBTSxDQUFDRyxPQUFYLEVBQW9CO0FBQ3pCTixNQUFBQSxHQUFHLENBQUNLLElBQUosQ0FBUyxPQUFUO0FBQ0Q7O0FBRURMLElBQUFBLEdBQUcsQ0FBQ0ssSUFBSixDQUFTRSxVQUFVLENBQUNKLE1BQU0sQ0FBQ0ssS0FBUixDQUFuQjs7QUFFQSxRQUFJTCxNQUFNLENBQUNDLEtBQVgsRUFBa0I7QUFDaEJKLE1BQUFBLEdBQUcsQ0FBQ0ssSUFBSixDQUFTLFFBQVQ7QUFDRCxLQUZELE1BRU8sSUFBSUYsTUFBTSxDQUFDRyxPQUFYLEVBQW9CO0FBQ3pCTixNQUFBQSxHQUFHLENBQUNLLElBQUosQ0FBUyxRQUFUO0FBQ0Q7QUFDRjs7QUFDRCxTQUFPTCxHQUFHLENBQUNTLElBQUosQ0FBUyxFQUFULENBQVA7QUFDRDs7QUFFRCxTQUFTRixVQUFULENBQW9CRyxDQUFwQixFQUF1QjtBQUNyQixNQUFJQyxDQUFDLEdBQUdELENBQVI7QUFDQUMsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLE9BQWhCLENBQUo7QUFDQUQsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLE1BQWhCLENBQUo7QUFDQUQsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLE1BQWhCLENBQUo7QUFDQUQsRUFBQUEsQ0FBQyxHQUFHQSxDQUFDLENBQUNDLE9BQUYsQ0FBVSxJQUFWLEVBQWdCLFFBQWhCLENBQUo7QUFFQSxTQUFPRCxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gY29udmVydENoYW5nZXNUb1hNTChjaGFuZ2VzKSB7XG4gIGxldCByZXQgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGNoYW5nZSA9IGNoYW5nZXNbaV07XG4gICAgaWYgKGNoYW5nZS5hZGRlZCkge1xuICAgICAgcmV0LnB1c2goJzxpbnM+Jyk7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UucmVtb3ZlZCkge1xuICAgICAgcmV0LnB1c2goJzxkZWw+Jyk7XG4gICAgfVxuXG4gICAgcmV0LnB1c2goZXNjYXBlSFRNTChjaGFuZ2UudmFsdWUpKTtcblxuICAgIGlmIChjaGFuZ2UuYWRkZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8L2lucz4nKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZS5yZW1vdmVkKSB7XG4gICAgICByZXQucHVzaCgnPC9kZWw+Jyk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXQuam9pbignJyk7XG59XG5cbmZ1bmN0aW9uIGVzY2FwZUhUTUwocykge1xuICBsZXQgbiA9IHM7XG4gIG4gPSBuLnJlcGxhY2UoLyYvZywgJyZhbXA7Jyk7XG4gIG4gPSBuLnJlcGxhY2UoLzwvZywgJyZsdDsnKTtcbiAgbiA9IG4ucmVwbGFjZSgvPi9nLCAnJmd0OycpO1xuICBuID0gbi5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7Jyk7XG5cbiAgcmV0dXJuIG47XG59XG4iXX0= diff --git a/node_modules/diff/lib/diff/array.js b/node_modules/diff/lib/diff/array.js deleted file mode 100644 index 19e36809893c1..0000000000000 --- a/node_modules/diff/lib/diff/array.js +++ /dev/null @@ -1,45 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffArrays = diffArrays; -exports.arrayDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -var arrayDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); - -/*istanbul ignore start*/ -exports.arrayDiff = arrayDiff; - -/*istanbul ignore end*/ -arrayDiff.tokenize = function (value) { - return value.slice(); -}; - -arrayDiff.join = arrayDiff.removeEmpty = function (value) { - return value; -}; - -function diffArrays(oldArr, newArr, callback) { - return arrayDiff.diff(oldArr, newArr, callback); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2FycmF5LmpzIl0sIm5hbWVzIjpbImFycmF5RGlmZiIsIkRpZmYiLCJ0b2tlbml6ZSIsInZhbHVlIiwic2xpY2UiLCJqb2luIiwicmVtb3ZlRW1wdHkiLCJkaWZmQXJyYXlzIiwib2xkQXJyIiwibmV3QXJyIiwiY2FsbGJhY2siLCJkaWZmIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7QUFFTyxJQUFNQSxTQUFTLEdBQUc7QUFBSUM7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUEsQ0FBSixFQUFsQjs7Ozs7O0FBQ1BELFNBQVMsQ0FBQ0UsUUFBVixHQUFxQixVQUFTQyxLQUFULEVBQWdCO0FBQ25DLFNBQU9BLEtBQUssQ0FBQ0MsS0FBTixFQUFQO0FBQ0QsQ0FGRDs7QUFHQUosU0FBUyxDQUFDSyxJQUFWLEdBQWlCTCxTQUFTLENBQUNNLFdBQVYsR0FBd0IsVUFBU0gsS0FBVCxFQUFnQjtBQUN2RCxTQUFPQSxLQUFQO0FBQ0QsQ0FGRDs7QUFJTyxTQUFTSSxVQUFULENBQW9CQyxNQUFwQixFQUE0QkMsTUFBNUIsRUFBb0NDLFFBQXBDLEVBQThDO0FBQUUsU0FBT1YsU0FBUyxDQUFDVyxJQUFWLENBQWVILE1BQWYsRUFBdUJDLE1BQXZCLEVBQStCQyxRQUEvQixDQUFQO0FBQWtEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGFycmF5RGlmZiA9IG5ldyBEaWZmKCk7XG5hcnJheURpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc2xpY2UoKTtcbn07XG5hcnJheURpZmYuam9pbiA9IGFycmF5RGlmZi5yZW1vdmVFbXB0eSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWZmQXJyYXlzKG9sZEFyciwgbmV3QXJyLCBjYWxsYmFjaykgeyByZXR1cm4gYXJyYXlEaWZmLmRpZmYob2xkQXJyLCBuZXdBcnIsIGNhbGxiYWNrKTsgfVxuIl19 diff --git a/node_modules/diff/lib/diff/base.js b/node_modules/diff/lib/diff/base.js deleted file mode 100644 index 48bbe234c74c4..0000000000000 --- a/node_modules/diff/lib/diff/base.js +++ /dev/null @@ -1,304 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = Diff; - -/*istanbul ignore end*/ -function Diff() {} - -Diff.prototype = { - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - diff: function diff(oldString, newString) { - /*istanbul ignore start*/ - var - /*istanbul ignore end*/ - options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var callback = options.callback; - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - this.options = options; - var self = this; - - function done(value) { - if (callback) { - setTimeout(function () { - callback(undefined, value); - }, 0); - return true; - } else { - return value; - } - } // Allow subclasses to massage the input prior to running - - - oldString = this.castInput(oldString); - newString = this.castInput(newString); - oldString = this.removeEmpty(this.tokenize(oldString)); - newString = this.removeEmpty(this.tokenize(newString)); - var newLen = newString.length, - oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ - newPos: -1, - components: [] - }]; // Seed editLength = 0, i.e. the content starts with the same values - - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{ - value: this.join(newString), - count: newString.length - }]); - } // Main worker method. checks all permutations of a given edit length for acceptance. - - - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath = - /*istanbul ignore start*/ - void 0 - /*istanbul ignore end*/ - ; - - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } - - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; - - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - - - if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } - - _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done - - if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { - return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } - } - - editLength++; - } // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - - - if (callback) { - (function exec() { - setTimeout(function () { - // This should not happen, but we want to be safe. - - /* istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } - - if (!execEditLength()) { - exec(); - } - }, 0); - })(); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - - if (ret) { - return ret; - } - } - } - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - pushComponent: function pushComponent(components, added, removed) { - var last = components[components.length - 1]; - - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = { - count: last.count + 1, - added: added, - removed: removed - }; - } else { - components.push({ - count: 1, - added: added, - removed: removed - }); - } - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, - commonCount = 0; - - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - - if (commonCount) { - basePath.components.push({ - count: commonCount - }); - } - - basePath.newPos = newPos; - return oldPos; - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - equals: function equals(left, right) { - if (this.options.comparator) { - return this.options.comparator(left, right); - } else { - return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); - } - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - removeEmpty: function removeEmpty(array) { - var ret = []; - - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); - } - } - - return ret; - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - castInput: function castInput(value) { - return value; - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - tokenize: function tokenize(value) { - return value.split(''); - }, - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - join: function join(chars) { - return chars.join(''); - } -}; - -function buildValues(diff, components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; - - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = value.map(function (value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); - component.value = diff.join(value); - } else { - component.value = diff.join(newString.slice(newPos, newPos + component.count)); - } - - newPos += component.count; // Common case - - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); - oldPos += component.count; // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } - } - } // Special case handle for when one terminal is ignored (i.e. whitespace). - // For this case we merge the terminal into the prior string and drop the change. - // This is only available for string mode. - - - var lastComponent = components[componentLen - 1]; - - if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { - components[componentLen - 2].value += lastComponent.value; - components.pop(); - } - - return components; -} - -function clonePath(path) { - return { - newPos: path.newPos, - components: path.components.slice(0) - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2Jhc2UuanMiXSwibmFtZXMiOlsiRGlmZiIsInByb3RvdHlwZSIsImRpZmYiLCJvbGRTdHJpbmciLCJuZXdTdHJpbmciLCJvcHRpb25zIiwiY2FsbGJhY2siLCJzZWxmIiwiZG9uZSIsInZhbHVlIiwic2V0VGltZW91dCIsInVuZGVmaW5lZCIsImNhc3RJbnB1dCIsInJlbW92ZUVtcHR5IiwidG9rZW5pemUiLCJuZXdMZW4iLCJsZW5ndGgiLCJvbGRMZW4iLCJlZGl0TGVuZ3RoIiwibWF4RWRpdExlbmd0aCIsImJlc3RQYXRoIiwibmV3UG9zIiwiY29tcG9uZW50cyIsIm9sZFBvcyIsImV4dHJhY3RDb21tb24iLCJqb2luIiwiY291bnQiLCJleGVjRWRpdExlbmd0aCIsImRpYWdvbmFsUGF0aCIsImJhc2VQYXRoIiwiYWRkUGF0aCIsInJlbW92ZVBhdGgiLCJjYW5BZGQiLCJjYW5SZW1vdmUiLCJjbG9uZVBhdGgiLCJwdXNoQ29tcG9uZW50IiwiYnVpbGRWYWx1ZXMiLCJ1c2VMb25nZXN0VG9rZW4iLCJleGVjIiwicmV0IiwiYWRkZWQiLCJyZW1vdmVkIiwibGFzdCIsInB1c2giLCJjb21tb25Db3VudCIsImVxdWFscyIsImxlZnQiLCJyaWdodCIsImNvbXBhcmF0b3IiLCJpZ25vcmVDYXNlIiwidG9Mb3dlckNhc2UiLCJhcnJheSIsImkiLCJzcGxpdCIsImNoYXJzIiwiY29tcG9uZW50UG9zIiwiY29tcG9uZW50TGVuIiwiY29tcG9uZW50Iiwic2xpY2UiLCJtYXAiLCJvbGRWYWx1ZSIsInRtcCIsImxhc3RDb21wb25lbnQiLCJwb3AiLCJwYXRoIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBZSxTQUFTQSxJQUFULEdBQWdCLENBQUU7O0FBRWpDQSxJQUFJLENBQUNDLFNBQUwsR0FBaUI7QUFBQTs7QUFBQTtBQUNmQyxFQUFBQSxJQURlLGdCQUNWQyxTQURVLEVBQ0NDLFNBREQsRUFDMEI7QUFBQTtBQUFBO0FBQUE7QUFBZEMsSUFBQUEsT0FBYyx1RUFBSixFQUFJO0FBQ3ZDLFFBQUlDLFFBQVEsR0FBR0QsT0FBTyxDQUFDQyxRQUF2Qjs7QUFDQSxRQUFJLE9BQU9ELE9BQVAsS0FBbUIsVUFBdkIsRUFBbUM7QUFDakNDLE1BQUFBLFFBQVEsR0FBR0QsT0FBWDtBQUNBQSxNQUFBQSxPQUFPLEdBQUcsRUFBVjtBQUNEOztBQUNELFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUVBLFFBQUlFLElBQUksR0FBRyxJQUFYOztBQUVBLGFBQVNDLElBQVQsQ0FBY0MsS0FBZCxFQUFxQjtBQUNuQixVQUFJSCxRQUFKLEVBQWM7QUFDWkksUUFBQUEsVUFBVSxDQUFDLFlBQVc7QUFBRUosVUFBQUEsUUFBUSxDQUFDSyxTQUFELEVBQVlGLEtBQVosQ0FBUjtBQUE2QixTQUEzQyxFQUE2QyxDQUE3QyxDQUFWO0FBQ0EsZUFBTyxJQUFQO0FBQ0QsT0FIRCxNQUdPO0FBQ0wsZUFBT0EsS0FBUDtBQUNEO0FBQ0YsS0FqQnNDLENBbUJ2Qzs7O0FBQ0FOLElBQUFBLFNBQVMsR0FBRyxLQUFLUyxTQUFMLENBQWVULFNBQWYsQ0FBWjtBQUNBQyxJQUFBQSxTQUFTLEdBQUcsS0FBS1EsU0FBTCxDQUFlUixTQUFmLENBQVo7QUFFQUQsSUFBQUEsU0FBUyxHQUFHLEtBQUtVLFdBQUwsQ0FBaUIsS0FBS0MsUUFBTCxDQUFjWCxTQUFkLENBQWpCLENBQVo7QUFDQUMsSUFBQUEsU0FBUyxHQUFHLEtBQUtTLFdBQUwsQ0FBaUIsS0FBS0MsUUFBTCxDQUFjVixTQUFkLENBQWpCLENBQVo7QUFFQSxRQUFJVyxNQUFNLEdBQUdYLFNBQVMsQ0FBQ1ksTUFBdkI7QUFBQSxRQUErQkMsTUFBTSxHQUFHZCxTQUFTLENBQUNhLE1BQWxEO0FBQ0EsUUFBSUUsVUFBVSxHQUFHLENBQWpCO0FBQ0EsUUFBSUMsYUFBYSxHQUFHSixNQUFNLEdBQUdFLE1BQTdCO0FBQ0EsUUFBSUcsUUFBUSxHQUFHLENBQUM7QUFBRUMsTUFBQUEsTUFBTSxFQUFFLENBQUMsQ0FBWDtBQUFjQyxNQUFBQSxVQUFVLEVBQUU7QUFBMUIsS0FBRCxDQUFmLENBN0J1QyxDQStCdkM7O0FBQ0EsUUFBSUMsTUFBTSxHQUFHLEtBQUtDLGFBQUwsQ0FBbUJKLFFBQVEsQ0FBQyxDQUFELENBQTNCLEVBQWdDaEIsU0FBaEMsRUFBMkNELFNBQTNDLEVBQXNELENBQXRELENBQWI7O0FBQ0EsUUFBSWlCLFFBQVEsQ0FBQyxDQUFELENBQVIsQ0FBWUMsTUFBWixHQUFxQixDQUFyQixJQUEwQk4sTUFBMUIsSUFBb0NRLE1BQU0sR0FBRyxDQUFULElBQWNOLE1BQXRELEVBQThEO0FBQzVEO0FBQ0EsYUFBT1QsSUFBSSxDQUFDLENBQUM7QUFBQ0MsUUFBQUEsS0FBSyxFQUFFLEtBQUtnQixJQUFMLENBQVVyQixTQUFWLENBQVI7QUFBOEJzQixRQUFBQSxLQUFLLEVBQUV0QixTQUFTLENBQUNZO0FBQS9DLE9BQUQsQ0FBRCxDQUFYO0FBQ0QsS0FwQ3NDLENBc0N2Qzs7O0FBQ0EsYUFBU1csY0FBVCxHQUEwQjtBQUN4QixXQUFLLElBQUlDLFlBQVksR0FBRyxDQUFDLENBQUQsR0FBS1YsVUFBN0IsRUFBeUNVLFlBQVksSUFBSVYsVUFBekQsRUFBcUVVLFlBQVksSUFBSSxDQUFyRixFQUF3RjtBQUN0RixZQUFJQyxRQUFRO0FBQUE7QUFBQTtBQUFaO0FBQUE7O0FBQ0EsWUFBSUMsT0FBTyxHQUFHVixRQUFRLENBQUNRLFlBQVksR0FBRyxDQUFoQixDQUF0QjtBQUFBLFlBQ0lHLFVBQVUsR0FBR1gsUUFBUSxDQUFDUSxZQUFZLEdBQUcsQ0FBaEIsQ0FEekI7QUFBQSxZQUVJTCxPQUFNLEdBQUcsQ0FBQ1EsVUFBVSxHQUFHQSxVQUFVLENBQUNWLE1BQWQsR0FBdUIsQ0FBbEMsSUFBdUNPLFlBRnBEOztBQUdBLFlBQUlFLE9BQUosRUFBYTtBQUNYO0FBQ0FWLFVBQUFBLFFBQVEsQ0FBQ1EsWUFBWSxHQUFHLENBQWhCLENBQVIsR0FBNkJqQixTQUE3QjtBQUNEOztBQUVELFlBQUlxQixNQUFNLEdBQUdGLE9BQU8sSUFBSUEsT0FBTyxDQUFDVCxNQUFSLEdBQWlCLENBQWpCLEdBQXFCTixNQUE3QztBQUFBLFlBQ0lrQixTQUFTLEdBQUdGLFVBQVUsSUFBSSxLQUFLUixPQUFuQixJQUE2QkEsT0FBTSxHQUFHTixNQUR0RDs7QUFFQSxZQUFJLENBQUNlLE1BQUQsSUFBVyxDQUFDQyxTQUFoQixFQUEyQjtBQUN6QjtBQUNBYixVQUFBQSxRQUFRLENBQUNRLFlBQUQsQ0FBUixHQUF5QmpCLFNBQXpCO0FBQ0E7QUFDRCxTQWhCcUYsQ0FrQnRGO0FBQ0E7QUFDQTs7O0FBQ0EsWUFBSSxDQUFDcUIsTUFBRCxJQUFZQyxTQUFTLElBQUlILE9BQU8sQ0FBQ1QsTUFBUixHQUFpQlUsVUFBVSxDQUFDVixNQUF6RCxFQUFrRTtBQUNoRVEsVUFBQUEsUUFBUSxHQUFHSyxTQUFTLENBQUNILFVBQUQsQ0FBcEI7QUFDQXhCLFVBQUFBLElBQUksQ0FBQzRCLGFBQUwsQ0FBbUJOLFFBQVEsQ0FBQ1AsVUFBNUIsRUFBd0NYLFNBQXhDLEVBQW1ELElBQW5EO0FBQ0QsU0FIRCxNQUdPO0FBQ0xrQixVQUFBQSxRQUFRLEdBQUdDLE9BQVgsQ0FESyxDQUNlOztBQUNwQkQsVUFBQUEsUUFBUSxDQUFDUixNQUFUO0FBQ0FkLFVBQUFBLElBQUksQ0FBQzRCLGFBQUwsQ0FBbUJOLFFBQVEsQ0FBQ1AsVUFBNUIsRUFBd0MsSUFBeEMsRUFBOENYLFNBQTlDO0FBQ0Q7O0FBRURZLFFBQUFBLE9BQU0sR0FBR2hCLElBQUksQ0FBQ2lCLGFBQUwsQ0FBbUJLLFFBQW5CLEVBQTZCekIsU0FBN0IsRUFBd0NELFNBQXhDLEVBQW1EeUIsWUFBbkQsQ0FBVCxDQTlCc0YsQ0FnQ3RGOztBQUNBLFlBQUlDLFFBQVEsQ0FBQ1IsTUFBVCxHQUFrQixDQUFsQixJQUF1Qk4sTUFBdkIsSUFBaUNRLE9BQU0sR0FBRyxDQUFULElBQWNOLE1BQW5ELEVBQTJEO0FBQ3pELGlCQUFPVCxJQUFJLENBQUM0QixXQUFXLENBQUM3QixJQUFELEVBQU9zQixRQUFRLENBQUNQLFVBQWhCLEVBQTRCbEIsU0FBNUIsRUFBdUNELFNBQXZDLEVBQWtESSxJQUFJLENBQUM4QixlQUF2RCxDQUFaLENBQVg7QUFDRCxTQUZELE1BRU87QUFDTDtBQUNBakIsVUFBQUEsUUFBUSxDQUFDUSxZQUFELENBQVIsR0FBeUJDLFFBQXpCO0FBQ0Q7QUFDRjs7QUFFRFgsTUFBQUEsVUFBVTtBQUNYLEtBbEZzQyxDQW9GdkM7QUFDQTtBQUNBOzs7QUFDQSxRQUFJWixRQUFKLEVBQWM7QUFDWCxnQkFBU2dDLElBQVQsR0FBZ0I7QUFDZjVCLFFBQUFBLFVBQVUsQ0FBQyxZQUFXO0FBQ3BCOztBQUNBO0FBQ0EsY0FBSVEsVUFBVSxHQUFHQyxhQUFqQixFQUFnQztBQUM5QixtQkFBT2IsUUFBUSxFQUFmO0FBQ0Q7O0FBRUQsY0FBSSxDQUFDcUIsY0FBYyxFQUFuQixFQUF1QjtBQUNyQlcsWUFBQUEsSUFBSTtBQUNMO0FBQ0YsU0FWUyxFQVVQLENBVk8sQ0FBVjtBQVdELE9BWkEsR0FBRDtBQWFELEtBZEQsTUFjTztBQUNMLGFBQU9wQixVQUFVLElBQUlDLGFBQXJCLEVBQW9DO0FBQ2xDLFlBQUlvQixHQUFHLEdBQUdaLGNBQWMsRUFBeEI7O0FBQ0EsWUFBSVksR0FBSixFQUFTO0FBQ1AsaUJBQU9BLEdBQVA7QUFDRDtBQUNGO0FBQ0Y7QUFDRixHQTlHYzs7QUFBQTs7QUFBQTtBQWdIZkosRUFBQUEsYUFoSGUseUJBZ0hEYixVQWhIQyxFQWdIV2tCLEtBaEhYLEVBZ0hrQkMsT0FoSGxCLEVBZ0gyQjtBQUN4QyxRQUFJQyxJQUFJLEdBQUdwQixVQUFVLENBQUNBLFVBQVUsQ0FBQ04sTUFBWCxHQUFvQixDQUFyQixDQUFyQjs7QUFDQSxRQUFJMEIsSUFBSSxJQUFJQSxJQUFJLENBQUNGLEtBQUwsS0FBZUEsS0FBdkIsSUFBZ0NFLElBQUksQ0FBQ0QsT0FBTCxLQUFpQkEsT0FBckQsRUFBOEQ7QUFDNUQ7QUFDQTtBQUNBbkIsTUFBQUEsVUFBVSxDQUFDQSxVQUFVLENBQUNOLE1BQVgsR0FBb0IsQ0FBckIsQ0FBVixHQUFvQztBQUFDVSxRQUFBQSxLQUFLLEVBQUVnQixJQUFJLENBQUNoQixLQUFMLEdBQWEsQ0FBckI7QUFBd0JjLFFBQUFBLEtBQUssRUFBRUEsS0FBL0I7QUFBc0NDLFFBQUFBLE9BQU8sRUFBRUE7QUFBL0MsT0FBcEM7QUFDRCxLQUpELE1BSU87QUFDTG5CLE1BQUFBLFVBQVUsQ0FBQ3FCLElBQVgsQ0FBZ0I7QUFBQ2pCLFFBQUFBLEtBQUssRUFBRSxDQUFSO0FBQVdjLFFBQUFBLEtBQUssRUFBRUEsS0FBbEI7QUFBeUJDLFFBQUFBLE9BQU8sRUFBRUE7QUFBbEMsT0FBaEI7QUFDRDtBQUNGLEdBekhjOztBQUFBOztBQUFBO0FBMEhmakIsRUFBQUEsYUExSGUseUJBMEhESyxRQTFIQyxFQTBIU3pCLFNBMUhULEVBMEhvQkQsU0ExSHBCLEVBMEgrQnlCLFlBMUgvQixFQTBINkM7QUFDMUQsUUFBSWIsTUFBTSxHQUFHWCxTQUFTLENBQUNZLE1BQXZCO0FBQUEsUUFDSUMsTUFBTSxHQUFHZCxTQUFTLENBQUNhLE1BRHZCO0FBQUEsUUFFSUssTUFBTSxHQUFHUSxRQUFRLENBQUNSLE1BRnRCO0FBQUEsUUFHSUUsTUFBTSxHQUFHRixNQUFNLEdBQUdPLFlBSHRCO0FBQUEsUUFLSWdCLFdBQVcsR0FBRyxDQUxsQjs7QUFNQSxXQUFPdkIsTUFBTSxHQUFHLENBQVQsR0FBYU4sTUFBYixJQUF1QlEsTUFBTSxHQUFHLENBQVQsR0FBYU4sTUFBcEMsSUFBOEMsS0FBSzRCLE1BQUwsQ0FBWXpDLFNBQVMsQ0FBQ2lCLE1BQU0sR0FBRyxDQUFWLENBQXJCLEVBQW1DbEIsU0FBUyxDQUFDb0IsTUFBTSxHQUFHLENBQVYsQ0FBNUMsQ0FBckQsRUFBZ0g7QUFDOUdGLE1BQUFBLE1BQU07QUFDTkUsTUFBQUEsTUFBTTtBQUNOcUIsTUFBQUEsV0FBVztBQUNaOztBQUVELFFBQUlBLFdBQUosRUFBaUI7QUFDZmYsTUFBQUEsUUFBUSxDQUFDUCxVQUFULENBQW9CcUIsSUFBcEIsQ0FBeUI7QUFBQ2pCLFFBQUFBLEtBQUssRUFBRWtCO0FBQVIsT0FBekI7QUFDRDs7QUFFRGYsSUFBQUEsUUFBUSxDQUFDUixNQUFULEdBQWtCQSxNQUFsQjtBQUNBLFdBQU9FLE1BQVA7QUFDRCxHQTdJYzs7QUFBQTs7QUFBQTtBQStJZnNCLEVBQUFBLE1BL0llLGtCQStJUkMsSUEvSVEsRUErSUZDLEtBL0lFLEVBK0lLO0FBQ2xCLFFBQUksS0FBSzFDLE9BQUwsQ0FBYTJDLFVBQWpCLEVBQTZCO0FBQzNCLGFBQU8sS0FBSzNDLE9BQUwsQ0FBYTJDLFVBQWIsQ0FBd0JGLElBQXhCLEVBQThCQyxLQUE5QixDQUFQO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsYUFBT0QsSUFBSSxLQUFLQyxLQUFULElBQ0QsS0FBSzFDLE9BQUwsQ0FBYTRDLFVBQWIsSUFBMkJILElBQUksQ0FBQ0ksV0FBTCxPQUF1QkgsS0FBSyxDQUFDRyxXQUFOLEVBRHhEO0FBRUQ7QUFDRixHQXRKYzs7QUFBQTs7QUFBQTtBQXVKZnJDLEVBQUFBLFdBdkplLHVCQXVKSHNDLEtBdkpHLEVBdUpJO0FBQ2pCLFFBQUlaLEdBQUcsR0FBRyxFQUFWOztBQUNBLFNBQUssSUFBSWEsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0QsS0FBSyxDQUFDbkMsTUFBMUIsRUFBa0NvQyxDQUFDLEVBQW5DLEVBQXVDO0FBQ3JDLFVBQUlELEtBQUssQ0FBQ0MsQ0FBRCxDQUFULEVBQWM7QUFDWmIsUUFBQUEsR0FBRyxDQUFDSSxJQUFKLENBQVNRLEtBQUssQ0FBQ0MsQ0FBRCxDQUFkO0FBQ0Q7QUFDRjs7QUFDRCxXQUFPYixHQUFQO0FBQ0QsR0EvSmM7O0FBQUE7O0FBQUE7QUFnS2YzQixFQUFBQSxTQWhLZSxxQkFnS0xILEtBaEtLLEVBZ0tFO0FBQ2YsV0FBT0EsS0FBUDtBQUNELEdBbEtjOztBQUFBOztBQUFBO0FBbUtmSyxFQUFBQSxRQW5LZSxvQkFtS05MLEtBbktNLEVBbUtDO0FBQ2QsV0FBT0EsS0FBSyxDQUFDNEMsS0FBTixDQUFZLEVBQVosQ0FBUDtBQUNELEdBcktjOztBQUFBOztBQUFBO0FBc0tmNUIsRUFBQUEsSUF0S2UsZ0JBc0tWNkIsS0F0S1UsRUFzS0g7QUFDVixXQUFPQSxLQUFLLENBQUM3QixJQUFOLENBQVcsRUFBWCxDQUFQO0FBQ0Q7QUF4S2MsQ0FBakI7O0FBMktBLFNBQVNXLFdBQVQsQ0FBcUJsQyxJQUFyQixFQUEyQm9CLFVBQTNCLEVBQXVDbEIsU0FBdkMsRUFBa0RELFNBQWxELEVBQTZEa0MsZUFBN0QsRUFBOEU7QUFDNUUsTUFBSWtCLFlBQVksR0FBRyxDQUFuQjtBQUFBLE1BQ0lDLFlBQVksR0FBR2xDLFVBQVUsQ0FBQ04sTUFEOUI7QUFBQSxNQUVJSyxNQUFNLEdBQUcsQ0FGYjtBQUFBLE1BR0lFLE1BQU0sR0FBRyxDQUhiOztBQUtBLFNBQU9nQyxZQUFZLEdBQUdDLFlBQXRCLEVBQW9DRCxZQUFZLEVBQWhELEVBQW9EO0FBQ2xELFFBQUlFLFNBQVMsR0FBR25DLFVBQVUsQ0FBQ2lDLFlBQUQsQ0FBMUI7O0FBQ0EsUUFBSSxDQUFDRSxTQUFTLENBQUNoQixPQUFmLEVBQXdCO0FBQ3RCLFVBQUksQ0FBQ2dCLFNBQVMsQ0FBQ2pCLEtBQVgsSUFBb0JILGVBQXhCLEVBQXlDO0FBQ3ZDLFlBQUk1QixLQUFLLEdBQUdMLFNBQVMsQ0FBQ3NELEtBQVYsQ0FBZ0JyQyxNQUFoQixFQUF3QkEsTUFBTSxHQUFHb0MsU0FBUyxDQUFDL0IsS0FBM0MsQ0FBWjtBQUNBakIsUUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNrRCxHQUFOLENBQVUsVUFBU2xELEtBQVQsRUFBZ0IyQyxDQUFoQixFQUFtQjtBQUNuQyxjQUFJUSxRQUFRLEdBQUd6RCxTQUFTLENBQUNvQixNQUFNLEdBQUc2QixDQUFWLENBQXhCO0FBQ0EsaUJBQU9RLFFBQVEsQ0FBQzVDLE1BQVQsR0FBa0JQLEtBQUssQ0FBQ08sTUFBeEIsR0FBaUM0QyxRQUFqQyxHQUE0Q25ELEtBQW5EO0FBQ0QsU0FITyxDQUFSO0FBS0FnRCxRQUFBQSxTQUFTLENBQUNoRCxLQUFWLEdBQWtCUCxJQUFJLENBQUN1QixJQUFMLENBQVVoQixLQUFWLENBQWxCO0FBQ0QsT0FSRCxNQVFPO0FBQ0xnRCxRQUFBQSxTQUFTLENBQUNoRCxLQUFWLEdBQWtCUCxJQUFJLENBQUN1QixJQUFMLENBQVVyQixTQUFTLENBQUNzRCxLQUFWLENBQWdCckMsTUFBaEIsRUFBd0JBLE1BQU0sR0FBR29DLFNBQVMsQ0FBQy9CLEtBQTNDLENBQVYsQ0FBbEI7QUFDRDs7QUFDREwsTUFBQUEsTUFBTSxJQUFJb0MsU0FBUyxDQUFDL0IsS0FBcEIsQ0Fac0IsQ0FjdEI7O0FBQ0EsVUFBSSxDQUFDK0IsU0FBUyxDQUFDakIsS0FBZixFQUFzQjtBQUNwQmpCLFFBQUFBLE1BQU0sSUFBSWtDLFNBQVMsQ0FBQy9CLEtBQXBCO0FBQ0Q7QUFDRixLQWxCRCxNQWtCTztBQUNMK0IsTUFBQUEsU0FBUyxDQUFDaEQsS0FBVixHQUFrQlAsSUFBSSxDQUFDdUIsSUFBTCxDQUFVdEIsU0FBUyxDQUFDdUQsS0FBVixDQUFnQm5DLE1BQWhCLEVBQXdCQSxNQUFNLEdBQUdrQyxTQUFTLENBQUMvQixLQUEzQyxDQUFWLENBQWxCO0FBQ0FILE1BQUFBLE1BQU0sSUFBSWtDLFNBQVMsQ0FBQy9CLEtBQXBCLENBRkssQ0FJTDtBQUNBO0FBQ0E7O0FBQ0EsVUFBSTZCLFlBQVksSUFBSWpDLFVBQVUsQ0FBQ2lDLFlBQVksR0FBRyxDQUFoQixDQUFWLENBQTZCZixLQUFqRCxFQUF3RDtBQUN0RCxZQUFJcUIsR0FBRyxHQUFHdkMsVUFBVSxDQUFDaUMsWUFBWSxHQUFHLENBQWhCLENBQXBCO0FBQ0FqQyxRQUFBQSxVQUFVLENBQUNpQyxZQUFZLEdBQUcsQ0FBaEIsQ0FBVixHQUErQmpDLFVBQVUsQ0FBQ2lDLFlBQUQsQ0FBekM7QUFDQWpDLFFBQUFBLFVBQVUsQ0FBQ2lDLFlBQUQsQ0FBVixHQUEyQk0sR0FBM0I7QUFDRDtBQUNGO0FBQ0YsR0F2QzJFLENBeUM1RTtBQUNBO0FBQ0E7OztBQUNBLE1BQUlDLGFBQWEsR0FBR3hDLFVBQVUsQ0FBQ2tDLFlBQVksR0FBRyxDQUFoQixDQUE5Qjs7QUFDQSxNQUFJQSxZQUFZLEdBQUcsQ0FBZixJQUNHLE9BQU9NLGFBQWEsQ0FBQ3JELEtBQXJCLEtBQStCLFFBRGxDLEtBRUlxRCxhQUFhLENBQUN0QixLQUFkLElBQXVCc0IsYUFBYSxDQUFDckIsT0FGekMsS0FHR3ZDLElBQUksQ0FBQzJDLE1BQUwsQ0FBWSxFQUFaLEVBQWdCaUIsYUFBYSxDQUFDckQsS0FBOUIsQ0FIUCxFQUc2QztBQUMzQ2EsSUFBQUEsVUFBVSxDQUFDa0MsWUFBWSxHQUFHLENBQWhCLENBQVYsQ0FBNkIvQyxLQUE3QixJQUFzQ3FELGFBQWEsQ0FBQ3JELEtBQXBEO0FBQ0FhLElBQUFBLFVBQVUsQ0FBQ3lDLEdBQVg7QUFDRDs7QUFFRCxTQUFPekMsVUFBUDtBQUNEOztBQUVELFNBQVNZLFNBQVQsQ0FBbUI4QixJQUFuQixFQUF5QjtBQUN2QixTQUFPO0FBQUUzQyxJQUFBQSxNQUFNLEVBQUUyQyxJQUFJLENBQUMzQyxNQUFmO0FBQXVCQyxJQUFBQSxVQUFVLEVBQUUwQyxJQUFJLENBQUMxQyxVQUFMLENBQWdCb0MsS0FBaEIsQ0FBc0IsQ0FBdEI7QUFBbkMsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlmZigpIHt9XG5cbkRpZmYucHJvdG90eXBlID0ge1xuICBkaWZmKG9sZFN0cmluZywgbmV3U3RyaW5nLCBvcHRpb25zID0ge30pIHtcbiAgICBsZXQgY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgbGV0IHNlbGYgPSB0aGlzO1xuXG4gICAgZnVuY3Rpb24gZG9uZSh2YWx1ZSkge1xuICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKHVuZGVmaW5lZCwgdmFsdWUpOyB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgc3ViY2xhc3NlcyB0byBtYXNzYWdlIHRoZSBpbnB1dCBwcmlvciB0byBydW5uaW5nXG4gICAgb2xkU3RyaW5nID0gdGhpcy5jYXN0SW5wdXQob2xkU3RyaW5nKTtcbiAgICBuZXdTdHJpbmcgPSB0aGlzLmNhc3RJbnB1dChuZXdTdHJpbmcpO1xuXG4gICAgb2xkU3RyaW5nID0gdGhpcy5yZW1vdmVFbXB0eSh0aGlzLnRva2VuaXplKG9sZFN0cmluZykpO1xuICAgIG5ld1N0cmluZyA9IHRoaXMucmVtb3ZlRW1wdHkodGhpcy50b2tlbml6ZShuZXdTdHJpbmcpKTtcblxuICAgIGxldCBuZXdMZW4gPSBuZXdTdHJpbmcubGVuZ3RoLCBvbGRMZW4gPSBvbGRTdHJpbmcubGVuZ3RoO1xuICAgIGxldCBlZGl0TGVuZ3RoID0gMTtcbiAgICBsZXQgbWF4RWRpdExlbmd0aCA9IG5ld0xlbiArIG9sZExlbjtcbiAgICBsZXQgYmVzdFBhdGggPSBbeyBuZXdQb3M6IC0xLCBjb21wb25lbnRzOiBbXSB9XTtcblxuICAgIC8vIFNlZWQgZWRpdExlbmd0aCA9IDAsIGkuZS4gdGhlIGNvbnRlbnQgc3RhcnRzIHdpdGggdGhlIHNhbWUgdmFsdWVzXG4gICAgbGV0IG9sZFBvcyA9IHRoaXMuZXh0cmFjdENvbW1vbihiZXN0UGF0aFswXSwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIDApO1xuICAgIGlmIChiZXN0UGF0aFswXS5uZXdQb3MgKyAxID49IG5ld0xlbiAmJiBvbGRQb3MgKyAxID49IG9sZExlbikge1xuICAgICAgLy8gSWRlbnRpdHkgcGVyIHRoZSBlcXVhbGl0eSBhbmQgdG9rZW5pemVyXG4gICAgICByZXR1cm4gZG9uZShbe3ZhbHVlOiB0aGlzLmpvaW4obmV3U3RyaW5nKSwgY291bnQ6IG5ld1N0cmluZy5sZW5ndGh9XSk7XG4gICAgfVxuXG4gICAgLy8gTWFpbiB3b3JrZXIgbWV0aG9kLiBjaGVja3MgYWxsIHBlcm11dGF0aW9ucyBvZiBhIGdpdmVuIGVkaXQgbGVuZ3RoIGZvciBhY2NlcHRhbmNlLlxuICAgIGZ1bmN0aW9uIGV4ZWNFZGl0TGVuZ3RoKCkge1xuICAgICAgZm9yIChsZXQgZGlhZ29uYWxQYXRoID0gLTEgKiBlZGl0TGVuZ3RoOyBkaWFnb25hbFBhdGggPD0gZWRpdExlbmd0aDsgZGlhZ29uYWxQYXRoICs9IDIpIHtcbiAgICAgICAgbGV0IGJhc2VQYXRoO1xuICAgICAgICBsZXQgYWRkUGF0aCA9IGJlc3RQYXRoW2RpYWdvbmFsUGF0aCAtIDFdLFxuICAgICAgICAgICAgcmVtb3ZlUGF0aCA9IGJlc3RQYXRoW2RpYWdvbmFsUGF0aCArIDFdLFxuICAgICAgICAgICAgb2xkUG9zID0gKHJlbW92ZVBhdGggPyByZW1vdmVQYXRoLm5ld1BvcyA6IDApIC0gZGlhZ29uYWxQYXRoO1xuICAgICAgICBpZiAoYWRkUGF0aCkge1xuICAgICAgICAgIC8vIE5vIG9uZSBlbHNlIGlzIGdvaW5nIHRvIGF0dGVtcHQgdG8gdXNlIHRoaXMgdmFsdWUsIGNsZWFyIGl0XG4gICAgICAgICAgYmVzdFBhdGhbZGlhZ29uYWxQYXRoIC0gMV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY2FuQWRkID0gYWRkUGF0aCAmJiBhZGRQYXRoLm5ld1BvcyArIDEgPCBuZXdMZW4sXG4gICAgICAgICAgICBjYW5SZW1vdmUgPSByZW1vdmVQYXRoICYmIDAgPD0gb2xkUG9zICYmIG9sZFBvcyA8IG9sZExlbjtcbiAgICAgICAgaWYgKCFjYW5BZGQgJiYgIWNhblJlbW92ZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgcGF0aCBpcyBhIHRlcm1pbmFsIHRoZW4gcHJ1bmVcbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGhdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VsZWN0IHRoZSBkaWFnb25hbCB0aGF0IHdlIHdhbnQgdG8gYnJhbmNoIGZyb20uIFdlIHNlbGVjdCB0aGUgcHJpb3JcbiAgICAgICAgLy8gcGF0aCB3aG9zZSBwb3NpdGlvbiBpbiB0aGUgbmV3IHN0cmluZyBpcyB0aGUgZmFydGhlc3QgZnJvbSB0aGUgb3JpZ2luXG4gICAgICAgIC8vIGFuZCBkb2VzIG5vdCBwYXNzIHRoZSBib3VuZHMgb2YgdGhlIGRpZmYgZ3JhcGhcbiAgICAgICAgaWYgKCFjYW5BZGQgfHwgKGNhblJlbW92ZSAmJiBhZGRQYXRoLm5ld1BvcyA8IHJlbW92ZVBhdGgubmV3UG9zKSkge1xuICAgICAgICAgIGJhc2VQYXRoID0gY2xvbmVQYXRoKHJlbW92ZVBhdGgpO1xuICAgICAgICAgIHNlbGYucHVzaENvbXBvbmVudChiYXNlUGF0aC5jb21wb25lbnRzLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJhc2VQYXRoID0gYWRkUGF0aDsgLy8gTm8gbmVlZCB0byBjbG9uZSwgd2UndmUgcHVsbGVkIGl0IGZyb20gdGhlIGxpc3RcbiAgICAgICAgICBiYXNlUGF0aC5uZXdQb3MrKztcbiAgICAgICAgICBzZWxmLnB1c2hDb21wb25lbnQoYmFzZVBhdGguY29tcG9uZW50cywgdHJ1ZSwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9sZFBvcyA9IHNlbGYuZXh0cmFjdENvbW1vbihiYXNlUGF0aCwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIGRpYWdvbmFsUGF0aCk7XG5cbiAgICAgICAgLy8gSWYgd2UgaGF2ZSBoaXQgdGhlIGVuZCBvZiBib3RoIHN0cmluZ3MsIHRoZW4gd2UgYXJlIGRvbmVcbiAgICAgICAgaWYgKGJhc2VQYXRoLm5ld1BvcyArIDEgPj0gbmV3TGVuICYmIG9sZFBvcyArIDEgPj0gb2xkTGVuKSB7XG4gICAgICAgICAgcmV0dXJuIGRvbmUoYnVpbGRWYWx1ZXMoc2VsZiwgYmFzZVBhdGguY29tcG9uZW50cywgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIHNlbGYudXNlTG9uZ2VzdFRva2VuKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIHRyYWNrIHRoaXMgcGF0aCBhcyBhIHBvdGVudGlhbCBjYW5kaWRhdGUgYW5kIGNvbnRpbnVlLlxuICAgICAgICAgIGJlc3RQYXRoW2RpYWdvbmFsUGF0aF0gPSBiYXNlUGF0aDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlZGl0TGVuZ3RoKys7XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybXMgdGhlIGxlbmd0aCBvZiBlZGl0IGl0ZXJhdGlvbi4gSXMgYSBiaXQgZnVnbHkgYXMgdGhpcyBoYXMgdG8gc3VwcG9ydCB0aGVcbiAgICAvLyBzeW5jIGFuZCBhc3luYyBtb2RlIHdoaWNoIGlzIG5ldmVyIGZ1bi4gTG9vcHMgb3ZlciBleGVjRWRpdExlbmd0aCB1bnRpbCBhIHZhbHVlXG4gICAgLy8gaXMgcHJvZHVjZWQuXG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAoZnVuY3Rpb24gZXhlYygpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAvLyBUaGlzIHNob3VsZCBub3QgaGFwcGVuLCBidXQgd2Ugd2FudCB0byBiZSBzYWZlLlxuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgaWYgKGVkaXRMZW5ndGggPiBtYXhFZGl0TGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWV4ZWNFZGl0TGVuZ3RoKCkpIHtcbiAgICAgICAgICAgIGV4ZWMoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIDApO1xuICAgICAgfSgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hpbGUgKGVkaXRMZW5ndGggPD0gbWF4RWRpdExlbmd0aCkge1xuICAgICAgICBsZXQgcmV0ID0gZXhlY0VkaXRMZW5ndGgoKTtcbiAgICAgICAgaWYgKHJldCkge1xuICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgcHVzaENvbXBvbmVudChjb21wb25lbnRzLCBhZGRlZCwgcmVtb3ZlZCkge1xuICAgIGxldCBsYXN0ID0gY29tcG9uZW50c1tjb21wb25lbnRzLmxlbmd0aCAtIDFdO1xuICAgIGlmIChsYXN0ICYmIGxhc3QuYWRkZWQgPT09IGFkZGVkICYmIGxhc3QucmVtb3ZlZCA9PT0gcmVtb3ZlZCkge1xuICAgICAgLy8gV2UgbmVlZCB0byBjbG9uZSBoZXJlIGFzIHRoZSBjb21wb25lbnQgY2xvbmUgb3BlcmF0aW9uIGlzIGp1c3RcbiAgICAgIC8vIGFzIHNoYWxsb3cgYXJyYXkgY2xvbmVcbiAgICAgIGNvbXBvbmVudHNbY29tcG9uZW50cy5sZW5ndGggLSAxXSA9IHtjb3VudDogbGFzdC5jb3VudCArIDEsIGFkZGVkOiBhZGRlZCwgcmVtb3ZlZDogcmVtb3ZlZCB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb21wb25lbnRzLnB1c2goe2NvdW50OiAxLCBhZGRlZDogYWRkZWQsIHJlbW92ZWQ6IHJlbW92ZWQgfSk7XG4gICAgfVxuICB9LFxuICBleHRyYWN0Q29tbW9uKGJhc2VQYXRoLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgZGlhZ29uYWxQYXRoKSB7XG4gICAgbGV0IG5ld0xlbiA9IG5ld1N0cmluZy5sZW5ndGgsXG4gICAgICAgIG9sZExlbiA9IG9sZFN0cmluZy5sZW5ndGgsXG4gICAgICAgIG5ld1BvcyA9IGJhc2VQYXRoLm5ld1BvcyxcbiAgICAgICAgb2xkUG9zID0gbmV3UG9zIC0gZGlhZ29uYWxQYXRoLFxuXG4gICAgICAgIGNvbW1vbkNvdW50ID0gMDtcbiAgICB3aGlsZSAobmV3UG9zICsgMSA8IG5ld0xlbiAmJiBvbGRQb3MgKyAxIDwgb2xkTGVuICYmIHRoaXMuZXF1YWxzKG5ld1N0cmluZ1tuZXdQb3MgKyAxXSwgb2xkU3RyaW5nW29sZFBvcyArIDFdKSkge1xuICAgICAgbmV3UG9zKys7XG4gICAgICBvbGRQb3MrKztcbiAgICAgIGNvbW1vbkNvdW50Kys7XG4gICAgfVxuXG4gICAgaWYgKGNvbW1vbkNvdW50KSB7XG4gICAgICBiYXNlUGF0aC5jb21wb25lbnRzLnB1c2goe2NvdW50OiBjb21tb25Db3VudH0pO1xuICAgIH1cblxuICAgIGJhc2VQYXRoLm5ld1BvcyA9IG5ld1BvcztcbiAgICByZXR1cm4gb2xkUG9zO1xuICB9LFxuXG4gIGVxdWFscyhsZWZ0LCByaWdodCkge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5jb21wYXJhdG9yKGxlZnQsIHJpZ2h0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGxlZnQgPT09IHJpZ2h0XG4gICAgICAgIHx8ICh0aGlzLm9wdGlvbnMuaWdub3JlQ2FzZSAmJiBsZWZ0LnRvTG93ZXJDYXNlKCkgPT09IHJpZ2h0LnRvTG93ZXJDYXNlKCkpO1xuICAgIH1cbiAgfSxcbiAgcmVtb3ZlRW1wdHkoYXJyYXkpIHtcbiAgICBsZXQgcmV0ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFycmF5W2ldKSB7XG4gICAgICAgIHJldC5wdXNoKGFycmF5W2ldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfSxcbiAgY2FzdElucHV0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICB0b2tlbml6ZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZS5zcGxpdCgnJyk7XG4gIH0sXG4gIGpvaW4oY2hhcnMpIHtcbiAgICByZXR1cm4gY2hhcnMuam9pbignJyk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGJ1aWxkVmFsdWVzKGRpZmYsIGNvbXBvbmVudHMsIG5ld1N0cmluZywgb2xkU3RyaW5nLCB1c2VMb25nZXN0VG9rZW4pIHtcbiAgbGV0IGNvbXBvbmVudFBvcyA9IDAsXG4gICAgICBjb21wb25lbnRMZW4gPSBjb21wb25lbnRzLmxlbmd0aCxcbiAgICAgIG5ld1BvcyA9IDAsXG4gICAgICBvbGRQb3MgPSAwO1xuXG4gIGZvciAoOyBjb21wb25lbnRQb3MgPCBjb21wb25lbnRMZW47IGNvbXBvbmVudFBvcysrKSB7XG4gICAgbGV0IGNvbXBvbmVudCA9IGNvbXBvbmVudHNbY29tcG9uZW50UG9zXTtcbiAgICBpZiAoIWNvbXBvbmVudC5yZW1vdmVkKSB7XG4gICAgICBpZiAoIWNvbXBvbmVudC5hZGRlZCAmJiB1c2VMb25nZXN0VG9rZW4pIHtcbiAgICAgICAgbGV0IHZhbHVlID0gbmV3U3RyaW5nLnNsaWNlKG5ld1BvcywgbmV3UG9zICsgY29tcG9uZW50LmNvdW50KTtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5tYXAoZnVuY3Rpb24odmFsdWUsIGkpIHtcbiAgICAgICAgICBsZXQgb2xkVmFsdWUgPSBvbGRTdHJpbmdbb2xkUG9zICsgaV07XG4gICAgICAgICAgcmV0dXJuIG9sZFZhbHVlLmxlbmd0aCA+IHZhbHVlLmxlbmd0aCA/IG9sZFZhbHVlIDogdmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbXBvbmVudC52YWx1ZSA9IGRpZmYuam9pbih2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb21wb25lbnQudmFsdWUgPSBkaWZmLmpvaW4obmV3U3RyaW5nLnNsaWNlKG5ld1BvcywgbmV3UG9zICsgY29tcG9uZW50LmNvdW50KSk7XG4gICAgICB9XG4gICAgICBuZXdQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuXG4gICAgICAvLyBDb21tb24gY2FzZVxuICAgICAgaWYgKCFjb21wb25lbnQuYWRkZWQpIHtcbiAgICAgICAgb2xkUG9zICs9IGNvbXBvbmVudC5jb3VudDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29tcG9uZW50LnZhbHVlID0gZGlmZi5qb2luKG9sZFN0cmluZy5zbGljZShvbGRQb3MsIG9sZFBvcyArIGNvbXBvbmVudC5jb3VudCkpO1xuICAgICAgb2xkUG9zICs9IGNvbXBvbmVudC5jb3VudDtcblxuICAgICAgLy8gUmV2ZXJzZSBhZGQgYW5kIHJlbW92ZSBzbyByZW1vdmVzIGFyZSBvdXRwdXQgZmlyc3QgdG8gbWF0Y2ggY29tbW9uIGNvbnZlbnRpb25cbiAgICAgIC8vIFRoZSBkaWZmaW5nIGFsZ29yaXRobSBpcyB0aWVkIHRvIGFkZCB0aGVuIHJlbW92ZSBvdXRwdXQgYW5kIHRoaXMgaXMgdGhlIHNpbXBsZXN0XG4gICAgICAvLyByb3V0ZSB0byBnZXQgdGhlIGRlc2lyZWQgb3V0cHV0IHdpdGggbWluaW1hbCBvdmVyaGVhZC5cbiAgICAgIGlmIChjb21wb25lbnRQb3MgJiYgY29tcG9uZW50c1tjb21wb25lbnRQb3MgLSAxXS5hZGRlZCkge1xuICAgICAgICBsZXQgdG1wID0gY29tcG9uZW50c1tjb21wb25lbnRQb3MgLSAxXTtcbiAgICAgICAgY29tcG9uZW50c1tjb21wb25lbnRQb3MgLSAxXSA9IGNvbXBvbmVudHNbY29tcG9uZW50UG9zXTtcbiAgICAgICAgY29tcG9uZW50c1tjb21wb25lbnRQb3NdID0gdG1wO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFNwZWNpYWwgY2FzZSBoYW5kbGUgZm9yIHdoZW4gb25lIHRlcm1pbmFsIGlzIGlnbm9yZWQgKGkuZS4gd2hpdGVzcGFjZSkuXG4gIC8vIEZvciB0aGlzIGNhc2Ugd2UgbWVyZ2UgdGhlIHRlcm1pbmFsIGludG8gdGhlIHByaW9yIHN0cmluZyBhbmQgZHJvcCB0aGUgY2hhbmdlLlxuICAvLyBUaGlzIGlzIG9ubHkgYXZhaWxhYmxlIGZvciBzdHJpbmcgbW9kZS5cbiAgbGV0IGxhc3RDb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudExlbiAtIDFdO1xuICBpZiAoY29tcG9uZW50TGVuID4gMVxuICAgICAgJiYgdHlwZW9mIGxhc3RDb21wb25lbnQudmFsdWUgPT09ICdzdHJpbmcnXG4gICAgICAmJiAobGFzdENvbXBvbmVudC5hZGRlZCB8fCBsYXN0Q29tcG9uZW50LnJlbW92ZWQpXG4gICAgICAmJiBkaWZmLmVxdWFscygnJywgbGFzdENvbXBvbmVudC52YWx1ZSkpIHtcbiAgICBjb21wb25lbnRzW2NvbXBvbmVudExlbiAtIDJdLnZhbHVlICs9IGxhc3RDb21wb25lbnQudmFsdWU7XG4gICAgY29tcG9uZW50cy5wb3AoKTtcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnRzO1xufVxuXG5mdW5jdGlvbiBjbG9uZVBhdGgocGF0aCkge1xuICByZXR1cm4geyBuZXdQb3M6IHBhdGgubmV3UG9zLCBjb21wb25lbnRzOiBwYXRoLmNvbXBvbmVudHMuc2xpY2UoMCkgfTtcbn1cbiJdfQ== diff --git a/node_modules/diff/lib/diff/character.js b/node_modules/diff/lib/diff/character.js deleted file mode 100644 index 7ddfa205e394a..0000000000000 --- a/node_modules/diff/lib/diff/character.js +++ /dev/null @@ -1,37 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffChars = diffChars; -exports.characterDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -var characterDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); - -/*istanbul ignore start*/ -exports.characterDiff = characterDiff; - -/*istanbul ignore end*/ -function diffChars(oldStr, newStr, options) { - return characterDiff.diff(oldStr, newStr, options); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2NoYXJhY3Rlci5qcyJdLCJuYW1lcyI6WyJjaGFyYWN0ZXJEaWZmIiwiRGlmZiIsImRpZmZDaGFycyIsIm9sZFN0ciIsIm5ld1N0ciIsIm9wdGlvbnMiLCJkaWZmIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7QUFFTyxJQUFNQSxhQUFhLEdBQUc7QUFBSUM7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUEsQ0FBSixFQUF0Qjs7Ozs7O0FBQ0EsU0FBU0MsU0FBVCxDQUFtQkMsTUFBbkIsRUFBMkJDLE1BQTNCLEVBQW1DQyxPQUFuQyxFQUE0QztBQUFFLFNBQU9MLGFBQWEsQ0FBQ00sSUFBZCxDQUFtQkgsTUFBbkIsRUFBMkJDLE1BQTNCLEVBQW1DQyxPQUFuQyxDQUFQO0FBQXFEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGNoYXJhY3RlckRpZmYgPSBuZXcgRGlmZigpO1xuZXhwb3J0IGZ1bmN0aW9uIGRpZmZDaGFycyhvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucykgeyByZXR1cm4gY2hhcmFjdGVyRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTsgfVxuIl19 diff --git a/node_modules/diff/lib/diff/css.js b/node_modules/diff/lib/diff/css.js deleted file mode 100644 index e3ad1fcba5f0e..0000000000000 --- a/node_modules/diff/lib/diff/css.js +++ /dev/null @@ -1,41 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffCss = diffCss; -exports.cssDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -var cssDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); - -/*istanbul ignore start*/ -exports.cssDiff = cssDiff; - -/*istanbul ignore end*/ -cssDiff.tokenize = function (value) { - return value.split(/([{}:;,]|\s+)/); -}; - -function diffCss(oldStr, newStr, callback) { - return cssDiff.diff(oldStr, newStr, callback); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2Nzcy5qcyJdLCJuYW1lcyI6WyJjc3NEaWZmIiwiRGlmZiIsInRva2VuaXplIiwidmFsdWUiLCJzcGxpdCIsImRpZmZDc3MiLCJvbGRTdHIiLCJuZXdTdHIiLCJjYWxsYmFjayIsImRpZmYiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7OztBQUVPLElBQU1BLE9BQU8sR0FBRztBQUFJQztBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQSxDQUFKLEVBQWhCOzs7Ozs7QUFDUEQsT0FBTyxDQUFDRSxRQUFSLEdBQW1CLFVBQVNDLEtBQVQsRUFBZ0I7QUFDakMsU0FBT0EsS0FBSyxDQUFDQyxLQUFOLENBQVksZUFBWixDQUFQO0FBQ0QsQ0FGRDs7QUFJTyxTQUFTQyxPQUFULENBQWlCQyxNQUFqQixFQUF5QkMsTUFBekIsRUFBaUNDLFFBQWpDLEVBQTJDO0FBQUUsU0FBT1IsT0FBTyxDQUFDUyxJQUFSLENBQWFILE1BQWIsRUFBcUJDLE1BQXJCLEVBQTZCQyxRQUE3QixDQUFQO0FBQWdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGNzc0RpZmYgPSBuZXcgRGlmZigpO1xuY3NzRGlmZi50b2tlbml6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZS5zcGxpdCgvKFt7fTo7LF18XFxzKykvKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWZmQ3NzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykgeyByZXR1cm4gY3NzRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbiJdfQ== diff --git a/node_modules/diff/lib/diff/json.js b/node_modules/diff/lib/diff/json.js deleted file mode 100644 index 67c2f175f73b4..0000000000000 --- a/node_modules/diff/lib/diff/json.js +++ /dev/null @@ -1,163 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffJson = diffJson; -exports.canonicalize = canonicalize; -exports.jsonDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_line = require("./line") -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } - -/*istanbul ignore end*/ -var objectPrototypeToString = Object.prototype.toString; -var jsonDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a -// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - -/*istanbul ignore start*/ -exports.jsonDiff = jsonDiff; - -/*istanbul ignore end*/ -jsonDiff.useLongestToken = true; -jsonDiff.tokenize = -/*istanbul ignore start*/ -_line -/*istanbul ignore end*/ -. -/*istanbul ignore start*/ -lineDiff -/*istanbul ignore end*/ -.tokenize; - -jsonDiff.castInput = function (value) { - /*istanbul ignore start*/ - var _this$options = - /*istanbul ignore end*/ - this.options, - undefinedReplacement = _this$options.undefinedReplacement, - _this$options$stringi = _this$options.stringifyReplacer, - stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) - /*istanbul ignore start*/ - { - return ( - /*istanbul ignore end*/ - typeof v === 'undefined' ? undefinedReplacement : v - ); - } : _this$options$stringi; - return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' '); -}; - -jsonDiff.equals = function (left, right) { - return ( - /*istanbul ignore start*/ - _base - /*istanbul ignore end*/ - [ - /*istanbul ignore start*/ - "default" - /*istanbul ignore end*/ - ].prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')) - ); -}; - -function diffJson(oldObj, newObj, options) { - return jsonDiff.diff(oldObj, newObj, options); -} // This function handles the presence of circular references by bailing out when encountering an -// object that is already on the "stack" of items being processed. Accepts an optional replacer - - -function canonicalize(obj, stack, replacementStack, replacer, key) { - stack = stack || []; - replacementStack = replacementStack || []; - - if (replacer) { - obj = replacer(key, obj); - } - - var i; - - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } - } - - var canonicalizedObj; - - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key); - } - - stack.pop(); - replacementStack.pop(); - return canonicalizedObj; - } - - if (obj && obj.toJSON) { - obj = obj.toJSON(); - } - - if ( - /*istanbul ignore start*/ - _typeof( - /*istanbul ignore end*/ - obj) === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - - var sortedKeys = [], - _key; - - for (_key in obj) { - /* istanbul ignore else */ - if (obj.hasOwnProperty(_key)) { - sortedKeys.push(_key); - } - } - - sortedKeys.sort(); - - for (i = 0; i < sortedKeys.length; i += 1) { - _key = sortedKeys[i]; - canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key); - } - - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; - } - - return canonicalizedObj; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2pzb24uanMiXSwibmFtZXMiOlsib2JqZWN0UHJvdG90eXBlVG9TdHJpbmciLCJPYmplY3QiLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImpzb25EaWZmIiwiRGlmZiIsInVzZUxvbmdlc3RUb2tlbiIsInRva2VuaXplIiwibGluZURpZmYiLCJjYXN0SW5wdXQiLCJ2YWx1ZSIsIm9wdGlvbnMiLCJ1bmRlZmluZWRSZXBsYWNlbWVudCIsInN0cmluZ2lmeVJlcGxhY2VyIiwiayIsInYiLCJKU09OIiwic3RyaW5naWZ5IiwiY2Fub25pY2FsaXplIiwiZXF1YWxzIiwibGVmdCIsInJpZ2h0IiwiY2FsbCIsInJlcGxhY2UiLCJkaWZmSnNvbiIsIm9sZE9iaiIsIm5ld09iaiIsImRpZmYiLCJvYmoiLCJzdGFjayIsInJlcGxhY2VtZW50U3RhY2siLCJyZXBsYWNlciIsImtleSIsImkiLCJsZW5ndGgiLCJjYW5vbmljYWxpemVkT2JqIiwicHVzaCIsIkFycmF5IiwicG9wIiwidG9KU09OIiwic29ydGVkS2V5cyIsImhhc093blByb3BlcnR5Iiwic29ydCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7Ozs7QUFFQSxJQUFNQSx1QkFBdUIsR0FBR0MsTUFBTSxDQUFDQyxTQUFQLENBQWlCQyxRQUFqRDtBQUdPLElBQU1DLFFBQVEsR0FBRztBQUFJQztBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQSxDQUFKLEVBQWpCLEMsQ0FDUDtBQUNBOzs7Ozs7QUFDQUQsUUFBUSxDQUFDRSxlQUFULEdBQTJCLElBQTNCO0FBRUFGLFFBQVEsQ0FBQ0csUUFBVDtBQUFvQkM7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQTtBQUFBLENBQVNELFFBQTdCOztBQUNBSCxRQUFRLENBQUNLLFNBQVQsR0FBcUIsVUFBU0MsS0FBVCxFQUFnQjtBQUFBO0FBQUE7QUFBQTtBQUMrRSxPQUFLQyxPQURwRjtBQUFBLE1BQzVCQyxvQkFENEIsaUJBQzVCQSxvQkFENEI7QUFBQSw0Q0FDTkMsaUJBRE07QUFBQSxNQUNOQSxpQkFETSxzQ0FDYyxVQUFDQyxDQUFELEVBQUlDLENBQUo7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFVLGFBQU9BLENBQVAsS0FBYSxXQUFiLEdBQTJCSCxvQkFBM0IsR0FBa0RHO0FBQTVEO0FBQUEsR0FEZDtBQUduQyxTQUFPLE9BQU9MLEtBQVAsS0FBaUIsUUFBakIsR0FBNEJBLEtBQTVCLEdBQW9DTSxJQUFJLENBQUNDLFNBQUwsQ0FBZUMsWUFBWSxDQUFDUixLQUFELEVBQVEsSUFBUixFQUFjLElBQWQsRUFBb0JHLGlCQUFwQixDQUEzQixFQUFtRUEsaUJBQW5FLEVBQXNGLElBQXRGLENBQTNDO0FBQ0QsQ0FKRDs7QUFLQVQsUUFBUSxDQUFDZSxNQUFULEdBQWtCLFVBQVNDLElBQVQsRUFBZUMsS0FBZixFQUFzQjtBQUN0QyxTQUFPaEI7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUEsTUFBS0gsU0FBTCxDQUFlaUIsTUFBZixDQUFzQkcsSUFBdEIsQ0FBMkJsQixRQUEzQixFQUFxQ2dCLElBQUksQ0FBQ0csT0FBTCxDQUFhLFlBQWIsRUFBMkIsSUFBM0IsQ0FBckMsRUFBdUVGLEtBQUssQ0FBQ0UsT0FBTixDQUFjLFlBQWQsRUFBNEIsSUFBNUIsQ0FBdkU7QUFBUDtBQUNELENBRkQ7O0FBSU8sU0FBU0MsUUFBVCxDQUFrQkMsTUFBbEIsRUFBMEJDLE1BQTFCLEVBQWtDZixPQUFsQyxFQUEyQztBQUFFLFNBQU9QLFFBQVEsQ0FBQ3VCLElBQVQsQ0FBY0YsTUFBZCxFQUFzQkMsTUFBdEIsRUFBOEJmLE9BQTlCLENBQVA7QUFBZ0QsQyxDQUVwRztBQUNBOzs7QUFDTyxTQUFTTyxZQUFULENBQXNCVSxHQUF0QixFQUEyQkMsS0FBM0IsRUFBa0NDLGdCQUFsQyxFQUFvREMsUUFBcEQsRUFBOERDLEdBQTlELEVBQW1FO0FBQ3hFSCxFQUFBQSxLQUFLLEdBQUdBLEtBQUssSUFBSSxFQUFqQjtBQUNBQyxFQUFBQSxnQkFBZ0IsR0FBR0EsZ0JBQWdCLElBQUksRUFBdkM7O0FBRUEsTUFBSUMsUUFBSixFQUFjO0FBQ1pILElBQUFBLEdBQUcsR0FBR0csUUFBUSxDQUFDQyxHQUFELEVBQU1KLEdBQU4sQ0FBZDtBQUNEOztBQUVELE1BQUlLLENBQUo7O0FBRUEsT0FBS0EsQ0FBQyxHQUFHLENBQVQsRUFBWUEsQ0FBQyxHQUFHSixLQUFLLENBQUNLLE1BQXRCLEVBQThCRCxDQUFDLElBQUksQ0FBbkMsRUFBc0M7QUFDcEMsUUFBSUosS0FBSyxDQUFDSSxDQUFELENBQUwsS0FBYUwsR0FBakIsRUFBc0I7QUFDcEIsYUFBT0UsZ0JBQWdCLENBQUNHLENBQUQsQ0FBdkI7QUFDRDtBQUNGOztBQUVELE1BQUlFLGdCQUFKOztBQUVBLE1BQUkscUJBQXFCbkMsdUJBQXVCLENBQUNzQixJQUF4QixDQUE2Qk0sR0FBN0IsQ0FBekIsRUFBNEQ7QUFDMURDLElBQUFBLEtBQUssQ0FBQ08sSUFBTixDQUFXUixHQUFYO0FBQ0FPLElBQUFBLGdCQUFnQixHQUFHLElBQUlFLEtBQUosQ0FBVVQsR0FBRyxDQUFDTSxNQUFkLENBQW5CO0FBQ0FKLElBQUFBLGdCQUFnQixDQUFDTSxJQUFqQixDQUFzQkQsZ0JBQXRCOztBQUNBLFNBQUtGLENBQUMsR0FBRyxDQUFULEVBQVlBLENBQUMsR0FBR0wsR0FBRyxDQUFDTSxNQUFwQixFQUE0QkQsQ0FBQyxJQUFJLENBQWpDLEVBQW9DO0FBQ2xDRSxNQUFBQSxnQkFBZ0IsQ0FBQ0YsQ0FBRCxDQUFoQixHQUFzQmYsWUFBWSxDQUFDVSxHQUFHLENBQUNLLENBQUQsQ0FBSixFQUFTSixLQUFULEVBQWdCQyxnQkFBaEIsRUFBa0NDLFFBQWxDLEVBQTRDQyxHQUE1QyxDQUFsQztBQUNEOztBQUNESCxJQUFBQSxLQUFLLENBQUNTLEdBQU47QUFDQVIsSUFBQUEsZ0JBQWdCLENBQUNRLEdBQWpCO0FBQ0EsV0FBT0gsZ0JBQVA7QUFDRDs7QUFFRCxNQUFJUCxHQUFHLElBQUlBLEdBQUcsQ0FBQ1csTUFBZixFQUF1QjtBQUNyQlgsSUFBQUEsR0FBRyxHQUFHQSxHQUFHLENBQUNXLE1BQUosRUFBTjtBQUNEOztBQUVEO0FBQUk7QUFBQTtBQUFBO0FBQU9YLEVBQUFBLEdBQVAsTUFBZSxRQUFmLElBQTJCQSxHQUFHLEtBQUssSUFBdkMsRUFBNkM7QUFDM0NDLElBQUFBLEtBQUssQ0FBQ08sSUFBTixDQUFXUixHQUFYO0FBQ0FPLElBQUFBLGdCQUFnQixHQUFHLEVBQW5CO0FBQ0FMLElBQUFBLGdCQUFnQixDQUFDTSxJQUFqQixDQUFzQkQsZ0JBQXRCOztBQUNBLFFBQUlLLFVBQVUsR0FBRyxFQUFqQjtBQUFBLFFBQ0lSLElBREo7O0FBRUEsU0FBS0EsSUFBTCxJQUFZSixHQUFaLEVBQWlCO0FBQ2Y7QUFDQSxVQUFJQSxHQUFHLENBQUNhLGNBQUosQ0FBbUJULElBQW5CLENBQUosRUFBNkI7QUFDM0JRLFFBQUFBLFVBQVUsQ0FBQ0osSUFBWCxDQUFnQkosSUFBaEI7QUFDRDtBQUNGOztBQUNEUSxJQUFBQSxVQUFVLENBQUNFLElBQVg7O0FBQ0EsU0FBS1QsQ0FBQyxHQUFHLENBQVQsRUFBWUEsQ0FBQyxHQUFHTyxVQUFVLENBQUNOLE1BQTNCLEVBQW1DRCxDQUFDLElBQUksQ0FBeEMsRUFBMkM7QUFDekNELE1BQUFBLElBQUcsR0FBR1EsVUFBVSxDQUFDUCxDQUFELENBQWhCO0FBQ0FFLE1BQUFBLGdCQUFnQixDQUFDSCxJQUFELENBQWhCLEdBQXdCZCxZQUFZLENBQUNVLEdBQUcsQ0FBQ0ksSUFBRCxDQUFKLEVBQVdILEtBQVgsRUFBa0JDLGdCQUFsQixFQUFvQ0MsUUFBcEMsRUFBOENDLElBQTlDLENBQXBDO0FBQ0Q7O0FBQ0RILElBQUFBLEtBQUssQ0FBQ1MsR0FBTjtBQUNBUixJQUFBQSxnQkFBZ0IsQ0FBQ1EsR0FBakI7QUFDRCxHQW5CRCxNQW1CTztBQUNMSCxJQUFBQSxnQkFBZ0IsR0FBR1AsR0FBbkI7QUFDRDs7QUFDRCxTQUFPTyxnQkFBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7bGluZURpZmZ9IGZyb20gJy4vbGluZSc7XG5cbmNvbnN0IG9iamVjdFByb3RvdHlwZVRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuXG5leHBvcnQgY29uc3QganNvbkRpZmYgPSBuZXcgRGlmZigpO1xuLy8gRGlzY3JpbWluYXRlIGJldHdlZW4gdHdvIGxpbmVzIG9mIHByZXR0eS1wcmludGVkLCBzZXJpYWxpemVkIEpTT04gd2hlcmUgb25lIG9mIHRoZW0gaGFzIGFcbi8vIGRhbmdsaW5nIGNvbW1hIGFuZCB0aGUgb3RoZXIgZG9lc24ndC4gVHVybnMgb3V0IGluY2x1ZGluZyB0aGUgZGFuZ2xpbmcgY29tbWEgeWllbGRzIHRoZSBuaWNlc3Qgb3V0cHV0OlxuanNvbkRpZmYudXNlTG9uZ2VzdFRva2VuID0gdHJ1ZTtcblxuanNvbkRpZmYudG9rZW5pemUgPSBsaW5lRGlmZi50b2tlbml6ZTtcbmpzb25EaWZmLmNhc3RJbnB1dCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGNvbnN0IHt1bmRlZmluZWRSZXBsYWNlbWVudCwgc3RyaW5naWZ5UmVwbGFjZXIgPSAoaywgdikgPT4gdHlwZW9mIHYgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkUmVwbGFjZW1lbnQgOiB2fSA9IHRoaXMub3B0aW9ucztcblxuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlIDogSlNPTi5zdHJpbmdpZnkoY2Fub25pY2FsaXplKHZhbHVlLCBudWxsLCBudWxsLCBzdHJpbmdpZnlSZXBsYWNlciksIHN0cmluZ2lmeVJlcGxhY2VyLCAnICAnKTtcbn07XG5qc29uRGlmZi5lcXVhbHMgPSBmdW5jdGlvbihsZWZ0LCByaWdodCkge1xuICByZXR1cm4gRGlmZi5wcm90b3R5cGUuZXF1YWxzLmNhbGwoanNvbkRpZmYsIGxlZnQucmVwbGFjZSgvLChbXFxyXFxuXSkvZywgJyQxJyksIHJpZ2h0LnJlcGxhY2UoLywoW1xcclxcbl0pL2csICckMScpKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWZmSnNvbihvbGRPYmosIG5ld09iaiwgb3B0aW9ucykgeyByZXR1cm4ganNvbkRpZmYuZGlmZihvbGRPYmosIG5ld09iaiwgb3B0aW9ucyk7IH1cblxuLy8gVGhpcyBmdW5jdGlvbiBoYW5kbGVzIHRoZSBwcmVzZW5jZSBvZiBjaXJjdWxhciByZWZlcmVuY2VzIGJ5IGJhaWxpbmcgb3V0IHdoZW4gZW5jb3VudGVyaW5nIGFuXG4vLyBvYmplY3QgdGhhdCBpcyBhbHJlYWR5IG9uIHRoZSBcInN0YWNrXCIgb2YgaXRlbXMgYmVpbmcgcHJvY2Vzc2VkLiBBY2NlcHRzIGFuIG9wdGlvbmFsIHJlcGxhY2VyXG5leHBvcnQgZnVuY3Rpb24gY2Fub25pY2FsaXplKG9iaiwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2ssIHJlcGxhY2VyLCBrZXkpIHtcbiAgc3RhY2sgPSBzdGFjayB8fCBbXTtcbiAgcmVwbGFjZW1lbnRTdGFjayA9IHJlcGxhY2VtZW50U3RhY2sgfHwgW107XG5cbiAgaWYgKHJlcGxhY2VyKSB7XG4gICAgb2JqID0gcmVwbGFjZXIoa2V5LCBvYmopO1xuICB9XG5cbiAgbGV0IGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHN0YWNrLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKHN0YWNrW2ldID09PSBvYmopIHtcbiAgICAgIHJldHVybiByZXBsYWNlbWVudFN0YWNrW2ldO1xuICAgIH1cbiAgfVxuXG4gIGxldCBjYW5vbmljYWxpemVkT2JqO1xuXG4gIGlmICgnW29iamVjdCBBcnJheV0nID09PSBvYmplY3RQcm90b3R5cGVUb1N0cmluZy5jYWxsKG9iaikpIHtcbiAgICBzdGFjay5wdXNoKG9iaik7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IG5ldyBBcnJheShvYmoubGVuZ3RoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnB1c2goY2Fub25pY2FsaXplZE9iaik7XG4gICAgZm9yIChpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY2Fub25pY2FsaXplZE9ialtpXSA9IGNhbm9uaWNhbGl6ZShvYmpbaV0sIHN0YWNrLCByZXBsYWNlbWVudFN0YWNrLCByZXBsYWNlciwga2V5KTtcbiAgICB9XG4gICAgc3RhY2sucG9wKCk7XG4gICAgcmVwbGFjZW1lbnRTdGFjay5wb3AoKTtcbiAgICByZXR1cm4gY2Fub25pY2FsaXplZE9iajtcbiAgfVxuXG4gIGlmIChvYmogJiYgb2JqLnRvSlNPTikge1xuICAgIG9iaiA9IG9iai50b0pTT04oKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogIT09IG51bGwpIHtcbiAgICBzdGFjay5wdXNoKG9iaik7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IHt9O1xuICAgIHJlcGxhY2VtZW50U3RhY2sucHVzaChjYW5vbmljYWxpemVkT2JqKTtcbiAgICBsZXQgc29ydGVkS2V5cyA9IFtdLFxuICAgICAgICBrZXk7XG4gICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIHNvcnRlZEtleXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgICBzb3J0ZWRLZXlzLnNvcnQoKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgc29ydGVkS2V5cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAga2V5ID0gc29ydGVkS2V5c1tpXTtcbiAgICAgIGNhbm9uaWNhbGl6ZWRPYmpba2V5XSA9IGNhbm9uaWNhbGl6ZShvYmpba2V5XSwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2ssIHJlcGxhY2VyLCBrZXkpO1xuICAgIH1cbiAgICBzdGFjay5wb3AoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIGNhbm9uaWNhbGl6ZWRPYmogPSBvYmo7XG4gIH1cbiAgcmV0dXJuIGNhbm9uaWNhbGl6ZWRPYmo7XG59XG4iXX0= diff --git a/node_modules/diff/lib/diff/line.js b/node_modules/diff/lib/diff/line.js deleted file mode 100644 index 855fe30b9cc2c..0000000000000 --- a/node_modules/diff/lib/diff/line.js +++ /dev/null @@ -1,89 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffLines = diffLines; -exports.diffTrimmedLines = diffTrimmedLines; -exports.lineDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_params = require("../util/params") -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -var lineDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); - -/*istanbul ignore start*/ -exports.lineDiff = lineDiff; - -/*istanbul ignore end*/ -lineDiff.tokenize = function (value) { - var retLines = [], - linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line - - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } // Merge the content and line separators into single tokens - - - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; - - if (i % 2 && !this.options.newlineIsToken) { - retLines[retLines.length - 1] += line; - } else { - if (this.options.ignoreWhitespace) { - line = line.trim(); - } - - retLines.push(line); - } - } - - return retLines; -}; - -function diffLines(oldStr, newStr, callback) { - return lineDiff.diff(oldStr, newStr, callback); -} - -function diffTrimmedLines(oldStr, newStr, callback) { - var options = - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _params - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - generateOptions) - /*istanbul ignore end*/ - (callback, { - ignoreWhitespace: true - }); - return lineDiff.diff(oldStr, newStr, options); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL2xpbmUuanMiXSwibmFtZXMiOlsibGluZURpZmYiLCJEaWZmIiwidG9rZW5pemUiLCJ2YWx1ZSIsInJldExpbmVzIiwibGluZXNBbmROZXdsaW5lcyIsInNwbGl0IiwibGVuZ3RoIiwicG9wIiwiaSIsImxpbmUiLCJvcHRpb25zIiwibmV3bGluZUlzVG9rZW4iLCJpZ25vcmVXaGl0ZXNwYWNlIiwidHJpbSIsInB1c2giLCJkaWZmTGluZXMiLCJvbGRTdHIiLCJuZXdTdHIiLCJjYWxsYmFjayIsImRpZmYiLCJkaWZmVHJpbW1lZExpbmVzIiwiZ2VuZXJhdGVPcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7QUFFTyxJQUFNQSxRQUFRLEdBQUc7QUFBSUM7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUEsQ0FBSixFQUFqQjs7Ozs7O0FBQ1BELFFBQVEsQ0FBQ0UsUUFBVCxHQUFvQixVQUFTQyxLQUFULEVBQWdCO0FBQ2xDLE1BQUlDLFFBQVEsR0FBRyxFQUFmO0FBQUEsTUFDSUMsZ0JBQWdCLEdBQUdGLEtBQUssQ0FBQ0csS0FBTixDQUFZLFdBQVosQ0FEdkIsQ0FEa0MsQ0FJbEM7O0FBQ0EsTUFBSSxDQUFDRCxnQkFBZ0IsQ0FBQ0EsZ0JBQWdCLENBQUNFLE1BQWpCLEdBQTBCLENBQTNCLENBQXJCLEVBQW9EO0FBQ2xERixJQUFBQSxnQkFBZ0IsQ0FBQ0csR0FBakI7QUFDRCxHQVBpQyxDQVNsQzs7O0FBQ0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHSixnQkFBZ0IsQ0FBQ0UsTUFBckMsRUFBNkNFLENBQUMsRUFBOUMsRUFBa0Q7QUFDaEQsUUFBSUMsSUFBSSxHQUFHTCxnQkFBZ0IsQ0FBQ0ksQ0FBRCxDQUEzQjs7QUFFQSxRQUFJQSxDQUFDLEdBQUcsQ0FBSixJQUFTLENBQUMsS0FBS0UsT0FBTCxDQUFhQyxjQUEzQixFQUEyQztBQUN6Q1IsTUFBQUEsUUFBUSxDQUFDQSxRQUFRLENBQUNHLE1BQVQsR0FBa0IsQ0FBbkIsQ0FBUixJQUFpQ0csSUFBakM7QUFDRCxLQUZELE1BRU87QUFDTCxVQUFJLEtBQUtDLE9BQUwsQ0FBYUUsZ0JBQWpCLEVBQW1DO0FBQ2pDSCxRQUFBQSxJQUFJLEdBQUdBLElBQUksQ0FBQ0ksSUFBTCxFQUFQO0FBQ0Q7O0FBQ0RWLE1BQUFBLFFBQVEsQ0FBQ1csSUFBVCxDQUFjTCxJQUFkO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPTixRQUFQO0FBQ0QsQ0F4QkQ7O0FBMEJPLFNBQVNZLFNBQVQsQ0FBbUJDLE1BQW5CLEVBQTJCQyxNQUEzQixFQUFtQ0MsUUFBbkMsRUFBNkM7QUFBRSxTQUFPbkIsUUFBUSxDQUFDb0IsSUFBVCxDQUFjSCxNQUFkLEVBQXNCQyxNQUF0QixFQUE4QkMsUUFBOUIsQ0FBUDtBQUFpRDs7QUFDaEcsU0FBU0UsZ0JBQVQsQ0FBMEJKLE1BQTFCLEVBQWtDQyxNQUFsQyxFQUEwQ0MsUUFBMUMsRUFBb0Q7QUFDekQsTUFBSVIsT0FBTztBQUFHO0FBQUE7QUFBQTs7QUFBQVc7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQTtBQUFBLEdBQWdCSCxRQUFoQixFQUEwQjtBQUFDTixJQUFBQSxnQkFBZ0IsRUFBRTtBQUFuQixHQUExQixDQUFkO0FBQ0EsU0FBT2IsUUFBUSxDQUFDb0IsSUFBVCxDQUFjSCxNQUFkLEVBQXNCQyxNQUF0QixFQUE4QlAsT0FBOUIsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7Z2VuZXJhdGVPcHRpb25zfSBmcm9tICcuLi91dGlsL3BhcmFtcyc7XG5cbmV4cG9ydCBjb25zdCBsaW5lRGlmZiA9IG5ldyBEaWZmKCk7XG5saW5lRGlmZi50b2tlbml6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGxldCByZXRMaW5lcyA9IFtdLFxuICAgICAgbGluZXNBbmROZXdsaW5lcyA9IHZhbHVlLnNwbGl0KC8oXFxufFxcclxcbikvKTtcblxuICAvLyBJZ25vcmUgdGhlIGZpbmFsIGVtcHR5IHRva2VuIHRoYXQgb2NjdXJzIGlmIHRoZSBzdHJpbmcgZW5kcyB3aXRoIGEgbmV3IGxpbmVcbiAgaWYgKCFsaW5lc0FuZE5ld2xpbmVzW2xpbmVzQW5kTmV3bGluZXMubGVuZ3RoIC0gMV0pIHtcbiAgICBsaW5lc0FuZE5ld2xpbmVzLnBvcCgpO1xuICB9XG5cbiAgLy8gTWVyZ2UgdGhlIGNvbnRlbnQgYW5kIGxpbmUgc2VwYXJhdG9ycyBpbnRvIHNpbmdsZSB0b2tlbnNcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lc0FuZE5ld2xpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGxpbmUgPSBsaW5lc0FuZE5ld2xpbmVzW2ldO1xuXG4gICAgaWYgKGkgJSAyICYmICF0aGlzLm9wdGlvbnMubmV3bGluZUlzVG9rZW4pIHtcbiAgICAgIHJldExpbmVzW3JldExpbmVzLmxlbmd0aCAtIDFdICs9IGxpbmU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuaWdub3JlV2hpdGVzcGFjZSkge1xuICAgICAgICBsaW5lID0gbGluZS50cmltKCk7XG4gICAgICB9XG4gICAgICByZXRMaW5lcy5wdXNoKGxpbmUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXRMaW5lcztcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWZmTGluZXMob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7IHJldHVybiBsaW5lRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbmV4cG9ydCBmdW5jdGlvbiBkaWZmVHJpbW1lZExpbmVzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykge1xuICBsZXQgb3B0aW9ucyA9IGdlbmVyYXRlT3B0aW9ucyhjYWxsYmFjaywge2lnbm9yZVdoaXRlc3BhY2U6IHRydWV9KTtcbiAgcmV0dXJuIGxpbmVEaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIG9wdGlvbnMpO1xufVxuIl19 diff --git a/node_modules/diff/lib/diff/sentence.js b/node_modules/diff/lib/diff/sentence.js deleted file mode 100644 index 95158d6f58f9f..0000000000000 --- a/node_modules/diff/lib/diff/sentence.js +++ /dev/null @@ -1,41 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffSentences = diffSentences; -exports.sentenceDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -var sentenceDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); - -/*istanbul ignore start*/ -exports.sentenceDiff = sentenceDiff; - -/*istanbul ignore end*/ -sentenceDiff.tokenize = function (value) { - return value.split(/(\S.+?[.!?])(?=\s+|$)/); -}; - -function diffSentences(oldStr, newStr, callback) { - return sentenceDiff.diff(oldStr, newStr, callback); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL3NlbnRlbmNlLmpzIl0sIm5hbWVzIjpbInNlbnRlbmNlRGlmZiIsIkRpZmYiLCJ0b2tlbml6ZSIsInZhbHVlIiwic3BsaXQiLCJkaWZmU2VudGVuY2VzIiwib2xkU3RyIiwibmV3U3RyIiwiY2FsbGJhY2siLCJkaWZmIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7QUFHTyxJQUFNQSxZQUFZLEdBQUc7QUFBSUM7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUEsQ0FBSixFQUFyQjs7Ozs7O0FBQ1BELFlBQVksQ0FBQ0UsUUFBYixHQUF3QixVQUFTQyxLQUFULEVBQWdCO0FBQ3RDLFNBQU9BLEtBQUssQ0FBQ0MsS0FBTixDQUFZLHVCQUFaLENBQVA7QUFDRCxDQUZEOztBQUlPLFNBQVNDLGFBQVQsQ0FBdUJDLE1BQXZCLEVBQStCQyxNQUEvQixFQUF1Q0MsUUFBdkMsRUFBaUQ7QUFBRSxTQUFPUixZQUFZLENBQUNTLElBQWIsQ0FBa0JILE1BQWxCLEVBQTBCQyxNQUExQixFQUFrQ0MsUUFBbEMsQ0FBUDtBQUFxRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cblxuZXhwb3J0IGNvbnN0IHNlbnRlbmNlRGlmZiA9IG5ldyBEaWZmKCk7XG5zZW50ZW5jZURpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc3BsaXQoLyhcXFMuKz9bLiE/XSkoPz1cXHMrfCQpLyk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZlNlbnRlbmNlcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIHNlbnRlbmNlRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbiJdfQ== diff --git a/node_modules/diff/lib/diff/word.js b/node_modules/diff/lib/diff/word.js deleted file mode 100644 index cef7fe17befe6..0000000000000 --- a/node_modules/diff/lib/diff/word.js +++ /dev/null @@ -1,108 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.diffWords = diffWords; -exports.diffWordsWithSpace = diffWordsWithSpace; -exports.wordDiff = void 0; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./base")) -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_params = require("../util/params") -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode -// -// Ranges and exceptions: -// Latin-1 Supplement, 0080–00FF -// - U+00D7 × Multiplication sign -// - U+00F7 ÷ Division sign -// Latin Extended-A, 0100–017F -// Latin Extended-B, 0180–024F -// IPA Extensions, 0250–02AF -// Spacing Modifier Letters, 02B0–02FF -// - U+02C7 ˇ ˇ Caron -// - U+02D8 ˘ ˘ Breve -// - U+02D9 ˙ ˙ Dot Above -// - U+02DA ˚ ˚ Ring Above -// - U+02DB ˛ ˛ Ogonek -// - U+02DC ˜ ˜ Small Tilde -// - U+02DD ˝ ˝ Double Acute Accent -// Latin Extended Additional, 1E00–1EFF -var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; -var reWhitespace = /\S/; -var wordDiff = new -/*istanbul ignore start*/ -_base -/*istanbul ignore end*/ -[ -/*istanbul ignore start*/ -"default" -/*istanbul ignore end*/ -](); - -/*istanbul ignore start*/ -exports.wordDiff = wordDiff; - -/*istanbul ignore end*/ -wordDiff.equals = function (left, right) { - if (this.options.ignoreCase) { - left = left.toLowerCase(); - right = right.toLowerCase(); - } - - return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); -}; - -wordDiff.tokenize = function (value) { - // All whitespace symbols except newline group into one token, each newline - in separate token - var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. - - for (var i = 0; i < tokens.length - 1; i++) { - // If we have an empty string in the next field and we have only word chars before and after, merge - if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { - tokens[i] += tokens[i + 2]; - tokens.splice(i + 1, 2); - i--; - } - } - - return tokens; -}; - -function diffWords(oldStr, newStr, options) { - options = - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _params - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - generateOptions) - /*istanbul ignore end*/ - (options, { - ignoreWhitespace: true - }); - return wordDiff.diff(oldStr, newStr, options); -} - -function diffWordsWithSpace(oldStr, newStr, options) { - return wordDiff.diff(oldStr, newStr, options); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWZmL3dvcmQuanMiXSwibmFtZXMiOlsiZXh0ZW5kZWRXb3JkQ2hhcnMiLCJyZVdoaXRlc3BhY2UiLCJ3b3JkRGlmZiIsIkRpZmYiLCJlcXVhbHMiLCJsZWZ0IiwicmlnaHQiLCJvcHRpb25zIiwiaWdub3JlQ2FzZSIsInRvTG93ZXJDYXNlIiwiaWdub3JlV2hpdGVzcGFjZSIsInRlc3QiLCJ0b2tlbml6ZSIsInZhbHVlIiwidG9rZW5zIiwic3BsaXQiLCJpIiwibGVuZ3RoIiwic3BsaWNlIiwiZGlmZldvcmRzIiwib2xkU3RyIiwibmV3U3RyIiwiZ2VuZXJhdGVPcHRpb25zIiwiZGlmZiIsImRpZmZXb3Jkc1dpdGhTcGFjZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBTUEsaUJBQWlCLEdBQUcsK0RBQTFCO0FBRUEsSUFBTUMsWUFBWSxHQUFHLElBQXJCO0FBRU8sSUFBTUMsUUFBUSxHQUFHO0FBQUlDO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBLENBQUosRUFBakI7Ozs7OztBQUNQRCxRQUFRLENBQUNFLE1BQVQsR0FBa0IsVUFBU0MsSUFBVCxFQUFlQyxLQUFmLEVBQXNCO0FBQ3RDLE1BQUksS0FBS0MsT0FBTCxDQUFhQyxVQUFqQixFQUE2QjtBQUMzQkgsSUFBQUEsSUFBSSxHQUFHQSxJQUFJLENBQUNJLFdBQUwsRUFBUDtBQUNBSCxJQUFBQSxLQUFLLEdBQUdBLEtBQUssQ0FBQ0csV0FBTixFQUFSO0FBQ0Q7O0FBQ0QsU0FBT0osSUFBSSxLQUFLQyxLQUFULElBQW1CLEtBQUtDLE9BQUwsQ0FBYUcsZ0JBQWIsSUFBaUMsQ0FBQ1QsWUFBWSxDQUFDVSxJQUFiLENBQWtCTixJQUFsQixDQUFsQyxJQUE2RCxDQUFDSixZQUFZLENBQUNVLElBQWIsQ0FBa0JMLEtBQWxCLENBQXhGO0FBQ0QsQ0FORDs7QUFPQUosUUFBUSxDQUFDVSxRQUFULEdBQW9CLFVBQVNDLEtBQVQsRUFBZ0I7QUFDbEM7QUFDQSxNQUFJQyxNQUFNLEdBQUdELEtBQUssQ0FBQ0UsS0FBTixDQUFZLGlDQUFaLENBQWIsQ0FGa0MsQ0FJbEM7O0FBQ0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHRixNQUFNLENBQUNHLE1BQVAsR0FBZ0IsQ0FBcEMsRUFBdUNELENBQUMsRUFBeEMsRUFBNEM7QUFDMUM7QUFDQSxRQUFJLENBQUNGLE1BQU0sQ0FBQ0UsQ0FBQyxHQUFHLENBQUwsQ0FBUCxJQUFrQkYsTUFBTSxDQUFDRSxDQUFDLEdBQUcsQ0FBTCxDQUF4QixJQUNLaEIsaUJBQWlCLENBQUNXLElBQWxCLENBQXVCRyxNQUFNLENBQUNFLENBQUQsQ0FBN0IsQ0FETCxJQUVLaEIsaUJBQWlCLENBQUNXLElBQWxCLENBQXVCRyxNQUFNLENBQUNFLENBQUMsR0FBRyxDQUFMLENBQTdCLENBRlQsRUFFZ0Q7QUFDOUNGLE1BQUFBLE1BQU0sQ0FBQ0UsQ0FBRCxDQUFOLElBQWFGLE1BQU0sQ0FBQ0UsQ0FBQyxHQUFHLENBQUwsQ0FBbkI7QUFDQUYsTUFBQUEsTUFBTSxDQUFDSSxNQUFQLENBQWNGLENBQUMsR0FBRyxDQUFsQixFQUFxQixDQUFyQjtBQUNBQSxNQUFBQSxDQUFDO0FBQ0Y7QUFDRjs7QUFFRCxTQUFPRixNQUFQO0FBQ0QsQ0FqQkQ7O0FBbUJPLFNBQVNLLFNBQVQsQ0FBbUJDLE1BQW5CLEVBQTJCQyxNQUEzQixFQUFtQ2QsT0FBbkMsRUFBNEM7QUFDakRBLEVBQUFBLE9BQU87QUFBRztBQUFBO0FBQUE7O0FBQUFlO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUE7QUFBQSxHQUFnQmYsT0FBaEIsRUFBeUI7QUFBQ0csSUFBQUEsZ0JBQWdCLEVBQUU7QUFBbkIsR0FBekIsQ0FBVjtBQUNBLFNBQU9SLFFBQVEsQ0FBQ3FCLElBQVQsQ0FBY0gsTUFBZCxFQUFzQkMsTUFBdEIsRUFBOEJkLE9BQTlCLENBQVA7QUFDRDs7QUFFTSxTQUFTaUIsa0JBQVQsQ0FBNEJKLE1BQTVCLEVBQW9DQyxNQUFwQyxFQUE0Q2QsT0FBNUMsRUFBcUQ7QUFDMUQsU0FBT0wsUUFBUSxDQUFDcUIsSUFBVCxDQUFjSCxNQUFkLEVBQXNCQyxNQUF0QixFQUE4QmQsT0FBOUIsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7Z2VuZXJhdGVPcHRpb25zfSBmcm9tICcuLi91dGlsL3BhcmFtcyc7XG5cbi8vIEJhc2VkIG9uIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhdGluX3NjcmlwdF9pbl9Vbmljb2RlXG4vL1xuLy8gUmFuZ2VzIGFuZCBleGNlcHRpb25zOlxuLy8gTGF0aW4tMSBTdXBwbGVtZW50LCAwMDgw4oCTMDBGRlxuLy8gIC0gVSswMEQ3ICDDlyBNdWx0aXBsaWNhdGlvbiBzaWduXG4vLyAgLSBVKzAwRjcgIMO3IERpdmlzaW9uIHNpZ25cbi8vIExhdGluIEV4dGVuZGVkLUEsIDAxMDDigJMwMTdGXG4vLyBMYXRpbiBFeHRlbmRlZC1CLCAwMTgw4oCTMDI0RlxuLy8gSVBBIEV4dGVuc2lvbnMsIDAyNTDigJMwMkFGXG4vLyBTcGFjaW5nIE1vZGlmaWVyIExldHRlcnMsIDAyQjDigJMwMkZGXG4vLyAgLSBVKzAyQzcgIMuHICYjNzExOyAgQ2Fyb25cbi8vICAtIFUrMDJEOCAgy5ggJiM3Mjg7ICBCcmV2ZVxuLy8gIC0gVSswMkQ5ICDLmSAmIzcyOTsgIERvdCBBYm92ZVxuLy8gIC0gVSswMkRBICDLmiAmIzczMDsgIFJpbmcgQWJvdmVcbi8vICAtIFUrMDJEQiAgy5sgJiM3MzE7ICBPZ29uZWtcbi8vICAtIFUrMDJEQyAgy5wgJiM3MzI7ICBTbWFsbCBUaWxkZVxuLy8gIC0gVSswMkREICDLnSAmIzczMzsgIERvdWJsZSBBY3V0ZSBBY2NlbnRcbi8vIExhdGluIEV4dGVuZGVkIEFkZGl0aW9uYWwsIDFFMDDigJMxRUZGXG5jb25zdCBleHRlbmRlZFdvcmRDaGFycyA9IC9eW2EtekEtWlxcdXtDMH0tXFx1e0ZGfVxcdXtEOH0tXFx1e0Y2fVxcdXtGOH0tXFx1ezJDNn1cXHV7MkM4fS1cXHV7MkQ3fVxcdXsyREV9LVxcdXsyRkZ9XFx1ezFFMDB9LVxcdXsxRUZGfV0rJC91O1xuXG5jb25zdCByZVdoaXRlc3BhY2UgPSAvXFxTLztcblxuZXhwb3J0IGNvbnN0IHdvcmREaWZmID0gbmV3IERpZmYoKTtcbndvcmREaWZmLmVxdWFscyA9IGZ1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7XG4gIGlmICh0aGlzLm9wdGlvbnMuaWdub3JlQ2FzZSkge1xuICAgIGxlZnQgPSBsZWZ0LnRvTG93ZXJDYXNlKCk7XG4gICAgcmlnaHQgPSByaWdodC50b0xvd2VyQ2FzZSgpO1xuICB9XG4gIHJldHVybiBsZWZ0ID09PSByaWdodCB8fCAodGhpcy5vcHRpb25zLmlnbm9yZVdoaXRlc3BhY2UgJiYgIXJlV2hpdGVzcGFjZS50ZXN0KGxlZnQpICYmICFyZVdoaXRlc3BhY2UudGVzdChyaWdodCkpO1xufTtcbndvcmREaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgLy8gQWxsIHdoaXRlc3BhY2Ugc3ltYm9scyBleGNlcHQgbmV3bGluZSBncm91cCBpbnRvIG9uZSB0b2tlbiwgZWFjaCBuZXdsaW5lIC0gaW4gc2VwYXJhdGUgdG9rZW5cbiAgbGV0IHRva2VucyA9IHZhbHVlLnNwbGl0KC8oW15cXFNcXHJcXG5dK3xbKClbXFxde30nXCJcXHJcXG5dfFxcYikvKTtcblxuICAvLyBKb2luIHRoZSBib3VuZGFyeSBzcGxpdHMgdGhhdCB3ZSBkbyBub3QgY29uc2lkZXIgdG8gYmUgYm91bmRhcmllcy4gVGhpcyBpcyBwcmltYXJpbHkgdGhlIGV4dGVuZGVkIExhdGluIGNoYXJhY3RlciBzZXQuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIC8vIElmIHdlIGhhdmUgYW4gZW1wdHkgc3RyaW5nIGluIHRoZSBuZXh0IGZpZWxkIGFuZCB3ZSBoYXZlIG9ubHkgd29yZCBjaGFycyBiZWZvcmUgYW5kIGFmdGVyLCBtZXJnZVxuICAgIGlmICghdG9rZW5zW2kgKyAxXSAmJiB0b2tlbnNbaSArIDJdXG4gICAgICAgICAgJiYgZXh0ZW5kZWRXb3JkQ2hhcnMudGVzdCh0b2tlbnNbaV0pXG4gICAgICAgICAgJiYgZXh0ZW5kZWRXb3JkQ2hhcnMudGVzdCh0b2tlbnNbaSArIDJdKSkge1xuICAgICAgdG9rZW5zW2ldICs9IHRva2Vuc1tpICsgMl07XG4gICAgICB0b2tlbnMuc3BsaWNlKGkgKyAxLCAyKTtcbiAgICAgIGktLTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdG9rZW5zO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZXb3JkcyhvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucykge1xuICBvcHRpb25zID0gZ2VuZXJhdGVPcHRpb25zKG9wdGlvbnMsIHtpZ25vcmVXaGl0ZXNwYWNlOiB0cnVlfSk7XG4gIHJldHVybiB3b3JkRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZXb3Jkc1dpdGhTcGFjZShvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucykge1xuICByZXR1cm4gd29yZERpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucyk7XG59XG4iXX0= diff --git a/node_modules/diff/lib/index.es6.js b/node_modules/diff/lib/index.es6.js deleted file mode 100644 index ca0e5917c44a4..0000000000000 --- a/node_modules/diff/lib/index.es6.js +++ /dev/null @@ -1,1553 +0,0 @@ -function Diff() {} -Diff.prototype = { - diff: function diff(oldString, newString) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var callback = options.callback; - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - this.options = options; - var self = this; - - function done(value) { - if (callback) { - setTimeout(function () { - callback(undefined, value); - }, 0); - return true; - } else { - return value; - } - } // Allow subclasses to massage the input prior to running - - - oldString = this.castInput(oldString); - newString = this.castInput(newString); - oldString = this.removeEmpty(this.tokenize(oldString)); - newString = this.removeEmpty(this.tokenize(newString)); - var newLen = newString.length, - oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ - newPos: -1, - components: [] - }]; // Seed editLength = 0, i.e. the content starts with the same values - - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{ - value: this.join(newString), - count: newString.length - }]); - } // Main worker method. checks all permutations of a given edit length for acceptance. - - - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath = void 0; - - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } - - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; - - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - - - if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } - - _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done - - if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { - return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } - } - - editLength++; - } // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - - - if (callback) { - (function exec() { - setTimeout(function () { - // This should not happen, but we want to be safe. - - /* istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } - - if (!execEditLength()) { - exec(); - } - }, 0); - })(); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - - if (ret) { - return ret; - } - } - } - }, - pushComponent: function pushComponent(components, added, removed) { - var last = components[components.length - 1]; - - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = { - count: last.count + 1, - added: added, - removed: removed - }; - } else { - components.push({ - count: 1, - added: added, - removed: removed - }); - } - }, - extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, - commonCount = 0; - - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - - if (commonCount) { - basePath.components.push({ - count: commonCount - }); - } - - basePath.newPos = newPos; - return oldPos; - }, - equals: function equals(left, right) { - if (this.options.comparator) { - return this.options.comparator(left, right); - } else { - return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); - } - }, - removeEmpty: function removeEmpty(array) { - var ret = []; - - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); - } - } - - return ret; - }, - castInput: function castInput(value) { - return value; - }, - tokenize: function tokenize(value) { - return value.split(''); - }, - join: function join(chars) { - return chars.join(''); - } -}; - -function buildValues(diff, components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; - - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = value.map(function (value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); - component.value = diff.join(value); - } else { - component.value = diff.join(newString.slice(newPos, newPos + component.count)); - } - - newPos += component.count; // Common case - - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); - oldPos += component.count; // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } - } - } // Special case handle for when one terminal is ignored (i.e. whitespace). - // For this case we merge the terminal into the prior string and drop the change. - // This is only available for string mode. - - - var lastComponent = components[componentLen - 1]; - - if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { - components[componentLen - 2].value += lastComponent.value; - components.pop(); - } - - return components; -} - -function clonePath(path) { - return { - newPos: path.newPos, - components: path.components.slice(0) - }; -} - -var characterDiff = new Diff(); -function diffChars(oldStr, newStr, options) { - return characterDiff.diff(oldStr, newStr, options); -} - -function generateOptions(options, defaults) { - if (typeof options === 'function') { - defaults.callback = options; - } else if (options) { - for (var name in options) { - /* istanbul ignore else */ - if (options.hasOwnProperty(name)) { - defaults[name] = options[name]; - } - } - } - - return defaults; -} - -// -// Ranges and exceptions: -// Latin-1 Supplement, 0080–00FF -// - U+00D7 × Multiplication sign -// - U+00F7 ÷ Division sign -// Latin Extended-A, 0100–017F -// Latin Extended-B, 0180–024F -// IPA Extensions, 0250–02AF -// Spacing Modifier Letters, 02B0–02FF -// - U+02C7 ˇ ˇ Caron -// - U+02D8 ˘ ˘ Breve -// - U+02D9 ˙ ˙ Dot Above -// - U+02DA ˚ ˚ Ring Above -// - U+02DB ˛ ˛ Ogonek -// - U+02DC ˜ ˜ Small Tilde -// - U+02DD ˝ ˝ Double Acute Accent -// Latin Extended Additional, 1E00–1EFF - -var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; -var reWhitespace = /\S/; -var wordDiff = new Diff(); - -wordDiff.equals = function (left, right) { - if (this.options.ignoreCase) { - left = left.toLowerCase(); - right = right.toLowerCase(); - } - - return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); -}; - -wordDiff.tokenize = function (value) { - // All whitespace symbols except newline group into one token, each newline - in separate token - var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. - - for (var i = 0; i < tokens.length - 1; i++) { - // If we have an empty string in the next field and we have only word chars before and after, merge - if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { - tokens[i] += tokens[i + 2]; - tokens.splice(i + 1, 2); - i--; - } - } - - return tokens; -}; - -function diffWords(oldStr, newStr, options) { - options = generateOptions(options, { - ignoreWhitespace: true - }); - return wordDiff.diff(oldStr, newStr, options); -} -function diffWordsWithSpace(oldStr, newStr, options) { - return wordDiff.diff(oldStr, newStr, options); -} - -var lineDiff = new Diff(); - -lineDiff.tokenize = function (value) { - var retLines = [], - linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line - - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } // Merge the content and line separators into single tokens - - - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; - - if (i % 2 && !this.options.newlineIsToken) { - retLines[retLines.length - 1] += line; - } else { - if (this.options.ignoreWhitespace) { - line = line.trim(); - } - - retLines.push(line); - } - } - - return retLines; -}; - -function diffLines(oldStr, newStr, callback) { - return lineDiff.diff(oldStr, newStr, callback); -} -function diffTrimmedLines(oldStr, newStr, callback) { - var options = generateOptions(callback, { - ignoreWhitespace: true - }); - return lineDiff.diff(oldStr, newStr, options); -} - -var sentenceDiff = new Diff(); - -sentenceDiff.tokenize = function (value) { - return value.split(/(\S.+?[.!?])(?=\s+|$)/); -}; - -function diffSentences(oldStr, newStr, callback) { - return sentenceDiff.diff(oldStr, newStr, callback); -} - -var cssDiff = new Diff(); - -cssDiff.tokenize = function (value) { - return value.split(/([{}:;,]|\s+)/); -}; - -function diffCss(oldStr, newStr, callback) { - return cssDiff.diff(oldStr, newStr, callback); -} - -function _typeof(obj) { - "@babel/helpers - typeof"; - - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - } - - return _typeof(obj); -} - -function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); -} - -function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); -} - -function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); -} - -function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); -} - -function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - - return arr2; -} - -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} - -var objectPrototypeToString = Object.prototype.toString; -var jsonDiff = new Diff(); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a -// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - -jsonDiff.useLongestToken = true; -jsonDiff.tokenize = lineDiff.tokenize; - -jsonDiff.castInput = function (value) { - var _this$options = this.options, - undefinedReplacement = _this$options.undefinedReplacement, - _this$options$stringi = _this$options.stringifyReplacer, - stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) { - return typeof v === 'undefined' ? undefinedReplacement : v; - } : _this$options$stringi; - return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' '); -}; - -jsonDiff.equals = function (left, right) { - return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); -}; - -function diffJson(oldObj, newObj, options) { - return jsonDiff.diff(oldObj, newObj, options); -} // This function handles the presence of circular references by bailing out when encountering an -// object that is already on the "stack" of items being processed. Accepts an optional replacer - -function canonicalize(obj, stack, replacementStack, replacer, key) { - stack = stack || []; - replacementStack = replacementStack || []; - - if (replacer) { - obj = replacer(key, obj); - } - - var i; - - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } - } - - var canonicalizedObj; - - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key); - } - - stack.pop(); - replacementStack.pop(); - return canonicalizedObj; - } - - if (obj && obj.toJSON) { - obj = obj.toJSON(); - } - - if (_typeof(obj) === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - - var sortedKeys = [], - _key; - - for (_key in obj) { - /* istanbul ignore else */ - if (obj.hasOwnProperty(_key)) { - sortedKeys.push(_key); - } - } - - sortedKeys.sort(); - - for (i = 0; i < sortedKeys.length; i += 1) { - _key = sortedKeys[i]; - canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key); - } - - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; - } - - return canonicalizedObj; -} - -var arrayDiff = new Diff(); - -arrayDiff.tokenize = function (value) { - return value.slice(); -}; - -arrayDiff.join = arrayDiff.removeEmpty = function (value) { - return value; -}; - -function diffArrays(oldArr, newArr, callback) { - return arrayDiff.diff(oldArr, newArr, callback); -} - -function parsePatch(uniDiff) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], - list = [], - i = 0; - - function parseIndex() { - var index = {}; - list.push(index); // Parse diff metadata - - while (i < diffstr.length) { - var line = diffstr[i]; // File header found, end parsing diff metadata - - if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { - break; - } // Diff index - - - var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); - - if (header) { - index.index = header[1]; - } - - i++; - } // Parse file headers if they are defined. Unified diff requires them, but - // there's no technical issues to have an isolated hunk without file header - - - parseFileHeader(index); - parseFileHeader(index); // Parse hunks - - index.hunks = []; - - while (i < diffstr.length) { - var _line = diffstr[i]; - - if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { - break; - } else if (/^@@/.test(_line)) { - index.hunks.push(parseHunk()); - } else if (_line && options.strict) { - // Ignore unexpected content unless in strict mode - throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); - } else { - i++; - } - } - } // Parses the --- and +++ headers, if none are found, no lines - // are consumed. - - - function parseFileHeader(index) { - var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]); - - if (fileHeader) { - var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; - var data = fileHeader[2].split('\t', 2); - var fileName = data[0].replace(/\\\\/g, '\\'); - - if (/^".*"$/.test(fileName)) { - fileName = fileName.substr(1, fileName.length - 2); - } - - index[keyPrefix + 'FileName'] = fileName; - index[keyPrefix + 'Header'] = (data[1] || '').trim(); - i++; - } - } // Parses a hunk - // This assumes that we are at the start of a hunk. - - - function parseHunk() { - var chunkHeaderIndex = i, - chunkHeaderLine = diffstr[i++], - chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); - var hunk = { - oldStart: +chunkHeader[1], - oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], - newStart: +chunkHeader[3], - newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], - lines: [], - linedelimiters: [] - }; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart += 1; - } - - if (hunk.newLines === 0) { - hunk.newStart += 1; - } - - var addCount = 0, - removeCount = 0; - - for (; i < diffstr.length; i++) { - // Lines starting with '---' could be mistaken for the "remove line" operation - // But they could be the header for the next file. Therefore prune such cases out. - if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { - break; - } - - var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0]; - - if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { - hunk.lines.push(diffstr[i]); - hunk.linedelimiters.push(delimiters[i] || '\n'); - - if (operation === '+') { - addCount++; - } else if (operation === '-') { - removeCount++; - } else if (operation === ' ') { - addCount++; - removeCount++; - } - } else { - break; - } - } // Handle the empty block count case - - - if (!addCount && hunk.newLines === 1) { - hunk.newLines = 0; - } - - if (!removeCount && hunk.oldLines === 1) { - hunk.oldLines = 0; - } // Perform optional sanity checking - - - if (options.strict) { - if (addCount !== hunk.newLines) { - throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - - if (removeCount !== hunk.oldLines) { - throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - } - - return hunk; - } - - while (i < diffstr.length) { - parseIndex(); - } - - return list; -} - -// Iterator that traverses in the range of [min, max], stepping -// by distance from a given start position. I.e. for [0, 4], with -// start of 2, this will iterate 2, 3, 1, 4, 0. -function distanceIterator (start, minLine, maxLine) { - var wantForward = true, - backwardExhausted = false, - forwardExhausted = false, - localOffset = 1; - return function iterator() { - if (wantForward && !forwardExhausted) { - if (backwardExhausted) { - localOffset++; - } else { - wantForward = false; - } // Check if trying to fit beyond text length, and if not, check it fits - // after offset location (or desired location on first iteration) - - - if (start + localOffset <= maxLine) { - return localOffset; - } - - forwardExhausted = true; - } - - if (!backwardExhausted) { - if (!forwardExhausted) { - wantForward = true; - } // Check if trying to fit before text beginning, and if not, check it fits - // before offset location - - - if (minLine <= start - localOffset) { - return -localOffset++; - } - - backwardExhausted = true; - return iterator(); - } // We tried to fit hunk before text beginning and beyond text length, then - // hunk can't fit on the text. Return undefined - - }; -} - -function applyPatch(source, uniDiff) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); - } - - if (Array.isArray(uniDiff)) { - if (uniDiff.length > 1) { - throw new Error('applyPatch only works with a single input.'); - } - - uniDiff = uniDiff[0]; - } // Apply the diff to the input - - - var lines = source.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], - hunks = uniDiff.hunks, - compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) { - return line === patchContent; - }, - errorCount = 0, - fuzzFactor = options.fuzzFactor || 0, - minLine = 0, - offset = 0, - removeEOFNL, - addEOFNL; - /** - * Checks if the hunk exactly fits on the provided location - */ - - - function hunkFits(hunk, toPos) { - for (var j = 0; j < hunk.lines.length; j++) { - var line = hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line; - - if (operation === ' ' || operation === '-') { - // Context sanity check - if (!compareLine(toPos + 1, lines[toPos], operation, content)) { - errorCount++; - - if (errorCount > fuzzFactor) { - return false; - } - } - - toPos++; - } - } - - return true; - } // Search best fit offsets for each hunk based on the previous ones - - - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i], - maxLine = lines.length - hunk.oldLines, - localOffset = 0, - toPos = offset + hunk.oldStart - 1; - var iterator = distanceIterator(toPos, minLine, maxLine); - - for (; localOffset !== undefined; localOffset = iterator()) { - if (hunkFits(hunk, toPos + localOffset)) { - hunk.offset = offset += localOffset; - break; - } - } - - if (localOffset === undefined) { - return false; - } // Set lower text limit to end of the current hunk, so next ones don't try - // to fit over already patched text - - - minLine = hunk.offset + hunk.oldStart + hunk.oldLines; - } // Apply patch hunks - - - var diffOffset = 0; - - for (var _i = 0; _i < hunks.length; _i++) { - var _hunk = hunks[_i], - _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1; - - diffOffset += _hunk.newLines - _hunk.oldLines; - - for (var j = 0; j < _hunk.lines.length; j++) { - var line = _hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line, - delimiter = _hunk.linedelimiters[j]; - - if (operation === ' ') { - _toPos++; - } else if (operation === '-') { - lines.splice(_toPos, 1); - delimiters.splice(_toPos, 1); - /* istanbul ignore else */ - } else if (operation === '+') { - lines.splice(_toPos, 0, content); - delimiters.splice(_toPos, 0, delimiter); - _toPos++; - } else if (operation === '\\') { - var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; - - if (previousOperation === '+') { - removeEOFNL = true; - } else if (previousOperation === '-') { - addEOFNL = true; - } - } - } - } // Handle EOFNL insertion/removal - - - if (removeEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - delimiters.pop(); - } - } else if (addEOFNL) { - lines.push(''); - delimiters.push('\n'); - } - - for (var _k = 0; _k < lines.length - 1; _k++) { - lines[_k] = lines[_k] + delimiters[_k]; - } - - return lines.join(''); -} // Wrapper that supports multiple file patches via callbacks. - -function applyPatches(uniDiff, options) { - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); - } - - var currentIndex = 0; - - function processIndex() { - var index = uniDiff[currentIndex++]; - - if (!index) { - return options.complete(); - } - - options.loadFile(index, function (err, data) { - if (err) { - return options.complete(err); - } - - var updatedContent = applyPatch(data, index, options); - options.patched(index, updatedContent, function (err) { - if (err) { - return options.complete(err); - } - - processIndex(); - }); - }); - } - - processIndex(); -} - -function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - if (!options) { - options = {}; - } - - if (typeof options.context === 'undefined') { - options.context = 4; - } - - var diff = diffLines(oldStr, newStr, options); - diff.push({ - value: '', - lines: [] - }); // Append an empty value to make cleanup easier - - function contextLines(lines) { - return lines.map(function (entry) { - return ' ' + entry; - }); - } - - var hunks = []; - var oldRangeStart = 0, - newRangeStart = 0, - curRange = [], - oldLine = 1, - newLine = 1; - - var _loop = function _loop(i) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; - - if (current.added || current.removed) { - var _curRange; - - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; - - if (prev) { - curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } // Output our changes - - - (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) { - return (current.added ? '+' : '-') + entry; - }))); // Track the updated file position - - - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= options.context * 2 && i < diff.length - 2) { - var _curRange2; - - // Overlapping - (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines))); - } else { - var _curRange3; - - // end the range and output - var contextSize = Math.min(lines.length, options.context); - - (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize)))); - - var hunk = { - oldStart: oldRangeStart, - oldLines: oldLine - oldRangeStart + contextSize, - newStart: newRangeStart, - newLines: newLine - newRangeStart + contextSize, - lines: curRange - }; - - if (i >= diff.length - 2 && lines.length <= options.context) { - // EOF is inside this hunk - var oldEOFNewline = /\n$/.test(oldStr); - var newEOFNewline = /\n$/.test(newStr); - var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; - - if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) { - // special case: old has no eol and no trailing context; no-nl can end up before adds - // however, if the old file is empty, do not output the no-nl line - curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); - } - - if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) { - curRange.push('\\ No newline at end of file'); - } - } - - hunks.push(hunk); - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - - oldLine += lines.length; - newLine += lines.length; - } - }; - - for (var i = 0; i < diff.length; i++) { - _loop(i); - } - - return { - oldFileName: oldFileName, - newFileName: newFileName, - oldHeader: oldHeader, - newHeader: newHeader, - hunks: hunks - }; -} -function formatPatch(diff) { - var ret = []; - - if (diff.oldFileName == diff.newFileName) { - ret.push('Index: ' + diff.oldFileName); - } - - ret.push('==================================================================='); - ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); - ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); - - for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart -= 1; - } - - if (hunk.newLines === 0) { - hunk.newStart -= 1; - } - - ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); - ret.push.apply(ret, hunk.lines); - } - - return ret.join('\n') + '\n'; -} -function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)); -} -function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { - return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); -} - -function arrayEqual(a, b) { - if (a.length !== b.length) { - return false; - } - - return arrayStartsWith(a, b); -} -function arrayStartsWith(array, start) { - if (start.length > array.length) { - return false; - } - - for (var i = 0; i < start.length; i++) { - if (start[i] !== array[i]) { - return false; - } - } - - return true; -} - -function calcLineCount(hunk) { - var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines), - oldLines = _calcOldNewLineCount.oldLines, - newLines = _calcOldNewLineCount.newLines; - - if (oldLines !== undefined) { - hunk.oldLines = oldLines; - } else { - delete hunk.oldLines; - } - - if (newLines !== undefined) { - hunk.newLines = newLines; - } else { - delete hunk.newLines; - } -} -function merge(mine, theirs, base) { - mine = loadPatch(mine, base); - theirs = loadPatch(theirs, base); - var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning. - // Leaving sanity checks on this to the API consumer that may know more about the - // meaning in their own context. - - if (mine.index || theirs.index) { - ret.index = mine.index || theirs.index; - } - - if (mine.newFileName || theirs.newFileName) { - if (!fileNameChanged(mine)) { - // No header or no change in ours, use theirs (and ours if theirs does not exist) - ret.oldFileName = theirs.oldFileName || mine.oldFileName; - ret.newFileName = theirs.newFileName || mine.newFileName; - ret.oldHeader = theirs.oldHeader || mine.oldHeader; - ret.newHeader = theirs.newHeader || mine.newHeader; - } else if (!fileNameChanged(theirs)) { - // No header or no change in theirs, use ours - ret.oldFileName = mine.oldFileName; - ret.newFileName = mine.newFileName; - ret.oldHeader = mine.oldHeader; - ret.newHeader = mine.newHeader; - } else { - // Both changed... figure it out - ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName); - ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName); - ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader); - ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader); - } - } - - ret.hunks = []; - var mineIndex = 0, - theirsIndex = 0, - mineOffset = 0, - theirsOffset = 0; - - while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) { - var mineCurrent = mine.hunks[mineIndex] || { - oldStart: Infinity - }, - theirsCurrent = theirs.hunks[theirsIndex] || { - oldStart: Infinity - }; - - if (hunkBefore(mineCurrent, theirsCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(mineCurrent, mineOffset)); - mineIndex++; - theirsOffset += mineCurrent.newLines - mineCurrent.oldLines; - } else if (hunkBefore(theirsCurrent, mineCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset)); - theirsIndex++; - mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines; - } else { - // Overlap, merge as best we can - var mergedHunk = { - oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart), - oldLines: 0, - newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset), - newLines: 0, - lines: [] - }; - mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines); - theirsIndex++; - mineIndex++; - ret.hunks.push(mergedHunk); - } - } - - return ret; -} - -function loadPatch(param, base) { - if (typeof param === 'string') { - if (/^@@/m.test(param) || /^Index:/m.test(param)) { - return parsePatch(param)[0]; - } - - if (!base) { - throw new Error('Must provide a base reference or pass in a patch'); - } - - return structuredPatch(undefined, undefined, base, param); - } - - return param; -} - -function fileNameChanged(patch) { - return patch.newFileName && patch.newFileName !== patch.oldFileName; -} - -function selectField(index, mine, theirs) { - if (mine === theirs) { - return mine; - } else { - index.conflict = true; - return { - mine: mine, - theirs: theirs - }; - } -} - -function hunkBefore(test, check) { - return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart; -} - -function cloneHunk(hunk, offset) { - return { - oldStart: hunk.oldStart, - oldLines: hunk.oldLines, - newStart: hunk.newStart + offset, - newLines: hunk.newLines, - lines: hunk.lines - }; -} - -function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) { - // This will generally result in a conflicted hunk, but there are cases where the context - // is the only overlap where we can successfully merge the content here. - var mine = { - offset: mineOffset, - lines: mineLines, - index: 0 - }, - their = { - offset: theirOffset, - lines: theirLines, - index: 0 - }; // Handle any leading content - - insertLeading(hunk, mine, their); - insertLeading(hunk, their, mine); // Now in the overlap content. Scan through and select the best changes from each. - - while (mine.index < mine.lines.length && their.index < their.lines.length) { - var mineCurrent = mine.lines[mine.index], - theirCurrent = their.lines[their.index]; - - if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) { - // Both modified ... - mutualChange(hunk, mine, their); - } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') { - var _hunk$lines; - - // Mine inserted - (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine))); - } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') { - var _hunk$lines2; - - // Theirs inserted - (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their))); - } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') { - // Mine removed or edited - removal(hunk, mine, their); - } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') { - // Their removed or edited - removal(hunk, their, mine, true); - } else if (mineCurrent === theirCurrent) { - // Context identity - hunk.lines.push(mineCurrent); - mine.index++; - their.index++; - } else { - // Context mismatch - conflict(hunk, collectChange(mine), collectChange(their)); - } - } // Now push anything that may be remaining - - - insertTrailing(hunk, mine); - insertTrailing(hunk, their); - calcLineCount(hunk); -} - -function mutualChange(hunk, mine, their) { - var myChanges = collectChange(mine), - theirChanges = collectChange(their); - - if (allRemoves(myChanges) && allRemoves(theirChanges)) { - // Special case for remove changes that are supersets of one another - if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) { - var _hunk$lines3; - - (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges)); - - return; - } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) { - var _hunk$lines4; - - (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges)); - - return; - } - } else if (arrayEqual(myChanges, theirChanges)) { - var _hunk$lines5; - - (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges)); - - return; - } - - conflict(hunk, myChanges, theirChanges); -} - -function removal(hunk, mine, their, swap) { - var myChanges = collectChange(mine), - theirChanges = collectContext(their, myChanges); - - if (theirChanges.merged) { - var _hunk$lines6; - - (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged)); - } else { - conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges); - } -} - -function conflict(hunk, mine, their) { - hunk.conflict = true; - hunk.lines.push({ - conflict: true, - mine: mine, - theirs: their - }); -} - -function insertLeading(hunk, insert, their) { - while (insert.offset < their.offset && insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - insert.offset++; - } -} - -function insertTrailing(hunk, insert) { - while (insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - } -} - -function collectChange(state) { - var ret = [], - operation = state.lines[state.index][0]; - - while (state.index < state.lines.length) { - var line = state.lines[state.index]; // Group additions that are immediately after subtractions and treat them as one "atomic" modify change. - - if (operation === '-' && line[0] === '+') { - operation = '+'; - } - - if (operation === line[0]) { - ret.push(line); - state.index++; - } else { - break; - } - } - - return ret; -} - -function collectContext(state, matchChanges) { - var changes = [], - merged = [], - matchIndex = 0, - contextChanges = false, - conflicted = false; - - while (matchIndex < matchChanges.length && state.index < state.lines.length) { - var change = state.lines[state.index], - match = matchChanges[matchIndex]; // Once we've hit our add, then we are done - - if (match[0] === '+') { - break; - } - - contextChanges = contextChanges || change[0] !== ' '; - merged.push(match); - matchIndex++; // Consume any additions in the other block as a conflict to attempt - // to pull in the remaining context after this - - if (change[0] === '+') { - conflicted = true; - - while (change[0] === '+') { - changes.push(change); - change = state.lines[++state.index]; - } - } - - if (match.substr(1) === change.substr(1)) { - changes.push(change); - state.index++; - } else { - conflicted = true; - } - } - - if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) { - conflicted = true; - } - - if (conflicted) { - return changes; - } - - while (matchIndex < matchChanges.length) { - merged.push(matchChanges[matchIndex++]); - } - - return { - merged: merged, - changes: changes - }; -} - -function allRemoves(changes) { - return changes.reduce(function (prev, change) { - return prev && change[0] === '-'; - }, true); -} - -function skipRemoveSuperset(state, removeChanges, delta) { - for (var i = 0; i < delta; i++) { - var changeContent = removeChanges[removeChanges.length - delta + i].substr(1); - - if (state.lines[state.index + i] !== ' ' + changeContent) { - return false; - } - } - - state.index += delta; - return true; -} - -function calcOldNewLineCount(lines) { - var oldLines = 0; - var newLines = 0; - lines.forEach(function (line) { - if (typeof line !== 'string') { - var myCount = calcOldNewLineCount(line.mine); - var theirCount = calcOldNewLineCount(line.theirs); - - if (oldLines !== undefined) { - if (myCount.oldLines === theirCount.oldLines) { - oldLines += myCount.oldLines; - } else { - oldLines = undefined; - } - } - - if (newLines !== undefined) { - if (myCount.newLines === theirCount.newLines) { - newLines += myCount.newLines; - } else { - newLines = undefined; - } - } - } else { - if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) { - newLines++; - } - - if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) { - oldLines++; - } - } - }); - return { - oldLines: oldLines, - newLines: newLines - }; -} - -// See: http://code.google.com/p/google-diff-match-patch/wiki/API -function convertChangesToDMP(changes) { - var ret = [], - change, - operation; - - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); - } - - return ret; -} - -function convertChangesToXML(changes) { - var ret = []; - - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - - if (change.added) { - ret.push('<ins>'); - } else if (change.removed) { - ret.push('<del>'); - } - - ret.push(escapeHTML(change.value)); - - if (change.added) { - ret.push('</ins>'); - } else if (change.removed) { - ret.push('</del>'); - } - } - - return ret.join(''); -} - -function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(/</g, '<'); - n = n.replace(/>/g, '>'); - n = n.replace(/"/g, '"'); - return n; -} - -export { Diff, applyPatch, applyPatches, canonicalize, convertChangesToDMP, convertChangesToXML, createPatch, createTwoFilesPatch, diffArrays, diffChars, diffCss, diffJson, diffLines, diffSentences, diffTrimmedLines, diffWords, diffWordsWithSpace, merge, parsePatch, structuredPatch }; diff --git a/node_modules/diff/lib/index.js b/node_modules/diff/lib/index.js deleted file mode 100644 index 920f0feeb0caf..0000000000000 --- a/node_modules/diff/lib/index.js +++ /dev/null @@ -1,216 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "Diff", { - enumerable: true, - get: function get() { - return _base["default"]; - } -}); -Object.defineProperty(exports, "diffChars", { - enumerable: true, - get: function get() { - return _character.diffChars; - } -}); -Object.defineProperty(exports, "diffWords", { - enumerable: true, - get: function get() { - return _word.diffWords; - } -}); -Object.defineProperty(exports, "diffWordsWithSpace", { - enumerable: true, - get: function get() { - return _word.diffWordsWithSpace; - } -}); -Object.defineProperty(exports, "diffLines", { - enumerable: true, - get: function get() { - return _line.diffLines; - } -}); -Object.defineProperty(exports, "diffTrimmedLines", { - enumerable: true, - get: function get() { - return _line.diffTrimmedLines; - } -}); -Object.defineProperty(exports, "diffSentences", { - enumerable: true, - get: function get() { - return _sentence.diffSentences; - } -}); -Object.defineProperty(exports, "diffCss", { - enumerable: true, - get: function get() { - return _css.diffCss; - } -}); -Object.defineProperty(exports, "diffJson", { - enumerable: true, - get: function get() { - return _json.diffJson; - } -}); -Object.defineProperty(exports, "canonicalize", { - enumerable: true, - get: function get() { - return _json.canonicalize; - } -}); -Object.defineProperty(exports, "diffArrays", { - enumerable: true, - get: function get() { - return _array.diffArrays; - } -}); -Object.defineProperty(exports, "applyPatch", { - enumerable: true, - get: function get() { - return _apply.applyPatch; - } -}); -Object.defineProperty(exports, "applyPatches", { - enumerable: true, - get: function get() { - return _apply.applyPatches; - } -}); -Object.defineProperty(exports, "parsePatch", { - enumerable: true, - get: function get() { - return _parse.parsePatch; - } -}); -Object.defineProperty(exports, "merge", { - enumerable: true, - get: function get() { - return _merge.merge; - } -}); -Object.defineProperty(exports, "structuredPatch", { - enumerable: true, - get: function get() { - return _create.structuredPatch; - } -}); -Object.defineProperty(exports, "createTwoFilesPatch", { - enumerable: true, - get: function get() { - return _create.createTwoFilesPatch; - } -}); -Object.defineProperty(exports, "createPatch", { - enumerable: true, - get: function get() { - return _create.createPatch; - } -}); -Object.defineProperty(exports, "convertChangesToDMP", { - enumerable: true, - get: function get() { - return _dmp.convertChangesToDMP; - } -}); -Object.defineProperty(exports, "convertChangesToXML", { - enumerable: true, - get: function get() { - return _xml.convertChangesToXML; - } -}); - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_base = _interopRequireDefault(require("./diff/base")) -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_character = require("./diff/character") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_word = require("./diff/word") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_line = require("./diff/line") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_sentence = require("./diff/sentence") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_css = require("./diff/css") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_json = require("./diff/json") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_array = require("./diff/array") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_apply = require("./patch/apply") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_parse = require("./patch/parse") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_merge = require("./patch/merge") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_create = require("./patch/create") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_dmp = require("./convert/dmp") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_xml = require("./convert/xml") -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdCQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBTZWUgTElDRU5TRSBmaWxlIGZvciB0ZXJtcyBvZiB1c2UgKi9cblxuLypcbiAqIFRleHQgZGlmZiBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBUaGlzIGxpYnJhcnkgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBBUElTOlxuICogSnNEaWZmLmRpZmZDaGFyczogQ2hhcmFjdGVyIGJ5IGNoYXJhY3RlciBkaWZmXG4gKiBKc0RpZmYuZGlmZldvcmRzOiBXb3JkIChhcyBkZWZpbmVkIGJ5IFxcYiByZWdleCkgZGlmZiB3aGljaCBpZ25vcmVzIHdoaXRlc3BhY2VcbiAqIEpzRGlmZi5kaWZmTGluZXM6IExpbmUgYmFzZWQgZGlmZlxuICpcbiAqIEpzRGlmZi5kaWZmQ3NzOiBEaWZmIHRhcmdldGVkIGF0IENTUyBjb250ZW50XG4gKlxuICogVGhlc2UgbWV0aG9kcyBhcmUgYmFzZWQgb24gdGhlIGltcGxlbWVudGF0aW9uIHByb3Bvc2VkIGluXG4gKiBcIkFuIE8oTkQpIERpZmZlcmVuY2UgQWxnb3JpdGhtIGFuZCBpdHMgVmFyaWF0aW9uc1wiIChNeWVycywgMTk4NikuXG4gKiBodHRwOi8vY2l0ZXNlZXJ4LmlzdC5wc3UuZWR1L3ZpZXdkb2Mvc3VtbWFyeT9kb2k9MTAuMS4xLjQuNjkyN1xuICovXG5pbXBvcnQgRGlmZiBmcm9tICcuL2RpZmYvYmFzZSc7XG5pbXBvcnQge2RpZmZDaGFyc30gZnJvbSAnLi9kaWZmL2NoYXJhY3Rlcic7XG5pbXBvcnQge2RpZmZXb3JkcywgZGlmZldvcmRzV2l0aFNwYWNlfSBmcm9tICcuL2RpZmYvd29yZCc7XG5pbXBvcnQge2RpZmZMaW5lcywgZGlmZlRyaW1tZWRMaW5lc30gZnJvbSAnLi9kaWZmL2xpbmUnO1xuaW1wb3J0IHtkaWZmU2VudGVuY2VzfSBmcm9tICcuL2RpZmYvc2VudGVuY2UnO1xuXG5pbXBvcnQge2RpZmZDc3N9IGZyb20gJy4vZGlmZi9jc3MnO1xuaW1wb3J0IHtkaWZmSnNvbiwgY2Fub25pY2FsaXplfSBmcm9tICcuL2RpZmYvanNvbic7XG5cbmltcG9ydCB7ZGlmZkFycmF5c30gZnJvbSAnLi9kaWZmL2FycmF5JztcblxuaW1wb3J0IHthcHBseVBhdGNoLCBhcHBseVBhdGNoZXN9IGZyb20gJy4vcGF0Y2gvYXBwbHknO1xuaW1wb3J0IHtwYXJzZVBhdGNofSBmcm9tICcuL3BhdGNoL3BhcnNlJztcbmltcG9ydCB7bWVyZ2V9IGZyb20gJy4vcGF0Y2gvbWVyZ2UnO1xuaW1wb3J0IHtzdHJ1Y3R1cmVkUGF0Y2gsIGNyZWF0ZVR3b0ZpbGVzUGF0Y2gsIGNyZWF0ZVBhdGNofSBmcm9tICcuL3BhdGNoL2NyZWF0ZSc7XG5cbmltcG9ydCB7Y29udmVydENoYW5nZXNUb0RNUH0gZnJvbSAnLi9jb252ZXJ0L2RtcCc7XG5pbXBvcnQge2NvbnZlcnRDaGFuZ2VzVG9YTUx9IGZyb20gJy4vY29udmVydC94bWwnO1xuXG5leHBvcnQge1xuICBEaWZmLFxuXG4gIGRpZmZDaGFycyxcbiAgZGlmZldvcmRzLFxuICBkaWZmV29yZHNXaXRoU3BhY2UsXG4gIGRpZmZMaW5lcyxcbiAgZGlmZlRyaW1tZWRMaW5lcyxcbiAgZGlmZlNlbnRlbmNlcyxcblxuICBkaWZmQ3NzLFxuICBkaWZmSnNvbixcblxuICBkaWZmQXJyYXlzLFxuXG4gIHN0cnVjdHVyZWRQYXRjaCxcbiAgY3JlYXRlVHdvRmlsZXNQYXRjaCxcbiAgY3JlYXRlUGF0Y2gsXG4gIGFwcGx5UGF0Y2gsXG4gIGFwcGx5UGF0Y2hlcyxcbiAgcGFyc2VQYXRjaCxcbiAgbWVyZ2UsXG4gIGNvbnZlcnRDaGFuZ2VzVG9ETVAsXG4gIGNvbnZlcnRDaGFuZ2VzVG9YTUwsXG4gIGNhbm9uaWNhbGl6ZVxufTtcbiJdfQ== diff --git a/node_modules/diff/lib/index.mjs b/node_modules/diff/lib/index.mjs deleted file mode 100644 index ca0e5917c44a4..0000000000000 --- a/node_modules/diff/lib/index.mjs +++ /dev/null @@ -1,1553 +0,0 @@ -function Diff() {} -Diff.prototype = { - diff: function diff(oldString, newString) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var callback = options.callback; - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - this.options = options; - var self = this; - - function done(value) { - if (callback) { - setTimeout(function () { - callback(undefined, value); - }, 0); - return true; - } else { - return value; - } - } // Allow subclasses to massage the input prior to running - - - oldString = this.castInput(oldString); - newString = this.castInput(newString); - oldString = this.removeEmpty(this.tokenize(oldString)); - newString = this.removeEmpty(this.tokenize(newString)); - var newLen = newString.length, - oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ - newPos: -1, - components: [] - }]; // Seed editLength = 0, i.e. the content starts with the same values - - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{ - value: this.join(newString), - count: newString.length - }]); - } // Main worker method. checks all permutations of a given edit length for acceptance. - - - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath = void 0; - - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } - - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; - - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - - - if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } - - _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done - - if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { - return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } - } - - editLength++; - } // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - - - if (callback) { - (function exec() { - setTimeout(function () { - // This should not happen, but we want to be safe. - - /* istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } - - if (!execEditLength()) { - exec(); - } - }, 0); - })(); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - - if (ret) { - return ret; - } - } - } - }, - pushComponent: function pushComponent(components, added, removed) { - var last = components[components.length - 1]; - - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = { - count: last.count + 1, - added: added, - removed: removed - }; - } else { - components.push({ - count: 1, - added: added, - removed: removed - }); - } - }, - extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, - commonCount = 0; - - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - - if (commonCount) { - basePath.components.push({ - count: commonCount - }); - } - - basePath.newPos = newPos; - return oldPos; - }, - equals: function equals(left, right) { - if (this.options.comparator) { - return this.options.comparator(left, right); - } else { - return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); - } - }, - removeEmpty: function removeEmpty(array) { - var ret = []; - - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); - } - } - - return ret; - }, - castInput: function castInput(value) { - return value; - }, - tokenize: function tokenize(value) { - return value.split(''); - }, - join: function join(chars) { - return chars.join(''); - } -}; - -function buildValues(diff, components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; - - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = value.map(function (value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); - component.value = diff.join(value); - } else { - component.value = diff.join(newString.slice(newPos, newPos + component.count)); - } - - newPos += component.count; // Common case - - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); - oldPos += component.count; // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } - } - } // Special case handle for when one terminal is ignored (i.e. whitespace). - // For this case we merge the terminal into the prior string and drop the change. - // This is only available for string mode. - - - var lastComponent = components[componentLen - 1]; - - if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { - components[componentLen - 2].value += lastComponent.value; - components.pop(); - } - - return components; -} - -function clonePath(path) { - return { - newPos: path.newPos, - components: path.components.slice(0) - }; -} - -var characterDiff = new Diff(); -function diffChars(oldStr, newStr, options) { - return characterDiff.diff(oldStr, newStr, options); -} - -function generateOptions(options, defaults) { - if (typeof options === 'function') { - defaults.callback = options; - } else if (options) { - for (var name in options) { - /* istanbul ignore else */ - if (options.hasOwnProperty(name)) { - defaults[name] = options[name]; - } - } - } - - return defaults; -} - -// -// Ranges and exceptions: -// Latin-1 Supplement, 0080–00FF -// - U+00D7 × Multiplication sign -// - U+00F7 ÷ Division sign -// Latin Extended-A, 0100–017F -// Latin Extended-B, 0180–024F -// IPA Extensions, 0250–02AF -// Spacing Modifier Letters, 02B0–02FF -// - U+02C7 ˇ ˇ Caron -// - U+02D8 ˘ ˘ Breve -// - U+02D9 ˙ ˙ Dot Above -// - U+02DA ˚ ˚ Ring Above -// - U+02DB ˛ ˛ Ogonek -// - U+02DC ˜ ˜ Small Tilde -// - U+02DD ˝ ˝ Double Acute Accent -// Latin Extended Additional, 1E00–1EFF - -var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; -var reWhitespace = /\S/; -var wordDiff = new Diff(); - -wordDiff.equals = function (left, right) { - if (this.options.ignoreCase) { - left = left.toLowerCase(); - right = right.toLowerCase(); - } - - return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); -}; - -wordDiff.tokenize = function (value) { - // All whitespace symbols except newline group into one token, each newline - in separate token - var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. - - for (var i = 0; i < tokens.length - 1; i++) { - // If we have an empty string in the next field and we have only word chars before and after, merge - if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { - tokens[i] += tokens[i + 2]; - tokens.splice(i + 1, 2); - i--; - } - } - - return tokens; -}; - -function diffWords(oldStr, newStr, options) { - options = generateOptions(options, { - ignoreWhitespace: true - }); - return wordDiff.diff(oldStr, newStr, options); -} -function diffWordsWithSpace(oldStr, newStr, options) { - return wordDiff.diff(oldStr, newStr, options); -} - -var lineDiff = new Diff(); - -lineDiff.tokenize = function (value) { - var retLines = [], - linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line - - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } // Merge the content and line separators into single tokens - - - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; - - if (i % 2 && !this.options.newlineIsToken) { - retLines[retLines.length - 1] += line; - } else { - if (this.options.ignoreWhitespace) { - line = line.trim(); - } - - retLines.push(line); - } - } - - return retLines; -}; - -function diffLines(oldStr, newStr, callback) { - return lineDiff.diff(oldStr, newStr, callback); -} -function diffTrimmedLines(oldStr, newStr, callback) { - var options = generateOptions(callback, { - ignoreWhitespace: true - }); - return lineDiff.diff(oldStr, newStr, options); -} - -var sentenceDiff = new Diff(); - -sentenceDiff.tokenize = function (value) { - return value.split(/(\S.+?[.!?])(?=\s+|$)/); -}; - -function diffSentences(oldStr, newStr, callback) { - return sentenceDiff.diff(oldStr, newStr, callback); -} - -var cssDiff = new Diff(); - -cssDiff.tokenize = function (value) { - return value.split(/([{}:;,]|\s+)/); -}; - -function diffCss(oldStr, newStr, callback) { - return cssDiff.diff(oldStr, newStr, callback); -} - -function _typeof(obj) { - "@babel/helpers - typeof"; - - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - } - - return _typeof(obj); -} - -function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); -} - -function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); -} - -function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); -} - -function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); -} - -function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - - return arr2; -} - -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} - -var objectPrototypeToString = Object.prototype.toString; -var jsonDiff = new Diff(); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a -// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - -jsonDiff.useLongestToken = true; -jsonDiff.tokenize = lineDiff.tokenize; - -jsonDiff.castInput = function (value) { - var _this$options = this.options, - undefinedReplacement = _this$options.undefinedReplacement, - _this$options$stringi = _this$options.stringifyReplacer, - stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) { - return typeof v === 'undefined' ? undefinedReplacement : v; - } : _this$options$stringi; - return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' '); -}; - -jsonDiff.equals = function (left, right) { - return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); -}; - -function diffJson(oldObj, newObj, options) { - return jsonDiff.diff(oldObj, newObj, options); -} // This function handles the presence of circular references by bailing out when encountering an -// object that is already on the "stack" of items being processed. Accepts an optional replacer - -function canonicalize(obj, stack, replacementStack, replacer, key) { - stack = stack || []; - replacementStack = replacementStack || []; - - if (replacer) { - obj = replacer(key, obj); - } - - var i; - - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } - } - - var canonicalizedObj; - - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key); - } - - stack.pop(); - replacementStack.pop(); - return canonicalizedObj; - } - - if (obj && obj.toJSON) { - obj = obj.toJSON(); - } - - if (_typeof(obj) === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - - var sortedKeys = [], - _key; - - for (_key in obj) { - /* istanbul ignore else */ - if (obj.hasOwnProperty(_key)) { - sortedKeys.push(_key); - } - } - - sortedKeys.sort(); - - for (i = 0; i < sortedKeys.length; i += 1) { - _key = sortedKeys[i]; - canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key); - } - - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; - } - - return canonicalizedObj; -} - -var arrayDiff = new Diff(); - -arrayDiff.tokenize = function (value) { - return value.slice(); -}; - -arrayDiff.join = arrayDiff.removeEmpty = function (value) { - return value; -}; - -function diffArrays(oldArr, newArr, callback) { - return arrayDiff.diff(oldArr, newArr, callback); -} - -function parsePatch(uniDiff) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], - list = [], - i = 0; - - function parseIndex() { - var index = {}; - list.push(index); // Parse diff metadata - - while (i < diffstr.length) { - var line = diffstr[i]; // File header found, end parsing diff metadata - - if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { - break; - } // Diff index - - - var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); - - if (header) { - index.index = header[1]; - } - - i++; - } // Parse file headers if they are defined. Unified diff requires them, but - // there's no technical issues to have an isolated hunk without file header - - - parseFileHeader(index); - parseFileHeader(index); // Parse hunks - - index.hunks = []; - - while (i < diffstr.length) { - var _line = diffstr[i]; - - if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { - break; - } else if (/^@@/.test(_line)) { - index.hunks.push(parseHunk()); - } else if (_line && options.strict) { - // Ignore unexpected content unless in strict mode - throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); - } else { - i++; - } - } - } // Parses the --- and +++ headers, if none are found, no lines - // are consumed. - - - function parseFileHeader(index) { - var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]); - - if (fileHeader) { - var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; - var data = fileHeader[2].split('\t', 2); - var fileName = data[0].replace(/\\\\/g, '\\'); - - if (/^".*"$/.test(fileName)) { - fileName = fileName.substr(1, fileName.length - 2); - } - - index[keyPrefix + 'FileName'] = fileName; - index[keyPrefix + 'Header'] = (data[1] || '').trim(); - i++; - } - } // Parses a hunk - // This assumes that we are at the start of a hunk. - - - function parseHunk() { - var chunkHeaderIndex = i, - chunkHeaderLine = diffstr[i++], - chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); - var hunk = { - oldStart: +chunkHeader[1], - oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], - newStart: +chunkHeader[3], - newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], - lines: [], - linedelimiters: [] - }; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart += 1; - } - - if (hunk.newLines === 0) { - hunk.newStart += 1; - } - - var addCount = 0, - removeCount = 0; - - for (; i < diffstr.length; i++) { - // Lines starting with '---' could be mistaken for the "remove line" operation - // But they could be the header for the next file. Therefore prune such cases out. - if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { - break; - } - - var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0]; - - if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { - hunk.lines.push(diffstr[i]); - hunk.linedelimiters.push(delimiters[i] || '\n'); - - if (operation === '+') { - addCount++; - } else if (operation === '-') { - removeCount++; - } else if (operation === ' ') { - addCount++; - removeCount++; - } - } else { - break; - } - } // Handle the empty block count case - - - if (!addCount && hunk.newLines === 1) { - hunk.newLines = 0; - } - - if (!removeCount && hunk.oldLines === 1) { - hunk.oldLines = 0; - } // Perform optional sanity checking - - - if (options.strict) { - if (addCount !== hunk.newLines) { - throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - - if (removeCount !== hunk.oldLines) { - throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - } - - return hunk; - } - - while (i < diffstr.length) { - parseIndex(); - } - - return list; -} - -// Iterator that traverses in the range of [min, max], stepping -// by distance from a given start position. I.e. for [0, 4], with -// start of 2, this will iterate 2, 3, 1, 4, 0. -function distanceIterator (start, minLine, maxLine) { - var wantForward = true, - backwardExhausted = false, - forwardExhausted = false, - localOffset = 1; - return function iterator() { - if (wantForward && !forwardExhausted) { - if (backwardExhausted) { - localOffset++; - } else { - wantForward = false; - } // Check if trying to fit beyond text length, and if not, check it fits - // after offset location (or desired location on first iteration) - - - if (start + localOffset <= maxLine) { - return localOffset; - } - - forwardExhausted = true; - } - - if (!backwardExhausted) { - if (!forwardExhausted) { - wantForward = true; - } // Check if trying to fit before text beginning, and if not, check it fits - // before offset location - - - if (minLine <= start - localOffset) { - return -localOffset++; - } - - backwardExhausted = true; - return iterator(); - } // We tried to fit hunk before text beginning and beyond text length, then - // hunk can't fit on the text. Return undefined - - }; -} - -function applyPatch(source, uniDiff) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); - } - - if (Array.isArray(uniDiff)) { - if (uniDiff.length > 1) { - throw new Error('applyPatch only works with a single input.'); - } - - uniDiff = uniDiff[0]; - } // Apply the diff to the input - - - var lines = source.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], - hunks = uniDiff.hunks, - compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) { - return line === patchContent; - }, - errorCount = 0, - fuzzFactor = options.fuzzFactor || 0, - minLine = 0, - offset = 0, - removeEOFNL, - addEOFNL; - /** - * Checks if the hunk exactly fits on the provided location - */ - - - function hunkFits(hunk, toPos) { - for (var j = 0; j < hunk.lines.length; j++) { - var line = hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line; - - if (operation === ' ' || operation === '-') { - // Context sanity check - if (!compareLine(toPos + 1, lines[toPos], operation, content)) { - errorCount++; - - if (errorCount > fuzzFactor) { - return false; - } - } - - toPos++; - } - } - - return true; - } // Search best fit offsets for each hunk based on the previous ones - - - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i], - maxLine = lines.length - hunk.oldLines, - localOffset = 0, - toPos = offset + hunk.oldStart - 1; - var iterator = distanceIterator(toPos, minLine, maxLine); - - for (; localOffset !== undefined; localOffset = iterator()) { - if (hunkFits(hunk, toPos + localOffset)) { - hunk.offset = offset += localOffset; - break; - } - } - - if (localOffset === undefined) { - return false; - } // Set lower text limit to end of the current hunk, so next ones don't try - // to fit over already patched text - - - minLine = hunk.offset + hunk.oldStart + hunk.oldLines; - } // Apply patch hunks - - - var diffOffset = 0; - - for (var _i = 0; _i < hunks.length; _i++) { - var _hunk = hunks[_i], - _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1; - - diffOffset += _hunk.newLines - _hunk.oldLines; - - for (var j = 0; j < _hunk.lines.length; j++) { - var line = _hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line, - delimiter = _hunk.linedelimiters[j]; - - if (operation === ' ') { - _toPos++; - } else if (operation === '-') { - lines.splice(_toPos, 1); - delimiters.splice(_toPos, 1); - /* istanbul ignore else */ - } else if (operation === '+') { - lines.splice(_toPos, 0, content); - delimiters.splice(_toPos, 0, delimiter); - _toPos++; - } else if (operation === '\\') { - var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; - - if (previousOperation === '+') { - removeEOFNL = true; - } else if (previousOperation === '-') { - addEOFNL = true; - } - } - } - } // Handle EOFNL insertion/removal - - - if (removeEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - delimiters.pop(); - } - } else if (addEOFNL) { - lines.push(''); - delimiters.push('\n'); - } - - for (var _k = 0; _k < lines.length - 1; _k++) { - lines[_k] = lines[_k] + delimiters[_k]; - } - - return lines.join(''); -} // Wrapper that supports multiple file patches via callbacks. - -function applyPatches(uniDiff, options) { - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); - } - - var currentIndex = 0; - - function processIndex() { - var index = uniDiff[currentIndex++]; - - if (!index) { - return options.complete(); - } - - options.loadFile(index, function (err, data) { - if (err) { - return options.complete(err); - } - - var updatedContent = applyPatch(data, index, options); - options.patched(index, updatedContent, function (err) { - if (err) { - return options.complete(err); - } - - processIndex(); - }); - }); - } - - processIndex(); -} - -function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - if (!options) { - options = {}; - } - - if (typeof options.context === 'undefined') { - options.context = 4; - } - - var diff = diffLines(oldStr, newStr, options); - diff.push({ - value: '', - lines: [] - }); // Append an empty value to make cleanup easier - - function contextLines(lines) { - return lines.map(function (entry) { - return ' ' + entry; - }); - } - - var hunks = []; - var oldRangeStart = 0, - newRangeStart = 0, - curRange = [], - oldLine = 1, - newLine = 1; - - var _loop = function _loop(i) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; - - if (current.added || current.removed) { - var _curRange; - - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; - - if (prev) { - curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } // Output our changes - - - (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) { - return (current.added ? '+' : '-') + entry; - }))); // Track the updated file position - - - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= options.context * 2 && i < diff.length - 2) { - var _curRange2; - - // Overlapping - (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines))); - } else { - var _curRange3; - - // end the range and output - var contextSize = Math.min(lines.length, options.context); - - (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize)))); - - var hunk = { - oldStart: oldRangeStart, - oldLines: oldLine - oldRangeStart + contextSize, - newStart: newRangeStart, - newLines: newLine - newRangeStart + contextSize, - lines: curRange - }; - - if (i >= diff.length - 2 && lines.length <= options.context) { - // EOF is inside this hunk - var oldEOFNewline = /\n$/.test(oldStr); - var newEOFNewline = /\n$/.test(newStr); - var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; - - if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) { - // special case: old has no eol and no trailing context; no-nl can end up before adds - // however, if the old file is empty, do not output the no-nl line - curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); - } - - if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) { - curRange.push('\\ No newline at end of file'); - } - } - - hunks.push(hunk); - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - - oldLine += lines.length; - newLine += lines.length; - } - }; - - for (var i = 0; i < diff.length; i++) { - _loop(i); - } - - return { - oldFileName: oldFileName, - newFileName: newFileName, - oldHeader: oldHeader, - newHeader: newHeader, - hunks: hunks - }; -} -function formatPatch(diff) { - var ret = []; - - if (diff.oldFileName == diff.newFileName) { - ret.push('Index: ' + diff.oldFileName); - } - - ret.push('==================================================================='); - ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); - ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); - - for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart -= 1; - } - - if (hunk.newLines === 0) { - hunk.newStart -= 1; - } - - ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); - ret.push.apply(ret, hunk.lines); - } - - return ret.join('\n') + '\n'; -} -function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)); -} -function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { - return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); -} - -function arrayEqual(a, b) { - if (a.length !== b.length) { - return false; - } - - return arrayStartsWith(a, b); -} -function arrayStartsWith(array, start) { - if (start.length > array.length) { - return false; - } - - for (var i = 0; i < start.length; i++) { - if (start[i] !== array[i]) { - return false; - } - } - - return true; -} - -function calcLineCount(hunk) { - var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines), - oldLines = _calcOldNewLineCount.oldLines, - newLines = _calcOldNewLineCount.newLines; - - if (oldLines !== undefined) { - hunk.oldLines = oldLines; - } else { - delete hunk.oldLines; - } - - if (newLines !== undefined) { - hunk.newLines = newLines; - } else { - delete hunk.newLines; - } -} -function merge(mine, theirs, base) { - mine = loadPatch(mine, base); - theirs = loadPatch(theirs, base); - var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning. - // Leaving sanity checks on this to the API consumer that may know more about the - // meaning in their own context. - - if (mine.index || theirs.index) { - ret.index = mine.index || theirs.index; - } - - if (mine.newFileName || theirs.newFileName) { - if (!fileNameChanged(mine)) { - // No header or no change in ours, use theirs (and ours if theirs does not exist) - ret.oldFileName = theirs.oldFileName || mine.oldFileName; - ret.newFileName = theirs.newFileName || mine.newFileName; - ret.oldHeader = theirs.oldHeader || mine.oldHeader; - ret.newHeader = theirs.newHeader || mine.newHeader; - } else if (!fileNameChanged(theirs)) { - // No header or no change in theirs, use ours - ret.oldFileName = mine.oldFileName; - ret.newFileName = mine.newFileName; - ret.oldHeader = mine.oldHeader; - ret.newHeader = mine.newHeader; - } else { - // Both changed... figure it out - ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName); - ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName); - ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader); - ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader); - } - } - - ret.hunks = []; - var mineIndex = 0, - theirsIndex = 0, - mineOffset = 0, - theirsOffset = 0; - - while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) { - var mineCurrent = mine.hunks[mineIndex] || { - oldStart: Infinity - }, - theirsCurrent = theirs.hunks[theirsIndex] || { - oldStart: Infinity - }; - - if (hunkBefore(mineCurrent, theirsCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(mineCurrent, mineOffset)); - mineIndex++; - theirsOffset += mineCurrent.newLines - mineCurrent.oldLines; - } else if (hunkBefore(theirsCurrent, mineCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset)); - theirsIndex++; - mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines; - } else { - // Overlap, merge as best we can - var mergedHunk = { - oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart), - oldLines: 0, - newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset), - newLines: 0, - lines: [] - }; - mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines); - theirsIndex++; - mineIndex++; - ret.hunks.push(mergedHunk); - } - } - - return ret; -} - -function loadPatch(param, base) { - if (typeof param === 'string') { - if (/^@@/m.test(param) || /^Index:/m.test(param)) { - return parsePatch(param)[0]; - } - - if (!base) { - throw new Error('Must provide a base reference or pass in a patch'); - } - - return structuredPatch(undefined, undefined, base, param); - } - - return param; -} - -function fileNameChanged(patch) { - return patch.newFileName && patch.newFileName !== patch.oldFileName; -} - -function selectField(index, mine, theirs) { - if (mine === theirs) { - return mine; - } else { - index.conflict = true; - return { - mine: mine, - theirs: theirs - }; - } -} - -function hunkBefore(test, check) { - return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart; -} - -function cloneHunk(hunk, offset) { - return { - oldStart: hunk.oldStart, - oldLines: hunk.oldLines, - newStart: hunk.newStart + offset, - newLines: hunk.newLines, - lines: hunk.lines - }; -} - -function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) { - // This will generally result in a conflicted hunk, but there are cases where the context - // is the only overlap where we can successfully merge the content here. - var mine = { - offset: mineOffset, - lines: mineLines, - index: 0 - }, - their = { - offset: theirOffset, - lines: theirLines, - index: 0 - }; // Handle any leading content - - insertLeading(hunk, mine, their); - insertLeading(hunk, their, mine); // Now in the overlap content. Scan through and select the best changes from each. - - while (mine.index < mine.lines.length && their.index < their.lines.length) { - var mineCurrent = mine.lines[mine.index], - theirCurrent = their.lines[their.index]; - - if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) { - // Both modified ... - mutualChange(hunk, mine, their); - } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') { - var _hunk$lines; - - // Mine inserted - (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine))); - } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') { - var _hunk$lines2; - - // Theirs inserted - (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their))); - } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') { - // Mine removed or edited - removal(hunk, mine, their); - } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') { - // Their removed or edited - removal(hunk, their, mine, true); - } else if (mineCurrent === theirCurrent) { - // Context identity - hunk.lines.push(mineCurrent); - mine.index++; - their.index++; - } else { - // Context mismatch - conflict(hunk, collectChange(mine), collectChange(their)); - } - } // Now push anything that may be remaining - - - insertTrailing(hunk, mine); - insertTrailing(hunk, their); - calcLineCount(hunk); -} - -function mutualChange(hunk, mine, their) { - var myChanges = collectChange(mine), - theirChanges = collectChange(their); - - if (allRemoves(myChanges) && allRemoves(theirChanges)) { - // Special case for remove changes that are supersets of one another - if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) { - var _hunk$lines3; - - (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges)); - - return; - } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) { - var _hunk$lines4; - - (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges)); - - return; - } - } else if (arrayEqual(myChanges, theirChanges)) { - var _hunk$lines5; - - (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges)); - - return; - } - - conflict(hunk, myChanges, theirChanges); -} - -function removal(hunk, mine, their, swap) { - var myChanges = collectChange(mine), - theirChanges = collectContext(their, myChanges); - - if (theirChanges.merged) { - var _hunk$lines6; - - (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged)); - } else { - conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges); - } -} - -function conflict(hunk, mine, their) { - hunk.conflict = true; - hunk.lines.push({ - conflict: true, - mine: mine, - theirs: their - }); -} - -function insertLeading(hunk, insert, their) { - while (insert.offset < their.offset && insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - insert.offset++; - } -} - -function insertTrailing(hunk, insert) { - while (insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - } -} - -function collectChange(state) { - var ret = [], - operation = state.lines[state.index][0]; - - while (state.index < state.lines.length) { - var line = state.lines[state.index]; // Group additions that are immediately after subtractions and treat them as one "atomic" modify change. - - if (operation === '-' && line[0] === '+') { - operation = '+'; - } - - if (operation === line[0]) { - ret.push(line); - state.index++; - } else { - break; - } - } - - return ret; -} - -function collectContext(state, matchChanges) { - var changes = [], - merged = [], - matchIndex = 0, - contextChanges = false, - conflicted = false; - - while (matchIndex < matchChanges.length && state.index < state.lines.length) { - var change = state.lines[state.index], - match = matchChanges[matchIndex]; // Once we've hit our add, then we are done - - if (match[0] === '+') { - break; - } - - contextChanges = contextChanges || change[0] !== ' '; - merged.push(match); - matchIndex++; // Consume any additions in the other block as a conflict to attempt - // to pull in the remaining context after this - - if (change[0] === '+') { - conflicted = true; - - while (change[0] === '+') { - changes.push(change); - change = state.lines[++state.index]; - } - } - - if (match.substr(1) === change.substr(1)) { - changes.push(change); - state.index++; - } else { - conflicted = true; - } - } - - if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) { - conflicted = true; - } - - if (conflicted) { - return changes; - } - - while (matchIndex < matchChanges.length) { - merged.push(matchChanges[matchIndex++]); - } - - return { - merged: merged, - changes: changes - }; -} - -function allRemoves(changes) { - return changes.reduce(function (prev, change) { - return prev && change[0] === '-'; - }, true); -} - -function skipRemoveSuperset(state, removeChanges, delta) { - for (var i = 0; i < delta; i++) { - var changeContent = removeChanges[removeChanges.length - delta + i].substr(1); - - if (state.lines[state.index + i] !== ' ' + changeContent) { - return false; - } - } - - state.index += delta; - return true; -} - -function calcOldNewLineCount(lines) { - var oldLines = 0; - var newLines = 0; - lines.forEach(function (line) { - if (typeof line !== 'string') { - var myCount = calcOldNewLineCount(line.mine); - var theirCount = calcOldNewLineCount(line.theirs); - - if (oldLines !== undefined) { - if (myCount.oldLines === theirCount.oldLines) { - oldLines += myCount.oldLines; - } else { - oldLines = undefined; - } - } - - if (newLines !== undefined) { - if (myCount.newLines === theirCount.newLines) { - newLines += myCount.newLines; - } else { - newLines = undefined; - } - } - } else { - if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) { - newLines++; - } - - if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) { - oldLines++; - } - } - }); - return { - oldLines: oldLines, - newLines: newLines - }; -} - -// See: http://code.google.com/p/google-diff-match-patch/wiki/API -function convertChangesToDMP(changes) { - var ret = [], - change, - operation; - - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); - } - - return ret; -} - -function convertChangesToXML(changes) { - var ret = []; - - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - - if (change.added) { - ret.push('<ins>'); - } else if (change.removed) { - ret.push('<del>'); - } - - ret.push(escapeHTML(change.value)); - - if (change.added) { - ret.push('</ins>'); - } else if (change.removed) { - ret.push('</del>'); - } - } - - return ret.join(''); -} - -function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(/</g, '<'); - n = n.replace(/>/g, '>'); - n = n.replace(/"/g, '"'); - return n; -} - -export { Diff, applyPatch, applyPatches, canonicalize, convertChangesToDMP, convertChangesToXML, createPatch, createTwoFilesPatch, diffArrays, diffChars, diffCss, diffJson, diffLines, diffSentences, diffTrimmedLines, diffWords, diffWordsWithSpace, merge, parsePatch, structuredPatch }; diff --git a/node_modules/diff/lib/patch/apply.js b/node_modules/diff/lib/patch/apply.js deleted file mode 100644 index 21c76ddb76ba7..0000000000000 --- a/node_modules/diff/lib/patch/apply.js +++ /dev/null @@ -1,238 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.applyPatch = applyPatch; -exports.applyPatches = applyPatches; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_parse = require("./parse") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_distanceIterator = _interopRequireDefault(require("../util/distance-iterator")) -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/*istanbul ignore end*/ -function applyPatch(source, uniDiff) { - /*istanbul ignore start*/ - var - /*istanbul ignore end*/ - options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - if (typeof uniDiff === 'string') { - uniDiff = - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _parse - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - parsePatch) - /*istanbul ignore end*/ - (uniDiff); - } - - if (Array.isArray(uniDiff)) { - if (uniDiff.length > 1) { - throw new Error('applyPatch only works with a single input.'); - } - - uniDiff = uniDiff[0]; - } // Apply the diff to the input - - - var lines = source.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], - hunks = uniDiff.hunks, - compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) - /*istanbul ignore start*/ - { - return ( - /*istanbul ignore end*/ - line === patchContent - ); - }, - errorCount = 0, - fuzzFactor = options.fuzzFactor || 0, - minLine = 0, - offset = 0, - removeEOFNL, - addEOFNL; - /** - * Checks if the hunk exactly fits on the provided location - */ - - - function hunkFits(hunk, toPos) { - for (var j = 0; j < hunk.lines.length; j++) { - var line = hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line; - - if (operation === ' ' || operation === '-') { - // Context sanity check - if (!compareLine(toPos + 1, lines[toPos], operation, content)) { - errorCount++; - - if (errorCount > fuzzFactor) { - return false; - } - } - - toPos++; - } - } - - return true; - } // Search best fit offsets for each hunk based on the previous ones - - - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i], - maxLine = lines.length - hunk.oldLines, - localOffset = 0, - toPos = offset + hunk.oldStart - 1; - var iterator = - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _distanceIterator - /*istanbul ignore end*/ - [ - /*istanbul ignore start*/ - "default" - /*istanbul ignore end*/ - ])(toPos, minLine, maxLine); - - for (; localOffset !== undefined; localOffset = iterator()) { - if (hunkFits(hunk, toPos + localOffset)) { - hunk.offset = offset += localOffset; - break; - } - } - - if (localOffset === undefined) { - return false; - } // Set lower text limit to end of the current hunk, so next ones don't try - // to fit over already patched text - - - minLine = hunk.offset + hunk.oldStart + hunk.oldLines; - } // Apply patch hunks - - - var diffOffset = 0; - - for (var _i = 0; _i < hunks.length; _i++) { - var _hunk = hunks[_i], - _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1; - - diffOffset += _hunk.newLines - _hunk.oldLines; - - for (var j = 0; j < _hunk.lines.length; j++) { - var line = _hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line, - delimiter = _hunk.linedelimiters[j]; - - if (operation === ' ') { - _toPos++; - } else if (operation === '-') { - lines.splice(_toPos, 1); - delimiters.splice(_toPos, 1); - /* istanbul ignore else */ - } else if (operation === '+') { - lines.splice(_toPos, 0, content); - delimiters.splice(_toPos, 0, delimiter); - _toPos++; - } else if (operation === '\\') { - var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; - - if (previousOperation === '+') { - removeEOFNL = true; - } else if (previousOperation === '-') { - addEOFNL = true; - } - } - } - } // Handle EOFNL insertion/removal - - - if (removeEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - delimiters.pop(); - } - } else if (addEOFNL) { - lines.push(''); - delimiters.push('\n'); - } - - for (var _k = 0; _k < lines.length - 1; _k++) { - lines[_k] = lines[_k] + delimiters[_k]; - } - - return lines.join(''); -} // Wrapper that supports multiple file patches via callbacks. - - -function applyPatches(uniDiff, options) { - if (typeof uniDiff === 'string') { - uniDiff = - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _parse - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - parsePatch) - /*istanbul ignore end*/ - (uniDiff); - } - - var currentIndex = 0; - - function processIndex() { - var index = uniDiff[currentIndex++]; - - if (!index) { - return options.complete(); - } - - options.loadFile(index, function (err, data) { - if (err) { - return options.complete(err); - } - - var updatedContent = applyPatch(data, index, options); - options.patched(index, updatedContent, function (err) { - if (err) { - return options.complete(err); - } - - processIndex(); - }); - }); - } - - processIndex(); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wYXRjaC9hcHBseS5qcyJdLCJuYW1lcyI6WyJhcHBseVBhdGNoIiwic291cmNlIiwidW5pRGlmZiIsIm9wdGlvbnMiLCJwYXJzZVBhdGNoIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiRXJyb3IiLCJsaW5lcyIsInNwbGl0IiwiZGVsaW1pdGVycyIsIm1hdGNoIiwiaHVua3MiLCJjb21wYXJlTGluZSIsImxpbmVOdW1iZXIiLCJsaW5lIiwib3BlcmF0aW9uIiwicGF0Y2hDb250ZW50IiwiZXJyb3JDb3VudCIsImZ1enpGYWN0b3IiLCJtaW5MaW5lIiwib2Zmc2V0IiwicmVtb3ZlRU9GTkwiLCJhZGRFT0ZOTCIsImh1bmtGaXRzIiwiaHVuayIsInRvUG9zIiwiaiIsImNvbnRlbnQiLCJzdWJzdHIiLCJpIiwibWF4TGluZSIsIm9sZExpbmVzIiwibG9jYWxPZmZzZXQiLCJvbGRTdGFydCIsIml0ZXJhdG9yIiwiZGlzdGFuY2VJdGVyYXRvciIsInVuZGVmaW5lZCIsImRpZmZPZmZzZXQiLCJuZXdMaW5lcyIsImRlbGltaXRlciIsImxpbmVkZWxpbWl0ZXJzIiwic3BsaWNlIiwicHJldmlvdXNPcGVyYXRpb24iLCJwb3AiLCJwdXNoIiwiX2siLCJqb2luIiwiYXBwbHlQYXRjaGVzIiwiY3VycmVudEluZGV4IiwicHJvY2Vzc0luZGV4IiwiaW5kZXgiLCJjb21wbGV0ZSIsImxvYWRGaWxlIiwiZXJyIiwiZGF0YSIsInVwZGF0ZWRDb250ZW50IiwicGF0Y2hlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTs7Ozs7QUFFTyxTQUFTQSxVQUFULENBQW9CQyxNQUFwQixFQUE0QkMsT0FBNUIsRUFBbUQ7QUFBQTtBQUFBO0FBQUE7QUFBZEMsRUFBQUEsT0FBYyx1RUFBSixFQUFJOztBQUN4RCxNQUFJLE9BQU9ELE9BQVAsS0FBbUIsUUFBdkIsRUFBaUM7QUFDL0JBLElBQUFBLE9BQU87QUFBRztBQUFBO0FBQUE7O0FBQUFFO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUE7QUFBQSxLQUFXRixPQUFYLENBQVY7QUFDRDs7QUFFRCxNQUFJRyxLQUFLLENBQUNDLE9BQU4sQ0FBY0osT0FBZCxDQUFKLEVBQTRCO0FBQzFCLFFBQUlBLE9BQU8sQ0FBQ0ssTUFBUixHQUFpQixDQUFyQixFQUF3QjtBQUN0QixZQUFNLElBQUlDLEtBQUosQ0FBVSw0Q0FBVixDQUFOO0FBQ0Q7O0FBRUROLElBQUFBLE9BQU8sR0FBR0EsT0FBTyxDQUFDLENBQUQsQ0FBakI7QUFDRCxHQVh1RCxDQWF4RDs7O0FBQ0EsTUFBSU8sS0FBSyxHQUFHUixNQUFNLENBQUNTLEtBQVAsQ0FBYSxxQkFBYixDQUFaO0FBQUEsTUFDSUMsVUFBVSxHQUFHVixNQUFNLENBQUNXLEtBQVAsQ0FBYSxzQkFBYixLQUF3QyxFQUR6RDtBQUFBLE1BRUlDLEtBQUssR0FBR1gsT0FBTyxDQUFDVyxLQUZwQjtBQUFBLE1BSUlDLFdBQVcsR0FBR1gsT0FBTyxDQUFDVyxXQUFSLElBQXdCLFVBQUNDLFVBQUQsRUFBYUMsSUFBYixFQUFtQkMsU0FBbkIsRUFBOEJDLFlBQTlCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBK0NGLE1BQUFBLElBQUksS0FBS0U7QUFBeEQ7QUFBQSxHQUoxQztBQUFBLE1BS0lDLFVBQVUsR0FBRyxDQUxqQjtBQUFBLE1BTUlDLFVBQVUsR0FBR2pCLE9BQU8sQ0FBQ2lCLFVBQVIsSUFBc0IsQ0FOdkM7QUFBQSxNQU9JQyxPQUFPLEdBQUcsQ0FQZDtBQUFBLE1BUUlDLE1BQU0sR0FBRyxDQVJiO0FBQUEsTUFVSUMsV0FWSjtBQUFBLE1BV0lDLFFBWEo7QUFhQTs7Ozs7QUFHQSxXQUFTQyxRQUFULENBQWtCQyxJQUFsQixFQUF3QkMsS0FBeEIsRUFBK0I7QUFDN0IsU0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHRixJQUFJLENBQUNqQixLQUFMLENBQVdGLE1BQS9CLEVBQXVDcUIsQ0FBQyxFQUF4QyxFQUE0QztBQUMxQyxVQUFJWixJQUFJLEdBQUdVLElBQUksQ0FBQ2pCLEtBQUwsQ0FBV21CLENBQVgsQ0FBWDtBQUFBLFVBQ0lYLFNBQVMsR0FBSUQsSUFBSSxDQUFDVCxNQUFMLEdBQWMsQ0FBZCxHQUFrQlMsSUFBSSxDQUFDLENBQUQsQ0FBdEIsR0FBNEIsR0FEN0M7QUFBQSxVQUVJYSxPQUFPLEdBQUliLElBQUksQ0FBQ1QsTUFBTCxHQUFjLENBQWQsR0FBa0JTLElBQUksQ0FBQ2MsTUFBTCxDQUFZLENBQVosQ0FBbEIsR0FBbUNkLElBRmxEOztBQUlBLFVBQUlDLFNBQVMsS0FBSyxHQUFkLElBQXFCQSxTQUFTLEtBQUssR0FBdkMsRUFBNEM7QUFDMUM7QUFDQSxZQUFJLENBQUNILFdBQVcsQ0FBQ2EsS0FBSyxHQUFHLENBQVQsRUFBWWxCLEtBQUssQ0FBQ2tCLEtBQUQsQ0FBakIsRUFBMEJWLFNBQTFCLEVBQXFDWSxPQUFyQyxDQUFoQixFQUErRDtBQUM3RFYsVUFBQUEsVUFBVTs7QUFFVixjQUFJQSxVQUFVLEdBQUdDLFVBQWpCLEVBQTZCO0FBQzNCLG1CQUFPLEtBQVA7QUFDRDtBQUNGOztBQUNETyxRQUFBQSxLQUFLO0FBQ047QUFDRjs7QUFFRCxXQUFPLElBQVA7QUFDRCxHQWxEdUQsQ0FvRHhEOzs7QUFDQSxPQUFLLElBQUlJLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdsQixLQUFLLENBQUNOLE1BQTFCLEVBQWtDd0IsQ0FBQyxFQUFuQyxFQUF1QztBQUNyQyxRQUFJTCxJQUFJLEdBQUdiLEtBQUssQ0FBQ2tCLENBQUQsQ0FBaEI7QUFBQSxRQUNJQyxPQUFPLEdBQUd2QixLQUFLLENBQUNGLE1BQU4sR0FBZW1CLElBQUksQ0FBQ08sUUFEbEM7QUFBQSxRQUVJQyxXQUFXLEdBQUcsQ0FGbEI7QUFBQSxRQUdJUCxLQUFLLEdBQUdMLE1BQU0sR0FBR0ksSUFBSSxDQUFDUyxRQUFkLEdBQXlCLENBSHJDO0FBS0EsUUFBSUMsUUFBUTtBQUFHO0FBQUE7QUFBQTs7QUFBQUM7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUEsT0FBaUJWLEtBQWpCLEVBQXdCTixPQUF4QixFQUFpQ1csT0FBakMsQ0FBZjs7QUFFQSxXQUFPRSxXQUFXLEtBQUtJLFNBQXZCLEVBQWtDSixXQUFXLEdBQUdFLFFBQVEsRUFBeEQsRUFBNEQ7QUFDMUQsVUFBSVgsUUFBUSxDQUFDQyxJQUFELEVBQU9DLEtBQUssR0FBR08sV0FBZixDQUFaLEVBQXlDO0FBQ3ZDUixRQUFBQSxJQUFJLENBQUNKLE1BQUwsR0FBY0EsTUFBTSxJQUFJWSxXQUF4QjtBQUNBO0FBQ0Q7QUFDRjs7QUFFRCxRQUFJQSxXQUFXLEtBQUtJLFNBQXBCLEVBQStCO0FBQzdCLGFBQU8sS0FBUDtBQUNELEtBakJvQyxDQW1CckM7QUFDQTs7O0FBQ0FqQixJQUFBQSxPQUFPLEdBQUdLLElBQUksQ0FBQ0osTUFBTCxHQUFjSSxJQUFJLENBQUNTLFFBQW5CLEdBQThCVCxJQUFJLENBQUNPLFFBQTdDO0FBQ0QsR0EzRXVELENBNkV4RDs7O0FBQ0EsTUFBSU0sVUFBVSxHQUFHLENBQWpCOztBQUNBLE9BQUssSUFBSVIsRUFBQyxHQUFHLENBQWIsRUFBZ0JBLEVBQUMsR0FBR2xCLEtBQUssQ0FBQ04sTUFBMUIsRUFBa0N3QixFQUFDLEVBQW5DLEVBQXVDO0FBQ3JDLFFBQUlMLEtBQUksR0FBR2IsS0FBSyxDQUFDa0IsRUFBRCxDQUFoQjtBQUFBLFFBQ0lKLE1BQUssR0FBR0QsS0FBSSxDQUFDUyxRQUFMLEdBQWdCVCxLQUFJLENBQUNKLE1BQXJCLEdBQThCaUIsVUFBOUIsR0FBMkMsQ0FEdkQ7O0FBRUFBLElBQUFBLFVBQVUsSUFBSWIsS0FBSSxDQUFDYyxRQUFMLEdBQWdCZCxLQUFJLENBQUNPLFFBQW5DOztBQUVBLFNBQUssSUFBSUwsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0YsS0FBSSxDQUFDakIsS0FBTCxDQUFXRixNQUEvQixFQUF1Q3FCLENBQUMsRUFBeEMsRUFBNEM7QUFDMUMsVUFBSVosSUFBSSxHQUFHVSxLQUFJLENBQUNqQixLQUFMLENBQVdtQixDQUFYLENBQVg7QUFBQSxVQUNJWCxTQUFTLEdBQUlELElBQUksQ0FBQ1QsTUFBTCxHQUFjLENBQWQsR0FBa0JTLElBQUksQ0FBQyxDQUFELENBQXRCLEdBQTRCLEdBRDdDO0FBQUEsVUFFSWEsT0FBTyxHQUFJYixJQUFJLENBQUNULE1BQUwsR0FBYyxDQUFkLEdBQWtCUyxJQUFJLENBQUNjLE1BQUwsQ0FBWSxDQUFaLENBQWxCLEdBQW1DZCxJQUZsRDtBQUFBLFVBR0l5QixTQUFTLEdBQUdmLEtBQUksQ0FBQ2dCLGNBQUwsQ0FBb0JkLENBQXBCLENBSGhCOztBQUtBLFVBQUlYLFNBQVMsS0FBSyxHQUFsQixFQUF1QjtBQUNyQlUsUUFBQUEsTUFBSztBQUNOLE9BRkQsTUFFTyxJQUFJVixTQUFTLEtBQUssR0FBbEIsRUFBdUI7QUFDNUJSLFFBQUFBLEtBQUssQ0FBQ2tDLE1BQU4sQ0FBYWhCLE1BQWIsRUFBb0IsQ0FBcEI7QUFDQWhCLFFBQUFBLFVBQVUsQ0FBQ2dDLE1BQVgsQ0FBa0JoQixNQUFsQixFQUF5QixDQUF6QjtBQUNGO0FBQ0MsT0FKTSxNQUlBLElBQUlWLFNBQVMsS0FBSyxHQUFsQixFQUF1QjtBQUM1QlIsUUFBQUEsS0FBSyxDQUFDa0MsTUFBTixDQUFhaEIsTUFBYixFQUFvQixDQUFwQixFQUF1QkUsT0FBdkI7QUFDQWxCLFFBQUFBLFVBQVUsQ0FBQ2dDLE1BQVgsQ0FBa0JoQixNQUFsQixFQUF5QixDQUF6QixFQUE0QmMsU0FBNUI7QUFDQWQsUUFBQUEsTUFBSztBQUNOLE9BSk0sTUFJQSxJQUFJVixTQUFTLEtBQUssSUFBbEIsRUFBd0I7QUFDN0IsWUFBSTJCLGlCQUFpQixHQUFHbEIsS0FBSSxDQUFDakIsS0FBTCxDQUFXbUIsQ0FBQyxHQUFHLENBQWYsSUFBb0JGLEtBQUksQ0FBQ2pCLEtBQUwsQ0FBV21CLENBQUMsR0FBRyxDQUFmLEVBQWtCLENBQWxCLENBQXBCLEdBQTJDLElBQW5FOztBQUNBLFlBQUlnQixpQkFBaUIsS0FBSyxHQUExQixFQUErQjtBQUM3QnJCLFVBQUFBLFdBQVcsR0FBRyxJQUFkO0FBQ0QsU0FGRCxNQUVPLElBQUlxQixpQkFBaUIsS0FBSyxHQUExQixFQUErQjtBQUNwQ3BCLFVBQUFBLFFBQVEsR0FBRyxJQUFYO0FBQ0Q7QUFDRjtBQUNGO0FBQ0YsR0E3R3VELENBK0d4RDs7O0FBQ0EsTUFBSUQsV0FBSixFQUFpQjtBQUNmLFdBQU8sQ0FBQ2QsS0FBSyxDQUFDQSxLQUFLLENBQUNGLE1BQU4sR0FBZSxDQUFoQixDQUFiLEVBQWlDO0FBQy9CRSxNQUFBQSxLQUFLLENBQUNvQyxHQUFOO0FBQ0FsQyxNQUFBQSxVQUFVLENBQUNrQyxHQUFYO0FBQ0Q7QUFDRixHQUxELE1BS08sSUFBSXJCLFFBQUosRUFBYztBQUNuQmYsSUFBQUEsS0FBSyxDQUFDcUMsSUFBTixDQUFXLEVBQVg7QUFDQW5DLElBQUFBLFVBQVUsQ0FBQ21DLElBQVgsQ0FBZ0IsSUFBaEI7QUFDRDs7QUFDRCxPQUFLLElBQUlDLEVBQUUsR0FBRyxDQUFkLEVBQWlCQSxFQUFFLEdBQUd0QyxLQUFLLENBQUNGLE1BQU4sR0FBZSxDQUFyQyxFQUF3Q3dDLEVBQUUsRUFBMUMsRUFBOEM7QUFDNUN0QyxJQUFBQSxLQUFLLENBQUNzQyxFQUFELENBQUwsR0FBWXRDLEtBQUssQ0FBQ3NDLEVBQUQsQ0FBTCxHQUFZcEMsVUFBVSxDQUFDb0MsRUFBRCxDQUFsQztBQUNEOztBQUNELFNBQU90QyxLQUFLLENBQUN1QyxJQUFOLENBQVcsRUFBWCxDQUFQO0FBQ0QsQyxDQUVEOzs7QUFDTyxTQUFTQyxZQUFULENBQXNCL0MsT0FBdEIsRUFBK0JDLE9BQS9CLEVBQXdDO0FBQzdDLE1BQUksT0FBT0QsT0FBUCxLQUFtQixRQUF2QixFQUFpQztBQUMvQkEsSUFBQUEsT0FBTztBQUFHO0FBQUE7QUFBQTs7QUFBQUU7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQUE7QUFBQTtBQUFBLEtBQVdGLE9BQVgsQ0FBVjtBQUNEOztBQUVELE1BQUlnRCxZQUFZLEdBQUcsQ0FBbkI7O0FBQ0EsV0FBU0MsWUFBVCxHQUF3QjtBQUN0QixRQUFJQyxLQUFLLEdBQUdsRCxPQUFPLENBQUNnRCxZQUFZLEVBQWIsQ0FBbkI7O0FBQ0EsUUFBSSxDQUFDRSxLQUFMLEVBQVk7QUFDVixhQUFPakQsT0FBTyxDQUFDa0QsUUFBUixFQUFQO0FBQ0Q7O0FBRURsRCxJQUFBQSxPQUFPLENBQUNtRCxRQUFSLENBQWlCRixLQUFqQixFQUF3QixVQUFTRyxHQUFULEVBQWNDLElBQWQsRUFBb0I7QUFDMUMsVUFBSUQsR0FBSixFQUFTO0FBQ1AsZUFBT3BELE9BQU8sQ0FBQ2tELFFBQVIsQ0FBaUJFLEdBQWpCLENBQVA7QUFDRDs7QUFFRCxVQUFJRSxjQUFjLEdBQUd6RCxVQUFVLENBQUN3RCxJQUFELEVBQU9KLEtBQVAsRUFBY2pELE9BQWQsQ0FBL0I7QUFDQUEsTUFBQUEsT0FBTyxDQUFDdUQsT0FBUixDQUFnQk4sS0FBaEIsRUFBdUJLLGNBQXZCLEVBQXVDLFVBQVNGLEdBQVQsRUFBYztBQUNuRCxZQUFJQSxHQUFKLEVBQVM7QUFDUCxpQkFBT3BELE9BQU8sQ0FBQ2tELFFBQVIsQ0FBaUJFLEdBQWpCLENBQVA7QUFDRDs7QUFFREosUUFBQUEsWUFBWTtBQUNiLE9BTkQ7QUFPRCxLQWJEO0FBY0Q7O0FBQ0RBLEVBQUFBLFlBQVk7QUFDYiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7cGFyc2VQYXRjaH0gZnJvbSAnLi9wYXJzZSc7XG5pbXBvcnQgZGlzdGFuY2VJdGVyYXRvciBmcm9tICcuLi91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2goc291cmNlLCB1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgaWYgKHR5cGVvZiB1bmlEaWZmID09PSAnc3RyaW5nJykge1xuICAgIHVuaURpZmYgPSBwYXJzZVBhdGNoKHVuaURpZmYpO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodW5pRGlmZikpIHtcbiAgICBpZiAodW5pRGlmZi5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FwcGx5UGF0Y2ggb25seSB3b3JrcyB3aXRoIGEgc2luZ2xlIGlucHV0LicpO1xuICAgIH1cblxuICAgIHVuaURpZmYgPSB1bmlEaWZmWzBdO1xuICB9XG5cbiAgLy8gQXBwbHkgdGhlIGRpZmYgdG8gdGhlIGlucHV0XG4gIGxldCBsaW5lcyA9IHNvdXJjZS5zcGxpdCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vKSxcbiAgICAgIGRlbGltaXRlcnMgPSBzb3VyY2UubWF0Y2goL1xcclxcbnxbXFxuXFx2XFxmXFxyXFx4ODVdL2cpIHx8IFtdLFxuICAgICAgaHVua3MgPSB1bmlEaWZmLmh1bmtzLFxuXG4gICAgICBjb21wYXJlTGluZSA9IG9wdGlvbnMuY29tcGFyZUxpbmUgfHwgKChsaW5lTnVtYmVyLCBsaW5lLCBvcGVyYXRpb24sIHBhdGNoQ29udGVudCkgPT4gbGluZSA9PT0gcGF0Y2hDb250ZW50KSxcbiAgICAgIGVycm9yQ291bnQgPSAwLFxuICAgICAgZnV6ekZhY3RvciA9IG9wdGlvbnMuZnV6ekZhY3RvciB8fCAwLFxuICAgICAgbWluTGluZSA9IDAsXG4gICAgICBvZmZzZXQgPSAwLFxuXG4gICAgICByZW1vdmVFT0ZOTCxcbiAgICAgIGFkZEVPRk5MO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGh1bmsgZXhhY3RseSBmaXRzIG9uIHRoZSBwcm92aWRlZCBsb2NhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gaHVua0ZpdHMoaHVuaywgdG9Qb3MpIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGh1bmsubGluZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGxldCBsaW5lID0gaHVuay5saW5lc1tqXSxcbiAgICAgICAgICBvcGVyYXRpb24gPSAobGluZS5sZW5ndGggPiAwID8gbGluZVswXSA6ICcgJyksXG4gICAgICAgICAgY29udGVudCA9IChsaW5lLmxlbmd0aCA+IDAgPyBsaW5lLnN1YnN0cigxKSA6IGxpbmUpO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnICcgfHwgb3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgLy8gQ29udGV4dCBzYW5pdHkgY2hlY2tcbiAgICAgICAgaWYgKCFjb21wYXJlTGluZSh0b1BvcyArIDEsIGxpbmVzW3RvUG9zXSwgb3BlcmF0aW9uLCBjb250ZW50KSkge1xuICAgICAgICAgIGVycm9yQ291bnQrKztcblxuICAgICAgICAgIGlmIChlcnJvckNvdW50ID4gZnV6ekZhY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0b1BvcysrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gU2VhcmNoIGJlc3QgZml0IG9mZnNldHMgZm9yIGVhY2ggaHVuayBiYXNlZCBvbiB0aGUgcHJldmlvdXMgb25lc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGh1bmsgPSBodW5rc1tpXSxcbiAgICAgICAgbWF4TGluZSA9IGxpbmVzLmxlbmd0aCAtIGh1bmsub2xkTGluZXMsXG4gICAgICAgIGxvY2FsT2Zmc2V0ID0gMCxcbiAgICAgICAgdG9Qb3MgPSBvZmZzZXQgKyBodW5rLm9sZFN0YXJ0IC0gMTtcblxuICAgIGxldCBpdGVyYXRvciA9IGRpc3RhbmNlSXRlcmF0b3IodG9Qb3MsIG1pbkxpbmUsIG1heExpbmUpO1xuXG4gICAgZm9yICg7IGxvY2FsT2Zmc2V0ICE9PSB1bmRlZmluZWQ7IGxvY2FsT2Zmc2V0ID0gaXRlcmF0b3IoKSkge1xuICAgICAgaWYgKGh1bmtGaXRzKGh1bmssIHRvUG9zICsgbG9jYWxPZmZzZXQpKSB7XG4gICAgICAgIGh1bmsub2Zmc2V0ID0gb2Zmc2V0ICs9IGxvY2FsT2Zmc2V0O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobG9jYWxPZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFNldCBsb3dlciB0ZXh0IGxpbWl0IHRvIGVuZCBvZiB0aGUgY3VycmVudCBodW5rLCBzbyBuZXh0IG9uZXMgZG9uJ3QgdHJ5XG4gICAgLy8gdG8gZml0IG92ZXIgYWxyZWFkeSBwYXRjaGVkIHRleHRcbiAgICBtaW5MaW5lID0gaHVuay5vZmZzZXQgKyBodW5rLm9sZFN0YXJ0ICsgaHVuay5vbGRMaW5lcztcbiAgfVxuXG4gIC8vIEFwcGx5IHBhdGNoIGh1bmtzXG4gIGxldCBkaWZmT2Zmc2V0ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBodW5rcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBodW5rID0gaHVua3NbaV0sXG4gICAgICAgIHRvUG9zID0gaHVuay5vbGRTdGFydCArIGh1bmsub2Zmc2V0ICsgZGlmZk9mZnNldCAtIDE7XG4gICAgZGlmZk9mZnNldCArPSBodW5rLm5ld0xpbmVzIC0gaHVuay5vbGRMaW5lcztcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaHVuay5saW5lcy5sZW5ndGg7IGorKykge1xuICAgICAgbGV0IGxpbmUgPSBodW5rLmxpbmVzW2pdLFxuICAgICAgICAgIG9wZXJhdGlvbiA9IChsaW5lLmxlbmd0aCA+IDAgPyBsaW5lWzBdIDogJyAnKSxcbiAgICAgICAgICBjb250ZW50ID0gKGxpbmUubGVuZ3RoID4gMCA/IGxpbmUuc3Vic3RyKDEpIDogbGluZSksXG4gICAgICAgICAgZGVsaW1pdGVyID0gaHVuay5saW5lZGVsaW1pdGVyc1tqXTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJyAnKSB7XG4gICAgICAgIHRvUG9zKys7XG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgIGxpbmVzLnNwbGljZSh0b1BvcywgMSk7XG4gICAgICAgIGRlbGltaXRlcnMuc3BsaWNlKHRvUG9zLCAxKTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJysnKSB7XG4gICAgICAgIGxpbmVzLnNwbGljZSh0b1BvcywgMCwgY29udGVudCk7XG4gICAgICAgIGRlbGltaXRlcnMuc3BsaWNlKHRvUG9zLCAwLCBkZWxpbWl0ZXIpO1xuICAgICAgICB0b1BvcysrO1xuICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdcXFxcJykge1xuICAgICAgICBsZXQgcHJldmlvdXNPcGVyYXRpb24gPSBodW5rLmxpbmVzW2ogLSAxXSA/IGh1bmsubGluZXNbaiAtIDFdWzBdIDogbnVsbDtcbiAgICAgICAgaWYgKHByZXZpb3VzT3BlcmF0aW9uID09PSAnKycpIHtcbiAgICAgICAgICByZW1vdmVFT0ZOTCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAocHJldmlvdXNPcGVyYXRpb24gPT09ICctJykge1xuICAgICAgICAgIGFkZEVPRk5MID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEhhbmRsZSBFT0ZOTCBpbnNlcnRpb24vcmVtb3ZhbFxuICBpZiAocmVtb3ZlRU9GTkwpIHtcbiAgICB3aGlsZSAoIWxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdKSB7XG4gICAgICBsaW5lcy5wb3AoKTtcbiAgICAgIGRlbGltaXRlcnMucG9wKCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGFkZEVPRk5MKSB7XG4gICAgbGluZXMucHVzaCgnJyk7XG4gICAgZGVsaW1pdGVycy5wdXNoKCdcXG4nKTtcbiAgfVxuICBmb3IgKGxldCBfayA9IDA7IF9rIDwgbGluZXMubGVuZ3RoIC0gMTsgX2srKykge1xuICAgIGxpbmVzW19rXSA9IGxpbmVzW19rXSArIGRlbGltaXRlcnNbX2tdO1xuICB9XG4gIHJldHVybiBsaW5lcy5qb2luKCcnKTtcbn1cblxuLy8gV3JhcHBlciB0aGF0IHN1cHBvcnRzIG11bHRpcGxlIGZpbGUgcGF0Y2hlcyB2aWEgY2FsbGJhY2tzLlxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2hlcyh1bmlEaWZmLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgdW5pRGlmZiA9PT0gJ3N0cmluZycpIHtcbiAgICB1bmlEaWZmID0gcGFyc2VQYXRjaCh1bmlEaWZmKTtcbiAgfVxuXG4gIGxldCBjdXJyZW50SW5kZXggPSAwO1xuICBmdW5jdGlvbiBwcm9jZXNzSW5kZXgoKSB7XG4gICAgbGV0IGluZGV4ID0gdW5pRGlmZltjdXJyZW50SW5kZXgrK107XG4gICAgaWYgKCFpbmRleCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLmxvYWRGaWxlKGluZGV4LCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoZXJyKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHVwZGF0ZWRDb250ZW50ID0gYXBwbHlQYXRjaChkYXRhLCBpbmRleCwgb3B0aW9ucyk7XG4gICAgICBvcHRpb25zLnBhdGNoZWQoaW5kZXgsIHVwZGF0ZWRDb250ZW50LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiBvcHRpb25zLmNvbXBsZXRlKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9jZXNzSW5kZXgoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHByb2Nlc3NJbmRleCgpO1xufVxuIl19 diff --git a/node_modules/diff/lib/patch/create.js b/node_modules/diff/lib/patch/create.js deleted file mode 100644 index 48bb4668442a9..0000000000000 --- a/node_modules/diff/lib/patch/create.js +++ /dev/null @@ -1,267 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.structuredPatch = structuredPatch; -exports.formatPatch = formatPatch; -exports.createTwoFilesPatch = createTwoFilesPatch; -exports.createPatch = createPatch; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_line = require("../diff/line") -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } - -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } - -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -/*istanbul ignore end*/ -function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - if (!options) { - options = {}; - } - - if (typeof options.context === 'undefined') { - options.context = 4; - } - - var diff = - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _line - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - diffLines) - /*istanbul ignore end*/ - (oldStr, newStr, options); - diff.push({ - value: '', - lines: [] - }); // Append an empty value to make cleanup easier - - function contextLines(lines) { - return lines.map(function (entry) { - return ' ' + entry; - }); - } - - var hunks = []; - var oldRangeStart = 0, - newRangeStart = 0, - curRange = [], - oldLine = 1, - newLine = 1; - - /*istanbul ignore start*/ - var _loop = function _loop( - /*istanbul ignore end*/ - i) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; - - if (current.added || current.removed) { - /*istanbul ignore start*/ - var _curRange; - - /*istanbul ignore end*/ - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; - - if (prev) { - curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } // Output our changes - - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_curRange = - /*istanbul ignore end*/ - curRange).push.apply( - /*istanbul ignore start*/ - _curRange - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - lines.map(function (entry) { - return (current.added ? '+' : '-') + entry; - }))); // Track the updated file position - - - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= options.context * 2 && i < diff.length - 2) { - /*istanbul ignore start*/ - var _curRange2; - - /*istanbul ignore end*/ - // Overlapping - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_curRange2 = - /*istanbul ignore end*/ - curRange).push.apply( - /*istanbul ignore start*/ - _curRange2 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - contextLines(lines))); - } else { - /*istanbul ignore start*/ - var _curRange3; - - /*istanbul ignore end*/ - // end the range and output - var contextSize = Math.min(lines.length, options.context); - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_curRange3 = - /*istanbul ignore end*/ - curRange).push.apply( - /*istanbul ignore start*/ - _curRange3 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - contextLines(lines.slice(0, contextSize)))); - - var hunk = { - oldStart: oldRangeStart, - oldLines: oldLine - oldRangeStart + contextSize, - newStart: newRangeStart, - newLines: newLine - newRangeStart + contextSize, - lines: curRange - }; - - if (i >= diff.length - 2 && lines.length <= options.context) { - // EOF is inside this hunk - var oldEOFNewline = /\n$/.test(oldStr); - var newEOFNewline = /\n$/.test(newStr); - var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; - - if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) { - // special case: old has no eol and no trailing context; no-nl can end up before adds - // however, if the old file is empty, do not output the no-nl line - curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); - } - - if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) { - curRange.push('\\ No newline at end of file'); - } - } - - hunks.push(hunk); - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - - oldLine += lines.length; - newLine += lines.length; - } - }; - - for (var i = 0; i < diff.length; i++) { - /*istanbul ignore start*/ - _loop( - /*istanbul ignore end*/ - i); - } - - return { - oldFileName: oldFileName, - newFileName: newFileName, - oldHeader: oldHeader, - newHeader: newHeader, - hunks: hunks - }; -} - -function formatPatch(diff) { - var ret = []; - - if (diff.oldFileName == diff.newFileName) { - ret.push('Index: ' + diff.oldFileName); - } - - ret.push('==================================================================='); - ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); - ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); - - for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart -= 1; - } - - if (hunk.newLines === 0) { - hunk.newStart -= 1; - } - - ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); - ret.push.apply(ret, hunk.lines); - } - - return ret.join('\n') + '\n'; -} - -function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)); -} - -function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { - return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wYXRjaC9jcmVhdGUuanMiXSwibmFtZXMiOlsic3RydWN0dXJlZFBhdGNoIiwib2xkRmlsZU5hbWUiLCJuZXdGaWxlTmFtZSIsIm9sZFN0ciIsIm5ld1N0ciIsIm9sZEhlYWRlciIsIm5ld0hlYWRlciIsIm9wdGlvbnMiLCJjb250ZXh0IiwiZGlmZiIsImRpZmZMaW5lcyIsInB1c2giLCJ2YWx1ZSIsImxpbmVzIiwiY29udGV4dExpbmVzIiwibWFwIiwiZW50cnkiLCJodW5rcyIsIm9sZFJhbmdlU3RhcnQiLCJuZXdSYW5nZVN0YXJ0IiwiY3VyUmFuZ2UiLCJvbGRMaW5lIiwibmV3TGluZSIsImkiLCJjdXJyZW50IiwicmVwbGFjZSIsInNwbGl0IiwiYWRkZWQiLCJyZW1vdmVkIiwicHJldiIsInNsaWNlIiwibGVuZ3RoIiwiY29udGV4dFNpemUiLCJNYXRoIiwibWluIiwiaHVuayIsIm9sZFN0YXJ0Iiwib2xkTGluZXMiLCJuZXdTdGFydCIsIm5ld0xpbmVzIiwib2xkRU9GTmV3bGluZSIsInRlc3QiLCJuZXdFT0ZOZXdsaW5lIiwibm9ObEJlZm9yZUFkZHMiLCJzcGxpY2UiLCJmb3JtYXRQYXRjaCIsInJldCIsImFwcGx5Iiwiam9pbiIsImNyZWF0ZVR3b0ZpbGVzUGF0Y2giLCJjcmVhdGVQYXRjaCIsImZpbGVOYW1lIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7QUFFTyxTQUFTQSxlQUFULENBQXlCQyxXQUF6QixFQUFzQ0MsV0FBdEMsRUFBbURDLE1BQW5ELEVBQTJEQyxNQUEzRCxFQUFtRUMsU0FBbkUsRUFBOEVDLFNBQTlFLEVBQXlGQyxPQUF6RixFQUFrRztBQUN2RyxNQUFJLENBQUNBLE9BQUwsRUFBYztBQUNaQSxJQUFBQSxPQUFPLEdBQUcsRUFBVjtBQUNEOztBQUNELE1BQUksT0FBT0EsT0FBTyxDQUFDQyxPQUFmLEtBQTJCLFdBQS9CLEVBQTRDO0FBQzFDRCxJQUFBQSxPQUFPLENBQUNDLE9BQVIsR0FBa0IsQ0FBbEI7QUFDRDs7QUFFRCxNQUFNQyxJQUFJO0FBQUc7QUFBQTtBQUFBOztBQUFBQztBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBO0FBQUEsR0FBVVAsTUFBVixFQUFrQkMsTUFBbEIsRUFBMEJHLE9BQTFCLENBQWI7QUFDQUUsRUFBQUEsSUFBSSxDQUFDRSxJQUFMLENBQVU7QUFBQ0MsSUFBQUEsS0FBSyxFQUFFLEVBQVI7QUFBWUMsSUFBQUEsS0FBSyxFQUFFO0FBQW5CLEdBQVYsRUFUdUcsQ0FTcEU7O0FBRW5DLFdBQVNDLFlBQVQsQ0FBc0JELEtBQXRCLEVBQTZCO0FBQzNCLFdBQU9BLEtBQUssQ0FBQ0UsR0FBTixDQUFVLFVBQVNDLEtBQVQsRUFBZ0I7QUFBRSxhQUFPLE1BQU1BLEtBQWI7QUFBcUIsS0FBakQsQ0FBUDtBQUNEOztBQUVELE1BQUlDLEtBQUssR0FBRyxFQUFaO0FBQ0EsTUFBSUMsYUFBYSxHQUFHLENBQXBCO0FBQUEsTUFBdUJDLGFBQWEsR0FBRyxDQUF2QztBQUFBLE1BQTBDQyxRQUFRLEdBQUcsRUFBckQ7QUFBQSxNQUNJQyxPQUFPLEdBQUcsQ0FEZDtBQUFBLE1BQ2lCQyxPQUFPLEdBQUcsQ0FEM0I7O0FBaEJ1RztBQUFBO0FBQUE7QUFrQjlGQyxFQUFBQSxDQWxCOEY7QUFtQnJHLFFBQU1DLE9BQU8sR0FBR2YsSUFBSSxDQUFDYyxDQUFELENBQXBCO0FBQUEsUUFDTVYsS0FBSyxHQUFHVyxPQUFPLENBQUNYLEtBQVIsSUFBaUJXLE9BQU8sQ0FBQ1osS0FBUixDQUFjYSxPQUFkLENBQXNCLEtBQXRCLEVBQTZCLEVBQTdCLEVBQWlDQyxLQUFqQyxDQUF1QyxJQUF2QyxDQUQvQjtBQUVBRixJQUFBQSxPQUFPLENBQUNYLEtBQVIsR0FBZ0JBLEtBQWhCOztBQUVBLFFBQUlXLE9BQU8sQ0FBQ0csS0FBUixJQUFpQkgsT0FBTyxDQUFDSSxPQUE3QixFQUFzQztBQUFBO0FBQUE7O0FBQUE7QUFDcEM7QUFDQSxVQUFJLENBQUNWLGFBQUwsRUFBb0I7QUFDbEIsWUFBTVcsSUFBSSxHQUFHcEIsSUFBSSxDQUFDYyxDQUFDLEdBQUcsQ0FBTCxDQUFqQjtBQUNBTCxRQUFBQSxhQUFhLEdBQUdHLE9BQWhCO0FBQ0FGLFFBQUFBLGFBQWEsR0FBR0csT0FBaEI7O0FBRUEsWUFBSU8sSUFBSixFQUFVO0FBQ1JULFVBQUFBLFFBQVEsR0FBR2IsT0FBTyxDQUFDQyxPQUFSLEdBQWtCLENBQWxCLEdBQXNCTSxZQUFZLENBQUNlLElBQUksQ0FBQ2hCLEtBQUwsQ0FBV2lCLEtBQVgsQ0FBaUIsQ0FBQ3ZCLE9BQU8sQ0FBQ0MsT0FBMUIsQ0FBRCxDQUFsQyxHQUF5RSxFQUFwRjtBQUNBVSxVQUFBQSxhQUFhLElBQUlFLFFBQVEsQ0FBQ1csTUFBMUI7QUFDQVosVUFBQUEsYUFBYSxJQUFJQyxRQUFRLENBQUNXLE1BQTFCO0FBQ0Q7QUFDRixPQVptQyxDQWNwQzs7O0FBQ0E7O0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUFYLE1BQUFBLFFBQVEsRUFBQ1QsSUFBVDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQWtCRSxNQUFBQSxLQUFLLENBQUNFLEdBQU4sQ0FBVSxVQUFTQyxLQUFULEVBQWdCO0FBQzFDLGVBQU8sQ0FBQ1EsT0FBTyxDQUFDRyxLQUFSLEdBQWdCLEdBQWhCLEdBQXNCLEdBQXZCLElBQThCWCxLQUFyQztBQUNELE9BRmlCLENBQWxCLEdBZm9DLENBbUJwQzs7O0FBQ0EsVUFBSVEsT0FBTyxDQUFDRyxLQUFaLEVBQW1CO0FBQ2pCTCxRQUFBQSxPQUFPLElBQUlULEtBQUssQ0FBQ2tCLE1BQWpCO0FBQ0QsT0FGRCxNQUVPO0FBQ0xWLFFBQUFBLE9BQU8sSUFBSVIsS0FBSyxDQUFDa0IsTUFBakI7QUFDRDtBQUNGLEtBekJELE1BeUJPO0FBQ0w7QUFDQSxVQUFJYixhQUFKLEVBQW1CO0FBQ2pCO0FBQ0EsWUFBSUwsS0FBSyxDQUFDa0IsTUFBTixJQUFnQnhCLE9BQU8sQ0FBQ0MsT0FBUixHQUFrQixDQUFsQyxJQUF1Q2UsQ0FBQyxHQUFHZCxJQUFJLENBQUNzQixNQUFMLEdBQWMsQ0FBN0QsRUFBZ0U7QUFBQTtBQUFBOztBQUFBO0FBQzlEOztBQUNBOztBQUFBOztBQUFBO0FBQUE7QUFBQTtBQUFBWCxVQUFBQSxRQUFRLEVBQUNULElBQVQ7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFrQkcsVUFBQUEsWUFBWSxDQUFDRCxLQUFELENBQTlCO0FBQ0QsU0FIRCxNQUdPO0FBQUE7QUFBQTs7QUFBQTtBQUNMO0FBQ0EsY0FBSW1CLFdBQVcsR0FBR0MsSUFBSSxDQUFDQyxHQUFMLENBQVNyQixLQUFLLENBQUNrQixNQUFmLEVBQXVCeEIsT0FBTyxDQUFDQyxPQUEvQixDQUFsQjs7QUFDQTs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQVksVUFBQUEsUUFBUSxFQUFDVCxJQUFUO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0JHLFVBQUFBLFlBQVksQ0FBQ0QsS0FBSyxDQUFDaUIsS0FBTixDQUFZLENBQVosRUFBZUUsV0FBZixDQUFELENBQTlCOztBQUVBLGNBQUlHLElBQUksR0FBRztBQUNUQyxZQUFBQSxRQUFRLEVBQUVsQixhQUREO0FBRVRtQixZQUFBQSxRQUFRLEVBQUdoQixPQUFPLEdBQUdILGFBQVYsR0FBMEJjLFdBRjVCO0FBR1RNLFlBQUFBLFFBQVEsRUFBRW5CLGFBSEQ7QUFJVG9CLFlBQUFBLFFBQVEsRUFBR2pCLE9BQU8sR0FBR0gsYUFBVixHQUEwQmEsV0FKNUI7QUFLVG5CLFlBQUFBLEtBQUssRUFBRU87QUFMRSxXQUFYOztBQU9BLGNBQUlHLENBQUMsSUFBSWQsSUFBSSxDQUFDc0IsTUFBTCxHQUFjLENBQW5CLElBQXdCbEIsS0FBSyxDQUFDa0IsTUFBTixJQUFnQnhCLE9BQU8sQ0FBQ0MsT0FBcEQsRUFBNkQ7QUFDM0Q7QUFDQSxnQkFBSWdDLGFBQWEsR0FBSyxLQUFELENBQVFDLElBQVIsQ0FBYXRDLE1BQWIsQ0FBckI7QUFDQSxnQkFBSXVDLGFBQWEsR0FBSyxLQUFELENBQVFELElBQVIsQ0FBYXJDLE1BQWIsQ0FBckI7QUFDQSxnQkFBSXVDLGNBQWMsR0FBRzlCLEtBQUssQ0FBQ2tCLE1BQU4sSUFBZ0IsQ0FBaEIsSUFBcUJYLFFBQVEsQ0FBQ1csTUFBVCxHQUFrQkksSUFBSSxDQUFDRSxRQUFqRTs7QUFDQSxnQkFBSSxDQUFDRyxhQUFELElBQWtCRyxjQUFsQixJQUFvQ3hDLE1BQU0sQ0FBQzRCLE1BQVAsR0FBZ0IsQ0FBeEQsRUFBMkQ7QUFDekQ7QUFDQTtBQUNBWCxjQUFBQSxRQUFRLENBQUN3QixNQUFULENBQWdCVCxJQUFJLENBQUNFLFFBQXJCLEVBQStCLENBQS9CLEVBQWtDLDhCQUFsQztBQUNEOztBQUNELGdCQUFLLENBQUNHLGFBQUQsSUFBa0IsQ0FBQ0csY0FBcEIsSUFBdUMsQ0FBQ0QsYUFBNUMsRUFBMkQ7QUFDekR0QixjQUFBQSxRQUFRLENBQUNULElBQVQsQ0FBYyw4QkFBZDtBQUNEO0FBQ0Y7O0FBQ0RNLFVBQUFBLEtBQUssQ0FBQ04sSUFBTixDQUFXd0IsSUFBWDtBQUVBakIsVUFBQUEsYUFBYSxHQUFHLENBQWhCO0FBQ0FDLFVBQUFBLGFBQWEsR0FBRyxDQUFoQjtBQUNBQyxVQUFBQSxRQUFRLEdBQUcsRUFBWDtBQUNEO0FBQ0Y7O0FBQ0RDLE1BQUFBLE9BQU8sSUFBSVIsS0FBSyxDQUFDa0IsTUFBakI7QUFDQVQsTUFBQUEsT0FBTyxJQUFJVCxLQUFLLENBQUNrQixNQUFqQjtBQUNEO0FBMUZvRzs7QUFrQnZHLE9BQUssSUFBSVIsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR2QsSUFBSSxDQUFDc0IsTUFBekIsRUFBaUNSLENBQUMsRUFBbEMsRUFBc0M7QUFBQTtBQUFBO0FBQUE7QUFBN0JBLElBQUFBLENBQTZCO0FBeUVyQzs7QUFFRCxTQUFPO0FBQ0x0QixJQUFBQSxXQUFXLEVBQUVBLFdBRFI7QUFDcUJDLElBQUFBLFdBQVcsRUFBRUEsV0FEbEM7QUFFTEcsSUFBQUEsU0FBUyxFQUFFQSxTQUZOO0FBRWlCQyxJQUFBQSxTQUFTLEVBQUVBLFNBRjVCO0FBR0xXLElBQUFBLEtBQUssRUFBRUE7QUFIRixHQUFQO0FBS0Q7O0FBRU0sU0FBUzRCLFdBQVQsQ0FBcUJwQyxJQUFyQixFQUEyQjtBQUNoQyxNQUFNcUMsR0FBRyxHQUFHLEVBQVo7O0FBQ0EsTUFBSXJDLElBQUksQ0FBQ1IsV0FBTCxJQUFvQlEsSUFBSSxDQUFDUCxXQUE3QixFQUEwQztBQUN4QzRDLElBQUFBLEdBQUcsQ0FBQ25DLElBQUosQ0FBUyxZQUFZRixJQUFJLENBQUNSLFdBQTFCO0FBQ0Q7O0FBQ0Q2QyxFQUFBQSxHQUFHLENBQUNuQyxJQUFKLENBQVMscUVBQVQ7QUFDQW1DLEVBQUFBLEdBQUcsQ0FBQ25DLElBQUosQ0FBUyxTQUFTRixJQUFJLENBQUNSLFdBQWQsSUFBNkIsT0FBT1EsSUFBSSxDQUFDSixTQUFaLEtBQTBCLFdBQTFCLEdBQXdDLEVBQXhDLEdBQTZDLE9BQU9JLElBQUksQ0FBQ0osU0FBdEYsQ0FBVDtBQUNBeUMsRUFBQUEsR0FBRyxDQUFDbkMsSUFBSixDQUFTLFNBQVNGLElBQUksQ0FBQ1AsV0FBZCxJQUE2QixPQUFPTyxJQUFJLENBQUNILFNBQVosS0FBMEIsV0FBMUIsR0FBd0MsRUFBeEMsR0FBNkMsT0FBT0csSUFBSSxDQUFDSCxTQUF0RixDQUFUOztBQUVBLE9BQUssSUFBSWlCLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdkLElBQUksQ0FBQ1EsS0FBTCxDQUFXYyxNQUEvQixFQUF1Q1IsQ0FBQyxFQUF4QyxFQUE0QztBQUMxQyxRQUFNWSxJQUFJLEdBQUcxQixJQUFJLENBQUNRLEtBQUwsQ0FBV00sQ0FBWCxDQUFiLENBRDBDLENBRTFDO0FBQ0E7QUFDQTs7QUFDQSxRQUFJWSxJQUFJLENBQUNFLFFBQUwsS0FBa0IsQ0FBdEIsRUFBeUI7QUFDdkJGLE1BQUFBLElBQUksQ0FBQ0MsUUFBTCxJQUFpQixDQUFqQjtBQUNEOztBQUNELFFBQUlELElBQUksQ0FBQ0ksUUFBTCxLQUFrQixDQUF0QixFQUF5QjtBQUN2QkosTUFBQUEsSUFBSSxDQUFDRyxRQUFMLElBQWlCLENBQWpCO0FBQ0Q7O0FBQ0RRLElBQUFBLEdBQUcsQ0FBQ25DLElBQUosQ0FDRSxTQUFTd0IsSUFBSSxDQUFDQyxRQUFkLEdBQXlCLEdBQXpCLEdBQStCRCxJQUFJLENBQUNFLFFBQXBDLEdBQ0UsSUFERixHQUNTRixJQUFJLENBQUNHLFFBRGQsR0FDeUIsR0FEekIsR0FDK0JILElBQUksQ0FBQ0ksUUFEcEMsR0FFRSxLQUhKO0FBS0FPLElBQUFBLEdBQUcsQ0FBQ25DLElBQUosQ0FBU29DLEtBQVQsQ0FBZUQsR0FBZixFQUFvQlgsSUFBSSxDQUFDdEIsS0FBekI7QUFDRDs7QUFFRCxTQUFPaUMsR0FBRyxDQUFDRSxJQUFKLENBQVMsSUFBVCxJQUFpQixJQUF4QjtBQUNEOztBQUVNLFNBQVNDLG1CQUFULENBQTZCaEQsV0FBN0IsRUFBMENDLFdBQTFDLEVBQXVEQyxNQUF2RCxFQUErREMsTUFBL0QsRUFBdUVDLFNBQXZFLEVBQWtGQyxTQUFsRixFQUE2RkMsT0FBN0YsRUFBc0c7QUFDM0csU0FBT3NDLFdBQVcsQ0FBQzdDLGVBQWUsQ0FBQ0MsV0FBRCxFQUFjQyxXQUFkLEVBQTJCQyxNQUEzQixFQUFtQ0MsTUFBbkMsRUFBMkNDLFNBQTNDLEVBQXNEQyxTQUF0RCxFQUFpRUMsT0FBakUsQ0FBaEIsQ0FBbEI7QUFDRDs7QUFFTSxTQUFTMkMsV0FBVCxDQUFxQkMsUUFBckIsRUFBK0JoRCxNQUEvQixFQUF1Q0MsTUFBdkMsRUFBK0NDLFNBQS9DLEVBQTBEQyxTQUExRCxFQUFxRUMsT0FBckUsRUFBOEU7QUFDbkYsU0FBTzBDLG1CQUFtQixDQUFDRSxRQUFELEVBQVdBLFFBQVgsRUFBcUJoRCxNQUFyQixFQUE2QkMsTUFBN0IsRUFBcUNDLFNBQXJDLEVBQWdEQyxTQUFoRCxFQUEyREMsT0FBM0QsQ0FBMUI7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7ZGlmZkxpbmVzfSBmcm9tICcuLi9kaWZmL2xpbmUnO1xuXG5leHBvcnQgZnVuY3Rpb24gc3RydWN0dXJlZFBhdGNoKG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZSwgb2xkU3RyLCBuZXdTdHIsIG9sZEhlYWRlciwgbmV3SGVhZGVyLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBpZiAodHlwZW9mIG9wdGlvbnMuY29udGV4dCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBvcHRpb25zLmNvbnRleHQgPSA0O1xuICB9XG5cbiAgY29uc3QgZGlmZiA9IGRpZmZMaW5lcyhvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucyk7XG4gIGRpZmYucHVzaCh7dmFsdWU6ICcnLCBsaW5lczogW119KTsgLy8gQXBwZW5kIGFuIGVtcHR5IHZhbHVlIHRvIG1ha2UgY2xlYW51cCBlYXNpZXJcblxuICBmdW5jdGlvbiBjb250ZXh0TGluZXMobGluZXMpIHtcbiAgICByZXR1cm4gbGluZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7IHJldHVybiAnICcgKyBlbnRyeTsgfSk7XG4gIH1cblxuICBsZXQgaHVua3MgPSBbXTtcbiAgbGV0IG9sZFJhbmdlU3RhcnQgPSAwLCBuZXdSYW5nZVN0YXJ0ID0gMCwgY3VyUmFuZ2UgPSBbXSxcbiAgICAgIG9sZExpbmUgPSAxLCBuZXdMaW5lID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWZmLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY3VycmVudCA9IGRpZmZbaV0sXG4gICAgICAgICAgbGluZXMgPSBjdXJyZW50LmxpbmVzIHx8IGN1cnJlbnQudmFsdWUucmVwbGFjZSgvXFxuJC8sICcnKS5zcGxpdCgnXFxuJyk7XG4gICAgY3VycmVudC5saW5lcyA9IGxpbmVzO1xuXG4gICAgaWYgKGN1cnJlbnQuYWRkZWQgfHwgY3VycmVudC5yZW1vdmVkKSB7XG4gICAgICAvLyBJZiB3ZSBoYXZlIHByZXZpb3VzIGNvbnRleHQsIHN0YXJ0IHdpdGggdGhhdFxuICAgICAgaWYgKCFvbGRSYW5nZVN0YXJ0KSB7XG4gICAgICAgIGNvbnN0IHByZXYgPSBkaWZmW2kgLSAxXTtcbiAgICAgICAgb2xkUmFuZ2VTdGFydCA9IG9sZExpbmU7XG4gICAgICAgIG5ld1JhbmdlU3RhcnQgPSBuZXdMaW5lO1xuXG4gICAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgICAgY3VyUmFuZ2UgPSBvcHRpb25zLmNvbnRleHQgPiAwID8gY29udGV4dExpbmVzKHByZXYubGluZXMuc2xpY2UoLW9wdGlvbnMuY29udGV4dCkpIDogW107XG4gICAgICAgICAgb2xkUmFuZ2VTdGFydCAtPSBjdXJSYW5nZS5sZW5ndGg7XG4gICAgICAgICAgbmV3UmFuZ2VTdGFydCAtPSBjdXJSYW5nZS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT3V0cHV0IG91ciBjaGFuZ2VzXG4gICAgICBjdXJSYW5nZS5wdXNoKC4uLiBsaW5lcy5tYXAoZnVuY3Rpb24oZW50cnkpIHtcbiAgICAgICAgcmV0dXJuIChjdXJyZW50LmFkZGVkID8gJysnIDogJy0nKSArIGVudHJ5O1xuICAgICAgfSkpO1xuXG4gICAgICAvLyBUcmFjayB0aGUgdXBkYXRlZCBmaWxlIHBvc2l0aW9uXG4gICAgICBpZiAoY3VycmVudC5hZGRlZCkge1xuICAgICAgICBuZXdMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9sZExpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZGVudGljYWwgY29udGV4dCBsaW5lcy4gVHJhY2sgbGluZSBjaGFuZ2VzXG4gICAgICBpZiAob2xkUmFuZ2VTdGFydCkge1xuICAgICAgICAvLyBDbG9zZSBvdXQgYW55IGNoYW5nZXMgdGhhdCBoYXZlIGJlZW4gb3V0cHV0IChvciBqb2luIG92ZXJsYXBwaW5nKVxuICAgICAgICBpZiAobGluZXMubGVuZ3RoIDw9IG9wdGlvbnMuY29udGV4dCAqIDIgJiYgaSA8IGRpZmYubGVuZ3RoIC0gMikge1xuICAgICAgICAgIC8vIE92ZXJsYXBwaW5nXG4gICAgICAgICAgY3VyUmFuZ2UucHVzaCguLi4gY29udGV4dExpbmVzKGxpbmVzKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZW5kIHRoZSByYW5nZSBhbmQgb3V0cHV0XG4gICAgICAgICAgbGV0IGNvbnRleHRTaXplID0gTWF0aC5taW4obGluZXMubGVuZ3RoLCBvcHRpb25zLmNvbnRleHQpO1xuICAgICAgICAgIGN1clJhbmdlLnB1c2goLi4uIGNvbnRleHRMaW5lcyhsaW5lcy5zbGljZSgwLCBjb250ZXh0U2l6ZSkpKTtcblxuICAgICAgICAgIGxldCBodW5rID0ge1xuICAgICAgICAgICAgb2xkU3RhcnQ6IG9sZFJhbmdlU3RhcnQsXG4gICAgICAgICAgICBvbGRMaW5lczogKG9sZExpbmUgLSBvbGRSYW5nZVN0YXJ0ICsgY29udGV4dFNpemUpLFxuICAgICAgICAgICAgbmV3U3RhcnQ6IG5ld1JhbmdlU3RhcnQsXG4gICAgICAgICAgICBuZXdMaW5lczogKG5ld0xpbmUgLSBuZXdSYW5nZVN0YXJ0ICsgY29udGV4dFNpemUpLFxuICAgICAgICAgICAgbGluZXM6IGN1clJhbmdlXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAoaSA+PSBkaWZmLmxlbmd0aCAtIDIgJiYgbGluZXMubGVuZ3RoIDw9IG9wdGlvbnMuY29udGV4dCkge1xuICAgICAgICAgICAgLy8gRU9GIGlzIGluc2lkZSB0aGlzIGh1bmtcbiAgICAgICAgICAgIGxldCBvbGRFT0ZOZXdsaW5lID0gKCgvXFxuJC8pLnRlc3Qob2xkU3RyKSk7XG4gICAgICAgICAgICBsZXQgbmV3RU9GTmV3bGluZSA9ICgoL1xcbiQvKS50ZXN0KG5ld1N0cikpO1xuICAgICAgICAgICAgbGV0IG5vTmxCZWZvcmVBZGRzID0gbGluZXMubGVuZ3RoID09IDAgJiYgY3VyUmFuZ2UubGVuZ3RoID4gaHVuay5vbGRMaW5lcztcbiAgICAgICAgICAgIGlmICghb2xkRU9GTmV3bGluZSAmJiBub05sQmVmb3JlQWRkcyAmJiBvbGRTdHIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAvLyBzcGVjaWFsIGNhc2U6IG9sZCBoYXMgbm8gZW9sIGFuZCBubyB0cmFpbGluZyBjb250ZXh0OyBuby1ubCBjYW4gZW5kIHVwIGJlZm9yZSBhZGRzXG4gICAgICAgICAgICAgIC8vIGhvd2V2ZXIsIGlmIHRoZSBvbGQgZmlsZSBpcyBlbXB0eSwgZG8gbm90IG91dHB1dCB0aGUgbm8tbmwgbGluZVxuICAgICAgICAgICAgICBjdXJSYW5nZS5zcGxpY2UoaHVuay5vbGRMaW5lcywgMCwgJ1xcXFwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCghb2xkRU9GTmV3bGluZSAmJiAhbm9ObEJlZm9yZUFkZHMpIHx8ICFuZXdFT0ZOZXdsaW5lKSB7XG4gICAgICAgICAgICAgIGN1clJhbmdlLnB1c2goJ1xcXFwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBodW5rcy5wdXNoKGh1bmspO1xuXG4gICAgICAgICAgb2xkUmFuZ2VTdGFydCA9IDA7XG4gICAgICAgICAgbmV3UmFuZ2VTdGFydCA9IDA7XG4gICAgICAgICAgY3VyUmFuZ2UgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgb2xkTGluZSArPSBsaW5lcy5sZW5ndGg7XG4gICAgICBuZXdMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG9sZEZpbGVOYW1lOiBvbGRGaWxlTmFtZSwgbmV3RmlsZU5hbWU6IG5ld0ZpbGVOYW1lLFxuICAgIG9sZEhlYWRlcjogb2xkSGVhZGVyLCBuZXdIZWFkZXI6IG5ld0hlYWRlcixcbiAgICBodW5rczogaHVua3NcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFBhdGNoKGRpZmYpIHtcbiAgY29uc3QgcmV0ID0gW107XG4gIGlmIChkaWZmLm9sZEZpbGVOYW1lID09IGRpZmYubmV3RmlsZU5hbWUpIHtcbiAgICByZXQucHVzaCgnSW5kZXg6ICcgKyBkaWZmLm9sZEZpbGVOYW1lKTtcbiAgfVxuICByZXQucHVzaCgnPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PScpO1xuICByZXQucHVzaCgnLS0tICcgKyBkaWZmLm9sZEZpbGVOYW1lICsgKHR5cGVvZiBkaWZmLm9sZEhlYWRlciA9PT0gJ3VuZGVmaW5lZCcgPyAnJyA6ICdcXHQnICsgZGlmZi5vbGRIZWFkZXIpKTtcbiAgcmV0LnB1c2goJysrKyAnICsgZGlmZi5uZXdGaWxlTmFtZSArICh0eXBlb2YgZGlmZi5uZXdIZWFkZXIgPT09ICd1bmRlZmluZWQnID8gJycgOiAnXFx0JyArIGRpZmYubmV3SGVhZGVyKSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWZmLmh1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgaHVuayA9IGRpZmYuaHVua3NbaV07XG4gICAgLy8gVW5pZmllZCBEaWZmIEZvcm1hdCBxdWlyazogSWYgdGhlIGNodW5rIHNpemUgaXMgMCxcbiAgICAvLyB0aGUgZmlyc3QgbnVtYmVyIGlzIG9uZSBsb3dlciB0aGFuIG9uZSB3b3VsZCBleHBlY3QuXG4gICAgLy8gaHR0cHM6Ly93d3cuYXJ0aW1hLmNvbS93ZWJsb2dzL3ZpZXdwb3N0LmpzcD90aHJlYWQ9MTY0MjkzXG4gICAgaWYgKGh1bmsub2xkTGluZXMgPT09IDApIHtcbiAgICAgIGh1bmsub2xkU3RhcnQgLT0gMTtcbiAgICB9XG4gICAgaWYgKGh1bmsubmV3TGluZXMgPT09IDApIHtcbiAgICAgIGh1bmsubmV3U3RhcnQgLT0gMTtcbiAgICB9XG4gICAgcmV0LnB1c2goXG4gICAgICAnQEAgLScgKyBodW5rLm9sZFN0YXJ0ICsgJywnICsgaHVuay5vbGRMaW5lc1xuICAgICAgKyAnICsnICsgaHVuay5uZXdTdGFydCArICcsJyArIGh1bmsubmV3TGluZXNcbiAgICAgICsgJyBAQCdcbiAgICApO1xuICAgIHJldC5wdXNoLmFwcGx5KHJldCwgaHVuay5saW5lcyk7XG4gIH1cblxuICByZXR1cm4gcmV0LmpvaW4oJ1xcbicpICsgJ1xcbic7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUd29GaWxlc1BhdGNoKG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZSwgb2xkU3RyLCBuZXdTdHIsIG9sZEhlYWRlciwgbmV3SGVhZGVyLCBvcHRpb25zKSB7XG4gIHJldHVybiBmb3JtYXRQYXRjaChzdHJ1Y3R1cmVkUGF0Y2gob2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBhdGNoKGZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGNyZWF0ZVR3b0ZpbGVzUGF0Y2goZmlsZU5hbWUsIGZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpO1xufVxuIl19 diff --git a/node_modules/diff/lib/patch/merge.js b/node_modules/diff/lib/patch/merge.js deleted file mode 100644 index b46faaaba8e8b..0000000000000 --- a/node_modules/diff/lib/patch/merge.js +++ /dev/null @@ -1,613 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.calcLineCount = calcLineCount; -exports.merge = merge; - -/*istanbul ignore end*/ -var -/*istanbul ignore start*/ -_create = require("./create") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_parse = require("./parse") -/*istanbul ignore end*/ -; - -var -/*istanbul ignore start*/ -_array = require("../util/array") -/*istanbul ignore end*/ -; - -/*istanbul ignore start*/ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } - -function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - -function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - -function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } - -function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } - -function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - -/*istanbul ignore end*/ -function calcLineCount(hunk) { - /*istanbul ignore start*/ - var _calcOldNewLineCount = - /*istanbul ignore end*/ - calcOldNewLineCount(hunk.lines), - oldLines = _calcOldNewLineCount.oldLines, - newLines = _calcOldNewLineCount.newLines; - - if (oldLines !== undefined) { - hunk.oldLines = oldLines; - } else { - delete hunk.oldLines; - } - - if (newLines !== undefined) { - hunk.newLines = newLines; - } else { - delete hunk.newLines; - } -} - -function merge(mine, theirs, base) { - mine = loadPatch(mine, base); - theirs = loadPatch(theirs, base); - var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning. - // Leaving sanity checks on this to the API consumer that may know more about the - // meaning in their own context. - - if (mine.index || theirs.index) { - ret.index = mine.index || theirs.index; - } - - if (mine.newFileName || theirs.newFileName) { - if (!fileNameChanged(mine)) { - // No header or no change in ours, use theirs (and ours if theirs does not exist) - ret.oldFileName = theirs.oldFileName || mine.oldFileName; - ret.newFileName = theirs.newFileName || mine.newFileName; - ret.oldHeader = theirs.oldHeader || mine.oldHeader; - ret.newHeader = theirs.newHeader || mine.newHeader; - } else if (!fileNameChanged(theirs)) { - // No header or no change in theirs, use ours - ret.oldFileName = mine.oldFileName; - ret.newFileName = mine.newFileName; - ret.oldHeader = mine.oldHeader; - ret.newHeader = mine.newHeader; - } else { - // Both changed... figure it out - ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName); - ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName); - ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader); - ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader); - } - } - - ret.hunks = []; - var mineIndex = 0, - theirsIndex = 0, - mineOffset = 0, - theirsOffset = 0; - - while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) { - var mineCurrent = mine.hunks[mineIndex] || { - oldStart: Infinity - }, - theirsCurrent = theirs.hunks[theirsIndex] || { - oldStart: Infinity - }; - - if (hunkBefore(mineCurrent, theirsCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(mineCurrent, mineOffset)); - mineIndex++; - theirsOffset += mineCurrent.newLines - mineCurrent.oldLines; - } else if (hunkBefore(theirsCurrent, mineCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset)); - theirsIndex++; - mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines; - } else { - // Overlap, merge as best we can - var mergedHunk = { - oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart), - oldLines: 0, - newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset), - newLines: 0, - lines: [] - }; - mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines); - theirsIndex++; - mineIndex++; - ret.hunks.push(mergedHunk); - } - } - - return ret; -} - -function loadPatch(param, base) { - if (typeof param === 'string') { - if (/^@@/m.test(param) || /^Index:/m.test(param)) { - return ( - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _parse - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - parsePatch) - /*istanbul ignore end*/ - (param)[0] - ); - } - - if (!base) { - throw new Error('Must provide a base reference or pass in a patch'); - } - - return ( - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _create - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - structuredPatch) - /*istanbul ignore end*/ - (undefined, undefined, base, param) - ); - } - - return param; -} - -function fileNameChanged(patch) { - return patch.newFileName && patch.newFileName !== patch.oldFileName; -} - -function selectField(index, mine, theirs) { - if (mine === theirs) { - return mine; - } else { - index.conflict = true; - return { - mine: mine, - theirs: theirs - }; - } -} - -function hunkBefore(test, check) { - return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart; -} - -function cloneHunk(hunk, offset) { - return { - oldStart: hunk.oldStart, - oldLines: hunk.oldLines, - newStart: hunk.newStart + offset, - newLines: hunk.newLines, - lines: hunk.lines - }; -} - -function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) { - // This will generally result in a conflicted hunk, but there are cases where the context - // is the only overlap where we can successfully merge the content here. - var mine = { - offset: mineOffset, - lines: mineLines, - index: 0 - }, - their = { - offset: theirOffset, - lines: theirLines, - index: 0 - }; // Handle any leading content - - insertLeading(hunk, mine, their); - insertLeading(hunk, their, mine); // Now in the overlap content. Scan through and select the best changes from each. - - while (mine.index < mine.lines.length && their.index < their.lines.length) { - var mineCurrent = mine.lines[mine.index], - theirCurrent = their.lines[their.index]; - - if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) { - // Both modified ... - mutualChange(hunk, mine, their); - } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') { - /*istanbul ignore start*/ - var _hunk$lines; - - /*istanbul ignore end*/ - // Mine inserted - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_hunk$lines = - /*istanbul ignore end*/ - hunk.lines).push.apply( - /*istanbul ignore start*/ - _hunk$lines - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - collectChange(mine))); - } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') { - /*istanbul ignore start*/ - var _hunk$lines2; - - /*istanbul ignore end*/ - // Theirs inserted - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_hunk$lines2 = - /*istanbul ignore end*/ - hunk.lines).push.apply( - /*istanbul ignore start*/ - _hunk$lines2 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - collectChange(their))); - } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') { - // Mine removed or edited - removal(hunk, mine, their); - } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') { - // Their removed or edited - removal(hunk, their, mine, true); - } else if (mineCurrent === theirCurrent) { - // Context identity - hunk.lines.push(mineCurrent); - mine.index++; - their.index++; - } else { - // Context mismatch - conflict(hunk, collectChange(mine), collectChange(their)); - } - } // Now push anything that may be remaining - - - insertTrailing(hunk, mine); - insertTrailing(hunk, their); - calcLineCount(hunk); -} - -function mutualChange(hunk, mine, their) { - var myChanges = collectChange(mine), - theirChanges = collectChange(their); - - if (allRemoves(myChanges) && allRemoves(theirChanges)) { - // Special case for remove changes that are supersets of one another - if ( - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _array - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - arrayStartsWith) - /*istanbul ignore end*/ - (myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) { - /*istanbul ignore start*/ - var _hunk$lines3; - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_hunk$lines3 = - /*istanbul ignore end*/ - hunk.lines).push.apply( - /*istanbul ignore start*/ - _hunk$lines3 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - myChanges)); - - return; - } else if ( - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _array - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - arrayStartsWith) - /*istanbul ignore end*/ - (theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) { - /*istanbul ignore start*/ - var _hunk$lines4; - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_hunk$lines4 = - /*istanbul ignore end*/ - hunk.lines).push.apply( - /*istanbul ignore start*/ - _hunk$lines4 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - theirChanges)); - - return; - } - } else if ( - /*istanbul ignore start*/ - (0, - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - _array - /*istanbul ignore end*/ - . - /*istanbul ignore start*/ - arrayEqual) - /*istanbul ignore end*/ - (myChanges, theirChanges)) { - /*istanbul ignore start*/ - var _hunk$lines5; - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_hunk$lines5 = - /*istanbul ignore end*/ - hunk.lines).push.apply( - /*istanbul ignore start*/ - _hunk$lines5 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - myChanges)); - - return; - } - - conflict(hunk, myChanges, theirChanges); -} - -function removal(hunk, mine, their, swap) { - var myChanges = collectChange(mine), - theirChanges = collectContext(their, myChanges); - - if (theirChanges.merged) { - /*istanbul ignore start*/ - var _hunk$lines6; - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - - /*istanbul ignore end*/ - - /*istanbul ignore start*/ - (_hunk$lines6 = - /*istanbul ignore end*/ - hunk.lines).push.apply( - /*istanbul ignore start*/ - _hunk$lines6 - /*istanbul ignore end*/ - , - /*istanbul ignore start*/ - _toConsumableArray( - /*istanbul ignore end*/ - theirChanges.merged)); - } else { - conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges); - } -} - -function conflict(hunk, mine, their) { - hunk.conflict = true; - hunk.lines.push({ - conflict: true, - mine: mine, - theirs: their - }); -} - -function insertLeading(hunk, insert, their) { - while (insert.offset < their.offset && insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - insert.offset++; - } -} - -function insertTrailing(hunk, insert) { - while (insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - } -} - -function collectChange(state) { - var ret = [], - operation = state.lines[state.index][0]; - - while (state.index < state.lines.length) { - var line = state.lines[state.index]; // Group additions that are immediately after subtractions and treat them as one "atomic" modify change. - - if (operation === '-' && line[0] === '+') { - operation = '+'; - } - - if (operation === line[0]) { - ret.push(line); - state.index++; - } else { - break; - } - } - - return ret; -} - -function collectContext(state, matchChanges) { - var changes = [], - merged = [], - matchIndex = 0, - contextChanges = false, - conflicted = false; - - while (matchIndex < matchChanges.length && state.index < state.lines.length) { - var change = state.lines[state.index], - match = matchChanges[matchIndex]; // Once we've hit our add, then we are done - - if (match[0] === '+') { - break; - } - - contextChanges = contextChanges || change[0] !== ' '; - merged.push(match); - matchIndex++; // Consume any additions in the other block as a conflict to attempt - // to pull in the remaining context after this - - if (change[0] === '+') { - conflicted = true; - - while (change[0] === '+') { - changes.push(change); - change = state.lines[++state.index]; - } - } - - if (match.substr(1) === change.substr(1)) { - changes.push(change); - state.index++; - } else { - conflicted = true; - } - } - - if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) { - conflicted = true; - } - - if (conflicted) { - return changes; - } - - while (matchIndex < matchChanges.length) { - merged.push(matchChanges[matchIndex++]); - } - - return { - merged: merged, - changes: changes - }; -} - -function allRemoves(changes) { - return changes.reduce(function (prev, change) { - return prev && change[0] === '-'; - }, true); -} - -function skipRemoveSuperset(state, removeChanges, delta) { - for (var i = 0; i < delta; i++) { - var changeContent = removeChanges[removeChanges.length - delta + i].substr(1); - - if (state.lines[state.index + i] !== ' ' + changeContent) { - return false; - } - } - - state.index += delta; - return true; -} - -function calcOldNewLineCount(lines) { - var oldLines = 0; - var newLines = 0; - lines.forEach(function (line) { - if (typeof line !== 'string') { - var myCount = calcOldNewLineCount(line.mine); - var theirCount = calcOldNewLineCount(line.theirs); - - if (oldLines !== undefined) { - if (myCount.oldLines === theirCount.oldLines) { - oldLines += myCount.oldLines; - } else { - oldLines = undefined; - } - } - - if (newLines !== undefined) { - if (myCount.newLines === theirCount.newLines) { - newLines += myCount.newLines; - } else { - newLines = undefined; - } - } - } else { - if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) { - newLines++; - } - - if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) { - oldLines++; - } - } - }); - return { - oldLines: oldLines, - newLines: newLines - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wYXRjaC9tZXJnZS5qcyJdLCJuYW1lcyI6WyJjYWxjTGluZUNvdW50IiwiaHVuayIsImNhbGNPbGROZXdMaW5lQ291bnQiLCJsaW5lcyIsIm9sZExpbmVzIiwibmV3TGluZXMiLCJ1bmRlZmluZWQiLCJtZXJnZSIsIm1pbmUiLCJ0aGVpcnMiLCJiYXNlIiwibG9hZFBhdGNoIiwicmV0IiwiaW5kZXgiLCJuZXdGaWxlTmFtZSIsImZpbGVOYW1lQ2hhbmdlZCIsIm9sZEZpbGVOYW1lIiwib2xkSGVhZGVyIiwibmV3SGVhZGVyIiwic2VsZWN0RmllbGQiLCJodW5rcyIsIm1pbmVJbmRleCIsInRoZWlyc0luZGV4IiwibWluZU9mZnNldCIsInRoZWlyc09mZnNldCIsImxlbmd0aCIsIm1pbmVDdXJyZW50Iiwib2xkU3RhcnQiLCJJbmZpbml0eSIsInRoZWlyc0N1cnJlbnQiLCJodW5rQmVmb3JlIiwicHVzaCIsImNsb25lSHVuayIsIm1lcmdlZEh1bmsiLCJNYXRoIiwibWluIiwibmV3U3RhcnQiLCJtZXJnZUxpbmVzIiwicGFyYW0iLCJ0ZXN0IiwicGFyc2VQYXRjaCIsIkVycm9yIiwic3RydWN0dXJlZFBhdGNoIiwicGF0Y2giLCJjb25mbGljdCIsImNoZWNrIiwib2Zmc2V0IiwibWluZUxpbmVzIiwidGhlaXJPZmZzZXQiLCJ0aGVpckxpbmVzIiwidGhlaXIiLCJpbnNlcnRMZWFkaW5nIiwidGhlaXJDdXJyZW50IiwibXV0dWFsQ2hhbmdlIiwiY29sbGVjdENoYW5nZSIsInJlbW92YWwiLCJpbnNlcnRUcmFpbGluZyIsIm15Q2hhbmdlcyIsInRoZWlyQ2hhbmdlcyIsImFsbFJlbW92ZXMiLCJhcnJheVN0YXJ0c1dpdGgiLCJza2lwUmVtb3ZlU3VwZXJzZXQiLCJhcnJheUVxdWFsIiwic3dhcCIsImNvbGxlY3RDb250ZXh0IiwibWVyZ2VkIiwiaW5zZXJ0IiwibGluZSIsInN0YXRlIiwib3BlcmF0aW9uIiwibWF0Y2hDaGFuZ2VzIiwiY2hhbmdlcyIsIm1hdGNoSW5kZXgiLCJjb250ZXh0Q2hhbmdlcyIsImNvbmZsaWN0ZWQiLCJjaGFuZ2UiLCJtYXRjaCIsInN1YnN0ciIsInJlZHVjZSIsInByZXYiLCJyZW1vdmVDaGFuZ2VzIiwiZGVsdGEiLCJpIiwiY2hhbmdlQ29udGVudCIsImZvckVhY2giLCJteUNvdW50IiwidGhlaXJDb3VudCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTs7QUFFQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7QUFFTyxTQUFTQSxhQUFULENBQXVCQyxJQUF2QixFQUE2QjtBQUFBO0FBQUE7QUFBQTtBQUNMQyxFQUFBQSxtQkFBbUIsQ0FBQ0QsSUFBSSxDQUFDRSxLQUFOLENBRGQ7QUFBQSxNQUMzQkMsUUFEMkIsd0JBQzNCQSxRQUQyQjtBQUFBLE1BQ2pCQyxRQURpQix3QkFDakJBLFFBRGlCOztBQUdsQyxNQUFJRCxRQUFRLEtBQUtFLFNBQWpCLEVBQTRCO0FBQzFCTCxJQUFBQSxJQUFJLENBQUNHLFFBQUwsR0FBZ0JBLFFBQWhCO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsV0FBT0gsSUFBSSxDQUFDRyxRQUFaO0FBQ0Q7O0FBRUQsTUFBSUMsUUFBUSxLQUFLQyxTQUFqQixFQUE0QjtBQUMxQkwsSUFBQUEsSUFBSSxDQUFDSSxRQUFMLEdBQWdCQSxRQUFoQjtBQUNELEdBRkQsTUFFTztBQUNMLFdBQU9KLElBQUksQ0FBQ0ksUUFBWjtBQUNEO0FBQ0Y7O0FBRU0sU0FBU0UsS0FBVCxDQUFlQyxJQUFmLEVBQXFCQyxNQUFyQixFQUE2QkMsSUFBN0IsRUFBbUM7QUFDeENGLEVBQUFBLElBQUksR0FBR0csU0FBUyxDQUFDSCxJQUFELEVBQU9FLElBQVAsQ0FBaEI7QUFDQUQsRUFBQUEsTUFBTSxHQUFHRSxTQUFTLENBQUNGLE1BQUQsRUFBU0MsSUFBVCxDQUFsQjtBQUVBLE1BQUlFLEdBQUcsR0FBRyxFQUFWLENBSndDLENBTXhDO0FBQ0E7QUFDQTs7QUFDQSxNQUFJSixJQUFJLENBQUNLLEtBQUwsSUFBY0osTUFBTSxDQUFDSSxLQUF6QixFQUFnQztBQUM5QkQsSUFBQUEsR0FBRyxDQUFDQyxLQUFKLEdBQVlMLElBQUksQ0FBQ0ssS0FBTCxJQUFjSixNQUFNLENBQUNJLEtBQWpDO0FBQ0Q7O0FBRUQsTUFBSUwsSUFBSSxDQUFDTSxXQUFMLElBQW9CTCxNQUFNLENBQUNLLFdBQS9CLEVBQTRDO0FBQzFDLFFBQUksQ0FBQ0MsZUFBZSxDQUFDUCxJQUFELENBQXBCLEVBQTRCO0FBQzFCO0FBQ0FJLE1BQUFBLEdBQUcsQ0FBQ0ksV0FBSixHQUFrQlAsTUFBTSxDQUFDTyxXQUFQLElBQXNCUixJQUFJLENBQUNRLFdBQTdDO0FBQ0FKLE1BQUFBLEdBQUcsQ0FBQ0UsV0FBSixHQUFrQkwsTUFBTSxDQUFDSyxXQUFQLElBQXNCTixJQUFJLENBQUNNLFdBQTdDO0FBQ0FGLE1BQUFBLEdBQUcsQ0FBQ0ssU0FBSixHQUFnQlIsTUFBTSxDQUFDUSxTQUFQLElBQW9CVCxJQUFJLENBQUNTLFNBQXpDO0FBQ0FMLE1BQUFBLEdBQUcsQ0FBQ00sU0FBSixHQUFnQlQsTUFBTSxDQUFDUyxTQUFQLElBQW9CVixJQUFJLENBQUNVLFNBQXpDO0FBQ0QsS0FORCxNQU1PLElBQUksQ0FBQ0gsZUFBZSxDQUFDTixNQUFELENBQXBCLEVBQThCO0FBQ25DO0FBQ0FHLE1BQUFBLEdBQUcsQ0FBQ0ksV0FBSixHQUFrQlIsSUFBSSxDQUFDUSxXQUF2QjtBQUNBSixNQUFBQSxHQUFHLENBQUNFLFdBQUosR0FBa0JOLElBQUksQ0FBQ00sV0FBdkI7QUFDQUYsTUFBQUEsR0FBRyxDQUFDSyxTQUFKLEdBQWdCVCxJQUFJLENBQUNTLFNBQXJCO0FBQ0FMLE1BQUFBLEdBQUcsQ0FBQ00sU0FBSixHQUFnQlYsSUFBSSxDQUFDVSxTQUFyQjtBQUNELEtBTk0sTUFNQTtBQUNMO0FBQ0FOLE1BQUFBLEdBQUcsQ0FBQ0ksV0FBSixHQUFrQkcsV0FBVyxDQUFDUCxHQUFELEVBQU1KLElBQUksQ0FBQ1EsV0FBWCxFQUF3QlAsTUFBTSxDQUFDTyxXQUEvQixDQUE3QjtBQUNBSixNQUFBQSxHQUFHLENBQUNFLFdBQUosR0FBa0JLLFdBQVcsQ0FBQ1AsR0FBRCxFQUFNSixJQUFJLENBQUNNLFdBQVgsRUFBd0JMLE1BQU0sQ0FBQ0ssV0FBL0IsQ0FBN0I7QUFDQUYsTUFBQUEsR0FBRyxDQUFDSyxTQUFKLEdBQWdCRSxXQUFXLENBQUNQLEdBQUQsRUFBTUosSUFBSSxDQUFDUyxTQUFYLEVBQXNCUixNQUFNLENBQUNRLFNBQTdCLENBQTNCO0FBQ0FMLE1BQUFBLEdBQUcsQ0FBQ00sU0FBSixHQUFnQkMsV0FBVyxDQUFDUCxHQUFELEVBQU1KLElBQUksQ0FBQ1UsU0FBWCxFQUFzQlQsTUFBTSxDQUFDUyxTQUE3QixDQUEzQjtBQUNEO0FBQ0Y7O0FBRUROLEVBQUFBLEdBQUcsQ0FBQ1EsS0FBSixHQUFZLEVBQVo7QUFFQSxNQUFJQyxTQUFTLEdBQUcsQ0FBaEI7QUFBQSxNQUNJQyxXQUFXLEdBQUcsQ0FEbEI7QUFBQSxNQUVJQyxVQUFVLEdBQUcsQ0FGakI7QUFBQSxNQUdJQyxZQUFZLEdBQUcsQ0FIbkI7O0FBS0EsU0FBT0gsU0FBUyxHQUFHYixJQUFJLENBQUNZLEtBQUwsQ0FBV0ssTUFBdkIsSUFBaUNILFdBQVcsR0FBR2IsTUFBTSxDQUFDVyxLQUFQLENBQWFLLE1BQW5FLEVBQTJFO0FBQ3pFLFFBQUlDLFdBQVcsR0FBR2xCLElBQUksQ0FBQ1ksS0FBTCxDQUFXQyxTQUFYLEtBQXlCO0FBQUNNLE1BQUFBLFFBQVEsRUFBRUM7QUFBWCxLQUEzQztBQUFBLFFBQ0lDLGFBQWEsR0FBR3BCLE1BQU0sQ0FBQ1csS0FBUCxDQUFhRSxXQUFiLEtBQTZCO0FBQUNLLE1BQUFBLFFBQVEsRUFBRUM7QUFBWCxLQURqRDs7QUFHQSxRQUFJRSxVQUFVLENBQUNKLFdBQUQsRUFBY0csYUFBZCxDQUFkLEVBQTRDO0FBQzFDO0FBQ0FqQixNQUFBQSxHQUFHLENBQUNRLEtBQUosQ0FBVVcsSUFBVixDQUFlQyxTQUFTLENBQUNOLFdBQUQsRUFBY0gsVUFBZCxDQUF4QjtBQUNBRixNQUFBQSxTQUFTO0FBQ1RHLE1BQUFBLFlBQVksSUFBSUUsV0FBVyxDQUFDckIsUUFBWixHQUF1QnFCLFdBQVcsQ0FBQ3RCLFFBQW5EO0FBQ0QsS0FMRCxNQUtPLElBQUkwQixVQUFVLENBQUNELGFBQUQsRUFBZ0JILFdBQWhCLENBQWQsRUFBNEM7QUFDakQ7QUFDQWQsTUFBQUEsR0FBRyxDQUFDUSxLQUFKLENBQVVXLElBQVYsQ0FBZUMsU0FBUyxDQUFDSCxhQUFELEVBQWdCTCxZQUFoQixDQUF4QjtBQUNBRixNQUFBQSxXQUFXO0FBQ1hDLE1BQUFBLFVBQVUsSUFBSU0sYUFBYSxDQUFDeEIsUUFBZCxHQUF5QndCLGFBQWEsQ0FBQ3pCLFFBQXJEO0FBQ0QsS0FMTSxNQUtBO0FBQ0w7QUFDQSxVQUFJNkIsVUFBVSxHQUFHO0FBQ2ZOLFFBQUFBLFFBQVEsRUFBRU8sSUFBSSxDQUFDQyxHQUFMLENBQVNULFdBQVcsQ0FBQ0MsUUFBckIsRUFBK0JFLGFBQWEsQ0FBQ0YsUUFBN0MsQ0FESztBQUVmdkIsUUFBQUEsUUFBUSxFQUFFLENBRks7QUFHZmdDLFFBQUFBLFFBQVEsRUFBRUYsSUFBSSxDQUFDQyxHQUFMLENBQVNULFdBQVcsQ0FBQ1UsUUFBWixHQUF1QmIsVUFBaEMsRUFBNENNLGFBQWEsQ0FBQ0YsUUFBZCxHQUF5QkgsWUFBckUsQ0FISztBQUlmbkIsUUFBQUEsUUFBUSxFQUFFLENBSks7QUFLZkYsUUFBQUEsS0FBSyxFQUFFO0FBTFEsT0FBakI7QUFPQWtDLE1BQUFBLFVBQVUsQ0FBQ0osVUFBRCxFQUFhUCxXQUFXLENBQUNDLFFBQXpCLEVBQW1DRCxXQUFXLENBQUN2QixLQUEvQyxFQUFzRDBCLGFBQWEsQ0FBQ0YsUUFBcEUsRUFBOEVFLGFBQWEsQ0FBQzFCLEtBQTVGLENBQVY7QUFDQW1CLE1BQUFBLFdBQVc7QUFDWEQsTUFBQUEsU0FBUztBQUVUVCxNQUFBQSxHQUFHLENBQUNRLEtBQUosQ0FBVVcsSUFBVixDQUFlRSxVQUFmO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPckIsR0FBUDtBQUNEOztBQUVELFNBQVNELFNBQVQsQ0FBbUIyQixLQUFuQixFQUEwQjVCLElBQTFCLEVBQWdDO0FBQzlCLE1BQUksT0FBTzRCLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsUUFBSyxNQUFELENBQVNDLElBQVQsQ0FBY0QsS0FBZCxLQUEwQixVQUFELENBQWFDLElBQWIsQ0FBa0JELEtBQWxCLENBQTdCLEVBQXdEO0FBQ3RELGFBQU87QUFBQTtBQUFBO0FBQUE7O0FBQUFFO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUE7QUFBQSxTQUFXRixLQUFYLEVBQWtCLENBQWxCO0FBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUM1QixJQUFMLEVBQVc7QUFDVCxZQUFNLElBQUkrQixLQUFKLENBQVUsa0RBQVYsQ0FBTjtBQUNEOztBQUNELFdBQU87QUFBQTtBQUFBO0FBQUE7O0FBQUFDO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUE7QUFBQSxPQUFnQnBDLFNBQWhCLEVBQTJCQSxTQUEzQixFQUFzQ0ksSUFBdEMsRUFBNEM0QixLQUE1QztBQUFQO0FBQ0Q7O0FBRUQsU0FBT0EsS0FBUDtBQUNEOztBQUVELFNBQVN2QixlQUFULENBQXlCNEIsS0FBekIsRUFBZ0M7QUFDOUIsU0FBT0EsS0FBSyxDQUFDN0IsV0FBTixJQUFxQjZCLEtBQUssQ0FBQzdCLFdBQU4sS0FBc0I2QixLQUFLLENBQUMzQixXQUF4RDtBQUNEOztBQUVELFNBQVNHLFdBQVQsQ0FBcUJOLEtBQXJCLEVBQTRCTCxJQUE1QixFQUFrQ0MsTUFBbEMsRUFBMEM7QUFDeEMsTUFBSUQsSUFBSSxLQUFLQyxNQUFiLEVBQXFCO0FBQ25CLFdBQU9ELElBQVA7QUFDRCxHQUZELE1BRU87QUFDTEssSUFBQUEsS0FBSyxDQUFDK0IsUUFBTixHQUFpQixJQUFqQjtBQUNBLFdBQU87QUFBQ3BDLE1BQUFBLElBQUksRUFBSkEsSUFBRDtBQUFPQyxNQUFBQSxNQUFNLEVBQU5BO0FBQVAsS0FBUDtBQUNEO0FBQ0Y7O0FBRUQsU0FBU3FCLFVBQVQsQ0FBb0JTLElBQXBCLEVBQTBCTSxLQUExQixFQUFpQztBQUMvQixTQUFPTixJQUFJLENBQUNaLFFBQUwsR0FBZ0JrQixLQUFLLENBQUNsQixRQUF0QixJQUNEWSxJQUFJLENBQUNaLFFBQUwsR0FBZ0JZLElBQUksQ0FBQ25DLFFBQXRCLEdBQWtDeUMsS0FBSyxDQUFDbEIsUUFEN0M7QUFFRDs7QUFFRCxTQUFTSyxTQUFULENBQW1CL0IsSUFBbkIsRUFBeUI2QyxNQUF6QixFQUFpQztBQUMvQixTQUFPO0FBQ0xuQixJQUFBQSxRQUFRLEVBQUUxQixJQUFJLENBQUMwQixRQURWO0FBQ29CdkIsSUFBQUEsUUFBUSxFQUFFSCxJQUFJLENBQUNHLFFBRG5DO0FBRUxnQyxJQUFBQSxRQUFRLEVBQUVuQyxJQUFJLENBQUNtQyxRQUFMLEdBQWdCVSxNQUZyQjtBQUU2QnpDLElBQUFBLFFBQVEsRUFBRUosSUFBSSxDQUFDSSxRQUY1QztBQUdMRixJQUFBQSxLQUFLLEVBQUVGLElBQUksQ0FBQ0U7QUFIUCxHQUFQO0FBS0Q7O0FBRUQsU0FBU2tDLFVBQVQsQ0FBb0JwQyxJQUFwQixFQUEwQnNCLFVBQTFCLEVBQXNDd0IsU0FBdEMsRUFBaURDLFdBQWpELEVBQThEQyxVQUE5RCxFQUEwRTtBQUN4RTtBQUNBO0FBQ0EsTUFBSXpDLElBQUksR0FBRztBQUFDc0MsSUFBQUEsTUFBTSxFQUFFdkIsVUFBVDtBQUFxQnBCLElBQUFBLEtBQUssRUFBRTRDLFNBQTVCO0FBQXVDbEMsSUFBQUEsS0FBSyxFQUFFO0FBQTlDLEdBQVg7QUFBQSxNQUNJcUMsS0FBSyxHQUFHO0FBQUNKLElBQUFBLE1BQU0sRUFBRUUsV0FBVDtBQUFzQjdDLElBQUFBLEtBQUssRUFBRThDLFVBQTdCO0FBQXlDcEMsSUFBQUEsS0FBSyxFQUFFO0FBQWhELEdBRFosQ0FId0UsQ0FNeEU7O0FBQ0FzQyxFQUFBQSxhQUFhLENBQUNsRCxJQUFELEVBQU9PLElBQVAsRUFBYTBDLEtBQWIsQ0FBYjtBQUNBQyxFQUFBQSxhQUFhLENBQUNsRCxJQUFELEVBQU9pRCxLQUFQLEVBQWMxQyxJQUFkLENBQWIsQ0FSd0UsQ0FVeEU7O0FBQ0EsU0FBT0EsSUFBSSxDQUFDSyxLQUFMLEdBQWFMLElBQUksQ0FBQ0wsS0FBTCxDQUFXc0IsTUFBeEIsSUFBa0N5QixLQUFLLENBQUNyQyxLQUFOLEdBQWNxQyxLQUFLLENBQUMvQyxLQUFOLENBQVlzQixNQUFuRSxFQUEyRTtBQUN6RSxRQUFJQyxXQUFXLEdBQUdsQixJQUFJLENBQUNMLEtBQUwsQ0FBV0ssSUFBSSxDQUFDSyxLQUFoQixDQUFsQjtBQUFBLFFBQ0l1QyxZQUFZLEdBQUdGLEtBQUssQ0FBQy9DLEtBQU4sQ0FBWStDLEtBQUssQ0FBQ3JDLEtBQWxCLENBRG5COztBQUdBLFFBQUksQ0FBQ2EsV0FBVyxDQUFDLENBQUQsQ0FBWCxLQUFtQixHQUFuQixJQUEwQkEsV0FBVyxDQUFDLENBQUQsQ0FBWCxLQUFtQixHQUE5QyxNQUNJMEIsWUFBWSxDQUFDLENBQUQsQ0FBWixLQUFvQixHQUFwQixJQUEyQkEsWUFBWSxDQUFDLENBQUQsQ0FBWixLQUFvQixHQURuRCxDQUFKLEVBQzZEO0FBQzNEO0FBQ0FDLE1BQUFBLFlBQVksQ0FBQ3BELElBQUQsRUFBT08sSUFBUCxFQUFhMEMsS0FBYixDQUFaO0FBQ0QsS0FKRCxNQUlPLElBQUl4QixXQUFXLENBQUMsQ0FBRCxDQUFYLEtBQW1CLEdBQW5CLElBQTBCMEIsWUFBWSxDQUFDLENBQUQsQ0FBWixLQUFvQixHQUFsRCxFQUF1RDtBQUFBO0FBQUE7O0FBQUE7QUFDNUQ7O0FBQ0E7O0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUFuRCxNQUFBQSxJQUFJLENBQUNFLEtBQUwsRUFBVzRCLElBQVg7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFvQnVCLE1BQUFBLGFBQWEsQ0FBQzlDLElBQUQsQ0FBakM7QUFDRCxLQUhNLE1BR0EsSUFBSTRDLFlBQVksQ0FBQyxDQUFELENBQVosS0FBb0IsR0FBcEIsSUFBMkIxQixXQUFXLENBQUMsQ0FBRCxDQUFYLEtBQW1CLEdBQWxELEVBQXVEO0FBQUE7QUFBQTs7QUFBQTtBQUM1RDs7QUFDQTs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQXpCLE1BQUFBLElBQUksQ0FBQ0UsS0FBTCxFQUFXNEIsSUFBWDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQW9CdUIsTUFBQUEsYUFBYSxDQUFDSixLQUFELENBQWpDO0FBQ0QsS0FITSxNQUdBLElBQUl4QixXQUFXLENBQUMsQ0FBRCxDQUFYLEtBQW1CLEdBQW5CLElBQTBCMEIsWUFBWSxDQUFDLENBQUQsQ0FBWixLQUFvQixHQUFsRCxFQUF1RDtBQUM1RDtBQUNBRyxNQUFBQSxPQUFPLENBQUN0RCxJQUFELEVBQU9PLElBQVAsRUFBYTBDLEtBQWIsQ0FBUDtBQUNELEtBSE0sTUFHQSxJQUFJRSxZQUFZLENBQUMsQ0FBRCxDQUFaLEtBQW9CLEdBQXBCLElBQTJCMUIsV0FBVyxDQUFDLENBQUQsQ0FBWCxLQUFtQixHQUFsRCxFQUF1RDtBQUM1RDtBQUNBNkIsTUFBQUEsT0FBTyxDQUFDdEQsSUFBRCxFQUFPaUQsS0FBUCxFQUFjMUMsSUFBZCxFQUFvQixJQUFwQixDQUFQO0FBQ0QsS0FITSxNQUdBLElBQUlrQixXQUFXLEtBQUswQixZQUFwQixFQUFrQztBQUN2QztBQUNBbkQsTUFBQUEsSUFBSSxDQUFDRSxLQUFMLENBQVc0QixJQUFYLENBQWdCTCxXQUFoQjtBQUNBbEIsTUFBQUEsSUFBSSxDQUFDSyxLQUFMO0FBQ0FxQyxNQUFBQSxLQUFLLENBQUNyQyxLQUFOO0FBQ0QsS0FMTSxNQUtBO0FBQ0w7QUFDQStCLE1BQUFBLFFBQVEsQ0FBQzNDLElBQUQsRUFBT3FELGFBQWEsQ0FBQzlDLElBQUQsQ0FBcEIsRUFBNEI4QyxhQUFhLENBQUNKLEtBQUQsQ0FBekMsQ0FBUjtBQUNEO0FBQ0YsR0F4Q3VFLENBMEN4RTs7O0FBQ0FNLEVBQUFBLGNBQWMsQ0FBQ3ZELElBQUQsRUFBT08sSUFBUCxDQUFkO0FBQ0FnRCxFQUFBQSxjQUFjLENBQUN2RCxJQUFELEVBQU9pRCxLQUFQLENBQWQ7QUFFQWxELEVBQUFBLGFBQWEsQ0FBQ0MsSUFBRCxDQUFiO0FBQ0Q7O0FBRUQsU0FBU29ELFlBQVQsQ0FBc0JwRCxJQUF0QixFQUE0Qk8sSUFBNUIsRUFBa0MwQyxLQUFsQyxFQUF5QztBQUN2QyxNQUFJTyxTQUFTLEdBQUdILGFBQWEsQ0FBQzlDLElBQUQsQ0FBN0I7QUFBQSxNQUNJa0QsWUFBWSxHQUFHSixhQUFhLENBQUNKLEtBQUQsQ0FEaEM7O0FBR0EsTUFBSVMsVUFBVSxDQUFDRixTQUFELENBQVYsSUFBeUJFLFVBQVUsQ0FBQ0QsWUFBRCxDQUF2QyxFQUF1RDtBQUNyRDtBQUNBO0FBQUk7QUFBQTtBQUFBOztBQUFBRTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBQTtBQUFBO0FBQUEsS0FBZ0JILFNBQWhCLEVBQTJCQyxZQUEzQixLQUNHRyxrQkFBa0IsQ0FBQ1gsS0FBRCxFQUFRTyxTQUFSLEVBQW1CQSxTQUFTLENBQUNoQyxNQUFWLEdBQW1CaUMsWUFBWSxDQUFDakMsTUFBbkQsQ0FEekIsRUFDcUY7QUFBQTtBQUFBOztBQUFBOztBQUNuRjs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQXhCLE1BQUFBLElBQUksQ0FBQ0UsS0FBTCxFQUFXNEIsSUFBWDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQW9CMEIsTUFBQUEsU0FBcEI7O0FBQ0E7QUFDRCxLQUpELE1BSU87QUFBSTtBQUFBO0FBQUE7O0FBQUFHO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUE7QUFBQSxLQUFnQkYsWUFBaEIsRUFBOEJELFNBQTlCLEtBQ0pJLGtCQUFrQixDQUFDckQsSUFBRCxFQUFPa0QsWUFBUCxFQUFxQkEsWUFBWSxDQUFDakMsTUFBYixHQUFzQmdDLFNBQVMsQ0FBQ2hDLE1BQXJELENBRGxCLEVBQ2dGO0FBQUE7QUFBQTs7QUFBQTs7QUFDckY7O0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUF4QixNQUFBQSxJQUFJLENBQUNFLEtBQUwsRUFBVzRCLElBQVg7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFvQjJCLE1BQUFBLFlBQXBCOztBQUNBO0FBQ0Q7QUFDRixHQVhELE1BV087QUFBSTtBQUFBO0FBQUE7O0FBQUFJO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUFBO0FBQUE7QUFBQSxHQUFXTCxTQUFYLEVBQXNCQyxZQUF0QixDQUFKLEVBQXlDO0FBQUE7QUFBQTs7QUFBQTs7QUFDOUM7O0FBQUE7O0FBQUE7QUFBQTtBQUFBO0FBQUF6RCxJQUFBQSxJQUFJLENBQUNFLEtBQUwsRUFBVzRCLElBQVg7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFvQjBCLElBQUFBLFNBQXBCOztBQUNBO0FBQ0Q7O0FBRURiLEVBQUFBLFFBQVEsQ0FBQzNDLElBQUQsRUFBT3dELFNBQVAsRUFBa0JDLFlBQWxCLENBQVI7QUFDRDs7QUFFRCxTQUFTSCxPQUFULENBQWlCdEQsSUFBakIsRUFBdUJPLElBQXZCLEVBQTZCMEMsS0FBN0IsRUFBb0NhLElBQXBDLEVBQTBDO0FBQ3hDLE1BQUlOLFNBQVMsR0FBR0gsYUFBYSxDQUFDOUMsSUFBRCxDQUE3QjtBQUFBLE1BQ0lrRCxZQUFZLEdBQUdNLGNBQWMsQ0FBQ2QsS0FBRCxFQUFRTyxTQUFSLENBRGpDOztBQUVBLE1BQUlDLFlBQVksQ0FBQ08sTUFBakIsRUFBeUI7QUFBQTtBQUFBOztBQUFBOztBQUN2Qjs7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQWhFLElBQUFBLElBQUksQ0FBQ0UsS0FBTCxFQUFXNEIsSUFBWDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQW9CMkIsSUFBQUEsWUFBWSxDQUFDTyxNQUFqQztBQUNELEdBRkQsTUFFTztBQUNMckIsSUFBQUEsUUFBUSxDQUFDM0MsSUFBRCxFQUFPOEQsSUFBSSxHQUFHTCxZQUFILEdBQWtCRCxTQUE3QixFQUF3Q00sSUFBSSxHQUFHTixTQUFILEdBQWVDLFlBQTNELENBQVI7QUFDRDtBQUNGOztBQUVELFNBQVNkLFFBQVQsQ0FBa0IzQyxJQUFsQixFQUF3Qk8sSUFBeEIsRUFBOEIwQyxLQUE5QixFQUFxQztBQUNuQ2pELEVBQUFBLElBQUksQ0FBQzJDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQTNDLEVBQUFBLElBQUksQ0FBQ0UsS0FBTCxDQUFXNEIsSUFBWCxDQUFnQjtBQUNkYSxJQUFBQSxRQUFRLEVBQUUsSUFESTtBQUVkcEMsSUFBQUEsSUFBSSxFQUFFQSxJQUZRO0FBR2RDLElBQUFBLE1BQU0sRUFBRXlDO0FBSE0sR0FBaEI7QUFLRDs7QUFFRCxTQUFTQyxhQUFULENBQXVCbEQsSUFBdkIsRUFBNkJpRSxNQUE3QixFQUFxQ2hCLEtBQXJDLEVBQTRDO0FBQzFDLFNBQU9nQixNQUFNLENBQUNwQixNQUFQLEdBQWdCSSxLQUFLLENBQUNKLE1BQXRCLElBQWdDb0IsTUFBTSxDQUFDckQsS0FBUCxHQUFlcUQsTUFBTSxDQUFDL0QsS0FBUCxDQUFhc0IsTUFBbkUsRUFBMkU7QUFDekUsUUFBSTBDLElBQUksR0FBR0QsTUFBTSxDQUFDL0QsS0FBUCxDQUFhK0QsTUFBTSxDQUFDckQsS0FBUCxFQUFiLENBQVg7QUFDQVosSUFBQUEsSUFBSSxDQUFDRSxLQUFMLENBQVc0QixJQUFYLENBQWdCb0MsSUFBaEI7QUFDQUQsSUFBQUEsTUFBTSxDQUFDcEIsTUFBUDtBQUNEO0FBQ0Y7O0FBQ0QsU0FBU1UsY0FBVCxDQUF3QnZELElBQXhCLEVBQThCaUUsTUFBOUIsRUFBc0M7QUFDcEMsU0FBT0EsTUFBTSxDQUFDckQsS0FBUCxHQUFlcUQsTUFBTSxDQUFDL0QsS0FBUCxDQUFhc0IsTUFBbkMsRUFBMkM7QUFDekMsUUFBSTBDLElBQUksR0FBR0QsTUFBTSxDQUFDL0QsS0FBUCxDQUFhK0QsTUFBTSxDQUFDckQsS0FBUCxFQUFiLENBQVg7QUFDQVosSUFBQUEsSUFBSSxDQUFDRSxLQUFMLENBQVc0QixJQUFYLENBQWdCb0MsSUFBaEI7QUFDRDtBQUNGOztBQUVELFNBQVNiLGFBQVQsQ0FBdUJjLEtBQXZCLEVBQThCO0FBQzVCLE1BQUl4RCxHQUFHLEdBQUcsRUFBVjtBQUFBLE1BQ0l5RCxTQUFTLEdBQUdELEtBQUssQ0FBQ2pFLEtBQU4sQ0FBWWlFLEtBQUssQ0FBQ3ZELEtBQWxCLEVBQXlCLENBQXpCLENBRGhCOztBQUVBLFNBQU91RCxLQUFLLENBQUN2RCxLQUFOLEdBQWN1RCxLQUFLLENBQUNqRSxLQUFOLENBQVlzQixNQUFqQyxFQUF5QztBQUN2QyxRQUFJMEMsSUFBSSxHQUFHQyxLQUFLLENBQUNqRSxLQUFOLENBQVlpRSxLQUFLLENBQUN2RCxLQUFsQixDQUFYLENBRHVDLENBR3ZDOztBQUNBLFFBQUl3RCxTQUFTLEtBQUssR0FBZCxJQUFxQkYsSUFBSSxDQUFDLENBQUQsQ0FBSixLQUFZLEdBQXJDLEVBQTBDO0FBQ3hDRSxNQUFBQSxTQUFTLEdBQUcsR0FBWjtBQUNEOztBQUVELFFBQUlBLFNBQVMsS0FBS0YsSUFBSSxDQUFDLENBQUQsQ0FBdEIsRUFBMkI7QUFDekJ2RCxNQUFBQSxHQUFHLENBQUNtQixJQUFKLENBQVNvQyxJQUFUO0FBQ0FDLE1BQUFBLEtBQUssQ0FBQ3ZELEtBQU47QUFDRCxLQUhELE1BR087QUFDTDtBQUNEO0FBQ0Y7O0FBRUQsU0FBT0QsR0FBUDtBQUNEOztBQUNELFNBQVNvRCxjQUFULENBQXdCSSxLQUF4QixFQUErQkUsWUFBL0IsRUFBNkM7QUFDM0MsTUFBSUMsT0FBTyxHQUFHLEVBQWQ7QUFBQSxNQUNJTixNQUFNLEdBQUcsRUFEYjtBQUFBLE1BRUlPLFVBQVUsR0FBRyxDQUZqQjtBQUFBLE1BR0lDLGNBQWMsR0FBRyxLQUhyQjtBQUFBLE1BSUlDLFVBQVUsR0FBRyxLQUpqQjs7QUFLQSxTQUFPRixVQUFVLEdBQUdGLFlBQVksQ0FBQzdDLE1BQTFCLElBQ0UyQyxLQUFLLENBQUN2RCxLQUFOLEdBQWN1RCxLQUFLLENBQUNqRSxLQUFOLENBQVlzQixNQURuQyxFQUMyQztBQUN6QyxRQUFJa0QsTUFBTSxHQUFHUCxLQUFLLENBQUNqRSxLQUFOLENBQVlpRSxLQUFLLENBQUN2RCxLQUFsQixDQUFiO0FBQUEsUUFDSStELEtBQUssR0FBR04sWUFBWSxDQUFDRSxVQUFELENBRHhCLENBRHlDLENBSXpDOztBQUNBLFFBQUlJLEtBQUssQ0FBQyxDQUFELENBQUwsS0FBYSxHQUFqQixFQUFzQjtBQUNwQjtBQUNEOztBQUVESCxJQUFBQSxjQUFjLEdBQUdBLGNBQWMsSUFBSUUsTUFBTSxDQUFDLENBQUQsQ0FBTixLQUFjLEdBQWpEO0FBRUFWLElBQUFBLE1BQU0sQ0FBQ2xDLElBQVAsQ0FBWTZDLEtBQVo7QUFDQUosSUFBQUEsVUFBVSxHQVorQixDQWN6QztBQUNBOztBQUNBLFFBQUlHLE1BQU0sQ0FBQyxDQUFELENBQU4sS0FBYyxHQUFsQixFQUF1QjtBQUNyQkQsTUFBQUEsVUFBVSxHQUFHLElBQWI7O0FBRUEsYUFBT0MsTUFBTSxDQUFDLENBQUQsQ0FBTixLQUFjLEdBQXJCLEVBQTBCO0FBQ3hCSixRQUFBQSxPQUFPLENBQUN4QyxJQUFSLENBQWE0QyxNQUFiO0FBQ0FBLFFBQUFBLE1BQU0sR0FBR1AsS0FBSyxDQUFDakUsS0FBTixDQUFZLEVBQUVpRSxLQUFLLENBQUN2RCxLQUFwQixDQUFUO0FBQ0Q7QUFDRjs7QUFFRCxRQUFJK0QsS0FBSyxDQUFDQyxNQUFOLENBQWEsQ0FBYixNQUFvQkYsTUFBTSxDQUFDRSxNQUFQLENBQWMsQ0FBZCxDQUF4QixFQUEwQztBQUN4Q04sTUFBQUEsT0FBTyxDQUFDeEMsSUFBUixDQUFhNEMsTUFBYjtBQUNBUCxNQUFBQSxLQUFLLENBQUN2RCxLQUFOO0FBQ0QsS0FIRCxNQUdPO0FBQ0w2RCxNQUFBQSxVQUFVLEdBQUcsSUFBYjtBQUNEO0FBQ0Y7O0FBRUQsTUFBSSxDQUFDSixZQUFZLENBQUNFLFVBQUQsQ0FBWixJQUE0QixFQUE3QixFQUFpQyxDQUFqQyxNQUF3QyxHQUF4QyxJQUNHQyxjQURQLEVBQ3VCO0FBQ3JCQyxJQUFBQSxVQUFVLEdBQUcsSUFBYjtBQUNEOztBQUVELE1BQUlBLFVBQUosRUFBZ0I7QUFDZCxXQUFPSCxPQUFQO0FBQ0Q7O0FBRUQsU0FBT0MsVUFBVSxHQUFHRixZQUFZLENBQUM3QyxNQUFqQyxFQUF5QztBQUN2Q3dDLElBQUFBLE1BQU0sQ0FBQ2xDLElBQVAsQ0FBWXVDLFlBQVksQ0FBQ0UsVUFBVSxFQUFYLENBQXhCO0FBQ0Q7O0FBRUQsU0FBTztBQUNMUCxJQUFBQSxNQUFNLEVBQU5BLE1BREs7QUFFTE0sSUFBQUEsT0FBTyxFQUFQQTtBQUZLLEdBQVA7QUFJRDs7QUFFRCxTQUFTWixVQUFULENBQW9CWSxPQUFwQixFQUE2QjtBQUMzQixTQUFPQSxPQUFPLENBQUNPLE1BQVIsQ0FBZSxVQUFTQyxJQUFULEVBQWVKLE1BQWYsRUFBdUI7QUFDM0MsV0FBT0ksSUFBSSxJQUFJSixNQUFNLENBQUMsQ0FBRCxDQUFOLEtBQWMsR0FBN0I7QUFDRCxHQUZNLEVBRUosSUFGSSxDQUFQO0FBR0Q7O0FBQ0QsU0FBU2Qsa0JBQVQsQ0FBNEJPLEtBQTVCLEVBQW1DWSxhQUFuQyxFQUFrREMsS0FBbEQsRUFBeUQ7QUFDdkQsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHRCxLQUFwQixFQUEyQkMsQ0FBQyxFQUE1QixFQUFnQztBQUM5QixRQUFJQyxhQUFhLEdBQUdILGFBQWEsQ0FBQ0EsYUFBYSxDQUFDdkQsTUFBZCxHQUF1QndELEtBQXZCLEdBQStCQyxDQUFoQyxDQUFiLENBQWdETCxNQUFoRCxDQUF1RCxDQUF2RCxDQUFwQjs7QUFDQSxRQUFJVCxLQUFLLENBQUNqRSxLQUFOLENBQVlpRSxLQUFLLENBQUN2RCxLQUFOLEdBQWNxRSxDQUExQixNQUFpQyxNQUFNQyxhQUEzQyxFQUEwRDtBQUN4RCxhQUFPLEtBQVA7QUFDRDtBQUNGOztBQUVEZixFQUFBQSxLQUFLLENBQUN2RCxLQUFOLElBQWVvRSxLQUFmO0FBQ0EsU0FBTyxJQUFQO0FBQ0Q7O0FBRUQsU0FBUy9FLG1CQUFULENBQTZCQyxLQUE3QixFQUFvQztBQUNsQyxNQUFJQyxRQUFRLEdBQUcsQ0FBZjtBQUNBLE1BQUlDLFFBQVEsR0FBRyxDQUFmO0FBRUFGLEVBQUFBLEtBQUssQ0FBQ2lGLE9BQU4sQ0FBYyxVQUFTakIsSUFBVCxFQUFlO0FBQzNCLFFBQUksT0FBT0EsSUFBUCxLQUFnQixRQUFwQixFQUE4QjtBQUM1QixVQUFJa0IsT0FBTyxHQUFHbkYsbUJBQW1CLENBQUNpRSxJQUFJLENBQUMzRCxJQUFOLENBQWpDO0FBQ0EsVUFBSThFLFVBQVUsR0FBR3BGLG1CQUFtQixDQUFDaUUsSUFBSSxDQUFDMUQsTUFBTixDQUFwQzs7QUFFQSxVQUFJTCxRQUFRLEtBQUtFLFNBQWpCLEVBQTRCO0FBQzFCLFlBQUkrRSxPQUFPLENBQUNqRixRQUFSLEtBQXFCa0YsVUFBVSxDQUFDbEYsUUFBcEMsRUFBOEM7QUFDNUNBLFVBQUFBLFFBQVEsSUFBSWlGLE9BQU8sQ0FBQ2pGLFFBQXBCO0FBQ0QsU0FGRCxNQUVPO0FBQ0xBLFVBQUFBLFFBQVEsR0FBR0UsU0FBWDtBQUNEO0FBQ0Y7O0FBRUQsVUFBSUQsUUFBUSxLQUFLQyxTQUFqQixFQUE0QjtBQUMxQixZQUFJK0UsT0FBTyxDQUFDaEYsUUFBUixLQUFxQmlGLFVBQVUsQ0FBQ2pGLFFBQXBDLEVBQThDO0FBQzVDQSxVQUFBQSxRQUFRLElBQUlnRixPQUFPLENBQUNoRixRQUFwQjtBQUNELFNBRkQsTUFFTztBQUNMQSxVQUFBQSxRQUFRLEdBQUdDLFNBQVg7QUFDRDtBQUNGO0FBQ0YsS0FuQkQsTUFtQk87QUFDTCxVQUFJRCxRQUFRLEtBQUtDLFNBQWIsS0FBMkI2RCxJQUFJLENBQUMsQ0FBRCxDQUFKLEtBQVksR0FBWixJQUFtQkEsSUFBSSxDQUFDLENBQUQsQ0FBSixLQUFZLEdBQTFELENBQUosRUFBb0U7QUFDbEU5RCxRQUFBQSxRQUFRO0FBQ1Q7O0FBQ0QsVUFBSUQsUUFBUSxLQUFLRSxTQUFiLEtBQTJCNkQsSUFBSSxDQUFDLENBQUQsQ0FBSixLQUFZLEdBQVosSUFBbUJBLElBQUksQ0FBQyxDQUFELENBQUosS0FBWSxHQUExRCxDQUFKLEVBQW9FO0FBQ2xFL0QsUUFBQUEsUUFBUTtBQUNUO0FBQ0Y7QUFDRixHQTVCRDtBQThCQSxTQUFPO0FBQUNBLElBQUFBLFFBQVEsRUFBUkEsUUFBRDtBQUFXQyxJQUFBQSxRQUFRLEVBQVJBO0FBQVgsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtzdHJ1Y3R1cmVkUGF0Y2h9IGZyb20gJy4vY3JlYXRlJztcbmltcG9ydCB7cGFyc2VQYXRjaH0gZnJvbSAnLi9wYXJzZSc7XG5cbmltcG9ydCB7YXJyYXlFcXVhbCwgYXJyYXlTdGFydHNXaXRofSBmcm9tICcuLi91dGlsL2FycmF5JztcblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGNMaW5lQ291bnQoaHVuaykge1xuICBjb25zdCB7b2xkTGluZXMsIG5ld0xpbmVzfSA9IGNhbGNPbGROZXdMaW5lQ291bnQoaHVuay5saW5lcyk7XG5cbiAgaWYgKG9sZExpbmVzICE9PSB1bmRlZmluZWQpIHtcbiAgICBodW5rLm9sZExpbmVzID0gb2xkTGluZXM7XG4gIH0gZWxzZSB7XG4gICAgZGVsZXRlIGh1bmsub2xkTGluZXM7XG4gIH1cblxuICBpZiAobmV3TGluZXMgIT09IHVuZGVmaW5lZCkge1xuICAgIGh1bmsubmV3TGluZXMgPSBuZXdMaW5lcztcbiAgfSBlbHNlIHtcbiAgICBkZWxldGUgaHVuay5uZXdMaW5lcztcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2UobWluZSwgdGhlaXJzLCBiYXNlKSB7XG4gIG1pbmUgPSBsb2FkUGF0Y2gobWluZSwgYmFzZSk7XG4gIHRoZWlycyA9IGxvYWRQYXRjaCh0aGVpcnMsIGJhc2UpO1xuXG4gIGxldCByZXQgPSB7fTtcblxuICAvLyBGb3IgaW5kZXggd2UganVzdCBsZXQgaXQgcGFzcyB0aHJvdWdoIGFzIGl0IGRvZXNuJ3QgaGF2ZSBhbnkgbmVjZXNzYXJ5IG1lYW5pbmcuXG4gIC8vIExlYXZpbmcgc2FuaXR5IGNoZWNrcyBvbiB0aGlzIHRvIHRoZSBBUEkgY29uc3VtZXIgdGhhdCBtYXkga25vdyBtb3JlIGFib3V0IHRoZVxuICAvLyBtZWFuaW5nIGluIHRoZWlyIG93biBjb250ZXh0LlxuICBpZiAobWluZS5pbmRleCB8fCB0aGVpcnMuaW5kZXgpIHtcbiAgICByZXQuaW5kZXggPSBtaW5lLmluZGV4IHx8IHRoZWlycy5pbmRleDtcbiAgfVxuXG4gIGlmIChtaW5lLm5ld0ZpbGVOYW1lIHx8IHRoZWlycy5uZXdGaWxlTmFtZSkge1xuICAgIGlmICghZmlsZU5hbWVDaGFuZ2VkKG1pbmUpKSB7XG4gICAgICAvLyBObyBoZWFkZXIgb3Igbm8gY2hhbmdlIGluIG91cnMsIHVzZSB0aGVpcnMgKGFuZCBvdXJzIGlmIHRoZWlycyBkb2VzIG5vdCBleGlzdClcbiAgICAgIHJldC5vbGRGaWxlTmFtZSA9IHRoZWlycy5vbGRGaWxlTmFtZSB8fCBtaW5lLm9sZEZpbGVOYW1lO1xuICAgICAgcmV0Lm5ld0ZpbGVOYW1lID0gdGhlaXJzLm5ld0ZpbGVOYW1lIHx8IG1pbmUubmV3RmlsZU5hbWU7XG4gICAgICByZXQub2xkSGVhZGVyID0gdGhlaXJzLm9sZEhlYWRlciB8fCBtaW5lLm9sZEhlYWRlcjtcbiAgICAgIHJldC5uZXdIZWFkZXIgPSB0aGVpcnMubmV3SGVhZGVyIHx8IG1pbmUubmV3SGVhZGVyO1xuICAgIH0gZWxzZSBpZiAoIWZpbGVOYW1lQ2hhbmdlZCh0aGVpcnMpKSB7XG4gICAgICAvLyBObyBoZWFkZXIgb3Igbm8gY2hhbmdlIGluIHRoZWlycywgdXNlIG91cnNcbiAgICAgIHJldC5vbGRGaWxlTmFtZSA9IG1pbmUub2xkRmlsZU5hbWU7XG4gICAgICByZXQubmV3RmlsZU5hbWUgPSBtaW5lLm5ld0ZpbGVOYW1lO1xuICAgICAgcmV0Lm9sZEhlYWRlciA9IG1pbmUub2xkSGVhZGVyO1xuICAgICAgcmV0Lm5ld0hlYWRlciA9IG1pbmUubmV3SGVhZGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBCb3RoIGNoYW5nZWQuLi4gZmlndXJlIGl0IG91dFxuICAgICAgcmV0Lm9sZEZpbGVOYW1lID0gc2VsZWN0RmllbGQocmV0LCBtaW5lLm9sZEZpbGVOYW1lLCB0aGVpcnMub2xkRmlsZU5hbWUpO1xuICAgICAgcmV0Lm5ld0ZpbGVOYW1lID0gc2VsZWN0RmllbGQocmV0LCBtaW5lLm5ld0ZpbGVOYW1lLCB0aGVpcnMubmV3RmlsZU5hbWUpO1xuICAgICAgcmV0Lm9sZEhlYWRlciA9IHNlbGVjdEZpZWxkKHJldCwgbWluZS5vbGRIZWFkZXIsIHRoZWlycy5vbGRIZWFkZXIpO1xuICAgICAgcmV0Lm5ld0hlYWRlciA9IHNlbGVjdEZpZWxkKHJldCwgbWluZS5uZXdIZWFkZXIsIHRoZWlycy5uZXdIZWFkZXIpO1xuICAgIH1cbiAgfVxuXG4gIHJldC5odW5rcyA9IFtdO1xuXG4gIGxldCBtaW5lSW5kZXggPSAwLFxuICAgICAgdGhlaXJzSW5kZXggPSAwLFxuICAgICAgbWluZU9mZnNldCA9IDAsXG4gICAgICB0aGVpcnNPZmZzZXQgPSAwO1xuXG4gIHdoaWxlIChtaW5lSW5kZXggPCBtaW5lLmh1bmtzLmxlbmd0aCB8fCB0aGVpcnNJbmRleCA8IHRoZWlycy5odW5rcy5sZW5ndGgpIHtcbiAgICBsZXQgbWluZUN1cnJlbnQgPSBtaW5lLmh1bmtzW21pbmVJbmRleF0gfHwge29sZFN0YXJ0OiBJbmZpbml0eX0sXG4gICAgICAgIHRoZWlyc0N1cnJlbnQgPSB0aGVpcnMuaHVua3NbdGhlaXJzSW5kZXhdIHx8IHtvbGRTdGFydDogSW5maW5pdHl9O1xuXG4gICAgaWYgKGh1bmtCZWZvcmUobWluZUN1cnJlbnQsIHRoZWlyc0N1cnJlbnQpKSB7XG4gICAgICAvLyBUaGlzIHBhdGNoIGRvZXMgbm90IG92ZXJsYXAgd2l0aCBhbnkgb2YgdGhlIG90aGVycywgeWF5LlxuICAgICAgcmV0Lmh1bmtzLnB1c2goY2xvbmVIdW5rKG1pbmVDdXJyZW50LCBtaW5lT2Zmc2V0KSk7XG4gICAgICBtaW5lSW5kZXgrKztcbiAgICAgIHRoZWlyc09mZnNldCArPSBtaW5lQ3VycmVudC5uZXdMaW5lcyAtIG1pbmVDdXJyZW50Lm9sZExpbmVzO1xuICAgIH0gZWxzZSBpZiAoaHVua0JlZm9yZSh0aGVpcnNDdXJyZW50LCBtaW5lQ3VycmVudCkpIHtcbiAgICAgIC8vIFRoaXMgcGF0Y2ggZG9lcyBub3Qgb3ZlcmxhcCB3aXRoIGFueSBvZiB0aGUgb3RoZXJzLCB5YXkuXG4gICAgICByZXQuaHVua3MucHVzaChjbG9uZUh1bmsodGhlaXJzQ3VycmVudCwgdGhlaXJzT2Zmc2V0KSk7XG4gICAgICB0aGVpcnNJbmRleCsrO1xuICAgICAgbWluZU9mZnNldCArPSB0aGVpcnNDdXJyZW50Lm5ld0xpbmVzIC0gdGhlaXJzQ3VycmVudC5vbGRMaW5lcztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gT3ZlcmxhcCwgbWVyZ2UgYXMgYmVzdCB3ZSBjYW5cbiAgICAgIGxldCBtZXJnZWRIdW5rID0ge1xuICAgICAgICBvbGRTdGFydDogTWF0aC5taW4obWluZUN1cnJlbnQub2xkU3RhcnQsIHRoZWlyc0N1cnJlbnQub2xkU3RhcnQpLFxuICAgICAgICBvbGRMaW5lczogMCxcbiAgICAgICAgbmV3U3RhcnQ6IE1hdGgubWluKG1pbmVDdXJyZW50Lm5ld1N0YXJ0ICsgbWluZU9mZnNldCwgdGhlaXJzQ3VycmVudC5vbGRTdGFydCArIHRoZWlyc09mZnNldCksXG4gICAgICAgIG5ld0xpbmVzOiAwLFxuICAgICAgICBsaW5lczogW11cbiAgICAgIH07XG4gICAgICBtZXJnZUxpbmVzKG1lcmdlZEh1bmssIG1pbmVDdXJyZW50Lm9sZFN0YXJ0LCBtaW5lQ3VycmVudC5saW5lcywgdGhlaXJzQ3VycmVudC5vbGRTdGFydCwgdGhlaXJzQ3VycmVudC5saW5lcyk7XG4gICAgICB0aGVpcnNJbmRleCsrO1xuICAgICAgbWluZUluZGV4Kys7XG5cbiAgICAgIHJldC5odW5rcy5wdXNoKG1lcmdlZEh1bmspO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGxvYWRQYXRjaChwYXJhbSwgYmFzZSkge1xuICBpZiAodHlwZW9mIHBhcmFtID09PSAnc3RyaW5nJykge1xuICAgIGlmICgoL15AQC9tKS50ZXN0KHBhcmFtKSB8fCAoKC9eSW5kZXg6L20pLnRlc3QocGFyYW0pKSkge1xuICAgICAgcmV0dXJuIHBhcnNlUGF0Y2gocGFyYW0pWzBdO1xuICAgIH1cblxuICAgIGlmICghYmFzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdXN0IHByb3ZpZGUgYSBiYXNlIHJlZmVyZW5jZSBvciBwYXNzIGluIGEgcGF0Y2gnKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cnVjdHVyZWRQYXRjaCh1bmRlZmluZWQsIHVuZGVmaW5lZCwgYmFzZSwgcGFyYW0pO1xuICB9XG5cbiAgcmV0dXJuIHBhcmFtO1xufVxuXG5mdW5jdGlvbiBmaWxlTmFtZUNoYW5nZWQocGF0Y2gpIHtcbiAgcmV0dXJuIHBhdGNoLm5ld0ZpbGVOYW1lICYmIHBhdGNoLm5ld0ZpbGVOYW1lICE9PSBwYXRjaC5vbGRGaWxlTmFtZTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0RmllbGQoaW5kZXgsIG1pbmUsIHRoZWlycykge1xuICBpZiAobWluZSA9PT0gdGhlaXJzKSB7XG4gICAgcmV0dXJuIG1pbmU7XG4gIH0gZWxzZSB7XG4gICAgaW5kZXguY29uZmxpY3QgPSB0cnVlO1xuICAgIHJldHVybiB7bWluZSwgdGhlaXJzfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBodW5rQmVmb3JlKHRlc3QsIGNoZWNrKSB7XG4gIHJldHVybiB0ZXN0Lm9sZFN0YXJ0IDwgY2hlY2sub2xkU3RhcnRcbiAgICAmJiAodGVzdC5vbGRTdGFydCArIHRlc3Qub2xkTGluZXMpIDwgY2hlY2sub2xkU3RhcnQ7XG59XG5cbmZ1bmN0aW9uIGNsb25lSHVuayhodW5rLCBvZmZzZXQpIHtcbiAgcmV0dXJuIHtcbiAgICBvbGRTdGFydDogaHVuay5vbGRTdGFydCwgb2xkTGluZXM6IGh1bmsub2xkTGluZXMsXG4gICAgbmV3U3RhcnQ6IGh1bmsubmV3U3RhcnQgKyBvZmZzZXQsIG5ld0xpbmVzOiBodW5rLm5ld0xpbmVzLFxuICAgIGxpbmVzOiBodW5rLmxpbmVzXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1lcmdlTGluZXMoaHVuaywgbWluZU9mZnNldCwgbWluZUxpbmVzLCB0aGVpck9mZnNldCwgdGhlaXJMaW5lcykge1xuICAvLyBUaGlzIHdpbGwgZ2VuZXJhbGx5IHJlc3VsdCBpbiBhIGNvbmZsaWN0ZWQgaHVuaywgYnV0IHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGUgY29udGV4dFxuICAvLyBpcyB0aGUgb25seSBvdmVybGFwIHdoZXJlIHdlIGNhbiBzdWNjZXNzZnVsbHkgbWVyZ2UgdGhlIGNvbnRlbnQgaGVyZS5cbiAgbGV0IG1pbmUgPSB7b2Zmc2V0OiBtaW5lT2Zmc2V0LCBsaW5lczogbWluZUxpbmVzLCBpbmRleDogMH0sXG4gICAgICB0aGVpciA9IHtvZmZzZXQ6IHRoZWlyT2Zmc2V0LCBsaW5lczogdGhlaXJMaW5lcywgaW5kZXg6IDB9O1xuXG4gIC8vIEhhbmRsZSBhbnkgbGVhZGluZyBjb250ZW50XG4gIGluc2VydExlYWRpbmcoaHVuaywgbWluZSwgdGhlaXIpO1xuICBpbnNlcnRMZWFkaW5nKGh1bmssIHRoZWlyLCBtaW5lKTtcblxuICAvLyBOb3cgaW4gdGhlIG92ZXJsYXAgY29udGVudC4gU2NhbiB0aHJvdWdoIGFuZCBzZWxlY3QgdGhlIGJlc3QgY2hhbmdlcyBmcm9tIGVhY2guXG4gIHdoaWxlIChtaW5lLmluZGV4IDwgbWluZS5saW5lcy5sZW5ndGggJiYgdGhlaXIuaW5kZXggPCB0aGVpci5saW5lcy5sZW5ndGgpIHtcbiAgICBsZXQgbWluZUN1cnJlbnQgPSBtaW5lLmxpbmVzW21pbmUuaW5kZXhdLFxuICAgICAgICB0aGVpckN1cnJlbnQgPSB0aGVpci5saW5lc1t0aGVpci5pbmRleF07XG5cbiAgICBpZiAoKG1pbmVDdXJyZW50WzBdID09PSAnLScgfHwgbWluZUN1cnJlbnRbMF0gPT09ICcrJylcbiAgICAgICAgJiYgKHRoZWlyQ3VycmVudFswXSA9PT0gJy0nIHx8IHRoZWlyQ3VycmVudFswXSA9PT0gJysnKSkge1xuICAgICAgLy8gQm90aCBtb2RpZmllZCAuLi5cbiAgICAgIG11dHVhbENoYW5nZShodW5rLCBtaW5lLCB0aGVpcik7XG4gICAgfSBlbHNlIGlmIChtaW5lQ3VycmVudFswXSA9PT0gJysnICYmIHRoZWlyQ3VycmVudFswXSA9PT0gJyAnKSB7XG4gICAgICAvLyBNaW5lIGluc2VydGVkXG4gICAgICBodW5rLmxpbmVzLnB1c2goLi4uIGNvbGxlY3RDaGFuZ2UobWluZSkpO1xuICAgIH0gZWxzZSBpZiAodGhlaXJDdXJyZW50WzBdID09PSAnKycgJiYgbWluZUN1cnJlbnRbMF0gPT09ICcgJykge1xuICAgICAgLy8gVGhlaXJzIGluc2VydGVkXG4gICAgICBodW5rLmxpbmVzLnB1c2goLi4uIGNvbGxlY3RDaGFuZ2UodGhlaXIpKTtcbiAgICB9IGVsc2UgaWYgKG1pbmVDdXJyZW50WzBdID09PSAnLScgJiYgdGhlaXJDdXJyZW50WzBdID09PSAnICcpIHtcbiAgICAgIC8vIE1pbmUgcmVtb3ZlZCBvciBlZGl0ZWRcbiAgICAgIHJlbW92YWwoaHVuaywgbWluZSwgdGhlaXIpO1xuICAgIH0gZWxzZSBpZiAodGhlaXJDdXJyZW50WzBdID09PSAnLScgJiYgbWluZUN1cnJlbnRbMF0gPT09ICcgJykge1xuICAgICAgLy8gVGhlaXIgcmVtb3ZlZCBvciBlZGl0ZWRcbiAgICAgIHJlbW92YWwoaHVuaywgdGhlaXIsIG1pbmUsIHRydWUpO1xuICAgIH0gZWxzZSBpZiAobWluZUN1cnJlbnQgPT09IHRoZWlyQ3VycmVudCkge1xuICAgICAgLy8gQ29udGV4dCBpZGVudGl0eVxuICAgICAgaHVuay5saW5lcy5wdXNoKG1pbmVDdXJyZW50KTtcbiAgICAgIG1pbmUuaW5kZXgrKztcbiAgICAgIHRoZWlyLmluZGV4Kys7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENvbnRleHQgbWlzbWF0Y2hcbiAgICAgIGNvbmZsaWN0KGh1bmssIGNvbGxlY3RDaGFuZ2UobWluZSksIGNvbGxlY3RDaGFuZ2UodGhlaXIpKTtcbiAgICB9XG4gIH1cblxuICAvLyBOb3cgcHVzaCBhbnl0aGluZyB0aGF0IG1heSBiZSByZW1haW5pbmdcbiAgaW5zZXJ0VHJhaWxpbmcoaHVuaywgbWluZSk7XG4gIGluc2VydFRyYWlsaW5nKGh1bmssIHRoZWlyKTtcblxuICBjYWxjTGluZUNvdW50KGh1bmspO1xufVxuXG5mdW5jdGlvbiBtdXR1YWxDaGFuZ2UoaHVuaywgbWluZSwgdGhlaXIpIHtcbiAgbGV0IG15Q2hhbmdlcyA9IGNvbGxlY3RDaGFuZ2UobWluZSksXG4gICAgICB0aGVpckNoYW5nZXMgPSBjb2xsZWN0Q2hhbmdlKHRoZWlyKTtcblxuICBpZiAoYWxsUmVtb3ZlcyhteUNoYW5nZXMpICYmIGFsbFJlbW92ZXModGhlaXJDaGFuZ2VzKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgcmVtb3ZlIGNoYW5nZXMgdGhhdCBhcmUgc3VwZXJzZXRzIG9mIG9uZSBhbm90aGVyXG4gICAgaWYgKGFycmF5U3RhcnRzV2l0aChteUNoYW5nZXMsIHRoZWlyQ2hhbmdlcylcbiAgICAgICAgJiYgc2tpcFJlbW92ZVN1cGVyc2V0KHRoZWlyLCBteUNoYW5nZXMsIG15Q2hhbmdlcy5sZW5ndGggLSB0aGVpckNoYW5nZXMubGVuZ3RoKSkge1xuICAgICAgaHVuay5saW5lcy5wdXNoKC4uLiBteUNoYW5nZXMpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoYXJyYXlTdGFydHNXaXRoKHRoZWlyQ2hhbmdlcywgbXlDaGFuZ2VzKVxuICAgICAgICAmJiBza2lwUmVtb3ZlU3VwZXJzZXQobWluZSwgdGhlaXJDaGFuZ2VzLCB0aGVpckNoYW5nZXMubGVuZ3RoIC0gbXlDaGFuZ2VzLmxlbmd0aCkpIHtcbiAgICAgIGh1bmsubGluZXMucHVzaCguLi4gdGhlaXJDaGFuZ2VzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0gZWxzZSBpZiAoYXJyYXlFcXVhbChteUNoYW5nZXMsIHRoZWlyQ2hhbmdlcykpIHtcbiAgICBodW5rLmxpbmVzLnB1c2goLi4uIG15Q2hhbmdlcyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uZmxpY3QoaHVuaywgbXlDaGFuZ2VzLCB0aGVpckNoYW5nZXMpO1xufVxuXG5mdW5jdGlvbiByZW1vdmFsKGh1bmssIG1pbmUsIHRoZWlyLCBzd2FwKSB7XG4gIGxldCBteUNoYW5nZXMgPSBjb2xsZWN0Q2hhbmdlKG1pbmUpLFxuICAgICAgdGhlaXJDaGFuZ2VzID0gY29sbGVjdENvbnRleHQodGhlaXIsIG15Q2hhbmdlcyk7XG4gIGlmICh0aGVpckNoYW5nZXMubWVyZ2VkKSB7XG4gICAgaHVuay5saW5lcy5wdXNoKC4uLiB0aGVpckNoYW5nZXMubWVyZ2VkKTtcbiAgfSBlbHNlIHtcbiAgICBjb25mbGljdChodW5rLCBzd2FwID8gdGhlaXJDaGFuZ2VzIDogbXlDaGFuZ2VzLCBzd2FwID8gbXlDaGFuZ2VzIDogdGhlaXJDaGFuZ2VzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb25mbGljdChodW5rLCBtaW5lLCB0aGVpcikge1xuICBodW5rLmNvbmZsaWN0ID0gdHJ1ZTtcbiAgaHVuay5saW5lcy5wdXNoKHtcbiAgICBjb25mbGljdDogdHJ1ZSxcbiAgICBtaW5lOiBtaW5lLFxuICAgIHRoZWlyczogdGhlaXJcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGluc2VydExlYWRpbmcoaHVuaywgaW5zZXJ0LCB0aGVpcikge1xuICB3aGlsZSAoaW5zZXJ0Lm9mZnNldCA8IHRoZWlyLm9mZnNldCAmJiBpbnNlcnQuaW5kZXggPCBpbnNlcnQubGluZXMubGVuZ3RoKSB7XG4gICAgbGV0IGxpbmUgPSBpbnNlcnQubGluZXNbaW5zZXJ0LmluZGV4KytdO1xuICAgIGh1bmsubGluZXMucHVzaChsaW5lKTtcbiAgICBpbnNlcnQub2Zmc2V0Kys7XG4gIH1cbn1cbmZ1bmN0aW9uIGluc2VydFRyYWlsaW5nKGh1bmssIGluc2VydCkge1xuICB3aGlsZSAoaW5zZXJ0LmluZGV4IDwgaW5zZXJ0LmxpbmVzLmxlbmd0aCkge1xuICAgIGxldCBsaW5lID0gaW5zZXJ0LmxpbmVzW2luc2VydC5pbmRleCsrXTtcbiAgICBodW5rLmxpbmVzLnB1c2gobGluZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29sbGVjdENoYW5nZShzdGF0ZSkge1xuICBsZXQgcmV0ID0gW10sXG4gICAgICBvcGVyYXRpb24gPSBzdGF0ZS5saW5lc1tzdGF0ZS5pbmRleF1bMF07XG4gIHdoaWxlIChzdGF0ZS5pbmRleCA8IHN0YXRlLmxpbmVzLmxlbmd0aCkge1xuICAgIGxldCBsaW5lID0gc3RhdGUubGluZXNbc3RhdGUuaW5kZXhdO1xuXG4gICAgLy8gR3JvdXAgYWRkaXRpb25zIHRoYXQgYXJlIGltbWVkaWF0ZWx5IGFmdGVyIHN1YnRyYWN0aW9ucyBhbmQgdHJlYXQgdGhlbSBhcyBvbmUgXCJhdG9taWNcIiBtb2RpZnkgY2hhbmdlLlxuICAgIGlmIChvcGVyYXRpb24gPT09ICctJyAmJiBsaW5lWzBdID09PSAnKycpIHtcbiAgICAgIG9wZXJhdGlvbiA9ICcrJztcbiAgICB9XG5cbiAgICBpZiAob3BlcmF0aW9uID09PSBsaW5lWzBdKSB7XG4gICAgICByZXQucHVzaChsaW5lKTtcbiAgICAgIHN0YXRlLmluZGV4Kys7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5mdW5jdGlvbiBjb2xsZWN0Q29udGV4dChzdGF0ZSwgbWF0Y2hDaGFuZ2VzKSB7XG4gIGxldCBjaGFuZ2VzID0gW10sXG4gICAgICBtZXJnZWQgPSBbXSxcbiAgICAgIG1hdGNoSW5kZXggPSAwLFxuICAgICAgY29udGV4dENoYW5nZXMgPSBmYWxzZSxcbiAgICAgIGNvbmZsaWN0ZWQgPSBmYWxzZTtcbiAgd2hpbGUgKG1hdGNoSW5kZXggPCBtYXRjaENoYW5nZXMubGVuZ3RoXG4gICAgICAgICYmIHN0YXRlLmluZGV4IDwgc3RhdGUubGluZXMubGVuZ3RoKSB7XG4gICAgbGV0IGNoYW5nZSA9IHN0YXRlLmxpbmVzW3N0YXRlLmluZGV4XSxcbiAgICAgICAgbWF0Y2ggPSBtYXRjaENoYW5nZXNbbWF0Y2hJbmRleF07XG5cbiAgICAvLyBPbmNlIHdlJ3ZlIGhpdCBvdXIgYWRkLCB0aGVuIHdlIGFyZSBkb25lXG4gICAgaWYgKG1hdGNoWzBdID09PSAnKycpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGNvbnRleHRDaGFuZ2VzID0gY29udGV4dENoYW5nZXMgfHwgY2hhbmdlWzBdICE9PSAnICc7XG5cbiAgICBtZXJnZWQucHVzaChtYXRjaCk7XG4gICAgbWF0Y2hJbmRleCsrO1xuXG4gICAgLy8gQ29uc3VtZSBhbnkgYWRkaXRpb25zIGluIHRoZSBvdGhlciBibG9jayBhcyBhIGNvbmZsaWN0IHRvIGF0dGVtcHRcbiAgICAvLyB0byBwdWxsIGluIHRoZSByZW1haW5pbmcgY29udGV4dCBhZnRlciB0aGlzXG4gICAgaWYgKGNoYW5nZVswXSA9PT0gJysnKSB7XG4gICAgICBjb25mbGljdGVkID0gdHJ1ZTtcblxuICAgICAgd2hpbGUgKGNoYW5nZVswXSA9PT0gJysnKSB7XG4gICAgICAgIGNoYW5nZXMucHVzaChjaGFuZ2UpO1xuICAgICAgICBjaGFuZ2UgPSBzdGF0ZS5saW5lc1srK3N0YXRlLmluZGV4XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF0Y2guc3Vic3RyKDEpID09PSBjaGFuZ2Uuc3Vic3RyKDEpKSB7XG4gICAgICBjaGFuZ2VzLnB1c2goY2hhbmdlKTtcbiAgICAgIHN0YXRlLmluZGV4Kys7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbmZsaWN0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICgobWF0Y2hDaGFuZ2VzW21hdGNoSW5kZXhdIHx8ICcnKVswXSA9PT0gJysnXG4gICAgICAmJiBjb250ZXh0Q2hhbmdlcykge1xuICAgIGNvbmZsaWN0ZWQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKGNvbmZsaWN0ZWQpIHtcbiAgICByZXR1cm4gY2hhbmdlcztcbiAgfVxuXG4gIHdoaWxlIChtYXRjaEluZGV4IDwgbWF0Y2hDaGFuZ2VzLmxlbmd0aCkge1xuICAgIG1lcmdlZC5wdXNoKG1hdGNoQ2hhbmdlc1ttYXRjaEluZGV4KytdKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbWVyZ2VkLFxuICAgIGNoYW5nZXNcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWxsUmVtb3ZlcyhjaGFuZ2VzKSB7XG4gIHJldHVybiBjaGFuZ2VzLnJlZHVjZShmdW5jdGlvbihwcmV2LCBjaGFuZ2UpIHtcbiAgICByZXR1cm4gcHJldiAmJiBjaGFuZ2VbMF0gPT09ICctJztcbiAgfSwgdHJ1ZSk7XG59XG5mdW5jdGlvbiBza2lwUmVtb3ZlU3VwZXJzZXQoc3RhdGUsIHJlbW92ZUNoYW5nZXMsIGRlbHRhKSB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGVsdGE7IGkrKykge1xuICAgIGxldCBjaGFuZ2VDb250ZW50ID0gcmVtb3ZlQ2hhbmdlc1tyZW1vdmVDaGFuZ2VzLmxlbmd0aCAtIGRlbHRhICsgaV0uc3Vic3RyKDEpO1xuICAgIGlmIChzdGF0ZS5saW5lc1tzdGF0ZS5pbmRleCArIGldICE9PSAnICcgKyBjaGFuZ2VDb250ZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUuaW5kZXggKz0gZGVsdGE7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjYWxjT2xkTmV3TGluZUNvdW50KGxpbmVzKSB7XG4gIGxldCBvbGRMaW5lcyA9IDA7XG4gIGxldCBuZXdMaW5lcyA9IDA7XG5cbiAgbGluZXMuZm9yRWFjaChmdW5jdGlvbihsaW5lKSB7XG4gICAgaWYgKHR5cGVvZiBsaW5lICE9PSAnc3RyaW5nJykge1xuICAgICAgbGV0IG15Q291bnQgPSBjYWxjT2xkTmV3TGluZUNvdW50KGxpbmUubWluZSk7XG4gICAgICBsZXQgdGhlaXJDb3VudCA9IGNhbGNPbGROZXdMaW5lQ291bnQobGluZS50aGVpcnMpO1xuXG4gICAgICBpZiAob2xkTGluZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAobXlDb3VudC5vbGRMaW5lcyA9PT0gdGhlaXJDb3VudC5vbGRMaW5lcykge1xuICAgICAgICAgIG9sZExpbmVzICs9IG15Q291bnQub2xkTGluZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb2xkTGluZXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG5ld0xpbmVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKG15Q291bnQubmV3TGluZXMgPT09IHRoZWlyQ291bnQubmV3TGluZXMpIHtcbiAgICAgICAgICBuZXdMaW5lcyArPSBteUNvdW50Lm5ld0xpbmVzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0xpbmVzID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChuZXdMaW5lcyAhPT0gdW5kZWZpbmVkICYmIChsaW5lWzBdID09PSAnKycgfHwgbGluZVswXSA9PT0gJyAnKSkge1xuICAgICAgICBuZXdMaW5lcysrO1xuICAgICAgfVxuICAgICAgaWYgKG9sZExpbmVzICE9PSB1bmRlZmluZWQgJiYgKGxpbmVbMF0gPT09ICctJyB8fCBsaW5lWzBdID09PSAnICcpKSB7XG4gICAgICAgIG9sZExpbmVzKys7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4ge29sZExpbmVzLCBuZXdMaW5lc307XG59XG4iXX0= diff --git a/node_modules/diff/lib/patch/parse.js b/node_modules/diff/lib/patch/parse.js deleted file mode 100644 index f1501048014f1..0000000000000 --- a/node_modules/diff/lib/patch/parse.js +++ /dev/null @@ -1,167 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.parsePatch = parsePatch; - -/*istanbul ignore end*/ -function parsePatch(uniDiff) { - /*istanbul ignore start*/ - var - /*istanbul ignore end*/ - options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], - list = [], - i = 0; - - function parseIndex() { - var index = {}; - list.push(index); // Parse diff metadata - - while (i < diffstr.length) { - var line = diffstr[i]; // File header found, end parsing diff metadata - - if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { - break; - } // Diff index - - - var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); - - if (header) { - index.index = header[1]; - } - - i++; - } // Parse file headers if they are defined. Unified diff requires them, but - // there's no technical issues to have an isolated hunk without file header - - - parseFileHeader(index); - parseFileHeader(index); // Parse hunks - - index.hunks = []; - - while (i < diffstr.length) { - var _line = diffstr[i]; - - if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { - break; - } else if (/^@@/.test(_line)) { - index.hunks.push(parseHunk()); - } else if (_line && options.strict) { - // Ignore unexpected content unless in strict mode - throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); - } else { - i++; - } - } - } // Parses the --- and +++ headers, if none are found, no lines - // are consumed. - - - function parseFileHeader(index) { - var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]); - - if (fileHeader) { - var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; - var data = fileHeader[2].split('\t', 2); - var fileName = data[0].replace(/\\\\/g, '\\'); - - if (/^".*"$/.test(fileName)) { - fileName = fileName.substr(1, fileName.length - 2); - } - - index[keyPrefix + 'FileName'] = fileName; - index[keyPrefix + 'Header'] = (data[1] || '').trim(); - i++; - } - } // Parses a hunk - // This assumes that we are at the start of a hunk. - - - function parseHunk() { - var chunkHeaderIndex = i, - chunkHeaderLine = diffstr[i++], - chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); - var hunk = { - oldStart: +chunkHeader[1], - oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], - newStart: +chunkHeader[3], - newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], - lines: [], - linedelimiters: [] - }; // Unified Diff Format quirk: If the chunk size is 0, - // the first number is one lower than one would expect. - // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 - - if (hunk.oldLines === 0) { - hunk.oldStart += 1; - } - - if (hunk.newLines === 0) { - hunk.newStart += 1; - } - - var addCount = 0, - removeCount = 0; - - for (; i < diffstr.length; i++) { - // Lines starting with '---' could be mistaken for the "remove line" operation - // But they could be the header for the next file. Therefore prune such cases out. - if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { - break; - } - - var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0]; - - if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { - hunk.lines.push(diffstr[i]); - hunk.linedelimiters.push(delimiters[i] || '\n'); - - if (operation === '+') { - addCount++; - } else if (operation === '-') { - removeCount++; - } else if (operation === ' ') { - addCount++; - removeCount++; - } - } else { - break; - } - } // Handle the empty block count case - - - if (!addCount && hunk.newLines === 1) { - hunk.newLines = 0; - } - - if (!removeCount && hunk.oldLines === 1) { - hunk.oldLines = 0; - } // Perform optional sanity checking - - - if (options.strict) { - if (addCount !== hunk.newLines) { - throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - - if (removeCount !== hunk.oldLines) { - throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - } - - return hunk; - } - - while (i < diffstr.length) { - parseIndex(); - } - - return list; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wYXRjaC9wYXJzZS5qcyJdLCJuYW1lcyI6WyJwYXJzZVBhdGNoIiwidW5pRGlmZiIsIm9wdGlvbnMiLCJkaWZmc3RyIiwic3BsaXQiLCJkZWxpbWl0ZXJzIiwibWF0Y2giLCJsaXN0IiwiaSIsInBhcnNlSW5kZXgiLCJpbmRleCIsInB1c2giLCJsZW5ndGgiLCJsaW5lIiwidGVzdCIsImhlYWRlciIsImV4ZWMiLCJwYXJzZUZpbGVIZWFkZXIiLCJodW5rcyIsInBhcnNlSHVuayIsInN0cmljdCIsIkVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsImZpbGVIZWFkZXIiLCJrZXlQcmVmaXgiLCJkYXRhIiwiZmlsZU5hbWUiLCJyZXBsYWNlIiwic3Vic3RyIiwidHJpbSIsImNodW5rSGVhZGVySW5kZXgiLCJjaHVua0hlYWRlckxpbmUiLCJjaHVua0hlYWRlciIsImh1bmsiLCJvbGRTdGFydCIsIm9sZExpbmVzIiwibmV3U3RhcnQiLCJuZXdMaW5lcyIsImxpbmVzIiwibGluZWRlbGltaXRlcnMiLCJhZGRDb3VudCIsInJlbW92ZUNvdW50IiwiaW5kZXhPZiIsIm9wZXJhdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQU8sU0FBU0EsVUFBVCxDQUFvQkMsT0FBcEIsRUFBMkM7QUFBQTtBQUFBO0FBQUE7QUFBZEMsRUFBQUEsT0FBYyx1RUFBSixFQUFJO0FBQ2hELE1BQUlDLE9BQU8sR0FBR0YsT0FBTyxDQUFDRyxLQUFSLENBQWMscUJBQWQsQ0FBZDtBQUFBLE1BQ0lDLFVBQVUsR0FBR0osT0FBTyxDQUFDSyxLQUFSLENBQWMsc0JBQWQsS0FBeUMsRUFEMUQ7QUFBQSxNQUVJQyxJQUFJLEdBQUcsRUFGWDtBQUFBLE1BR0lDLENBQUMsR0FBRyxDQUhSOztBQUtBLFdBQVNDLFVBQVQsR0FBc0I7QUFDcEIsUUFBSUMsS0FBSyxHQUFHLEVBQVo7QUFDQUgsSUFBQUEsSUFBSSxDQUFDSSxJQUFMLENBQVVELEtBQVYsRUFGb0IsQ0FJcEI7O0FBQ0EsV0FBT0YsQ0FBQyxHQUFHTCxPQUFPLENBQUNTLE1BQW5CLEVBQTJCO0FBQ3pCLFVBQUlDLElBQUksR0FBR1YsT0FBTyxDQUFDSyxDQUFELENBQWxCLENBRHlCLENBR3pCOztBQUNBLFVBQUssdUJBQUQsQ0FBMEJNLElBQTFCLENBQStCRCxJQUEvQixDQUFKLEVBQTBDO0FBQ3hDO0FBQ0QsT0FOd0IsQ0FRekI7OztBQUNBLFVBQUlFLE1BQU0sR0FBSSwwQ0FBRCxDQUE2Q0MsSUFBN0MsQ0FBa0RILElBQWxELENBQWI7O0FBQ0EsVUFBSUUsTUFBSixFQUFZO0FBQ1ZMLFFBQUFBLEtBQUssQ0FBQ0EsS0FBTixHQUFjSyxNQUFNLENBQUMsQ0FBRCxDQUFwQjtBQUNEOztBQUVEUCxNQUFBQSxDQUFDO0FBQ0YsS0FwQm1CLENBc0JwQjtBQUNBOzs7QUFDQVMsSUFBQUEsZUFBZSxDQUFDUCxLQUFELENBQWY7QUFDQU8sSUFBQUEsZUFBZSxDQUFDUCxLQUFELENBQWYsQ0F6Qm9CLENBMkJwQjs7QUFDQUEsSUFBQUEsS0FBSyxDQUFDUSxLQUFOLEdBQWMsRUFBZDs7QUFFQSxXQUFPVixDQUFDLEdBQUdMLE9BQU8sQ0FBQ1MsTUFBbkIsRUFBMkI7QUFDekIsVUFBSUMsS0FBSSxHQUFHVixPQUFPLENBQUNLLENBQUQsQ0FBbEI7O0FBRUEsVUFBSyxnQ0FBRCxDQUFtQ00sSUFBbkMsQ0FBd0NELEtBQXhDLENBQUosRUFBbUQ7QUFDakQ7QUFDRCxPQUZELE1BRU8sSUFBSyxLQUFELENBQVFDLElBQVIsQ0FBYUQsS0FBYixDQUFKLEVBQXdCO0FBQzdCSCxRQUFBQSxLQUFLLENBQUNRLEtBQU4sQ0FBWVAsSUFBWixDQUFpQlEsU0FBUyxFQUExQjtBQUNELE9BRk0sTUFFQSxJQUFJTixLQUFJLElBQUlYLE9BQU8sQ0FBQ2tCLE1BQXBCLEVBQTRCO0FBQ2pDO0FBQ0EsY0FBTSxJQUFJQyxLQUFKLENBQVUsbUJBQW1CYixDQUFDLEdBQUcsQ0FBdkIsSUFBNEIsR0FBNUIsR0FBa0NjLElBQUksQ0FBQ0MsU0FBTCxDQUFlVixLQUFmLENBQTVDLENBQU47QUFDRCxPQUhNLE1BR0E7QUFDTEwsUUFBQUEsQ0FBQztBQUNGO0FBQ0Y7QUFDRixHQWxEK0MsQ0FvRGhEO0FBQ0E7OztBQUNBLFdBQVNTLGVBQVQsQ0FBeUJQLEtBQXpCLEVBQWdDO0FBQzlCLFFBQU1jLFVBQVUsR0FBSSx1QkFBRCxDQUEwQlIsSUFBMUIsQ0FBK0JiLE9BQU8sQ0FBQ0ssQ0FBRCxDQUF0QyxDQUFuQjs7QUFDQSxRQUFJZ0IsVUFBSixFQUFnQjtBQUNkLFVBQUlDLFNBQVMsR0FBR0QsVUFBVSxDQUFDLENBQUQsQ0FBVixLQUFrQixLQUFsQixHQUEwQixLQUExQixHQUFrQyxLQUFsRDtBQUNBLFVBQU1FLElBQUksR0FBR0YsVUFBVSxDQUFDLENBQUQsQ0FBVixDQUFjcEIsS0FBZCxDQUFvQixJQUFwQixFQUEwQixDQUExQixDQUFiO0FBQ0EsVUFBSXVCLFFBQVEsR0FBR0QsSUFBSSxDQUFDLENBQUQsQ0FBSixDQUFRRSxPQUFSLENBQWdCLE9BQWhCLEVBQXlCLElBQXpCLENBQWY7O0FBQ0EsVUFBSyxRQUFELENBQVdkLElBQVgsQ0FBZ0JhLFFBQWhCLENBQUosRUFBK0I7QUFDN0JBLFFBQUFBLFFBQVEsR0FBR0EsUUFBUSxDQUFDRSxNQUFULENBQWdCLENBQWhCLEVBQW1CRixRQUFRLENBQUNmLE1BQVQsR0FBa0IsQ0FBckMsQ0FBWDtBQUNEOztBQUNERixNQUFBQSxLQUFLLENBQUNlLFNBQVMsR0FBRyxVQUFiLENBQUwsR0FBZ0NFLFFBQWhDO0FBQ0FqQixNQUFBQSxLQUFLLENBQUNlLFNBQVMsR0FBRyxRQUFiLENBQUwsR0FBOEIsQ0FBQ0MsSUFBSSxDQUFDLENBQUQsQ0FBSixJQUFXLEVBQVosRUFBZ0JJLElBQWhCLEVBQTlCO0FBRUF0QixNQUFBQSxDQUFDO0FBQ0Y7QUFDRixHQXBFK0MsQ0FzRWhEO0FBQ0E7OztBQUNBLFdBQVNXLFNBQVQsR0FBcUI7QUFDbkIsUUFBSVksZ0JBQWdCLEdBQUd2QixDQUF2QjtBQUFBLFFBQ0l3QixlQUFlLEdBQUc3QixPQUFPLENBQUNLLENBQUMsRUFBRixDQUQ3QjtBQUFBLFFBRUl5QixXQUFXLEdBQUdELGVBQWUsQ0FBQzVCLEtBQWhCLENBQXNCLDRDQUF0QixDQUZsQjtBQUlBLFFBQUk4QixJQUFJLEdBQUc7QUFDVEMsTUFBQUEsUUFBUSxFQUFFLENBQUNGLFdBQVcsQ0FBQyxDQUFELENBRGI7QUFFVEcsTUFBQUEsUUFBUSxFQUFFLE9BQU9ILFdBQVcsQ0FBQyxDQUFELENBQWxCLEtBQTBCLFdBQTFCLEdBQXdDLENBQXhDLEdBQTRDLENBQUNBLFdBQVcsQ0FBQyxDQUFELENBRnpEO0FBR1RJLE1BQUFBLFFBQVEsRUFBRSxDQUFDSixXQUFXLENBQUMsQ0FBRCxDQUhiO0FBSVRLLE1BQUFBLFFBQVEsRUFBRSxPQUFPTCxXQUFXLENBQUMsQ0FBRCxDQUFsQixLQUEwQixXQUExQixHQUF3QyxDQUF4QyxHQUE0QyxDQUFDQSxXQUFXLENBQUMsQ0FBRCxDQUp6RDtBQUtUTSxNQUFBQSxLQUFLLEVBQUUsRUFMRTtBQU1UQyxNQUFBQSxjQUFjLEVBQUU7QUFOUCxLQUFYLENBTG1CLENBY25CO0FBQ0E7QUFDQTs7QUFDQSxRQUFJTixJQUFJLENBQUNFLFFBQUwsS0FBa0IsQ0FBdEIsRUFBeUI7QUFDdkJGLE1BQUFBLElBQUksQ0FBQ0MsUUFBTCxJQUFpQixDQUFqQjtBQUNEOztBQUNELFFBQUlELElBQUksQ0FBQ0ksUUFBTCxLQUFrQixDQUF0QixFQUF5QjtBQUN2QkosTUFBQUEsSUFBSSxDQUFDRyxRQUFMLElBQWlCLENBQWpCO0FBQ0Q7O0FBRUQsUUFBSUksUUFBUSxHQUFHLENBQWY7QUFBQSxRQUNJQyxXQUFXLEdBQUcsQ0FEbEI7O0FBRUEsV0FBT2xDLENBQUMsR0FBR0wsT0FBTyxDQUFDUyxNQUFuQixFQUEyQkosQ0FBQyxFQUE1QixFQUFnQztBQUM5QjtBQUNBO0FBQ0EsVUFBSUwsT0FBTyxDQUFDSyxDQUFELENBQVAsQ0FBV21DLE9BQVgsQ0FBbUIsTUFBbkIsTUFBK0IsQ0FBL0IsSUFDTW5DLENBQUMsR0FBRyxDQUFKLEdBQVFMLE9BQU8sQ0FBQ1MsTUFEdEIsSUFFS1QsT0FBTyxDQUFDSyxDQUFDLEdBQUcsQ0FBTCxDQUFQLENBQWVtQyxPQUFmLENBQXVCLE1BQXZCLE1BQW1DLENBRnhDLElBR0t4QyxPQUFPLENBQUNLLENBQUMsR0FBRyxDQUFMLENBQVAsQ0FBZW1DLE9BQWYsQ0FBdUIsSUFBdkIsTUFBaUMsQ0FIMUMsRUFHNkM7QUFDekM7QUFDSDs7QUFDRCxVQUFJQyxTQUFTLEdBQUl6QyxPQUFPLENBQUNLLENBQUQsQ0FBUCxDQUFXSSxNQUFYLElBQXFCLENBQXJCLElBQTBCSixDQUFDLElBQUtMLE9BQU8sQ0FBQ1MsTUFBUixHQUFpQixDQUFsRCxHQUF3RCxHQUF4RCxHQUE4RFQsT0FBTyxDQUFDSyxDQUFELENBQVAsQ0FBVyxDQUFYLENBQTlFOztBQUVBLFVBQUlvQyxTQUFTLEtBQUssR0FBZCxJQUFxQkEsU0FBUyxLQUFLLEdBQW5DLElBQTBDQSxTQUFTLEtBQUssR0FBeEQsSUFBK0RBLFNBQVMsS0FBSyxJQUFqRixFQUF1RjtBQUNyRlYsUUFBQUEsSUFBSSxDQUFDSyxLQUFMLENBQVc1QixJQUFYLENBQWdCUixPQUFPLENBQUNLLENBQUQsQ0FBdkI7QUFDQTBCLFFBQUFBLElBQUksQ0FBQ00sY0FBTCxDQUFvQjdCLElBQXBCLENBQXlCTixVQUFVLENBQUNHLENBQUQsQ0FBVixJQUFpQixJQUExQzs7QUFFQSxZQUFJb0MsU0FBUyxLQUFLLEdBQWxCLEVBQXVCO0FBQ3JCSCxVQUFBQSxRQUFRO0FBQ1QsU0FGRCxNQUVPLElBQUlHLFNBQVMsS0FBSyxHQUFsQixFQUF1QjtBQUM1QkYsVUFBQUEsV0FBVztBQUNaLFNBRk0sTUFFQSxJQUFJRSxTQUFTLEtBQUssR0FBbEIsRUFBdUI7QUFDNUJILFVBQUFBLFFBQVE7QUFDUkMsVUFBQUEsV0FBVztBQUNaO0FBQ0YsT0FaRCxNQVlPO0FBQ0w7QUFDRDtBQUNGLEtBcERrQixDQXNEbkI7OztBQUNBLFFBQUksQ0FBQ0QsUUFBRCxJQUFhUCxJQUFJLENBQUNJLFFBQUwsS0FBa0IsQ0FBbkMsRUFBc0M7QUFDcENKLE1BQUFBLElBQUksQ0FBQ0ksUUFBTCxHQUFnQixDQUFoQjtBQUNEOztBQUNELFFBQUksQ0FBQ0ksV0FBRCxJQUFnQlIsSUFBSSxDQUFDRSxRQUFMLEtBQWtCLENBQXRDLEVBQXlDO0FBQ3ZDRixNQUFBQSxJQUFJLENBQUNFLFFBQUwsR0FBZ0IsQ0FBaEI7QUFDRCxLQTVEa0IsQ0E4RG5COzs7QUFDQSxRQUFJbEMsT0FBTyxDQUFDa0IsTUFBWixFQUFvQjtBQUNsQixVQUFJcUIsUUFBUSxLQUFLUCxJQUFJLENBQUNJLFFBQXRCLEVBQWdDO0FBQzlCLGNBQU0sSUFBSWpCLEtBQUosQ0FBVSxzREFBc0RVLGdCQUFnQixHQUFHLENBQXpFLENBQVYsQ0FBTjtBQUNEOztBQUNELFVBQUlXLFdBQVcsS0FBS1IsSUFBSSxDQUFDRSxRQUF6QixFQUFtQztBQUNqQyxjQUFNLElBQUlmLEtBQUosQ0FBVSx3REFBd0RVLGdCQUFnQixHQUFHLENBQTNFLENBQVYsQ0FBTjtBQUNEO0FBQ0Y7O0FBRUQsV0FBT0csSUFBUDtBQUNEOztBQUVELFNBQU8xQixDQUFDLEdBQUdMLE9BQU8sQ0FBQ1MsTUFBbkIsRUFBMkI7QUFDekJILElBQUFBLFVBQVU7QUFDWDs7QUFFRCxTQUFPRixJQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gcGFyc2VQYXRjaCh1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgbGV0IGRpZmZzdHIgPSB1bmlEaWZmLnNwbGl0KC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS8pLFxuICAgICAgZGVsaW1pdGVycyA9IHVuaURpZmYubWF0Y2goL1xcclxcbnxbXFxuXFx2XFxmXFxyXFx4ODVdL2cpIHx8IFtdLFxuICAgICAgbGlzdCA9IFtdLFxuICAgICAgaSA9IDA7XG5cbiAgZnVuY3Rpb24gcGFyc2VJbmRleCgpIHtcbiAgICBsZXQgaW5kZXggPSB7fTtcbiAgICBsaXN0LnB1c2goaW5kZXgpO1xuXG4gICAgLy8gUGFyc2UgZGlmZiBtZXRhZGF0YVxuICAgIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICAgIGxldCBsaW5lID0gZGlmZnN0cltpXTtcblxuICAgICAgLy8gRmlsZSBoZWFkZXIgZm91bmQsIGVuZCBwYXJzaW5nIGRpZmYgbWV0YWRhdGFcbiAgICAgIGlmICgoL14oXFwtXFwtXFwtfFxcK1xcK1xcK3xAQClcXHMvKS50ZXN0KGxpbmUpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBEaWZmIGluZGV4XG4gICAgICBsZXQgaGVhZGVyID0gKC9eKD86SW5kZXg6fGRpZmYoPzogLXIgXFx3KykrKVxccysoLis/KVxccyokLykuZXhlYyhsaW5lKTtcbiAgICAgIGlmIChoZWFkZXIpIHtcbiAgICAgICAgaW5kZXguaW5kZXggPSBoZWFkZXJbMV07XG4gICAgICB9XG5cbiAgICAgIGkrKztcbiAgICB9XG5cbiAgICAvLyBQYXJzZSBmaWxlIGhlYWRlcnMgaWYgdGhleSBhcmUgZGVmaW5lZC4gVW5pZmllZCBkaWZmIHJlcXVpcmVzIHRoZW0sIGJ1dFxuICAgIC8vIHRoZXJlJ3Mgbm8gdGVjaG5pY2FsIGlzc3VlcyB0byBoYXZlIGFuIGlzb2xhdGVkIGh1bmsgd2l0aG91dCBmaWxlIGhlYWRlclxuICAgIHBhcnNlRmlsZUhlYWRlcihpbmRleCk7XG4gICAgcGFyc2VGaWxlSGVhZGVyKGluZGV4KTtcblxuICAgIC8vIFBhcnNlIGh1bmtzXG4gICAgaW5kZXguaHVua3MgPSBbXTtcblxuICAgIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICAgIGxldCBsaW5lID0gZGlmZnN0cltpXTtcblxuICAgICAgaWYgKCgvXihJbmRleDp8ZGlmZnxcXC1cXC1cXC18XFwrXFwrXFwrKVxccy8pLnRlc3QobGluZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKCgvXkBALykudGVzdChsaW5lKSkge1xuICAgICAgICBpbmRleC5odW5rcy5wdXNoKHBhcnNlSHVuaygpKTtcbiAgICAgIH0gZWxzZSBpZiAobGluZSAmJiBvcHRpb25zLnN0cmljdCkge1xuICAgICAgICAvLyBJZ25vcmUgdW5leHBlY3RlZCBjb250ZW50IHVubGVzcyBpbiBzdHJpY3QgbW9kZVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbGluZSAnICsgKGkgKyAxKSArICcgJyArIEpTT04uc3RyaW5naWZ5KGxpbmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBQYXJzZXMgdGhlIC0tLSBhbmQgKysrIGhlYWRlcnMsIGlmIG5vbmUgYXJlIGZvdW5kLCBubyBsaW5lc1xuICAvLyBhcmUgY29uc3VtZWQuXG4gIGZ1bmN0aW9uIHBhcnNlRmlsZUhlYWRlcihpbmRleCkge1xuICAgIGNvbnN0IGZpbGVIZWFkZXIgPSAoL14oLS0tfFxcK1xcK1xcKylcXHMrKC4qKSQvKS5leGVjKGRpZmZzdHJbaV0pO1xuICAgIGlmIChmaWxlSGVhZGVyKSB7XG4gICAgICBsZXQga2V5UHJlZml4ID0gZmlsZUhlYWRlclsxXSA9PT0gJy0tLScgPyAnb2xkJyA6ICduZXcnO1xuICAgICAgY29uc3QgZGF0YSA9IGZpbGVIZWFkZXJbMl0uc3BsaXQoJ1xcdCcsIDIpO1xuICAgICAgbGV0IGZpbGVOYW1lID0gZGF0YVswXS5yZXBsYWNlKC9cXFxcXFxcXC9nLCAnXFxcXCcpO1xuICAgICAgaWYgKCgvXlwiLipcIiQvKS50ZXN0KGZpbGVOYW1lKSkge1xuICAgICAgICBmaWxlTmFtZSA9IGZpbGVOYW1lLnN1YnN0cigxLCBmaWxlTmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIH1cbiAgICAgIGluZGV4W2tleVByZWZpeCArICdGaWxlTmFtZSddID0gZmlsZU5hbWU7XG4gICAgICBpbmRleFtrZXlQcmVmaXggKyAnSGVhZGVyJ10gPSAoZGF0YVsxXSB8fCAnJykudHJpbSgpO1xuXG4gICAgICBpKys7XG4gICAgfVxuICB9XG5cbiAgLy8gUGFyc2VzIGEgaHVua1xuICAvLyBUaGlzIGFzc3VtZXMgdGhhdCB3ZSBhcmUgYXQgdGhlIHN0YXJ0IG9mIGEgaHVuay5cbiAgZnVuY3Rpb24gcGFyc2VIdW5rKCkge1xuICAgIGxldCBjaHVua0hlYWRlckluZGV4ID0gaSxcbiAgICAgICAgY2h1bmtIZWFkZXJMaW5lID0gZGlmZnN0cltpKytdLFxuICAgICAgICBjaHVua0hlYWRlciA9IGNodW5rSGVhZGVyTGluZS5zcGxpdCgvQEAgLShcXGQrKSg/OiwoXFxkKykpPyBcXCsoXFxkKykoPzosKFxcZCspKT8gQEAvKTtcblxuICAgIGxldCBodW5rID0ge1xuICAgICAgb2xkU3RhcnQ6ICtjaHVua0hlYWRlclsxXSxcbiAgICAgIG9sZExpbmVzOiB0eXBlb2YgY2h1bmtIZWFkZXJbMl0gPT09ICd1bmRlZmluZWQnID8gMSA6ICtjaHVua0hlYWRlclsyXSxcbiAgICAgIG5ld1N0YXJ0OiArY2h1bmtIZWFkZXJbM10sXG4gICAgICBuZXdMaW5lczogdHlwZW9mIGNodW5rSGVhZGVyWzRdID09PSAndW5kZWZpbmVkJyA/IDEgOiArY2h1bmtIZWFkZXJbNF0sXG4gICAgICBsaW5lczogW10sXG4gICAgICBsaW5lZGVsaW1pdGVyczogW11cbiAgICB9O1xuXG4gICAgLy8gVW5pZmllZCBEaWZmIEZvcm1hdCBxdWlyazogSWYgdGhlIGNodW5rIHNpemUgaXMgMCxcbiAgICAvLyB0aGUgZmlyc3QgbnVtYmVyIGlzIG9uZSBsb3dlciB0aGFuIG9uZSB3b3VsZCBleHBlY3QuXG4gICAgLy8gaHR0cHM6Ly93d3cuYXJ0aW1hLmNvbS93ZWJsb2dzL3ZpZXdwb3N0LmpzcD90aHJlYWQ9MTY0MjkzXG4gICAgaWYgKGh1bmsub2xkTGluZXMgPT09IDApIHtcbiAgICAgIGh1bmsub2xkU3RhcnQgKz0gMTtcbiAgICB9XG4gICAgaWYgKGh1bmsubmV3TGluZXMgPT09IDApIHtcbiAgICAgIGh1bmsubmV3U3RhcnQgKz0gMTtcbiAgICB9XG5cbiAgICBsZXQgYWRkQ291bnQgPSAwLFxuICAgICAgICByZW1vdmVDb3VudCA9IDA7XG4gICAgZm9yICg7IGkgPCBkaWZmc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBMaW5lcyBzdGFydGluZyB3aXRoICctLS0nIGNvdWxkIGJlIG1pc3Rha2VuIGZvciB0aGUgXCJyZW1vdmUgbGluZVwiIG9wZXJhdGlvblxuICAgICAgLy8gQnV0IHRoZXkgY291bGQgYmUgdGhlIGhlYWRlciBmb3IgdGhlIG5leHQgZmlsZS4gVGhlcmVmb3JlIHBydW5lIHN1Y2ggY2FzZXMgb3V0LlxuICAgICAgaWYgKGRpZmZzdHJbaV0uaW5kZXhPZignLS0tICcpID09PSAwXG4gICAgICAgICAgICAmJiAoaSArIDIgPCBkaWZmc3RyLmxlbmd0aClcbiAgICAgICAgICAgICYmIGRpZmZzdHJbaSArIDFdLmluZGV4T2YoJysrKyAnKSA9PT0gMFxuICAgICAgICAgICAgJiYgZGlmZnN0cltpICsgMl0uaW5kZXhPZignQEAnKSA9PT0gMCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgbGV0IG9wZXJhdGlvbiA9IChkaWZmc3RyW2ldLmxlbmd0aCA9PSAwICYmIGkgIT0gKGRpZmZzdHIubGVuZ3RoIC0gMSkpID8gJyAnIDogZGlmZnN0cltpXVswXTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJysnIHx8IG9wZXJhdGlvbiA9PT0gJy0nIHx8IG9wZXJhdGlvbiA9PT0gJyAnIHx8IG9wZXJhdGlvbiA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGh1bmsubGluZXMucHVzaChkaWZmc3RyW2ldKTtcbiAgICAgICAgaHVuay5saW5lZGVsaW1pdGVycy5wdXNoKGRlbGltaXRlcnNbaV0gfHwgJ1xcbicpO1xuXG4gICAgICAgIGlmIChvcGVyYXRpb24gPT09ICcrJykge1xuICAgICAgICAgIGFkZENvdW50Kys7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgICByZW1vdmVDb3VudCsrO1xuICAgICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJyAnKSB7XG4gICAgICAgICAgYWRkQ291bnQrKztcbiAgICAgICAgICByZW1vdmVDb3VudCsrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgdGhlIGVtcHR5IGJsb2NrIGNvdW50IGNhc2VcbiAgICBpZiAoIWFkZENvdW50ICYmIGh1bmsubmV3TGluZXMgPT09IDEpIHtcbiAgICAgIGh1bmsubmV3TGluZXMgPSAwO1xuICAgIH1cbiAgICBpZiAoIXJlbW92ZUNvdW50ICYmIGh1bmsub2xkTGluZXMgPT09IDEpIHtcbiAgICAgIGh1bmsub2xkTGluZXMgPSAwO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm0gb3B0aW9uYWwgc2FuaXR5IGNoZWNraW5nXG4gICAgaWYgKG9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICBpZiAoYWRkQ291bnQgIT09IGh1bmsubmV3TGluZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZGRlZCBsaW5lIGNvdW50IGRpZCBub3QgbWF0Y2ggZm9yIGh1bmsgYXQgbGluZSAnICsgKGNodW5rSGVhZGVySW5kZXggKyAxKSk7XG4gICAgICB9XG4gICAgICBpZiAocmVtb3ZlQ291bnQgIT09IGh1bmsub2xkTGluZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZW1vdmVkIGxpbmUgY291bnQgZGlkIG5vdCBtYXRjaCBmb3IgaHVuayBhdCBsaW5lICcgKyAoY2h1bmtIZWFkZXJJbmRleCArIDEpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaHVuaztcbiAgfVxuXG4gIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICBwYXJzZUluZGV4KCk7XG4gIH1cblxuICByZXR1cm4gbGlzdDtcbn1cbiJdfQ== diff --git a/node_modules/diff/lib/util/array.js b/node_modules/diff/lib/util/array.js deleted file mode 100644 index aecf67ac817c1..0000000000000 --- a/node_modules/diff/lib/util/array.js +++ /dev/null @@ -1,32 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.arrayEqual = arrayEqual; -exports.arrayStartsWith = arrayStartsWith; - -/*istanbul ignore end*/ -function arrayEqual(a, b) { - if (a.length !== b.length) { - return false; - } - - return arrayStartsWith(a, b); -} - -function arrayStartsWith(array, start) { - if (start.length > array.length) { - return false; - } - - for (var i = 0; i < start.length; i++) { - if (start[i] !== array[i]) { - return false; - } - } - - return true; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsL2FycmF5LmpzIl0sIm5hbWVzIjpbImFycmF5RXF1YWwiLCJhIiwiYiIsImxlbmd0aCIsImFycmF5U3RhcnRzV2l0aCIsImFycmF5Iiwic3RhcnQiLCJpIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQU8sU0FBU0EsVUFBVCxDQUFvQkMsQ0FBcEIsRUFBdUJDLENBQXZCLEVBQTBCO0FBQy9CLE1BQUlELENBQUMsQ0FBQ0UsTUFBRixLQUFhRCxDQUFDLENBQUNDLE1BQW5CLEVBQTJCO0FBQ3pCLFdBQU8sS0FBUDtBQUNEOztBQUVELFNBQU9DLGVBQWUsQ0FBQ0gsQ0FBRCxFQUFJQyxDQUFKLENBQXRCO0FBQ0Q7O0FBRU0sU0FBU0UsZUFBVCxDQUF5QkMsS0FBekIsRUFBZ0NDLEtBQWhDLEVBQXVDO0FBQzVDLE1BQUlBLEtBQUssQ0FBQ0gsTUFBTixHQUFlRSxLQUFLLENBQUNGLE1BQXpCLEVBQWlDO0FBQy9CLFdBQU8sS0FBUDtBQUNEOztBQUVELE9BQUssSUFBSUksQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR0QsS0FBSyxDQUFDSCxNQUExQixFQUFrQ0ksQ0FBQyxFQUFuQyxFQUF1QztBQUNyQyxRQUFJRCxLQUFLLENBQUNDLENBQUQsQ0FBTCxLQUFhRixLQUFLLENBQUNFLENBQUQsQ0FBdEIsRUFBMkI7QUFDekIsYUFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUFFRCxTQUFPLElBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBhcnJheUVxdWFsKGEsIGIpIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBhcnJheVN0YXJ0c1dpdGgoYSwgYik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcnJheVN0YXJ0c1dpdGgoYXJyYXksIHN0YXJ0KSB7XG4gIGlmIChzdGFydC5sZW5ndGggPiBhcnJheS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YXJ0Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0YXJ0W2ldICE9PSBhcnJheVtpXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuIl19 diff --git a/node_modules/diff/lib/util/distance-iterator.js b/node_modules/diff/lib/util/distance-iterator.js deleted file mode 100644 index 57c06a3f9cf1c..0000000000000 --- a/node_modules/diff/lib/util/distance-iterator.js +++ /dev/null @@ -1,57 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = _default; - -/*istanbul ignore end*/ -// Iterator that traverses in the range of [min, max], stepping -// by distance from a given start position. I.e. for [0, 4], with -// start of 2, this will iterate 2, 3, 1, 4, 0. -function -/*istanbul ignore start*/ -_default -/*istanbul ignore end*/ -(start, minLine, maxLine) { - var wantForward = true, - backwardExhausted = false, - forwardExhausted = false, - localOffset = 1; - return function iterator() { - if (wantForward && !forwardExhausted) { - if (backwardExhausted) { - localOffset++; - } else { - wantForward = false; - } // Check if trying to fit beyond text length, and if not, check it fits - // after offset location (or desired location on first iteration) - - - if (start + localOffset <= maxLine) { - return localOffset; - } - - forwardExhausted = true; - } - - if (!backwardExhausted) { - if (!forwardExhausted) { - wantForward = true; - } // Check if trying to fit before text beginning, and if not, check it fits - // before offset location - - - if (minLine <= start - localOffset) { - return -localOffset++; - } - - backwardExhausted = true; - return iterator(); - } // We tried to fit hunk before text beginning and beyond text length, then - // hunk can't fit on the text. Return undefined - - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yLmpzIl0sIm5hbWVzIjpbInN0YXJ0IiwibWluTGluZSIsIm1heExpbmUiLCJ3YW50Rm9yd2FyZCIsImJhY2t3YXJkRXhoYXVzdGVkIiwiZm9yd2FyZEV4aGF1c3RlZCIsImxvY2FsT2Zmc2V0IiwiaXRlcmF0b3IiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNlO0FBQUE7QUFBQTtBQUFBO0FBQUEsQ0FBU0EsS0FBVCxFQUFnQkMsT0FBaEIsRUFBeUJDLE9BQXpCLEVBQWtDO0FBQy9DLE1BQUlDLFdBQVcsR0FBRyxJQUFsQjtBQUFBLE1BQ0lDLGlCQUFpQixHQUFHLEtBRHhCO0FBQUEsTUFFSUMsZ0JBQWdCLEdBQUcsS0FGdkI7QUFBQSxNQUdJQyxXQUFXLEdBQUcsQ0FIbEI7QUFLQSxTQUFPLFNBQVNDLFFBQVQsR0FBb0I7QUFDekIsUUFBSUosV0FBVyxJQUFJLENBQUNFLGdCQUFwQixFQUFzQztBQUNwQyxVQUFJRCxpQkFBSixFQUF1QjtBQUNyQkUsUUFBQUEsV0FBVztBQUNaLE9BRkQsTUFFTztBQUNMSCxRQUFBQSxXQUFXLEdBQUcsS0FBZDtBQUNELE9BTG1DLENBT3BDO0FBQ0E7OztBQUNBLFVBQUlILEtBQUssR0FBR00sV0FBUixJQUF1QkosT0FBM0IsRUFBb0M7QUFDbEMsZUFBT0ksV0FBUDtBQUNEOztBQUVERCxNQUFBQSxnQkFBZ0IsR0FBRyxJQUFuQjtBQUNEOztBQUVELFFBQUksQ0FBQ0QsaUJBQUwsRUFBd0I7QUFDdEIsVUFBSSxDQUFDQyxnQkFBTCxFQUF1QjtBQUNyQkYsUUFBQUEsV0FBVyxHQUFHLElBQWQ7QUFDRCxPQUhxQixDQUt0QjtBQUNBOzs7QUFDQSxVQUFJRixPQUFPLElBQUlELEtBQUssR0FBR00sV0FBdkIsRUFBb0M7QUFDbEMsZUFBTyxDQUFDQSxXQUFXLEVBQW5CO0FBQ0Q7O0FBRURGLE1BQUFBLGlCQUFpQixHQUFHLElBQXBCO0FBQ0EsYUFBT0csUUFBUSxFQUFmO0FBQ0QsS0E5QndCLENBZ0N6QjtBQUNBOztBQUNELEdBbENEO0FBbUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSXRlcmF0b3IgdGhhdCB0cmF2ZXJzZXMgaW4gdGhlIHJhbmdlIG9mIFttaW4sIG1heF0sIHN0ZXBwaW5nXG4vLyBieSBkaXN0YW5jZSBmcm9tIGEgZ2l2ZW4gc3RhcnQgcG9zaXRpb24uIEkuZS4gZm9yIFswLCA0XSwgd2l0aFxuLy8gc3RhcnQgb2YgMiwgdGhpcyB3aWxsIGl0ZXJhdGUgMiwgMywgMSwgNCwgMC5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKHN0YXJ0LCBtaW5MaW5lLCBtYXhMaW5lKSB7XG4gIGxldCB3YW50Rm9yd2FyZCA9IHRydWUsXG4gICAgICBiYWNrd2FyZEV4aGF1c3RlZCA9IGZhbHNlLFxuICAgICAgZm9yd2FyZEV4aGF1c3RlZCA9IGZhbHNlLFxuICAgICAgbG9jYWxPZmZzZXQgPSAxO1xuXG4gIHJldHVybiBmdW5jdGlvbiBpdGVyYXRvcigpIHtcbiAgICBpZiAod2FudEZvcndhcmQgJiYgIWZvcndhcmRFeGhhdXN0ZWQpIHtcbiAgICAgIGlmIChiYWNrd2FyZEV4aGF1c3RlZCkge1xuICAgICAgICBsb2NhbE9mZnNldCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2FudEZvcndhcmQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdHJ5aW5nIHRvIGZpdCBiZXlvbmQgdGV4dCBsZW5ndGgsIGFuZCBpZiBub3QsIGNoZWNrIGl0IGZpdHNcbiAgICAgIC8vIGFmdGVyIG9mZnNldCBsb2NhdGlvbiAob3IgZGVzaXJlZCBsb2NhdGlvbiBvbiBmaXJzdCBpdGVyYXRpb24pXG4gICAgICBpZiAoc3RhcnQgKyBsb2NhbE9mZnNldCA8PSBtYXhMaW5lKSB7XG4gICAgICAgIHJldHVybiBsb2NhbE9mZnNldDtcbiAgICAgIH1cblxuICAgICAgZm9yd2FyZEV4aGF1c3RlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCFiYWNrd2FyZEV4aGF1c3RlZCkge1xuICAgICAgaWYgKCFmb3J3YXJkRXhoYXVzdGVkKSB7XG4gICAgICAgIHdhbnRGb3J3YXJkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdHJ5aW5nIHRvIGZpdCBiZWZvcmUgdGV4dCBiZWdpbm5pbmcsIGFuZCBpZiBub3QsIGNoZWNrIGl0IGZpdHNcbiAgICAgIC8vIGJlZm9yZSBvZmZzZXQgbG9jYXRpb25cbiAgICAgIGlmIChtaW5MaW5lIDw9IHN0YXJ0IC0gbG9jYWxPZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIC1sb2NhbE9mZnNldCsrO1xuICAgICAgfVxuXG4gICAgICBiYWNrd2FyZEV4aGF1c3RlZCA9IHRydWU7XG4gICAgICByZXR1cm4gaXRlcmF0b3IoKTtcbiAgICB9XG5cbiAgICAvLyBXZSB0cmllZCB0byBmaXQgaHVuayBiZWZvcmUgdGV4dCBiZWdpbm5pbmcgYW5kIGJleW9uZCB0ZXh0IGxlbmd0aCwgdGhlblxuICAgIC8vIGh1bmsgY2FuJ3QgZml0IG9uIHRoZSB0ZXh0LiBSZXR1cm4gdW5kZWZpbmVkXG4gIH07XG59XG4iXX0= diff --git a/node_modules/diff/lib/util/params.js b/node_modules/diff/lib/util/params.js deleted file mode 100644 index e838eb2f42d15..0000000000000 --- a/node_modules/diff/lib/util/params.js +++ /dev/null @@ -1,24 +0,0 @@ -/*istanbul ignore start*/ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.generateOptions = generateOptions; - -/*istanbul ignore end*/ -function generateOptions(options, defaults) { - if (typeof options === 'function') { - defaults.callback = options; - } else if (options) { - for (var name in options) { - /* istanbul ignore else */ - if (options.hasOwnProperty(name)) { - defaults[name] = options[name]; - } - } - } - - return defaults; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsL3BhcmFtcy5qcyJdLCJuYW1lcyI6WyJnZW5lcmF0ZU9wdGlvbnMiLCJvcHRpb25zIiwiZGVmYXVsdHMiLCJjYWxsYmFjayIsIm5hbWUiLCJoYXNPd25Qcm9wZXJ0eSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQU8sU0FBU0EsZUFBVCxDQUF5QkMsT0FBekIsRUFBa0NDLFFBQWxDLEVBQTRDO0FBQ2pELE1BQUksT0FBT0QsT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUNqQ0MsSUFBQUEsUUFBUSxDQUFDQyxRQUFULEdBQW9CRixPQUFwQjtBQUNELEdBRkQsTUFFTyxJQUFJQSxPQUFKLEVBQWE7QUFDbEIsU0FBSyxJQUFJRyxJQUFULElBQWlCSCxPQUFqQixFQUEwQjtBQUN4QjtBQUNBLFVBQUlBLE9BQU8sQ0FBQ0ksY0FBUixDQUF1QkQsSUFBdkIsQ0FBSixFQUFrQztBQUNoQ0YsUUFBQUEsUUFBUSxDQUFDRSxJQUFELENBQVIsR0FBaUJILE9BQU8sQ0FBQ0csSUFBRCxDQUF4QjtBQUNEO0FBQ0Y7QUFDRjs7QUFDRCxTQUFPRixRQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVPcHRpb25zKG9wdGlvbnMsIGRlZmF1bHRzKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGRlZmF1bHRzLmNhbGxiYWNrID0gb3B0aW9ucztcbiAgfSBlbHNlIGlmIChvcHRpb25zKSB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBvcHRpb25zKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgZGVmYXVsdHNbbmFtZV0gPSBvcHRpb25zW25hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZGVmYXVsdHM7XG59XG4iXX0= diff --git a/node_modules/diff/libcjs/convert/dmp.js b/node_modules/diff/libcjs/convert/dmp.js new file mode 100644 index 0000000000000..10680ff38801f --- /dev/null +++ b/node_modules/diff/libcjs/convert/dmp.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.convertChangesToDMP = convertChangesToDMP; +/** + * converts a list of change objects to the format returned by Google's [diff-match-patch](https://github.com/google/diff-match-patch) library + */ +function convertChangesToDMP(changes) { + var ret = []; + var change, operation; + for (var i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } + else if (change.removed) { + operation = -1; + } + else { + operation = 0; + } + ret.push([operation, change.value]); + } + return ret; +} diff --git a/node_modules/diff/libcjs/convert/xml.js b/node_modules/diff/libcjs/convert/xml.js new file mode 100644 index 0000000000000..5ecd8aa255b86 --- /dev/null +++ b/node_modules/diff/libcjs/convert/xml.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.convertChangesToXML = convertChangesToXML; +/** + * converts a list of change objects to a serialized XML format + */ +function convertChangesToXML(changes) { + var ret = []; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + if (change.added) { + ret.push('<ins>'); + } + else if (change.removed) { + ret.push('<del>'); + } + ret.push(escapeHTML(change.value)); + if (change.added) { + ret.push('</ins>'); + } + else if (change.removed) { + ret.push('</del>'); + } + } + return ret.join(''); +} +function escapeHTML(s) { + var n = s; + n = n.replace(/&/g, '&'); + n = n.replace(/</g, '<'); + n = n.replace(/>/g, '>'); + n = n.replace(/"/g, '"'); + return n; +} diff --git a/node_modules/diff/libcjs/diff/array.js b/node_modules/diff/libcjs/diff/array.js new file mode 100644 index 0000000000000..2050261be823f --- /dev/null +++ b/node_modules/diff/libcjs/diff/array.js @@ -0,0 +1,40 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayDiff = void 0; +exports.diffArrays = diffArrays; +var base_js_1 = require("./base.js"); +var ArrayDiff = /** @class */ (function (_super) { + __extends(ArrayDiff, _super); + function ArrayDiff() { + return _super !== null && _super.apply(this, arguments) || this; + } + ArrayDiff.prototype.tokenize = function (value) { + return value.slice(); + }; + ArrayDiff.prototype.join = function (value) { + return value; + }; + ArrayDiff.prototype.removeEmpty = function (value) { + return value; + }; + return ArrayDiff; +}(base_js_1.default)); +exports.arrayDiff = new ArrayDiff(); +function diffArrays(oldArr, newArr, options) { + return exports.arrayDiff.diff(oldArr, newArr, options); +} diff --git a/node_modules/diff/libcjs/diff/base.js b/node_modules/diff/libcjs/diff/base.js new file mode 100644 index 0000000000000..5248d95693009 --- /dev/null +++ b/node_modules/diff/libcjs/diff/base.js @@ -0,0 +1,265 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Diff = /** @class */ (function () { + function Diff() { + } + Diff.prototype.diff = function (oldStr, newStr, + // Type below is not accurate/complete - see above for full possibilities - but it compiles + options) { + if (options === void 0) { options = {}; } + var callback; + if (typeof options === 'function') { + callback = options; + options = {}; + } + else if ('callback' in options) { + callback = options.callback; + } + // Allow subclasses to massage the input prior to running + var oldString = this.castInput(oldStr, options); + var newString = this.castInput(newStr, options); + var oldTokens = this.removeEmpty(this.tokenize(oldString, options)); + var newTokens = this.removeEmpty(this.tokenize(newString, options)); + return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); + }; + Diff.prototype.diffWithOptionsObj = function (oldTokens, newTokens, options, callback) { + var _this = this; + var _a; + var done = function (value) { + value = _this.postProcess(value, options); + if (callback) { + setTimeout(function () { callback(value); }, 0); + return undefined; + } + else { + return value; + } + }; + var newLen = newTokens.length, oldLen = oldTokens.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + if (options.maxEditLength != null) { + maxEditLength = Math.min(maxEditLength, options.maxEditLength); + } + var maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; + var abortAfterTimestamp = Date.now() + maxExecutionTime; + var bestPath = [{ oldPos: -1, lastComponent: undefined }]; + // Seed editLength = 0, i.e. the content starts with the same values + var newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); + if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { + // Identity per the equality and tokenizer + return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); + } + // Once we hit the right edge of the edit graph on some diagonal k, we can + // definitely reach the end of the edit graph in no more than k edits, so + // there's no point in considering any moves to diagonal k+1 any more (from + // which we're guaranteed to need at least k+1 more edits). + // Similarly, once we've reached the bottom of the edit graph, there's no + // point considering moves to lower diagonals. + // We record this fact by setting minDiagonalToConsider and + // maxDiagonalToConsider to some finite value once we've hit the edge of + // the edit graph. + // This optimization is not faithful to the original algorithm presented in + // Myers's paper, which instead pointlessly extends D-paths off the end of + // the edit graph - see page 7 of Myers's paper which notes this point + // explicitly and illustrates it with a diagram. This has major performance + // implications for some common scenarios. For instance, to compute a diff + // where the new text simply appends d characters on the end of the + // original text of length n, the true Myers algorithm will take O(n+d^2) + // time while this optimization needs only O(n+d) time. + var minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; + // Main worker method. checks all permutations of a given edit length for acceptance. + var execEditLength = function () { + for (var diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { + var basePath = void 0; + var removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; + if (removePath) { + // No one else is going to attempt to use this value, clear it + // @ts-expect-error - perf optimisation. This type-violating value will never be read. + bestPath[diagonalPath - 1] = undefined; + } + var canAdd = false; + if (addPath) { + // what newPos will be after we do an insertion: + var addPathNewPos = addPath.oldPos - diagonalPath; + canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; + } + var canRemove = removePath && removePath.oldPos + 1 < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + // @ts-expect-error - perf optimisation. This type-violating value will never be read. + bestPath[diagonalPath] = undefined; + continue; + } + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the old string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canRemove || (canAdd && removePath.oldPos < addPath.oldPos)) { + basePath = _this.addToPath(addPath, true, false, 0, options); + } + else { + basePath = _this.addToPath(removePath, false, true, 1, options); + } + newPos = _this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); + if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { + // If we have hit the end of both strings, then we are done + return done(_this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; + } + else { + bestPath[diagonalPath] = basePath; + if (basePath.oldPos + 1 >= oldLen) { + maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); + } + if (newPos + 1 >= newLen) { + minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); + } + } + } + editLength++; + }; + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced, or until the edit length exceeds options.maxEditLength (if given), + // in which case it will return undefined. + if (callback) { + (function exec() { + setTimeout(function () { + if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { + return callback(undefined); + } + if (!execEditLength()) { + exec(); + } + }, 0); + }()); + } + else { + while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } + } + }; + Diff.prototype.addToPath = function (path, added, removed, oldPosInc, options) { + var last = path.lastComponent; + if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) { + return { + oldPos: path.oldPos + oldPosInc, + lastComponent: { count: last.count + 1, added: added, removed: removed, previousComponent: last.previousComponent } + }; + } + else { + return { + oldPos: path.oldPos + oldPosInc, + lastComponent: { count: 1, added: added, removed: removed, previousComponent: last } + }; + } + }; + Diff.prototype.extractCommon = function (basePath, newTokens, oldTokens, diagonalPath, options) { + var newLen = newTokens.length, oldLen = oldTokens.length; + var oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { + newPos++; + oldPos++; + commonCount++; + if (options.oneChangePerToken) { + basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; + } + } + if (commonCount && !options.oneChangePerToken) { + basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; + } + basePath.oldPos = oldPos; + return newPos; + }; + Diff.prototype.equals = function (left, right, options) { + if (options.comparator) { + return options.comparator(left, right); + } + else { + return left === right + || (!!options.ignoreCase && left.toLowerCase() === right.toLowerCase()); + } + }; + Diff.prototype.removeEmpty = function (array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } + } + return ret; + }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + Diff.prototype.castInput = function (value, options) { + return value; + }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + Diff.prototype.tokenize = function (value, options) { + return Array.from(value); + }; + Diff.prototype.join = function (chars) { + // Assumes ValueT is string, which is the case for most subclasses. + // When it's false, e.g. in diffArrays, this method needs to be overridden (e.g. with a no-op) + // Yes, the casts are verbose and ugly, because this pattern - of having the base class SORT OF + // assume tokens and values are strings, but not completely - is weird and janky. + return chars.join(''); + }; + Diff.prototype.postProcess = function (changeObjects, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + options) { + return changeObjects; + }; + Object.defineProperty(Diff.prototype, "useLongestToken", { + get: function () { + return false; + }, + enumerable: false, + configurable: true + }); + Diff.prototype.buildValues = function (lastComponent, newTokens, oldTokens) { + // First we convert our linked list of components in reverse order to an + // array in the right order: + var components = []; + var nextComponent; + while (lastComponent) { + components.push(lastComponent); + nextComponent = lastComponent.previousComponent; + delete lastComponent.previousComponent; + lastComponent = nextComponent; + } + components.reverse(); + var componentLen = components.length; + var componentPos = 0, newPos = 0, oldPos = 0; + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + if (!component.added && this.useLongestToken) { + var value = newTokens.slice(newPos, newPos + component.count); + value = value.map(function (value, i) { + var oldValue = oldTokens[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); + component.value = this.join(value); + } + else { + component.value = this.join(newTokens.slice(newPos, newPos + component.count)); + } + newPos += component.count; + // Common case + if (!component.added) { + oldPos += component.count; + } + } + else { + component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); + oldPos += component.count; + } + } + return components; + }; + return Diff; +}()); +exports.default = Diff; diff --git a/node_modules/diff/libcjs/diff/character.js b/node_modules/diff/libcjs/diff/character.js new file mode 100644 index 0000000000000..8e974ef9ad551 --- /dev/null +++ b/node_modules/diff/libcjs/diff/character.js @@ -0,0 +1,31 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.characterDiff = void 0; +exports.diffChars = diffChars; +var base_js_1 = require("./base.js"); +var CharacterDiff = /** @class */ (function (_super) { + __extends(CharacterDiff, _super); + function CharacterDiff() { + return _super !== null && _super.apply(this, arguments) || this; + } + return CharacterDiff; +}(base_js_1.default)); +exports.characterDiff = new CharacterDiff(); +function diffChars(oldStr, newStr, options) { + return exports.characterDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libcjs/diff/css.js b/node_modules/diff/libcjs/diff/css.js new file mode 100644 index 0000000000000..45c5559c00cc1 --- /dev/null +++ b/node_modules/diff/libcjs/diff/css.js @@ -0,0 +1,34 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.cssDiff = void 0; +exports.diffCss = diffCss; +var base_js_1 = require("./base.js"); +var CssDiff = /** @class */ (function (_super) { + __extends(CssDiff, _super); + function CssDiff() { + return _super !== null && _super.apply(this, arguments) || this; + } + CssDiff.prototype.tokenize = function (value) { + return value.split(/([{}:;,]|\s+)/); + }; + return CssDiff; +}(base_js_1.default)); +exports.cssDiff = new CssDiff(); +function diffCss(oldStr, newStr, options) { + return exports.cssDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libcjs/diff/json.js b/node_modules/diff/libcjs/diff/json.js new file mode 100644 index 0000000000000..15f942b4b9168 --- /dev/null +++ b/node_modules/diff/libcjs/diff/json.js @@ -0,0 +1,105 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsonDiff = void 0; +exports.diffJson = diffJson; +exports.canonicalize = canonicalize; +var base_js_1 = require("./base.js"); +var line_js_1 = require("./line.js"); +var JsonDiff = /** @class */ (function (_super) { + __extends(JsonDiff, _super); + function JsonDiff() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.tokenize = line_js_1.tokenize; + return _this; + } + Object.defineProperty(JsonDiff.prototype, "useLongestToken", { + get: function () { + // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a + // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: + return true; + }, + enumerable: false, + configurable: true + }); + JsonDiff.prototype.castInput = function (value, options) { + var undefinedReplacement = options.undefinedReplacement, _a = options.stringifyReplacer, stringifyReplacer = _a === void 0 ? function (k, v) { return typeof v === 'undefined' ? undefinedReplacement : v; } : _a; + return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), null, ' '); + }; + JsonDiff.prototype.equals = function (left, right, options) { + return _super.prototype.equals.call(this, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'), options); + }; + return JsonDiff; +}(base_js_1.default)); +exports.jsonDiff = new JsonDiff(); +function diffJson(oldStr, newStr, options) { + return exports.jsonDiff.diff(oldStr, newStr, options); +} +// This function handles the presence of circular references by bailing out when encountering an +// object that is already on the "stack" of items being processed. Accepts an optional replacer +function canonicalize(obj, stack, replacementStack, replacer, key) { + stack = stack || []; + replacementStack = replacementStack || []; + if (replacer) { + obj = replacer(key === undefined ? '' : key, obj); + } + var i; + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } + var canonicalizedObj; + if ('[object Array]' === Object.prototype.toString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, String(i)); + } + stack.pop(); + replacementStack.pop(); + return canonicalizedObj; + } + if (obj && obj.toJSON) { + obj = obj.toJSON(); + } + if (typeof obj === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + var sortedKeys = []; + var key_1; + for (key_1 in obj) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(obj, key_1)) { + sortedKeys.push(key_1); + } + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key_1 = sortedKeys[i]; + canonicalizedObj[key_1] = canonicalize(obj[key_1], stack, replacementStack, replacer, key_1); + } + stack.pop(); + replacementStack.pop(); + } + else { + canonicalizedObj = obj; + } + return canonicalizedObj; +} diff --git a/node_modules/diff/libcjs/diff/line.js b/node_modules/diff/libcjs/diff/line.js new file mode 100644 index 0000000000000..8f4a1f412c171 --- /dev/null +++ b/node_modules/diff/libcjs/diff/line.js @@ -0,0 +1,89 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.lineDiff = void 0; +exports.diffLines = diffLines; +exports.diffTrimmedLines = diffTrimmedLines; +exports.tokenize = tokenize; +var base_js_1 = require("./base.js"); +var params_js_1 = require("../util/params.js"); +var LineDiff = /** @class */ (function (_super) { + __extends(LineDiff, _super); + function LineDiff() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.tokenize = tokenize; + return _this; + } + LineDiff.prototype.equals = function (left, right, options) { + // If we're ignoring whitespace, we need to normalise lines by stripping + // whitespace before checking equality. (This has an annoying interaction + // with newlineIsToken that requires special handling: if newlines get their + // own token, then we DON'T want to trim the *newline* tokens down to empty + // strings, since this would cause us to treat whitespace-only line content + // as equal to a separator between lines, which would be weird and + // inconsistent with the documented behavior of the options.) + if (options.ignoreWhitespace) { + if (!options.newlineIsToken || !left.includes('\n')) { + left = left.trim(); + } + if (!options.newlineIsToken || !right.includes('\n')) { + right = right.trim(); + } + } + else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { + if (left.endsWith('\n')) { + left = left.slice(0, -1); + } + if (right.endsWith('\n')) { + right = right.slice(0, -1); + } + } + return _super.prototype.equals.call(this, left, right, options); + }; + return LineDiff; +}(base_js_1.default)); +exports.lineDiff = new LineDiff(); +function diffLines(oldStr, newStr, options) { + return exports.lineDiff.diff(oldStr, newStr, options); +} +function diffTrimmedLines(oldStr, newStr, options) { + options = (0, params_js_1.generateOptions)(options, { ignoreWhitespace: true }); + return exports.lineDiff.diff(oldStr, newStr, options); +} +// Exported standalone so it can be used from jsonDiff too. +function tokenize(value, options) { + if (options.stripTrailingCr) { + // remove one \r before \n to match GNU diff's --strip-trailing-cr behavior + value = value.replace(/\r\n/g, '\n'); + } + var retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } + // Merge the content and line separators into single tokens + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; + if (i % 2 && !options.newlineIsToken) { + retLines[retLines.length - 1] += line; + } + else { + retLines.push(line); + } + } + return retLines; +} diff --git a/node_modules/diff/libcjs/diff/sentence.js b/node_modules/diff/libcjs/diff/sentence.js new file mode 100644 index 0000000000000..dac837fbdc90a --- /dev/null +++ b/node_modules/diff/libcjs/diff/sentence.js @@ -0,0 +1,67 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sentenceDiff = void 0; +exports.diffSentences = diffSentences; +var base_js_1 = require("./base.js"); +function isSentenceEndPunct(char) { + return char == '.' || char == '!' || char == '?'; +} +var SentenceDiff = /** @class */ (function (_super) { + __extends(SentenceDiff, _super); + function SentenceDiff() { + return _super !== null && _super.apply(this, arguments) || this; + } + SentenceDiff.prototype.tokenize = function (value) { + var _a; + // If in future we drop support for environments that don't support lookbehinds, we can replace + // this entire function with: + // return value.split(/(?<=[.!?])(\s+|$)/); + // but until then, for similar reasons to the trailingWs function in string.ts, we are forced + // to do this verbosely "by hand" instead of using a regex. + var result = []; + var tokenStartI = 0; + for (var i = 0; i < value.length; i++) { + if (i == value.length - 1) { + result.push(value.slice(tokenStartI)); + break; + } + if (isSentenceEndPunct(value[i]) && value[i + 1].match(/\s/)) { + // We've hit a sentence break - i.e. a punctuation mark followed by whitespace. + // We now want to push TWO tokens to the result: + // 1. the sentence + result.push(value.slice(tokenStartI, i + 1)); + // 2. the whitespace + i = tokenStartI = i + 1; + while ((_a = value[i + 1]) === null || _a === void 0 ? void 0 : _a.match(/\s/)) { + i++; + } + result.push(value.slice(tokenStartI, i + 1)); + // Then the next token (a sentence) starts on the character after the whitespace. + // (It's okay if this is off the end of the string - then the outer loop will terminate + // here anyway.) + tokenStartI = i + 1; + } + } + return result; + }; + return SentenceDiff; +}(base_js_1.default)); +exports.sentenceDiff = new SentenceDiff(); +function diffSentences(oldStr, newStr, options) { + return exports.sentenceDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libcjs/diff/word.js b/node_modules/diff/libcjs/diff/word.js new file mode 100644 index 0000000000000..e3cf8ba6bc1ee --- /dev/null +++ b/node_modules/diff/libcjs/diff/word.js @@ -0,0 +1,328 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.wordsWithSpaceDiff = exports.wordDiff = void 0; +exports.diffWords = diffWords; +exports.diffWordsWithSpace = diffWordsWithSpace; +var base_js_1 = require("./base.js"); +var string_js_1 = require("../util/string.js"); +// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode +// +// Chars/ranges counted as "word" characters by this regex are as follows: +// +// + U+00AD Soft hyphen +// + 00C0–00FF (letters with diacritics from the Latin-1 Supplement), except: +// - U+00D7 × Multiplication sign +// - U+00F7 ÷ Division sign +// + Latin Extended-A, 0100–017F +// + Latin Extended-B, 0180–024F +// + IPA Extensions, 0250–02AF +// + Spacing Modifier Letters, 02B0–02FF, except: +// - U+02C7 ˇ ˇ Caron +// - U+02D8 ˘ ˘ Breve +// - U+02D9 ˙ ˙ Dot Above +// - U+02DA ˚ ˚ Ring Above +// - U+02DB ˛ ˛ Ogonek +// - U+02DC ˜ ˜ Small Tilde +// - U+02DD ˝ ˝ Double Acute Accent +// + Latin Extended Additional, 1E00–1EFF +var extendedWordChars = 'a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}'; +// Each token is one of the following: +// - A punctuation mark plus the surrounding whitespace +// - A word plus the surrounding whitespace +// - Pure whitespace (but only in the special case where the entire text +// is just whitespace) +// +// We have to include surrounding whitespace in the tokens because the two +// alternative approaches produce horribly broken results: +// * If we just discard the whitespace, we can't fully reproduce the original +// text from the sequence of tokens and any attempt to render the diff will +// get the whitespace wrong. +// * If we have separate tokens for whitespace, then in a typical text every +// second token will be a single space character. But this often results in +// the optimal diff between two texts being a perverse one that preserves +// the spaces between words but deletes and reinserts actual common words. +// See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640 +// for an example. +// +// Keeping the surrounding whitespace of course has implications for .equals +// and .join, not just .tokenize. +// This regex does NOT fully implement the tokenization rules described above. +// Instead, it gives runs of whitespace their own "token". The tokenize method +// then handles stitching whitespace tokens onto adjacent word or punctuation +// tokens. +var tokenizeIncludingWhitespace = new RegExp("[".concat(extendedWordChars, "]+|\\s+|[^").concat(extendedWordChars, "]"), 'ug'); +var WordDiff = /** @class */ (function (_super) { + __extends(WordDiff, _super); + function WordDiff() { + return _super !== null && _super.apply(this, arguments) || this; + } + WordDiff.prototype.equals = function (left, right, options) { + if (options.ignoreCase) { + left = left.toLowerCase(); + right = right.toLowerCase(); + } + return left.trim() === right.trim(); + }; + WordDiff.prototype.tokenize = function (value, options) { + if (options === void 0) { options = {}; } + var parts; + if (options.intlSegmenter) { + var segmenter = options.intlSegmenter; + if (segmenter.resolvedOptions().granularity != 'word') { + throw new Error('The segmenter passed must have a granularity of "word"'); + } + // We want `parts` to be an array whose elements alternate between being + // pure whitespace and being pure non-whitespace. This is ALMOST what the + // segments returned by a word-based Intl.Segmenter already look like, + // and therefore we can ALMOST get what we want by simply doing... + // parts = Array.from(segmenter.segment(value), segment => segment.segment); + // ... but not QUITE, because there's of one annoying special case: every + // newline character gets its own segment, instead of sharing a segment + // with other surrounding whitespace. We therefore need to manually merge + // consecutive segments of whitespace into a single part: + parts = []; + for (var _i = 0, _a = Array.from(segmenter.segment(value)); _i < _a.length; _i++) { + var segmentObj = _a[_i]; + var segment = segmentObj.segment; + if (parts.length && (/\s/).test(parts[parts.length - 1]) && (/\s/).test(segment)) { + parts[parts.length - 1] += segment; + } + else { + parts.push(segment); + } + } + } + else { + parts = value.match(tokenizeIncludingWhitespace) || []; + } + var tokens = []; + var prevPart = null; + parts.forEach(function (part) { + if ((/\s/).test(part)) { + if (prevPart == null) { + tokens.push(part); + } + else { + tokens.push(tokens.pop() + part); + } + } + else if (prevPart != null && (/\s/).test(prevPart)) { + if (tokens[tokens.length - 1] == prevPart) { + tokens.push(tokens.pop() + part); + } + else { + tokens.push(prevPart + part); + } + } + else { + tokens.push(part); + } + prevPart = part; + }); + return tokens; + }; + WordDiff.prototype.join = function (tokens) { + // Tokens being joined here will always have appeared consecutively in the + // same text, so we can simply strip off the leading whitespace from all the + // tokens except the first (and except any whitespace-only tokens - but such + // a token will always be the first and only token anyway) and then join them + // and the whitespace around words and punctuation will end up correct. + return tokens.map(function (token, i) { + if (i == 0) { + return token; + } + else { + return token.replace((/^\s+/), ''); + } + }).join(''); + }; + WordDiff.prototype.postProcess = function (changes, options) { + if (!changes || options.oneChangePerToken) { + return changes; + } + var lastKeep = null; + // Change objects representing any insertion or deletion since the last + // "keep" change object. There can be at most one of each. + var insertion = null; + var deletion = null; + changes.forEach(function (change) { + if (change.added) { + insertion = change; + } + else if (change.removed) { + deletion = change; + } + else { + if (insertion || deletion) { // May be false at start of text + dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change); + } + lastKeep = change; + insertion = null; + deletion = null; + } + }); + if (insertion || deletion) { + dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null); + } + return changes; + }; + return WordDiff; +}(base_js_1.default)); +exports.wordDiff = new WordDiff(); +function diffWords(oldStr, newStr, options) { + // This option has never been documented and never will be (it's clearer to + // just call `diffWordsWithSpace` directly if you need that behavior), but + // has existed in jsdiff for a long time, so we retain support for it here + // for the sake of backwards compatibility. + if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) { + return diffWordsWithSpace(oldStr, newStr, options); + } + return exports.wordDiff.diff(oldStr, newStr, options); +} +function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) { + // Before returning, we tidy up the leading and trailing whitespace of the + // change objects to eliminate cases where trailing whitespace in one object + // is repeated as leading whitespace in the next. + // Below are examples of the outcomes we want here to explain the code. + // I=insert, K=keep, D=delete + // 1. diffing 'foo bar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz' + // After cleanup, we want: K:'foo ' D:'bar ' K:'baz' + // + // 2. Diffing 'foo bar baz' vs 'foo qux baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz' + // After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz' + // + // 3. Diffing 'foo\nbar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:'\nbar ' K:' baz' + // After cleanup, we want K'foo' D:'\nbar' K:' baz' + // + // 4. Diffing 'foo baz' vs 'foo\nbar baz' + // Prior to cleanup, we have K:'foo\n' I:'\nbar ' K:' baz' + // After cleanup, we ideally want K'foo' I:'\nbar' K:' baz' + // but don't actually manage this currently (the pre-cleanup change + // objects don't contain enough information to make it possible). + // + // 5. Diffing 'foo bar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz' + // After cleanup, we want K:'foo ' D:' bar ' K:'baz' + // + // Our handling is unavoidably imperfect in the case where there's a single + // indel between keeps and the whitespace has changed. For instance, consider + // diffing 'foo\tbar\nbaz' vs 'foo baz'. Unless we create an extra change + // object to represent the insertion of the space character (which isn't even + // a token), we have no way to avoid losing information about the texts' + // original whitespace in the result we return. Still, we do our best to + // output something that will look sensible if we e.g. print it with + // insertions in green and deletions in red. + // Between two "keep" change objects (or before the first or after the last + // change object), we can have either: + // * A "delete" followed by an "insert" + // * Just an "insert" + // * Just a "delete" + // We handle the three cases separately. + if (deletion && insertion) { + var oldWsPrefix = (0, string_js_1.leadingWs)(deletion.value); + var oldWsSuffix = (0, string_js_1.trailingWs)(deletion.value); + var newWsPrefix = (0, string_js_1.leadingWs)(insertion.value); + var newWsSuffix = (0, string_js_1.trailingWs)(insertion.value); + if (startKeep) { + var commonWsPrefix = (0, string_js_1.longestCommonPrefix)(oldWsPrefix, newWsPrefix); + startKeep.value = (0, string_js_1.replaceSuffix)(startKeep.value, newWsPrefix, commonWsPrefix); + deletion.value = (0, string_js_1.removePrefix)(deletion.value, commonWsPrefix); + insertion.value = (0, string_js_1.removePrefix)(insertion.value, commonWsPrefix); + } + if (endKeep) { + var commonWsSuffix = (0, string_js_1.longestCommonSuffix)(oldWsSuffix, newWsSuffix); + endKeep.value = (0, string_js_1.replacePrefix)(endKeep.value, newWsSuffix, commonWsSuffix); + deletion.value = (0, string_js_1.removeSuffix)(deletion.value, commonWsSuffix); + insertion.value = (0, string_js_1.removeSuffix)(insertion.value, commonWsSuffix); + } + } + else if (insertion) { + // The whitespaces all reflect what was in the new text rather than + // the old, so we essentially have no information about whitespace + // insertion or deletion. We just want to dedupe the whitespace. + // We do that by having each change object keep its trailing + // whitespace and deleting duplicate leading whitespace where + // present. + if (startKeep) { + var ws = (0, string_js_1.leadingWs)(insertion.value); + insertion.value = insertion.value.substring(ws.length); + } + if (endKeep) { + var ws = (0, string_js_1.leadingWs)(endKeep.value); + endKeep.value = endKeep.value.substring(ws.length); + } + // otherwise we've got a deletion and no insertion + } + else if (startKeep && endKeep) { + var newWsFull = (0, string_js_1.leadingWs)(endKeep.value), delWsStart = (0, string_js_1.leadingWs)(deletion.value), delWsEnd = (0, string_js_1.trailingWs)(deletion.value); + // Any whitespace that comes straight after startKeep in both the old and + // new texts, assign to startKeep and remove from the deletion. + var newWsStart = (0, string_js_1.longestCommonPrefix)(newWsFull, delWsStart); + deletion.value = (0, string_js_1.removePrefix)(deletion.value, newWsStart); + // Any whitespace that comes straight before endKeep in both the old and + // new texts, and hasn't already been assigned to startKeep, assign to + // endKeep and remove from the deletion. + var newWsEnd = (0, string_js_1.longestCommonSuffix)((0, string_js_1.removePrefix)(newWsFull, newWsStart), delWsEnd); + deletion.value = (0, string_js_1.removeSuffix)(deletion.value, newWsEnd); + endKeep.value = (0, string_js_1.replacePrefix)(endKeep.value, newWsFull, newWsEnd); + // If there's any whitespace from the new text that HASN'T already been + // assigned, assign it to the start: + startKeep.value = (0, string_js_1.replaceSuffix)(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length)); + } + else if (endKeep) { + // We are at the start of the text. Preserve all the whitespace on + // endKeep, and just remove whitespace from the end of deletion to the + // extent that it overlaps with the start of endKeep. + var endKeepWsPrefix = (0, string_js_1.leadingWs)(endKeep.value); + var deletionWsSuffix = (0, string_js_1.trailingWs)(deletion.value); + var overlap = (0, string_js_1.maximumOverlap)(deletionWsSuffix, endKeepWsPrefix); + deletion.value = (0, string_js_1.removeSuffix)(deletion.value, overlap); + } + else if (startKeep) { + // We are at the END of the text. Preserve all the whitespace on + // startKeep, and just remove whitespace from the start of deletion to + // the extent that it overlaps with the end of startKeep. + var startKeepWsSuffix = (0, string_js_1.trailingWs)(startKeep.value); + var deletionWsPrefix = (0, string_js_1.leadingWs)(deletion.value); + var overlap = (0, string_js_1.maximumOverlap)(startKeepWsSuffix, deletionWsPrefix); + deletion.value = (0, string_js_1.removePrefix)(deletion.value, overlap); + } +} +var WordsWithSpaceDiff = /** @class */ (function (_super) { + __extends(WordsWithSpaceDiff, _super); + function WordsWithSpaceDiff() { + return _super !== null && _super.apply(this, arguments) || this; + } + WordsWithSpaceDiff.prototype.tokenize = function (value) { + // Slightly different to the tokenizeIncludingWhitespace regex used above in + // that this one treats each individual newline as a distinct token, rather + // than merging them into other surrounding whitespace. This was requested + // in https://github.com/kpdecker/jsdiff/issues/180 & + // https://github.com/kpdecker/jsdiff/issues/211 + var regex = new RegExp("(\\r?\\n)|[".concat(extendedWordChars, "]+|[^\\S\\n\\r]+|[^").concat(extendedWordChars, "]"), 'ug'); + return value.match(regex) || []; + }; + return WordsWithSpaceDiff; +}(base_js_1.default)); +exports.wordsWithSpaceDiff = new WordsWithSpaceDiff(); +function diffWordsWithSpace(oldStr, newStr, options) { + return exports.wordsWithSpaceDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libcjs/index.js b/node_modules/diff/libcjs/index.js new file mode 100644 index 0000000000000..3ad381e4f3460 --- /dev/null +++ b/node_modules/diff/libcjs/index.js @@ -0,0 +1,64 @@ +"use strict"; +/* See LICENSE file for terms of use */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.canonicalize = exports.convertChangesToXML = exports.convertChangesToDMP = exports.reversePatch = exports.parsePatch = exports.applyPatches = exports.applyPatch = exports.OMIT_HEADERS = exports.FILE_HEADERS_ONLY = exports.INCLUDE_HEADERS = exports.formatPatch = exports.createPatch = exports.createTwoFilesPatch = exports.structuredPatch = exports.arrayDiff = exports.diffArrays = exports.jsonDiff = exports.diffJson = exports.cssDiff = exports.diffCss = exports.sentenceDiff = exports.diffSentences = exports.diffTrimmedLines = exports.lineDiff = exports.diffLines = exports.wordsWithSpaceDiff = exports.diffWordsWithSpace = exports.wordDiff = exports.diffWords = exports.characterDiff = exports.diffChars = exports.Diff = void 0; +/* + * Text diff implementation. + * + * This library supports the following APIs: + * Diff.diffChars: Character by character diff + * Diff.diffWords: Word (as defined by \b regex) diff which ignores whitespace + * Diff.diffLines: Line based diff + * + * Diff.diffCss: Diff targeted at CSS content + * + * These methods are based on the implementation proposed in + * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 + */ +var base_js_1 = require("./diff/base.js"); +exports.Diff = base_js_1.default; +var character_js_1 = require("./diff/character.js"); +Object.defineProperty(exports, "diffChars", { enumerable: true, get: function () { return character_js_1.diffChars; } }); +Object.defineProperty(exports, "characterDiff", { enumerable: true, get: function () { return character_js_1.characterDiff; } }); +var word_js_1 = require("./diff/word.js"); +Object.defineProperty(exports, "diffWords", { enumerable: true, get: function () { return word_js_1.diffWords; } }); +Object.defineProperty(exports, "diffWordsWithSpace", { enumerable: true, get: function () { return word_js_1.diffWordsWithSpace; } }); +Object.defineProperty(exports, "wordDiff", { enumerable: true, get: function () { return word_js_1.wordDiff; } }); +Object.defineProperty(exports, "wordsWithSpaceDiff", { enumerable: true, get: function () { return word_js_1.wordsWithSpaceDiff; } }); +var line_js_1 = require("./diff/line.js"); +Object.defineProperty(exports, "diffLines", { enumerable: true, get: function () { return line_js_1.diffLines; } }); +Object.defineProperty(exports, "diffTrimmedLines", { enumerable: true, get: function () { return line_js_1.diffTrimmedLines; } }); +Object.defineProperty(exports, "lineDiff", { enumerable: true, get: function () { return line_js_1.lineDiff; } }); +var sentence_js_1 = require("./diff/sentence.js"); +Object.defineProperty(exports, "diffSentences", { enumerable: true, get: function () { return sentence_js_1.diffSentences; } }); +Object.defineProperty(exports, "sentenceDiff", { enumerable: true, get: function () { return sentence_js_1.sentenceDiff; } }); +var css_js_1 = require("./diff/css.js"); +Object.defineProperty(exports, "diffCss", { enumerable: true, get: function () { return css_js_1.diffCss; } }); +Object.defineProperty(exports, "cssDiff", { enumerable: true, get: function () { return css_js_1.cssDiff; } }); +var json_js_1 = require("./diff/json.js"); +Object.defineProperty(exports, "diffJson", { enumerable: true, get: function () { return json_js_1.diffJson; } }); +Object.defineProperty(exports, "canonicalize", { enumerable: true, get: function () { return json_js_1.canonicalize; } }); +Object.defineProperty(exports, "jsonDiff", { enumerable: true, get: function () { return json_js_1.jsonDiff; } }); +var array_js_1 = require("./diff/array.js"); +Object.defineProperty(exports, "diffArrays", { enumerable: true, get: function () { return array_js_1.diffArrays; } }); +Object.defineProperty(exports, "arrayDiff", { enumerable: true, get: function () { return array_js_1.arrayDiff; } }); +var apply_js_1 = require("./patch/apply.js"); +Object.defineProperty(exports, "applyPatch", { enumerable: true, get: function () { return apply_js_1.applyPatch; } }); +Object.defineProperty(exports, "applyPatches", { enumerable: true, get: function () { return apply_js_1.applyPatches; } }); +var parse_js_1 = require("./patch/parse.js"); +Object.defineProperty(exports, "parsePatch", { enumerable: true, get: function () { return parse_js_1.parsePatch; } }); +var reverse_js_1 = require("./patch/reverse.js"); +Object.defineProperty(exports, "reversePatch", { enumerable: true, get: function () { return reverse_js_1.reversePatch; } }); +var create_js_1 = require("./patch/create.js"); +Object.defineProperty(exports, "structuredPatch", { enumerable: true, get: function () { return create_js_1.structuredPatch; } }); +Object.defineProperty(exports, "createTwoFilesPatch", { enumerable: true, get: function () { return create_js_1.createTwoFilesPatch; } }); +Object.defineProperty(exports, "createPatch", { enumerable: true, get: function () { return create_js_1.createPatch; } }); +Object.defineProperty(exports, "formatPatch", { enumerable: true, get: function () { return create_js_1.formatPatch; } }); +Object.defineProperty(exports, "INCLUDE_HEADERS", { enumerable: true, get: function () { return create_js_1.INCLUDE_HEADERS; } }); +Object.defineProperty(exports, "FILE_HEADERS_ONLY", { enumerable: true, get: function () { return create_js_1.FILE_HEADERS_ONLY; } }); +Object.defineProperty(exports, "OMIT_HEADERS", { enumerable: true, get: function () { return create_js_1.OMIT_HEADERS; } }); +var dmp_js_1 = require("./convert/dmp.js"); +Object.defineProperty(exports, "convertChangesToDMP", { enumerable: true, get: function () { return dmp_js_1.convertChangesToDMP; } }); +var xml_js_1 = require("./convert/xml.js"); +Object.defineProperty(exports, "convertChangesToXML", { enumerable: true, get: function () { return xml_js_1.convertChangesToXML; } }); diff --git a/node_modules/diff/libcjs/package.json b/node_modules/diff/libcjs/package.json new file mode 100644 index 0000000000000..731cf3f1d319d --- /dev/null +++ b/node_modules/diff/libcjs/package.json @@ -0,0 +1 @@ +{"type":"commonjs","sideEffects":false} \ No newline at end of file diff --git a/node_modules/diff/libcjs/patch/apply.js b/node_modules/diff/libcjs/patch/apply.js new file mode 100644 index 0000000000000..4f49c7c6d08b4 --- /dev/null +++ b/node_modules/diff/libcjs/patch/apply.js @@ -0,0 +1,267 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.applyPatch = applyPatch; +exports.applyPatches = applyPatches; +var string_js_1 = require("../util/string.js"); +var line_endings_js_1 = require("./line-endings.js"); +var parse_js_1 = require("./parse.js"); +var distance_iterator_js_1 = require("../util/distance-iterator.js"); +/** + * attempts to apply a unified diff patch. + * + * Hunks are applied first to last. + * `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly. + * If that fails, it tries scanning backwards and forwards, one line at a time, to find a place to apply the hunk where the context lines match exactly. + * If that still fails, and `fuzzFactor` is greater than zero, it increments the maximum number of mismatches (missing, extra, or changed context lines) that there can be between the hunk context and a region where we are trying to apply the patch such that the hunk will still be considered to match. + * Regardless of `fuzzFactor`, lines to be deleted in the hunk *must* be present for a hunk to match, and the context lines *immediately* before and after an insertion must match exactly. + * + * Once a hunk is successfully fitted, the process begins again with the next hunk. + * Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks. + * + * If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`. + * + * If a hunk is successfully fitted but not at the line number specified by the hunk header, all subsequent hunks have their target line number adjusted accordingly. + * (e.g. if the first hunk is applied 10 lines below where the hunk header said it should fit, `applyPatch` will *start* looking for somewhere to apply the second hunk 10 lines below where its hunk header says it goes.) + * + * If the patch was applied successfully, returns a string containing the patched text. + * If the patch could not be applied (because some hunks in the patch couldn't be fitted to the text in `source`), `applyPatch` returns false. + * + * @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods. + */ +function applyPatch(source, patch, options) { + if (options === void 0) { options = {}; } + var patches; + if (typeof patch === 'string') { + patches = (0, parse_js_1.parsePatch)(patch); + } + else if (Array.isArray(patch)) { + patches = patch; + } + else { + patches = [patch]; + } + if (patches.length > 1) { + throw new Error('applyPatch only works with a single input.'); + } + return applyStructuredPatch(source, patches[0], options); +} +function applyStructuredPatch(source, patch, options) { + if (options === void 0) { options = {}; } + if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) { + if ((0, string_js_1.hasOnlyWinLineEndings)(source) && (0, line_endings_js_1.isUnix)(patch)) { + patch = (0, line_endings_js_1.unixToWin)(patch); + } + else if ((0, string_js_1.hasOnlyUnixLineEndings)(source) && (0, line_endings_js_1.isWin)(patch)) { + patch = (0, line_endings_js_1.winToUnix)(patch); + } + } + // Apply the diff to the input + var lines = source.split('\n'), hunks = patch.hunks, compareLine = options.compareLine || (function (lineNumber, line, operation, patchContent) { return line === patchContent; }), fuzzFactor = options.fuzzFactor || 0; + var minLine = 0; + if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) { + throw new Error('fuzzFactor must be a non-negative integer'); + } + // Special case for empty patch. + if (!hunks.length) { + return source; + } + // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change + // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a + // newline that already exists - then we either return false and fail to apply the patch (if + // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0). + // If we do need to remove/add a newline at EOF, this will always be in the final hunk: + var prevLine = '', removeEOFNL = false, addEOFNL = false; + for (var i = 0; i < hunks[hunks.length - 1].lines.length; i++) { + var line = hunks[hunks.length - 1].lines[i]; + if (line[0] == '\\') { + if (prevLine[0] == '+') { + removeEOFNL = true; + } + else if (prevLine[0] == '-') { + addEOFNL = true; + } + } + prevLine = line; + } + if (removeEOFNL) { + if (addEOFNL) { + // This means the final line gets changed but doesn't have a trailing newline in either the + // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if + // fuzzFactor is 0, we simply validate that the source file has no trailing newline. + if (!fuzzFactor && lines[lines.length - 1] == '') { + return false; + } + } + else if (lines[lines.length - 1] == '') { + lines.pop(); + } + else if (!fuzzFactor) { + return false; + } + } + else if (addEOFNL) { + if (lines[lines.length - 1] != '') { + lines.push(''); + } + else if (!fuzzFactor) { + return false; + } + } + /** + * Checks if the hunk can be made to fit at the provided location with at most `maxErrors` + * insertions, substitutions, or deletions, while ensuring also that: + * - lines deleted in the hunk match exactly, and + * - wherever an insertion operation or block of insertion operations appears in the hunk, the + * immediately preceding and following lines of context match exactly + * + * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0]. + * + * If the hunk can be applied, returns an object with properties `oldLineLastI` and + * `replacementLines`. Otherwise, returns null. + */ + function applyHunk(hunkLines, toPos, maxErrors, hunkLinesI, lastContextLineMatched, patchedLines, patchedLinesLength) { + if (hunkLinesI === void 0) { hunkLinesI = 0; } + if (lastContextLineMatched === void 0) { lastContextLineMatched = true; } + if (patchedLines === void 0) { patchedLines = []; } + if (patchedLinesLength === void 0) { patchedLinesLength = 0; } + var nConsecutiveOldContextLines = 0; + var nextContextLineMustMatch = false; + for (; hunkLinesI < hunkLines.length; hunkLinesI++) { + var hunkLine = hunkLines[hunkLinesI], operation = (hunkLine.length > 0 ? hunkLine[0] : ' '), content = (hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine); + if (operation === '-') { + if (compareLine(toPos + 1, lines[toPos], operation, content)) { + toPos++; + nConsecutiveOldContextLines = 0; + } + else { + if (!maxErrors || lines[toPos] == null) { + return null; + } + patchedLines[patchedLinesLength] = lines[toPos]; + return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1); + } + } + if (operation === '+') { + if (!lastContextLineMatched) { + return null; + } + patchedLines[patchedLinesLength] = content; + patchedLinesLength++; + nConsecutiveOldContextLines = 0; + nextContextLineMustMatch = true; + } + if (operation === ' ') { + nConsecutiveOldContextLines++; + patchedLines[patchedLinesLength] = lines[toPos]; + if (compareLine(toPos + 1, lines[toPos], operation, content)) { + patchedLinesLength++; + lastContextLineMatched = true; + nextContextLineMustMatch = false; + toPos++; + } + else { + if (nextContextLineMustMatch || !maxErrors) { + return null; + } + // Consider 3 possibilities in sequence: + // 1. lines contains a *substitution* not included in the patch context, or + // 2. lines contains an *insertion* not included in the patch context, or + // 3. lines contains a *deletion* not included in the patch context + // The first two options are of course only possible if the line from lines is non-null - + // i.e. only option 3 is possible if we've overrun the end of the old file. + return (lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength)); + } + } + } + // Before returning, trim any unmodified context lines off the end of patchedLines and reduce + // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region + // that starts in this hunk's trailing context. + patchedLinesLength -= nConsecutiveOldContextLines; + toPos -= nConsecutiveOldContextLines; + patchedLines.length = patchedLinesLength; + return { + patchedLines: patchedLines, + oldLineLastI: toPos - 1 + }; + } + var resultLines = []; + // Search best fit offsets for each hunk based on the previous ones + var prevHunkOffset = 0; + for (var i = 0; i < hunks.length; i++) { + var hunk = hunks[i]; + var hunkResult = void 0; + var maxLine = lines.length - hunk.oldLines + fuzzFactor; + var toPos = void 0; + for (var maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) { + toPos = hunk.oldStart + prevHunkOffset - 1; + var iterator = (0, distance_iterator_js_1.default)(toPos, minLine, maxLine); + for (; toPos !== undefined; toPos = iterator()) { + hunkResult = applyHunk(hunk.lines, toPos, maxErrors); + if (hunkResult) { + break; + } + } + if (hunkResult) { + break; + } + } + if (!hunkResult) { + return false; + } + // Copy everything from the end of where we applied the last hunk to the start of this hunk + for (var i_1 = minLine; i_1 < toPos; i_1++) { + resultLines.push(lines[i_1]); + } + // Add the lines produced by applying the hunk: + for (var i_2 = 0; i_2 < hunkResult.patchedLines.length; i_2++) { + var line = hunkResult.patchedLines[i_2]; + resultLines.push(line); + } + // Set lower text limit to end of the current hunk, so next ones don't try + // to fit over already patched text + minLine = hunkResult.oldLineLastI + 1; + // Note the offset between where the patch said the hunk should've applied and where we + // applied it, so we can adjust future hunks accordingly: + prevHunkOffset = toPos + 1 - hunk.oldStart; + } + // Copy over the rest of the lines from the old text + for (var i = minLine; i < lines.length; i++) { + resultLines.push(lines[i]); + } + return resultLines.join('\n'); +} +/** + * applies one or more patches. + * + * `patch` may be either an array of structured patch objects, or a string representing a patch in unified diff format (which may patch one or more files). + * + * This method will iterate over the contents of the patch and apply to data provided through callbacks. The general flow for each patch index is: + * + * - `options.loadFile(index, callback)` is called. The caller should then load the contents of the file and then pass that to the `callback(err, data)` callback. Passing an `err` will terminate further patch execution. + * - `options.patched(index, content, callback)` is called once the patch has been applied. `content` will be the return value from `applyPatch`. When it's ready, the caller should call `callback(err)` callback. Passing an `err` will terminate further patch execution. + * + * Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made. + */ +function applyPatches(uniDiff, options) { + var spDiff = typeof uniDiff === 'string' ? (0, parse_js_1.parsePatch)(uniDiff) : uniDiff; + var currentIndex = 0; + function processIndex() { + var index = spDiff[currentIndex++]; + if (!index) { + return options.complete(); + } + options.loadFile(index, function (err, data) { + if (err) { + return options.complete(err); + } + var updatedContent = applyPatch(data, index, options); + options.patched(index, updatedContent, function (err) { + if (err) { + return options.complete(err); + } + processIndex(); + }); + }); + } + processIndex(); +} diff --git a/node_modules/diff/libcjs/patch/create.js b/node_modules/diff/libcjs/patch/create.js new file mode 100644 index 0000000000000..d9328c2e7709f --- /dev/null +++ b/node_modules/diff/libcjs/patch/create.js @@ -0,0 +1,251 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.OMIT_HEADERS = exports.FILE_HEADERS_ONLY = exports.INCLUDE_HEADERS = void 0; +exports.structuredPatch = structuredPatch; +exports.formatPatch = formatPatch; +exports.createTwoFilesPatch = createTwoFilesPatch; +exports.createPatch = createPatch; +var line_js_1 = require("../diff/line.js"); +exports.INCLUDE_HEADERS = { + includeIndex: true, + includeUnderline: true, + includeFileHeaders: true +}; +exports.FILE_HEADERS_ONLY = { + includeIndex: false, + includeUnderline: false, + includeFileHeaders: true +}; +exports.OMIT_HEADERS = { + includeIndex: false, + includeUnderline: false, + includeFileHeaders: false +}; +function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + var optionsObj; + if (!options) { + optionsObj = {}; + } + else if (typeof options === 'function') { + optionsObj = { callback: options }; + } + else { + optionsObj = options; + } + if (typeof optionsObj.context === 'undefined') { + optionsObj.context = 4; + } + // We copy this into its own variable to placate TypeScript, which thinks + // optionsObj.context might be undefined in the callbacks below. + var context = optionsObj.context; + // @ts-expect-error (runtime check for something that is correctly a static type error) + if (optionsObj.newlineIsToken) { + throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions'); + } + if (!optionsObj.callback) { + return diffLinesResultToPatch((0, line_js_1.diffLines)(oldStr, newStr, optionsObj)); + } + else { + var callback_1 = optionsObj.callback; + (0, line_js_1.diffLines)(oldStr, newStr, __assign(__assign({}, optionsObj), { callback: function (diff) { + var patch = diffLinesResultToPatch(diff); + // TypeScript is unhappy without the cast because it does not understand that `patch` may + // be undefined here only if `callback` is StructuredPatchCallbackAbortable: + callback_1(patch); + } })); + } + function diffLinesResultToPatch(diff) { + // STEP 1: Build up the patch with no "\ No newline at end of file" lines and with the arrays + // of lines containing trailing newline characters. We'll tidy up later... + if (!diff) { + return; + } + diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier + function contextLines(lines) { + return lines.map(function (entry) { return ' ' + entry; }); + } + var hunks = []; + var oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1; + for (var i = 0; i < diff.length; i++) { + var current = diff[i], lines = current.lines || splitLines(current.value); + current.lines = lines; + if (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + var prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; + if (prev) { + curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : []; + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } + // Output our changes + for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) { + var line = lines_1[_i]; + curRange.push((current.added ? '+' : '-') + line); + } + // Track the updated file position + if (current.added) { + newLine += lines.length; + } + else { + oldLine += lines.length; + } + } + else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= context * 2 && i < diff.length - 2) { + // Overlapping + for (var _a = 0, _b = contextLines(lines); _a < _b.length; _a++) { + var line = _b[_a]; + curRange.push(line); + } + } + else { + // end the range and output + var contextSize = Math.min(lines.length, context); + for (var _c = 0, _d = contextLines(lines.slice(0, contextSize)); _c < _d.length; _c++) { + var line = _d[_c]; + curRange.push(line); + } + var hunk = { + oldStart: oldRangeStart, + oldLines: (oldLine - oldRangeStart + contextSize), + newStart: newRangeStart, + newLines: (newLine - newRangeStart + contextSize), + lines: curRange + }; + hunks.push(hunk); + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } + // Step 2: eliminate the trailing `\n` from each line of each hunk, and, where needed, add + // "\ No newline at end of file". + for (var _e = 0, hunks_1 = hunks; _e < hunks_1.length; _e++) { + var hunk = hunks_1[_e]; + for (var i = 0; i < hunk.lines.length; i++) { + if (hunk.lines[i].endsWith('\n')) { + hunk.lines[i] = hunk.lines[i].slice(0, -1); + } + else { + hunk.lines.splice(i + 1, 0, '\\ No newline at end of file'); + i++; // Skip the line we just added, then continue iterating + } + } + } + return { + oldFileName: oldFileName, newFileName: newFileName, + oldHeader: oldHeader, newHeader: newHeader, + hunks: hunks + }; + } +} +/** + * creates a unified diff patch. + * @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`) + */ +function formatPatch(patch, headerOptions) { + if (!headerOptions) { + headerOptions = exports.INCLUDE_HEADERS; + } + if (Array.isArray(patch)) { + if (patch.length > 1 && !headerOptions.includeFileHeaders) { + throw new Error('Cannot omit file headers on a multi-file patch. ' + + '(The result would be unparseable; how would a tool trying to apply ' + + 'the patch know which changes are to which file?)'); + } + return patch.map(function (p) { return formatPatch(p, headerOptions); }).join('\n'); + } + var ret = []; + if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) { + ret.push('Index: ' + patch.oldFileName); + } + if (headerOptions.includeUnderline) { + ret.push('==================================================================='); + } + if (headerOptions.includeFileHeaders) { + ret.push('--- ' + patch.oldFileName + (typeof patch.oldHeader === 'undefined' ? '' : '\t' + patch.oldHeader)); + ret.push('+++ ' + patch.newFileName + (typeof patch.newHeader === 'undefined' ? '' : '\t' + patch.newHeader)); + } + for (var i = 0; i < patch.hunks.length; i++) { + var hunk = patch.hunks[i]; + // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + if (hunk.oldLines === 0) { + hunk.oldStart -= 1; + } + if (hunk.newLines === 0) { + hunk.newStart -= 1; + } + ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + + ' +' + hunk.newStart + ',' + hunk.newLines + + ' @@'); + for (var _i = 0, _a = hunk.lines; _i < _a.length; _i++) { + var line = _a[_i]; + ret.push(line); + } + } + return ret.join('\n') + '\n'; +} +function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + if (typeof options === 'function') { + options = { callback: options }; + } + if (!(options === null || options === void 0 ? void 0 : options.callback)) { + var patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); + if (!patchObj) { + return; + } + return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions); + } + else { + var callback_2 = options.callback; + structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, __assign(__assign({}, options), { callback: function (patchObj) { + if (!patchObj) { + callback_2(undefined); + } + else { + callback_2(formatPatch(patchObj, options.headerOptions)); + } + } })); + } +} +function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { + return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); +} +/** + * Split `text` into an array of lines, including the trailing newline character (where present) + */ +function splitLines(text) { + var hasTrailingNl = text.endsWith('\n'); + var result = text.split('\n').map(function (line) { return line + '\n'; }); + if (hasTrailingNl) { + result.pop(); + } + else { + result.push(result.pop().slice(0, -1)); + } + return result; +} diff --git a/node_modules/diff/libcjs/patch/line-endings.js b/node_modules/diff/libcjs/patch/line-endings.js new file mode 100644 index 0000000000000..be45f0c8a326f --- /dev/null +++ b/node_modules/diff/libcjs/patch/line-endings.js @@ -0,0 +1,61 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unixToWin = unixToWin; +exports.winToUnix = winToUnix; +exports.isUnix = isUnix; +exports.isWin = isWin; +function unixToWin(patch) { + if (Array.isArray(patch)) { + // It would be cleaner if instead of the line below we could just write + // return patch.map(unixToWin) + // but mysteriously TypeScript (v5.7.3 at the time of writing) does not like this and it will + // refuse to compile, thinking that unixToWin could then return StructuredPatch[][] and the + // result would be incompatible with the overload signatures. + // See bug report at https://github.com/microsoft/TypeScript/issues/61398. + return patch.map(function (p) { return unixToWin(p); }); + } + return __assign(__assign({}, patch), { hunks: patch.hunks.map(function (hunk) { return (__assign(__assign({}, hunk), { lines: hunk.lines.map(function (line, i) { + var _a; + return (line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))) + ? line + : line + '\r'; + }) })); }) }); +} +function winToUnix(patch) { + if (Array.isArray(patch)) { + // (See comment above equivalent line in unixToWin) + return patch.map(function (p) { return winToUnix(p); }); + } + return __assign(__assign({}, patch), { hunks: patch.hunks.map(function (hunk) { return (__assign(__assign({}, hunk), { lines: hunk.lines.map(function (line) { return line.endsWith('\r') ? line.substring(0, line.length - 1) : line; }) })); }) }); +} +/** + * Returns true if the patch consistently uses Unix line endings (or only involves one line and has + * no line endings). + */ +function isUnix(patch) { + if (!Array.isArray(patch)) { + patch = [patch]; + } + return !patch.some(function (index) { return index.hunks.some(function (hunk) { return hunk.lines.some(function (line) { return !line.startsWith('\\') && line.endsWith('\r'); }); }); }); +} +/** + * Returns true if the patch uses Windows line endings and only Windows line endings. + */ +function isWin(patch) { + if (!Array.isArray(patch)) { + patch = [patch]; + } + return patch.some(function (index) { return index.hunks.some(function (hunk) { return hunk.lines.some(function (line) { return line.endsWith('\r'); }); }); }) + && patch.every(function (index) { return index.hunks.every(function (hunk) { return hunk.lines.every(function (line, i) { var _a; return line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\')); }); }); }); +} diff --git a/node_modules/diff/libcjs/patch/parse.js b/node_modules/diff/libcjs/patch/parse.js new file mode 100644 index 0000000000000..f2769cff9a537 --- /dev/null +++ b/node_modules/diff/libcjs/patch/parse.js @@ -0,0 +1,150 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.parsePatch = parsePatch; +/** + * Parses a patch into structured data, in the same structure returned by `structuredPatch`. + * + * @return a JSON object representation of the a patch, suitable for use with the `applyPatch` method. + */ +function parsePatch(uniDiff) { + var diffstr = uniDiff.split(/\n/), list = []; + var i = 0; + function parseIndex() { + var index = {}; + list.push(index); + // Parse diff metadata + while (i < diffstr.length) { + var line = diffstr[i]; + // File header found, end parsing diff metadata + if ((/^(---|\+\+\+|@@)\s/).test(line)) { + break; + } + // Try to parse the line as a diff header, like + // Index: README.md + // or + // diff -r 9117c6561b0b -r 273ce12ad8f1 .hgignore + // or + // Index: something with multiple words + // and extract the filename (or whatever else is used as an index name) + // from the end (i.e. 'README.md', '.hgignore', or + // 'something with multiple words' in the examples above). + // + // TODO: It seems awkward that we indiscriminately trim off trailing + // whitespace here. Theoretically, couldn't that be meaningful - + // e.g. if the patch represents a diff of a file whose name ends + // with a space? Seems wrong to nuke it. + // But this behaviour has been around since v2.2.1 in 2015, so if + // it's going to change, it should be done cautiously and in a new + // major release, for backwards-compat reasons. + // -- ExplodingCabbage + var headerMatch = (/^(?:Index:|diff(?: -r \w+)+)\s+/).exec(line); + if (headerMatch) { + index.index = line.substring(headerMatch[0].length).trim(); + } + i++; + } + // Parse file headers if they are defined. Unified diff requires them, but + // there's no technical issues to have an isolated hunk without file header + parseFileHeader(index); + parseFileHeader(index); + // Parse hunks + index.hunks = []; + while (i < diffstr.length) { + var line = diffstr[i]; + if ((/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/).test(line)) { + break; + } + else if ((/^@@/).test(line)) { + index.hunks.push(parseHunk()); + } + else if (line) { + throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(line)); + } + else { + i++; + } + } + } + // Parses the --- and +++ headers, if none are found, no lines + // are consumed. + function parseFileHeader(index) { + var fileHeaderMatch = (/^(---|\+\+\+)\s+/).exec(diffstr[i]); + if (fileHeaderMatch) { + var prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split('\t', 2), header = (data[1] || '').trim(); + var fileName = data[0].replace(/\\\\/g, '\\'); + if (fileName.startsWith('"') && fileName.endsWith('"')) { + fileName = fileName.substr(1, fileName.length - 2); + } + if (prefix === '---') { + index.oldFileName = fileName; + index.oldHeader = header; + } + else { + index.newFileName = fileName; + index.newHeader = header; + } + i++; + } + } + // Parses a hunk + // This assumes that we are at the start of a hunk. + function parseHunk() { + var _a; + var chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); + var hunk = { + oldStart: +chunkHeader[1], + oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], + newStart: +chunkHeader[3], + newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], + lines: [] + }; + // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + if (hunk.oldLines === 0) { + hunk.oldStart += 1; + } + if (hunk.newLines === 0) { + hunk.newStart += 1; + } + var addCount = 0, removeCount = 0; + for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))); i++) { + var operation = (diffstr[i].length == 0 && i != (diffstr.length - 1)) ? ' ' : diffstr[i][0]; + if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { + hunk.lines.push(diffstr[i]); + if (operation === '+') { + addCount++; + } + else if (operation === '-') { + removeCount++; + } + else if (operation === ' ') { + addCount++; + removeCount++; + } + } + else { + throw new Error("Hunk at line ".concat(chunkHeaderIndex + 1, " contained invalid line ").concat(diffstr[i])); + } + } + // Handle the empty block count case + if (!addCount && hunk.newLines === 1) { + hunk.newLines = 0; + } + if (!removeCount && hunk.oldLines === 1) { + hunk.oldLines = 0; + } + // Perform sanity checking + if (addCount !== hunk.newLines) { + throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + if (removeCount !== hunk.oldLines) { + throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + return hunk; + } + while (i < diffstr.length) { + parseIndex(); + } + return list; +} diff --git a/node_modules/diff/libcjs/patch/reverse.js b/node_modules/diff/libcjs/patch/reverse.js new file mode 100644 index 0000000000000..078fcdaea0bbc --- /dev/null +++ b/node_modules/diff/libcjs/patch/reverse.js @@ -0,0 +1,37 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.reversePatch = reversePatch; +function reversePatch(structuredPatch) { + if (Array.isArray(structuredPatch)) { + // (See comment in unixToWin for why we need the pointless-looking anonymous function here) + return structuredPatch.map(function (patch) { return reversePatch(patch); }).reverse(); + } + return __assign(__assign({}, structuredPatch), { oldFileName: structuredPatch.newFileName, oldHeader: structuredPatch.newHeader, newFileName: structuredPatch.oldFileName, newHeader: structuredPatch.oldHeader, hunks: structuredPatch.hunks.map(function (hunk) { + return { + oldLines: hunk.newLines, + oldStart: hunk.newStart, + newLines: hunk.oldLines, + newStart: hunk.oldStart, + lines: hunk.lines.map(function (l) { + if (l.startsWith('-')) { + return "+".concat(l.slice(1)); + } + if (l.startsWith('+')) { + return "-".concat(l.slice(1)); + } + return l; + }) + }; + }) }); +} diff --git a/node_modules/diff/libcjs/types.js b/node_modules/diff/libcjs/types.js new file mode 100644 index 0000000000000..c8ad2e549bdc6 --- /dev/null +++ b/node_modules/diff/libcjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/diff/libcjs/util/array.js b/node_modules/diff/libcjs/util/array.js new file mode 100644 index 0000000000000..c21937ee0fe51 --- /dev/null +++ b/node_modules/diff/libcjs/util/array.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.arrayEqual = arrayEqual; +exports.arrayStartsWith = arrayStartsWith; +function arrayEqual(a, b) { + if (a.length !== b.length) { + return false; + } + return arrayStartsWith(a, b); +} +function arrayStartsWith(array, start) { + if (start.length > array.length) { + return false; + } + for (var i = 0; i < start.length; i++) { + if (start[i] !== array[i]) { + return false; + } + } + return true; +} diff --git a/node_modules/diff/libcjs/util/distance-iterator.js b/node_modules/diff/libcjs/util/distance-iterator.js new file mode 100644 index 0000000000000..2421553c444ea --- /dev/null +++ b/node_modules/diff/libcjs/util/distance-iterator.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = default_1; +// Iterator that traverses in the range of [min, max], stepping +// by distance from a given start position. I.e. for [0, 4], with +// start of 2, this will iterate 2, 3, 1, 4, 0. +function default_1(start, minLine, maxLine) { + var wantForward = true, backwardExhausted = false, forwardExhausted = false, localOffset = 1; + return function iterator() { + if (wantForward && !forwardExhausted) { + if (backwardExhausted) { + localOffset++; + } + else { + wantForward = false; + } + // Check if trying to fit beyond text length, and if not, check it fits + // after offset location (or desired location on first iteration) + if (start + localOffset <= maxLine) { + return start + localOffset; + } + forwardExhausted = true; + } + if (!backwardExhausted) { + if (!forwardExhausted) { + wantForward = true; + } + // Check if trying to fit before text beginning, and if not, check it fits + // before offset location + if (minLine <= start - localOffset) { + return start - localOffset++; + } + backwardExhausted = true; + return iterator(); + } + // We tried to fit hunk before text beginning and beyond text length, then + // hunk can't fit on the text. Return undefined + return undefined; + }; +} diff --git a/node_modules/diff/libcjs/util/params.js b/node_modules/diff/libcjs/util/params.js new file mode 100644 index 0000000000000..6eefddba7922c --- /dev/null +++ b/node_modules/diff/libcjs/util/params.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.generateOptions = generateOptions; +function generateOptions(options, defaults) { + if (typeof options === 'function') { + defaults.callback = options; + } + else if (options) { + for (var name in options) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(options, name)) { + defaults[name] = options[name]; + } + } + } + return defaults; +} diff --git a/node_modules/diff/libcjs/util/string.js b/node_modules/diff/libcjs/util/string.js new file mode 100644 index 0000000000000..a36bf61eea2e4 --- /dev/null +++ b/node_modules/diff/libcjs/util/string.js @@ -0,0 +1,141 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.longestCommonPrefix = longestCommonPrefix; +exports.longestCommonSuffix = longestCommonSuffix; +exports.replacePrefix = replacePrefix; +exports.replaceSuffix = replaceSuffix; +exports.removePrefix = removePrefix; +exports.removeSuffix = removeSuffix; +exports.maximumOverlap = maximumOverlap; +exports.hasOnlyWinLineEndings = hasOnlyWinLineEndings; +exports.hasOnlyUnixLineEndings = hasOnlyUnixLineEndings; +exports.trailingWs = trailingWs; +exports.leadingWs = leadingWs; +function longestCommonPrefix(str1, str2) { + var i; + for (i = 0; i < str1.length && i < str2.length; i++) { + if (str1[i] != str2[i]) { + return str1.slice(0, i); + } + } + return str1.slice(0, i); +} +function longestCommonSuffix(str1, str2) { + var i; + // Unlike longestCommonPrefix, we need a special case to handle all scenarios + // where we return the empty string since str1.slice(-0) will return the + // entire string. + if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) { + return ''; + } + for (i = 0; i < str1.length && i < str2.length; i++) { + if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) { + return str1.slice(-i); + } + } + return str1.slice(-i); +} +function replacePrefix(string, oldPrefix, newPrefix) { + if (string.slice(0, oldPrefix.length) != oldPrefix) { + throw Error("string ".concat(JSON.stringify(string), " doesn't start with prefix ").concat(JSON.stringify(oldPrefix), "; this is a bug")); + } + return newPrefix + string.slice(oldPrefix.length); +} +function replaceSuffix(string, oldSuffix, newSuffix) { + if (!oldSuffix) { + return string + newSuffix; + } + if (string.slice(-oldSuffix.length) != oldSuffix) { + throw Error("string ".concat(JSON.stringify(string), " doesn't end with suffix ").concat(JSON.stringify(oldSuffix), "; this is a bug")); + } + return string.slice(0, -oldSuffix.length) + newSuffix; +} +function removePrefix(string, oldPrefix) { + return replacePrefix(string, oldPrefix, ''); +} +function removeSuffix(string, oldSuffix) { + return replaceSuffix(string, oldSuffix, ''); +} +function maximumOverlap(string1, string2) { + return string2.slice(0, overlapCount(string1, string2)); +} +// Nicked from https://stackoverflow.com/a/60422853/1709587 +function overlapCount(a, b) { + // Deal with cases where the strings differ in length + var startA = 0; + if (a.length > b.length) { + startA = a.length - b.length; + } + var endB = b.length; + if (a.length < b.length) { + endB = a.length; + } + // Create a back-reference for each index + // that should be followed in case of a mismatch. + // We only need B to make these references: + var map = Array(endB); + var k = 0; // Index that lags behind j + map[0] = 0; + for (var j = 1; j < endB; j++) { + if (b[j] == b[k]) { + map[j] = map[k]; // skip over the same character (optional optimisation) + } + else { + map[j] = k; + } + while (k > 0 && b[j] != b[k]) { + k = map[k]; + } + if (b[j] == b[k]) { + k++; + } + } + // Phase 2: use these references while iterating over A + k = 0; + for (var i = startA; i < a.length; i++) { + while (k > 0 && a[i] != b[k]) { + k = map[k]; + } + if (a[i] == b[k]) { + k++; + } + } + return k; +} +/** + * Returns true if the string consistently uses Windows line endings. + */ +function hasOnlyWinLineEndings(string) { + return string.includes('\r\n') && !string.startsWith('\n') && !string.match(/[^\r]\n/); +} +/** + * Returns true if the string consistently uses Unix line endings. + */ +function hasOnlyUnixLineEndings(string) { + return !string.includes('\r\n') && string.includes('\n'); +} +function trailingWs(string) { + // Yes, this looks overcomplicated and dumb - why not replace the whole function with + // return string.match(/\s*$/)[0] + // you ask? Because: + // 1. the trap described at https://markamery.com/blog/quadratic-time-regexes/ would mean doing + // this would cause this function to take O(n²) time in the worst case (specifically when + // there is a massive run of NON-TRAILING whitespace in `string`), and + // 2. the fix proposed in the same blog post, of using a negative lookbehind, is incompatible + // with old Safari versions that we'd like to not break if possible (see + // https://github.com/kpdecker/jsdiff/pull/550) + // It feels absurd to do this with an explicit loop instead of a regex, but I really can't see a + // better way that doesn't result in broken behaviour. + var i; + for (i = string.length - 1; i >= 0; i--) { + if (!string[i].match(/\s/)) { + break; + } + } + return string.substring(i + 1); +} +function leadingWs(string) { + // Thankfully the annoying considerations described in trailingWs don't apply here: + var match = string.match(/^\s*/); + return match ? match[0] : ''; +} diff --git a/node_modules/diff/libesm/convert/dmp.js b/node_modules/diff/libesm/convert/dmp.js new file mode 100644 index 0000000000000..44d2841465887 --- /dev/null +++ b/node_modules/diff/libesm/convert/dmp.js @@ -0,0 +1,21 @@ +/** + * converts a list of change objects to the format returned by Google's [diff-match-patch](https://github.com/google/diff-match-patch) library + */ +export function convertChangesToDMP(changes) { + const ret = []; + let change, operation; + for (let i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } + else if (change.removed) { + operation = -1; + } + else { + operation = 0; + } + ret.push([operation, change.value]); + } + return ret; +} diff --git a/node_modules/diff/libesm/convert/xml.js b/node_modules/diff/libesm/convert/xml.js new file mode 100644 index 0000000000000..90ea8a2b8c667 --- /dev/null +++ b/node_modules/diff/libesm/convert/xml.js @@ -0,0 +1,31 @@ +/** + * converts a list of change objects to a serialized XML format + */ +export function convertChangesToXML(changes) { + const ret = []; + for (let i = 0; i < changes.length; i++) { + const change = changes[i]; + if (change.added) { + ret.push('<ins>'); + } + else if (change.removed) { + ret.push('<del>'); + } + ret.push(escapeHTML(change.value)); + if (change.added) { + ret.push('</ins>'); + } + else if (change.removed) { + ret.push('</del>'); + } + } + return ret.join(''); +} +function escapeHTML(s) { + let n = s; + n = n.replace(/&/g, '&'); + n = n.replace(/</g, '<'); + n = n.replace(/>/g, '>'); + n = n.replace(/"/g, '"'); + return n; +} diff --git a/node_modules/diff/libesm/diff/array.js b/node_modules/diff/libesm/diff/array.js new file mode 100644 index 0000000000000..d92aeb485682d --- /dev/null +++ b/node_modules/diff/libesm/diff/array.js @@ -0,0 +1,16 @@ +import Diff from './base.js'; +class ArrayDiff extends Diff { + tokenize(value) { + return value.slice(); + } + join(value) { + return value; + } + removeEmpty(value) { + return value; + } +} +export const arrayDiff = new ArrayDiff(); +export function diffArrays(oldArr, newArr, options) { + return arrayDiff.diff(oldArr, newArr, options); +} diff --git a/node_modules/diff/libesm/diff/base.js b/node_modules/diff/libesm/diff/base.js new file mode 100644 index 0000000000000..db02845d419b9 --- /dev/null +++ b/node_modules/diff/libesm/diff/base.js @@ -0,0 +1,253 @@ +export default class Diff { + diff(oldStr, newStr, + // Type below is not accurate/complete - see above for full possibilities - but it compiles + options = {}) { + let callback; + if (typeof options === 'function') { + callback = options; + options = {}; + } + else if ('callback' in options) { + callback = options.callback; + } + // Allow subclasses to massage the input prior to running + const oldString = this.castInput(oldStr, options); + const newString = this.castInput(newStr, options); + const oldTokens = this.removeEmpty(this.tokenize(oldString, options)); + const newTokens = this.removeEmpty(this.tokenize(newString, options)); + return this.diffWithOptionsObj(oldTokens, newTokens, options, callback); + } + diffWithOptionsObj(oldTokens, newTokens, options, callback) { + var _a; + const done = (value) => { + value = this.postProcess(value, options); + if (callback) { + setTimeout(function () { callback(value); }, 0); + return undefined; + } + else { + return value; + } + }; + const newLen = newTokens.length, oldLen = oldTokens.length; + let editLength = 1; + let maxEditLength = newLen + oldLen; + if (options.maxEditLength != null) { + maxEditLength = Math.min(maxEditLength, options.maxEditLength); + } + const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity; + const abortAfterTimestamp = Date.now() + maxExecutionTime; + const bestPath = [{ oldPos: -1, lastComponent: undefined }]; + // Seed editLength = 0, i.e. the content starts with the same values + let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options); + if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) { + // Identity per the equality and tokenizer + return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens)); + } + // Once we hit the right edge of the edit graph on some diagonal k, we can + // definitely reach the end of the edit graph in no more than k edits, so + // there's no point in considering any moves to diagonal k+1 any more (from + // which we're guaranteed to need at least k+1 more edits). + // Similarly, once we've reached the bottom of the edit graph, there's no + // point considering moves to lower diagonals. + // We record this fact by setting minDiagonalToConsider and + // maxDiagonalToConsider to some finite value once we've hit the edge of + // the edit graph. + // This optimization is not faithful to the original algorithm presented in + // Myers's paper, which instead pointlessly extends D-paths off the end of + // the edit graph - see page 7 of Myers's paper which notes this point + // explicitly and illustrates it with a diagram. This has major performance + // implications for some common scenarios. For instance, to compute a diff + // where the new text simply appends d characters on the end of the + // original text of length n, the true Myers algorithm will take O(n+d^2) + // time while this optimization needs only O(n+d) time. + let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity; + // Main worker method. checks all permutations of a given edit length for acceptance. + const execEditLength = () => { + for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) { + let basePath; + const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1]; + if (removePath) { + // No one else is going to attempt to use this value, clear it + // @ts-expect-error - perf optimisation. This type-violating value will never be read. + bestPath[diagonalPath - 1] = undefined; + } + let canAdd = false; + if (addPath) { + // what newPos will be after we do an insertion: + const addPathNewPos = addPath.oldPos - diagonalPath; + canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen; + } + const canRemove = removePath && removePath.oldPos + 1 < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + // @ts-expect-error - perf optimisation. This type-violating value will never be read. + bestPath[diagonalPath] = undefined; + continue; + } + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the old string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canRemove || (canAdd && removePath.oldPos < addPath.oldPos)) { + basePath = this.addToPath(addPath, true, false, 0, options); + } + else { + basePath = this.addToPath(removePath, false, true, 1, options); + } + newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options); + if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) { + // If we have hit the end of both strings, then we are done + return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true; + } + else { + bestPath[diagonalPath] = basePath; + if (basePath.oldPos + 1 >= oldLen) { + maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1); + } + if (newPos + 1 >= newLen) { + minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1); + } + } + } + editLength++; + }; + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced, or until the edit length exceeds options.maxEditLength (if given), + // in which case it will return undefined. + if (callback) { + (function exec() { + setTimeout(function () { + if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) { + return callback(undefined); + } + if (!execEditLength()) { + exec(); + } + }, 0); + }()); + } + else { + while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) { + const ret = execEditLength(); + if (ret) { + return ret; + } + } + } + } + addToPath(path, added, removed, oldPosInc, options) { + const last = path.lastComponent; + if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) { + return { + oldPos: path.oldPos + oldPosInc, + lastComponent: { count: last.count + 1, added: added, removed: removed, previousComponent: last.previousComponent } + }; + } + else { + return { + oldPos: path.oldPos + oldPosInc, + lastComponent: { count: 1, added: added, removed: removed, previousComponent: last } + }; + } + } + extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) { + const newLen = newTokens.length, oldLen = oldTokens.length; + let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) { + newPos++; + oldPos++; + commonCount++; + if (options.oneChangePerToken) { + basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false }; + } + } + if (commonCount && !options.oneChangePerToken) { + basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false }; + } + basePath.oldPos = oldPos; + return newPos; + } + equals(left, right, options) { + if (options.comparator) { + return options.comparator(left, right); + } + else { + return left === right + || (!!options.ignoreCase && left.toLowerCase() === right.toLowerCase()); + } + } + removeEmpty(array) { + const ret = []; + for (let i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } + } + return ret; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + castInput(value, options) { + return value; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + tokenize(value, options) { + return Array.from(value); + } + join(chars) { + // Assumes ValueT is string, which is the case for most subclasses. + // When it's false, e.g. in diffArrays, this method needs to be overridden (e.g. with a no-op) + // Yes, the casts are verbose and ugly, because this pattern - of having the base class SORT OF + // assume tokens and values are strings, but not completely - is weird and janky. + return chars.join(''); + } + postProcess(changeObjects, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + options) { + return changeObjects; + } + get useLongestToken() { + return false; + } + buildValues(lastComponent, newTokens, oldTokens) { + // First we convert our linked list of components in reverse order to an + // array in the right order: + const components = []; + let nextComponent; + while (lastComponent) { + components.push(lastComponent); + nextComponent = lastComponent.previousComponent; + delete lastComponent.previousComponent; + lastComponent = nextComponent; + } + components.reverse(); + const componentLen = components.length; + let componentPos = 0, newPos = 0, oldPos = 0; + for (; componentPos < componentLen; componentPos++) { + const component = components[componentPos]; + if (!component.removed) { + if (!component.added && this.useLongestToken) { + let value = newTokens.slice(newPos, newPos + component.count); + value = value.map(function (value, i) { + const oldValue = oldTokens[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); + component.value = this.join(value); + } + else { + component.value = this.join(newTokens.slice(newPos, newPos + component.count)); + } + newPos += component.count; + // Common case + if (!component.added) { + oldPos += component.count; + } + } + else { + component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count)); + oldPos += component.count; + } + } + return components; + } +} diff --git a/node_modules/diff/libesm/diff/character.js b/node_modules/diff/libesm/diff/character.js new file mode 100644 index 0000000000000..ca70d065d37cb --- /dev/null +++ b/node_modules/diff/libesm/diff/character.js @@ -0,0 +1,7 @@ +import Diff from './base.js'; +class CharacterDiff extends Diff { +} +export const characterDiff = new CharacterDiff(); +export function diffChars(oldStr, newStr, options) { + return characterDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libesm/diff/css.js b/node_modules/diff/libesm/diff/css.js new file mode 100644 index 0000000000000..2e7adcc3c2c3d --- /dev/null +++ b/node_modules/diff/libesm/diff/css.js @@ -0,0 +1,10 @@ +import Diff from './base.js'; +class CssDiff extends Diff { + tokenize(value) { + return value.split(/([{}:;,]|\s+)/); + } +} +export const cssDiff = new CssDiff(); +export function diffCss(oldStr, newStr, options) { + return cssDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libesm/diff/json.js b/node_modules/diff/libesm/diff/json.js new file mode 100644 index 0000000000000..be9f7617df997 --- /dev/null +++ b/node_modules/diff/libesm/diff/json.js @@ -0,0 +1,78 @@ +import Diff from './base.js'; +import { tokenize } from './line.js'; +class JsonDiff extends Diff { + constructor() { + super(...arguments); + this.tokenize = tokenize; + } + get useLongestToken() { + // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a + // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: + return true; + } + castInput(value, options) { + const { undefinedReplacement, stringifyReplacer = (k, v) => typeof v === 'undefined' ? undefinedReplacement : v } = options; + return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), null, ' '); + } + equals(left, right, options) { + return super.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'), options); + } +} +export const jsonDiff = new JsonDiff(); +export function diffJson(oldStr, newStr, options) { + return jsonDiff.diff(oldStr, newStr, options); +} +// This function handles the presence of circular references by bailing out when encountering an +// object that is already on the "stack" of items being processed. Accepts an optional replacer +export function canonicalize(obj, stack, replacementStack, replacer, key) { + stack = stack || []; + replacementStack = replacementStack || []; + if (replacer) { + obj = replacer(key === undefined ? '' : key, obj); + } + let i; + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } + let canonicalizedObj; + if ('[object Array]' === Object.prototype.toString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, String(i)); + } + stack.pop(); + replacementStack.pop(); + return canonicalizedObj; + } + if (obj && obj.toJSON) { + obj = obj.toJSON(); + } + if (typeof obj === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + const sortedKeys = []; + let key; + for (key in obj) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(obj, key)) { + sortedKeys.push(key); + } + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key = sortedKeys[i]; + canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack, replacer, key); + } + stack.pop(); + replacementStack.pop(); + } + else { + canonicalizedObj = obj; + } + return canonicalizedObj; +} diff --git a/node_modules/diff/libesm/diff/line.js b/node_modules/diff/libesm/diff/line.js new file mode 100644 index 0000000000000..0675d4fb003f9 --- /dev/null +++ b/node_modules/diff/libesm/diff/line.js @@ -0,0 +1,65 @@ +import Diff from './base.js'; +import { generateOptions } from '../util/params.js'; +class LineDiff extends Diff { + constructor() { + super(...arguments); + this.tokenize = tokenize; + } + equals(left, right, options) { + // If we're ignoring whitespace, we need to normalise lines by stripping + // whitespace before checking equality. (This has an annoying interaction + // with newlineIsToken that requires special handling: if newlines get their + // own token, then we DON'T want to trim the *newline* tokens down to empty + // strings, since this would cause us to treat whitespace-only line content + // as equal to a separator between lines, which would be weird and + // inconsistent with the documented behavior of the options.) + if (options.ignoreWhitespace) { + if (!options.newlineIsToken || !left.includes('\n')) { + left = left.trim(); + } + if (!options.newlineIsToken || !right.includes('\n')) { + right = right.trim(); + } + } + else if (options.ignoreNewlineAtEof && !options.newlineIsToken) { + if (left.endsWith('\n')) { + left = left.slice(0, -1); + } + if (right.endsWith('\n')) { + right = right.slice(0, -1); + } + } + return super.equals(left, right, options); + } +} +export const lineDiff = new LineDiff(); +export function diffLines(oldStr, newStr, options) { + return lineDiff.diff(oldStr, newStr, options); +} +export function diffTrimmedLines(oldStr, newStr, options) { + options = generateOptions(options, { ignoreWhitespace: true }); + return lineDiff.diff(oldStr, newStr, options); +} +// Exported standalone so it can be used from jsonDiff too. +export function tokenize(value, options) { + if (options.stripTrailingCr) { + // remove one \r before \n to match GNU diff's --strip-trailing-cr behavior + value = value.replace(/\r\n/g, '\n'); + } + const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/); + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } + // Merge the content and line separators into single tokens + for (let i = 0; i < linesAndNewlines.length; i++) { + const line = linesAndNewlines[i]; + if (i % 2 && !options.newlineIsToken) { + retLines[retLines.length - 1] += line; + } + else { + retLines.push(line); + } + } + return retLines; +} diff --git a/node_modules/diff/libesm/diff/sentence.js b/node_modules/diff/libesm/diff/sentence.js new file mode 100644 index 0000000000000..db37010ef6472 --- /dev/null +++ b/node_modules/diff/libesm/diff/sentence.js @@ -0,0 +1,43 @@ +import Diff from './base.js'; +function isSentenceEndPunct(char) { + return char == '.' || char == '!' || char == '?'; +} +class SentenceDiff extends Diff { + tokenize(value) { + var _a; + // If in future we drop support for environments that don't support lookbehinds, we can replace + // this entire function with: + // return value.split(/(?<=[.!?])(\s+|$)/); + // but until then, for similar reasons to the trailingWs function in string.ts, we are forced + // to do this verbosely "by hand" instead of using a regex. + const result = []; + let tokenStartI = 0; + for (let i = 0; i < value.length; i++) { + if (i == value.length - 1) { + result.push(value.slice(tokenStartI)); + break; + } + if (isSentenceEndPunct(value[i]) && value[i + 1].match(/\s/)) { + // We've hit a sentence break - i.e. a punctuation mark followed by whitespace. + // We now want to push TWO tokens to the result: + // 1. the sentence + result.push(value.slice(tokenStartI, i + 1)); + // 2. the whitespace + i = tokenStartI = i + 1; + while ((_a = value[i + 1]) === null || _a === void 0 ? void 0 : _a.match(/\s/)) { + i++; + } + result.push(value.slice(tokenStartI, i + 1)); + // Then the next token (a sentence) starts on the character after the whitespace. + // (It's okay if this is off the end of the string - then the outer loop will terminate + // here anyway.) + tokenStartI = i + 1; + } + } + return result; + } +} +export const sentenceDiff = new SentenceDiff(); +export function diffSentences(oldStr, newStr, options) { + return sentenceDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libesm/diff/word.js b/node_modules/diff/libesm/diff/word.js new file mode 100644 index 0000000000000..e828f825020f4 --- /dev/null +++ b/node_modules/diff/libesm/diff/word.js @@ -0,0 +1,296 @@ +import Diff from './base.js'; +import { longestCommonPrefix, longestCommonSuffix, replacePrefix, replaceSuffix, removePrefix, removeSuffix, maximumOverlap, leadingWs, trailingWs } from '../util/string.js'; +// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode +// +// Chars/ranges counted as "word" characters by this regex are as follows: +// +// + U+00AD Soft hyphen +// + 00C0–00FF (letters with diacritics from the Latin-1 Supplement), except: +// - U+00D7 × Multiplication sign +// - U+00F7 ÷ Division sign +// + Latin Extended-A, 0100–017F +// + Latin Extended-B, 0180–024F +// + IPA Extensions, 0250–02AF +// + Spacing Modifier Letters, 02B0–02FF, except: +// - U+02C7 ˇ ˇ Caron +// - U+02D8 ˘ ˘ Breve +// - U+02D9 ˙ ˙ Dot Above +// - U+02DA ˚ ˚ Ring Above +// - U+02DB ˛ ˛ Ogonek +// - U+02DC ˜ ˜ Small Tilde +// - U+02DD ˝ ˝ Double Acute Accent +// + Latin Extended Additional, 1E00–1EFF +const extendedWordChars = 'a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}'; +// Each token is one of the following: +// - A punctuation mark plus the surrounding whitespace +// - A word plus the surrounding whitespace +// - Pure whitespace (but only in the special case where the entire text +// is just whitespace) +// +// We have to include surrounding whitespace in the tokens because the two +// alternative approaches produce horribly broken results: +// * If we just discard the whitespace, we can't fully reproduce the original +// text from the sequence of tokens and any attempt to render the diff will +// get the whitespace wrong. +// * If we have separate tokens for whitespace, then in a typical text every +// second token will be a single space character. But this often results in +// the optimal diff between two texts being a perverse one that preserves +// the spaces between words but deletes and reinserts actual common words. +// See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640 +// for an example. +// +// Keeping the surrounding whitespace of course has implications for .equals +// and .join, not just .tokenize. +// This regex does NOT fully implement the tokenization rules described above. +// Instead, it gives runs of whitespace their own "token". The tokenize method +// then handles stitching whitespace tokens onto adjacent word or punctuation +// tokens. +const tokenizeIncludingWhitespace = new RegExp(`[${extendedWordChars}]+|\\s+|[^${extendedWordChars}]`, 'ug'); +class WordDiff extends Diff { + equals(left, right, options) { + if (options.ignoreCase) { + left = left.toLowerCase(); + right = right.toLowerCase(); + } + return left.trim() === right.trim(); + } + tokenize(value, options = {}) { + let parts; + if (options.intlSegmenter) { + const segmenter = options.intlSegmenter; + if (segmenter.resolvedOptions().granularity != 'word') { + throw new Error('The segmenter passed must have a granularity of "word"'); + } + // We want `parts` to be an array whose elements alternate between being + // pure whitespace and being pure non-whitespace. This is ALMOST what the + // segments returned by a word-based Intl.Segmenter already look like, + // and therefore we can ALMOST get what we want by simply doing... + // parts = Array.from(segmenter.segment(value), segment => segment.segment); + // ... but not QUITE, because there's of one annoying special case: every + // newline character gets its own segment, instead of sharing a segment + // with other surrounding whitespace. We therefore need to manually merge + // consecutive segments of whitespace into a single part: + parts = []; + for (const segmentObj of Array.from(segmenter.segment(value))) { + const segment = segmentObj.segment; + if (parts.length && (/\s/).test(parts[parts.length - 1]) && (/\s/).test(segment)) { + parts[parts.length - 1] += segment; + } + else { + parts.push(segment); + } + } + } + else { + parts = value.match(tokenizeIncludingWhitespace) || []; + } + const tokens = []; + let prevPart = null; + parts.forEach(part => { + if ((/\s/).test(part)) { + if (prevPart == null) { + tokens.push(part); + } + else { + tokens.push(tokens.pop() + part); + } + } + else if (prevPart != null && (/\s/).test(prevPart)) { + if (tokens[tokens.length - 1] == prevPart) { + tokens.push(tokens.pop() + part); + } + else { + tokens.push(prevPart + part); + } + } + else { + tokens.push(part); + } + prevPart = part; + }); + return tokens; + } + join(tokens) { + // Tokens being joined here will always have appeared consecutively in the + // same text, so we can simply strip off the leading whitespace from all the + // tokens except the first (and except any whitespace-only tokens - but such + // a token will always be the first and only token anyway) and then join them + // and the whitespace around words and punctuation will end up correct. + return tokens.map((token, i) => { + if (i == 0) { + return token; + } + else { + return token.replace((/^\s+/), ''); + } + }).join(''); + } + postProcess(changes, options) { + if (!changes || options.oneChangePerToken) { + return changes; + } + let lastKeep = null; + // Change objects representing any insertion or deletion since the last + // "keep" change object. There can be at most one of each. + let insertion = null; + let deletion = null; + changes.forEach(change => { + if (change.added) { + insertion = change; + } + else if (change.removed) { + deletion = change; + } + else { + if (insertion || deletion) { // May be false at start of text + dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change); + } + lastKeep = change; + insertion = null; + deletion = null; + } + }); + if (insertion || deletion) { + dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null); + } + return changes; + } +} +export const wordDiff = new WordDiff(); +export function diffWords(oldStr, newStr, options) { + // This option has never been documented and never will be (it's clearer to + // just call `diffWordsWithSpace` directly if you need that behavior), but + // has existed in jsdiff for a long time, so we retain support for it here + // for the sake of backwards compatibility. + if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) { + return diffWordsWithSpace(oldStr, newStr, options); + } + return wordDiff.diff(oldStr, newStr, options); +} +function dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) { + // Before returning, we tidy up the leading and trailing whitespace of the + // change objects to eliminate cases where trailing whitespace in one object + // is repeated as leading whitespace in the next. + // Below are examples of the outcomes we want here to explain the code. + // I=insert, K=keep, D=delete + // 1. diffing 'foo bar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz' + // After cleanup, we want: K:'foo ' D:'bar ' K:'baz' + // + // 2. Diffing 'foo bar baz' vs 'foo qux baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz' + // After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz' + // + // 3. Diffing 'foo\nbar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:'\nbar ' K:' baz' + // After cleanup, we want K'foo' D:'\nbar' K:' baz' + // + // 4. Diffing 'foo baz' vs 'foo\nbar baz' + // Prior to cleanup, we have K:'foo\n' I:'\nbar ' K:' baz' + // After cleanup, we ideally want K'foo' I:'\nbar' K:' baz' + // but don't actually manage this currently (the pre-cleanup change + // objects don't contain enough information to make it possible). + // + // 5. Diffing 'foo bar baz' vs 'foo baz' + // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz' + // After cleanup, we want K:'foo ' D:' bar ' K:'baz' + // + // Our handling is unavoidably imperfect in the case where there's a single + // indel between keeps and the whitespace has changed. For instance, consider + // diffing 'foo\tbar\nbaz' vs 'foo baz'. Unless we create an extra change + // object to represent the insertion of the space character (which isn't even + // a token), we have no way to avoid losing information about the texts' + // original whitespace in the result we return. Still, we do our best to + // output something that will look sensible if we e.g. print it with + // insertions in green and deletions in red. + // Between two "keep" change objects (or before the first or after the last + // change object), we can have either: + // * A "delete" followed by an "insert" + // * Just an "insert" + // * Just a "delete" + // We handle the three cases separately. + if (deletion && insertion) { + const oldWsPrefix = leadingWs(deletion.value); + const oldWsSuffix = trailingWs(deletion.value); + const newWsPrefix = leadingWs(insertion.value); + const newWsSuffix = trailingWs(insertion.value); + if (startKeep) { + const commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix); + startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix); + deletion.value = removePrefix(deletion.value, commonWsPrefix); + insertion.value = removePrefix(insertion.value, commonWsPrefix); + } + if (endKeep) { + const commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix); + endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix); + deletion.value = removeSuffix(deletion.value, commonWsSuffix); + insertion.value = removeSuffix(insertion.value, commonWsSuffix); + } + } + else if (insertion) { + // The whitespaces all reflect what was in the new text rather than + // the old, so we essentially have no information about whitespace + // insertion or deletion. We just want to dedupe the whitespace. + // We do that by having each change object keep its trailing + // whitespace and deleting duplicate leading whitespace where + // present. + if (startKeep) { + const ws = leadingWs(insertion.value); + insertion.value = insertion.value.substring(ws.length); + } + if (endKeep) { + const ws = leadingWs(endKeep.value); + endKeep.value = endKeep.value.substring(ws.length); + } + // otherwise we've got a deletion and no insertion + } + else if (startKeep && endKeep) { + const newWsFull = leadingWs(endKeep.value), delWsStart = leadingWs(deletion.value), delWsEnd = trailingWs(deletion.value); + // Any whitespace that comes straight after startKeep in both the old and + // new texts, assign to startKeep and remove from the deletion. + const newWsStart = longestCommonPrefix(newWsFull, delWsStart); + deletion.value = removePrefix(deletion.value, newWsStart); + // Any whitespace that comes straight before endKeep in both the old and + // new texts, and hasn't already been assigned to startKeep, assign to + // endKeep and remove from the deletion. + const newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd); + deletion.value = removeSuffix(deletion.value, newWsEnd); + endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd); + // If there's any whitespace from the new text that HASN'T already been + // assigned, assign it to the start: + startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length)); + } + else if (endKeep) { + // We are at the start of the text. Preserve all the whitespace on + // endKeep, and just remove whitespace from the end of deletion to the + // extent that it overlaps with the start of endKeep. + const endKeepWsPrefix = leadingWs(endKeep.value); + const deletionWsSuffix = trailingWs(deletion.value); + const overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix); + deletion.value = removeSuffix(deletion.value, overlap); + } + else if (startKeep) { + // We are at the END of the text. Preserve all the whitespace on + // startKeep, and just remove whitespace from the start of deletion to + // the extent that it overlaps with the end of startKeep. + const startKeepWsSuffix = trailingWs(startKeep.value); + const deletionWsPrefix = leadingWs(deletion.value); + const overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix); + deletion.value = removePrefix(deletion.value, overlap); + } +} +class WordsWithSpaceDiff extends Diff { + tokenize(value) { + // Slightly different to the tokenizeIncludingWhitespace regex used above in + // that this one treats each individual newline as a distinct token, rather + // than merging them into other surrounding whitespace. This was requested + // in https://github.com/kpdecker/jsdiff/issues/180 & + // https://github.com/kpdecker/jsdiff/issues/211 + const regex = new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`, 'ug'); + return value.match(regex) || []; + } +} +export const wordsWithSpaceDiff = new WordsWithSpaceDiff(); +export function diffWordsWithSpace(oldStr, newStr, options) { + return wordsWithSpaceDiff.diff(oldStr, newStr, options); +} diff --git a/node_modules/diff/libesm/index.js b/node_modules/diff/libesm/index.js new file mode 100644 index 0000000000000..18a495a18f663 --- /dev/null +++ b/node_modules/diff/libesm/index.js @@ -0,0 +1,30 @@ +/* See LICENSE file for terms of use */ +/* + * Text diff implementation. + * + * This library supports the following APIs: + * Diff.diffChars: Character by character diff + * Diff.diffWords: Word (as defined by \b regex) diff which ignores whitespace + * Diff.diffLines: Line based diff + * + * Diff.diffCss: Diff targeted at CSS content + * + * These methods are based on the implementation proposed in + * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 + */ +import Diff from './diff/base.js'; +import { diffChars, characterDiff } from './diff/character.js'; +import { diffWords, diffWordsWithSpace, wordDiff, wordsWithSpaceDiff } from './diff/word.js'; +import { diffLines, diffTrimmedLines, lineDiff } from './diff/line.js'; +import { diffSentences, sentenceDiff } from './diff/sentence.js'; +import { diffCss, cssDiff } from './diff/css.js'; +import { diffJson, canonicalize, jsonDiff } from './diff/json.js'; +import { diffArrays, arrayDiff } from './diff/array.js'; +import { applyPatch, applyPatches } from './patch/apply.js'; +import { parsePatch } from './patch/parse.js'; +import { reversePatch } from './patch/reverse.js'; +import { structuredPatch, createTwoFilesPatch, createPatch, formatPatch, INCLUDE_HEADERS, FILE_HEADERS_ONLY, OMIT_HEADERS } from './patch/create.js'; +import { convertChangesToDMP } from './convert/dmp.js'; +import { convertChangesToXML } from './convert/xml.js'; +export { Diff, diffChars, characterDiff, diffWords, wordDiff, diffWordsWithSpace, wordsWithSpaceDiff, diffLines, lineDiff, diffTrimmedLines, diffSentences, sentenceDiff, diffCss, cssDiff, diffJson, jsonDiff, diffArrays, arrayDiff, structuredPatch, createTwoFilesPatch, createPatch, formatPatch, INCLUDE_HEADERS, FILE_HEADERS_ONLY, OMIT_HEADERS, applyPatch, applyPatches, parsePatch, reversePatch, convertChangesToDMP, convertChangesToXML, canonicalize }; diff --git a/node_modules/diff/libesm/package.json b/node_modules/diff/libesm/package.json new file mode 100644 index 0000000000000..2bd6e5099f38c --- /dev/null +++ b/node_modules/diff/libesm/package.json @@ -0,0 +1 @@ +{"type":"module","sideEffects":false} \ No newline at end of file diff --git a/node_modules/diff/libesm/patch/apply.js b/node_modules/diff/libesm/patch/apply.js new file mode 100644 index 0000000000000..fe2e8db5c465d --- /dev/null +++ b/node_modules/diff/libesm/patch/apply.js @@ -0,0 +1,257 @@ +import { hasOnlyWinLineEndings, hasOnlyUnixLineEndings } from '../util/string.js'; +import { isWin, isUnix, unixToWin, winToUnix } from './line-endings.js'; +import { parsePatch } from './parse.js'; +import distanceIterator from '../util/distance-iterator.js'; +/** + * attempts to apply a unified diff patch. + * + * Hunks are applied first to last. + * `applyPatch` first tries to apply the first hunk at the line number specified in the hunk header, and with all context lines matching exactly. + * If that fails, it tries scanning backwards and forwards, one line at a time, to find a place to apply the hunk where the context lines match exactly. + * If that still fails, and `fuzzFactor` is greater than zero, it increments the maximum number of mismatches (missing, extra, or changed context lines) that there can be between the hunk context and a region where we are trying to apply the patch such that the hunk will still be considered to match. + * Regardless of `fuzzFactor`, lines to be deleted in the hunk *must* be present for a hunk to match, and the context lines *immediately* before and after an insertion must match exactly. + * + * Once a hunk is successfully fitted, the process begins again with the next hunk. + * Regardless of `fuzzFactor`, later hunks must be applied later in the file than earlier hunks. + * + * If a hunk cannot be successfully fitted *anywhere* with fewer than `fuzzFactor` mismatches, `applyPatch` fails and returns `false`. + * + * If a hunk is successfully fitted but not at the line number specified by the hunk header, all subsequent hunks have their target line number adjusted accordingly. + * (e.g. if the first hunk is applied 10 lines below where the hunk header said it should fit, `applyPatch` will *start* looking for somewhere to apply the second hunk 10 lines below where its hunk header says it goes.) + * + * If the patch was applied successfully, returns a string containing the patched text. + * If the patch could not be applied (because some hunks in the patch couldn't be fitted to the text in `source`), `applyPatch` returns false. + * + * @param patch a string diff or the output from the `parsePatch` or `structuredPatch` methods. + */ +export function applyPatch(source, patch, options = {}) { + let patches; + if (typeof patch === 'string') { + patches = parsePatch(patch); + } + else if (Array.isArray(patch)) { + patches = patch; + } + else { + patches = [patch]; + } + if (patches.length > 1) { + throw new Error('applyPatch only works with a single input.'); + } + return applyStructuredPatch(source, patches[0], options); +} +function applyStructuredPatch(source, patch, options = {}) { + if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) { + if (hasOnlyWinLineEndings(source) && isUnix(patch)) { + patch = unixToWin(patch); + } + else if (hasOnlyUnixLineEndings(source) && isWin(patch)) { + patch = winToUnix(patch); + } + } + // Apply the diff to the input + const lines = source.split('\n'), hunks = patch.hunks, compareLine = options.compareLine || ((lineNumber, line, operation, patchContent) => line === patchContent), fuzzFactor = options.fuzzFactor || 0; + let minLine = 0; + if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) { + throw new Error('fuzzFactor must be a non-negative integer'); + } + // Special case for empty patch. + if (!hunks.length) { + return source; + } + // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change + // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a + // newline that already exists - then we either return false and fail to apply the patch (if + // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0). + // If we do need to remove/add a newline at EOF, this will always be in the final hunk: + let prevLine = '', removeEOFNL = false, addEOFNL = false; + for (let i = 0; i < hunks[hunks.length - 1].lines.length; i++) { + const line = hunks[hunks.length - 1].lines[i]; + if (line[0] == '\\') { + if (prevLine[0] == '+') { + removeEOFNL = true; + } + else if (prevLine[0] == '-') { + addEOFNL = true; + } + } + prevLine = line; + } + if (removeEOFNL) { + if (addEOFNL) { + // This means the final line gets changed but doesn't have a trailing newline in either the + // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if + // fuzzFactor is 0, we simply validate that the source file has no trailing newline. + if (!fuzzFactor && lines[lines.length - 1] == '') { + return false; + } + } + else if (lines[lines.length - 1] == '') { + lines.pop(); + } + else if (!fuzzFactor) { + return false; + } + } + else if (addEOFNL) { + if (lines[lines.length - 1] != '') { + lines.push(''); + } + else if (!fuzzFactor) { + return false; + } + } + /** + * Checks if the hunk can be made to fit at the provided location with at most `maxErrors` + * insertions, substitutions, or deletions, while ensuring also that: + * - lines deleted in the hunk match exactly, and + * - wherever an insertion operation or block of insertion operations appears in the hunk, the + * immediately preceding and following lines of context match exactly + * + * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0]. + * + * If the hunk can be applied, returns an object with properties `oldLineLastI` and + * `replacementLines`. Otherwise, returns null. + */ + function applyHunk(hunkLines, toPos, maxErrors, hunkLinesI = 0, lastContextLineMatched = true, patchedLines = [], patchedLinesLength = 0) { + let nConsecutiveOldContextLines = 0; + let nextContextLineMustMatch = false; + for (; hunkLinesI < hunkLines.length; hunkLinesI++) { + const hunkLine = hunkLines[hunkLinesI], operation = (hunkLine.length > 0 ? hunkLine[0] : ' '), content = (hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine); + if (operation === '-') { + if (compareLine(toPos + 1, lines[toPos], operation, content)) { + toPos++; + nConsecutiveOldContextLines = 0; + } + else { + if (!maxErrors || lines[toPos] == null) { + return null; + } + patchedLines[patchedLinesLength] = lines[toPos]; + return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1); + } + } + if (operation === '+') { + if (!lastContextLineMatched) { + return null; + } + patchedLines[patchedLinesLength] = content; + patchedLinesLength++; + nConsecutiveOldContextLines = 0; + nextContextLineMustMatch = true; + } + if (operation === ' ') { + nConsecutiveOldContextLines++; + patchedLines[patchedLinesLength] = lines[toPos]; + if (compareLine(toPos + 1, lines[toPos], operation, content)) { + patchedLinesLength++; + lastContextLineMatched = true; + nextContextLineMustMatch = false; + toPos++; + } + else { + if (nextContextLineMustMatch || !maxErrors) { + return null; + } + // Consider 3 possibilities in sequence: + // 1. lines contains a *substitution* not included in the patch context, or + // 2. lines contains an *insertion* not included in the patch context, or + // 3. lines contains a *deletion* not included in the patch context + // The first two options are of course only possible if the line from lines is non-null - + // i.e. only option 3 is possible if we've overrun the end of the old file. + return (lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength)); + } + } + } + // Before returning, trim any unmodified context lines off the end of patchedLines and reduce + // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region + // that starts in this hunk's trailing context. + patchedLinesLength -= nConsecutiveOldContextLines; + toPos -= nConsecutiveOldContextLines; + patchedLines.length = patchedLinesLength; + return { + patchedLines, + oldLineLastI: toPos - 1 + }; + } + const resultLines = []; + // Search best fit offsets for each hunk based on the previous ones + let prevHunkOffset = 0; + for (let i = 0; i < hunks.length; i++) { + const hunk = hunks[i]; + let hunkResult; + const maxLine = lines.length - hunk.oldLines + fuzzFactor; + let toPos; + for (let maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) { + toPos = hunk.oldStart + prevHunkOffset - 1; + const iterator = distanceIterator(toPos, minLine, maxLine); + for (; toPos !== undefined; toPos = iterator()) { + hunkResult = applyHunk(hunk.lines, toPos, maxErrors); + if (hunkResult) { + break; + } + } + if (hunkResult) { + break; + } + } + if (!hunkResult) { + return false; + } + // Copy everything from the end of where we applied the last hunk to the start of this hunk + for (let i = minLine; i < toPos; i++) { + resultLines.push(lines[i]); + } + // Add the lines produced by applying the hunk: + for (let i = 0; i < hunkResult.patchedLines.length; i++) { + const line = hunkResult.patchedLines[i]; + resultLines.push(line); + } + // Set lower text limit to end of the current hunk, so next ones don't try + // to fit over already patched text + minLine = hunkResult.oldLineLastI + 1; + // Note the offset between where the patch said the hunk should've applied and where we + // applied it, so we can adjust future hunks accordingly: + prevHunkOffset = toPos + 1 - hunk.oldStart; + } + // Copy over the rest of the lines from the old text + for (let i = minLine; i < lines.length; i++) { + resultLines.push(lines[i]); + } + return resultLines.join('\n'); +} +/** + * applies one or more patches. + * + * `patch` may be either an array of structured patch objects, or a string representing a patch in unified diff format (which may patch one or more files). + * + * This method will iterate over the contents of the patch and apply to data provided through callbacks. The general flow for each patch index is: + * + * - `options.loadFile(index, callback)` is called. The caller should then load the contents of the file and then pass that to the `callback(err, data)` callback. Passing an `err` will terminate further patch execution. + * - `options.patched(index, content, callback)` is called once the patch has been applied. `content` will be the return value from `applyPatch`. When it's ready, the caller should call `callback(err)` callback. Passing an `err` will terminate further patch execution. + * + * Once all patches have been applied or an error occurs, the `options.complete(err)` callback is made. + */ +export function applyPatches(uniDiff, options) { + const spDiff = typeof uniDiff === 'string' ? parsePatch(uniDiff) : uniDiff; + let currentIndex = 0; + function processIndex() { + const index = spDiff[currentIndex++]; + if (!index) { + return options.complete(); + } + options.loadFile(index, function (err, data) { + if (err) { + return options.complete(err); + } + const updatedContent = applyPatch(data, index, options); + options.patched(index, updatedContent, function (err) { + if (err) { + return options.complete(err); + } + processIndex(); + }); + }); + } + processIndex(); +} diff --git a/node_modules/diff/libesm/patch/create.js b/node_modules/diff/libesm/patch/create.js new file mode 100644 index 0000000000000..73ba2969cf94a --- /dev/null +++ b/node_modules/diff/libesm/patch/create.js @@ -0,0 +1,228 @@ +import { diffLines } from '../diff/line.js'; +export const INCLUDE_HEADERS = { + includeIndex: true, + includeUnderline: true, + includeFileHeaders: true +}; +export const FILE_HEADERS_ONLY = { + includeIndex: false, + includeUnderline: false, + includeFileHeaders: true +}; +export const OMIT_HEADERS = { + includeIndex: false, + includeUnderline: false, + includeFileHeaders: false +}; +export function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + let optionsObj; + if (!options) { + optionsObj = {}; + } + else if (typeof options === 'function') { + optionsObj = { callback: options }; + } + else { + optionsObj = options; + } + if (typeof optionsObj.context === 'undefined') { + optionsObj.context = 4; + } + // We copy this into its own variable to placate TypeScript, which thinks + // optionsObj.context might be undefined in the callbacks below. + const context = optionsObj.context; + // @ts-expect-error (runtime check for something that is correctly a static type error) + if (optionsObj.newlineIsToken) { + throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions'); + } + if (!optionsObj.callback) { + return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj)); + } + else { + const { callback } = optionsObj; + diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => { + const patch = diffLinesResultToPatch(diff); + // TypeScript is unhappy without the cast because it does not understand that `patch` may + // be undefined here only if `callback` is StructuredPatchCallbackAbortable: + callback(patch); + } })); + } + function diffLinesResultToPatch(diff) { + // STEP 1: Build up the patch with no "\ No newline at end of file" lines and with the arrays + // of lines containing trailing newline characters. We'll tidy up later... + if (!diff) { + return; + } + diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier + function contextLines(lines) { + return lines.map(function (entry) { return ' ' + entry; }); + } + const hunks = []; + let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1; + for (let i = 0; i < diff.length; i++) { + const current = diff[i], lines = current.lines || splitLines(current.value); + current.lines = lines; + if (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + const prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; + if (prev) { + curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : []; + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } + // Output our changes + for (const line of lines) { + curRange.push((current.added ? '+' : '-') + line); + } + // Track the updated file position + if (current.added) { + newLine += lines.length; + } + else { + oldLine += lines.length; + } + } + else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= context * 2 && i < diff.length - 2) { + // Overlapping + for (const line of contextLines(lines)) { + curRange.push(line); + } + } + else { + // end the range and output + const contextSize = Math.min(lines.length, context); + for (const line of contextLines(lines.slice(0, contextSize))) { + curRange.push(line); + } + const hunk = { + oldStart: oldRangeStart, + oldLines: (oldLine - oldRangeStart + contextSize), + newStart: newRangeStart, + newLines: (newLine - newRangeStart + contextSize), + lines: curRange + }; + hunks.push(hunk); + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } + // Step 2: eliminate the trailing `\n` from each line of each hunk, and, where needed, add + // "\ No newline at end of file". + for (const hunk of hunks) { + for (let i = 0; i < hunk.lines.length; i++) { + if (hunk.lines[i].endsWith('\n')) { + hunk.lines[i] = hunk.lines[i].slice(0, -1); + } + else { + hunk.lines.splice(i + 1, 0, '\\ No newline at end of file'); + i++; // Skip the line we just added, then continue iterating + } + } + } + return { + oldFileName: oldFileName, newFileName: newFileName, + oldHeader: oldHeader, newHeader: newHeader, + hunks: hunks + }; + } +} +/** + * creates a unified diff patch. + * @param patch either a single structured patch object (as returned by `structuredPatch`) or an array of them (as returned by `parsePatch`) + */ +export function formatPatch(patch, headerOptions) { + if (!headerOptions) { + headerOptions = INCLUDE_HEADERS; + } + if (Array.isArray(patch)) { + if (patch.length > 1 && !headerOptions.includeFileHeaders) { + throw new Error('Cannot omit file headers on a multi-file patch. ' + + '(The result would be unparseable; how would a tool trying to apply ' + + 'the patch know which changes are to which file?)'); + } + return patch.map(p => formatPatch(p, headerOptions)).join('\n'); + } + const ret = []; + if (headerOptions.includeIndex && patch.oldFileName == patch.newFileName) { + ret.push('Index: ' + patch.oldFileName); + } + if (headerOptions.includeUnderline) { + ret.push('==================================================================='); + } + if (headerOptions.includeFileHeaders) { + ret.push('--- ' + patch.oldFileName + (typeof patch.oldHeader === 'undefined' ? '' : '\t' + patch.oldHeader)); + ret.push('+++ ' + patch.newFileName + (typeof patch.newHeader === 'undefined' ? '' : '\t' + patch.newHeader)); + } + for (let i = 0; i < patch.hunks.length; i++) { + const hunk = patch.hunks[i]; + // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + if (hunk.oldLines === 0) { + hunk.oldStart -= 1; + } + if (hunk.newLines === 0) { + hunk.newStart -= 1; + } + ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + + ' +' + hunk.newStart + ',' + hunk.newLines + + ' @@'); + for (const line of hunk.lines) { + ret.push(line); + } + } + return ret.join('\n') + '\n'; +} +export function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + if (typeof options === 'function') { + options = { callback: options }; + } + if (!(options === null || options === void 0 ? void 0 : options.callback)) { + const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); + if (!patchObj) { + return; + } + return formatPatch(patchObj, options === null || options === void 0 ? void 0 : options.headerOptions); + } + else { + const { callback } = options; + structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: patchObj => { + if (!patchObj) { + callback(undefined); + } + else { + callback(formatPatch(patchObj, options.headerOptions)); + } + } })); + } +} +export function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { + return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); +} +/** + * Split `text` into an array of lines, including the trailing newline character (where present) + */ +function splitLines(text) { + const hasTrailingNl = text.endsWith('\n'); + const result = text.split('\n').map(line => line + '\n'); + if (hasTrailingNl) { + result.pop(); + } + else { + result.push(result.pop().slice(0, -1)); + } + return result; +} diff --git a/node_modules/diff/libesm/patch/line-endings.js b/node_modules/diff/libesm/patch/line-endings.js new file mode 100644 index 0000000000000..ab54b715f0047 --- /dev/null +++ b/node_modules/diff/libesm/patch/line-endings.js @@ -0,0 +1,44 @@ +export function unixToWin(patch) { + if (Array.isArray(patch)) { + // It would be cleaner if instead of the line below we could just write + // return patch.map(unixToWin) + // but mysteriously TypeScript (v5.7.3 at the time of writing) does not like this and it will + // refuse to compile, thinking that unixToWin could then return StructuredPatch[][] and the + // result would be incompatible with the overload signatures. + // See bug report at https://github.com/microsoft/TypeScript/issues/61398. + return patch.map(p => unixToWin(p)); + } + return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map(hunk => (Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map((line, i) => { + var _a; + return (line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))) + ? line + : line + '\r'; + }) }))) }); +} +export function winToUnix(patch) { + if (Array.isArray(patch)) { + // (See comment above equivalent line in unixToWin) + return patch.map(p => winToUnix(p)); + } + return Object.assign(Object.assign({}, patch), { hunks: patch.hunks.map(hunk => (Object.assign(Object.assign({}, hunk), { lines: hunk.lines.map(line => line.endsWith('\r') ? line.substring(0, line.length - 1) : line) }))) }); +} +/** + * Returns true if the patch consistently uses Unix line endings (or only involves one line and has + * no line endings). + */ +export function isUnix(patch) { + if (!Array.isArray(patch)) { + patch = [patch]; + } + return !patch.some(index => index.hunks.some(hunk => hunk.lines.some(line => !line.startsWith('\\') && line.endsWith('\r')))); +} +/** + * Returns true if the patch uses Windows line endings and only Windows line endings. + */ +export function isWin(patch) { + if (!Array.isArray(patch)) { + patch = [patch]; + } + return patch.some(index => index.hunks.some(hunk => hunk.lines.some(line => line.endsWith('\r')))) + && patch.every(index => index.hunks.every(hunk => hunk.lines.every((line, i) => { var _a; return line.startsWith('\\') || line.endsWith('\r') || ((_a = hunk.lines[i + 1]) === null || _a === void 0 ? void 0 : _a.startsWith('\\')); }))); +} diff --git a/node_modules/diff/libesm/patch/parse.js b/node_modules/diff/libesm/patch/parse.js new file mode 100644 index 0000000000000..1dacac74bcf00 --- /dev/null +++ b/node_modules/diff/libesm/patch/parse.js @@ -0,0 +1,147 @@ +/** + * Parses a patch into structured data, in the same structure returned by `structuredPatch`. + * + * @return a JSON object representation of the a patch, suitable for use with the `applyPatch` method. + */ +export function parsePatch(uniDiff) { + const diffstr = uniDiff.split(/\n/), list = []; + let i = 0; + function parseIndex() { + const index = {}; + list.push(index); + // Parse diff metadata + while (i < diffstr.length) { + const line = diffstr[i]; + // File header found, end parsing diff metadata + if ((/^(---|\+\+\+|@@)\s/).test(line)) { + break; + } + // Try to parse the line as a diff header, like + // Index: README.md + // or + // diff -r 9117c6561b0b -r 273ce12ad8f1 .hgignore + // or + // Index: something with multiple words + // and extract the filename (or whatever else is used as an index name) + // from the end (i.e. 'README.md', '.hgignore', or + // 'something with multiple words' in the examples above). + // + // TODO: It seems awkward that we indiscriminately trim off trailing + // whitespace here. Theoretically, couldn't that be meaningful - + // e.g. if the patch represents a diff of a file whose name ends + // with a space? Seems wrong to nuke it. + // But this behaviour has been around since v2.2.1 in 2015, so if + // it's going to change, it should be done cautiously and in a new + // major release, for backwards-compat reasons. + // -- ExplodingCabbage + const headerMatch = (/^(?:Index:|diff(?: -r \w+)+)\s+/).exec(line); + if (headerMatch) { + index.index = line.substring(headerMatch[0].length).trim(); + } + i++; + } + // Parse file headers if they are defined. Unified diff requires them, but + // there's no technical issues to have an isolated hunk without file header + parseFileHeader(index); + parseFileHeader(index); + // Parse hunks + index.hunks = []; + while (i < diffstr.length) { + const line = diffstr[i]; + if ((/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/).test(line)) { + break; + } + else if ((/^@@/).test(line)) { + index.hunks.push(parseHunk()); + } + else if (line) { + throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(line)); + } + else { + i++; + } + } + } + // Parses the --- and +++ headers, if none are found, no lines + // are consumed. + function parseFileHeader(index) { + const fileHeaderMatch = (/^(---|\+\+\+)\s+/).exec(diffstr[i]); + if (fileHeaderMatch) { + const prefix = fileHeaderMatch[1], data = diffstr[i].substring(3).trim().split('\t', 2), header = (data[1] || '').trim(); + let fileName = data[0].replace(/\\\\/g, '\\'); + if (fileName.startsWith('"') && fileName.endsWith('"')) { + fileName = fileName.substr(1, fileName.length - 2); + } + if (prefix === '---') { + index.oldFileName = fileName; + index.oldHeader = header; + } + else { + index.newFileName = fileName; + index.newHeader = header; + } + i++; + } + } + // Parses a hunk + // This assumes that we are at the start of a hunk. + function parseHunk() { + var _a; + const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); + const hunk = { + oldStart: +chunkHeader[1], + oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], + newStart: +chunkHeader[3], + newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], + lines: [] + }; + // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + if (hunk.oldLines === 0) { + hunk.oldStart += 1; + } + if (hunk.newLines === 0) { + hunk.newStart += 1; + } + let addCount = 0, removeCount = 0; + for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a = diffstr[i]) === null || _a === void 0 ? void 0 : _a.startsWith('\\'))); i++) { + const operation = (diffstr[i].length == 0 && i != (diffstr.length - 1)) ? ' ' : diffstr[i][0]; + if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { + hunk.lines.push(diffstr[i]); + if (operation === '+') { + addCount++; + } + else if (operation === '-') { + removeCount++; + } + else if (operation === ' ') { + addCount++; + removeCount++; + } + } + else { + throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`); + } + } + // Handle the empty block count case + if (!addCount && hunk.newLines === 1) { + hunk.newLines = 0; + } + if (!removeCount && hunk.oldLines === 1) { + hunk.oldLines = 0; + } + // Perform sanity checking + if (addCount !== hunk.newLines) { + throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + if (removeCount !== hunk.oldLines) { + throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + return hunk; + } + while (i < diffstr.length) { + parseIndex(); + } + return list; +} diff --git a/node_modules/diff/libesm/patch/reverse.js b/node_modules/diff/libesm/patch/reverse.js new file mode 100644 index 0000000000000..9207b51c63c55 --- /dev/null +++ b/node_modules/diff/libesm/patch/reverse.js @@ -0,0 +1,23 @@ +export function reversePatch(structuredPatch) { + if (Array.isArray(structuredPatch)) { + // (See comment in unixToWin for why we need the pointless-looking anonymous function here) + return structuredPatch.map(patch => reversePatch(patch)).reverse(); + } + return Object.assign(Object.assign({}, structuredPatch), { oldFileName: structuredPatch.newFileName, oldHeader: structuredPatch.newHeader, newFileName: structuredPatch.oldFileName, newHeader: structuredPatch.oldHeader, hunks: structuredPatch.hunks.map(hunk => { + return { + oldLines: hunk.newLines, + oldStart: hunk.newStart, + newLines: hunk.oldLines, + newStart: hunk.oldStart, + lines: hunk.lines.map(l => { + if (l.startsWith('-')) { + return `+${l.slice(1)}`; + } + if (l.startsWith('+')) { + return `-${l.slice(1)}`; + } + return l; + }) + }; + }) }); +} diff --git a/node_modules/diff/libesm/types.js b/node_modules/diff/libesm/types.js new file mode 100644 index 0000000000000..cb0ff5c3b541f --- /dev/null +++ b/node_modules/diff/libesm/types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/diff/libesm/util/array.js b/node_modules/diff/libesm/util/array.js new file mode 100644 index 0000000000000..c3e00f8500390 --- /dev/null +++ b/node_modules/diff/libesm/util/array.js @@ -0,0 +1,17 @@ +export function arrayEqual(a, b) { + if (a.length !== b.length) { + return false; + } + return arrayStartsWith(a, b); +} +export function arrayStartsWith(array, start) { + if (start.length > array.length) { + return false; + } + for (let i = 0; i < start.length; i++) { + if (start[i] !== array[i]) { + return false; + } + } + return true; +} diff --git a/node_modules/diff/libesm/util/distance-iterator.js b/node_modules/diff/libesm/util/distance-iterator.js new file mode 100644 index 0000000000000..afa638143ece1 --- /dev/null +++ b/node_modules/diff/libesm/util/distance-iterator.js @@ -0,0 +1,37 @@ +// Iterator that traverses in the range of [min, max], stepping +// by distance from a given start position. I.e. for [0, 4], with +// start of 2, this will iterate 2, 3, 1, 4, 0. +export default function (start, minLine, maxLine) { + let wantForward = true, backwardExhausted = false, forwardExhausted = false, localOffset = 1; + return function iterator() { + if (wantForward && !forwardExhausted) { + if (backwardExhausted) { + localOffset++; + } + else { + wantForward = false; + } + // Check if trying to fit beyond text length, and if not, check it fits + // after offset location (or desired location on first iteration) + if (start + localOffset <= maxLine) { + return start + localOffset; + } + forwardExhausted = true; + } + if (!backwardExhausted) { + if (!forwardExhausted) { + wantForward = true; + } + // Check if trying to fit before text beginning, and if not, check it fits + // before offset location + if (minLine <= start - localOffset) { + return start - localOffset++; + } + backwardExhausted = true; + return iterator(); + } + // We tried to fit hunk before text beginning and beyond text length, then + // hunk can't fit on the text. Return undefined + return undefined; + }; +} diff --git a/node_modules/diff/libesm/util/params.js b/node_modules/diff/libesm/util/params.js new file mode 100644 index 0000000000000..c9921a2106257 --- /dev/null +++ b/node_modules/diff/libesm/util/params.js @@ -0,0 +1,14 @@ +export function generateOptions(options, defaults) { + if (typeof options === 'function') { + defaults.callback = options; + } + else if (options) { + for (const name in options) { + /* istanbul ignore else */ + if (Object.prototype.hasOwnProperty.call(options, name)) { + defaults[name] = options[name]; + } + } + } + return defaults; +} diff --git a/node_modules/diff/libesm/util/string.js b/node_modules/diff/libesm/util/string.js new file mode 100644 index 0000000000000..32ab86455bf3f --- /dev/null +++ b/node_modules/diff/libesm/util/string.js @@ -0,0 +1,128 @@ +export function longestCommonPrefix(str1, str2) { + let i; + for (i = 0; i < str1.length && i < str2.length; i++) { + if (str1[i] != str2[i]) { + return str1.slice(0, i); + } + } + return str1.slice(0, i); +} +export function longestCommonSuffix(str1, str2) { + let i; + // Unlike longestCommonPrefix, we need a special case to handle all scenarios + // where we return the empty string since str1.slice(-0) will return the + // entire string. + if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) { + return ''; + } + for (i = 0; i < str1.length && i < str2.length; i++) { + if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) { + return str1.slice(-i); + } + } + return str1.slice(-i); +} +export function replacePrefix(string, oldPrefix, newPrefix) { + if (string.slice(0, oldPrefix.length) != oldPrefix) { + throw Error(`string ${JSON.stringify(string)} doesn't start with prefix ${JSON.stringify(oldPrefix)}; this is a bug`); + } + return newPrefix + string.slice(oldPrefix.length); +} +export function replaceSuffix(string, oldSuffix, newSuffix) { + if (!oldSuffix) { + return string + newSuffix; + } + if (string.slice(-oldSuffix.length) != oldSuffix) { + throw Error(`string ${JSON.stringify(string)} doesn't end with suffix ${JSON.stringify(oldSuffix)}; this is a bug`); + } + return string.slice(0, -oldSuffix.length) + newSuffix; +} +export function removePrefix(string, oldPrefix) { + return replacePrefix(string, oldPrefix, ''); +} +export function removeSuffix(string, oldSuffix) { + return replaceSuffix(string, oldSuffix, ''); +} +export function maximumOverlap(string1, string2) { + return string2.slice(0, overlapCount(string1, string2)); +} +// Nicked from https://stackoverflow.com/a/60422853/1709587 +function overlapCount(a, b) { + // Deal with cases where the strings differ in length + let startA = 0; + if (a.length > b.length) { + startA = a.length - b.length; + } + let endB = b.length; + if (a.length < b.length) { + endB = a.length; + } + // Create a back-reference for each index + // that should be followed in case of a mismatch. + // We only need B to make these references: + const map = Array(endB); + let k = 0; // Index that lags behind j + map[0] = 0; + for (let j = 1; j < endB; j++) { + if (b[j] == b[k]) { + map[j] = map[k]; // skip over the same character (optional optimisation) + } + else { + map[j] = k; + } + while (k > 0 && b[j] != b[k]) { + k = map[k]; + } + if (b[j] == b[k]) { + k++; + } + } + // Phase 2: use these references while iterating over A + k = 0; + for (let i = startA; i < a.length; i++) { + while (k > 0 && a[i] != b[k]) { + k = map[k]; + } + if (a[i] == b[k]) { + k++; + } + } + return k; +} +/** + * Returns true if the string consistently uses Windows line endings. + */ +export function hasOnlyWinLineEndings(string) { + return string.includes('\r\n') && !string.startsWith('\n') && !string.match(/[^\r]\n/); +} +/** + * Returns true if the string consistently uses Unix line endings. + */ +export function hasOnlyUnixLineEndings(string) { + return !string.includes('\r\n') && string.includes('\n'); +} +export function trailingWs(string) { + // Yes, this looks overcomplicated and dumb - why not replace the whole function with + // return string.match(/\s*$/)[0] + // you ask? Because: + // 1. the trap described at https://markamery.com/blog/quadratic-time-regexes/ would mean doing + // this would cause this function to take O(n²) time in the worst case (specifically when + // there is a massive run of NON-TRAILING whitespace in `string`), and + // 2. the fix proposed in the same blog post, of using a negative lookbehind, is incompatible + // with old Safari versions that we'd like to not break if possible (see + // https://github.com/kpdecker/jsdiff/pull/550) + // It feels absurd to do this with an explicit loop instead of a regex, but I really can't see a + // better way that doesn't result in broken behaviour. + let i; + for (i = string.length - 1; i >= 0; i--) { + if (!string[i].match(/\s/)) { + break; + } + } + return string.substring(i + 1); +} +export function leadingWs(string) { + // Thankfully the annoying considerations described in trailingWs don't apply here: + const match = string.match(/^\s*/); + return match ? match[0] : ''; +} diff --git a/node_modules/diff/package.json b/node_modules/diff/package.json index 2b6eea7f1cbff..f5a87f0610a88 100644 --- a/node_modules/diff/package.json +++ b/node_modules/diff/package.json @@ -1,7 +1,7 @@ { "name": "diff", - "version": "5.0.0", - "description": "A javascript text diff implementation.", + "version": "8.0.3", + "description": "A JavaScript text diff implementation.", "keywords": [ "diff", "jsdiff", @@ -13,7 +13,8 @@ "javascript" ], "maintainers": [ - "Kevin Decker <kpdecker@gmail.com> (http://incaseofstairs.com)" + "Kevin Decker <kpdecker@gmail.com> (http://incaseofstairs.com)", + "Mark Amery <markrobertamery+jsdiff@gmail.com>" ], "bugs": { "email": "kpdecker@gmail.com", @@ -22,66 +23,110 @@ "license": "BSD-3-Clause", "repository": { "type": "git", - "url": "git://github.com/kpdecker/jsdiff.git" + "url": "https://github.com/kpdecker/jsdiff.git" }, "engines": { "node": ">=0.3.1" }, - "main": "./lib/index.js", - "module": "./lib/index.es6.js", + "main": "./libcjs/index.js", + "module": "./libesm/index.js", "browser": "./dist/diff.js", "unpkg": "./dist/diff.js", "exports": { ".": { - "import": "./lib/index.mjs", - "require": "./lib/index.js" + "import": { + "types": "./libesm/index.d.ts", + "default": "./libesm/index.js" + }, + "require": { + "types": "./libcjs/index.d.ts", + "default": "./libcjs/index.js" + } }, "./package.json": "./package.json", - "./": "./" + "./lib/*.js": { + "import": { + "types": "./libesm/*.d.ts", + "default": "./libesm/*.js" + }, + "require": { + "types": "./libcjs/*.d.ts", + "default": "./libcjs/*.js" + } + }, + "./lib/": { + "import": { + "types": "./libesm/", + "default": "./libesm/" + }, + "require": { + "types": "./libcjs/", + "default": "./libcjs/" + } + } }, + "type": "module", + "types": "libcjs/index.d.ts", "scripts": { - "clean": "rm -rf lib/ dist/", - "build:node": "yarn babel --out-dir lib --source-maps=inline src", - "test": "grunt" + "clean": "rm -rf libcjs/ libesm/ dist/ coverage/ .nyc_output/", + "lint": "yarn eslint", + "build": "yarn lint && yarn generate-esm && yarn generate-cjs && yarn check-types && yarn run-rollup && yarn run-uglify", + "generate-cjs": "yarn tsc --module commonjs --outDir libcjs && node --eval \"fs.writeFileSync('libcjs/package.json', JSON.stringify({type:'commonjs',sideEffects:false}))\"", + "generate-esm": "yarn tsc --module nodenext --outDir libesm --target es6 && node --eval \"fs.writeFileSync('libesm/package.json', JSON.stringify({type:'module',sideEffects:false}))\"", + "check-types": "yarn run-tsd && yarn run-attw", + "test": "nyc yarn _test", + "_test": "yarn build && cross-env NODE_ENV=test yarn run-mocha", + "run-attw": "yarn attw --pack --entrypoints . && yarn attw --pack --entrypoints lib/diff/word.js --profile node16", + "run-tsd": "yarn tsd --typings libesm/ && yarn tsd --files test-d/", + "run-rollup": "rollup -c rollup.config.mjs", + "run-uglify": "uglifyjs dist/diff.js -c -o dist/diff.min.js", + "run-mocha": "mocha --require ./runtime 'test/**/*.js'" }, "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/plugin-transform-modules-commonjs": "^7.2.0", - "@babel/preset-env": "^7.2.3", - "@babel/register": "^7.0.0", - "babel-eslint": "^10.0.1", - "babel-loader": "^8.0.5", - "chai": "^4.2.0", - "colors": "^1.3.3", - "eslint": "^5.12.0", - "grunt": "^1.0.3", - "grunt-babel": "^8.0.0", - "grunt-cli": "^1.3.2", - "grunt-contrib-clean": "^2.0.0", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-uglify": "^5.0.0", - "grunt-contrib-watch": "^1.1.0", - "grunt-eslint": "^23.0.0", - "grunt-exec": "^3.0.0", - "grunt-karma": "^4.0.0", - "grunt-mocha-istanbul": "^5.0.2", - "grunt-mocha-test": "^0.13.3", - "grunt-webpack": "^3.1.3", - "istanbul": "github:kpdecker/istanbul", - "karma": "^5.1.1", - "karma-chrome-launcher": "^3.1.0", + "@arethetypeswrong/cli": "^0.17.4", + "@babel/core": "^7.26.9", + "@babel/preset-env": "^7.26.9", + "@babel/register": "^7.25.9", + "@colors/colors": "^1.6.0", + "@eslint/js": "^9.25.1", + "babel-loader": "^10.0.0", + "babel-plugin-istanbul": "^7.0.0", + "chai": "^5.2.0", + "cross-env": "^7.0.3", + "eslint": "^9.25.1", + "globals": "^16.0.0", + "karma": "^6.4.4", "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.0.0", - "karma-sauce-launcher": "^4.1.5", - "karma-sourcemap-loader": "^0.3.6", - "karma-webpack": "^4.0.2", - "mocha": "^6.0.0", - "rollup": "^1.0.2", - "rollup-plugin-babel": "^4.2.0", - "semver": "^7.3.2", - "webpack": "^4.28.3", - "webpack-dev-server": "^3.1.14" + "karma-mocha-reporter": "^2.2.5", + "karma-sourcemap-loader": "^0.4.0", + "karma-webpack": "^5.0.1", + "mocha": "^11.1.0", + "nyc": "^17.1.0", + "rollup": "^4.40.1", + "tsd": "^0.32.0", + "typescript": "^5.8.3", + "typescript-eslint": "^8.31.0", + "uglify-js": "^3.19.3", + "webpack": "^5.99.7", + "webpack-dev-server": "^5.2.1" + }, + "optionalDependencies": {}, + "dependencies": {}, + "nyc": { + "require": [ + "@babel/register" + ], + "reporter": [ + "lcov", + "text" + ], + "sourceMap": false, + "instrument": false, + "check-coverage": true, + "branches": 100, + "lines": 100, + "functions": 100, + "statements": 100 }, - "optionalDependencies": {} + "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610" } diff --git a/node_modules/diff/release-notes.md b/node_modules/diff/release-notes.md index acc75aa83d88e..28b633788c394 100644 --- a/node_modules/diff/release-notes.md +++ b/node_modules/diff/release-notes.md @@ -1,8 +1,109 @@ # Release Notes -## Development +## 8.0.3 -[Commits](https://github.com/kpdecker/jsdiff/compare/v5.0.0...master) +- [#631](https://github.com/kpdecker/jsdiff/pull/631) - **fix support for using an `Intl.Segmenter` with `diffWords`**. This has been almost completely broken since the feature was added in v6.0.0, since it would outright crash on any text that featured two consecutive newlines between a pair of words (a very common case). +- [#635](https://github.com/kpdecker/jsdiff/pull/635) - **small tweaks to tokenization behaviour of `diffWords`** when used *without* an `Intl.Segmenter`. Specifically, the soft hyphen (U+00AD) is no longer considered to be a word break, and the multiplication and division signs (`×` and `÷`) are now treated as punctuation instead of as letters / word characters. +- [#641](https://github.com/kpdecker/jsdiff/pull/641) - **the format of file headers in `createPatch` etc. patches can now be customised somewhat**. It now takes a `headerOptions` option that can be used to disable the file headers entirely, or omit the `Index:` line and/or the underline. In particular, this was motivated by a request to make jsdiff patches compatible with react-diff-view, which they now are if produced with `headerOptions: FILE_HEADERS_ONLY`. +- [#647](https://github.com/kpdecker/jsdiff/pull/647) and [#649](https://github.com/kpdecker/jsdiff/pull/649) - **fix denial-of-service vulnerabilities in `parsePatch` whereby adversarial input could cause a memory-leaking infinite loop, typically crashing the calling process**. Also fixed ReDOS vulnerabilities whereby adversarially-crafted patch headers could take cubic time to parse. Now, `parsePatch` should reliably take linear time. (Handling of headers that include the line break characters `\r`, `\u2028`, or `\u2029` in non-trailing positions is also now more reasonable as side effect of the fix.) + +## 8.0.2 + +- [#616](https://github.com/kpdecker/jsdiff/pull/616) **Restored compatibility of `diffSentences` with old Safari versions.** This was broken in 8.0.0 by the introduction of a regex with a [lookbehind assertion](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion); these weren't supported in Safari prior to version 16.4. +- [#612](https://github.com/kpdecker/jsdiff/pull/612) **Improved tree shakeability** by marking the built CJS and ESM packages with `sideEffects: false`. + +## 8.0.1 + +- [#610](https://github.com/kpdecker/jsdiff/pull/610) **Fixes types for `diffJson` which were broken by 8.0.0**. The new bundled types in 8.0.0 only allowed `diffJson` to be passed string arguments, but it should've been possible to pass either strings or objects (and now is). Thanks to Josh Kelley for the fix. + +## 8.0.0 + +- [#580](https://github.com/kpdecker/jsdiff/pull/580) **Multiple tweaks to `diffSentences`**: + * tokenization no longer takes quadratic time on pathological inputs (reported as a ReDOS vulnerability by Snyk); is now linear instead + * the final sentence in the string is now handled the same by the tokenizer regardless of whether it has a trailing punctuation mark or not. (Previously, "foo. bar." tokenized to `["foo.", " ", "bar."]` but "foo. bar" tokenized to `["foo.", " bar"]` - i.e. whether the space between sentences was treated as a separate token depended upon whether the final sentence had trailing punctuation or not. This was arbitrary and surprising; it is no longer the case.) + * in a string that starts with a sentence end, like "! hello.", the "!" is now treated as a separate sentence + * the README now correctly documents the tokenization behaviour (it was wrong before) +- [#581](https://github.com/kpdecker/jsdiff/pull/581) - **fixed some regex operations used for tokenization in `diffWords` taking O(n^2) time** in pathological cases +- [#595](https://github.com/kpdecker/jsdiff/pull/595) - **fixed a crash in patch creation functions when handling a single hunk consisting of a very large number (e.g. >130k) of lines**. (This was caused by spreading indefinitely-large arrays to `.push()` using `.apply` or the spread operator and hitting the JS-implementation-specific limit on the maximum number of arguments to a function, as shown at https://stackoverflow.com/a/56809779/1709587; thus the exact threshold to hit the error will depend on the environment in which you were running JsDiff.) +- [#596](https://github.com/kpdecker/jsdiff/pull/596) - **removed the `merge` function**. Previously JsDiff included an undocumented function called `merge` that was meant to, in some sense, merge patches. It had at least a couple of serious bugs that could lead to it returning unambiguously wrong results, and it was difficult to simply "fix" because it was [unclear precisely what it was meant to do](https://github.com/kpdecker/jsdiff/issues/181#issuecomment-2198319542). For now, the fix is to remove it entirely. +- [#591](https://github.com/kpdecker/jsdiff/pull/591) - JsDiff's source code has been rewritten in TypeScript. This change entails the following changes for end users: + * **the `diff` package on npm now includes its own TypeScript type definitions**. Users who previously used the `@types/diff` npm package from DefinitelyTyped should remove that dependency when upgrading JsDiff to v8. + + Note that the transition from the DefinitelyTyped types to JsDiff's own type definitions includes multiple fixes and also removes many exported types previously used for `options` arguments to diffing and patch-generation functions. (There are now different exported options types for abortable calls - ones with a `timeout` or `maxEditLength` that may give a result of `undefined` - and non-abortable calls.) See the TypeScript section of the README for some usage tips. + + * **The `Diff` object is now a class**. Custom extensions of `Diff`, as described in the "Defining custom diffing behaviors" section of the README, can therefore now be done by writing a `class CustomDiff extends Diff` and overriding methods, instead of the old way based on prototype inheritance. (I *think* code that did things the old way should still work, though!) + + * **`diff/lib/index.es6.js` and `diff/lib/index.mjs` no longer exist, and the ESM version of the library is no longer bundled into a single file.** + + * **The `ignoreWhitespace` option for `diffWords` is no longer included in the type declarations**. The effect of passing `ignoreWhitespace: true` has always been to make `diffWords` just call `diffWordsWithSpace` instead, which was confusing, because that behaviour doesn't seem properly described as "ignoring" whitespace at all. The property remains available to non-TypeScript applications for the sake of backwards compatibility, but TypeScript applications will now see a type error if they try to pass `ignoreWhitespace: true` to `diffWords` and should change their code to call `diffWordsWithSpace` instead. + + * JsDiff no longer purports to support ES3 environments. (I'm pretty sure it never truly did, despite claiming to in its README, since even the 1.0.0 release used `Array.map` which was added in ES5.) +- [#601](https://github.com/kpdecker/jsdiff/pull/601) - **`diffJson`'s `stringifyReplacer` option behaves more like `JSON.stringify`'s `replacer` argument now.** In particular: + * Each key/value pair now gets passed through the replacer once instead of twice + * The `key` passed to the replacer when the top-level object is passed in as `value` is now `""` (previously, was `undefined`), and the `key` passed with an array element is the array index as a string, like `"0"` or `"1"` (previously was whatever the key for the entire array was). Both the new behaviours match that of `JSON.stringify`. +- [#602](https://github.com/kpdecker/jsdiff/pull/602) - **diffing functions now consistently return `undefined` when called in async mode** (i.e. with a callback). Previously, there was an odd quirk where they would return `true` if the strings being diffed were equal and `undefined` otherwise. + +## 7.0.0 + +Just a single (breaking) bugfix, undoing a behaviour change introduced accidentally in 6.0.0: + +- [#554](https://github.com/kpdecker/jsdiff/pull/554) **`diffWords` treats numbers and underscores as word characters again.** This behaviour was broken in v6.0.0. + +## 6.0.0 + +This is a release containing many, *many* breaking changes. The objective of this release was to carry out a mass fix, in one go, of all the open bugs and design problems that required breaking changes to fix. A substantial, but exhaustive, changelog is below. + +[Commits](https://github.com/kpdecker/jsdiff/compare/v5.2.0...v6.0.0) + +- [#497](https://github.com/kpdecker/jsdiff/pull/497) **`diffWords` behavior has been radically changed.** Previously, even with `ignoreWhitespace: true`, runs of whitespace were tokens, which led to unhelpful and unintuitive diffing behavior in typical texts. Specifically, even when two texts contained overlapping passages, `diffWords` would sometimes choose to delete all the words from the old text and insert them anew in their new positions in order to avoid having to delete or insert whitespace tokens. Whitespace sequences are no longer tokens as of this release, which affects both the generated diffs and the `count`s. + + Runs of whitespace are still tokens in `diffWordsWithSpace`. + + As part of the changes to `diffWords`, **a new `.postProcess` method has been added on the base `Diff` type**, which can be overridden in custom `Diff` implementations. + + **`diffLines` with `ignoreWhitespace: true` will no longer ignore the insertion or deletion of entire extra lines of whitespace at the end of the text**. Previously, these would not show up as insertions or deletions, as a side effect of a hack in the base diffing algorithm meant to help ignore whitespace in `diffWords`. More generally, **the undocumented special handling in the core algorithm for ignored terminals has been removed entirely.** (This special case behavior used to rewrite the final two change objects in a scenario where the final change object was an addition or deletion and its `value` was treated as equal to the empty string when compared using the diff object's `.equals` method.) + +- [#500](https://github.com/kpdecker/jsdiff/pull/500) **`diffChars` now diffs Unicode code points** instead of UTF-16 code units. +- [#508](https://github.com/kpdecker/jsdiff/pull/508) **`parsePatch` now always runs in what was previously "strict" mode; the undocumented `strict` option has been removed.** Previously, by default, `parsePatch` (and other patch functions that use it under the hood to parse patches) would accept a patch where the line counts in the headers were inconsistent with the actual patch content - e.g. where a hunk started with the header `@@ -1,3 +1,6 @@`, indicating that the content below spanned 3 lines in the old file and 6 lines in the new file, but then the actual content below the header consisted of some different number of lines, say 10 lines of context, 5 deletions, and 1 insertion. Actually trying to work with these patches using `applyPatch` or `merge`, however, would produce incorrect results instead of just ignoring the incorrect headers, making this "feature" more of a trap than something actually useful. It's been ripped out, and now we are always "strict" and will reject patches where the line counts in the headers aren't consistent with the actual patch content. +- [#435](https://github.com/kpdecker/jsdiff/pull/435) **Fix `parsePatch` handling of control characters.** `parsePatch` used to interpret various unusual control characters - namely vertical tabs, form feeds, lone carriage returns without a line feed, and EBCDIC NELs - as line breaks when parsing a patch file. This was inconsistent with the behavior of both JsDiff's own `diffLines` method and also the Unix `diff` and `patch` utils, which all simply treat those control characters as ordinary characters. The result of this discrepancy was that some well-formed patches - produced either by `diff` or by JsDiff itself and handled properly by the `patch` util - would be wrongly parsed by `parsePatch`, with the effect that it would disregard the remainder of a hunk after encountering one of these control characters. +- [#439](https://github.com/kpdecker/jsdiff/pull/439) **Prefer diffs that order deletions before insertions.** When faced with a choice between two diffs with an equal total edit distance, the Myers diff algorithm generally prefers one that does deletions before insertions rather than insertions before deletions. For instance, when diffing `abcd` against `acbd`, it will prefer a diff that says to delete the `b` and then insert a new `b` after the `c`, over a diff that says to insert a `c` before the `b` and then delete the existing `c`. JsDiff deviated from the published Myers algorithm in a way that led to it having the opposite preference in many cases, including that example. This is now fixed, meaning diffs output by JsDiff will more accurately reflect what the published Myers diff algorithm would output. +- [#455](https://github.com/kpdecker/jsdiff/pull/455) **The `added` and `removed` properties of change objects are now guaranteed to be set to a boolean value.** (Previously, they would be set to `undefined` or omitted entirely instead of setting them to false.) +- [#464](https://github.com/kpdecker/jsdiff/pull/464) Specifying `{maxEditLength: 0}` now sets a max edit length of 0 instead of no maximum. +- [#460](https://github.com/kpdecker/jsdiff/pull/460) **Added `oneChangePerToken` option.** +- [#467](https://github.com/kpdecker/jsdiff/pull/467) **Consistent ordering of arguments to `comparator(left, right)`.** Values from the old array will now consistently be passed as the first argument (`left`) and values from the new array as the second argument (`right`). Previously this was almost (but not quite) always the other way round. +- [#480](https://github.com/kpdecker/jsdiff/pull/480) **Passing `maxEditLength` to `createPatch` & `createTwoFilesPatch` now works properly** (i.e. returns undefined if the max edit distance is exceeded; previous behavior was to crash with a `TypeError` if the edit distance was exceeded). +- [#486](https://github.com/kpdecker/jsdiff/pull/486) **The `ignoreWhitespace` option of `diffLines` behaves more sensibly now.** `value`s in returned change objects now include leading/trailing whitespace even when `ignoreWhitespace` is used, just like how with `ignoreCase` the `value`s still reflect the case of one of the original texts instead of being all-lowercase. `ignoreWhitespace` is also now compatible with `newlineIsToken`. Finally, **`diffTrimmedLines` is deprecated** (and removed from the docs) in favour of using `diffLines` with `ignoreWhitespace: true`; the two are, and always have been, equivalent. +- [#490](https://github.com/kpdecker/jsdiff/pull/490) **When calling diffing functions in async mode by passing a `callback` option, the diff result will now be passed as the *first* argument to the callback instead of the second.** (Previously, the first argument was never used at all and would always have value `undefined`.) +- [#489](https://github.com/kpdecker/jsdiff/pull/489) **`this.options` no longer exists on `Diff` objects.** Instead, `options` is now passed as an argument to methods that rely on options, like `equals(left, right, options)`. This fixes a race condition in async mode, where diffing behaviour could be changed mid-execution if a concurrent usage of the same `Diff` instances overwrote its `options`. +- [#518](https://github.com/kpdecker/jsdiff/pull/518) **`linedelimiters` no longer exists** on patch objects; instead, when a patch with Windows-style CRLF line endings is parsed, **the lines in `lines` will end with `\r`**. There is now a **new `autoConvertLineEndings` option, on by default**, which makes it so that when a patch with Windows-style line endings is applied to a source file with Unix style line endings, the patch gets autoconverted to use Unix-style line endings, and when a patch with Unix-style line endings is applied to a source file with Windows-style line endings, it gets autoconverted to use Windows-style line endings. +- [#521](https://github.com/kpdecker/jsdiff/pull/521) **the `callback` option is now supported by `structuredPatch`, `createPatch`, and `createTwoFilesPatch`** +- [#529](https://github.com/kpdecker/jsdiff/pull/529) **`parsePatch` can now parse patches where lines starting with `--` or `++` are deleted/inserted**; previously, there were edge cases where the parser would choke on valid patches or give wrong results. +- [#530](https://github.com/kpdecker/jsdiff/pull/530) **Added `ignoreNewlineAtEof` option to `diffLines`** +- [#533](https://github.com/kpdecker/jsdiff/pull/533) **`applyPatch` uses an entirely new algorithm for fuzzy matching.** Differences between the old and new algorithm are as follows: + * The `fuzzFactor` now indicates the maximum [*Levenshtein* distance](https://en.wikipedia.org/wiki/Levenshtein_distance) that there can be between the context shown in a hunk and the actual file content at a location where we try to apply the hunk. (Previously, it represented a maximum [*Hamming* distance](https://en.wikipedia.org/wiki/Hamming_distance), meaning that a single insertion or deletion in the source file could stop a hunk from applying even with a high `fuzzFactor`.) + * A hunk containing a deletion can now only be applied in a context where the line to be deleted actually appears verbatim. (Previously, as long as enough context lines in the hunk matched, `applyPatch` would apply the hunk anyway and delete a completely different line.) + * The context line immediately before and immediately after an insertion must match exactly between the hunk and the file for a hunk to apply. (Previously this was not required.) +- [#535](https://github.com/kpdecker/jsdiff/pull/535) **A bug in patch generation functions is now fixed** that would sometimes previously cause `\ No newline at end of file` to appear in the wrong place in the generated patch, resulting in the patch being invalid. **These invalid patches can also no longer be applied successfully with `applyPatch`.** (It was already the case that tools other than jsdiff, like GNU `patch`, would consider them malformed and refuse to apply them; versions of jsdiff with this fix now do the same thing if you ask them to apply a malformed patch emitted by jsdiff v5.) +- [#535](https://github.com/kpdecker/jsdiff/pull/535) **Passing `newlineIsToken: true` to *patch*-generation functions is no longer allowed.** (Passing it to `diffLines` is still supported - it's only functions like `createPatch` where passing `newlineIsToken` is now an error.) Allowing it to be passed never really made sense, since in cases where the option had any effect on the output at all, the effect tended to be causing a garbled patch to be created that couldn't actually be applied to the source file. +- [#539](https://github.com/kpdecker/jsdiff/pull/539) **`diffWords` now takes an optional `intlSegmenter` option** which should be an `Intl.Segmenter` with word-level granularity. This provides better tokenization of text into words than the default behaviour, even for English but especially for some other languages for which the default behaviour is poor. + +## v5.2.0 + +[Commits](https://github.com/kpdecker/jsdiff/compare/v5.1.0...v5.2.0) + +- [#411](https://github.com/kpdecker/jsdiff/pull/411) Big performance improvement. Previously an O(n) array-copying operation inside the innermost loop of jsdiff's base diffing code increased the overall worst-case time complexity of computing a diff from O(n²) to O(n³). This is now fixed, bringing the worst-case time complexity down to what it theoretically should be for a Myers diff implementation. +- [#448](https://github.com/kpdecker/jsdiff/pull/448) Performance improvement. Diagonals whose furthest-reaching D-path would go off the edge of the edit graph are now skipped, rather than being pointlessly considered as called for by the original Myers diff algorithm. This dramatically speeds up computing diffs where the new text just appends or truncates content at the end of the old text. +- [#351](https://github.com/kpdecker/jsdiff/issues/351) Importing from the lib folder - e.g. `require("diff/lib/diff/word.js")` - will work again now. This had been broken for users on the latest version of Node since Node 17.5.0, which changed how Node interprets the `exports` property in jsdiff's `package.json` file. +- [#344](https://github.com/kpdecker/jsdiff/issues/344) `diffLines`, `createTwoFilesPatch`, and other patch-creation methods now take an optional `stripTrailingCr: true` option which causes Windows-style `\r\n` line endings to be replaced with Unix-style `\n` line endings before calculating the diff, just like GNU `diff`'s `--strip-trailing-cr` flag. +- [#451](https://github.com/kpdecker/jsdiff/pull/451) Added `diff.formatPatch`. +- [#450](https://github.com/kpdecker/jsdiff/pull/450) Added `diff.reversePatch`. +- [#478](https://github.com/kpdecker/jsdiff/pull/478) Added `timeout` option. + +## v5.1.0 + +- [#365](https://github.com/kpdecker/jsdiff/issues/365) Allow early termination to limit execution time with degenerate cases + +[Commits](https://github.com/kpdecker/jsdiff/compare/v5.0.0...v5.1.0) ## v5.0.0 diff --git a/node_modules/diff/runtime.js b/node_modules/diff/runtime.js deleted file mode 100644 index 82ea7e696aa01..0000000000000 --- a/node_modules/diff/runtime.js +++ /dev/null @@ -1,3 +0,0 @@ -require('@babel/register')({ - ignore: ['lib', 'node_modules'] -}); diff --git a/node_modules/emoji-regex/index.d.ts b/node_modules/emoji-regex/index.d.ts deleted file mode 100644 index 1955b4704ecfc..0000000000000 --- a/node_modules/emoji-regex/index.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -declare module 'emoji-regex' { - function emojiRegex(): RegExp; - - export default emojiRegex; -} - -declare module 'emoji-regex/text' { - function emojiRegex(): RegExp; - - export default emojiRegex; -} - -declare module 'emoji-regex/es2015' { - function emojiRegex(): RegExp; - - export default emojiRegex; -} - -declare module 'emoji-regex/es2015/text' { - function emojiRegex(): RegExp; - - export default emojiRegex; -} diff --git a/node_modules/env-paths/index.d.ts b/node_modules/env-paths/index.d.ts deleted file mode 100644 index 277ddc0a183c9..0000000000000 --- a/node_modules/env-paths/index.d.ts +++ /dev/null @@ -1,101 +0,0 @@ -declare namespace envPaths { - export interface Options { - /** - __Don't use this option unless you really have to!__ - - Suffix appended to the project name to avoid name conflicts with native apps. Pass an empty string to disable it. - - @default 'nodejs' - */ - readonly suffix?: string; - } - - export interface Paths { - /** - Directory for data files. - - Example locations (with the default `nodejs` suffix): - - - macOS: `~/Library/Application Support/MyApp-nodejs` - - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Data` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Data`) - - Linux: `~/.local/share/MyApp-nodejs` (or `$XDG_DATA_HOME/MyApp-nodejs`) - */ - readonly data: string; - - /** - Directory for data files. - - Example locations (with the default `nodejs` suffix): - - - macOS: `~/Library/Preferences/MyApp-nodejs` - - Windows: `%APPDATA%\MyApp-nodejs\Config` (for example, `C:\Users\USERNAME\AppData\Roaming\MyApp-nodejs\Config`) - - Linux: `~/.config/MyApp-nodejs` (or `$XDG_CONFIG_HOME/MyApp-nodejs`) - */ - readonly config: string; - - /** - Directory for non-essential data files. - - Example locations (with the default `nodejs` suffix): - - - macOS: `~/Library/Caches/MyApp-nodejs` - - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Cache` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Cache`) - - Linux: `~/.cache/MyApp-nodejs` (or `$XDG_CACHE_HOME/MyApp-nodejs`) - */ - readonly cache: string; - - /** - Directory for log files. - - Example locations (with the default `nodejs` suffix): - - - macOS: `~/Library/Logs/MyApp-nodejs` - - Windows: `%LOCALAPPDATA%\MyApp-nodejs\Log` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Log`) - - Linux: `~/.local/state/MyApp-nodejs` (or `$XDG_STATE_HOME/MyApp-nodejs`) - */ - readonly log: string; - - /** - Directory for temporary files. - - Example locations (with the default `nodejs` suffix): - - - macOS: `/var/folders/jf/f2twvvvs5jl_m49tf034ffpw0000gn/T/MyApp-nodejs` - - Windows: `%LOCALAPPDATA%\Temp\MyApp-nodejs` (for example, `C:\Users\USERNAME\AppData\Local\Temp\MyApp-nodejs`) - - Linux: `/tmp/USERNAME/MyApp-nodejs` - */ - readonly temp: string; - } -} - -declare const envPaths: { - /** - Get paths for storing things like data, config, cache, etc. - - Note: It only generates the path strings. It doesn't create the directories for you. You could use [`make-dir`](https://github.com/sindresorhus/make-dir) to create the directories. - - @param name - Name of your project. Used to generate the paths. - @returns The paths to use for your project on current OS. - - @example - ``` - import envPaths = require('env-paths'); - - const paths = envPaths('MyApp'); - - paths.data; - //=> '/home/sindresorhus/.local/share/MyApp-nodejs' - - paths.config - //=> '/home/sindresorhus/.config/MyApp-nodejs' - ``` - */ - (name: string, options?: envPaths.Options): envPaths.Paths; - - // TODO: Remove this for the next major release, refactor the whole definition to: - // declare function envPaths(name: string, options?: envPaths.Options): envPaths.Paths; - // export = envPaths; - default: typeof envPaths; -}; - -export = envPaths; diff --git a/node_modules/env-paths/readme.md b/node_modules/env-paths/readme.md deleted file mode 100644 index b66d571af48df..0000000000000 --- a/node_modules/env-paths/readme.md +++ /dev/null @@ -1,115 +0,0 @@ -# env-paths - -> Get paths for storing things like data, config, cache, etc - -Uses the correct OS-specific paths. Most developers get this wrong. - - -## Install - -``` -$ npm install env-paths -``` - - -## Usage - -```js -const envPaths = require('env-paths'); - -const paths = envPaths('MyApp'); - -paths.data; -//=> '/home/sindresorhus/.local/share/MyApp-nodejs' - -paths.config -//=> '/home/sindresorhus/.config/MyApp-nodejs' -``` - - -## API - -### paths = envPaths(name, options?) - -Note: It only generates the path strings. It doesn't create the directories for you. You could use [`make-dir`](https://github.com/sindresorhus/make-dir) to create the directories. - -#### name - -Type: `string` - -Name of your project. Used to generate the paths. - -#### options - -Type: `object` - -##### suffix - -Type: `string`<br> -Default: `'nodejs'` - -**Don't use this option unless you really have to!**<br> -Suffix appended to the project name to avoid name conflicts with native -apps. Pass an empty string to disable it. - -### paths.data - -Directory for data files. - -Example locations (with the default `nodejs` [suffix](#suffix)): - -- macOS: `~/Library/Application Support/MyApp-nodejs` -- Windows: `%LOCALAPPDATA%\MyApp-nodejs\Data` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Data`) -- Linux: `~/.local/share/MyApp-nodejs` (or `$XDG_DATA_HOME/MyApp-nodejs`) - -### paths.config - -Directory for config files. - -Example locations (with the default `nodejs` [suffix](#suffix)): - -- macOS: `~/Library/Preferences/MyApp-nodejs` -- Windows: `%APPDATA%\MyApp-nodejs\Config` (for example, `C:\Users\USERNAME\AppData\Roaming\MyApp-nodejs\Config`) -- Linux: `~/.config/MyApp-nodejs` (or `$XDG_CONFIG_HOME/MyApp-nodejs`) - -### paths.cache - -Directory for non-essential data files. - -Example locations (with the default `nodejs` [suffix](#suffix)): - -- macOS: `~/Library/Caches/MyApp-nodejs` -- Windows: `%LOCALAPPDATA%\MyApp-nodejs\Cache` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Cache`) -- Linux: `~/.cache/MyApp-nodejs` (or `$XDG_CACHE_HOME/MyApp-nodejs`) - -### paths.log - -Directory for log files. - -Example locations (with the default `nodejs` [suffix](#suffix)): - -- macOS: `~/Library/Logs/MyApp-nodejs` -- Windows: `%LOCALAPPDATA%\MyApp-nodejs\Log` (for example, `C:\Users\USERNAME\AppData\Local\MyApp-nodejs\Log`) -- Linux: `~/.local/state/MyApp-nodejs` (or `$XDG_STATE_HOME/MyApp-nodejs`) - -### paths.temp - -Directory for temporary files. - -Example locations (with the default `nodejs` [suffix](#suffix)): - -- macOS: `/var/folders/jf/f2twvvvs5jl_m49tf034ffpw0000gn/T/MyApp-nodejs` -- Windows: `%LOCALAPPDATA%\Temp\MyApp-nodejs` (for example, `C:\Users\USERNAME\AppData\Local\Temp\MyApp-nodejs`) -- Linux: `/tmp/USERNAME/MyApp-nodejs` - ---- - -<div align="center"> - <b> - <a href="https://tidelift.com/subscription/pkg/npm-env-paths?utm_source=npm-env-paths&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> - </b> - <br> - <sub> - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. - </sub> -</div> diff --git a/node_modules/exponential-backoff/LICENSE b/node_modules/exponential-backoff/LICENSE new file mode 100644 index 0000000000000..4be46a90670d8 --- /dev/null +++ b/node_modules/exponential-backoff/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Coveo Solutions Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/exponential-backoff/dist/backoff.js b/node_modules/exponential-backoff/dist/backoff.js new file mode 100644 index 0000000000000..6a1b6bd3835ac --- /dev/null +++ b/node_modules/exponential-backoff/dist/backoff.js @@ -0,0 +1,124 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var options_1 = require("./options"); +var delay_factory_1 = require("./delay/delay.factory"); +/** + * Executes a function with exponential backoff. + * @param request the function to be executed + * @param options options to customize the backoff behavior + * @returns Promise that resolves to the result of the `request` function + */ +function backOff(request, options) { + if (options === void 0) { options = {}; } + return __awaiter(this, void 0, void 0, function () { + var sanitizedOptions, backOff; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + sanitizedOptions = options_1.getSanitizedOptions(options); + backOff = new BackOff(request, sanitizedOptions); + return [4 /*yield*/, backOff.execute()]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); +} +exports.backOff = backOff; +var BackOff = /** @class */ (function () { + function BackOff(request, options) { + this.request = request; + this.options = options; + this.attemptNumber = 0; + } + BackOff.prototype.execute = function () { + return __awaiter(this, void 0, void 0, function () { + var e_1, shouldRetry; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!!this.attemptLimitReached) return [3 /*break*/, 7]; + _a.label = 1; + case 1: + _a.trys.push([1, 4, , 6]); + return [4 /*yield*/, this.applyDelay()]; + case 2: + _a.sent(); + return [4 /*yield*/, this.request()]; + case 3: return [2 /*return*/, _a.sent()]; + case 4: + e_1 = _a.sent(); + this.attemptNumber++; + return [4 /*yield*/, this.options.retry(e_1, this.attemptNumber)]; + case 5: + shouldRetry = _a.sent(); + if (!shouldRetry || this.attemptLimitReached) { + throw e_1; + } + return [3 /*break*/, 6]; + case 6: return [3 /*break*/, 0]; + case 7: throw new Error("Something went wrong."); + } + }); + }); + }; + Object.defineProperty(BackOff.prototype, "attemptLimitReached", { + get: function () { + return this.attemptNumber >= this.options.numOfAttempts; + }, + enumerable: true, + configurable: true + }); + BackOff.prototype.applyDelay = function () { + return __awaiter(this, void 0, void 0, function () { + var delay; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + delay = delay_factory_1.DelayFactory(this.options, this.attemptNumber); + return [4 /*yield*/, delay.apply()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }; + return BackOff; +}()); +//# sourceMappingURL=backoff.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/delay/always/always.delay.js b/node_modules/exponential-backoff/dist/delay/always/always.delay.js new file mode 100644 index 0000000000000..40e34071e493d --- /dev/null +++ b/node_modules/exponential-backoff/dist/delay/always/always.delay.js @@ -0,0 +1,25 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var delay_base_1 = require("../delay.base"); +var AlwaysDelay = /** @class */ (function (_super) { + __extends(AlwaysDelay, _super); + function AlwaysDelay() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AlwaysDelay; +}(delay_base_1.Delay)); +exports.AlwaysDelay = AlwaysDelay; +//# sourceMappingURL=always.delay.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/delay/delay.base.js b/node_modules/exponential-backoff/dist/delay/delay.base.js new file mode 100644 index 0000000000000..b146c2fa62041 --- /dev/null +++ b/node_modules/exponential-backoff/dist/delay/delay.base.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var jitter_factory_1 = require("../jitter/jitter.factory"); +var Delay = /** @class */ (function () { + function Delay(options) { + this.options = options; + this.attempt = 0; + } + Delay.prototype.apply = function () { + var _this = this; + return new Promise(function (resolve) { return setTimeout(resolve, _this.jitteredDelay); }); + }; + Delay.prototype.setAttemptNumber = function (attempt) { + this.attempt = attempt; + }; + Object.defineProperty(Delay.prototype, "jitteredDelay", { + get: function () { + var jitter = jitter_factory_1.JitterFactory(this.options); + return jitter(this.delay); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Delay.prototype, "delay", { + get: function () { + var constant = this.options.startingDelay; + var base = this.options.timeMultiple; + var power = this.numOfDelayedAttempts; + var delay = constant * Math.pow(base, power); + return Math.min(delay, this.options.maxDelay); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Delay.prototype, "numOfDelayedAttempts", { + get: function () { + return this.attempt; + }, + enumerable: true, + configurable: true + }); + return Delay; +}()); +exports.Delay = Delay; +//# sourceMappingURL=delay.base.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/delay/delay.factory.js b/node_modules/exponential-backoff/dist/delay/delay.factory.js new file mode 100644 index 0000000000000..33008dbfc51c4 --- /dev/null +++ b/node_modules/exponential-backoff/dist/delay/delay.factory.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var skip_first_delay_1 = require("./skip-first/skip-first.delay"); +var always_delay_1 = require("./always/always.delay"); +function DelayFactory(options, attempt) { + var delay = initDelayClass(options); + delay.setAttemptNumber(attempt); + return delay; +} +exports.DelayFactory = DelayFactory; +function initDelayClass(options) { + if (!options.delayFirstAttempt) { + return new skip_first_delay_1.SkipFirstDelay(options); + } + return new always_delay_1.AlwaysDelay(options); +} +//# sourceMappingURL=delay.factory.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/delay/delay.interface.js b/node_modules/exponential-backoff/dist/delay/delay.interface.js new file mode 100644 index 0000000000000..6fe2a5a0e9d23 --- /dev/null +++ b/node_modules/exponential-backoff/dist/delay/delay.interface.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=delay.interface.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js b/node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js new file mode 100644 index 0000000000000..73f8841dadd01 --- /dev/null +++ b/node_modules/exponential-backoff/dist/delay/skip-first/skip-first.delay.js @@ -0,0 +1,82 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var delay_base_1 = require("../delay.base"); +var SkipFirstDelay = /** @class */ (function (_super) { + __extends(SkipFirstDelay, _super); + function SkipFirstDelay() { + return _super !== null && _super.apply(this, arguments) || this; + } + SkipFirstDelay.prototype.apply = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 /*return*/, this.isFirstAttempt ? true : _super.prototype.apply.call(this)]; + }); + }); + }; + Object.defineProperty(SkipFirstDelay.prototype, "isFirstAttempt", { + get: function () { + return this.attempt === 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SkipFirstDelay.prototype, "numOfDelayedAttempts", { + get: function () { + return this.attempt - 1; + }, + enumerable: true, + configurable: true + }); + return SkipFirstDelay; +}(delay_base_1.Delay)); +exports.SkipFirstDelay = SkipFirstDelay; +//# sourceMappingURL=skip-first.delay.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/jitter/full/full.jitter.js b/node_modules/exponential-backoff/dist/jitter/full/full.jitter.js new file mode 100644 index 0000000000000..16cee36bb5fa5 --- /dev/null +++ b/node_modules/exponential-backoff/dist/jitter/full/full.jitter.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function fullJitter(delay) { + var jitteredDelay = Math.random() * delay; + return Math.round(jitteredDelay); +} +exports.fullJitter = fullJitter; +//# sourceMappingURL=full.jitter.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/jitter/jitter.factory.js b/node_modules/exponential-backoff/dist/jitter/jitter.factory.js new file mode 100644 index 0000000000000..8aafe45f8fbb0 --- /dev/null +++ b/node_modules/exponential-backoff/dist/jitter/jitter.factory.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var full_jitter_1 = require("./full/full.jitter"); +var no_jitter_1 = require("./no/no.jitter"); +function JitterFactory(options) { + switch (options.jitter) { + case "full": + return full_jitter_1.fullJitter; + case "none": + default: + return no_jitter_1.noJitter; + } +} +exports.JitterFactory = JitterFactory; +//# sourceMappingURL=jitter.factory.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/jitter/no/no.jitter.js b/node_modules/exponential-backoff/dist/jitter/no/no.jitter.js new file mode 100644 index 0000000000000..15a40bb2a7bd6 --- /dev/null +++ b/node_modules/exponential-backoff/dist/jitter/no/no.jitter.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function noJitter(delay) { + return delay; +} +exports.noJitter = noJitter; +//# sourceMappingURL=no.jitter.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/dist/options.js b/node_modules/exponential-backoff/dist/options.js new file mode 100644 index 0000000000000..1d2ca1705dcfd --- /dev/null +++ b/node_modules/exponential-backoff/dist/options.js @@ -0,0 +1,31 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var defaultOptions = { + delayFirstAttempt: false, + jitter: "none", + maxDelay: Infinity, + numOfAttempts: 10, + retry: function () { return true; }, + startingDelay: 100, + timeMultiple: 2 +}; +function getSanitizedOptions(options) { + var sanitized = __assign(__assign({}, defaultOptions), options); + if (sanitized.numOfAttempts < 1) { + sanitized.numOfAttempts = 1; + } + return sanitized; +} +exports.getSanitizedOptions = getSanitizedOptions; +//# sourceMappingURL=options.js.map \ No newline at end of file diff --git a/node_modules/exponential-backoff/package.json b/node_modules/exponential-backoff/package.json new file mode 100644 index 0000000000000..e3e8dc9a5dccd --- /dev/null +++ b/node_modules/exponential-backoff/package.json @@ -0,0 +1,62 @@ +{ + "name": "exponential-backoff", + "version": "3.1.3", + "description": "A utility that allows retrying a function with an exponential delay between attempts.", + "files": [ + "dist/", + "src/" + ], + "main": "dist/backoff.js", + "types": "dist/backoff.d.ts", + "scripts": { + "build": "tsc", + "test": "jest", + "test:watch": "jest --watch" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.{ts,json,md}": [ + "prettier --write", + "git add" + ] + }, + "jest": { + "transform": { + "^.+\\.ts$": "ts-jest" + }, + "testRegex": "\\.spec\\.ts$", + "moduleFileExtensions": [ + "ts", + "js" + ] + }, + "repository": { + "type": "git", + "url": "git+https://github.com/coveooss/exponential-backoff.git" + }, + "keywords": [ + "exponential", + "backoff", + "retry" + ], + "author": "Sami Sayegh", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/coveooss/exponential-backoff/issues" + }, + "homepage": "https://github.com/coveooss/exponential-backoff#readme", + "devDependencies": { + "@types/jest": "^24.0.18", + "@types/node": "^10.14.21", + "husky": "^3.0.9", + "jest": "^24.9.0", + "lint-staged": "^9.4.2", + "prettier": "^1.18.2", + "ts-jest": "^24.1.0", + "typescript": "^3.6.4" + } +} diff --git a/node_modules/fastest-levenshtein/bench.js b/node_modules/fastest-levenshtein/bench.js new file mode 100644 index 0000000000000..1fd420bd737e8 --- /dev/null +++ b/node_modules/fastest-levenshtein/bench.js @@ -0,0 +1,96 @@ +"use strict"; +exports.__esModule = true; +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable no-console */ +var Benchmark = require("benchmark"); +var mod_js_1 = require("./mod.js"); +var fast_levenshtein_1 = require("fast-levenshtein"); +var fs = require("fs"); +var jslevenshtein = require("js-levenshtein"); +var leven = require("leven"); +var levenshteinEditDistance = require("levenshtein-edit-distance"); +var suite = new Benchmark.Suite(); +var randomstring = function (length) { + var result = ""; + var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + var charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}; +var randomstringArr = function (stringSize, arraySize) { + var i = 0; + var arr = []; + for (i = 0; i < arraySize; i++) { + arr.push(randomstring(stringSize)); + } + return arr; +}; +var arrSize = 1000; +if (!fs.existsSync("data.json")) { + var data_1 = [ + randomstringArr(4, arrSize), + randomstringArr(8, arrSize), + randomstringArr(16, arrSize), + randomstringArr(32, arrSize), + randomstringArr(64, arrSize), + randomstringArr(128, arrSize), + randomstringArr(256, arrSize), + randomstringArr(512, arrSize), + randomstringArr(1024, arrSize), + ]; + fs.writeFileSync("data.json", JSON.stringify(data_1)); +} +var data = JSON.parse(fs.readFileSync("data.json", "utf8")); +var _loop_1 = function (i) { + var datapick = data[i]; + if (process.argv[2] !== "no") { + suite + .add("".concat(i, " - js-levenshtein"), function () { + for (var j = 0; j < arrSize - 1; j += 2) { + jslevenshtein(datapick[j], datapick[j + 1]); + } + }) + .add("".concat(i, " - leven"), function () { + for (var j = 0; j < arrSize - 1; j += 2) { + leven(datapick[j], datapick[j + 1]); + } + }) + .add("".concat(i, " - fast-levenshtein"), function () { + for (var j = 0; j < arrSize - 1; j += 2) { + (0, fast_levenshtein_1.get)(datapick[j], datapick[j + 1]); + } + }) + .add("".concat(i, " - levenshtein-edit-distance"), function () { + for (var j = 0; j < arrSize - 1; j += 2) { + levenshteinEditDistance(datapick[j], datapick[j + 1]); + } + }); + } + suite.add("".concat(i, " - fastest-levenshtein"), function () { + for (var j = 0; j < arrSize - 1; j += 2) { + (0, mod_js_1.distance)(datapick[j], datapick[j + 1]); + } + }); +}; +// BENCHMARKS +for (var i = 0; i < 9; i++) { + _loop_1(i); +} +var results = new Map(); +suite + .on("cycle", function (event) { + console.log(String(event.target)); + if (results.has(event.target.name[0])) { + results.get(event.target.name[0]).push(event.target.hz); + } + else { + results.set(event.target.name[0], [event.target.hz]); + } +}) + .on("complete", function () { + console.log(results); +}) + // run async + .run({ async: true }); diff --git a/node_modules/fastest-levenshtein/esm/mod.js b/node_modules/fastest-levenshtein/esm/mod.js new file mode 100644 index 0000000000000..719f2b8fdade9 --- /dev/null +++ b/node_modules/fastest-levenshtein/esm/mod.js @@ -0,0 +1,138 @@ +const peq = new Uint32Array(0x10000); +const myers_32 = (a, b) => { + const n = a.length; + const m = b.length; + const lst = 1 << (n - 1); + let pv = -1; + let mv = 0; + let sc = n; + let i = n; + while (i--) { + peq[a.charCodeAt(i)] |= 1 << i; + } + for (i = 0; i < m; i++) { + let eq = peq[b.charCodeAt(i)]; + const xv = eq | mv; + eq |= ((eq & pv) + pv) ^ pv; + mv |= ~(eq | pv); + pv &= eq; + if (mv & lst) { + sc++; + } + if (pv & lst) { + sc--; + } + mv = (mv << 1) | 1; + pv = (pv << 1) | ~(xv | mv); + mv &= xv; + } + i = n; + while (i--) { + peq[a.charCodeAt(i)] = 0; + } + return sc; +}; +const myers_x = (b, a) => { + const n = a.length; + const m = b.length; + const mhc = []; + const phc = []; + const hsize = Math.ceil(n / 32); + const vsize = Math.ceil(m / 32); + for (let i = 0; i < hsize; i++) { + phc[i] = -1; + mhc[i] = 0; + } + let j = 0; + for (; j < vsize - 1; j++) { + let mv = 0; + let pv = -1; + const start = j * 32; + const vlen = Math.min(32, m) + start; + for (let k = start; k < vlen; k++) { + peq[b.charCodeAt(k)] |= 1 << k; + } + for (let i = 0; i < n; i++) { + const eq = peq[a.charCodeAt(i)]; + const pb = (phc[(i / 32) | 0] >>> i) & 1; + const mb = (mhc[(i / 32) | 0] >>> i) & 1; + const xv = eq | mv; + const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; + let ph = mv | ~(xh | pv); + let mh = pv & xh; + if ((ph >>> 31) ^ pb) { + phc[(i / 32) | 0] ^= 1 << i; + } + if ((mh >>> 31) ^ mb) { + mhc[(i / 32) | 0] ^= 1 << i; + } + ph = (ph << 1) | pb; + mh = (mh << 1) | mb; + pv = mh | ~(xv | ph); + mv = ph & xv; + } + for (let k = start; k < vlen; k++) { + peq[b.charCodeAt(k)] = 0; + } + } + let mv = 0; + let pv = -1; + const start = j * 32; + const vlen = Math.min(32, m - start) + start; + for (let k = start; k < vlen; k++) { + peq[b.charCodeAt(k)] |= 1 << k; + } + let score = m; + for (let i = 0; i < n; i++) { + const eq = peq[a.charCodeAt(i)]; + const pb = (phc[(i / 32) | 0] >>> i) & 1; + const mb = (mhc[(i / 32) | 0] >>> i) & 1; + const xv = eq | mv; + const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; + let ph = mv | ~(xh | pv); + let mh = pv & xh; + score += (ph >>> (m - 1)) & 1; + score -= (mh >>> (m - 1)) & 1; + if ((ph >>> 31) ^ pb) { + phc[(i / 32) | 0] ^= 1 << i; + } + if ((mh >>> 31) ^ mb) { + mhc[(i / 32) | 0] ^= 1 << i; + } + ph = (ph << 1) | pb; + mh = (mh << 1) | mb; + pv = mh | ~(xv | ph); + mv = ph & xv; + } + for (let k = start; k < vlen; k++) { + peq[b.charCodeAt(k)] = 0; + } + return score; +}; +const distance = (a, b) => { + if (a.length < b.length) { + const tmp = b; + b = a; + a = tmp; + } + if (b.length === 0) { + return a.length; + } + if (a.length <= 32) { + return myers_32(a, b); + } + return myers_x(a, b); +}; +const closest = (str, arr) => { + let min_distance = Infinity; + let min_index = 0; + for (let i = 0; i < arr.length; i++) { + const dist = distance(str, arr[i]); + if (dist < min_distance) { + min_distance = dist; + min_index = i; + } + } + return arr[min_index]; +}; +export { closest, distance }; diff --git a/node_modules/fastest-levenshtein/index.d.ts b/node_modules/fastest-levenshtein/index.d.ts deleted file mode 100644 index bdc2bb1cc32e0..0000000000000 --- a/node_modules/fastest-levenshtein/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function distance(a: string, b: string): number; -export function closest(str: string, arr: string[]): string; \ No newline at end of file diff --git a/node_modules/fastest-levenshtein/index.js b/node_modules/fastest-levenshtein/index.js deleted file mode 100644 index 437bdebfda388..0000000000000 --- a/node_modules/fastest-levenshtein/index.js +++ /dev/null @@ -1,147 +0,0 @@ -"use strict"; -const peq = new Uint32Array(0x10000); -const myers_32 = (a, b) => { - const n = a.length; - const m = b.length; - const lst = 1 << (n - 1); - let pv = -1; - let mv = 0; - let sc = n; - let i = n; - while (i--) { - peq[a.charCodeAt(i)] |= 1 << i; - } - for (i = 0; i < m; i++) { - let eq = peq[b.charCodeAt(i)]; - const xv = eq | mv; - eq |= ((eq & pv) + pv) ^ pv; - mv |= ~(eq | pv); - pv &= eq; - if (mv & lst) { - sc++; - } - if (pv & lst) { - sc--; - } - mv = (mv << 1) | 1; - pv = (pv << 1) | ~(xv | mv); - mv &= xv; - } - i = n; - while (i--) { - peq[a.charCodeAt(i)] = 0; - } - return sc; -}; - -const myers_x = (a, b) => { - const n = a.length; - const m = b.length; - const mhc = []; - const phc = []; - const hsize = Math.ceil(n / 32); - const vsize = Math.ceil(m / 32); - let score = m; - for (let i = 0; i < hsize; i++) { - phc[i] = -1; - mhc[i] = 0; - } - let j = 0; - for (; j < vsize - 1; j++) { - let mv = 0; - let pv = -1; - const start = j * 32; - const end = Math.min(32, m) + start; - for (let k = start; k < end; k++) { - peq[b.charCodeAt(k)] |= 1 << k; - } - score = m; - for (let i = 0; i < n; i++) { - const eq = peq[a.charCodeAt(i)]; - const pb = (phc[(i / 32) | 0] >>> i) & 1; - const mb = (mhc[(i / 32) | 0] >>> i) & 1; - const xv = eq | mv; - const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; - let ph = mv | ~(xh | pv); - let mh = pv & xh; - if ((ph >>> 31) ^ pb) { - phc[(i / 32) | 0] ^= 1 << i; - } - if ((mh >>> 31) ^ mb) { - mhc[(i / 32) | 0] ^= 1 << i; - } - ph = (ph << 1) | pb; - mh = (mh << 1) | mb; - pv = mh | ~(xv | ph); - mv = ph & xv; - } - for (let k = start; k < end; k++) { - peq[b.charCodeAt(k)] = 0; - } - } - let mv = 0; - let pv = -1; - const start = j * 32; - const end = Math.min(32, m - start) + start; - for (let k = start; k < end; k++) { - peq[b.charCodeAt(k)] |= 1 << k; - } - score = m; - for (let i = 0; i < n; i++) { - const eq = peq[a.charCodeAt(i)]; - const pb = (phc[(i / 32) | 0] >>> i) & 1; - const mb = (mhc[(i / 32) | 0] >>> i) & 1; - const xv = eq | mv; - const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; - let ph = mv | ~(xh | pv); - let mh = pv & xh; - score += (ph >>> (m - 1)) & 1; - score -= (mh >>> (m - 1)) & 1; - if ((ph >>> 31) ^ pb) { - phc[(i / 32) | 0] ^= 1 << i; - } - if ((mh >>> 31) ^ mb) { - mhc[(i / 32) | 0] ^= 1 << i; - } - ph = (ph << 1) | pb; - mh = (mh << 1) | mb; - pv = mh | ~(xv | ph); - mv = ph & xv; - } - for (let k = start; k < end; k++) { - peq[b.charCodeAt(k)] = 0; - } - return score; -}; - -const distance = (a, b) => { - if (a.length > b.length) { - const tmp = b; - b = a; - a = tmp; - } - if (a.length === 0) { - return b.length; - } - if (a.length <= 32) { - return myers_32(a, b); - } - return myers_x(a, b); -}; - -const closest = (str, arr) => { - let min_distance = Infinity; - let min_index = 0; - for (let i = 0; i < arr.length; i++) { - const dist = distance(str, arr[i]); - if (dist < min_distance) { - min_distance = dist; - min_index = i; - } - } - return arr[min_index]; -}; - -module.exports = { - closest, distance -} diff --git a/node_modules/fastest-levenshtein/mod.js b/node_modules/fastest-levenshtein/mod.js new file mode 100644 index 0000000000000..6bc27459399e6 --- /dev/null +++ b/node_modules/fastest-levenshtein/mod.js @@ -0,0 +1,142 @@ +"use strict"; +exports.__esModule = true; +exports.distance = exports.closest = void 0; +var peq = new Uint32Array(0x10000); +var myers_32 = function (a, b) { + var n = a.length; + var m = b.length; + var lst = 1 << (n - 1); + var pv = -1; + var mv = 0; + var sc = n; + var i = n; + while (i--) { + peq[a.charCodeAt(i)] |= 1 << i; + } + for (i = 0; i < m; i++) { + var eq = peq[b.charCodeAt(i)]; + var xv = eq | mv; + eq |= ((eq & pv) + pv) ^ pv; + mv |= ~(eq | pv); + pv &= eq; + if (mv & lst) { + sc++; + } + if (pv & lst) { + sc--; + } + mv = (mv << 1) | 1; + pv = (pv << 1) | ~(xv | mv); + mv &= xv; + } + i = n; + while (i--) { + peq[a.charCodeAt(i)] = 0; + } + return sc; +}; +var myers_x = function (b, a) { + var n = a.length; + var m = b.length; + var mhc = []; + var phc = []; + var hsize = Math.ceil(n / 32); + var vsize = Math.ceil(m / 32); + for (var i = 0; i < hsize; i++) { + phc[i] = -1; + mhc[i] = 0; + } + var j = 0; + for (; j < vsize - 1; j++) { + var mv_1 = 0; + var pv_1 = -1; + var start_1 = j * 32; + var vlen_1 = Math.min(32, m) + start_1; + for (var k = start_1; k < vlen_1; k++) { + peq[b.charCodeAt(k)] |= 1 << k; + } + for (var i = 0; i < n; i++) { + var eq = peq[a.charCodeAt(i)]; + var pb = (phc[(i / 32) | 0] >>> i) & 1; + var mb = (mhc[(i / 32) | 0] >>> i) & 1; + var xv = eq | mv_1; + var xh = ((((eq | mb) & pv_1) + pv_1) ^ pv_1) | eq | mb; + var ph = mv_1 | ~(xh | pv_1); + var mh = pv_1 & xh; + if ((ph >>> 31) ^ pb) { + phc[(i / 32) | 0] ^= 1 << i; + } + if ((mh >>> 31) ^ mb) { + mhc[(i / 32) | 0] ^= 1 << i; + } + ph = (ph << 1) | pb; + mh = (mh << 1) | mb; + pv_1 = mh | ~(xv | ph); + mv_1 = ph & xv; + } + for (var k = start_1; k < vlen_1; k++) { + peq[b.charCodeAt(k)] = 0; + } + } + var mv = 0; + var pv = -1; + var start = j * 32; + var vlen = Math.min(32, m - start) + start; + for (var k = start; k < vlen; k++) { + peq[b.charCodeAt(k)] |= 1 << k; + } + var score = m; + for (var i = 0; i < n; i++) { + var eq = peq[a.charCodeAt(i)]; + var pb = (phc[(i / 32) | 0] >>> i) & 1; + var mb = (mhc[(i / 32) | 0] >>> i) & 1; + var xv = eq | mv; + var xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; + var ph = mv | ~(xh | pv); + var mh = pv & xh; + score += (ph >>> (m - 1)) & 1; + score -= (mh >>> (m - 1)) & 1; + if ((ph >>> 31) ^ pb) { + phc[(i / 32) | 0] ^= 1 << i; + } + if ((mh >>> 31) ^ mb) { + mhc[(i / 32) | 0] ^= 1 << i; + } + ph = (ph << 1) | pb; + mh = (mh << 1) | mb; + pv = mh | ~(xv | ph); + mv = ph & xv; + } + for (var k = start; k < vlen; k++) { + peq[b.charCodeAt(k)] = 0; + } + return score; +}; +var distance = function (a, b) { + if (a.length < b.length) { + var tmp = b; + b = a; + a = tmp; + } + if (b.length === 0) { + return a.length; + } + if (a.length <= 32) { + return myers_32(a, b); + } + return myers_x(a, b); +}; +exports.distance = distance; +var closest = function (str, arr) { + var min_distance = Infinity; + var min_index = 0; + for (var i = 0; i < arr.length; i++) { + var dist = distance(str, arr[i]); + if (dist < min_distance) { + min_distance = dist; + min_index = i; + } + } + return arr[min_index]; +}; +exports.closest = closest; diff --git a/node_modules/fastest-levenshtein/package.json b/node_modules/fastest-levenshtein/package.json index 4d3ca34c92913..c395b852d5d92 100644 --- a/node_modules/fastest-levenshtein/package.json +++ b/node_modules/fastest-levenshtein/package.json @@ -1,8 +1,10 @@ { "name": "fastest-levenshtein", - "version": "1.0.12", + "version": "1.0.16", "description": "Fastest Levenshtein distance implementation in JS.", - "main": "index.js", + "main": "mod.js", + "types": "mod.d.ts", + "module": "./esm/mod.js", "repository": { "type": "git", "url": "git+https://github.com/ka-weihe/fastest-levenshtein.git" @@ -33,31 +35,38 @@ }, "homepage": "https://github.com/ka-weihe/fastest-levenshtein#README", "scripts": { - "test": "jest", - "test:coverage": "jest --coverage", - "test:coveralls": "jest --coverage --coverageReporters=text-lcov | coveralls" + "build": "tsc mod.ts --declaration", + "build:esm": "tsc --declaration -p tsconfig.esm.json", + "prepare": "npm run build && npm run build:esm", + "bench": "npm run build && tsc bench.ts && node bench.js", + "test": "npm run build && tsc test.ts && jest test.js", + "test:coverage": "npm run build && jest --coverage", + "test:coveralls": "npm run build && jest --coverage --coverageReporters=text-lcov | coveralls" }, "devDependencies": { + "@types/benchmark": "^1.0.33", + "@types/jest": "^26.0.15", + "@typescript-eslint/eslint-plugin": "^4.7.0", + "@typescript-eslint/parser": "^4.7.0", "benchmark": "^2.1.4", "coveralls": "^3.1.0", - "eslint": "^7.5.0", - "eslint-config-airbnb": "^18.2.0", - "eslint-config-airbnb-base": "^14.2.0", + "eslint": "^7.13.0", "eslint-config-node": "^4.1.0", - "eslint-config-prettier": "^6.11.0", - "eslint-plugin-import": "^2.22.0", - "eslint-plugin-jsx-a11y": "^6.3.1", + "eslint-config-prettier": "^6.15.0", + "eslint-plugin-import": "^2.22.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^3.1.4", - "eslint-plugin-react": "^7.20.3", - "eslint-plugin-react-hooks": "^4.0.0", "fast-levenshtein": "^2.0.6", - "jest": "^26.1.0", + "jest": "^26.6.3", "js-levenshtein": "^1.1.6", "leven": "^3.1.0", + "levenshtein-edit-distance": "^2.0.5", "natural": "^2.1.5", - "prettier": "^2.0.5", - "talisman": "^1.1.2", - "levenshtein-edit-distance": "^2.0.5" + "prettier": "^2.1.2", + "talisman": "^1.1.3", + "typescript": "^4.0.5" + }, + "engines": { + "node": ">= 4.9.1" } } diff --git a/node_modules/fastest-levenshtein/test.js b/node_modules/fastest-levenshtein/test.js index 4b5d6ecae6504..475063390a81b 100644 --- a/node_modules/fastest-levenshtein/test.js +++ b/node_modules/fastest-levenshtein/test.js @@ -1,64 +1,55 @@ -const {distance, closest} = require("./index.js"); - -const levenshtein = (a, b) => { - if (a.length === 0) return b.length; - if (b.length === 0) return a.length; - - if (a.length > b.length) { - const tmp = a; - a = b; - b = tmp; - } - - const row = []; - for (let i = 0; i <= a.length; i++) { - row[i] = i; - } - - for (let i = 1; i <= b.length; i++) { - let prev = i; - for (let j = 1; j <= a.length; j++) { - let val; - if (b.charAt(i - 1) === a.charAt(j - 1)) { - val = row[j - 1]; - } else { - val = Math.min(row[j - 1] + 1, prev + 1, row[j] + 1); - } - row[j - 1] = prev; - prev = val; +var _a = require("./mod.js"), closest = _a.closest, distance = _a.distance; +var levenshtein = function (a, b) { + if (a.length === 0) { + return b.length; } - row[a.length] = prev; - } - - return row[a.length]; + if (b.length === 0) { + return a.length; + } + if (a.length > b.length) { + var tmp = a; + a = b; + b = tmp; + } + var row = []; + for (var i = 0; i <= a.length; i++) { + row[i] = i; + } + for (var i = 1; i <= b.length; i++) { + var prev = i; + for (var j = 1; j <= a.length; j++) { + var val = 0; + if (b.charAt(i - 1) === a.charAt(j - 1)) { + val = row[j - 1]; + } + else { + val = Math.min(row[j - 1] + 1, prev + 1, row[j] + 1); + } + row[j - 1] = prev; + prev = val; + } + row[a.length] = prev; + } + return row[a.length]; }; - -function makeid(length) { - let result = ""; - const characters = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - const charactersLength = characters.length; - for (let i = 0; i < length; i++) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); - } - return result; +var makeid = function (length) { + var result = ""; + var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + var charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +}; +for (var i = 0; i < 10000; i++) { + var rnd_num1 = (Math.random() * 1000) | 0; + var rnd_num2 = (Math.random() * 1000) | 0; + var rnd_string1 = makeid(rnd_num1); + var rnd_string2 = makeid(rnd_num2); + var actual = distance(rnd_string1, rnd_string2); + var expected = levenshtein(rnd_string1, rnd_string2); + console.log(i); + if (actual !== expected) { + console.log("fail"); + } } - -test("test compare", () => { - const errors = 0; - for (let i = 0; i < 1000; i++) { - const rnd_num1 = (Math.random() * 1000) | 0; - const rnd_num2 = (Math.random() * 1000) | 0; - const rnd_string1 = makeid(rnd_num1); - const rnd_string2 = makeid(rnd_num2); - const actual = distance(rnd_string1, rnd_string2); - const expected = levenshtein(rnd_string1, rnd_string2); - expect(actual).toBe(expected); - } -}); - -test("test find", () => { - const actual = closest("fast", ["slow", "faster", "fastest"]); - const expected = "faster"; - expect(actual).toBe(expected); -}); diff --git a/node_modules/fs-minipass/index.js b/node_modules/fs-minipass/index.js deleted file mode 100644 index 9b0779c80c55e..0000000000000 --- a/node_modules/fs-minipass/index.js +++ /dev/null @@ -1,422 +0,0 @@ -'use strict' -const MiniPass = require('minipass') -const EE = require('events').EventEmitter -const fs = require('fs') - -let writev = fs.writev -/* istanbul ignore next */ -if (!writev) { - // This entire block can be removed if support for earlier than Node.js - // 12.9.0 is not needed. - const binding = process.binding('fs') - const FSReqWrap = binding.FSReqWrap || binding.FSReqCallback - - writev = (fd, iovec, pos, cb) => { - const done = (er, bw) => cb(er, bw, iovec) - const req = new FSReqWrap() - req.oncomplete = done - binding.writeBuffers(fd, iovec, pos, req) - } -} - -const _autoClose = Symbol('_autoClose') -const _close = Symbol('_close') -const _ended = Symbol('_ended') -const _fd = Symbol('_fd') -const _finished = Symbol('_finished') -const _flags = Symbol('_flags') -const _flush = Symbol('_flush') -const _handleChunk = Symbol('_handleChunk') -const _makeBuf = Symbol('_makeBuf') -const _mode = Symbol('_mode') -const _needDrain = Symbol('_needDrain') -const _onerror = Symbol('_onerror') -const _onopen = Symbol('_onopen') -const _onread = Symbol('_onread') -const _onwrite = Symbol('_onwrite') -const _open = Symbol('_open') -const _path = Symbol('_path') -const _pos = Symbol('_pos') -const _queue = Symbol('_queue') -const _read = Symbol('_read') -const _readSize = Symbol('_readSize') -const _reading = Symbol('_reading') -const _remain = Symbol('_remain') -const _size = Symbol('_size') -const _write = Symbol('_write') -const _writing = Symbol('_writing') -const _defaultFlag = Symbol('_defaultFlag') -const _errored = Symbol('_errored') - -class ReadStream extends MiniPass { - constructor (path, opt) { - opt = opt || {} - super(opt) - - this.readable = true - this.writable = false - - if (typeof path !== 'string') - throw new TypeError('path must be a string') - - this[_errored] = false - this[_fd] = typeof opt.fd === 'number' ? opt.fd : null - this[_path] = path - this[_readSize] = opt.readSize || 16*1024*1024 - this[_reading] = false - this[_size] = typeof opt.size === 'number' ? opt.size : Infinity - this[_remain] = this[_size] - this[_autoClose] = typeof opt.autoClose === 'boolean' ? - opt.autoClose : true - - if (typeof this[_fd] === 'number') - this[_read]() - else - this[_open]() - } - - get fd () { return this[_fd] } - get path () { return this[_path] } - - write () { - throw new TypeError('this is a readable stream') - } - - end () { - throw new TypeError('this is a readable stream') - } - - [_open] () { - fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd)) - } - - [_onopen] (er, fd) { - if (er) - this[_onerror](er) - else { - this[_fd] = fd - this.emit('open', fd) - this[_read]() - } - } - - [_makeBuf] () { - return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain])) - } - - [_read] () { - if (!this[_reading]) { - this[_reading] = true - const buf = this[_makeBuf]() - /* istanbul ignore if */ - if (buf.length === 0) - return process.nextTick(() => this[_onread](null, 0, buf)) - fs.read(this[_fd], buf, 0, buf.length, null, (er, br, buf) => - this[_onread](er, br, buf)) - } - } - - [_onread] (er, br, buf) { - this[_reading] = false - if (er) - this[_onerror](er) - else if (this[_handleChunk](br, buf)) - this[_read]() - } - - [_close] () { - if (this[_autoClose] && typeof this[_fd] === 'number') { - const fd = this[_fd] - this[_fd] = null - fs.close(fd, er => er ? this.emit('error', er) : this.emit('close')) - } - } - - [_onerror] (er) { - this[_reading] = true - this[_close]() - this.emit('error', er) - } - - [_handleChunk] (br, buf) { - let ret = false - // no effect if infinite - this[_remain] -= br - if (br > 0) - ret = super.write(br < buf.length ? buf.slice(0, br) : buf) - - if (br === 0 || this[_remain] <= 0) { - ret = false - this[_close]() - super.end() - } - - return ret - } - - emit (ev, data) { - switch (ev) { - case 'prefinish': - case 'finish': - break - - case 'drain': - if (typeof this[_fd] === 'number') - this[_read]() - break - - case 'error': - if (this[_errored]) - return - this[_errored] = true - return super.emit(ev, data) - - default: - return super.emit(ev, data) - } - } -} - -class ReadStreamSync extends ReadStream { - [_open] () { - let threw = true - try { - this[_onopen](null, fs.openSync(this[_path], 'r')) - threw = false - } finally { - if (threw) - this[_close]() - } - } - - [_read] () { - let threw = true - try { - if (!this[_reading]) { - this[_reading] = true - do { - const buf = this[_makeBuf]() - /* istanbul ignore next */ - const br = buf.length === 0 ? 0 - : fs.readSync(this[_fd], buf, 0, buf.length, null) - if (!this[_handleChunk](br, buf)) - break - } while (true) - this[_reading] = false - } - threw = false - } finally { - if (threw) - this[_close]() - } - } - - [_close] () { - if (this[_autoClose] && typeof this[_fd] === 'number') { - const fd = this[_fd] - this[_fd] = null - fs.closeSync(fd) - this.emit('close') - } - } -} - -class WriteStream extends EE { - constructor (path, opt) { - opt = opt || {} - super(opt) - this.readable = false - this.writable = true - this[_errored] = false - this[_writing] = false - this[_ended] = false - this[_needDrain] = false - this[_queue] = [] - this[_path] = path - this[_fd] = typeof opt.fd === 'number' ? opt.fd : null - this[_mode] = opt.mode === undefined ? 0o666 : opt.mode - this[_pos] = typeof opt.start === 'number' ? opt.start : null - this[_autoClose] = typeof opt.autoClose === 'boolean' ? - opt.autoClose : true - - // truncating makes no sense when writing into the middle - const defaultFlag = this[_pos] !== null ? 'r+' : 'w' - this[_defaultFlag] = opt.flags === undefined - this[_flags] = this[_defaultFlag] ? defaultFlag : opt.flags - - if (this[_fd] === null) - this[_open]() - } - - emit (ev, data) { - if (ev === 'error') { - if (this[_errored]) - return - this[_errored] = true - } - return super.emit(ev, data) - } - - - get fd () { return this[_fd] } - get path () { return this[_path] } - - [_onerror] (er) { - this[_close]() - this[_writing] = true - this.emit('error', er) - } - - [_open] () { - fs.open(this[_path], this[_flags], this[_mode], - (er, fd) => this[_onopen](er, fd)) - } - - [_onopen] (er, fd) { - if (this[_defaultFlag] && - this[_flags] === 'r+' && - er && er.code === 'ENOENT') { - this[_flags] = 'w' - this[_open]() - } else if (er) - this[_onerror](er) - else { - this[_fd] = fd - this.emit('open', fd) - this[_flush]() - } - } - - end (buf, enc) { - if (buf) - this.write(buf, enc) - - this[_ended] = true - - // synthetic after-write logic, where drain/finish live - if (!this[_writing] && !this[_queue].length && - typeof this[_fd] === 'number') - this[_onwrite](null, 0) - return this - } - - write (buf, enc) { - if (typeof buf === 'string') - buf = Buffer.from(buf, enc) - - if (this[_ended]) { - this.emit('error', new Error('write() after end()')) - return false - } - - if (this[_fd] === null || this[_writing] || this[_queue].length) { - this[_queue].push(buf) - this[_needDrain] = true - return false - } - - this[_writing] = true - this[_write](buf) - return true - } - - [_write] (buf) { - fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => - this[_onwrite](er, bw)) - } - - [_onwrite] (er, bw) { - if (er) - this[_onerror](er) - else { - if (this[_pos] !== null) - this[_pos] += bw - if (this[_queue].length) - this[_flush]() - else { - this[_writing] = false - - if (this[_ended] && !this[_finished]) { - this[_finished] = true - this[_close]() - this.emit('finish') - } else if (this[_needDrain]) { - this[_needDrain] = false - this.emit('drain') - } - } - } - } - - [_flush] () { - if (this[_queue].length === 0) { - if (this[_ended]) - this[_onwrite](null, 0) - } else if (this[_queue].length === 1) - this[_write](this[_queue].pop()) - else { - const iovec = this[_queue] - this[_queue] = [] - writev(this[_fd], iovec, this[_pos], - (er, bw) => this[_onwrite](er, bw)) - } - } - - [_close] () { - if (this[_autoClose] && typeof this[_fd] === 'number') { - const fd = this[_fd] - this[_fd] = null - fs.close(fd, er => er ? this.emit('error', er) : this.emit('close')) - } - } -} - -class WriteStreamSync extends WriteStream { - [_open] () { - let fd - // only wrap in a try{} block if we know we'll retry, to avoid - // the rethrow obscuring the error's source frame in most cases. - if (this[_defaultFlag] && this[_flags] === 'r+') { - try { - fd = fs.openSync(this[_path], this[_flags], this[_mode]) - } catch (er) { - if (er.code === 'ENOENT') { - this[_flags] = 'w' - return this[_open]() - } else - throw er - } - } else - fd = fs.openSync(this[_path], this[_flags], this[_mode]) - - this[_onopen](null, fd) - } - - [_close] () { - if (this[_autoClose] && typeof this[_fd] === 'number') { - const fd = this[_fd] - this[_fd] = null - fs.closeSync(fd) - this.emit('close') - } - } - - [_write] (buf) { - // throw the original, but try to close if it fails - let threw = true - try { - this[_onwrite](null, - fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos])) - threw = false - } finally { - if (threw) - try { this[_close]() } catch (_) {} - } - } -} - -exports.ReadStream = ReadStream -exports.ReadStreamSync = ReadStreamSync - -exports.WriteStream = WriteStream -exports.WriteStreamSync = WriteStreamSync diff --git a/node_modules/fs-minipass/lib/index.js b/node_modules/fs-minipass/lib/index.js new file mode 100644 index 0000000000000..3b84ff661448a --- /dev/null +++ b/node_modules/fs-minipass/lib/index.js @@ -0,0 +1,443 @@ +'use strict' +const { Minipass } = require('minipass') +const EE = require('events').EventEmitter +const fs = require('fs') + +const writev = fs.writev + +const _autoClose = Symbol('_autoClose') +const _close = Symbol('_close') +const _ended = Symbol('_ended') +const _fd = Symbol('_fd') +const _finished = Symbol('_finished') +const _flags = Symbol('_flags') +const _flush = Symbol('_flush') +const _handleChunk = Symbol('_handleChunk') +const _makeBuf = Symbol('_makeBuf') +const _mode = Symbol('_mode') +const _needDrain = Symbol('_needDrain') +const _onerror = Symbol('_onerror') +const _onopen = Symbol('_onopen') +const _onread = Symbol('_onread') +const _onwrite = Symbol('_onwrite') +const _open = Symbol('_open') +const _path = Symbol('_path') +const _pos = Symbol('_pos') +const _queue = Symbol('_queue') +const _read = Symbol('_read') +const _readSize = Symbol('_readSize') +const _reading = Symbol('_reading') +const _remain = Symbol('_remain') +const _size = Symbol('_size') +const _write = Symbol('_write') +const _writing = Symbol('_writing') +const _defaultFlag = Symbol('_defaultFlag') +const _errored = Symbol('_errored') + +class ReadStream extends Minipass { + constructor (path, opt) { + opt = opt || {} + super(opt) + + this.readable = true + this.writable = false + + if (typeof path !== 'string') { + throw new TypeError('path must be a string') + } + + this[_errored] = false + this[_fd] = typeof opt.fd === 'number' ? opt.fd : null + this[_path] = path + this[_readSize] = opt.readSize || 16 * 1024 * 1024 + this[_reading] = false + this[_size] = typeof opt.size === 'number' ? opt.size : Infinity + this[_remain] = this[_size] + this[_autoClose] = typeof opt.autoClose === 'boolean' ? + opt.autoClose : true + + if (typeof this[_fd] === 'number') { + this[_read]() + } else { + this[_open]() + } + } + + get fd () { + return this[_fd] + } + + get path () { + return this[_path] + } + + write () { + throw new TypeError('this is a readable stream') + } + + end () { + throw new TypeError('this is a readable stream') + } + + [_open] () { + fs.open(this[_path], 'r', (er, fd) => this[_onopen](er, fd)) + } + + [_onopen] (er, fd) { + if (er) { + this[_onerror](er) + } else { + this[_fd] = fd + this.emit('open', fd) + this[_read]() + } + } + + [_makeBuf] () { + return Buffer.allocUnsafe(Math.min(this[_readSize], this[_remain])) + } + + [_read] () { + if (!this[_reading]) { + this[_reading] = true + const buf = this[_makeBuf]() + /* istanbul ignore if */ + if (buf.length === 0) { + return process.nextTick(() => this[_onread](null, 0, buf)) + } + fs.read(this[_fd], buf, 0, buf.length, null, (er, br, b) => + this[_onread](er, br, b)) + } + } + + [_onread] (er, br, buf) { + this[_reading] = false + if (er) { + this[_onerror](er) + } else if (this[_handleChunk](br, buf)) { + this[_read]() + } + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd] + this[_fd] = null + fs.close(fd, er => er ? this.emit('error', er) : this.emit('close')) + } + } + + [_onerror] (er) { + this[_reading] = true + this[_close]() + this.emit('error', er) + } + + [_handleChunk] (br, buf) { + let ret = false + // no effect if infinite + this[_remain] -= br + if (br > 0) { + ret = super.write(br < buf.length ? buf.slice(0, br) : buf) + } + + if (br === 0 || this[_remain] <= 0) { + ret = false + this[_close]() + super.end() + } + + return ret + } + + emit (ev, data) { + switch (ev) { + case 'prefinish': + case 'finish': + break + + case 'drain': + if (typeof this[_fd] === 'number') { + this[_read]() + } + break + + case 'error': + if (this[_errored]) { + return + } + this[_errored] = true + return super.emit(ev, data) + + default: + return super.emit(ev, data) + } + } +} + +class ReadStreamSync extends ReadStream { + [_open] () { + let threw = true + try { + this[_onopen](null, fs.openSync(this[_path], 'r')) + threw = false + } finally { + if (threw) { + this[_close]() + } + } + } + + [_read] () { + let threw = true + try { + if (!this[_reading]) { + this[_reading] = true + do { + const buf = this[_makeBuf]() + /* istanbul ignore next */ + const br = buf.length === 0 ? 0 + : fs.readSync(this[_fd], buf, 0, buf.length, null) + if (!this[_handleChunk](br, buf)) { + break + } + } while (true) + this[_reading] = false + } + threw = false + } finally { + if (threw) { + this[_close]() + } + } + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd] + this[_fd] = null + fs.closeSync(fd) + this.emit('close') + } + } +} + +class WriteStream extends EE { + constructor (path, opt) { + opt = opt || {} + super(opt) + this.readable = false + this.writable = true + this[_errored] = false + this[_writing] = false + this[_ended] = false + this[_needDrain] = false + this[_queue] = [] + this[_path] = path + this[_fd] = typeof opt.fd === 'number' ? opt.fd : null + this[_mode] = opt.mode === undefined ? 0o666 : opt.mode + this[_pos] = typeof opt.start === 'number' ? opt.start : null + this[_autoClose] = typeof opt.autoClose === 'boolean' ? + opt.autoClose : true + + // truncating makes no sense when writing into the middle + const defaultFlag = this[_pos] !== null ? 'r+' : 'w' + this[_defaultFlag] = opt.flags === undefined + this[_flags] = this[_defaultFlag] ? defaultFlag : opt.flags + + if (this[_fd] === null) { + this[_open]() + } + } + + emit (ev, data) { + if (ev === 'error') { + if (this[_errored]) { + return + } + this[_errored] = true + } + return super.emit(ev, data) + } + + get fd () { + return this[_fd] + } + + get path () { + return this[_path] + } + + [_onerror] (er) { + this[_close]() + this[_writing] = true + this.emit('error', er) + } + + [_open] () { + fs.open(this[_path], this[_flags], this[_mode], + (er, fd) => this[_onopen](er, fd)) + } + + [_onopen] (er, fd) { + if (this[_defaultFlag] && + this[_flags] === 'r+' && + er && er.code === 'ENOENT') { + this[_flags] = 'w' + this[_open]() + } else if (er) { + this[_onerror](er) + } else { + this[_fd] = fd + this.emit('open', fd) + if (!this[_writing]) { + this[_flush]() + } + } + } + + end (buf, enc) { + if (buf) { + this.write(buf, enc) + } + + this[_ended] = true + + // synthetic after-write logic, where drain/finish live + if (!this[_writing] && !this[_queue].length && + typeof this[_fd] === 'number') { + this[_onwrite](null, 0) + } + return this + } + + write (buf, enc) { + if (typeof buf === 'string') { + buf = Buffer.from(buf, enc) + } + + if (this[_ended]) { + this.emit('error', new Error('write() after end()')) + return false + } + + if (this[_fd] === null || this[_writing] || this[_queue].length) { + this[_queue].push(buf) + this[_needDrain] = true + return false + } + + this[_writing] = true + this[_write](buf) + return true + } + + [_write] (buf) { + fs.write(this[_fd], buf, 0, buf.length, this[_pos], (er, bw) => + this[_onwrite](er, bw)) + } + + [_onwrite] (er, bw) { + if (er) { + this[_onerror](er) + } else { + if (this[_pos] !== null) { + this[_pos] += bw + } + if (this[_queue].length) { + this[_flush]() + } else { + this[_writing] = false + + if (this[_ended] && !this[_finished]) { + this[_finished] = true + this[_close]() + this.emit('finish') + } else if (this[_needDrain]) { + this[_needDrain] = false + this.emit('drain') + } + } + } + } + + [_flush] () { + if (this[_queue].length === 0) { + if (this[_ended]) { + this[_onwrite](null, 0) + } + } else if (this[_queue].length === 1) { + this[_write](this[_queue].pop()) + } else { + const iovec = this[_queue] + this[_queue] = [] + writev(this[_fd], iovec, this[_pos], + (er, bw) => this[_onwrite](er, bw)) + } + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd] + this[_fd] = null + fs.close(fd, er => er ? this.emit('error', er) : this.emit('close')) + } + } +} + +class WriteStreamSync extends WriteStream { + [_open] () { + let fd + // only wrap in a try{} block if we know we'll retry, to avoid + // the rethrow obscuring the error's source frame in most cases. + if (this[_defaultFlag] && this[_flags] === 'r+') { + try { + fd = fs.openSync(this[_path], this[_flags], this[_mode]) + } catch (er) { + if (er.code === 'ENOENT') { + this[_flags] = 'w' + return this[_open]() + } else { + throw er + } + } + } else { + fd = fs.openSync(this[_path], this[_flags], this[_mode]) + } + + this[_onopen](null, fd) + } + + [_close] () { + if (this[_autoClose] && typeof this[_fd] === 'number') { + const fd = this[_fd] + this[_fd] = null + fs.closeSync(fd) + this.emit('close') + } + } + + [_write] (buf) { + // throw the original, but try to close if it fails + let threw = true + try { + this[_onwrite](null, + fs.writeSync(this[_fd], buf, 0, buf.length, this[_pos])) + threw = false + } finally { + if (threw) { + try { + this[_close]() + } catch { + // ok error + } + } + } + } +} + +exports.ReadStream = ReadStream +exports.ReadStreamSync = ReadStreamSync + +exports.WriteStream = WriteStream +exports.WriteStreamSync = WriteStreamSync diff --git a/node_modules/fs-minipass/package.json b/node_modules/fs-minipass/package.json index 2f2436cb5c3b1..e501e6474294d 100644 --- a/node_modules/fs-minipass/package.json +++ b/node_modules/fs-minipass/package.json @@ -1,19 +1,22 @@ { "name": "fs-minipass", - "version": "2.1.0", - "main": "index.js", + "version": "3.0.3", + "main": "lib/index.js", "scripts": { "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" + "lint": "eslint \"**/*.js\"", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run lint -- --fix", + "snap": "tap", + "posttest": "npm run lint" }, "keywords": [], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "license": "ISC", "repository": { "type": "git", - "url": "git+https://github.com/npm/fs-minipass.git" + "url": "https://github.com/npm/fs-minipass.git" }, "bugs": { "url": "https://github.com/npm/fs-minipass/issues" @@ -21,19 +24,31 @@ "homepage": "https://github.com/npm/fs-minipass#readme", "description": "fs read and write streams based on minipass", "dependencies": { - "minipass": "^3.0.0" + "minipass": "^7.0.3" }, "devDependencies": { - "mutate-fs": "^2.0.1", - "tap": "^14.6.4" + "@npmcli/eslint-config": "^4.0.1", + "@npmcli/template-oss": "4.18.0", + "mutate-fs": "^2.1.1", + "tap": "^16.3.2" }, "files": [ - "index.js" + "bin/", + "lib/" ], "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": ">= 8" + "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.18.0", + "publish": "true" } } diff --git a/node_modules/fs.realpath/LICENSE b/node_modules/fs.realpath/LICENSE deleted file mode 100644 index 5bd884c252ac4..0000000000000 --- a/node_modules/fs.realpath/LICENSE +++ /dev/null @@ -1,43 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ----- - -This library bundles a version of the `fs.realpath` and `fs.realpathSync` -methods from Node.js v0.10 under the terms of the Node.js MIT license. - -Node's license follows, also included at the header of `old.js` which contains -the licensed code: - - Copyright Joyent, Inc. and other Node contributors. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. diff --git a/node_modules/fs.realpath/index.js b/node_modules/fs.realpath/index.js deleted file mode 100644 index b09c7c7e6364d..0000000000000 --- a/node_modules/fs.realpath/index.js +++ /dev/null @@ -1,66 +0,0 @@ -module.exports = realpath -realpath.realpath = realpath -realpath.sync = realpathSync -realpath.realpathSync = realpathSync -realpath.monkeypatch = monkeypatch -realpath.unmonkeypatch = unmonkeypatch - -var fs = require('fs') -var origRealpath = fs.realpath -var origRealpathSync = fs.realpathSync - -var version = process.version -var ok = /^v[0-5]\./.test(version) -var old = require('./old.js') - -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) -} - -function realpath (p, cache, cb) { - if (ok) { - return origRealpath(p, cache, cb) - } - - if (typeof cache === 'function') { - cb = cache - cache = null - } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb) - } else { - cb(er, result) - } - }) -} - -function realpathSync (p, cache) { - if (ok) { - return origRealpathSync(p, cache) - } - - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } - } -} - -function monkeypatch () { - fs.realpath = realpath - fs.realpathSync = realpathSync -} - -function unmonkeypatch () { - fs.realpath = origRealpath - fs.realpathSync = origRealpathSync -} diff --git a/node_modules/fs.realpath/old.js b/node_modules/fs.realpath/old.js deleted file mode 100644 index b40305e73fd58..0000000000000 --- a/node_modules/fs.realpath/old.js +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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 pathModule = require('path'); -var isWindows = process.platform === 'win32'; -var fs = require('fs'); - -// JavaScript implementation of realpath, ported from node pre-v6 - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; - - return callback; - - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } - } - - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } - } - } -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -var normalize = pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -exports.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -exports.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs.stat(base, function(err) { - if (err) return cb(err); - - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; diff --git a/node_modules/fs.realpath/package.json b/node_modules/fs.realpath/package.json deleted file mode 100644 index 3edc57d21c713..0000000000000 --- a/node_modules/fs.realpath/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "fs.realpath", - "version": "1.0.0", - "description": "Use node's fs.realpath, but fall back to the JS implementation if the native one fails", - "main": "index.js", - "dependencies": {}, - "devDependencies": {}, - "scripts": { - "test": "tap test/*.js --cov" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/fs.realpath.git" - }, - "keywords": [ - "realpath", - "fs", - "polyfill" - ], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "license": "ISC", - "files": [ - "old.js", - "index.js" - ] -} diff --git a/node_modules/function-bind/LICENSE b/node_modules/function-bind/LICENSE deleted file mode 100644 index 62d6d237ff179..0000000000000 --- a/node_modules/function-bind/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2013 Raynos. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/node_modules/function-bind/implementation.js b/node_modules/function-bind/implementation.js deleted file mode 100644 index cc4daec1b080a..0000000000000 --- a/node_modules/function-bind/implementation.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict'; - -/* eslint no-invalid-this: 1 */ - -var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; -var slice = Array.prototype.slice; -var toStr = Object.prototype.toString; -var funcType = '[object Function]'; - -module.exports = function bind(that) { - var target = this; - if (typeof target !== 'function' || toStr.call(target) !== funcType) { - throw new TypeError(ERROR_MESSAGE + target); - } - var args = slice.call(arguments, 1); - - var bound; - var binder = function () { - if (this instanceof bound) { - var result = target.apply( - this, - args.concat(slice.call(arguments)) - ); - if (Object(result) === result) { - return result; - } - return this; - } else { - return target.apply( - that, - args.concat(slice.call(arguments)) - ); - } - }; - - var boundLength = Math.max(0, target.length - args.length); - var boundArgs = []; - for (var i = 0; i < boundLength; i++) { - boundArgs.push('$' + i); - } - - bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); - - if (target.prototype) { - var Empty = function Empty() {}; - Empty.prototype = target.prototype; - bound.prototype = new Empty(); - Empty.prototype = null; - } - - return bound; -}; diff --git a/node_modules/function-bind/index.js b/node_modules/function-bind/index.js deleted file mode 100644 index 3bb6b9609889f..0000000000000 --- a/node_modules/function-bind/index.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -var implementation = require('./implementation'); - -module.exports = Function.prototype.bind || implementation; diff --git a/node_modules/function-bind/package.json b/node_modules/function-bind/package.json deleted file mode 100644 index 20a1727cbf871..0000000000000 --- a/node_modules/function-bind/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "function-bind", - "version": "1.1.1", - "description": "Implementation of Function.prototype.bind", - "keywords": [ - "function", - "bind", - "shim", - "es5" - ], - "author": "Raynos <raynos2@gmail.com>", - "repository": "git://github.com/Raynos/function-bind.git", - "main": "index", - "homepage": "https://github.com/Raynos/function-bind", - "contributors": [ - { - "name": "Raynos" - }, - { - "name": "Jordan Harband", - "url": "https://github.com/ljharb" - } - ], - "bugs": { - "url": "https://github.com/Raynos/function-bind/issues", - "email": "raynos2@gmail.com" - }, - "dependencies": {}, - "devDependencies": { - "@ljharb/eslint-config": "^12.2.1", - "covert": "^1.1.0", - "eslint": "^4.5.0", - "jscs": "^3.0.7", - "tape": "^4.8.0" - }, - "license": "MIT", - "scripts": { - "pretest": "npm run lint", - "test": "npm run tests-only", - "posttest": "npm run coverage -- --quiet", - "tests-only": "node test", - "coverage": "covert test/*.js", - "lint": "npm run jscs && npm run eslint", - "jscs": "jscs *.js */*.js", - "eslint": "eslint *.js */*.js" - }, - "testling": { - "files": "test/index.js", - "browsers": [ - "ie/8..latest", - "firefox/16..latest", - "firefox/nightly", - "chrome/22..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/node_modules/function-bind/test/index.js b/node_modules/function-bind/test/index.js deleted file mode 100644 index 2edecce2f0fa5..0000000000000 --- a/node_modules/function-bind/test/index.js +++ /dev/null @@ -1,252 +0,0 @@ -// jscs:disable requireUseStrict - -var test = require('tape'); - -var functionBind = require('../implementation'); -var getCurrentContext = function () { return this; }; - -test('functionBind is a function', function (t) { - t.equal(typeof functionBind, 'function'); - t.end(); -}); - -test('non-functions', function (t) { - var nonFunctions = [true, false, [], {}, 42, 'foo', NaN, /a/g]; - t.plan(nonFunctions.length); - for (var i = 0; i < nonFunctions.length; ++i) { - try { functionBind.call(nonFunctions[i]); } catch (ex) { - t.ok(ex instanceof TypeError, 'throws when given ' + String(nonFunctions[i])); - } - } - t.end(); -}); - -test('without a context', function (t) { - t.test('binds properly', function (st) { - var args, context; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - context = this; - }) - }; - namespace.func(1, 2, 3); - st.deepEqual(args, [1, 2, 3]); - st.equal(context, getCurrentContext.call()); - st.end(); - }); - - t.test('binds properly, and still supplies bound arguments', function (st) { - var args, context; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - context = this; - }, undefined, 1, 2, 3) - }; - namespace.func(4, 5, 6); - st.deepEqual(args, [1, 2, 3, 4, 5, 6]); - st.equal(context, getCurrentContext.call()); - st.end(); - }); - - t.test('returns properly', function (st) { - var args; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - return this; - }, null) - }; - var context = namespace.func(1, 2, 3); - st.equal(context, getCurrentContext.call(), 'returned context is namespaced context'); - st.deepEqual(args, [1, 2, 3], 'passed arguments are correct'); - st.end(); - }); - - t.test('returns properly with bound arguments', function (st) { - var args; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - return this; - }, null, 1, 2, 3) - }; - var context = namespace.func(4, 5, 6); - st.equal(context, getCurrentContext.call(), 'returned context is namespaced context'); - st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct'); - st.end(); - }); - - t.test('called as a constructor', function (st) { - var thunkify = function (value) { - return function () { return value; }; - }; - st.test('returns object value', function (sst) { - var expectedReturnValue = [1, 2, 3]; - var Constructor = functionBind.call(thunkify(expectedReturnValue), null); - var result = new Constructor(); - sst.equal(result, expectedReturnValue); - sst.end(); - }); - - st.test('does not return primitive value', function (sst) { - var Constructor = functionBind.call(thunkify(42), null); - var result = new Constructor(); - sst.notEqual(result, 42); - sst.end(); - }); - - st.test('object from bound constructor is instance of original and bound constructor', function (sst) { - var A = function (x) { - this.name = x || 'A'; - }; - var B = functionBind.call(A, null, 'B'); - - var result = new B(); - sst.ok(result instanceof B, 'result is instance of bound constructor'); - sst.ok(result instanceof A, 'result is instance of original constructor'); - sst.end(); - }); - - st.end(); - }); - - t.end(); -}); - -test('with a context', function (t) { - t.test('with no bound arguments', function (st) { - var args, context; - var boundContext = {}; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - context = this; - }, boundContext) - }; - namespace.func(1, 2, 3); - st.equal(context, boundContext, 'binds a context properly'); - st.deepEqual(args, [1, 2, 3], 'supplies passed arguments'); - st.end(); - }); - - t.test('with bound arguments', function (st) { - var args, context; - var boundContext = {}; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - context = this; - }, boundContext, 1, 2, 3) - }; - namespace.func(4, 5, 6); - st.equal(context, boundContext, 'binds a context properly'); - st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'supplies bound and passed arguments'); - st.end(); - }); - - t.test('returns properly', function (st) { - var boundContext = {}; - var args; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - return this; - }, boundContext) - }; - var context = namespace.func(1, 2, 3); - st.equal(context, boundContext, 'returned context is bound context'); - st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context'); - st.deepEqual(args, [1, 2, 3], 'passed arguments are correct'); - st.end(); - }); - - t.test('returns properly with bound arguments', function (st) { - var boundContext = {}; - var args; - var namespace = { - func: functionBind.call(function () { - args = Array.prototype.slice.call(arguments); - return this; - }, boundContext, 1, 2, 3) - }; - var context = namespace.func(4, 5, 6); - st.equal(context, boundContext, 'returned context is bound context'); - st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context'); - st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct'); - st.end(); - }); - - t.test('passes the correct arguments when called as a constructor', function (st) { - var expected = { name: 'Correct' }; - var namespace = { - Func: functionBind.call(function (arg) { - return arg; - }, { name: 'Incorrect' }) - }; - var returned = new namespace.Func(expected); - st.equal(returned, expected, 'returns the right arg when called as a constructor'); - st.end(); - }); - - t.test('has the new instance\'s context when called as a constructor', function (st) { - var actualContext; - var expectedContext = { foo: 'bar' }; - var namespace = { - Func: functionBind.call(function () { - actualContext = this; - }, expectedContext) - }; - var result = new namespace.Func(); - st.equal(result instanceof namespace.Func, true); - st.notEqual(actualContext, expectedContext); - st.end(); - }); - - t.end(); -}); - -test('bound function length', function (t) { - t.test('sets a correct length without thisArg', function (st) { - var subject = functionBind.call(function (a, b, c) { return a + b + c; }); - st.equal(subject.length, 3); - st.equal(subject(1, 2, 3), 6); - st.end(); - }); - - t.test('sets a correct length with thisArg', function (st) { - var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}); - st.equal(subject.length, 3); - st.equal(subject(1, 2, 3), 6); - st.end(); - }); - - t.test('sets a correct length without thisArg and first argument', function (st) { - var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1); - st.equal(subject.length, 2); - st.equal(subject(2, 3), 6); - st.end(); - }); - - t.test('sets a correct length with thisArg and first argument', function (st) { - var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1); - st.equal(subject.length, 2); - st.equal(subject(2, 3), 6); - st.end(); - }); - - t.test('sets a correct length without thisArg and too many arguments', function (st) { - var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1, 2, 3, 4); - st.equal(subject.length, 0); - st.equal(subject(), 6); - st.end(); - }); - - t.test('sets a correct length with thisArg and too many arguments', function (st) { - var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1, 2, 3, 4); - st.equal(subject.length, 0); - st.equal(subject(), 6); - st.end(); - }); -}); diff --git a/node_modules/gauge/LICENSE.md b/node_modules/gauge/LICENSE.md deleted file mode 100644 index 5fc208ff122e0..0000000000000 --- a/node_modules/gauge/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> - -ISC License - -Copyright npm, Inc. - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/gauge/lib/base-theme.js b/node_modules/gauge/lib/base-theme.js deleted file mode 100644 index 00bf5684cddab..0000000000000 --- a/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/node_modules/gauge/lib/error.js b/node_modules/gauge/lib/error.js deleted file mode 100644 index d9914ba5335d2..0000000000000 --- a/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/node_modules/gauge/lib/has-color.js b/node_modules/gauge/lib/has-color.js deleted file mode 100644 index 16cba0eb47d33..0000000000000 --- a/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/node_modules/gauge/lib/index.js b/node_modules/gauge/lib/index.js deleted file mode 100644 index 37fc5ac60a16f..0000000000000 --- a/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') -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/node_modules/gauge/lib/plumbing.js b/node_modules/gauge/lib/plumbing.js deleted file mode 100644 index c4dc3e074b95e..0000000000000 --- a/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/node_modules/gauge/lib/process.js b/node_modules/gauge/lib/process.js deleted file mode 100644 index 05e85694d755b..0000000000000 --- a/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/node_modules/gauge/lib/progress-bar.js b/node_modules/gauge/lib/progress-bar.js deleted file mode 100644 index 184ff2500aae4..0000000000000 --- a/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/node_modules/gauge/lib/render-template.js b/node_modules/gauge/lib/render-template.js deleted file mode 100644 index d1b52c0f48095..0000000000000 --- a/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/node_modules/gauge/lib/set-immediate.js b/node_modules/gauge/lib/set-immediate.js deleted file mode 100644 index 6650a485c4993..0000000000000 --- a/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/node_modules/gauge/lib/set-interval.js b/node_modules/gauge/lib/set-interval.js deleted file mode 100644 index 576198793c550..0000000000000 --- a/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/node_modules/gauge/lib/spin.js b/node_modules/gauge/lib/spin.js deleted file mode 100644 index 34142ee31acc7..0000000000000 --- a/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/node_modules/gauge/lib/template-item.js b/node_modules/gauge/lib/template-item.js deleted file mode 100644 index e307e9b7421e7..0000000000000 --- a/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/node_modules/gauge/lib/theme-set.js b/node_modules/gauge/lib/theme-set.js deleted file mode 100644 index 643d7dbb1da34..0000000000000 --- a/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/node_modules/gauge/lib/themes.js b/node_modules/gauge/lib/themes.js deleted file mode 100644 index d2e62bbccb3d8..0000000000000 --- a/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/node_modules/gauge/lib/wide-truncate.js b/node_modules/gauge/lib/wide-truncate.js deleted file mode 100644 index 5284a699ac3fb..0000000000000 --- a/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/node_modules/gauge/package.json b/node_modules/gauge/package.json deleted file mode 100644 index bce3e68a33f69..0000000000000 --- a/node_modules/gauge/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "gauge", - "version": "4.0.4", - "description": "A terminal based horizontal gauge", - "main": "lib", - "scripts": { - "test": "tap", - "lint": "eslint \"**/*.js\"", - "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "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": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.0", - "readable-stream": "^3.6.0", - "tap": "^16.0.1" - }, - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "tap": { - "branches": 79, - "statements": 89, - "functions": 92, - "lines": 90 - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.0" - } -} diff --git a/node_modules/glob/LICENSE b/node_modules/glob/LICENSE deleted file mode 100644 index 39e8fe16f665a..0000000000000 --- a/node_modules/glob/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/glob/LICENSE.md b/node_modules/glob/LICENSE.md new file mode 100644 index 0000000000000..881248b6d7f0c --- /dev/null +++ b/node_modules/glob/LICENSE.md @@ -0,0 +1,63 @@ +All packages under `src/` are licensed according to the terms in +their respective `LICENSE` or `LICENSE.md` files. + +The remainder of this project is licensed under the Blue Oak +Model License, as follows: + +----- + +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/glob/common.js b/node_modules/glob/common.js deleted file mode 100644 index e094f750472f7..0000000000000 --- a/node_modules/glob/common.js +++ /dev/null @@ -1,240 +0,0 @@ -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var fs = require("fs") -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path").isAbsolute -var Minimatch = minimatch.Minimatch - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - self.fs = options.fs || fs - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = path.resolve(cwd) - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - self.nomount = !!options.nomount - - if (process.platform === "win32") { - self.root = self.root.replace(/\\/g, "/") - self.cwd = self.cwd.replace(/\\/g, "/") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - } - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = true - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} diff --git a/node_modules/glob/dist/commonjs/glob.js b/node_modules/glob/dist/commonjs/glob.js new file mode 100644 index 0000000000000..e1339bbbcf57f --- /dev/null +++ b/node_modules/glob/dist/commonjs/glob.js @@ -0,0 +1,247 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Glob = void 0; +const minimatch_1 = require("minimatch"); +const node_url_1 = require("node:url"); +const path_scurry_1 = require("path-scurry"); +const pattern_js_1 = require("./pattern.js"); +const walker_js_1 = require("./walker.js"); +// if no process global, just call it linux. +// so we default to case-sensitive, / separators +const defaultPlatform = (typeof process === 'object' && + process && + typeof process.platform === 'string') ? + process.platform + : 'linux'; +/** + * An object that can perform glob pattern traversals. + */ +class Glob { + absolute; + cwd; + root; + dot; + dotRelative; + follow; + ignore; + magicalBraces; + mark; + matchBase; + maxDepth; + nobrace; + nocase; + nodir; + noext; + noglobstar; + pattern; + platform; + realpath; + scurry; + stat; + signal; + windowsPathsNoEscape; + withFileTypes; + includeChildMatches; + /** + * The options provided to the constructor. + */ + opts; + /** + * An array of parsed immutable {@link Pattern} objects. + */ + patterns; + /** + * All options are stored as properties on the `Glob` object. + * + * See {@link GlobOptions} for full options descriptions. + * + * Note that a previous `Glob` object can be passed as the + * `GlobOptions` to another `Glob` instantiation to re-use settings + * and caches with a new pattern. + * + * Traversal functions can be called multiple times to run the walk + * again. + */ + constructor(pattern, opts) { + /* c8 ignore start */ + if (!opts) + throw new TypeError('glob options required'); + /* c8 ignore stop */ + this.withFileTypes = !!opts.withFileTypes; + this.signal = opts.signal; + this.follow = !!opts.follow; + this.dot = !!opts.dot; + this.dotRelative = !!opts.dotRelative; + this.nodir = !!opts.nodir; + this.mark = !!opts.mark; + if (!opts.cwd) { + this.cwd = ''; + } + else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) { + opts.cwd = (0, node_url_1.fileURLToPath)(opts.cwd); + } + this.cwd = opts.cwd || ''; + this.root = opts.root; + this.magicalBraces = !!opts.magicalBraces; + this.nobrace = !!opts.nobrace; + this.noext = !!opts.noext; + this.realpath = !!opts.realpath; + this.absolute = opts.absolute; + this.includeChildMatches = opts.includeChildMatches !== false; + this.noglobstar = !!opts.noglobstar; + this.matchBase = !!opts.matchBase; + this.maxDepth = + typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity; + this.stat = !!opts.stat; + this.ignore = opts.ignore; + if (this.withFileTypes && this.absolute !== undefined) { + throw new Error('cannot set absolute and withFileTypes:true'); + } + if (typeof pattern === 'string') { + pattern = [pattern]; + } + this.windowsPathsNoEscape = + !!opts.windowsPathsNoEscape || + opts.allowWindowsEscape === + false; + if (this.windowsPathsNoEscape) { + pattern = pattern.map(p => p.replace(/\\/g, '/')); + } + if (this.matchBase) { + if (opts.noglobstar) { + throw new TypeError('base matching requires globstar'); + } + pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`)); + } + this.pattern = pattern; + this.platform = opts.platform || defaultPlatform; + this.opts = { ...opts, platform: this.platform }; + if (opts.scurry) { + this.scurry = opts.scurry; + if (opts.nocase !== undefined && + opts.nocase !== opts.scurry.nocase) { + throw new Error('nocase option contradicts provided scurry option'); + } + } + else { + const Scurry = opts.platform === 'win32' ? path_scurry_1.PathScurryWin32 + : opts.platform === 'darwin' ? path_scurry_1.PathScurryDarwin + : opts.platform ? path_scurry_1.PathScurryPosix + : path_scurry_1.PathScurry; + this.scurry = new Scurry(this.cwd, { + nocase: opts.nocase, + fs: opts.fs, + }); + } + this.nocase = this.scurry.nocase; + // If you do nocase:true on a case-sensitive file system, then + // we need to use regexps instead of strings for non-magic + // path portions, because statting `aBc` won't return results + // for the file `AbC` for example. + const nocaseMagicOnly = this.platform === 'darwin' || this.platform === 'win32'; + const mmo = { + // default nocase based on platform + ...opts, + dot: this.dot, + matchBase: this.matchBase, + nobrace: this.nobrace, + nocase: this.nocase, + nocaseMagicOnly, + nocomment: true, + noext: this.noext, + nonegate: true, + optimizationLevel: 2, + platform: this.platform, + windowsPathsNoEscape: this.windowsPathsNoEscape, + debug: !!this.opts.debug, + }; + const mms = this.pattern.map(p => new minimatch_1.Minimatch(p, mmo)); + const [matchSet, globParts] = mms.reduce((set, m) => { + set[0].push(...m.set); + set[1].push(...m.globParts); + return set; + }, [[], []]); + this.patterns = matchSet.map((set, i) => { + const g = globParts[i]; + /* c8 ignore start */ + if (!g) + throw new Error('invalid pattern object'); + /* c8 ignore stop */ + return new pattern_js_1.Pattern(set, g, 0, this.platform); + }); + } + async walk() { + // Walkers always return array of Path objects, so we just have to + // coerce them into the right shape. It will have already called + // realpath() if the option was set to do so, so we know that's cached. + // start out knowing the cwd, at least + return [ + ...(await new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).walk()), + ]; + } + walkSync() { + return [ + ...new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).walkSync(), + ]; + } + stream() { + return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).stream(); + } + streamSync() { + return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).streamSync(); + } + /** + * Default sync iteration function. Returns a Generator that + * iterates over the results. + */ + iterateSync() { + return this.streamSync()[Symbol.iterator](); + } + [Symbol.iterator]() { + return this.iterateSync(); + } + /** + * Default async iteration function. Returns an AsyncGenerator that + * iterates over the results. + */ + iterate() { + return this.stream()[Symbol.asyncIterator](); + } + [Symbol.asyncIterator]() { + return this.iterate(); + } +} +exports.Glob = Glob; +//# sourceMappingURL=glob.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/commonjs/has-magic.js b/node_modules/glob/dist/commonjs/has-magic.js new file mode 100644 index 0000000000000..0918bd57e0f1c --- /dev/null +++ b/node_modules/glob/dist/commonjs/has-magic.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.hasMagic = void 0; +const minimatch_1 = require("minimatch"); +/** + * Return true if the patterns provided contain any magic glob characters, + * given the options provided. + * + * Brace expansion is not considered "magic" unless the `magicalBraces` option + * is set, as brace expansion just turns one string into an array of strings. + * So a pattern like `'x{a,b}y'` would return `false`, because `'xay'` and + * `'xby'` both do not contain any magic glob characters, and it's treated the + * same as if you had called it on `['xay', 'xby']`. When `magicalBraces:true` + * is in the options, brace expansion _is_ treated as a pattern having magic. + */ +const hasMagic = (pattern, options = {}) => { + if (!Array.isArray(pattern)) { + pattern = [pattern]; + } + for (const p of pattern) { + if (new minimatch_1.Minimatch(p, options).hasMagic()) + return true; + } + return false; +}; +exports.hasMagic = hasMagic; +//# sourceMappingURL=has-magic.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/commonjs/ignore.js b/node_modules/glob/dist/commonjs/ignore.js new file mode 100644 index 0000000000000..5f1fde0680dea --- /dev/null +++ b/node_modules/glob/dist/commonjs/ignore.js @@ -0,0 +1,119 @@ +"use strict"; +// give it a pattern, and it'll be able to tell you if +// a given path should be ignored. +// Ignoring a path ignores its children if the pattern ends in /** +// Ignores are always parsed in dot:true mode +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Ignore = void 0; +const minimatch_1 = require("minimatch"); +const pattern_js_1 = require("./pattern.js"); +const defaultPlatform = (typeof process === 'object' && + process && + typeof process.platform === 'string') ? + process.platform + : 'linux'; +/** + * Class used to process ignored patterns + */ +class Ignore { + relative; + relativeChildren; + absolute; + absoluteChildren; + platform; + mmopts; + constructor(ignored, { nobrace, nocase, noext, noglobstar, platform = defaultPlatform, }) { + this.relative = []; + this.absolute = []; + this.relativeChildren = []; + this.absoluteChildren = []; + this.platform = platform; + this.mmopts = { + dot: true, + nobrace, + nocase, + noext, + noglobstar, + optimizationLevel: 2, + platform, + nocomment: true, + nonegate: true, + }; + for (const ign of ignored) + this.add(ign); + } + add(ign) { + // this is a little weird, but it gives us a clean set of optimized + // minimatch matchers, without getting tripped up if one of them + // ends in /** inside a brace section, and it's only inefficient at + // the start of the walk, not along it. + // It'd be nice if the Pattern class just had a .test() method, but + // handling globstars is a bit of a pita, and that code already lives + // in minimatch anyway. + // Another way would be if maybe Minimatch could take its set/globParts + // as an option, and then we could at least just use Pattern to test + // for absolute-ness. + // Yet another way, Minimatch could take an array of glob strings, and + // a cwd option, and do the right thing. + const mm = new minimatch_1.Minimatch(ign, this.mmopts); + for (let i = 0; i < mm.set.length; i++) { + const parsed = mm.set[i]; + const globParts = mm.globParts[i]; + /* c8 ignore start */ + if (!parsed || !globParts) { + throw new Error('invalid pattern object'); + } + // strip off leading ./ portions + // https://github.com/isaacs/node-glob/issues/570 + while (parsed[0] === '.' && globParts[0] === '.') { + parsed.shift(); + globParts.shift(); + } + /* c8 ignore stop */ + const p = new pattern_js_1.Pattern(parsed, globParts, 0, this.platform); + const m = new minimatch_1.Minimatch(p.globString(), this.mmopts); + const children = globParts[globParts.length - 1] === '**'; + const absolute = p.isAbsolute(); + if (absolute) + this.absolute.push(m); + else + this.relative.push(m); + if (children) { + if (absolute) + this.absoluteChildren.push(m); + else + this.relativeChildren.push(m); + } + } + } + ignored(p) { + const fullpath = p.fullpath(); + const fullpaths = `${fullpath}/`; + const relative = p.relative() || '.'; + const relatives = `${relative}/`; + for (const m of this.relative) { + if (m.match(relative) || m.match(relatives)) + return true; + } + for (const m of this.absolute) { + if (m.match(fullpath) || m.match(fullpaths)) + return true; + } + return false; + } + childrenIgnored(p) { + const fullpath = p.fullpath() + '/'; + const relative = (p.relative() || '.') + '/'; + for (const m of this.relativeChildren) { + if (m.match(relative)) + return true; + } + for (const m of this.absoluteChildren) { + if (m.match(fullpath)) + return true; + } + return false; + } +} +exports.Ignore = Ignore; +//# sourceMappingURL=ignore.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/commonjs/index.js b/node_modules/glob/dist/commonjs/index.js new file mode 100644 index 0000000000000..151495d170efa --- /dev/null +++ b/node_modules/glob/dist/commonjs/index.js @@ -0,0 +1,68 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.glob = exports.sync = exports.iterate = exports.iterateSync = exports.stream = exports.streamSync = exports.Ignore = exports.hasMagic = exports.Glob = exports.unescape = exports.escape = void 0; +exports.globStreamSync = globStreamSync; +exports.globStream = globStream; +exports.globSync = globSync; +exports.globIterateSync = globIterateSync; +exports.globIterate = globIterate; +const minimatch_1 = require("minimatch"); +const glob_js_1 = require("./glob.js"); +const has_magic_js_1 = require("./has-magic.js"); +var minimatch_2 = require("minimatch"); +Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return minimatch_2.escape; } }); +Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return minimatch_2.unescape; } }); +var glob_js_2 = require("./glob.js"); +Object.defineProperty(exports, "Glob", { enumerable: true, get: function () { return glob_js_2.Glob; } }); +var has_magic_js_2 = require("./has-magic.js"); +Object.defineProperty(exports, "hasMagic", { enumerable: true, get: function () { return has_magic_js_2.hasMagic; } }); +var ignore_js_1 = require("./ignore.js"); +Object.defineProperty(exports, "Ignore", { enumerable: true, get: function () { return ignore_js_1.Ignore; } }); +function globStreamSync(pattern, options = {}) { + return new glob_js_1.Glob(pattern, options).streamSync(); +} +function globStream(pattern, options = {}) { + return new glob_js_1.Glob(pattern, options).stream(); +} +function globSync(pattern, options = {}) { + return new glob_js_1.Glob(pattern, options).walkSync(); +} +async function glob_(pattern, options = {}) { + return new glob_js_1.Glob(pattern, options).walk(); +} +function globIterateSync(pattern, options = {}) { + return new glob_js_1.Glob(pattern, options).iterateSync(); +} +function globIterate(pattern, options = {}) { + return new glob_js_1.Glob(pattern, options).iterate(); +} +// aliases: glob.sync.stream() glob.stream.sync() glob.sync() etc +exports.streamSync = globStreamSync; +exports.stream = Object.assign(globStream, { sync: globStreamSync }); +exports.iterateSync = globIterateSync; +exports.iterate = Object.assign(globIterate, { + sync: globIterateSync, +}); +exports.sync = Object.assign(globSync, { + stream: globStreamSync, + iterate: globIterateSync, +}); +exports.glob = Object.assign(glob_, { + glob: glob_, + globSync, + sync: exports.sync, + globStream, + stream: exports.stream, + globStreamSync, + streamSync: exports.streamSync, + globIterate, + iterate: exports.iterate, + globIterateSync, + iterateSync: exports.iterateSync, + Glob: glob_js_1.Glob, + hasMagic: has_magic_js_1.hasMagic, + escape: minimatch_1.escape, + unescape: minimatch_1.unescape, +}); +exports.glob.glob = exports.glob; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/commonjs/package.json b/node_modules/glob/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/glob/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/glob/dist/commonjs/pattern.js b/node_modules/glob/dist/commonjs/pattern.js new file mode 100644 index 0000000000000..f0de35fb5bed9 --- /dev/null +++ b/node_modules/glob/dist/commonjs/pattern.js @@ -0,0 +1,219 @@ +"use strict"; +// this is just a very light wrapper around 2 arrays with an offset index +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Pattern = void 0; +const minimatch_1 = require("minimatch"); +const isPatternList = (pl) => pl.length >= 1; +const isGlobList = (gl) => gl.length >= 1; +/** + * An immutable-ish view on an array of glob parts and their parsed + * results + */ +class Pattern { + #patternList; + #globList; + #index; + length; + #platform; + #rest; + #globString; + #isDrive; + #isUNC; + #isAbsolute; + #followGlobstar = true; + constructor(patternList, globList, index, platform) { + if (!isPatternList(patternList)) { + throw new TypeError('empty pattern list'); + } + if (!isGlobList(globList)) { + throw new TypeError('empty glob list'); + } + if (globList.length !== patternList.length) { + throw new TypeError('mismatched pattern list and glob list lengths'); + } + this.length = patternList.length; + if (index < 0 || index >= this.length) { + throw new TypeError('index out of range'); + } + this.#patternList = patternList; + this.#globList = globList; + this.#index = index; + this.#platform = platform; + // normalize root entries of absolute patterns on initial creation. + if (this.#index === 0) { + // c: => ['c:/'] + // C:/ => ['C:/'] + // C:/x => ['C:/', 'x'] + // //host/share => ['//host/share/'] + // //host/share/ => ['//host/share/'] + // //host/share/x => ['//host/share/', 'x'] + // /etc => ['/', 'etc'] + // / => ['/'] + if (this.isUNC()) { + // '' / '' / 'host' / 'share' + const [p0, p1, p2, p3, ...prest] = this.#patternList; + const [g0, g1, g2, g3, ...grest] = this.#globList; + if (prest[0] === '') { + // ends in / + prest.shift(); + grest.shift(); + } + const p = [p0, p1, p2, p3, ''].join('/'); + const g = [g0, g1, g2, g3, ''].join('/'); + this.#patternList = [p, ...prest]; + this.#globList = [g, ...grest]; + this.length = this.#patternList.length; + } + else if (this.isDrive() || this.isAbsolute()) { + const [p1, ...prest] = this.#patternList; + const [g1, ...grest] = this.#globList; + if (prest[0] === '') { + // ends in / + prest.shift(); + grest.shift(); + } + const p = p1 + '/'; + const g = g1 + '/'; + this.#patternList = [p, ...prest]; + this.#globList = [g, ...grest]; + this.length = this.#patternList.length; + } + } + } + /** + * The first entry in the parsed list of patterns + */ + pattern() { + return this.#patternList[this.#index]; + } + /** + * true of if pattern() returns a string + */ + isString() { + return typeof this.#patternList[this.#index] === 'string'; + } + /** + * true of if pattern() returns GLOBSTAR + */ + isGlobstar() { + return this.#patternList[this.#index] === minimatch_1.GLOBSTAR; + } + /** + * true if pattern() returns a regexp + */ + isRegExp() { + return this.#patternList[this.#index] instanceof RegExp; + } + /** + * The /-joined set of glob parts that make up this pattern + */ + globString() { + return (this.#globString = + this.#globString || + (this.#index === 0 ? + this.isAbsolute() ? + this.#globList[0] + this.#globList.slice(1).join('/') + : this.#globList.join('/') + : this.#globList.slice(this.#index).join('/'))); + } + /** + * true if there are more pattern parts after this one + */ + hasMore() { + return this.length > this.#index + 1; + } + /** + * The rest of the pattern after this part, or null if this is the end + */ + rest() { + if (this.#rest !== undefined) + return this.#rest; + if (!this.hasMore()) + return (this.#rest = null); + this.#rest = new Pattern(this.#patternList, this.#globList, this.#index + 1, this.#platform); + this.#rest.#isAbsolute = this.#isAbsolute; + this.#rest.#isUNC = this.#isUNC; + this.#rest.#isDrive = this.#isDrive; + return this.#rest; + } + /** + * true if the pattern represents a //unc/path/ on windows + */ + isUNC() { + const pl = this.#patternList; + return this.#isUNC !== undefined ? + this.#isUNC + : (this.#isUNC = + this.#platform === 'win32' && + this.#index === 0 && + pl[0] === '' && + pl[1] === '' && + typeof pl[2] === 'string' && + !!pl[2] && + typeof pl[3] === 'string' && + !!pl[3]); + } + // pattern like C:/... + // split = ['C:', ...] + // XXX: would be nice to handle patterns like `c:*` to test the cwd + // in c: for *, but I don't know of a way to even figure out what that + // cwd is without actually chdir'ing into it? + /** + * True if the pattern starts with a drive letter on Windows + */ + isDrive() { + const pl = this.#patternList; + return this.#isDrive !== undefined ? + this.#isDrive + : (this.#isDrive = + this.#platform === 'win32' && + this.#index === 0 && + this.length > 1 && + typeof pl[0] === 'string' && + /^[a-z]:$/i.test(pl[0])); + } + // pattern = '/' or '/...' or '/x/...' + // split = ['', ''] or ['', ...] or ['', 'x', ...] + // Drive and UNC both considered absolute on windows + /** + * True if the pattern is rooted on an absolute path + */ + isAbsolute() { + const pl = this.#patternList; + return this.#isAbsolute !== undefined ? + this.#isAbsolute + : (this.#isAbsolute = + (pl[0] === '' && pl.length > 1) || + this.isDrive() || + this.isUNC()); + } + /** + * consume the root of the pattern, and return it + */ + root() { + const p = this.#patternList[0]; + return (typeof p === 'string' && this.isAbsolute() && this.#index === 0) ? + p + : ''; + } + /** + * Check to see if the current globstar pattern is allowed to follow + * a symbolic link. + */ + checkFollowGlobstar() { + return !(this.#index === 0 || + !this.isGlobstar() || + !this.#followGlobstar); + } + /** + * Mark that the current globstar pattern is following a symbolic link + */ + markFollowGlobstar() { + if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar) + return false; + this.#followGlobstar = false; + return true; + } +} +exports.Pattern = Pattern; +//# sourceMappingURL=pattern.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/commonjs/processor.js b/node_modules/glob/dist/commonjs/processor.js new file mode 100644 index 0000000000000..ee3bb4397e0b2 --- /dev/null +++ b/node_modules/glob/dist/commonjs/processor.js @@ -0,0 +1,301 @@ +"use strict"; +// synchronous utility for filtering entries and calculating subwalks +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Processor = exports.SubWalks = exports.MatchRecord = exports.HasWalkedCache = void 0; +const minimatch_1 = require("minimatch"); +/** + * A cache of which patterns have been processed for a given Path + */ +class HasWalkedCache { + store; + constructor(store = new Map()) { + this.store = store; + } + copy() { + return new HasWalkedCache(new Map(this.store)); + } + hasWalked(target, pattern) { + return this.store.get(target.fullpath())?.has(pattern.globString()); + } + storeWalked(target, pattern) { + const fullpath = target.fullpath(); + const cached = this.store.get(fullpath); + if (cached) + cached.add(pattern.globString()); + else + this.store.set(fullpath, new Set([pattern.globString()])); + } +} +exports.HasWalkedCache = HasWalkedCache; +/** + * A record of which paths have been matched in a given walk step, + * and whether they only are considered a match if they are a directory, + * and whether their absolute or relative path should be returned. + */ +class MatchRecord { + store = new Map(); + add(target, absolute, ifDir) { + const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0); + const current = this.store.get(target); + this.store.set(target, current === undefined ? n : n & current); + } + // match, absolute, ifdir + entries() { + return [...this.store.entries()].map(([path, n]) => [ + path, + !!(n & 2), + !!(n & 1), + ]); + } +} +exports.MatchRecord = MatchRecord; +/** + * A collection of patterns that must be processed in a subsequent step + * for a given path. + */ +class SubWalks { + store = new Map(); + add(target, pattern) { + if (!target.canReaddir()) { + return; + } + const subs = this.store.get(target); + if (subs) { + if (!subs.find(p => p.globString() === pattern.globString())) { + subs.push(pattern); + } + } + else + this.store.set(target, [pattern]); + } + get(target) { + const subs = this.store.get(target); + /* c8 ignore start */ + if (!subs) { + throw new Error('attempting to walk unknown path'); + } + /* c8 ignore stop */ + return subs; + } + entries() { + return this.keys().map(k => [k, this.store.get(k)]); + } + keys() { + return [...this.store.keys()].filter(t => t.canReaddir()); + } +} +exports.SubWalks = SubWalks; +/** + * The class that processes patterns for a given path. + * + * Handles child entry filtering, and determining whether a path's + * directory contents must be read. + */ +class Processor { + hasWalkedCache; + matches = new MatchRecord(); + subwalks = new SubWalks(); + patterns; + follow; + dot; + opts; + constructor(opts, hasWalkedCache) { + this.opts = opts; + this.follow = !!opts.follow; + this.dot = !!opts.dot; + this.hasWalkedCache = + hasWalkedCache ? hasWalkedCache.copy() : new HasWalkedCache(); + } + processPatterns(target, patterns) { + this.patterns = patterns; + const processingSet = patterns.map(p => [target, p]); + // map of paths to the magic-starting subwalks they need to walk + // first item in patterns is the filter + for (let [t, pattern] of processingSet) { + this.hasWalkedCache.storeWalked(t, pattern); + const root = pattern.root(); + const absolute = pattern.isAbsolute() && this.opts.absolute !== false; + // start absolute patterns at root + if (root) { + t = t.resolve(root === '/' && this.opts.root !== undefined ? + this.opts.root + : root); + const rest = pattern.rest(); + if (!rest) { + this.matches.add(t, true, false); + continue; + } + else { + pattern = rest; + } + } + if (t.isENOENT()) + continue; + let p; + let rest; + let changed = false; + while (typeof (p = pattern.pattern()) === 'string' && + (rest = pattern.rest())) { + const c = t.resolve(p); + t = c; + pattern = rest; + changed = true; + } + p = pattern.pattern(); + rest = pattern.rest(); + if (changed) { + if (this.hasWalkedCache.hasWalked(t, pattern)) + continue; + this.hasWalkedCache.storeWalked(t, pattern); + } + // now we have either a final string for a known entry, + // more strings for an unknown entry, + // or a pattern starting with magic, mounted on t. + if (typeof p === 'string') { + // must not be final entry, otherwise we would have + // concatenated it earlier. + const ifDir = p === '..' || p === '' || p === '.'; + this.matches.add(t.resolve(p), absolute, ifDir); + continue; + } + else if (p === minimatch_1.GLOBSTAR) { + // if no rest, match and subwalk pattern + // if rest, process rest and subwalk pattern + // if it's a symlink, but we didn't get here by way of a + // globstar match (meaning it's the first time THIS globstar + // has traversed a symlink), then we follow it. Otherwise, stop. + if (!t.isSymbolicLink() || + this.follow || + pattern.checkFollowGlobstar()) { + this.subwalks.add(t, pattern); + } + const rp = rest?.pattern(); + const rrest = rest?.rest(); + if (!rest || ((rp === '' || rp === '.') && !rrest)) { + // only HAS to be a dir if it ends in **/ or **/. + // but ending in ** will match files as well. + this.matches.add(t, absolute, rp === '' || rp === '.'); + } + else { + if (rp === '..') { + // this would mean you're matching **/.. at the fs root, + // and no thanks, I'm not gonna test that specific case. + /* c8 ignore start */ + const tp = t.parent || t; + /* c8 ignore stop */ + if (!rrest) + this.matches.add(tp, absolute, true); + else if (!this.hasWalkedCache.hasWalked(tp, rrest)) { + this.subwalks.add(tp, rrest); + } + } + } + } + else if (p instanceof RegExp) { + this.subwalks.add(t, pattern); + } + } + return this; + } + subwalkTargets() { + return this.subwalks.keys(); + } + child() { + return new Processor(this.opts, this.hasWalkedCache); + } + // return a new Processor containing the subwalks for each + // child entry, and a set of matches, and + // a hasWalkedCache that's a copy of this one + // then we're going to call + filterEntries(parent, entries) { + const patterns = this.subwalks.get(parent); + // put matches and entry walks into the results processor + const results = this.child(); + for (const e of entries) { + for (const pattern of patterns) { + const absolute = pattern.isAbsolute(); + const p = pattern.pattern(); + const rest = pattern.rest(); + if (p === minimatch_1.GLOBSTAR) { + results.testGlobstar(e, pattern, rest, absolute); + } + else if (p instanceof RegExp) { + results.testRegExp(e, p, rest, absolute); + } + else { + results.testString(e, p, rest, absolute); + } + } + } + return results; + } + testGlobstar(e, pattern, rest, absolute) { + if (this.dot || !e.name.startsWith('.')) { + if (!pattern.hasMore()) { + this.matches.add(e, absolute, false); + } + if (e.canReaddir()) { + // if we're in follow mode or it's not a symlink, just keep + // testing the same pattern. If there's more after the globstar, + // then this symlink consumes the globstar. If not, then we can + // follow at most ONE symlink along the way, so we mark it, which + // also checks to ensure that it wasn't already marked. + if (this.follow || !e.isSymbolicLink()) { + this.subwalks.add(e, pattern); + } + else if (e.isSymbolicLink()) { + if (rest && pattern.checkFollowGlobstar()) { + this.subwalks.add(e, rest); + } + else if (pattern.markFollowGlobstar()) { + this.subwalks.add(e, pattern); + } + } + } + } + // if the NEXT thing matches this entry, then also add + // the rest. + if (rest) { + const rp = rest.pattern(); + if (typeof rp === 'string' && + // dots and empty were handled already + rp !== '..' && + rp !== '' && + rp !== '.') { + this.testString(e, rp, rest.rest(), absolute); + } + else if (rp === '..') { + /* c8 ignore start */ + const ep = e.parent || e; + /* c8 ignore stop */ + this.subwalks.add(ep, rest); + } + else if (rp instanceof RegExp) { + this.testRegExp(e, rp, rest.rest(), absolute); + } + } + } + testRegExp(e, p, rest, absolute) { + if (!p.test(e.name)) + return; + if (!rest) { + this.matches.add(e, absolute, false); + } + else { + this.subwalks.add(e, rest); + } + } + testString(e, p, rest, absolute) { + // should never happen? + if (!e.isNamed(p)) + return; + if (!rest) { + this.matches.add(e, absolute, false); + } + else { + this.subwalks.add(e, rest); + } + } +} +exports.Processor = Processor; +//# sourceMappingURL=processor.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/commonjs/walker.js b/node_modules/glob/dist/commonjs/walker.js new file mode 100644 index 0000000000000..cb15946d9a852 --- /dev/null +++ b/node_modules/glob/dist/commonjs/walker.js @@ -0,0 +1,387 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GlobStream = exports.GlobWalker = exports.GlobUtil = void 0; +/** + * Single-use utility classes to provide functionality to the {@link Glob} + * methods. + * + * @module + */ +const minipass_1 = require("minipass"); +const ignore_js_1 = require("./ignore.js"); +const processor_js_1 = require("./processor.js"); +const makeIgnore = (ignore, opts) => typeof ignore === 'string' ? new ignore_js_1.Ignore([ignore], opts) + : Array.isArray(ignore) ? new ignore_js_1.Ignore(ignore, opts) + : ignore; +/** + * basic walking utilities that all the glob walker types use + */ +class GlobUtil { + path; + patterns; + opts; + seen = new Set(); + paused = false; + aborted = false; + #onResume = []; + #ignore; + #sep; + signal; + maxDepth; + includeChildMatches; + constructor(patterns, path, opts) { + this.patterns = patterns; + this.path = path; + this.opts = opts; + this.#sep = !opts.posix && opts.platform === 'win32' ? '\\' : '/'; + this.includeChildMatches = opts.includeChildMatches !== false; + if (opts.ignore || !this.includeChildMatches) { + this.#ignore = makeIgnore(opts.ignore ?? [], opts); + if (!this.includeChildMatches && + typeof this.#ignore.add !== 'function') { + const m = 'cannot ignore child matches, ignore lacks add() method.'; + throw new Error(m); + } + } + // ignore, always set with maxDepth, but it's optional on the + // GlobOptions type + /* c8 ignore start */ + this.maxDepth = opts.maxDepth || Infinity; + /* c8 ignore stop */ + if (opts.signal) { + this.signal = opts.signal; + this.signal.addEventListener('abort', () => { + this.#onResume.length = 0; + }); + } + } + #ignored(path) { + return this.seen.has(path) || !!this.#ignore?.ignored?.(path); + } + #childrenIgnored(path) { + return !!this.#ignore?.childrenIgnored?.(path); + } + // backpressure mechanism + pause() { + this.paused = true; + } + resume() { + /* c8 ignore start */ + if (this.signal?.aborted) + return; + /* c8 ignore stop */ + this.paused = false; + let fn = undefined; + while (!this.paused && (fn = this.#onResume.shift())) { + fn(); + } + } + onResume(fn) { + if (this.signal?.aborted) + return; + /* c8 ignore start */ + if (!this.paused) { + fn(); + } + else { + /* c8 ignore stop */ + this.#onResume.push(fn); + } + } + // do the requisite realpath/stat checking, and return the path + // to add or undefined to filter it out. + async matchCheck(e, ifDir) { + if (ifDir && this.opts.nodir) + return undefined; + let rpc; + if (this.opts.realpath) { + rpc = e.realpathCached() || (await e.realpath()); + if (!rpc) + return undefined; + e = rpc; + } + const needStat = e.isUnknown() || this.opts.stat; + const s = needStat ? await e.lstat() : e; + if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) { + const target = await s.realpath(); + /* c8 ignore start */ + if (target && (target.isUnknown() || this.opts.stat)) { + await target.lstat(); + } + /* c8 ignore stop */ + } + return this.matchCheckTest(s, ifDir); + } + matchCheckTest(e, ifDir) { + return (e && + (this.maxDepth === Infinity || e.depth() <= this.maxDepth) && + (!ifDir || e.canReaddir()) && + (!this.opts.nodir || !e.isDirectory()) && + (!this.opts.nodir || + !this.opts.follow || + !e.isSymbolicLink() || + !e.realpathCached()?.isDirectory()) && + !this.#ignored(e)) ? + e + : undefined; + } + matchCheckSync(e, ifDir) { + if (ifDir && this.opts.nodir) + return undefined; + let rpc; + if (this.opts.realpath) { + rpc = e.realpathCached() || e.realpathSync(); + if (!rpc) + return undefined; + e = rpc; + } + const needStat = e.isUnknown() || this.opts.stat; + const s = needStat ? e.lstatSync() : e; + if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) { + const target = s.realpathSync(); + if (target && (target?.isUnknown() || this.opts.stat)) { + target.lstatSync(); + } + } + return this.matchCheckTest(s, ifDir); + } + matchFinish(e, absolute) { + if (this.#ignored(e)) + return; + // we know we have an ignore if this is false, but TS doesn't + if (!this.includeChildMatches && this.#ignore?.add) { + const ign = `${e.relativePosix()}/**`; + this.#ignore.add(ign); + } + const abs = this.opts.absolute === undefined ? absolute : this.opts.absolute; + this.seen.add(e); + const mark = this.opts.mark && e.isDirectory() ? this.#sep : ''; + // ok, we have what we need! + if (this.opts.withFileTypes) { + this.matchEmit(e); + } + else if (abs) { + const abs = this.opts.posix ? e.fullpathPosix() : e.fullpath(); + this.matchEmit(abs + mark); + } + else { + const rel = this.opts.posix ? e.relativePosix() : e.relative(); + const pre = this.opts.dotRelative && !rel.startsWith('..' + this.#sep) ? + '.' + this.#sep + : ''; + this.matchEmit(!rel ? '.' + mark : pre + rel + mark); + } + } + async match(e, absolute, ifDir) { + const p = await this.matchCheck(e, ifDir); + if (p) + this.matchFinish(p, absolute); + } + matchSync(e, absolute, ifDir) { + const p = this.matchCheckSync(e, ifDir); + if (p) + this.matchFinish(p, absolute); + } + walkCB(target, patterns, cb) { + /* c8 ignore start */ + if (this.signal?.aborted) + cb(); + /* c8 ignore stop */ + this.walkCB2(target, patterns, new processor_js_1.Processor(this.opts), cb); + } + walkCB2(target, patterns, processor, cb) { + if (this.#childrenIgnored(target)) + return cb(); + if (this.signal?.aborted) + cb(); + if (this.paused) { + this.onResume(() => this.walkCB2(target, patterns, processor, cb)); + return; + } + processor.processPatterns(target, patterns); + // done processing. all of the above is sync, can be abstracted out. + // subwalks is a map of paths to the entry filters they need + // matches is a map of paths to [absolute, ifDir] tuples. + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + tasks++; + this.match(m, absolute, ifDir).then(() => next()); + } + for (const t of processor.subwalkTargets()) { + if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) { + continue; + } + tasks++; + const childrenCached = t.readdirCached(); + if (t.calledReaddir()) + this.walkCB3(t, childrenCached, processor, next); + else { + t.readdirCB((_, entries) => this.walkCB3(t, entries, processor, next), true); + } + } + next(); + } + walkCB3(target, entries, processor, cb) { + processor = processor.filterEntries(target, entries); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + tasks++; + this.match(m, absolute, ifDir).then(() => next()); + } + for (const [target, patterns] of processor.subwalks.entries()) { + tasks++; + this.walkCB2(target, patterns, processor.child(), next); + } + next(); + } + walkCBSync(target, patterns, cb) { + /* c8 ignore start */ + if (this.signal?.aborted) + cb(); + /* c8 ignore stop */ + this.walkCB2Sync(target, patterns, new processor_js_1.Processor(this.opts), cb); + } + walkCB2Sync(target, patterns, processor, cb) { + if (this.#childrenIgnored(target)) + return cb(); + if (this.signal?.aborted) + cb(); + if (this.paused) { + this.onResume(() => this.walkCB2Sync(target, patterns, processor, cb)); + return; + } + processor.processPatterns(target, patterns); + // done processing. all of the above is sync, can be abstracted out. + // subwalks is a map of paths to the entry filters they need + // matches is a map of paths to [absolute, ifDir] tuples. + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + this.matchSync(m, absolute, ifDir); + } + for (const t of processor.subwalkTargets()) { + if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) { + continue; + } + tasks++; + const children = t.readdirSync(); + this.walkCB3Sync(t, children, processor, next); + } + next(); + } + walkCB3Sync(target, entries, processor, cb) { + processor = processor.filterEntries(target, entries); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + this.matchSync(m, absolute, ifDir); + } + for (const [target, patterns] of processor.subwalks.entries()) { + tasks++; + this.walkCB2Sync(target, patterns, processor.child(), next); + } + next(); + } +} +exports.GlobUtil = GlobUtil; +class GlobWalker extends GlobUtil { + matches = new Set(); + constructor(patterns, path, opts) { + super(patterns, path, opts); + } + matchEmit(e) { + this.matches.add(e); + } + async walk() { + if (this.signal?.aborted) + throw this.signal.reason; + if (this.path.isUnknown()) { + await this.path.lstat(); + } + await new Promise((res, rej) => { + this.walkCB(this.path, this.patterns, () => { + if (this.signal?.aborted) { + rej(this.signal.reason); + } + else { + res(this.matches); + } + }); + }); + return this.matches; + } + walkSync() { + if (this.signal?.aborted) + throw this.signal.reason; + if (this.path.isUnknown()) { + this.path.lstatSync(); + } + // nothing for the callback to do, because this never pauses + this.walkCBSync(this.path, this.patterns, () => { + if (this.signal?.aborted) + throw this.signal.reason; + }); + return this.matches; + } +} +exports.GlobWalker = GlobWalker; +class GlobStream extends GlobUtil { + results; + constructor(patterns, path, opts) { + super(patterns, path, opts); + this.results = new minipass_1.Minipass({ + signal: this.signal, + objectMode: true, + }); + this.results.on('drain', () => this.resume()); + this.results.on('resume', () => this.resume()); + } + matchEmit(e) { + this.results.write(e); + if (!this.results.flowing) + this.pause(); + } + stream() { + const target = this.path; + if (target.isUnknown()) { + target.lstat().then(() => { + this.walkCB(target, this.patterns, () => this.results.end()); + }); + } + else { + this.walkCB(target, this.patterns, () => this.results.end()); + } + return this.results; + } + streamSync() { + if (this.path.isUnknown()) { + this.path.lstatSync(); + } + this.walkCBSync(this.path, this.patterns, () => this.results.end()); + return this.results; + } +} +exports.GlobStream = GlobStream; +//# sourceMappingURL=walker.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/glob.js b/node_modules/glob/dist/esm/glob.js new file mode 100644 index 0000000000000..c9ff3b0036d94 --- /dev/null +++ b/node_modules/glob/dist/esm/glob.js @@ -0,0 +1,243 @@ +import { Minimatch } from 'minimatch'; +import { fileURLToPath } from 'node:url'; +import { PathScurry, PathScurryDarwin, PathScurryPosix, PathScurryWin32, } from 'path-scurry'; +import { Pattern } from './pattern.js'; +import { GlobStream, GlobWalker } from './walker.js'; +// if no process global, just call it linux. +// so we default to case-sensitive, / separators +const defaultPlatform = (typeof process === 'object' && + process && + typeof process.platform === 'string') ? + process.platform + : 'linux'; +/** + * An object that can perform glob pattern traversals. + */ +export class Glob { + absolute; + cwd; + root; + dot; + dotRelative; + follow; + ignore; + magicalBraces; + mark; + matchBase; + maxDepth; + nobrace; + nocase; + nodir; + noext; + noglobstar; + pattern; + platform; + realpath; + scurry; + stat; + signal; + windowsPathsNoEscape; + withFileTypes; + includeChildMatches; + /** + * The options provided to the constructor. + */ + opts; + /** + * An array of parsed immutable {@link Pattern} objects. + */ + patterns; + /** + * All options are stored as properties on the `Glob` object. + * + * See {@link GlobOptions} for full options descriptions. + * + * Note that a previous `Glob` object can be passed as the + * `GlobOptions` to another `Glob` instantiation to re-use settings + * and caches with a new pattern. + * + * Traversal functions can be called multiple times to run the walk + * again. + */ + constructor(pattern, opts) { + /* c8 ignore start */ + if (!opts) + throw new TypeError('glob options required'); + /* c8 ignore stop */ + this.withFileTypes = !!opts.withFileTypes; + this.signal = opts.signal; + this.follow = !!opts.follow; + this.dot = !!opts.dot; + this.dotRelative = !!opts.dotRelative; + this.nodir = !!opts.nodir; + this.mark = !!opts.mark; + if (!opts.cwd) { + this.cwd = ''; + } + else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) { + opts.cwd = fileURLToPath(opts.cwd); + } + this.cwd = opts.cwd || ''; + this.root = opts.root; + this.magicalBraces = !!opts.magicalBraces; + this.nobrace = !!opts.nobrace; + this.noext = !!opts.noext; + this.realpath = !!opts.realpath; + this.absolute = opts.absolute; + this.includeChildMatches = opts.includeChildMatches !== false; + this.noglobstar = !!opts.noglobstar; + this.matchBase = !!opts.matchBase; + this.maxDepth = + typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity; + this.stat = !!opts.stat; + this.ignore = opts.ignore; + if (this.withFileTypes && this.absolute !== undefined) { + throw new Error('cannot set absolute and withFileTypes:true'); + } + if (typeof pattern === 'string') { + pattern = [pattern]; + } + this.windowsPathsNoEscape = + !!opts.windowsPathsNoEscape || + opts.allowWindowsEscape === + false; + if (this.windowsPathsNoEscape) { + pattern = pattern.map(p => p.replace(/\\/g, '/')); + } + if (this.matchBase) { + if (opts.noglobstar) { + throw new TypeError('base matching requires globstar'); + } + pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`)); + } + this.pattern = pattern; + this.platform = opts.platform || defaultPlatform; + this.opts = { ...opts, platform: this.platform }; + if (opts.scurry) { + this.scurry = opts.scurry; + if (opts.nocase !== undefined && + opts.nocase !== opts.scurry.nocase) { + throw new Error('nocase option contradicts provided scurry option'); + } + } + else { + const Scurry = opts.platform === 'win32' ? PathScurryWin32 + : opts.platform === 'darwin' ? PathScurryDarwin + : opts.platform ? PathScurryPosix + : PathScurry; + this.scurry = new Scurry(this.cwd, { + nocase: opts.nocase, + fs: opts.fs, + }); + } + this.nocase = this.scurry.nocase; + // If you do nocase:true on a case-sensitive file system, then + // we need to use regexps instead of strings for non-magic + // path portions, because statting `aBc` won't return results + // for the file `AbC` for example. + const nocaseMagicOnly = this.platform === 'darwin' || this.platform === 'win32'; + const mmo = { + // default nocase based on platform + ...opts, + dot: this.dot, + matchBase: this.matchBase, + nobrace: this.nobrace, + nocase: this.nocase, + nocaseMagicOnly, + nocomment: true, + noext: this.noext, + nonegate: true, + optimizationLevel: 2, + platform: this.platform, + windowsPathsNoEscape: this.windowsPathsNoEscape, + debug: !!this.opts.debug, + }; + const mms = this.pattern.map(p => new Minimatch(p, mmo)); + const [matchSet, globParts] = mms.reduce((set, m) => { + set[0].push(...m.set); + set[1].push(...m.globParts); + return set; + }, [[], []]); + this.patterns = matchSet.map((set, i) => { + const g = globParts[i]; + /* c8 ignore start */ + if (!g) + throw new Error('invalid pattern object'); + /* c8 ignore stop */ + return new Pattern(set, g, 0, this.platform); + }); + } + async walk() { + // Walkers always return array of Path objects, so we just have to + // coerce them into the right shape. It will have already called + // realpath() if the option was set to do so, so we know that's cached. + // start out knowing the cwd, at least + return [ + ...(await new GlobWalker(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).walk()), + ]; + } + walkSync() { + return [ + ...new GlobWalker(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).walkSync(), + ]; + } + stream() { + return new GlobStream(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).stream(); + } + streamSync() { + return new GlobStream(this.patterns, this.scurry.cwd, { + ...this.opts, + maxDepth: this.maxDepth !== Infinity ? + this.maxDepth + this.scurry.cwd.depth() + : Infinity, + platform: this.platform, + nocase: this.nocase, + includeChildMatches: this.includeChildMatches, + }).streamSync(); + } + /** + * Default sync iteration function. Returns a Generator that + * iterates over the results. + */ + iterateSync() { + return this.streamSync()[Symbol.iterator](); + } + [Symbol.iterator]() { + return this.iterateSync(); + } + /** + * Default async iteration function. Returns an AsyncGenerator that + * iterates over the results. + */ + iterate() { + return this.stream()[Symbol.asyncIterator](); + } + [Symbol.asyncIterator]() { + return this.iterate(); + } +} +//# sourceMappingURL=glob.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/has-magic.js b/node_modules/glob/dist/esm/has-magic.js new file mode 100644 index 0000000000000..ba2321ab868d0 --- /dev/null +++ b/node_modules/glob/dist/esm/has-magic.js @@ -0,0 +1,23 @@ +import { Minimatch } from 'minimatch'; +/** + * Return true if the patterns provided contain any magic glob characters, + * given the options provided. + * + * Brace expansion is not considered "magic" unless the `magicalBraces` option + * is set, as brace expansion just turns one string into an array of strings. + * So a pattern like `'x{a,b}y'` would return `false`, because `'xay'` and + * `'xby'` both do not contain any magic glob characters, and it's treated the + * same as if you had called it on `['xay', 'xby']`. When `magicalBraces:true` + * is in the options, brace expansion _is_ treated as a pattern having magic. + */ +export const hasMagic = (pattern, options = {}) => { + if (!Array.isArray(pattern)) { + pattern = [pattern]; + } + for (const p of pattern) { + if (new Minimatch(p, options).hasMagic()) + return true; + } + return false; +}; +//# sourceMappingURL=has-magic.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/ignore.js b/node_modules/glob/dist/esm/ignore.js new file mode 100644 index 0000000000000..539c4a4fdebc4 --- /dev/null +++ b/node_modules/glob/dist/esm/ignore.js @@ -0,0 +1,115 @@ +// give it a pattern, and it'll be able to tell you if +// a given path should be ignored. +// Ignoring a path ignores its children if the pattern ends in /** +// Ignores are always parsed in dot:true mode +import { Minimatch } from 'minimatch'; +import { Pattern } from './pattern.js'; +const defaultPlatform = (typeof process === 'object' && + process && + typeof process.platform === 'string') ? + process.platform + : 'linux'; +/** + * Class used to process ignored patterns + */ +export class Ignore { + relative; + relativeChildren; + absolute; + absoluteChildren; + platform; + mmopts; + constructor(ignored, { nobrace, nocase, noext, noglobstar, platform = defaultPlatform, }) { + this.relative = []; + this.absolute = []; + this.relativeChildren = []; + this.absoluteChildren = []; + this.platform = platform; + this.mmopts = { + dot: true, + nobrace, + nocase, + noext, + noglobstar, + optimizationLevel: 2, + platform, + nocomment: true, + nonegate: true, + }; + for (const ign of ignored) + this.add(ign); + } + add(ign) { + // this is a little weird, but it gives us a clean set of optimized + // minimatch matchers, without getting tripped up if one of them + // ends in /** inside a brace section, and it's only inefficient at + // the start of the walk, not along it. + // It'd be nice if the Pattern class just had a .test() method, but + // handling globstars is a bit of a pita, and that code already lives + // in minimatch anyway. + // Another way would be if maybe Minimatch could take its set/globParts + // as an option, and then we could at least just use Pattern to test + // for absolute-ness. + // Yet another way, Minimatch could take an array of glob strings, and + // a cwd option, and do the right thing. + const mm = new Minimatch(ign, this.mmopts); + for (let i = 0; i < mm.set.length; i++) { + const parsed = mm.set[i]; + const globParts = mm.globParts[i]; + /* c8 ignore start */ + if (!parsed || !globParts) { + throw new Error('invalid pattern object'); + } + // strip off leading ./ portions + // https://github.com/isaacs/node-glob/issues/570 + while (parsed[0] === '.' && globParts[0] === '.') { + parsed.shift(); + globParts.shift(); + } + /* c8 ignore stop */ + const p = new Pattern(parsed, globParts, 0, this.platform); + const m = new Minimatch(p.globString(), this.mmopts); + const children = globParts[globParts.length - 1] === '**'; + const absolute = p.isAbsolute(); + if (absolute) + this.absolute.push(m); + else + this.relative.push(m); + if (children) { + if (absolute) + this.absoluteChildren.push(m); + else + this.relativeChildren.push(m); + } + } + } + ignored(p) { + const fullpath = p.fullpath(); + const fullpaths = `${fullpath}/`; + const relative = p.relative() || '.'; + const relatives = `${relative}/`; + for (const m of this.relative) { + if (m.match(relative) || m.match(relatives)) + return true; + } + for (const m of this.absolute) { + if (m.match(fullpath) || m.match(fullpaths)) + return true; + } + return false; + } + childrenIgnored(p) { + const fullpath = p.fullpath() + '/'; + const relative = (p.relative() || '.') + '/'; + for (const m of this.relativeChildren) { + if (m.match(relative)) + return true; + } + for (const m of this.absoluteChildren) { + if (m.match(fullpath)) + return true; + } + return false; + } +} +//# sourceMappingURL=ignore.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/index.js b/node_modules/glob/dist/esm/index.js new file mode 100644 index 0000000000000..e15c1f9c4cb03 --- /dev/null +++ b/node_modules/glob/dist/esm/index.js @@ -0,0 +1,55 @@ +import { escape, unescape } from 'minimatch'; +import { Glob } from './glob.js'; +import { hasMagic } from './has-magic.js'; +export { escape, unescape } from 'minimatch'; +export { Glob } from './glob.js'; +export { hasMagic } from './has-magic.js'; +export { Ignore } from './ignore.js'; +export function globStreamSync(pattern, options = {}) { + return new Glob(pattern, options).streamSync(); +} +export function globStream(pattern, options = {}) { + return new Glob(pattern, options).stream(); +} +export function globSync(pattern, options = {}) { + return new Glob(pattern, options).walkSync(); +} +async function glob_(pattern, options = {}) { + return new Glob(pattern, options).walk(); +} +export function globIterateSync(pattern, options = {}) { + return new Glob(pattern, options).iterateSync(); +} +export function globIterate(pattern, options = {}) { + return new Glob(pattern, options).iterate(); +} +// aliases: glob.sync.stream() glob.stream.sync() glob.sync() etc +export const streamSync = globStreamSync; +export const stream = Object.assign(globStream, { sync: globStreamSync }); +export const iterateSync = globIterateSync; +export const iterate = Object.assign(globIterate, { + sync: globIterateSync, +}); +export const sync = Object.assign(globSync, { + stream: globStreamSync, + iterate: globIterateSync, +}); +export const glob = Object.assign(glob_, { + glob: glob_, + globSync, + sync, + globStream, + stream, + globStreamSync, + streamSync, + globIterate, + iterate, + globIterateSync, + iterateSync, + Glob, + hasMagic, + escape, + unescape, +}); +glob.glob = glob; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/package.json b/node_modules/glob/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/glob/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/glob/dist/esm/pattern.js b/node_modules/glob/dist/esm/pattern.js new file mode 100644 index 0000000000000..b41defa10c6a3 --- /dev/null +++ b/node_modules/glob/dist/esm/pattern.js @@ -0,0 +1,215 @@ +// this is just a very light wrapper around 2 arrays with an offset index +import { GLOBSTAR } from 'minimatch'; +const isPatternList = (pl) => pl.length >= 1; +const isGlobList = (gl) => gl.length >= 1; +/** + * An immutable-ish view on an array of glob parts and their parsed + * results + */ +export class Pattern { + #patternList; + #globList; + #index; + length; + #platform; + #rest; + #globString; + #isDrive; + #isUNC; + #isAbsolute; + #followGlobstar = true; + constructor(patternList, globList, index, platform) { + if (!isPatternList(patternList)) { + throw new TypeError('empty pattern list'); + } + if (!isGlobList(globList)) { + throw new TypeError('empty glob list'); + } + if (globList.length !== patternList.length) { + throw new TypeError('mismatched pattern list and glob list lengths'); + } + this.length = patternList.length; + if (index < 0 || index >= this.length) { + throw new TypeError('index out of range'); + } + this.#patternList = patternList; + this.#globList = globList; + this.#index = index; + this.#platform = platform; + // normalize root entries of absolute patterns on initial creation. + if (this.#index === 0) { + // c: => ['c:/'] + // C:/ => ['C:/'] + // C:/x => ['C:/', 'x'] + // //host/share => ['//host/share/'] + // //host/share/ => ['//host/share/'] + // //host/share/x => ['//host/share/', 'x'] + // /etc => ['/', 'etc'] + // / => ['/'] + if (this.isUNC()) { + // '' / '' / 'host' / 'share' + const [p0, p1, p2, p3, ...prest] = this.#patternList; + const [g0, g1, g2, g3, ...grest] = this.#globList; + if (prest[0] === '') { + // ends in / + prest.shift(); + grest.shift(); + } + const p = [p0, p1, p2, p3, ''].join('/'); + const g = [g0, g1, g2, g3, ''].join('/'); + this.#patternList = [p, ...prest]; + this.#globList = [g, ...grest]; + this.length = this.#patternList.length; + } + else if (this.isDrive() || this.isAbsolute()) { + const [p1, ...prest] = this.#patternList; + const [g1, ...grest] = this.#globList; + if (prest[0] === '') { + // ends in / + prest.shift(); + grest.shift(); + } + const p = p1 + '/'; + const g = g1 + '/'; + this.#patternList = [p, ...prest]; + this.#globList = [g, ...grest]; + this.length = this.#patternList.length; + } + } + } + /** + * The first entry in the parsed list of patterns + */ + pattern() { + return this.#patternList[this.#index]; + } + /** + * true of if pattern() returns a string + */ + isString() { + return typeof this.#patternList[this.#index] === 'string'; + } + /** + * true of if pattern() returns GLOBSTAR + */ + isGlobstar() { + return this.#patternList[this.#index] === GLOBSTAR; + } + /** + * true if pattern() returns a regexp + */ + isRegExp() { + return this.#patternList[this.#index] instanceof RegExp; + } + /** + * The /-joined set of glob parts that make up this pattern + */ + globString() { + return (this.#globString = + this.#globString || + (this.#index === 0 ? + this.isAbsolute() ? + this.#globList[0] + this.#globList.slice(1).join('/') + : this.#globList.join('/') + : this.#globList.slice(this.#index).join('/'))); + } + /** + * true if there are more pattern parts after this one + */ + hasMore() { + return this.length > this.#index + 1; + } + /** + * The rest of the pattern after this part, or null if this is the end + */ + rest() { + if (this.#rest !== undefined) + return this.#rest; + if (!this.hasMore()) + return (this.#rest = null); + this.#rest = new Pattern(this.#patternList, this.#globList, this.#index + 1, this.#platform); + this.#rest.#isAbsolute = this.#isAbsolute; + this.#rest.#isUNC = this.#isUNC; + this.#rest.#isDrive = this.#isDrive; + return this.#rest; + } + /** + * true if the pattern represents a //unc/path/ on windows + */ + isUNC() { + const pl = this.#patternList; + return this.#isUNC !== undefined ? + this.#isUNC + : (this.#isUNC = + this.#platform === 'win32' && + this.#index === 0 && + pl[0] === '' && + pl[1] === '' && + typeof pl[2] === 'string' && + !!pl[2] && + typeof pl[3] === 'string' && + !!pl[3]); + } + // pattern like C:/... + // split = ['C:', ...] + // XXX: would be nice to handle patterns like `c:*` to test the cwd + // in c: for *, but I don't know of a way to even figure out what that + // cwd is without actually chdir'ing into it? + /** + * True if the pattern starts with a drive letter on Windows + */ + isDrive() { + const pl = this.#patternList; + return this.#isDrive !== undefined ? + this.#isDrive + : (this.#isDrive = + this.#platform === 'win32' && + this.#index === 0 && + this.length > 1 && + typeof pl[0] === 'string' && + /^[a-z]:$/i.test(pl[0])); + } + // pattern = '/' or '/...' or '/x/...' + // split = ['', ''] or ['', ...] or ['', 'x', ...] + // Drive and UNC both considered absolute on windows + /** + * True if the pattern is rooted on an absolute path + */ + isAbsolute() { + const pl = this.#patternList; + return this.#isAbsolute !== undefined ? + this.#isAbsolute + : (this.#isAbsolute = + (pl[0] === '' && pl.length > 1) || + this.isDrive() || + this.isUNC()); + } + /** + * consume the root of the pattern, and return it + */ + root() { + const p = this.#patternList[0]; + return (typeof p === 'string' && this.isAbsolute() && this.#index === 0) ? + p + : ''; + } + /** + * Check to see if the current globstar pattern is allowed to follow + * a symbolic link. + */ + checkFollowGlobstar() { + return !(this.#index === 0 || + !this.isGlobstar() || + !this.#followGlobstar); + } + /** + * Mark that the current globstar pattern is following a symbolic link + */ + markFollowGlobstar() { + if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar) + return false; + this.#followGlobstar = false; + return true; + } +} +//# sourceMappingURL=pattern.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/processor.js b/node_modules/glob/dist/esm/processor.js new file mode 100644 index 0000000000000..f874892ffed0c --- /dev/null +++ b/node_modules/glob/dist/esm/processor.js @@ -0,0 +1,294 @@ +// synchronous utility for filtering entries and calculating subwalks +import { GLOBSTAR } from 'minimatch'; +/** + * A cache of which patterns have been processed for a given Path + */ +export class HasWalkedCache { + store; + constructor(store = new Map()) { + this.store = store; + } + copy() { + return new HasWalkedCache(new Map(this.store)); + } + hasWalked(target, pattern) { + return this.store.get(target.fullpath())?.has(pattern.globString()); + } + storeWalked(target, pattern) { + const fullpath = target.fullpath(); + const cached = this.store.get(fullpath); + if (cached) + cached.add(pattern.globString()); + else + this.store.set(fullpath, new Set([pattern.globString()])); + } +} +/** + * A record of which paths have been matched in a given walk step, + * and whether they only are considered a match if they are a directory, + * and whether their absolute or relative path should be returned. + */ +export class MatchRecord { + store = new Map(); + add(target, absolute, ifDir) { + const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0); + const current = this.store.get(target); + this.store.set(target, current === undefined ? n : n & current); + } + // match, absolute, ifdir + entries() { + return [...this.store.entries()].map(([path, n]) => [ + path, + !!(n & 2), + !!(n & 1), + ]); + } +} +/** + * A collection of patterns that must be processed in a subsequent step + * for a given path. + */ +export class SubWalks { + store = new Map(); + add(target, pattern) { + if (!target.canReaddir()) { + return; + } + const subs = this.store.get(target); + if (subs) { + if (!subs.find(p => p.globString() === pattern.globString())) { + subs.push(pattern); + } + } + else + this.store.set(target, [pattern]); + } + get(target) { + const subs = this.store.get(target); + /* c8 ignore start */ + if (!subs) { + throw new Error('attempting to walk unknown path'); + } + /* c8 ignore stop */ + return subs; + } + entries() { + return this.keys().map(k => [k, this.store.get(k)]); + } + keys() { + return [...this.store.keys()].filter(t => t.canReaddir()); + } +} +/** + * The class that processes patterns for a given path. + * + * Handles child entry filtering, and determining whether a path's + * directory contents must be read. + */ +export class Processor { + hasWalkedCache; + matches = new MatchRecord(); + subwalks = new SubWalks(); + patterns; + follow; + dot; + opts; + constructor(opts, hasWalkedCache) { + this.opts = opts; + this.follow = !!opts.follow; + this.dot = !!opts.dot; + this.hasWalkedCache = + hasWalkedCache ? hasWalkedCache.copy() : new HasWalkedCache(); + } + processPatterns(target, patterns) { + this.patterns = patterns; + const processingSet = patterns.map(p => [target, p]); + // map of paths to the magic-starting subwalks they need to walk + // first item in patterns is the filter + for (let [t, pattern] of processingSet) { + this.hasWalkedCache.storeWalked(t, pattern); + const root = pattern.root(); + const absolute = pattern.isAbsolute() && this.opts.absolute !== false; + // start absolute patterns at root + if (root) { + t = t.resolve(root === '/' && this.opts.root !== undefined ? + this.opts.root + : root); + const rest = pattern.rest(); + if (!rest) { + this.matches.add(t, true, false); + continue; + } + else { + pattern = rest; + } + } + if (t.isENOENT()) + continue; + let p; + let rest; + let changed = false; + while (typeof (p = pattern.pattern()) === 'string' && + (rest = pattern.rest())) { + const c = t.resolve(p); + t = c; + pattern = rest; + changed = true; + } + p = pattern.pattern(); + rest = pattern.rest(); + if (changed) { + if (this.hasWalkedCache.hasWalked(t, pattern)) + continue; + this.hasWalkedCache.storeWalked(t, pattern); + } + // now we have either a final string for a known entry, + // more strings for an unknown entry, + // or a pattern starting with magic, mounted on t. + if (typeof p === 'string') { + // must not be final entry, otherwise we would have + // concatenated it earlier. + const ifDir = p === '..' || p === '' || p === '.'; + this.matches.add(t.resolve(p), absolute, ifDir); + continue; + } + else if (p === GLOBSTAR) { + // if no rest, match and subwalk pattern + // if rest, process rest and subwalk pattern + // if it's a symlink, but we didn't get here by way of a + // globstar match (meaning it's the first time THIS globstar + // has traversed a symlink), then we follow it. Otherwise, stop. + if (!t.isSymbolicLink() || + this.follow || + pattern.checkFollowGlobstar()) { + this.subwalks.add(t, pattern); + } + const rp = rest?.pattern(); + const rrest = rest?.rest(); + if (!rest || ((rp === '' || rp === '.') && !rrest)) { + // only HAS to be a dir if it ends in **/ or **/. + // but ending in ** will match files as well. + this.matches.add(t, absolute, rp === '' || rp === '.'); + } + else { + if (rp === '..') { + // this would mean you're matching **/.. at the fs root, + // and no thanks, I'm not gonna test that specific case. + /* c8 ignore start */ + const tp = t.parent || t; + /* c8 ignore stop */ + if (!rrest) + this.matches.add(tp, absolute, true); + else if (!this.hasWalkedCache.hasWalked(tp, rrest)) { + this.subwalks.add(tp, rrest); + } + } + } + } + else if (p instanceof RegExp) { + this.subwalks.add(t, pattern); + } + } + return this; + } + subwalkTargets() { + return this.subwalks.keys(); + } + child() { + return new Processor(this.opts, this.hasWalkedCache); + } + // return a new Processor containing the subwalks for each + // child entry, and a set of matches, and + // a hasWalkedCache that's a copy of this one + // then we're going to call + filterEntries(parent, entries) { + const patterns = this.subwalks.get(parent); + // put matches and entry walks into the results processor + const results = this.child(); + for (const e of entries) { + for (const pattern of patterns) { + const absolute = pattern.isAbsolute(); + const p = pattern.pattern(); + const rest = pattern.rest(); + if (p === GLOBSTAR) { + results.testGlobstar(e, pattern, rest, absolute); + } + else if (p instanceof RegExp) { + results.testRegExp(e, p, rest, absolute); + } + else { + results.testString(e, p, rest, absolute); + } + } + } + return results; + } + testGlobstar(e, pattern, rest, absolute) { + if (this.dot || !e.name.startsWith('.')) { + if (!pattern.hasMore()) { + this.matches.add(e, absolute, false); + } + if (e.canReaddir()) { + // if we're in follow mode or it's not a symlink, just keep + // testing the same pattern. If there's more after the globstar, + // then this symlink consumes the globstar. If not, then we can + // follow at most ONE symlink along the way, so we mark it, which + // also checks to ensure that it wasn't already marked. + if (this.follow || !e.isSymbolicLink()) { + this.subwalks.add(e, pattern); + } + else if (e.isSymbolicLink()) { + if (rest && pattern.checkFollowGlobstar()) { + this.subwalks.add(e, rest); + } + else if (pattern.markFollowGlobstar()) { + this.subwalks.add(e, pattern); + } + } + } + } + // if the NEXT thing matches this entry, then also add + // the rest. + if (rest) { + const rp = rest.pattern(); + if (typeof rp === 'string' && + // dots and empty were handled already + rp !== '..' && + rp !== '' && + rp !== '.') { + this.testString(e, rp, rest.rest(), absolute); + } + else if (rp === '..') { + /* c8 ignore start */ + const ep = e.parent || e; + /* c8 ignore stop */ + this.subwalks.add(ep, rest); + } + else if (rp instanceof RegExp) { + this.testRegExp(e, rp, rest.rest(), absolute); + } + } + } + testRegExp(e, p, rest, absolute) { + if (!p.test(e.name)) + return; + if (!rest) { + this.matches.add(e, absolute, false); + } + else { + this.subwalks.add(e, rest); + } + } + testString(e, p, rest, absolute) { + // should never happen? + if (!e.isNamed(p)) + return; + if (!rest) { + this.matches.add(e, absolute, false); + } + else { + this.subwalks.add(e, rest); + } + } +} +//# sourceMappingURL=processor.js.map \ No newline at end of file diff --git a/node_modules/glob/dist/esm/walker.js b/node_modules/glob/dist/esm/walker.js new file mode 100644 index 0000000000000..3d68196c4f175 --- /dev/null +++ b/node_modules/glob/dist/esm/walker.js @@ -0,0 +1,381 @@ +/** + * Single-use utility classes to provide functionality to the {@link Glob} + * methods. + * + * @module + */ +import { Minipass } from 'minipass'; +import { Ignore } from './ignore.js'; +import { Processor } from './processor.js'; +const makeIgnore = (ignore, opts) => typeof ignore === 'string' ? new Ignore([ignore], opts) + : Array.isArray(ignore) ? new Ignore(ignore, opts) + : ignore; +/** + * basic walking utilities that all the glob walker types use + */ +export class GlobUtil { + path; + patterns; + opts; + seen = new Set(); + paused = false; + aborted = false; + #onResume = []; + #ignore; + #sep; + signal; + maxDepth; + includeChildMatches; + constructor(patterns, path, opts) { + this.patterns = patterns; + this.path = path; + this.opts = opts; + this.#sep = !opts.posix && opts.platform === 'win32' ? '\\' : '/'; + this.includeChildMatches = opts.includeChildMatches !== false; + if (opts.ignore || !this.includeChildMatches) { + this.#ignore = makeIgnore(opts.ignore ?? [], opts); + if (!this.includeChildMatches && + typeof this.#ignore.add !== 'function') { + const m = 'cannot ignore child matches, ignore lacks add() method.'; + throw new Error(m); + } + } + // ignore, always set with maxDepth, but it's optional on the + // GlobOptions type + /* c8 ignore start */ + this.maxDepth = opts.maxDepth || Infinity; + /* c8 ignore stop */ + if (opts.signal) { + this.signal = opts.signal; + this.signal.addEventListener('abort', () => { + this.#onResume.length = 0; + }); + } + } + #ignored(path) { + return this.seen.has(path) || !!this.#ignore?.ignored?.(path); + } + #childrenIgnored(path) { + return !!this.#ignore?.childrenIgnored?.(path); + } + // backpressure mechanism + pause() { + this.paused = true; + } + resume() { + /* c8 ignore start */ + if (this.signal?.aborted) + return; + /* c8 ignore stop */ + this.paused = false; + let fn = undefined; + while (!this.paused && (fn = this.#onResume.shift())) { + fn(); + } + } + onResume(fn) { + if (this.signal?.aborted) + return; + /* c8 ignore start */ + if (!this.paused) { + fn(); + } + else { + /* c8 ignore stop */ + this.#onResume.push(fn); + } + } + // do the requisite realpath/stat checking, and return the path + // to add or undefined to filter it out. + async matchCheck(e, ifDir) { + if (ifDir && this.opts.nodir) + return undefined; + let rpc; + if (this.opts.realpath) { + rpc = e.realpathCached() || (await e.realpath()); + if (!rpc) + return undefined; + e = rpc; + } + const needStat = e.isUnknown() || this.opts.stat; + const s = needStat ? await e.lstat() : e; + if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) { + const target = await s.realpath(); + /* c8 ignore start */ + if (target && (target.isUnknown() || this.opts.stat)) { + await target.lstat(); + } + /* c8 ignore stop */ + } + return this.matchCheckTest(s, ifDir); + } + matchCheckTest(e, ifDir) { + return (e && + (this.maxDepth === Infinity || e.depth() <= this.maxDepth) && + (!ifDir || e.canReaddir()) && + (!this.opts.nodir || !e.isDirectory()) && + (!this.opts.nodir || + !this.opts.follow || + !e.isSymbolicLink() || + !e.realpathCached()?.isDirectory()) && + !this.#ignored(e)) ? + e + : undefined; + } + matchCheckSync(e, ifDir) { + if (ifDir && this.opts.nodir) + return undefined; + let rpc; + if (this.opts.realpath) { + rpc = e.realpathCached() || e.realpathSync(); + if (!rpc) + return undefined; + e = rpc; + } + const needStat = e.isUnknown() || this.opts.stat; + const s = needStat ? e.lstatSync() : e; + if (this.opts.follow && this.opts.nodir && s?.isSymbolicLink()) { + const target = s.realpathSync(); + if (target && (target?.isUnknown() || this.opts.stat)) { + target.lstatSync(); + } + } + return this.matchCheckTest(s, ifDir); + } + matchFinish(e, absolute) { + if (this.#ignored(e)) + return; + // we know we have an ignore if this is false, but TS doesn't + if (!this.includeChildMatches && this.#ignore?.add) { + const ign = `${e.relativePosix()}/**`; + this.#ignore.add(ign); + } + const abs = this.opts.absolute === undefined ? absolute : this.opts.absolute; + this.seen.add(e); + const mark = this.opts.mark && e.isDirectory() ? this.#sep : ''; + // ok, we have what we need! + if (this.opts.withFileTypes) { + this.matchEmit(e); + } + else if (abs) { + const abs = this.opts.posix ? e.fullpathPosix() : e.fullpath(); + this.matchEmit(abs + mark); + } + else { + const rel = this.opts.posix ? e.relativePosix() : e.relative(); + const pre = this.opts.dotRelative && !rel.startsWith('..' + this.#sep) ? + '.' + this.#sep + : ''; + this.matchEmit(!rel ? '.' + mark : pre + rel + mark); + } + } + async match(e, absolute, ifDir) { + const p = await this.matchCheck(e, ifDir); + if (p) + this.matchFinish(p, absolute); + } + matchSync(e, absolute, ifDir) { + const p = this.matchCheckSync(e, ifDir); + if (p) + this.matchFinish(p, absolute); + } + walkCB(target, patterns, cb) { + /* c8 ignore start */ + if (this.signal?.aborted) + cb(); + /* c8 ignore stop */ + this.walkCB2(target, patterns, new Processor(this.opts), cb); + } + walkCB2(target, patterns, processor, cb) { + if (this.#childrenIgnored(target)) + return cb(); + if (this.signal?.aborted) + cb(); + if (this.paused) { + this.onResume(() => this.walkCB2(target, patterns, processor, cb)); + return; + } + processor.processPatterns(target, patterns); + // done processing. all of the above is sync, can be abstracted out. + // subwalks is a map of paths to the entry filters they need + // matches is a map of paths to [absolute, ifDir] tuples. + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + tasks++; + this.match(m, absolute, ifDir).then(() => next()); + } + for (const t of processor.subwalkTargets()) { + if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) { + continue; + } + tasks++; + const childrenCached = t.readdirCached(); + if (t.calledReaddir()) + this.walkCB3(t, childrenCached, processor, next); + else { + t.readdirCB((_, entries) => this.walkCB3(t, entries, processor, next), true); + } + } + next(); + } + walkCB3(target, entries, processor, cb) { + processor = processor.filterEntries(target, entries); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + tasks++; + this.match(m, absolute, ifDir).then(() => next()); + } + for (const [target, patterns] of processor.subwalks.entries()) { + tasks++; + this.walkCB2(target, patterns, processor.child(), next); + } + next(); + } + walkCBSync(target, patterns, cb) { + /* c8 ignore start */ + if (this.signal?.aborted) + cb(); + /* c8 ignore stop */ + this.walkCB2Sync(target, patterns, new Processor(this.opts), cb); + } + walkCB2Sync(target, patterns, processor, cb) { + if (this.#childrenIgnored(target)) + return cb(); + if (this.signal?.aborted) + cb(); + if (this.paused) { + this.onResume(() => this.walkCB2Sync(target, patterns, processor, cb)); + return; + } + processor.processPatterns(target, patterns); + // done processing. all of the above is sync, can be abstracted out. + // subwalks is a map of paths to the entry filters they need + // matches is a map of paths to [absolute, ifDir] tuples. + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + this.matchSync(m, absolute, ifDir); + } + for (const t of processor.subwalkTargets()) { + if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) { + continue; + } + tasks++; + const children = t.readdirSync(); + this.walkCB3Sync(t, children, processor, next); + } + next(); + } + walkCB3Sync(target, entries, processor, cb) { + processor = processor.filterEntries(target, entries); + let tasks = 1; + const next = () => { + if (--tasks === 0) + cb(); + }; + for (const [m, absolute, ifDir] of processor.matches.entries()) { + if (this.#ignored(m)) + continue; + this.matchSync(m, absolute, ifDir); + } + for (const [target, patterns] of processor.subwalks.entries()) { + tasks++; + this.walkCB2Sync(target, patterns, processor.child(), next); + } + next(); + } +} +export class GlobWalker extends GlobUtil { + matches = new Set(); + constructor(patterns, path, opts) { + super(patterns, path, opts); + } + matchEmit(e) { + this.matches.add(e); + } + async walk() { + if (this.signal?.aborted) + throw this.signal.reason; + if (this.path.isUnknown()) { + await this.path.lstat(); + } + await new Promise((res, rej) => { + this.walkCB(this.path, this.patterns, () => { + if (this.signal?.aborted) { + rej(this.signal.reason); + } + else { + res(this.matches); + } + }); + }); + return this.matches; + } + walkSync() { + if (this.signal?.aborted) + throw this.signal.reason; + if (this.path.isUnknown()) { + this.path.lstatSync(); + } + // nothing for the callback to do, because this never pauses + this.walkCBSync(this.path, this.patterns, () => { + if (this.signal?.aborted) + throw this.signal.reason; + }); + return this.matches; + } +} +export class GlobStream extends GlobUtil { + results; + constructor(patterns, path, opts) { + super(patterns, path, opts); + this.results = new Minipass({ + signal: this.signal, + objectMode: true, + }); + this.results.on('drain', () => this.resume()); + this.results.on('resume', () => this.resume()); + } + matchEmit(e) { + this.results.write(e); + if (!this.results.flowing) + this.pause(); + } + stream() { + const target = this.path; + if (target.isUnknown()) { + target.lstat().then(() => { + this.walkCB(target, this.patterns, () => this.results.end()); + }); + } + else { + this.walkCB(target, this.patterns, () => this.results.end()); + } + return this.results; + } + streamSync() { + if (this.path.isUnknown()) { + this.path.lstatSync(); + } + this.walkCBSync(this.path, this.patterns, () => this.results.end()); + return this.results; + } +} +//# sourceMappingURL=walker.js.map \ No newline at end of file diff --git a/node_modules/glob/glob.js b/node_modules/glob/glob.js deleted file mode 100644 index 2112a957dc501..0000000000000 --- a/node_modules/glob/glob.js +++ /dev/null @@ -1,790 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path').isAbsolute -var globSync = require('./sync.js') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {<filename>: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) - e = abs - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - self.fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - self.fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - self.fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return self.fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -} diff --git a/node_modules/glob/package.json b/node_modules/glob/package.json index 5134253e32226..b99bb5fb38f8f 100644 --- a/node_modules/glob/package.json +++ b/node_modules/glob/package.json @@ -1,55 +1,81 @@ { - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "Isaac Z. Schlueter <i@izs.me> (https://blog.izs.me/)", "name": "glob", - "description": "a little globber", - "version": "8.0.3", + "description": "the most correct and second fastest glob implementation in JavaScript", + "version": "13.0.1", + "type": "module", + "tshy": { + "main": true, + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, "repository": { "type": "git", - "url": "git://github.com/isaacs/node-glob.git" + "url": "git@github.com:isaacs/node-glob.git" }, - "main": "glob.js", "files": [ - "glob.js", - "sync.js", - "common.js" + "dist" ], - "engines": { - "node": ">=12" + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "npm run benchclean; git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --log-level warn", + "typedoc": "typedoc", + "profclean": "rm -f v8.log profile.txt", + "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.ts", + "prebench": "npm run prepare", + "bench": "bash benchmark.sh", + "preprof": "npm run prepare", + "prof": "bash prof.sh", + "benchclean": "node benchclean.cjs" }, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^10.1.2", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" }, "devDependencies": { - "memfs": "^3.2.0", - "mkdirp": "0", - "rimraf": "^2.2.8", - "tap": "^16.0.1", - "tick": "0.0.6" + "@types/node": "^24.10.0", + "memfs": "^4.50.0", + "mkdirp": "^3.0.1", + "prettier": "^3.6.2", + "rimraf": "^6.1.0", + "tap": "^21.1.3", + "tshy": "^3.0.3", + "typedoc": "^0.28.14" }, "tap": { - "before": "test/00-setup.js", - "after": "test/zz-cleanup.js", - "statements": 90, - "branches": 90, - "functions": 90, - "lines": 90, - "jobs": 1 + "before": "test/00-setup.ts" }, - "scripts": { - "prepublish": "npm run benchclean", - "profclean": "rm -f v8.log profile.txt", - "test": "tap", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", - "bench": "bash benchmark.sh", - "prof": "bash prof.sh && cat profile.txt", - "benchclean": "node benchclean.js" - }, - "license": "ISC", + "license": "BlueOak-1.0.0", "funding": { "url": "https://github.com/sponsors/isaacs" - } + }, + "engines": { + "node": "20 || >=22" + }, + "module": "./dist/esm/index.js" } diff --git a/node_modules/glob/sync.js b/node_modules/glob/sync.js deleted file mode 100644 index af4600dd59508..0000000000000 --- a/node_modules/glob/sync.js +++ /dev/null @@ -1,486 +0,0 @@ -module.exports = globSync -globSync.GlobSync = GlobSync - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path').isAbsolute -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert.ok(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert.ok(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) { - e = abs - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, this.fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = this.fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} diff --git a/node_modules/graceful-fs/package.json b/node_modules/graceful-fs/package.json index 305785687247c..87babf0248563 100644 --- a/node_modules/graceful-fs/package.json +++ b/node_modules/graceful-fs/package.json @@ -1,7 +1,7 @@ { "name": "graceful-fs", "description": "A drop-in replacement for fs, making various improvements.", - "version": "4.2.10", + "version": "4.2.11", "repository": { "type": "git", "url": "https://github.com/isaacs/node-graceful-fs" @@ -38,7 +38,7 @@ "import-fresh": "^2.0.0", "mkdirp": "^0.5.0", "rimraf": "^2.2.8", - "tap": "^12.7.0" + "tap": "^16.3.4" }, "files": [ "fs.js", @@ -46,5 +46,8 @@ "legacy-streams.js", "polyfills.js", "clone.js" - ] + ], + "tap": { + "reporter": "classic" + } } diff --git a/node_modules/graceful-fs/polyfills.js b/node_modules/graceful-fs/polyfills.js index 46dea36cc490f..453f1a9e702d1 100644 --- a/node_modules/graceful-fs/polyfills.js +++ b/node_modules/graceful-fs/polyfills.js @@ -101,7 +101,7 @@ function patch (fs) { var backoff = 0; fs$rename(from, to, function CB (er) { if (er - && (er.code === "EACCES" || er.code === "EPERM") + && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 60000) { setTimeout(function() { fs.stat(to, function (stater, st) { diff --git a/node_modules/has-flag/index.d.ts b/node_modules/has-flag/index.d.ts deleted file mode 100644 index a0a48c8911278..0000000000000 --- a/node_modules/has-flag/index.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** -Check if [`argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv) has a specific flag. - -@param flag - CLI flag to look for. The `--` prefix is optional. -@param argv - CLI arguments. Default: `process.argv`. -@returns Whether the flag exists. - -@example -``` -// $ ts-node foo.ts -f --unicorn --foo=bar -- --rainbow - -// foo.ts -import hasFlag = require('has-flag'); - -hasFlag('unicorn'); -//=> true - -hasFlag('--unicorn'); -//=> true - -hasFlag('f'); -//=> true - -hasFlag('-f'); -//=> true - -hasFlag('foo=bar'); -//=> true - -hasFlag('foo'); -//=> false - -hasFlag('rainbow'); -//=> false -``` -*/ -declare function hasFlag(flag: string, argv?: string[]): boolean; - -export = hasFlag; diff --git a/node_modules/has-flag/index.js b/node_modules/has-flag/index.js deleted file mode 100644 index b6f80b1f8ffd7..0000000000000 --- a/node_modules/has-flag/index.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -module.exports = (flag, argv = process.argv) => { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -}; diff --git a/node_modules/has-flag/license b/node_modules/has-flag/license deleted file mode 100644 index e7af2f77107d7..0000000000000 --- a/node_modules/has-flag/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/has-flag/package.json b/node_modules/has-flag/package.json deleted file mode 100644 index a9cba4b856d04..0000000000000 --- a/node_modules/has-flag/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "has-flag", - "version": "4.0.0", - "description": "Check if argv has a specific flag", - "license": "MIT", - "repository": "sindresorhus/has-flag", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "has", - "check", - "detect", - "contains", - "find", - "flag", - "cli", - "command-line", - "argv", - "process", - "arg", - "args", - "argument", - "arguments", - "getopt", - "minimist", - "optimist" - ], - "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" - } -} diff --git a/node_modules/has-flag/readme.md b/node_modules/has-flag/readme.md deleted file mode 100644 index 3f72dff29a696..0000000000000 --- a/node_modules/has-flag/readme.md +++ /dev/null @@ -1,89 +0,0 @@ -# has-flag [![Build Status](https://travis-ci.org/sindresorhus/has-flag.svg?branch=master)](https://travis-ci.org/sindresorhus/has-flag) - -> Check if [`argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv) has a specific flag - -Correctly stops looking after an `--` argument terminator. - ---- - -<div align="center"> - <b> - <a href="https://tidelift.com/subscription/pkg/npm-has-flag?utm_source=npm-has-flag&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> - </b> - <br> - <sub> - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. - </sub> -</div> - ---- - - -## Install - -``` -$ npm install has-flag -``` - - -## Usage - -```js -// foo.js -const hasFlag = require('has-flag'); - -hasFlag('unicorn'); -//=> true - -hasFlag('--unicorn'); -//=> true - -hasFlag('f'); -//=> true - -hasFlag('-f'); -//=> true - -hasFlag('foo=bar'); -//=> true - -hasFlag('foo'); -//=> false - -hasFlag('rainbow'); -//=> false -``` - -``` -$ node foo.js -f --unicorn --foo=bar -- --rainbow -``` - - -## API - -### hasFlag(flag, [argv]) - -Returns a boolean for whether the flag exists. - -#### flag - -Type: `string` - -CLI flag to look for. The `--` prefix is optional. - -#### argv - -Type: `string[]`<br> -Default: `process.argv` - -CLI arguments. - - -## Security - -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/has-unicode/LICENSE b/node_modules/has-unicode/LICENSE deleted file mode 100644 index d42e25e95655b..0000000000000 --- a/node_modules/has-unicode/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2014, Rebecca Turner <me@re-becca.org> - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/node_modules/has-unicode/index.js b/node_modules/has-unicode/index.js deleted file mode 100644 index 9b0fe44540131..0000000000000 --- a/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/node_modules/has-unicode/package.json b/node_modules/has-unicode/package.json deleted file mode 100644 index ebe9d76d62158..0000000000000 --- a/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 <me@re-becca.org>", - "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/node_modules/has/LICENSE-MIT b/node_modules/has/LICENSE-MIT deleted file mode 100644 index ae7014d385df3..0000000000000 --- a/node_modules/has/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 Thiago de Arruda - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/has/package.json b/node_modules/has/package.json deleted file mode 100644 index 7c4592f16de07..0000000000000 --- a/node_modules/has/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "has", - "description": "Object.prototype.hasOwnProperty.call shortcut", - "version": "1.0.3", - "homepage": "https://github.com/tarruda/has", - "author": { - "name": "Thiago de Arruda", - "email": "tpadilha84@gmail.com" - }, - "contributors": [ - { - "name": "Jordan Harband", - "email": "ljharb@gmail.com", - "url": "http://ljharb.codes" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/tarruda/has.git" - }, - "bugs": { - "url": "https://github.com/tarruda/has/issues" - }, - "license": "MIT", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/tarruda/has/blob/master/LICENSE-MIT" - } - ], - "main": "./src", - "dependencies": { - "function-bind": "^1.1.1" - }, - "devDependencies": { - "@ljharb/eslint-config": "^12.2.1", - "eslint": "^4.19.1", - "tape": "^4.9.0" - }, - "engines": { - "node": ">= 0.4.0" - }, - "scripts": { - "lint": "eslint .", - "pretest": "npm run lint", - "test": "tape test" - } -} diff --git a/node_modules/has/src/index.js b/node_modules/has/src/index.js deleted file mode 100644 index dd92dd9094edb..0000000000000 --- a/node_modules/has/src/index.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -var bind = require('function-bind'); - -module.exports = bind.call(Function.call, Object.prototype.hasOwnProperty); diff --git a/node_modules/has/test/index.js b/node_modules/has/test/index.js deleted file mode 100644 index 43d480b2c2e76..0000000000000 --- a/node_modules/has/test/index.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -var test = require('tape'); -var has = require('../'); - -test('has', function (t) { - t.equal(has({}, 'hasOwnProperty'), false, 'object literal does not have own property "hasOwnProperty"'); - t.equal(has(Object.prototype, 'hasOwnProperty'), true, 'Object.prototype has own property "hasOwnProperty"'); - t.end(); -}); diff --git a/node_modules/hosted-git-info/lib/from-url.js b/node_modules/hosted-git-info/lib/from-url.js new file mode 100644 index 0000000000000..efc1247d59d12 --- /dev/null +++ b/node_modules/hosted-git-info/lib/from-url.js @@ -0,0 +1,122 @@ +'use strict' + +const parseUrl = require('./parse-url') + +// look for github shorthand inputs, such as npm/cli +const isGitHubShorthand = (arg) => { + // it cannot contain whitespace before the first # + // it cannot start with a / because that's probably an absolute file path + // but it must include a slash since repos are username/repository + // it cannot start with a . because that's probably a relative file path + // it cannot start with an @ because that's a scoped package if it passes the other tests + // it cannot contain a : before a # because that tells us that there's a protocol + // a second / may not exist before a # + const firstHash = arg.indexOf('#') + const firstSlash = arg.indexOf('/') + const secondSlash = arg.indexOf('/', firstSlash + 1) + const firstColon = arg.indexOf(':') + const firstSpace = /\s/.exec(arg) + const firstAt = arg.indexOf('@') + + const spaceOnlyAfterHash = !firstSpace || (firstHash > -1 && firstSpace.index > firstHash) + const atOnlyAfterHash = firstAt === -1 || (firstHash > -1 && firstAt > firstHash) + const colonOnlyAfterHash = firstColon === -1 || (firstHash > -1 && firstColon > firstHash) + const secondSlashOnlyAfterHash = secondSlash === -1 || (firstHash > -1 && secondSlash > firstHash) + const hasSlash = firstSlash > 0 + // if a # is found, what we really want to know is that the character + // immediately before # is not a / + const doesNotEndWithSlash = firstHash > -1 ? arg[firstHash - 1] !== '/' : !arg.endsWith('/') + const doesNotStartWithDot = !arg.startsWith('.') + + return spaceOnlyAfterHash && hasSlash && doesNotEndWithSlash && + doesNotStartWithDot && atOnlyAfterHash && colonOnlyAfterHash && + secondSlashOnlyAfterHash +} + +module.exports = (giturl, opts, { gitHosts, protocols }) => { + if (!giturl) { + return + } + + const correctedUrl = isGitHubShorthand(giturl) ? `github:${giturl}` : giturl + const parsed = parseUrl(correctedUrl, protocols) + if (!parsed) { + return + } + + const gitHostShortcut = gitHosts.byShortcut[parsed.protocol] + const gitHostDomain = gitHosts.byDomain[parsed.hostname.startsWith('www.') + ? parsed.hostname.slice(4) + : parsed.hostname] + const gitHostName = gitHostShortcut || gitHostDomain + if (!gitHostName) { + return + } + + const gitHostInfo = gitHosts[gitHostShortcut || gitHostDomain] + let auth = null + if (protocols[parsed.protocol]?.auth && (parsed.username || parsed.password)) { + auth = `${parsed.username}${parsed.password ? ':' + parsed.password : ''}` + } + + let committish = null + let user = null + let project = null + let defaultRepresentation = null + + try { + if (gitHostShortcut) { + let pathname = parsed.pathname.startsWith('/') ? parsed.pathname.slice(1) : parsed.pathname + const firstAt = pathname.indexOf('@') + // we ignore auth for shortcuts, so just trim it out + if (firstAt > -1) { + pathname = pathname.slice(firstAt + 1) + } + + const lastSlash = pathname.lastIndexOf('/') + if (lastSlash > -1) { + user = decodeURIComponent(pathname.slice(0, lastSlash)) + // we want nulls only, never empty strings + if (!user) { + user = null + } + project = decodeURIComponent(pathname.slice(lastSlash + 1)) + } else { + project = decodeURIComponent(pathname) + } + + if (project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (parsed.hash) { + committish = decodeURIComponent(parsed.hash.slice(1)) + } + + defaultRepresentation = 'shortcut' + } else { + if (!gitHostInfo.protocols.includes(parsed.protocol)) { + return + } + + const segments = gitHostInfo.extract(parsed) + if (!segments) { + return + } + + user = segments.user && decodeURIComponent(segments.user) + project = decodeURIComponent(segments.project) + committish = decodeURIComponent(segments.committish) + defaultRepresentation = protocols[parsed.protocol]?.name || parsed.protocol.slice(0, -1) + } + } catch (err) { + /* istanbul ignore else */ + if (err instanceof URIError) { + return + } else { + throw err + } + } + + return [gitHostName, user, auth, project, committish, defaultRepresentation, opts] +} diff --git a/node_modules/hosted-git-info/lib/git-host-info.js b/node_modules/hosted-git-info/lib/git-host-info.js deleted file mode 100644 index 9a9720fa3c339..0000000000000 --- a/node_modules/hosted-git-info/lib/git-host-info.js +++ /dev/null @@ -1,185 +0,0 @@ -/* eslint-disable max-len */ -'use strict' -const maybeJoin = (...args) => args.every(arg => arg) ? args.join('') : '' -const maybeEncode = (arg) => arg ? encodeURIComponent(arg) : '' - -const defaults = { - sshtemplate: ({ domain, user, project, committish }) => `git@${domain}:${user}/${project}.git${maybeJoin('#', committish)}`, - sshurltemplate: ({ domain, user, project, committish }) => `git+ssh://git@${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, - browsetemplate: ({ domain, user, project, committish, treepath }) => `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}`, - browsefiletemplate: ({ domain, user, project, committish, treepath, path, fragment, hashformat }) => `https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || 'master')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`, - docstemplate: ({ domain, user, project, treepath, committish }) => `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}#readme`, - httpstemplate: ({ auth, domain, user, project, committish }) => `git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, - filetemplate: ({ domain, user, project, committish, path }) => `https://${domain}/${user}/${project}/raw/${maybeEncode(committish) || 'master'}/${path}`, - shortcuttemplate: ({ type, user, project, committish }) => `${type}:${user}/${project}${maybeJoin('#', committish)}`, - pathtemplate: ({ user, project, committish }) => `${user}/${project}${maybeJoin('#', committish)}`, - bugstemplate: ({ domain, user, project }) => `https://${domain}/${user}/${project}/issues`, - hashformat: formatHashFragment, -} - -const gitHosts = {} -gitHosts.github = Object.assign({}, defaults, { - // First two are insecure and generally shouldn't be used any more, but - // they are still supported. - protocols: ['git:', 'http:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'], - domain: 'github.com', - treepath: 'tree', - filetemplate: ({ auth, user, project, committish, path }) => `https://${maybeJoin(auth, '@')}raw.githubusercontent.com/${user}/${project}/${maybeEncode(committish) || 'master'}/${path}`, - gittemplate: ({ auth, domain, user, project, committish }) => `git://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, - tarballtemplate: ({ domain, user, project, committish }) => `https://codeload.${domain}/${user}/${project}/tar.gz/${maybeEncode(committish) || 'master'}`, - extract: (url) => { - let [, user, project, type, committish] = url.pathname.split('/', 5) - if (type && type !== 'tree') { - return - } - - if (!type) { - committish = url.hash.slice(1) - } - - if (project && project.endsWith('.git')) { - project = project.slice(0, -4) - } - - if (!user || !project) { - return - } - - return { user, project, committish } - }, -}) - -gitHosts.bitbucket = Object.assign({}, defaults, { - protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'], - domain: 'bitbucket.org', - treepath: 'src', - tarballtemplate: ({ domain, user, project, committish }) => `https://${domain}/${user}/${project}/get/${maybeEncode(committish) || 'master'}.tar.gz`, - extract: (url) => { - let [, user, project, aux] = url.pathname.split('/', 4) - if (['get'].includes(aux)) { - return - } - - if (project && project.endsWith('.git')) { - project = project.slice(0, -4) - } - - if (!user || !project) { - return - } - - return { user, project, committish: url.hash.slice(1) } - }, -}) - -gitHosts.gitlab = Object.assign({}, defaults, { - protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'], - domain: 'gitlab.com', - treepath: 'tree', - httpstemplate: ({ auth, domain, user, project, committish }) => `git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, - tarballtemplate: ({ domain, user, project, committish }) => `https://${domain}/${user}/${project}/repository/archive.tar.gz?ref=${maybeEncode(committish) || 'master'}`, - extract: (url) => { - const path = url.pathname.slice(1) - if (path.includes('/-/') || path.includes('/archive.tar.gz')) { - return - } - - const segments = path.split('/') - let project = segments.pop() - if (project.endsWith('.git')) { - project = project.slice(0, -4) - } - - const user = segments.join('/') - if (!user || !project) { - return - } - - return { user, project, committish: url.hash.slice(1) } - }, -}) - -gitHosts.gist = Object.assign({}, defaults, { - protocols: ['git:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'], - domain: 'gist.github.com', - sshtemplate: ({ domain, project, committish }) => `git@${domain}:${project}.git${maybeJoin('#', committish)}`, - sshurltemplate: ({ domain, project, committish }) => `git+ssh://git@${domain}/${project}.git${maybeJoin('#', committish)}`, - browsetemplate: ({ domain, project, committish }) => `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`, - browsefiletemplate: ({ domain, project, committish, path, hashformat }) => `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`, - docstemplate: ({ domain, project, committish }) => `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`, - httpstemplate: ({ domain, project, committish }) => `git+https://${domain}/${project}.git${maybeJoin('#', committish)}`, - filetemplate: ({ user, project, committish, path }) => `https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin('/', maybeEncode(committish))}/${path}`, - shortcuttemplate: ({ type, project, committish }) => `${type}:${project}${maybeJoin('#', committish)}`, - pathtemplate: ({ project, committish }) => `${project}${maybeJoin('#', committish)}`, - bugstemplate: ({ domain, project }) => `https://${domain}/${project}`, - gittemplate: ({ domain, project, committish }) => `git://${domain}/${project}.git${maybeJoin('#', committish)}`, - tarballtemplate: ({ project, committish }) => `https://codeload.github.com/gist/${project}/tar.gz/${maybeEncode(committish) || 'master'}`, - extract: (url) => { - let [, user, project, aux] = url.pathname.split('/', 4) - if (aux === 'raw') { - return - } - - if (!project) { - if (!user) { - return - } - - project = user - user = null - } - - if (project.endsWith('.git')) { - project = project.slice(0, -4) - } - - return { user, project, committish: url.hash.slice(1) } - }, - hashformat: function (fragment) { - return fragment && 'file-' + formatHashFragment(fragment) - }, -}) - -gitHosts.sourcehut = Object.assign({}, defaults, { - protocols: ['git+ssh:', 'https:'], - domain: 'git.sr.ht', - treepath: 'tree', - browsefiletemplate: ({ domain, user, project, committish, treepath, path, fragment, hashformat }) => `https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || 'main')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`, - filetemplate: ({ domain, user, project, committish, path }) => `https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || 'main'}/${path}`, - httpstemplate: ({ domain, user, project, committish }) => `https://${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, - tarballtemplate: ({ domain, user, project, committish }) => `https://${domain}/${user}/${project}/archive/${maybeEncode(committish) || 'main'}.tar.gz`, - bugstemplate: ({ domain, user, project }) => `https://todo.sr.ht/${user}/${project}`, - docstemplate: ({ domain, user, project, treepath, committish }) => `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}#readme`, - extract: (url) => { - let [, user, project, aux] = url.pathname.split('/', 4) - - // tarball url - if (['archive'].includes(aux)) { - return - } - - if (project && project.endsWith('.git')) { - project = project.slice(0, -4) - } - - if (!user || !project) { - return - } - - return { user, project, committish: url.hash.slice(1) } - }, -}) - -const names = Object.keys(gitHosts) -gitHosts.byShortcut = {} -gitHosts.byDomain = {} -for (const name of names) { - gitHosts.byShortcut[`${name}:`] = name - gitHosts.byDomain[gitHosts[name].domain] = name -} - -function formatHashFragment (fragment) { - return fragment.toLowerCase().replace(/^\W+|\/|\W+$/g, '').replace(/\W+/g, '-') -} - -module.exports = gitHosts diff --git a/node_modules/hosted-git-info/lib/git-host.js b/node_modules/hosted-git-info/lib/git-host.js deleted file mode 100644 index 8a975e92e58bb..0000000000000 --- a/node_modules/hosted-git-info/lib/git-host.js +++ /dev/null @@ -1,110 +0,0 @@ -'use strict' -const gitHosts = require('./git-host-info.js') - -class GitHost { - constructor (type, user, auth, project, committish, defaultRepresentation, opts = {}) { - Object.assign(this, gitHosts[type]) - this.type = type - this.user = user - this.auth = auth - this.project = project - this.committish = committish - this.default = defaultRepresentation - this.opts = opts - } - - hash () { - return this.committish ? `#${this.committish}` : '' - } - - ssh (opts) { - return this._fill(this.sshtemplate, opts) - } - - _fill (template, opts) { - if (typeof template === 'function') { - const options = { ...this, ...this.opts, ...opts } - - // the path should always be set so we don't end up with 'undefined' in urls - if (!options.path) { - options.path = '' - } - - // template functions will insert the leading slash themselves - if (options.path.startsWith('/')) { - options.path = options.path.slice(1) - } - - if (options.noCommittish) { - options.committish = null - } - - const result = template(options) - return options.noGitPlus && result.startsWith('git+') ? result.slice(4) : result - } - - return null - } - - sshurl (opts) { - return this._fill(this.sshurltemplate, opts) - } - - browse (path, fragment, opts) { - // not a string, treat path as opts - if (typeof path !== 'string') { - return this._fill(this.browsetemplate, path) - } - - if (typeof fragment !== 'string') { - opts = fragment - fragment = null - } - return this._fill(this.browsefiletemplate, { ...opts, fragment, path }) - } - - docs (opts) { - return this._fill(this.docstemplate, opts) - } - - bugs (opts) { - return this._fill(this.bugstemplate, opts) - } - - https (opts) { - return this._fill(this.httpstemplate, opts) - } - - git (opts) { - return this._fill(this.gittemplate, opts) - } - - shortcut (opts) { - return this._fill(this.shortcuttemplate, opts) - } - - path (opts) { - return this._fill(this.pathtemplate, opts) - } - - tarball (opts) { - return this._fill(this.tarballtemplate, { ...opts, noCommittish: false }) - } - - file (path, opts) { - return this._fill(this.filetemplate, { ...opts, path }) - } - - getDefaultRepresentation () { - return this.default - } - - toString (opts) { - if (this.default && typeof this[this.default] === 'function') { - return this[this.default](opts) - } - - return this.sshurl(opts) - } -} -module.exports = GitHost diff --git a/node_modules/hosted-git-info/lib/hosts.js b/node_modules/hosted-git-info/lib/hosts.js new file mode 100644 index 0000000000000..6e7c123dbff8b --- /dev/null +++ b/node_modules/hosted-git-info/lib/hosts.js @@ -0,0 +1,229 @@ +/* eslint-disable max-len */ + +'use strict' + +const maybeJoin = (...args) => args.every(arg => arg) ? args.join('') : '' +const maybeEncode = (arg) => arg ? encodeURIComponent(arg) : '' +const formatHashFragment = (f) => f.toLowerCase() + .replace(/^\W+/g, '') // strip leading non-characters + .replace(/(?<!\W)\W+$/, '') // strip trailing non-characters + .replace(/\//g, '') // strip all slashes + .replace(/\W+/g, '-') // replace remaining non-characters with '-' + +const defaults = { + sshtemplate: ({ domain, user, project, committish }) => + `git@${domain}:${user}/${project}.git${maybeJoin('#', committish)}`, + sshurltemplate: ({ domain, user, project, committish }) => + `git+ssh://git@${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + edittemplate: ({ domain, user, project, committish, editpath, path }) => + `https://${domain}/${user}/${project}${maybeJoin('/', editpath, '/', maybeEncode(committish || 'HEAD'), '/', path)}`, + browsetemplate: ({ domain, user, project, committish, treepath }) => + `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}`, + browsetreetemplate: ({ domain, user, project, committish, treepath, path, fragment, hashformat }) => + `https://${domain}/${user}/${project}/${treepath}/${maybeEncode(committish || 'HEAD')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`, + browseblobtemplate: ({ domain, user, project, committish, blobpath, path, fragment, hashformat }) => + `https://${domain}/${user}/${project}/${blobpath}/${maybeEncode(committish || 'HEAD')}/${path}${maybeJoin('#', hashformat(fragment || ''))}`, + docstemplate: ({ domain, user, project, treepath, committish }) => + `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish))}#readme`, + httpstemplate: ({ auth, domain, user, project, committish }) => + `git+https://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + filetemplate: ({ domain, user, project, committish, path }) => + `https://${domain}/${user}/${project}/raw/${maybeEncode(committish || 'HEAD')}/${path}`, + shortcuttemplate: ({ type, user, project, committish }) => + `${type}:${user}/${project}${maybeJoin('#', committish)}`, + pathtemplate: ({ user, project, committish }) => + `${user}/${project}${maybeJoin('#', committish)}`, + bugstemplate: ({ domain, user, project }) => + `https://${domain}/${user}/${project}/issues`, + hashformat: formatHashFragment, +} + +const hosts = {} +hosts.github = { + // First two are insecure and generally shouldn't be used any more, but + // they are still supported. + protocols: ['git:', 'http:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'github.com', + treepath: 'tree', + blobpath: 'blob', + editpath: 'edit', + filetemplate: ({ auth, user, project, committish, path }) => + `https://${maybeJoin(auth, '@')}raw.githubusercontent.com/${user}/${project}/${maybeEncode(committish || 'HEAD')}/${path}`, + gittemplate: ({ auth, domain, user, project, committish }) => + `git://${maybeJoin(auth, '@')}${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://codeload.${domain}/${user}/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`, + extract: (url) => { + let [, user, project, type, committish] = url.pathname.split('/', 5) + if (type && type !== 'tree') { + return + } + + if (!type) { + committish = url.hash.slice(1) + } + + if (project && project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (!user || !project) { + return + } + + return { user, project, committish } + }, +} + +hosts.bitbucket = { + protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'bitbucket.org', + treepath: 'src', + blobpath: 'src', + editpath: '?mode=edit', + edittemplate: ({ domain, user, project, committish, treepath, path, editpath }) => + `https://${domain}/${user}/${project}${maybeJoin('/', treepath, '/', maybeEncode(committish || 'HEAD'), '/', path, editpath)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}/get/${maybeEncode(committish || 'HEAD')}.tar.gz`, + extract: (url) => { + let [, user, project, aux] = url.pathname.split('/', 4) + if (['get'].includes(aux)) { + return + } + + if (project && project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (!user || !project) { + return + } + + return { user, project, committish: url.hash.slice(1) } + }, +} + +hosts.gitlab = { + protocols: ['git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'gitlab.com', + treepath: 'tree', + blobpath: 'tree', + editpath: '-/edit', + tarballtemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}/repository/archive.tar.gz?ref=${maybeEncode(committish || 'HEAD')}`, + extract: (url) => { + const path = url.pathname.slice(1) + if (path.includes('/-/') || path.includes('/archive.tar.gz')) { + return + } + + const segments = path.split('/') + let project = segments.pop() + if (project.endsWith('.git')) { + project = project.slice(0, -4) + } + + const user = segments.join('/') + if (!user || !project) { + return + } + + return { user, project, committish: url.hash.slice(1) } + }, +} + +hosts.gist = { + protocols: ['git:', 'git+ssh:', 'git+https:', 'ssh:', 'https:'], + domain: 'gist.github.com', + editpath: 'edit', + sshtemplate: ({ domain, project, committish }) => + `git@${domain}:${project}.git${maybeJoin('#', committish)}`, + sshurltemplate: ({ domain, project, committish }) => + `git+ssh://git@${domain}/${project}.git${maybeJoin('#', committish)}`, + edittemplate: ({ domain, user, project, committish, editpath }) => + `https://${domain}/${user}/${project}${maybeJoin('/', maybeEncode(committish))}/${editpath}`, + browsetemplate: ({ domain, project, committish }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`, + browsetreetemplate: ({ domain, project, committish, path, hashformat }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`, + browseblobtemplate: ({ domain, project, committish, path, hashformat }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}${maybeJoin('#', hashformat(path))}`, + docstemplate: ({ domain, project, committish }) => + `https://${domain}/${project}${maybeJoin('/', maybeEncode(committish))}`, + httpstemplate: ({ domain, project, committish }) => + `git+https://${domain}/${project}.git${maybeJoin('#', committish)}`, + filetemplate: ({ user, project, committish, path }) => + `https://gist.githubusercontent.com/${user}/${project}/raw${maybeJoin('/', maybeEncode(committish))}/${path}`, + shortcuttemplate: ({ type, project, committish }) => + `${type}:${project}${maybeJoin('#', committish)}`, + pathtemplate: ({ project, committish }) => + `${project}${maybeJoin('#', committish)}`, + bugstemplate: ({ domain, project }) => + `https://${domain}/${project}`, + gittemplate: ({ domain, project, committish }) => + `git://${domain}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ project, committish }) => + `https://codeload.github.com/gist/${project}/tar.gz/${maybeEncode(committish || 'HEAD')}`, + extract: (url) => { + let [, user, project, aux] = url.pathname.split('/', 4) + if (aux === 'raw') { + return + } + + if (!project) { + if (!user) { + return + } + + project = user + user = null + } + + if (project.endsWith('.git')) { + project = project.slice(0, -4) + } + + return { user, project, committish: url.hash.slice(1) } + }, + hashformat: function (fragment) { + return fragment && 'file-' + formatHashFragment(fragment) + }, +} + +hosts.sourcehut = { + protocols: ['git+ssh:', 'https:'], + domain: 'git.sr.ht', + treepath: 'tree', + blobpath: 'tree', + filetemplate: ({ domain, user, project, committish, path }) => + `https://${domain}/${user}/${project}/blob/${maybeEncode(committish) || 'HEAD'}/${path}`, + httpstemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}.git${maybeJoin('#', committish)}`, + tarballtemplate: ({ domain, user, project, committish }) => + `https://${domain}/${user}/${project}/archive/${maybeEncode(committish) || 'HEAD'}.tar.gz`, + bugstemplate: () => null, + extract: (url) => { + let [, user, project, aux] = url.pathname.split('/', 4) + + // tarball url + if (['archive'].includes(aux)) { + return + } + + if (project && project.endsWith('.git')) { + project = project.slice(0, -4) + } + + if (!user || !project) { + return + } + + return { user, project, committish: url.hash.slice(1) } + }, +} + +for (const [name, host] of Object.entries(hosts)) { + hosts[name] = Object.assign({}, defaults, host) +} + +module.exports = hosts diff --git a/node_modules/hosted-git-info/lib/index.js b/node_modules/hosted-git-info/lib/index.js index 8bce6b3c28d51..2a7100dcee6e7 100644 --- a/node_modules/hosted-git-info/lib/index.js +++ b/node_modules/hosted-git-info/lib/index.js @@ -1,244 +1,227 @@ 'use strict' -const url = require('url') -const gitHosts = require('./git-host-info.js') -const GitHost = module.exports = require('./git-host.js') -const LRU = require('lru-cache') -const cache = new LRU({ max: 1000 }) - -const protocolToRepresentationMap = { - 'git+ssh:': 'sshurl', - 'git+https:': 'https', - 'ssh:': 'sshurl', - 'git:': 'git', -} -function protocolToRepresentation (protocol) { - return protocolToRepresentationMap[protocol] || protocol.slice(0, -1) -} +const { LRUCache } = require('lru-cache') +const hosts = require('./hosts.js') +const fromUrl = require('./from-url.js') +const parseUrl = require('./parse-url.js') + +const cache = new LRUCache({ max: 1000 }) + +function unknownHostedUrl (url) { + try { + const { + protocol, + hostname, + pathname, + } = new URL(url) + + if (!hostname) { + return null + } -const authProtocols = { - 'git:': true, - 'https:': true, - 'git+https:': true, - 'http:': true, - 'git+http:': true, + const proto = /(?:git\+)http:$/.test(protocol) ? 'http:' : 'https:' + const path = pathname.replace(/\.git$/, '') + return `${proto}//${hostname}${path}` + } catch { + return null + } } -const knownProtocols = Object.keys(gitHosts.byShortcut) - .concat(['http:', 'https:', 'git:', 'git+ssh:', 'git+https:', 'ssh:']) +class GitHost { + constructor (type, user, auth, project, committish, defaultRepresentation, opts = {}) { + Object.assign(this, GitHost.#gitHosts[type], { + type, + user, + auth, + project, + committish, + default: defaultRepresentation, + opts, + }) + } + + static #gitHosts = { byShortcut: {}, byDomain: {} } + static #protocols = { + 'git+ssh:': { name: 'sshurl' }, + 'ssh:': { name: 'sshurl' }, + 'git+https:': { name: 'https', auth: true }, + 'git:': { auth: true }, + 'http:': { auth: true }, + 'https:': { auth: true }, + 'git+http:': { auth: true }, + } -module.exports.fromUrl = function (giturl, opts) { - if (typeof giturl !== 'string') { - return + static addHost (name, host) { + GitHost.#gitHosts[name] = host + GitHost.#gitHosts.byDomain[host.domain] = name + GitHost.#gitHosts.byShortcut[`${name}:`] = name + GitHost.#protocols[`${name}:`] = { name } } - const key = giturl + JSON.stringify(opts || {}) + static fromUrl (giturl, opts) { + if (typeof giturl !== 'string') { + return + } + + const key = giturl + JSON.stringify(opts || {}) + + if (!cache.has(key)) { + const hostArgs = fromUrl(giturl, opts, { + gitHosts: GitHost.#gitHosts, + protocols: GitHost.#protocols, + }) + cache.set(key, hostArgs ? new GitHost(...hostArgs) : undefined) + } - if (!cache.has(key)) { - cache.set(key, fromUrl(giturl, opts)) + return cache.get(key) } - return cache.get(key) -} + static fromManifest (manifest, opts = {}) { + if (!manifest || typeof manifest !== 'object') { + return + } + + const r = manifest.repository + // TODO: look into also checking the `bugs`/`homepage` URLs + + const rurl = r && ( + typeof r === 'string' + ? r + : typeof r === 'object' && typeof r.url === 'string' + ? r.url + : null + ) + + if (!rurl) { + throw new Error('no repository') + } + + const info = (rurl && GitHost.fromUrl(rurl.replace(/^git\+/, ''), opts)) || null + if (info) { + return info + } + const unk = unknownHostedUrl(rurl) + return GitHost.fromUrl(unk, opts) || unk + } + + static parseUrl (url) { + return parseUrl(url) + } + + #fill (template, opts) { + if (typeof template !== 'function') { + return null + } + + const options = { ...this, ...this.opts, ...opts } + + // the path should always be set so we don't end up with 'undefined' in urls + if (!options.path) { + options.path = '' + } + + // template functions will insert the leading slash themselves + if (options.path.startsWith('/')) { + options.path = options.path.slice(1) + } + + if (options.noCommittish) { + options.committish = null + } -function fromUrl (giturl, opts) { - if (!giturl) { - return + const result = template(options) + return options.noGitPlus && result.startsWith('git+') ? result.slice(4) : result } - const url = isGitHubShorthand(giturl) ? 'github:' + giturl : correctProtocol(giturl) - const parsed = parseGitUrl(url) - if (!parsed) { - return parsed + hash () { + return this.committish ? `#${this.committish}` : '' } - const gitHostShortcut = gitHosts.byShortcut[parsed.protocol] - const gitHostDomain = - gitHosts.byDomain[parsed.hostname.startsWith('www.') ? - parsed.hostname.slice(4) : - parsed.hostname] - const gitHostName = gitHostShortcut || gitHostDomain - if (!gitHostName) { - return + ssh (opts) { + return this.#fill(this.sshtemplate, opts) } - const gitHostInfo = gitHosts[gitHostShortcut || gitHostDomain] - let auth = null - if (authProtocols[parsed.protocol] && (parsed.username || parsed.password)) { - auth = `${parsed.username}${parsed.password ? ':' + parsed.password : ''}` + sshurl (opts) { + return this.#fill(this.sshurltemplate, opts) } - let committish = null - let user = null - let project = null - let defaultRepresentation = null + browse (path, ...args) { + // not a string, treat path as opts + if (typeof path !== 'string') { + return this.#fill(this.browsetemplate, path) + } - try { - if (gitHostShortcut) { - let pathname = parsed.pathname.startsWith('/') ? parsed.pathname.slice(1) : parsed.pathname - const firstAt = pathname.indexOf('@') - // we ignore auth for shortcuts, so just trim it out - if (firstAt > -1) { - pathname = pathname.slice(firstAt + 1) - } - - const lastSlash = pathname.lastIndexOf('/') - if (lastSlash > -1) { - user = decodeURIComponent(pathname.slice(0, lastSlash)) - // we want nulls only, never empty strings - if (!user) { - user = null - } - project = decodeURIComponent(pathname.slice(lastSlash + 1)) - } else { - project = decodeURIComponent(pathname) - } - - if (project.endsWith('.git')) { - project = project.slice(0, -4) - } - - if (parsed.hash) { - committish = decodeURIComponent(parsed.hash.slice(1)) - } - - defaultRepresentation = 'shortcut' - } else { - if (!gitHostInfo.protocols.includes(parsed.protocol)) { - return - } - - const segments = gitHostInfo.extract(parsed) - if (!segments) { - return - } - - user = segments.user && decodeURIComponent(segments.user) - project = decodeURIComponent(segments.project) - committish = decodeURIComponent(segments.committish) - defaultRepresentation = protocolToRepresentation(parsed.protocol) + if (typeof args[0] !== 'string') { + return this.#fill(this.browsetreetemplate, { ...args[0], path }) } - } catch (err) { - /* istanbul ignore else */ - if (err instanceof URIError) { - return - } else { - throw err + + return this.#fill(this.browsetreetemplate, { ...args[1], fragment: args[0], path }) + } + + // If the path is known to be a file, then browseFile should be used. For some hosts + // the url is the same as browse, but for others like GitHub a file can use both `/tree/` + // and `/blob/` in the path. When using a default committish of `HEAD` then the `/tree/` + // path will redirect to a specific commit. Using the `/blob/` path avoids this and + // does not redirect to a different commit. + browseFile (path, ...args) { + if (typeof args[0] !== 'string') { + return this.#fill(this.browseblobtemplate, { ...args[0], path }) } + + return this.#fill(this.browseblobtemplate, { ...args[1], fragment: args[0], path }) } - return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts) -} + docs (opts) { + return this.#fill(this.docstemplate, opts) + } -// accepts input like git:github.com:user/repo and inserts the // after the first : -const correctProtocol = (arg) => { - const firstColon = arg.indexOf(':') - const proto = arg.slice(0, firstColon + 1) - if (knownProtocols.includes(proto)) { - return arg + bugs (opts) { + return this.#fill(this.bugstemplate, opts) } - const firstAt = arg.indexOf('@') - if (firstAt > -1) { - if (firstAt > firstColon) { - return `git+ssh://${arg}` - } else { - return arg - } + https (opts) { + return this.#fill(this.httpstemplate, opts) } - const doubleSlash = arg.indexOf('//') - if (doubleSlash === firstColon + 1) { - return arg + git (opts) { + return this.#fill(this.gittemplate, opts) } - return arg.slice(0, firstColon + 1) + '//' + arg.slice(firstColon + 1) -} + shortcut (opts) { + return this.#fill(this.shortcuttemplate, opts) + } -// look for github shorthand inputs, such as npm/cli -const isGitHubShorthand = (arg) => { - // it cannot contain whitespace before the first # - // it cannot start with a / because that's probably an absolute file path - // but it must include a slash since repos are username/repository - // it cannot start with a . because that's probably a relative file path - // it cannot start with an @ because that's a scoped package if it passes the other tests - // it cannot contain a : before a # because that tells us that there's a protocol - // a second / may not exist before a # - const firstHash = arg.indexOf('#') - const firstSlash = arg.indexOf('/') - const secondSlash = arg.indexOf('/', firstSlash + 1) - const firstColon = arg.indexOf(':') - const firstSpace = /\s/.exec(arg) - const firstAt = arg.indexOf('@') - - const spaceOnlyAfterHash = !firstSpace || (firstHash > -1 && firstSpace.index > firstHash) - const atOnlyAfterHash = firstAt === -1 || (firstHash > -1 && firstAt > firstHash) - const colonOnlyAfterHash = firstColon === -1 || (firstHash > -1 && firstColon > firstHash) - const secondSlashOnlyAfterHash = secondSlash === -1 || (firstHash > -1 && secondSlash > firstHash) - const hasSlash = firstSlash > 0 - // if a # is found, what we really want to know is that the character - // immediately before # is not a / - const doesNotEndWithSlash = firstHash > -1 ? arg[firstHash - 1] !== '/' : !arg.endsWith('/') - const doesNotStartWithDot = !arg.startsWith('.') - - return spaceOnlyAfterHash && hasSlash && doesNotEndWithSlash && - doesNotStartWithDot && atOnlyAfterHash && colonOnlyAfterHash && - secondSlashOnlyAfterHash -} + path (opts) { + return this.#fill(this.pathtemplate, opts) + } -// attempt to correct an scp style url so that it will parse with `new URL()` -const correctUrl = (giturl) => { - const firstAt = giturl.indexOf('@') - const lastHash = giturl.lastIndexOf('#') - let firstColon = giturl.indexOf(':') - let lastColon = giturl.lastIndexOf(':', lastHash > -1 ? lastHash : Infinity) - - let corrected - if (lastColon > firstAt) { - // the last : comes after the first @ (or there is no @) - // like it would in: - // proto://hostname.com:user/repo - // username@hostname.com:user/repo - // :password@hostname.com:user/repo - // username:password@hostname.com:user/repo - // proto://username@hostname.com:user/repo - // proto://:password@hostname.com:user/repo - // proto://username:password@hostname.com:user/repo - // then we replace the last : with a / to create a valid path - corrected = giturl.slice(0, lastColon) + '/' + giturl.slice(lastColon + 1) - // // and we find our new : positions - firstColon = corrected.indexOf(':') - lastColon = corrected.lastIndexOf(':') - } - - if (firstColon === -1 && giturl.indexOf('//') === -1) { - // we have no : at all - // as it would be in: - // username@hostname.com/user/repo - // then we prepend a protocol - corrected = `git+ssh://${corrected}` - } - - return corrected -} + tarball (opts) { + return this.#fill(this.tarballtemplate, { ...opts, noCommittish: false }) + } -// try to parse the url as its given to us, if that throws -// then we try to clean the url and parse that result instead -// THIS FUNCTION SHOULD NEVER THROW -const parseGitUrl = (giturl) => { - let result - try { - result = new url.URL(giturl) - } catch (err) {} + file (path, opts) { + return this.#fill(this.filetemplate, { ...opts, path }) + } - if (result) { - return result + edit (path, opts) { + return this.#fill(this.edittemplate, { ...opts, path }) } - const correctedUrl = correctUrl(giturl) - try { - result = new url.URL(correctedUrl) - } catch (err) {} + getDefaultRepresentation () { + return this.default + } + + toString (opts) { + if (this.default && typeof this[this.default] === 'function') { + return this[this.default](opts) + } - return result + return this.sshurl(opts) + } } + +for (const [name, host] of Object.entries(hosts)) { + GitHost.addHost(name, host) +} + +module.exports = GitHost diff --git a/node_modules/hosted-git-info/lib/parse-url.js b/node_modules/hosted-git-info/lib/parse-url.js new file mode 100644 index 0000000000000..bfd54b9140c11 --- /dev/null +++ b/node_modules/hosted-git-info/lib/parse-url.js @@ -0,0 +1,81 @@ +const url = require('url') + +const lastIndexOfBefore = (str, char, beforeChar) => { + const startPosition = str.indexOf(beforeChar) + return str.lastIndexOf(char, startPosition > -1 ? startPosition : Infinity) +} + +const safeUrl = (u) => { + try { + return new url.URL(u) + } catch { + // this fn should never throw + } +} + +// accepts input like git:github.com:user/repo and inserts the // after the first : +const correctProtocol = (arg, protocols) => { + const firstColon = arg.indexOf(':') + const proto = arg.slice(0, firstColon + 1) + if (Object.prototype.hasOwnProperty.call(protocols, proto)) { + return arg + } + + if (arg.substr(firstColon, 3) === '://') { + // If arg is given as <foo>://<bar>, then this is already a valid URL. + return arg + } + + const firstAt = arg.indexOf('@') + if (firstAt > -1) { + if (firstAt > firstColon) { + // URL has the form of <foo>:<bar>@<baz>. Assume this is a git+ssh URL. + return `git+ssh://${arg}` + } else { + // URL has the form 'git@github.com:npm/hosted-git-info.git'. + return arg + } + } + + // Correct <foo>:<bar> to <foo>://<bar> + return `${arg.slice(0, firstColon + 1)}//${arg.slice(firstColon + 1)}` +} + +// attempt to correct an scp style url so that it will parse with `new URL()` +const correctUrl = (giturl) => { + // ignore @ that come after the first hash since the denotes the start + // of a committish which can contain @ characters + const firstAt = lastIndexOfBefore(giturl, '@', '#') + // ignore colons that come after the hash since that could include colons such as: + // git@github.com:user/package-2#semver:^1.0.0 + const lastColonBeforeHash = lastIndexOfBefore(giturl, ':', '#') + + if (lastColonBeforeHash > firstAt) { + // the last : comes after the first @ (or there is no @) + // like it would in: + // proto://hostname.com:user/repo + // username@hostname.com:user/repo + // :password@hostname.com:user/repo + // username:password@hostname.com:user/repo + // proto://username@hostname.com:user/repo + // proto://:password@hostname.com:user/repo + // proto://username:password@hostname.com:user/repo + // then we replace the last : with a / to create a valid path + giturl = giturl.slice(0, lastColonBeforeHash) + '/' + giturl.slice(lastColonBeforeHash + 1) + } + + if (lastIndexOfBefore(giturl, ':', '#') === -1 && giturl.indexOf('//') === -1) { + // we have no : at all + // as it would be in: + // username@hostname.com/user/repo + // then we prepend a protocol + giturl = `git+ssh://${giturl}` + } + + return giturl +} + +module.exports = (giturl, protocols) => { + const withProtocol = protocols ? correctProtocol(giturl, protocols) : giturl + return safeUrl(withProtocol) || safeUrl(correctUrl(withProtocol)) +} diff --git a/node_modules/hosted-git-info/package.json b/node_modules/hosted-git-info/package.json index 0153b0852cbf4..1e74eda1656d7 100644 --- a/node_modules/hosted-git-info/package.json +++ b/node_modules/hosted-git-info/package.json @@ -1,6 +1,6 @@ { "name": "hosted-git-info", - "version": "5.0.0", + "version": "9.0.2", "description": "Provides metadata and conversions from repository urls for GitHub, Bitbucket and GitLab", "main": "./lib/index.js", "repository": { @@ -21,36 +21,41 @@ "homepage": "https://github.com/npm/hosted-git-info", "scripts": { "posttest": "npm run lint", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "preversion": "npm test", "snap": "tap", "test": "tap", "test:coverage": "tap --coverage-report=html", - "lint": "eslint '**/*.js'", - "postlint": "npm-template-check", - "template-copy": "npm-template-copy --force", - "lintfix": "npm run lint -- --fix" + "lint": "npm run eslint", + "postlint": "template-oss-check", + "lintfix": "npm run eslint -- --fix", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "dependencies": { - "lru-cache": "^7.5.1" + "lru-cache": "^11.1.0" }, "devDependencies": { - "@npmcli/template-oss": "^2.9.2", - "tap": "^15.1.6" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.0.1" }, "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^20.17.0 || >=22.9.0" }, "tap": { "color": 1, - "coverage": true + "coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "templateOSS": { - "version": "2.9.2" + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.25.1", + "publish": "true" } } diff --git a/node_modules/http-cache-semantics/index.js b/node_modules/http-cache-semantics/index.js index 4f6c2f30498b4..f01e9a16b4781 100644 --- a/node_modules/http-cache-semantics/index.js +++ b/node_modules/http-cache-semantics/index.js @@ -1,5 +1,22 @@ 'use strict'; -// rfc7231 6.1 + +/** + * @typedef {Object} HttpRequest + * @property {Record<string, string>} headers - Request headers + * @property {string} [method] - HTTP method + * @property {string} [url] - Request URL + */ + +/** + * @typedef {Object} HttpResponse + * @property {Record<string, string>} headers - Response headers + * @property {number} [status] - HTTP status code + */ + +/** + * Set of default cacheable status codes per RFC 7231 section 6.1. + * @type {Set<number>} + */ const statusCodeCacheableByDefault = new Set([ 200, 203, @@ -7,6 +24,7 @@ const statusCodeCacheableByDefault = new Set([ 206, 300, 301, + 308, 404, 405, 410, @@ -14,7 +32,11 @@ const statusCodeCacheableByDefault = new Set([ 501, ]); -// This implementation does not understand partial responses (206) +/** + * Set of HTTP status codes that the cache implementation understands. + * Note: This implementation does not understand partial responses (206). + * @type {Set<number>} + */ const understoodStatuses = new Set([ 200, 203, @@ -32,13 +54,21 @@ const understoodStatuses = new Set([ 501, ]); +/** + * Set of HTTP error status codes. + * @type {Set<number>} + */ const errorStatusCodes = new Set([ 500, 502, - 503, + 503, 504, ]); +/** + * Object representing hop-by-hop headers that should be removed. + * @type {Record<string, boolean>} + */ const hopByHopHeaders = { date: true, // included, because we add Age update Date connection: true, @@ -51,6 +81,10 @@ const hopByHopHeaders = { upgrade: true, }; +/** + * Headers that are excluded from revalidation update. + * @type {Record<string, boolean>} + */ const excludedFromRevalidationUpdate = { // Since the old body is reused, it doesn't make sense to change properties of the body 'content-length': true, @@ -59,35 +93,56 @@ const excludedFromRevalidationUpdate = { 'content-range': true, }; +/** + * Converts a string to a number or returns zero if the conversion fails. + * @param {string} s - The string to convert. + * @returns {number} The parsed number or 0. + */ function toNumberOrZero(s) { const n = parseInt(s, 10); return isFinite(n) ? n : 0; } -// RFC 5861 +/** + * Determines if the given response is an error response. + * Implements RFC 5861 behavior. + * @param {HttpResponse|undefined} response - The HTTP response object. + * @returns {boolean} true if the response is an error or undefined, false otherwise. + */ function isErrorResponse(response) { // consider undefined response as faulty - if(!response) { - return true + if (!response) { + return true; } return errorStatusCodes.has(response.status); } +/** + * Parses a Cache-Control header string into an object. + * @param {string} [header] - The Cache-Control header value. + * @returns {Record<string, string|boolean>} An object representing Cache-Control directives. + */ function parseCacheControl(header) { + /** @type {Record<string, string|boolean>} */ const cc = {}; if (!header) return cc; // TODO: When there is more than one value present for a given directive (e.g., two Expires header fields, multiple Cache-Control: max-age directives), // the directive's value is considered invalid. Caches are encouraged to consider responses that have invalid freshness information to be stale - const parts = header.trim().split(/\s*,\s*/); // TODO: lame parsing + const parts = header.trim().split(/,/); for (const part of parts) { - const [k, v] = part.split(/\s*=\s*/, 2); - cc[k] = v === undefined ? true : v.replace(/^"|"$/g, ''); // TODO: lame unquoting + const [k, v] = part.split(/=/, 2); + cc[k.trim()] = v === undefined ? true : v.trim().replace(/^"|"$/g, ''); } return cc; } +/** + * Formats a Cache-Control directives object into a header string. + * @param {Record<string, string|boolean>} cc - The Cache-Control directives. + * @returns {string|undefined} A formatted Cache-Control header string or undefined if empty. + */ function formatCacheControl(cc) { let parts = []; for (const k in cc) { @@ -101,6 +156,17 @@ function formatCacheControl(cc) { } module.exports = class CachePolicy { + /** + * Creates a new CachePolicy instance. + * @param {HttpRequest} req - Incoming client request. + * @param {HttpResponse} res - Received server response. + * @param {Object} [options={}] - Configuration options. + * @param {boolean} [options.shared=true] - Is the cache shared (a public proxy)? `false` for personal browser caches. + * @param {number} [options.cacheHeuristic=0.1] - Fallback heuristic (age fraction) for cache duration. + * @param {number} [options.immutableMinTimeToLive=86400000] - Minimum TTL for immutable responses in milliseconds. + * @param {boolean} [options.ignoreCargoCult=false] - Detect nonsense cache headers, and override them. + * @param {any} [options._fromObject] - Internal parameter for deserialization. Do not use. + */ constructor( req, res, @@ -122,29 +188,44 @@ module.exports = class CachePolicy { } this._assertRequestHasHeaders(req); + /** @type {number} Timestamp when the response was received */ this._responseTime = this.now(); + /** @type {boolean} Indicates if the cache is shared */ this._isShared = shared !== false; + /** @type {boolean} Indicates if legacy cargo cult directives should be ignored */ + this._ignoreCargoCult = !!ignoreCargoCult; + /** @type {number} Heuristic cache fraction */ this._cacheHeuristic = undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE + /** @type {number} Minimum TTL for immutable responses in ms */ this._immutableMinTtl = undefined !== immutableMinTimeToLive ? immutableMinTimeToLive : 24 * 3600 * 1000; + /** @type {number} HTTP status code */ this._status = 'status' in res ? res.status : 200; + /** @type {Record<string, string>} Response headers */ this._resHeaders = res.headers; + /** @type {Record<string, string|boolean>} Parsed Cache-Control directives from response */ this._rescc = parseCacheControl(res.headers['cache-control']); + /** @type {string} HTTP method (e.g., GET, POST) */ this._method = 'method' in req ? req.method : 'GET'; + /** @type {string} Request URL */ this._url = req.url; + /** @type {string} Host header from the request */ this._host = req.headers.host; + /** @type {boolean} Whether the request does not include an Authorization header */ this._noAuthorization = !req.headers.authorization; + /** @type {Record<string, string>|null} Request headers used for Vary matching */ this._reqHeaders = res.headers.vary ? req.headers : null; // Don't keep all request headers if they won't be used + /** @type {Record<string, string|boolean>} Parsed Cache-Control directives from request */ this._reqcc = parseCacheControl(req.headers['cache-control']); // Assume that if someone uses legacy, non-standard uncecessary options they don't understand caching, // so there's no point stricly adhering to the blindly copy&pasted directives. if ( - ignoreCargoCult && + this._ignoreCargoCult && 'pre-check' in this._rescc && 'post-check' in this._rescc ) { @@ -170,10 +251,18 @@ module.exports = class CachePolicy { } } + /** + * You can monkey-patch it for testing. + * @returns {number} Current time in milliseconds. + */ now() { return Date.now(); } + /** + * Determines if the response is storable in a cache. + * @returns {boolean} `false` if can never be cached. + */ storable() { // The "no-store" request directive indicates that a cache MUST NOT store any part of either this request or any response to it. return !!( @@ -207,62 +296,160 @@ module.exports = class CachePolicy { ); } + /** + * @returns {boolean} true if expiration is explicitly defined. + */ _hasExplicitExpiration() { // 4.2.1 Calculating Freshness Lifetime - return ( + return !!( (this._isShared && this._rescc['s-maxage']) || this._rescc['max-age'] || this._resHeaders.expires ); } + /** + * @param {HttpRequest} req - a request + * @throws {Error} if the headers are missing. + */ _assertRequestHasHeaders(req) { if (!req || !req.headers) { throw Error('Request headers missing'); } } + /** + * Checks if the request matches the cache and can be satisfied from the cache immediately, + * without having to make a request to the server. + * + * This doesn't support `stale-while-revalidate`. See `evaluateRequest()` for a more complete solution. + * + * @param {HttpRequest} req - The new incoming HTTP request. + * @returns {boolean} `true`` if the cached response used to construct this cache policy satisfies the request without revalidation. + */ satisfiesWithoutRevalidation(req) { + const result = this.evaluateRequest(req); + return !result.revalidation; + } + + /** + * @param {{headers: Record<string, string>, synchronous: boolean}|undefined} revalidation - Revalidation information, if any. + * @returns {{response: {headers: Record<string, string>}, revalidation: {headers: Record<string, string>, synchronous: boolean}|undefined}} An object with a cached response headers and revalidation info. + */ + _evaluateRequestHitResult(revalidation) { + return { + response: { + headers: this.responseHeaders(), + }, + revalidation, + }; + } + + /** + * @param {HttpRequest} request - new incoming + * @param {boolean} synchronous - whether revalidation must be synchronous (not s-w-r). + * @returns {{headers: Record<string, string>, synchronous: boolean}} An object with revalidation headers and a synchronous flag. + */ + _evaluateRequestRevalidation(request, synchronous) { + return { + synchronous, + headers: this.revalidationHeaders(request), + }; + } + + /** + * @param {HttpRequest} request - new incoming + * @returns {{response: undefined, revalidation: {headers: Record<string, string>, synchronous: boolean}}} An object indicating no cached response and revalidation details. + */ + _evaluateRequestMissResult(request) { + return { + response: undefined, + revalidation: this._evaluateRequestRevalidation(request, true), + }; + } + + /** + * Checks if the given request matches this cache entry, and how the cache can be used to satisfy it. Returns an object with: + * + * ``` + * { + * // If defined, you must send a request to the server. + * revalidation: { + * headers: {}, // HTTP headers to use when sending the revalidation response + * // If true, you MUST wait for a response from the server before using the cache + * // If false, this is stale-while-revalidate. The cache is stale, but you can use it while you update it asynchronously. + * synchronous: bool, + * }, + * // If defined, you can use this cached response. + * response: { + * headers: {}, // Updated cached HTTP headers you must use when responding to the client + * }, + * } + * ``` + * @param {HttpRequest} req - new incoming HTTP request + * @returns {{response: {headers: Record<string, string>}|undefined, revalidation: {headers: Record<string, string>, synchronous: boolean}|undefined}} An object containing keys: + * - revalidation: { headers: Record<string, string>, synchronous: boolean } Set if you should send this to the origin server + * - response: { headers: Record<string, string> } Set if you can respond to the client with these cached headers + */ + evaluateRequest(req) { this._assertRequestHasHeaders(req); + // In all circumstances, a cache MUST NOT ignore the must-revalidate directive + if (this._rescc['must-revalidate']) { + return this._evaluateRequestMissResult(req); + } + + if (!this._requestMatches(req, false)) { + return this._evaluateRequestMissResult(req); + } + // When presented with a request, a cache MUST NOT reuse a stored response, unless: // the presented request does not contain the no-cache pragma (Section 5.4), nor the no-cache cache directive, // unless the stored response is successfully validated (Section 4.3), and const requestCC = parseCacheControl(req.headers['cache-control']); + if (requestCC['no-cache'] || /no-cache/.test(req.headers.pragma)) { - return false; + return this._evaluateRequestMissResult(req); } - if (requestCC['max-age'] && this.age() > requestCC['max-age']) { - return false; + if (requestCC['max-age'] && this.age() > toNumberOrZero(requestCC['max-age'])) { + return this._evaluateRequestMissResult(req); } - if ( - requestCC['min-fresh'] && - this.timeToLive() < 1000 * requestCC['min-fresh'] - ) { - return false; + if (requestCC['min-fresh'] && this.maxAge() - this.age() < toNumberOrZero(requestCC['min-fresh'])) { + return this._evaluateRequestMissResult(req); } // the stored response is either: // fresh, or allowed to be served stale if (this.stale()) { - const allowsStale = - requestCC['max-stale'] && - !this._rescc['must-revalidate'] && - (true === requestCC['max-stale'] || - requestCC['max-stale'] > this.age() - this.maxAge()); - if (!allowsStale) { - return false; + // If a value is present, then the client is willing to accept a response that has + // exceeded its freshness lifetime by no more than the specified number of seconds + const allowsStaleWithoutRevalidation = 'max-stale' in requestCC && + (true === requestCC['max-stale'] || requestCC['max-stale'] > this.age() - this.maxAge()); + + if (allowsStaleWithoutRevalidation) { + return this._evaluateRequestHitResult(undefined); + } + + if (this.useStaleWhileRevalidate()) { + return this._evaluateRequestHitResult(this._evaluateRequestRevalidation(req, false)); } + + return this._evaluateRequestMissResult(req); } - return this._requestMatches(req, false); + return this._evaluateRequestHitResult(undefined); } + /** + * @param {HttpRequest} req - check if this is for the same cache entry + * @param {boolean} allowHeadMethod - allow a HEAD method to match. + * @returns {boolean} `true` if the request matches. + */ _requestMatches(req, allowHeadMethod) { // The presented effective request URI and that of the stored response match, and - return ( + return !!( (!this._url || this._url === req.url) && this._host === req.headers.host && // the request method associated with the stored response allows it to be used for the presented request, and @@ -274,15 +461,24 @@ module.exports = class CachePolicy { ); } + /** + * Determines whether storing authenticated responses is allowed. + * @returns {boolean} `true` if allowed. + */ _allowsStoringAuthenticated() { - // following Cache-Control response directives (Section 5.2.2) have such an effect: must-revalidate, public, and s-maxage. - return ( + // following Cache-Control response directives (Section 5.2.2) have such an effect: must-revalidate, public, and s-maxage. + return !!( this._rescc['must-revalidate'] || this._rescc.public || this._rescc['s-maxage'] ); } + /** + * Checks whether the Vary header in the response matches the new request. + * @param {HttpRequest} req - incoming HTTP request + * @returns {boolean} `true` if the vary headers match. + */ _varyMatches(req) { if (!this._resHeaders.vary) { return true; @@ -303,7 +499,13 @@ module.exports = class CachePolicy { return true; } + /** + * Creates a copy of the given headers without any hop-by-hop headers. + * @param {Record<string, string>} inHeaders - old headers from the cached response + * @returns {Record<string, string>} A new headers object without hop-by-hop headers. + */ _copyWithoutHopByHopHeaders(inHeaders) { + /** @type {Record<string, string>} */ const headers = {}; for (const name in inHeaders) { if (hopByHopHeaders[name]) continue; @@ -329,6 +531,11 @@ module.exports = class CachePolicy { return headers; } + /** + * Returns the response headers adjusted for serving the cached response. + * Removes hop-by-hop headers and updates the Age and Date headers. + * @returns {Record<string, string>} The adjusted response headers. + */ responseHeaders() { const headers = this._copyWithoutHopByHopHeaders(this._resHeaders); const age = this.age(); @@ -350,8 +557,8 @@ module.exports = class CachePolicy { } /** - * Value of the Date response header or current time if Date was invalid - * @return timestamp + * Returns the Date header value from the response or the current time if invalid. + * @returns {number} Timestamp (in milliseconds) representing the Date header or response time. */ date() { const serverDate = Date.parse(this._resHeaders.date); @@ -364,8 +571,7 @@ module.exports = class CachePolicy { /** * Value of the Age header, in seconds, updated for the current time. * May be fractional. - * - * @return Number + * @returns {number} The age in seconds. */ age() { let age = this._ageValue(); @@ -374,16 +580,21 @@ module.exports = class CachePolicy { return age + residentTime; } + /** + * @returns {number} The Age header value as a number. + */ _ageValue() { return toNumberOrZero(this._resHeaders.age); } /** - * Value of applicable max-age (or heuristic equivalent) in seconds. This counts since response's `Date`. + * Possibly outdated value of applicable max-age (or heuristic equivalent) in seconds. + * This counts since response's `Date`. * * For an up-to-date value, see `timeToLive()`. * - * @return Number + * Returns the maximum age (freshness lifetime) of the response in seconds. + * @returns {number} The max-age value in seconds. */ maxAge() { if (!this.storable() || this._rescc['no-cache']) { @@ -445,29 +656,57 @@ module.exports = class CachePolicy { return defaultMinTtl; } + /** + * Remaining time this cache entry may be useful for, in *milliseconds*. + * You can use this as an expiration time for your cache storage. + * + * Prefer this method over `maxAge()`, because it includes other factors like `age` and `stale-while-revalidate`. + * @returns {number} Time-to-live in milliseconds. + */ timeToLive() { const age = this.maxAge() - this.age(); const staleIfErrorAge = age + toNumberOrZero(this._rescc['stale-if-error']); const staleWhileRevalidateAge = age + toNumberOrZero(this._rescc['stale-while-revalidate']); - return Math.max(0, age, staleIfErrorAge, staleWhileRevalidateAge) * 1000; + return Math.round(Math.max(0, age, staleIfErrorAge, staleWhileRevalidateAge) * 1000); } + /** + * If true, this cache entry is past its expiration date. + * Note that stale cache may be useful sometimes, see `evaluateRequest()`. + * @returns {boolean} `false` doesn't mean it's fresh nor usable + */ stale() { return this.maxAge() <= this.age(); } + /** + * @returns {boolean} `true` if `stale-if-error` condition allows use of a stale response. + */ _useStaleIfError() { return this.maxAge() + toNumberOrZero(this._rescc['stale-if-error']) > this.age(); } + /** See `evaluateRequest()` for a more complete solution + * @returns {boolean} `true` if `stale-while-revalidate` is currently allowed. + */ useStaleWhileRevalidate() { - return this.maxAge() + toNumberOrZero(this._rescc['stale-while-revalidate']) > this.age(); + const swr = toNumberOrZero(this._rescc['stale-while-revalidate']); + return swr > 0 && this.maxAge() + swr > this.age(); } + /** + * Creates a `CachePolicy` instance from a serialized object. + * @param {Object} obj - The serialized object. + * @returns {CachePolicy} A new CachePolicy instance. + */ static fromObject(obj) { return new this(undefined, undefined, { _fromObject: obj }); } + /** + * @param {any} obj - The serialized object. + * @throws {Error} If already initialized or if the object is invalid. + */ _fromObject(obj) { if (this._responseTime) throw Error('Reinitialized'); if (!obj || obj.v !== 1) throw Error('Invalid serialization'); @@ -477,6 +716,7 @@ module.exports = class CachePolicy { this._cacheHeuristic = obj.ch; this._immutableMinTtl = obj.imm !== undefined ? obj.imm : 24 * 3600 * 1000; + this._ignoreCargoCult = !!obj.icc; this._status = obj.st; this._resHeaders = obj.resh; this._rescc = obj.rescc; @@ -488,6 +728,10 @@ module.exports = class CachePolicy { this._reqcc = obj.reqcc; } + /** + * Serializes the `CachePolicy` instance into a JSON-serializable object. + * @returns {Object} The serialized object. + */ toObject() { return { v: 1, @@ -495,6 +739,7 @@ module.exports = class CachePolicy { sh: this._isShared, ch: this._cacheHeuristic, imm: this._immutableMinTtl, + icc: this._ignoreCargoCult, st: this._status, resh: this._resHeaders, rescc: this._rescc, @@ -513,6 +758,8 @@ module.exports = class CachePolicy { * * Hop by hop headers are always stripped. * Revalidation headers may be added or removed, depending on request. + * @param {HttpRequest} incomingReq - The incoming HTTP request. + * @returns {Record<string, string>} The headers for the revalidation request. */ revalidationHeaders(incomingReq) { this._assertRequestHasHeaders(incomingReq); @@ -577,17 +824,22 @@ module.exports = class CachePolicy { * Returns {policy, modified} where modified is a boolean indicating * whether the response body has been modified, and old cached body can't be used. * - * @return {Object} {policy: CachePolicy, modified: Boolean} + * @param {HttpRequest} request - The latest HTTP request asking for the cached entry. + * @param {HttpResponse} response - The latest revalidation HTTP response from the origin server. + * @returns {{policy: CachePolicy, modified: boolean, matches: boolean}} The updated policy and modification status. + * @throws {Error} If the response headers are missing. */ revalidatedPolicy(request, response) { this._assertRequestHasHeaders(request); - if(this._useStaleIfError() && isErrorResponse(response)) { // I consider the revalidation request unsuccessful + + if (this._useStaleIfError() && isErrorResponse(response)) { return { - modified: false, - matches: false, - policy: this, + policy: this, + modified: false, + matches: true, }; } + if (!response || !response.headers) { throw Error('Response headers missing'); } @@ -634,9 +886,16 @@ module.exports = class CachePolicy { } } + const optionsCopy = { + shared: this._isShared, + cacheHeuristic: this._cacheHeuristic, + immutableMinTimeToLive: this._immutableMinTtl, + ignoreCargoCult: this._ignoreCargoCult, + }; + if (!matches) { return { - policy: new this.constructor(request, response), + policy: new this.constructor(request, response, optionsCopy), // Client receiving 304 without body, even if it's invalid/mismatched has no option // but to reuse a cached body. We don't have a good way to tell clients to do // error recovery in such case. @@ -661,11 +920,7 @@ module.exports = class CachePolicy { headers, }); return { - policy: new this.constructor(request, newResponse, { - shared: this._isShared, - cacheHeuristic: this._cacheHeuristic, - immutableMinTimeToLive: this._immutableMinTtl, - }), + policy: new this.constructor(request, newResponse, optionsCopy), modified: false, matches: true, }; diff --git a/node_modules/http-cache-semantics/package.json b/node_modules/http-cache-semantics/package.json index 897798d8ccc79..d45dfa1274e0d 100644 --- a/node_modules/http-cache-semantics/package.json +++ b/node_modules/http-cache-semantics/package.json @@ -1,24 +1,22 @@ { "name": "http-cache-semantics", - "version": "4.1.0", + "version": "4.2.0", "description": "Parses Cache-Control and other headers. Helps building correct HTTP caches and proxies", - "repository": "https://github.com/kornelski/http-cache-semantics.git", + "repository": { + "type": "git", + "url": "git+https://github.com/kornelski/http-cache-semantics.git" + }, "main": "index.js", + "types": "index.js", "scripts": { "test": "mocha" }, "files": [ "index.js" ], - "author": "Kornel Lesiński <kornel@geekhood.net> (https://kornel.ski/)", + "author": "Kornel Lesiński <npms2@geekhood.net> (https://kornel.ski/)", "license": "BSD-2-Clause", "devDependencies": { - "eslint": "^5.13.0", - "eslint-plugin-prettier": "^3.0.1", - "husky": "^0.14.3", - "lint-staged": "^8.1.3", - "mocha": "^5.1.0", - "prettier": "^1.14.3", - "prettier-eslint-cli": "^4.7.1" + "mocha": "^11.0" } } diff --git a/node_modules/http-proxy-agent/LICENSE b/node_modules/http-proxy-agent/LICENSE new file mode 100644 index 0000000000000..7ddd1e9bdb450 --- /dev/null +++ b/node_modules/http-proxy-agent/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/http-proxy-agent/dist/agent.d.ts b/node_modules/http-proxy-agent/dist/agent.d.ts deleted file mode 100644 index 3f043f7f9f756..0000000000000 --- a/node_modules/http-proxy-agent/dist/agent.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/// <reference types="node" /> -import net from 'net'; -import { Agent, ClientRequest, RequestOptions } from 'agent-base'; -import { HttpProxyAgentOptions } from '.'; -interface HttpProxyAgentClientRequest extends ClientRequest { - path: string; - output?: string[]; - outputData?: { - data: string; - }[]; - _header?: string | null; - _implicitHeader(): void; -} -/** - * The `HttpProxyAgent` implements an HTTP Agent subclass that connects - * to the specified "HTTP proxy server" in order to proxy HTTP requests. - * - * @api public - */ -export default class HttpProxyAgent extends Agent { - private secureProxy; - private proxy; - constructor(_opts: string | HttpProxyAgentOptions); - /** - * Called when the node-core HTTP client library is creating a - * new HTTP request. - * - * @api protected - */ - callback(req: HttpProxyAgentClientRequest, opts: RequestOptions): Promise<net.Socket>; -} -export {}; diff --git a/node_modules/http-proxy-agent/dist/agent.js b/node_modules/http-proxy-agent/dist/agent.js deleted file mode 100644 index aca8280431488..0000000000000 --- a/node_modules/http-proxy-agent/dist/agent.js +++ /dev/null @@ -1,145 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const net_1 = __importDefault(require("net")); -const tls_1 = __importDefault(require("tls")); -const url_1 = __importDefault(require("url")); -const debug_1 = __importDefault(require("debug")); -const once_1 = __importDefault(require("@tootallnate/once")); -const agent_base_1 = require("agent-base"); -const debug = (0, debug_1.default)('http-proxy-agent'); -function isHTTPS(protocol) { - return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false; -} -/** - * The `HttpProxyAgent` implements an HTTP Agent subclass that connects - * to the specified "HTTP proxy server" in order to proxy HTTP requests. - * - * @api public - */ -class HttpProxyAgent extends agent_base_1.Agent { - constructor(_opts) { - let opts; - if (typeof _opts === 'string') { - opts = url_1.default.parse(_opts); - } - else { - opts = _opts; - } - if (!opts) { - throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!'); - } - debug('Creating new HttpProxyAgent instance: %o', opts); - super(opts); - const proxy = Object.assign({}, opts); - // If `true`, then connect to the proxy server over TLS. - // Defaults to `false`. - this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol); - // Prefer `hostname` over `host`, and set the `port` if needed. - proxy.host = proxy.hostname || proxy.host; - if (typeof proxy.port === 'string') { - proxy.port = parseInt(proxy.port, 10); - } - if (!proxy.port && proxy.host) { - proxy.port = this.secureProxy ? 443 : 80; - } - if (proxy.host && proxy.path) { - // If both a `host` and `path` are specified then it's most likely - // the result of a `url.parse()` call... we need to remove the - // `path` portion so that `net.connect()` doesn't attempt to open - // that as a Unix socket file. - delete proxy.path; - delete proxy.pathname; - } - this.proxy = proxy; - } - /** - * Called when the node-core HTTP client library is creating a - * new HTTP request. - * - * @api protected - */ - callback(req, opts) { - return __awaiter(this, void 0, void 0, function* () { - const { proxy, secureProxy } = this; - const parsed = url_1.default.parse(req.path); - if (!parsed.protocol) { - parsed.protocol = 'http:'; - } - if (!parsed.hostname) { - parsed.hostname = opts.hostname || opts.host || null; - } - if (parsed.port == null && typeof opts.port) { - parsed.port = String(opts.port); - } - if (parsed.port === '80') { - // if port is 80, then we can remove the port so that the - // ":80" portion is not on the produced URL - parsed.port = ''; - } - // Change the `http.ClientRequest` instance's "path" field - // to the absolute path of the URL that will be requested. - req.path = url_1.default.format(parsed); - // Inject the `Proxy-Authorization` header if necessary. - if (proxy.auth) { - req.setHeader('Proxy-Authorization', `Basic ${Buffer.from(proxy.auth).toString('base64')}`); - } - // Create a socket connection to the proxy server. - let socket; - if (secureProxy) { - debug('Creating `tls.Socket`: %o', proxy); - socket = tls_1.default.connect(proxy); - } - else { - debug('Creating `net.Socket`: %o', proxy); - socket = net_1.default.connect(proxy); - } - // At this point, the http ClientRequest's internal `_header` field - // might have already been set. If this is the case then we'll need - // to re-generate the string since we just changed the `req.path`. - if (req._header) { - let first; - let endOfHeaders; - debug('Regenerating stored HTTP header string for request'); - req._header = null; - req._implicitHeader(); - if (req.output && req.output.length > 0) { - // Node < 12 - debug('Patching connection write() output buffer with updated header'); - first = req.output[0]; - endOfHeaders = first.indexOf('\r\n\r\n') + 4; - req.output[0] = req._header + first.substring(endOfHeaders); - debug('Output buffer: %o', req.output); - } - else if (req.outputData && req.outputData.length > 0) { - // Node >= 12 - debug('Patching connection write() output buffer with updated header'); - first = req.outputData[0].data; - endOfHeaders = first.indexOf('\r\n\r\n') + 4; - req.outputData[0].data = - req._header + first.substring(endOfHeaders); - debug('Output buffer: %o', req.outputData[0].data); - } - } - // Wait for the socket's `connect` event, so that this `callback()` - // function throws instead of the `http` request machinery. This is - // important for i.e. `PacProxyAgent` which determines a failed proxy - // connection via the `callback()` function throwing. - yield (0, once_1.default)(socket, 'connect'); - return socket; - }); - } -} -exports.default = HttpProxyAgent; -//# sourceMappingURL=agent.js.map \ No newline at end of file diff --git a/node_modules/http-proxy-agent/dist/agent.js.map b/node_modules/http-proxy-agent/dist/agent.js.map deleted file mode 100644 index bd3b56aa6dfdb..0000000000000 --- a/node_modules/http-proxy-agent/dist/agent.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,8CAAsB;AACtB,8CAAsB;AACtB,8CAAsB;AACtB,kDAAgC;AAChC,6DAAqC;AACrC,2CAAkE;AAGlE,MAAM,KAAK,GAAG,IAAA,eAAW,EAAC,kBAAkB,CAAC,CAAC;AAY9C,SAAS,OAAO,CAAC,QAAwB;IACxC,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3E,CAAC;AAED;;;;;GAKG;AACH,MAAqB,cAAe,SAAQ,kBAAK;IAIhD,YAAY,KAAqC;QAChD,IAAI,IAA2B,CAAC;QAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC9B,IAAI,GAAG,aAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACxB;aAAM;YACN,IAAI,GAAG,KAAK,CAAC;SACb;QACD,IAAI,CAAC,IAAI,EAAE;YACV,MAAM,IAAI,KAAK,CACd,8DAA8D,CAC9D,CAAC;SACF;QACD,KAAK,CAAC,0CAA0C,EAAE,IAAI,CAAC,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,CAAC;QAEZ,MAAM,KAAK,qBAA+B,IAAI,CAAE,CAAC;QAEjD,wDAAwD;QACxD,uBAAuB;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE/D,+DAA+D;QAC/D,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC;QAC1C,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;YACnC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;SACtC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YAC9B,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;SACzC;QAED,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YAC7B,kEAAkE;YAClE,8DAA8D;YAC9D,iEAAiE;YACjE,8BAA8B;YAC9B,OAAO,KAAK,CAAC,IAAI,CAAC;YAClB,OAAO,KAAK,CAAC,QAAQ,CAAC;SACtB;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACG,QAAQ,CACb,GAAgC,EAChC,IAAoB;;YAEpB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;YACpC,MAAM,MAAM,GAAG,aAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAEnC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACrB,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC;aAC1B;YAED,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACrB,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;aACrD;YAED,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,EAAE;gBAC5C,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAChC;YAED,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE;gBACzB,yDAAyD;gBACzD,2CAA2C;gBAC3C,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;aACjB;YAED,0DAA0D;YAC1D,0DAA0D;YAC1D,GAAG,CAAC,IAAI,GAAG,aAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAE9B,wDAAwD;YACxD,IAAI,KAAK,CAAC,IAAI,EAAE;gBACf,GAAG,CAAC,SAAS,CACZ,qBAAqB,EACrB,SAAS,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CACrD,CAAC;aACF;YAED,kDAAkD;YAClD,IAAI,MAAkB,CAAC;YACvB,IAAI,WAAW,EAAE;gBAChB,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,GAAG,aAAG,CAAC,OAAO,CAAC,KAA8B,CAAC,CAAC;aACrD;iBAAM;gBACN,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,GAAG,aAAG,CAAC,OAAO,CAAC,KAA2B,CAAC,CAAC;aAClD;YAED,mEAAmE;YACnE,mEAAmE;YACnE,kEAAkE;YAClE,IAAI,GAAG,CAAC,OAAO,EAAE;gBAChB,IAAI,KAAa,CAAC;gBAClB,IAAI,YAAoB,CAAC;gBACzB,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBAC5D,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;gBACnB,GAAG,CAAC,eAAe,EAAE,CAAC;gBACtB,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;oBACxC,YAAY;oBACZ,KAAK,CACJ,+DAA+D,CAC/D,CAAC;oBACF,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oBACtB,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC7C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBAC5D,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;iBACvC;qBAAM,IAAI,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;oBACvD,aAAa;oBACb,KAAK,CACJ,+DAA+D,CAC/D,CAAC;oBACF,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBAC/B,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC7C,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;wBACrB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBAC7C,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;iBACnD;aACD;YAED,mEAAmE;YACnE,mEAAmE;YACnE,qEAAqE;YACrE,qDAAqD;YACrD,MAAM,IAAA,cAAI,EAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAE9B,OAAO,MAAM,CAAC;QACf,CAAC;KAAA;CACD;AA1ID,iCA0IC"} \ No newline at end of file diff --git a/node_modules/http-proxy-agent/dist/index.d.ts b/node_modules/http-proxy-agent/dist/index.d.ts deleted file mode 100644 index 24bdb52efcedc..0000000000000 --- a/node_modules/http-proxy-agent/dist/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -/// <reference types="node" /> -import net from 'net'; -import tls from 'tls'; -import { Url } from 'url'; -import { AgentOptions } from 'agent-base'; -import _HttpProxyAgent from './agent'; -declare function createHttpProxyAgent(opts: string | createHttpProxyAgent.HttpProxyAgentOptions): _HttpProxyAgent; -declare namespace createHttpProxyAgent { - interface BaseHttpProxyAgentOptions { - secureProxy?: boolean; - host?: string | null; - path?: string | null; - port?: string | number | null; - } - export interface HttpProxyAgentOptions extends AgentOptions, BaseHttpProxyAgentOptions, Partial<Omit<Url & net.NetConnectOpts & tls.ConnectionOptions, keyof BaseHttpProxyAgentOptions>> { - } - export type HttpProxyAgent = _HttpProxyAgent; - export const HttpProxyAgent: typeof _HttpProxyAgent; - export {}; -} -export = createHttpProxyAgent; diff --git a/node_modules/http-proxy-agent/dist/index.js b/node_modules/http-proxy-agent/dist/index.js index 0a71180594605..fb2751c226431 100644 --- a/node_modules/http-proxy-agent/dist/index.js +++ b/node_modules/http-proxy-agent/dist/index.js @@ -1,14 +1,148 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; -const agent_1 = __importDefault(require("./agent")); -function createHttpProxyAgent(opts) { - return new agent_1.default(opts); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HttpProxyAgent = void 0; +const net = __importStar(require("net")); +const tls = __importStar(require("tls")); +const debug_1 = __importDefault(require("debug")); +const events_1 = require("events"); +const agent_base_1 = require("agent-base"); +const url_1 = require("url"); +const debug = (0, debug_1.default)('http-proxy-agent'); +/** + * The `HttpProxyAgent` implements an HTTP Agent subclass that connects + * to the specified "HTTP proxy server" in order to proxy HTTP requests. + */ +class HttpProxyAgent extends agent_base_1.Agent { + constructor(proxy, opts) { + super(opts); + this.proxy = typeof proxy === 'string' ? new url_1.URL(proxy) : proxy; + this.proxyHeaders = opts?.headers ?? {}; + debug('Creating new HttpProxyAgent instance: %o', this.proxy.href); + // Trim off the brackets from IPv6 addresses + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ''); + const port = this.proxy.port + ? parseInt(this.proxy.port, 10) + : this.proxy.protocol === 'https:' + ? 443 + : 80; + this.connectOpts = { + ...(opts ? omit(opts, 'headers') : null), + host, + port, + }; + } + addRequest(req, opts) { + req._header = null; + this.setRequestProps(req, opts); + // @ts-expect-error `addRequest()` isn't defined in `@types/node` + super.addRequest(req, opts); + } + setRequestProps(req, opts) { + const { proxy } = this; + const protocol = opts.secureEndpoint ? 'https:' : 'http:'; + const hostname = req.getHeader('host') || 'localhost'; + const base = `${protocol}//${hostname}`; + const url = new url_1.URL(req.path, base); + if (opts.port !== 80) { + url.port = String(opts.port); + } + // Change the `http.ClientRequest` instance's "path" field + // to the absolute path of the URL that will be requested. + req.path = String(url); + // Inject the `Proxy-Authorization` header if necessary. + const headers = typeof this.proxyHeaders === 'function' + ? this.proxyHeaders() + : { ...this.proxyHeaders }; + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; + } + if (!headers['Proxy-Connection']) { + headers['Proxy-Connection'] = this.keepAlive + ? 'Keep-Alive' + : 'close'; + } + for (const name of Object.keys(headers)) { + const value = headers[name]; + if (value) { + req.setHeader(name, value); + } + } + } + async connect(req, opts) { + req._header = null; + if (!req.path.includes('://')) { + this.setRequestProps(req, opts); + } + // At this point, the http ClientRequest's internal `_header` field + // might have already been set. If this is the case then we'll need + // to re-generate the string since we just changed the `req.path`. + let first; + let endOfHeaders; + debug('Regenerating stored HTTP header string for request'); + req._implicitHeader(); + if (req.outputData && req.outputData.length > 0) { + debug('Patching connection write() output buffer with updated header'); + first = req.outputData[0].data; + endOfHeaders = first.indexOf('\r\n\r\n') + 4; + req.outputData[0].data = + req._header + first.substring(endOfHeaders); + debug('Output buffer: %o', req.outputData[0].data); + } + // Create a socket connection to the proxy server. + let socket; + if (this.proxy.protocol === 'https:') { + debug('Creating `tls.Socket`: %o', this.connectOpts); + socket = tls.connect(this.connectOpts); + } + else { + debug('Creating `net.Socket`: %o', this.connectOpts); + socket = net.connect(this.connectOpts); + } + // Wait for the socket's `connect` event, so that this `callback()` + // function throws instead of the `http` request machinery. This is + // important for i.e. `PacProxyAgent` which determines a failed proxy + // connection via the `callback()` function throwing. + await (0, events_1.once)(socket, 'connect'); + return socket; + } +} +HttpProxyAgent.protocols = ['http', 'https']; +exports.HttpProxyAgent = HttpProxyAgent; +function omit(obj, ...keys) { + const ret = {}; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; + } + } + return ret; } -(function (createHttpProxyAgent) { - createHttpProxyAgent.HttpProxyAgent = agent_1.default; - createHttpProxyAgent.prototype = agent_1.default.prototype; -})(createHttpProxyAgent || (createHttpProxyAgent = {})); -module.exports = createHttpProxyAgent; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/http-proxy-agent/dist/index.js.map b/node_modules/http-proxy-agent/dist/index.js.map deleted file mode 100644 index e07dae5b08455..0000000000000 --- a/node_modules/http-proxy-agent/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAIA,oDAAsC;AAEtC,SAAS,oBAAoB,CAC5B,IAAyD;IAEzD,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,WAAU,oBAAoB;IAmBhB,mCAAc,GAAG,eAAe,CAAC;IAE9C,oBAAoB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;AAC5D,CAAC,EAtBS,oBAAoB,KAApB,oBAAoB,QAsB7B;AAED,iBAAS,oBAAoB,CAAC"} \ No newline at end of file diff --git a/node_modules/http-proxy-agent/package.json b/node_modules/http-proxy-agent/package.json index 659d6e11e80e4..a53940a3d88a3 100644 --- a/node_modules/http-proxy-agent/package.json +++ b/node_modules/http-proxy-agent/package.json @@ -1,22 +1,16 @@ { "name": "http-proxy-agent", - "version": "5.0.0", + "version": "7.0.2", "description": "An HTTP(s) proxy `http.Agent` implementation for HTTP", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], - "scripts": { - "prebuild": "rimraf dist", - "build": "tsc", - "test": "mocha", - "test-lint": "eslint src --ext .js,.ts", - "prepublishOnly": "npm run build" - }, "repository": { "type": "git", - "url": "git://github.com/TooTallNate/node-http-proxy-agent.git" + "url": "https://github.com/TooTallNate/proxy-agents.git", + "directory": "packages/http-proxy-agent" }, "keywords": [ "http", @@ -26,32 +20,28 @@ ], "author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)", "license": "MIT", - "bugs": { - "url": "https://github.com/TooTallNate/node-http-proxy-agent/issues" - }, "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "devDependencies": { - "@types/debug": "4", - "@types/node": "^12.19.2", - "@typescript-eslint/eslint-plugin": "1.6.0", - "@typescript-eslint/parser": "1.1.0", - "eslint": "5.16.0", - "eslint-config-airbnb": "17.1.0", - "eslint-config-prettier": "4.1.0", - "eslint-import-resolver-typescript": "1.1.1", - "eslint-plugin-import": "2.16.0", - "eslint-plugin-jsx-a11y": "6.2.1", - "eslint-plugin-react": "7.12.4", - "mocha": "^6.2.2", - "proxy": "1", - "rimraf": "^3.0.0", - "typescript": "^4.4.3" + "@types/debug": "^4.1.7", + "@types/jest": "^29.5.1", + "@types/node": "^14.18.45", + "async-listen": "^3.0.0", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "typescript": "^5.0.4", + "proxy": "2.1.1", + "tsconfig": "0.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 14" + }, + "scripts": { + "build": "tsc", + "test": "jest --env node --verbose --bail", + "lint": "eslint . --ext .ts", + "pack": "node ../../scripts/pack.mjs" } -} +} \ No newline at end of file diff --git a/node_modules/https-proxy-agent/LICENSE b/node_modules/https-proxy-agent/LICENSE new file mode 100644 index 0000000000000..008728cb51847 --- /dev/null +++ b/node_modules/https-proxy-agent/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> + +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. \ No newline at end of file diff --git a/node_modules/https-proxy-agent/dist/agent.d.ts b/node_modules/https-proxy-agent/dist/agent.d.ts deleted file mode 100644 index 4f1c63624117f..0000000000000 --- a/node_modules/https-proxy-agent/dist/agent.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -/// <reference types="node" /> -import net from 'net'; -import { Agent, ClientRequest, RequestOptions } from 'agent-base'; -import { HttpsProxyAgentOptions } from '.'; -/** - * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to - * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. - * - * Outgoing HTTP requests are first tunneled through the proxy server using the - * `CONNECT` HTTP request method to establish a connection to the proxy server, - * and then the proxy server connects to the destination target and issues the - * HTTP request from the proxy server. - * - * `https:` requests have their socket connection upgraded to TLS once - * the connection to the proxy server has been established. - * - * @api public - */ -export default class HttpsProxyAgent extends Agent { - private secureProxy; - private proxy; - constructor(_opts: string | HttpsProxyAgentOptions); - /** - * Called when the node-core HTTP client library is creating a - * new HTTP request. - * - * @api protected - */ - callback(req: ClientRequest, opts: RequestOptions): Promise<net.Socket>; -} diff --git a/node_modules/https-proxy-agent/dist/agent.js b/node_modules/https-proxy-agent/dist/agent.js deleted file mode 100644 index 75d11364ed300..0000000000000 --- a/node_modules/https-proxy-agent/dist/agent.js +++ /dev/null @@ -1,177 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const net_1 = __importDefault(require("net")); -const tls_1 = __importDefault(require("tls")); -const url_1 = __importDefault(require("url")); -const assert_1 = __importDefault(require("assert")); -const debug_1 = __importDefault(require("debug")); -const agent_base_1 = require("agent-base"); -const parse_proxy_response_1 = __importDefault(require("./parse-proxy-response")); -const debug = debug_1.default('https-proxy-agent:agent'); -/** - * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to - * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. - * - * Outgoing HTTP requests are first tunneled through the proxy server using the - * `CONNECT` HTTP request method to establish a connection to the proxy server, - * and then the proxy server connects to the destination target and issues the - * HTTP request from the proxy server. - * - * `https:` requests have their socket connection upgraded to TLS once - * the connection to the proxy server has been established. - * - * @api public - */ -class HttpsProxyAgent extends agent_base_1.Agent { - constructor(_opts) { - let opts; - if (typeof _opts === 'string') { - opts = url_1.default.parse(_opts); - } - else { - opts = _opts; - } - if (!opts) { - throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!'); - } - debug('creating new HttpsProxyAgent instance: %o', opts); - super(opts); - const proxy = Object.assign({}, opts); - // If `true`, then connect to the proxy server over TLS. - // Defaults to `false`. - this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol); - // Prefer `hostname` over `host`, and set the `port` if needed. - proxy.host = proxy.hostname || proxy.host; - if (typeof proxy.port === 'string') { - proxy.port = parseInt(proxy.port, 10); - } - if (!proxy.port && proxy.host) { - proxy.port = this.secureProxy ? 443 : 80; - } - // ALPN is supported by Node.js >= v5. - // attempt to negotiate http/1.1 for proxy servers that support http/2 - if (this.secureProxy && !('ALPNProtocols' in proxy)) { - proxy.ALPNProtocols = ['http 1.1']; - } - if (proxy.host && proxy.path) { - // If both a `host` and `path` are specified then it's most likely - // the result of a `url.parse()` call... we need to remove the - // `path` portion so that `net.connect()` doesn't attempt to open - // that as a Unix socket file. - delete proxy.path; - delete proxy.pathname; - } - this.proxy = proxy; - } - /** - * Called when the node-core HTTP client library is creating a - * new HTTP request. - * - * @api protected - */ - callback(req, opts) { - return __awaiter(this, void 0, void 0, function* () { - const { proxy, secureProxy } = this; - // Create a socket connection to the proxy server. - let socket; - if (secureProxy) { - debug('Creating `tls.Socket`: %o', proxy); - socket = tls_1.default.connect(proxy); - } - else { - debug('Creating `net.Socket`: %o', proxy); - socket = net_1.default.connect(proxy); - } - const headers = Object.assign({}, proxy.headers); - const hostname = `${opts.host}:${opts.port}`; - let payload = `CONNECT ${hostname} HTTP/1.1\r\n`; - // Inject the `Proxy-Authorization` header if necessary. - if (proxy.auth) { - headers['Proxy-Authorization'] = `Basic ${Buffer.from(proxy.auth).toString('base64')}`; - } - // The `Host` header should only include the port - // number when it is not the default port. - let { host, port, secureEndpoint } = opts; - if (!isDefaultPort(port, secureEndpoint)) { - host += `:${port}`; - } - headers.Host = host; - headers.Connection = 'close'; - for (const name of Object.keys(headers)) { - payload += `${name}: ${headers[name]}\r\n`; - } - const proxyResponsePromise = parse_proxy_response_1.default(socket); - socket.write(`${payload}\r\n`); - const { statusCode, buffered } = yield proxyResponsePromise; - if (statusCode === 200) { - req.once('socket', resume); - if (opts.secureEndpoint) { - // The proxy is connecting to a TLS server, so upgrade - // this socket connection to a TLS connection. - debug('Upgrading socket connection to TLS'); - const servername = opts.servername || opts.host; - return tls_1.default.connect(Object.assign(Object.assign({}, omit(opts, 'host', 'hostname', 'path', 'port')), { socket, - servername })); - } - return socket; - } - // Some other status code that's not 200... need to re-play the HTTP - // header "data" events onto the socket once the HTTP machinery is - // attached so that the node core `http` can parse and handle the - // error status code. - // Close the original socket, and a new "fake" socket is returned - // instead, so that the proxy doesn't get the HTTP request - // written to it (which may contain `Authorization` headers or other - // sensitive data). - // - // See: https://hackerone.com/reports/541502 - socket.destroy(); - const fakeSocket = new net_1.default.Socket({ writable: false }); - fakeSocket.readable = true; - // Need to wait for the "socket" event to re-play the "data" events. - req.once('socket', (s) => { - debug('replaying proxy buffer for failed request'); - assert_1.default(s.listenerCount('data') > 0); - // Replay the "buffered" Buffer onto the fake `socket`, since at - // this point the HTTP module machinery has been hooked up for - // the user. - s.push(buffered); - s.push(null); - }); - return fakeSocket; - }); - } -} -exports.default = HttpsProxyAgent; -function resume(socket) { - socket.resume(); -} -function isDefaultPort(port, secure) { - return Boolean((!secure && port === 80) || (secure && port === 443)); -} -function isHTTPS(protocol) { - return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false; -} -function omit(obj, ...keys) { - const ret = {}; - let key; - for (key in obj) { - if (!keys.includes(key)) { - ret[key] = obj[key]; - } - } - return ret; -} -//# sourceMappingURL=agent.js.map \ No newline at end of file diff --git a/node_modules/https-proxy-agent/dist/agent.js.map b/node_modules/https-proxy-agent/dist/agent.js.map deleted file mode 100644 index 0af6c17a3e78a..0000000000000 --- a/node_modules/https-proxy-agent/dist/agent.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,8CAAsB;AACtB,8CAAsB;AACtB,8CAAsB;AACtB,oDAA4B;AAC5B,kDAAgC;AAEhC,2CAAkE;AAElE,kFAAwD;AAExD,MAAM,KAAK,GAAG,eAAW,CAAC,yBAAyB,CAAC,CAAC;AAErD;;;;;;;;;;;;;GAaG;AACH,MAAqB,eAAgB,SAAQ,kBAAK;IAIjD,YAAY,KAAsC;QACjD,IAAI,IAA4B,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC9B,IAAI,GAAG,aAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SACxB;aAAM;YACN,IAAI,GAAG,KAAK,CAAC;SACb;QACD,IAAI,CAAC,IAAI,EAAE;YACV,MAAM,IAAI,KAAK,CACd,8DAA8D,CAC9D,CAAC;SACF;QACD,KAAK,CAAC,2CAA2C,EAAE,IAAI,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,CAAC;QAEZ,MAAM,KAAK,qBAAgC,IAAI,CAAE,CAAC;QAElD,wDAAwD;QACxD,uBAAuB;QACvB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE/D,+DAA+D;QAC/D,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC;QAC1C,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;YACnC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;SACtC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YAC9B,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;SACzC;QAED,sCAAsC;QACtC,sEAAsE;QACtE,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,eAAe,IAAI,KAAK,CAAC,EAAE;YACpD,KAAK,CAAC,aAAa,GAAG,CAAC,UAAU,CAAC,CAAC;SACnC;QAED,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;YAC7B,kEAAkE;YAClE,8DAA8D;YAC9D,iEAAiE;YACjE,8BAA8B;YAC9B,OAAO,KAAK,CAAC,IAAI,CAAC;YAClB,OAAO,KAAK,CAAC,QAAQ,CAAC;SACtB;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACG,QAAQ,CACb,GAAkB,EAClB,IAAoB;;YAEpB,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;YAEpC,kDAAkD;YAClD,IAAI,MAAkB,CAAC;YACvB,IAAI,WAAW,EAAE;gBAChB,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,GAAG,aAAG,CAAC,OAAO,CAAC,KAA8B,CAAC,CAAC;aACrD;iBAAM;gBACN,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;gBAC1C,MAAM,GAAG,aAAG,CAAC,OAAO,CAAC,KAA2B,CAAC,CAAC;aAClD;YAED,MAAM,OAAO,qBAA6B,KAAK,CAAC,OAAO,CAAE,CAAC;YAC1D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7C,IAAI,OAAO,GAAG,WAAW,QAAQ,eAAe,CAAC;YAEjD,wDAAwD;YACxD,IAAI,KAAK,CAAC,IAAI,EAAE;gBACf,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,MAAM,CAAC,IAAI,CACpD,KAAK,CAAC,IAAI,CACV,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;aACvB;YAED,iDAAiD;YACjD,0CAA0C;YAC1C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;YAC1C,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE;gBACzC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;aACnB;YACD,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YAEpB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;YAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBACxC,OAAO,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;aAC3C;YAED,MAAM,oBAAoB,GAAG,8BAAkB,CAAC,MAAM,CAAC,CAAC;YAExD,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;YAE/B,MAAM,EACL,UAAU,EACV,QAAQ,EACR,GAAG,MAAM,oBAAoB,CAAC;YAE/B,IAAI,UAAU,KAAK,GAAG,EAAE;gBACvB,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAE3B,IAAI,IAAI,CAAC,cAAc,EAAE;oBACxB,sDAAsD;oBACtD,8CAA8C;oBAC9C,KAAK,CAAC,oCAAoC,CAAC,CAAC;oBAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC;oBAChD,OAAO,aAAG,CAAC,OAAO,iCACd,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,KACjD,MAAM;wBACN,UAAU,IACT,CAAC;iBACH;gBAED,OAAO,MAAM,CAAC;aACd;YAED,oEAAoE;YACpE,kEAAkE;YAClE,iEAAiE;YACjE,qBAAqB;YAErB,iEAAiE;YACjE,0DAA0D;YAC1D,oEAAoE;YACpE,mBAAmB;YACnB,EAAE;YACF,4CAA4C;YAC5C,MAAM,CAAC,OAAO,EAAE,CAAC;YAEjB,MAAM,UAAU,GAAG,IAAI,aAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YACvD,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC;YAE3B,oEAAoE;YACpE,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAa,EAAE,EAAE;gBACpC,KAAK,CAAC,2CAA2C,CAAC,CAAC;gBACnD,gBAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAEpC,gEAAgE;gBAChE,8DAA8D;gBAC9D,YAAY;gBACZ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACjB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,OAAO,UAAU,CAAC;QACnB,CAAC;KAAA;CACD;AA3JD,kCA2JC;AAED,SAAS,MAAM,CAAC,MAAkC;IACjD,MAAM,CAAC,MAAM,EAAE,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,MAAe;IACnD,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,OAAO,CAAC,QAAwB;IACxC,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3E,CAAC;AAED,SAAS,IAAI,CACZ,GAAM,EACN,GAAG,IAAO;IAIV,MAAM,GAAG,GAAG,EAEX,CAAC;IACF,IAAI,GAAqB,CAAC;IAC1B,KAAK,GAAG,IAAI,GAAG,EAAE;QAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;SACpB;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"} \ No newline at end of file diff --git a/node_modules/https-proxy-agent/dist/index.d.ts b/node_modules/https-proxy-agent/dist/index.d.ts deleted file mode 100644 index 0d60062ee2079..0000000000000 --- a/node_modules/https-proxy-agent/dist/index.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/// <reference types="node" /> -import net from 'net'; -import tls from 'tls'; -import { Url } from 'url'; -import { AgentOptions } from 'agent-base'; -import { OutgoingHttpHeaders } from 'http'; -import _HttpsProxyAgent from './agent'; -declare function createHttpsProxyAgent(opts: string | createHttpsProxyAgent.HttpsProxyAgentOptions): _HttpsProxyAgent; -declare namespace createHttpsProxyAgent { - interface BaseHttpsProxyAgentOptions { - headers?: OutgoingHttpHeaders; - secureProxy?: boolean; - host?: string | null; - path?: string | null; - port?: string | number | null; - } - export interface HttpsProxyAgentOptions extends AgentOptions, BaseHttpsProxyAgentOptions, Partial<Omit<Url & net.NetConnectOpts & tls.ConnectionOptions, keyof BaseHttpsProxyAgentOptions>> { - } - export type HttpsProxyAgent = _HttpsProxyAgent; - export const HttpsProxyAgent: typeof _HttpsProxyAgent; - export {}; -} -export = createHttpsProxyAgent; diff --git a/node_modules/https-proxy-agent/dist/index.js b/node_modules/https-proxy-agent/dist/index.js index b03e7631a45a4..1857f464724e2 100644 --- a/node_modules/https-proxy-agent/dist/index.js +++ b/node_modules/https-proxy-agent/dist/index.js @@ -1,14 +1,180 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; -const agent_1 = __importDefault(require("./agent")); -function createHttpsProxyAgent(opts) { - return new agent_1.default(opts); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HttpsProxyAgent = void 0; +const net = __importStar(require("net")); +const tls = __importStar(require("tls")); +const assert_1 = __importDefault(require("assert")); +const debug_1 = __importDefault(require("debug")); +const agent_base_1 = require("agent-base"); +const url_1 = require("url"); +const parse_proxy_response_1 = require("./parse-proxy-response"); +const debug = (0, debug_1.default)('https-proxy-agent'); +const setServernameFromNonIpHost = (options) => { + if (options.servername === undefined && + options.host && + !net.isIP(options.host)) { + return { + ...options, + servername: options.host, + }; + } + return options; +}; +/** + * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to + * the specified "HTTP(s) proxy server" in order to proxy HTTPS requests. + * + * Outgoing HTTP requests are first tunneled through the proxy server using the + * `CONNECT` HTTP request method to establish a connection to the proxy server, + * and then the proxy server connects to the destination target and issues the + * HTTP request from the proxy server. + * + * `https:` requests have their socket connection upgraded to TLS once + * the connection to the proxy server has been established. + */ +class HttpsProxyAgent extends agent_base_1.Agent { + constructor(proxy, opts) { + super(opts); + this.options = { path: undefined }; + this.proxy = typeof proxy === 'string' ? new url_1.URL(proxy) : proxy; + this.proxyHeaders = opts?.headers ?? {}; + debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href); + // Trim off the brackets from IPv6 addresses + const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ''); + const port = this.proxy.port + ? parseInt(this.proxy.port, 10) + : this.proxy.protocol === 'https:' + ? 443 + : 80; + this.connectOpts = { + // Attempt to negotiate http/1.1 for proxy servers that support http/2 + ALPNProtocols: ['http/1.1'], + ...(opts ? omit(opts, 'headers') : null), + host, + port, + }; + } + /** + * Called when the node-core HTTP client library is creating a + * new HTTP request. + */ + async connect(req, opts) { + const { proxy } = this; + if (!opts.host) { + throw new TypeError('No "host" provided'); + } + // Create a socket connection to the proxy server. + let socket; + if (proxy.protocol === 'https:') { + debug('Creating `tls.Socket`: %o', this.connectOpts); + socket = tls.connect(setServernameFromNonIpHost(this.connectOpts)); + } + else { + debug('Creating `net.Socket`: %o', this.connectOpts); + socket = net.connect(this.connectOpts); + } + const headers = typeof this.proxyHeaders === 'function' + ? this.proxyHeaders() + : { ...this.proxyHeaders }; + const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host; + let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`; + // Inject the `Proxy-Authorization` header if necessary. + if (proxy.username || proxy.password) { + const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; + headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; + } + headers.Host = `${host}:${opts.port}`; + if (!headers['Proxy-Connection']) { + headers['Proxy-Connection'] = this.keepAlive + ? 'Keep-Alive' + : 'close'; + } + for (const name of Object.keys(headers)) { + payload += `${name}: ${headers[name]}\r\n`; + } + const proxyResponsePromise = (0, parse_proxy_response_1.parseProxyResponse)(socket); + socket.write(`${payload}\r\n`); + const { connect, buffered } = await proxyResponsePromise; + req.emit('proxyConnect', connect); + this.emit('proxyConnect', connect, req); + if (connect.statusCode === 200) { + req.once('socket', resume); + if (opts.secureEndpoint) { + // The proxy is connecting to a TLS server, so upgrade + // this socket connection to a TLS connection. + debug('Upgrading socket connection to TLS'); + return tls.connect({ + ...omit(setServernameFromNonIpHost(opts), 'host', 'path', 'port'), + socket, + }); + } + return socket; + } + // Some other status code that's not 200... need to re-play the HTTP + // header "data" events onto the socket once the HTTP machinery is + // attached so that the node core `http` can parse and handle the + // error status code. + // Close the original socket, and a new "fake" socket is returned + // instead, so that the proxy doesn't get the HTTP request + // written to it (which may contain `Authorization` headers or other + // sensitive data). + // + // See: https://hackerone.com/reports/541502 + socket.destroy(); + const fakeSocket = new net.Socket({ writable: false }); + fakeSocket.readable = true; + // Need to wait for the "socket" event to re-play the "data" events. + req.once('socket', (s) => { + debug('Replaying proxy buffer for failed request'); + (0, assert_1.default)(s.listenerCount('data') > 0); + // Replay the "buffered" Buffer onto the fake `socket`, since at + // this point the HTTP module machinery has been hooked up for + // the user. + s.push(buffered); + s.push(null); + }); + return fakeSocket; + } +} +HttpsProxyAgent.protocols = ['http', 'https']; +exports.HttpsProxyAgent = HttpsProxyAgent; +function resume(socket) { + socket.resume(); +} +function omit(obj, ...keys) { + const ret = {}; + let key; + for (key in obj) { + if (!keys.includes(key)) { + ret[key] = obj[key]; + } + } + return ret; } -(function (createHttpsProxyAgent) { - createHttpsProxyAgent.HttpsProxyAgent = agent_1.default; - createHttpsProxyAgent.prototype = agent_1.default.prototype; -})(createHttpsProxyAgent || (createHttpsProxyAgent = {})); -module.exports = createHttpsProxyAgent; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/https-proxy-agent/dist/index.js.map b/node_modules/https-proxy-agent/dist/index.js.map deleted file mode 100644 index f3ce559de0200..0000000000000 --- a/node_modules/https-proxy-agent/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAKA,oDAAuC;AAEvC,SAAS,qBAAqB,CAC7B,IAA2D;IAE3D,OAAO,IAAI,eAAgB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,WAAU,qBAAqB;IAoBjB,qCAAe,GAAG,eAAgB,CAAC;IAEhD,qBAAqB,CAAC,SAAS,GAAG,eAAgB,CAAC,SAAS,CAAC;AAC9D,CAAC,EAvBS,qBAAqB,KAArB,qBAAqB,QAuB9B;AAED,iBAAS,qBAAqB,CAAC"} \ No newline at end of file diff --git a/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts b/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts deleted file mode 100644 index 7565674a338cb..0000000000000 --- a/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/// <reference types="node" /> -import { Readable } from 'stream'; -export interface ProxyResponse { - statusCode: number; - buffered: Buffer; -} -export default function parseProxyResponse(socket: Readable): Promise<ProxyResponse>; diff --git a/node_modules/https-proxy-agent/dist/parse-proxy-response.js b/node_modules/https-proxy-agent/dist/parse-proxy-response.js index aa5ce3cc2d371..d3f506f941306 100644 --- a/node_modules/https-proxy-agent/dist/parse-proxy-response.js +++ b/node_modules/https-proxy-agent/dist/parse-proxy-response.js @@ -3,8 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.parseProxyResponse = void 0; const debug_1 = __importDefault(require("debug")); -const debug = debug_1.default('https-proxy-agent:parse-proxy-response'); +const debug = (0, debug_1.default)('https-proxy-agent:parse-proxy-response'); function parseProxyResponse(socket) { return new Promise((resolve, reject) => { // we need to buffer any HTTP traffic that happens with the proxy before we get @@ -23,14 +24,12 @@ function parseProxyResponse(socket) { function cleanup() { socket.removeListener('end', onend); socket.removeListener('error', onerror); - socket.removeListener('close', onclose); socket.removeListener('readable', read); } - function onclose(err) { - debug('onclose had error %o', err); - } function onend() { + cleanup(); debug('onend'); + reject(new Error('Proxy connection ended before receiving CONNECT response')); } function onerror(err) { cleanup(); @@ -48,19 +47,55 @@ function parseProxyResponse(socket) { read(); return; } - const firstLine = buffered.toString('ascii', 0, buffered.indexOf('\r\n')); - const statusCode = +firstLine.split(' ')[1]; - debug('got proxy server response: %o', firstLine); + const headerParts = buffered + .slice(0, endOfHeaders) + .toString('ascii') + .split('\r\n'); + const firstLine = headerParts.shift(); + if (!firstLine) { + socket.destroy(); + return reject(new Error('No header received from proxy CONNECT response')); + } + const firstLineParts = firstLine.split(' '); + const statusCode = +firstLineParts[1]; + const statusText = firstLineParts.slice(2).join(' '); + const headers = {}; + for (const header of headerParts) { + if (!header) + continue; + const firstColon = header.indexOf(':'); + if (firstColon === -1) { + socket.destroy(); + return reject(new Error(`Invalid header from proxy CONNECT response: "${header}"`)); + } + const key = header.slice(0, firstColon).toLowerCase(); + const value = header.slice(firstColon + 1).trimStart(); + const current = headers[key]; + if (typeof current === 'string') { + headers[key] = [current, value]; + } + else if (Array.isArray(current)) { + current.push(value); + } + else { + headers[key] = value; + } + } + debug('got proxy server response: %o %o', firstLine, headers); + cleanup(); resolve({ - statusCode, - buffered + connect: { + statusCode, + statusText, + headers, + }, + buffered, }); } socket.on('error', onerror); - socket.on('close', onclose); socket.on('end', onend); read(); }); } -exports.default = parseProxyResponse; +exports.parseProxyResponse = parseProxyResponse; //# sourceMappingURL=parse-proxy-response.js.map \ No newline at end of file diff --git a/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map b/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map deleted file mode 100644 index bacdb84b9ec2f..0000000000000 --- a/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"parse-proxy-response.js","sourceRoot":"","sources":["../src/parse-proxy-response.ts"],"names":[],"mappings":";;;;;AAAA,kDAAgC;AAGhC,MAAM,KAAK,GAAG,eAAW,CAAC,wCAAwC,CAAC,CAAC;AAOpE,SAAwB,kBAAkB,CACzC,MAAgB;IAEhB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,+EAA+E;QAC/E,gFAAgF;QAChF,8EAA8E;QAC9E,8BAA8B;QAC9B,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,SAAS,IAAI;YACZ,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAC,CAAC;;gBACZ,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QAED,SAAS,OAAO;YACf,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACpC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,SAAS,OAAO,CAAC,GAAW;YAC3B,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;QACpC,CAAC;QAED,SAAS,KAAK;YACb,KAAK,CAAC,OAAO,CAAC,CAAC;QAChB,CAAC;QAED,SAAS,OAAO,CAAC,GAAU;YAC1B,OAAO,EAAE,CAAC;YACV,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;QAED,SAAS,MAAM,CAAC,CAAS;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,aAAa,IAAI,CAAC,CAAC,MAAM,CAAC;YAE1B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACvD,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAElD,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE;gBACxB,iBAAiB;gBACjB,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBACtD,IAAI,EAAE,CAAC;gBACP,OAAO;aACP;YAED,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAClC,OAAO,EACP,CAAC,EACD,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CACxB,CAAC;YACF,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,KAAK,CAAC,+BAA+B,EAAE,SAAS,CAAC,CAAC;YAClD,OAAO,CAAC;gBACP,UAAU;gBACV,QAAQ;aACR,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,EAAE,CAAC;IACR,CAAC,CAAC,CAAC;AACJ,CAAC;AAvED,qCAuEC"} \ No newline at end of file diff --git a/node_modules/https-proxy-agent/package.json b/node_modules/https-proxy-agent/package.json index fb2aba1b94695..51b7e1175ff51 100644 --- a/node_modules/https-proxy-agent/package.json +++ b/node_modules/https-proxy-agent/package.json @@ -1,22 +1,16 @@ { "name": "https-proxy-agent", - "version": "5.0.1", + "version": "7.0.6", "description": "An HTTP(s) proxy `http.Agent` implementation for HTTPS", - "main": "dist/index", - "types": "dist/index", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "files": [ "dist" ], - "scripts": { - "prebuild": "rimraf dist", - "build": "tsc", - "test": "mocha --reporter spec", - "test-lint": "eslint src --ext .js,.ts", - "prepublishOnly": "npm run build" - }, "repository": { "type": "git", - "url": "git://github.com/TooTallNate/node-https-proxy-agent.git" + "url": "https://github.com/TooTallNate/proxy-agents.git", + "directory": "packages/https-proxy-agent" }, "keywords": [ "https", @@ -26,31 +20,31 @@ ], "author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)", "license": "MIT", - "bugs": { - "url": "https://github.com/TooTallNate/node-https-proxy-agent/issues" - }, "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "devDependencies": { + "@types/async-retry": "^1.4.5", "@types/debug": "4", - "@types/node": "^12.12.11", - "@typescript-eslint/eslint-plugin": "1.6.0", - "@typescript-eslint/parser": "1.1.0", - "eslint": "5.16.0", - "eslint-config-airbnb": "17.1.0", - "eslint-config-prettier": "4.1.0", - "eslint-import-resolver-typescript": "1.1.1", - "eslint-plugin-import": "2.16.0", - "eslint-plugin-jsx-a11y": "6.2.1", - "eslint-plugin-react": "7.12.4", - "mocha": "^6.2.2", - "proxy": "1", - "rimraf": "^3.0.0", - "typescript": "^3.5.3" + "@types/jest": "^29.5.1", + "@types/node": "^14.18.45", + "async-listen": "^3.0.0", + "async-retry": "^1.3.3", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "typescript": "^5.0.4", + "proxy": "2.2.0", + "tsconfig": "0.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 14" + }, + "scripts": { + "build": "tsc", + "test": "jest --env node --verbose --bail test/test.ts", + "test-e2e": "jest --env node --verbose --bail test/e2e.test.ts", + "lint": "eslint --ext .ts", + "pack": "node ../../scripts/pack.mjs" } -} +} \ No newline at end of file diff --git a/node_modules/humanize-ms/History.md b/node_modules/humanize-ms/History.md deleted file mode 100644 index b159587050119..0000000000000 --- a/node_modules/humanize-ms/History.md +++ /dev/null @@ -1,25 +0,0 @@ - -1.2.1 / 2017-05-19 -================== - - * fix: package.json to reduce vulnerabilities (#3) - -1.2.0 / 2016-05-21 -================== - - * feat: warn with stack - -1.1.0 / 2016-04-04 -================== - - * deps: upgrade ms to 0.7.0 - -1.0.1 / 2014-12-31 -================== - - * feat(index.js): warn when result is undefined - -1.0.0 / 2014-08-14 -================== - - * init diff --git a/node_modules/humanize-ms/LICENSE b/node_modules/humanize-ms/LICENSE deleted file mode 100644 index 89de354795ec7..0000000000000 --- a/node_modules/humanize-ms/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/node_modules/humanize-ms/index.js b/node_modules/humanize-ms/index.js deleted file mode 100644 index 660df81def512..0000000000000 --- a/node_modules/humanize-ms/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * humanize-ms - index.js - * Copyright(c) 2014 dead_horse <dead_horse@qq.com> - * MIT Licensed - */ - -'use strict'; - -/** - * Module dependencies. - */ - -var util = require('util'); -var ms = require('ms'); - -module.exports = function (t) { - if (typeof t === 'number') return t; - var r = ms(t); - if (r === undefined) { - var err = new Error(util.format('humanize-ms(%j) result undefined', t)); - console.warn(err.stack); - } - return r; -}; diff --git a/node_modules/humanize-ms/package.json b/node_modules/humanize-ms/package.json deleted file mode 100644 index da4ab7f571a68..0000000000000 --- a/node_modules/humanize-ms/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "humanize-ms", - "version": "1.2.1", - "description": "transform humanize time to ms", - "main": "index.js", - "files": [ - "index.js" - ], - "scripts": { - "test": "make test" - }, - "keywords": [ - "humanize", - "ms" - ], - "author": { - "name": "dead-horse", - "email": "dead_horse@qq.com", - "url": "http://deadhorse.me" - }, - "repository": { - "type": "git", - "url": "https://github.com/node-modules/humanize-ms" - }, - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - }, - "devDependencies": { - "autod": "*", - "beautify-benchmark": "~0.2.4", - "benchmark": "~1.0.0", - "istanbul": "*", - "mocha": "*", - "should": "*" - } -} diff --git a/node_modules/iconv-lite/Changelog.md b/node_modules/iconv-lite/Changelog.md deleted file mode 100644 index 464549b148481..0000000000000 --- a/node_modules/iconv-lite/Changelog.md +++ /dev/null @@ -1,212 +0,0 @@ -## 0.6.3 / 2021-05-23 - * Fix HKSCS encoding to prefer Big5 codes if both Big5 and HKSCS codes are possible (#264) - - -## 0.6.2 / 2020-07-08 - * Support Uint8Array-s decoding without conversion to Buffers, plus fix an edge case. - - -## 0.6.1 / 2020-06-28 - * Support Uint8Array-s directly when decoding (#246, by @gyzerok) - * Unify package.json version ranges to be strictly semver-compatible (#241) - * Fix minor issue in UTF-32 decoder's endianness detection code. - - -## 0.6.0 / 2020-06-08 - * Updated 'gb18030' encoding to :2005 edition (see https://github.com/whatwg/encoding/issues/22). - * Removed `iconv.extendNodeEncodings()` mechanism. It was deprecated 5 years ago and didn't work - in recent Node versions. - * Reworked Streaming API behavior in browser environments to fix #204. Streaming API will be - excluded by default in browser packs, saving ~100Kb bundle size, unless enabled explicitly using - `iconv.enableStreamingAPI(require('stream'))`. - * Updates to development environment & tests: - * Added ./test/webpack private package to test complex new use cases that need custom environment. - It's tested as a separate job in Travis CI. - * Updated generation code for the new EUC-KR index file format from Encoding Standard. - * Removed Buffer() constructor in tests (#197 by @gabrielschulhof). - - -## 0.5.2 / 2020-06-08 - * Added `iconv.getEncoder()` and `iconv.getDecoder()` methods to typescript definitions (#229). - * Fixed semver version to 6.1.2 to support Node 8.x (by @tanandara). - * Capped iconv version to 2.x as 3.x has dropped support for older Node versions. - * Switched from instanbul to c8 for code coverage. - - -## 0.5.1 / 2020-01-18 - - * Added cp720 encoding (#221, by @kr-deps) - * (minor) Changed Changelog.md formatting to use h2. - - -## 0.5.0 / 2019-06-26 - - * Added UTF-32 encoding, both little-endian and big-endian variants (UTF-32LE, UTF32-BE). If endianness - is not provided for decoding, it's deduced automatically from the stream using a heuristic similar to - what we use in UTF-16. (great work in #216 by @kshetline) - * Several minor updates to README (#217 by @oldj, plus some more) - * Added Node versions 10 and 12 to Travis test harness. - - -## 0.4.24 / 2018-08-22 - - * Added MIK encoding (#196, by @Ivan-Kalatchev) - - -## 0.4.23 / 2018-05-07 - - * Fix deprecation warning in Node v10 due to the last usage of `new Buffer` (#185, by @felixbuenemann) - * Switched from NodeBuffer to Buffer in typings (#155 by @felixfbecker, #186 by @larssn) - - -## 0.4.22 / 2018-05-05 - - * Use older semver style for dependencies to be compatible with Node version 0.10 (#182, by @dougwilson) - * Fix tests to accomodate fixes in Node v10 (#182, by @dougwilson) - - -## 0.4.21 / 2018-04-06 - - * Fix encoding canonicalization (#156) - * Fix the paths in the "browser" field in package.json (#174 by @LMLB) - * Removed "contributors" section in package.json - see Git history instead. - - -## 0.4.20 / 2018-04-06 - - * Updated `new Buffer()` usages with recommended replacements as it's being deprecated in Node v10 (#176, #178 by @ChALkeR) - - -## 0.4.19 / 2017-09-09 - - * Fixed iso8859-1 codec regression in handling untranslatable characters (#162, caused by #147) - * Re-generated windows1255 codec, because it was updated in iconv project - * Fixed grammar in error message when iconv-lite is loaded with encoding other than utf8 - - -## 0.4.18 / 2017-06-13 - - * Fixed CESU-8 regression in Node v8. - - -## 0.4.17 / 2017-04-22 - - * Updated typescript definition file to support Angular 2 AoT mode (#153 by @larssn) - - -## 0.4.16 / 2017-04-22 - - * Added support for React Native (#150) - * Changed iso8859-1 encoding to usine internal 'binary' encoding, as it's the same thing (#147 by @mscdex) - * Fixed typo in Readme (#138 by @jiangzhuo) - * Fixed build for Node v6.10+ by making correct version comparison - * Added a warning if iconv-lite is loaded not as utf-8 (see #142) - - -## 0.4.15 / 2016-11-21 - - * Fixed typescript type definition (#137) - - -## 0.4.14 / 2016-11-20 - - * Preparation for v1.0 - * Added Node v6 and latest Node versions to Travis CI test rig - * Deprecated Node v0.8 support - * Typescript typings (@larssn) - * Fix encoding of Euro character in GB 18030 (inspired by @lygstate) - * Add ms prefix to dbcs windows encodings (@rokoroku) - - -## 0.4.13 / 2015-10-01 - - * Fix silly mistake in deprecation notice. - - -## 0.4.12 / 2015-09-26 - - * Node v4 support: - * Added CESU-8 decoding (#106) - * Added deprecation notice for `extendNodeEncodings` - * Added Travis tests for Node v4 and io.js latest (#105 by @Mithgol) - - -## 0.4.11 / 2015-07-03 - - * Added CESU-8 encoding. - - -## 0.4.10 / 2015-05-26 - - * Changed UTF-16 endianness heuristic to take into account any ASCII chars, not - just spaces. This should minimize the importance of "default" endianness. - - -## 0.4.9 / 2015-05-24 - - * Streamlined BOM handling: strip BOM by default, add BOM when encoding if - addBOM: true. Added docs to Readme. - * UTF16 now uses UTF16-LE by default. - * Fixed minor issue with big5 encoding. - * Added io.js testing on Travis; updated node-iconv version to test against. - Now we just skip testing SBCS encodings that node-iconv doesn't support. - * (internal refactoring) Updated codec interface to use classes. - * Use strict mode in all files. - - -## 0.4.8 / 2015-04-14 - - * added alias UNICODE-1-1-UTF-7 for UTF-7 encoding (#94) - - -## 0.4.7 / 2015-02-05 - - * stop official support of Node.js v0.8. Should still work, but no guarantees. - reason: Packages needed for testing are hard to get on Travis CI. - * work in environment where Object.prototype is monkey patched with enumerable - props (#89). - - -## 0.4.6 / 2015-01-12 - - * fix rare aliases of single-byte encodings (thanks @mscdex) - * double the timeout for dbcs tests to make them less flaky on travis - - -## 0.4.5 / 2014-11-20 - - * fix windows-31j and x-sjis encoding support (@nleush) - * minor fix: undefined variable reference when internal error happens - - -## 0.4.4 / 2014-07-16 - - * added encodings UTF-7 (RFC2152) and UTF-7-IMAP (RFC3501 Section 5.1.3) - * fixed streaming base64 encoding - - -## 0.4.3 / 2014-06-14 - - * added encodings UTF-16BE and UTF-16 with BOM - - -## 0.4.2 / 2014-06-12 - - * don't throw exception if `extendNodeEncodings()` is called more than once - - -## 0.4.1 / 2014-06-11 - - * codepage 808 added - - -## 0.4.0 / 2014-06-10 - - * code is rewritten from scratch - * all widespread encodings are supported - * streaming interface added - * browserify compatibility added - * (optional) extend core primitive encodings to make usage even simpler - * moved from vows to mocha as the testing framework - - diff --git a/node_modules/iconv-lite/lib/index.d.ts b/node_modules/iconv-lite/lib/index.d.ts deleted file mode 100644 index 99f200f4ab04c..0000000000000 --- a/node_modules/iconv-lite/lib/index.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - * REQUIREMENT: This definition is dependent on the @types/node definition. - * Install with `npm install @types/node --save-dev` - *--------------------------------------------------------------------------------------------*/ - -declare module 'iconv-lite' { - // Basic API - export function decode(buffer: Buffer, encoding: string, options?: Options): string; - - export function encode(content: string, encoding: string, options?: Options): Buffer; - - export function encodingExists(encoding: string): boolean; - - // Stream API - export function decodeStream(encoding: string, options?: Options): NodeJS.ReadWriteStream; - - export function encodeStream(encoding: string, options?: Options): NodeJS.ReadWriteStream; - - // Low-level stream APIs - export function getEncoder(encoding: string, options?: Options): EncoderStream; - - export function getDecoder(encoding: string, options?: Options): DecoderStream; -} - -export interface Options { - stripBOM?: boolean; - addBOM?: boolean; - defaultEncoding?: string; -} - -export interface EncoderStream { - write(str: string): Buffer; - end(): Buffer | undefined; -} - -export interface DecoderStream { - write(buf: Buffer): string; - end(): string | undefined; -} diff --git a/node_modules/ignore-walk/lib/index.js b/node_modules/ignore-walk/lib/index.js index 40a0726c3257f..366d95e2d516c 100644 --- a/node_modules/ignore-walk/lib/index.js +++ b/node_modules/ignore-walk/lib/index.js @@ -22,6 +22,7 @@ class Walker extends EE { this.result = this.parent ? this.parent.result : new Set() this.entries = null this.sawError = false + this.exact = opts.exact } sort (a, b) { @@ -84,7 +85,7 @@ class Walker extends EE { .filter(e => this.isIgnoreFile(e)) let igCount = newIg.length - const then = _ => { + const then = () => { if (--igCount === 0) { this.filterEntries() } @@ -140,7 +141,7 @@ class Walker extends EE { if (entryCount === 0) { this.emit('done', this.result) } else { - const then = _ => { + const then = () => { if (--entryCount === 0) { this.emit('done', this.result) } @@ -164,7 +165,7 @@ class Walker extends EE { } else { // is a directory if (dir) { - this.walker(entry, { isSymbolicLink }, then) + this.walker(entry, { isSymbolicLink, exact: file || this.filterEntry(entry + '/') }, then) } else { then() } @@ -208,15 +209,19 @@ class Walker extends EE { new Walker(this.walkerOpt(entry, opts)).on('done', then).start() } - filterEntry (entry, partial) { + filterEntry (entry, partial, entryBasename) { let included = true // this = /a/b/c // entry = d // parent /a/b sees c/d if (this.parent && this.parent.filterEntry) { - var pt = this.basename + '/' + entry - included = this.parent.filterEntry(pt, partial) + const parentEntry = this.basename + '/' + entry + const parentBasename = entryBasename || entry + included = this.parent.filterEntry(parentEntry, partial, parentBasename) + if (!included && !this.exact) { + return false + } } this.ignoreFiles.forEach(f => { @@ -226,17 +231,28 @@ class Walker extends EE { // so if it's negated, and already included, no need to check // likewise if it's neither negated nor included if (rule.negate !== included) { + const isRelativeRule = entryBasename && rule.globParts.some(part => + part.length <= (part.slice(-1)[0] ? 1 : 2) + ) + // first, match against /foo/bar // then, against foo/bar // then, in the case of partials, match with a / + // then, if also the rule is relative, match against basename const match = rule.match('/' + entry) || rule.match(entry) || - (!!partial && ( + !!partial && ( rule.match('/' + entry + '/') || - rule.match(entry + '/'))) || - (!!partial && rule.negate && ( - rule.match('/' + entry, true) || - rule.match(entry, true))) + rule.match(entry + '/') || + rule.negate && ( + rule.match('/' + entry, true) || + rule.match(entry, true)) || + isRelativeRule && ( + rule.match('/' + entryBasename + '/') || + rule.match(entryBasename + '/') || + rule.negate && ( + rule.match('/' + entryBasename, true) || + rule.match(entryBasename, true)))) if (match) { included = rule.negate diff --git a/node_modules/ignore-walk/package.json b/node_modules/ignore-walk/package.json index 1bf96eb211bbc..ea640d5dbc1fa 100644 --- a/node_modules/ignore-walk/package.json +++ b/node_modules/ignore-walk/package.json @@ -1,31 +1,24 @@ { "name": "ignore-walk", - "version": "5.0.1", + "version": "8.0.0", "description": "Nested/recursive `.gitignore`/`.npmignore` parsing and filtering.", "main": "lib/index.js", "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "mkdirp": "^1.0.4", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.24.3", "mutate-fs": "^2.1.1", - "rimraf": "^3.0.2", "tap": "^16.0.1" }, "scripts": { "test": "tap", "posttest": "npm run lint", - "lint": "eslint \"**/*.js\"", - "eslint": "eslint", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "npmclilint": "npmcli-lint", - "postsnap": "npm run lintfix --", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "prepublishOnly": "git push origin --follow-tags", - "snap": "tap" + "test:windows-coverage": "npm pkg set tap.statements=99 --json && npm pkg set tap.branches=98 --json && npm pkg set tap.lines=99 --json", + "snap": "tap", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "keywords": [ "ignorefile", @@ -39,27 +32,33 @@ "license": "ISC", "repository": { "type": "git", - "url": "https://github.com/npm/ignore-walk.git" + "url": "git+https://github.com/npm/ignore-walk.git" }, "files": [ "bin/", "lib/" ], "dependencies": { - "minimatch": "^5.0.1" + "minimatch": "^10.0.3" }, "tap": { "test-env": "LC_ALL=sk", "before": "test/00-setup.js", "after": "test/zz-cleanup.js", - "jobs": 1 + "timeout": 600, + "jobs": 1, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2", - "windowsCI": false + "version": "4.24.3", + "content": "scripts/template-oss", + "publish": "true" } } diff --git a/node_modules/indent-string/index.d.ts b/node_modules/indent-string/index.d.ts deleted file mode 100644 index 118523115645a..0000000000000 --- a/node_modules/indent-string/index.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -declare namespace indentString { - interface Options { - /** - The string to use for the indent. - - @default ' ' - */ - readonly indent?: string; - - /** - Also indent empty lines. - - @default false - */ - readonly includeEmptyLines?: boolean; - } -} - -/** -Indent each line in a string. - -@param string - The string to indent. -@param count - How many times you want `options.indent` repeated. Default: `1`. - -@example -``` -import indentString = require('indent-string'); - -indentString('Unicorns\nRainbows', 4); -//=> ' Unicorns\n Rainbows' - -indentString('Unicorns\nRainbows', 4, {indent: '♥'}); -//=> '♥♥♥♥Unicorns\n♥♥♥♥Rainbows' -``` -*/ -declare function indentString( - string: string, - count?: number, - options?: indentString.Options -): string; - -export = indentString; diff --git a/node_modules/indent-string/index.js b/node_modules/indent-string/index.js deleted file mode 100644 index e1ab804f2fd8a..0000000000000 --- a/node_modules/indent-string/index.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -module.exports = (string, count = 1, options) => { - options = { - indent: ' ', - includeEmptyLines: false, - ...options - }; - - if (typeof string !== 'string') { - throw new TypeError( - `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` - ); - } - - if (typeof count !== 'number') { - throw new TypeError( - `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` - ); - } - - if (typeof options.indent !== 'string') { - throw new TypeError( - `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` - ); - } - - if (count === 0) { - return string; - } - - const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; - - return string.replace(regex, options.indent.repeat(count)); -}; diff --git a/node_modules/indent-string/license b/node_modules/indent-string/license deleted file mode 100644 index e7af2f77107d7..0000000000000 --- a/node_modules/indent-string/license +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/indent-string/package.json b/node_modules/indent-string/package.json deleted file mode 100644 index 497bb83bbd9b7..0000000000000 --- a/node_modules/indent-string/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "indent-string", - "version": "4.0.0", - "description": "Indent each line in a string", - "license": "MIT", - "repository": "sindresorhus/indent-string", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=8" - }, - "scripts": { - "test": "xo && ava && tsd" - }, - "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "indent", - "string", - "pad", - "align", - "line", - "text", - "each", - "every" - ], - "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" - } -} diff --git a/node_modules/indent-string/readme.md b/node_modules/indent-string/readme.md deleted file mode 100644 index 49967de074f2f..0000000000000 --- a/node_modules/indent-string/readme.md +++ /dev/null @@ -1,70 +0,0 @@ -# indent-string [![Build Status](https://travis-ci.org/sindresorhus/indent-string.svg?branch=master)](https://travis-ci.org/sindresorhus/indent-string) - -> Indent each line in a string - - -## Install - -``` -$ npm install indent-string -``` - - -## Usage - -```js -const indentString = require('indent-string'); - -indentString('Unicorns\nRainbows', 4); -//=> ' Unicorns\n Rainbows' - -indentString('Unicorns\nRainbows', 4, {indent: '♥'}); -//=> '♥♥♥♥Unicorns\n♥♥♥♥Rainbows' -``` - - -## API - -### indentString(string, [count], [options]) - -#### string - -Type: `string` - -The string to indent. - -#### count - -Type: `number`<br> -Default: `1` - -How many times you want `options.indent` repeated. - -#### options - -Type: `object` - -##### indent - -Type: `string`<br> -Default: `' '` - -The string to use for the indent. - -##### includeEmptyLines - -Type: `boolean`<br> -Default: `false` - -Also indent empty lines. - - -## Related - -- [indent-string-cli](https://github.com/sindresorhus/indent-string-cli) - CLI for this module -- [strip-indent](https://github.com/sindresorhus/strip-indent) - Strip leading whitespace from every line in a string - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/infer-owner/LICENSE b/node_modules/infer-owner/LICENSE deleted file mode 100644 index 20a4762540923..0000000000000 --- a/node_modules/infer-owner/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) npm, Inc. and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/infer-owner/index.js b/node_modules/infer-owner/index.js deleted file mode 100644 index a7bddcbd2288b..0000000000000 --- a/node_modules/infer-owner/index.js +++ /dev/null @@ -1,71 +0,0 @@ -const cache = new Map() -const fs = require('fs') -const { dirname, resolve } = require('path') - - -const lstat = path => new Promise((res, rej) => - fs.lstat(path, (er, st) => er ? rej(er) : res(st))) - -const inferOwner = path => { - path = resolve(path) - if (cache.has(path)) - return Promise.resolve(cache.get(path)) - - const statThen = st => { - const { uid, gid } = st - cache.set(path, { uid, gid }) - return { uid, gid } - } - const parent = dirname(path) - const parentTrap = parent === path ? null : er => { - return inferOwner(parent).then((owner) => { - cache.set(path, owner) - return owner - }) - } - return lstat(path).then(statThen, parentTrap) -} - -const inferOwnerSync = path => { - path = resolve(path) - if (cache.has(path)) - return cache.get(path) - - const parent = dirname(path) - - // avoid obscuring call site by re-throwing - // "catch" the error by returning from a finally, - // only if we're not at the root, and the parent call works. - let threw = true - try { - const st = fs.lstatSync(path) - threw = false - const { uid, gid } = st - cache.set(path, { uid, gid }) - return { uid, gid } - } finally { - if (threw && parent !== path) { - const owner = inferOwnerSync(parent) - cache.set(path, owner) - return owner // eslint-disable-line no-unsafe-finally - } - } -} - -const inflight = new Map() -module.exports = path => { - path = resolve(path) - if (inflight.has(path)) - return Promise.resolve(inflight.get(path)) - const p = inferOwner(path).then(owner => { - inflight.delete(path) - return owner - }) - inflight.set(path, p) - return p -} -module.exports.sync = inferOwnerSync -module.exports.clearCache = () => { - cache.clear() - inflight.clear() -} diff --git a/node_modules/infer-owner/package.json b/node_modules/infer-owner/package.json deleted file mode 100644 index c4b2b6e6df206..0000000000000 --- a/node_modules/infer-owner/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "infer-owner", - "version": "1.0.4", - "description": "Infer the owner of a path based on the owner of its nearest existing parent", - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", - "license": "ISC", - "scripts": { - "test": "tap -J test/*.js --100", - "snap": "TAP_SNAPSHOT=1 tap -J test/*.js --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "devDependencies": { - "mutate-fs": "^2.1.1", - "tap": "^12.4.2" - }, - "main": "index.js", - "repository": "https://github.com/npm/infer-owner", - "publishConfig": { - "access": "public" - }, - "files": [ - "index.js" - ] -} diff --git a/node_modules/inflight/LICENSE b/node_modules/inflight/LICENSE deleted file mode 100644 index 05eeeb88c2ef4..0000000000000 --- a/node_modules/inflight/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/inflight/inflight.js b/node_modules/inflight/inflight.js deleted file mode 100644 index 48202b3ca41d9..0000000000000 --- a/node_modules/inflight/inflight.js +++ /dev/null @@ -1,54 +0,0 @@ -var wrappy = require('wrappy') -var reqs = Object.create(null) -var once = require('once') - -module.exports = wrappy(inflight) - -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) - } -} - -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) - - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] - } - } - }) -} - -function slice (args) { - var length = args.length - var array = [] - - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} diff --git a/node_modules/inflight/package.json b/node_modules/inflight/package.json deleted file mode 100644 index 6084d3509a5d6..0000000000000 --- a/node_modules/inflight/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "inflight", - "version": "1.0.6", - "description": "Add callbacks to requests in flight to avoid async duplication", - "main": "inflight.js", - "files": [ - "inflight.js" - ], - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - }, - "devDependencies": { - "tap": "^7.1.2" - }, - "scripts": { - "test": "tap test.js --100" - }, - "repository": { - "type": "git", - "url": "https://github.com/npm/inflight.git" - }, - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "bugs": { - "url": "https://github.com/isaacs/inflight/issues" - }, - "homepage": "https://github.com/isaacs/inflight", - "license": "ISC" -} diff --git a/node_modules/inherits/LICENSE b/node_modules/inherits/LICENSE deleted file mode 100644 index dea3013d6710e..0000000000000 --- a/node_modules/inherits/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - diff --git a/node_modules/inherits/inherits.js b/node_modules/inherits/inherits.js deleted file mode 100644 index f71f2d93294a6..0000000000000 --- a/node_modules/inherits/inherits.js +++ /dev/null @@ -1,9 +0,0 @@ -try { - var util = require('util'); - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - /* istanbul ignore next */ - module.exports = require('./inherits_browser.js'); -} diff --git a/node_modules/inherits/inherits_browser.js b/node_modules/inherits/inherits_browser.js deleted file mode 100644 index 86bbb3dc29e48..0000000000000 --- a/node_modules/inherits/inherits_browser.js +++ /dev/null @@ -1,27 +0,0 @@ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }) - } - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } - } -} diff --git a/node_modules/inherits/package.json b/node_modules/inherits/package.json deleted file mode 100644 index 37b4366b83e63..0000000000000 --- a/node_modules/inherits/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "inherits", - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "version": "2.0.4", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "main": "./inherits.js", - "browser": "./inherits_browser.js", - "repository": "git://github.com/isaacs/inherits", - "license": "ISC", - "scripts": { - "test": "tap" - }, - "devDependencies": { - "tap": "^14.2.4" - }, - "files": [ - "inherits.js", - "inherits_browser.js" - ] -} diff --git a/node_modules/ini/lib/ini.js b/node_modules/ini/lib/ini.js index 965e702493b1d..beb390d0b0ee2 100644 --- a/node_modules/ini/lib/ini.js +++ b/node_modules/ini/lib/ini.js @@ -1,49 +1,71 @@ const { hasOwnProperty } = Object.prototype -/* istanbul ignore next */ -const eol = typeof process !== 'undefined' && - process.platform === 'win32' ? '\r\n' : '\n' +const encode = (obj, opt = {}) => { + if (typeof opt === 'string') { + opt = { section: opt } + } + opt.align = opt.align === true + opt.newline = opt.newline === true + opt.sort = opt.sort === true + opt.whitespace = opt.whitespace === true || opt.align === true + // The `typeof` check is required because accessing the `process` directly fails on browsers. + /* istanbul ignore next */ + opt.platform = opt.platform || (typeof process !== 'undefined' && process.platform) + opt.bracketedArray = opt.bracketedArray !== false -const encode = (obj, opt) => { + /* istanbul ignore next */ + const eol = opt.platform === 'win32' ? '\r\n' : '\n' + const separator = opt.whitespace ? ' = ' : '=' const children = [] - let out = '' - if (typeof opt === 'string') { - opt = { - section: opt, - whitespace: false, - } - } else { - opt = opt || Object.create(null) - opt.whitespace = opt.whitespace === true + const keys = opt.sort ? Object.keys(obj).sort() : Object.keys(obj) + + let padToChars = 0 + // If aligning on the separator, then padToChars is determined as follows: + // 1. Get the keys + // 2. Exclude keys pointing to objects unless the value is null or an array + // 3. Add `[]` to array keys + // 4. Ensure non empty set of keys + // 5. Reduce the set to the longest `safe` key + // 6. Get the `safe` length + if (opt.align) { + padToChars = safe( + ( + keys + .filter(k => obj[k] === null || Array.isArray(obj[k]) || typeof obj[k] !== 'object') + .map(k => Array.isArray(obj[k]) ? `${k}[]` : k) + ) + .concat(['']) + .reduce((a, b) => safe(a).length >= safe(b).length ? a : b) + ).length } - const separator = opt.whitespace ? ' = ' : '=' + let out = '' + const arraySuffix = opt.bracketedArray ? '[]' : '' - for (const k of Object.keys(obj)) { + for (const k of keys) { const val = obj[k] if (val && Array.isArray(val)) { for (const item of val) { - out += safe(k + '[]') + separator + safe(item) + eol + out += safe(`${k}${arraySuffix}`).padEnd(padToChars, ' ') + separator + safe(item) + eol } } else if (val && typeof val === 'object') { children.push(k) } else { - out += safe(k) + separator + safe(val) + eol + out += safe(k).padEnd(padToChars, ' ') + separator + safe(val) + eol } } if (opt.section && out.length) { - out = '[' + safe(opt.section) + ']' + eol + out + out = '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out } for (const k of children) { - const nk = dotSplit(k).join('\\.') + const nk = splitSections(k, '.').join('\\.') const section = (opt.section ? opt.section + '.' : '') + nk - const { whitespace } = opt const child = encode(obj[k], { + ...opt, section, - whitespace, }) if (out.length && child.length) { out += eol @@ -55,24 +77,44 @@ const encode = (obj, opt) => { return out } -const dotSplit = str => - str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002') - .replace(/\\\./g, '\u0001') - .split(/\./) - .map(part => - part.replace(/\1/g, '\\.') - .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001')) +function splitSections (str, separator) { + var lastMatchIndex = 0 + var lastSeparatorIndex = 0 + var nextIndex = 0 + var sections = [] + + do { + nextIndex = str.indexOf(separator, lastMatchIndex) + + if (nextIndex !== -1) { + lastMatchIndex = nextIndex + separator.length -const decode = str => { + if (nextIndex > 0 && str[nextIndex - 1] === '\\') { + continue + } + + sections.push(str.slice(lastSeparatorIndex, nextIndex)) + lastSeparatorIndex = nextIndex + separator.length + } + } while (nextIndex !== -1) + + sections.push(str.slice(lastSeparatorIndex)) + + return sections +} + +const decode = (str, opt = {}) => { + opt.bracketedArray = opt.bracketedArray !== false const out = Object.create(null) let p = out let section = null - // section |key = value - const re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i + // section |key = value + const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i const lines = str.split(/[\r\n]+/g) + const duplicates = {} for (const line of lines) { - if (!line || line.match(/^\s*[;#]/)) { + if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) { continue } const match = line.match(re) @@ -91,8 +133,16 @@ const decode = str => { continue } const keyRaw = unsafe(match[2]) - const isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]' - const key = isArray ? keyRaw.slice(0, -2) : keyRaw + let isArray + if (opt.bracketedArray) { + isArray = keyRaw.length > 2 && keyRaw.slice(-2) === '[]' + } else { + duplicates[keyRaw] = (duplicates?.[keyRaw] || 0) + 1 + isArray = duplicates[keyRaw] > 1 + } + const key = isArray && keyRaw.endsWith('[]') + ? keyRaw.slice(0, -2) : keyRaw + if (key === '__proto__') { continue } @@ -125,14 +175,14 @@ const decode = str => { const remove = [] for (const k of Object.keys(out)) { if (!hasOwnProperty.call(out, k) || - typeof out[k] !== 'object' || - Array.isArray(out[k])) { + typeof out[k] !== 'object' || + Array.isArray(out[k])) { continue } // see if the parent section is also an object. // if so, add it to that, and mark this one for deletion - const parts = dotSplit(k) + const parts = splitSections(k, '.') p = out const l = parts.pop() const nl = l.replace(/\\\./g, '.') @@ -177,7 +227,7 @@ const safe = val => { return val.split(';').join('\\;').split('#').join('\\#') } -const unsafe = (val, doUnesc) => { +const unsafe = val => { val = (val || '').trim() if (isQuoted(val)) { // remove the single quotes before calling JSON.parse @@ -186,7 +236,9 @@ const unsafe = (val, doUnesc) => { } try { val = JSON.parse(val) - } catch (_) {} + } catch { + // ignore errors + } } else { // walk the val to find the first not-escaped ; character let esc = false diff --git a/node_modules/ini/package.json b/node_modules/ini/package.json index 1fe32c8f162a3..7bbc0576937c5 100644 --- a/node_modules/ini/package.json +++ b/node_modules/ini/package.json @@ -2,28 +2,25 @@ "author": "GitHub Inc.", "name": "ini", "description": "An ini encoder/decoder for node", - "version": "3.0.0", + "version": "6.0.0", "repository": { "type": "git", - "url": "https://github.com/npm/ini.git" + "url": "git+https://github.com/npm/ini.git" }, "main": "lib/ini.js", "scripts": { - "eslint": "eslint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "test": "tap", "snap": "tap", "posttest": "npm run lint", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "license": "ISC", @@ -32,10 +29,17 @@ "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.27.1", + "publish": "true" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/init-package-json/lib/default-input.js b/node_modules/init-package-json/lib/default-input.js index fe5abfdd85e45..d72feee7f44d3 100644 --- a/node_modules/init-package-json/lib/default-input.js +++ b/node_modules/init-package-json/lib/default-input.js @@ -1,190 +1,170 @@ -/* eslint-disable no-undef */ -var fs = require('fs') -var path = require('path') -var validateLicense = require('validate-npm-package-license') -var validateName = require('validate-npm-package-name') -var npa = require('npm-package-arg') -var semver = require('semver') +/* globals config, dirname, package, basename, yes, prompt */ + +const fs = require('fs/promises') +const path = require('path') +const validateLicense = require('validate-npm-package-license') +const validateName = require('validate-npm-package-name') +const npa = require('npm-package-arg') +const semver = require('semver') // more popular packages should go here, maybe? -function isTestPkg (p) { - return !!p.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/) -} +const testPkgs = [ + 'coco', + 'coffee-script', + 'expresso', + 'jasmine', + 'jest', + 'mocha', + 'streamline', + 'tap', +] +const isTestPkg = p => testPkgs.includes(p) -function niceName (n) { - return n.replace(/^node-|[.-]js$/g, '').replace(/\s+/g, ' ').replace(/ /g, '-').toLowerCase() -} +const invalid = (msg) => Object.assign(new Error(msg), { notValid: true }) -function readDeps (test, excluded) { - return function (cb) { - fs.readdir('node_modules', function (readdirErr, dir) { - if (readdirErr) { - return cb() - } - var deps = {} - var n = dir.length - if (n === 0) { - return cb(null, deps) - } - dir.forEach(function (d) { - if (d.match(/^\./)) { - return next() - } - if (test !== isTestPkg(d) || excluded[d]) { - return next() - } +const readDeps = (test, excluded) => async () => { + const dirs = await fs.readdir('node_modules').catch(() => null) - var dp = path.join(dirname, 'node_modules', d, 'package.json') - fs.readFile(dp, 'utf8', function (readFileErr, p) { - if (readFileErr) { - return next() - } - try { - p = JSON.parse(p) - } catch (e) { - return next() - } - if (!p.version) { - return next() - } - if (p._requiredBy) { - if (!p._requiredBy.some(function (req) { - return req === '#USER' - })) { - return next() - } - } - deps[d] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version - return next() - }) - }) - function next () { - if (--n === 0) { - return cb(null, deps) - } - } - }) + if (!dirs) { + return } + + const deps = {} + for (const dir of dirs) { + if (dir.match(/^\./) || test !== isTestPkg(dir) || excluded[dir]) { + continue + } + + const dp = path.join(dirname, 'node_modules', dir, 'package.json') + const p = await fs.readFile(dp, 'utf8').then((d) => JSON.parse(d)).catch(() => null) + + if (!p || !p.version || p?._requiredBy?.some((r) => r === '#USER')) { + continue + } + + deps[dir] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version + } + + return deps } -var name = niceName(package.name || basename) -var spec -try { - spec = npa(name) -} catch (e) { - spec = {} +const getConfig = (key) => { + // dots take precedence over dashes + const def = config?.defaults?.[`init.${key}`] + const val = config.get(`init.${key}`) + return (val !== def && val) ? val : config.get(`init-${key.replace(/\./g, '-')}`) } -var scope = config.get('scope') -if (scope) { - if (scope.charAt(0) !== '@') { - scope = '@' + scope + +const getName = () => { + const rawName = package.name || basename + let name = rawName + .replace(/^node-|[.-]js$/g, '') + .replace(/\s+/g, ' ') + .replace(/ /g, '-') + .toLowerCase() + + let spec + try { + spec = npa(name) + } catch { + spec = {} } - if (spec.scope) { - name = scope + '/' + spec.name.split('/')[1] - } else { - name = scope + '/' + name + + let scope = config.get('scope') + + if (scope) { + if (scope.charAt(0) !== '@') { + scope = '@' + scope + } + if (spec.scope) { + name = scope + '/' + spec.name.split('/')[1] + } else { + name = scope + '/' + name + } } + + return name } -exports.name = yes ? name : prompt('package name', name, function (data) { - var its = validateName(data) + +const name = getName() +exports.name = yes ? name : prompt('package name', name, (data) => { + const its = validateName(data) if (its.validForNewPackages) { return data } - var errors = (its.errors || []).concat(its.warnings || []) - var er = new Error('Sorry, ' + errors.join(' and ') + '.') - er.notValid = true - return er + const errors = (its.errors || []).concat(its.warnings || []) + return invalid(`Sorry, ${errors.join(' and ')}.`) }) -const defaultDottedInitVersion = config && - config.defaults && - config.defaults['init.version'] -const dottedInitVersion = - config.get('init.version') !== defaultDottedInitVersion && - config.get('init.version') -var version = package.version || - dottedInitVersion || - config.get('init-version') || - '1.0.0' -exports.version = yes ? - version : - prompt('version', version, function (promptedVersion) { - if (semver.valid(promptedVersion)) { - return promptedVersion - } - var er = new Error('Invalid version: "' + promptedVersion + '"') - er.notValid = true - return er - }) +const version = package.version || getConfig('version') || '1.0.0' +exports.version = yes ? version : prompt('version', version, (v) => { + if (semver.valid(v)) { + return v + } + return invalid(`Invalid version: "${v}"`) +}) if (!package.description) { exports.description = yes ? '' : prompt('description') } if (!package.main) { - exports.main = function (cb) { - fs.readdir(dirname, function (er, f) { - if (er) { - f = [] - } - - f = f.filter(function (filtered) { - return filtered.match(/\.js$/) - }) + exports.main = async () => { + const files = await fs.readdir(dirname) + .then(list => list.filter((f) => f.match(/\.js$/))) + .catch(() => []) - if (f.indexOf('index.js') !== -1) { - f = 'index.js' - } else if (f.indexOf('main.js') !== -1) { - f = 'main.js' - } else if (f.indexOf(basename + '.js') !== -1) { - f = basename + '.js' - } else { - f = f[0] - } + let index + if (files.includes('index.js')) { + index = 'index.js' + } else if (files.includes('main.js')) { + index = 'main.js' + } else if (files.includes(basename + '.js')) { + index = basename + '.js' + } else { + index = files[0] || 'index.js' + } - var index = f || 'index.js' - return cb(null, yes ? index : prompt('entry point', index)) - }) + return yes ? index : prompt('entry point', index) } } if (!package.bin) { - exports.bin = function (cb) { - fs.readdir(path.resolve(dirname, 'bin'), function (er, d) { - // no bins - if (er) { - return cb() - } + exports.bin = async () => { + try { + const d = await fs.readdir(path.resolve(dirname, 'bin')) // just take the first js file we find there, or nada let r = d.find(f => f.match(/\.js$/)) if (r) { r = `bin/${r}` } - return cb(null, r) - }) + return r + } catch { + // no bins + } } } -exports.directories = function (cb) { - fs.readdir(dirname, function (er, dirs) { - if (er) { - return cb(er) - } - var res = {} - dirs.forEach(function (d) { - switch (d) { - case 'example': case 'examples': return res.example = d - case 'test': case 'tests': return res.test = d - case 'doc': case 'docs': return res.doc = d - case 'man': return res.man = d - case 'lib': return res.lib = d - } - }) - if (Object.keys(res).length === 0) { - res = undefined +exports.directories = async () => { + const dirs = await fs.readdir(dirname) + + const res = dirs.reduce((acc, d) => { + if (/^examples?$/.test(d)) { + acc.example = d + } else if (/^tests?$/.test(d)) { + acc.test = d + } else if (/^docs?$/.test(d)) { + acc.doc = d + } else if (d === 'man') { + acc.man = d + } else if (d === 'lib') { + acc.lib = d } - return cb(null, res) - }) + + return acc + }, {}) + + return Object.keys(res).length === 0 ? undefined : res } if (!package.dependencies) { @@ -196,116 +176,113 @@ if (!package.devDependencies) { } // MUST have a test script! -var s = package.scripts || {} -var notest = 'echo "Error: no test specified" && exit 1' if (!package.scripts) { - exports.scripts = function (cb) { - fs.readdir(path.join(dirname, 'node_modules'), function (er, d) { - setupScripts(d || [], cb) - }) - } -} -function setupScripts (d, cb) { - // check to see what framework is in use, if any - function tx (test) { - return test || notest - } - if (!s.test || s.test === notest) { - var commands = { - tap: 'tap test/*.js', - expresso: 'expresso test', - mocha: 'mocha', - } - var command - Object.keys(commands).forEach(function (k) { - if (d.indexOf(k) !== -1) { - command = commands[k] + const scripts = package.scripts || {} + const notest = 'echo "Error: no test specified" && exit 1' + exports.scripts = async () => { + const d = await fs.readdir(path.join(dirname, 'node_modules')).catch(() => []) + + // check to see what framework is in use, if any + let command + if (!scripts.test || scripts.test === notest) { + const commands = { + tap: 'tap test/*.js', + expresso: 'expresso test', + mocha: 'mocha', + } + for (const [k, v] of Object.entries(commands)) { + if (d.includes(k)) { + command = v + } } - }) - var ps = 'test command' - if (yes) { - s.test = command || notest - } else { - s.test = command ? prompt(ps, command, tx) : prompt(ps, tx) } + + const promptArgs = ['test command', (t) => t || notest] + if (command) { + promptArgs.splice(1, 0, command) + } + scripts.test = yes ? command || notest : prompt(...promptArgs) + + return scripts } - return cb(null, s) } if (!package.repository) { - exports.repository = function (cb) { - fs.readFile('.git/config', 'utf8', function (er, gconf) { - if (er || !gconf) { - return cb(null, yes ? '' : prompt('git repository')) - } - gconf = gconf.split(/\r?\n/) - var i = gconf.indexOf('[remote "origin"]') - if (i !== -1) { - var u = gconf[i + 1] - if (!u.match(/^\s*url =/)) { - u = gconf[i + 2] - } - if (!u.match(/^\s*url =/)) { - u = null - } else { - u = u.replace(/^\s*url = /, '') - } + exports.repository = async () => { + const gitConfigPath = path.resolve(dirname, '.git', 'config') + const gconf = await fs.readFile(gitConfigPath, 'utf8').catch(() => '') + const lines = gconf.split(/\r?\n/) + + let url + const i = lines.indexOf('[remote "origin"]') + + if (i !== -1) { + url = lines[i + 1] + if (!url.match(/^\s*url =/)) { + url = lines[i + 2] } - if (u && u.match(/^git@github.com:/)) { - u = u.replace(/^git@github.com:/, 'https://github.com/') + if (!url.match(/^\s*url =/)) { + url = null + } else { + url = url.replace(/^\s*url = /, '') } + } + + if (url && url.match(/^git@github.com:/)) { + url = url.replace(/^git@github.com:/, 'https://github.com/') + } - return cb(null, yes ? u : prompt('git repository', u)) - }) + return yes ? url || '' : prompt('git repository', url || undefined) } } if (!package.keywords) { - exports.keywords = yes ? '' : prompt('keywords', function (promptedKeywords) { - if (!promptedKeywords) { - return undefined + exports.keywords = yes ? '' : prompt('keywords', (data) => { + if (!data) { + return } - if (Array.isArray(promptedKeywords)) { - promptedKeywords = promptedKeywords.join(' ') + if (Array.isArray(data)) { + data = data.join(' ') } - if (typeof promptedKeywords !== 'string') { - return promptedKeywords + if (typeof data !== 'string') { + return data } - return promptedKeywords.split(/[\s,]+/) + return data.split(/[\s,]+/) }) } if (!package.author) { - exports.author = config.get('init.author.name') || - config.get('init-author-name') + const authorName = getConfig('author.name') + exports.author = authorName ? { - name: config.get('init.author.name') || - config.get('init-author-name'), - email: config.get('init.author.email') || - config.get('init-author-email'), - url: config.get('init.author.url') || - config.get('init-author-url'), + name: authorName, + email: getConfig('author.email'), + url: getConfig('author.url'), } : yes ? '' : prompt('author') } -const defaultDottedInitLicense = config && - config.defaults && - config.defaults['init.license'] -const dottedInitLicense = - config.get('init.license') !== defaultDottedInitLicense && - config.get('init.license') -var license = package.license || - dottedInitLicense || - config.get('init-license') || - 'ISC' -exports.license = yes ? license : prompt('license', license, function (data) { - var its = validateLicense(data) +const license = package.license || getConfig('license') || 'ISC' +exports.license = yes ? license : prompt('license', license, (data) => { + const its = validateLicense(data) if (its.validForNewPackages) { return data } - var errors = (its.errors || []).concat(its.warnings || []) - var er = new Error('Sorry, ' + errors.join(' and ') + '.') - er.notValid = true - return er + const errors = (its.errors || []).concat(its.warnings || []) + return invalid(`Sorry, ${errors.join(' and ')}.`) +}) + +const type = package.type || getConfig('type') || 'commonjs' +exports.type = yes ? type : prompt('type', type, (data) => { + return data }) + +// Only include private field if it already exists or if explicitly set in config +const configPrivate = getConfig('private') +if (package.private !== undefined || configPrivate !== undefined) { + if (package.private !== undefined) { + exports.private = package.private + } else if (!config.isDefault || !config.isDefault('init-private')) { + exports.private = configPrivate + } +} diff --git a/node_modules/init-package-json/lib/init-package-json.js b/node_modules/init-package-json/lib/init-package-json.js index 230bcd81747bd..b67ae418f7abd 100644 --- a/node_modules/init-package-json/lib/init-package-json.js +++ b/node_modules/init-package-json/lib/init-package-json.js @@ -1,184 +1,147 @@ -module.exports = init -module.exports.yes = yes - -var PZ = require('promzard').PromZard -var path = require('path') -var def = require.resolve('./default-input.js') - -var fs = require('fs') -var semver = require('semver') -var read = require('read') - -// to validate the data object at the end as a worthwhile package -// and assign default values for things. -var readJson = require('read-package-json') - -function yes (conf) { - return !!( - conf.get('yes') || conf.get('y') || - conf.get('force') || conf.get('f') - ) +const promzard = require('promzard') +const path = require('path') +const semver = require('semver') +const { read } = require('read') +const util = require('util') +const PackageJson = require('@npmcli/package-json') + +const def = require.resolve('./default-input.js') + +const extras = [ + 'bundleDependencies', + 'gypfile', + 'serverjs', + 'scriptpath', + 'readme', + 'bin', + 'githead', + 'fillTypes', + 'normalizeData', +] + +const isYes = (c) => !!(c.get('yes') || c.get('y') || c.get('force') || c.get('f')) + +const getConfig = (c) => { + // accept either a plain-jane object, or a config object with a "get" method. + if (typeof c.get !== 'function') { + const data = c + return { + get: (k) => data[k], + toJSON: () => data, + } + } + return c } -function init (dir, input, config, cb) { - if (typeof config === 'function') { - cb = config - config = {} +// Coverage disabled because this is just walking back the fixPeople +// normalization from the normalizeData step and we don't need to re-test all +// of those paths. +/* istanbul ignore next */ +const stringifyPerson = (p) => { + const { name, url, web, email, mail } = p + const u = url || web + const e = email || mail + return `${name}${e ? ` <${e}>` : ''}${u ? ` (${u})` : ''}` +} +async function init (dir, + // TODO test for non-default definitions + /* istanbul ignore next */ + input = def, + c = {}) { + const config = getConfig(c) + const yes = isYes(config) + const packageFile = path.resolve(dir, 'package.json') + + // read what's already there to inform our prompts + const pkg = await PackageJson.load(dir, { create: true }) + await pkg.normalize() + + if (!semver.valid(pkg.content.version)) { + delete pkg.content.version } - // accept either a plain-jane object, or a config object - // with a "get" method. - if (typeof config.get !== 'function') { - var data = config - config = { - get: function (k) { - return data[k] - }, - toJSON: function () { - return data - }, + // make sure that the input is valid. if not, use the default + const pzData = await promzard(path.resolve(input), { + yes, + config, + filename: packageFile, + dirname: dir, + basename: path.basename(dir), + package: pkg.content, + }, { backupFile: def }) + + for (const [k, v] of Object.entries(pzData)) { + if (v != null) { + pkg.content[k] = v } } - var packageFile = path.resolve(dir, 'package.json') - input = path.resolve(input) - var pkg - var ctx = { yes: yes(config) } - - var es = readJson.extraSet - readJson.extraSet = es.filter(function (fn) { - return fn.name !== 'authors' && fn.name !== 'mans' - }) - readJson(packageFile, function (er, d) { - readJson.extraSet = es - - if (er) { - pkg = {} - } else { - pkg = d - } + await pkg.normalize({ steps: extras }) - ctx.filename = packageFile - ctx.dirname = path.dirname(packageFile) - ctx.basename = path.basename(ctx.dirname) - if (!pkg.version || !semver.valid(pkg.version)) { - delete pkg.version - } + // turn the objects back into somewhat more humane strings. + // "normalizeData" does this and there isn't a way to choose which of those steps happen + if (pkg.content.author) { + pkg.content.author = stringifyPerson(pkg.content.author) + } - ctx.package = pkg - ctx.config = config || {} - - // make sure that the input is valid. - // if not, use the default - var pz = new PZ(input, ctx) - pz.backupFile = def - pz.on('error', cb) - pz.on('data', function (pzData) { - Object.keys(pzData).forEach(function (k) { - if (pzData[k] !== undefined && pzData[k] !== null) { - pkg[k] = pzData[k] - } - }) - - // only do a few of these. - // no need for mans or contributors if they're in the files - es = readJson.extraSet - readJson.extraSet = es.filter(function (fn) { - return fn.name !== 'authors' && fn.name !== 'mans' - }) - readJson.extras(packageFile, pkg, function (extrasErr, pkgWithExtras) { - if (extrasErr) { - return cb(extrasErr, pkgWithExtras) - } - readJson.extraSet = es - pkgWithExtras = unParsePeople(pkgWithExtras) - // no need for the readme now. - delete pkgWithExtras.readme - delete pkgWithExtras.readmeFilename - - // really don't want to have this lying around in the file - delete pkgWithExtras._id - - // ditto - delete pkgWithExtras.gitHead - - // if the repo is empty, remove it. - if (!pkgWithExtras.repository) { - delete pkgWithExtras.repository - } - - // readJson filters out empty descriptions, but init-package-json - // traditionally leaves them alone - if (!pkgWithExtras.description) { - pkgWithExtras.description = pzData.description - } - - var stringified = JSON.stringify(updateDeps(pkgWithExtras), null, 2) + '\n' - function write (writeYes) { - fs.writeFile(packageFile, stringified, 'utf8', function (writeFileErr) { - if (!writeFileErr && writeYes && !config.get('silent')) { - console.log('Wrote to %s:\n\n%s\n', packageFile, stringified) - } - return cb(writeFileErr, pkgWithExtras) - }) - } - if (ctx.yes) { - return write(true) - } - console.log('About to write to %s:\n\n%s\n', packageFile, stringified) - read({ prompt: 'Is this OK? ', default: 'yes' }, function (promptErr, ok) { - if (promptErr) { - return cb(promptErr) - } - if (!ok || ok.toLowerCase().charAt(0) !== 'y') { - console.log('Aborted.') - } else { - return write() - } - }) - }) - }) - }) -} + // no need for the readme now. + delete pkg.content.readme + delete pkg.content.readmeFilename + + // really don't want to have this lying around in the file + delete pkg.content._id + + // ditto + delete pkg.content.gitHead + + // if the repo is empty, remove it. + if (!pkg.content.repository) { + delete pkg.content.repository + } + + // readJson filters out empty descriptions, but init-package-json + // traditionally leaves them alone + if (!pkg.content.description) { + pkg.content.description = pzData.description + } -function updateDeps (depsData) { // optionalDependencies don't need to be repeated in two places - if (depsData.dependencies) { - if (depsData.optionalDependencies) { - for (const name of Object.keys(depsData.optionalDependencies)) { - delete depsData.dependencies[name] + if (pkg.content.dependencies) { + if (pkg.content.optionalDependencies) { + for (const name of Object.keys(pkg.content.optionalDependencies)) { + delete pkg.content.dependencies[name] } } - if (Object.keys(depsData.dependencies).length === 0) { - delete depsData.dependencies + if (Object.keys(pkg.content.dependencies).length === 0) { + delete pkg.content.dependencies } } - return depsData -} + const stringified = JSON.stringify(pkg.content, null, 2) + '\n' + const msg = util.format('%s:\n\n%s\n', packageFile, stringified) -// turn the objects into somewhat more humane strings. -function unParsePeople (data) { - if (data.author) { - data.author = unParsePerson(data.author) - }['maintainers', 'contributors'].forEach(function (set) { - if (!Array.isArray(data[set])) { - return + if (yes) { + await pkg.save() + if (!config.get('silent')) { + // eslint-disable-next-line no-console + console.log(`Wrote to ${msg}`) } - data[set] = data[set].map(unParsePerson) - }) - return data -} + return pkg.content + } -function unParsePerson (person) { - if (typeof person === 'string') { - return person + // eslint-disable-next-line no-console + console.log(`About to write to ${msg}`) + const ok = await read({ prompt: 'Is this OK? ', default: 'yes' }) + if (!ok || !ok.toLowerCase().startsWith('y')) { + // eslint-disable-next-line no-console + console.log('Aborted.') + return } - var name = person.name || '' - var u = person.url || person.web - var url = u ? (' (' + u + ')') : '' - var e = person.email || person.mail - var email = e ? (' <' + e + '>') : '' - return name + email + url + + await pkg.save({ sort: true }) + return pkg.content } + +module.exports = init +module.exports.yes = isYes diff --git a/node_modules/init-package-json/package.json b/node_modules/init-package-json/package.json index 91d4b7a109f08..f41bb69f756ff 100644 --- a/node_modules/init-package-json/package.json +++ b/node_modules/init-package-json/package.json @@ -1,48 +1,49 @@ { "name": "init-package-json", - "version": "3.0.2", + "version": "8.2.4", "main": "lib/init-package-json.js", "scripts": { "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "snap": "tap", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/init-package-json.git" + "url": "git+https://github.com/npm/init-package-json.git" }, "author": "GitHub Inc.", "license": "ISC", "description": "A node module to get your node module started", "dependencies": { - "npm-package-arg": "^9.0.1", - "promzard": "^0.3.0", - "read": "^1.0.7", - "read-package-json": "^5.0.0", - "semver": "^7.3.5", + "@npmcli/package-json": "^7.0.0", + "npm-package-arg": "^13.0.0", + "promzard": "^3.0.1", + "read": "^5.0.1", + "semver": "^7.7.2", "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0" + "validate-npm-package-name": "^7.0.0" }, "devDependencies": { - "@npmcli/config": "^4.0.1", - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.1", + "@npmcli/config": "^10.0.0", + "@npmcli/eslint-config": "^6.0.1", + "@npmcli/template-oss": "4.23.4", "tap": "^16.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "tap": { - "statements": "94", - "branches": "83", - "lines": "94" + "test-ignore": "fixtures/", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ], + "timeout": 300 }, "keywords": [ "init", @@ -60,6 +61,7 @@ ], "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.1" + "version": "4.23.4", + "publish": true } } diff --git a/node_modules/ip-address/LICENSE b/node_modules/ip-address/LICENSE new file mode 100644 index 0000000000000..ec79adb0c4020 --- /dev/null +++ b/node_modules/ip-address/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2011 by Beau Gunderson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/ip-address/dist/address-error.js b/node_modules/ip-address/dist/address-error.js new file mode 100644 index 0000000000000..c178ae48200ac --- /dev/null +++ b/node_modules/ip-address/dist/address-error.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AddressError = void 0; +class AddressError extends Error { + constructor(message, parseMessage) { + super(message); + this.name = 'AddressError'; + this.parseMessage = parseMessage; + } +} +exports.AddressError = AddressError; +//# sourceMappingURL=address-error.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/common.js b/node_modules/ip-address/dist/common.js new file mode 100644 index 0000000000000..273a01e28e317 --- /dev/null +++ b/node_modules/ip-address/dist/common.js @@ -0,0 +1,46 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isInSubnet = isInSubnet; +exports.isCorrect = isCorrect; +exports.numberToPaddedHex = numberToPaddedHex; +exports.stringToPaddedHex = stringToPaddedHex; +exports.testBit = testBit; +function isInSubnet(address) { + if (this.subnetMask < address.subnetMask) { + return false; + } + if (this.mask(address.subnetMask) === address.mask()) { + return true; + } + return false; +} +function isCorrect(defaultBits) { + return function () { + if (this.addressMinusSuffix !== this.correctForm()) { + return false; + } + if (this.subnetMask === defaultBits && !this.parsedSubnet) { + return true; + } + return this.parsedSubnet === String(this.subnetMask); + }; +} +function numberToPaddedHex(number) { + return number.toString(16).padStart(2, '0'); +} +function stringToPaddedHex(numberString) { + return numberToPaddedHex(parseInt(numberString, 10)); +} +/** + * @param binaryValue Binary representation of a value (e.g. `10`) + * @param position Byte position, where 0 is the least significant bit + */ +function testBit(binaryValue, position) { + const { length } = binaryValue; + if (position > length) { + return false; + } + const positionInString = length - position; + return binaryValue.substring(positionInString, positionInString + 1) === '1'; +} +//# sourceMappingURL=common.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/ip-address.js b/node_modules/ip-address/dist/ip-address.js new file mode 100644 index 0000000000000..84f348709fe54 --- /dev/null +++ b/node_modules/ip-address/dist/ip-address.js @@ -0,0 +1,35 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.v6 = exports.AddressError = exports.Address6 = exports.Address4 = void 0; +var ipv4_1 = require("./ipv4"); +Object.defineProperty(exports, "Address4", { enumerable: true, get: function () { return ipv4_1.Address4; } }); +var ipv6_1 = require("./ipv6"); +Object.defineProperty(exports, "Address6", { enumerable: true, get: function () { return ipv6_1.Address6; } }); +var address_error_1 = require("./address-error"); +Object.defineProperty(exports, "AddressError", { enumerable: true, get: function () { return address_error_1.AddressError; } }); +const helpers = __importStar(require("./v6/helpers")); +exports.v6 = { helpers }; +//# sourceMappingURL=ip-address.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/ipv4.js b/node_modules/ip-address/dist/ipv4.js new file mode 100644 index 0000000000000..311c89c6965cb --- /dev/null +++ b/node_modules/ip-address/dist/ipv4.js @@ -0,0 +1,360 @@ +"use strict"; +/* eslint-disable no-param-reassign */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Address4 = void 0; +const common = __importStar(require("./common")); +const constants = __importStar(require("./v4/constants")); +const address_error_1 = require("./address-error"); +/** + * Represents an IPv4 address + * @class Address4 + * @param {string} address - An IPv4 address string + */ +class Address4 { + constructor(address) { + this.groups = constants.GROUPS; + this.parsedAddress = []; + this.parsedSubnet = ''; + this.subnet = '/32'; + this.subnetMask = 32; + this.v4 = true; + /** + * Returns true if the address is correct, false otherwise + * @memberof Address4 + * @instance + * @returns {Boolean} + */ + this.isCorrect = common.isCorrect(constants.BITS); + /** + * Returns true if the given address is in the subnet of the current address + * @memberof Address4 + * @instance + * @returns {boolean} + */ + this.isInSubnet = common.isInSubnet; + this.address = address; + const subnet = constants.RE_SUBNET_STRING.exec(address); + if (subnet) { + this.parsedSubnet = subnet[0].replace('/', ''); + this.subnetMask = parseInt(this.parsedSubnet, 10); + this.subnet = `/${this.subnetMask}`; + if (this.subnetMask < 0 || this.subnetMask > constants.BITS) { + throw new address_error_1.AddressError('Invalid subnet mask.'); + } + address = address.replace(constants.RE_SUBNET_STRING, ''); + } + this.addressMinusSuffix = address; + this.parsedAddress = this.parse(address); + } + static isValid(address) { + try { + // eslint-disable-next-line no-new + new Address4(address); + return true; + } + catch (e) { + return false; + } + } + /* + * Parses a v4 address + */ + parse(address) { + const groups = address.split('.'); + if (!address.match(constants.RE_ADDRESS)) { + throw new address_error_1.AddressError('Invalid IPv4 address.'); + } + return groups; + } + /** + * Returns the correct form of an address + * @memberof Address4 + * @instance + * @returns {String} + */ + correctForm() { + return this.parsedAddress.map((part) => parseInt(part, 10)).join('.'); + } + /** + * Converts a hex string to an IPv4 address object + * @memberof Address4 + * @static + * @param {string} hex - a hex string to convert + * @returns {Address4} + */ + static fromHex(hex) { + const padded = hex.replace(/:/g, '').padStart(8, '0'); + const groups = []; + let i; + for (i = 0; i < 8; i += 2) { + const h = padded.slice(i, i + 2); + groups.push(parseInt(h, 16)); + } + return new Address4(groups.join('.')); + } + /** + * Converts an integer into a IPv4 address object + * @memberof Address4 + * @static + * @param {integer} integer - a number to convert + * @returns {Address4} + */ + static fromInteger(integer) { + return Address4.fromHex(integer.toString(16)); + } + /** + * Return an address from in-addr.arpa form + * @memberof Address4 + * @static + * @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address + * @returns {Adress4} + * @example + * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.) + * address.correctForm(); // '192.0.2.42' + */ + static fromArpa(arpaFormAddress) { + // remove ending ".in-addr.arpa." or just "." + const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, ''); + const address = leader.split('.').reverse().join('.'); + return new Address4(address); + } + /** + * Converts an IPv4 address object to a hex string + * @memberof Address4 + * @instance + * @returns {String} + */ + toHex() { + return this.parsedAddress.map((part) => common.stringToPaddedHex(part)).join(':'); + } + /** + * Converts an IPv4 address object to an array of bytes + * @memberof Address4 + * @instance + * @returns {Array} + */ + toArray() { + return this.parsedAddress.map((part) => parseInt(part, 10)); + } + /** + * Converts an IPv4 address object to an IPv6 address group + * @memberof Address4 + * @instance + * @returns {String} + */ + toGroup6() { + const output = []; + let i; + for (i = 0; i < constants.GROUPS; i += 2) { + output.push(`${common.stringToPaddedHex(this.parsedAddress[i])}${common.stringToPaddedHex(this.parsedAddress[i + 1])}`); + } + return output.join(':'); + } + /** + * Returns the address as a `bigint` + * @memberof Address4 + * @instance + * @returns {bigint} + */ + bigInt() { + return BigInt(`0x${this.parsedAddress.map((n) => common.stringToPaddedHex(n)).join('')}`); + } + /** + * Helper function getting start address. + * @memberof Address4 + * @instance + * @returns {bigint} + */ + _startAddress() { + return BigInt(`0b${this.mask() + '0'.repeat(constants.BITS - this.subnetMask)}`); + } + /** + * The first address in the range given by this address' subnet. + * Often referred to as the Network Address. + * @memberof Address4 + * @instance + * @returns {Address4} + */ + startAddress() { + return Address4.fromBigInt(this._startAddress()); + } + /** + * The first host address in the range given by this address's subnet ie + * the first address after the Network Address + * @memberof Address4 + * @instance + * @returns {Address4} + */ + startAddressExclusive() { + const adjust = BigInt('1'); + return Address4.fromBigInt(this._startAddress() + adjust); + } + /** + * Helper function getting end address. + * @memberof Address4 + * @instance + * @returns {bigint} + */ + _endAddress() { + return BigInt(`0b${this.mask() + '1'.repeat(constants.BITS - this.subnetMask)}`); + } + /** + * The last address in the range given by this address' subnet + * Often referred to as the Broadcast + * @memberof Address4 + * @instance + * @returns {Address4} + */ + endAddress() { + return Address4.fromBigInt(this._endAddress()); + } + /** + * The last host address in the range given by this address's subnet ie + * the last address prior to the Broadcast Address + * @memberof Address4 + * @instance + * @returns {Address4} + */ + endAddressExclusive() { + const adjust = BigInt('1'); + return Address4.fromBigInt(this._endAddress() - adjust); + } + /** + * Converts a BigInt to a v4 address object + * @memberof Address4 + * @static + * @param {bigint} bigInt - a BigInt to convert + * @returns {Address4} + */ + static fromBigInt(bigInt) { + return Address4.fromHex(bigInt.toString(16)); + } + /** + * Convert a byte array to an Address4 object + * @memberof Address4 + * @static + * @param {Array<number>} bytes - an array of 4 bytes (0-255) + * @returns {Address4} + */ + static fromByteArray(bytes) { + if (bytes.length !== 4) { + throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes'); + } + // Validate that all bytes are within valid range (0-255) + for (let i = 0; i < bytes.length; i++) { + if (!Number.isInteger(bytes[i]) || bytes[i] < 0 || bytes[i] > 255) { + throw new address_error_1.AddressError('All bytes must be integers between 0 and 255'); + } + } + return this.fromUnsignedByteArray(bytes); + } + /** + * Convert an unsigned byte array to an Address4 object + * @memberof Address4 + * @static + * @param {Array<number>} bytes - an array of 4 unsigned bytes (0-255) + * @returns {Address4} + */ + static fromUnsignedByteArray(bytes) { + if (bytes.length !== 4) { + throw new address_error_1.AddressError('IPv4 addresses require exactly 4 bytes'); + } + const address = bytes.join('.'); + return new Address4(address); + } + /** + * Returns the first n bits of the address, defaulting to the + * subnet mask + * @memberof Address4 + * @instance + * @returns {String} + */ + mask(mask) { + if (mask === undefined) { + mask = this.subnetMask; + } + return this.getBitsBase2(0, mask); + } + /** + * Returns the bits in the given range as a base-2 string + * @memberof Address4 + * @instance + * @returns {string} + */ + getBitsBase2(start, end) { + return this.binaryZeroPad().slice(start, end); + } + /** + * Return the reversed ip6.arpa form of the address + * @memberof Address4 + * @param {Object} options + * @param {boolean} options.omitSuffix - omit the "in-addr.arpa" suffix + * @instance + * @returns {String} + */ + reverseForm(options) { + if (!options) { + options = {}; + } + const reversed = this.correctForm().split('.').reverse().join('.'); + if (options.omitSuffix) { + return reversed; + } + return `${reversed}.in-addr.arpa.`; + } + /** + * Returns true if the given address is a multicast address + * @memberof Address4 + * @instance + * @returns {boolean} + */ + isMulticast() { + return this.isInSubnet(new Address4('224.0.0.0/4')); + } + /** + * Returns a zero-padded base-2 string representation of the address + * @memberof Address4 + * @instance + * @returns {string} + */ + binaryZeroPad() { + return this.bigInt().toString(2).padStart(constants.BITS, '0'); + } + /** + * Groups an IPv4 address for inclusion at the end of an IPv6 address + * @returns {String} + */ + groupForV6() { + const segments = this.parsedAddress; + return this.address.replace(constants.RE_ADDRESS, `<span class="hover-group group-v4 group-6">${segments + .slice(0, 2) + .join('.')}</span>.<span class="hover-group group-v4 group-7">${segments + .slice(2, 4) + .join('.')}</span>`); + } +} +exports.Address4 = Address4; +//# sourceMappingURL=ipv4.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/ipv6.js b/node_modules/ip-address/dist/ipv6.js new file mode 100644 index 0000000000000..5f88ab63a56eb --- /dev/null +++ b/node_modules/ip-address/dist/ipv6.js @@ -0,0 +1,1003 @@ +"use strict"; +/* eslint-disable prefer-destructuring */ +/* eslint-disable no-param-reassign */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Address6 = void 0; +const common = __importStar(require("./common")); +const constants4 = __importStar(require("./v4/constants")); +const constants6 = __importStar(require("./v6/constants")); +const helpers = __importStar(require("./v6/helpers")); +const ipv4_1 = require("./ipv4"); +const regular_expressions_1 = require("./v6/regular-expressions"); +const address_error_1 = require("./address-error"); +const common_1 = require("./common"); +function assert(condition) { + if (!condition) { + throw new Error('Assertion failed.'); + } +} +function addCommas(number) { + const r = /(\d+)(\d{3})/; + while (r.test(number)) { + number = number.replace(r, '$1,$2'); + } + return number; +} +function spanLeadingZeroes4(n) { + n = n.replace(/^(0{1,})([1-9]+)$/, '<span class="parse-error">$1</span>$2'); + n = n.replace(/^(0{1,})(0)$/, '<span class="parse-error">$1</span>$2'); + return n; +} +/* + * A helper function to compact an array + */ +function compact(address, slice) { + const s1 = []; + const s2 = []; + let i; + for (i = 0; i < address.length; i++) { + if (i < slice[0]) { + s1.push(address[i]); + } + else if (i > slice[1]) { + s2.push(address[i]); + } + } + return s1.concat(['compact']).concat(s2); +} +function paddedHex(octet) { + return parseInt(octet, 16).toString(16).padStart(4, '0'); +} +function unsignByte(b) { + // eslint-disable-next-line no-bitwise + return b & 0xff; +} +/** + * Represents an IPv6 address + * @class Address6 + * @param {string} address - An IPv6 address string + * @param {number} [groups=8] - How many octets to parse + * @example + * var address = new Address6('2001::/32'); + */ +class Address6 { + constructor(address, optionalGroups) { + this.addressMinusSuffix = ''; + this.parsedSubnet = ''; + this.subnet = '/128'; + this.subnetMask = 128; + this.v4 = false; + this.zone = ''; + // #region Attributes + /** + * Returns true if the given address is in the subnet of the current address + * @memberof Address6 + * @instance + * @returns {boolean} + */ + this.isInSubnet = common.isInSubnet; + /** + * Returns true if the address is correct, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + this.isCorrect = common.isCorrect(constants6.BITS); + if (optionalGroups === undefined) { + this.groups = constants6.GROUPS; + } + else { + this.groups = optionalGroups; + } + this.address = address; + const subnet = constants6.RE_SUBNET_STRING.exec(address); + if (subnet) { + this.parsedSubnet = subnet[0].replace('/', ''); + this.subnetMask = parseInt(this.parsedSubnet, 10); + this.subnet = `/${this.subnetMask}`; + if (Number.isNaN(this.subnetMask) || + this.subnetMask < 0 || + this.subnetMask > constants6.BITS) { + throw new address_error_1.AddressError('Invalid subnet mask.'); + } + address = address.replace(constants6.RE_SUBNET_STRING, ''); + } + else if (/\//.test(address)) { + throw new address_error_1.AddressError('Invalid subnet mask.'); + } + const zone = constants6.RE_ZONE_STRING.exec(address); + if (zone) { + this.zone = zone[0]; + address = address.replace(constants6.RE_ZONE_STRING, ''); + } + this.addressMinusSuffix = address; + this.parsedAddress = this.parse(this.addressMinusSuffix); + } + static isValid(address) { + try { + // eslint-disable-next-line no-new + new Address6(address); + return true; + } + catch (e) { + return false; + } + } + /** + * Convert a BigInt to a v6 address object + * @memberof Address6 + * @static + * @param {bigint} bigInt - a BigInt to convert + * @returns {Address6} + * @example + * var bigInt = BigInt('1000000000000'); + * var address = Address6.fromBigInt(bigInt); + * address.correctForm(); // '::e8:d4a5:1000' + */ + static fromBigInt(bigInt) { + const hex = bigInt.toString(16).padStart(32, '0'); + const groups = []; + let i; + for (i = 0; i < constants6.GROUPS; i++) { + groups.push(hex.slice(i * 4, (i + 1) * 4)); + } + return new Address6(groups.join(':')); + } + /** + * Convert a URL (with optional port number) to an address object + * @memberof Address6 + * @static + * @param {string} url - a URL with optional port number + * @example + * var addressAndPort = Address6.fromURL('http://[ffff::]:8080/foo/'); + * addressAndPort.address.correctForm(); // 'ffff::' + * addressAndPort.port; // 8080 + */ + static fromURL(url) { + let host; + let port = null; + let result; + // If we have brackets parse them and find a port + if (url.indexOf('[') !== -1 && url.indexOf(']:') !== -1) { + result = constants6.RE_URL_WITH_PORT.exec(url); + if (result === null) { + return { + error: 'failed to parse address with port', + address: null, + port: null, + }; + } + host = result[1]; + port = result[2]; + // If there's a URL extract the address + } + else if (url.indexOf('/') !== -1) { + // Remove the protocol prefix + url = url.replace(/^[a-z0-9]+:\/\//, ''); + // Parse the address + result = constants6.RE_URL.exec(url); + if (result === null) { + return { + error: 'failed to parse address from URL', + address: null, + port: null, + }; + } + host = result[1]; + // Otherwise just assign the URL to the host and let the library parse it + } + else { + host = url; + } + // If there's a port convert it to an integer + if (port) { + port = parseInt(port, 10); + // squelch out of range ports + if (port < 0 || port > 65536) { + port = null; + } + } + else { + // Standardize `undefined` to `null` + port = null; + } + return { + address: new Address6(host), + port, + }; + } + /** + * Create an IPv6-mapped address given an IPv4 address + * @memberof Address6 + * @static + * @param {string} address - An IPv4 address string + * @returns {Address6} + * @example + * var address = Address6.fromAddress4('192.168.0.1'); + * address.correctForm(); // '::ffff:c0a8:1' + * address.to4in6(); // '::ffff:192.168.0.1' + */ + static fromAddress4(address) { + const address4 = new ipv4_1.Address4(address); + const mask6 = constants6.BITS - (constants4.BITS - address4.subnetMask); + return new Address6(`::ffff:${address4.correctForm()}/${mask6}`); + } + /** + * Return an address from ip6.arpa form + * @memberof Address6 + * @static + * @param {string} arpaFormAddress - an 'ip6.arpa' form address + * @returns {Adress6} + * @example + * var address = Address6.fromArpa(e.f.f.f.3.c.2.6.f.f.f.e.6.6.8.e.1.0.6.7.9.4.e.c.0.0.0.0.1.0.0.2.ip6.arpa.) + * address.correctForm(); // '2001:0:ce49:7601:e866:efff:62c3:fffe' + */ + static fromArpa(arpaFormAddress) { + // remove ending ".ip6.arpa." or just "." + let address = arpaFormAddress.replace(/(\.ip6\.arpa)?\.$/, ''); + const semicolonAmount = 7; + // correct ip6.arpa form with ending removed will be 63 characters + if (address.length !== 63) { + throw new address_error_1.AddressError("Invalid 'ip6.arpa' form."); + } + const parts = address.split('.').reverse(); + for (let i = semicolonAmount; i > 0; i--) { + const insertIndex = i * 4; + parts.splice(insertIndex, 0, ':'); + } + address = parts.join(''); + return new Address6(address); + } + /** + * Return the Microsoft UNC transcription of the address + * @memberof Address6 + * @instance + * @returns {String} the Microsoft UNC transcription of the address + */ + microsoftTranscription() { + return `${this.correctForm().replace(/:/g, '-')}.ipv6-literal.net`; + } + /** + * Return the first n bits of the address, defaulting to the subnet mask + * @memberof Address6 + * @instance + * @param {number} [mask=subnet] - the number of bits to mask + * @returns {String} the first n bits of the address as a string + */ + mask(mask = this.subnetMask) { + return this.getBitsBase2(0, mask); + } + /** + * Return the number of possible subnets of a given size in the address + * @memberof Address6 + * @instance + * @param {number} [subnetSize=128] - the subnet size + * @returns {String} + */ + // TODO: probably useful to have a numeric version of this too + possibleSubnets(subnetSize = 128) { + const availableBits = constants6.BITS - this.subnetMask; + const subnetBits = Math.abs(subnetSize - constants6.BITS); + const subnetPowers = availableBits - subnetBits; + if (subnetPowers < 0) { + return '0'; + } + return addCommas((BigInt('2') ** BigInt(subnetPowers)).toString(10)); + } + /** + * Helper function getting start address. + * @memberof Address6 + * @instance + * @returns {bigint} + */ + _startAddress() { + return BigInt(`0b${this.mask() + '0'.repeat(constants6.BITS - this.subnetMask)}`); + } + /** + * The first address in the range given by this address' subnet + * Often referred to as the Network Address. + * @memberof Address6 + * @instance + * @returns {Address6} + */ + startAddress() { + return Address6.fromBigInt(this._startAddress()); + } + /** + * The first host address in the range given by this address's subnet ie + * the first address after the Network Address + * @memberof Address6 + * @instance + * @returns {Address6} + */ + startAddressExclusive() { + const adjust = BigInt('1'); + return Address6.fromBigInt(this._startAddress() + adjust); + } + /** + * Helper function getting end address. + * @memberof Address6 + * @instance + * @returns {bigint} + */ + _endAddress() { + return BigInt(`0b${this.mask() + '1'.repeat(constants6.BITS - this.subnetMask)}`); + } + /** + * The last address in the range given by this address' subnet + * Often referred to as the Broadcast + * @memberof Address6 + * @instance + * @returns {Address6} + */ + endAddress() { + return Address6.fromBigInt(this._endAddress()); + } + /** + * The last host address in the range given by this address's subnet ie + * the last address prior to the Broadcast Address + * @memberof Address6 + * @instance + * @returns {Address6} + */ + endAddressExclusive() { + const adjust = BigInt('1'); + return Address6.fromBigInt(this._endAddress() - adjust); + } + /** + * Return the scope of the address + * @memberof Address6 + * @instance + * @returns {String} + */ + getScope() { + let scope = constants6.SCOPES[parseInt(this.getBits(12, 16).toString(10), 10)]; + if (this.getType() === 'Global unicast' && scope !== 'Link local') { + scope = 'Global'; + } + return scope || 'Unknown'; + } + /** + * Return the type of the address + * @memberof Address6 + * @instance + * @returns {String} + */ + getType() { + for (const subnet of Object.keys(constants6.TYPES)) { + if (this.isInSubnet(new Address6(subnet))) { + return constants6.TYPES[subnet]; + } + } + return 'Global unicast'; + } + /** + * Return the bits in the given range as a BigInt + * @memberof Address6 + * @instance + * @returns {bigint} + */ + getBits(start, end) { + return BigInt(`0b${this.getBitsBase2(start, end)}`); + } + /** + * Return the bits in the given range as a base-2 string + * @memberof Address6 + * @instance + * @returns {String} + */ + getBitsBase2(start, end) { + return this.binaryZeroPad().slice(start, end); + } + /** + * Return the bits in the given range as a base-16 string + * @memberof Address6 + * @instance + * @returns {String} + */ + getBitsBase16(start, end) { + const length = end - start; + if (length % 4 !== 0) { + throw new Error('Length of bits to retrieve must be divisible by four'); + } + return this.getBits(start, end) + .toString(16) + .padStart(length / 4, '0'); + } + /** + * Return the bits that are set past the subnet mask length + * @memberof Address6 + * @instance + * @returns {String} + */ + getBitsPastSubnet() { + return this.getBitsBase2(this.subnetMask, constants6.BITS); + } + /** + * Return the reversed ip6.arpa form of the address + * @memberof Address6 + * @param {Object} options + * @param {boolean} options.omitSuffix - omit the "ip6.arpa" suffix + * @instance + * @returns {String} + */ + reverseForm(options) { + if (!options) { + options = {}; + } + const characters = Math.floor(this.subnetMask / 4); + const reversed = this.canonicalForm() + .replace(/:/g, '') + .split('') + .slice(0, characters) + .reverse() + .join('.'); + if (characters > 0) { + if (options.omitSuffix) { + return reversed; + } + return `${reversed}.ip6.arpa.`; + } + if (options.omitSuffix) { + return ''; + } + return 'ip6.arpa.'; + } + /** + * Return the correct form of the address + * @memberof Address6 + * @instance + * @returns {String} + */ + correctForm() { + let i; + let groups = []; + let zeroCounter = 0; + const zeroes = []; + for (i = 0; i < this.parsedAddress.length; i++) { + const value = parseInt(this.parsedAddress[i], 16); + if (value === 0) { + zeroCounter++; + } + if (value !== 0 && zeroCounter > 0) { + if (zeroCounter > 1) { + zeroes.push([i - zeroCounter, i - 1]); + } + zeroCounter = 0; + } + } + // Do we end with a string of zeroes? + if (zeroCounter > 1) { + zeroes.push([this.parsedAddress.length - zeroCounter, this.parsedAddress.length - 1]); + } + const zeroLengths = zeroes.map((n) => n[1] - n[0] + 1); + if (zeroes.length > 0) { + const index = zeroLengths.indexOf(Math.max(...zeroLengths)); + groups = compact(this.parsedAddress, zeroes[index]); + } + else { + groups = this.parsedAddress; + } + for (i = 0; i < groups.length; i++) { + if (groups[i] !== 'compact') { + groups[i] = parseInt(groups[i], 16).toString(16); + } + } + let correct = groups.join(':'); + correct = correct.replace(/^compact$/, '::'); + correct = correct.replace(/(^compact)|(compact$)/, ':'); + correct = correct.replace(/compact/, ''); + return correct; + } + /** + * Return a zero-padded base-2 string representation of the address + * @memberof Address6 + * @instance + * @returns {String} + * @example + * var address = new Address6('2001:4860:4001:803::1011'); + * address.binaryZeroPad(); + * // '0010000000000001010010000110000001000000000000010000100000000011 + * // 0000000000000000000000000000000000000000000000000001000000010001' + */ + binaryZeroPad() { + return this.bigInt().toString(2).padStart(constants6.BITS, '0'); + } + // TODO: Improve the semantics of this helper function + parse4in6(address) { + const groups = address.split(':'); + const lastGroup = groups.slice(-1)[0]; + const address4 = lastGroup.match(constants4.RE_ADDRESS); + if (address4) { + this.parsedAddress4 = address4[0]; + this.address4 = new ipv4_1.Address4(this.parsedAddress4); + for (let i = 0; i < this.address4.groups; i++) { + if (/^0[0-9]+/.test(this.address4.parsedAddress[i])) { + throw new address_error_1.AddressError("IPv4 addresses can't have leading zeroes.", address.replace(constants4.RE_ADDRESS, this.address4.parsedAddress.map(spanLeadingZeroes4).join('.'))); + } + } + this.v4 = true; + groups[groups.length - 1] = this.address4.toGroup6(); + address = groups.join(':'); + } + return address; + } + // TODO: Make private? + parse(address) { + address = this.parse4in6(address); + const badCharacters = address.match(constants6.RE_BAD_CHARACTERS); + if (badCharacters) { + throw new address_error_1.AddressError(`Bad character${badCharacters.length > 1 ? 's' : ''} detected in address: ${badCharacters.join('')}`, address.replace(constants6.RE_BAD_CHARACTERS, '<span class="parse-error">$1</span>')); + } + const badAddress = address.match(constants6.RE_BAD_ADDRESS); + if (badAddress) { + throw new address_error_1.AddressError(`Address failed regex: ${badAddress.join('')}`, address.replace(constants6.RE_BAD_ADDRESS, '<span class="parse-error">$1</span>')); + } + let groups = []; + const halves = address.split('::'); + if (halves.length === 2) { + let first = halves[0].split(':'); + let last = halves[1].split(':'); + if (first.length === 1 && first[0] === '') { + first = []; + } + if (last.length === 1 && last[0] === '') { + last = []; + } + const remaining = this.groups - (first.length + last.length); + if (!remaining) { + throw new address_error_1.AddressError('Error parsing groups'); + } + this.elidedGroups = remaining; + this.elisionBegin = first.length; + this.elisionEnd = first.length + this.elidedGroups; + groups = groups.concat(first); + for (let i = 0; i < remaining; i++) { + groups.push('0'); + } + groups = groups.concat(last); + } + else if (halves.length === 1) { + groups = address.split(':'); + this.elidedGroups = 0; + } + else { + throw new address_error_1.AddressError('Too many :: groups found'); + } + groups = groups.map((group) => parseInt(group, 16).toString(16)); + if (groups.length !== this.groups) { + throw new address_error_1.AddressError('Incorrect number of groups found'); + } + return groups; + } + /** + * Return the canonical form of the address + * @memberof Address6 + * @instance + * @returns {String} + */ + canonicalForm() { + return this.parsedAddress.map(paddedHex).join(':'); + } + /** + * Return the decimal form of the address + * @memberof Address6 + * @instance + * @returns {String} + */ + decimal() { + return this.parsedAddress.map((n) => parseInt(n, 16).toString(10).padStart(5, '0')).join(':'); + } + /** + * Return the address as a BigInt + * @memberof Address6 + * @instance + * @returns {bigint} + */ + bigInt() { + return BigInt(`0x${this.parsedAddress.map(paddedHex).join('')}`); + } + /** + * Return the last two groups of this address as an IPv4 address string + * @memberof Address6 + * @instance + * @returns {Address4} + * @example + * var address = new Address6('2001:4860:4001::1825:bf11'); + * address.to4().correctForm(); // '24.37.191.17' + */ + to4() { + const binary = this.binaryZeroPad().split(''); + return ipv4_1.Address4.fromHex(BigInt(`0b${binary.slice(96, 128).join('')}`).toString(16)); + } + /** + * Return the v4-in-v6 form of the address + * @memberof Address6 + * @instance + * @returns {String} + */ + to4in6() { + const address4 = this.to4(); + const address6 = new Address6(this.parsedAddress.slice(0, 6).join(':'), 6); + const correct = address6.correctForm(); + let infix = ''; + if (!/:$/.test(correct)) { + infix = ':'; + } + return correct + infix + address4.address; + } + /** + * Return an object containing the Teredo properties of the address + * @memberof Address6 + * @instance + * @returns {Object} + */ + inspectTeredo() { + /* + - Bits 0 to 31 are set to the Teredo prefix (normally 2001:0000::/32). + - Bits 32 to 63 embed the primary IPv4 address of the Teredo server that + is used. + - Bits 64 to 79 can be used to define some flags. Currently only the + higher order bit is used; it is set to 1 if the Teredo client is + located behind a cone NAT, 0 otherwise. For Microsoft's Windows Vista + and Windows Server 2008 implementations, more bits are used. In those + implementations, the format for these 16 bits is "CRAAAAUG AAAAAAAA", + where "C" remains the "Cone" flag. The "R" bit is reserved for future + use. The "U" bit is for the Universal/Local flag (set to 0). The "G" bit + is Individual/Group flag (set to 0). The A bits are set to a 12-bit + randomly generated number chosen by the Teredo client to introduce + additional protection for the Teredo node against IPv6-based scanning + attacks. + - Bits 80 to 95 contains the obfuscated UDP port number. This is the + port number that is mapped by the NAT to the Teredo client with all + bits inverted. + - Bits 96 to 127 contains the obfuscated IPv4 address. This is the + public IPv4 address of the NAT with all bits inverted. + */ + const prefix = this.getBitsBase16(0, 32); + const bitsForUdpPort = this.getBits(80, 96); + // eslint-disable-next-line no-bitwise + const udpPort = (bitsForUdpPort ^ BigInt('0xffff')).toString(); + const server4 = ipv4_1.Address4.fromHex(this.getBitsBase16(32, 64)); + const bitsForClient4 = this.getBits(96, 128); + // eslint-disable-next-line no-bitwise + const client4 = ipv4_1.Address4.fromHex((bitsForClient4 ^ BigInt('0xffffffff')).toString(16)); + const flagsBase2 = this.getBitsBase2(64, 80); + const coneNat = (0, common_1.testBit)(flagsBase2, 15); + const reserved = (0, common_1.testBit)(flagsBase2, 14); + const groupIndividual = (0, common_1.testBit)(flagsBase2, 8); + const universalLocal = (0, common_1.testBit)(flagsBase2, 9); + const nonce = BigInt(`0b${flagsBase2.slice(2, 6) + flagsBase2.slice(8, 16)}`).toString(10); + return { + prefix: `${prefix.slice(0, 4)}:${prefix.slice(4, 8)}`, + server4: server4.address, + client4: client4.address, + flags: flagsBase2, + coneNat, + microsoft: { + reserved, + universalLocal, + groupIndividual, + nonce, + }, + udpPort, + }; + } + /** + * Return an object containing the 6to4 properties of the address + * @memberof Address6 + * @instance + * @returns {Object} + */ + inspect6to4() { + /* + - Bits 0 to 15 are set to the 6to4 prefix (2002::/16). + - Bits 16 to 48 embed the IPv4 address of the 6to4 gateway that is used. + */ + const prefix = this.getBitsBase16(0, 16); + const gateway = ipv4_1.Address4.fromHex(this.getBitsBase16(16, 48)); + return { + prefix: prefix.slice(0, 4), + gateway: gateway.address, + }; + } + /** + * Return a v6 6to4 address from a v6 v4inv6 address + * @memberof Address6 + * @instance + * @returns {Address6} + */ + to6to4() { + if (!this.is4()) { + return null; + } + const addr6to4 = [ + '2002', + this.getBitsBase16(96, 112), + this.getBitsBase16(112, 128), + '', + '/16', + ].join(':'); + return new Address6(addr6to4); + } + /** + * Return a byte array + * @memberof Address6 + * @instance + * @returns {Array} + */ + toByteArray() { + const valueWithoutPadding = this.bigInt().toString(16); + const leadingPad = '0'.repeat(valueWithoutPadding.length % 2); + const value = `${leadingPad}${valueWithoutPadding}`; + const bytes = []; + for (let i = 0, length = value.length; i < length; i += 2) { + bytes.push(parseInt(value.substring(i, i + 2), 16)); + } + return bytes; + } + /** + * Return an unsigned byte array + * @memberof Address6 + * @instance + * @returns {Array} + */ + toUnsignedByteArray() { + return this.toByteArray().map(unsignByte); + } + /** + * Convert a byte array to an Address6 object + * @memberof Address6 + * @static + * @returns {Address6} + */ + static fromByteArray(bytes) { + return this.fromUnsignedByteArray(bytes.map(unsignByte)); + } + /** + * Convert an unsigned byte array to an Address6 object + * @memberof Address6 + * @static + * @returns {Address6} + */ + static fromUnsignedByteArray(bytes) { + const BYTE_MAX = BigInt('256'); + let result = BigInt('0'); + let multiplier = BigInt('1'); + for (let i = bytes.length - 1; i >= 0; i--) { + result += multiplier * BigInt(bytes[i].toString(10)); + multiplier *= BYTE_MAX; + } + return Address6.fromBigInt(result); + } + /** + * Returns true if the address is in the canonical form, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + isCanonical() { + return this.addressMinusSuffix === this.canonicalForm(); + } + /** + * Returns true if the address is a link local address, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + isLinkLocal() { + // Zeroes are required, i.e. we can't check isInSubnet with 'fe80::/10' + if (this.getBitsBase2(0, 64) === + '1111111010000000000000000000000000000000000000000000000000000000') { + return true; + } + return false; + } + /** + * Returns true if the address is a multicast address, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + isMulticast() { + return this.getType() === 'Multicast'; + } + /** + * Returns true if the address is a v4-in-v6 address, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + is4() { + return this.v4; + } + /** + * Returns true if the address is a Teredo address, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + isTeredo() { + return this.isInSubnet(new Address6('2001::/32')); + } + /** + * Returns true if the address is a 6to4 address, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + is6to4() { + return this.isInSubnet(new Address6('2002::/16')); + } + /** + * Returns true if the address is a loopback address, false otherwise + * @memberof Address6 + * @instance + * @returns {boolean} + */ + isLoopback() { + return this.getType() === 'Loopback'; + } + // #endregion + // #region HTML + /** + * @returns {String} the address in link form with a default port of 80 + */ + href(optionalPort) { + if (optionalPort === undefined) { + optionalPort = ''; + } + else { + optionalPort = `:${optionalPort}`; + } + return `http://[${this.correctForm()}]${optionalPort}/`; + } + /** + * @returns {String} a link suitable for conveying the address via a URL hash + */ + link(options) { + if (!options) { + options = {}; + } + if (options.className === undefined) { + options.className = ''; + } + if (options.prefix === undefined) { + options.prefix = '/#address='; + } + if (options.v4 === undefined) { + options.v4 = false; + } + let formFunction = this.correctForm; + if (options.v4) { + formFunction = this.to4in6; + } + const form = formFunction.call(this); + if (options.className) { + return `<a href="${options.prefix}${form}" class="${options.className}">${form}</a>`; + } + return `<a href="${options.prefix}${form}">${form}</a>`; + } + /** + * Groups an address + * @returns {String} + */ + group() { + if (this.elidedGroups === 0) { + // The simple case + return helpers.simpleGroup(this.address).join(':'); + } + assert(typeof this.elidedGroups === 'number'); + assert(typeof this.elisionBegin === 'number'); + // The elided case + const output = []; + const [left, right] = this.address.split('::'); + if (left.length) { + output.push(...helpers.simpleGroup(left)); + } + else { + output.push(''); + } + const classes = ['hover-group']; + for (let i = this.elisionBegin; i < this.elisionBegin + this.elidedGroups; i++) { + classes.push(`group-${i}`); + } + output.push(`<span class="${classes.join(' ')}"></span>`); + if (right.length) { + output.push(...helpers.simpleGroup(right, this.elisionEnd)); + } + else { + output.push(''); + } + if (this.is4()) { + assert(this.address4 instanceof ipv4_1.Address4); + output.pop(); + output.push(this.address4.groupForV6()); + } + return output.join(':'); + } + // #endregion + // #region Regular expressions + /** + * Generate a regular expression string that can be used to find or validate + * all variations of this address + * @memberof Address6 + * @instance + * @param {boolean} substringSearch + * @returns {string} + */ + regularExpressionString(substringSearch = false) { + let output = []; + // TODO: revisit why this is necessary + const address6 = new Address6(this.correctForm()); + if (address6.elidedGroups === 0) { + // The simple case + output.push((0, regular_expressions_1.simpleRegularExpression)(address6.parsedAddress)); + } + else if (address6.elidedGroups === constants6.GROUPS) { + // A completely elided address + output.push((0, regular_expressions_1.possibleElisions)(constants6.GROUPS)); + } + else { + // A partially elided address + const halves = address6.address.split('::'); + if (halves[0].length) { + output.push((0, regular_expressions_1.simpleRegularExpression)(halves[0].split(':'))); + } + assert(typeof address6.elidedGroups === 'number'); + output.push((0, regular_expressions_1.possibleElisions)(address6.elidedGroups, halves[0].length !== 0, halves[1].length !== 0)); + if (halves[1].length) { + output.push((0, regular_expressions_1.simpleRegularExpression)(halves[1].split(':'))); + } + output = [output.join(':')]; + } + if (!substringSearch) { + output = [ + '(?=^|', + regular_expressions_1.ADDRESS_BOUNDARY, + '|[^\\w\\:])(', + ...output, + ')(?=[^\\w\\:]|', + regular_expressions_1.ADDRESS_BOUNDARY, + '|$)', + ]; + } + return output.join(''); + } + /** + * Generate a regular expression that can be used to find or validate all + * variations of this address. + * @memberof Address6 + * @instance + * @param {boolean} substringSearch + * @returns {RegExp} + */ + regularExpression(substringSearch = false) { + return new RegExp(this.regularExpressionString(substringSearch), 'i'); + } +} +exports.Address6 = Address6; +//# sourceMappingURL=ipv6.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/v4/constants.js b/node_modules/ip-address/dist/v4/constants.js new file mode 100644 index 0000000000000..6fa2518f96491 --- /dev/null +++ b/node_modules/ip-address/dist/v4/constants.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RE_SUBNET_STRING = exports.RE_ADDRESS = exports.GROUPS = exports.BITS = void 0; +exports.BITS = 32; +exports.GROUPS = 4; +exports.RE_ADDRESS = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g; +exports.RE_SUBNET_STRING = /\/\d{1,2}$/; +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/v6/constants.js b/node_modules/ip-address/dist/v6/constants.js new file mode 100644 index 0000000000000..0abc423e0a91a --- /dev/null +++ b/node_modules/ip-address/dist/v6/constants.js @@ -0,0 +1,76 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RE_URL_WITH_PORT = exports.RE_URL = exports.RE_ZONE_STRING = exports.RE_SUBNET_STRING = exports.RE_BAD_ADDRESS = exports.RE_BAD_CHARACTERS = exports.TYPES = exports.SCOPES = exports.GROUPS = exports.BITS = void 0; +exports.BITS = 128; +exports.GROUPS = 8; +/** + * Represents IPv6 address scopes + * @memberof Address6 + * @static + */ +exports.SCOPES = { + 0: 'Reserved', + 1: 'Interface local', + 2: 'Link local', + 4: 'Admin local', + 5: 'Site local', + 8: 'Organization local', + 14: 'Global', + 15: 'Reserved', +}; +/** + * Represents IPv6 address types + * @memberof Address6 + * @static + */ +exports.TYPES = { + 'ff01::1/128': 'Multicast (All nodes on this interface)', + 'ff01::2/128': 'Multicast (All routers on this interface)', + 'ff02::1/128': 'Multicast (All nodes on this link)', + 'ff02::2/128': 'Multicast (All routers on this link)', + 'ff05::2/128': 'Multicast (All routers in this site)', + 'ff02::5/128': 'Multicast (OSPFv3 AllSPF routers)', + 'ff02::6/128': 'Multicast (OSPFv3 AllDR routers)', + 'ff02::9/128': 'Multicast (RIP routers)', + 'ff02::a/128': 'Multicast (EIGRP routers)', + 'ff02::d/128': 'Multicast (PIM routers)', + 'ff02::16/128': 'Multicast (MLDv2 reports)', + 'ff01::fb/128': 'Multicast (mDNSv6)', + 'ff02::fb/128': 'Multicast (mDNSv6)', + 'ff05::fb/128': 'Multicast (mDNSv6)', + 'ff02::1:2/128': 'Multicast (All DHCP servers and relay agents on this link)', + 'ff05::1:2/128': 'Multicast (All DHCP servers and relay agents in this site)', + 'ff02::1:3/128': 'Multicast (All DHCP servers on this link)', + 'ff05::1:3/128': 'Multicast (All DHCP servers in this site)', + '::/128': 'Unspecified', + '::1/128': 'Loopback', + 'ff00::/8': 'Multicast', + 'fe80::/10': 'Link-local unicast', +}; +/** + * A regular expression that matches bad characters in an IPv6 address + * @memberof Address6 + * @static + */ +exports.RE_BAD_CHARACTERS = /([^0-9a-f:/%])/gi; +/** + * A regular expression that matches an incorrect IPv6 address + * @memberof Address6 + * @static + */ +exports.RE_BAD_ADDRESS = /([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi; +/** + * A regular expression that matches an IPv6 subnet + * @memberof Address6 + * @static + */ +exports.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/; +/** + * A regular expression that matches an IPv6 zone + * @memberof Address6 + * @static + */ +exports.RE_ZONE_STRING = /%.*$/; +exports.RE_URL = /^\[{0,1}([0-9a-f:]+)\]{0,1}/; +exports.RE_URL_WITH_PORT = /\[([0-9a-f:]+)\]:([0-9]{1,5})/; +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/v6/helpers.js b/node_modules/ip-address/dist/v6/helpers.js new file mode 100644 index 0000000000000..fafca0c2712dd --- /dev/null +++ b/node_modules/ip-address/dist/v6/helpers.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.spanAllZeroes = spanAllZeroes; +exports.spanAll = spanAll; +exports.spanLeadingZeroes = spanLeadingZeroes; +exports.simpleGroup = simpleGroup; +/** + * @returns {String} the string with all zeroes contained in a <span> + */ +function spanAllZeroes(s) { + return s.replace(/(0+)/g, '<span class="zero">$1</span>'); +} +/** + * @returns {String} the string with each character contained in a <span> + */ +function spanAll(s, offset = 0) { + const letters = s.split(''); + return letters + .map((n, i) => `<span class="digit value-${n} position-${i + offset}">${spanAllZeroes(n)}</span>`) + .join(''); +} +function spanLeadingZeroesSimple(group) { + return group.replace(/^(0+)/, '<span class="zero">$1</span>'); +} +/** + * @returns {String} the string with leading zeroes contained in a <span> + */ +function spanLeadingZeroes(address) { + const groups = address.split(':'); + return groups.map((g) => spanLeadingZeroesSimple(g)).join(':'); +} +/** + * Groups an address + * @returns {String} a grouped address + */ +function simpleGroup(addressString, offset = 0) { + const groups = addressString.split(':'); + return groups.map((g, i) => { + if (/group-v4/.test(g)) { + return g; + } + return `<span class="hover-group group-${i + offset}">${spanLeadingZeroesSimple(g)}</span>`; + }); +} +//# sourceMappingURL=helpers.js.map \ No newline at end of file diff --git a/node_modules/ip-address/dist/v6/regular-expressions.js b/node_modules/ip-address/dist/v6/regular-expressions.js new file mode 100644 index 0000000000000..a2c51459307fd --- /dev/null +++ b/node_modules/ip-address/dist/v6/regular-expressions.js @@ -0,0 +1,95 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ADDRESS_BOUNDARY = void 0; +exports.groupPossibilities = groupPossibilities; +exports.padGroup = padGroup; +exports.simpleRegularExpression = simpleRegularExpression; +exports.possibleElisions = possibleElisions; +const v6 = __importStar(require("./constants")); +function groupPossibilities(possibilities) { + return `(${possibilities.join('|')})`; +} +function padGroup(group) { + if (group.length < 4) { + return `0{0,${4 - group.length}}${group}`; + } + return group; +} +exports.ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]'; +function simpleRegularExpression(groups) { + const zeroIndexes = []; + groups.forEach((group, i) => { + const groupInteger = parseInt(group, 16); + if (groupInteger === 0) { + zeroIndexes.push(i); + } + }); + // You can technically elide a single 0, this creates the regular expressions + // to match that eventuality + const possibilities = zeroIndexes.map((zeroIndex) => groups + .map((group, i) => { + if (i === zeroIndex) { + const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : ''; + return groupPossibilities([padGroup(group), elision]); + } + return padGroup(group); + }) + .join(':')); + // The simplest case + possibilities.push(groups.map(padGroup).join(':')); + return groupPossibilities(possibilities); +} +function possibleElisions(elidedGroups, moreLeft, moreRight) { + const left = moreLeft ? '' : ':'; + const right = moreRight ? '' : ':'; + const possibilities = []; + // 1. elision of everything (::) + if (!moreLeft && !moreRight) { + possibilities.push('::'); + } + // 2. complete elision of the middle + if (moreLeft && moreRight) { + possibilities.push(''); + } + if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) { + // 3. complete elision of one side + possibilities.push(':'); + } + // 4. elision from the left side + possibilities.push(`${left}(:0{1,4}){1,${elidedGroups - 1}}`); + // 5. elision from the right side + possibilities.push(`(0{1,4}:){1,${elidedGroups - 1}}${right}`); + // 6. no elision + possibilities.push(`(0{1,4}:){${elidedGroups - 1}}0{1,4}`); + // 7. elision (including sloppy elision) from the middle + for (let groups = 1; groups < elidedGroups - 1; groups++) { + for (let position = 1; position < elidedGroups - groups; position++) { + possibilities.push(`(0{1,4}:){${position}}:(0{1,4}:){${elidedGroups - position - groups - 1}}0{1,4}`); + } + } + return groupPossibilities(possibilities); +} +//# sourceMappingURL=regular-expressions.js.map \ No newline at end of file diff --git a/node_modules/ip-address/package.json b/node_modules/ip-address/package.json new file mode 100644 index 0000000000000..5cf811e8c563a --- /dev/null +++ b/node_modules/ip-address/package.json @@ -0,0 +1,78 @@ +{ + "name": "ip-address", + "description": "A library for parsing IPv4 and IPv6 IP addresses in node and the browser.", + "keywords": [ + "ipv6", + "ipv4", + "browser", + "validation" + ], + "version": "10.1.0", + "author": "Beau Gunderson <beau@beaugunderson.com> (https://beaugunderson.com/)", + "license": "MIT", + "main": "dist/ip-address.js", + "types": "dist/ip-address.d.ts", + "scripts": { + "docs": "documentation build --github --output docs --format html ./ip-address.js", + "build": "rm -rf dist; mkdir dist; tsc", + "prepack": "npm run build", + "release": "release-it", + "test-ci": "nyc mocha", + "test": "mocha", + "watch": "mocha --watch" + }, + "nyc": { + "extension": [ + ".ts" + ], + "exclude": [ + "**/*.d.ts", + ".eslintrc.js", + "coverage/", + "dist/", + "test/", + "tmp/" + ], + "reporter": [ + "html", + "lcov", + "text" + ], + "all": true + }, + "engines": { + "node": ">= 12" + }, + "files": [ + "src", + "dist" + ], + "repository": { + "type": "git", + "url": "git://github.com/beaugunderson/ip-address.git" + }, + "devDependencies": { + "@types/chai": "^5.0.0", + "@types/mocha": "^10.0.8", + "@typescript-eslint/eslint-plugin": "^8.8.0", + "@typescript-eslint/parser": "^8.8.0", + "chai": "^5.1.1", + "documentation": "^14.0.3", + "eslint": "^8.50.0", + "eslint_d": "^14.0.4", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-filenames": "^1.3.2", + "eslint-plugin-import": "^2.30.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", + "mocha": "^10.7.3", + "nyc": "^17.1.0", + "prettier": "^3.3.3", + "release-it": "^17.6.0", + "source-map-support": "^0.5.21", + "tsx": "^4.19.1", + "typescript": "<5.6.0" + } +} diff --git a/node_modules/ip-regex/index.d.ts b/node_modules/ip-regex/index.d.ts deleted file mode 100644 index 0999ed287f790..0000000000000 --- a/node_modules/ip-regex/index.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -declare namespace ip { - interface Options { - /** - Only match an exact string. Useful with `RegExp#test()` to check if a string is an IP address. *(`false` matches any IP address in a string)* - - @default false - */ - readonly exact?: boolean; - - /** - Include boundaries in the regex. When `true`, `192.168.0.2000000000` will report as an invalid IPv4 address. If this option is not set, the mentioned IPv4 address would report as valid (ignoring the trailing zeros). - - @default false - */ - readonly includeBoundaries?: boolean; - } -} - -declare const ip: { - /** - Regular expression for matching IP addresses. - - @returns A regex for matching both IPv4 and IPv6. - - @example - ``` - import ipRegex = require('ip-regex'); - - // Contains an IP address? - ipRegex().test('unicorn 192.168.0.1'); - //=> true - - // Is an IP address? - ipRegex({exact: true}).test('unicorn 192.168.0.1'); - //=> false - - 'unicorn 192.168.0.1 cake 1:2:3:4:5:6:7:8 rainbow'.match(ipRegex()); - //=> ['192.168.0.1', '1:2:3:4:5:6:7:8'] - - // Contains an IP address? - ipRegex({includeBoundaries: true}).test('192.168.0.2000000000'); - //=> false - - // Matches an IP address? - '192.168.0.2000000000'.match(ipRegex({includeBoundaries: true})); - //=> null - ``` - */ - (options?: ip.Options): RegExp; - - /** - @returns A regex for matching IPv4. - */ - v4(options?: ip.Options): RegExp; - - /** - @returns A regex for matching IPv6. - - @example - ``` - import ipRegex = require('ip-regex'); - - ipRegex.v6({exact: true}).test('1:2:3:4:5:6:7:8'); - //=> true - ``` - */ - v6(options?: ip.Options): RegExp; -}; - -export = ip; diff --git a/node_modules/ip-regex/index.js b/node_modules/ip-regex/index.js index ab7a37f1caf0e..1fe723cb7f5a9 100644 --- a/node_modules/ip-regex/index.js +++ b/node_modules/ip-regex/index.js @@ -1,23 +1,23 @@ -'use strict'; - const word = '[a-fA-F\\d:]'; -const b = options => options && options.includeBoundaries ? - `(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))` : - ''; + +const boundry = options => options && options.includeBoundaries + ? `(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))` + : ''; const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}'; -const v6seg = '[a-fA-F\\d]{1,4}'; +const v6segment = '[a-fA-F\\d]{1,4}'; + const v6 = ` (?: -(?:${v6seg}:){7}(?:${v6seg}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8 -(?:${v6seg}:){6}(?:${v4}|:${v6seg}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4 -(?:${v6seg}:){5}(?::${v4}|(?::${v6seg}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4 -(?:${v6seg}:){4}(?:(?::${v6seg}){0,1}:${v4}|(?::${v6seg}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4 -(?:${v6seg}:){3}(?:(?::${v6seg}){0,2}:${v4}|(?::${v6seg}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4 -(?:${v6seg}:){2}(?:(?::${v6seg}){0,3}:${v4}|(?::${v6seg}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4 -(?:${v6seg}:){1}(?:(?::${v6seg}){0,4}:${v4}|(?::${v6seg}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4 -(?::(?:(?::${v6seg}){0,5}:${v4}|(?::${v6seg}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 +(?:${v6segment}:){7}(?:${v6segment}|:)| // 1:2:3:4:5:6:7:: 1:2:3:4:5:6:7:8 +(?:${v6segment}:){6}(?:${v4}|:${v6segment}|:)| // 1:2:3:4:5:6:: 1:2:3:4:5:6::8 1:2:3:4:5:6::8 1:2:3:4:5:6::1.2.3.4 +(?:${v6segment}:){5}(?::${v4}|(?::${v6segment}){1,2}|:)| // 1:2:3:4:5:: 1:2:3:4:5::7:8 1:2:3:4:5::8 1:2:3:4:5::7:1.2.3.4 +(?:${v6segment}:){4}(?:(?::${v6segment}){0,1}:${v4}|(?::${v6segment}){1,3}|:)| // 1:2:3:4:: 1:2:3:4::6:7:8 1:2:3:4::8 1:2:3:4::6:7:1.2.3.4 +(?:${v6segment}:){3}(?:(?::${v6segment}){0,2}:${v4}|(?::${v6segment}){1,4}|:)| // 1:2:3:: 1:2:3::5:6:7:8 1:2:3::8 1:2:3::5:6:7:1.2.3.4 +(?:${v6segment}:){2}(?:(?::${v6segment}){0,3}:${v4}|(?::${v6segment}){1,5}|:)| // 1:2:: 1:2::4:5:6:7:8 1:2::8 1:2::4:5:6:7:1.2.3.4 +(?:${v6segment}:){1}(?:(?::${v6segment}){0,4}:${v4}|(?::${v6segment}){1,6}|:)| // 1:: 1::3:4:5:6:7:8 1::8 1::3:4:5:6:7:1.2.3.4 +(?::(?:(?::${v6segment}){0,5}:${v4}|(?::${v6segment}){1,7}|:)) // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::1.2.3.4 )(?:%[0-9a-zA-Z]{1,})? // %eth0 %1 `.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim(); @@ -26,11 +26,11 @@ const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`); const v4exact = new RegExp(`^${v4}$`); const v6exact = new RegExp(`^${v6}$`); -const ip = options => options && options.exact ? - v46Exact : - new RegExp(`(?:${b(options)}${v4}${b(options)})|(?:${b(options)}${v6}${b(options)})`, 'g'); +const ipRegex = options => options && options.exact + ? v46Exact + : new RegExp(`(?:${boundry(options)}${v4}${boundry(options)})|(?:${boundry(options)}${v6}${boundry(options)})`, 'g'); -ip.v4 = options => options && options.exact ? v4exact : new RegExp(`${b(options)}${v4}${b(options)}`, 'g'); -ip.v6 = options => options && options.exact ? v6exact : new RegExp(`${b(options)}${v6}${b(options)}`, 'g'); +ipRegex.v4 = options => options && options.exact ? v4exact : new RegExp(`${boundry(options)}${v4}${boundry(options)}`, 'g'); +ipRegex.v6 = options => options && options.exact ? v6exact : new RegExp(`${boundry(options)}${v6}${boundry(options)}`, 'g'); -module.exports = ip; +export default ipRegex; diff --git a/node_modules/ip-regex/license b/node_modules/ip-regex/license index e7af2f77107d7..fa7ceba3eb4a9 100644 --- a/node_modules/ip-regex/license +++ b/node_modules/ip-regex/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/node_modules/ip-regex/package.json b/node_modules/ip-regex/package.json index 2fb8a03c812a0..1f82fd5947262 100644 --- a/node_modules/ip-regex/package.json +++ b/node_modules/ip-regex/package.json @@ -1,16 +1,19 @@ { "name": "ip-regex", - "version": "4.3.0", + "version": "5.0.0", "description": "Regular expression for matching IP addresses (IPv4 & IPv6)", "license": "MIT", "repository": "sindresorhus/ip-regex", + "funding": "https://github.com/sponsors/sindresorhus", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", "url": "sindresorhus.com" }, + "type": "module", + "exports": "./index.js", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "scripts": { "test": "xo && ava && tsd" @@ -37,8 +40,8 @@ "validate" ], "devDependencies": { - "ava": "^1.4.1", - "tsd": "^0.7.2", - "xo": "^0.24.0" + "ava": "^3.15.0", + "tsd": "^0.19.1", + "xo": "^0.47.0" } } diff --git a/node_modules/ip-regex/readme.md b/node_modules/ip-regex/readme.md deleted file mode 100644 index 81723a0f950ec..0000000000000 --- a/node_modules/ip-regex/readme.md +++ /dev/null @@ -1,86 +0,0 @@ -# ip-regex - -> Regular expression for matching IP addresses - - -## Install - -``` -$ npm install ip-regex -``` - -This module targets Node.js 8 or later and the latest version of Chrome, Firefox, and Safari. If you want support for older browsers, use version 2.1.0: `npm install ip-regex@2.1.0` - - -## Usage - -```js -const ipRegex = require('ip-regex'); - -// Contains an IP address? -ipRegex().test('unicorn 192.168.0.1'); -//=> true - -// Is an IP address? -ipRegex({exact: true}).test('unicorn 192.168.0.1'); -//=> false - -ipRegex.v6({exact: true}).test('1:2:3:4:5:6:7:8'); -//=> true - -'unicorn 192.168.0.1 cake 1:2:3:4:5:6:7:8 rainbow'.match(ipRegex()); -//=> ['192.168.0.1', '1:2:3:4:5:6:7:8'] - -// Contains an IP address? -ipRegex({includeBoundaries: true}).test('192.168.0.2000000000'); -//=> false - -// Matches an IP address? -'192.168.0.2000000000'.match(ipRegex({includeBoundaries: true})); -//=> null -``` - - -## API - -### ipRegex([options]) - -Returns a regex for matching both IPv4 and IPv6. - -### ipRegex.v4([options]) - -Returns a regex for matching IPv4. - -### ipRegex.v6([options]) - -Returns a regex for matching IPv6. - -#### options - -Type: `Object` - -##### exact - -Type: `boolean`<br> -Default: `false` *(Matches any IP address in a string)* - -Only match an exact string. Useful with `RegExp#test()` to check if a string is an IP address. - -##### includeBoundaries - -Type: `boolean`<br> -Default: `false` - -Include boundaries in the regex. When `true`, `192.168.0.2000000000` will report as an invalid IPv4 address. If this option is not set, the mentioned IPv4 address would report as valid (ignoring the trailing zeros). - - -## Related - -- [is-ip](https://github.com/sindresorhus/is-ip) - Check if a string is an IP address -- [is-cidr](https://github.com/silverwind/is-cidr) - Check if a string is an IP address in CIDR notation -- [cidr-regex](https://github.com/silverwind/cidr-regex) - Regular expression for matching IP addresses in CIDR notation - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/ip/lib/ip.js b/node_modules/ip/lib/ip.js deleted file mode 100644 index 5b5ccc246a4ab..0000000000000 --- a/node_modules/ip/lib/ip.js +++ /dev/null @@ -1,427 +0,0 @@ -var ip = exports; -var { Buffer } = require('buffer'); -var os = require('os'); - -ip.toBuffer = function (ip, buff, offset) { - offset = ~~offset; - - var result; - - if (this.isV4Format(ip)) { - result = buff || new Buffer(offset + 4); - ip.split(/\./g).map((byte) => { - result[offset++] = parseInt(byte, 10) & 0xff; - }); - } else if (this.isV6Format(ip)) { - var sections = ip.split(':', 8); - - var i; - for (i = 0; i < sections.length; i++) { - var isv4 = this.isV4Format(sections[i]); - var v4Buffer; - - if (isv4) { - v4Buffer = this.toBuffer(sections[i]); - sections[i] = v4Buffer.slice(0, 2).toString('hex'); - } - - if (v4Buffer && ++i < 8) { - sections.splice(i, 0, v4Buffer.slice(2, 4).toString('hex')); - } - } - - if (sections[0] === '') { - while (sections.length < 8) sections.unshift('0'); - } else if (sections[sections.length - 1] === '') { - while (sections.length < 8) sections.push('0'); - } else if (sections.length < 8) { - for (i = 0; i < sections.length && sections[i] !== ''; i++); - var argv = [i, 1]; - for (i = 9 - sections.length; i > 0; i--) { - argv.push('0'); - } - sections.splice.apply(sections, argv); - } - - result = buff || new Buffer(offset + 16); - for (i = 0; i < sections.length; i++) { - var word = parseInt(sections[i], 16); - result[offset++] = (word >> 8) & 0xff; - result[offset++] = word & 0xff; - } - } - - if (!result) { - throw Error(`Invalid ip address: ${ip}`); - } - - return result; -}; - -ip.toString = function (buff, offset, length) { - offset = ~~offset; - length = length || (buff.length - offset); - - var result = []; - var i; - if (length === 4) { - // IPv4 - for (i = 0; i < length; i++) { - result.push(buff[offset + i]); - } - result = result.join('.'); - } else if (length === 16) { - // IPv6 - for (i = 0; i < length; i += 2) { - result.push(buff.readUInt16BE(offset + i).toString(16)); - } - result = result.join(':'); - result = result.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3'); - result = result.replace(/:{3,4}/, '::'); - } - - return result; -}; - -var ipv4Regex = /^(\d{1,3}\.){3,3}\d{1,3}$/; -var ipv6Regex = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i; - -ip.isV4Format = function (ip) { - return ipv4Regex.test(ip); -}; - -ip.isV6Format = function (ip) { - return ipv6Regex.test(ip); -}; - -function _normalizeFamily(family) { - if (family === 4) { - return 'ipv4'; - } - if (family === 6) { - return 'ipv6'; - } - return family ? family.toLowerCase() : 'ipv4'; -} - -ip.fromPrefixLen = function (prefixlen, family) { - if (prefixlen > 32) { - family = 'ipv6'; - } else { - family = _normalizeFamily(family); - } - - var len = 4; - if (family === 'ipv6') { - len = 16; - } - var buff = new Buffer(len); - - for (var i = 0, n = buff.length; i < n; ++i) { - var bits = 8; - if (prefixlen < 8) { - bits = prefixlen; - } - prefixlen -= bits; - - buff[i] = ~(0xff >> bits) & 0xff; - } - - return ip.toString(buff); -}; - -ip.mask = function (addr, mask) { - addr = ip.toBuffer(addr); - mask = ip.toBuffer(mask); - - var result = new Buffer(Math.max(addr.length, mask.length)); - - // Same protocol - do bitwise and - var i; - if (addr.length === mask.length) { - for (i = 0; i < addr.length; i++) { - result[i] = addr[i] & mask[i]; - } - } else if (mask.length === 4) { - // IPv6 address and IPv4 mask - // (Mask low bits) - for (i = 0; i < mask.length; i++) { - result[i] = addr[addr.length - 4 + i] & mask[i]; - } - } else { - // IPv6 mask and IPv4 addr - for (i = 0; i < result.length - 6; i++) { - result[i] = 0; - } - - // ::ffff:ipv4 - result[10] = 0xff; - result[11] = 0xff; - for (i = 0; i < addr.length; i++) { - result[i + 12] = addr[i] & mask[i + 12]; - } - i += 12; - } - for (; i < result.length; i++) { - result[i] = 0; - } - - return ip.toString(result); -}; - -ip.cidr = function (cidrString) { - var cidrParts = cidrString.split('/'); - - var addr = cidrParts[0]; - if (cidrParts.length !== 2) { - throw new Error(`invalid CIDR subnet: ${addr}`); - } - - var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10)); - - return ip.mask(addr, mask); -}; - -ip.subnet = function (addr, mask) { - var networkAddress = ip.toLong(ip.mask(addr, mask)); - - // Calculate the mask's length. - var maskBuffer = ip.toBuffer(mask); - var maskLength = 0; - - for (var i = 0; i < maskBuffer.length; i++) { - if (maskBuffer[i] === 0xff) { - maskLength += 8; - } else { - var octet = maskBuffer[i] & 0xff; - while (octet) { - octet = (octet << 1) & 0xff; - maskLength++; - } - } - } - - var numberOfAddresses = Math.pow(2, 32 - maskLength); - - return { - networkAddress: ip.fromLong(networkAddress), - firstAddress: numberOfAddresses <= 2 - ? ip.fromLong(networkAddress) - : ip.fromLong(networkAddress + 1), - lastAddress: numberOfAddresses <= 2 - ? ip.fromLong(networkAddress + numberOfAddresses - 1) - : ip.fromLong(networkAddress + numberOfAddresses - 2), - broadcastAddress: ip.fromLong(networkAddress + numberOfAddresses - 1), - subnetMask: mask, - subnetMaskLength: maskLength, - numHosts: numberOfAddresses <= 2 - ? numberOfAddresses : numberOfAddresses - 2, - length: numberOfAddresses, - contains(other) { - return networkAddress === ip.toLong(ip.mask(other, mask)); - }, - }; -}; - -ip.cidrSubnet = function (cidrString) { - var cidrParts = cidrString.split('/'); - - var addr = cidrParts[0]; - if (cidrParts.length !== 2) { - throw new Error(`invalid CIDR subnet: ${addr}`); - } - - var mask = ip.fromPrefixLen(parseInt(cidrParts[1], 10)); - - return ip.subnet(addr, mask); -}; - -ip.not = function (addr) { - var buff = ip.toBuffer(addr); - for (var i = 0; i < buff.length; i++) { - buff[i] = 0xff ^ buff[i]; - } - return ip.toString(buff); -}; - -ip.or = function (a, b) { - var i; - - a = ip.toBuffer(a); - b = ip.toBuffer(b); - - // same protocol - if (a.length === b.length) { - for (i = 0; i < a.length; ++i) { - a[i] |= b[i]; - } - return ip.toString(a); - - // mixed protocols - } - var buff = a; - var other = b; - if (b.length > a.length) { - buff = b; - other = a; - } - - var offset = buff.length - other.length; - for (i = offset; i < buff.length; ++i) { - buff[i] |= other[i - offset]; - } - - return ip.toString(buff); -}; - -ip.isEqual = function (a, b) { - var i; - - a = ip.toBuffer(a); - b = ip.toBuffer(b); - - // Same protocol - if (a.length === b.length) { - for (i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; - } - - // Swap - if (b.length === 4) { - var t = b; - b = a; - a = t; - } - - // a - IPv4, b - IPv6 - for (i = 0; i < 10; i++) { - if (b[i] !== 0) return false; - } - - var word = b.readUInt16BE(10); - if (word !== 0 && word !== 0xffff) return false; - - for (i = 0; i < 4; i++) { - if (a[i] !== b[i + 12]) return false; - } - - return true; -}; - -ip.isPrivate = function (addr) { - return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i - .test(addr) - || /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) - || /^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i - .test(addr) - || /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) - || /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) - || /^f[cd][0-9a-f]{2}:/i.test(addr) - || /^fe80:/i.test(addr) - || /^::1$/.test(addr) - || /^::$/.test(addr); -}; - -ip.isPublic = function (addr) { - return !ip.isPrivate(addr); -}; - -ip.isLoopback = function (addr) { - return /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/ - .test(addr) - || /^fe80::1$/.test(addr) - || /^::1$/.test(addr) - || /^::$/.test(addr); -}; - -ip.loopback = function (family) { - // - // Default to `ipv4` - // - family = _normalizeFamily(family); - - if (family !== 'ipv4' && family !== 'ipv6') { - throw new Error('family must be ipv4 or ipv6'); - } - - return family === 'ipv4' ? '127.0.0.1' : 'fe80::1'; -}; - -// -// ### function address (name, family) -// #### @name {string|'public'|'private'} **Optional** Name or security -// of the network interface. -// #### @family {ipv4|ipv6} **Optional** IP family of the address (defaults -// to ipv4). -// -// Returns the address for the network interface on the current system with -// the specified `name`: -// * String: First `family` address of the interface. -// If not found see `undefined`. -// * 'public': the first public ip address of family. -// * 'private': the first private ip address of family. -// * undefined: First address with `ipv4` or loopback address `127.0.0.1`. -// -ip.address = function (name, family) { - var interfaces = os.networkInterfaces(); - - // - // Default to `ipv4` - // - family = _normalizeFamily(family); - - // - // If a specific network interface has been named, - // return the address. - // - if (name && name !== 'private' && name !== 'public') { - var res = interfaces[name].filter((details) => { - var itemFamily = _normalizeFamily(details.family); - return itemFamily === family; - }); - if (res.length === 0) { - return undefined; - } - return res[0].address; - } - - var all = Object.keys(interfaces).map((nic) => { - // - // Note: name will only be `public` or `private` - // when this is called. - // - var addresses = interfaces[nic].filter((details) => { - details.family = _normalizeFamily(details.family); - if (details.family !== family || ip.isLoopback(details.address)) { - return false; - } if (!name) { - return true; - } - - return name === 'public' ? ip.isPrivate(details.address) - : ip.isPublic(details.address); - }); - - return addresses.length ? addresses[0].address : undefined; - }).filter(Boolean); - - return !all.length ? ip.loopback(family) : all[0]; -}; - -ip.toLong = function (ip) { - var ipl = 0; - ip.split('.').forEach((octet) => { - ipl <<= 8; - ipl += parseInt(octet); - }); - return (ipl >>> 0); -}; - -ip.fromLong = function (ipl) { - return (`${ipl >>> 24}.${ - ipl >> 16 & 255}.${ - ipl >> 8 & 255}.${ - ipl & 255}`); -}; diff --git a/node_modules/ip/package.json b/node_modules/ip/package.json deleted file mode 100644 index 70e1a4f02aeb7..0000000000000 --- a/node_modules/ip/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "ip", - "version": "1.1.8", - "author": "Fedor Indutny <fedor@indutny.com>", - "homepage": "https://github.com/indutny/node-ip", - "repository": { - "type": "git", - "url": "http://github.com/indutny/node-ip.git" - }, - "files": [ - "lib", - "README.md" - ], - "main": "lib/ip", - "devDependencies": { - "eslint": "^8.15.0", - "mocha": "^10.0.0" - }, - "scripts": { - "lint": "eslint lib/*.js test/*.js", - "test": "npm run lint && mocha --reporter spec test/*-test.js", - "fix": "npm run lint -- --fix" - }, - "license": "MIT" -} diff --git a/node_modules/is-cidr/dist/index.js b/node_modules/is-cidr/dist/index.js new file mode 100644 index 0000000000000..35fba31c48c66 --- /dev/null +++ b/node_modules/is-cidr/dist/index.js @@ -0,0 +1,11 @@ +import { v4 as v4$1, v6 as v6$1 } from "cidr-regex"; +const re4 = v4$1({ exact: true }); +const re6 = v6$1({ exact: true }); +const isCidr = (str) => re4.test(str) ? 4 : re6.test(str) ? 6 : 0; +const v4 = isCidr.v4 = (str) => re4.test(str); +const v6 = isCidr.v6 = (str) => re6.test(str); +export { + isCidr as default, + v4, + v6 +}; diff --git a/node_modules/is-cidr/index.d.ts b/node_modules/is-cidr/index.d.ts deleted file mode 100644 index c4ba96a1fe82b..0000000000000 --- a/node_modules/is-cidr/index.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -declare const isCidr: { - /** - Check if `string` is a IPv4 or IPv6 CIDR address. - @returns Either `4`, `6` (indicating the IP version) or `0` if the string is not a CIDR. - @example - ``` - import isCidr = require('is-cidr'); - isCidr('192.168.0.1/24'); //=> 4 - isCidr('1:2:3:4:5:6:7:8/64'); //=> 6 - isCidr('10.0.0.0'); //=> 0 - ``` - */ - (string: string): 6 | 4 | 0; - - /** - Check if `string` is a IPv4 CIDR address. - */ - v4(string: string): boolean; - - /** - Check if `string` is a IPv6 CIDR address. - @example - ``` - import isCidr = require('is-cidr'); - isCidr.v6('10.0.0.0/24'); //=> false - ``` - */ - v6(string: string): boolean; -}; - -export = isCidr; diff --git a/node_modules/is-cidr/index.js b/node_modules/is-cidr/index.js deleted file mode 100644 index 8caef5fbb72a3..0000000000000 --- a/node_modules/is-cidr/index.js +++ /dev/null @@ -1,9 +0,0 @@ -"use strict"; -const {v4, v6} = require("cidr-regex"); - -const re4 = v4({exact: true}); -const re6 = v6({exact: true}); - -module.exports = str => re4.test(str) ? 4 : (re6.test(str) ? 6 : 0); -module.exports.v4 = str => re4.test(str); -module.exports.v6 = str => re6.test(str); diff --git a/node_modules/is-cidr/package.json b/node_modules/is-cidr/package.json index b02775a0e3f6f..413a6ddf4b70a 100644 --- a/node_modules/is-cidr/package.json +++ b/node_modules/is-cidr/package.json @@ -1,6 +1,6 @@ { "name": "is-cidr", - "version": "4.0.2", + "version": "6.0.2", "description": "Check if a string is an IP address in CIDR notation", "author": "silverwind <me@silverwind.io>", "contributors": [ @@ -8,39 +8,31 @@ ], "repository": "silverwind/is-cidr", "license": "BSD-2-Clause", - "scripts": { - "test": "make test" - }, - "engines": { - "node": ">=10" - }, + "type": "module", + "sideEffects": false, + "main": "./dist/index.js", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", "files": [ - "index.js", - "index.d.ts" - ], - "keywords": [ - "cidr", - "regex", - "notation", - "cidr notation", - "prefix", - "prefixes", - "ip", - "ip address", - "network" + "dist" ], + "engines": { + "node": ">=20" + }, "dependencies": { - "cidr-regex": "^3.1.1" + "cidr-regex": "^5.0.1" }, "devDependencies": { - "eslint": "7.10.0", - "eslint-config-silverwind": "18.0.10", - "jest": "26.4.2", - "updates": "11.1.5", - "versions": "8.4.3" - }, - "jest": { - "verbose": false, - "testTimeout": 10000 + "@types/node": "25.0.10", + "eslint": "9.39.2", + "eslint-config-silverwind": "118.0.0", + "typescript": "5.9.3", + "typescript-config-silverwind": "14.0.0", + "updates": "17.0.8", + "versions": "14.0.3", + "vite": "7.3.1", + "vite-config-silverwind": "6.0.9", + "vitest": "4.0.18", + "vitest-config-silverwind": "10.6.1" } } diff --git a/node_modules/is-core-module/LICENSE b/node_modules/is-core-module/LICENSE deleted file mode 100644 index 2e502872a7423..0000000000000 --- a/node_modules/is-core-module/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Dave Justice - -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. \ No newline at end of file diff --git a/node_modules/is-core-module/core.json b/node_modules/is-core-module/core.json deleted file mode 100644 index 058584b78998a..0000000000000 --- a/node_modules/is-core-module/core.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "assert": true, - "node:assert": [">= 14.18 && < 15", ">= 16"], - "assert/strict": ">= 15", - "node:assert/strict": ">= 16", - "async_hooks": ">= 8", - "node:async_hooks": [">= 14.18 && < 15", ">= 16"], - "buffer_ieee754": ">= 0.5 && < 0.9.7", - "buffer": true, - "node:buffer": [">= 14.18 && < 15", ">= 16"], - "child_process": true, - "node:child_process": [">= 14.18 && < 15", ">= 16"], - "cluster": ">= 0.5", - "node:cluster": [">= 14.18 && < 15", ">= 16"], - "console": true, - "node:console": [">= 14.18 && < 15", ">= 16"], - "constants": true, - "node:constants": [">= 14.18 && < 15", ">= 16"], - "crypto": true, - "node:crypto": [">= 14.18 && < 15", ">= 16"], - "_debug_agent": ">= 1 && < 8", - "_debugger": "< 8", - "dgram": true, - "node:dgram": [">= 14.18 && < 15", ">= 16"], - "diagnostics_channel": [">= 14.17 && < 15", ">= 15.1"], - "node:diagnostics_channel": [">= 14.18 && < 15", ">= 16"], - "dns": true, - "node:dns": [">= 14.18 && < 15", ">= 16"], - "dns/promises": ">= 15", - "node:dns/promises": ">= 16", - "domain": ">= 0.7.12", - "node:domain": [">= 14.18 && < 15", ">= 16"], - "events": true, - "node:events": [">= 14.18 && < 15", ">= 16"], - "freelist": "< 6", - "fs": true, - "node:fs": [">= 14.18 && < 15", ">= 16"], - "fs/promises": [">= 10 && < 10.1", ">= 14"], - "node:fs/promises": [">= 14.18 && < 15", ">= 16"], - "_http_agent": ">= 0.11.1", - "node:_http_agent": [">= 14.18 && < 15", ">= 16"], - "_http_client": ">= 0.11.1", - "node:_http_client": [">= 14.18 && < 15", ">= 16"], - "_http_common": ">= 0.11.1", - "node:_http_common": [">= 14.18 && < 15", ">= 16"], - "_http_incoming": ">= 0.11.1", - "node:_http_incoming": [">= 14.18 && < 15", ">= 16"], - "_http_outgoing": ">= 0.11.1", - "node:_http_outgoing": [">= 14.18 && < 15", ">= 16"], - "_http_server": ">= 0.11.1", - "node:_http_server": [">= 14.18 && < 15", ">= 16"], - "http": true, - "node:http": [">= 14.18 && < 15", ">= 16"], - "http2": ">= 8.8", - "node:http2": [">= 14.18 && < 15", ">= 16"], - "https": true, - "node:https": [">= 14.18 && < 15", ">= 16"], - "inspector": ">= 8", - "node:inspector": [">= 14.18 && < 15", ">= 16"], - "_linklist": "< 8", - "module": true, - "node:module": [">= 14.18 && < 15", ">= 16"], - "net": true, - "node:net": [">= 14.18 && < 15", ">= 16"], - "node-inspect/lib/_inspect": ">= 7.6 && < 12", - "node-inspect/lib/internal/inspect_client": ">= 7.6 && < 12", - "node-inspect/lib/internal/inspect_repl": ">= 7.6 && < 12", - "os": true, - "node:os": [">= 14.18 && < 15", ">= 16"], - "path": true, - "node:path": [">= 14.18 && < 15", ">= 16"], - "path/posix": ">= 15.3", - "node:path/posix": ">= 16", - "path/win32": ">= 15.3", - "node:path/win32": ">= 16", - "perf_hooks": ">= 8.5", - "node:perf_hooks": [">= 14.18 && < 15", ">= 16"], - "process": ">= 1", - "node:process": [">= 14.18 && < 15", ">= 16"], - "punycode": ">= 0.5", - "node:punycode": [">= 14.18 && < 15", ">= 16"], - "querystring": true, - "node:querystring": [">= 14.18 && < 15", ">= 16"], - "readline": true, - "node:readline": [">= 14.18 && < 15", ">= 16"], - "readline/promises": ">= 17", - "node:readline/promises": ">= 17", - "repl": true, - "node:repl": [">= 14.18 && < 15", ">= 16"], - "smalloc": ">= 0.11.5 && < 3", - "_stream_duplex": ">= 0.9.4", - "node:_stream_duplex": [">= 14.18 && < 15", ">= 16"], - "_stream_transform": ">= 0.9.4", - "node:_stream_transform": [">= 14.18 && < 15", ">= 16"], - "_stream_wrap": ">= 1.4.1", - "node:_stream_wrap": [">= 14.18 && < 15", ">= 16"], - "_stream_passthrough": ">= 0.9.4", - "node:_stream_passthrough": [">= 14.18 && < 15", ">= 16"], - "_stream_readable": ">= 0.9.4", - "node:_stream_readable": [">= 14.18 && < 15", ">= 16"], - "_stream_writable": ">= 0.9.4", - "node:_stream_writable": [">= 14.18 && < 15", ">= 16"], - "stream": true, - "node:stream": [">= 14.18 && < 15", ">= 16"], - "stream/consumers": ">= 16.7", - "node:stream/consumers": ">= 16.7", - "stream/promises": ">= 15", - "node:stream/promises": ">= 16", - "stream/web": ">= 16.5", - "node:stream/web": ">= 16.5", - "string_decoder": true, - "node:string_decoder": [">= 14.18 && < 15", ">= 16"], - "sys": [">= 0.4 && < 0.7", ">= 0.8"], - "node:sys": [">= 14.18 && < 15", ">= 16"], - "node:test": ">= 18", - "timers": true, - "node:timers": [">= 14.18 && < 15", ">= 16"], - "timers/promises": ">= 15", - "node:timers/promises": ">= 16", - "_tls_common": ">= 0.11.13", - "node:_tls_common": [">= 14.18 && < 15", ">= 16"], - "_tls_legacy": ">= 0.11.3 && < 10", - "_tls_wrap": ">= 0.11.3", - "node:_tls_wrap": [">= 14.18 && < 15", ">= 16"], - "tls": true, - "node:tls": [">= 14.18 && < 15", ">= 16"], - "trace_events": ">= 10", - "node:trace_events": [">= 14.18 && < 15", ">= 16"], - "tty": true, - "node:tty": [">= 14.18 && < 15", ">= 16"], - "url": true, - "node:url": [">= 14.18 && < 15", ">= 16"], - "util": true, - "node:util": [">= 14.18 && < 15", ">= 16"], - "util/types": ">= 15.3", - "node:util/types": ">= 16", - "v8/tools/arguments": ">= 10 && < 12", - "v8/tools/codemap": [">= 4.4 && < 5", ">= 5.2 && < 12"], - "v8/tools/consarray": [">= 4.4 && < 5", ">= 5.2 && < 12"], - "v8/tools/csvparser": [">= 4.4 && < 5", ">= 5.2 && < 12"], - "v8/tools/logreader": [">= 4.4 && < 5", ">= 5.2 && < 12"], - "v8/tools/profile_view": [">= 4.4 && < 5", ">= 5.2 && < 12"], - "v8/tools/splaytree": [">= 4.4 && < 5", ">= 5.2 && < 12"], - "v8": ">= 1", - "node:v8": [">= 14.18 && < 15", ">= 16"], - "vm": true, - "node:vm": [">= 14.18 && < 15", ">= 16"], - "wasi": ">= 13.4 && < 13.5", - "worker_threads": ">= 11.7", - "node:worker_threads": [">= 14.18 && < 15", ">= 16"], - "zlib": ">= 0.5", - "node:zlib": [">= 14.18 && < 15", ">= 16"] -} diff --git a/node_modules/is-core-module/index.js b/node_modules/is-core-module/index.js deleted file mode 100644 index f9637e0e7d3ff..0000000000000 --- a/node_modules/is-core-module/index.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict'; - -var has = require('has'); - -function specifierIncluded(current, specifier) { - var nodeParts = current.split('.'); - var parts = specifier.split(' '); - var op = parts.length > 1 ? parts[0] : '='; - var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); - - for (var i = 0; i < 3; ++i) { - var cur = parseInt(nodeParts[i] || 0, 10); - var ver = parseInt(versionParts[i] || 0, 10); - if (cur === ver) { - continue; // eslint-disable-line no-restricted-syntax, no-continue - } - if (op === '<') { - return cur < ver; - } - if (op === '>=') { - return cur >= ver; - } - return false; - } - return op === '>='; -} - -function matchesRange(current, range) { - var specifiers = range.split(/ ?&& ?/); - if (specifiers.length === 0) { - return false; - } - for (var i = 0; i < specifiers.length; ++i) { - if (!specifierIncluded(current, specifiers[i])) { - return false; - } - } - return true; -} - -function versionIncluded(nodeVersion, specifierValue) { - if (typeof specifierValue === 'boolean') { - return specifierValue; - } - - var current = typeof nodeVersion === 'undefined' - ? process.versions && process.versions.node - : nodeVersion; - - if (typeof current !== 'string') { - throw new TypeError(typeof nodeVersion === 'undefined' ? 'Unable to determine current node version' : 'If provided, a valid node version is required'); - } - - if (specifierValue && typeof specifierValue === 'object') { - for (var i = 0; i < specifierValue.length; ++i) { - if (matchesRange(current, specifierValue[i])) { - return true; - } - } - return false; - } - return matchesRange(current, specifierValue); -} - -var data = require('./core.json'); - -module.exports = function isCore(x, nodeVersion) { - return has(data, x) && versionIncluded(nodeVersion, data[x]); -}; diff --git a/node_modules/is-core-module/package.json b/node_modules/is-core-module/package.json deleted file mode 100644 index 80ce9f5bb1797..0000000000000 --- a/node_modules/is-core-module/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "is-core-module", - "version": "2.9.0", - "description": "Is this specifier a node.js core module?", - "main": "index.js", - "sideEffects": false, - "exports": { - ".": "./index.js", - "./package.json": "./package.json" - }, - "scripts": { - "prepublish": "not-in-publish || npm run prepublishOnly", - "prepublishOnly": "safe-publish-latest", - "lint": "eslint .", - "pretest": "npm run lint", - "tests-only": "nyc tape 'test/**/*.js'", - "test": "npm run tests-only", - "posttest": "aud --production", - "version": "auto-changelog && git add CHANGELOG.md", - "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/inspect-js/is-core-module.git" - }, - "keywords": [ - "core", - "modules", - "module", - "npm", - "node", - "dependencies" - ], - "author": "Jordan Harband <ljharb@gmail.com>", - "funding": { - "url": "https://github.com/sponsors/ljharb" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/inspect-js/is-core-module/issues" - }, - "homepage": "https://github.com/inspect-js/is-core-module", - "dependencies": { - "has": "^1.0.3" - }, - "devDependencies": { - "@ljharb/eslint-config": "^21.0.0", - "aud": "^2.0.0", - "auto-changelog": "^2.4.0", - "eslint": "=8.8.0", - "mock-property": "^1.0.0", - "nyc": "^10.3.2", - "safe-publish-latest": "^2.0.0", - "semver": "^6.3.0", - "tape": "^5.5.3" - }, - "auto-changelog": { - "output": "CHANGELOG.md", - "template": "keepachangelog", - "unreleased": false, - "commitLimit": false, - "backfillLimit": false, - "hideCredit": true - } -} diff --git a/node_modules/is-core-module/test/index.js b/node_modules/is-core-module/test/index.js deleted file mode 100644 index 4385b20ea1489..0000000000000 --- a/node_modules/is-core-module/test/index.js +++ /dev/null @@ -1,133 +0,0 @@ -'use strict'; - -var test = require('tape'); -var keys = require('object-keys'); -var semver = require('semver'); -var mockProperty = require('mock-property'); - -var isCore = require('../'); -var data = require('../core.json'); - -var supportsNodePrefix = semver.satisfies(process.versions.node, '^14.18 || >= 16', { includePrerelease: true }); - -test('core modules', function (t) { - t.test('isCore()', function (st) { - st.ok(isCore('fs')); - st.ok(isCore('net')); - st.ok(isCore('http')); - - st.ok(!isCore('seq')); - st.ok(!isCore('../')); - - st.ok(!isCore('toString')); - - st.end(); - }); - - t.test('core list', function (st) { - var cores = keys(data); - st.plan(cores.length); - - for (var i = 0; i < cores.length; ++i) { - var mod = cores[i]; - var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func - if (isCore(mod)) { - st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw'); - } else { - st['throws'](requireFunc, mod + ' not supported; requiring throws'); - } - } - - st.end(); - }); - - t.test('core via repl module', { skip: !data.repl }, function (st) { - var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle - if (!libs) { - st.skip('module.builtinModules does not exist'); - } else { - for (var i = 0; i < libs.length; ++i) { - var mod = libs[i]; - st.ok(data[mod], mod + ' is a core module'); - st.doesNotThrow( - function () { require(mod); }, // eslint-disable-line no-loop-func - 'requiring ' + mod + ' does not throw' - ); - if (mod.slice(0, 5) !== 'node:') { - if (supportsNodePrefix) { - st.doesNotThrow( - function () { require('node:' + mod); }, // eslint-disable-line no-loop-func - 'requiring node:' + mod + ' does not throw' - ); - } else { - st['throws']( - function () { require('node:' + mod); }, // eslint-disable-line no-loop-func - 'requiring node:' + mod + ' throws' - ); - } - } - } - } - st.end(); - }); - - t.test('core via builtinModules list', { skip: !data.module }, function (st) { - var libs = require('module').builtinModules; - if (!libs) { - st.skip('module.builtinModules does not exist'); - } else { - var excludeList = [ - '_debug_agent', - 'v8/tools/tickprocessor-driver', - 'v8/tools/SourceMap', - 'v8/tools/tickprocessor', - 'v8/tools/profile' - ]; - // see https://github.com/nodejs/node/issues/42785 - if (semver.satisfies(process.version, '>= 18')) { - libs = libs.concat('node:test'); - } - for (var i = 0; i < libs.length; ++i) { - var mod = libs[i]; - if (excludeList.indexOf(mod) === -1) { - st.ok(data[mod], mod + ' is a core module'); - st.doesNotThrow( - function () { require(mod); }, // eslint-disable-line no-loop-func - 'requiring ' + mod + ' does not throw' - ); - if (mod.slice(0, 5) !== 'node:') { - if (supportsNodePrefix) { - st.doesNotThrow( - function () { require('node:' + mod); }, // eslint-disable-line no-loop-func - 'requiring node:' + mod + ' does not throw' - ); - } else { - st['throws']( - function () { require('node:' + mod); }, // eslint-disable-line no-loop-func - 'requiring node:' + mod + ' throws' - ); - } - } - } - } - } - st.end(); - }); - - t.test('Object.prototype pollution', function (st) { - var nonKey = 'not a core module'; - st.teardown(mockProperty(Object.prototype, 'fs', { value: false })); - st.teardown(mockProperty(Object.prototype, 'path', { value: '>= 999999999' })); - st.teardown(mockProperty(Object.prototype, 'http', { value: data.http })); - st.teardown(mockProperty(Object.prototype, nonKey, { value: true })); - - st.equal(isCore('fs'), true, 'fs is a core module even if Object.prototype lies'); - st.equal(isCore('path'), true, 'path is a core module even if Object.prototype lies'); - st.equal(isCore('http'), true, 'path is a core module even if Object.prototype matches data'); - st.equal(isCore(nonKey), false, '"' + nonKey + '" is not a core module even if Object.prototype lies'); - - st.end(); - }); - - t.end(); -}); diff --git a/node_modules/is-fullwidth-code-point/index.d.ts b/node_modules/is-fullwidth-code-point/index.d.ts deleted file mode 100644 index 729d2020516f0..0000000000000 --- a/node_modules/is-fullwidth-code-point/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** -Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms). - -@param codePoint - The [code point](https://en.wikipedia.org/wiki/Code_point) of a character. - -@example -``` -import isFullwidthCodePoint from 'is-fullwidth-code-point'; - -isFullwidthCodePoint('谢'.codePointAt(0)); -//=> true - -isFullwidthCodePoint('a'.codePointAt(0)); -//=> false -``` -*/ -export default function isFullwidthCodePoint(codePoint: number): boolean; diff --git a/node_modules/is-fullwidth-code-point/readme.md b/node_modules/is-fullwidth-code-point/readme.md deleted file mode 100644 index 4236bba980d8f..0000000000000 --- a/node_modules/is-fullwidth-code-point/readme.md +++ /dev/null @@ -1,39 +0,0 @@ -# is-fullwidth-code-point [![Build Status](https://travis-ci.org/sindresorhus/is-fullwidth-code-point.svg?branch=master)](https://travis-ci.org/sindresorhus/is-fullwidth-code-point) - -> Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) - - -## Install - -``` -$ npm install is-fullwidth-code-point -``` - - -## Usage - -```js -const isFullwidthCodePoint = require('is-fullwidth-code-point'); - -isFullwidthCodePoint('谢'.codePointAt(0)); -//=> true - -isFullwidthCodePoint('a'.codePointAt(0)); -//=> false -``` - - -## API - -### isFullwidthCodePoint(codePoint) - -#### codePoint - -Type: `number` - -The [code point](https://en.wikipedia.org/wiki/Code_point) of a character. - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/is-lambda/LICENSE b/node_modules/is-lambda/LICENSE deleted file mode 100644 index 4a59c94175c2a..0000000000000 --- a/node_modules/is-lambda/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2017 Thomas Watson Steen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/is-lambda/index.js b/node_modules/is-lambda/index.js deleted file mode 100644 index b245ab1c68df1..0000000000000 --- a/node_modules/is-lambda/index.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict' - -module.exports = !!( - (process.env.LAMBDA_TASK_ROOT && process.env.AWS_EXECUTION_ENV) || - false -) diff --git a/node_modules/is-lambda/package.json b/node_modules/is-lambda/package.json deleted file mode 100644 index d8550898b4e4d..0000000000000 --- a/node_modules/is-lambda/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "is-lambda", - "version": "1.0.1", - "description": "Detect if your code is running on an AWS Lambda server", - "main": "index.js", - "dependencies": {}, - "devDependencies": { - "clear-require": "^1.0.1", - "standard": "^10.0.2" - }, - "scripts": { - "test": "standard && node test.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/watson/is-lambda.git" - }, - "keywords": [ - "aws", - "hosting", - "hosted", - "lambda", - "detect" - ], - "author": "Thomas Watson Steen <w@tson.dk> (https://twitter.com/wa7son)", - "license": "MIT", - "bugs": { - "url": "https://github.com/watson/is-lambda/issues" - }, - "homepage": "https://github.com/watson/is-lambda", - "coordinates": [ - 37.3859955, - -122.0838831 - ] -} diff --git a/node_modules/is-lambda/test.js b/node_modules/is-lambda/test.js deleted file mode 100644 index e8e73257ad4ad..0000000000000 --- a/node_modules/is-lambda/test.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -var assert = require('assert') -var clearRequire = require('clear-require') - -process.env.AWS_EXECUTION_ENV = 'AWS_Lambda_nodejs6.10' -process.env.LAMBDA_TASK_ROOT = '/var/task' - -var isCI = require('./') -assert(isCI) - -delete process.env.AWS_EXECUTION_ENV - -clearRequire('./') -isCI = require('./') -assert(!isCI) diff --git a/node_modules/isexe/LICENSE b/node_modules/isexe/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/isexe/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/isexe/dist/cjs/index.js b/node_modules/isexe/dist/cjs/index.js new file mode 100644 index 0000000000000..cefcb66b5c543 --- /dev/null +++ b/node_modules/isexe/dist/cjs/index.js @@ -0,0 +1,46 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sync = exports.isexe = exports.posix = exports.win32 = void 0; +const posix = __importStar(require("./posix.js")); +exports.posix = posix; +const win32 = __importStar(require("./win32.js")); +exports.win32 = win32; +__exportStar(require("./options.js"), exports); +const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform; +const impl = platform === 'win32' ? win32 : posix; +/** + * Determine whether a path is executable on the current platform. + */ +exports.isexe = impl.isexe; +/** + * Synchronously determine whether a path is executable on the + * current platform. + */ +exports.sync = impl.sync; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/cjs/options.js b/node_modules/isexe/dist/cjs/options.js new file mode 100644 index 0000000000000..0dfad0762cc32 --- /dev/null +++ b/node_modules/isexe/dist/cjs/options.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=options.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/cjs/package.json b/node_modules/isexe/dist/cjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/isexe/dist/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/isexe/dist/cjs/posix.js b/node_modules/isexe/dist/cjs/posix.js new file mode 100644 index 0000000000000..3bc5e79d7007e --- /dev/null +++ b/node_modules/isexe/dist/cjs/posix.js @@ -0,0 +1,67 @@ +"use strict"; +/** + * This is the Posix implementation of isexe, which uses the file + * mode and uid/gid values. + * + * @module + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sync = exports.isexe = void 0; +const fs_1 = require("fs"); +const promises_1 = require("fs/promises"); +/** + * Determine whether a path is executable according to the mode and + * current (or specified) user and group IDs. + */ +const isexe = async (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat(await (0, promises_1.stat)(path), options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +exports.isexe = isexe; +/** + * Synchronously determine whether a path is executable according to + * the mode and current (or specified) user and group IDs. + */ +const sync = (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat((0, fs_1.statSync)(path), options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +exports.sync = sync; +const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options); +const checkMode = (stat, options) => { + const myUid = options.uid ?? process.getuid?.(); + const myGroups = options.groups ?? process.getgroups?.() ?? []; + const myGid = options.gid ?? process.getgid?.() ?? myGroups[0]; + if (myUid === undefined || myGid === undefined) { + throw new Error('cannot get uid or gid'); + } + const groups = new Set([myGid, ...myGroups]); + const mod = stat.mode; + const uid = stat.uid; + const gid = stat.gid; + const u = parseInt('100', 8); + const g = parseInt('010', 8); + const o = parseInt('001', 8); + const ug = u | g; + return !!(mod & o || + (mod & g && groups.has(gid)) || + (mod & u && uid === myUid) || + (mod & ug && myUid === 0)); +}; +//# sourceMappingURL=posix.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/cjs/win32.js b/node_modules/isexe/dist/cjs/win32.js new file mode 100644 index 0000000000000..fa7a4d2f7d240 --- /dev/null +++ b/node_modules/isexe/dist/cjs/win32.js @@ -0,0 +1,62 @@ +"use strict"; +/** + * This is the Windows implementation of isexe, which uses the file + * extension and PATHEXT setting. + * + * @module + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sync = exports.isexe = void 0; +const fs_1 = require("fs"); +const promises_1 = require("fs/promises"); +/** + * Determine whether a path is executable based on the file extension + * and PATHEXT environment variable (or specified pathExt option) + */ +const isexe = async (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat(await (0, promises_1.stat)(path), path, options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +exports.isexe = isexe; +/** + * Synchronously determine whether a path is executable based on the file + * extension and PATHEXT environment variable (or specified pathExt option) + */ +const sync = (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat((0, fs_1.statSync)(path), path, options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +exports.sync = sync; +const checkPathExt = (path, options) => { + const { pathExt = process.env.PATHEXT || '' } = options; + const peSplit = pathExt.split(';'); + if (peSplit.indexOf('') !== -1) { + return true; + } + for (let i = 0; i < peSplit.length; i++) { + const p = peSplit[i].toLowerCase(); + const ext = path.substring(path.length - p.length).toLowerCase(); + if (p && ext === p) { + return true; + } + } + return false; +}; +const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options); +//# sourceMappingURL=win32.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/mjs/index.js b/node_modules/isexe/dist/mjs/index.js new file mode 100644 index 0000000000000..1e309acd7355e --- /dev/null +++ b/node_modules/isexe/dist/mjs/index.js @@ -0,0 +1,16 @@ +import * as posix from './posix.js'; +import * as win32 from './win32.js'; +export * from './options.js'; +export { win32, posix }; +const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform; +const impl = platform === 'win32' ? win32 : posix; +/** + * Determine whether a path is executable on the current platform. + */ +export const isexe = impl.isexe; +/** + * Synchronously determine whether a path is executable on the + * current platform. + */ +export const sync = impl.sync; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/mjs/options.js b/node_modules/isexe/dist/mjs/options.js new file mode 100644 index 0000000000000..e9ded40bd5b2c --- /dev/null +++ b/node_modules/isexe/dist/mjs/options.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=options.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/mjs/package.json b/node_modules/isexe/dist/mjs/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/isexe/dist/mjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/isexe/dist/mjs/posix.js b/node_modules/isexe/dist/mjs/posix.js new file mode 100644 index 0000000000000..c453776c0452f --- /dev/null +++ b/node_modules/isexe/dist/mjs/posix.js @@ -0,0 +1,62 @@ +/** + * This is the Posix implementation of isexe, which uses the file + * mode and uid/gid values. + * + * @module + */ +import { statSync } from 'fs'; +import { stat } from 'fs/promises'; +/** + * Determine whether a path is executable according to the mode and + * current (or specified) user and group IDs. + */ +export const isexe = async (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat(await stat(path), options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +/** + * Synchronously determine whether a path is executable according to + * the mode and current (or specified) user and group IDs. + */ +export const sync = (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat(statSync(path), options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options); +const checkMode = (stat, options) => { + const myUid = options.uid ?? process.getuid?.(); + const myGroups = options.groups ?? process.getgroups?.() ?? []; + const myGid = options.gid ?? process.getgid?.() ?? myGroups[0]; + if (myUid === undefined || myGid === undefined) { + throw new Error('cannot get uid or gid'); + } + const groups = new Set([myGid, ...myGroups]); + const mod = stat.mode; + const uid = stat.uid; + const gid = stat.gid; + const u = parseInt('100', 8); + const g = parseInt('010', 8); + const o = parseInt('001', 8); + const ug = u | g; + return !!(mod & o || + (mod & g && groups.has(gid)) || + (mod & u && uid === myUid) || + (mod & ug && myUid === 0)); +}; +//# sourceMappingURL=posix.js.map \ No newline at end of file diff --git a/node_modules/isexe/dist/mjs/win32.js b/node_modules/isexe/dist/mjs/win32.js new file mode 100644 index 0000000000000..a354ee2a5115c --- /dev/null +++ b/node_modules/isexe/dist/mjs/win32.js @@ -0,0 +1,57 @@ +/** + * This is the Windows implementation of isexe, which uses the file + * extension and PATHEXT setting. + * + * @module + */ +import { statSync } from 'fs'; +import { stat } from 'fs/promises'; +/** + * Determine whether a path is executable based on the file extension + * and PATHEXT environment variable (or specified pathExt option) + */ +export const isexe = async (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat(await stat(path), path, options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +/** + * Synchronously determine whether a path is executable based on the file + * extension and PATHEXT environment variable (or specified pathExt option) + */ +export const sync = (path, options = {}) => { + const { ignoreErrors = false } = options; + try { + return checkStat(statSync(path), path, options); + } + catch (e) { + const er = e; + if (ignoreErrors || er.code === 'EACCES') + return false; + throw er; + } +}; +const checkPathExt = (path, options) => { + const { pathExt = process.env.PATHEXT || '' } = options; + const peSplit = pathExt.split(';'); + if (peSplit.indexOf('') !== -1) { + return true; + } + for (let i = 0; i < peSplit.length; i++) { + const p = peSplit[i].toLowerCase(); + const ext = path.substring(path.length - p.length).toLowerCase(); + if (p && ext === p) { + return true; + } + } + return false; +}; +const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options); +//# sourceMappingURL=win32.js.map \ No newline at end of file diff --git a/node_modules/isexe/index.js b/node_modules/isexe/index.js deleted file mode 100644 index 553fb32b119bd..0000000000000 --- a/node_modules/isexe/index.js +++ /dev/null @@ -1,57 +0,0 @@ -var fs = require('fs') -var core -if (process.platform === 'win32' || global.TESTING_WINDOWS) { - core = require('./windows.js') -} else { - core = require('./mode.js') -} - -module.exports = isexe -isexe.sync = sync - -function isexe (path, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } - - if (!cb) { - if (typeof Promise !== 'function') { - throw new TypeError('callback not provided') - } - - return new Promise(function (resolve, reject) { - isexe(path, options || {}, function (er, is) { - if (er) { - reject(er) - } else { - resolve(is) - } - }) - }) - } - - core(path, options || {}, function (er, is) { - // ignore EACCES because that just means we aren't allowed to run it - if (er) { - if (er.code === 'EACCES' || options && options.ignoreErrors) { - er = null - is = false - } - } - cb(er, is) - }) -} - -function sync (path, options) { - // my kingdom for a filtered catch - try { - return core.sync(path, options || {}) - } catch (er) { - if (options && options.ignoreErrors || er.code === 'EACCES') { - return false - } else { - throw er - } - } -} diff --git a/node_modules/isexe/mode.js b/node_modules/isexe/mode.js deleted file mode 100644 index 1995ea4a06aec..0000000000000 --- a/node_modules/isexe/mode.js +++ /dev/null @@ -1,41 +0,0 @@ -module.exports = isexe -isexe.sync = sync - -var fs = require('fs') - -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, options)) - }) -} - -function sync (path, options) { - return checkStat(fs.statSync(path), options) -} - -function checkStat (stat, options) { - return stat.isFile() && checkMode(stat, options) -} - -function checkMode (stat, options) { - var mod = stat.mode - var uid = stat.uid - var gid = stat.gid - - var myUid = options.uid !== undefined ? - options.uid : process.getuid && process.getuid() - var myGid = options.gid !== undefined ? - options.gid : process.getgid && process.getgid() - - var u = parseInt('100', 8) - var g = parseInt('010', 8) - var o = parseInt('001', 8) - var ug = u | g - - var ret = (mod & o) || - (mod & g) && gid === myGid || - (mod & u) && uid === myUid || - (mod & ug) && myUid === 0 - - return ret -} diff --git a/node_modules/isexe/package.json b/node_modules/isexe/package.json index e452689442f20..a0e2cd04bfdbf 100644 --- a/node_modules/isexe/package.json +++ b/node_modules/isexe/package.json @@ -1,31 +1,96 @@ { "name": "isexe", - "version": "2.0.0", + "version": "3.1.1", "description": "Minimal module to check if a file is executable.", - "main": "index.js", - "directories": { - "test": "test" + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "types": "./dist/cjs/index.js", + "files": [ + "dist" + ], + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./posix": { + "import": { + "types": "./dist/mjs/posix.d.ts", + "default": "./dist/mjs/posix.js" + }, + "require": { + "types": "./dist/cjs/posix.d.ts", + "default": "./dist/cjs/posix.js" + } + }, + "./win32": { + "import": { + "types": "./dist/mjs/win32.d.ts", + "default": "./dist/mjs/win32.js" + }, + "require": { + "types": "./dist/cjs/win32.d.ts", + "default": "./dist/cjs/win32.js" + } + }, + "./package.json": "./package.json" }, "devDependencies": { + "@types/node": "^20.4.5", + "@types/tap": "^15.0.8", + "c8": "^8.0.1", "mkdirp": "^0.5.1", + "prettier": "^2.8.8", "rimraf": "^2.5.0", - "tap": "^10.3.0" + "sync-content": "^1.0.2", + "tap": "^16.3.8", + "ts-node": "^10.9.1", + "typedoc": "^0.24.8", + "typescript": "^5.1.6" }, "scripts": { - "test": "tap test/*.js --100", "preversion": "npm test", "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tsc -p tsconfig/cjs.json && tsc -p tsconfig/esm.json && bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn --ignore-path ../../.prettierignore --cache", + "typedoc": "typedoc --tsconfig tsconfig/esm.json ./src/*.ts" }, "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", "license": "ISC", - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/isexe.git" + "tap": { + "coverage": false, + "node-arg": [ + "--enable-source-maps", + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false }, - "keywords": [], - "bugs": { - "url": "https://github.com/isaacs/isexe/issues" + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" }, - "homepage": "https://github.com/isaacs/isexe#readme" + "repository": "https://github.com/isaacs/isexe", + "engines": { + "node": ">=16" + } } diff --git a/node_modules/isexe/test/basic.js b/node_modules/isexe/test/basic.js deleted file mode 100644 index d926df64b9024..0000000000000 --- a/node_modules/isexe/test/basic.js +++ /dev/null @@ -1,221 +0,0 @@ -var t = require('tap') -var fs = require('fs') -var path = require('path') -var fixture = path.resolve(__dirname, 'fixtures') -var meow = fixture + '/meow.cat' -var mine = fixture + '/mine.cat' -var ours = fixture + '/ours.cat' -var fail = fixture + '/fail.false' -var noent = fixture + '/enoent.exe' -var mkdirp = require('mkdirp') -var rimraf = require('rimraf') - -var isWindows = process.platform === 'win32' -var hasAccess = typeof fs.access === 'function' -var winSkip = isWindows && 'windows' -var accessSkip = !hasAccess && 'no fs.access function' -var hasPromise = typeof Promise === 'function' -var promiseSkip = !hasPromise && 'no global Promise' - -function reset () { - delete require.cache[require.resolve('../')] - return require('../') -} - -t.test('setup fixtures', function (t) { - rimraf.sync(fixture) - mkdirp.sync(fixture) - fs.writeFileSync(meow, '#!/usr/bin/env cat\nmeow\n') - fs.chmodSync(meow, parseInt('0755', 8)) - fs.writeFileSync(fail, '#!/usr/bin/env false\n') - fs.chmodSync(fail, parseInt('0644', 8)) - fs.writeFileSync(mine, '#!/usr/bin/env cat\nmine\n') - fs.chmodSync(mine, parseInt('0744', 8)) - fs.writeFileSync(ours, '#!/usr/bin/env cat\nours\n') - fs.chmodSync(ours, parseInt('0754', 8)) - t.end() -}) - -t.test('promise', { skip: promiseSkip }, function (t) { - var isexe = reset() - t.test('meow async', function (t) { - isexe(meow).then(function (is) { - t.ok(is) - t.end() - }) - }) - t.test('fail async', function (t) { - isexe(fail).then(function (is) { - t.notOk(is) - t.end() - }) - }) - t.test('noent async', function (t) { - isexe(noent).catch(function (er) { - t.ok(er) - t.end() - }) - }) - t.test('noent ignore async', function (t) { - isexe(noent, { ignoreErrors: true }).then(function (is) { - t.notOk(is) - t.end() - }) - }) - t.end() -}) - -t.test('no promise', function (t) { - global.Promise = null - var isexe = reset() - t.throws('try to meow a promise', function () { - isexe(meow) - }) - t.end() -}) - -t.test('access', { skip: accessSkip || winSkip }, function (t) { - runTest(t) -}) - -t.test('mode', { skip: winSkip }, function (t) { - delete fs.access - delete fs.accessSync - var isexe = reset() - t.ok(isexe.sync(ours, { uid: 0, gid: 0 })) - t.ok(isexe.sync(mine, { uid: 0, gid: 0 })) - runTest(t) -}) - -t.test('windows', function (t) { - global.TESTING_WINDOWS = true - var pathExt = '.EXE;.CAT;.CMD;.COM' - t.test('pathExt option', function (t) { - runTest(t, { pathExt: '.EXE;.CAT;.CMD;.COM' }) - }) - t.test('pathExt env', function (t) { - process.env.PATHEXT = pathExt - runTest(t) - }) - t.test('no pathExt', function (t) { - // with a pathExt of '', any filename is fine. - // so the "fail" one would still pass. - runTest(t, { pathExt: '', skipFail: true }) - }) - t.test('pathext with empty entry', function (t) { - // with a pathExt of '', any filename is fine. - // so the "fail" one would still pass. - runTest(t, { pathExt: ';' + pathExt, skipFail: true }) - }) - t.end() -}) - -t.test('cleanup', function (t) { - rimraf.sync(fixture) - t.end() -}) - -function runTest (t, options) { - var isexe = reset() - - var optionsIgnore = Object.create(options || {}) - optionsIgnore.ignoreErrors = true - - if (!options || !options.skipFail) { - t.notOk(isexe.sync(fail, options)) - } - t.notOk(isexe.sync(noent, optionsIgnore)) - if (!options) { - t.ok(isexe.sync(meow)) - } else { - t.ok(isexe.sync(meow, options)) - } - - t.ok(isexe.sync(mine, options)) - t.ok(isexe.sync(ours, options)) - t.throws(function () { - isexe.sync(noent, options) - }) - - t.test('meow async', function (t) { - if (!options) { - isexe(meow, function (er, is) { - if (er) { - throw er - } - t.ok(is) - t.end() - }) - } else { - isexe(meow, options, function (er, is) { - if (er) { - throw er - } - t.ok(is) - t.end() - }) - } - }) - - t.test('mine async', function (t) { - isexe(mine, options, function (er, is) { - if (er) { - throw er - } - t.ok(is) - t.end() - }) - }) - - t.test('ours async', function (t) { - isexe(ours, options, function (er, is) { - if (er) { - throw er - } - t.ok(is) - t.end() - }) - }) - - if (!options || !options.skipFail) { - t.test('fail async', function (t) { - isexe(fail, options, function (er, is) { - if (er) { - throw er - } - t.notOk(is) - t.end() - }) - }) - } - - t.test('noent async', function (t) { - isexe(noent, options, function (er, is) { - t.ok(er) - t.notOk(is) - t.end() - }) - }) - - t.test('noent ignore async', function (t) { - isexe(noent, optionsIgnore, function (er, is) { - if (er) { - throw er - } - t.notOk(is) - t.end() - }) - }) - - t.test('directory is not executable', function (t) { - isexe(__dirname, options, function (er, is) { - if (er) { - throw er - } - t.notOk(is) - t.end() - }) - }) - - t.end() -} diff --git a/node_modules/isexe/windows.js b/node_modules/isexe/windows.js deleted file mode 100644 index 34996734d8ef3..0000000000000 --- a/node_modules/isexe/windows.js +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = isexe -isexe.sync = sync - -var fs = require('fs') - -function checkPathExt (path, options) { - var pathext = options.pathExt !== undefined ? - options.pathExt : process.env.PATHEXT - - if (!pathext) { - return true - } - - pathext = pathext.split(';') - if (pathext.indexOf('') !== -1) { - return true - } - for (var i = 0; i < pathext.length; i++) { - var p = pathext[i].toLowerCase() - if (p && path.substr(-p.length).toLowerCase() === p) { - return true - } - } - return false -} - -function checkStat (stat, path, options) { - if (!stat.isSymbolicLink() && !stat.isFile()) { - return false - } - return checkPathExt(path, options) -} - -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, path, options)) - }) -} - -function sync (path, options) { - return checkStat(fs.statSync(path), path, options) -} diff --git a/node_modules/json-parse-even-better-errors/index.js b/node_modules/json-parse-even-better-errors/index.js deleted file mode 100644 index 86a1fdc1ae809..0000000000000 --- a/node_modules/json-parse-even-better-errors/index.js +++ /dev/null @@ -1,121 +0,0 @@ -'use strict' - -const hexify = char => { - const h = char.charCodeAt(0).toString(16).toUpperCase() - return '0x' + (h.length % 2 ? '0' : '') + h -} - -const parseError = (e, txt, context) => { - if (!txt) { - return { - message: e.message + ' while parsing empty string', - position: 0, - } - } - const badToken = e.message.match(/^Unexpected token (.) .*position\s+(\d+)/i) - const errIdx = badToken ? +badToken[2] - : e.message.match(/^Unexpected end of JSON.*/i) ? txt.length - 1 - : null - - const msg = badToken ? e.message.replace(/^Unexpected token ./, `Unexpected token ${ - JSON.stringify(badToken[1]) - } (${hexify(badToken[1])})`) - : e.message - - if (errIdx !== null && errIdx !== undefined) { - const start = errIdx <= context ? 0 - : errIdx - context - - const end = errIdx + context >= txt.length ? txt.length - : errIdx + context - - const slice = (start === 0 ? '' : '...') + - txt.slice(start, end) + - (end === txt.length ? '' : '...') - - const near = txt === slice ? '' : 'near ' - - return { - message: msg + ` while parsing ${near}${JSON.stringify(slice)}`, - position: errIdx, - } - } else { - return { - message: msg + ` while parsing '${txt.slice(0, context * 2)}'`, - position: 0, - } - } -} - -class JSONParseError extends SyntaxError { - constructor (er, txt, context, caller) { - context = context || 20 - const metadata = parseError(er, txt, context) - super(metadata.message) - Object.assign(this, metadata) - this.code = 'EJSONPARSE' - this.systemError = er - Error.captureStackTrace(this, caller || this.constructor) - } - get name () { return this.constructor.name } - set name (n) {} - get [Symbol.toStringTag] () { return this.constructor.name } -} - -const kIndent = Symbol.for('indent') -const kNewline = Symbol.for('newline') -// only respect indentation if we got a line break, otherwise squash it -// things other than objects and arrays aren't indented, so ignore those -// Important: in both of these regexps, the $1 capture group is the newline -// or undefined, and the $2 capture group is the indent, or undefined. -const formatRE = /^\s*[{\[]((?:\r?\n)+)([\s\t]*)/ -const emptyRE = /^(?:\{\}|\[\])((?:\r?\n)+)?$/ - -const parseJson = (txt, reviver, context) => { - const parseText = stripBOM(txt) - context = context || 20 - try { - // get the indentation so that we can save it back nicely - // if the file starts with {" then we have an indent of '', ie, none - // otherwise, pick the indentation of the next line after the first \n - // If the pattern doesn't match, then it means no indentation. - // JSON.stringify ignores symbols, so this is reasonably safe. - // if the string is '{}' or '[]', then use the default 2-space indent. - const [, newline = '\n', indent = ' '] = parseText.match(emptyRE) || - parseText.match(formatRE) || - [, '', ''] - - const result = JSON.parse(parseText, reviver) - if (result && typeof result === 'object') { - result[kNewline] = newline - result[kIndent] = indent - } - return result - } catch (e) { - if (typeof txt !== 'string' && !Buffer.isBuffer(txt)) { - const isEmptyArray = Array.isArray(txt) && txt.length === 0 - throw Object.assign(new TypeError( - `Cannot parse ${isEmptyArray ? 'an empty array' : String(txt)}` - ), { - code: 'EJSONPARSE', - systemError: e, - }) - } - - throw new JSONParseError(e, parseText, context, parseJson) - } -} - -// 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. -const stripBOM = txt => String(txt).replace(/^\uFEFF/, '') - -module.exports = parseJson -parseJson.JSONParseError = JSONParseError - -parseJson.noExceptions = (txt, reviver) => { - try { - return JSON.parse(stripBOM(txt), reviver) - } catch (e) {} -} diff --git a/node_modules/json-parse-even-better-errors/lib/index.js b/node_modules/json-parse-even-better-errors/lib/index.js new file mode 100644 index 0000000000000..3ffdaac96d2dc --- /dev/null +++ b/node_modules/json-parse-even-better-errors/lib/index.js @@ -0,0 +1,137 @@ +'use strict' + +const INDENT = Symbol.for('indent') +const NEWLINE = Symbol.for('newline') + +const DEFAULT_NEWLINE = '\n' +const DEFAULT_INDENT = ' ' +const BOM = /^\uFEFF/ + +// only respect indentation if we got a line break, otherwise squash it +// things other than objects and arrays aren't indented, so ignore those +// Important: in both of these regexps, the $1 capture group is the newline +// or undefined, and the $2 capture group is the indent, or undefined. +const FORMAT = /^\s*[{[]((?:\r?\n)+)([\s\t]*)/ +const EMPTY = /^(?:\{\}|\[\])((?:\r?\n)+)?$/ + +// Node 20 puts single quotes around the token and a comma after it +const UNEXPECTED_TOKEN = /^Unexpected token '?(.)'?(,)? /i + +const hexify = (char) => { + const h = char.charCodeAt(0).toString(16).toUpperCase() + return `0x${h.length % 2 ? '0' : ''}${h}` +} + +// 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. +const stripBOM = (txt) => String(txt).replace(BOM, '') + +const makeParsedError = (msg, parsing, position = 0) => ({ + message: `${msg} while parsing ${parsing}`, + position, +}) + +const parseError = (e, txt, context = 20) => { + let msg = e.message + + if (!txt) { + return makeParsedError(msg, 'empty string') + } + + const badTokenMatch = msg.match(UNEXPECTED_TOKEN) + const badIndexMatch = msg.match(/ position\s+(\d+)/i) + + if (badTokenMatch) { + msg = msg.replace( + UNEXPECTED_TOKEN, + `Unexpected token ${JSON.stringify(badTokenMatch[1])} (${hexify(badTokenMatch[1])})$2 ` + ) + } + + let errIdx + if (badIndexMatch) { + errIdx = +badIndexMatch[1] + } else /* istanbul ignore next - doesnt happen in Node 22 */ if ( + msg.match(/^Unexpected end of JSON.*/i) + ) { + errIdx = txt.length - 1 + } + + if (errIdx == null) { + return makeParsedError(msg, `'${txt.slice(0, context * 2)}'`) + } + + const start = errIdx <= context ? 0 : errIdx - context + const end = errIdx + context >= txt.length ? txt.length : errIdx + context + const slice = `${start ? '...' : ''}${txt.slice(start, end)}${end === txt.length ? '' : '...'}` + + return makeParsedError( + msg, + `${txt === slice ? '' : 'near '}${JSON.stringify(slice)}`, + errIdx + ) +} + +class JSONParseError extends SyntaxError { + constructor (er, txt, context, caller) { + const metadata = parseError(er, txt, context) + super(metadata.message) + Object.assign(this, metadata) + this.code = 'EJSONPARSE' + this.systemError = er + Error.captureStackTrace(this, caller || this.constructor) + } + + get name () { + return this.constructor.name + } + + set name (n) {} + + get [Symbol.toStringTag] () { + return this.constructor.name + } +} + +const parseJson = (txt, reviver) => { + const result = JSON.parse(txt, reviver) + if (result && typeof result === 'object') { + // get the indentation so that we can save it back nicely + // if the file starts with {" then we have an indent of '', ie, none + // otherwise, pick the indentation of the next line after the first \n If the + // pattern doesn't match, then it means no indentation. JSON.stringify ignores + // symbols, so this is reasonably safe. if the string is '{}' or '[]', then + // use the default 2-space indent. + const match = txt.match(EMPTY) || txt.match(FORMAT) || [null, '', ''] + result[NEWLINE] = match[1] ?? DEFAULT_NEWLINE + result[INDENT] = match[2] ?? DEFAULT_INDENT + } + return result +} + +const parseJsonError = (raw, reviver, context) => { + const txt = stripBOM(raw) + try { + return parseJson(txt, reviver) + } catch (e) { + if (typeof raw !== 'string' && !Buffer.isBuffer(raw)) { + const msg = Array.isArray(raw) && raw.length === 0 ? 'an empty array' : String(raw) + throw Object.assign( + new TypeError(`Cannot parse ${msg}`), + { code: 'EJSONPARSE', systemError: e } + ) + } + throw new JSONParseError(e, txt, context, parseJsonError) + } +} + +module.exports = parseJsonError +parseJsonError.JSONParseError = JSONParseError +parseJsonError.noExceptions = (raw, reviver) => { + try { + return parseJson(stripBOM(raw), reviver) + } catch { + // no exceptions + } +} diff --git a/node_modules/json-parse-even-better-errors/package.json b/node_modules/json-parse-even-better-errors/package.json index ed0fdaf2e0f6f..6e696c98548db 100644 --- a/node_modules/json-parse-even-better-errors/package.json +++ b/node_modules/json-parse-even-better-errors/package.json @@ -1,33 +1,50 @@ { "name": "json-parse-even-better-errors", - "version": "2.3.1", + "version": "5.0.0", "description": "JSON.parse with context information on error", - "main": "index.js", + "main": "lib/index.js", "files": [ - "*.js" + "bin/", + "lib/" ], "scripts": { - "preversion": "npm t", - "postversion": "npm publish", - "prepublishOnly": "git push --follow-tags", "test": "tap", - "snap": "tap" + "snap": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npm/json-parse-even-better-errors.git" }, - "repository": "https://github.com/npm/json-parse-even-better-errors", "keywords": [ "JSON", "parser" ], - "author": { - "name": "Kat Marchán", - "email": "kzm@zkat.tech", - "twitter": "maybekatz" - }, + "author": "GitHub Inc.", "license": "MIT", "devDependencies": { - "tap": "^14.6.5" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/just-diff-apply/index.js b/node_modules/just-diff-apply/index.cjs similarity index 100% rename from node_modules/just-diff-apply/index.js rename to node_modules/just-diff-apply/index.cjs diff --git a/node_modules/just-diff-apply/index.d.ts b/node_modules/just-diff-apply/index.d.ts deleted file mode 100644 index 7547b722f484f..0000000000000 --- a/node_modules/just-diff-apply/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Definitions by: Eddie Atkinson <https://github.com/eddie-atkinson> - -type Operation = "add" | "replace" | "remove" | "move"; - -type DiffOps = Array<{ - op: Operation; - path: Array<string | number>; - value?: any; -}>; -type PathConverter = (path: string) => string[]; - -export function diffApply<T extends object>( - obj: T, - diff: DiffOps, - pathConverter?: PathConverter -): T; -export const jsonPatchPathConverter: PathConverter; diff --git a/node_modules/just-diff-apply/index.tests.ts b/node_modules/just-diff-apply/index.tests.ts deleted file mode 100644 index d02ba89b838cd..0000000000000 --- a/node_modules/just-diff-apply/index.tests.ts +++ /dev/null @@ -1,108 +0,0 @@ -import * as diffObj from "./index"; - -const { diffApply, jsonPatchPathConverter } = diffObj; -const obj1 = { - a: 2, - b: 3, - c: { - d: 5 - } -}; -const arr1 = [1, "bee"]; - -const objOps: diffObj.DiffOps = [ - { - op: "replace", - path: ["a"], - value: 10 - }, - { - op: "remove", - path: ["b"] - }, - { - op: "add", - path: ["e"], - value: 15 - }, - { - op: "remove", - path: ["c", "d"] - } -]; - -const arrOps: diffObj.DiffOps = [ - { - op: "replace", - path: [1], - value: 10 - }, - { - op: "remove", - path: [2] - }, - { - op: "add", - path: [7], - value: 15 - } -]; - -//OK -diffApply(obj1, objOps); -diffApply(obj1, []); -diffApply(arr1, arrOps); -diffApply(arr1, []); -diffApply(obj1, objOps, jsonPatchPathConverter); -diffApply(arr1, arrOps, jsonPatchPathConverter); - -// not OK -// @ts-expect-error -diffApply(obj1); -// @ts-expect-error -diffApply(arr2); -// @ts-expect-error -diffApply("a"); -// @ts-expect-error -diffApply(true); - -// @ts-expect-error -diffApply(obj1, 1); -// @ts-expect-error -diffApply(3, arr2); -// @ts-expect-error -diffApply(obj1, "a"); -// @ts-expect-error -diffApply("b", arr2); - -// @ts-expect-error -diffApply(obj1, [{ op: "delete", path: ["a"] }]); -// @ts-expect-error -diffApply(obj1, [{ op: "delete", path: ["a"] }], jsonPatchPathConverter); -// @ts-expect-error -diffApply(obj1, "a", jsonPatchPathConverter); -// @ts-expect-error -diffApply(obj1, ["a", "b", "c"], jsonPatchPathConverter); - -// @ts-expect-error -diff("a", jsonPatchPathConverter); -// @ts-expect-error -diff(true, jsonPatchPathConverter); - -// @ts-expect-error -diff(obj1, 1, jsonPatchPathConverter); -// @ts-expect-error -diff(3, arr2, jsonPatchPathConverter); -// @ts-expect-error -diff(obj1, "a", jsonPatchPathConverter); -// @ts-expect-error -diff("b", arr2, jsonPatchPathConverter); - -// @ts-expect-error -diff(obj1, obj2, "a"); -// @ts-expect-error -diff(arr1, arr2, 1); -// @ts-expect-error -diff(obj1, arr1, "bee"); -// @ts-expect-error -diff(obj2, arr2, "nope"); diff --git a/node_modules/just-diff-apply/package.json b/node_modules/just-diff-apply/package.json index b2f80b73a19c6..be2879aacfadc 100644 --- a/node_modules/just-diff-apply/package.json +++ b/node_modules/just-diff-apply/package.json @@ -1,15 +1,17 @@ { "name": "just-diff-apply", - "version": "5.3.1", + "version": "5.5.0", "description": "Apply a diff to an object. Optionally supports jsonPatch protocol", - "main": "index.js", - "module": "index.mjs", + "type": "module", "exports": { ".": { - "require": "./index.js", - "default": "./index.mjs" - } + "types": "./index.d.ts", + "require": "./index.cjs", + "import": "./index.mjs" + }, + "./package.json": "./package.json" }, + "main": "index.cjs", "types": "index.d.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -29,4 +31,4 @@ "bugs": { "url": "https://github.com/angus-c/just/issues" } -} +} \ No newline at end of file diff --git a/node_modules/just-diff/index.cjs b/node_modules/just-diff/index.cjs new file mode 100644 index 0000000000000..b74099de2b2af --- /dev/null +++ b/node_modules/just-diff/index.cjs @@ -0,0 +1,230 @@ +module.exports = { + diff: diff, + jsonPatchPathConverter: jsonPatchPathConverter, +}; + +/* + const obj1 = {a: 4, b: 5}; + const obj2 = {a: 3, b: 5}; + const obj3 = {a: 4, c: 5}; + + diff(obj1, obj2); + [ + { "op": "replace", "path": ['a'], "value": 3 } + ] + + diff(obj2, obj3); + [ + { "op": "remove", "path": ['b'] }, + { "op": "replace", "path": ['a'], "value": 4 } + { "op": "add", "path": ['c'], "value": 5 } + ] + + // using converter to generate jsPatch standard paths + // see http://jsonpatch.com + import {diff, jsonPatchPathConverter} from 'just-diff' + diff(obj1, obj2, jsonPatchPathConverter); + [ + { "op": "replace", "path": '/a', "value": 3 } + ] + + diff(obj2, obj3, jsonPatchPathConverter); + [ + { "op": "remove", "path": '/b' }, + { "op": "replace", "path": '/a', "value": 4 } + { "op": "add", "path": '/c', "value": 5 } + ] + + // arrays + const obj4 = {a: 4, b: [1, 2, 3]}; + const obj5 = {a: 3, b: [1, 2, 4]}; + const obj6 = {a: 3, b: [1, 2, 4, 5]}; + + diff(obj4, obj5); + [ + { "op": "replace", "path": ['a'], "value": 3 } + { "op": "replace", "path": ['b', 2], "value": 4 } + ] + + diff(obj5, obj6); + [ + { "op": "add", "path": ['b', 3], "value": 5 } + ] + + // nested paths + const obj7 = {a: 4, b: {c: 3}}; + const obj8 = {a: 4, b: {c: 4}}; + const obj9 = {a: 5, b: {d: 4}}; + + diff(obj7, obj8); + [ + { "op": "replace", "path": ['b', 'c'], "value": 4 } + ] + + diff(obj8, obj9); + [ + { "op": "replace", "path": ['a'], "value": 5 } + { "op": "remove", "path": ['b', 'c']} + { "op": "add", "path": ['b', 'd'], "value": 4 } + ] +*/ + +function diff(obj1, obj2, pathConverter) { + if (!obj1 || typeof obj1 != 'object' || !obj2 || typeof obj2 != 'object') { + throw new Error('both arguments must be objects or arrays'); + } + + pathConverter || + (pathConverter = function(arr) { + return arr; + }); + + function getDiff({obj1, obj2, basePath, basePathForRemoves, diffs}) { + var obj1Keys = Object.keys(obj1); + var obj1KeysLength = obj1Keys.length; + var obj2Keys = Object.keys(obj2); + var obj2KeysLength = obj2Keys.length; + var path; + + var lengthDelta = obj1.length - obj2.length; + + if (trimFromRight(obj1, obj2)) { + for (var i = 0; i < obj1KeysLength; i++) { + var key = Array.isArray(obj1) ? Number(obj1Keys[i]) : obj1Keys[i]; + if (!(key in obj2)) { + path = basePathForRemoves.concat(key); + diffs.remove.push({ + op: 'remove', + path: pathConverter(path), + }); + } + } + + for (var i = 0; i < obj2KeysLength; i++) { + var key = Array.isArray(obj2) ? Number(obj2Keys[i]) : obj2Keys[i]; + pushReplaces({ + key, + obj1, + obj2, + path: basePath.concat(key), + pathForRemoves: basePath.concat(key), + diffs, + }); + } + } else { + // trim from left, objects are both arrays + for (var i = 0; i < lengthDelta; i++) { + path = basePathForRemoves.concat(i); + diffs.remove.push({ + op: 'remove', + path: pathConverter(path), + }); + } + + // now make a copy of obj1 with excess elements left trimmed and see if there any replaces + var obj1Trimmed = obj1.slice(lengthDelta);; + for (var i = 0; i < obj2KeysLength; i++) { + pushReplaces({ + key: i, + obj1: obj1Trimmed, + obj2, + path: basePath.concat(i), + // since list of removes are reversed before presenting result, + // we need to ignore existing parent removes when doing nested removes + pathForRemoves: basePath.concat(i + lengthDelta), + diffs, + }); + } + } + } + + var diffs = {remove: [], replace: [], add: []}; + getDiff({ + obj1, + obj2, + basePath: [], + basePathForRemoves: [], + diffs, + }); + + // reverse removes since we want to maintain indexes + return diffs.remove + .reverse() + .concat(diffs.replace) + .concat(diffs.add); + + function pushReplaces({key, obj1, obj2, path, pathForRemoves, diffs}) { + var obj1AtKey = obj1[key]; + var obj2AtKey = obj2[key]; + + if(!(key in obj1) && (key in obj2)) { + var obj2Value = obj2AtKey; + diffs.add.push({ + op: 'add', + path: pathConverter(path), + value: obj2Value, + }); + } else if(obj1AtKey !== obj2AtKey) { + if(Object(obj1AtKey) !== obj1AtKey || + Object(obj2AtKey) !== obj2AtKey || differentTypes(obj1AtKey, obj2AtKey) + ) { + pushReplace(path, diffs, obj2AtKey); + } else { + if(!Object.keys(obj1AtKey).length && + !Object.keys(obj2AtKey).length && + String(obj1AtKey) != String(obj2AtKey)) { + pushReplace(path, diffs, obj2AtKey); + } else { + getDiff({ + obj1: obj1[key], + obj2: obj2[key], + basePath: path, + basePathForRemoves: pathForRemoves, + diffs}); + } + } + } + } + + function pushReplace(path, diffs, newValue) { + diffs.replace.push({ + op: 'replace', + path: pathConverter(path), + value: newValue, + }); + } +} + +function jsonPatchPathConverter(arrayPath) { + return [''].concat(arrayPath).join('/'); +} + +function differentTypes(a, b) { + return Object.prototype.toString.call(a) != Object.prototype.toString.call(b); +} + +function trimFromRight(obj1, obj2) { + var lengthDelta = obj1.length - obj2.length; + if (Array.isArray(obj1) && Array.isArray(obj2) && lengthDelta > 0) { + var leftMatches = 0; + var rightMatches = 0; + for (var i = 0; i < obj2.length; i++) { + if (String(obj1[i]) === String(obj2[i])) { + leftMatches++; + } else { + break; + } + } + for (var j = obj2.length; j > 0; j--) { + if (String(obj1[j + lengthDelta]) === String(obj2[j])) { + rightMatches++; + } else { + break; + } + } + + // bias to trim right becase it requires less index shifting + return leftMatches >= rightMatches; + } + return true; +} diff --git a/node_modules/just-diff/index.d.ts b/node_modules/just-diff/index.d.ts deleted file mode 100644 index 576ddc54957fc..0000000000000 --- a/node_modules/just-diff/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Definitions by: Cameron Hunter <https://github.com/cameronhunter> -// Modified by: Angus Croll <https://github.com/angus-c> -type Operation = "add" | "replace" | "remove"; - -type JSONPatchPathConverter<OUTPUT> = ( - arrayPath: Array<string | number> -) => OUTPUT; - -export function diff( - a: object | Array<any>, - b: object | Array<any>, -): Array<{ op: Operation; path: Array<string | number>; value: any }>; - -export function diff<PATH>( - a: object | Array<any>, - b: object | Array<any>, - jsonPatchPathConverter: JSONPatchPathConverter<PATH> -): Array<{ op: Operation; path: PATH; value: any }>; - -export const jsonPatchPathConverter: JSONPatchPathConverter<string>; \ No newline at end of file diff --git a/node_modules/just-diff/index.js b/node_modules/just-diff/index.js deleted file mode 100644 index 11ad3710b98f4..0000000000000 --- a/node_modules/just-diff/index.js +++ /dev/null @@ -1,153 +0,0 @@ -module.exports = { - diff: diff, - jsonPatchPathConverter: jsonPatchPathConverter, -}; - -/* - const obj1 = {a: 4, b: 5}; - const obj2 = {a: 3, b: 5}; - const obj3 = {a: 4, c: 5}; - - diff(obj1, obj2); - [ - { "op": "replace", "path": ['a'], "value": 3 } - ] - - diff(obj2, obj3); - [ - { "op": "remove", "path": ['b'] }, - { "op": "replace", "path": ['a'], "value": 4 } - { "op": "add", "path": ['c'], "value": 5 } - ] - - // using converter to generate jsPatch standard paths - // see http://jsonpatch.com - import {diff, jsonPatchPathConverter} from 'just-diff' - diff(obj1, obj2, jsonPatchPathConverter); - [ - { "op": "replace", "path": '/a', "value": 3 } - ] - - diff(obj2, obj3, jsonPatchPathConverter); - [ - { "op": "remove", "path": '/b' }, - { "op": "replace", "path": '/a', "value": 4 } - { "op": "add", "path": '/c', "value": 5 } - ] - - // arrays - const obj4 = {a: 4, b: [1, 2, 3]}; - const obj5 = {a: 3, b: [1, 2, 4]}; - const obj6 = {a: 3, b: [1, 2, 4, 5]}; - - diff(obj4, obj5); - [ - { "op": "replace", "path": ['a'], "value": 3 } - { "op": "replace", "path": ['b', 2], "value": 4 } - ] - - diff(obj5, obj6); - [ - { "op": "add", "path": ['b', 3], "value": 5 } - ] - - // nested paths - const obj7 = {a: 4, b: {c: 3}}; - const obj8 = {a: 4, b: {c: 4}}; - const obj9 = {a: 5, b: {d: 4}}; - - diff(obj7, obj8); - [ - { "op": "replace", "path": ['b', 'c'], "value": 4 } - ] - - diff(obj8, obj9); - [ - { "op": "replace", "path": ['a'], "value": 5 } - { "op": "remove", "path": ['b', 'c']} - { "op": "add", "path": ['b', 'd'], "value": 4 } - ] -*/ - -function diff(obj1, obj2, pathConverter) { - if (!obj1 || typeof obj1 != 'object' || !obj2 || typeof obj2 != 'object') { - throw new Error('both arguments must be objects or arrays'); - } - - pathConverter || - (pathConverter = function(arr) { - return arr; - }); - - function getDiff(obj1, obj2, basePath, diffs) { - var obj1Keys = Object.keys(obj1); - var obj1KeysLength = obj1Keys.length; - var obj2Keys = Object.keys(obj2); - var obj2KeysLength = obj2Keys.length; - var path; - - for (var i = 0; i < obj1KeysLength; i++) { - var key = Array.isArray(obj1) ? Number(obj1Keys[i]) : obj1Keys[i]; - if (!(key in obj2)) { - path = basePath.concat(key); - diffs.remove.push({ - op: 'remove', - path: pathConverter(path), - }); - } - } - - for (var i = 0; i < obj2KeysLength; i++) { - var key = Array.isArray(obj2) ? Number(obj2Keys[i]) : obj2Keys[i]; - var obj1AtKey = obj1[key]; - var obj2AtKey = obj2[key]; - if (!(key in obj1)) { - path = basePath.concat(key); - var obj2Value = obj2[key]; - diffs.add.push({ - op: 'add', - path: pathConverter(path), - value: obj2Value, - }); - } else if (obj1AtKey !== obj2AtKey) { - if ( - Object(obj1AtKey) !== obj1AtKey || - Object(obj2AtKey) !== obj2AtKey - ) { - path = pushReplace(path, basePath, key, diffs, pathConverter, obj2); - } else { - if ( - !Object.keys(obj1AtKey).length && - !Object.keys(obj2AtKey).length && - String(obj1AtKey) != String(obj2AtKey) - ) { - path = pushReplace(path, basePath, key, diffs, pathConverter, obj2); - } else { - getDiff(obj1[key], obj2[key], basePath.concat(key), diffs); - } - } - } - } - - return diffs; - } - const finalDiffs = getDiff(obj1, obj2, [], {remove: [], replace: [], add: []}); - return finalDiffs.remove - .reverse() - .concat(finalDiffs.replace) - .concat(finalDiffs.add); -} - -function pushReplace(path, basePath, key, diffs, pathConverter, obj2) { - path = basePath.concat(key); - diffs.replace.push({ - op: 'replace', - path: pathConverter(path), - value: obj2[key], - }); - return path; -} - -function jsonPatchPathConverter(arrayPath) { - return [''].concat(arrayPath).join('/'); -} diff --git a/node_modules/just-diff/index.mjs b/node_modules/just-diff/index.mjs index a0c5834475fea..4a847874c3504 100644 --- a/node_modules/just-diff/index.mjs +++ b/node_modules/just-diff/index.mjs @@ -74,77 +74,154 @@ function diff(obj1, obj2, pathConverter) { return arr; }); - function getDiff(obj1, obj2, basePath, diffs) { + function getDiff({obj1, obj2, basePath, basePathForRemoves, diffs}) { var obj1Keys = Object.keys(obj1); var obj1KeysLength = obj1Keys.length; var obj2Keys = Object.keys(obj2); var obj2KeysLength = obj2Keys.length; var path; - for (var i = 0; i < obj1KeysLength; i++) { - var key = Array.isArray(obj1) ? Number(obj1Keys[i]) : obj1Keys[i]; - if (!(key in obj2)) { - path = basePath.concat(key); + var lengthDelta = obj1.length - obj2.length; + + if (trimFromRight(obj1, obj2)) { + for (var i = 0; i < obj1KeysLength; i++) { + var key = Array.isArray(obj1) ? Number(obj1Keys[i]) : obj1Keys[i]; + if (!(key in obj2)) { + path = basePathForRemoves.concat(key); + diffs.remove.push({ + op: 'remove', + path: pathConverter(path), + }); + } + } + + for (var i = 0; i < obj2KeysLength; i++) { + var key = Array.isArray(obj2) ? Number(obj2Keys[i]) : obj2Keys[i]; + pushReplaces({ + key, + obj1, + obj2, + path: basePath.concat(key), + pathForRemoves: basePath.concat(key), + diffs, + }); + } + } else { + // trim from left, objects are both arrays + for (var i = 0; i < lengthDelta; i++) { + path = basePathForRemoves.concat(i); diffs.remove.push({ op: 'remove', path: pathConverter(path), }); } - } - for (var i = 0; i < obj2KeysLength; i++) { - var key = Array.isArray(obj2) ? Number(obj2Keys[i]) : obj2Keys[i]; - var obj1AtKey = obj1[key]; - var obj2AtKey = obj2[key]; - if (!(key in obj1)) { - path = basePath.concat(key); - var obj2Value = obj2[key]; - diffs.add.push({ - op: 'add', - path: pathConverter(path), - value: obj2Value, + // now make a copy of obj1 with excess elements left trimmed and see if there any replaces + var obj1Trimmed = obj1.slice(lengthDelta);; + for (var i = 0; i < obj2KeysLength; i++) { + pushReplaces({ + key: i, + obj1: obj1Trimmed, + obj2, + path: basePath.concat(i), + // since list of removes are reversed before presenting result, + // we need to ignore existing parent removes when doing nested removes + pathForRemoves: basePath.concat(i + lengthDelta), + diffs, }); - } else if (obj1AtKey !== obj2AtKey) { - if ( - Object(obj1AtKey) !== obj1AtKey || - Object(obj2AtKey) !== obj2AtKey - ) { - path = pushReplace(path, basePath, key, diffs, pathConverter, obj2); + } + } + } + + var diffs = {remove: [], replace: [], add: []}; + getDiff({ + obj1, + obj2, + basePath: [], + basePathForRemoves: [], + diffs, + }); + + // reverse removes since we want to maintain indexes + return diffs.remove + .reverse() + .concat(diffs.replace) + .concat(diffs.add); + + function pushReplaces({key, obj1, obj2, path, pathForRemoves, diffs}) { + var obj1AtKey = obj1[key]; + var obj2AtKey = obj2[key]; + + if(!(key in obj1) && (key in obj2)) { + var obj2Value = obj2AtKey; + diffs.add.push({ + op: 'add', + path: pathConverter(path), + value: obj2Value, + }); + } else if(obj1AtKey !== obj2AtKey) { + if(Object(obj1AtKey) !== obj1AtKey || + Object(obj2AtKey) !== obj2AtKey || differentTypes(obj1AtKey, obj2AtKey) + ) { + pushReplace(path, diffs, obj2AtKey); + } else { + if(!Object.keys(obj1AtKey).length && + !Object.keys(obj2AtKey).length && + String(obj1AtKey) != String(obj2AtKey)) { + pushReplace(path, diffs, obj2AtKey); } else { - if ( - !Object.keys(obj1AtKey).length && - !Object.keys(obj2AtKey).length && - String(obj1AtKey) != String(obj2AtKey) - ) { - path = pushReplace(path, basePath, key, diffs, pathConverter, obj2); - } else { - getDiff(obj1[key], obj2[key], basePath.concat(key), diffs); - } + getDiff({ + obj1: obj1[key], + obj2: obj2[key], + basePath: path, + basePathForRemoves: pathForRemoves, + diffs}); } } } - - return diffs; } - const finalDiffs = getDiff(obj1, obj2, [], {remove: [], replace: [], add: []}); - return finalDiffs.remove - .reverse() - .concat(finalDiffs.replace) - .concat(finalDiffs.add); -} -function pushReplace(path, basePath, key, diffs, pathConverter, obj2) { - path = basePath.concat(key); - diffs.replace.push({ - op: 'replace', - path: pathConverter(path), - value: obj2[key], - }); - return path; + function pushReplace(path, diffs, newValue) { + diffs.replace.push({ + op: 'replace', + path: pathConverter(path), + value: newValue, + }); + } } function jsonPatchPathConverter(arrayPath) { return [''].concat(arrayPath).join('/'); } +function differentTypes(a, b) { + return Object.prototype.toString.call(a) != Object.prototype.toString.call(b); +} + +function trimFromRight(obj1, obj2) { + var lengthDelta = obj1.length - obj2.length; + if (Array.isArray(obj1) && Array.isArray(obj2) && lengthDelta > 0) { + var leftMatches = 0; + var rightMatches = 0; + for (var i = 0; i < obj2.length; i++) { + if (String(obj1[i]) === String(obj2[i])) { + leftMatches++; + } else { + break; + } + } + for (var j = obj2.length; j > 0; j--) { + if (String(obj1[j + lengthDelta]) === String(obj2[j])) { + rightMatches++; + } else { + break; + } + } + + // bias to trim right becase it requires less index shifting + return leftMatches >= rightMatches; + } + return true; +} + export {diff, jsonPatchPathConverter}; diff --git a/node_modules/just-diff/index.tests.ts b/node_modules/just-diff/index.tests.ts deleted file mode 100644 index 91eaecd8d49e8..0000000000000 --- a/node_modules/just-diff/index.tests.ts +++ /dev/null @@ -1,65 +0,0 @@ -import * as diffObj from './index' - -const {diff, jsonPatchPathConverter} = diffObj; -const obj1 = {a: 2, b: 3}; -const obj2 = {a: 2, c: 1}; -const arr1 = [1, 'bee']; -const arr2 = [2, 'bee']; - - -//OK -diff(obj1, obj2); -diff(arr1, arr2); -diff(obj1, arr1); -diff(obj2, arr2); -diff(/yes/, arr1); -diff(new Date(), arr2); - - -diff(obj1, obj2, jsonPatchPathConverter); -diff(arr1, arr2, jsonPatchPathConverter); -diff(obj1, arr1, jsonPatchPathConverter); -diff(obj2, arr2, jsonPatchPathConverter); - -// not OK -// @ts-expect-error -diff(obj1); -// @ts-expect-error -diff(arr2); -// @ts-expect-error -diff('a'); -// @ts-expect-error -diff(true); - -// @ts-expect-error -diff(obj1, 1); -// @ts-expect-error -diff(3, arr2); -// @ts-expect-error -diff(obj1, 'a'); -// @ts-expect-error -diff('b', arr2); - -// @ts-expect-error -diff('a', jsonPatchPathConverter); -// @ts-expect-error -diff(true, jsonPatchPathConverter); - -// @ts-expect-error -diff(obj1, 1, jsonPatchPathConverter); -// @ts-expect-error -diff(3, arr2, jsonPatchPathConverter); -// @ts-expect-error -diff(obj1, 'a', jsonPatchPathConverter); -// @ts-expect-error -diff('b', arr2, jsonPatchPathConverter); - -// @ts-expect-error -diff(obj1, obj2, 'a'); -// @ts-expect-error -diff(arr1, arr2, 1); -// @ts-expect-error -diff(obj1, arr1, 'bee'); -// @ts-expect-error -diff(obj2, arr2, 'nope'); - diff --git a/node_modules/just-diff/package.json b/node_modules/just-diff/package.json index 9c6a8bbe2f94b..0403b04cfeeb9 100644 --- a/node_modules/just-diff/package.json +++ b/node_modules/just-diff/package.json @@ -1,15 +1,17 @@ { "name": "just-diff", - "version": "5.0.3", + "version": "6.0.2", "description": "Return an object representing the diffs between two objects. Supports jsonPatch protocol", - "main": "index.js", - "module": "index.mjs", + "type": "module", "exports": { ".": { - "require": "./index.js", - "default": "./index.mjs" - } + "types": "./index.d.ts", + "require": "./index.cjs", + "import": "./index.mjs" + }, + "./package.json": "./package.json" }, + "main": "index.cjs", "types": "index.d.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -28,4 +30,4 @@ "bugs": { "url": "https://github.com/angus-c/just/issues" } -} +} \ No newline at end of file diff --git a/node_modules/libnpmaccess b/node_modules/libnpmaccess deleted file mode 120000 index b3a138bb62b43..0000000000000 --- a/node_modules/libnpmaccess +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmaccess \ No newline at end of file diff --git a/node_modules/libnpmdiff b/node_modules/libnpmdiff deleted file mode 120000 index 70ab2f9c6bbee..0000000000000 --- a/node_modules/libnpmdiff +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmdiff \ No newline at end of file diff --git a/node_modules/libnpmexec b/node_modules/libnpmexec deleted file mode 120000 index 6fc0a19cf63a4..0000000000000 --- a/node_modules/libnpmexec +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmexec \ No newline at end of file diff --git a/node_modules/libnpmfund b/node_modules/libnpmfund deleted file mode 120000 index d82688b40a0f8..0000000000000 --- a/node_modules/libnpmfund +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmfund \ No newline at end of file diff --git a/node_modules/libnpmhook b/node_modules/libnpmhook deleted file mode 120000 index 2c01b4ad01384..0000000000000 --- a/node_modules/libnpmhook +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmhook \ No newline at end of file diff --git a/node_modules/libnpmorg b/node_modules/libnpmorg deleted file mode 120000 index 6b2e24155f1ab..0000000000000 --- a/node_modules/libnpmorg +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmorg \ No newline at end of file diff --git a/node_modules/libnpmpack b/node_modules/libnpmpack deleted file mode 120000 index e6c52f5106c6d..0000000000000 --- a/node_modules/libnpmpack +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmpack \ No newline at end of file diff --git a/node_modules/libnpmpublish b/node_modules/libnpmpublish deleted file mode 120000 index ed6ad89c30934..0000000000000 --- a/node_modules/libnpmpublish +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmpublish \ No newline at end of file diff --git a/node_modules/libnpmsearch b/node_modules/libnpmsearch deleted file mode 120000 index db3ba8d84df37..0000000000000 --- a/node_modules/libnpmsearch +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmsearch \ No newline at end of file diff --git a/node_modules/libnpmteam b/node_modules/libnpmteam deleted file mode 120000 index 3445d078310a9..0000000000000 --- a/node_modules/libnpmteam +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmteam \ No newline at end of file diff --git a/node_modules/libnpmversion b/node_modules/libnpmversion deleted file mode 120000 index 28738cfa6bcfc..0000000000000 --- a/node_modules/libnpmversion +++ /dev/null @@ -1 +0,0 @@ -../workspaces/libnpmversion \ No newline at end of file diff --git a/node_modules/lru-cache/LICENSE b/node_modules/lru-cache/LICENSE deleted file mode 100644 index 9b58a3e03d1df..0000000000000 --- a/node_modules/lru-cache/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/lru-cache/LICENSE.md b/node_modules/lru-cache/LICENSE.md new file mode 100644 index 0000000000000..c5402b9577a8c --- /dev/null +++ b/node_modules/lru-cache/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/lru-cache/dist/commonjs/index.js b/node_modules/lru-cache/dist/commonjs/index.js new file mode 100644 index 0000000000000..91a8dea125fef --- /dev/null +++ b/node_modules/lru-cache/dist/commonjs/index.js @@ -0,0 +1,1589 @@ +"use strict"; +/** + * @module LRUCache + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LRUCache = void 0; +const defaultPerf = (typeof performance === 'object' && + performance && + typeof performance.now === 'function') ? + performance + : Date; +const warned = new Set(); +/* c8 ignore start */ +const PROCESS = (typeof process === 'object' && !!process ? + process + : {}); +/* c8 ignore start */ +const emitWarning = (msg, type, code, fn) => { + typeof PROCESS.emitWarning === 'function' ? + PROCESS.emitWarning(msg, type, code, fn) + : console.error(`[${code}] ${type}: ${msg}`); +}; +let AC = globalThis.AbortController; +let AS = globalThis.AbortSignal; +/* c8 ignore start */ +if (typeof AC === 'undefined') { + //@ts-ignore + AS = class AbortSignal { + onabort; + _onabort = []; + reason; + aborted = false; + addEventListener(_, fn) { + this._onabort.push(fn); + } + }; + //@ts-ignore + AC = class AbortController { + constructor() { + warnACPolyfill(); + } + signal = new AS(); + abort(reason) { + if (this.signal.aborted) + return; + //@ts-ignore + this.signal.reason = reason; + //@ts-ignore + this.signal.aborted = true; + //@ts-ignore + for (const fn of this.signal._onabort) { + fn(reason); + } + this.signal.onabort?.(reason); + } + }; + let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1'; + const warnACPolyfill = () => { + if (!printACPolyfillWarning) + return; + printACPolyfillWarning = false; + emitWarning('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', warnACPolyfill); + }; +} +/* c8 ignore stop */ +const shouldWarn = (code) => !warned.has(code); +const TYPE = Symbol('type'); +const isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n); +/* c8 ignore start */ +// This is a little bit ridiculous, tbh. +// The maximum array length is 2^32-1 or thereabouts on most JS impls. +// And well before that point, you're caching the entire world, I mean, +// that's ~32GB of just integers for the next/prev links, plus whatever +// else to hold that many keys and values. Just filling the memory with +// zeroes at init time is brutal when you get that big. +// But why not be complete? +// Maybe in the future, these limits will have expanded. +const getUintArray = (max) => !isPosInt(max) ? null + : max <= Math.pow(2, 8) ? Uint8Array + : max <= Math.pow(2, 16) ? Uint16Array + : max <= Math.pow(2, 32) ? Uint32Array + : max <= Number.MAX_SAFE_INTEGER ? ZeroArray + : null; +/* c8 ignore stop */ +class ZeroArray extends Array { + constructor(size) { + super(size); + this.fill(0); + } +} +class Stack { + heap; + length; + // private constructor + static #constructing = false; + static create(max) { + const HeapCls = getUintArray(max); + if (!HeapCls) + return []; + Stack.#constructing = true; + const s = new Stack(max, HeapCls); + Stack.#constructing = false; + return s; + } + constructor(max, HeapCls) { + /* c8 ignore start */ + if (!Stack.#constructing) { + throw new TypeError('instantiate Stack using Stack.create(n)'); + } + /* c8 ignore stop */ + this.heap = new HeapCls(max); + this.length = 0; + } + push(n) { + this.heap[this.length++] = n; + } + pop() { + return this.heap[--this.length]; + } +} +/** + * Default export, the thing you're using this module to get. + * + * The `K` and `V` types define the key and value types, respectively. The + * optional `FC` type defines the type of the `context` object passed to + * `cache.fetch()` and `cache.memo()`. + * + * Keys and values **must not** be `null` or `undefined`. + * + * All properties from the options object (with the exception of `max`, + * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are + * added as normal public members. (The listed options are read-only getters.) + * + * Changing any of these will alter the defaults for subsequent method calls. + */ +class LRUCache { + // options that cannot be changed without disaster + #max; + #maxSize; + #dispose; + #onInsert; + #disposeAfter; + #fetchMethod; + #memoMethod; + #perf; + /** + * {@link LRUCache.OptionsBase.perf} + */ + get perf() { + return this.#perf; + } + /** + * {@link LRUCache.OptionsBase.ttl} + */ + ttl; + /** + * {@link LRUCache.OptionsBase.ttlResolution} + */ + ttlResolution; + /** + * {@link LRUCache.OptionsBase.ttlAutopurge} + */ + ttlAutopurge; + /** + * {@link LRUCache.OptionsBase.updateAgeOnGet} + */ + updateAgeOnGet; + /** + * {@link LRUCache.OptionsBase.updateAgeOnHas} + */ + updateAgeOnHas; + /** + * {@link LRUCache.OptionsBase.allowStale} + */ + allowStale; + /** + * {@link LRUCache.OptionsBase.noDisposeOnSet} + */ + noDisposeOnSet; + /** + * {@link LRUCache.OptionsBase.noUpdateTTL} + */ + noUpdateTTL; + /** + * {@link LRUCache.OptionsBase.maxEntrySize} + */ + maxEntrySize; + /** + * {@link LRUCache.OptionsBase.sizeCalculation} + */ + sizeCalculation; + /** + * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection} + */ + noDeleteOnFetchRejection; + /** + * {@link LRUCache.OptionsBase.noDeleteOnStaleGet} + */ + noDeleteOnStaleGet; + /** + * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort} + */ + allowStaleOnFetchAbort; + /** + * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection} + */ + allowStaleOnFetchRejection; + /** + * {@link LRUCache.OptionsBase.ignoreFetchAbort} + */ + ignoreFetchAbort; + // computed properties + #size; + #calculatedSize; + #keyMap; + #keyList; + #valList; + #next; + #prev; + #head; + #tail; + #free; + #disposed; + #sizes; + #starts; + #ttls; + #autopurgeTimers; + #hasDispose; + #hasFetchMethod; + #hasDisposeAfter; + #hasOnInsert; + /** + * Do not call this method unless you need to inspect the + * inner workings of the cache. If anything returned by this + * object is modified in any way, strange breakage may occur. + * + * These fields are private for a reason! + * + * @internal + */ + static unsafeExposeInternals(c) { + return { + // properties + starts: c.#starts, + ttls: c.#ttls, + autopurgeTimers: c.#autopurgeTimers, + sizes: c.#sizes, + keyMap: c.#keyMap, + keyList: c.#keyList, + valList: c.#valList, + next: c.#next, + prev: c.#prev, + get head() { + return c.#head; + }, + get tail() { + return c.#tail; + }, + free: c.#free, + // methods + isBackgroundFetch: (p) => c.#isBackgroundFetch(p), + backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context), + moveToTail: (index) => c.#moveToTail(index), + indexes: (options) => c.#indexes(options), + rindexes: (options) => c.#rindexes(options), + isStale: (index) => c.#isStale(index), + }; + } + // Protected read-only members + /** + * {@link LRUCache.OptionsBase.max} (read-only) + */ + get max() { + return this.#max; + } + /** + * {@link LRUCache.OptionsBase.maxSize} (read-only) + */ + get maxSize() { + return this.#maxSize; + } + /** + * The total computed size of items in the cache (read-only) + */ + get calculatedSize() { + return this.#calculatedSize; + } + /** + * The number of items stored in the cache (read-only) + */ + get size() { + return this.#size; + } + /** + * {@link LRUCache.OptionsBase.fetchMethod} (read-only) + */ + get fetchMethod() { + return this.#fetchMethod; + } + get memoMethod() { + return this.#memoMethod; + } + /** + * {@link LRUCache.OptionsBase.dispose} (read-only) + */ + get dispose() { + return this.#dispose; + } + /** + * {@link LRUCache.OptionsBase.onInsert} (read-only) + */ + get onInsert() { + return this.#onInsert; + } + /** + * {@link LRUCache.OptionsBase.disposeAfter} (read-only) + */ + get disposeAfter() { + return this.#disposeAfter; + } + constructor(options) { + const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, onInsert, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, perf, } = options; + if (perf !== undefined) { + if (typeof perf?.now !== 'function') { + throw new TypeError('perf option must have a now() method if specified'); + } + } + this.#perf = perf ?? defaultPerf; + if (max !== 0 && !isPosInt(max)) { + throw new TypeError('max option must be a nonnegative integer'); + } + const UintArray = max ? getUintArray(max) : Array; + if (!UintArray) { + throw new Error('invalid max value: ' + max); + } + this.#max = max; + this.#maxSize = maxSize; + this.maxEntrySize = maxEntrySize || this.#maxSize; + this.sizeCalculation = sizeCalculation; + if (this.sizeCalculation) { + if (!this.#maxSize && !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 (memoMethod !== undefined && typeof memoMethod !== 'function') { + throw new TypeError('memoMethod must be a function if defined'); + } + this.#memoMethod = memoMethod; + if (fetchMethod !== undefined && typeof fetchMethod !== 'function') { + throw new TypeError('fetchMethod must be a function if specified'); + } + this.#fetchMethod = fetchMethod; + this.#hasFetchMethod = !!fetchMethod; + this.#keyMap = new Map(); + this.#keyList = new Array(max).fill(undefined); + this.#valList = new Array(max).fill(undefined); + this.#next = new UintArray(max); + this.#prev = new UintArray(max); + this.#head = 0; + this.#tail = 0; + this.#free = Stack.create(max); + this.#size = 0; + this.#calculatedSize = 0; + if (typeof dispose === 'function') { + this.#dispose = dispose; + } + if (typeof onInsert === 'function') { + this.#onInsert = onInsert; + } + if (typeof disposeAfter === 'function') { + this.#disposeAfter = disposeAfter; + this.#disposed = []; + } + else { + this.#disposeAfter = undefined; + this.#disposed = undefined; + } + this.#hasDispose = !!this.#dispose; + this.#hasOnInsert = !!this.#onInsert; + this.#hasDisposeAfter = !!this.#disposeAfter; + this.noDisposeOnSet = !!noDisposeOnSet; + this.noUpdateTTL = !!noUpdateTTL; + this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection; + this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection; + this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort; + this.ignoreFetchAbort = !!ignoreFetchAbort; + // NB: maxEntrySize is set to maxSize if it's set + if (this.maxEntrySize !== 0) { + if (this.#maxSize !== 0) { + if (!isPosInt(this.#maxSize)) { + throw new TypeError('maxSize must be a positive integer if specified'); + } + } + if (!isPosInt(this.maxEntrySize)) { + throw new TypeError('maxEntrySize must be a positive integer if specified'); + } + this.#initializeSizeTracking(); + } + this.allowStale = !!allowStale; + this.noDeleteOnStaleGet = !!noDeleteOnStaleGet; + this.updateAgeOnGet = !!updateAgeOnGet; + this.updateAgeOnHas = !!updateAgeOnHas; + this.ttlResolution = + isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1; + this.ttlAutopurge = !!ttlAutopurge; + this.ttl = ttl || 0; + if (this.ttl) { + if (!isPosInt(this.ttl)) { + throw new TypeError('ttl must be a positive integer if specified'); + } + this.#initializeTTLTracking(); + } + // do not allow completely unbounded caches + if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) { + throw new TypeError('At least one of max, maxSize, or ttl is required'); + } + if (!this.ttlAutopurge && !this.#max && !this.#maxSize) { + const code = 'LRU_CACHE_UNBOUNDED'; + if (shouldWarn(code)) { + warned.add(code); + const msg = 'TTL caching without ttlAutopurge, max, or maxSize can ' + + 'result in unbounded memory consumption.'; + emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache); + } + } + } + /** + * Return the number of ms left in the item's TTL. If item is not in cache, + * returns `0`. Returns `Infinity` if item is in cache without a defined TTL. + */ + getRemainingTTL(key) { + return this.#keyMap.has(key) ? Infinity : 0; + } + #initializeTTLTracking() { + const ttls = new ZeroArray(this.#max); + const starts = new ZeroArray(this.#max); + this.#ttls = ttls; + this.#starts = starts; + const purgeTimers = this.ttlAutopurge ? + new Array(this.#max) + : undefined; + this.#autopurgeTimers = purgeTimers; + this.#setItemTTL = (index, ttl, start = this.#perf.now()) => { + starts[index] = ttl !== 0 ? start : 0; + ttls[index] = ttl; + // clear out the purge timer if we're setting TTL to 0, and + // previously had a ttl purge timer running, so it doesn't + // fire unnecessarily. + if (purgeTimers?.[index]) { + clearTimeout(purgeTimers[index]); + purgeTimers[index] = undefined; + } + if (ttl !== 0 && purgeTimers) { + const t = setTimeout(() => { + if (this.#isStale(index)) { + this.#delete(this.#keyList[index], 'expire'); + } + }, ttl + 1); + // unref() not supported on all platforms + /* c8 ignore start */ + if (t.unref) { + t.unref(); + } + /* c8 ignore stop */ + purgeTimers[index] = t; + } + }; + this.#updateItemAge = index => { + starts[index] = ttls[index] !== 0 ? this.#perf.now() : 0; + }; + this.#statusTTL = (status, index) => { + if (ttls[index]) { + const ttl = ttls[index]; + const start = starts[index]; + /* c8 ignore next */ + if (!ttl || !start) + return; + status.ttl = ttl; + status.start = start; + status.now = cachedNow || getNow(); + const age = status.now - start; + status.remainingTTL = ttl - age; + } + }; + // debounce calls to perf.now() to 1s so we're not hitting + // that costly call repeatedly. + let cachedNow = 0; + const getNow = () => { + const n = this.#perf.now(); + if (this.ttlResolution > 0) { + cachedNow = n; + const t = setTimeout(() => (cachedNow = 0), this.ttlResolution); + // not available on all platforms + /* c8 ignore start */ + if (t.unref) { + t.unref(); + } + /* c8 ignore stop */ + } + return n; + }; + this.getRemainingTTL = key => { + const index = this.#keyMap.get(key); + if (index === undefined) { + return 0; + } + const ttl = ttls[index]; + const start = starts[index]; + if (!ttl || !start) { + return Infinity; + } + const age = (cachedNow || getNow()) - start; + return ttl - age; + }; + this.#isStale = index => { + const s = starts[index]; + const t = ttls[index]; + return !!t && !!s && (cachedNow || getNow()) - s > t; + }; + } + // conditionally set private methods related to TTL + #updateItemAge = () => { }; + #statusTTL = () => { }; + #setItemTTL = () => { }; + /* c8 ignore stop */ + #isStale = () => false; + #initializeSizeTracking() { + const sizes = new ZeroArray(this.#max); + this.#calculatedSize = 0; + this.#sizes = sizes; + this.#removeItemSize = index => { + this.#calculatedSize -= sizes[index]; + sizes[index] = 0; + }; + this.#requireSize = (k, v, size, sizeCalculation) => { + // provisionally accept background fetches. + // actual value size will be checked when they return. + if (this.#isBackgroundFetch(v)) { + return 0; + } + if (!isPosInt(size)) { + if (sizeCalculation) { + if (typeof sizeCalculation !== 'function') { + throw new TypeError('sizeCalculation must be a function'); + } + size = sizeCalculation(v, k); + if (!isPosInt(size)) { + 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 size; + }; + this.#addItemSize = (index, size, status) => { + sizes[index] = size; + if (this.#maxSize) { + const maxSize = this.#maxSize - sizes[index]; + while (this.#calculatedSize > maxSize) { + this.#evict(true); + } + } + this.#calculatedSize += sizes[index]; + if (status) { + status.entrySize = size; + status.totalCalculatedSize = this.#calculatedSize; + } + }; + } + #removeItemSize = _i => { }; + #addItemSize = (_i, _s, _st) => { }; + #requireSize = (_k, _v, size, sizeCalculation) => { + if (size || sizeCalculation) { + throw new TypeError('cannot set size without setting maxSize or maxEntrySize on cache'); + } + return 0; + }; + *#indexes({ allowStale = this.allowStale } = {}) { + if (this.#size) { + for (let i = this.#tail; true;) { + if (!this.#isValidIndex(i)) { + break; + } + if (allowStale || !this.#isStale(i)) { + yield i; + } + if (i === this.#head) { + break; + } + else { + i = this.#prev[i]; + } + } + } + } + *#rindexes({ allowStale = this.allowStale } = {}) { + if (this.#size) { + for (let i = this.#head; true;) { + if (!this.#isValidIndex(i)) { + break; + } + if (allowStale || !this.#isStale(i)) { + yield i; + } + if (i === this.#tail) { + break; + } + else { + i = this.#next[i]; + } + } + } + } + #isValidIndex(index) { + return (index !== undefined && + this.#keyMap.get(this.#keyList[index]) === index); + } + /** + * Return a generator yielding `[key, value]` pairs, + * in order from most recently used to least recently used. + */ + *entries() { + for (const i of this.#indexes()) { + if (this.#valList[i] !== undefined && + this.#keyList[i] !== undefined && + !this.#isBackgroundFetch(this.#valList[i])) { + yield [this.#keyList[i], this.#valList[i]]; + } + } + } + /** + * Inverse order version of {@link LRUCache.entries} + * + * Return a generator yielding `[key, value]` pairs, + * in order from least recently used to most recently used. + */ + *rentries() { + for (const i of this.#rindexes()) { + if (this.#valList[i] !== undefined && + this.#keyList[i] !== undefined && + !this.#isBackgroundFetch(this.#valList[i])) { + yield [this.#keyList[i], this.#valList[i]]; + } + } + } + /** + * Return a generator yielding the keys in the cache, + * in order from most recently used to least recently used. + */ + *keys() { + for (const i of this.#indexes()) { + const k = this.#keyList[i]; + if (k !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield k; + } + } + } + /** + * Inverse order version of {@link LRUCache.keys} + * + * Return a generator yielding the keys in the cache, + * in order from least recently used to most recently used. + */ + *rkeys() { + for (const i of this.#rindexes()) { + const k = this.#keyList[i]; + if (k !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield k; + } + } + } + /** + * Return a generator yielding the values in the cache, + * in order from most recently used to least recently used. + */ + *values() { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + if (v !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield this.#valList[i]; + } + } + } + /** + * Inverse order version of {@link LRUCache.values} + * + * Return a generator yielding the values in the cache, + * in order from least recently used to most recently used. + */ + *rvalues() { + for (const i of this.#rindexes()) { + const v = this.#valList[i]; + if (v !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield this.#valList[i]; + } + } + } + /** + * Iterating over the cache itself yields the same results as + * {@link LRUCache.entries} + */ + [Symbol.iterator]() { + return this.entries(); + } + /** + * A String value that is used in the creation of the default string + * description of an object. Called by the built-in method + * `Object.prototype.toString`. + */ + [Symbol.toStringTag] = 'LRUCache'; + /** + * Find a value for which the supplied fn method returns a truthy value, + * similar to `Array.find()`. fn is called as `fn(value, key, cache)`. + */ + find(fn, getOptions = {}) { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + continue; + if (fn(value, this.#keyList[i], this)) { + return this.get(this.#keyList[i], getOptions); + } + } + } + /** + * Call the supplied function on each item in the cache, in order from most + * recently used to least recently used. + * + * `fn` is called as `fn(value, key, cache)`. + * + * If `thisp` is provided, function will be called in the `this`-context of + * the provided object, or the cache if no `thisp` object is provided. + * + * Does not update age or recenty of use, or iterate over stale values. + */ + forEach(fn, thisp = this) { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + continue; + fn.call(thisp, value, this.#keyList[i], this); + } + } + /** + * The same as {@link LRUCache.forEach} but items are iterated over in + * reverse order. (ie, less recently used items are iterated over first.) + */ + rforEach(fn, thisp = this) { + for (const i of this.#rindexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + continue; + fn.call(thisp, value, this.#keyList[i], this); + } + } + /** + * Delete any stale entries. Returns true if anything was removed, + * false otherwise. + */ + purgeStale() { + let deleted = false; + for (const i of this.#rindexes({ allowStale: true })) { + if (this.#isStale(i)) { + this.#delete(this.#keyList[i], 'expire'); + deleted = true; + } + } + return deleted; + } + /** + * Get the extended info about a given entry, to get its value, size, and + * TTL info simultaneously. Returns `undefined` if the key is not present. + * + * Unlike {@link LRUCache#dump}, which is designed to be portable and survive + * serialization, the `start` value is always the current timestamp, and the + * `ttl` is a calculated remaining time to live (negative if expired). + * + * Always returns stale values, if their info is found in the cache, so be + * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl}) + * if relevant. + */ + info(key) { + const i = this.#keyMap.get(key); + if (i === undefined) + return undefined; + const v = this.#valList[i]; + /* c8 ignore start - this isn't tested for the info function, + * but it's the same logic as found in other places. */ + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + return undefined; + /* c8 ignore end */ + const entry = { value }; + if (this.#ttls && this.#starts) { + const ttl = this.#ttls[i]; + const start = this.#starts[i]; + if (ttl && start) { + const remain = ttl - (this.#perf.now() - start); + entry.ttl = remain; + entry.start = Date.now(); + } + } + if (this.#sizes) { + entry.size = this.#sizes[i]; + } + return entry; + } + /** + * Return an array of [key, {@link LRUCache.Entry}] tuples which can be + * passed to {@link LRUCache#load}. + * + * The `start` fields are calculated relative to a portable `Date.now()` + * timestamp, even if `performance.now()` is available. + * + * Stale entries are always included in the `dump`, even if + * {@link LRUCache.OptionsBase.allowStale} is false. + * + * Note: this returns an actual array, not a generator, so it can be more + * easily passed around. + */ + dump() { + const arr = []; + for (const i of this.#indexes({ allowStale: true })) { + const key = this.#keyList[i]; + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined || key === undefined) + continue; + const entry = { value }; + if (this.#ttls && this.#starts) { + entry.ttl = this.#ttls[i]; + // always dump the start relative to a portable timestamp + // it's ok for this to be a bit slow, it's a rare operation. + const age = this.#perf.now() - this.#starts[i]; + entry.start = Math.floor(Date.now() - age); + } + if (this.#sizes) { + entry.size = this.#sizes[i]; + } + arr.unshift([key, entry]); + } + return arr; + } + /** + * Reset the cache and load in the items in entries in the order listed. + * + * The shape of the resulting cache may be different if the same options are + * not used in both caches. + * + * The `start` fields are assumed to be calculated relative to a portable + * `Date.now()` timestamp, even if `performance.now()` is available. + */ + load(arr) { + this.clear(); + for (const [key, entry] of arr) { + if (entry.start) { + // entry.start is a portable timestamp, but we may be using + // node's performance.now(), so calculate the offset, so that + // we get the intended remaining TTL, no matter how long it's + // been on ice. + // + // it's ok for this to be a bit slow, it's a rare operation. + const age = Date.now() - entry.start; + entry.start = this.#perf.now() - age; + } + this.set(key, entry.value, entry); + } + } + /** + * Add a value to the cache. + * + * Note: if `undefined` is specified as a value, this is an alias for + * {@link LRUCache#delete} + * + * Fields on the {@link LRUCache.SetOptions} options param will override + * their corresponding values in the constructor options for the scope + * of this single `set()` operation. + * + * If `start` is provided, then that will set the effective start + * time for the TTL calculation. Note that this must be a previous + * value of `performance.now()` if supported, or a previous value of + * `Date.now()` if not. + * + * Options object may also include `size`, which will prevent + * calling the `sizeCalculation` function and just use the specified + * number if it is a positive integer, and `noDisposeOnSet` which + * will prevent calling a `dispose` function in the case of + * overwrites. + * + * If the `size` (or return value of `sizeCalculation`) for a given + * entry is greater than `maxEntrySize`, then the item will not be + * added to the cache. + * + * Will update the recency of the entry. + * + * If the value is `undefined`, then this is an alias for + * `cache.delete(key)`. `undefined` is never stored in the cache. + */ + set(k, v, setOptions = {}) { + if (v === undefined) { + this.delete(k); + return this; + } + const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status, } = setOptions; + let { noUpdateTTL = this.noUpdateTTL } = setOptions; + const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation); + // if the item doesn't fit, don't do anything + // NB: maxEntrySize set to maxSize by default + if (this.maxEntrySize && size > this.maxEntrySize) { + if (status) { + status.set = 'miss'; + status.maxEntrySizeExceeded = true; + } + // have to delete, in case something is there already. + this.#delete(k, 'set'); + return this; + } + let index = this.#size === 0 ? undefined : this.#keyMap.get(k); + if (index === undefined) { + // addition + index = (this.#size === 0 ? this.#tail + : this.#free.length !== 0 ? this.#free.pop() + : this.#size === this.#max ? this.#evict(false) + : this.#size); + this.#keyList[index] = k; + this.#valList[index] = v; + this.#keyMap.set(k, index); + this.#next[this.#tail] = index; + this.#prev[index] = this.#tail; + this.#tail = index; + this.#size++; + this.#addItemSize(index, size, status); + if (status) + status.set = 'add'; + noUpdateTTL = false; + if (this.#hasOnInsert) { + this.#onInsert?.(v, k, 'add'); + } + } + else { + // update + this.#moveToTail(index); + const oldVal = this.#valList[index]; + if (v !== oldVal) { + if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) { + oldVal.__abortController.abort(new Error('replaced')); + const { __staleWhileFetching: s } = oldVal; + if (s !== undefined && !noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(s, k, 'set'); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([s, k, 'set']); + } + } + } + else if (!noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(oldVal, k, 'set'); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([oldVal, k, 'set']); + } + } + this.#removeItemSize(index); + this.#addItemSize(index, size, status); + this.#valList[index] = v; + if (status) { + status.set = 'replace'; + const oldValue = oldVal && this.#isBackgroundFetch(oldVal) ? + oldVal.__staleWhileFetching + : oldVal; + if (oldValue !== undefined) + status.oldValue = oldValue; + } + } + else if (status) { + status.set = 'update'; + } + if (this.#hasOnInsert) { + this.onInsert?.(v, k, v === oldVal ? 'update' : 'replace'); + } + } + if (ttl !== 0 && !this.#ttls) { + this.#initializeTTLTracking(); + } + if (this.#ttls) { + if (!noUpdateTTL) { + this.#setItemTTL(index, ttl, start); + } + if (status) + this.#statusTTL(status, index); + } + if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + return this; + } + /** + * Evict the least recently used item, returning its value or + * `undefined` if cache is empty. + */ + pop() { + try { + while (this.#size) { + const val = this.#valList[this.#head]; + this.#evict(true); + if (this.#isBackgroundFetch(val)) { + if (val.__staleWhileFetching) { + return val.__staleWhileFetching; + } + } + else if (val !== undefined) { + return val; + } + } + } + finally { + if (this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + } + } + #evict(free) { + const head = this.#head; + const k = this.#keyList[head]; + const v = this.#valList[head]; + if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error('evicted')); + } + else if (this.#hasDispose || this.#hasDisposeAfter) { + if (this.#hasDispose) { + this.#dispose?.(v, k, 'evict'); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, 'evict']); + } + } + this.#removeItemSize(head); + if (this.#autopurgeTimers?.[head]) { + clearTimeout(this.#autopurgeTimers[head]); + this.#autopurgeTimers[head] = undefined; + } + // if we aren't about to use the index, then null these out + if (free) { + this.#keyList[head] = undefined; + this.#valList[head] = undefined; + this.#free.push(head); + } + if (this.#size === 1) { + this.#head = this.#tail = 0; + this.#free.length = 0; + } + else { + this.#head = this.#next[head]; + } + this.#keyMap.delete(k); + this.#size--; + return head; + } + /** + * Check if a key is in the cache, without updating the recency of use. + * Will return false if the item is stale, even though it is technically + * in the cache. + * + * Check if a key is in the cache, without updating the recency of + * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set + * to `true` in either the options or the constructor. + * + * Will return `false` if the item is stale, even though it is technically in + * the cache. The difference can be determined (if it matters) by using a + * `status` argument, and inspecting the `has` field. + * + * Will not update item age unless + * {@link LRUCache.OptionsBase.updateAgeOnHas} is set. + */ + has(k, hasOptions = {}) { + const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions; + const index = this.#keyMap.get(k); + if (index !== undefined) { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v) && + v.__staleWhileFetching === undefined) { + return false; + } + if (!this.#isStale(index)) { + if (updateAgeOnHas) { + this.#updateItemAge(index); + } + if (status) { + status.has = 'hit'; + this.#statusTTL(status, index); + } + return true; + } + else if (status) { + status.has = 'stale'; + this.#statusTTL(status, index); + } + } + else if (status) { + status.has = 'miss'; + } + return false; + } + /** + * Like {@link LRUCache#get} but doesn't update recency or delete stale + * items. + * + * Returns `undefined` if the item is stale, unless + * {@link LRUCache.OptionsBase.allowStale} is set. + */ + peek(k, peekOptions = {}) { + const { allowStale = this.allowStale } = peekOptions; + const index = this.#keyMap.get(k); + if (index === undefined || (!allowStale && this.#isStale(index))) { + return; + } + const v = this.#valList[index]; + // either stale and allowed, or forcing a refresh of non-stale value + return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + } + #backgroundFetch(k, index, options, context) { + const v = index === undefined ? undefined : this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + return v; + } + const ac = new AC(); + const { signal } = options; + // when/if our AC signals, then stop listening to theirs. + signal?.addEventListener('abort', () => ac.abort(signal.reason), { + signal: ac.signal, + }); + const fetchOpts = { + signal: ac.signal, + options, + context, + }; + const cb = (v, updateCache = false) => { + const { aborted } = ac.signal; + const ignoreAbort = options.ignoreFetchAbort && v !== undefined; + const proceed = options.ignoreFetchAbort || + !!(options.allowStaleOnFetchAbort && v !== undefined); + if (options.status) { + if (aborted && !updateCache) { + options.status.fetchAborted = true; + options.status.fetchError = ac.signal.reason; + if (ignoreAbort) + options.status.fetchAbortIgnored = true; + } + else { + options.status.fetchResolved = true; + } + } + if (aborted && !ignoreAbort && !updateCache) { + return fetchFail(ac.signal.reason, proceed); + } + // either we didn't abort, and are still here, or we did, and ignored + const bf = p; + // if nothing else has been written there but we're set to update the + // cache and ignore the abort, or if it's still pending on this specific + // background request, then write it to the cache. + const vl = this.#valList[index]; + if (vl === p || (ignoreAbort && updateCache && vl === undefined)) { + if (v === undefined) { + if (bf.__staleWhileFetching !== undefined) { + this.#valList[index] = bf.__staleWhileFetching; + } + else { + this.#delete(k, 'fetch'); + } + } + else { + if (options.status) + options.status.fetchUpdated = true; + this.set(k, v, fetchOpts.options); + } + } + return v; + }; + const eb = (er) => { + if (options.status) { + options.status.fetchRejected = true; + options.status.fetchError = er; + } + // do not pass go, do not collect $200 + return fetchFail(er, false); + }; + const fetchFail = (er, proceed) => { + const { aborted } = ac.signal; + const allowStaleAborted = aborted && options.allowStaleOnFetchAbort; + const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection; + const noDelete = allowStale || options.noDeleteOnFetchRejection; + const bf = p; + if (this.#valList[index] === p) { + // if we allow stale on fetch rejections, then we need to ensure that + // the stale value is not removed from the cache when the fetch fails. + const del = !noDelete || + !proceed && bf.__staleWhileFetching === undefined; + if (del) { + this.#delete(k, 'fetch'); + } + else if (!allowStaleAborted) { + // still replace the *promise* with the stale value, + // since we are done with the promise at this point. + // leave it untouched if we're still waiting for an + // aborted background fetch that hasn't yet returned. + this.#valList[index] = bf.__staleWhileFetching; + } + } + if (allowStale) { + if (options.status && bf.__staleWhileFetching !== undefined) { + options.status.returnedStale = true; + } + return bf.__staleWhileFetching; + } + else if (bf.__returned === bf) { + throw er; + } + }; + const pcall = (res, rej) => { + const fmp = this.#fetchMethod?.(k, v, fetchOpts); + if (fmp && fmp instanceof Promise) { + fmp.then(v => res(v === undefined ? undefined : v), rej); + } + // ignored, we go until we finish, regardless. + // defer check until we are actually aborting, + // so fetchMethod can override. + ac.signal.addEventListener('abort', () => { + if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) { + res(undefined); + // when it eventually resolves, update the cache. + if (options.allowStaleOnFetchAbort) { + res = v => cb(v, true); + } + } + }); + }; + if (options.status) + options.status.fetchDispatched = true; + const p = new Promise(pcall).then(cb, eb); + const bf = Object.assign(p, { + __abortController: ac, + __staleWhileFetching: v, + __returned: undefined, + }); + if (index === undefined) { + // internal, don't expose status. + this.set(k, bf, { ...fetchOpts.options, status: undefined }); + index = this.#keyMap.get(k); + } + else { + this.#valList[index] = bf; + } + return bf; + } + #isBackgroundFetch(p) { + if (!this.#hasFetchMethod) + return false; + const b = p; + return (!!b && + b instanceof Promise && + b.hasOwnProperty('__staleWhileFetching') && + b.__abortController instanceof AC); + } + async fetch(k, fetchOptions = {}) { + const { + // get options + allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, + // set options + ttl = this.ttl, noDisposeOnSet = this.noDisposeOnSet, size = 0, sizeCalculation = this.sizeCalculation, noUpdateTTL = this.noUpdateTTL, + // fetch exclusive options + noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, ignoreFetchAbort = this.ignoreFetchAbort, allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, context, forceRefresh = false, status, signal, } = fetchOptions; + if (!this.#hasFetchMethod) { + if (status) + status.fetch = 'get'; + return this.get(k, { + allowStale, + updateAgeOnGet, + noDeleteOnStaleGet, + status, + }); + } + const options = { + allowStale, + updateAgeOnGet, + noDeleteOnStaleGet, + ttl, + noDisposeOnSet, + size, + sizeCalculation, + noUpdateTTL, + noDeleteOnFetchRejection, + allowStaleOnFetchRejection, + allowStaleOnFetchAbort, + ignoreFetchAbort, + status, + signal, + }; + let index = this.#keyMap.get(k); + if (index === undefined) { + if (status) + status.fetch = 'miss'; + const p = this.#backgroundFetch(k, index, options, context); + return (p.__returned = p); + } + else { + // in cache, maybe already fetching + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + const stale = allowStale && v.__staleWhileFetching !== undefined; + if (status) { + status.fetch = 'inflight'; + if (stale) + status.returnedStale = true; + } + return stale ? v.__staleWhileFetching : (v.__returned = v); + } + // if we force a refresh, that means do NOT serve the cached value, + // unless we are already in the process of refreshing the cache. + const isStale = this.#isStale(index); + if (!forceRefresh && !isStale) { + if (status) + status.fetch = 'hit'; + this.#moveToTail(index); + if (updateAgeOnGet) { + this.#updateItemAge(index); + } + if (status) + this.#statusTTL(status, index); + return v; + } + // ok, it is stale or a forced refresh, and not already fetching. + // refresh the cache. + const p = this.#backgroundFetch(k, index, options, context); + const hasStale = p.__staleWhileFetching !== undefined; + const staleVal = hasStale && allowStale; + if (status) { + status.fetch = isStale ? 'stale' : 'refresh'; + if (staleVal && isStale) + status.returnedStale = true; + } + return staleVal ? p.__staleWhileFetching : (p.__returned = p); + } + } + async forceFetch(k, fetchOptions = {}) { + const v = await this.fetch(k, fetchOptions); + if (v === undefined) + throw new Error('fetch() returned undefined'); + return v; + } + memo(k, memoOptions = {}) { + const memoMethod = this.#memoMethod; + if (!memoMethod) { + throw new Error('no memoMethod provided to constructor'); + } + const { context, forceRefresh, ...options } = memoOptions; + const v = this.get(k, options); + if (!forceRefresh && v !== undefined) + return v; + const vv = memoMethod(k, v, { + options, + context, + }); + this.set(k, vv, options); + return vv; + } + /** + * Return a value from the cache. Will update the recency of the cache + * entry found. + * + * If the key is not found, get() will return `undefined`. + */ + get(k, getOptions = {}) { + const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status, } = getOptions; + const index = this.#keyMap.get(k); + if (index !== undefined) { + const value = this.#valList[index]; + const fetching = this.#isBackgroundFetch(value); + if (status) + this.#statusTTL(status, index); + if (this.#isStale(index)) { + if (status) + status.get = 'stale'; + // delete only if not an in-flight background fetch + if (!fetching) { + if (!noDeleteOnStaleGet) { + this.#delete(k, 'expire'); + } + if (status && allowStale) + status.returnedStale = true; + return allowStale ? value : undefined; + } + else { + if (status && + allowStale && + value.__staleWhileFetching !== undefined) { + status.returnedStale = true; + } + return allowStale ? value.__staleWhileFetching : undefined; + } + } + else { + if (status) + status.get = 'hit'; + // if we're currently fetching it, we don't actually have it yet + // it's not stale, which means this isn't a staleWhileRefetching. + // If it's not stale, and fetching, AND has a __staleWhileFetching + // value, then that means the user fetched with {forceRefresh:true}, + // so it's safe to return that value. + if (fetching) { + return value.__staleWhileFetching; + } + this.#moveToTail(index); + if (updateAgeOnGet) { + this.#updateItemAge(index); + } + return value; + } + } + else if (status) { + status.get = 'miss'; + } + } + #connect(p, n) { + this.#prev[n] = p; + this.#next[p] = n; + } + #moveToTail(index) { + // if tail already, nothing to do + // if head, move head to next[index] + // else + // move next[prev[index]] to next[index] (head has no prev) + // move prev[next[index]] to prev[index] + // prev[index] = tail + // next[tail] = index + // tail = index + if (index !== this.#tail) { + if (index === this.#head) { + this.#head = this.#next[index]; + } + else { + this.#connect(this.#prev[index], this.#next[index]); + } + this.#connect(this.#tail, index); + this.#tail = index; + } + } + /** + * Deletes a key out of the cache. + * + * Returns true if the key was deleted, false otherwise. + */ + delete(k) { + return this.#delete(k, 'delete'); + } + #delete(k, reason) { + let deleted = false; + if (this.#size !== 0) { + const index = this.#keyMap.get(k); + if (index !== undefined) { + if (this.#autopurgeTimers?.[index]) { + clearTimeout(this.#autopurgeTimers?.[index]); + this.#autopurgeTimers[index] = undefined; + } + deleted = true; + if (this.#size === 1) { + this.#clear(reason); + } + else { + this.#removeItemSize(index); + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error('deleted')); + } + else if (this.#hasDispose || this.#hasDisposeAfter) { + if (this.#hasDispose) { + this.#dispose?.(v, k, reason); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, reason]); + } + } + this.#keyMap.delete(k); + this.#keyList[index] = undefined; + this.#valList[index] = undefined; + if (index === this.#tail) { + this.#tail = this.#prev[index]; + } + else if (index === this.#head) { + this.#head = this.#next[index]; + } + else { + const pi = this.#prev[index]; + this.#next[pi] = this.#next[index]; + const ni = this.#next[index]; + this.#prev[ni] = this.#prev[index]; + } + this.#size--; + this.#free.push(index); + } + } + } + if (this.#hasDisposeAfter && this.#disposed?.length) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + return deleted; + } + /** + * Clear the cache entirely, throwing away all values. + */ + clear() { + return this.#clear('delete'); + } + #clear(reason) { + for (const index of this.#rindexes({ allowStale: true })) { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error('deleted')); + } + else { + const k = this.#keyList[index]; + if (this.#hasDispose) { + this.#dispose?.(v, k, reason); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, reason]); + } + } + } + this.#keyMap.clear(); + this.#valList.fill(undefined); + this.#keyList.fill(undefined); + if (this.#ttls && this.#starts) { + this.#ttls.fill(0); + this.#starts.fill(0); + for (const t of this.#autopurgeTimers ?? []) { + if (t !== undefined) + clearTimeout(t); + } + this.#autopurgeTimers?.fill(undefined); + } + if (this.#sizes) { + this.#sizes.fill(0); + } + this.#head = 0; + this.#tail = 0; + this.#free.length = 0; + this.#calculatedSize = 0; + this.#size = 0; + if (this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + } +} +exports.LRUCache = LRUCache; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/lru-cache/dist/commonjs/index.min.js b/node_modules/lru-cache/dist/commonjs/index.min.js new file mode 100644 index 0000000000000..2be540a202670 --- /dev/null +++ b/node_modules/lru-cache/dist/commonjs/index.min.js @@ -0,0 +1,2 @@ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.LRUCache=void 0;var x=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,U=new Set,R=typeof process=="object"&&process?process:{},I=(a,t,e,i)=>{typeof R.emitWarning=="function"?R.emitWarning(a,t,e,i):console.error(`[${e}] ${t}: ${a}`)},C=globalThis.AbortController,L=globalThis.AbortSignal;if(typeof C>"u"){L=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(i,s){this._onabort.push(s)}},C=class{constructor(){t()}signal=new L;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 a=R.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{a&&(a=!1,I("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 G=a=>!U.has(a),H=Symbol("type"),y=a=>a&&a===Math.floor(a)&&a>0&&isFinite(a),M=a=>y(a)?a<=Math.pow(2,8)?Uint8Array:a<=Math.pow(2,16)?Uint16Array:a<=Math.pow(2,32)?Uint32Array:a<=Number.MAX_SAFE_INTEGER?z:null:null,z=class extends Array{constructor(t){super(t),this.fill(0)}},W=class a{heap;length;static#o=!1;static create(t){let e=M(t);if(!e)return[];a.#o=!0;let i=new a(t,e);return a.#o=!1,i}constructor(t,e){if(!a.#o)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]}},D=class a{#o;#c;#w;#C;#S;#L;#U;#m;get perf(){return this.#m}ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#n;#_;#s;#i;#t;#a;#u;#l;#h;#b;#r;#y;#A;#d;#g;#T;#v;#f;#I;static unsafeExposeInternals(t){return{starts:t.#A,ttls:t.#d,autopurgeTimers:t.#g,sizes:t.#y,keyMap:t.#s,keyList:t.#i,valList:t.#t,next:t.#a,prev:t.#u,get head(){return t.#l},get tail(){return t.#h},free:t.#b,isBackgroundFetch:e=>t.#e(e),backgroundFetch:(e,i,s,h)=>t.#G(e,i,s,h),moveToTail:e=>t.#D(e),indexes:e=>t.#F(e),rindexes:e=>t.#O(e),isStale:e=>t.#p(e)}}get max(){return this.#o}get maxSize(){return this.#c}get calculatedSize(){return this.#_}get size(){return this.#n}get fetchMethod(){return this.#L}get memoMethod(){return this.#U}get dispose(){return this.#w}get onInsert(){return this.#C}get disposeAfter(){return this.#S}constructor(t){let{max:e=0,ttl:i,ttlResolution:s=1,ttlAutopurge:h,updateAgeOnGet:n,updateAgeOnHas:o,allowStale:r,dispose:f,onInsert:m,disposeAfter:c,noDisposeOnSet:d,noUpdateTTL:g,maxSize:A=0,maxEntrySize:p=0,sizeCalculation:_,fetchMethod:l,memoMethod:w,noDeleteOnFetchRejection:b,noDeleteOnStaleGet:S,allowStaleOnFetchRejection:u,allowStaleOnFetchAbort:T,ignoreFetchAbort:F,perf:v}=t;if(v!==void 0&&typeof v?.now!="function")throw new TypeError("perf option must have a now() method if specified");if(this.#m=v??x,e!==0&&!y(e))throw new TypeError("max option must be a nonnegative integer");let O=e?M(e):Array;if(!O)throw new Error("invalid max value: "+e);if(this.#o=e,this.#c=A,this.maxEntrySize=p||this.#c,this.sizeCalculation=_,this.sizeCalculation){if(!this.#c&&!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(w!==void 0&&typeof w!="function")throw new TypeError("memoMethod must be a function if defined");if(this.#U=w,l!==void 0&&typeof l!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#L=l,this.#v=!!l,this.#s=new Map,this.#i=new Array(e).fill(void 0),this.#t=new Array(e).fill(void 0),this.#a=new O(e),this.#u=new O(e),this.#l=0,this.#h=0,this.#b=W.create(e),this.#n=0,this.#_=0,typeof f=="function"&&(this.#w=f),typeof m=="function"&&(this.#C=m),typeof c=="function"?(this.#S=c,this.#r=[]):(this.#S=void 0,this.#r=void 0),this.#T=!!this.#w,this.#I=!!this.#C,this.#f=!!this.#S,this.noDisposeOnSet=!!d,this.noUpdateTTL=!!g,this.noDeleteOnFetchRejection=!!b,this.allowStaleOnFetchRejection=!!u,this.allowStaleOnFetchAbort=!!T,this.ignoreFetchAbort=!!F,this.maxEntrySize!==0){if(this.#c!==0&&!y(this.#c))throw new TypeError("maxSize must be a positive integer if specified");if(!y(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#B()}if(this.allowStale=!!r,this.noDeleteOnStaleGet=!!S,this.updateAgeOnGet=!!n,this.updateAgeOnHas=!!o,this.ttlResolution=y(s)||s===0?s:1,this.ttlAutopurge=!!h,this.ttl=i||0,this.ttl){if(!y(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#j()}if(this.#o===0&&this.ttl===0&&this.#c===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#o&&!this.#c){let E="LRU_CACHE_UNBOUNDED";G(E)&&(U.add(E),I("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",E,a))}}getRemainingTTL(t){return this.#s.has(t)?1/0:0}#j(){let t=new z(this.#o),e=new z(this.#o);this.#d=t,this.#A=e;let i=this.ttlAutopurge?new Array(this.#o):void 0;this.#g=i,this.#N=(n,o,r=this.#m.now())=>{if(e[n]=o!==0?r:0,t[n]=o,i?.[n]&&(clearTimeout(i[n]),i[n]=void 0),o!==0&&i){let f=setTimeout(()=>{this.#p(n)&&this.#E(this.#i[n],"expire")},o+1);f.unref&&f.unref(),i[n]=f}},this.#R=n=>{e[n]=t[n]!==0?this.#m.now():0},this.#z=(n,o)=>{if(t[o]){let r=t[o],f=e[o];if(!r||!f)return;n.ttl=r,n.start=f,n.now=s||h();let m=n.now-f;n.remainingTTL=r-m}};let s=0,h=()=>{let n=this.#m.now();if(this.ttlResolution>0){s=n;let o=setTimeout(()=>s=0,this.ttlResolution);o.unref&&o.unref()}return n};this.getRemainingTTL=n=>{let o=this.#s.get(n);if(o===void 0)return 0;let r=t[o],f=e[o];if(!r||!f)return 1/0;let m=(s||h())-f;return r-m},this.#p=n=>{let o=e[n],r=t[n];return!!r&&!!o&&(s||h())-o>r}}#R=()=>{};#z=()=>{};#N=()=>{};#p=()=>!1;#B(){let t=new z(this.#o);this.#_=0,this.#y=t,this.#W=e=>{this.#_-=t[e],t[e]=0},this.#P=(e,i,s,h)=>{if(this.#e(i))return 0;if(!y(s))if(h){if(typeof h!="function")throw new TypeError("sizeCalculation must be a function");if(s=h(i,e),!y(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.#M=(e,i,s)=>{if(t[e]=i,this.#c){let h=this.#c-t[e];for(;this.#_>h;)this.#x(!0)}this.#_+=t[e],s&&(s.entrySize=i,s.totalCalculatedSize=this.#_)}}#W=t=>{};#M=(t,e,i)=>{};#P=(t,e,i,s)=>{if(i||s)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#F({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#h;!(!this.#H(e)||((t||!this.#p(e))&&(yield e),e===this.#l));)e=this.#u[e]}*#O({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#l;!(!this.#H(e)||((t||!this.#p(e))&&(yield e),e===this.#h));)e=this.#a[e]}#H(t){return t!==void 0&&this.#s.get(this.#i[t])===t}*entries(){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]])}*rentries(){for(let t of this.#O())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.#F()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*rkeys(){for(let t of this.#O()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*values(){for(let t of this.#F())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}*rvalues(){for(let t of this.#O())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.#F()){let s=this.#t[i],h=this.#e(s)?s.__staleWhileFetching:s;if(h!==void 0&&t(h,this.#i[i],this))return this.get(this.#i[i],e)}}forEach(t,e=this){for(let i of this.#F()){let s=this.#t[i],h=this.#e(s)?s.__staleWhileFetching:s;h!==void 0&&t.call(e,h,this.#i[i],this)}}rforEach(t,e=this){for(let i of this.#O()){let s=this.#t[i],h=this.#e(s)?s.__staleWhileFetching:s;h!==void 0&&t.call(e,h,this.#i[i],this)}}purgeStale(){let t=!1;for(let e of this.#O({allowStale:!0}))this.#p(e)&&(this.#E(this.#i[e],"expire"),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 h={value:s};if(this.#d&&this.#A){let n=this.#d[e],o=this.#A[e];if(n&&o){let r=n-(this.#m.now()-o);h.ttl=r,h.start=Date.now()}}return this.#y&&(h.size=this.#y[e]),h}dump(){let t=[];for(let e of this.#F({allowStale:!0})){let i=this.#i[e],s=this.#t[e],h=this.#e(s)?s.__staleWhileFetching:s;if(h===void 0||i===void 0)continue;let n={value:h};if(this.#d&&this.#A){n.ttl=this.#d[e];let o=this.#m.now()-this.#A[e];n.start=Math.floor(Date.now()-o)}this.#y&&(n.size=this.#y[e]),t.unshift([i,n])}return t}load(t){this.clear();for(let[e,i]of t){if(i.start){let s=Date.now()-i.start;i.start=this.#m.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:h,noDisposeOnSet:n=this.noDisposeOnSet,sizeCalculation:o=this.sizeCalculation,status:r}=i,{noUpdateTTL:f=this.noUpdateTTL}=i,m=this.#P(t,e,i.size||0,o);if(this.maxEntrySize&&m>this.maxEntrySize)return r&&(r.set="miss",r.maxEntrySizeExceeded=!0),this.#E(t,"set"),this;let c=this.#n===0?void 0:this.#s.get(t);if(c===void 0)c=this.#n===0?this.#h:this.#b.length!==0?this.#b.pop():this.#n===this.#o?this.#x(!1):this.#n,this.#i[c]=t,this.#t[c]=e,this.#s.set(t,c),this.#a[this.#h]=c,this.#u[c]=this.#h,this.#h=c,this.#n++,this.#M(c,m,r),r&&(r.set="add"),f=!1,this.#I&&this.#C?.(e,t,"add");else{this.#D(c);let d=this.#t[c];if(e!==d){if(this.#v&&this.#e(d)){d.__abortController.abort(new Error("replaced"));let{__staleWhileFetching:g}=d;g!==void 0&&!n&&(this.#T&&this.#w?.(g,t,"set"),this.#f&&this.#r?.push([g,t,"set"]))}else n||(this.#T&&this.#w?.(d,t,"set"),this.#f&&this.#r?.push([d,t,"set"]));if(this.#W(c),this.#M(c,m,r),this.#t[c]=e,r){r.set="replace";let g=d&&this.#e(d)?d.__staleWhileFetching:d;g!==void 0&&(r.oldValue=g)}}else r&&(r.set="update");this.#I&&this.onInsert?.(e,t,e===d?"update":"replace")}if(s!==0&&!this.#d&&this.#j(),this.#d&&(f||this.#N(c,s,h),r&&this.#z(r,c)),!n&&this.#f&&this.#r){let d=this.#r,g;for(;g=d?.shift();)this.#S?.(...g)}return this}pop(){try{for(;this.#n;){let t=this.#t[this.#l];if(this.#x(!0),this.#e(t)){if(t.__staleWhileFetching)return t.__staleWhileFetching}else if(t!==void 0)return t}}finally{if(this.#f&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#S?.(...e)}}}#x(t){let e=this.#l,i=this.#i[e],s=this.#t[e];return this.#v&&this.#e(s)?s.__abortController.abort(new Error("evicted")):(this.#T||this.#f)&&(this.#T&&this.#w?.(s,i,"evict"),this.#f&&this.#r?.push([s,i,"evict"])),this.#W(e),this.#g?.[e]&&(clearTimeout(this.#g[e]),this.#g[e]=void 0),t&&(this.#i[e]=void 0,this.#t[e]=void 0,this.#b.push(e)),this.#n===1?(this.#l=this.#h=0,this.#b.length=0):this.#l=this.#a[e],this.#s.delete(i),this.#n--,e}has(t,e={}){let{updateAgeOnHas:i=this.updateAgeOnHas,status:s}=e,h=this.#s.get(t);if(h!==void 0){let n=this.#t[h];if(this.#e(n)&&n.__staleWhileFetching===void 0)return!1;if(this.#p(h))s&&(s.has="stale",this.#z(s,h));else return i&&this.#R(h),s&&(s.has="hit",this.#z(s,h)),!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.#p(s))return;let h=this.#t[s];return this.#e(h)?h.__staleWhileFetching:h}#G(t,e,i,s){let h=e===void 0?void 0:this.#t[e];if(this.#e(h))return h;let n=new C,{signal:o}=i;o?.addEventListener("abort",()=>n.abort(o.reason),{signal:n.signal});let r={signal:n.signal,options:i,context:s},f=(p,_=!1)=>{let{aborted:l}=n.signal,w=i.ignoreFetchAbort&&p!==void 0,b=i.ignoreFetchAbort||!!(i.allowStaleOnFetchAbort&&p!==void 0);if(i.status&&(l&&!_?(i.status.fetchAborted=!0,i.status.fetchError=n.signal.reason,w&&(i.status.fetchAbortIgnored=!0)):i.status.fetchResolved=!0),l&&!w&&!_)return c(n.signal.reason,b);let S=g,u=this.#t[e];return(u===g||w&&_&&u===void 0)&&(p===void 0?S.__staleWhileFetching!==void 0?this.#t[e]=S.__staleWhileFetching:this.#E(t,"fetch"):(i.status&&(i.status.fetchUpdated=!0),this.set(t,p,r.options))),p},m=p=>(i.status&&(i.status.fetchRejected=!0,i.status.fetchError=p),c(p,!1)),c=(p,_)=>{let{aborted:l}=n.signal,w=l&&i.allowStaleOnFetchAbort,b=w||i.allowStaleOnFetchRejection,S=b||i.noDeleteOnFetchRejection,u=g;if(this.#t[e]===g&&(!S||!_&&u.__staleWhileFetching===void 0?this.#E(t,"fetch"):w||(this.#t[e]=u.__staleWhileFetching)),b)return i.status&&u.__staleWhileFetching!==void 0&&(i.status.returnedStale=!0),u.__staleWhileFetching;if(u.__returned===u)throw p},d=(p,_)=>{let l=this.#L?.(t,h,r);l&&l instanceof Promise&&l.then(w=>p(w===void 0?void 0:w),_),n.signal.addEventListener("abort",()=>{(!i.ignoreFetchAbort||i.allowStaleOnFetchAbort)&&(p(void 0),i.allowStaleOnFetchAbort&&(p=w=>f(w,!0)))})};i.status&&(i.status.fetchDispatched=!0);let g=new Promise(d).then(f,m),A=Object.assign(g,{__abortController:n,__staleWhileFetching:h,__returned:void 0});return e===void 0?(this.set(t,A,{...r.options,status:void 0}),e=this.#s.get(t)):this.#t[e]=A,A}#e(t){if(!this.#v)return!1;let e=t;return!!e&&e instanceof Promise&&e.hasOwnProperty("__staleWhileFetching")&&e.__abortController instanceof C}async fetch(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:h=this.noDeleteOnStaleGet,ttl:n=this.ttl,noDisposeOnSet:o=this.noDisposeOnSet,size:r=0,sizeCalculation:f=this.sizeCalculation,noUpdateTTL:m=this.noUpdateTTL,noDeleteOnFetchRejection:c=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:d=this.allowStaleOnFetchRejection,ignoreFetchAbort:g=this.ignoreFetchAbort,allowStaleOnFetchAbort:A=this.allowStaleOnFetchAbort,context:p,forceRefresh:_=!1,status:l,signal:w}=e;if(!this.#v)return l&&(l.fetch="get"),this.get(t,{allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:h,status:l});let b={allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:h,ttl:n,noDisposeOnSet:o,size:r,sizeCalculation:f,noUpdateTTL:m,noDeleteOnFetchRejection:c,allowStaleOnFetchRejection:d,allowStaleOnFetchAbort:A,ignoreFetchAbort:g,status:l,signal:w},S=this.#s.get(t);if(S===void 0){l&&(l.fetch="miss");let u=this.#G(t,S,b,p);return u.__returned=u}else{let u=this.#t[S];if(this.#e(u)){let E=i&&u.__staleWhileFetching!==void 0;return l&&(l.fetch="inflight",E&&(l.returnedStale=!0)),E?u.__staleWhileFetching:u.__returned=u}let T=this.#p(S);if(!_&&!T)return l&&(l.fetch="hit"),this.#D(S),s&&this.#R(S),l&&this.#z(l,S),u;let F=this.#G(t,S,b,p),O=F.__staleWhileFetching!==void 0&&i;return l&&(l.fetch=T?"stale":"refresh",O&&T&&(l.returnedStale=!0)),O?F.__staleWhileFetching:F.__returned=F}}async forceFetch(t,e={}){let i=await this.fetch(t,e);if(i===void 0)throw new Error("fetch() returned undefined");return i}memo(t,e={}){let i=this.#U;if(!i)throw new Error("no memoMethod provided to constructor");let{context:s,forceRefresh:h,...n}=e,o=this.get(t,n);if(!h&&o!==void 0)return o;let r=i(t,o,{options:n,context:s});return this.set(t,r,n),r}get(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:h=this.noDeleteOnStaleGet,status:n}=e,o=this.#s.get(t);if(o!==void 0){let r=this.#t[o],f=this.#e(r);return n&&this.#z(n,o),this.#p(o)?(n&&(n.get="stale"),f?(n&&i&&r.__staleWhileFetching!==void 0&&(n.returnedStale=!0),i?r.__staleWhileFetching:void 0):(h||this.#E(t,"expire"),n&&i&&(n.returnedStale=!0),i?r:void 0)):(n&&(n.get="hit"),f?r.__staleWhileFetching:(this.#D(o),s&&this.#R(o),r))}else n&&(n.get="miss")}#k(t,e){this.#u[e]=t,this.#a[t]=e}#D(t){t!==this.#h&&(t===this.#l?this.#l=this.#a[t]:this.#k(this.#u[t],this.#a[t]),this.#k(this.#h,t),this.#h=t)}delete(t){return this.#E(t,"delete")}#E(t,e){let i=!1;if(this.#n!==0){let s=this.#s.get(t);if(s!==void 0)if(this.#g?.[s]&&(clearTimeout(this.#g?.[s]),this.#g[s]=void 0),i=!0,this.#n===1)this.#V(e);else{this.#W(s);let h=this.#t[s];if(this.#e(h)?h.__abortController.abort(new Error("deleted")):(this.#T||this.#f)&&(this.#T&&this.#w?.(h,t,e),this.#f&&this.#r?.push([h,t,e])),this.#s.delete(t),this.#i[s]=void 0,this.#t[s]=void 0,s===this.#h)this.#h=this.#u[s];else if(s===this.#l)this.#l=this.#a[s];else{let n=this.#u[s];this.#a[n]=this.#a[s];let o=this.#a[s];this.#u[o]=this.#u[s]}this.#n--,this.#b.push(s)}}if(this.#f&&this.#r?.length){let s=this.#r,h;for(;h=s?.shift();)this.#S?.(...h)}return i}clear(){return this.#V("delete")}#V(t){for(let e of this.#O({allowStale:!0})){let i=this.#t[e];if(this.#e(i))i.__abortController.abort(new Error("deleted"));else{let s=this.#i[e];this.#T&&this.#w?.(i,s,t),this.#f&&this.#r?.push([i,s,t])}}if(this.#s.clear(),this.#t.fill(void 0),this.#i.fill(void 0),this.#d&&this.#A){this.#d.fill(0),this.#A.fill(0);for(let e of this.#g??[])e!==void 0&&clearTimeout(e);this.#g?.fill(void 0)}if(this.#y&&this.#y.fill(0),this.#l=0,this.#h=0,this.#b.length=0,this.#_=0,this.#n=0,this.#f&&this.#r){let e=this.#r,i;for(;i=e?.shift();)this.#S?.(...i)}}};exports.LRUCache=D; +//# sourceMappingURL=index.min.js.map diff --git a/node_modules/lru-cache/dist/commonjs/package.json b/node_modules/lru-cache/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/lru-cache/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/lru-cache/dist/esm/index.js b/node_modules/lru-cache/dist/esm/index.js new file mode 100644 index 0000000000000..fa0b58cf58058 --- /dev/null +++ b/node_modules/lru-cache/dist/esm/index.js @@ -0,0 +1,1585 @@ +/** + * @module LRUCache + */ +const defaultPerf = (typeof performance === 'object' && + performance && + typeof performance.now === 'function') ? + performance + : Date; +const warned = new Set(); +/* c8 ignore start */ +const PROCESS = (typeof process === 'object' && !!process ? + process + : {}); +/* c8 ignore start */ +const emitWarning = (msg, type, code, fn) => { + typeof PROCESS.emitWarning === 'function' ? + PROCESS.emitWarning(msg, type, code, fn) + : console.error(`[${code}] ${type}: ${msg}`); +}; +let AC = globalThis.AbortController; +let AS = globalThis.AbortSignal; +/* c8 ignore start */ +if (typeof AC === 'undefined') { + //@ts-ignore + AS = class AbortSignal { + onabort; + _onabort = []; + reason; + aborted = false; + addEventListener(_, fn) { + this._onabort.push(fn); + } + }; + //@ts-ignore + AC = class AbortController { + constructor() { + warnACPolyfill(); + } + signal = new AS(); + abort(reason) { + if (this.signal.aborted) + return; + //@ts-ignore + this.signal.reason = reason; + //@ts-ignore + this.signal.aborted = true; + //@ts-ignore + for (const fn of this.signal._onabort) { + fn(reason); + } + this.signal.onabort?.(reason); + } + }; + let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1'; + const warnACPolyfill = () => { + if (!printACPolyfillWarning) + return; + printACPolyfillWarning = false; + emitWarning('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', warnACPolyfill); + }; +} +/* c8 ignore stop */ +const shouldWarn = (code) => !warned.has(code); +const TYPE = Symbol('type'); +const isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n); +/* c8 ignore start */ +// This is a little bit ridiculous, tbh. +// The maximum array length is 2^32-1 or thereabouts on most JS impls. +// And well before that point, you're caching the entire world, I mean, +// that's ~32GB of just integers for the next/prev links, plus whatever +// else to hold that many keys and values. Just filling the memory with +// zeroes at init time is brutal when you get that big. +// But why not be complete? +// Maybe in the future, these limits will have expanded. +const getUintArray = (max) => !isPosInt(max) ? null + : max <= Math.pow(2, 8) ? Uint8Array + : max <= Math.pow(2, 16) ? Uint16Array + : max <= Math.pow(2, 32) ? Uint32Array + : max <= Number.MAX_SAFE_INTEGER ? ZeroArray + : null; +/* c8 ignore stop */ +class ZeroArray extends Array { + constructor(size) { + super(size); + this.fill(0); + } +} +class Stack { + heap; + length; + // private constructor + static #constructing = false; + static create(max) { + const HeapCls = getUintArray(max); + if (!HeapCls) + return []; + Stack.#constructing = true; + const s = new Stack(max, HeapCls); + Stack.#constructing = false; + return s; + } + constructor(max, HeapCls) { + /* c8 ignore start */ + if (!Stack.#constructing) { + throw new TypeError('instantiate Stack using Stack.create(n)'); + } + /* c8 ignore stop */ + this.heap = new HeapCls(max); + this.length = 0; + } + push(n) { + this.heap[this.length++] = n; + } + pop() { + return this.heap[--this.length]; + } +} +/** + * Default export, the thing you're using this module to get. + * + * The `K` and `V` types define the key and value types, respectively. The + * optional `FC` type defines the type of the `context` object passed to + * `cache.fetch()` and `cache.memo()`. + * + * Keys and values **must not** be `null` or `undefined`. + * + * All properties from the options object (with the exception of `max`, + * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are + * added as normal public members. (The listed options are read-only getters.) + * + * Changing any of these will alter the defaults for subsequent method calls. + */ +export class LRUCache { + // options that cannot be changed without disaster + #max; + #maxSize; + #dispose; + #onInsert; + #disposeAfter; + #fetchMethod; + #memoMethod; + #perf; + /** + * {@link LRUCache.OptionsBase.perf} + */ + get perf() { + return this.#perf; + } + /** + * {@link LRUCache.OptionsBase.ttl} + */ + ttl; + /** + * {@link LRUCache.OptionsBase.ttlResolution} + */ + ttlResolution; + /** + * {@link LRUCache.OptionsBase.ttlAutopurge} + */ + ttlAutopurge; + /** + * {@link LRUCache.OptionsBase.updateAgeOnGet} + */ + updateAgeOnGet; + /** + * {@link LRUCache.OptionsBase.updateAgeOnHas} + */ + updateAgeOnHas; + /** + * {@link LRUCache.OptionsBase.allowStale} + */ + allowStale; + /** + * {@link LRUCache.OptionsBase.noDisposeOnSet} + */ + noDisposeOnSet; + /** + * {@link LRUCache.OptionsBase.noUpdateTTL} + */ + noUpdateTTL; + /** + * {@link LRUCache.OptionsBase.maxEntrySize} + */ + maxEntrySize; + /** + * {@link LRUCache.OptionsBase.sizeCalculation} + */ + sizeCalculation; + /** + * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection} + */ + noDeleteOnFetchRejection; + /** + * {@link LRUCache.OptionsBase.noDeleteOnStaleGet} + */ + noDeleteOnStaleGet; + /** + * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort} + */ + allowStaleOnFetchAbort; + /** + * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection} + */ + allowStaleOnFetchRejection; + /** + * {@link LRUCache.OptionsBase.ignoreFetchAbort} + */ + ignoreFetchAbort; + // computed properties + #size; + #calculatedSize; + #keyMap; + #keyList; + #valList; + #next; + #prev; + #head; + #tail; + #free; + #disposed; + #sizes; + #starts; + #ttls; + #autopurgeTimers; + #hasDispose; + #hasFetchMethod; + #hasDisposeAfter; + #hasOnInsert; + /** + * Do not call this method unless you need to inspect the + * inner workings of the cache. If anything returned by this + * object is modified in any way, strange breakage may occur. + * + * These fields are private for a reason! + * + * @internal + */ + static unsafeExposeInternals(c) { + return { + // properties + starts: c.#starts, + ttls: c.#ttls, + autopurgeTimers: c.#autopurgeTimers, + sizes: c.#sizes, + keyMap: c.#keyMap, + keyList: c.#keyList, + valList: c.#valList, + next: c.#next, + prev: c.#prev, + get head() { + return c.#head; + }, + get tail() { + return c.#tail; + }, + free: c.#free, + // methods + isBackgroundFetch: (p) => c.#isBackgroundFetch(p), + backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context), + moveToTail: (index) => c.#moveToTail(index), + indexes: (options) => c.#indexes(options), + rindexes: (options) => c.#rindexes(options), + isStale: (index) => c.#isStale(index), + }; + } + // Protected read-only members + /** + * {@link LRUCache.OptionsBase.max} (read-only) + */ + get max() { + return this.#max; + } + /** + * {@link LRUCache.OptionsBase.maxSize} (read-only) + */ + get maxSize() { + return this.#maxSize; + } + /** + * The total computed size of items in the cache (read-only) + */ + get calculatedSize() { + return this.#calculatedSize; + } + /** + * The number of items stored in the cache (read-only) + */ + get size() { + return this.#size; + } + /** + * {@link LRUCache.OptionsBase.fetchMethod} (read-only) + */ + get fetchMethod() { + return this.#fetchMethod; + } + get memoMethod() { + return this.#memoMethod; + } + /** + * {@link LRUCache.OptionsBase.dispose} (read-only) + */ + get dispose() { + return this.#dispose; + } + /** + * {@link LRUCache.OptionsBase.onInsert} (read-only) + */ + get onInsert() { + return this.#onInsert; + } + /** + * {@link LRUCache.OptionsBase.disposeAfter} (read-only) + */ + get disposeAfter() { + return this.#disposeAfter; + } + constructor(options) { + const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, onInsert, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, perf, } = options; + if (perf !== undefined) { + if (typeof perf?.now !== 'function') { + throw new TypeError('perf option must have a now() method if specified'); + } + } + this.#perf = perf ?? defaultPerf; + if (max !== 0 && !isPosInt(max)) { + throw new TypeError('max option must be a nonnegative integer'); + } + const UintArray = max ? getUintArray(max) : Array; + if (!UintArray) { + throw new Error('invalid max value: ' + max); + } + this.#max = max; + this.#maxSize = maxSize; + this.maxEntrySize = maxEntrySize || this.#maxSize; + this.sizeCalculation = sizeCalculation; + if (this.sizeCalculation) { + if (!this.#maxSize && !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 (memoMethod !== undefined && typeof memoMethod !== 'function') { + throw new TypeError('memoMethod must be a function if defined'); + } + this.#memoMethod = memoMethod; + if (fetchMethod !== undefined && typeof fetchMethod !== 'function') { + throw new TypeError('fetchMethod must be a function if specified'); + } + this.#fetchMethod = fetchMethod; + this.#hasFetchMethod = !!fetchMethod; + this.#keyMap = new Map(); + this.#keyList = new Array(max).fill(undefined); + this.#valList = new Array(max).fill(undefined); + this.#next = new UintArray(max); + this.#prev = new UintArray(max); + this.#head = 0; + this.#tail = 0; + this.#free = Stack.create(max); + this.#size = 0; + this.#calculatedSize = 0; + if (typeof dispose === 'function') { + this.#dispose = dispose; + } + if (typeof onInsert === 'function') { + this.#onInsert = onInsert; + } + if (typeof disposeAfter === 'function') { + this.#disposeAfter = disposeAfter; + this.#disposed = []; + } + else { + this.#disposeAfter = undefined; + this.#disposed = undefined; + } + this.#hasDispose = !!this.#dispose; + this.#hasOnInsert = !!this.#onInsert; + this.#hasDisposeAfter = !!this.#disposeAfter; + this.noDisposeOnSet = !!noDisposeOnSet; + this.noUpdateTTL = !!noUpdateTTL; + this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection; + this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection; + this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort; + this.ignoreFetchAbort = !!ignoreFetchAbort; + // NB: maxEntrySize is set to maxSize if it's set + if (this.maxEntrySize !== 0) { + if (this.#maxSize !== 0) { + if (!isPosInt(this.#maxSize)) { + throw new TypeError('maxSize must be a positive integer if specified'); + } + } + if (!isPosInt(this.maxEntrySize)) { + throw new TypeError('maxEntrySize must be a positive integer if specified'); + } + this.#initializeSizeTracking(); + } + this.allowStale = !!allowStale; + this.noDeleteOnStaleGet = !!noDeleteOnStaleGet; + this.updateAgeOnGet = !!updateAgeOnGet; + this.updateAgeOnHas = !!updateAgeOnHas; + this.ttlResolution = + isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1; + this.ttlAutopurge = !!ttlAutopurge; + this.ttl = ttl || 0; + if (this.ttl) { + if (!isPosInt(this.ttl)) { + throw new TypeError('ttl must be a positive integer if specified'); + } + this.#initializeTTLTracking(); + } + // do not allow completely unbounded caches + if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) { + throw new TypeError('At least one of max, maxSize, or ttl is required'); + } + if (!this.ttlAutopurge && !this.#max && !this.#maxSize) { + const code = 'LRU_CACHE_UNBOUNDED'; + if (shouldWarn(code)) { + warned.add(code); + const msg = 'TTL caching without ttlAutopurge, max, or maxSize can ' + + 'result in unbounded memory consumption.'; + emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache); + } + } + } + /** + * Return the number of ms left in the item's TTL. If item is not in cache, + * returns `0`. Returns `Infinity` if item is in cache without a defined TTL. + */ + getRemainingTTL(key) { + return this.#keyMap.has(key) ? Infinity : 0; + } + #initializeTTLTracking() { + const ttls = new ZeroArray(this.#max); + const starts = new ZeroArray(this.#max); + this.#ttls = ttls; + this.#starts = starts; + const purgeTimers = this.ttlAutopurge ? + new Array(this.#max) + : undefined; + this.#autopurgeTimers = purgeTimers; + this.#setItemTTL = (index, ttl, start = this.#perf.now()) => { + starts[index] = ttl !== 0 ? start : 0; + ttls[index] = ttl; + // clear out the purge timer if we're setting TTL to 0, and + // previously had a ttl purge timer running, so it doesn't + // fire unnecessarily. + if (purgeTimers?.[index]) { + clearTimeout(purgeTimers[index]); + purgeTimers[index] = undefined; + } + if (ttl !== 0 && purgeTimers) { + const t = setTimeout(() => { + if (this.#isStale(index)) { + this.#delete(this.#keyList[index], 'expire'); + } + }, ttl + 1); + // unref() not supported on all platforms + /* c8 ignore start */ + if (t.unref) { + t.unref(); + } + /* c8 ignore stop */ + purgeTimers[index] = t; + } + }; + this.#updateItemAge = index => { + starts[index] = ttls[index] !== 0 ? this.#perf.now() : 0; + }; + this.#statusTTL = (status, index) => { + if (ttls[index]) { + const ttl = ttls[index]; + const start = starts[index]; + /* c8 ignore next */ + if (!ttl || !start) + return; + status.ttl = ttl; + status.start = start; + status.now = cachedNow || getNow(); + const age = status.now - start; + status.remainingTTL = ttl - age; + } + }; + // debounce calls to perf.now() to 1s so we're not hitting + // that costly call repeatedly. + let cachedNow = 0; + const getNow = () => { + const n = this.#perf.now(); + if (this.ttlResolution > 0) { + cachedNow = n; + const t = setTimeout(() => (cachedNow = 0), this.ttlResolution); + // not available on all platforms + /* c8 ignore start */ + if (t.unref) { + t.unref(); + } + /* c8 ignore stop */ + } + return n; + }; + this.getRemainingTTL = key => { + const index = this.#keyMap.get(key); + if (index === undefined) { + return 0; + } + const ttl = ttls[index]; + const start = starts[index]; + if (!ttl || !start) { + return Infinity; + } + const age = (cachedNow || getNow()) - start; + return ttl - age; + }; + this.#isStale = index => { + const s = starts[index]; + const t = ttls[index]; + return !!t && !!s && (cachedNow || getNow()) - s > t; + }; + } + // conditionally set private methods related to TTL + #updateItemAge = () => { }; + #statusTTL = () => { }; + #setItemTTL = () => { }; + /* c8 ignore stop */ + #isStale = () => false; + #initializeSizeTracking() { + const sizes = new ZeroArray(this.#max); + this.#calculatedSize = 0; + this.#sizes = sizes; + this.#removeItemSize = index => { + this.#calculatedSize -= sizes[index]; + sizes[index] = 0; + }; + this.#requireSize = (k, v, size, sizeCalculation) => { + // provisionally accept background fetches. + // actual value size will be checked when they return. + if (this.#isBackgroundFetch(v)) { + return 0; + } + if (!isPosInt(size)) { + if (sizeCalculation) { + if (typeof sizeCalculation !== 'function') { + throw new TypeError('sizeCalculation must be a function'); + } + size = sizeCalculation(v, k); + if (!isPosInt(size)) { + 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 size; + }; + this.#addItemSize = (index, size, status) => { + sizes[index] = size; + if (this.#maxSize) { + const maxSize = this.#maxSize - sizes[index]; + while (this.#calculatedSize > maxSize) { + this.#evict(true); + } + } + this.#calculatedSize += sizes[index]; + if (status) { + status.entrySize = size; + status.totalCalculatedSize = this.#calculatedSize; + } + }; + } + #removeItemSize = _i => { }; + #addItemSize = (_i, _s, _st) => { }; + #requireSize = (_k, _v, size, sizeCalculation) => { + if (size || sizeCalculation) { + throw new TypeError('cannot set size without setting maxSize or maxEntrySize on cache'); + } + return 0; + }; + *#indexes({ allowStale = this.allowStale } = {}) { + if (this.#size) { + for (let i = this.#tail; true;) { + if (!this.#isValidIndex(i)) { + break; + } + if (allowStale || !this.#isStale(i)) { + yield i; + } + if (i === this.#head) { + break; + } + else { + i = this.#prev[i]; + } + } + } + } + *#rindexes({ allowStale = this.allowStale } = {}) { + if (this.#size) { + for (let i = this.#head; true;) { + if (!this.#isValidIndex(i)) { + break; + } + if (allowStale || !this.#isStale(i)) { + yield i; + } + if (i === this.#tail) { + break; + } + else { + i = this.#next[i]; + } + } + } + } + #isValidIndex(index) { + return (index !== undefined && + this.#keyMap.get(this.#keyList[index]) === index); + } + /** + * Return a generator yielding `[key, value]` pairs, + * in order from most recently used to least recently used. + */ + *entries() { + for (const i of this.#indexes()) { + if (this.#valList[i] !== undefined && + this.#keyList[i] !== undefined && + !this.#isBackgroundFetch(this.#valList[i])) { + yield [this.#keyList[i], this.#valList[i]]; + } + } + } + /** + * Inverse order version of {@link LRUCache.entries} + * + * Return a generator yielding `[key, value]` pairs, + * in order from least recently used to most recently used. + */ + *rentries() { + for (const i of this.#rindexes()) { + if (this.#valList[i] !== undefined && + this.#keyList[i] !== undefined && + !this.#isBackgroundFetch(this.#valList[i])) { + yield [this.#keyList[i], this.#valList[i]]; + } + } + } + /** + * Return a generator yielding the keys in the cache, + * in order from most recently used to least recently used. + */ + *keys() { + for (const i of this.#indexes()) { + const k = this.#keyList[i]; + if (k !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield k; + } + } + } + /** + * Inverse order version of {@link LRUCache.keys} + * + * Return a generator yielding the keys in the cache, + * in order from least recently used to most recently used. + */ + *rkeys() { + for (const i of this.#rindexes()) { + const k = this.#keyList[i]; + if (k !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield k; + } + } + } + /** + * Return a generator yielding the values in the cache, + * in order from most recently used to least recently used. + */ + *values() { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + if (v !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield this.#valList[i]; + } + } + } + /** + * Inverse order version of {@link LRUCache.values} + * + * Return a generator yielding the values in the cache, + * in order from least recently used to most recently used. + */ + *rvalues() { + for (const i of this.#rindexes()) { + const v = this.#valList[i]; + if (v !== undefined && !this.#isBackgroundFetch(this.#valList[i])) { + yield this.#valList[i]; + } + } + } + /** + * Iterating over the cache itself yields the same results as + * {@link LRUCache.entries} + */ + [Symbol.iterator]() { + return this.entries(); + } + /** + * A String value that is used in the creation of the default string + * description of an object. Called by the built-in method + * `Object.prototype.toString`. + */ + [Symbol.toStringTag] = 'LRUCache'; + /** + * Find a value for which the supplied fn method returns a truthy value, + * similar to `Array.find()`. fn is called as `fn(value, key, cache)`. + */ + find(fn, getOptions = {}) { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + continue; + if (fn(value, this.#keyList[i], this)) { + return this.get(this.#keyList[i], getOptions); + } + } + } + /** + * Call the supplied function on each item in the cache, in order from most + * recently used to least recently used. + * + * `fn` is called as `fn(value, key, cache)`. + * + * If `thisp` is provided, function will be called in the `this`-context of + * the provided object, or the cache if no `thisp` object is provided. + * + * Does not update age or recenty of use, or iterate over stale values. + */ + forEach(fn, thisp = this) { + for (const i of this.#indexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + continue; + fn.call(thisp, value, this.#keyList[i], this); + } + } + /** + * The same as {@link LRUCache.forEach} but items are iterated over in + * reverse order. (ie, less recently used items are iterated over first.) + */ + rforEach(fn, thisp = this) { + for (const i of this.#rindexes()) { + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + continue; + fn.call(thisp, value, this.#keyList[i], this); + } + } + /** + * Delete any stale entries. Returns true if anything was removed, + * false otherwise. + */ + purgeStale() { + let deleted = false; + for (const i of this.#rindexes({ allowStale: true })) { + if (this.#isStale(i)) { + this.#delete(this.#keyList[i], 'expire'); + deleted = true; + } + } + return deleted; + } + /** + * Get the extended info about a given entry, to get its value, size, and + * TTL info simultaneously. Returns `undefined` if the key is not present. + * + * Unlike {@link LRUCache#dump}, which is designed to be portable and survive + * serialization, the `start` value is always the current timestamp, and the + * `ttl` is a calculated remaining time to live (negative if expired). + * + * Always returns stale values, if their info is found in the cache, so be + * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl}) + * if relevant. + */ + info(key) { + const i = this.#keyMap.get(key); + if (i === undefined) + return undefined; + const v = this.#valList[i]; + /* c8 ignore start - this isn't tested for the info function, + * but it's the same logic as found in other places. */ + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined) + return undefined; + /* c8 ignore end */ + const entry = { value }; + if (this.#ttls && this.#starts) { + const ttl = this.#ttls[i]; + const start = this.#starts[i]; + if (ttl && start) { + const remain = ttl - (this.#perf.now() - start); + entry.ttl = remain; + entry.start = Date.now(); + } + } + if (this.#sizes) { + entry.size = this.#sizes[i]; + } + return entry; + } + /** + * Return an array of [key, {@link LRUCache.Entry}] tuples which can be + * passed to {@link LRUCache#load}. + * + * The `start` fields are calculated relative to a portable `Date.now()` + * timestamp, even if `performance.now()` is available. + * + * Stale entries are always included in the `dump`, even if + * {@link LRUCache.OptionsBase.allowStale} is false. + * + * Note: this returns an actual array, not a generator, so it can be more + * easily passed around. + */ + dump() { + const arr = []; + for (const i of this.#indexes({ allowStale: true })) { + const key = this.#keyList[i]; + const v = this.#valList[i]; + const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + if (value === undefined || key === undefined) + continue; + const entry = { value }; + if (this.#ttls && this.#starts) { + entry.ttl = this.#ttls[i]; + // always dump the start relative to a portable timestamp + // it's ok for this to be a bit slow, it's a rare operation. + const age = this.#perf.now() - this.#starts[i]; + entry.start = Math.floor(Date.now() - age); + } + if (this.#sizes) { + entry.size = this.#sizes[i]; + } + arr.unshift([key, entry]); + } + return arr; + } + /** + * Reset the cache and load in the items in entries in the order listed. + * + * The shape of the resulting cache may be different if the same options are + * not used in both caches. + * + * The `start` fields are assumed to be calculated relative to a portable + * `Date.now()` timestamp, even if `performance.now()` is available. + */ + load(arr) { + this.clear(); + for (const [key, entry] of arr) { + if (entry.start) { + // entry.start is a portable timestamp, but we may be using + // node's performance.now(), so calculate the offset, so that + // we get the intended remaining TTL, no matter how long it's + // been on ice. + // + // it's ok for this to be a bit slow, it's a rare operation. + const age = Date.now() - entry.start; + entry.start = this.#perf.now() - age; + } + this.set(key, entry.value, entry); + } + } + /** + * Add a value to the cache. + * + * Note: if `undefined` is specified as a value, this is an alias for + * {@link LRUCache#delete} + * + * Fields on the {@link LRUCache.SetOptions} options param will override + * their corresponding values in the constructor options for the scope + * of this single `set()` operation. + * + * If `start` is provided, then that will set the effective start + * time for the TTL calculation. Note that this must be a previous + * value of `performance.now()` if supported, or a previous value of + * `Date.now()` if not. + * + * Options object may also include `size`, which will prevent + * calling the `sizeCalculation` function and just use the specified + * number if it is a positive integer, and `noDisposeOnSet` which + * will prevent calling a `dispose` function in the case of + * overwrites. + * + * If the `size` (or return value of `sizeCalculation`) for a given + * entry is greater than `maxEntrySize`, then the item will not be + * added to the cache. + * + * Will update the recency of the entry. + * + * If the value is `undefined`, then this is an alias for + * `cache.delete(key)`. `undefined` is never stored in the cache. + */ + set(k, v, setOptions = {}) { + if (v === undefined) { + this.delete(k); + return this; + } + const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status, } = setOptions; + let { noUpdateTTL = this.noUpdateTTL } = setOptions; + const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation); + // if the item doesn't fit, don't do anything + // NB: maxEntrySize set to maxSize by default + if (this.maxEntrySize && size > this.maxEntrySize) { + if (status) { + status.set = 'miss'; + status.maxEntrySizeExceeded = true; + } + // have to delete, in case something is there already. + this.#delete(k, 'set'); + return this; + } + let index = this.#size === 0 ? undefined : this.#keyMap.get(k); + if (index === undefined) { + // addition + index = (this.#size === 0 ? this.#tail + : this.#free.length !== 0 ? this.#free.pop() + : this.#size === this.#max ? this.#evict(false) + : this.#size); + this.#keyList[index] = k; + this.#valList[index] = v; + this.#keyMap.set(k, index); + this.#next[this.#tail] = index; + this.#prev[index] = this.#tail; + this.#tail = index; + this.#size++; + this.#addItemSize(index, size, status); + if (status) + status.set = 'add'; + noUpdateTTL = false; + if (this.#hasOnInsert) { + this.#onInsert?.(v, k, 'add'); + } + } + else { + // update + this.#moveToTail(index); + const oldVal = this.#valList[index]; + if (v !== oldVal) { + if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) { + oldVal.__abortController.abort(new Error('replaced')); + const { __staleWhileFetching: s } = oldVal; + if (s !== undefined && !noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(s, k, 'set'); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([s, k, 'set']); + } + } + } + else if (!noDisposeOnSet) { + if (this.#hasDispose) { + this.#dispose?.(oldVal, k, 'set'); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([oldVal, k, 'set']); + } + } + this.#removeItemSize(index); + this.#addItemSize(index, size, status); + this.#valList[index] = v; + if (status) { + status.set = 'replace'; + const oldValue = oldVal && this.#isBackgroundFetch(oldVal) ? + oldVal.__staleWhileFetching + : oldVal; + if (oldValue !== undefined) + status.oldValue = oldValue; + } + } + else if (status) { + status.set = 'update'; + } + if (this.#hasOnInsert) { + this.onInsert?.(v, k, v === oldVal ? 'update' : 'replace'); + } + } + if (ttl !== 0 && !this.#ttls) { + this.#initializeTTLTracking(); + } + if (this.#ttls) { + if (!noUpdateTTL) { + this.#setItemTTL(index, ttl, start); + } + if (status) + this.#statusTTL(status, index); + } + if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + return this; + } + /** + * Evict the least recently used item, returning its value or + * `undefined` if cache is empty. + */ + pop() { + try { + while (this.#size) { + const val = this.#valList[this.#head]; + this.#evict(true); + if (this.#isBackgroundFetch(val)) { + if (val.__staleWhileFetching) { + return val.__staleWhileFetching; + } + } + else if (val !== undefined) { + return val; + } + } + } + finally { + if (this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + } + } + #evict(free) { + const head = this.#head; + const k = this.#keyList[head]; + const v = this.#valList[head]; + if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error('evicted')); + } + else if (this.#hasDispose || this.#hasDisposeAfter) { + if (this.#hasDispose) { + this.#dispose?.(v, k, 'evict'); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, 'evict']); + } + } + this.#removeItemSize(head); + if (this.#autopurgeTimers?.[head]) { + clearTimeout(this.#autopurgeTimers[head]); + this.#autopurgeTimers[head] = undefined; + } + // if we aren't about to use the index, then null these out + if (free) { + this.#keyList[head] = undefined; + this.#valList[head] = undefined; + this.#free.push(head); + } + if (this.#size === 1) { + this.#head = this.#tail = 0; + this.#free.length = 0; + } + else { + this.#head = this.#next[head]; + } + this.#keyMap.delete(k); + this.#size--; + return head; + } + /** + * Check if a key is in the cache, without updating the recency of use. + * Will return false if the item is stale, even though it is technically + * in the cache. + * + * Check if a key is in the cache, without updating the recency of + * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set + * to `true` in either the options or the constructor. + * + * Will return `false` if the item is stale, even though it is technically in + * the cache. The difference can be determined (if it matters) by using a + * `status` argument, and inspecting the `has` field. + * + * Will not update item age unless + * {@link LRUCache.OptionsBase.updateAgeOnHas} is set. + */ + has(k, hasOptions = {}) { + const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions; + const index = this.#keyMap.get(k); + if (index !== undefined) { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v) && + v.__staleWhileFetching === undefined) { + return false; + } + if (!this.#isStale(index)) { + if (updateAgeOnHas) { + this.#updateItemAge(index); + } + if (status) { + status.has = 'hit'; + this.#statusTTL(status, index); + } + return true; + } + else if (status) { + status.has = 'stale'; + this.#statusTTL(status, index); + } + } + else if (status) { + status.has = 'miss'; + } + return false; + } + /** + * Like {@link LRUCache#get} but doesn't update recency or delete stale + * items. + * + * Returns `undefined` if the item is stale, unless + * {@link LRUCache.OptionsBase.allowStale} is set. + */ + peek(k, peekOptions = {}) { + const { allowStale = this.allowStale } = peekOptions; + const index = this.#keyMap.get(k); + if (index === undefined || (!allowStale && this.#isStale(index))) { + return; + } + const v = this.#valList[index]; + // either stale and allowed, or forcing a refresh of non-stale value + return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v; + } + #backgroundFetch(k, index, options, context) { + const v = index === undefined ? undefined : this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + return v; + } + const ac = new AC(); + const { signal } = options; + // when/if our AC signals, then stop listening to theirs. + signal?.addEventListener('abort', () => ac.abort(signal.reason), { + signal: ac.signal, + }); + const fetchOpts = { + signal: ac.signal, + options, + context, + }; + const cb = (v, updateCache = false) => { + const { aborted } = ac.signal; + const ignoreAbort = options.ignoreFetchAbort && v !== undefined; + const proceed = options.ignoreFetchAbort || + !!(options.allowStaleOnFetchAbort && v !== undefined); + if (options.status) { + if (aborted && !updateCache) { + options.status.fetchAborted = true; + options.status.fetchError = ac.signal.reason; + if (ignoreAbort) + options.status.fetchAbortIgnored = true; + } + else { + options.status.fetchResolved = true; + } + } + if (aborted && !ignoreAbort && !updateCache) { + return fetchFail(ac.signal.reason, proceed); + } + // either we didn't abort, and are still here, or we did, and ignored + const bf = p; + // if nothing else has been written there but we're set to update the + // cache and ignore the abort, or if it's still pending on this specific + // background request, then write it to the cache. + const vl = this.#valList[index]; + if (vl === p || (ignoreAbort && updateCache && vl === undefined)) { + if (v === undefined) { + if (bf.__staleWhileFetching !== undefined) { + this.#valList[index] = bf.__staleWhileFetching; + } + else { + this.#delete(k, 'fetch'); + } + } + else { + if (options.status) + options.status.fetchUpdated = true; + this.set(k, v, fetchOpts.options); + } + } + return v; + }; + const eb = (er) => { + if (options.status) { + options.status.fetchRejected = true; + options.status.fetchError = er; + } + // do not pass go, do not collect $200 + return fetchFail(er, false); + }; + const fetchFail = (er, proceed) => { + const { aborted } = ac.signal; + const allowStaleAborted = aborted && options.allowStaleOnFetchAbort; + const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection; + const noDelete = allowStale || options.noDeleteOnFetchRejection; + const bf = p; + if (this.#valList[index] === p) { + // if we allow stale on fetch rejections, then we need to ensure that + // the stale value is not removed from the cache when the fetch fails. + const del = !noDelete || + !proceed && bf.__staleWhileFetching === undefined; + if (del) { + this.#delete(k, 'fetch'); + } + else if (!allowStaleAborted) { + // still replace the *promise* with the stale value, + // since we are done with the promise at this point. + // leave it untouched if we're still waiting for an + // aborted background fetch that hasn't yet returned. + this.#valList[index] = bf.__staleWhileFetching; + } + } + if (allowStale) { + if (options.status && bf.__staleWhileFetching !== undefined) { + options.status.returnedStale = true; + } + return bf.__staleWhileFetching; + } + else if (bf.__returned === bf) { + throw er; + } + }; + const pcall = (res, rej) => { + const fmp = this.#fetchMethod?.(k, v, fetchOpts); + if (fmp && fmp instanceof Promise) { + fmp.then(v => res(v === undefined ? undefined : v), rej); + } + // ignored, we go until we finish, regardless. + // defer check until we are actually aborting, + // so fetchMethod can override. + ac.signal.addEventListener('abort', () => { + if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) { + res(undefined); + // when it eventually resolves, update the cache. + if (options.allowStaleOnFetchAbort) { + res = v => cb(v, true); + } + } + }); + }; + if (options.status) + options.status.fetchDispatched = true; + const p = new Promise(pcall).then(cb, eb); + const bf = Object.assign(p, { + __abortController: ac, + __staleWhileFetching: v, + __returned: undefined, + }); + if (index === undefined) { + // internal, don't expose status. + this.set(k, bf, { ...fetchOpts.options, status: undefined }); + index = this.#keyMap.get(k); + } + else { + this.#valList[index] = bf; + } + return bf; + } + #isBackgroundFetch(p) { + if (!this.#hasFetchMethod) + return false; + const b = p; + return (!!b && + b instanceof Promise && + b.hasOwnProperty('__staleWhileFetching') && + b.__abortController instanceof AC); + } + async fetch(k, fetchOptions = {}) { + const { + // get options + allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, + // set options + ttl = this.ttl, noDisposeOnSet = this.noDisposeOnSet, size = 0, sizeCalculation = this.sizeCalculation, noUpdateTTL = this.noUpdateTTL, + // fetch exclusive options + noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, ignoreFetchAbort = this.ignoreFetchAbort, allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, context, forceRefresh = false, status, signal, } = fetchOptions; + if (!this.#hasFetchMethod) { + if (status) + status.fetch = 'get'; + return this.get(k, { + allowStale, + updateAgeOnGet, + noDeleteOnStaleGet, + status, + }); + } + const options = { + allowStale, + updateAgeOnGet, + noDeleteOnStaleGet, + ttl, + noDisposeOnSet, + size, + sizeCalculation, + noUpdateTTL, + noDeleteOnFetchRejection, + allowStaleOnFetchRejection, + allowStaleOnFetchAbort, + ignoreFetchAbort, + status, + signal, + }; + let index = this.#keyMap.get(k); + if (index === undefined) { + if (status) + status.fetch = 'miss'; + const p = this.#backgroundFetch(k, index, options, context); + return (p.__returned = p); + } + else { + // in cache, maybe already fetching + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + const stale = allowStale && v.__staleWhileFetching !== undefined; + if (status) { + status.fetch = 'inflight'; + if (stale) + status.returnedStale = true; + } + return stale ? v.__staleWhileFetching : (v.__returned = v); + } + // if we force a refresh, that means do NOT serve the cached value, + // unless we are already in the process of refreshing the cache. + const isStale = this.#isStale(index); + if (!forceRefresh && !isStale) { + if (status) + status.fetch = 'hit'; + this.#moveToTail(index); + if (updateAgeOnGet) { + this.#updateItemAge(index); + } + if (status) + this.#statusTTL(status, index); + return v; + } + // ok, it is stale or a forced refresh, and not already fetching. + // refresh the cache. + const p = this.#backgroundFetch(k, index, options, context); + const hasStale = p.__staleWhileFetching !== undefined; + const staleVal = hasStale && allowStale; + if (status) { + status.fetch = isStale ? 'stale' : 'refresh'; + if (staleVal && isStale) + status.returnedStale = true; + } + return staleVal ? p.__staleWhileFetching : (p.__returned = p); + } + } + async forceFetch(k, fetchOptions = {}) { + const v = await this.fetch(k, fetchOptions); + if (v === undefined) + throw new Error('fetch() returned undefined'); + return v; + } + memo(k, memoOptions = {}) { + const memoMethod = this.#memoMethod; + if (!memoMethod) { + throw new Error('no memoMethod provided to constructor'); + } + const { context, forceRefresh, ...options } = memoOptions; + const v = this.get(k, options); + if (!forceRefresh && v !== undefined) + return v; + const vv = memoMethod(k, v, { + options, + context, + }); + this.set(k, vv, options); + return vv; + } + /** + * Return a value from the cache. Will update the recency of the cache + * entry found. + * + * If the key is not found, get() will return `undefined`. + */ + get(k, getOptions = {}) { + const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status, } = getOptions; + const index = this.#keyMap.get(k); + if (index !== undefined) { + const value = this.#valList[index]; + const fetching = this.#isBackgroundFetch(value); + if (status) + this.#statusTTL(status, index); + if (this.#isStale(index)) { + if (status) + status.get = 'stale'; + // delete only if not an in-flight background fetch + if (!fetching) { + if (!noDeleteOnStaleGet) { + this.#delete(k, 'expire'); + } + if (status && allowStale) + status.returnedStale = true; + return allowStale ? value : undefined; + } + else { + if (status && + allowStale && + value.__staleWhileFetching !== undefined) { + status.returnedStale = true; + } + return allowStale ? value.__staleWhileFetching : undefined; + } + } + else { + if (status) + status.get = 'hit'; + // if we're currently fetching it, we don't actually have it yet + // it's not stale, which means this isn't a staleWhileRefetching. + // If it's not stale, and fetching, AND has a __staleWhileFetching + // value, then that means the user fetched with {forceRefresh:true}, + // so it's safe to return that value. + if (fetching) { + return value.__staleWhileFetching; + } + this.#moveToTail(index); + if (updateAgeOnGet) { + this.#updateItemAge(index); + } + return value; + } + } + else if (status) { + status.get = 'miss'; + } + } + #connect(p, n) { + this.#prev[n] = p; + this.#next[p] = n; + } + #moveToTail(index) { + // if tail already, nothing to do + // if head, move head to next[index] + // else + // move next[prev[index]] to next[index] (head has no prev) + // move prev[next[index]] to prev[index] + // prev[index] = tail + // next[tail] = index + // tail = index + if (index !== this.#tail) { + if (index === this.#head) { + this.#head = this.#next[index]; + } + else { + this.#connect(this.#prev[index], this.#next[index]); + } + this.#connect(this.#tail, index); + this.#tail = index; + } + } + /** + * Deletes a key out of the cache. + * + * Returns true if the key was deleted, false otherwise. + */ + delete(k) { + return this.#delete(k, 'delete'); + } + #delete(k, reason) { + let deleted = false; + if (this.#size !== 0) { + const index = this.#keyMap.get(k); + if (index !== undefined) { + if (this.#autopurgeTimers?.[index]) { + clearTimeout(this.#autopurgeTimers?.[index]); + this.#autopurgeTimers[index] = undefined; + } + deleted = true; + if (this.#size === 1) { + this.#clear(reason); + } + else { + this.#removeItemSize(index); + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error('deleted')); + } + else if (this.#hasDispose || this.#hasDisposeAfter) { + if (this.#hasDispose) { + this.#dispose?.(v, k, reason); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, reason]); + } + } + this.#keyMap.delete(k); + this.#keyList[index] = undefined; + this.#valList[index] = undefined; + if (index === this.#tail) { + this.#tail = this.#prev[index]; + } + else if (index === this.#head) { + this.#head = this.#next[index]; + } + else { + const pi = this.#prev[index]; + this.#next[pi] = this.#next[index]; + const ni = this.#next[index]; + this.#prev[ni] = this.#prev[index]; + } + this.#size--; + this.#free.push(index); + } + } + } + if (this.#hasDisposeAfter && this.#disposed?.length) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + return deleted; + } + /** + * Clear the cache entirely, throwing away all values. + */ + clear() { + return this.#clear('delete'); + } + #clear(reason) { + for (const index of this.#rindexes({ allowStale: true })) { + const v = this.#valList[index]; + if (this.#isBackgroundFetch(v)) { + v.__abortController.abort(new Error('deleted')); + } + else { + const k = this.#keyList[index]; + if (this.#hasDispose) { + this.#dispose?.(v, k, reason); + } + if (this.#hasDisposeAfter) { + this.#disposed?.push([v, k, reason]); + } + } + } + this.#keyMap.clear(); + this.#valList.fill(undefined); + this.#keyList.fill(undefined); + if (this.#ttls && this.#starts) { + this.#ttls.fill(0); + this.#starts.fill(0); + for (const t of this.#autopurgeTimers ?? []) { + if (t !== undefined) + clearTimeout(t); + } + this.#autopurgeTimers?.fill(undefined); + } + if (this.#sizes) { + this.#sizes.fill(0); + } + this.#head = 0; + this.#tail = 0; + this.#free.length = 0; + this.#calculatedSize = 0; + this.#size = 0; + if (this.#hasDisposeAfter && this.#disposed) { + const dt = this.#disposed; + let task; + while ((task = dt?.shift())) { + this.#disposeAfter?.(...task); + } + } + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/lru-cache/dist/esm/index.min.js b/node_modules/lru-cache/dist/esm/index.min.js new file mode 100644 index 0000000000000..81f29da1dea9f --- /dev/null +++ b/node_modules/lru-cache/dist/esm/index.min.js @@ -0,0 +1,2 @@ +var M=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,I=new Set,R=typeof process=="object"&&process?process:{},x=(a,t,e,i)=>{typeof R.emitWarning=="function"?R.emitWarning(a,t,e,i):console.error(`[${e}] ${t}: ${a}`)},C=globalThis.AbortController,D=globalThis.AbortSignal;if(typeof C>"u"){D=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(i,s){this._onabort.push(s)}},C=class{constructor(){t()}signal=new D;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 a=R.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{a&&(a=!1,x("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 G=a=>!I.has(a),H=Symbol("type"),y=a=>a&&a===Math.floor(a)&&a>0&&isFinite(a),U=a=>y(a)?a<=Math.pow(2,8)?Uint8Array:a<=Math.pow(2,16)?Uint16Array:a<=Math.pow(2,32)?Uint32Array:a<=Number.MAX_SAFE_INTEGER?z:null:null,z=class extends Array{constructor(t){super(t),this.fill(0)}},W=class a{heap;length;static#o=!1;static create(t){let e=U(t);if(!e)return[];a.#o=!0;let i=new a(t,e);return a.#o=!1,i}constructor(t,e){if(!a.#o)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]}},L=class a{#o;#c;#w;#C;#S;#L;#I;#m;get perf(){return this.#m}ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#n;#_;#s;#i;#t;#a;#u;#l;#h;#b;#r;#y;#A;#d;#g;#T;#v;#f;#x;static unsafeExposeInternals(t){return{starts:t.#A,ttls:t.#d,autopurgeTimers:t.#g,sizes:t.#y,keyMap:t.#s,keyList:t.#i,valList:t.#t,next:t.#a,prev:t.#u,get head(){return t.#l},get tail(){return t.#h},free:t.#b,isBackgroundFetch:e=>t.#e(e),backgroundFetch:(e,i,s,h)=>t.#G(e,i,s,h),moveToTail:e=>t.#D(e),indexes:e=>t.#F(e),rindexes:e=>t.#O(e),isStale:e=>t.#p(e)}}get max(){return this.#o}get maxSize(){return this.#c}get calculatedSize(){return this.#_}get size(){return this.#n}get fetchMethod(){return this.#L}get memoMethod(){return this.#I}get dispose(){return this.#w}get onInsert(){return this.#C}get disposeAfter(){return this.#S}constructor(t){let{max:e=0,ttl:i,ttlResolution:s=1,ttlAutopurge:h,updateAgeOnGet:n,updateAgeOnHas:o,allowStale:r,dispose:f,onInsert:m,disposeAfter:c,noDisposeOnSet:d,noUpdateTTL:g,maxSize:A=0,maxEntrySize:p=0,sizeCalculation:_,fetchMethod:l,memoMethod:w,noDeleteOnFetchRejection:b,noDeleteOnStaleGet:S,allowStaleOnFetchRejection:u,allowStaleOnFetchAbort:T,ignoreFetchAbort:F,perf:v}=t;if(v!==void 0&&typeof v?.now!="function")throw new TypeError("perf option must have a now() method if specified");if(this.#m=v??M,e!==0&&!y(e))throw new TypeError("max option must be a nonnegative integer");let O=e?U(e):Array;if(!O)throw new Error("invalid max value: "+e);if(this.#o=e,this.#c=A,this.maxEntrySize=p||this.#c,this.sizeCalculation=_,this.sizeCalculation){if(!this.#c&&!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(w!==void 0&&typeof w!="function")throw new TypeError("memoMethod must be a function if defined");if(this.#I=w,l!==void 0&&typeof l!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#L=l,this.#v=!!l,this.#s=new Map,this.#i=new Array(e).fill(void 0),this.#t=new Array(e).fill(void 0),this.#a=new O(e),this.#u=new O(e),this.#l=0,this.#h=0,this.#b=W.create(e),this.#n=0,this.#_=0,typeof f=="function"&&(this.#w=f),typeof m=="function"&&(this.#C=m),typeof c=="function"?(this.#S=c,this.#r=[]):(this.#S=void 0,this.#r=void 0),this.#T=!!this.#w,this.#x=!!this.#C,this.#f=!!this.#S,this.noDisposeOnSet=!!d,this.noUpdateTTL=!!g,this.noDeleteOnFetchRejection=!!b,this.allowStaleOnFetchRejection=!!u,this.allowStaleOnFetchAbort=!!T,this.ignoreFetchAbort=!!F,this.maxEntrySize!==0){if(this.#c!==0&&!y(this.#c))throw new TypeError("maxSize must be a positive integer if specified");if(!y(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#B()}if(this.allowStale=!!r,this.noDeleteOnStaleGet=!!S,this.updateAgeOnGet=!!n,this.updateAgeOnHas=!!o,this.ttlResolution=y(s)||s===0?s:1,this.ttlAutopurge=!!h,this.ttl=i||0,this.ttl){if(!y(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#j()}if(this.#o===0&&this.ttl===0&&this.#c===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#o&&!this.#c){let E="LRU_CACHE_UNBOUNDED";G(E)&&(I.add(E),x("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",E,a))}}getRemainingTTL(t){return this.#s.has(t)?1/0:0}#j(){let t=new z(this.#o),e=new z(this.#o);this.#d=t,this.#A=e;let i=this.ttlAutopurge?new Array(this.#o):void 0;this.#g=i,this.#N=(n,o,r=this.#m.now())=>{if(e[n]=o!==0?r:0,t[n]=o,i?.[n]&&(clearTimeout(i[n]),i[n]=void 0),o!==0&&i){let f=setTimeout(()=>{this.#p(n)&&this.#E(this.#i[n],"expire")},o+1);f.unref&&f.unref(),i[n]=f}},this.#R=n=>{e[n]=t[n]!==0?this.#m.now():0},this.#z=(n,o)=>{if(t[o]){let r=t[o],f=e[o];if(!r||!f)return;n.ttl=r,n.start=f,n.now=s||h();let m=n.now-f;n.remainingTTL=r-m}};let s=0,h=()=>{let n=this.#m.now();if(this.ttlResolution>0){s=n;let o=setTimeout(()=>s=0,this.ttlResolution);o.unref&&o.unref()}return n};this.getRemainingTTL=n=>{let o=this.#s.get(n);if(o===void 0)return 0;let r=t[o],f=e[o];if(!r||!f)return 1/0;let m=(s||h())-f;return r-m},this.#p=n=>{let o=e[n],r=t[n];return!!r&&!!o&&(s||h())-o>r}}#R=()=>{};#z=()=>{};#N=()=>{};#p=()=>!1;#B(){let t=new z(this.#o);this.#_=0,this.#y=t,this.#W=e=>{this.#_-=t[e],t[e]=0},this.#P=(e,i,s,h)=>{if(this.#e(i))return 0;if(!y(s))if(h){if(typeof h!="function")throw new TypeError("sizeCalculation must be a function");if(s=h(i,e),!y(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.#U=(e,i,s)=>{if(t[e]=i,this.#c){let h=this.#c-t[e];for(;this.#_>h;)this.#M(!0)}this.#_+=t[e],s&&(s.entrySize=i,s.totalCalculatedSize=this.#_)}}#W=t=>{};#U=(t,e,i)=>{};#P=(t,e,i,s)=>{if(i||s)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#F({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#h;!(!this.#H(e)||((t||!this.#p(e))&&(yield e),e===this.#l));)e=this.#u[e]}*#O({allowStale:t=this.allowStale}={}){if(this.#n)for(let e=this.#l;!(!this.#H(e)||((t||!this.#p(e))&&(yield e),e===this.#h));)e=this.#a[e]}#H(t){return t!==void 0&&this.#s.get(this.#i[t])===t}*entries(){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]])}*rentries(){for(let t of this.#O())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.#F()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*rkeys(){for(let t of this.#O()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*values(){for(let t of this.#F())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}*rvalues(){for(let t of this.#O())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.#F()){let s=this.#t[i],h=this.#e(s)?s.__staleWhileFetching:s;if(h!==void 0&&t(h,this.#i[i],this))return this.get(this.#i[i],e)}}forEach(t,e=this){for(let i of this.#F()){let s=this.#t[i],h=this.#e(s)?s.__staleWhileFetching:s;h!==void 0&&t.call(e,h,this.#i[i],this)}}rforEach(t,e=this){for(let i of this.#O()){let s=this.#t[i],h=this.#e(s)?s.__staleWhileFetching:s;h!==void 0&&t.call(e,h,this.#i[i],this)}}purgeStale(){let t=!1;for(let e of this.#O({allowStale:!0}))this.#p(e)&&(this.#E(this.#i[e],"expire"),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 h={value:s};if(this.#d&&this.#A){let n=this.#d[e],o=this.#A[e];if(n&&o){let r=n-(this.#m.now()-o);h.ttl=r,h.start=Date.now()}}return this.#y&&(h.size=this.#y[e]),h}dump(){let t=[];for(let e of this.#F({allowStale:!0})){let i=this.#i[e],s=this.#t[e],h=this.#e(s)?s.__staleWhileFetching:s;if(h===void 0||i===void 0)continue;let n={value:h};if(this.#d&&this.#A){n.ttl=this.#d[e];let o=this.#m.now()-this.#A[e];n.start=Math.floor(Date.now()-o)}this.#y&&(n.size=this.#y[e]),t.unshift([i,n])}return t}load(t){this.clear();for(let[e,i]of t){if(i.start){let s=Date.now()-i.start;i.start=this.#m.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:h,noDisposeOnSet:n=this.noDisposeOnSet,sizeCalculation:o=this.sizeCalculation,status:r}=i,{noUpdateTTL:f=this.noUpdateTTL}=i,m=this.#P(t,e,i.size||0,o);if(this.maxEntrySize&&m>this.maxEntrySize)return r&&(r.set="miss",r.maxEntrySizeExceeded=!0),this.#E(t,"set"),this;let c=this.#n===0?void 0:this.#s.get(t);if(c===void 0)c=this.#n===0?this.#h:this.#b.length!==0?this.#b.pop():this.#n===this.#o?this.#M(!1):this.#n,this.#i[c]=t,this.#t[c]=e,this.#s.set(t,c),this.#a[this.#h]=c,this.#u[c]=this.#h,this.#h=c,this.#n++,this.#U(c,m,r),r&&(r.set="add"),f=!1,this.#x&&this.#C?.(e,t,"add");else{this.#D(c);let d=this.#t[c];if(e!==d){if(this.#v&&this.#e(d)){d.__abortController.abort(new Error("replaced"));let{__staleWhileFetching:g}=d;g!==void 0&&!n&&(this.#T&&this.#w?.(g,t,"set"),this.#f&&this.#r?.push([g,t,"set"]))}else n||(this.#T&&this.#w?.(d,t,"set"),this.#f&&this.#r?.push([d,t,"set"]));if(this.#W(c),this.#U(c,m,r),this.#t[c]=e,r){r.set="replace";let g=d&&this.#e(d)?d.__staleWhileFetching:d;g!==void 0&&(r.oldValue=g)}}else r&&(r.set="update");this.#x&&this.onInsert?.(e,t,e===d?"update":"replace")}if(s!==0&&!this.#d&&this.#j(),this.#d&&(f||this.#N(c,s,h),r&&this.#z(r,c)),!n&&this.#f&&this.#r){let d=this.#r,g;for(;g=d?.shift();)this.#S?.(...g)}return this}pop(){try{for(;this.#n;){let t=this.#t[this.#l];if(this.#M(!0),this.#e(t)){if(t.__staleWhileFetching)return t.__staleWhileFetching}else if(t!==void 0)return t}}finally{if(this.#f&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#S?.(...e)}}}#M(t){let e=this.#l,i=this.#i[e],s=this.#t[e];return this.#v&&this.#e(s)?s.__abortController.abort(new Error("evicted")):(this.#T||this.#f)&&(this.#T&&this.#w?.(s,i,"evict"),this.#f&&this.#r?.push([s,i,"evict"])),this.#W(e),this.#g?.[e]&&(clearTimeout(this.#g[e]),this.#g[e]=void 0),t&&(this.#i[e]=void 0,this.#t[e]=void 0,this.#b.push(e)),this.#n===1?(this.#l=this.#h=0,this.#b.length=0):this.#l=this.#a[e],this.#s.delete(i),this.#n--,e}has(t,e={}){let{updateAgeOnHas:i=this.updateAgeOnHas,status:s}=e,h=this.#s.get(t);if(h!==void 0){let n=this.#t[h];if(this.#e(n)&&n.__staleWhileFetching===void 0)return!1;if(this.#p(h))s&&(s.has="stale",this.#z(s,h));else return i&&this.#R(h),s&&(s.has="hit",this.#z(s,h)),!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.#p(s))return;let h=this.#t[s];return this.#e(h)?h.__staleWhileFetching:h}#G(t,e,i,s){let h=e===void 0?void 0:this.#t[e];if(this.#e(h))return h;let n=new C,{signal:o}=i;o?.addEventListener("abort",()=>n.abort(o.reason),{signal:n.signal});let r={signal:n.signal,options:i,context:s},f=(p,_=!1)=>{let{aborted:l}=n.signal,w=i.ignoreFetchAbort&&p!==void 0,b=i.ignoreFetchAbort||!!(i.allowStaleOnFetchAbort&&p!==void 0);if(i.status&&(l&&!_?(i.status.fetchAborted=!0,i.status.fetchError=n.signal.reason,w&&(i.status.fetchAbortIgnored=!0)):i.status.fetchResolved=!0),l&&!w&&!_)return c(n.signal.reason,b);let S=g,u=this.#t[e];return(u===g||w&&_&&u===void 0)&&(p===void 0?S.__staleWhileFetching!==void 0?this.#t[e]=S.__staleWhileFetching:this.#E(t,"fetch"):(i.status&&(i.status.fetchUpdated=!0),this.set(t,p,r.options))),p},m=p=>(i.status&&(i.status.fetchRejected=!0,i.status.fetchError=p),c(p,!1)),c=(p,_)=>{let{aborted:l}=n.signal,w=l&&i.allowStaleOnFetchAbort,b=w||i.allowStaleOnFetchRejection,S=b||i.noDeleteOnFetchRejection,u=g;if(this.#t[e]===g&&(!S||!_&&u.__staleWhileFetching===void 0?this.#E(t,"fetch"):w||(this.#t[e]=u.__staleWhileFetching)),b)return i.status&&u.__staleWhileFetching!==void 0&&(i.status.returnedStale=!0),u.__staleWhileFetching;if(u.__returned===u)throw p},d=(p,_)=>{let l=this.#L?.(t,h,r);l&&l instanceof Promise&&l.then(w=>p(w===void 0?void 0:w),_),n.signal.addEventListener("abort",()=>{(!i.ignoreFetchAbort||i.allowStaleOnFetchAbort)&&(p(void 0),i.allowStaleOnFetchAbort&&(p=w=>f(w,!0)))})};i.status&&(i.status.fetchDispatched=!0);let g=new Promise(d).then(f,m),A=Object.assign(g,{__abortController:n,__staleWhileFetching:h,__returned:void 0});return e===void 0?(this.set(t,A,{...r.options,status:void 0}),e=this.#s.get(t)):this.#t[e]=A,A}#e(t){if(!this.#v)return!1;let e=t;return!!e&&e instanceof Promise&&e.hasOwnProperty("__staleWhileFetching")&&e.__abortController instanceof C}async fetch(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:h=this.noDeleteOnStaleGet,ttl:n=this.ttl,noDisposeOnSet:o=this.noDisposeOnSet,size:r=0,sizeCalculation:f=this.sizeCalculation,noUpdateTTL:m=this.noUpdateTTL,noDeleteOnFetchRejection:c=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:d=this.allowStaleOnFetchRejection,ignoreFetchAbort:g=this.ignoreFetchAbort,allowStaleOnFetchAbort:A=this.allowStaleOnFetchAbort,context:p,forceRefresh:_=!1,status:l,signal:w}=e;if(!this.#v)return l&&(l.fetch="get"),this.get(t,{allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:h,status:l});let b={allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:h,ttl:n,noDisposeOnSet:o,size:r,sizeCalculation:f,noUpdateTTL:m,noDeleteOnFetchRejection:c,allowStaleOnFetchRejection:d,allowStaleOnFetchAbort:A,ignoreFetchAbort:g,status:l,signal:w},S=this.#s.get(t);if(S===void 0){l&&(l.fetch="miss");let u=this.#G(t,S,b,p);return u.__returned=u}else{let u=this.#t[S];if(this.#e(u)){let E=i&&u.__staleWhileFetching!==void 0;return l&&(l.fetch="inflight",E&&(l.returnedStale=!0)),E?u.__staleWhileFetching:u.__returned=u}let T=this.#p(S);if(!_&&!T)return l&&(l.fetch="hit"),this.#D(S),s&&this.#R(S),l&&this.#z(l,S),u;let F=this.#G(t,S,b,p),O=F.__staleWhileFetching!==void 0&&i;return l&&(l.fetch=T?"stale":"refresh",O&&T&&(l.returnedStale=!0)),O?F.__staleWhileFetching:F.__returned=F}}async forceFetch(t,e={}){let i=await this.fetch(t,e);if(i===void 0)throw new Error("fetch() returned undefined");return i}memo(t,e={}){let i=this.#I;if(!i)throw new Error("no memoMethod provided to constructor");let{context:s,forceRefresh:h,...n}=e,o=this.get(t,n);if(!h&&o!==void 0)return o;let r=i(t,o,{options:n,context:s});return this.set(t,r,n),r}get(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:h=this.noDeleteOnStaleGet,status:n}=e,o=this.#s.get(t);if(o!==void 0){let r=this.#t[o],f=this.#e(r);return n&&this.#z(n,o),this.#p(o)?(n&&(n.get="stale"),f?(n&&i&&r.__staleWhileFetching!==void 0&&(n.returnedStale=!0),i?r.__staleWhileFetching:void 0):(h||this.#E(t,"expire"),n&&i&&(n.returnedStale=!0),i?r:void 0)):(n&&(n.get="hit"),f?r.__staleWhileFetching:(this.#D(o),s&&this.#R(o),r))}else n&&(n.get="miss")}#k(t,e){this.#u[e]=t,this.#a[t]=e}#D(t){t!==this.#h&&(t===this.#l?this.#l=this.#a[t]:this.#k(this.#u[t],this.#a[t]),this.#k(this.#h,t),this.#h=t)}delete(t){return this.#E(t,"delete")}#E(t,e){let i=!1;if(this.#n!==0){let s=this.#s.get(t);if(s!==void 0)if(this.#g?.[s]&&(clearTimeout(this.#g?.[s]),this.#g[s]=void 0),i=!0,this.#n===1)this.#V(e);else{this.#W(s);let h=this.#t[s];if(this.#e(h)?h.__abortController.abort(new Error("deleted")):(this.#T||this.#f)&&(this.#T&&this.#w?.(h,t,e),this.#f&&this.#r?.push([h,t,e])),this.#s.delete(t),this.#i[s]=void 0,this.#t[s]=void 0,s===this.#h)this.#h=this.#u[s];else if(s===this.#l)this.#l=this.#a[s];else{let n=this.#u[s];this.#a[n]=this.#a[s];let o=this.#a[s];this.#u[o]=this.#u[s]}this.#n--,this.#b.push(s)}}if(this.#f&&this.#r?.length){let s=this.#r,h;for(;h=s?.shift();)this.#S?.(...h)}return i}clear(){return this.#V("delete")}#V(t){for(let e of this.#O({allowStale:!0})){let i=this.#t[e];if(this.#e(i))i.__abortController.abort(new Error("deleted"));else{let s=this.#i[e];this.#T&&this.#w?.(i,s,t),this.#f&&this.#r?.push([i,s,t])}}if(this.#s.clear(),this.#t.fill(void 0),this.#i.fill(void 0),this.#d&&this.#A){this.#d.fill(0),this.#A.fill(0);for(let e of this.#g??[])e!==void 0&&clearTimeout(e);this.#g?.fill(void 0)}if(this.#y&&this.#y.fill(0),this.#l=0,this.#h=0,this.#b.length=0,this.#_=0,this.#n=0,this.#f&&this.#r){let e=this.#r,i;for(;i=e?.shift();)this.#S?.(...i)}}};export{L as LRUCache}; +//# sourceMappingURL=index.min.js.map diff --git a/node_modules/lru-cache/dist/esm/package.json b/node_modules/lru-cache/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/lru-cache/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/lru-cache/index.d.ts b/node_modules/lru-cache/index.d.ts deleted file mode 100644 index b9375a8b96a71..0000000000000 --- a/node_modules/lru-cache/index.d.ts +++ /dev/null @@ -1,593 +0,0 @@ -// Type definitions for lru-cache 7.10.0 -// Project: https://github.com/isaacs/node-lru-cache -// Based initially on @types/lru-cache -// https://github.com/DefinitelyTyped/DefinitelyTyped -// used under the terms of the MIT License, shown below. -// -// DefinitelyTyped license: -// ------ -// MIT License -// -// Copyright (c) Microsoft Corporation. -// -// 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 -// ------ -// -// Changes by Isaac Z. Schlueter released under the terms found in the -// LICENSE file within this project. - -/// <reference lib="DOM" /> -//tslint:disable:member-access -declare class LRUCache<K, V> implements Iterable<[K, V]> { - constructor(options: LRUCache.Options<K, V>) - - /** - * Number of items in the cache. - * Alias for `cache.size` - * - * @deprecated since 7.0 use `cache.size` instead - */ - public readonly length: number - - public readonly max: number - public readonly maxSize: number - public readonly sizeCalculation: - | LRUCache.SizeCalculator<K, V> - | undefined - public readonly dispose: LRUCache.Disposer<K, V> - /** - * @since 7.4.0 - */ - public readonly disposeAfter: LRUCache.Disposer<K, V> | null - public readonly noDisposeOnSet: boolean - public readonly ttl: number - public readonly ttlResolution: number - public readonly ttlAutopurge: boolean - public readonly allowStale: boolean - public readonly updateAgeOnGet: boolean - /** - * @since 7.11.0 - */ - public readonly noDeleteOnStaleGet: boolean - /** - * @since 7.6.0 - */ - public readonly fetchMethod: LRUCache.Fetcher<K, V> | null - - /** - * The total number of items held in the cache at the current moment. - */ - public readonly size: number - - /** - * The total size of items in cache when using size tracking. - */ - public readonly calculatedSize: number - - /** - * Add a value to the cache. - */ - public set( - key: K, - value: V, - options?: LRUCache.SetOptions<K, V> - ): this - - /** - * Return a value from the cache. - * Will update the recency of the cache entry found. - * If the key is not found, `get()` will return `undefined`. - * This can be confusing when setting values specifically to `undefined`, - * as in `cache.set(key, undefined)`. Use `cache.has()` to determine - * whether a key is present in the cache at all. - */ - // tslint:disable-next-line:no-unnecessary-generics - public get<T = V>( - key: K, - options?: LRUCache.GetOptions - ): T | undefined - - /** - * Like `get()` but doesn't update recency or delete stale items. - * Returns `undefined` if the item is stale, unless `allowStale` is set - * either on the cache or in the options object. - */ - // tslint:disable-next-line:no-unnecessary-generics - public peek<T = V>( - key: K, - options?: LRUCache.PeekOptions - ): T | undefined - - /** - * Check if a key is in the cache, without updating the recency of use. - * Will return false if the item is stale, even though it is technically - * in the cache. - * Will not update item age unless `updateAgeOnHas` is set in the options - * or constructor. - */ - public has(key: K, options?: LRUCache.HasOptions): boolean - - /** - * Deletes a key out of the cache. - * Returns true if the key was deleted, false otherwise. - */ - public delete(key: K): boolean - - /** - * Clear the cache entirely, throwing away all values. - */ - public clear(): void - - /** - * Delete any stale entries. Returns true if anything was removed, false - * otherwise. - */ - public purgeStale(): boolean - - /** - * Find a value for which the supplied fn method returns a truthy value, - * similar to Array.find(). fn is called as fn(value, key, cache). - */ - // tslint:disable-next-line:no-unnecessary-generics - public find<T = V>( - callbackFn: ( - value: V, - key: K, - cache: this - ) => boolean | undefined | void, - options?: LRUCache.GetOptions - ): T - - /** - * Call the supplied function on each item in the cache, in order from - * most recently used to least recently used. fn is called as - * fn(value, key, cache). Does not update age or recenty of use. - */ - public forEach<T = this>( - callbackFn: (this: T, value: V, key: K, cache: this) => void, - thisArg?: T - ): void - - /** - * The same as `cache.forEach(...)` but items are iterated over in reverse - * order. (ie, less recently used items are iterated over first.) - */ - public rforEach<T = this>( - callbackFn: (this: T, value: V, key: K, cache: this) => void, - thisArg?: T - ): void - - /** - * Return a generator yielding the keys in the cache, - * in order from most recently used to least recently used. - */ - public keys(): Generator<K> - - /** - * Inverse order version of `cache.keys()` - * Return a generator yielding the keys in the cache, - * in order from least recently used to most recently used. - */ - public rkeys(): Generator<K> - - /** - * Return a generator yielding the values in the cache, - * in order from most recently used to least recently used. - */ - public values(): Generator<V> - - /** - * Inverse order version of `cache.values()` - * Return a generator yielding the values in the cache, - * in order from least recently used to most recently used. - */ - public rvalues(): Generator<V> - - /** - * Return a generator yielding `[key, value]` pairs, - * in order from most recently used to least recently used. - */ - public entries(): Generator<[K, V]> - - /** - * Inverse order version of `cache.entries()` - * Return a generator yielding `[key, value]` pairs, - * in order from least recently used to most recently used. - */ - public rentries(): Generator<[K, V]> - - /** - * Iterating over the cache itself yields the same results as - * `cache.entries()` - */ - public [Symbol.iterator](): Iterator<[K, V]> - - /** - * Return an array of [key, entry] objects which can be passed to - * cache.load() - */ - public dump(): Array<[K, LRUCache.Entry<V>]> - - /** - * Reset the cache and load in the items in entries in the order listed. - * Note that the shape of the resulting cache may be different if the - * same options are not used in both caches. - */ - public load( - cacheEntries: ReadonlyArray<[K, LRUCache.Entry<V>]> - ): void - - /** - * Evict the least recently used item, returning its value or `undefined` - * if cache is empty. - */ - public pop(): V | undefined - - /** - * Deletes a key out of the cache. - * - * @deprecated since 7.0 use delete() instead - */ - public del(key: K): boolean - - /** - * Clear the cache entirely, throwing away all values. - * - * @deprecated since 7.0 use clear() instead - */ - public reset(): void - - /** - * Manually iterates over the entire cache proactively pruning old entries. - * - * @deprecated since 7.0 use purgeStale() instead - */ - public prune(): boolean - - /** - * since: 7.6.0 - */ - // tslint:disable-next-line:no-unnecessary-generics - public fetch<ExpectedValue = V>( - key: K, - options?: LRUCache.FetchOptions<K, V> - ): Promise<ExpectedValue | undefined> - - /** - * since: 7.6.0 - */ - public getRemainingTTL(key: K): number -} - -declare namespace LRUCache { - type LRUMilliseconds = number - type DisposeReason = 'evict' | 'set' | 'delete' - - type SizeCalculator<K, V> = (value: V, key: K) => number - type Disposer<K, V> = ( - value: V, - key: K, - reason: DisposeReason - ) => void - type Fetcher<K, V> = ( - key: K, - staleValue: V, - options: FetcherOptions<K, V> - ) => Promise<V | void | undefined> | V | void | undefined - - interface DeprecatedOptions<K, V> { - /** - * alias for ttl - * - * @deprecated since 7.0 use options.ttl instead - */ - maxAge?: number - - /** - * alias for sizeCalculation - * - * @deprecated since 7.0 use options.sizeCalculation instead - */ - length?: SizeCalculator<K, V> - - /** - * alias for allowStale - * - * @deprecated since 7.0 use options.allowStale instead - */ - stale?: boolean - } - - interface LimitedByCount { - /** - * The number of most recently used items to keep. - * Note that we may store fewer items than this if maxSize is hit. - */ - max: number - } - - interface LimitedBySize<K, V> { - /** - * If you wish to track item size, you must provide a maxSize - * note that we still will only keep up to max *actual items*, - * if max is set, so size tracking may cause fewer than max items - * to be stored. At the extreme, a single item of maxSize size - * will cause everything else in the cache to be dropped when it - * is added. Use with caution! - * Note also that size tracking can negatively impact performance, - * though for most cases, only minimally. - */ - maxSize: number - - /** - * Function to calculate size of items. Useful if storing strings or - * buffers or other items where memory size depends on the object itself. - * Also note that oversized items do NOT immediately get dropped from - * the cache, though they will cause faster turnover in the storage. - */ - sizeCalculation?: SizeCalculator<K, V> - } - - interface LimitedByTTL { - /** - * Max time in milliseconds for items to live in cache before they are - * considered stale. Note that stale items are NOT preemptively removed - * by default, and MAY live in the cache, contributing to its LRU max, - * long after they have expired. - * - * Also, as this cache is optimized for LRU/MRU operations, some of - * the staleness/TTL checks will reduce performance, as they will incur - * overhead by deleting items. - * - * Must be an integer number of ms, defaults to 0, which means "no TTL" - */ - ttl: number - - /** - * Boolean flag to tell the cache to not update the TTL when - * setting a new value for an existing key (ie, when updating a value - * rather than inserting a new value). Note that the TTL value is - * _always_ set (if provided) when adding a new entry into the cache. - * - * @default false - * @since 7.4.0 - */ - noUpdateTTL?: boolean - - /** - * Minimum amount of time in ms in which to check for staleness. - * Defaults to 1, which means that the current time is checked - * at most once per millisecond. - * - * Set to 0 to check the current time every time staleness is tested. - * (This reduces performance, and is theoretically unnecessary.) - * - * Setting this to a higher value will improve performance somewhat - * while using ttl tracking, albeit at the expense of keeping stale - * items around a bit longer than intended. - * - * @default 1 - * @since 7.1.0 - */ - ttlResolution?: number - - /** - * Preemptively remove stale items from the cache. - * Note that this may significantly degrade performance, - * especially if the cache is storing a large number of items. - * It is almost always best to just leave the stale items in - * the cache, and let them fall out as new items are added. - * - * Note that this means that allowStale is a bit pointless, - * as stale items will be deleted almost as soon as they expire. - * - * Use with caution! - * - * @default false - * @since 7.1.0 - */ - ttlAutopurge?: boolean - - /** - * Return stale items from cache.get() before disposing of them. - * Return stale values from cache.fetch() while performing a call - * to the `fetchMethod` in the background. - * - * @default false - */ - allowStale?: boolean - - /** - * Update the age of items on cache.get(), renewing their TTL - * - * @default false - */ - updateAgeOnGet?: boolean - - /** - * Do not delete stale items when they are retrieved with cache.get() - * Note that the get() return value will still be `undefined` unless - * allowStale is true. - * - * @default false - * @since 7.11.0 - */ - noDeleteOnStaleGet?: boolean - - /** - * Update the age of items on cache.has(), renewing their TTL - * - * @default false - */ - updateAgeOnHas?: boolean - } - - type SafetyBounds<K, V> = - | LimitedByCount - | LimitedBySize<K, V> - | LimitedByTTL - - // options shared by all three of the limiting scenarios - interface SharedOptions<K, V> { - /** - * Function that is called on items when they are dropped from the cache. - * This can be handy if you want to close file descriptors or do other - * cleanup tasks when items are no longer accessible. Called with `key, - * value`. It's called before actually removing the item from the - * internal cache, so it is *NOT* safe to re-add them. - * Use `disposeAfter` if you wish to dispose items after they have been - * full removed, when it is safe to add them back to the cache. - */ - dispose?: Disposer<K, V> - - /** - * The same as dispose, but called *after* the entry is completely - * removed and the cache is once again in a clean state. It is safe to - * add an item right back into the cache at this point. - * However, note that it is *very* easy to inadvertently create infinite - * recursion this way. - * - * @since 7.3.0 - */ - disposeAfter?: Disposer<K, V> - - /** - * Set to true to suppress calling the dispose() function if the entry - * key is still accessible within the cache. - * This may be overridden by passing an options object to cache.set(). - * - * @default false - */ - noDisposeOnSet?: boolean - - /** - * `fetchMethod` Function that is used to make background asynchronous - * fetches. Called with `fetchMethod(key, staleValue)`. May return a - * Promise. - * - * If `fetchMethod` is not provided, then `cache.fetch(key)` is - * equivalent to `Promise.resolve(cache.get(key))`. - * - * @since 7.6.0 - */ - fetchMethod?: LRUCache.Fetcher<K, V> - - /** - * Set to true to suppress the deletion of stale data when a - * `fetchMethod` throws an error or returns a rejected promise - * - * @default false - * @since 7.10.0 - */ - noDeleteOnFetchRejection?: boolean - - /** - * Set to any value in the constructor or fetch() options to - * pass arbitrary data to the fetch() method in the options.context - * field. - * - * @since 7.12.0 - */ - fetchContext?: any - } - - type Options<K, V> = SharedOptions<K, V> & - DeprecatedOptions<K, V> & - SafetyBounds<K, V> - - /** - * options which override the options set in the LRUCache constructor - * when making `cache.set()` calls. - */ - interface SetOptions<K, V> { - /** - * A value for the size of the entry, prevents calls to - * `sizeCalculation` function. - */ - size?: number - sizeCalculation?: SizeCalculator<K, V> - ttl?: number - start?: number - noDisposeOnSet?: boolean - noUpdateTTL?: boolean - } - - /** - * options which override the options set in the LRUCAche constructor - * when making `cache.has()` calls. - */ - interface HasOptions { - updateAgeOnHas?: boolean - } - - /** - * options which override the options set in the LRUCache constructor - * when making `cache.get()` calls. - */ - interface GetOptions { - allowStale?: boolean - updateAgeOnGet?: boolean - noDeleteOnStaleGet?: boolean - } - - /** - * options which override the options set in the LRUCache constructor - * when making `cache.peek()` calls. - */ - interface PeekOptions { - allowStale?: boolean - } - - interface FetcherFetchOptions<K, V> { - allowStale?: boolean - updateAgeOnGet?: boolean - noDeleteOnStaleGet?: boolean - size?: number - sizeCalculation?: SizeCalculator<K, V> - ttl?: number - noDisposeOnSet?: boolean - noUpdateTTL?: boolean - noDeleteOnFetchRejection?: boolean - } - - /** - * options which override the options set in the LRUCache constructor - * when making `cache.fetch()` calls. - * This is the union of GetOptions and SetOptions, plus the - * `noDeleteOnFetchRejection` and `fetchContext` fields. - */ - interface FetchOptions<K, V> extends FetcherFetchOptions<K, V> { - fetchContext?: any - } - - interface FetcherOptions<K, V> { - signal: AbortSignal - options: FetcherFetchOptions<K, V> - context: any - } - - interface Entry<V> { - value: V - ttl?: number - size?: number - start?: number - } -} - -export = LRUCache diff --git a/node_modules/lru-cache/index.js b/node_modules/lru-cache/index.js deleted file mode 100644 index 479ffc8656b70..0000000000000 --- a/node_modules/lru-cache/index.js +++ /dev/null @@ -1,980 +0,0 @@ -const perf = - typeof performance === 'object' && - performance && - typeof performance.now === 'function' - ? performance - : Date - -const hasAbortController = typeof AbortController === 'function' - -// minimal backwards-compatibility polyfill -// this doesn't have nearly all the checks and whatnot that -// actual AbortController/Signal has, but it's enough for -// our purposes, and if used properly, behaves the same. -const AC = hasAbortController - ? AbortController - : class AbortController { - constructor() { - this.signal = new AS() - } - abort() { - this.signal.dispatchEvent('abort') - } - } - -const hasAbortSignal = typeof AbortSignal === 'function' -// Some polyfills put this on the AC class, not global -const hasACAbortSignal = typeof AC.AbortSignal === 'function' -const AS = hasAbortSignal - ? AbortSignal - : hasACAbortSignal - ? AC.AbortController - : class AbortSignal { - constructor() { - this.aborted = false - this._listeners = [] - } - dispatchEvent(type) { - if (type === 'abort') { - this.aborted = true - const e = { type, target: this } - this.onabort(e) - this._listeners.forEach(f => f(e), this) - } - } - onabort() {} - addEventListener(ev, fn) { - if (ev === 'abort') { - this._listeners.push(fn) - } - } - removeEventListener(ev, fn) { - if (ev === 'abort') { - this._listeners = this._listeners.filter(f => f !== fn) - } - } - } - -const warned = new Set() -const deprecatedOption = (opt, instead) => { - const code = `LRU_CACHE_OPTION_${opt}` - if (shouldWarn(code)) { - warn(code, `${opt} option`, `options.${instead}`, LRUCache) - } -} -const deprecatedMethod = (method, instead) => { - const code = `LRU_CACHE_METHOD_${method}` - if (shouldWarn(code)) { - const { prototype } = LRUCache - const { get } = Object.getOwnPropertyDescriptor(prototype, method) - warn(code, `${method} method`, `cache.${instead}()`, get) - } -} -const deprecatedProperty = (field, instead) => { - const code = `LRU_CACHE_PROPERTY_${field}` - if (shouldWarn(code)) { - const { prototype } = LRUCache - const { get } = Object.getOwnPropertyDescriptor(prototype, field) - warn(code, `${field} property`, `cache.${instead}`, get) - } -} - -const emitWarning = (...a) => { - typeof process === 'object' && - process && - typeof process.emitWarning === 'function' - ? process.emitWarning(...a) - : console.error(...a) -} - -const shouldWarn = code => !warned.has(code) - -const warn = (code, what, instead, fn) => { - warned.add(code) - const msg = `The ${what} is deprecated. Please use ${instead} instead.` - emitWarning(msg, 'DeprecationWarning', code, fn) -} - -const isPosInt = n => n && n === Math.floor(n) && n > 0 && isFinite(n) - -/* istanbul ignore next - This is a little bit ridiculous, tbh. - * The maximum array length is 2^32-1 or thereabouts on most JS impls. - * And well before that point, you're caching the entire world, I mean, - * that's ~32GB of just integers for the next/prev links, plus whatever - * else to hold that many keys and values. Just filling the memory with - * zeroes at init time is brutal when you get that big. - * But why not be complete? - * Maybe in the future, these limits will have expanded. */ -const getUintArray = max => - !isPosInt(max) - ? null - : max <= Math.pow(2, 8) - ? Uint8Array - : max <= Math.pow(2, 16) - ? Uint16Array - : max <= Math.pow(2, 32) - ? Uint32Array - : max <= Number.MAX_SAFE_INTEGER - ? ZeroArray - : null - -class ZeroArray extends Array { - constructor(size) { - super(size) - this.fill(0) - } -} - -class Stack { - constructor(max) { - if (max === 0) { - return [] - } - const UintArray = getUintArray(max) - this.heap = new UintArray(max) - this.length = 0 - } - push(n) { - this.heap[this.length++] = n - } - pop() { - return this.heap[--this.length] - } -} - -class LRUCache { - constructor(options = {}) { - const { - max = 0, - ttl, - ttlResolution = 1, - ttlAutopurge, - updateAgeOnGet, - updateAgeOnHas, - allowStale, - dispose, - disposeAfter, - noDisposeOnSet, - noUpdateTTL, - maxSize = 0, - sizeCalculation, - fetchMethod, - fetchContext, - noDeleteOnFetchRejection, - noDeleteOnStaleGet, - } = options - - // deprecated options, don't trigger a warning for getting them if - // the thing being passed in is another LRUCache we're copying. - const { length, maxAge, stale } = - options instanceof LRUCache ? {} : options - - if (max !== 0 && !isPosInt(max)) { - throw new TypeError('max option must be a nonnegative integer') - } - - const UintArray = max ? getUintArray(max) : Array - if (!UintArray) { - throw new Error('invalid max value: ' + max) - } - - this.max = max - this.maxSize = maxSize - this.sizeCalculation = sizeCalculation || length - if (this.sizeCalculation) { - if (!this.maxSize) { - throw new TypeError( - 'cannot set sizeCalculation without setting maxSize' - ) - } - if (typeof this.sizeCalculation !== 'function') { - throw new TypeError('sizeCalculation set to non-function') - } - } - - this.fetchMethod = fetchMethod || null - if (this.fetchMethod && typeof this.fetchMethod !== 'function') { - throw new TypeError( - 'fetchMethod must be a function if specified' - ) - } - - this.fetchContext = fetchContext - if (!this.fetchMethod && fetchContext !== undefined) { - throw new TypeError( - 'cannot set fetchContext without fetchMethod' - ) - } - - this.keyMap = new Map() - this.keyList = new Array(max).fill(null) - this.valList = new Array(max).fill(null) - this.next = new UintArray(max) - this.prev = new UintArray(max) - this.head = 0 - this.tail = 0 - this.free = new Stack(max) - this.initialFill = 1 - this.size = 0 - - if (typeof dispose === 'function') { - this.dispose = dispose - } - if (typeof disposeAfter === 'function') { - this.disposeAfter = disposeAfter - this.disposed = [] - } else { - this.disposeAfter = null - this.disposed = null - } - this.noDisposeOnSet = !!noDisposeOnSet - this.noUpdateTTL = !!noUpdateTTL - this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection - - if (this.maxSize !== 0) { - if (!isPosInt(this.maxSize)) { - throw new TypeError( - 'maxSize must be a positive integer if specified' - ) - } - this.initializeSizeTracking() - } - - this.allowStale = !!allowStale || !!stale - this.noDeleteOnStaleGet = !!noDeleteOnStaleGet - this.updateAgeOnGet = !!updateAgeOnGet - this.updateAgeOnHas = !!updateAgeOnHas - this.ttlResolution = - isPosInt(ttlResolution) || ttlResolution === 0 - ? ttlResolution - : 1 - this.ttlAutopurge = !!ttlAutopurge - this.ttl = ttl || maxAge || 0 - if (this.ttl) { - if (!isPosInt(this.ttl)) { - throw new TypeError( - 'ttl must be a positive integer if specified' - ) - } - this.initializeTTLTracking() - } - - // do not allow completely unbounded caches - if (this.max === 0 && this.ttl === 0 && this.maxSize === 0) { - throw new TypeError( - 'At least one of max, maxSize, or ttl is required' - ) - } - if (!this.ttlAutopurge && !this.max && !this.maxSize) { - const code = 'LRU_CACHE_UNBOUNDED' - if (shouldWarn(code)) { - warned.add(code) - const msg = - 'TTL caching without ttlAutopurge, max, or maxSize can ' + - 'result in unbounded memory consumption.' - emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache) - } - } - - if (stale) { - deprecatedOption('stale', 'allowStale') - } - if (maxAge) { - deprecatedOption('maxAge', 'ttl') - } - if (length) { - deprecatedOption('length', 'sizeCalculation') - } - } - - getRemainingTTL(key) { - return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0 - } - - initializeTTLTracking() { - this.ttls = new ZeroArray(this.max) - this.starts = new ZeroArray(this.max) - - this.setItemTTL = (index, ttl, start = perf.now()) => { - this.starts[index] = ttl !== 0 ? start : 0 - this.ttls[index] = ttl - if (ttl !== 0 && this.ttlAutopurge) { - const t = setTimeout(() => { - if (this.isStale(index)) { - this.delete(this.keyList[index]) - } - }, ttl + 1) - /* istanbul ignore else - unref() not supported on all platforms */ - if (t.unref) { - t.unref() - } - } - } - - this.updateItemAge = index => { - this.starts[index] = this.ttls[index] !== 0 ? perf.now() : 0 - } - - // debounce calls to perf.now() to 1s so we're not hitting - // that costly call repeatedly. - let cachedNow = 0 - const getNow = () => { - const n = perf.now() - if (this.ttlResolution > 0) { - cachedNow = n - const t = setTimeout( - () => (cachedNow = 0), - this.ttlResolution - ) - /* istanbul ignore else - not available on all platforms */ - if (t.unref) { - t.unref() - } - } - return n - } - - this.getRemainingTTL = key => { - const index = this.keyMap.get(key) - if (index === undefined) { - return 0 - } - return this.ttls[index] === 0 || this.starts[index] === 0 - ? Infinity - : this.starts[index] + - this.ttls[index] - - (cachedNow || getNow()) - } - - this.isStale = index => { - return ( - this.ttls[index] !== 0 && - this.starts[index] !== 0 && - (cachedNow || getNow()) - this.starts[index] > - this.ttls[index] - ) - } - } - updateItemAge(index) {} - setItemTTL(index, ttl, start) {} - isStale(index) { - return false - } - - initializeSizeTracking() { - this.calculatedSize = 0 - this.sizes = new ZeroArray(this.max) - this.removeItemSize = index => - (this.calculatedSize -= this.sizes[index]) - this.requireSize = (k, v, size, sizeCalculation) => { - if (!isPosInt(size)) { - if (sizeCalculation) { - if (typeof sizeCalculation !== 'function') { - throw new TypeError('sizeCalculation must be a function') - } - size = sizeCalculation(v, k) - if (!isPosInt(size)) { - throw new TypeError( - 'sizeCalculation return invalid (expect positive integer)' - ) - } - } else { - throw new TypeError( - 'invalid size value (must be positive integer)' - ) - } - } - return size - } - this.addItemSize = (index, v, k, size) => { - this.sizes[index] = size - const maxSize = this.maxSize - this.sizes[index] - while (this.calculatedSize > maxSize) { - this.evict(true) - } - this.calculatedSize += this.sizes[index] - } - } - removeItemSize(index) {} - addItemSize(index, v, k, size) {} - requireSize(k, v, size, sizeCalculation) { - if (size || sizeCalculation) { - throw new TypeError( - 'cannot set size without setting maxSize on cache' - ) - } - } - - *indexes({ allowStale = this.allowStale } = {}) { - if (this.size) { - for (let i = this.tail; true; ) { - if (!this.isValidIndex(i)) { - break - } - if (allowStale || !this.isStale(i)) { - yield i - } - if (i === this.head) { - break - } else { - i = this.prev[i] - } - } - } - } - - *rindexes({ allowStale = this.allowStale } = {}) { - if (this.size) { - for (let i = this.head; true; ) { - if (!this.isValidIndex(i)) { - break - } - if (allowStale || !this.isStale(i)) { - yield i - } - if (i === this.tail) { - break - } else { - i = this.next[i] - } - } - } - } - - isValidIndex(index) { - return this.keyMap.get(this.keyList[index]) === index - } - - *entries() { - for (const i of this.indexes()) { - yield [this.keyList[i], this.valList[i]] - } - } - *rentries() { - for (const i of this.rindexes()) { - yield [this.keyList[i], this.valList[i]] - } - } - - *keys() { - for (const i of this.indexes()) { - yield this.keyList[i] - } - } - *rkeys() { - for (const i of this.rindexes()) { - yield this.keyList[i] - } - } - - *values() { - for (const i of this.indexes()) { - yield this.valList[i] - } - } - *rvalues() { - for (const i of this.rindexes()) { - yield this.valList[i] - } - } - - [Symbol.iterator]() { - return this.entries() - } - - find(fn, getOptions = {}) { - for (const i of this.indexes()) { - if (fn(this.valList[i], this.keyList[i], this)) { - return this.get(this.keyList[i], getOptions) - } - } - } - - forEach(fn, thisp = this) { - for (const i of this.indexes()) { - fn.call(thisp, this.valList[i], this.keyList[i], this) - } - } - - rforEach(fn, thisp = this) { - for (const i of this.rindexes()) { - fn.call(thisp, this.valList[i], this.keyList[i], this) - } - } - - get prune() { - deprecatedMethod('prune', 'purgeStale') - return this.purgeStale - } - - purgeStale() { - let deleted = false - for (const i of this.rindexes({ allowStale: true })) { - if (this.isStale(i)) { - this.delete(this.keyList[i]) - deleted = true - } - } - return deleted - } - - dump() { - const arr = [] - for (const i of this.indexes({ allowStale: true })) { - const key = this.keyList[i] - const v = this.valList[i] - const value = this.isBackgroundFetch(v) ? v.__staleWhileFetching : v - const entry = { value } - if (this.ttls) { - entry.ttl = this.ttls[i] - // always dump the start relative to a portable timestamp - // it's ok for this to be a bit slow, it's a rare operation. - const age = perf.now() - this.starts[i] - entry.start = Math.floor(Date.now() - age) - } - if (this.sizes) { - entry.size = this.sizes[i] - } - arr.unshift([key, entry]) - } - return arr - } - - load(arr) { - this.clear() - for (const [key, entry] of arr) { - if (entry.start) { - // entry.start is a portable timestamp, but we may be using - // node's performance.now(), so calculate the offset. - // it's ok for this to be a bit slow, it's a rare operation. - const age = Date.now() - entry.start - entry.start = perf.now() - age - } - this.set(key, entry.value, entry) - } - } - - dispose(v, k, reason) {} - - set( - k, - v, - { - ttl = this.ttl, - start, - noDisposeOnSet = this.noDisposeOnSet, - size = 0, - sizeCalculation = this.sizeCalculation, - noUpdateTTL = this.noUpdateTTL, - } = {} - ) { - size = this.requireSize(k, v, size, sizeCalculation) - let index = this.size === 0 ? undefined : this.keyMap.get(k) - if (index === undefined) { - // addition - index = this.newIndex() - this.keyList[index] = k - this.valList[index] = v - this.keyMap.set(k, index) - this.next[this.tail] = index - this.prev[index] = this.tail - this.tail = index - this.size++ - this.addItemSize(index, v, k, size) - noUpdateTTL = false - } else { - // update - const oldVal = this.valList[index] - if (v !== oldVal) { - if (this.isBackgroundFetch(oldVal)) { - oldVal.__abortController.abort() - } else { - if (!noDisposeOnSet) { - this.dispose(oldVal, k, 'set') - if (this.disposeAfter) { - this.disposed.push([oldVal, k, 'set']) - } - } - } - this.removeItemSize(index) - this.valList[index] = v - this.addItemSize(index, v, k, size) - } - this.moveToTail(index) - } - if (ttl !== 0 && this.ttl === 0 && !this.ttls) { - this.initializeTTLTracking() - } - if (!noUpdateTTL) { - this.setItemTTL(index, ttl, start) - } - if (this.disposeAfter) { - while (this.disposed.length) { - this.disposeAfter(...this.disposed.shift()) - } - } - return this - } - - newIndex() { - if (this.size === 0) { - return this.tail - } - if (this.size === this.max && this.max !== 0) { - return this.evict(false) - } - if (this.free.length !== 0) { - return this.free.pop() - } - // initial fill, just keep writing down the list - return this.initialFill++ - } - - pop() { - if (this.size) { - const val = this.valList[this.head] - this.evict(true) - return val - } - } - - evict(free) { - const head = this.head - const k = this.keyList[head] - const v = this.valList[head] - if (this.isBackgroundFetch(v)) { - v.__abortController.abort() - } else { - this.dispose(v, k, 'evict') - if (this.disposeAfter) { - this.disposed.push([v, k, 'evict']) - } - } - this.removeItemSize(head) - // if we aren't about to use the index, then null these out - if (free) { - this.keyList[head] = null - this.valList[head] = null - this.free.push(head) - } - this.head = this.next[head] - this.keyMap.delete(k) - this.size-- - return head - } - - has(k, { updateAgeOnHas = this.updateAgeOnHas } = {}) { - const index = this.keyMap.get(k) - if (index !== undefined) { - if (!this.isStale(index)) { - if (updateAgeOnHas) { - this.updateItemAge(index) - } - return true - } - } - return false - } - - // like get(), but without any LRU updating or TTL expiration - peek(k, { allowStale = this.allowStale } = {}) { - const index = this.keyMap.get(k) - if (index !== undefined && (allowStale || !this.isStale(index))) { - return this.valList[index] - } - } - - backgroundFetch(k, index, options, context) { - const v = index === undefined ? undefined : this.valList[index] - if (this.isBackgroundFetch(v)) { - return v - } - const ac = new AC() - const fetchOpts = { - signal: ac.signal, - options, - context, - } - const cb = v => { - if (!ac.signal.aborted) { - this.set(k, v, fetchOpts.options) - } - return v - } - const eb = er => { - if (this.valList[index] === p) { - const del = - !options.noDeleteOnFetchRejection || - p.__staleWhileFetching === undefined - if (del) { - this.delete(k) - } else { - // still replace the *promise* with the stale value, - // since we are done with the promise at this point. - this.valList[index] = p.__staleWhileFetching - } - } - if (p.__returned === p) { - throw er - } - } - const pcall = res => res(this.fetchMethod(k, v, fetchOpts)) - const p = new Promise(pcall).then(cb, eb) - p.__abortController = ac - p.__staleWhileFetching = v - p.__returned = null - if (index === undefined) { - this.set(k, p, fetchOpts.options) - index = this.keyMap.get(k) - } else { - this.valList[index] = p - } - return p - } - - isBackgroundFetch(p) { - return ( - p && - typeof p === 'object' && - typeof p.then === 'function' && - Object.prototype.hasOwnProperty.call( - p, - '__staleWhileFetching' - ) && - Object.prototype.hasOwnProperty.call(p, '__returned') && - (p.__returned === p || p.__returned === null) - ) - } - - // this takes the union of get() and set() opts, because it does both - async fetch( - k, - { - // get options - allowStale = this.allowStale, - updateAgeOnGet = this.updateAgeOnGet, - noDeleteOnStaleGet = this.noDeleteOnStaleGet, - // set options - ttl = this.ttl, - noDisposeOnSet = this.noDisposeOnSet, - size = 0, - sizeCalculation = this.sizeCalculation, - noUpdateTTL = this.noUpdateTTL, - // fetch exclusive options - noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, - fetchContext = this.fetchContext, - } = {} - ) { - if (!this.fetchMethod) { - return this.get(k, { allowStale, updateAgeOnGet, noDeleteOnStaleGet }) - } - - const options = { - allowStale, - updateAgeOnGet, - noDeleteOnStaleGet, - ttl, - noDisposeOnSet, - size, - sizeCalculation, - noUpdateTTL, - noDeleteOnFetchRejection, - } - - let index = this.keyMap.get(k) - if (index === undefined) { - const p = this.backgroundFetch(k, index, options, fetchContext) - return (p.__returned = p) - } else { - // in cache, maybe already fetching - const v = this.valList[index] - if (this.isBackgroundFetch(v)) { - return allowStale && v.__staleWhileFetching !== undefined - ? v.__staleWhileFetching - : (v.__returned = v) - } - - if (!this.isStale(index)) { - this.moveToTail(index) - if (updateAgeOnGet) { - this.updateItemAge(index) - } - return v - } - - // ok, it is stale, and not already fetching - // refresh the cache. - const p = this.backgroundFetch(k, index, options, fetchContext) - return allowStale && p.__staleWhileFetching !== undefined - ? p.__staleWhileFetching - : (p.__returned = p) - } - } - - get( - k, - { - allowStale = this.allowStale, - updateAgeOnGet = this.updateAgeOnGet, - noDeleteOnStaleGet = this.noDeleteOnStaleGet, - } = {} - ) { - const index = this.keyMap.get(k) - if (index !== undefined) { - const value = this.valList[index] - const fetching = this.isBackgroundFetch(value) - if (this.isStale(index)) { - // delete only if not an in-flight background fetch - if (!fetching) { - if (!noDeleteOnStaleGet) { - this.delete(k) - } - return allowStale ? value : undefined - } else { - return allowStale ? value.__staleWhileFetching : undefined - } - } else { - // if we're currently fetching it, we don't actually have it yet - // it's not stale, which means this isn't a staleWhileRefetching, - // so we just return undefined - if (fetching) { - return undefined - } - this.moveToTail(index) - if (updateAgeOnGet) { - this.updateItemAge(index) - } - return value - } - } - } - - connect(p, n) { - this.prev[n] = p - this.next[p] = n - } - - moveToTail(index) { - // if tail already, nothing to do - // if head, move head to next[index] - // else - // move next[prev[index]] to next[index] (head has no prev) - // move prev[next[index]] to prev[index] - // prev[index] = tail - // next[tail] = index - // tail = index - if (index !== this.tail) { - if (index === this.head) { - this.head = this.next[index] - } else { - this.connect(this.prev[index], this.next[index]) - } - this.connect(this.tail, index) - this.tail = index - } - } - - get del() { - deprecatedMethod('del', 'delete') - return this.delete - } - - delete(k) { - let deleted = false - if (this.size !== 0) { - const index = this.keyMap.get(k) - if (index !== undefined) { - deleted = true - if (this.size === 1) { - this.clear() - } else { - this.removeItemSize(index) - const v = this.valList[index] - if (this.isBackgroundFetch(v)) { - v.__abortController.abort() - } else { - this.dispose(v, k, 'delete') - if (this.disposeAfter) { - this.disposed.push([v, k, 'delete']) - } - } - this.keyMap.delete(k) - this.keyList[index] = null - this.valList[index] = null - if (index === this.tail) { - this.tail = this.prev[index] - } else if (index === this.head) { - this.head = this.next[index] - } else { - this.next[this.prev[index]] = this.next[index] - this.prev[this.next[index]] = this.prev[index] - } - this.size-- - this.free.push(index) - } - } - } - if (this.disposed) { - while (this.disposed.length) { - this.disposeAfter(...this.disposed.shift()) - } - } - return deleted - } - - clear() { - for (const index of this.rindexes({ allowStale: true })) { - const v = this.valList[index] - if (this.isBackgroundFetch(v)) { - v.__abortController.abort() - } else { - const k = this.keyList[index] - this.dispose(v, k, 'delete') - if (this.disposeAfter) { - this.disposed.push([v, k, 'delete']) - } - } - } - - this.keyMap.clear() - this.valList.fill(null) - this.keyList.fill(null) - if (this.ttls) { - this.ttls.fill(0) - this.starts.fill(0) - } - if (this.sizes) { - this.sizes.fill(0) - } - this.head = 0 - this.tail = 0 - this.initialFill = 1 - this.free.length = 0 - this.calculatedSize = 0 - this.size = 0 - if (this.disposed) { - while (this.disposed.length) { - this.disposeAfter(...this.disposed.shift()) - } - } - } - - get reset() { - deprecatedMethod('reset', 'clear') - return this.clear - } - - get length() { - deprecatedProperty('length', 'size') - return this.size - } - - static get AbortController() { - return AC - } - static get AbortSignal() { - return AS - } -} - -module.exports = LRUCache diff --git a/node_modules/lru-cache/package.json b/node_modules/lru-cache/package.json index c023ce6c49aca..5b271f0dda7ae 100644 --- a/node_modules/lru-cache/package.json +++ b/node_modules/lru-cache/package.json @@ -1,73 +1,101 @@ { "name": "lru-cache", "description": "A cache object that deletes the least-recently-used items.", - "version": "7.12.0", + "version": "11.2.5", "author": "Isaac Z. Schlueter <i@izs.me>", "keywords": [ "mru", "lru", "cache" ], + "sideEffects": false, "scripts": { - "build": "", - "size": "size-limit", + "build": "npm run prepare", + "prepare": "tshy && bash fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", "test": "tap", "snap": "tap", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", - "format": "prettier --write ." + "format": "prettier --write .", + "typedoc": "typedoc --tsconfig ./.tshy/esm.json ./src/*.ts", + "benchmark-results-typedoc": "bash scripts/benchmark-results-typedoc.sh", + "prebenchmark": "npm run prepare", + "benchmark": "make -C benchmark", + "preprofile": "npm run prepare", + "profile": "make -C benchmark profile" + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "tshy": { + "exports": { + ".": "./src/index.ts", + "./min": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.min.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.min.js" + } + } + } + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/node-lru-cache.git" }, - "main": "index.js", - "repository": "git://github.com/isaacs/node-lru-cache.git", "devDependencies": { - "@size-limit/preset-small-lib": "^7.0.8", - "@types/node": "^17.0.31", - "@types/tap": "^15.0.6", + "@types/node": "^24.3.0", "benchmark": "^2.1.4", - "c8": "^7.11.2", - "clock-mock": "^1.0.4", - "eslint-config-prettier": "^8.5.0", - "prettier": "^2.6.2", - "size-limit": "^7.0.8", - "tap": "^16.0.1", - "ts-node": "^10.7.0", - "tslib": "^2.4.0", - "typescript": "^4.6.4" + "esbuild": "^0.25.9", + "marked": "^4.2.12", + "mkdirp": "^3.0.1", + "prettier": "^3.6.2", + "tap": "^21.1.0", + "tshy": "^3.0.2", + "typedoc": "^0.28.12" }, - "license": "ISC", + "license": "BlueOak-1.0.0", "files": [ - "index.js", - "index.d.ts" + "dist" ], "engines": { - "node": ">=12" - }, - "prettier": { - "semi": false, - "printWidth": 70, - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "jsxSingleQuote": false, - "bracketSameLine": true, - "arrowParens": "avoid", - "endOfLine": "lf" + "node": "20 || >=22" }, "tap": { - "nyc-arg": [ - "--include=index.js" - ], "node-arg": [ - "--expose-gc", - "--require", - "ts-node/register" + "--expose-gc" ], - "ts": false + "plugin": [ + "@tapjs/clock" + ] }, - "size-limit": [ - { - "path": "./index.js" + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + }, + "./min": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.min.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.min.js" + } } - ] + }, + "type": "module", + "module": "./dist/esm/index.js" } diff --git a/node_modules/make-fetch-happen/lib/agent.js b/node_modules/make-fetch-happen/lib/agent.js deleted file mode 100644 index dd68492ed7ea7..0000000000000 --- a/node_modules/make-fetch-happen/lib/agent.js +++ /dev/null @@ -1,214 +0,0 @@ -'use strict' -const LRU = require('lru-cache') -const url = require('url') -const isLambda = require('is-lambda') -const dns = require('./dns.js') - -const AGENT_CACHE = new LRU({ max: 50 }) -const HttpAgent = require('agentkeepalive') -const HttpsAgent = HttpAgent.HttpsAgent - -module.exports = getAgent - -const getAgentTimeout = timeout => - typeof timeout !== 'number' || !timeout ? 0 : timeout + 1 - -const getMaxSockets = maxSockets => maxSockets || 15 - -function getAgent (uri, opts) { - const parsedUri = new url.URL(typeof uri === 'string' ? uri : uri.url) - const isHttps = parsedUri.protocol === 'https:' - const pxuri = getProxyUri(parsedUri.href, opts) - - // If opts.timeout is zero, set the agentTimeout to zero as well. A timeout - // of zero disables the timeout behavior (OS limits still apply). Else, if - // opts.timeout is a non-zero value, set it to timeout + 1, to ensure that - // the node-fetch-npm timeout will always fire first, giving us more - // consistent errors. - const agentTimeout = getAgentTimeout(opts.timeout) - const agentMaxSockets = getMaxSockets(opts.maxSockets) - - const key = [ - `https:${isHttps}`, - pxuri - ? `proxy:${pxuri.protocol}//${pxuri.host}:${pxuri.port}` - : '>no-proxy<', - `local-address:${opts.localAddress || '>no-local-address<'}`, - `strict-ssl:${isHttps ? opts.rejectUnauthorized : '>no-strict-ssl<'}`, - `ca:${(isHttps && opts.ca) || '>no-ca<'}`, - `cert:${(isHttps && opts.cert) || '>no-cert<'}`, - `key:${(isHttps && opts.key) || '>no-key<'}`, - `timeout:${agentTimeout}`, - `maxSockets:${agentMaxSockets}`, - ].join(':') - - if (opts.agent != null) { // `agent: false` has special behavior! - return opts.agent - } - - // keep alive in AWS lambda makes no sense - const lambdaAgent = !isLambda ? null - : isHttps ? require('https').globalAgent - : require('http').globalAgent - - if (isLambda && !pxuri) { - return lambdaAgent - } - - if (AGENT_CACHE.peek(key)) { - return AGENT_CACHE.get(key) - } - - if (pxuri) { - const pxopts = isLambda ? { - ...opts, - agent: lambdaAgent, - } : opts - const proxy = getProxy(pxuri, pxopts, isHttps) - AGENT_CACHE.set(key, proxy) - return proxy - } - - const agent = isHttps ? new HttpsAgent({ - maxSockets: agentMaxSockets, - ca: opts.ca, - cert: opts.cert, - key: opts.key, - localAddress: opts.localAddress, - rejectUnauthorized: opts.rejectUnauthorized, - timeout: agentTimeout, - freeSocketTimeout: 15000, - lookup: dns.getLookup(opts.dns), - }) : new HttpAgent({ - maxSockets: agentMaxSockets, - localAddress: opts.localAddress, - timeout: agentTimeout, - freeSocketTimeout: 15000, - lookup: dns.getLookup(opts.dns), - }) - AGENT_CACHE.set(key, agent) - return agent -} - -function checkNoProxy (uri, opts) { - const host = new url.URL(uri).hostname.split('.').reverse() - let noproxy = (opts.noProxy || getProcessEnv('no_proxy')) - if (typeof noproxy === 'string') { - noproxy = noproxy.split(',').map(n => n.trim()) - } - - return noproxy && noproxy.some(no => { - const noParts = no.split('.').filter(x => x).reverse() - if (!noParts.length) { - return false - } - for (let i = 0; i < noParts.length; i++) { - if (host[i] !== noParts[i]) { - return false - } - } - return true - }) -} - -module.exports.getProcessEnv = getProcessEnv - -function getProcessEnv (env) { - if (!env) { - return - } - - let value - - if (Array.isArray(env)) { - for (const e of env) { - value = process.env[e] || - process.env[e.toUpperCase()] || - process.env[e.toLowerCase()] - if (typeof value !== 'undefined') { - break - } - } - } - - if (typeof env === 'string') { - value = process.env[env] || - process.env[env.toUpperCase()] || - process.env[env.toLowerCase()] - } - - return value -} - -module.exports.getProxyUri = getProxyUri -function getProxyUri (uri, opts) { - const protocol = new url.URL(uri).protocol - - const proxy = opts.proxy || - ( - protocol === 'https:' && - getProcessEnv('https_proxy') - ) || - ( - protocol === 'http:' && - getProcessEnv(['https_proxy', 'http_proxy', 'proxy']) - ) - if (!proxy) { - return null - } - - const parsedProxy = (typeof proxy === 'string') ? new url.URL(proxy) : proxy - - return !checkNoProxy(uri, opts) && parsedProxy -} - -const getAuth = u => - u.username && u.password ? decodeURIComponent(`${u.username}:${u.password}`) - : u.username ? decodeURIComponent(u.username) - : null - -const getPath = u => u.pathname + u.search + u.hash - -const HttpProxyAgent = require('http-proxy-agent') -const HttpsProxyAgent = require('https-proxy-agent') -const { SocksProxyAgent } = require('socks-proxy-agent') -module.exports.getProxy = getProxy -function getProxy (proxyUrl, opts, isHttps) { - // our current proxy agents do not support an overridden dns lookup method, so will not - // benefit from the dns cache - const popts = { - host: proxyUrl.hostname, - port: proxyUrl.port, - protocol: proxyUrl.protocol, - path: getPath(proxyUrl), - auth: getAuth(proxyUrl), - ca: opts.ca, - cert: opts.cert, - key: opts.key, - timeout: getAgentTimeout(opts.timeout), - localAddress: opts.localAddress, - maxSockets: getMaxSockets(opts.maxSockets), - rejectUnauthorized: opts.rejectUnauthorized, - } - - if (proxyUrl.protocol === 'http:' || proxyUrl.protocol === 'https:') { - if (!isHttps) { - return new HttpProxyAgent(popts) - } else { - return new HttpsProxyAgent(popts) - } - } else if (proxyUrl.protocol.startsWith('socks')) { - // socks-proxy-agent uses hostname not host - popts.hostname = popts.host - delete popts.host - return new SocksProxyAgent(popts) - } else { - throw Object.assign( - new Error(`unsupported proxy protocol: '${proxyUrl.protocol}'`), - { - code: 'EUNSUPPORTEDPROXY', - url: proxyUrl.href, - } - ) - } -} diff --git a/node_modules/make-fetch-happen/lib/cache/entry.js b/node_modules/make-fetch-happen/lib/cache/entry.js index 4307962b889d0..bfcfacbcc95e1 100644 --- a/node_modules/make-fetch-happen/lib/cache/entry.js +++ b/node_modules/make-fetch-happen/lib/cache/entry.js @@ -1,5 +1,5 @@ const { Request, Response } = require('minipass-fetch') -const Minipass = require('minipass') +const { Minipass } = require('minipass') const MinipassFlush = require('minipass-flush') const cacache = require('cacache') const url = require('url') @@ -99,6 +99,12 @@ const getMetadata = (request, response, options) => { } } + for (const name of options.cacheAdditionalHeaders) { + if (response.headers.has(name)) { + metadata.resHeaders[name] = response.headers.get(name) + } + } + return metadata } @@ -268,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({ @@ -288,6 +296,7 @@ class CacheEntry { // stick a flag on here so downstream users will know if they can expect integrity events tee.pipe(cacheStream) // TODO if the cache write fails, log a warning but return the response anyway + // eslint-disable-next-line promise/catch-or-return cacheStream.promise().then(cacheWriteResolve, cacheWriteReject) body.unshift(tee) body.unshift(this.response.body) @@ -330,6 +339,7 @@ class CacheEntry { // that reads from cacache and attach it to a new Response const body = new Minipass() const headers = { ...this.policy.responseHeaders() } + const onResume = () => { const cacheStream = cacache.get.stream.byDigest( this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize } @@ -416,6 +426,24 @@ class CacheEntry { } } + for (const name of options.cacheAdditionalHeaders) { + const inMeta = hasOwnProperty(metadata.resHeaders, name) + const inEntry = hasOwnProperty(this.entry.metadata.resHeaders, name) + const inPolicy = hasOwnProperty(this.policy.response.headers, name) + + // if the header is in the existing entry, but it is not in the metadata + // then we need to write it to the metadata as this will refresh the on-disk cache + if (!inMeta && inEntry) { + metadata.resHeaders[name] = this.entry.metadata.resHeaders[name] + } + // if the header is in the metadata, but not in the policy, then we need to set + // it in the policy so that it's included in the immediate response. future + // responses will load a new cache entry, so we don't need to change that + if (!inPolicy && inMeta) { + this.policy.response.headers[name] = metadata.resHeaders[name] + } + } + try { await cacache.index.insert(options.cachePath, this.key, this.entry.integrity, { size: this.entry.size, diff --git a/node_modules/make-fetch-happen/lib/dns.js b/node_modules/make-fetch-happen/lib/dns.js deleted file mode 100644 index 13102b57c4aa0..0000000000000 --- a/node_modules/make-fetch-happen/lib/dns.js +++ /dev/null @@ -1,49 +0,0 @@ -const LRUCache = require('lru-cache') -const dns = require('dns') - -const defaultOptions = exports.defaultOptions = { - family: undefined, - hints: dns.ADDRCONFIG, - all: false, - verbatim: undefined, -} - -const lookupCache = exports.lookupCache = new LRUCache({ max: 50 }) - -// this is a factory so that each request can have its own opts (i.e. ttl) -// while still sharing the cache across all requests -exports.getLookup = (dnsOptions) => { - return (hostname, options, callback) => { - if (typeof options === 'function') { - callback = options - options = null - } else if (typeof options === 'number') { - options = { family: options } - } - - options = { ...defaultOptions, ...options } - - const key = JSON.stringify({ - hostname, - family: options.family, - hints: options.hints, - all: options.all, - verbatim: options.verbatim, - }) - - if (lookupCache.has(key)) { - const [address, family] = lookupCache.get(key) - process.nextTick(callback, null, address, family) - return - } - - dnsOptions.lookup(hostname, options, (err, address, family) => { - if (err) { - return callback(err) - } - - lookupCache.set(key, [address, family], { ttl: dnsOptions.ttl }) - return callback(null, address, family) - }) - } -} diff --git a/node_modules/make-fetch-happen/lib/options.js b/node_modules/make-fetch-happen/lib/options.js index daa9ecd9d5d5f..db51cc6324817 100644 --- a/node_modules/make-fetch-happen/lib/options.js +++ b/node_modules/make-fetch-happen/lib/options.js @@ -11,7 +11,12 @@ const conditionalHeaders = [ const configureOptions = (opts) => { const { strictSSL, ...options } = { ...opts } options.method = options.method ? options.method.toUpperCase() : 'GET' - options.rejectUnauthorized = strictSSL !== false + + if (strictSSL === undefined || strictSSL === null) { + options.rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0' + } else { + options.rejectUnauthorized = strictSSL !== false + } if (!options.retry) { options.retry = { retries: 0 } @@ -40,6 +45,8 @@ const configureOptions = (opts) => { } } + options.cacheAdditionalHeaders = options.cacheAdditionalHeaders || [] + // cacheManager is deprecated, but if it's set and // cachePath is not we should copy it to the new field if (options.cacheManager && !options.cachePath) { diff --git a/node_modules/make-fetch-happen/lib/remote.js b/node_modules/make-fetch-happen/lib/remote.js index 068c73a8a7a7e..1d640e5380baa 100644 --- a/node_modules/make-fetch-happen/lib/remote.js +++ b/node_modules/make-fetch-happen/lib/remote.js @@ -1,10 +1,11 @@ -const Minipass = require('minipass') +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('./agent.js') +const { getAgent } = require('@npmcli/agent') const pkg = require('../package.json') const USER_AGENT = `${pkg.name}/${pkg.version} (+https://npm.im/${pkg.name})` @@ -14,9 +15,15 @@ const RETRY_ERRORS = [ 'ECONNREFUSED', // remote host refused to open connection 'EADDRINUSE', // failed to bind to a local port (proxy?) 'ETIMEDOUT', // someone in the transaction is WAY TOO SLOW - 'ERR_SOCKET_TIMEOUT', // same as above, but this one comes from agentkeepalive + // from @npmcli/agent + 'ECONNECTIONTIMEOUT', + 'EIDLETIMEOUT', + 'ERESPONSETIMEOUT', + 'ETRANSFERTIMEOUT', // Known codes we do NOT retry on: // ENOTFOUND (getaddrinfo failure. Either bad hostname, or offline) + // EINVALIDPROXY // invalid protocol from @npmcli/agent + // EINVALIDRESPONSE // invalid status code from @npmcli/agent ] const RETRY_TYPES = [ @@ -28,7 +35,8 @@ const RETRY_TYPES = [ // following redirects (through the cache if necessary) // and verifying response integrity const remoteFetch = (request, options) => { - const agent = getAgent(request.url, options) + // options.signal is intended for the fetch itself, not the agent. Attaching it to the agent will re-use that signal across multiple requests, which prevents any connections beyond the first one. + const agent = getAgent(request.url, { ...options, signal: undefined }) if (!request.headers.has('connection')) { request.headers.set('connection', agent ? 'keep-alive' : 'close') } @@ -83,6 +91,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) } @@ -106,6 +116,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/node_modules/make-fetch-happen/package.json b/node_modules/make-fetch-happen/package.json index 8b21901f34fc1..203b32304c461 100644 --- a/node_modules/make-fetch-happen/package.json +++ b/node_modules/make-fetch-happen/package.json @@ -1,6 +1,6 @@ { "name": "make-fetch-happen", - "version": "10.2.0", + "version": "15.0.3", "description": "Opinionated, caching, retrying fetch client", "main": "lib/index.js", "files": [ @@ -8,21 +8,18 @@ "lib/" ], "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "test": "tap", "posttest": "npm run lint", - "eslint": "eslint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "postlint": "template-oss-check", "snap": "tap", "template-oss-apply": "template-oss-apply --force" }, "repository": { "type": "git", - "url": "https://github.com/npm/make-fetch-happen.git" + "url": "git+https://github.com/npm/make-fetch-happen.git" }, "keywords": [ "http", @@ -36,44 +33,42 @@ "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" + "ssri": "^13.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "mkdirp": "^1.0.4", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.25.0", "nock": "^13.2.4", - "rimraf": "^3.0.2", "safe-buffer": "^5.2.1", "standard-version": "^9.3.2", "tap": "^16.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "tap": { "color": 1, "files": "test/*.js", "check-coverage": true, - "timeout": 60 + "timeout": 60, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.25.0", + "publish": "true" } } diff --git a/node_modules/minimatch/LICENSE b/node_modules/minimatch/LICENSE deleted file mode 100644 index 9517b7d995bb0..0000000000000 --- a/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) 2011-2022 Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/minimatch/LICENSE.md b/node_modules/minimatch/LICENSE.md new file mode 100644 index 0000000000000..8cb5cc6e616c0 --- /dev/null +++ b/node_modules/minimatch/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +**_As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim._** diff --git a/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js b/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js new file mode 100644 index 0000000000000..5fc86bbd0116c --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.assertValidPattern = void 0; +const MAX_PATTERN_LENGTH = 1024 * 64; +const assertValidPattern = (pattern) => { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern'); + } + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long'); + } +}; +exports.assertValidPattern = assertValidPattern; +//# sourceMappingURL=assert-valid-pattern.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/commonjs/ast.js b/node_modules/minimatch/dist/commonjs/ast.js new file mode 100644 index 0000000000000..fd7f3d73ed31d --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/ast.js @@ -0,0 +1,591 @@ +"use strict"; +// parse a single path portion +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AST = void 0; +const brace_expressions_js_1 = require("./brace-expressions.js"); +const unescape_js_1 = require("./unescape.js"); +const types = new Set(['!', '?', '+', '*', '@']); +const isExtglobType = (c) => types.has(c); +// Patterns that get prepended to bind to the start of either the +// entire string, or just a single path portion, to prevent dots +// and/or traversal patterns, when needed. +// Exts don't need the ^ or / bit, because the root binds that already. +const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))'; +const startNoDot = '(?!\\.)'; +// characters that indicate a start of pattern needs the "no dots" bit, +// because a dot *might* be matched. ( is not in the list, because in +// the case of a child extglob, it will handle the prevention itself. +const addPatternStart = new Set(['[', '.']); +// cases where traversal is A-OK, no dot prevention needed +const justDots = new Set(['..', '.']); +const reSpecials = new Set('().*{}+?[]^$\\!'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// any single thing other than / +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// use + when we need to ensure that *something* matches, because the * is +// the only thing in the path portion. +const starNoEmpty = qmark + '+?'; +// remove the \ chars that we added if we end up doing a nonmagic compare +// const deslash = (s: string) => s.replace(/\\(.)/g, '$1') +class AST { + type; + #root; + #hasMagic; + #uflag = false; + #parts = []; + #parent; + #parentIndex; + #negs; + #filledNegs = false; + #options; + #toString; + // set to true if it's an extglob with no children + // (which really means one child of '') + #emptyExt = false; + constructor(type, parent, options = {}) { + this.type = type; + // extglobs are inherently magical + if (type) + this.#hasMagic = true; + this.#parent = parent; + this.#root = this.#parent ? this.#parent.#root : this; + this.#options = this.#root === this ? options : this.#root.#options; + this.#negs = this.#root === this ? [] : this.#root.#negs; + if (type === '!' && !this.#root.#filledNegs) + this.#negs.push(this); + this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0; + } + get hasMagic() { + /* c8 ignore start */ + if (this.#hasMagic !== undefined) + return this.#hasMagic; + /* c8 ignore stop */ + for (const p of this.#parts) { + if (typeof p === 'string') + continue; + if (p.type || p.hasMagic) + return (this.#hasMagic = true); + } + // note: will be undefined until we generate the regexp src and find out + return this.#hasMagic; + } + // reconstructs the pattern + toString() { + if (this.#toString !== undefined) + return this.#toString; + if (!this.type) { + return (this.#toString = this.#parts.map(p => String(p)).join('')); + } + else { + return (this.#toString = + this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')'); + } + } + #fillNegs() { + /* c8 ignore start */ + if (this !== this.#root) + throw new Error('should only call on root'); + if (this.#filledNegs) + return this; + /* c8 ignore stop */ + // call toString() once to fill this out + this.toString(); + this.#filledNegs = true; + let n; + while ((n = this.#negs.pop())) { + if (n.type !== '!') + continue; + // walk up the tree, appending everthing that comes AFTER parentIndex + let p = n; + let pp = p.#parent; + while (pp) { + for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) { + for (const part of n.#parts) { + /* c8 ignore start */ + if (typeof part === 'string') { + throw new Error('string part in extglob AST??'); + } + /* c8 ignore stop */ + part.copyIn(pp.#parts[i]); + } + } + p = pp; + pp = p.#parent; + } + } + return this; + } + push(...parts) { + for (const p of parts) { + if (p === '') + continue; + /* c8 ignore start */ + if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) { + throw new Error('invalid part: ' + p); + } + /* c8 ignore stop */ + this.#parts.push(p); + } + } + toJSON() { + const ret = this.type === null + ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON())) + : [this.type, ...this.#parts.map(p => p.toJSON())]; + if (this.isStart() && !this.type) + ret.unshift([]); + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + ret.push({}); + } + return ret; + } + isStart() { + if (this.#root === this) + return true; + // if (this.type) return !!this.#parent?.isStart() + if (!this.#parent?.isStart()) + return false; + if (this.#parentIndex === 0) + return true; + // if everything AHEAD of this is a negation, then it's still the "start" + const p = this.#parent; + for (let i = 0; i < this.#parentIndex; i++) { + const pp = p.#parts[i]; + if (!(pp instanceof AST && pp.type === '!')) { + return false; + } + } + return true; + } + isEnd() { + if (this.#root === this) + return true; + if (this.#parent?.type === '!') + return true; + if (!this.#parent?.isEnd()) + return false; + if (!this.type) + return this.#parent?.isEnd(); + // if not root, it'll always have a parent + /* c8 ignore start */ + const pl = this.#parent ? this.#parent.#parts.length : 0; + /* c8 ignore stop */ + return this.#parentIndex === pl - 1; + } + copyIn(part) { + if (typeof part === 'string') + this.push(part); + else + this.push(part.clone(this)); + } + clone(parent) { + const c = new AST(this.type, parent); + for (const p of this.#parts) { + c.copyIn(p); + } + return c; + } + static #parseAST(str, ast, pos, opt) { + let escaping = false; + let inBrace = false; + let braceStart = -1; + let braceNeg = false; + if (ast.type === null) { + // outside of a extglob, append until we find a start + let i = pos; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (inBrace) { + if (i === braceStart + 1) { + if (c === '^' || c === '!') { + braceNeg = true; + } + } + else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { + inBrace = false; + } + acc += c; + continue; + } + else if (c === '[') { + inBrace = true; + braceStart = i; + braceNeg = false; + acc += c; + continue; + } + if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { + ast.push(acc); + acc = ''; + const ext = new AST(c, ast); + i = AST.#parseAST(str, ext, i, opt); + ast.push(ext); + continue; + } + acc += c; + } + ast.push(acc); + return i; + } + // some kind of extglob, pos is at the ( + // find the next | or ) + let i = pos + 1; + let part = new AST(null, ast); + const parts = []; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (inBrace) { + if (i === braceStart + 1) { + if (c === '^' || c === '!') { + braceNeg = true; + } + } + else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { + inBrace = false; + } + acc += c; + continue; + } + else if (c === '[') { + inBrace = true; + braceStart = i; + braceNeg = false; + acc += c; + continue; + } + if (isExtglobType(c) && str.charAt(i) === '(') { + part.push(acc); + acc = ''; + const ext = new AST(c, part); + part.push(ext); + i = AST.#parseAST(str, ext, i, opt); + continue; + } + if (c === '|') { + part.push(acc); + acc = ''; + parts.push(part); + part = new AST(null, ast); + continue; + } + if (c === ')') { + if (acc === '' && ast.#parts.length === 0) { + ast.#emptyExt = true; + } + part.push(acc); + acc = ''; + ast.push(...parts, part); + return i; + } + acc += c; + } + // unfinished extglob + // if we got here, it was a malformed extglob! not an extglob, but + // maybe something else in there. + ast.type = null; + ast.#hasMagic = undefined; + ast.#parts = [str.substring(pos - 1)]; + return i; + } + static fromGlob(pattern, options = {}) { + const ast = new AST(null, undefined, options); + AST.#parseAST(pattern, ast, 0, options); + return ast; + } + // returns the regular expression if there's magic, or the unescaped + // string if not. + toMMPattern() { + // should only be called on root + /* c8 ignore start */ + if (this !== this.#root) + return this.#root.toMMPattern(); + /* c8 ignore stop */ + const glob = this.toString(); + const [re, body, hasMagic, uflag] = this.toRegExpSource(); + // if we're in nocase mode, and not nocaseMagicOnly, then we do + // still need a regular expression if we have to case-insensitively + // match capital/lowercase characters. + const anyMagic = hasMagic || + this.#hasMagic || + (this.#options.nocase && + !this.#options.nocaseMagicOnly && + glob.toUpperCase() !== glob.toLowerCase()); + if (!anyMagic) { + return body; + } + const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : ''); + return Object.assign(new RegExp(`^${re}$`, flags), { + _src: re, + _glob: glob, + }); + } + get options() { + return this.#options; + } + // returns the string match, the regexp source, whether there's magic + // in the regexp (so a regular expression is required) and whether or + // not the uflag is needed for the regular expression (for posix classes) + // TODO: instead of injecting the start/end at this point, just return + // the BODY of the regexp, along with the start/end portions suitable + // for binding the start/end in either a joined full-path makeRe context + // (where we bind to (^|/), or a standalone matchPart context (where + // we bind to ^, and not /). Otherwise slashes get duped! + // + // In part-matching mode, the start is: + // - if not isStart: nothing + // - if traversal possible, but not allowed: ^(?!\.\.?$) + // - if dots allowed or not possible: ^ + // - if dots possible and not allowed: ^(?!\.) + // end is: + // - if not isEnd(): nothing + // - else: $ + // + // In full-path matching mode, we put the slash at the START of the + // pattern, so start is: + // - if first pattern: same as part-matching mode + // - if not isStart(): nothing + // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/)) + // - if dots allowed or not possible: / + // - if dots possible and not allowed: /(?!\.) + // end is: + // - if last pattern, same as part-matching mode + // - else nothing + // + // Always put the (?:$|/) on negated tails, though, because that has to be + // there to bind the end of the negated pattern portion, and it's easier to + // just stick it in now rather than try to inject it later in the middle of + // the pattern. + // + // We can just always return the same end, and leave it up to the caller + // to know whether it's going to be used joined or in parts. + // And, if the start is adjusted slightly, can do the same there: + // - if not isStart: nothing + // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$) + // - if dots allowed or not possible: (?:/|^) + // - if dots possible and not allowed: (?:/|^)(?!\.) + // + // But it's better to have a simpler binding without a conditional, for + // performance, so probably better to return both start options. + // + // Then the caller just ignores the end if it's not the first pattern, + // and the start always gets applied. + // + // But that's always going to be $ if it's the ending pattern, or nothing, + // so the caller can just attach $ at the end of the pattern when building. + // + // So the todo is: + // - better detect what kind of start is needed + // - return both flavors of starting pattern + // - attach $ at the end of the pattern when creating the actual RegExp + // + // Ah, but wait, no, that all only applies to the root when the first pattern + // is not an extglob. If the first pattern IS an extglob, then we need all + // that dot prevention biz to live in the extglob portions, because eg + // +(*|.x*) can match .xy but not .yx. + // + // So, return the two flavors if it's #root and the first child is not an + // AST, otherwise leave it to the child AST to handle it, and there, + // use the (?:^|/) style of start binding. + // + // Even simplified further: + // - Since the start for a join is eg /(?!\.) and the start for a part + // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root + // or start or whatever) and prepend ^ or / at the Regexp construction. + toRegExpSource(allowDot) { + const dot = allowDot ?? !!this.#options.dot; + if (this.#root === this) + this.#fillNegs(); + if (!this.type) { + const noEmpty = this.isStart() && + this.isEnd() && + !this.#parts.some(s => typeof s !== 'string'); + const src = this.#parts + .map(p => { + const [re, _, hasMagic, uflag] = typeof p === 'string' + ? AST.#parseGlob(p, this.#hasMagic, noEmpty) + : p.toRegExpSource(allowDot); + this.#hasMagic = this.#hasMagic || hasMagic; + this.#uflag = this.#uflag || uflag; + return re; + }) + .join(''); + let start = ''; + if (this.isStart()) { + if (typeof this.#parts[0] === 'string') { + // this is the string that will match the start of the pattern, + // so we need to protect against dots and such. + // '.' and '..' cannot match unless the pattern is that exactly, + // even if it starts with . or dot:true is set. + const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]); + if (!dotTravAllowed) { + const aps = addPatternStart; + // check if we have a possibility of matching . or .., + // and prevent that. + const needNoTrav = + // dots are allowed, and the pattern starts with [ or . + (dot && aps.has(src.charAt(0))) || + // the pattern starts with \., and then [ or . + (src.startsWith('\\.') && aps.has(src.charAt(2))) || + // the pattern starts with \.\., and then [ or . + (src.startsWith('\\.\\.') && aps.has(src.charAt(4))); + // no need to prevent dots if it can't match a dot, or if a + // sub-pattern will be preventing it anyway. + const needNoDot = !dot && !allowDot && aps.has(src.charAt(0)); + start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''; + } + } + } + // append the "end of path portion" pattern to negation tails + let end = ''; + if (this.isEnd() && + this.#root.#filledNegs && + this.#parent?.type === '!') { + end = '(?:$|\\/)'; + } + const final = start + src + end; + return [ + final, + (0, unescape_js_1.unescape)(src), + (this.#hasMagic = !!this.#hasMagic), + this.#uflag, + ]; + } + // We need to calculate the body *twice* if it's a repeat pattern + // at the start, once in nodot mode, then again in dot mode, so a + // pattern like *(?) can match 'x.y' + const repeated = this.type === '*' || this.type === '+'; + // some kind of extglob + const start = this.type === '!' ? '(?:(?!(?:' : '(?:'; + let body = this.#partsToRegExp(dot); + if (this.isStart() && this.isEnd() && !body && this.type !== '!') { + // invalid extglob, has to at least be *something* present, if it's + // the entire path portion. + const s = this.toString(); + this.#parts = [s]; + this.type = null; + this.#hasMagic = undefined; + return [s, (0, unescape_js_1.unescape)(this.toString()), false, false]; + } + // XXX abstract out this map method + let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot + ? '' + : this.#partsToRegExp(true); + if (bodyDotAllowed === body) { + bodyDotAllowed = ''; + } + if (bodyDotAllowed) { + body = `(?:${body})(?:${bodyDotAllowed})*?`; + } + // an empty !() is exactly equivalent to a starNoEmpty + let final = ''; + if (this.type === '!' && this.#emptyExt) { + final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty; + } + else { + const close = this.type === '!' + ? // !() must match something,but !(x) can match '' + '))' + + (this.isStart() && !dot && !allowDot ? startNoDot : '') + + star + + ')' + : this.type === '@' + ? ')' + : this.type === '?' + ? ')?' + : this.type === '+' && bodyDotAllowed + ? ')' + : this.type === '*' && bodyDotAllowed + ? `)?` + : `)${this.type}`; + final = start + body + close; + } + return [ + final, + (0, unescape_js_1.unescape)(body), + (this.#hasMagic = !!this.#hasMagic), + this.#uflag, + ]; + } + #partsToRegExp(dot) { + return this.#parts + .map(p => { + // extglob ASTs should only contain parent ASTs + /* c8 ignore start */ + if (typeof p === 'string') { + throw new Error('string type in extglob ast??'); + } + /* c8 ignore stop */ + // can ignore hasMagic, because extglobs are already always magic + const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot); + this.#uflag = this.#uflag || uflag; + return re; + }) + .filter(p => !(this.isStart() && this.isEnd()) || !!p) + .join('|'); + } + static #parseGlob(glob, hasMagic, noEmpty = false) { + let escaping = false; + let re = ''; + let uflag = false; + for (let i = 0; i < glob.length; i++) { + const c = glob.charAt(i); + if (escaping) { + escaping = false; + re += (reSpecials.has(c) ? '\\' : '') + c; + continue; + } + if (c === '\\') { + if (i === glob.length - 1) { + re += '\\\\'; + } + else { + escaping = true; + } + continue; + } + if (c === '[') { + const [src, needUflag, consumed, magic] = (0, brace_expressions_js_1.parseClass)(glob, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + continue; + } + } + if (c === '*') { + re += noEmpty && glob === '*' ? starNoEmpty : star; + hasMagic = true; + continue; + } + if (c === '?') { + re += qmark; + hasMagic = true; + continue; + } + re += regExpEscape(c); + } + return [re, (0, unescape_js_1.unescape)(glob), !!hasMagic, uflag]; + } +} +exports.AST = AST; +//# sourceMappingURL=ast.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/commonjs/brace-expressions.js b/node_modules/minimatch/dist/commonjs/brace-expressions.js new file mode 100644 index 0000000000000..0e13eefc4cfee --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/brace-expressions.js @@ -0,0 +1,152 @@ +"use strict"; +// translate the various posix character classes into unicode properties +// this works across all unicode locales +Object.defineProperty(exports, "__esModule", { value: true }); +exports.parseClass = void 0; +// { <posix class>: [<translation>, /u flag required, negated] +const posixClasses = { + '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true], + '[:alpha:]': ['\\p{L}\\p{Nl}', true], + '[:ascii:]': ['\\x' + '00-\\x' + '7f', false], + '[:blank:]': ['\\p{Zs}\\t', true], + '[:cntrl:]': ['\\p{Cc}', true], + '[:digit:]': ['\\p{Nd}', true], + '[:graph:]': ['\\p{Z}\\p{C}', true, true], + '[:lower:]': ['\\p{Ll}', true], + '[:print:]': ['\\p{C}', true], + '[:punct:]': ['\\p{P}', true], + '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true], + '[:upper:]': ['\\p{Lu}', true], + '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true], + '[:xdigit:]': ['A-Fa-f0-9', false], +}; +// only need to escape a few things inside of brace expressions +// escapes: [ \ ] - +const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&'); +// escape all regexp magic characters +const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// everything has already been escaped, we just have to join +const rangesToString = (ranges) => ranges.join(''); +// takes a glob string at a posix brace expression, and returns +// an equivalent regular expression source, and boolean indicating +// whether the /u flag needs to be applied, and the number of chars +// consumed to parse the character class. +// This also removes out of order ranges, and returns ($.) if the +// entire class just no good. +const parseClass = (glob, position) => { + const pos = position; + /* c8 ignore start */ + if (glob.charAt(pos) !== '[') { + throw new Error('not in a brace expression'); + } + /* c8 ignore stop */ + const ranges = []; + const negs = []; + let i = pos + 1; + let sawStart = false; + let uflag = false; + let escaping = false; + let negate = false; + let endPos = pos; + let rangeStart = ''; + WHILE: while (i < glob.length) { + const c = glob.charAt(i); + if ((c === '!' || c === '^') && i === pos + 1) { + negate = true; + i++; + continue; + } + if (c === ']' && sawStart && !escaping) { + endPos = i + 1; + break; + } + sawStart = true; + if (c === '\\') { + if (!escaping) { + escaping = true; + i++; + continue; + } + // escaped \ char, fall through and treat like normal char + } + if (c === '[' && !escaping) { + // either a posix class, a collation equivalent, or just a [ + for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) { + if (glob.startsWith(cls, i)) { + // invalid, [a-[] is fine, but not [a-[:alpha]] + if (rangeStart) { + return ['$.', false, glob.length - pos, true]; + } + i += cls.length; + if (neg) + negs.push(unip); + else + ranges.push(unip); + uflag = uflag || u; + continue WHILE; + } + } + } + // now it's just a normal character, effectively + escaping = false; + if (rangeStart) { + // throw this range away if it's not valid, but others + // can still match. + if (c > rangeStart) { + ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c)); + } + else if (c === rangeStart) { + ranges.push(braceEscape(c)); + } + rangeStart = ''; + i++; + continue; + } + // now might be the start of a range. + // can be either c-d or c-] or c<more...>] or c] at this point + if (glob.startsWith('-]', i + 1)) { + ranges.push(braceEscape(c + '-')); + i += 2; + continue; + } + if (glob.startsWith('-', i + 1)) { + rangeStart = c; + i += 2; + continue; + } + // not the start of a range, just a single character + ranges.push(braceEscape(c)); + i++; + } + if (endPos < i) { + // didn't see the end of the class, not a valid class, + // but might still be valid as a literal match. + return ['', false, 0, false]; + } + // if we got no ranges and no negates, then we have a range that + // cannot possibly match anything, and that poisons the whole glob + if (!ranges.length && !negs.length) { + return ['$.', false, glob.length - pos, true]; + } + // if we got one positive range, and it's a single character, then that's + // not actually a magic pattern, it's just that one literal character. + // we should not treat that as "magic", we should just return the literal + // character. [_] is a perfectly valid way to escape glob magic chars. + if (negs.length === 0 && + ranges.length === 1 && + /^\\?.$/.test(ranges[0]) && + !negate) { + const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]; + return [regexpEscape(r), false, endPos - pos, false]; + } + const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'; + const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'; + const comb = ranges.length && negs.length + ? '(' + sranges + '|' + snegs + ')' + : ranges.length + ? sranges + : snegs; + return [comb, uflag, endPos - pos, true]; +}; +exports.parseClass = parseClass; +//# sourceMappingURL=brace-expressions.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/commonjs/escape.js b/node_modules/minimatch/dist/commonjs/escape.js new file mode 100644 index 0000000000000..6fb634fb41033 --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/escape.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.escape = void 0; +/** + * Escape all magic characters in a glob pattern. + * + * If the {@link MinimatchOptions.windowsPathsNoEscape} + * option is used, then characters are escaped by wrapping in `[]`, because + * a magic character wrapped in a character class can only be satisfied by + * that exact character. In this mode, `\` is _not_ escaped, because it is + * not interpreted as a magic character, but instead as a path separator. + * + * If the {@link MinimatchOptions.magicalBraces} option is used, + * then braces (`{` and `}`) will be escaped. + */ +const escape = (s, { windowsPathsNoEscape = false, magicalBraces = false, } = {}) => { + // don't need to escape +@! because we escape the parens + // that make those magic, and escaping ! as [!] isn't valid, + // because [!]] is a valid glob class meaning not ']'. + if (magicalBraces) { + return windowsPathsNoEscape + ? s.replace(/[?*()[\]{}]/g, '[$&]') + : s.replace(/[?*()[\]\\{}]/g, '\\$&'); + } + return windowsPathsNoEscape + ? s.replace(/[?*()[\]]/g, '[$&]') + : s.replace(/[?*()[\]\\]/g, '\\$&'); +}; +exports.escape = escape; +//# sourceMappingURL=escape.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/commonjs/index.js b/node_modules/minimatch/dist/commonjs/index.js new file mode 100644 index 0000000000000..966dc9b8bb216 --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/index.js @@ -0,0 +1,1029 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unescape = exports.escape = exports.AST = exports.Minimatch = exports.match = exports.makeRe = exports.braceExpand = exports.defaults = exports.filter = exports.GLOBSTAR = exports.sep = exports.minimatch = void 0; +const brace_expansion_1 = require("@isaacs/brace-expansion"); +const assert_valid_pattern_js_1 = require("./assert-valid-pattern.js"); +const ast_js_1 = require("./ast.js"); +const escape_js_1 = require("./escape.js"); +const unescape_js_1 = require("./unescape.js"); +const minimatch = (p, pattern, options = {}) => { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false; + } + return new Minimatch(pattern, options).match(p); +}; +exports.minimatch = minimatch; +// Optimized checking for the most common glob patterns. +const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; +const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); +const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); +const starDotExtTestNocase = (ext) => { + ext = ext.toLowerCase(); + return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); +}; +const starDotExtTestNocaseDot = (ext) => { + ext = ext.toLowerCase(); + return (f) => f.toLowerCase().endsWith(ext); +}; +const starDotStarRE = /^\*+\.\*+$/; +const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); +const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); +const dotStarRE = /^\.\*+$/; +const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); +const starRE = /^\*+$/; +const starTest = (f) => f.length !== 0 && !f.startsWith('.'); +const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; +const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; +const qmarksTestNocase = ([$0, ext = '']) => { + const noext = qmarksTestNoExt([$0]); + if (!ext) + return noext; + ext = ext.toLowerCase(); + return (f) => noext(f) && f.toLowerCase().endsWith(ext); +}; +const qmarksTestNocaseDot = ([$0, ext = '']) => { + const noext = qmarksTestNoExtDot([$0]); + if (!ext) + return noext; + ext = ext.toLowerCase(); + return (f) => noext(f) && f.toLowerCase().endsWith(ext); +}; +const qmarksTestDot = ([$0, ext = '']) => { + const noext = qmarksTestNoExtDot([$0]); + return !ext ? noext : (f) => noext(f) && f.endsWith(ext); +}; +const qmarksTest = ([$0, ext = '']) => { + const noext = qmarksTestNoExt([$0]); + return !ext ? noext : (f) => noext(f) && f.endsWith(ext); +}; +const qmarksTestNoExt = ([$0]) => { + const len = $0.length; + return (f) => f.length === len && !f.startsWith('.'); +}; +const qmarksTestNoExtDot = ([$0]) => { + const len = $0.length; + return (f) => f.length === len && f !== '.' && f !== '..'; +}; +/* c8 ignore start */ +const defaultPlatform = (typeof process === 'object' && process + ? (typeof process.env === 'object' && + process.env && + process.env.__MINIMATCH_TESTING_PLATFORM__) || + process.platform + : 'posix'); +const path = { + win32: { sep: '\\' }, + posix: { sep: '/' }, +}; +/* c8 ignore stop */ +exports.sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep; +exports.minimatch.sep = exports.sep; +exports.GLOBSTAR = Symbol('globstar **'); +exports.minimatch.GLOBSTAR = exports.GLOBSTAR; +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; +const filter = (pattern, options = {}) => (p) => (0, exports.minimatch)(p, pattern, options); +exports.filter = filter; +exports.minimatch.filter = exports.filter; +const ext = (a, b = {}) => Object.assign({}, a, b); +const defaults = (def) => { + if (!def || typeof def !== 'object' || !Object.keys(def).length) { + return exports.minimatch; + } + const orig = exports.minimatch; + const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); + return Object.assign(m, { + Minimatch: class Minimatch extends orig.Minimatch { + constructor(pattern, options = {}) { + super(pattern, ext(def, options)); + } + static defaults(options) { + return orig.defaults(ext(def, options)).Minimatch; + } + }, + AST: class AST extends orig.AST { + /* c8 ignore start */ + constructor(type, parent, options = {}) { + super(type, parent, ext(def, options)); + } + /* c8 ignore stop */ + static fromGlob(pattern, options = {}) { + return orig.AST.fromGlob(pattern, ext(def, options)); + } + }, + unescape: (s, options = {}) => orig.unescape(s, ext(def, options)), + escape: (s, options = {}) => orig.escape(s, ext(def, options)), + filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), + defaults: (options) => orig.defaults(ext(def, options)), + makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), + braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), + match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), + sep: orig.sep, + GLOBSTAR: exports.GLOBSTAR, + }); +}; +exports.defaults = defaults; +exports.minimatch.defaults = exports.defaults; +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +const braceExpand = (pattern, options = {}) => { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + // Thanks to Yeting Li <https://github.com/yetingli> for + // improving this regexp to avoid a ReDOS vulnerability. + if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + // shortcut. no need to expand. + return [pattern]; + } + return (0, brace_expansion_1.expand)(pattern); +}; +exports.braceExpand = braceExpand; +exports.minimatch.braceExpand = exports.braceExpand; +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); +exports.makeRe = makeRe; +exports.minimatch.makeRe = exports.makeRe; +const match = (list, pattern, options = {}) => { + const mm = new Minimatch(pattern, options); + list = list.filter(f => mm.match(f)); + if (mm.options.nonull && !list.length) { + list.push(pattern); + } + return list; +}; +exports.match = match; +exports.minimatch.match = exports.match; +// replace stuff like \* with * +const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +class Minimatch { + options; + set; + pattern; + windowsPathsNoEscape; + nonegate; + negate; + comment; + empty; + preserveMultipleSlashes; + partial; + globSet; + globParts; + nocase; + isWindows; + platform; + windowsNoMagicRoot; + regexp; + constructor(pattern, options = {}) { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + options = options || {}; + this.options = options; + this.pattern = pattern; + this.platform = options.platform || defaultPlatform; + this.isWindows = this.platform === 'win32'; + this.windowsPathsNoEscape = + !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; + if (this.windowsPathsNoEscape) { + this.pattern = this.pattern.replace(/\\/g, '/'); + } + this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; + this.regexp = null; + this.negate = false; + this.nonegate = !!options.nonegate; + this.comment = false; + this.empty = false; + this.partial = !!options.partial; + this.nocase = !!this.options.nocase; + this.windowsNoMagicRoot = + options.windowsNoMagicRoot !== undefined + ? options.windowsNoMagicRoot + : !!(this.isWindows && this.nocase); + this.globSet = []; + this.globParts = []; + this.set = []; + // make the set of regexps etc. + this.make(); + } + hasMagic() { + if (this.options.magicalBraces && this.set.length > 1) { + return true; + } + for (const pattern of this.set) { + for (const part of pattern) { + if (typeof part !== 'string') + return true; + } + } + return false; + } + debug(..._) { } + make() { + const pattern = this.pattern; + const options = this.options; + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true; + return; + } + if (!pattern) { + this.empty = true; + return; + } + // step 1: figure out negation, etc. + this.parseNegate(); + // step 2: expand braces + this.globSet = [...new Set(this.braceExpand())]; + if (options.debug) { + this.debug = (...args) => console.error(...args); + } + this.debug(this.pattern, this.globSet); + // step 3: now we have a set, so turn each one into a series of + // path-portion matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + // + // First, we preprocess to make the glob pattern sets a bit simpler + // and deduped. There are some perf-killing patterns that can cause + // problems with a glob walk, but we can simplify them down a bit. + const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); + this.globParts = this.preprocess(rawGlobParts); + this.debug(this.pattern, this.globParts); + // glob --> regexps + let set = this.globParts.map((s, _, __) => { + if (this.isWindows && this.windowsNoMagicRoot) { + // check if it's a drive or unc path. + const isUNC = s[0] === '' && + s[1] === '' && + (s[2] === '?' || !globMagic.test(s[2])) && + !globMagic.test(s[3]); + const isDrive = /^[a-z]:/i.test(s[0]); + if (isUNC) { + return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]; + } + else if (isDrive) { + return [s[0], ...s.slice(1).map(ss => this.parse(ss))]; + } + } + return s.map(ss => this.parse(ss)); + }); + this.debug(this.pattern, set); + // filter out everything that didn't compile properly. + this.set = set.filter(s => s.indexOf(false) === -1); + // do not treat the ? in UNC paths as magic + if (this.isWindows) { + for (let i = 0; i < this.set.length; i++) { + const p = this.set[i]; + if (p[0] === '' && + p[1] === '' && + this.globParts[i][2] === '?' && + typeof p[3] === 'string' && + /^[a-z]:$/i.test(p[3])) { + p[2] = '?'; + } + } + } + this.debug(this.pattern, this.set); + } + // various transforms to equivalent pattern sets that are + // faster to process in a filesystem walk. The goal is to + // eliminate what we can, and push all ** patterns as far + // to the right as possible, even if it increases the number + // of patterns that we have to process. + preprocess(globParts) { + // if we're not in globstar mode, then turn all ** into * + if (this.options.noglobstar) { + for (let i = 0; i < globParts.length; i++) { + for (let j = 0; j < globParts[i].length; j++) { + if (globParts[i][j] === '**') { + globParts[i][j] = '*'; + } + } + } + } + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + // aggressive optimization for the purpose of fs walking + globParts = this.firstPhasePreProcess(globParts); + globParts = this.secondPhasePreProcess(globParts); + } + else if (optimizationLevel >= 1) { + // just basic optimizations to remove some .. parts + globParts = this.levelOneOptimize(globParts); + } + else { + // just collapse multiple ** portions into one + globParts = this.adjascentGlobstarOptimize(globParts); + } + return globParts; + } + // just get rid of adjascent ** portions + adjascentGlobstarOptimize(globParts) { + return globParts.map(parts => { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let i = gs; + while (parts[i + 1] === '**') { + i++; + } + if (i !== gs) { + parts.splice(gs, i - gs); + } + } + return parts; + }); + } + // get rid of adjascent ** and resolve .. portions + levelOneOptimize(globParts) { + return globParts.map(parts => { + parts = parts.reduce((set, part) => { + const prev = set[set.length - 1]; + if (part === '**' && prev === '**') { + return set; + } + if (part === '..') { + if (prev && prev !== '..' && prev !== '.' && prev !== '**') { + set.pop(); + return set; + } + } + set.push(part); + return set; + }, []); + return parts.length === 0 ? [''] : parts; + }); + } + levelTwoFileOptimize(parts) { + if (!Array.isArray(parts)) { + parts = this.slashSplit(parts); + } + let didSomething = false; + do { + didSomething = false; + // <pre>/<e>/<rest> -> <pre>/<rest> + if (!this.preserveMultipleSlashes) { + for (let i = 1; i < parts.length - 1; i++) { + const p = parts[i]; + // don't squeeze out UNC patterns + if (i === 1 && p === '' && parts[0] === '') + continue; + if (p === '.' || p === '') { + didSomething = true; + parts.splice(i, 1); + i--; + } + } + if (parts[0] === '.' && + parts.length === 2 && + (parts[1] === '.' || parts[1] === '')) { + didSomething = true; + parts.pop(); + } + } + // <pre>/<p>/../<rest> -> <pre>/<rest> + let dd = 0; + while (-1 !== (dd = parts.indexOf('..', dd + 1))) { + const p = parts[dd - 1]; + if (p && p !== '.' && p !== '..' && p !== '**') { + didSomething = true; + parts.splice(dd - 1, 2); + dd -= 2; + } + } + } while (didSomething); + return parts.length === 0 ? [''] : parts; + } + // First phase: single-pattern processing + // <pre> is 1 or more portions + // <rest> is 1 or more portions + // <p> is any portion other than ., .., '', or ** + // <e> is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} + // <pre>/<e>/<rest> -> <pre>/<rest> + // <pre>/<p>/../<rest> -> <pre>/<rest> + // **/**/<rest> -> **/<rest> + // + // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow + // this WOULD be allowed if ** did follow symlinks, or * didn't + firstPhasePreProcess(globParts) { + let didSomething = false; + do { + didSomething = false; + // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss = gs; + while (parts[gss + 1] === '**') { + // <pre>/**/**/<rest> -> <pre>/**/<rest> + gss++; + } + // eg, if gs is 2 and gss is 4, that means we have 3 ** + // parts, and can remove 2 of them. + if (gss > gs) { + parts.splice(gs + 1, gss - gs); + } + let next = parts[gs + 1]; + const p = parts[gs + 2]; + const p2 = parts[gs + 3]; + if (next !== '..') + continue; + if (!p || + p === '.' || + p === '..' || + !p2 || + p2 === '.' || + p2 === '..') { + continue; + } + didSomething = true; + // edit parts in place, and push the new one + parts.splice(gs, 1); + const other = parts.slice(0); + other[gs] = '**'; + globParts.push(other); + gs--; + } + // <pre>/<e>/<rest> -> <pre>/<rest> + if (!this.preserveMultipleSlashes) { + for (let i = 1; i < parts.length - 1; i++) { + const p = parts[i]; + // don't squeeze out UNC patterns + if (i === 1 && p === '' && parts[0] === '') + continue; + if (p === '.' || p === '') { + didSomething = true; + parts.splice(i, 1); + i--; + } + } + if (parts[0] === '.' && + parts.length === 2 && + (parts[1] === '.' || parts[1] === '')) { + didSomething = true; + parts.pop(); + } + } + // <pre>/<p>/../<rest> -> <pre>/<rest> + let dd = 0; + while (-1 !== (dd = parts.indexOf('..', dd + 1))) { + const p = parts[dd - 1]; + if (p && p !== '.' && p !== '..' && p !== '**') { + didSomething = true; + const needDot = dd === 1 && parts[dd + 1] === '**'; + const splin = needDot ? ['.'] : []; + parts.splice(dd - 1, 2, ...splin); + if (parts.length === 0) + parts.push(''); + dd -= 2; + } + } + } + } while (didSomething); + return globParts; + } + // second phase: multi-pattern dedupes + // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest> + // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest> + // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest> + // + // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest> + // ^-- not valid because ** doens't follow symlinks + secondPhasePreProcess(globParts) { + for (let i = 0; i < globParts.length - 1; i++) { + for (let j = i + 1; j < globParts.length; j++) { + const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes); + if (matched) { + globParts[i] = []; + globParts[j] = matched; + break; + } + } + } + return globParts.filter(gs => gs.length); + } + partsMatch(a, b, emptyGSMatch = false) { + let ai = 0; + let bi = 0; + let result = []; + let which = ''; + while (ai < a.length && bi < b.length) { + if (a[ai] === b[bi]) { + result.push(which === 'b' ? b[bi] : a[ai]); + ai++; + bi++; + } + else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) { + result.push(a[ai]); + ai++; + } + else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) { + result.push(b[bi]); + bi++; + } + else if (a[ai] === '*' && + b[bi] && + (this.options.dot || !b[bi].startsWith('.')) && + b[bi] !== '**') { + if (which === 'b') + return false; + which = 'a'; + result.push(a[ai]); + ai++; + bi++; + } + else if (b[bi] === '*' && + a[ai] && + (this.options.dot || !a[ai].startsWith('.')) && + a[ai] !== '**') { + if (which === 'a') + return false; + which = 'b'; + result.push(b[bi]); + ai++; + bi++; + } + else { + return false; + } + } + // if we fall out of the loop, it means they two are identical + // as long as their lengths match + return a.length === b.length && result; + } + parseNegate() { + if (this.nonegate) + return; + const pattern = this.pattern; + let negate = false; + let negateOffset = 0; + for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { + negate = !negate; + negateOffset++; + } + if (negateOffset) + this.pattern = pattern.slice(negateOffset); + this.negate = negate; + } + // set partial to true to test if, for example, + // "/a/b" matches the start of "/*/b/*/d" + // Partial means, if you run out of file before you run + // out of pattern, then that's fine, as long as all + // the parts match. + matchOne(file, pattern, partial = false) { + const options = this.options; + // UNC paths like //?/X:/... can match X:/... and vice versa + // Drive letters in absolute drive or unc paths are always compared + // case-insensitively. + if (this.isWindows) { + const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]); + const fileUNC = !fileDrive && + file[0] === '' && + file[1] === '' && + file[2] === '?' && + /^[a-z]:$/i.test(file[3]); + const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]); + const patternUNC = !patternDrive && + pattern[0] === '' && + pattern[1] === '' && + pattern[2] === '?' && + typeof pattern[3] === 'string' && + /^[a-z]:$/i.test(pattern[3]); + const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined; + const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined; + if (typeof fdi === 'number' && typeof pdi === 'number') { + const [fd, pd] = [file[fdi], pattern[pdi]]; + if (fd.toLowerCase() === pd.toLowerCase()) { + pattern[pdi] = fd; + if (pdi > fdi) { + pattern = pattern.slice(pdi); + } + else if (fdi > pdi) { + file = file.slice(fdi); + } + } + } + } + // resolve and reduce . and .. portions in the file as well. + // don't need to do the second phase, because it's only one string[] + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + file = this.levelTwoFileOptimize(file); + } + this.debug('matchOne', this, { file, pattern }); + this.debug('matchOne', file.length, pattern.length); + for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { + this.debug('matchOne loop'); + var p = pattern[pi]; + var f = file[fi]; + this.debug(pattern, p, f); + // should be impossible. + // some invalid regexp stuff in the set. + /* c8 ignore start */ + if (p === false) { + return false; + } + /* c8 ignore stop */ + if (p === exports.GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]); + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi; + var pr = pi + 1; + if (pr === pl) { + this.debug('** at the end'); + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || + file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) + return false; + } + return true; + } + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr]; + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee); + // found a match. + return true; + } + else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || + swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr); + break; + } + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue'); + fr++; + } + } + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + /* c8 ignore start */ + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr); + if (fr === fl) { + return true; + } + } + /* c8 ignore stop */ + return false; + } + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + let hit; + if (typeof p === 'string') { + hit = f === p; + this.debug('string match', p, f, hit); + } + else { + hit = p.test(f); + this.debug('pattern match', p, f, hit); + } + if (!hit) + return false; + } + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true; + } + else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial; + } + else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + return fi === fl - 1 && file[fi] === ''; + /* c8 ignore start */ + } + else { + // should be unreachable. + throw new Error('wtf?'); + } + /* c8 ignore stop */ + } + braceExpand() { + return (0, exports.braceExpand)(this.pattern, this.options); + } + parse(pattern) { + (0, assert_valid_pattern_js_1.assertValidPattern)(pattern); + const options = this.options; + // shortcuts + if (pattern === '**') + return exports.GLOBSTAR; + if (pattern === '') + return ''; + // far and away, the most common glob pattern parts are + // *, *.*, and *.<ext> Add a fast check method for those. + let m; + let fastTest = null; + if ((m = pattern.match(starRE))) { + fastTest = options.dot ? starTestDot : starTest; + } + else if ((m = pattern.match(starDotExtRE))) { + fastTest = (options.nocase + ? options.dot + ? starDotExtTestNocaseDot + : starDotExtTestNocase + : options.dot + ? starDotExtTestDot + : starDotExtTest)(m[1]); + } + else if ((m = pattern.match(qmarksRE))) { + fastTest = (options.nocase + ? options.dot + ? qmarksTestNocaseDot + : qmarksTestNocase + : options.dot + ? qmarksTestDot + : qmarksTest)(m); + } + else if ((m = pattern.match(starDotStarRE))) { + fastTest = options.dot ? starDotStarTestDot : starDotStarTest; + } + else if ((m = pattern.match(dotStarRE))) { + fastTest = dotStarTest; + } + const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern(); + if (fastTest && typeof re === 'object') { + // Avoids overriding in frozen environments + Reflect.defineProperty(re, 'test', { value: fastTest }); + } + return re; + } + makeRe() { + if (this.regexp || this.regexp === false) + return this.regexp; + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + const set = this.set; + if (!set.length) { + this.regexp = false; + return this.regexp; + } + const options = this.options; + const twoStar = options.noglobstar + ? star + : options.dot + ? twoStarDot + : twoStarNoDot; + const flags = new Set(options.nocase ? ['i'] : []); + // regexpify non-globstar patterns + // if ** is only item, then we just do one twoStar + // if ** is first, and there are more, prepend (\/|twoStar\/)? to next + // if ** is last, append (\/twoStar|) to previous + // if ** is in the middle, append (\/|\/twoStar\/) to previous + // then filter out GLOBSTAR symbols + let re = set + .map(pattern => { + const pp = pattern.map(p => { + if (p instanceof RegExp) { + for (const f of p.flags.split('')) + flags.add(f); + } + return typeof p === 'string' + ? regExpEscape(p) + : p === exports.GLOBSTAR + ? exports.GLOBSTAR + : p._src; + }); + pp.forEach((p, i) => { + const next = pp[i + 1]; + const prev = pp[i - 1]; + if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) { + return; + } + if (prev === undefined) { + if (next !== undefined && next !== exports.GLOBSTAR) { + pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next; + } + else { + pp[i] = twoStar; + } + } + else if (next === undefined) { + pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + ')?'; + } + else if (next !== exports.GLOBSTAR) { + pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next; + pp[i + 1] = exports.GLOBSTAR; + } + }); + const filtered = pp.filter(p => p !== exports.GLOBSTAR); + // For partial matches, we need to make the pattern match + // any prefix of the full path. We do this by generating + // alternative patterns that match progressively longer prefixes. + if (this.partial && filtered.length >= 1) { + const prefixes = []; + for (let i = 1; i <= filtered.length; i++) { + prefixes.push(filtered.slice(0, i).join('/')); + } + return '(?:' + prefixes.join('|') + ')'; + } + return filtered.join('/'); + }) + .join('|'); + // need to wrap in parens if we had more than one thing with |, + // otherwise only the first will be anchored to ^ and the last to $ + const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']; + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^' + open + re + close + '$'; + // In partial mode, '/' should always match as it's a valid prefix for any pattern + if (this.partial) { + re = '^(?:\\/|' + open + re.slice(1, -1) + close + ')$'; + } + // can match anything, as long as it's not this. + if (this.negate) + re = '^(?!' + re + ').+$'; + try { + this.regexp = new RegExp(re, [...flags].join('')); + /* c8 ignore start */ + } + catch (ex) { + // should be impossible + this.regexp = false; + } + /* c8 ignore stop */ + return this.regexp; + } + slashSplit(p) { + // if p starts with // on windows, we preserve that + // so that UNC paths aren't broken. Otherwise, any number of + // / characters are coalesced into one, unless + // preserveMultipleSlashes is set to true. + if (this.preserveMultipleSlashes) { + return p.split('/'); + } + else if (this.isWindows && /^\/\/[^\/]+/.test(p)) { + // add an extra '' for the one we lose + return ['', ...p.split(/\/+/)]; + } + else { + return p.split(/\/+/); + } + } + match(f, partial = this.partial) { + this.debug('match', f, this.pattern); + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) { + return false; + } + if (this.empty) { + return f === ''; + } + if (f === '/' && partial) { + return true; + } + const options = this.options; + // windows: need to use /, not \ + if (this.isWindows) { + f = f.split('\\').join('/'); + } + // treat the test path as a set of pathparts. + const ff = this.slashSplit(f); + this.debug(this.pattern, 'split', ff); + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + const set = this.set; + this.debug(this.pattern, 'set', set); + // Find the basename of the path by looking for the last non-empty segment + let filename = ff[ff.length - 1]; + if (!filename) { + for (let i = ff.length - 2; !filename && i >= 0; i--) { + filename = ff[i]; + } + } + for (let i = 0; i < set.length; i++) { + const pattern = set[i]; + let file = ff; + if (options.matchBase && pattern.length === 1) { + file = [filename]; + } + const hit = this.matchOne(file, pattern, partial); + if (hit) { + if (options.flipNegate) { + return true; + } + return !this.negate; + } + } + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) { + return false; + } + return this.negate; + } + static defaults(def) { + return exports.minimatch.defaults(def).Minimatch; + } +} +exports.Minimatch = Minimatch; +/* c8 ignore start */ +var ast_js_2 = require("./ast.js"); +Object.defineProperty(exports, "AST", { enumerable: true, get: function () { return ast_js_2.AST; } }); +var escape_js_2 = require("./escape.js"); +Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return escape_js_2.escape; } }); +var unescape_js_2 = require("./unescape.js"); +Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return unescape_js_2.unescape; } }); +/* c8 ignore stop */ +exports.minimatch.AST = ast_js_1.AST; +exports.minimatch.Minimatch = Minimatch; +exports.minimatch.escape = escape_js_1.escape; +exports.minimatch.unescape = unescape_js_1.unescape; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/commonjs/package.json b/node_modules/minimatch/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/minimatch/dist/commonjs/unescape.js b/node_modules/minimatch/dist/commonjs/unescape.js new file mode 100644 index 0000000000000..171098d8a4ceb --- /dev/null +++ b/node_modules/minimatch/dist/commonjs/unescape.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unescape = void 0; +/** + * Un-escape a string that has been escaped with {@link escape}. + * + * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then + * square-bracket escapes are removed, but not backslash escapes. + * + * For example, it will turn the string `'[*]'` into `*`, but it will not + * turn `'\\*'` into `'*'`, because `\` is a path separator in + * `windowsPathsNoEscape` mode. + * + * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and + * backslash escapes are removed. + * + * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped + * or unescaped. + * + * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be + * unescaped. + */ +const unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true, } = {}) => { + if (magicalBraces) { + return windowsPathsNoEscape + ? s.replace(/\[([^\/\\])\]/g, '$1') + : s + .replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2') + .replace(/\\([^\/])/g, '$1'); + } + return windowsPathsNoEscape + ? s.replace(/\[([^\/\\{}])\]/g, '$1') + : s + .replace(/((?!\\).|^)\[([^\/\\{}])\]/g, '$1$2') + .replace(/\\([^\/{}])/g, '$1'); +}; +exports.unescape = unescape; +//# sourceMappingURL=unescape.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/esm/assert-valid-pattern.js b/node_modules/minimatch/dist/esm/assert-valid-pattern.js new file mode 100644 index 0000000000000..7b534fc30200b --- /dev/null +++ b/node_modules/minimatch/dist/esm/assert-valid-pattern.js @@ -0,0 +1,10 @@ +const MAX_PATTERN_LENGTH = 1024 * 64; +export const assertValidPattern = (pattern) => { + if (typeof pattern !== 'string') { + throw new TypeError('invalid pattern'); + } + if (pattern.length > MAX_PATTERN_LENGTH) { + throw new TypeError('pattern is too long'); + } +}; +//# sourceMappingURL=assert-valid-pattern.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/esm/ast.js b/node_modules/minimatch/dist/esm/ast.js new file mode 100644 index 0000000000000..e4547b16131b6 --- /dev/null +++ b/node_modules/minimatch/dist/esm/ast.js @@ -0,0 +1,587 @@ +// parse a single path portion +import { parseClass } from './brace-expressions.js'; +import { unescape } from './unescape.js'; +const types = new Set(['!', '?', '+', '*', '@']); +const isExtglobType = (c) => types.has(c); +// Patterns that get prepended to bind to the start of either the +// entire string, or just a single path portion, to prevent dots +// and/or traversal patterns, when needed. +// Exts don't need the ^ or / bit, because the root binds that already. +const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))'; +const startNoDot = '(?!\\.)'; +// characters that indicate a start of pattern needs the "no dots" bit, +// because a dot *might* be matched. ( is not in the list, because in +// the case of a child extglob, it will handle the prevention itself. +const addPatternStart = new Set(['[', '.']); +// cases where traversal is A-OK, no dot prevention needed +const justDots = new Set(['..', '.']); +const reSpecials = new Set('().*{}+?[]^$\\!'); +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// any single thing other than / +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// use + when we need to ensure that *something* matches, because the * is +// the only thing in the path portion. +const starNoEmpty = qmark + '+?'; +// remove the \ chars that we added if we end up doing a nonmagic compare +// const deslash = (s: string) => s.replace(/\\(.)/g, '$1') +export class AST { + type; + #root; + #hasMagic; + #uflag = false; + #parts = []; + #parent; + #parentIndex; + #negs; + #filledNegs = false; + #options; + #toString; + // set to true if it's an extglob with no children + // (which really means one child of '') + #emptyExt = false; + constructor(type, parent, options = {}) { + this.type = type; + // extglobs are inherently magical + if (type) + this.#hasMagic = true; + this.#parent = parent; + this.#root = this.#parent ? this.#parent.#root : this; + this.#options = this.#root === this ? options : this.#root.#options; + this.#negs = this.#root === this ? [] : this.#root.#negs; + if (type === '!' && !this.#root.#filledNegs) + this.#negs.push(this); + this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0; + } + get hasMagic() { + /* c8 ignore start */ + if (this.#hasMagic !== undefined) + return this.#hasMagic; + /* c8 ignore stop */ + for (const p of this.#parts) { + if (typeof p === 'string') + continue; + if (p.type || p.hasMagic) + return (this.#hasMagic = true); + } + // note: will be undefined until we generate the regexp src and find out + return this.#hasMagic; + } + // reconstructs the pattern + toString() { + if (this.#toString !== undefined) + return this.#toString; + if (!this.type) { + return (this.#toString = this.#parts.map(p => String(p)).join('')); + } + else { + return (this.#toString = + this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')'); + } + } + #fillNegs() { + /* c8 ignore start */ + if (this !== this.#root) + throw new Error('should only call on root'); + if (this.#filledNegs) + return this; + /* c8 ignore stop */ + // call toString() once to fill this out + this.toString(); + this.#filledNegs = true; + let n; + while ((n = this.#negs.pop())) { + if (n.type !== '!') + continue; + // walk up the tree, appending everthing that comes AFTER parentIndex + let p = n; + let pp = p.#parent; + while (pp) { + for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) { + for (const part of n.#parts) { + /* c8 ignore start */ + if (typeof part === 'string') { + throw new Error('string part in extglob AST??'); + } + /* c8 ignore stop */ + part.copyIn(pp.#parts[i]); + } + } + p = pp; + pp = p.#parent; + } + } + return this; + } + push(...parts) { + for (const p of parts) { + if (p === '') + continue; + /* c8 ignore start */ + if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) { + throw new Error('invalid part: ' + p); + } + /* c8 ignore stop */ + this.#parts.push(p); + } + } + toJSON() { + const ret = this.type === null + ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON())) + : [this.type, ...this.#parts.map(p => p.toJSON())]; + if (this.isStart() && !this.type) + ret.unshift([]); + if (this.isEnd() && + (this === this.#root || + (this.#root.#filledNegs && this.#parent?.type === '!'))) { + ret.push({}); + } + return ret; + } + isStart() { + if (this.#root === this) + return true; + // if (this.type) return !!this.#parent?.isStart() + if (!this.#parent?.isStart()) + return false; + if (this.#parentIndex === 0) + return true; + // if everything AHEAD of this is a negation, then it's still the "start" + const p = this.#parent; + for (let i = 0; i < this.#parentIndex; i++) { + const pp = p.#parts[i]; + if (!(pp instanceof AST && pp.type === '!')) { + return false; + } + } + return true; + } + isEnd() { + if (this.#root === this) + return true; + if (this.#parent?.type === '!') + return true; + if (!this.#parent?.isEnd()) + return false; + if (!this.type) + return this.#parent?.isEnd(); + // if not root, it'll always have a parent + /* c8 ignore start */ + const pl = this.#parent ? this.#parent.#parts.length : 0; + /* c8 ignore stop */ + return this.#parentIndex === pl - 1; + } + copyIn(part) { + if (typeof part === 'string') + this.push(part); + else + this.push(part.clone(this)); + } + clone(parent) { + const c = new AST(this.type, parent); + for (const p of this.#parts) { + c.copyIn(p); + } + return c; + } + static #parseAST(str, ast, pos, opt) { + let escaping = false; + let inBrace = false; + let braceStart = -1; + let braceNeg = false; + if (ast.type === null) { + // outside of a extglob, append until we find a start + let i = pos; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (inBrace) { + if (i === braceStart + 1) { + if (c === '^' || c === '!') { + braceNeg = true; + } + } + else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { + inBrace = false; + } + acc += c; + continue; + } + else if (c === '[') { + inBrace = true; + braceStart = i; + braceNeg = false; + acc += c; + continue; + } + if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') { + ast.push(acc); + acc = ''; + const ext = new AST(c, ast); + i = AST.#parseAST(str, ext, i, opt); + ast.push(ext); + continue; + } + acc += c; + } + ast.push(acc); + return i; + } + // some kind of extglob, pos is at the ( + // find the next | or ) + let i = pos + 1; + let part = new AST(null, ast); + const parts = []; + let acc = ''; + while (i < str.length) { + const c = str.charAt(i++); + // still accumulate escapes at this point, but we do ignore + // starts that are escaped + if (escaping || c === '\\') { + escaping = !escaping; + acc += c; + continue; + } + if (inBrace) { + if (i === braceStart + 1) { + if (c === '^' || c === '!') { + braceNeg = true; + } + } + else if (c === ']' && !(i === braceStart + 2 && braceNeg)) { + inBrace = false; + } + acc += c; + continue; + } + else if (c === '[') { + inBrace = true; + braceStart = i; + braceNeg = false; + acc += c; + continue; + } + if (isExtglobType(c) && str.charAt(i) === '(') { + part.push(acc); + acc = ''; + const ext = new AST(c, part); + part.push(ext); + i = AST.#parseAST(str, ext, i, opt); + continue; + } + if (c === '|') { + part.push(acc); + acc = ''; + parts.push(part); + part = new AST(null, ast); + continue; + } + if (c === ')') { + if (acc === '' && ast.#parts.length === 0) { + ast.#emptyExt = true; + } + part.push(acc); + acc = ''; + ast.push(...parts, part); + return i; + } + acc += c; + } + // unfinished extglob + // if we got here, it was a malformed extglob! not an extglob, but + // maybe something else in there. + ast.type = null; + ast.#hasMagic = undefined; + ast.#parts = [str.substring(pos - 1)]; + return i; + } + static fromGlob(pattern, options = {}) { + const ast = new AST(null, undefined, options); + AST.#parseAST(pattern, ast, 0, options); + return ast; + } + // returns the regular expression if there's magic, or the unescaped + // string if not. + toMMPattern() { + // should only be called on root + /* c8 ignore start */ + if (this !== this.#root) + return this.#root.toMMPattern(); + /* c8 ignore stop */ + const glob = this.toString(); + const [re, body, hasMagic, uflag] = this.toRegExpSource(); + // if we're in nocase mode, and not nocaseMagicOnly, then we do + // still need a regular expression if we have to case-insensitively + // match capital/lowercase characters. + const anyMagic = hasMagic || + this.#hasMagic || + (this.#options.nocase && + !this.#options.nocaseMagicOnly && + glob.toUpperCase() !== glob.toLowerCase()); + if (!anyMagic) { + return body; + } + const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : ''); + return Object.assign(new RegExp(`^${re}$`, flags), { + _src: re, + _glob: glob, + }); + } + get options() { + return this.#options; + } + // returns the string match, the regexp source, whether there's magic + // in the regexp (so a regular expression is required) and whether or + // not the uflag is needed for the regular expression (for posix classes) + // TODO: instead of injecting the start/end at this point, just return + // the BODY of the regexp, along with the start/end portions suitable + // for binding the start/end in either a joined full-path makeRe context + // (where we bind to (^|/), or a standalone matchPart context (where + // we bind to ^, and not /). Otherwise slashes get duped! + // + // In part-matching mode, the start is: + // - if not isStart: nothing + // - if traversal possible, but not allowed: ^(?!\.\.?$) + // - if dots allowed or not possible: ^ + // - if dots possible and not allowed: ^(?!\.) + // end is: + // - if not isEnd(): nothing + // - else: $ + // + // In full-path matching mode, we put the slash at the START of the + // pattern, so start is: + // - if first pattern: same as part-matching mode + // - if not isStart(): nothing + // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/)) + // - if dots allowed or not possible: / + // - if dots possible and not allowed: /(?!\.) + // end is: + // - if last pattern, same as part-matching mode + // - else nothing + // + // Always put the (?:$|/) on negated tails, though, because that has to be + // there to bind the end of the negated pattern portion, and it's easier to + // just stick it in now rather than try to inject it later in the middle of + // the pattern. + // + // We can just always return the same end, and leave it up to the caller + // to know whether it's going to be used joined or in parts. + // And, if the start is adjusted slightly, can do the same there: + // - if not isStart: nothing + // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$) + // - if dots allowed or not possible: (?:/|^) + // - if dots possible and not allowed: (?:/|^)(?!\.) + // + // But it's better to have a simpler binding without a conditional, for + // performance, so probably better to return both start options. + // + // Then the caller just ignores the end if it's not the first pattern, + // and the start always gets applied. + // + // But that's always going to be $ if it's the ending pattern, or nothing, + // so the caller can just attach $ at the end of the pattern when building. + // + // So the todo is: + // - better detect what kind of start is needed + // - return both flavors of starting pattern + // - attach $ at the end of the pattern when creating the actual RegExp + // + // Ah, but wait, no, that all only applies to the root when the first pattern + // is not an extglob. If the first pattern IS an extglob, then we need all + // that dot prevention biz to live in the extglob portions, because eg + // +(*|.x*) can match .xy but not .yx. + // + // So, return the two flavors if it's #root and the first child is not an + // AST, otherwise leave it to the child AST to handle it, and there, + // use the (?:^|/) style of start binding. + // + // Even simplified further: + // - Since the start for a join is eg /(?!\.) and the start for a part + // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root + // or start or whatever) and prepend ^ or / at the Regexp construction. + toRegExpSource(allowDot) { + const dot = allowDot ?? !!this.#options.dot; + if (this.#root === this) + this.#fillNegs(); + if (!this.type) { + const noEmpty = this.isStart() && + this.isEnd() && + !this.#parts.some(s => typeof s !== 'string'); + const src = this.#parts + .map(p => { + const [re, _, hasMagic, uflag] = typeof p === 'string' + ? AST.#parseGlob(p, this.#hasMagic, noEmpty) + : p.toRegExpSource(allowDot); + this.#hasMagic = this.#hasMagic || hasMagic; + this.#uflag = this.#uflag || uflag; + return re; + }) + .join(''); + let start = ''; + if (this.isStart()) { + if (typeof this.#parts[0] === 'string') { + // this is the string that will match the start of the pattern, + // so we need to protect against dots and such. + // '.' and '..' cannot match unless the pattern is that exactly, + // even if it starts with . or dot:true is set. + const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]); + if (!dotTravAllowed) { + const aps = addPatternStart; + // check if we have a possibility of matching . or .., + // and prevent that. + const needNoTrav = + // dots are allowed, and the pattern starts with [ or . + (dot && aps.has(src.charAt(0))) || + // the pattern starts with \., and then [ or . + (src.startsWith('\\.') && aps.has(src.charAt(2))) || + // the pattern starts with \.\., and then [ or . + (src.startsWith('\\.\\.') && aps.has(src.charAt(4))); + // no need to prevent dots if it can't match a dot, or if a + // sub-pattern will be preventing it anyway. + const needNoDot = !dot && !allowDot && aps.has(src.charAt(0)); + start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : ''; + } + } + } + // append the "end of path portion" pattern to negation tails + let end = ''; + if (this.isEnd() && + this.#root.#filledNegs && + this.#parent?.type === '!') { + end = '(?:$|\\/)'; + } + const final = start + src + end; + return [ + final, + unescape(src), + (this.#hasMagic = !!this.#hasMagic), + this.#uflag, + ]; + } + // We need to calculate the body *twice* if it's a repeat pattern + // at the start, once in nodot mode, then again in dot mode, so a + // pattern like *(?) can match 'x.y' + const repeated = this.type === '*' || this.type === '+'; + // some kind of extglob + const start = this.type === '!' ? '(?:(?!(?:' : '(?:'; + let body = this.#partsToRegExp(dot); + if (this.isStart() && this.isEnd() && !body && this.type !== '!') { + // invalid extglob, has to at least be *something* present, if it's + // the entire path portion. + const s = this.toString(); + this.#parts = [s]; + this.type = null; + this.#hasMagic = undefined; + return [s, unescape(this.toString()), false, false]; + } + // XXX abstract out this map method + let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot + ? '' + : this.#partsToRegExp(true); + if (bodyDotAllowed === body) { + bodyDotAllowed = ''; + } + if (bodyDotAllowed) { + body = `(?:${body})(?:${bodyDotAllowed})*?`; + } + // an empty !() is exactly equivalent to a starNoEmpty + let final = ''; + if (this.type === '!' && this.#emptyExt) { + final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty; + } + else { + const close = this.type === '!' + ? // !() must match something,but !(x) can match '' + '))' + + (this.isStart() && !dot && !allowDot ? startNoDot : '') + + star + + ')' + : this.type === '@' + ? ')' + : this.type === '?' + ? ')?' + : this.type === '+' && bodyDotAllowed + ? ')' + : this.type === '*' && bodyDotAllowed + ? `)?` + : `)${this.type}`; + final = start + body + close; + } + return [ + final, + unescape(body), + (this.#hasMagic = !!this.#hasMagic), + this.#uflag, + ]; + } + #partsToRegExp(dot) { + return this.#parts + .map(p => { + // extglob ASTs should only contain parent ASTs + /* c8 ignore start */ + if (typeof p === 'string') { + throw new Error('string type in extglob ast??'); + } + /* c8 ignore stop */ + // can ignore hasMagic, because extglobs are already always magic + const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot); + this.#uflag = this.#uflag || uflag; + return re; + }) + .filter(p => !(this.isStart() && this.isEnd()) || !!p) + .join('|'); + } + static #parseGlob(glob, hasMagic, noEmpty = false) { + let escaping = false; + let re = ''; + let uflag = false; + for (let i = 0; i < glob.length; i++) { + const c = glob.charAt(i); + if (escaping) { + escaping = false; + re += (reSpecials.has(c) ? '\\' : '') + c; + continue; + } + if (c === '\\') { + if (i === glob.length - 1) { + re += '\\\\'; + } + else { + escaping = true; + } + continue; + } + if (c === '[') { + const [src, needUflag, consumed, magic] = parseClass(glob, i); + if (consumed) { + re += src; + uflag = uflag || needUflag; + i += consumed - 1; + hasMagic = hasMagic || magic; + continue; + } + } + if (c === '*') { + re += noEmpty && glob === '*' ? starNoEmpty : star; + hasMagic = true; + continue; + } + if (c === '?') { + re += qmark; + hasMagic = true; + continue; + } + re += regExpEscape(c); + } + return [re, unescape(glob), !!hasMagic, uflag]; + } +} +//# sourceMappingURL=ast.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/esm/brace-expressions.js b/node_modules/minimatch/dist/esm/brace-expressions.js new file mode 100644 index 0000000000000..c629d6ae816e2 --- /dev/null +++ b/node_modules/minimatch/dist/esm/brace-expressions.js @@ -0,0 +1,148 @@ +// translate the various posix character classes into unicode properties +// this works across all unicode locales +// { <posix class>: [<translation>, /u flag required, negated] +const posixClasses = { + '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true], + '[:alpha:]': ['\\p{L}\\p{Nl}', true], + '[:ascii:]': ['\\x' + '00-\\x' + '7f', false], + '[:blank:]': ['\\p{Zs}\\t', true], + '[:cntrl:]': ['\\p{Cc}', true], + '[:digit:]': ['\\p{Nd}', true], + '[:graph:]': ['\\p{Z}\\p{C}', true, true], + '[:lower:]': ['\\p{Ll}', true], + '[:print:]': ['\\p{C}', true], + '[:punct:]': ['\\p{P}', true], + '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true], + '[:upper:]': ['\\p{Lu}', true], + '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true], + '[:xdigit:]': ['A-Fa-f0-9', false], +}; +// only need to escape a few things inside of brace expressions +// escapes: [ \ ] - +const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&'); +// escape all regexp magic characters +const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +// everything has already been escaped, we just have to join +const rangesToString = (ranges) => ranges.join(''); +// takes a glob string at a posix brace expression, and returns +// an equivalent regular expression source, and boolean indicating +// whether the /u flag needs to be applied, and the number of chars +// consumed to parse the character class. +// This also removes out of order ranges, and returns ($.) if the +// entire class just no good. +export const parseClass = (glob, position) => { + const pos = position; + /* c8 ignore start */ + if (glob.charAt(pos) !== '[') { + throw new Error('not in a brace expression'); + } + /* c8 ignore stop */ + const ranges = []; + const negs = []; + let i = pos + 1; + let sawStart = false; + let uflag = false; + let escaping = false; + let negate = false; + let endPos = pos; + let rangeStart = ''; + WHILE: while (i < glob.length) { + const c = glob.charAt(i); + if ((c === '!' || c === '^') && i === pos + 1) { + negate = true; + i++; + continue; + } + if (c === ']' && sawStart && !escaping) { + endPos = i + 1; + break; + } + sawStart = true; + if (c === '\\') { + if (!escaping) { + escaping = true; + i++; + continue; + } + // escaped \ char, fall through and treat like normal char + } + if (c === '[' && !escaping) { + // either a posix class, a collation equivalent, or just a [ + for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) { + if (glob.startsWith(cls, i)) { + // invalid, [a-[] is fine, but not [a-[:alpha]] + if (rangeStart) { + return ['$.', false, glob.length - pos, true]; + } + i += cls.length; + if (neg) + negs.push(unip); + else + ranges.push(unip); + uflag = uflag || u; + continue WHILE; + } + } + } + // now it's just a normal character, effectively + escaping = false; + if (rangeStart) { + // throw this range away if it's not valid, but others + // can still match. + if (c > rangeStart) { + ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c)); + } + else if (c === rangeStart) { + ranges.push(braceEscape(c)); + } + rangeStart = ''; + i++; + continue; + } + // now might be the start of a range. + // can be either c-d or c-] or c<more...>] or c] at this point + if (glob.startsWith('-]', i + 1)) { + ranges.push(braceEscape(c + '-')); + i += 2; + continue; + } + if (glob.startsWith('-', i + 1)) { + rangeStart = c; + i += 2; + continue; + } + // not the start of a range, just a single character + ranges.push(braceEscape(c)); + i++; + } + if (endPos < i) { + // didn't see the end of the class, not a valid class, + // but might still be valid as a literal match. + return ['', false, 0, false]; + } + // if we got no ranges and no negates, then we have a range that + // cannot possibly match anything, and that poisons the whole glob + if (!ranges.length && !negs.length) { + return ['$.', false, glob.length - pos, true]; + } + // if we got one positive range, and it's a single character, then that's + // not actually a magic pattern, it's just that one literal character. + // we should not treat that as "magic", we should just return the literal + // character. [_] is a perfectly valid way to escape glob magic chars. + if (negs.length === 0 && + ranges.length === 1 && + /^\\?.$/.test(ranges[0]) && + !negate) { + const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0]; + return [regexpEscape(r), false, endPos - pos, false]; + } + const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']'; + const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']'; + const comb = ranges.length && negs.length + ? '(' + sranges + '|' + snegs + ')' + : ranges.length + ? sranges + : snegs; + return [comb, uflag, endPos - pos, true]; +}; +//# sourceMappingURL=brace-expressions.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/esm/escape.js b/node_modules/minimatch/dist/esm/escape.js new file mode 100644 index 0000000000000..bab968ff3d83c --- /dev/null +++ b/node_modules/minimatch/dist/esm/escape.js @@ -0,0 +1,26 @@ +/** + * Escape all magic characters in a glob pattern. + * + * If the {@link MinimatchOptions.windowsPathsNoEscape} + * option is used, then characters are escaped by wrapping in `[]`, because + * a magic character wrapped in a character class can only be satisfied by + * that exact character. In this mode, `\` is _not_ escaped, because it is + * not interpreted as a magic character, but instead as a path separator. + * + * If the {@link MinimatchOptions.magicalBraces} option is used, + * then braces (`{` and `}`) will be escaped. + */ +export const escape = (s, { windowsPathsNoEscape = false, magicalBraces = false, } = {}) => { + // don't need to escape +@! because we escape the parens + // that make those magic, and escaping ! as [!] isn't valid, + // because [!]] is a valid glob class meaning not ']'. + if (magicalBraces) { + return windowsPathsNoEscape + ? s.replace(/[?*()[\]{}]/g, '[$&]') + : s.replace(/[?*()[\]\\{}]/g, '\\$&'); + } + return windowsPathsNoEscape + ? s.replace(/[?*()[\]]/g, '[$&]') + : s.replace(/[?*()[\]\\]/g, '\\$&'); +}; +//# sourceMappingURL=escape.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/esm/index.js b/node_modules/minimatch/dist/esm/index.js new file mode 100644 index 0000000000000..e83823fa6e1b5 --- /dev/null +++ b/node_modules/minimatch/dist/esm/index.js @@ -0,0 +1,1016 @@ +import { expand } from '@isaacs/brace-expansion'; +import { assertValidPattern } from './assert-valid-pattern.js'; +import { AST } from './ast.js'; +import { escape } from './escape.js'; +import { unescape } from './unescape.js'; +export const minimatch = (p, pattern, options = {}) => { + assertValidPattern(pattern); + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false; + } + return new Minimatch(pattern, options).match(p); +}; +// Optimized checking for the most common glob patterns. +const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/; +const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext); +const starDotExtTestDot = (ext) => (f) => f.endsWith(ext); +const starDotExtTestNocase = (ext) => { + ext = ext.toLowerCase(); + return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext); +}; +const starDotExtTestNocaseDot = (ext) => { + ext = ext.toLowerCase(); + return (f) => f.toLowerCase().endsWith(ext); +}; +const starDotStarRE = /^\*+\.\*+$/; +const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.'); +const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.'); +const dotStarRE = /^\.\*+$/; +const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.'); +const starRE = /^\*+$/; +const starTest = (f) => f.length !== 0 && !f.startsWith('.'); +const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..'; +const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/; +const qmarksTestNocase = ([$0, ext = '']) => { + const noext = qmarksTestNoExt([$0]); + if (!ext) + return noext; + ext = ext.toLowerCase(); + return (f) => noext(f) && f.toLowerCase().endsWith(ext); +}; +const qmarksTestNocaseDot = ([$0, ext = '']) => { + const noext = qmarksTestNoExtDot([$0]); + if (!ext) + return noext; + ext = ext.toLowerCase(); + return (f) => noext(f) && f.toLowerCase().endsWith(ext); +}; +const qmarksTestDot = ([$0, ext = '']) => { + const noext = qmarksTestNoExtDot([$0]); + return !ext ? noext : (f) => noext(f) && f.endsWith(ext); +}; +const qmarksTest = ([$0, ext = '']) => { + const noext = qmarksTestNoExt([$0]); + return !ext ? noext : (f) => noext(f) && f.endsWith(ext); +}; +const qmarksTestNoExt = ([$0]) => { + const len = $0.length; + return (f) => f.length === len && !f.startsWith('.'); +}; +const qmarksTestNoExtDot = ([$0]) => { + const len = $0.length; + return (f) => f.length === len && f !== '.' && f !== '..'; +}; +/* c8 ignore start */ +const defaultPlatform = (typeof process === 'object' && process + ? (typeof process.env === 'object' && + process.env && + process.env.__MINIMATCH_TESTING_PLATFORM__) || + process.platform + : 'posix'); +const path = { + win32: { sep: '\\' }, + posix: { sep: '/' }, +}; +/* c8 ignore stop */ +export const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep; +minimatch.sep = sep; +export const GLOBSTAR = Symbol('globstar **'); +minimatch.GLOBSTAR = GLOBSTAR; +// any single thing other than / +// don't need to escape / when using new RegExp() +const qmark = '[^/]'; +// * => any number of characters +const star = qmark + '*?'; +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?'; +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?'; +export const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options); +minimatch.filter = filter; +const ext = (a, b = {}) => Object.assign({}, a, b); +export const defaults = (def) => { + if (!def || typeof def !== 'object' || !Object.keys(def).length) { + return minimatch; + } + const orig = minimatch; + const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options)); + return Object.assign(m, { + Minimatch: class Minimatch extends orig.Minimatch { + constructor(pattern, options = {}) { + super(pattern, ext(def, options)); + } + static defaults(options) { + return orig.defaults(ext(def, options)).Minimatch; + } + }, + AST: class AST extends orig.AST { + /* c8 ignore start */ + constructor(type, parent, options = {}) { + super(type, parent, ext(def, options)); + } + /* c8 ignore stop */ + static fromGlob(pattern, options = {}) { + return orig.AST.fromGlob(pattern, ext(def, options)); + } + }, + unescape: (s, options = {}) => orig.unescape(s, ext(def, options)), + escape: (s, options = {}) => orig.escape(s, ext(def, options)), + filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)), + defaults: (options) => orig.defaults(ext(def, options)), + makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)), + braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)), + match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)), + sep: orig.sep, + GLOBSTAR: GLOBSTAR, + }); +}; +minimatch.defaults = defaults; +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +export const braceExpand = (pattern, options = {}) => { + assertValidPattern(pattern); + // Thanks to Yeting Li <https://github.com/yetingli> for + // improving this regexp to avoid a ReDOS vulnerability. + if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { + // shortcut. no need to expand. + return [pattern]; + } + return expand(pattern); +}; +minimatch.braceExpand = braceExpand; +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +export const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe(); +minimatch.makeRe = makeRe; +export const match = (list, pattern, options = {}) => { + const mm = new Minimatch(pattern, options); + list = list.filter(f => mm.match(f)); + if (mm.options.nonull && !list.length) { + list.push(pattern); + } + return list; +}; +minimatch.match = match; +// replace stuff like \* with * +const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/; +const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +export class Minimatch { + options; + set; + pattern; + windowsPathsNoEscape; + nonegate; + negate; + comment; + empty; + preserveMultipleSlashes; + partial; + globSet; + globParts; + nocase; + isWindows; + platform; + windowsNoMagicRoot; + regexp; + constructor(pattern, options = {}) { + assertValidPattern(pattern); + options = options || {}; + this.options = options; + this.pattern = pattern; + this.platform = options.platform || defaultPlatform; + this.isWindows = this.platform === 'win32'; + this.windowsPathsNoEscape = + !!options.windowsPathsNoEscape || options.allowWindowsEscape === false; + if (this.windowsPathsNoEscape) { + this.pattern = this.pattern.replace(/\\/g, '/'); + } + this.preserveMultipleSlashes = !!options.preserveMultipleSlashes; + this.regexp = null; + this.negate = false; + this.nonegate = !!options.nonegate; + this.comment = false; + this.empty = false; + this.partial = !!options.partial; + this.nocase = !!this.options.nocase; + this.windowsNoMagicRoot = + options.windowsNoMagicRoot !== undefined + ? options.windowsNoMagicRoot + : !!(this.isWindows && this.nocase); + this.globSet = []; + this.globParts = []; + this.set = []; + // make the set of regexps etc. + this.make(); + } + hasMagic() { + if (this.options.magicalBraces && this.set.length > 1) { + return true; + } + for (const pattern of this.set) { + for (const part of pattern) { + if (typeof part !== 'string') + return true; + } + } + return false; + } + debug(..._) { } + make() { + const pattern = this.pattern; + const options = this.options; + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true; + return; + } + if (!pattern) { + this.empty = true; + return; + } + // step 1: figure out negation, etc. + this.parseNegate(); + // step 2: expand braces + this.globSet = [...new Set(this.braceExpand())]; + if (options.debug) { + this.debug = (...args) => console.error(...args); + } + this.debug(this.pattern, this.globSet); + // step 3: now we have a set, so turn each one into a series of + // path-portion matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + // + // First, we preprocess to make the glob pattern sets a bit simpler + // and deduped. There are some perf-killing patterns that can cause + // problems with a glob walk, but we can simplify them down a bit. + const rawGlobParts = this.globSet.map(s => this.slashSplit(s)); + this.globParts = this.preprocess(rawGlobParts); + this.debug(this.pattern, this.globParts); + // glob --> regexps + let set = this.globParts.map((s, _, __) => { + if (this.isWindows && this.windowsNoMagicRoot) { + // check if it's a drive or unc path. + const isUNC = s[0] === '' && + s[1] === '' && + (s[2] === '?' || !globMagic.test(s[2])) && + !globMagic.test(s[3]); + const isDrive = /^[a-z]:/i.test(s[0]); + if (isUNC) { + return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]; + } + else if (isDrive) { + return [s[0], ...s.slice(1).map(ss => this.parse(ss))]; + } + } + return s.map(ss => this.parse(ss)); + }); + this.debug(this.pattern, set); + // filter out everything that didn't compile properly. + this.set = set.filter(s => s.indexOf(false) === -1); + // do not treat the ? in UNC paths as magic + if (this.isWindows) { + for (let i = 0; i < this.set.length; i++) { + const p = this.set[i]; + if (p[0] === '' && + p[1] === '' && + this.globParts[i][2] === '?' && + typeof p[3] === 'string' && + /^[a-z]:$/i.test(p[3])) { + p[2] = '?'; + } + } + } + this.debug(this.pattern, this.set); + } + // various transforms to equivalent pattern sets that are + // faster to process in a filesystem walk. The goal is to + // eliminate what we can, and push all ** patterns as far + // to the right as possible, even if it increases the number + // of patterns that we have to process. + preprocess(globParts) { + // if we're not in globstar mode, then turn all ** into * + if (this.options.noglobstar) { + for (let i = 0; i < globParts.length; i++) { + for (let j = 0; j < globParts[i].length; j++) { + if (globParts[i][j] === '**') { + globParts[i][j] = '*'; + } + } + } + } + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + // aggressive optimization for the purpose of fs walking + globParts = this.firstPhasePreProcess(globParts); + globParts = this.secondPhasePreProcess(globParts); + } + else if (optimizationLevel >= 1) { + // just basic optimizations to remove some .. parts + globParts = this.levelOneOptimize(globParts); + } + else { + // just collapse multiple ** portions into one + globParts = this.adjascentGlobstarOptimize(globParts); + } + return globParts; + } + // just get rid of adjascent ** portions + adjascentGlobstarOptimize(globParts) { + return globParts.map(parts => { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let i = gs; + while (parts[i + 1] === '**') { + i++; + } + if (i !== gs) { + parts.splice(gs, i - gs); + } + } + return parts; + }); + } + // get rid of adjascent ** and resolve .. portions + levelOneOptimize(globParts) { + return globParts.map(parts => { + parts = parts.reduce((set, part) => { + const prev = set[set.length - 1]; + if (part === '**' && prev === '**') { + return set; + } + if (part === '..') { + if (prev && prev !== '..' && prev !== '.' && prev !== '**') { + set.pop(); + return set; + } + } + set.push(part); + return set; + }, []); + return parts.length === 0 ? [''] : parts; + }); + } + levelTwoFileOptimize(parts) { + if (!Array.isArray(parts)) { + parts = this.slashSplit(parts); + } + let didSomething = false; + do { + didSomething = false; + // <pre>/<e>/<rest> -> <pre>/<rest> + if (!this.preserveMultipleSlashes) { + for (let i = 1; i < parts.length - 1; i++) { + const p = parts[i]; + // don't squeeze out UNC patterns + if (i === 1 && p === '' && parts[0] === '') + continue; + if (p === '.' || p === '') { + didSomething = true; + parts.splice(i, 1); + i--; + } + } + if (parts[0] === '.' && + parts.length === 2 && + (parts[1] === '.' || parts[1] === '')) { + didSomething = true; + parts.pop(); + } + } + // <pre>/<p>/../<rest> -> <pre>/<rest> + let dd = 0; + while (-1 !== (dd = parts.indexOf('..', dd + 1))) { + const p = parts[dd - 1]; + if (p && p !== '.' && p !== '..' && p !== '**') { + didSomething = true; + parts.splice(dd - 1, 2); + dd -= 2; + } + } + } while (didSomething); + return parts.length === 0 ? [''] : parts; + } + // First phase: single-pattern processing + // <pre> is 1 or more portions + // <rest> is 1 or more portions + // <p> is any portion other than ., .., '', or ** + // <e> is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} + // <pre>/<e>/<rest> -> <pre>/<rest> + // <pre>/<p>/../<rest> -> <pre>/<rest> + // **/**/<rest> -> **/<rest> + // + // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow + // this WOULD be allowed if ** did follow symlinks, or * didn't + firstPhasePreProcess(globParts) { + let didSomething = false; + do { + didSomething = false; + // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>} + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss = gs; + while (parts[gss + 1] === '**') { + // <pre>/**/**/<rest> -> <pre>/**/<rest> + gss++; + } + // eg, if gs is 2 and gss is 4, that means we have 3 ** + // parts, and can remove 2 of them. + if (gss > gs) { + parts.splice(gs + 1, gss - gs); + } + let next = parts[gs + 1]; + const p = parts[gs + 2]; + const p2 = parts[gs + 3]; + if (next !== '..') + continue; + if (!p || + p === '.' || + p === '..' || + !p2 || + p2 === '.' || + p2 === '..') { + continue; + } + didSomething = true; + // edit parts in place, and push the new one + parts.splice(gs, 1); + const other = parts.slice(0); + other[gs] = '**'; + globParts.push(other); + gs--; + } + // <pre>/<e>/<rest> -> <pre>/<rest> + if (!this.preserveMultipleSlashes) { + for (let i = 1; i < parts.length - 1; i++) { + const p = parts[i]; + // don't squeeze out UNC patterns + if (i === 1 && p === '' && parts[0] === '') + continue; + if (p === '.' || p === '') { + didSomething = true; + parts.splice(i, 1); + i--; + } + } + if (parts[0] === '.' && + parts.length === 2 && + (parts[1] === '.' || parts[1] === '')) { + didSomething = true; + parts.pop(); + } + } + // <pre>/<p>/../<rest> -> <pre>/<rest> + let dd = 0; + while (-1 !== (dd = parts.indexOf('..', dd + 1))) { + const p = parts[dd - 1]; + if (p && p !== '.' && p !== '..' && p !== '**') { + didSomething = true; + const needDot = dd === 1 && parts[dd + 1] === '**'; + const splin = needDot ? ['.'] : []; + parts.splice(dd - 1, 2, ...splin); + if (parts.length === 0) + parts.push(''); + dd -= 2; + } + } + } + } while (didSomething); + return globParts; + } + // second phase: multi-pattern dedupes + // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest> + // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest> + // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest> + // + // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest> + // ^-- not valid because ** doens't follow symlinks + secondPhasePreProcess(globParts) { + for (let i = 0; i < globParts.length - 1; i++) { + for (let j = i + 1; j < globParts.length; j++) { + const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes); + if (matched) { + globParts[i] = []; + globParts[j] = matched; + break; + } + } + } + return globParts.filter(gs => gs.length); + } + partsMatch(a, b, emptyGSMatch = false) { + let ai = 0; + let bi = 0; + let result = []; + let which = ''; + while (ai < a.length && bi < b.length) { + if (a[ai] === b[bi]) { + result.push(which === 'b' ? b[bi] : a[ai]); + ai++; + bi++; + } + else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) { + result.push(a[ai]); + ai++; + } + else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) { + result.push(b[bi]); + bi++; + } + else if (a[ai] === '*' && + b[bi] && + (this.options.dot || !b[bi].startsWith('.')) && + b[bi] !== '**') { + if (which === 'b') + return false; + which = 'a'; + result.push(a[ai]); + ai++; + bi++; + } + else if (b[bi] === '*' && + a[ai] && + (this.options.dot || !a[ai].startsWith('.')) && + a[ai] !== '**') { + if (which === 'a') + return false; + which = 'b'; + result.push(b[bi]); + ai++; + bi++; + } + else { + return false; + } + } + // if we fall out of the loop, it means they two are identical + // as long as their lengths match + return a.length === b.length && result; + } + parseNegate() { + if (this.nonegate) + return; + const pattern = this.pattern; + let negate = false; + let negateOffset = 0; + for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { + negate = !negate; + negateOffset++; + } + if (negateOffset) + this.pattern = pattern.slice(negateOffset); + this.negate = negate; + } + // set partial to true to test if, for example, + // "/a/b" matches the start of "/*/b/*/d" + // Partial means, if you run out of file before you run + // out of pattern, then that's fine, as long as all + // the parts match. + matchOne(file, pattern, partial = false) { + const options = this.options; + // UNC paths like //?/X:/... can match X:/... and vice versa + // Drive letters in absolute drive or unc paths are always compared + // case-insensitively. + if (this.isWindows) { + const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]); + const fileUNC = !fileDrive && + file[0] === '' && + file[1] === '' && + file[2] === '?' && + /^[a-z]:$/i.test(file[3]); + const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]); + const patternUNC = !patternDrive && + pattern[0] === '' && + pattern[1] === '' && + pattern[2] === '?' && + typeof pattern[3] === 'string' && + /^[a-z]:$/i.test(pattern[3]); + const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined; + const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined; + if (typeof fdi === 'number' && typeof pdi === 'number') { + const [fd, pd] = [file[fdi], pattern[pdi]]; + if (fd.toLowerCase() === pd.toLowerCase()) { + pattern[pdi] = fd; + if (pdi > fdi) { + pattern = pattern.slice(pdi); + } + else if (fdi > pdi) { + file = file.slice(fdi); + } + } + } + } + // resolve and reduce . and .. portions in the file as well. + // don't need to do the second phase, because it's only one string[] + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + file = this.levelTwoFileOptimize(file); + } + this.debug('matchOne', this, { file, pattern }); + this.debug('matchOne', file.length, pattern.length); + for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { + this.debug('matchOne loop'); + var p = pattern[pi]; + var f = file[fi]; + this.debug(pattern, p, f); + // should be impossible. + // some invalid regexp stuff in the set. + /* c8 ignore start */ + if (p === false) { + return false; + } + /* c8 ignore stop */ + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]); + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi; + var pr = pi + 1; + if (pr === pl) { + this.debug('** at the end'); + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || + file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) + return false; + } + return true; + } + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr]; + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee); + // found a match. + return true; + } + else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || + swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr); + break; + } + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue'); + fr++; + } + } + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + /* c8 ignore start */ + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr); + if (fr === fl) { + return true; + } + } + /* c8 ignore stop */ + return false; + } + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + let hit; + if (typeof p === 'string') { + hit = f === p; + this.debug('string match', p, f, hit); + } + else { + hit = p.test(f); + this.debug('pattern match', p, f, hit); + } + if (!hit) + return false; + } + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true; + } + else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial; + } + else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + return fi === fl - 1 && file[fi] === ''; + /* c8 ignore start */ + } + else { + // should be unreachable. + throw new Error('wtf?'); + } + /* c8 ignore stop */ + } + braceExpand() { + return braceExpand(this.pattern, this.options); + } + parse(pattern) { + assertValidPattern(pattern); + const options = this.options; + // shortcuts + if (pattern === '**') + return GLOBSTAR; + if (pattern === '') + return ''; + // far and away, the most common glob pattern parts are + // *, *.*, and *.<ext> Add a fast check method for those. + let m; + let fastTest = null; + if ((m = pattern.match(starRE))) { + fastTest = options.dot ? starTestDot : starTest; + } + else if ((m = pattern.match(starDotExtRE))) { + fastTest = (options.nocase + ? options.dot + ? starDotExtTestNocaseDot + : starDotExtTestNocase + : options.dot + ? starDotExtTestDot + : starDotExtTest)(m[1]); + } + else if ((m = pattern.match(qmarksRE))) { + fastTest = (options.nocase + ? options.dot + ? qmarksTestNocaseDot + : qmarksTestNocase + : options.dot + ? qmarksTestDot + : qmarksTest)(m); + } + else if ((m = pattern.match(starDotStarRE))) { + fastTest = options.dot ? starDotStarTestDot : starDotStarTest; + } + else if ((m = pattern.match(dotStarRE))) { + fastTest = dotStarTest; + } + const re = AST.fromGlob(pattern, this.options).toMMPattern(); + if (fastTest && typeof re === 'object') { + // Avoids overriding in frozen environments + Reflect.defineProperty(re, 'test', { value: fastTest }); + } + return re; + } + makeRe() { + if (this.regexp || this.regexp === false) + return this.regexp; + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + const set = this.set; + if (!set.length) { + this.regexp = false; + return this.regexp; + } + const options = this.options; + const twoStar = options.noglobstar + ? star + : options.dot + ? twoStarDot + : twoStarNoDot; + const flags = new Set(options.nocase ? ['i'] : []); + // regexpify non-globstar patterns + // if ** is only item, then we just do one twoStar + // if ** is first, and there are more, prepend (\/|twoStar\/)? to next + // if ** is last, append (\/twoStar|) to previous + // if ** is in the middle, append (\/|\/twoStar\/) to previous + // then filter out GLOBSTAR symbols + let re = set + .map(pattern => { + const pp = pattern.map(p => { + if (p instanceof RegExp) { + for (const f of p.flags.split('')) + flags.add(f); + } + return typeof p === 'string' + ? regExpEscape(p) + : p === GLOBSTAR + ? GLOBSTAR + : p._src; + }); + pp.forEach((p, i) => { + const next = pp[i + 1]; + const prev = pp[i - 1]; + if (p !== GLOBSTAR || prev === GLOBSTAR) { + return; + } + if (prev === undefined) { + if (next !== undefined && next !== GLOBSTAR) { + pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next; + } + else { + pp[i] = twoStar; + } + } + else if (next === undefined) { + pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + ')?'; + } + else if (next !== GLOBSTAR) { + pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next; + pp[i + 1] = GLOBSTAR; + } + }); + const filtered = pp.filter(p => p !== GLOBSTAR); + // For partial matches, we need to make the pattern match + // any prefix of the full path. We do this by generating + // alternative patterns that match progressively longer prefixes. + if (this.partial && filtered.length >= 1) { + const prefixes = []; + for (let i = 1; i <= filtered.length; i++) { + prefixes.push(filtered.slice(0, i).join('/')); + } + return '(?:' + prefixes.join('|') + ')'; + } + return filtered.join('/'); + }) + .join('|'); + // need to wrap in parens if we had more than one thing with |, + // otherwise only the first will be anchored to ^ and the last to $ + const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', '']; + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^' + open + re + close + '$'; + // In partial mode, '/' should always match as it's a valid prefix for any pattern + if (this.partial) { + re = '^(?:\\/|' + open + re.slice(1, -1) + close + ')$'; + } + // can match anything, as long as it's not this. + if (this.negate) + re = '^(?!' + re + ').+$'; + try { + this.regexp = new RegExp(re, [...flags].join('')); + /* c8 ignore start */ + } + catch (ex) { + // should be impossible + this.regexp = false; + } + /* c8 ignore stop */ + return this.regexp; + } + slashSplit(p) { + // if p starts with // on windows, we preserve that + // so that UNC paths aren't broken. Otherwise, any number of + // / characters are coalesced into one, unless + // preserveMultipleSlashes is set to true. + if (this.preserveMultipleSlashes) { + return p.split('/'); + } + else if (this.isWindows && /^\/\/[^\/]+/.test(p)) { + // add an extra '' for the one we lose + return ['', ...p.split(/\/+/)]; + } + else { + return p.split(/\/+/); + } + } + match(f, partial = this.partial) { + this.debug('match', f, this.pattern); + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) { + return false; + } + if (this.empty) { + return f === ''; + } + if (f === '/' && partial) { + return true; + } + const options = this.options; + // windows: need to use /, not \ + if (this.isWindows) { + f = f.split('\\').join('/'); + } + // treat the test path as a set of pathparts. + const ff = this.slashSplit(f); + this.debug(this.pattern, 'split', ff); + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + const set = this.set; + this.debug(this.pattern, 'set', set); + // Find the basename of the path by looking for the last non-empty segment + let filename = ff[ff.length - 1]; + if (!filename) { + for (let i = ff.length - 2; !filename && i >= 0; i--) { + filename = ff[i]; + } + } + for (let i = 0; i < set.length; i++) { + const pattern = set[i]; + let file = ff; + if (options.matchBase && pattern.length === 1) { + file = [filename]; + } + const hit = this.matchOne(file, pattern, partial); + if (hit) { + if (options.flipNegate) { + return true; + } + return !this.negate; + } + } + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) { + return false; + } + return this.negate; + } + static defaults(def) { + return minimatch.defaults(def).Minimatch; + } +} +/* c8 ignore start */ +export { AST } from './ast.js'; +export { escape } from './escape.js'; +export { unescape } from './unescape.js'; +/* c8 ignore stop */ +minimatch.AST = AST; +minimatch.Minimatch = Minimatch; +minimatch.escape = escape; +minimatch.unescape = unescape; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minimatch/dist/esm/package.json b/node_modules/minimatch/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/minimatch/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/minimatch/dist/esm/unescape.js b/node_modules/minimatch/dist/esm/unescape.js new file mode 100644 index 0000000000000..dfa408d39853b --- /dev/null +++ b/node_modules/minimatch/dist/esm/unescape.js @@ -0,0 +1,34 @@ +/** + * Un-escape a string that has been escaped with {@link escape}. + * + * If the {@link MinimatchOptions.windowsPathsNoEscape} option is used, then + * square-bracket escapes are removed, but not backslash escapes. + * + * For example, it will turn the string `'[*]'` into `*`, but it will not + * turn `'\\*'` into `'*'`, because `\` is a path separator in + * `windowsPathsNoEscape` mode. + * + * When `windowsPathsNoEscape` is not set, then both square-bracket escapes and + * backslash escapes are removed. + * + * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped + * or unescaped. + * + * When `magicalBraces` is not set, escapes of braces (`{` and `}`) will not be + * unescaped. + */ +export const unescape = (s, { windowsPathsNoEscape = false, magicalBraces = true, } = {}) => { + if (magicalBraces) { + return windowsPathsNoEscape + ? s.replace(/\[([^\/\\])\]/g, '$1') + : s + .replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2') + .replace(/\\([^\/])/g, '$1'); + } + return windowsPathsNoEscape + ? s.replace(/\[([^\/\\{}])\]/g, '$1') + : s + .replace(/((?!\\).|^)\[([^\/\\{}])\]/g, '$1$2') + .replace(/\\([^\/{}])/g, '$1'); +}; +//# sourceMappingURL=unescape.js.map \ No newline at end of file diff --git a/node_modules/minimatch/lib/path.js b/node_modules/minimatch/lib/path.js deleted file mode 100644 index ffe453d9e0557..0000000000000 --- a/node_modules/minimatch/lib/path.js +++ /dev/null @@ -1,4 +0,0 @@ -const isWindows = typeof process === 'object' && - process && - process.platform === 'win32' -module.exports = isWindows ? { sep: '\\' } : { sep: '/' } diff --git a/node_modules/minimatch/minimatch.js b/node_modules/minimatch/minimatch.js deleted file mode 100644 index 71c96a1fb71cc..0000000000000 --- a/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,906 +0,0 @@ -const minimatch = module.exports = (p, pattern, options = {}) => { - assertValidPattern(pattern) - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - return new Minimatch(pattern, options).match(p) -} - -module.exports = minimatch - -const path = require('./lib/path.js') -minimatch.sep = path.sep - -const GLOBSTAR = Symbol('globstar **') -minimatch.GLOBSTAR = GLOBSTAR -const expand = require('brace-expansion') - -const plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -const qmark = '[^/]' - -// * => any number of characters -const star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -const twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -const twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// "abc" -> { a:true, b:true, c:true } -const charSet = s => s.split('').reduce((set, c) => { - set[c] = true - return set -}, {}) - -// characters that need to be escaped in RegExp. -const reSpecials = charSet('().*{}+?[]^$\\!') - -// characters that indicate we have to add the pattern start -const addPatternStartSet = charSet('[.(') - -// normalizes slashes. -const slashSplit = /\/+/ - -minimatch.filter = (pattern, options = {}) => - (p, i, list) => minimatch(p, pattern, options) - -const ext = (a, b = {}) => { - const t = {} - Object.keys(a).forEach(k => t[k] = a[k]) - Object.keys(b).forEach(k => t[k] = b[k]) - return t -} - -minimatch.defaults = def => { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch - } - - const orig = minimatch - - const m = (p, pattern, options) => orig(p, pattern, ext(def, options)) - m.Minimatch = class Minimatch extends orig.Minimatch { - constructor (pattern, options) { - super(pattern, ext(def, options)) - } - } - m.Minimatch.defaults = options => orig.defaults(ext(def, options)).Minimatch - m.filter = (pattern, options) => orig.filter(pattern, ext(def, options)) - m.defaults = options => orig.defaults(ext(def, options)) - m.makeRe = (pattern, options) => orig.makeRe(pattern, ext(def, options)) - m.braceExpand = (pattern, options) => orig.braceExpand(pattern, ext(def, options)) - m.match = (list, pattern, options) => orig.match(list, pattern, ext(def, options)) - - return m -} - - - - - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = (pattern, options) => braceExpand(pattern, options) - -const braceExpand = (pattern, options = {}) => { - assertValidPattern(pattern) - - // Thanks to Yeting Li <https://github.com/yetingli> for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -const MAX_PATTERN_LENGTH = 1024 * 64 -const assertValidPattern = pattern => { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern') - } - - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long') - } -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -const SUBPARSE = Symbol('subparse') - -minimatch.makeRe = (pattern, options) => - new Minimatch(pattern, options || {}).makeRe() - -minimatch.match = (list, pattern, options = {}) => { - const mm = new Minimatch(pattern, options) - list = list.filter(f => mm.match(f)) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -// replace stuff like \* with * -const globUnescape = s => s.replace(/\\(.)/g, '$1') -const regExpEscape = s => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') - -class Minimatch { - constructor (pattern, options) { - assertValidPattern(pattern) - - if (!options) options = {} - - this.options = options - this.set = [] - this.pattern = pattern - this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || - options.allowWindowsEscape === false - if (this.windowsPathsNoEscape) { - this.pattern = this.pattern.replace(/\\/g, '/') - } - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - this.partial = !!options.partial - - // make the set of regexps etc. - this.make() - } - - debug () {} - - make () { - const pattern = this.pattern - const options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - let set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = (...args) => console.error(...args) - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(s => s.split(slashSplit)) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map((s, si, set) => s.map(this.parse, this)) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(s => s.indexOf(false) === -1) - - this.debug(this.pattern, set) - - this.set = set - } - - parseNegate () { - if (this.options.nonegate) return - - const pattern = this.pattern - let negate = false - let negateOffset = 0 - - for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate - } - - // set partial to true to test if, for example, - // "/a/b" matches the start of "/*/b/*/d" - // Partial means, if you run out of file before you run - // out of pattern, then that's fine, as long as all - // the parts match. - matchOne (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - /* istanbul ignore if */ - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - /* istanbul ignore if */ - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - hit = f === p - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else /* istanbul ignore else */ if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - return (fi === fl - 1) && (file[fi] === '') - } - - // should be unreachable. - /* istanbul ignore next */ - throw new Error('wtf?') - } - - braceExpand () { - return braceExpand(this.pattern, this.options) - } - - parse (pattern, isSub) { - assertValidPattern(pattern) - - const options = this.options - - // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR - else - pattern = '*' - } - if (pattern === '') return '' - - let re = '' - let hasMagic = !!options.nocase - let escaping = false - // ? => one single character - const patternListStack = [] - const negativeLists = [] - let stateChar - let inClass = false - let reClassStart = -1 - let classStart = -1 - let cs - let pl - let sp - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - const patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - - const clearStateChar = () => { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - this.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (let i = 0, c; (i < pattern.length) && (c = pattern.charAt(i)); i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping) { - /* istanbul ignore next - completely not allowed, even escaped. */ - if (c === '/') { - return false - } - - if (reSpecials[c]) { - re += '\\' - } - re += c - escaping = false - continue - } - - switch (c) { - /* istanbul ignore next */ - case '/': { - // Should already be path-split by now. - return false - } - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - this.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:<pattern>)<type> - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length) { - re += '\\|' - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (reSpecials[c] && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - break - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - let tail - tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, (_, $1, $2) => { - /* istanbul ignore else - should already be done */ - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - const t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - const addPatternStart = addPatternStartSet[re.charAt(0)] - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (let n = negativeLists.length - 1; n > -1; n--) { - const nl = negativeLists[n] - - const nlBefore = re.slice(0, nl.reStart) - const nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - let nlAfter = re.slice(nl.reEnd) - const nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - const openParensBefore = nlBefore.split('(').length - 1 - let cleanAfter = nlAfter - for (let i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - const dollar = nlAfter === '' && isSub !== SUBPARSE ? '$' : '' - re = nlBefore + nlFirst + nlAfter + dollar + nlLast - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - const flags = options.nocase ? 'i' : '' - try { - return Object.assign(new RegExp('^' + re + '$', flags), { - _glob: pattern, - _src: re, - }) - } catch (er) /* istanbul ignore next - should be impossible */ { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - } - - makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - const set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - const options = this.options - - const twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - const flags = options.nocase ? 'i' : '' - - // coalesce globstars and regexpify non-globstar patterns - // if it's the only item, then we just do one twoStar - // if it's the first, and there are more, prepend (\/|twoStar\/)? to next - // if it's the last, append (\/twoStar|) to previous - // if it's in the middle, append (\/|\/twoStar\/) to previous - // then filter out GLOBSTAR symbols - let re = set.map(pattern => { - pattern = pattern.map(p => - typeof p === 'string' ? regExpEscape(p) - : p === GLOBSTAR ? GLOBSTAR - : p._src - ).reduce((set, p) => { - if (!(set[set.length - 1] === GLOBSTAR && p === GLOBSTAR)) { - set.push(p) - } - return set - }, []) - pattern.forEach((p, i) => { - if (p !== GLOBSTAR || pattern[i-1] === GLOBSTAR) { - return - } - if (i === 0) { - if (pattern.length > 1) { - pattern[i+1] = '(?:\\\/|' + twoStar + '\\\/)?' + pattern[i+1] - } else { - pattern[i] = twoStar - } - } else if (i === pattern.length - 1) { - pattern[i-1] += '(?:\\\/|' + twoStar + ')?' - } else { - pattern[i-1] += '(?:\\\/|\\\/' + twoStar + '\\\/)' + pattern[i+1] - pattern[i+1] = GLOBSTAR - } - }) - return pattern.filter(p => p !== GLOBSTAR).join('/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) /* istanbul ignore next - should be impossible */ { - this.regexp = false - } - return this.regexp - } - - match (f, partial = this.partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - const options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - const set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - let filename - for (let i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (let i = 0; i < set.length; i++) { - const pattern = set[i] - let file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - const hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate - } - - static defaults (def) { - return minimatch.defaults(def).Minimatch - } -} - -minimatch.Minimatch = Minimatch diff --git a/node_modules/minimatch/package.json b/node_modules/minimatch/package.json index 8e1a84285d38f..74b945eb60d71 100644 --- a/node_modules/minimatch/package.json +++ b/node_modules/minimatch/package.json @@ -2,31 +2,66 @@ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", "name": "minimatch", "description": "a glob matcher in javascript", - "version": "5.1.0", + "version": "10.1.2", "repository": { "type": "git", - "url": "git://github.com/isaacs/minimatch.git" + "url": "git@github.com:isaacs/minimatch" }, - "main": "minimatch.js", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "files": [ + "dist" + ], "scripts": { - "test": "tap", - "snap": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --log-level warn", + "benchmark": "node benchmark/index.js", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" }, "engines": { - "node": ">=10" - }, - "dependencies": { - "brace-expansion": "^2.0.1" + "node": "20 || >=22" }, "devDependencies": { - "tap": "^15.1.6" + "@types/node": "^24.0.0", + "mkdirp": "^3.0.1", + "prettier": "^3.6.2", + "tap": "^21.1.0", + "tshy": "^3.0.2", + "typedoc": "^0.28.5" }, - "license": "ISC", - "files": [ - "minimatch.js", - "lib" - ] + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "license": "BlueOak-1.0.0", + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "type": "module", + "module": "./dist/esm/index.js", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.1" + } } diff --git a/node_modules/minipass-collect/LICENSE b/node_modules/minipass-collect/LICENSE index 19129e315fe59..8b8575ae6b7d3 100644 --- a/node_modules/minipass-collect/LICENSE +++ b/node_modules/minipass-collect/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) Isaac Z. Schlueter and Contributors +Copyright (c) 2019-2023 Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/node_modules/minipass-collect/index.js b/node_modules/minipass-collect/index.js index 2fe68c0b5a5a9..3497f55cbee19 100644 --- a/node_modules/minipass-collect/index.js +++ b/node_modules/minipass-collect/index.js @@ -1,4 +1,4 @@ -const Minipass = require('minipass') +const { Minipass } = require('minipass') const _data = Symbol('_data') const _length = Symbol('_length') class Collect extends Minipass { diff --git a/node_modules/minipass-collect/package.json b/node_modules/minipass-collect/package.json index 54d87ac2e63b2..f9daa81bafbc1 100644 --- a/node_modules/minipass-collect/package.json +++ b/node_modules/minipass-collect/package.json @@ -1,6 +1,6 @@ { "name": "minipass-collect", - "version": "1.0.2", + "version": "2.0.1", "description": "A Minipass stream that collects all the data into a single chunk", "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", "license": "ISC", @@ -9,21 +9,22 @@ "snap": "tap", "preversion": "npm test", "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags" }, "tap": { "check-coverage": true }, "devDependencies": { - "tap": "^14.6.9" + "tap": "^16.3.8" }, "dependencies": { - "minipass": "^3.0.0" + "minipass": "^7.0.3" }, "files": [ "index.js" ], "engines": { - "node": ">= 8" - } + "node": ">=16 || 14 >=14.17" + }, + "repository": "https://github.com/isaacs/minipass-collect" } diff --git a/node_modules/minipass-fetch/lib/blob.js b/node_modules/minipass-fetch/lib/blob.js index efe69a34458af..121b1730102e7 100644 --- a/node_modules/minipass-fetch/lib/blob.js +++ b/node_modules/minipass-fetch/lib/blob.js @@ -1,5 +1,5 @@ 'use strict' -const Minipass = require('minipass') +const { Minipass } = require('minipass') const TYPE = Symbol('type') const BUFFER = Symbol('buffer') diff --git a/node_modules/minipass-fetch/lib/body.js b/node_modules/minipass-fetch/lib/body.js index c7ffa5babcbc6..f7895d7f5c20d 100644 --- a/node_modules/minipass-fetch/lib/body.js +++ b/node_modules/minipass-fetch/lib/body.js @@ -1,6 +1,6 @@ 'use strict' -const Minipass = require('minipass') -const MinipassSized = require('minipass-sized') +const { Minipass } = require('minipass') +const { MinipassSized } = require('minipass-sized') const Blob = require('./blob.js') const { BUFFER } = Blob @@ -10,7 +10,9 @@ const FetchError = require('./fetch-error.js') let convert try { convert = require('encoding').convert -} catch (e) {} +} catch (e) { + // defer error until textConverted is called +} const INTERNALS = Symbol('Body internals') const CONSUME_BODY = Symbol('consumeBody') @@ -69,16 +71,16 @@ class Body { )) } - json () { - return this[CONSUME_BODY]().then(buf => { - try { - return JSON.parse(buf.toString()) - } catch (er) { - return Promise.reject(new FetchError( - `invalid json response body at ${ - this.url} reason: ${er.message}`, 'invalid-json')) - } - }) + async json () { + const buf = await this[CONSUME_BODY]() + try { + return JSON.parse(buf.toString()) + } catch (er) { + throw new FetchError( + `invalid json response body at ${this.url} reason: ${er.message}`, + 'invalid-json' + ) + } } text () { @@ -144,7 +146,7 @@ class Body { // do the pipe in the promise, because the pipe() can send too much // data through right away and upset the MP Sized object - return new Promise((resolve, reject) => { + return new Promise((resolve) => { // if the stream is some other kind of stream, then pipe through a MP // so we can collect it more easily. if (stream !== upstream) { diff --git a/node_modules/minipass-fetch/lib/index.js b/node_modules/minipass-fetch/lib/index.js index b1878ac0c06b5..f0f4bb66dbb67 100644 --- a/node_modules/minipass-fetch/lib/index.js +++ b/node_modules/minipass-fetch/lib/index.js @@ -3,7 +3,7 @@ const { URL } = require('url') const http = require('http') const https = require('https') const zlib = require('minizlib') -const Minipass = require('minipass') +const { Minipass } = require('minipass') const Body = require('./body.js') const { writeToStream, getTotalBytes } = Body @@ -103,7 +103,7 @@ const fetch = async (url, opts) => { let reqTimeout = null if (request.timeout) { - req.once('socket', socket => { + req.once('socket', () => { reqTimeout = setTimeout(() => { reject(new FetchError(`network timeout at: ${ request.url}`, 'request-timeout')) @@ -143,8 +143,20 @@ const fetch = async (url, opts) => { const location = headers.get('Location') // HTTP fetch step 5.3 - const locationURL = location === null ? null - : (new URL(location, request.url)).toString() + let locationURL = null + try { + locationURL = location === null ? null : new URL(location, request.url).toString() + } catch { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + /* eslint-disable-next-line max-len */ + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')) + finalize() + return + } + } // HTTP fetch step 5.5 if (request.redirect === 'error') { @@ -306,8 +318,7 @@ const fetch = async (url, opts) => { if (codings === 'deflate' || codings === 'x-deflate') { // handle the infamous raw deflate response from old servers // a hack for old IIS and Apache servers - const raw = res.pipe(new Minipass()) - raw.once('data', chunk => { + res.once('data', chunk => { // see http://stackoverflow.com/questions/37519828 const decoder = (chunk[0] & 0x0F) === 0x08 ? new zlib.Inflate() diff --git a/node_modules/minipass-fetch/lib/request.js b/node_modules/minipass-fetch/lib/request.js index e620df6de2c01..054439e669910 100644 --- a/node_modules/minipass-fetch/lib/request.js +++ b/node_modules/minipass-fetch/lib/request.js @@ -1,6 +1,6 @@ 'use strict' const { URL } = require('url') -const Minipass = require('minipass') +const { Minipass } = require('minipass') const Headers = require('./headers.js') const { exportNodeCompatibleHeaders } = Headers const Body = require('./body.js') @@ -265,6 +265,7 @@ class Request extends Body { secureProtocol, servername, sessionIdContext, + timeout: request.timeout, } } } diff --git a/node_modules/minipass-fetch/package.json b/node_modules/minipass-fetch/package.json index 1f663b9245dea..c2aaebcc90bfa 100644 --- a/node_modules/minipass-fetch/package.json +++ b/node_modules/minipass-fetch/package.json @@ -1,32 +1,35 @@ { "name": "minipass-fetch", - "version": "2.1.0", + "version": "5.0.1", "description": "An implementation of window.fetch in Node.js using Minipass streams", "license": "MIT", "main": "lib/index.js", "scripts": { + "test:tls-fixtures": "./test/fixtures/tls/setup.sh", "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { "coverage-map": "map.js", - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.1.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "@ungap/url-search-params": "^0.2.2", "abort-controller": "^3.0.0", "abortcontroller-polyfill": "~1.7.3", + "encoding": "^0.1.13", "form-data": "^4.0.0", "nock": "^13.2.4", "parted": "^0.1.1", @@ -34,16 +37,16 @@ "tap": "^16.0.0" }, "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" }, "repository": { "type": "git", - "url": "https://github.com/npm/minipass-fetch.git" + "url": "git+https://github.com/npm/minipass-fetch.git" }, "keywords": [ "fetch", @@ -56,11 +59,12 @@ "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.1.2" + "version": "4.27.1", + "publish": "true" } } diff --git a/node_modules/minipass-flush/node_modules/minipass/LICENSE b/node_modules/minipass-flush/node_modules/minipass/LICENSE new file mode 100644 index 0000000000000..bf1dece2e1f12 --- /dev/null +++ b/node_modules/minipass-flush/node_modules/minipass/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2017-2022 npm, Inc., Isaac Z. Schlueter, and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/minipass/index.js b/node_modules/minipass-flush/node_modules/minipass/index.js similarity index 100% rename from node_modules/minipass/index.js rename to node_modules/minipass-flush/node_modules/minipass/index.js diff --git a/node_modules/minipass-flush/node_modules/minipass/package.json b/node_modules/minipass-flush/node_modules/minipass/package.json new file mode 100644 index 0000000000000..548d03fa6d5d4 --- /dev/null +++ b/node_modules/minipass-flush/node_modules/minipass/package.json @@ -0,0 +1,56 @@ +{ + "name": "minipass", + "version": "3.3.6", + "description": "minimal implementation of a PassThrough stream", + "main": "index.js", + "types": "index.d.ts", + "dependencies": { + "yallist": "^4.0.0" + }, + "devDependencies": { + "@types/node": "^17.0.41", + "end-of-stream": "^1.4.0", + "prettier": "^2.6.2", + "tap": "^16.2.0", + "through2": "^2.0.3", + "ts-node": "^10.8.1", + "typescript": "^4.7.3" + }, + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --follow-tags" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/minipass.git" + }, + "keywords": [ + "passthrough", + "stream" + ], + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "license": "ISC", + "files": [ + "index.d.ts", + "index.js" + ], + "tap": { + "check-coverage": true + }, + "engines": { + "node": ">=8" + }, + "prettier": { + "semi": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + } +} diff --git a/node_modules/minipass-json-stream/LICENSE b/node_modules/minipass-json-stream/LICENSE deleted file mode 100644 index 2781a897b60fe..0000000000000 --- a/node_modules/minipass-json-stream/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -The MIT License - -Copyright (c) Isaac Z. Schlueter and Contributors -Copyright (c) 2011 Dominic Tarr - -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. - ----- -This is a derivative work based on JSONStream by Dominic Tarr, modified and -redistributed according to the terms of the MIT license above. -https://github.com/dominictarr/JSONStream diff --git a/node_modules/minipass-json-stream/index.js b/node_modules/minipass-json-stream/index.js deleted file mode 100644 index 5168d1322ac20..0000000000000 --- a/node_modules/minipass-json-stream/index.js +++ /dev/null @@ -1,227 +0,0 @@ -// put javascript in here -'use strict' - -const Parser = require('jsonparse') -const Minipass = require('minipass') - -class JSONStreamError extends Error { - constructor (err, caller) { - super(err.message) - Error.captureStackTrace(this, caller || this.constructor) - } - get name () { - return 'JSONStreamError' - } - set name (n) {} -} - -const check = (x, y) => - typeof x === 'string' ? String(y) === x - : x && typeof x.test === 'function' ? x.test(y) - : typeof x === 'boolean' || typeof x === 'object' ? x - : typeof x === 'function' ? x(y) - : false - -const _parser = Symbol('_parser') -const _onValue = Symbol('_onValue') -const _onTokenOriginal = Symbol('_onTokenOriginal') -const _onToken = Symbol('_onToken') -const _onError = Symbol('_onError') -const _count = Symbol('_count') -const _path = Symbol('_path') -const _map = Symbol('_map') -const _root = Symbol('_root') -const _header = Symbol('_header') -const _footer = Symbol('_footer') -const _setHeaderFooter = Symbol('_setHeaderFooter') -const _ending = Symbol('_ending') - -class JSONStream extends Minipass { - constructor (opts = {}) { - super({ - ...opts, - objectMode: true, - }) - - this[_ending] = false - const parser = this[_parser] = new Parser() - parser.onValue = value => this[_onValue](value) - this[_onTokenOriginal] = parser.onToken - parser.onToken = (token, value) => this[_onToken](token, value) - parser.onError = er => this[_onError](er) - - this[_count] = 0 - this[_path] = typeof opts.path === 'string' - ? opts.path.split('.').map(e => - e === '$*' ? { emitKey: true } - : e === '*' ? true - : e === '' ? { recurse: true } - : e) - : Array.isArray(opts.path) && opts.path.length ? opts.path - : null - - this[_map] = typeof opts.map === 'function' ? opts.map : null - this[_root] = null - this[_header] = null - this[_footer] = null - this[_count] = 0 - } - - [_setHeaderFooter] (key, value) { - // header has not been emitted yet - if (this[_header] !== false) { - this[_header] = this[_header] || {} - this[_header][key] = value - } - - // footer has not been emitted yet but header has - if (this[_footer] !== false && this[_header] === false) { - this[_footer] = this[_footer] || {} - this[_footer][key] = value - } - } - - [_onError] (er) { - // error will always happen during a write() call. - const caller = this[_ending] ? this.end : this.write - this[_ending] = false - return this.emit('error', new JSONStreamError(er, caller)) - } - - [_onToken] (token, value) { - const parser = this[_parser] - this[_onTokenOriginal].call(parser, token, value) - if (parser.stack.length === 0) { - if (this[_root]) { - const root = this[_root] - if (!this[_path]) - super.write(root) - this[_root] = null - this[_count] = 0 - } - } - } - - [_onValue] (value) { - const parser = this[_parser] - // the LAST onValue encountered is the root object. - // just overwrite it each time. - this[_root] = value - - if(!this[_path]) return - - let i = 0 // iterates on path - let j = 0 // iterates on stack - let emitKey = false - let emitPath = false - while (i < this[_path].length) { - const key = this[_path][i] - j++ - - if (key && !key.recurse) { - const c = (j === parser.stack.length) ? parser : parser.stack[j] - if (!c) return - if (!check(key, c.key)) { - this[_setHeaderFooter](c.key, value) - return - } - emitKey = !!key.emitKey; - emitPath = !!key.emitPath; - i++ - } else { - i++ - if (i >= this[_path].length) - return - const nextKey = this[_path][i] - if (!nextKey) - return - while (true) { - const c = (j === parser.stack.length) ? parser : parser.stack[j] - if (!c) return - if (check(nextKey, c.key)) { - i++ - if (!Object.isFrozen(parser.stack[j])) - parser.stack[j].value = null - break - } else { - this[_setHeaderFooter](c.key, value) - } - j++ - } - } - } - - // emit header - if (this[_header]) { - const header = this[_header] - this[_header] = false - this.emit('header', header) - } - if (j !== parser.stack.length) return - - this[_count] ++ - const actualPath = parser.stack.slice(1) - .map(e => e.key).concat([parser.key]) - if (value !== null && value !== undefined) { - const data = this[_map] ? this[_map](value, actualPath) : value - if (data !== null && data !== undefined) { - const emit = emitKey || emitPath ? { value: data } : data - if (emitKey) - emit.key = parser.key - if (emitPath) - emit.path = actualPath - super.write(emit) - } - } - - if (parser.value) - delete parser.value[parser.key] - - for (const k of parser.stack) { - k.value = null - } - } - - write (chunk, encoding, cb) { - if (typeof encoding === 'function') - cb = encoding, encoding = null - if (typeof chunk === 'string') - chunk = Buffer.from(chunk, encoding) - else if (!Buffer.isBuffer(chunk)) - return this.emit('error', new TypeError( - 'Can only parse JSON from string or buffer input')) - this[_parser].write(chunk) - if (cb) - cb() - return this.flowing - } - - end (chunk, encoding, cb) { - this[_ending] = true - if (typeof encoding === 'function') - cb = encoding, encoding = null - if (typeof chunk === 'function') - cb = chunk, chunk = null - if (chunk) - this.write(chunk, encoding) - if (cb) - this.once('end', cb) - - const h = this[_header] - this[_header] = null - const f = this[_footer] - this[_footer] = null - if (h) - this.emit('header', h) - if (f) - this.emit('footer', f) - return super.end() - } - - static get JSONStreamError () { return JSONStreamError } - static parse (path, map) { - return new JSONStream({path, map}) - } -} - -module.exports = JSONStream diff --git a/node_modules/minipass-json-stream/package.json b/node_modules/minipass-json-stream/package.json deleted file mode 100644 index 19d1f358fce62..0000000000000 --- a/node_modules/minipass-json-stream/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "minipass-json-stream", - "version": "1.0.1", - "description": "Like JSONStream, but using Minipass streams", - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", - "license": "MIT", - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "JSONStream": "^1.3.5", - "tap": "^14.6.9" - }, - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/npm/minipass-json-stream.git" - }, - "keywords": [ - "stream", - "json", - "parse", - "minipass", - "JSONStream" - ], - "files": [ - "index.js" - ] -} diff --git a/node_modules/minipass-pipeline/node_modules/minipass/LICENSE b/node_modules/minipass-pipeline/node_modules/minipass/LICENSE new file mode 100644 index 0000000000000..bf1dece2e1f12 --- /dev/null +++ b/node_modules/minipass-pipeline/node_modules/minipass/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2017-2022 npm, Inc., Isaac Z. Schlueter, and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/minipass-pipeline/node_modules/minipass/index.js b/node_modules/minipass-pipeline/node_modules/minipass/index.js new file mode 100644 index 0000000000000..e8797aab6cc27 --- /dev/null +++ b/node_modules/minipass-pipeline/node_modules/minipass/index.js @@ -0,0 +1,649 @@ +'use strict' +const proc = typeof process === 'object' && process ? process : { + stdout: null, + stderr: null, +} +const EE = require('events') +const Stream = require('stream') +const SD = require('string_decoder').StringDecoder + +const EOF = Symbol('EOF') +const MAYBE_EMIT_END = Symbol('maybeEmitEnd') +const EMITTED_END = Symbol('emittedEnd') +const EMITTING_END = Symbol('emittingEnd') +const EMITTED_ERROR = Symbol('emittedError') +const CLOSED = Symbol('closed') +const READ = Symbol('read') +const FLUSH = Symbol('flush') +const FLUSHCHUNK = Symbol('flushChunk') +const ENCODING = Symbol('encoding') +const DECODER = Symbol('decoder') +const FLOWING = Symbol('flowing') +const PAUSED = Symbol('paused') +const RESUME = Symbol('resume') +const BUFFERLENGTH = Symbol('bufferLength') +const BUFFERPUSH = Symbol('bufferPush') +const BUFFERSHIFT = Symbol('bufferShift') +const OBJECTMODE = Symbol('objectMode') +const DESTROYED = Symbol('destroyed') +const EMITDATA = Symbol('emitData') +const EMITEND = Symbol('emitEnd') +const EMITEND2 = Symbol('emitEnd2') +const ASYNC = Symbol('async') + +const defer = fn => Promise.resolve().then(fn) + +// TODO remove when Node v8 support drops +const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1' +const ASYNCITERATOR = doIter && Symbol.asyncIterator + || Symbol('asyncIterator not implemented') +const ITERATOR = doIter && Symbol.iterator + || Symbol('iterator not implemented') + +// events that mean 'the stream is over' +// these are treated specially, and re-emitted +// if they are listened for after emitting. +const isEndish = ev => + ev === 'end' || + ev === 'finish' || + ev === 'prefinish' + +const isArrayBuffer = b => b instanceof ArrayBuffer || + typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0 + +const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b) + +class Pipe { + constructor (src, dest, opts) { + this.src = src + this.dest = dest + this.opts = opts + this.ondrain = () => src[RESUME]() + dest.on('drain', this.ondrain) + } + unpipe () { + this.dest.removeListener('drain', this.ondrain) + } + // istanbul ignore next - only here for the prototype + proxyErrors () {} + end () { + this.unpipe() + if (this.opts.end) + this.dest.end() + } +} + +class PipeProxyErrors extends Pipe { + unpipe () { + this.src.removeListener('error', this.proxyErrors) + super.unpipe() + } + constructor (src, dest, opts) { + super(src, dest, opts) + this.proxyErrors = er => dest.emit('error', er) + src.on('error', this.proxyErrors) + } +} + +module.exports = class Minipass extends Stream { + constructor (options) { + super() + this[FLOWING] = false + // whether we're explicitly paused + this[PAUSED] = false + this.pipes = [] + this.buffer = [] + this[OBJECTMODE] = options && options.objectMode || false + if (this[OBJECTMODE]) + this[ENCODING] = null + else + this[ENCODING] = options && options.encoding || null + if (this[ENCODING] === 'buffer') + this[ENCODING] = null + this[ASYNC] = options && !!options.async || false + this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null + this[EOF] = false + this[EMITTED_END] = false + this[EMITTING_END] = false + this[CLOSED] = false + this[EMITTED_ERROR] = null + this.writable = true + this.readable = true + this[BUFFERLENGTH] = 0 + this[DESTROYED] = false + } + + get bufferLength () { return this[BUFFERLENGTH] } + + get encoding () { return this[ENCODING] } + set encoding (enc) { + if (this[OBJECTMODE]) + throw new Error('cannot set encoding in objectMode') + + if (this[ENCODING] && enc !== this[ENCODING] && + (this[DECODER] && this[DECODER].lastNeed || this[BUFFERLENGTH])) + throw new Error('cannot change encoding') + + if (this[ENCODING] !== enc) { + this[DECODER] = enc ? new SD(enc) : null + if (this.buffer.length) + this.buffer = this.buffer.map(chunk => this[DECODER].write(chunk)) + } + + this[ENCODING] = enc + } + + setEncoding (enc) { + this.encoding = enc + } + + get objectMode () { return this[OBJECTMODE] } + set objectMode (om) { this[OBJECTMODE] = this[OBJECTMODE] || !!om } + + get ['async'] () { return this[ASYNC] } + set ['async'] (a) { this[ASYNC] = this[ASYNC] || !!a } + + write (chunk, encoding, cb) { + if (this[EOF]) + throw new Error('write after end') + + if (this[DESTROYED]) { + this.emit('error', Object.assign( + new Error('Cannot call write after a stream was destroyed'), + { code: 'ERR_STREAM_DESTROYED' } + )) + return true + } + + if (typeof encoding === 'function') + cb = encoding, encoding = 'utf8' + + if (!encoding) + encoding = 'utf8' + + const fn = this[ASYNC] ? defer : f => f() + + // convert array buffers and typed array views into buffers + // at some point in the future, we may want to do the opposite! + // leave strings and buffers as-is + // anything else switches us into object mode + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) + else if (isArrayBuffer(chunk)) + chunk = Buffer.from(chunk) + else if (typeof chunk !== 'string') + // use the setter so we throw if we have encoding set + this.objectMode = true + } + + // handle object mode up front, since it's simpler + // this yields better performance, fewer checks later. + if (this[OBJECTMODE]) { + /* istanbul ignore if - maybe impossible? */ + if (this.flowing && this[BUFFERLENGTH] !== 0) + this[FLUSH](true) + + if (this.flowing) + this.emit('data', chunk) + else + this[BUFFERPUSH](chunk) + + if (this[BUFFERLENGTH] !== 0) + this.emit('readable') + + if (cb) + fn(cb) + + return this.flowing + } + + // at this point the chunk is a buffer or string + // don't buffer it up or send it to the decoder + if (!chunk.length) { + if (this[BUFFERLENGTH] !== 0) + this.emit('readable') + if (cb) + fn(cb) + return this.flowing + } + + // fast-path writing strings of same encoding to a stream with + // an empty buffer, skipping the buffer/decoder dance + if (typeof chunk === 'string' && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER].lastNeed)) { + chunk = Buffer.from(chunk, encoding) + } + + if (Buffer.isBuffer(chunk) && this[ENCODING]) + chunk = this[DECODER].write(chunk) + + // Note: flushing CAN potentially switch us into not-flowing mode + if (this.flowing && this[BUFFERLENGTH] !== 0) + this[FLUSH](true) + + if (this.flowing) + this.emit('data', chunk) + else + this[BUFFERPUSH](chunk) + + if (this[BUFFERLENGTH] !== 0) + this.emit('readable') + + if (cb) + fn(cb) + + return this.flowing + } + + read (n) { + if (this[DESTROYED]) + return null + + if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) { + this[MAYBE_EMIT_END]() + return null + } + + if (this[OBJECTMODE]) + n = null + + if (this.buffer.length > 1 && !this[OBJECTMODE]) { + if (this.encoding) + this.buffer = [this.buffer.join('')] + else + this.buffer = [Buffer.concat(this.buffer, this[BUFFERLENGTH])] + } + + const ret = this[READ](n || null, this.buffer[0]) + this[MAYBE_EMIT_END]() + return ret + } + + [READ] (n, chunk) { + if (n === chunk.length || n === null) + this[BUFFERSHIFT]() + else { + this.buffer[0] = chunk.slice(n) + chunk = chunk.slice(0, n) + this[BUFFERLENGTH] -= n + } + + this.emit('data', chunk) + + if (!this.buffer.length && !this[EOF]) + this.emit('drain') + + return chunk + } + + end (chunk, encoding, cb) { + if (typeof chunk === 'function') + cb = chunk, chunk = null + if (typeof encoding === 'function') + cb = encoding, encoding = 'utf8' + if (chunk) + this.write(chunk, encoding) + if (cb) + this.once('end', cb) + this[EOF] = true + this.writable = false + + // if we haven't written anything, then go ahead and emit, + // even if we're not reading. + // we'll re-emit if a new 'end' listener is added anyway. + // This makes MP more suitable to write-only use cases. + if (this.flowing || !this[PAUSED]) + this[MAYBE_EMIT_END]() + return this + } + + // don't let the internal resume be overwritten + [RESUME] () { + if (this[DESTROYED]) + return + + this[PAUSED] = false + this[FLOWING] = true + this.emit('resume') + if (this.buffer.length) + this[FLUSH]() + else if (this[EOF]) + this[MAYBE_EMIT_END]() + else + this.emit('drain') + } + + resume () { + return this[RESUME]() + } + + pause () { + this[FLOWING] = false + this[PAUSED] = true + } + + get destroyed () { + return this[DESTROYED] + } + + get flowing () { + return this[FLOWING] + } + + get paused () { + return this[PAUSED] + } + + [BUFFERPUSH] (chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1 + else + this[BUFFERLENGTH] += chunk.length + this.buffer.push(chunk) + } + + [BUFFERSHIFT] () { + if (this.buffer.length) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1 + else + this[BUFFERLENGTH] -= this.buffer[0].length + } + return this.buffer.shift() + } + + [FLUSH] (noDrain) { + do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]())) + + if (!noDrain && !this.buffer.length && !this[EOF]) + this.emit('drain') + } + + [FLUSHCHUNK] (chunk) { + return chunk ? (this.emit('data', chunk), this.flowing) : false + } + + pipe (dest, opts) { + if (this[DESTROYED]) + return + + const ended = this[EMITTED_END] + opts = opts || {} + if (dest === proc.stdout || dest === proc.stderr) + opts.end = false + else + opts.end = opts.end !== false + opts.proxyErrors = !!opts.proxyErrors + + // piping an ended stream ends immediately + if (ended) { + if (opts.end) + dest.end() + } else { + this.pipes.push(!opts.proxyErrors ? new Pipe(this, dest, opts) + : new PipeProxyErrors(this, dest, opts)) + if (this[ASYNC]) + defer(() => this[RESUME]()) + else + this[RESUME]() + } + + return dest + } + + unpipe (dest) { + const p = this.pipes.find(p => p.dest === dest) + if (p) { + this.pipes.splice(this.pipes.indexOf(p), 1) + p.unpipe() + } + } + + addListener (ev, fn) { + return this.on(ev, fn) + } + + on (ev, fn) { + const ret = super.on(ev, fn) + if (ev === 'data' && !this.pipes.length && !this.flowing) + this[RESUME]() + else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) + super.emit('readable') + else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev) + this.removeAllListeners(ev) + } else if (ev === 'error' && this[EMITTED_ERROR]) { + if (this[ASYNC]) + defer(() => fn.call(this, this[EMITTED_ERROR])) + else + fn.call(this, this[EMITTED_ERROR]) + } + return ret + } + + get emittedEnd () { + return this[EMITTED_END] + } + + [MAYBE_EMIT_END] () { + if (!this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this.buffer.length === 0 && + this[EOF]) { + this[EMITTING_END] = true + this.emit('end') + this.emit('prefinish') + this.emit('finish') + if (this[CLOSED]) + this.emit('close') + this[EMITTING_END] = false + } + } + + emit (ev, data, ...extra) { + // error and close are only events allowed after calling destroy() + if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED]) + return + else if (ev === 'data') { + return !data ? false + : this[ASYNC] ? defer(() => this[EMITDATA](data)) + : this[EMITDATA](data) + } else if (ev === 'end') { + return this[EMITEND]() + } else if (ev === 'close') { + this[CLOSED] = true + // don't emit close before 'end' and 'finish' + if (!this[EMITTED_END] && !this[DESTROYED]) + return + const ret = super.emit('close') + this.removeAllListeners('close') + return ret + } else if (ev === 'error') { + this[EMITTED_ERROR] = data + const ret = super.emit('error', data) + this[MAYBE_EMIT_END]() + return ret + } else if (ev === 'resume') { + const ret = super.emit('resume') + this[MAYBE_EMIT_END]() + return ret + } else if (ev === 'finish' || ev === 'prefinish') { + const ret = super.emit(ev) + this.removeAllListeners(ev) + return ret + } + + // Some other unknown event + const ret = super.emit(ev, data, ...extra) + this[MAYBE_EMIT_END]() + return ret + } + + [EMITDATA] (data) { + for (const p of this.pipes) { + if (p.dest.write(data) === false) + this.pause() + } + const ret = super.emit('data', data) + this[MAYBE_EMIT_END]() + return ret + } + + [EMITEND] () { + if (this[EMITTED_END]) + return + + this[EMITTED_END] = true + this.readable = false + if (this[ASYNC]) + defer(() => this[EMITEND2]()) + else + this[EMITEND2]() + } + + [EMITEND2] () { + if (this[DECODER]) { + const data = this[DECODER].end() + if (data) { + for (const p of this.pipes) { + p.dest.write(data) + } + super.emit('data', data) + } + } + + for (const p of this.pipes) { + p.end() + } + const ret = super.emit('end') + this.removeAllListeners('end') + return ret + } + + // const all = await stream.collect() + collect () { + const buf = [] + if (!this[OBJECTMODE]) + buf.dataLength = 0 + // set the promise first, in case an error is raised + // by triggering the flow here. + const p = this.promise() + this.on('data', c => { + buf.push(c) + if (!this[OBJECTMODE]) + buf.dataLength += c.length + }) + return p.then(() => buf) + } + + // const data = await stream.concat() + concat () { + return this[OBJECTMODE] + ? Promise.reject(new Error('cannot concat in objectMode')) + : this.collect().then(buf => + this[OBJECTMODE] + ? Promise.reject(new Error('cannot concat in objectMode')) + : this[ENCODING] ? buf.join('') : Buffer.concat(buf, buf.dataLength)) + } + + // stream.promise().then(() => done, er => emitted error) + promise () { + return new Promise((resolve, reject) => { + this.on(DESTROYED, () => reject(new Error('stream destroyed'))) + this.on('error', er => reject(er)) + this.on('end', () => resolve()) + }) + } + + // for await (let chunk of stream) + [ASYNCITERATOR] () { + const next = () => { + const res = this.read() + if (res !== null) + return Promise.resolve({ done: false, value: res }) + + if (this[EOF]) + return Promise.resolve({ done: true }) + + let resolve = null + let reject = null + const onerr = er => { + this.removeListener('data', ondata) + this.removeListener('end', onend) + reject(er) + } + const ondata = value => { + this.removeListener('error', onerr) + this.removeListener('end', onend) + this.pause() + resolve({ value: value, done: !!this[EOF] }) + } + const onend = () => { + this.removeListener('error', onerr) + this.removeListener('data', ondata) + resolve({ done: true }) + } + const ondestroy = () => onerr(new Error('stream destroyed')) + return new Promise((res, rej) => { + reject = rej + resolve = res + this.once(DESTROYED, ondestroy) + this.once('error', onerr) + this.once('end', onend) + this.once('data', ondata) + }) + } + + return { next } + } + + // for (let chunk of stream) + [ITERATOR] () { + const next = () => { + const value = this.read() + const done = value === null + return { value, done } + } + return { next } + } + + destroy (er) { + if (this[DESTROYED]) { + if (er) + this.emit('error', er) + else + this.emit(DESTROYED) + return this + } + + this[DESTROYED] = true + + // throw away all buffered data, it's never coming out + this.buffer.length = 0 + this[BUFFERLENGTH] = 0 + + if (typeof this.close === 'function' && !this[CLOSED]) + this.close() + + if (er) + this.emit('error', er) + else // if no error to emit, still reject pending promises + this.emit(DESTROYED) + + return this + } + + static isStream (s) { + return !!s && (s instanceof Minipass || s instanceof Stream || + s instanceof EE && ( + typeof s.pipe === 'function' || // readable + (typeof s.write === 'function' && typeof s.end === 'function') // writable + )) + } +} diff --git a/node_modules/minipass-pipeline/node_modules/minipass/package.json b/node_modules/minipass-pipeline/node_modules/minipass/package.json new file mode 100644 index 0000000000000..548d03fa6d5d4 --- /dev/null +++ b/node_modules/minipass-pipeline/node_modules/minipass/package.json @@ -0,0 +1,56 @@ +{ + "name": "minipass", + "version": "3.3.6", + "description": "minimal implementation of a PassThrough stream", + "main": "index.js", + "types": "index.d.ts", + "dependencies": { + "yallist": "^4.0.0" + }, + "devDependencies": { + "@types/node": "^17.0.41", + "end-of-stream": "^1.4.0", + "prettier": "^2.6.2", + "tap": "^16.2.0", + "through2": "^2.0.3", + "ts-node": "^10.8.1", + "typescript": "^4.7.3" + }, + "scripts": { + "test": "tap", + "preversion": "npm test", + "postversion": "npm publish", + "postpublish": "git push origin --follow-tags" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/minipass.git" + }, + "keywords": [ + "passthrough", + "stream" + ], + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "license": "ISC", + "files": [ + "index.d.ts", + "index.js" + ], + "tap": { + "check-coverage": true + }, + "engines": { + "node": ">=8" + }, + "prettier": { + "semi": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + } +} diff --git a/node_modules/minipass-sized/dist/commonjs/index.js b/node_modules/minipass-sized/dist/commonjs/index.js new file mode 100644 index 0000000000000..fbf76406d60d9 --- /dev/null +++ b/node_modules/minipass-sized/dist/commonjs/index.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.MinipassSized = exports.SizeError = void 0; +const minipass_1 = require("minipass"); +const isBufferEncoding = (enc) => typeof enc === 'string'; +class SizeError extends Error { + expect; + found; + code = 'EBADSIZE'; + constructor(found, expect, from) { + super(`Bad data size: expected ${expect} bytes, but got ${found}`); + this.expect = expect; + this.found = found; + Error.captureStackTrace(this, from ?? this.constructor); + } + get name() { + return 'SizeError'; + } +} +exports.SizeError = SizeError; +class MinipassSized extends minipass_1.Minipass { + found = 0; + expect; + constructor(options) { + const size = options?.size; + if (typeof size !== 'number' || + size > Number.MAX_SAFE_INTEGER || + isNaN(size) || + size < 0 || + !isFinite(size) || + size !== Math.floor(size)) { + throw new Error('invalid expected size: ' + size); + } + //@ts-ignore + super(options); + if (options.objectMode) { + throw new TypeError(`${this.constructor.name} streams only work with string and buffer data`); + } + this.expect = size; + } + write(chunk, encoding, cb) { + const buffer = Buffer.isBuffer(chunk) ? chunk + : typeof chunk === 'string' ? + Buffer.from(chunk, isBufferEncoding(encoding) ? encoding : 'utf8') + : chunk; + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + if (!Buffer.isBuffer(buffer)) { + this.emit('error', new TypeError(`${this.constructor.name} streams only work with string and buffer data`)); + return false; + } + this.found += buffer.length; + if (this.found > this.expect) + this.emit('error', new SizeError(this.found, this.expect)); + return super.write(chunk, encoding, cb); + } + emit(ev, ...args) { + if (ev === 'end') { + if (this.found !== this.expect) { + this.emit('error', new SizeError(this.found, this.expect, this.emit)); + } + } + return super.emit(ev, ...args); + } +} +exports.MinipassSized = MinipassSized; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minipass-sized/dist/commonjs/package.json b/node_modules/minipass-sized/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/minipass-sized/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/minipass-sized/dist/esm/index.js b/node_modules/minipass-sized/dist/esm/index.js new file mode 100644 index 0000000000000..69ed1846aa969 --- /dev/null +++ b/node_modules/minipass-sized/dist/esm/index.js @@ -0,0 +1,64 @@ +import { Minipass } from 'minipass'; +const isBufferEncoding = (enc) => typeof enc === 'string'; +export class SizeError extends Error { + expect; + found; + code = 'EBADSIZE'; + constructor(found, expect, from) { + super(`Bad data size: expected ${expect} bytes, but got ${found}`); + this.expect = expect; + this.found = found; + Error.captureStackTrace(this, from ?? this.constructor); + } + get name() { + return 'SizeError'; + } +} +export class MinipassSized extends Minipass { + found = 0; + expect; + constructor(options) { + const size = options?.size; + if (typeof size !== 'number' || + size > Number.MAX_SAFE_INTEGER || + isNaN(size) || + size < 0 || + !isFinite(size) || + size !== Math.floor(size)) { + throw new Error('invalid expected size: ' + size); + } + //@ts-ignore + super(options); + if (options.objectMode) { + throw new TypeError(`${this.constructor.name} streams only work with string and buffer data`); + } + this.expect = size; + } + write(chunk, encoding, cb) { + const buffer = Buffer.isBuffer(chunk) ? chunk + : typeof chunk === 'string' ? + Buffer.from(chunk, isBufferEncoding(encoding) ? encoding : 'utf8') + : chunk; + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + if (!Buffer.isBuffer(buffer)) { + this.emit('error', new TypeError(`${this.constructor.name} streams only work with string and buffer data`)); + return false; + } + this.found += buffer.length; + if (this.found > this.expect) + this.emit('error', new SizeError(this.found, this.expect)); + return super.write(chunk, encoding, cb); + } + emit(ev, ...args) { + if (ev === 'end') { + if (this.found !== this.expect) { + this.emit('error', new SizeError(this.found, this.expect, this.emit)); + } + } + return super.emit(ev, ...args); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minipass-sized/dist/esm/package.json b/node_modules/minipass-sized/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/minipass-sized/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/minipass-sized/index.js b/node_modules/minipass-sized/index.js deleted file mode 100644 index a0c8acde487fc..0000000000000 --- a/node_modules/minipass-sized/index.js +++ /dev/null @@ -1,67 +0,0 @@ -const Minipass = require('minipass') - -class SizeError extends Error { - constructor (found, expect) { - super(`Bad data size: expected ${expect} bytes, but got ${found}`) - this.expect = expect - this.found = found - this.code = 'EBADSIZE' - Error.captureStackTrace(this, this.constructor) - } - get name () { - return 'SizeError' - } -} - -class MinipassSized extends Minipass { - constructor (options = {}) { - super(options) - - if (options.objectMode) - throw new TypeError(`${ - this.constructor.name - } streams only work with string and buffer data`) - - this.found = 0 - this.expect = options.size - if (typeof this.expect !== 'number' || - this.expect > Number.MAX_SAFE_INTEGER || - isNaN(this.expect) || - this.expect < 0 || - !isFinite(this.expect) || - this.expect !== Math.floor(this.expect)) - throw new Error('invalid expected size: ' + this.expect) - } - - write (chunk, encoding, cb) { - const buffer = Buffer.isBuffer(chunk) ? chunk - : typeof chunk === 'string' ? - Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8') - : chunk - - if (!Buffer.isBuffer(buffer)) { - this.emit('error', new TypeError(`${ - this.constructor.name - } streams only work with string and buffer data`)) - return false - } - - this.found += buffer.length - if (this.found > this.expect) - this.emit('error', new SizeError(this.found, this.expect)) - - return super.write(chunk, encoding, cb) - } - - emit (ev, ...data) { - if (ev === 'end') { - if (this.found !== this.expect) - this.emit('error', new SizeError(this.found, this.expect)) - } - return super.emit(ev, ...data) - } -} - -MinipassSized.SizeError = SizeError - -module.exports = MinipassSized diff --git a/node_modules/minipass-sized/package-lock.json b/node_modules/minipass-sized/package-lock.json deleted file mode 100644 index 944b285252b1c..0000000000000 --- a/node_modules/minipass-sized/package-lock.json +++ /dev/null @@ -1,3464 +0,0 @@ -{ - "name": "minipass-sized", - "version": "1.0.3", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", - "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", - "dev": true, - "requires": { - "@babel/types": "^7.6.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", - "dev": true, - "requires": { - "@babel/types": "^7.4.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==", - "dev": true - }, - "@babel/runtime": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", - "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" - } - }, - "@babel/traverse": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", - "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz", - "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.0.tgz", - "integrity": "sha512-Ozz7l4ixzI7Oxj2+cw+p0tVUt27BpaJ+1+q1TCeANWxHpvyn2+Un+YamBdfKu0uh8xLodGhoa1v7595NhKDAuA==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", - "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "async-hook-domain": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-1.1.0.tgz", - "integrity": "sha512-NH7V97d1yCbIanu2oDLyPT2GFNct0esPeJyRfkk8J5hTztHVSQp4UiNfL2O42sCA9XZPU8OgHvzOmt9ewBhVqA==", - "dev": true, - "requires": { - "source-map-support": "^0.5.11" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "bind-obj-methods": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" - }, - "dependencies": { - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.1.1.tgz", - "integrity": "sha512-df4o16uZmMHzVQwECZRHwfguOt5ixpuQVaZHjYMvYisgKhE+JXwcj/Tcr3+3bu/XeOJQ9ycYmzu7Mv8XrGxJDQ==", - "dev": true, - "requires": { - "anymatch": "^3.1.0", - "braces": "^3.0.2", - "fsevents": "^2.0.6", - "glob-parent": "^5.0.0", - "is-binary-path": "^2.1.0", - "is-glob": "^4.0.1", - "normalize-path": "^3.0.0", - "readdirp": "^3.1.1" - } - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "coveralls": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.6.tgz", - "integrity": "sha512-Pgh4v3gCI4T/9VijVrm8Ym5v0OgjvGLKj3zTUwkvsCiwqae/p6VLzpsFNjQS2i6ewV7ef+DjFJ5TSKxYt/mCrA==", - "dev": true, - "requires": { - "growl": "~> 1.10.0", - "js-yaml": "^3.13.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.86.0" - } - }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events-to-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "findit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", - "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", - "dev": true - }, - "flow-parser": { - "version": "0.108.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.108.0.tgz", - "integrity": "sha512-Ug8VuwlyDIZq5Xgrf+T7XLpKydhqYyNd8lmFtf7PZbu90T5LL+FeHjWzxyrBn35RCCZMw7pXrjCrHOSs+2zXyg==", - "dev": true - }, - "flow-remove-types": { - "version": "2.108.0", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.108.0.tgz", - "integrity": "sha512-cbYe0AijNVlc6V1Xx99fNqQtRMJ+xbQwG5rQtcheFQiBPO6b6VwvhMs/OelJvpO+YUTz49IhFKzoZGj5xm74PA==", - "dev": true, - "requires": { - "flow-parser": "^0.108.0", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - } - }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-exists-cached": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", - "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", - "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", - "dev": true, - "optional": true - }, - "function-loop": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz", - "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", - "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "handlebars": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.2.1.tgz", - "integrity": "sha512-bqPIlDk06UWbVEIFoYj+LVo42WhK96J+b25l7hbFDpxrOXMphFM3fNIm+cluwg4Pk2jiLjWU5nHQY7igGE75NQ==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", - "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-processinfo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-1.0.0.tgz", - "integrity": "sha512-FY0cPmWa4WoQNlvB8VOcafiRoB5nB+l2Pz2xGuXHRSy1KM8QFOYfz/rN+bGMCAeejrY3mrpF5oJHcN0s/garCg==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^6.0.5", - "istanbul-lib-coverage": "^2.0.3", - "rimraf": "^2.6.3", - "uuid": "^3.3.2" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", - "dev": true, - "requires": { - "handlebars": "^4.1.2" - } - }, - "jackspeak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", - "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", - "dev": true, - "requires": { - "cliui": "^4.1.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", - "dev": true - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "dev": true, - "requires": { - "mime-db": "1.40.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "minipass": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.0.0.tgz", - "integrity": "sha512-FKNU4XrAPDX0+ynwns7njVu4RolyG1mUKSlT6n6GwGXLtYSYh2Znc0S83Rl6zEr1zgFfXvAzIBabnmItm+n19g==", - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "own-or": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", - "dev": true - }, - "own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", - "dev": true, - "requires": { - "own-or": "^1.0.0" - } - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - } - } - }, - "readdirp": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.2.tgz", - "integrity": "sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - } - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tap": { - "version": "14.6.4", - "resolved": "https://registry.npmjs.org/tap/-/tap-14.6.4.tgz", - "integrity": "sha512-qYO/ZlQumbYzibH+wCVfkrNAomtBhKcKvMHWAMaucHrTBzZGHCmLR/WmRhb1khOKN5gzxMbCpEct3GQIKYXRlw==", - "dev": true, - "requires": { - "async-hook-domain": "^1.1.0", - "bind-obj-methods": "^2.0.0", - "browser-process-hrtime": "^1.0.0", - "capture-stack-trace": "^1.0.0", - "chokidar": "^3.0.2", - "color-support": "^1.1.0", - "coveralls": "^3.0.6", - "diff": "^4.0.1", - "esm": "^3.2.25", - "findit": "^2.0.0", - "flow-remove-types": "^2.107.0", - "foreground-child": "^1.3.3", - "fs-exists-cached": "^1.0.0", - "function-loop": "^1.0.2", - "glob": "^7.1.4", - "import-jsx": "^2.0.0", - "ink": "^2.3.0", - "isexe": "^2.0.0", - "istanbul-lib-processinfo": "^1.0.0", - "jackspeak": "^1.4.0", - "minipass": "^2.5.1", - "mkdirp": "^0.5.1", - "nyc": "^14.1.1", - "opener": "^1.5.1", - "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "react": "^16.9.0", - "rimraf": "^2.7.1", - "signal-exit": "^3.0.0", - "source-map-support": "^0.5.13", - "stack-utils": "^1.0.2", - "tap-mocha-reporter": "^4.0.1", - "tap-parser": "^9.3.3", - "tap-yaml": "^1.0.0", - "tcompare": "^2.3.0", - "treport": "^0.4.0", - "trivial-deferred": "^1.0.1", - "ts-node": "^8.3.0", - "typescript": "^3.6.3", - "which": "^1.3.1", - "write-file-atomic": "^3.0.0", - "yaml": "^1.6.0", - "yapool": "^1.0.0" - }, - "dependencies": { - "@babel/runtime": { - "version": "7.4.5", - "bundled": true, - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.2", - "bundled": true, - "dev": true - } - } - }, - "@types/prop-types": { - "version": "15.7.1", - "bundled": true, - "dev": true - }, - "@types/react": { - "version": "16.8.22", - "bundled": true, - "dev": true, - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "auto-bind": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "@types/react": "^16.8.12" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "bundled": true, - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "bundled": true, - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - } - } - }, - "babel-helper-builder-react-jsx": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "esutils": "^2.0.2" - } - }, - "babel-helpers": { - "version": "6.24.1", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "bundled": true, - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "bundled": true, - "dev": true - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-react-jsx": { - "version": "6.24.1", - "bundled": true, - "dev": true, - "requires": { - "babel-helper-builder-react-jsx": "^6.24.1", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-register": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "bundled": true, - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "caller-callsite": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cardinal": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "ci-info": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "slice-ansi": "^1.0.0", - "string-width": "^2.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "bundled": true, - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "core-js": { - "version": "2.6.5", - "bundled": true, - "dev": true - }, - "csstype": { - "version": "2.6.5", - "bundled": true, - "dev": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "detect-indent": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "bundled": true, - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "esprima": { - "version": "4.0.1", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "events-to-array": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "globals": { - "version": "9.18.0", - "bundled": true, - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "home-or-tmp": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "import-jsx": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "babel-core": "^6.25.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-object-rest-spread": "^6.23.0", - "babel-plugin-transform-react-jsx": "^6.24.1", - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "ink": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "requires": { - "@types/react": "^16.8.6", - "arrify": "^1.0.1", - "auto-bind": "^2.0.0", - "chalk": "^2.4.1", - "cli-cursor": "^2.1.0", - "cli-truncate": "^1.1.0", - "is-ci": "^2.0.0", - "lodash.throttle": "^4.1.1", - "log-update": "^3.0.0", - "prop-types": "^15.6.2", - "react-reconciler": "^0.20.0", - "scheduler": "^0.13.2", - "signal-exit": "^3.0.2", - "slice-ansi": "^1.0.0", - "string-length": "^2.0.0", - "widest-line": "^2.0.0", - "wrap-ansi": "^5.0.0", - "yoga-layout-prebuilt": "^1.9.3" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "invariant": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-ci": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-finite": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "json5": { - "version": "0.5.1", - "bundled": true, - "dev": true - }, - "lodash": { - "version": "4.17.14", - "bundled": true, - "dev": true - }, - "lodash.throttle": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "log-update": { - "version": "3.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "loose-envify": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minipass": { - "version": "2.5.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true - } - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "onetime": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "private": { - "version": "0.1.8", - "bundled": true, - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "punycode": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "react": { - "version": "16.9.0", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-is": { - "version": "16.8.6", - "bundled": true, - "dev": true - }, - "react-reconciler": { - "version": "0.20.4", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.13.6" - } - }, - "redeyed": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "esprima": "~4.0.0" - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "bundled": true, - "dev": true - }, - "repeating": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "scheduler": { - "version": "0.13.6", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slash": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "string-length": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "tap-parser": { - "version": "9.3.3", - "bundled": true, - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "minipass": "^2.2.0", - "tap-yaml": "^1.0.0" - } - }, - "tap-yaml": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "yaml": "^1.5.0" - } - }, - "to-fast-properties": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "treport": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "requires": { - "cardinal": "^2.1.1", - "chalk": "^2.4.2", - "import-jsx": "^2.0.0", - "ink": "^2.1.1", - "ms": "^2.1.1", - "react": "^16.8.6", - "string-length": "^2.0.0", - "tap-parser": "^9.3.2", - "unicode-length": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "unicode-length": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "punycode": "^2.0.0", - "strip-ansi": "^3.0.1" - } - } - } - }, - "trim-right": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "widest-line": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1" - } - }, - "yaml": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "@babel/runtime": "^7.4.5" - } - }, - "yoga-layout-prebuilt": { - "version": "1.9.3", - "bundled": true, - "dev": true - } - } - }, - "tap-mocha-reporter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-4.0.1.tgz", - "integrity": "sha512-/KfXaaYeSPn8qBi5Be8WSIP3iKV83s2uj2vzImJAXmjNu22kzqZ+1Dv1riYWa53sPCiyo1R1w1jbJrftF8SpcQ==", - "dev": true, - "requires": { - "color-support": "^1.1.0", - "debug": "^2.1.3", - "diff": "^1.3.2", - "escape-string-regexp": "^1.0.3", - "glob": "^7.0.5", - "readable-stream": "^2.1.5", - "tap-parser": "^8.0.0", - "tap-yaml": "0 || 1", - "unicode-length": "^1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "tap-parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-8.1.0.tgz", - "integrity": "sha512-GgOzgDwThYLxhVR83RbS1JUR1TxcT+jfZsrETgPAvFdr12lUOnuvrHOBaUQgpkAp6ZyeW6r2Nwd91t88M0ru3w==", - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "minipass": "^2.2.0", - "tap-yaml": "0 || 1" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, - "tap-yaml": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", - "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", - "dev": true, - "requires": { - "yaml": "^1.5.0" - } - }, - "tcompare": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-2.3.0.tgz", - "integrity": "sha512-fAfA73uFtFGybWGt4+IYT6UPLYVZQ4NfsP+IXEZGY0vh8e2IF7LVKafcQNMRBLqP0wzEA65LM9Tqj+FSmO8GLw==", - "dev": true - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "trivial-deferred": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", - "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", - "dev": true - }, - "ts-node": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz", - "integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz", - "integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw==", - "dev": true - }, - "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" - } - }, - "unicode-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", - "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", - "dev": true, - "requires": { - "punycode": "^1.3.2", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.0.tgz", - "integrity": "sha512-EIgkf60l2oWsffja2Sf2AL384dx328c0B+cIYPTQq5q2rOYuDV00/iPFBOUiDKKwKMOhkymH8AidPaRvzfxY+Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yaml": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.6.0.tgz", - "integrity": "sha512-iZfse3lwrJRoSlfs/9KQ9iIXxs9++RvBFVzAqbbBiFT+giYtyanevreF9r61ZTbGMgWQBxAua3FzJiniiJXWWw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.4.5" - } - }, - "yapool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", - "dev": true - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/node_modules/minipass-sized/package.json b/node_modules/minipass-sized/package.json index a3257fd8f673a..e1160104dc5ec 100644 --- a/node_modules/minipass-sized/package.json +++ b/node_modules/minipass-sized/package.json @@ -1,26 +1,34 @@ { "name": "minipass-sized", - "version": "1.0.3", + "version": "2.0.0", "description": "A Minipass stream that raises an error if you get a different number of bytes than expected", "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", "license": "ISC", + "files": [ + "dist" + ], "scripts": { "test": "tap", "snap": "tap", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "prepare": "tshy", "preversion": "npm test", "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true + "prepublishOnly": "git push origin --follow-tags", + "format": "prettier --write . --log-level warn", + "typedoc": "typedoc" }, "devDependencies": { - "tap": "^14.6.4" + "prettier": "^3.7.4", + "tap": "^21.5.0", + "tshy": "^3.1.0", + "typedoc": "^0.28.15" }, "dependencies": { - "minipass": "^3.0.0" + "minipass": "^7.1.2" }, - "main": "index.js", + "main": "./dist/commonjs/index.js", "keywords": [ "minipass", "size", @@ -35,5 +43,27 @@ }, "engines": { "node": ">=8" - } + }, + "type": "module", + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" } diff --git a/node_modules/minipass-sized/test/basic.js b/node_modules/minipass-sized/test/basic.js deleted file mode 100644 index bbdcadaa8c4e2..0000000000000 --- a/node_modules/minipass-sized/test/basic.js +++ /dev/null @@ -1,83 +0,0 @@ -const t = require('tap') -const MPS = require('../') - -t.test('ok if size checks out', t => { - const mps = new MPS({ size: 4 }) - - mps.write(Buffer.from('a').toString('hex'), 'hex') - mps.write(Buffer.from('sd')) - mps.end('f') - return mps.concat().then(data => t.equal(data.toString(), 'asdf')) -}) - -t.test('error if size exceeded', t => { - const mps = new MPS({ size: 1 }) - mps.on('error', er => { - t.match(er, { - message: 'Bad data size: expected 1 bytes, but got 4', - found: 4, - expect: 1, - code: 'EBADSIZE', - name: 'SizeError', - }) - t.end() - }) - mps.write('asdf') -}) - -t.test('error if size is not met', t => { - const mps = new MPS({ size: 999 }) - t.throws(() => mps.end(), { - message: 'Bad data size: expected 999 bytes, but got 0', - found: 0, - name: 'SizeError', - expect: 999, - code: 'EBADSIZE', - }) - t.end() -}) - -t.test('error if non-string/buffer is written', t => { - const mps = new MPS({size:1}) - mps.on('error', er => { - t.match(er, { - message: 'MinipassSized streams only work with string and buffer data' - }) - t.end() - }) - mps.write({some:'object'}) -}) - -t.test('projectiles', t => { - t.throws(() => new MPS(), { - message: 'invalid expected size: undefined' - }, 'size is required') - t.throws(() => new MPS({size: true}), { - message: 'invalid expected size: true' - }, 'size must be number') - t.throws(() => new MPS({size: NaN}), { - message: 'invalid expected size: NaN' - }, 'size must not be NaN') - t.throws(() => new MPS({size:1.2}), { - message: 'invalid expected size: 1.2' - }, 'size must be integer') - t.throws(() => new MPS({size: Infinity}), { - message: 'invalid expected size: Infinity' - }, 'size must be finite') - t.throws(() => new MPS({size: -1}), { - message: 'invalid expected size: -1' - }, 'size must be positive') - t.throws(() => new MPS({objectMode: true}), { - message: 'MinipassSized streams only work with string and buffer data' - }, 'no objectMode') - t.throws(() => new MPS({size: Number.MAX_SAFE_INTEGER + 1000000}), { - message: 'invalid expected size: 9007199255740992' - }) - t.end() -}) - -t.test('exports SizeError class', t => { - t.isa(MPS.SizeError, 'function') - t.isa(MPS.SizeError.prototype, Error) - t.end() -}) diff --git a/node_modules/minipass/LICENSE b/node_modules/minipass/LICENSE index bf1dece2e1f12..97f8e32ed82e4 100644 --- a/node_modules/minipass/LICENSE +++ b/node_modules/minipass/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2017-2022 npm, Inc., Isaac Z. Schlueter, and Contributors +Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/node_modules/minipass/dist/commonjs/index.js b/node_modules/minipass/dist/commonjs/index.js new file mode 100644 index 0000000000000..068c095b69793 --- /dev/null +++ b/node_modules/minipass/dist/commonjs/index.js @@ -0,0 +1,1028 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Minipass = exports.isWritable = exports.isReadable = exports.isStream = void 0; +const proc = typeof process === 'object' && process + ? process + : { + stdout: null, + stderr: null, + }; +const node_events_1 = require("node:events"); +const node_stream_1 = __importDefault(require("node:stream")); +const node_string_decoder_1 = require("node:string_decoder"); +/** + * Return true if the argument is a Minipass stream, Node stream, or something + * else that Minipass can interact with. + */ +const isStream = (s) => !!s && + typeof s === 'object' && + (s instanceof Minipass || + s instanceof node_stream_1.default || + (0, exports.isReadable)(s) || + (0, exports.isWritable)(s)); +exports.isStream = isStream; +/** + * Return true if the argument is a valid {@link Minipass.Readable} + */ +const isReadable = (s) => !!s && + typeof s === 'object' && + s instanceof node_events_1.EventEmitter && + typeof s.pipe === 'function' && + // node core Writable streams have a pipe() method, but it throws + s.pipe !== node_stream_1.default.Writable.prototype.pipe; +exports.isReadable = isReadable; +/** + * Return true if the argument is a valid {@link Minipass.Writable} + */ +const isWritable = (s) => !!s && + typeof s === 'object' && + s instanceof node_events_1.EventEmitter && + typeof s.write === 'function' && + typeof s.end === 'function'; +exports.isWritable = isWritable; +const EOF = Symbol('EOF'); +const MAYBE_EMIT_END = Symbol('maybeEmitEnd'); +const EMITTED_END = Symbol('emittedEnd'); +const EMITTING_END = Symbol('emittingEnd'); +const EMITTED_ERROR = Symbol('emittedError'); +const CLOSED = Symbol('closed'); +const READ = Symbol('read'); +const FLUSH = Symbol('flush'); +const FLUSHCHUNK = Symbol('flushChunk'); +const ENCODING = Symbol('encoding'); +const DECODER = Symbol('decoder'); +const FLOWING = Symbol('flowing'); +const PAUSED = Symbol('paused'); +const RESUME = Symbol('resume'); +const BUFFER = Symbol('buffer'); +const PIPES = Symbol('pipes'); +const BUFFERLENGTH = Symbol('bufferLength'); +const BUFFERPUSH = Symbol('bufferPush'); +const BUFFERSHIFT = Symbol('bufferShift'); +const OBJECTMODE = Symbol('objectMode'); +// internal event when stream is destroyed +const DESTROYED = Symbol('destroyed'); +// internal event when stream has an error +const ERROR = Symbol('error'); +const EMITDATA = Symbol('emitData'); +const EMITEND = Symbol('emitEnd'); +const EMITEND2 = Symbol('emitEnd2'); +const ASYNC = Symbol('async'); +const ABORT = Symbol('abort'); +const ABORTED = Symbol('aborted'); +const SIGNAL = Symbol('signal'); +const DATALISTENERS = Symbol('dataListeners'); +const DISCARDED = Symbol('discarded'); +const defer = (fn) => Promise.resolve().then(fn); +const nodefer = (fn) => fn(); +const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish'; +const isArrayBufferLike = (b) => b instanceof ArrayBuffer || + (!!b && + typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0); +const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b); +/** + * Internal class representing a pipe to a destination stream. + * + * @internal + */ +class Pipe { + src; + dest; + opts; + ondrain; + constructor(src, dest, opts) { + this.src = src; + this.dest = dest; + this.opts = opts; + this.ondrain = () => src[RESUME](); + this.dest.on('drain', this.ondrain); + } + unpipe() { + this.dest.removeListener('drain', this.ondrain); + } + // only here for the prototype + /* c8 ignore start */ + proxyErrors(_er) { } + /* c8 ignore stop */ + end() { + this.unpipe(); + if (this.opts.end) + this.dest.end(); + } +} +/** + * Internal class representing a pipe to a destination stream where + * errors are proxied. + * + * @internal + */ +class PipeProxyErrors extends Pipe { + unpipe() { + this.src.removeListener('error', this.proxyErrors); + super.unpipe(); + } + constructor(src, dest, opts) { + super(src, dest, opts); + this.proxyErrors = er => dest.emit('error', er); + src.on('error', this.proxyErrors); + } +} +const isObjectModeOptions = (o) => !!o.objectMode; +const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer'; +/** + * Main export, the Minipass class + * + * `RType` is the type of data emitted, defaults to Buffer + * + * `WType` is the type of data to be written, if RType is buffer or string, + * then any {@link Minipass.ContiguousData} is allowed. + * + * `Events` is the set of event handler signatures that this object + * will emit, see {@link Minipass.Events} + */ +class Minipass extends node_events_1.EventEmitter { + [FLOWING] = false; + [PAUSED] = false; + [PIPES] = []; + [BUFFER] = []; + [OBJECTMODE]; + [ENCODING]; + [ASYNC]; + [DECODER]; + [EOF] = false; + [EMITTED_END] = false; + [EMITTING_END] = false; + [CLOSED] = false; + [EMITTED_ERROR] = null; + [BUFFERLENGTH] = 0; + [DESTROYED] = false; + [SIGNAL]; + [ABORTED] = false; + [DATALISTENERS] = 0; + [DISCARDED] = false; + /** + * true if the stream can be written + */ + writable = true; + /** + * true if the stream can be read + */ + readable = true; + /** + * If `RType` is Buffer, then options do not need to be provided. + * Otherwise, an options object must be provided to specify either + * {@link Minipass.SharedOptions.objectMode} or + * {@link Minipass.SharedOptions.encoding}, as appropriate. + */ + constructor(...args) { + const options = (args[0] || + {}); + super(); + if (options.objectMode && typeof options.encoding === 'string') { + throw new TypeError('Encoding and objectMode may not be used together'); + } + if (isObjectModeOptions(options)) { + this[OBJECTMODE] = true; + this[ENCODING] = null; + } + else if (isEncodingOptions(options)) { + this[ENCODING] = options.encoding; + this[OBJECTMODE] = false; + } + else { + this[OBJECTMODE] = false; + this[ENCODING] = null; + } + this[ASYNC] = !!options.async; + this[DECODER] = this[ENCODING] + ? new node_string_decoder_1.StringDecoder(this[ENCODING]) + : null; + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposeBuffer === true) { + Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] }); + } + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposePipes === true) { + Object.defineProperty(this, 'pipes', { get: () => this[PIPES] }); + } + const { signal } = options; + if (signal) { + this[SIGNAL] = signal; + if (signal.aborted) { + this[ABORT](); + } + else { + signal.addEventListener('abort', () => this[ABORT]()); + } + } + } + /** + * The amount of data stored in the buffer waiting to be read. + * + * For Buffer strings, this will be the total byte length. + * For string encoding streams, this will be the string character length, + * according to JavaScript's `string.length` logic. + * For objectMode streams, this is a count of the items waiting to be + * emitted. + */ + get bufferLength() { + return this[BUFFERLENGTH]; + } + /** + * The `BufferEncoding` currently in use, or `null` + */ + get encoding() { + return this[ENCODING]; + } + /** + * @deprecated - This is a read only property + */ + set encoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * @deprecated - Encoding may only be set at instantiation time + */ + setEncoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * True if this is an objectMode stream + */ + get objectMode() { + return this[OBJECTMODE]; + } + /** + * @deprecated - This is a read-only property + */ + set objectMode(_om) { + throw new Error('objectMode must be set at instantiation time'); + } + /** + * true if this is an async stream + */ + get ['async']() { + return this[ASYNC]; + } + /** + * Set to true to make this stream async. + * + * Once set, it cannot be unset, as this would potentially cause incorrect + * behavior. Ie, a sync stream can be made async, but an async stream + * cannot be safely made sync. + */ + set ['async'](a) { + this[ASYNC] = this[ASYNC] || !!a; + } + // drop everything and get out of the flow completely + [ABORT]() { + this[ABORTED] = true; + this.emit('abort', this[SIGNAL]?.reason); + this.destroy(this[SIGNAL]?.reason); + } + /** + * True if the stream has been aborted. + */ + get aborted() { + return this[ABORTED]; + } + /** + * No-op setter. Stream aborted status is set via the AbortSignal provided + * in the constructor options. + */ + set aborted(_) { } + write(chunk, encoding, cb) { + if (this[ABORTED]) + return false; + if (this[EOF]) + throw new Error('write after end'); + if (this[DESTROYED]) { + this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' })); + return true; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (!encoding) + encoding = 'utf8'; + const fn = this[ASYNC] ? defer : nodefer; + // convert array buffers and typed array views into buffers + // at some point in the future, we may want to do the opposite! + // leave strings and buffers as-is + // anything is only allowed if in object mode, so throw + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); + } + else if (isArrayBufferLike(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk); + } + else if (typeof chunk !== 'string') { + throw new Error('Non-contiguous data written to non-objectMode stream'); + } + } + // handle object mode up front, since it's simpler + // this yields better performance, fewer checks later. + if (this[OBJECTMODE]) { + // maybe impossible? + /* c8 ignore start */ + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + /* c8 ignore stop */ + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // at this point the chunk is a buffer or string + // don't buffer it up or send it to the decoder + if (!chunk.length) { + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // fast-path writing strings of same encoding to a stream with + // an empty buffer, skipping the buffer/decoder dance + if (typeof chunk === 'string' && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) { + //@ts-ignore - sinful unsafe type change + chunk = Buffer.from(chunk, encoding); + } + if (Buffer.isBuffer(chunk) && this[ENCODING]) { + //@ts-ignore - sinful unsafe type change + chunk = this[DECODER].write(chunk); + } + // Note: flushing CAN potentially switch us into not-flowing mode + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + /** + * Low-level explicit read method. + * + * In objectMode, the argument is ignored, and one item is returned if + * available. + * + * `n` is the number of bytes (or in the case of encoding streams, + * characters) to consume. If `n` is not provided, then the entire buffer + * is returned, or `null` is returned if no data is available. + * + * If `n` is greater that the amount of data in the internal buffer, + * then `null` is returned. + */ + read(n) { + if (this[DESTROYED]) + return null; + this[DISCARDED] = false; + if (this[BUFFERLENGTH] === 0 || + n === 0 || + (n && n > this[BUFFERLENGTH])) { + this[MAYBE_EMIT_END](); + return null; + } + if (this[OBJECTMODE]) + n = null; + if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { + // not object mode, so if we have an encoding, then RType is string + // otherwise, must be Buffer + this[BUFFER] = [ + (this[ENCODING] + ? this[BUFFER].join('') + : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])), + ]; + } + const ret = this[READ](n || null, this[BUFFER][0]); + this[MAYBE_EMIT_END](); + return ret; + } + [READ](n, chunk) { + if (this[OBJECTMODE]) + this[BUFFERSHIFT](); + else { + const c = chunk; + if (n === c.length || n === null) + this[BUFFERSHIFT](); + else if (typeof c === 'string') { + this[BUFFER][0] = c.slice(n); + chunk = c.slice(0, n); + this[BUFFERLENGTH] -= n; + } + else { + this[BUFFER][0] = c.subarray(n); + chunk = c.subarray(0, n); + this[BUFFERLENGTH] -= n; + } + } + this.emit('data', chunk); + if (!this[BUFFER].length && !this[EOF]) + this.emit('drain'); + return chunk; + } + end(chunk, encoding, cb) { + if (typeof chunk === 'function') { + cb = chunk; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (chunk !== undefined) + this.write(chunk, encoding); + if (cb) + this.once('end', cb); + this[EOF] = true; + this.writable = false; + // if we haven't written anything, then go ahead and emit, + // even if we're not reading. + // we'll re-emit if a new 'end' listener is added anyway. + // This makes MP more suitable to write-only use cases. + if (this[FLOWING] || !this[PAUSED]) + this[MAYBE_EMIT_END](); + return this; + } + // don't let the internal resume be overwritten + [RESUME]() { + if (this[DESTROYED]) + return; + if (!this[DATALISTENERS] && !this[PIPES].length) { + this[DISCARDED] = true; + } + this[PAUSED] = false; + this[FLOWING] = true; + this.emit('resume'); + if (this[BUFFER].length) + this[FLUSH](); + else if (this[EOF]) + this[MAYBE_EMIT_END](); + else + this.emit('drain'); + } + /** + * Resume the stream if it is currently in a paused state + * + * If called when there are no pipe destinations or `data` event listeners, + * this will place the stream in a "discarded" state, where all data will + * be thrown away. The discarded state is removed if a pipe destination or + * data handler is added, if pause() is called, or if any synchronous or + * asynchronous iteration is started. + */ + resume() { + return this[RESUME](); + } + /** + * Pause the stream + */ + pause() { + this[FLOWING] = false; + this[PAUSED] = true; + this[DISCARDED] = false; + } + /** + * true if the stream has been forcibly destroyed + */ + get destroyed() { + return this[DESTROYED]; + } + /** + * true if the stream is currently in a flowing state, meaning that + * any writes will be immediately emitted. + */ + get flowing() { + return this[FLOWING]; + } + /** + * true if the stream is currently in a paused state + */ + get paused() { + return this[PAUSED]; + } + [BUFFERPUSH](chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1; + else + this[BUFFERLENGTH] += chunk.length; + this[BUFFER].push(chunk); + } + [BUFFERSHIFT]() { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1; + else + this[BUFFERLENGTH] -= this[BUFFER][0].length; + return this[BUFFER].shift(); + } + [FLUSH](noDrain = false) { + do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && + this[BUFFER].length); + if (!noDrain && !this[BUFFER].length && !this[EOF]) + this.emit('drain'); + } + [FLUSHCHUNK](chunk) { + this.emit('data', chunk); + return this[FLOWING]; + } + /** + * Pipe all data emitted by this stream into the destination provided. + * + * Triggers the flow of data. + */ + pipe(dest, opts) { + if (this[DESTROYED]) + return dest; + this[DISCARDED] = false; + const ended = this[EMITTED_END]; + opts = opts || {}; + if (dest === proc.stdout || dest === proc.stderr) + opts.end = false; + else + opts.end = opts.end !== false; + opts.proxyErrors = !!opts.proxyErrors; + // piping an ended stream ends immediately + if (ended) { + if (opts.end) + dest.end(); + } + else { + // "as" here just ignores the WType, which pipes don't care about, + // since they're only consuming from us, and writing to the dest + this[PIPES].push(!opts.proxyErrors + ? new Pipe(this, dest, opts) + : new PipeProxyErrors(this, dest, opts)); + if (this[ASYNC]) + defer(() => this[RESUME]()); + else + this[RESUME](); + } + return dest; + } + /** + * Fully unhook a piped destination stream. + * + * If the destination stream was the only consumer of this stream (ie, + * there are no other piped destinations or `'data'` event listeners) + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + unpipe(dest) { + const p = this[PIPES].find(p => p.dest === dest); + if (p) { + if (this[PIPES].length === 1) { + if (this[FLOWING] && this[DATALISTENERS] === 0) { + this[FLOWING] = false; + } + this[PIPES] = []; + } + else + this[PIPES].splice(this[PIPES].indexOf(p), 1); + p.unpipe(); + } + } + /** + * Alias for {@link Minipass#on} + */ + addListener(ev, handler) { + return this.on(ev, handler); + } + /** + * Mostly identical to `EventEmitter.on`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * - Adding a 'data' event handler will trigger the flow of data + * + * - Adding a 'readable' event handler when there is data waiting to be read + * will cause 'readable' to be emitted immediately. + * + * - Adding an 'endish' event handler ('end', 'finish', etc.) which has + * already passed will cause the event to be emitted immediately and all + * handlers removed. + * + * - Adding an 'error' event handler after an error has been emitted will + * cause the event to be re-emitted immediately with the error previously + * raised. + */ + on(ev, handler) { + const ret = super.on(ev, handler); + if (ev === 'data') { + this[DISCARDED] = false; + this[DATALISTENERS]++; + if (!this[PIPES].length && !this[FLOWING]) { + this[RESUME](); + } + } + else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) { + super.emit('readable'); + } + else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev); + this.removeAllListeners(ev); + } + else if (ev === 'error' && this[EMITTED_ERROR]) { + const h = handler; + if (this[ASYNC]) + defer(() => h.call(this, this[EMITTED_ERROR])); + else + h.call(this, this[EMITTED_ERROR]); + } + return ret; + } + /** + * Alias for {@link Minipass#off} + */ + removeListener(ev, handler) { + return this.off(ev, handler); + } + /** + * Mostly identical to `EventEmitter.off` + * + * If a 'data' event handler is removed, and it was the last consumer + * (ie, there are no pipe destinations or other 'data' event listeners), + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + off(ev, handler) { + const ret = super.off(ev, handler); + // if we previously had listeners, and now we don't, and we don't + // have any pipes, then stop the flow, unless it's been explicitly + // put in a discarded flowing state via stream.resume(). + if (ev === 'data') { + this[DATALISTENERS] = this.listeners('data').length; + if (this[DATALISTENERS] === 0 && + !this[DISCARDED] && + !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * Mostly identical to `EventEmitter.removeAllListeners` + * + * If all 'data' event handlers are removed, and they were the last consumer + * (ie, there are no pipe destinations), then the flow of data will stop + * until there is another consumer or {@link Minipass#resume} is explicitly + * called. + */ + removeAllListeners(ev) { + const ret = super.removeAllListeners(ev); + if (ev === 'data' || ev === undefined) { + this[DATALISTENERS] = 0; + if (!this[DISCARDED] && !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * true if the 'end' event has been emitted + */ + get emittedEnd() { + return this[EMITTED_END]; + } + [MAYBE_EMIT_END]() { + if (!this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this[BUFFER].length === 0 && + this[EOF]) { + this[EMITTING_END] = true; + this.emit('end'); + this.emit('prefinish'); + this.emit('finish'); + if (this[CLOSED]) + this.emit('close'); + this[EMITTING_END] = false; + } + } + /** + * Mostly identical to `EventEmitter.emit`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * If the stream has been destroyed, and the event is something other + * than 'close' or 'error', then `false` is returned and no handlers + * are called. + * + * If the event is 'end', and has already been emitted, then the event + * is ignored. If the stream is in a paused or non-flowing state, then + * the event will be deferred until data flow resumes. If the stream is + * async, then handlers will be called on the next tick rather than + * immediately. + * + * If the event is 'close', and 'end' has not yet been emitted, then + * the event will be deferred until after 'end' is emitted. + * + * If the event is 'error', and an AbortSignal was provided for the stream, + * and there are no listeners, then the event is ignored, matching the + * behavior of node core streams in the presense of an AbortSignal. + * + * If the event is 'finish' or 'prefinish', then all listeners will be + * removed after emitting the event, to prevent double-firing. + */ + emit(ev, ...args) { + const data = args[0]; + // error and close are only events allowed after calling destroy() + if (ev !== 'error' && + ev !== 'close' && + ev !== DESTROYED && + this[DESTROYED]) { + return false; + } + else if (ev === 'data') { + return !this[OBJECTMODE] && !data + ? false + : this[ASYNC] + ? (defer(() => this[EMITDATA](data)), true) + : this[EMITDATA](data); + } + else if (ev === 'end') { + return this[EMITEND](); + } + else if (ev === 'close') { + this[CLOSED] = true; + // don't emit close before 'end' and 'finish' + if (!this[EMITTED_END] && !this[DESTROYED]) + return false; + const ret = super.emit('close'); + this.removeAllListeners('close'); + return ret; + } + else if (ev === 'error') { + this[EMITTED_ERROR] = data; + super.emit(ERROR, data); + const ret = !this[SIGNAL] || this.listeners('error').length + ? super.emit('error', data) + : false; + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'resume') { + const ret = super.emit('resume'); + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'finish' || ev === 'prefinish') { + const ret = super.emit(ev); + this.removeAllListeners(ev); + return ret; + } + // Some other unknown event + const ret = super.emit(ev, ...args); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITDATA](data) { + for (const p of this[PIPES]) { + if (p.dest.write(data) === false) + this.pause(); + } + const ret = this[DISCARDED] ? false : super.emit('data', data); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITEND]() { + if (this[EMITTED_END]) + return false; + this[EMITTED_END] = true; + this.readable = false; + return this[ASYNC] + ? (defer(() => this[EMITEND2]()), true) + : this[EMITEND2](); + } + [EMITEND2]() { + if (this[DECODER]) { + const data = this[DECODER].end(); + if (data) { + for (const p of this[PIPES]) { + p.dest.write(data); + } + if (!this[DISCARDED]) + super.emit('data', data); + } + } + for (const p of this[PIPES]) { + p.end(); + } + const ret = super.emit('end'); + this.removeAllListeners('end'); + return ret; + } + /** + * Return a Promise that resolves to an array of all emitted data once + * the stream ends. + */ + async collect() { + const buf = Object.assign([], { + dataLength: 0, + }); + if (!this[OBJECTMODE]) + buf.dataLength = 0; + // set the promise first, in case an error is raised + // by triggering the flow here. + const p = this.promise(); + this.on('data', c => { + buf.push(c); + if (!this[OBJECTMODE]) + buf.dataLength += c.length; + }); + await p; + return buf; + } + /** + * Return a Promise that resolves to the concatenation of all emitted data + * once the stream ends. + * + * Not allowed on objectMode streams. + */ + async concat() { + if (this[OBJECTMODE]) { + throw new Error('cannot concat in objectMode'); + } + const buf = await this.collect(); + return (this[ENCODING] + ? buf.join('') + : Buffer.concat(buf, buf.dataLength)); + } + /** + * Return a void Promise that resolves once the stream ends. + */ + async promise() { + return new Promise((resolve, reject) => { + this.on(DESTROYED, () => reject(new Error('stream destroyed'))); + this.on('error', er => reject(er)); + this.on('end', () => resolve()); + }); + } + /** + * Asynchronous `for await of` iteration. + * + * This will continue emitting all chunks until the stream terminates. + */ + [Symbol.asyncIterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = async () => { + this.pause(); + stopped = true; + return { value: undefined, done: true }; + }; + const next = () => { + if (stopped) + return stop(); + const res = this.read(); + if (res !== null) + return Promise.resolve({ done: false, value: res }); + if (this[EOF]) + return stop(); + let resolve; + let reject; + const onerr = (er) => { + this.off('data', ondata); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + stop(); + reject(er); + }; + const ondata = (value) => { + this.off('error', onerr); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + this.pause(); + resolve({ value, done: !!this[EOF] }); + }; + const onend = () => { + this.off('error', onerr); + this.off('data', ondata); + this.off(DESTROYED, ondestroy); + stop(); + resolve({ done: true, value: undefined }); + }; + const ondestroy = () => onerr(new Error('stream destroyed')); + return new Promise((res, rej) => { + reject = rej; + resolve = res; + this.once(DESTROYED, ondestroy); + this.once('error', onerr); + this.once('end', onend); + this.once('data', ondata); + }); + }; + return { + next, + throw: stop, + return: stop, + [Symbol.asyncIterator]() { + return this; + }, + }; + } + /** + * Synchronous `for of` iteration. + * + * The iteration will terminate when the internal buffer runs out, even + * if the stream has not yet terminated. + */ + [Symbol.iterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = () => { + this.pause(); + this.off(ERROR, stop); + this.off(DESTROYED, stop); + this.off('end', stop); + stopped = true; + return { done: true, value: undefined }; + }; + const next = () => { + if (stopped) + return stop(); + const value = this.read(); + return value === null ? stop() : { done: false, value }; + }; + this.once('end', stop); + this.once(ERROR, stop); + this.once(DESTROYED, stop); + return { + next, + throw: stop, + return: stop, + [Symbol.iterator]() { + return this; + }, + }; + } + /** + * Destroy a stream, preventing it from being used for any further purpose. + * + * If the stream has a `close()` method, then it will be called on + * destruction. + * + * After destruction, any attempt to write data, read data, or emit most + * events will be ignored. + * + * If an error argument is provided, then it will be emitted in an + * 'error' event. + */ + destroy(er) { + if (this[DESTROYED]) { + if (er) + this.emit('error', er); + else + this.emit(DESTROYED); + return this; + } + this[DESTROYED] = true; + this[DISCARDED] = true; + // throw away all buffered data, it's never coming out + this[BUFFER].length = 0; + this[BUFFERLENGTH] = 0; + const wc = this; + if (typeof wc.close === 'function' && !this[CLOSED]) + wc.close(); + if (er) + this.emit('error', er); + // if no error to emit, still reject pending promises + else + this.emit(DESTROYED); + return this; + } + /** + * Alias for {@link isStream} + * + * Former export location, maintained for backwards compatibility. + * + * @deprecated + */ + static get isStream() { + return exports.isStream; + } +} +exports.Minipass = Minipass; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minipass/dist/commonjs/package.json b/node_modules/minipass/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/minipass/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/minipass/dist/esm/index.js b/node_modules/minipass/dist/esm/index.js new file mode 100644 index 0000000000000..b5fa4513c9083 --- /dev/null +++ b/node_modules/minipass/dist/esm/index.js @@ -0,0 +1,1018 @@ +const proc = typeof process === 'object' && process + ? process + : { + stdout: null, + stderr: null, + }; +import { EventEmitter } from 'node:events'; +import Stream from 'node:stream'; +import { StringDecoder } from 'node:string_decoder'; +/** + * Return true if the argument is a Minipass stream, Node stream, or something + * else that Minipass can interact with. + */ +export const isStream = (s) => !!s && + typeof s === 'object' && + (s instanceof Minipass || + s instanceof Stream || + isReadable(s) || + isWritable(s)); +/** + * Return true if the argument is a valid {@link Minipass.Readable} + */ +export const isReadable = (s) => !!s && + typeof s === 'object' && + s instanceof EventEmitter && + typeof s.pipe === 'function' && + // node core Writable streams have a pipe() method, but it throws + s.pipe !== Stream.Writable.prototype.pipe; +/** + * Return true if the argument is a valid {@link Minipass.Writable} + */ +export const isWritable = (s) => !!s && + typeof s === 'object' && + s instanceof EventEmitter && + typeof s.write === 'function' && + typeof s.end === 'function'; +const EOF = Symbol('EOF'); +const MAYBE_EMIT_END = Symbol('maybeEmitEnd'); +const EMITTED_END = Symbol('emittedEnd'); +const EMITTING_END = Symbol('emittingEnd'); +const EMITTED_ERROR = Symbol('emittedError'); +const CLOSED = Symbol('closed'); +const READ = Symbol('read'); +const FLUSH = Symbol('flush'); +const FLUSHCHUNK = Symbol('flushChunk'); +const ENCODING = Symbol('encoding'); +const DECODER = Symbol('decoder'); +const FLOWING = Symbol('flowing'); +const PAUSED = Symbol('paused'); +const RESUME = Symbol('resume'); +const BUFFER = Symbol('buffer'); +const PIPES = Symbol('pipes'); +const BUFFERLENGTH = Symbol('bufferLength'); +const BUFFERPUSH = Symbol('bufferPush'); +const BUFFERSHIFT = Symbol('bufferShift'); +const OBJECTMODE = Symbol('objectMode'); +// internal event when stream is destroyed +const DESTROYED = Symbol('destroyed'); +// internal event when stream has an error +const ERROR = Symbol('error'); +const EMITDATA = Symbol('emitData'); +const EMITEND = Symbol('emitEnd'); +const EMITEND2 = Symbol('emitEnd2'); +const ASYNC = Symbol('async'); +const ABORT = Symbol('abort'); +const ABORTED = Symbol('aborted'); +const SIGNAL = Symbol('signal'); +const DATALISTENERS = Symbol('dataListeners'); +const DISCARDED = Symbol('discarded'); +const defer = (fn) => Promise.resolve().then(fn); +const nodefer = (fn) => fn(); +const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish'; +const isArrayBufferLike = (b) => b instanceof ArrayBuffer || + (!!b && + typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0); +const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b); +/** + * Internal class representing a pipe to a destination stream. + * + * @internal + */ +class Pipe { + src; + dest; + opts; + ondrain; + constructor(src, dest, opts) { + this.src = src; + this.dest = dest; + this.opts = opts; + this.ondrain = () => src[RESUME](); + this.dest.on('drain', this.ondrain); + } + unpipe() { + this.dest.removeListener('drain', this.ondrain); + } + // only here for the prototype + /* c8 ignore start */ + proxyErrors(_er) { } + /* c8 ignore stop */ + end() { + this.unpipe(); + if (this.opts.end) + this.dest.end(); + } +} +/** + * Internal class representing a pipe to a destination stream where + * errors are proxied. + * + * @internal + */ +class PipeProxyErrors extends Pipe { + unpipe() { + this.src.removeListener('error', this.proxyErrors); + super.unpipe(); + } + constructor(src, dest, opts) { + super(src, dest, opts); + this.proxyErrors = er => dest.emit('error', er); + src.on('error', this.proxyErrors); + } +} +const isObjectModeOptions = (o) => !!o.objectMode; +const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer'; +/** + * Main export, the Minipass class + * + * `RType` is the type of data emitted, defaults to Buffer + * + * `WType` is the type of data to be written, if RType is buffer or string, + * then any {@link Minipass.ContiguousData} is allowed. + * + * `Events` is the set of event handler signatures that this object + * will emit, see {@link Minipass.Events} + */ +export class Minipass extends EventEmitter { + [FLOWING] = false; + [PAUSED] = false; + [PIPES] = []; + [BUFFER] = []; + [OBJECTMODE]; + [ENCODING]; + [ASYNC]; + [DECODER]; + [EOF] = false; + [EMITTED_END] = false; + [EMITTING_END] = false; + [CLOSED] = false; + [EMITTED_ERROR] = null; + [BUFFERLENGTH] = 0; + [DESTROYED] = false; + [SIGNAL]; + [ABORTED] = false; + [DATALISTENERS] = 0; + [DISCARDED] = false; + /** + * true if the stream can be written + */ + writable = true; + /** + * true if the stream can be read + */ + readable = true; + /** + * If `RType` is Buffer, then options do not need to be provided. + * Otherwise, an options object must be provided to specify either + * {@link Minipass.SharedOptions.objectMode} or + * {@link Minipass.SharedOptions.encoding}, as appropriate. + */ + constructor(...args) { + const options = (args[0] || + {}); + super(); + if (options.objectMode && typeof options.encoding === 'string') { + throw new TypeError('Encoding and objectMode may not be used together'); + } + if (isObjectModeOptions(options)) { + this[OBJECTMODE] = true; + this[ENCODING] = null; + } + else if (isEncodingOptions(options)) { + this[ENCODING] = options.encoding; + this[OBJECTMODE] = false; + } + else { + this[OBJECTMODE] = false; + this[ENCODING] = null; + } + this[ASYNC] = !!options.async; + this[DECODER] = this[ENCODING] + ? new StringDecoder(this[ENCODING]) + : null; + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposeBuffer === true) { + Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] }); + } + //@ts-ignore - private option for debugging and testing + if (options && options.debugExposePipes === true) { + Object.defineProperty(this, 'pipes', { get: () => this[PIPES] }); + } + const { signal } = options; + if (signal) { + this[SIGNAL] = signal; + if (signal.aborted) { + this[ABORT](); + } + else { + signal.addEventListener('abort', () => this[ABORT]()); + } + } + } + /** + * The amount of data stored in the buffer waiting to be read. + * + * For Buffer strings, this will be the total byte length. + * For string encoding streams, this will be the string character length, + * according to JavaScript's `string.length` logic. + * For objectMode streams, this is a count of the items waiting to be + * emitted. + */ + get bufferLength() { + return this[BUFFERLENGTH]; + } + /** + * The `BufferEncoding` currently in use, or `null` + */ + get encoding() { + return this[ENCODING]; + } + /** + * @deprecated - This is a read only property + */ + set encoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * @deprecated - Encoding may only be set at instantiation time + */ + setEncoding(_enc) { + throw new Error('Encoding must be set at instantiation time'); + } + /** + * True if this is an objectMode stream + */ + get objectMode() { + return this[OBJECTMODE]; + } + /** + * @deprecated - This is a read-only property + */ + set objectMode(_om) { + throw new Error('objectMode must be set at instantiation time'); + } + /** + * true if this is an async stream + */ + get ['async']() { + return this[ASYNC]; + } + /** + * Set to true to make this stream async. + * + * Once set, it cannot be unset, as this would potentially cause incorrect + * behavior. Ie, a sync stream can be made async, but an async stream + * cannot be safely made sync. + */ + set ['async'](a) { + this[ASYNC] = this[ASYNC] || !!a; + } + // drop everything and get out of the flow completely + [ABORT]() { + this[ABORTED] = true; + this.emit('abort', this[SIGNAL]?.reason); + this.destroy(this[SIGNAL]?.reason); + } + /** + * True if the stream has been aborted. + */ + get aborted() { + return this[ABORTED]; + } + /** + * No-op setter. Stream aborted status is set via the AbortSignal provided + * in the constructor options. + */ + set aborted(_) { } + write(chunk, encoding, cb) { + if (this[ABORTED]) + return false; + if (this[EOF]) + throw new Error('write after end'); + if (this[DESTROYED]) { + this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' })); + return true; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (!encoding) + encoding = 'utf8'; + const fn = this[ASYNC] ? defer : nodefer; + // convert array buffers and typed array views into buffers + // at some point in the future, we may want to do the opposite! + // leave strings and buffers as-is + // anything is only allowed if in object mode, so throw + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); + } + else if (isArrayBufferLike(chunk)) { + //@ts-ignore - sinful unsafe type changing + chunk = Buffer.from(chunk); + } + else if (typeof chunk !== 'string') { + throw new Error('Non-contiguous data written to non-objectMode stream'); + } + } + // handle object mode up front, since it's simpler + // this yields better performance, fewer checks later. + if (this[OBJECTMODE]) { + // maybe impossible? + /* c8 ignore start */ + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + /* c8 ignore stop */ + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // at this point the chunk is a buffer or string + // don't buffer it up or send it to the decoder + if (!chunk.length) { + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + // fast-path writing strings of same encoding to a stream with + // an empty buffer, skipping the buffer/decoder dance + if (typeof chunk === 'string' && + // unless it is a string already ready for us to use + !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) { + //@ts-ignore - sinful unsafe type change + chunk = Buffer.from(chunk, encoding); + } + if (Buffer.isBuffer(chunk) && this[ENCODING]) { + //@ts-ignore - sinful unsafe type change + chunk = this[DECODER].write(chunk); + } + // Note: flushing CAN potentially switch us into not-flowing mode + if (this[FLOWING] && this[BUFFERLENGTH] !== 0) + this[FLUSH](true); + if (this[FLOWING]) + this.emit('data', chunk); + else + this[BUFFERPUSH](chunk); + if (this[BUFFERLENGTH] !== 0) + this.emit('readable'); + if (cb) + fn(cb); + return this[FLOWING]; + } + /** + * Low-level explicit read method. + * + * In objectMode, the argument is ignored, and one item is returned if + * available. + * + * `n` is the number of bytes (or in the case of encoding streams, + * characters) to consume. If `n` is not provided, then the entire buffer + * is returned, or `null` is returned if no data is available. + * + * If `n` is greater that the amount of data in the internal buffer, + * then `null` is returned. + */ + read(n) { + if (this[DESTROYED]) + return null; + this[DISCARDED] = false; + if (this[BUFFERLENGTH] === 0 || + n === 0 || + (n && n > this[BUFFERLENGTH])) { + this[MAYBE_EMIT_END](); + return null; + } + if (this[OBJECTMODE]) + n = null; + if (this[BUFFER].length > 1 && !this[OBJECTMODE]) { + // not object mode, so if we have an encoding, then RType is string + // otherwise, must be Buffer + this[BUFFER] = [ + (this[ENCODING] + ? this[BUFFER].join('') + : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])), + ]; + } + const ret = this[READ](n || null, this[BUFFER][0]); + this[MAYBE_EMIT_END](); + return ret; + } + [READ](n, chunk) { + if (this[OBJECTMODE]) + this[BUFFERSHIFT](); + else { + const c = chunk; + if (n === c.length || n === null) + this[BUFFERSHIFT](); + else if (typeof c === 'string') { + this[BUFFER][0] = c.slice(n); + chunk = c.slice(0, n); + this[BUFFERLENGTH] -= n; + } + else { + this[BUFFER][0] = c.subarray(n); + chunk = c.subarray(0, n); + this[BUFFERLENGTH] -= n; + } + } + this.emit('data', chunk); + if (!this[BUFFER].length && !this[EOF]) + this.emit('drain'); + return chunk; + } + end(chunk, encoding, cb) { + if (typeof chunk === 'function') { + cb = chunk; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = 'utf8'; + } + if (chunk !== undefined) + this.write(chunk, encoding); + if (cb) + this.once('end', cb); + this[EOF] = true; + this.writable = false; + // if we haven't written anything, then go ahead and emit, + // even if we're not reading. + // we'll re-emit if a new 'end' listener is added anyway. + // This makes MP more suitable to write-only use cases. + if (this[FLOWING] || !this[PAUSED]) + this[MAYBE_EMIT_END](); + return this; + } + // don't let the internal resume be overwritten + [RESUME]() { + if (this[DESTROYED]) + return; + if (!this[DATALISTENERS] && !this[PIPES].length) { + this[DISCARDED] = true; + } + this[PAUSED] = false; + this[FLOWING] = true; + this.emit('resume'); + if (this[BUFFER].length) + this[FLUSH](); + else if (this[EOF]) + this[MAYBE_EMIT_END](); + else + this.emit('drain'); + } + /** + * Resume the stream if it is currently in a paused state + * + * If called when there are no pipe destinations or `data` event listeners, + * this will place the stream in a "discarded" state, where all data will + * be thrown away. The discarded state is removed if a pipe destination or + * data handler is added, if pause() is called, or if any synchronous or + * asynchronous iteration is started. + */ + resume() { + return this[RESUME](); + } + /** + * Pause the stream + */ + pause() { + this[FLOWING] = false; + this[PAUSED] = true; + this[DISCARDED] = false; + } + /** + * true if the stream has been forcibly destroyed + */ + get destroyed() { + return this[DESTROYED]; + } + /** + * true if the stream is currently in a flowing state, meaning that + * any writes will be immediately emitted. + */ + get flowing() { + return this[FLOWING]; + } + /** + * true if the stream is currently in a paused state + */ + get paused() { + return this[PAUSED]; + } + [BUFFERPUSH](chunk) { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] += 1; + else + this[BUFFERLENGTH] += chunk.length; + this[BUFFER].push(chunk); + } + [BUFFERSHIFT]() { + if (this[OBJECTMODE]) + this[BUFFERLENGTH] -= 1; + else + this[BUFFERLENGTH] -= this[BUFFER][0].length; + return this[BUFFER].shift(); + } + [FLUSH](noDrain = false) { + do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && + this[BUFFER].length); + if (!noDrain && !this[BUFFER].length && !this[EOF]) + this.emit('drain'); + } + [FLUSHCHUNK](chunk) { + this.emit('data', chunk); + return this[FLOWING]; + } + /** + * Pipe all data emitted by this stream into the destination provided. + * + * Triggers the flow of data. + */ + pipe(dest, opts) { + if (this[DESTROYED]) + return dest; + this[DISCARDED] = false; + const ended = this[EMITTED_END]; + opts = opts || {}; + if (dest === proc.stdout || dest === proc.stderr) + opts.end = false; + else + opts.end = opts.end !== false; + opts.proxyErrors = !!opts.proxyErrors; + // piping an ended stream ends immediately + if (ended) { + if (opts.end) + dest.end(); + } + else { + // "as" here just ignores the WType, which pipes don't care about, + // since they're only consuming from us, and writing to the dest + this[PIPES].push(!opts.proxyErrors + ? new Pipe(this, dest, opts) + : new PipeProxyErrors(this, dest, opts)); + if (this[ASYNC]) + defer(() => this[RESUME]()); + else + this[RESUME](); + } + return dest; + } + /** + * Fully unhook a piped destination stream. + * + * If the destination stream was the only consumer of this stream (ie, + * there are no other piped destinations or `'data'` event listeners) + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + unpipe(dest) { + const p = this[PIPES].find(p => p.dest === dest); + if (p) { + if (this[PIPES].length === 1) { + if (this[FLOWING] && this[DATALISTENERS] === 0) { + this[FLOWING] = false; + } + this[PIPES] = []; + } + else + this[PIPES].splice(this[PIPES].indexOf(p), 1); + p.unpipe(); + } + } + /** + * Alias for {@link Minipass#on} + */ + addListener(ev, handler) { + return this.on(ev, handler); + } + /** + * Mostly identical to `EventEmitter.on`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * - Adding a 'data' event handler will trigger the flow of data + * + * - Adding a 'readable' event handler when there is data waiting to be read + * will cause 'readable' to be emitted immediately. + * + * - Adding an 'endish' event handler ('end', 'finish', etc.) which has + * already passed will cause the event to be emitted immediately and all + * handlers removed. + * + * - Adding an 'error' event handler after an error has been emitted will + * cause the event to be re-emitted immediately with the error previously + * raised. + */ + on(ev, handler) { + const ret = super.on(ev, handler); + if (ev === 'data') { + this[DISCARDED] = false; + this[DATALISTENERS]++; + if (!this[PIPES].length && !this[FLOWING]) { + this[RESUME](); + } + } + else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) { + super.emit('readable'); + } + else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev); + this.removeAllListeners(ev); + } + else if (ev === 'error' && this[EMITTED_ERROR]) { + const h = handler; + if (this[ASYNC]) + defer(() => h.call(this, this[EMITTED_ERROR])); + else + h.call(this, this[EMITTED_ERROR]); + } + return ret; + } + /** + * Alias for {@link Minipass#off} + */ + removeListener(ev, handler) { + return this.off(ev, handler); + } + /** + * Mostly identical to `EventEmitter.off` + * + * If a 'data' event handler is removed, and it was the last consumer + * (ie, there are no pipe destinations or other 'data' event listeners), + * then the flow of data will stop until there is another consumer or + * {@link Minipass#resume} is explicitly called. + */ + off(ev, handler) { + const ret = super.off(ev, handler); + // if we previously had listeners, and now we don't, and we don't + // have any pipes, then stop the flow, unless it's been explicitly + // put in a discarded flowing state via stream.resume(). + if (ev === 'data') { + this[DATALISTENERS] = this.listeners('data').length; + if (this[DATALISTENERS] === 0 && + !this[DISCARDED] && + !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * Mostly identical to `EventEmitter.removeAllListeners` + * + * If all 'data' event handlers are removed, and they were the last consumer + * (ie, there are no pipe destinations), then the flow of data will stop + * until there is another consumer or {@link Minipass#resume} is explicitly + * called. + */ + removeAllListeners(ev) { + const ret = super.removeAllListeners(ev); + if (ev === 'data' || ev === undefined) { + this[DATALISTENERS] = 0; + if (!this[DISCARDED] && !this[PIPES].length) { + this[FLOWING] = false; + } + } + return ret; + } + /** + * true if the 'end' event has been emitted + */ + get emittedEnd() { + return this[EMITTED_END]; + } + [MAYBE_EMIT_END]() { + if (!this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this[BUFFER].length === 0 && + this[EOF]) { + this[EMITTING_END] = true; + this.emit('end'); + this.emit('prefinish'); + this.emit('finish'); + if (this[CLOSED]) + this.emit('close'); + this[EMITTING_END] = false; + } + } + /** + * Mostly identical to `EventEmitter.emit`, with the following + * behavior differences to prevent data loss and unnecessary hangs: + * + * If the stream has been destroyed, and the event is something other + * than 'close' or 'error', then `false` is returned and no handlers + * are called. + * + * If the event is 'end', and has already been emitted, then the event + * is ignored. If the stream is in a paused or non-flowing state, then + * the event will be deferred until data flow resumes. If the stream is + * async, then handlers will be called on the next tick rather than + * immediately. + * + * If the event is 'close', and 'end' has not yet been emitted, then + * the event will be deferred until after 'end' is emitted. + * + * If the event is 'error', and an AbortSignal was provided for the stream, + * and there are no listeners, then the event is ignored, matching the + * behavior of node core streams in the presense of an AbortSignal. + * + * If the event is 'finish' or 'prefinish', then all listeners will be + * removed after emitting the event, to prevent double-firing. + */ + emit(ev, ...args) { + const data = args[0]; + // error and close are only events allowed after calling destroy() + if (ev !== 'error' && + ev !== 'close' && + ev !== DESTROYED && + this[DESTROYED]) { + return false; + } + else if (ev === 'data') { + return !this[OBJECTMODE] && !data + ? false + : this[ASYNC] + ? (defer(() => this[EMITDATA](data)), true) + : this[EMITDATA](data); + } + else if (ev === 'end') { + return this[EMITEND](); + } + else if (ev === 'close') { + this[CLOSED] = true; + // don't emit close before 'end' and 'finish' + if (!this[EMITTED_END] && !this[DESTROYED]) + return false; + const ret = super.emit('close'); + this.removeAllListeners('close'); + return ret; + } + else if (ev === 'error') { + this[EMITTED_ERROR] = data; + super.emit(ERROR, data); + const ret = !this[SIGNAL] || this.listeners('error').length + ? super.emit('error', data) + : false; + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'resume') { + const ret = super.emit('resume'); + this[MAYBE_EMIT_END](); + return ret; + } + else if (ev === 'finish' || ev === 'prefinish') { + const ret = super.emit(ev); + this.removeAllListeners(ev); + return ret; + } + // Some other unknown event + const ret = super.emit(ev, ...args); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITDATA](data) { + for (const p of this[PIPES]) { + if (p.dest.write(data) === false) + this.pause(); + } + const ret = this[DISCARDED] ? false : super.emit('data', data); + this[MAYBE_EMIT_END](); + return ret; + } + [EMITEND]() { + if (this[EMITTED_END]) + return false; + this[EMITTED_END] = true; + this.readable = false; + return this[ASYNC] + ? (defer(() => this[EMITEND2]()), true) + : this[EMITEND2](); + } + [EMITEND2]() { + if (this[DECODER]) { + const data = this[DECODER].end(); + if (data) { + for (const p of this[PIPES]) { + p.dest.write(data); + } + if (!this[DISCARDED]) + super.emit('data', data); + } + } + for (const p of this[PIPES]) { + p.end(); + } + const ret = super.emit('end'); + this.removeAllListeners('end'); + return ret; + } + /** + * Return a Promise that resolves to an array of all emitted data once + * the stream ends. + */ + async collect() { + const buf = Object.assign([], { + dataLength: 0, + }); + if (!this[OBJECTMODE]) + buf.dataLength = 0; + // set the promise first, in case an error is raised + // by triggering the flow here. + const p = this.promise(); + this.on('data', c => { + buf.push(c); + if (!this[OBJECTMODE]) + buf.dataLength += c.length; + }); + await p; + return buf; + } + /** + * Return a Promise that resolves to the concatenation of all emitted data + * once the stream ends. + * + * Not allowed on objectMode streams. + */ + async concat() { + if (this[OBJECTMODE]) { + throw new Error('cannot concat in objectMode'); + } + const buf = await this.collect(); + return (this[ENCODING] + ? buf.join('') + : Buffer.concat(buf, buf.dataLength)); + } + /** + * Return a void Promise that resolves once the stream ends. + */ + async promise() { + return new Promise((resolve, reject) => { + this.on(DESTROYED, () => reject(new Error('stream destroyed'))); + this.on('error', er => reject(er)); + this.on('end', () => resolve()); + }); + } + /** + * Asynchronous `for await of` iteration. + * + * This will continue emitting all chunks until the stream terminates. + */ + [Symbol.asyncIterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = async () => { + this.pause(); + stopped = true; + return { value: undefined, done: true }; + }; + const next = () => { + if (stopped) + return stop(); + const res = this.read(); + if (res !== null) + return Promise.resolve({ done: false, value: res }); + if (this[EOF]) + return stop(); + let resolve; + let reject; + const onerr = (er) => { + this.off('data', ondata); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + stop(); + reject(er); + }; + const ondata = (value) => { + this.off('error', onerr); + this.off('end', onend); + this.off(DESTROYED, ondestroy); + this.pause(); + resolve({ value, done: !!this[EOF] }); + }; + const onend = () => { + this.off('error', onerr); + this.off('data', ondata); + this.off(DESTROYED, ondestroy); + stop(); + resolve({ done: true, value: undefined }); + }; + const ondestroy = () => onerr(new Error('stream destroyed')); + return new Promise((res, rej) => { + reject = rej; + resolve = res; + this.once(DESTROYED, ondestroy); + this.once('error', onerr); + this.once('end', onend); + this.once('data', ondata); + }); + }; + return { + next, + throw: stop, + return: stop, + [Symbol.asyncIterator]() { + return this; + }, + }; + } + /** + * Synchronous `for of` iteration. + * + * The iteration will terminate when the internal buffer runs out, even + * if the stream has not yet terminated. + */ + [Symbol.iterator]() { + // set this up front, in case the consumer doesn't call next() + // right away. + this[DISCARDED] = false; + let stopped = false; + const stop = () => { + this.pause(); + this.off(ERROR, stop); + this.off(DESTROYED, stop); + this.off('end', stop); + stopped = true; + return { done: true, value: undefined }; + }; + const next = () => { + if (stopped) + return stop(); + const value = this.read(); + return value === null ? stop() : { done: false, value }; + }; + this.once('end', stop); + this.once(ERROR, stop); + this.once(DESTROYED, stop); + return { + next, + throw: stop, + return: stop, + [Symbol.iterator]() { + return this; + }, + }; + } + /** + * Destroy a stream, preventing it from being used for any further purpose. + * + * If the stream has a `close()` method, then it will be called on + * destruction. + * + * After destruction, any attempt to write data, read data, or emit most + * events will be ignored. + * + * If an error argument is provided, then it will be emitted in an + * 'error' event. + */ + destroy(er) { + if (this[DESTROYED]) { + if (er) + this.emit('error', er); + else + this.emit(DESTROYED); + return this; + } + this[DESTROYED] = true; + this[DISCARDED] = true; + // throw away all buffered data, it's never coming out + this[BUFFER].length = 0; + this[BUFFERLENGTH] = 0; + const wc = this; + if (typeof wc.close === 'function' && !this[CLOSED]) + wc.close(); + if (er) + this.emit('error', er); + // if no error to emit, still reject pending promises + else + this.emit(DESTROYED); + return this; + } + /** + * Alias for {@link isStream} + * + * Former export location, maintained for backwards compatibility. + * + * @deprecated + */ + static get isStream() { + return isStream; + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minipass/dist/esm/package.json b/node_modules/minipass/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/minipass/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/minipass/index.d.ts b/node_modules/minipass/index.d.ts deleted file mode 100644 index edbef54824801..0000000000000 --- a/node_modules/minipass/index.d.ts +++ /dev/null @@ -1,149 +0,0 @@ -/// <reference types="node" /> -import { EventEmitter } from 'events' -import { Stream } from 'stream' - -export type Encoding = BufferEncoding | 'buffer' | null - -interface Writable extends EventEmitter { - end(): any - write(chunk: any, ...args: any[]): any -} - -interface Readable extends EventEmitter { - pause(): any - resume(): any - pipe(): any -} - -interface Pipe<R, W> { - src: Minipass<R, W> - dest: Writable - opts: PipeOptions -} - -type DualIterable<T> = Iterable<T> & AsyncIterable<T> - -type ContiguousData = Buffer | ArrayBufferLike | ArrayBufferView | string - -type BufferOrString = Buffer | string - -export default class Minipass< - RType extends any = Buffer, - WType extends any = RType extends BufferOrString ? ContiguousData : RType - > - extends Stream - implements DualIterable<RType> -{ - static isStream(stream: any): stream is Readable | Writable - - readonly bufferLength: number - readonly flowing: boolean - readonly writable: boolean - readonly readable: boolean - readonly paused: boolean - readonly emittedEnd: boolean - readonly destroyed: boolean - - /** - * Not technically private or readonly, but not safe to mutate. - */ - private readonly buffer: RType[] - private readonly pipes: Pipe<RType, WType>[] - - /** - * Technically writable, but mutating it can change the type, - * so is not safe to do in TypeScript. - */ - readonly objectMode: boolean - async: boolean - - /** - * Note: encoding is not actually read-only, and setEncoding(enc) - * exists. However, this type definition will insist that TypeScript - * programs declare the type of a Minipass stream up front, and if - * that type is string, then an encoding MUST be set in the ctor. If - * the type is Buffer, then the encoding must be missing, or set to - * 'buffer' or null. If the type is anything else, then objectMode - * must be set in the constructor options. So there is effectively - * no allowed way that a TS program can set the encoding after - * construction, as doing so will destroy any hope of type safety. - * TypeScript does not provide many options for changing the type of - * an object at run-time, which is what changing the encoding does. - */ - readonly encoding: Encoding - // setEncoding(encoding: Encoding): void - - // Options required if not reading buffers - constructor( - ...args: RType extends Buffer - ? [] | [Options<RType>] - : [Options<RType>] - ) - - write(chunk: WType, cb?: () => void): boolean - write(chunk: WType, encoding?: Encoding, cb?: () => void): boolean - read(size?: number): RType - end(cb?: () => void): this - end(chunk: any, cb?: () => void): this - end(chunk: any, encoding?: Encoding, cb?: () => void): this - pause(): void - resume(): void - promise(): Promise<void> - collect(): Promise<RType[]> - - concat(): RType extends BufferOrString ? Promise<RType> : never - destroy(er?: any): void - pipe<W extends Writable>(dest: W, opts?: PipeOptions): W - unpipe<W extends Writable>(dest: W): void - - /** - * alias for on() - */ - addEventHandler(event: string, listener: (...args: any[]) => any): this - - on(event: string, listener: (...args: any[]) => any): this - on(event: 'data', listener: (chunk: RType) => any): this - on(event: 'error', listener: (error: any) => any): this - on( - event: - | 'readable' - | 'drain' - | 'resume' - | 'end' - | 'prefinish' - | 'finish' - | 'close', - listener: () => any - ): this - - [Symbol.iterator](): Iterator<RType> - [Symbol.asyncIterator](): AsyncIterator<RType> -} - -interface StringOptions { - encoding: BufferEncoding - objectMode?: boolean - async?: boolean -} - -interface BufferOptions { - encoding?: null | 'buffer' - objectMode?: boolean - async?: boolean -} - -interface ObjectModeOptions { - objectMode: true - async?: boolean -} - -export declare interface PipeOptions { - end?: boolean - proxyErrors?: boolean -} - -export declare type Options<T> = T extends string - ? StringOptions - : T extends Buffer - ? BufferOptions - : ObjectModeOptions diff --git a/node_modules/minipass/package.json b/node_modules/minipass/package.json index 47c90a4fcf4a7..771969b028546 100644 --- a/node_modules/minipass/package.json +++ b/node_modules/minipass/package.json @@ -1,49 +1,49 @@ { "name": "minipass", - "version": "3.3.4", + "version": "7.1.2", "description": "minimal implementation of a PassThrough stream", - "main": "index.js", - "dependencies": { - "yallist": "^4.0.0" + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "type": "module", + "tshy": { + "selfLink": false, + "main": true, + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } }, - "devDependencies": { - "@types/node": "^17.0.41", - "end-of-stream": "^1.4.0", - "prettier": "^2.6.2", - "tap": "^16.2.0", - "through2": "^2.0.3", - "ts-node": "^10.8.1", - "typescript": "^4.7.3" - }, - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish --tag=next", - "postpublish": "git push origin --follow-tags" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/minipass.git" + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } }, - "keywords": [ - "passthrough", - "stream" - ], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "license": "ISC", "files": [ - "index.d.ts", - "index.js" + "dist" ], - "tap": { - "check-coverage": true - }, - "engines": { - "node": ">=8" + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" }, "prettier": { "semi": false, - "printWidth": 80, + "printWidth": 75, "tabWidth": 2, "useTabs": false, "singleQuote": true, @@ -51,5 +51,32 @@ "bracketSameLine": true, "arrowParens": "avoid", "endOfLine": "lf" + }, + "devDependencies": { + "@types/end-of-stream": "^1.4.2", + "@types/node": "^20.1.2", + "end-of-stream": "^1.4.0", + "node-abort-controller": "^3.1.1", + "prettier": "^2.6.2", + "tap": "^19.0.0", + "through2": "^2.0.3", + "tshy": "^1.14.0", + "typedoc": "^0.25.1" + }, + "repository": "https://github.com/isaacs/minipass", + "keywords": [ + "passthrough", + "stream" + ], + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "tap": { + "typecheck": true, + "include": [ + "test/*.ts" + ] } } diff --git a/node_modules/minizlib/LICENSE b/node_modules/minizlib/LICENSE index ffce7383f53e7..49f7efe431c9e 100644 --- a/node_modules/minizlib/LICENSE +++ b/node_modules/minizlib/LICENSE @@ -2,9 +2,9 @@ Minizlib was created by Isaac Z. Schlueter. It is a derivative work of the Node.js project. """ -Copyright Isaac Z. Schlueter and Contributors -Copyright Node.js contributors. All rights reserved. -Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Copyright (c) 2017-2023 Isaac Z. Schlueter and Contributors +Copyright (c) 2017-2023 Node.js contributors. All rights reserved. +Copyright (c) 2017-2023 Joyent, Inc. and other Node contributors. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/node_modules/minizlib/constants.js b/node_modules/minizlib/constants.js deleted file mode 100644 index 641ebc73129bf..0000000000000 --- a/node_modules/minizlib/constants.js +++ /dev/null @@ -1,115 +0,0 @@ -// Update with any zlib constants that are added or changed in the future. -// Node v6 didn't export this, so we just hard code the version and rely -// on all the other hard-coded values from zlib v4736. When node v6 -// support drops, we can just export the realZlibConstants object. -const realZlibConstants = require('zlib').constants || - /* istanbul ignore next */ { ZLIB_VERNUM: 4736 } - -module.exports = Object.freeze(Object.assign(Object.create(null), { - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - Z_VERSION_ERROR: -6, - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - DEFLATE: 1, - INFLATE: 2, - GZIP: 3, - GUNZIP: 4, - DEFLATERAW: 5, - INFLATERAW: 6, - UNZIP: 7, - BROTLI_DECODE: 8, - BROTLI_ENCODE: 9, - Z_MIN_WINDOWBITS: 8, - Z_MAX_WINDOWBITS: 15, - Z_DEFAULT_WINDOWBITS: 15, - Z_MIN_CHUNK: 64, - Z_MAX_CHUNK: Infinity, - Z_DEFAULT_CHUNK: 16384, - Z_MIN_MEMLEVEL: 1, - Z_MAX_MEMLEVEL: 9, - Z_DEFAULT_MEMLEVEL: 8, - Z_MIN_LEVEL: -1, - Z_MAX_LEVEL: 9, - Z_DEFAULT_LEVEL: -1, - BROTLI_OPERATION_PROCESS: 0, - BROTLI_OPERATION_FLUSH: 1, - BROTLI_OPERATION_FINISH: 2, - BROTLI_OPERATION_EMIT_METADATA: 3, - BROTLI_MODE_GENERIC: 0, - BROTLI_MODE_TEXT: 1, - BROTLI_MODE_FONT: 2, - BROTLI_DEFAULT_MODE: 0, - BROTLI_MIN_QUALITY: 0, - BROTLI_MAX_QUALITY: 11, - BROTLI_DEFAULT_QUALITY: 11, - BROTLI_MIN_WINDOW_BITS: 10, - BROTLI_MAX_WINDOW_BITS: 24, - BROTLI_LARGE_MAX_WINDOW_BITS: 30, - BROTLI_DEFAULT_WINDOW: 22, - BROTLI_MIN_INPUT_BLOCK_BITS: 16, - BROTLI_MAX_INPUT_BLOCK_BITS: 24, - BROTLI_PARAM_MODE: 0, - BROTLI_PARAM_QUALITY: 1, - BROTLI_PARAM_LGWIN: 2, - BROTLI_PARAM_LGBLOCK: 3, - BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4, - BROTLI_PARAM_SIZE_HINT: 5, - BROTLI_PARAM_LARGE_WINDOW: 6, - BROTLI_PARAM_NPOSTFIX: 7, - BROTLI_PARAM_NDIRECT: 8, - BROTLI_DECODER_RESULT_ERROR: 0, - BROTLI_DECODER_RESULT_SUCCESS: 1, - BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2, - BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3, - BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0, - BROTLI_DECODER_PARAM_LARGE_WINDOW: 1, - BROTLI_DECODER_NO_ERROR: 0, - BROTLI_DECODER_SUCCESS: 1, - BROTLI_DECODER_NEEDS_MORE_INPUT: 2, - BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3, - BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1, - BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2, - BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3, - BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4, - BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5, - BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6, - BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7, - BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8, - BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9, - BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10, - BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11, - BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12, - BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13, - BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14, - BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15, - BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16, - BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19, - BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20, - BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21, - BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22, - BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25, - BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26, - BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27, - BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30, - BROTLI_DECODER_ERROR_UNREACHABLE: -31, -}, realZlibConstants)) diff --git a/node_modules/minizlib/dist/commonjs/constants.js b/node_modules/minizlib/dist/commonjs/constants.js new file mode 100644 index 0000000000000..dfc2c1957bfc9 --- /dev/null +++ b/node_modules/minizlib/dist/commonjs/constants.js @@ -0,0 +1,123 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.constants = void 0; +// Update with any zlib constants that are added or changed in the future. +// Node v6 didn't export this, so we just hard code the version and rely +// on all the other hard-coded values from zlib v4736. When node v6 +// support drops, we can just export the realZlibConstants object. +const zlib_1 = __importDefault(require("zlib")); +/* c8 ignore start */ +const realZlibConstants = zlib_1.default.constants || { ZLIB_VERNUM: 4736 }; +/* c8 ignore stop */ +exports.constants = Object.freeze(Object.assign(Object.create(null), { + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + Z_VERSION_ERROR: -6, + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + DEFLATE: 1, + INFLATE: 2, + GZIP: 3, + GUNZIP: 4, + DEFLATERAW: 5, + INFLATERAW: 6, + UNZIP: 7, + BROTLI_DECODE: 8, + BROTLI_ENCODE: 9, + Z_MIN_WINDOWBITS: 8, + Z_MAX_WINDOWBITS: 15, + Z_DEFAULT_WINDOWBITS: 15, + Z_MIN_CHUNK: 64, + Z_MAX_CHUNK: Infinity, + Z_DEFAULT_CHUNK: 16384, + Z_MIN_MEMLEVEL: 1, + Z_MAX_MEMLEVEL: 9, + Z_DEFAULT_MEMLEVEL: 8, + Z_MIN_LEVEL: -1, + Z_MAX_LEVEL: 9, + Z_DEFAULT_LEVEL: -1, + BROTLI_OPERATION_PROCESS: 0, + BROTLI_OPERATION_FLUSH: 1, + BROTLI_OPERATION_FINISH: 2, + BROTLI_OPERATION_EMIT_METADATA: 3, + BROTLI_MODE_GENERIC: 0, + BROTLI_MODE_TEXT: 1, + BROTLI_MODE_FONT: 2, + BROTLI_DEFAULT_MODE: 0, + BROTLI_MIN_QUALITY: 0, + BROTLI_MAX_QUALITY: 11, + BROTLI_DEFAULT_QUALITY: 11, + BROTLI_MIN_WINDOW_BITS: 10, + BROTLI_MAX_WINDOW_BITS: 24, + BROTLI_LARGE_MAX_WINDOW_BITS: 30, + BROTLI_DEFAULT_WINDOW: 22, + BROTLI_MIN_INPUT_BLOCK_BITS: 16, + BROTLI_MAX_INPUT_BLOCK_BITS: 24, + BROTLI_PARAM_MODE: 0, + BROTLI_PARAM_QUALITY: 1, + BROTLI_PARAM_LGWIN: 2, + BROTLI_PARAM_LGBLOCK: 3, + BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4, + BROTLI_PARAM_SIZE_HINT: 5, + BROTLI_PARAM_LARGE_WINDOW: 6, + BROTLI_PARAM_NPOSTFIX: 7, + BROTLI_PARAM_NDIRECT: 8, + BROTLI_DECODER_RESULT_ERROR: 0, + BROTLI_DECODER_RESULT_SUCCESS: 1, + BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2, + BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3, + BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0, + BROTLI_DECODER_PARAM_LARGE_WINDOW: 1, + BROTLI_DECODER_NO_ERROR: 0, + BROTLI_DECODER_SUCCESS: 1, + BROTLI_DECODER_NEEDS_MORE_INPUT: 2, + BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3, + BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1, + BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2, + BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3, + BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4, + BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5, + BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6, + BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7, + BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8, + BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9, + BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10, + BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11, + BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12, + BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13, + BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14, + BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15, + BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16, + BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19, + BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20, + BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21, + BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22, + BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25, + BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26, + BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27, + BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30, + BROTLI_DECODER_ERROR_UNREACHABLE: -31, +}, realZlibConstants)); +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/node_modules/minizlib/dist/commonjs/index.js b/node_modules/minizlib/dist/commonjs/index.js new file mode 100644 index 0000000000000..78c6536baf6be --- /dev/null +++ b/node_modules/minizlib/dist/commonjs/index.js @@ -0,0 +1,416 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ZstdDecompress = exports.ZstdCompress = exports.BrotliDecompress = exports.BrotliCompress = exports.Unzip = exports.InflateRaw = exports.DeflateRaw = exports.Gunzip = exports.Gzip = exports.Inflate = exports.Deflate = exports.Zlib = exports.ZlibError = exports.constants = void 0; +const assert_1 = __importDefault(require("assert")); +const buffer_1 = require("buffer"); +const minipass_1 = require("minipass"); +const realZlib = __importStar(require("zlib")); +const constants_js_1 = require("./constants.js"); +var constants_js_2 = require("./constants.js"); +Object.defineProperty(exports, "constants", { enumerable: true, get: function () { return constants_js_2.constants; } }); +const OriginalBufferConcat = buffer_1.Buffer.concat; +const desc = Object.getOwnPropertyDescriptor(buffer_1.Buffer, 'concat'); +const noop = (args) => args; +const passthroughBufferConcat = desc?.writable === true || desc?.set !== undefined + ? (makeNoOp) => { + buffer_1.Buffer.concat = makeNoOp ? noop : OriginalBufferConcat; + } + : (_) => { }; +const _superWrite = Symbol('_superWrite'); +class ZlibError extends Error { + code; + errno; + constructor(err, origin) { + super('zlib: ' + err.message, { cause: err }); + this.code = err.code; + this.errno = err.errno; + /* c8 ignore next */ + if (!this.code) + this.code = 'ZLIB_ERROR'; + this.message = 'zlib: ' + err.message; + Error.captureStackTrace(this, origin ?? this.constructor); + } + get name() { + return 'ZlibError'; + } +} +exports.ZlibError = ZlibError; +// the Zlib class they all inherit from +// This thing manages the queue of requests, and returns +// true or false if there is anything in the queue when +// you call the .write() method. +const _flushFlag = Symbol('flushFlag'); +class ZlibBase extends minipass_1.Minipass { + #sawError = false; + #ended = false; + #flushFlag; + #finishFlushFlag; + #fullFlushFlag; + #handle; + #onError; + get sawError() { + return this.#sawError; + } + get handle() { + return this.#handle; + } + /* c8 ignore start */ + get flushFlag() { + return this.#flushFlag; + } + /* c8 ignore stop */ + constructor(opts, mode) { + if (!opts || typeof opts !== 'object') + throw new TypeError('invalid options for ZlibBase constructor'); + //@ts-ignore + super(opts); + /* c8 ignore start */ + this.#flushFlag = opts.flush ?? 0; + this.#finishFlushFlag = opts.finishFlush ?? 0; + this.#fullFlushFlag = opts.fullFlushFlag ?? 0; + /* c8 ignore stop */ + //@ts-ignore + if (typeof realZlib[mode] !== 'function') { + throw new TypeError('Compression method not supported: ' + mode); + } + // this will throw if any options are invalid for the class selected + try { + // @types/node doesn't know that it exports the classes, but they're there + //@ts-ignore + this.#handle = new realZlib[mode](opts); + } + catch (er) { + // make sure that all errors get decorated properly + throw new ZlibError(er, this.constructor); + } + this.#onError = err => { + // no sense raising multiple errors, since we abort on the first one. + if (this.#sawError) + return; + this.#sawError = true; + // there is no way to cleanly recover. + // continuing only obscures problems. + this.close(); + this.emit('error', err); + }; + this.#handle?.on('error', er => this.#onError(new ZlibError(er))); + this.once('end', () => this.close); + } + close() { + if (this.#handle) { + this.#handle.close(); + this.#handle = undefined; + this.emit('close'); + } + } + reset() { + if (!this.#sawError) { + (0, assert_1.default)(this.#handle, 'zlib binding closed'); + //@ts-ignore + return this.#handle.reset?.(); + } + } + flush(flushFlag) { + if (this.ended) + return; + if (typeof flushFlag !== 'number') + flushFlag = this.#fullFlushFlag; + this.write(Object.assign(buffer_1.Buffer.alloc(0), { [_flushFlag]: flushFlag })); + } + end(chunk, encoding, cb) { + /* c8 ignore start */ + if (typeof chunk === 'function') { + cb = chunk; + encoding = undefined; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + /* c8 ignore stop */ + if (chunk) { + if (encoding) + this.write(chunk, encoding); + else + this.write(chunk); + } + this.flush(this.#finishFlushFlag); + this.#ended = true; + return super.end(cb); + } + get ended() { + return this.#ended; + } + // overridden in the gzip classes to do portable writes + [_superWrite](data) { + return super.write(data); + } + write(chunk, encoding, cb) { + // process the chunk using the sync process + // then super.write() all the outputted chunks + if (typeof encoding === 'function') + (cb = encoding), (encoding = 'utf8'); + if (typeof chunk === 'string') + chunk = buffer_1.Buffer.from(chunk, encoding); + if (this.#sawError) + return; + (0, assert_1.default)(this.#handle, 'zlib binding closed'); + // _processChunk tries to .close() the native handle after it's done, so we + // intercept that by temporarily making it a no-op. + // diving into the node:zlib internals a bit here + const nativeHandle = this.#handle + ._handle; + const originalNativeClose = nativeHandle.close; + nativeHandle.close = () => { }; + const originalClose = this.#handle.close; + this.#handle.close = () => { }; + // It also calls `Buffer.concat()` at the end, which may be convenient + // for some, but which we are not interested in as it slows us down. + passthroughBufferConcat(true); + let result = undefined; + try { + const flushFlag = typeof chunk[_flushFlag] === 'number' + ? chunk[_flushFlag] + : this.#flushFlag; + result = this.#handle._processChunk(chunk, flushFlag); + // if we don't throw, reset it back how it was + passthroughBufferConcat(false); + } + catch (err) { + // or if we do, put Buffer.concat() back before we emit error + // Error events call into user code, which may call Buffer.concat() + passthroughBufferConcat(false); + this.#onError(new ZlibError(err, this.write)); + } + finally { + if (this.#handle) { + // Core zlib resets `_handle` to null after attempting to close the + // native handle. Our no-op handler prevented actual closure, but we + // need to restore the `._handle` property. + ; + this.#handle._handle = + nativeHandle; + nativeHandle.close = originalNativeClose; + this.#handle.close = originalClose; + // `_processChunk()` adds an 'error' listener. If we don't remove it + // after each call, these handlers start piling up. + this.#handle.removeAllListeners('error'); + // make sure OUR error listener is still attached tho + } + } + if (this.#handle) + this.#handle.on('error', er => this.#onError(new ZlibError(er, this.write))); + let writeReturn; + if (result) { + if (Array.isArray(result) && result.length > 0) { + const r = result[0]; + // The first buffer is always `handle._outBuffer`, which would be + // re-used for later invocations; so, we always have to copy that one. + writeReturn = this[_superWrite](buffer_1.Buffer.from(r)); + for (let i = 1; i < result.length; i++) { + writeReturn = this[_superWrite](result[i]); + } + } + else { + // either a single Buffer or an empty array + writeReturn = this[_superWrite](buffer_1.Buffer.from(result)); + } + } + if (cb) + cb(); + return writeReturn; + } +} +class Zlib extends ZlibBase { + #level; + #strategy; + constructor(opts, mode) { + opts = opts || {}; + opts.flush = opts.flush || constants_js_1.constants.Z_NO_FLUSH; + opts.finishFlush = opts.finishFlush || constants_js_1.constants.Z_FINISH; + opts.fullFlushFlag = constants_js_1.constants.Z_FULL_FLUSH; + super(opts, mode); + this.#level = opts.level; + this.#strategy = opts.strategy; + } + params(level, strategy) { + if (this.sawError) + return; + if (!this.handle) + throw new Error('cannot switch params when binding is closed'); + // no way to test this without also not supporting params at all + /* c8 ignore start */ + if (!this.handle.params) + throw new Error('not supported in this implementation'); + /* c8 ignore stop */ + if (this.#level !== level || this.#strategy !== strategy) { + this.flush(constants_js_1.constants.Z_SYNC_FLUSH); + (0, assert_1.default)(this.handle, 'zlib binding closed'); + // .params() calls .flush(), but the latter is always async in the + // core zlib. We override .flush() temporarily to intercept that and + // flush synchronously. + const origFlush = this.handle.flush; + this.handle.flush = (flushFlag, cb) => { + /* c8 ignore start */ + if (typeof flushFlag === 'function') { + cb = flushFlag; + flushFlag = this.flushFlag; + } + /* c8 ignore stop */ + this.flush(flushFlag); + cb?.(); + }; + try { + ; + this.handle.params(level, strategy); + } + finally { + this.handle.flush = origFlush; + } + /* c8 ignore start */ + if (this.handle) { + this.#level = level; + this.#strategy = strategy; + } + /* c8 ignore stop */ + } + } +} +exports.Zlib = Zlib; +// minimal 2-byte header +class Deflate extends Zlib { + constructor(opts) { + super(opts, 'Deflate'); + } +} +exports.Deflate = Deflate; +class Inflate extends Zlib { + constructor(opts) { + super(opts, 'Inflate'); + } +} +exports.Inflate = Inflate; +class Gzip extends Zlib { + #portable; + constructor(opts) { + super(opts, 'Gzip'); + this.#portable = opts && !!opts.portable; + } + [_superWrite](data) { + if (!this.#portable) + return super[_superWrite](data); + // we'll always get the header emitted in one first chunk + // overwrite the OS indicator byte with 0xFF + this.#portable = false; + data[9] = 255; + return super[_superWrite](data); + } +} +exports.Gzip = Gzip; +class Gunzip extends Zlib { + constructor(opts) { + super(opts, 'Gunzip'); + } +} +exports.Gunzip = Gunzip; +// raw - no header +class DeflateRaw extends Zlib { + constructor(opts) { + super(opts, 'DeflateRaw'); + } +} +exports.DeflateRaw = DeflateRaw; +class InflateRaw extends Zlib { + constructor(opts) { + super(opts, 'InflateRaw'); + } +} +exports.InflateRaw = InflateRaw; +// auto-detect header. +class Unzip extends Zlib { + constructor(opts) { + super(opts, 'Unzip'); + } +} +exports.Unzip = Unzip; +class Brotli extends ZlibBase { + constructor(opts, mode) { + opts = opts || {}; + opts.flush = opts.flush || constants_js_1.constants.BROTLI_OPERATION_PROCESS; + opts.finishFlush = + opts.finishFlush || constants_js_1.constants.BROTLI_OPERATION_FINISH; + opts.fullFlushFlag = constants_js_1.constants.BROTLI_OPERATION_FLUSH; + super(opts, mode); + } +} +class BrotliCompress extends Brotli { + constructor(opts) { + super(opts, 'BrotliCompress'); + } +} +exports.BrotliCompress = BrotliCompress; +class BrotliDecompress extends Brotli { + constructor(opts) { + super(opts, 'BrotliDecompress'); + } +} +exports.BrotliDecompress = BrotliDecompress; +class Zstd extends ZlibBase { + constructor(opts, mode) { + opts = opts || {}; + opts.flush = opts.flush || constants_js_1.constants.ZSTD_e_continue; + opts.finishFlush = opts.finishFlush || constants_js_1.constants.ZSTD_e_end; + opts.fullFlushFlag = constants_js_1.constants.ZSTD_e_flush; + super(opts, mode); + } +} +class ZstdCompress extends Zstd { + constructor(opts) { + super(opts, 'ZstdCompress'); + } +} +exports.ZstdCompress = ZstdCompress; +class ZstdDecompress extends Zstd { + constructor(opts) { + super(opts, 'ZstdDecompress'); + } +} +exports.ZstdDecompress = ZstdDecompress; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minizlib/dist/commonjs/package.json b/node_modules/minizlib/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/minizlib/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/minizlib/dist/esm/constants.js b/node_modules/minizlib/dist/esm/constants.js new file mode 100644 index 0000000000000..7faf40be5068d --- /dev/null +++ b/node_modules/minizlib/dist/esm/constants.js @@ -0,0 +1,117 @@ +// Update with any zlib constants that are added or changed in the future. +// Node v6 didn't export this, so we just hard code the version and rely +// on all the other hard-coded values from zlib v4736. When node v6 +// support drops, we can just export the realZlibConstants object. +import realZlib from 'zlib'; +/* c8 ignore start */ +const realZlibConstants = realZlib.constants || { ZLIB_VERNUM: 4736 }; +/* c8 ignore stop */ +export const constants = Object.freeze(Object.assign(Object.create(null), { + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + Z_VERSION_ERROR: -6, + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + DEFLATE: 1, + INFLATE: 2, + GZIP: 3, + GUNZIP: 4, + DEFLATERAW: 5, + INFLATERAW: 6, + UNZIP: 7, + BROTLI_DECODE: 8, + BROTLI_ENCODE: 9, + Z_MIN_WINDOWBITS: 8, + Z_MAX_WINDOWBITS: 15, + Z_DEFAULT_WINDOWBITS: 15, + Z_MIN_CHUNK: 64, + Z_MAX_CHUNK: Infinity, + Z_DEFAULT_CHUNK: 16384, + Z_MIN_MEMLEVEL: 1, + Z_MAX_MEMLEVEL: 9, + Z_DEFAULT_MEMLEVEL: 8, + Z_MIN_LEVEL: -1, + Z_MAX_LEVEL: 9, + Z_DEFAULT_LEVEL: -1, + BROTLI_OPERATION_PROCESS: 0, + BROTLI_OPERATION_FLUSH: 1, + BROTLI_OPERATION_FINISH: 2, + BROTLI_OPERATION_EMIT_METADATA: 3, + BROTLI_MODE_GENERIC: 0, + BROTLI_MODE_TEXT: 1, + BROTLI_MODE_FONT: 2, + BROTLI_DEFAULT_MODE: 0, + BROTLI_MIN_QUALITY: 0, + BROTLI_MAX_QUALITY: 11, + BROTLI_DEFAULT_QUALITY: 11, + BROTLI_MIN_WINDOW_BITS: 10, + BROTLI_MAX_WINDOW_BITS: 24, + BROTLI_LARGE_MAX_WINDOW_BITS: 30, + BROTLI_DEFAULT_WINDOW: 22, + BROTLI_MIN_INPUT_BLOCK_BITS: 16, + BROTLI_MAX_INPUT_BLOCK_BITS: 24, + BROTLI_PARAM_MODE: 0, + BROTLI_PARAM_QUALITY: 1, + BROTLI_PARAM_LGWIN: 2, + BROTLI_PARAM_LGBLOCK: 3, + BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: 4, + BROTLI_PARAM_SIZE_HINT: 5, + BROTLI_PARAM_LARGE_WINDOW: 6, + BROTLI_PARAM_NPOSTFIX: 7, + BROTLI_PARAM_NDIRECT: 8, + BROTLI_DECODER_RESULT_ERROR: 0, + BROTLI_DECODER_RESULT_SUCCESS: 1, + BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: 2, + BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: 3, + BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: 0, + BROTLI_DECODER_PARAM_LARGE_WINDOW: 1, + BROTLI_DECODER_NO_ERROR: 0, + BROTLI_DECODER_SUCCESS: 1, + BROTLI_DECODER_NEEDS_MORE_INPUT: 2, + BROTLI_DECODER_NEEDS_MORE_OUTPUT: 3, + BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE: -1, + BROTLI_DECODER_ERROR_FORMAT_RESERVED: -2, + BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE: -3, + BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET: -4, + BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME: -5, + BROTLI_DECODER_ERROR_FORMAT_CL_SPACE: -6, + BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE: -7, + BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT: -8, + BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1: -9, + BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2: -10, + BROTLI_DECODER_ERROR_FORMAT_TRANSFORM: -11, + BROTLI_DECODER_ERROR_FORMAT_DICTIONARY: -12, + BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS: -13, + BROTLI_DECODER_ERROR_FORMAT_PADDING_1: -14, + BROTLI_DECODER_ERROR_FORMAT_PADDING_2: -15, + BROTLI_DECODER_ERROR_FORMAT_DISTANCE: -16, + BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET: -19, + BROTLI_DECODER_ERROR_INVALID_ARGUMENTS: -20, + BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES: -21, + BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS: -22, + BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP: -25, + BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1: -26, + BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2: -27, + BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES: -30, + BROTLI_DECODER_ERROR_UNREACHABLE: -31, +}, realZlibConstants)); +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/node_modules/minizlib/dist/esm/index.js b/node_modules/minizlib/dist/esm/index.js new file mode 100644 index 0000000000000..b70ba1f2cd84f --- /dev/null +++ b/node_modules/minizlib/dist/esm/index.js @@ -0,0 +1,363 @@ +import assert from 'assert'; +import { Buffer } from 'buffer'; +import { Minipass } from 'minipass'; +import * as realZlib from 'zlib'; +import { constants } from './constants.js'; +export { constants } from './constants.js'; +const OriginalBufferConcat = Buffer.concat; +const desc = Object.getOwnPropertyDescriptor(Buffer, 'concat'); +const noop = (args) => args; +const passthroughBufferConcat = desc?.writable === true || desc?.set !== undefined + ? (makeNoOp) => { + Buffer.concat = makeNoOp ? noop : OriginalBufferConcat; + } + : (_) => { }; +const _superWrite = Symbol('_superWrite'); +export class ZlibError extends Error { + code; + errno; + constructor(err, origin) { + super('zlib: ' + err.message, { cause: err }); + this.code = err.code; + this.errno = err.errno; + /* c8 ignore next */ + if (!this.code) + this.code = 'ZLIB_ERROR'; + this.message = 'zlib: ' + err.message; + Error.captureStackTrace(this, origin ?? this.constructor); + } + get name() { + return 'ZlibError'; + } +} +// the Zlib class they all inherit from +// This thing manages the queue of requests, and returns +// true or false if there is anything in the queue when +// you call the .write() method. +const _flushFlag = Symbol('flushFlag'); +class ZlibBase extends Minipass { + #sawError = false; + #ended = false; + #flushFlag; + #finishFlushFlag; + #fullFlushFlag; + #handle; + #onError; + get sawError() { + return this.#sawError; + } + get handle() { + return this.#handle; + } + /* c8 ignore start */ + get flushFlag() { + return this.#flushFlag; + } + /* c8 ignore stop */ + constructor(opts, mode) { + if (!opts || typeof opts !== 'object') + throw new TypeError('invalid options for ZlibBase constructor'); + //@ts-ignore + super(opts); + /* c8 ignore start */ + this.#flushFlag = opts.flush ?? 0; + this.#finishFlushFlag = opts.finishFlush ?? 0; + this.#fullFlushFlag = opts.fullFlushFlag ?? 0; + /* c8 ignore stop */ + //@ts-ignore + if (typeof realZlib[mode] !== 'function') { + throw new TypeError('Compression method not supported: ' + mode); + } + // this will throw if any options are invalid for the class selected + try { + // @types/node doesn't know that it exports the classes, but they're there + //@ts-ignore + this.#handle = new realZlib[mode](opts); + } + catch (er) { + // make sure that all errors get decorated properly + throw new ZlibError(er, this.constructor); + } + this.#onError = err => { + // no sense raising multiple errors, since we abort on the first one. + if (this.#sawError) + return; + this.#sawError = true; + // there is no way to cleanly recover. + // continuing only obscures problems. + this.close(); + this.emit('error', err); + }; + this.#handle?.on('error', er => this.#onError(new ZlibError(er))); + this.once('end', () => this.close); + } + close() { + if (this.#handle) { + this.#handle.close(); + this.#handle = undefined; + this.emit('close'); + } + } + reset() { + if (!this.#sawError) { + assert(this.#handle, 'zlib binding closed'); + //@ts-ignore + return this.#handle.reset?.(); + } + } + flush(flushFlag) { + if (this.ended) + return; + if (typeof flushFlag !== 'number') + flushFlag = this.#fullFlushFlag; + this.write(Object.assign(Buffer.alloc(0), { [_flushFlag]: flushFlag })); + } + end(chunk, encoding, cb) { + /* c8 ignore start */ + if (typeof chunk === 'function') { + cb = chunk; + encoding = undefined; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + /* c8 ignore stop */ + if (chunk) { + if (encoding) + this.write(chunk, encoding); + else + this.write(chunk); + } + this.flush(this.#finishFlushFlag); + this.#ended = true; + return super.end(cb); + } + get ended() { + return this.#ended; + } + // overridden in the gzip classes to do portable writes + [_superWrite](data) { + return super.write(data); + } + write(chunk, encoding, cb) { + // process the chunk using the sync process + // then super.write() all the outputted chunks + if (typeof encoding === 'function') + (cb = encoding), (encoding = 'utf8'); + if (typeof chunk === 'string') + chunk = Buffer.from(chunk, encoding); + if (this.#sawError) + return; + assert(this.#handle, 'zlib binding closed'); + // _processChunk tries to .close() the native handle after it's done, so we + // intercept that by temporarily making it a no-op. + // diving into the node:zlib internals a bit here + const nativeHandle = this.#handle + ._handle; + const originalNativeClose = nativeHandle.close; + nativeHandle.close = () => { }; + const originalClose = this.#handle.close; + this.#handle.close = () => { }; + // It also calls `Buffer.concat()` at the end, which may be convenient + // for some, but which we are not interested in as it slows us down. + passthroughBufferConcat(true); + let result = undefined; + try { + const flushFlag = typeof chunk[_flushFlag] === 'number' + ? chunk[_flushFlag] + : this.#flushFlag; + result = this.#handle._processChunk(chunk, flushFlag); + // if we don't throw, reset it back how it was + passthroughBufferConcat(false); + } + catch (err) { + // or if we do, put Buffer.concat() back before we emit error + // Error events call into user code, which may call Buffer.concat() + passthroughBufferConcat(false); + this.#onError(new ZlibError(err, this.write)); + } + finally { + if (this.#handle) { + // Core zlib resets `_handle` to null after attempting to close the + // native handle. Our no-op handler prevented actual closure, but we + // need to restore the `._handle` property. + ; + this.#handle._handle = + nativeHandle; + nativeHandle.close = originalNativeClose; + this.#handle.close = originalClose; + // `_processChunk()` adds an 'error' listener. If we don't remove it + // after each call, these handlers start piling up. + this.#handle.removeAllListeners('error'); + // make sure OUR error listener is still attached tho + } + } + if (this.#handle) + this.#handle.on('error', er => this.#onError(new ZlibError(er, this.write))); + let writeReturn; + if (result) { + if (Array.isArray(result) && result.length > 0) { + const r = result[0]; + // The first buffer is always `handle._outBuffer`, which would be + // re-used for later invocations; so, we always have to copy that one. + writeReturn = this[_superWrite](Buffer.from(r)); + for (let i = 1; i < result.length; i++) { + writeReturn = this[_superWrite](result[i]); + } + } + else { + // either a single Buffer or an empty array + writeReturn = this[_superWrite](Buffer.from(result)); + } + } + if (cb) + cb(); + return writeReturn; + } +} +export class Zlib extends ZlibBase { + #level; + #strategy; + constructor(opts, mode) { + opts = opts || {}; + opts.flush = opts.flush || constants.Z_NO_FLUSH; + opts.finishFlush = opts.finishFlush || constants.Z_FINISH; + opts.fullFlushFlag = constants.Z_FULL_FLUSH; + super(opts, mode); + this.#level = opts.level; + this.#strategy = opts.strategy; + } + params(level, strategy) { + if (this.sawError) + return; + if (!this.handle) + throw new Error('cannot switch params when binding is closed'); + // no way to test this without also not supporting params at all + /* c8 ignore start */ + if (!this.handle.params) + throw new Error('not supported in this implementation'); + /* c8 ignore stop */ + if (this.#level !== level || this.#strategy !== strategy) { + this.flush(constants.Z_SYNC_FLUSH); + assert(this.handle, 'zlib binding closed'); + // .params() calls .flush(), but the latter is always async in the + // core zlib. We override .flush() temporarily to intercept that and + // flush synchronously. + const origFlush = this.handle.flush; + this.handle.flush = (flushFlag, cb) => { + /* c8 ignore start */ + if (typeof flushFlag === 'function') { + cb = flushFlag; + flushFlag = this.flushFlag; + } + /* c8 ignore stop */ + this.flush(flushFlag); + cb?.(); + }; + try { + ; + this.handle.params(level, strategy); + } + finally { + this.handle.flush = origFlush; + } + /* c8 ignore start */ + if (this.handle) { + this.#level = level; + this.#strategy = strategy; + } + /* c8 ignore stop */ + } + } +} +// minimal 2-byte header +export class Deflate extends Zlib { + constructor(opts) { + super(opts, 'Deflate'); + } +} +export class Inflate extends Zlib { + constructor(opts) { + super(opts, 'Inflate'); + } +} +export class Gzip extends Zlib { + #portable; + constructor(opts) { + super(opts, 'Gzip'); + this.#portable = opts && !!opts.portable; + } + [_superWrite](data) { + if (!this.#portable) + return super[_superWrite](data); + // we'll always get the header emitted in one first chunk + // overwrite the OS indicator byte with 0xFF + this.#portable = false; + data[9] = 255; + return super[_superWrite](data); + } +} +export class Gunzip extends Zlib { + constructor(opts) { + super(opts, 'Gunzip'); + } +} +// raw - no header +export class DeflateRaw extends Zlib { + constructor(opts) { + super(opts, 'DeflateRaw'); + } +} +export class InflateRaw extends Zlib { + constructor(opts) { + super(opts, 'InflateRaw'); + } +} +// auto-detect header. +export class Unzip extends Zlib { + constructor(opts) { + super(opts, 'Unzip'); + } +} +class Brotli extends ZlibBase { + constructor(opts, mode) { + opts = opts || {}; + opts.flush = opts.flush || constants.BROTLI_OPERATION_PROCESS; + opts.finishFlush = + opts.finishFlush || constants.BROTLI_OPERATION_FINISH; + opts.fullFlushFlag = constants.BROTLI_OPERATION_FLUSH; + super(opts, mode); + } +} +export class BrotliCompress extends Brotli { + constructor(opts) { + super(opts, 'BrotliCompress'); + } +} +export class BrotliDecompress extends Brotli { + constructor(opts) { + super(opts, 'BrotliDecompress'); + } +} +class Zstd extends ZlibBase { + constructor(opts, mode) { + opts = opts || {}; + opts.flush = opts.flush || constants.ZSTD_e_continue; + opts.finishFlush = opts.finishFlush || constants.ZSTD_e_end; + opts.fullFlushFlag = constants.ZSTD_e_flush; + super(opts, mode); + } +} +export class ZstdCompress extends Zstd { + constructor(opts) { + super(opts, 'ZstdCompress'); + } +} +export class ZstdDecompress extends Zstd { + constructor(opts) { + super(opts, 'ZstdDecompress'); + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/minizlib/dist/esm/package.json b/node_modules/minizlib/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/minizlib/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/minizlib/index.js b/node_modules/minizlib/index.js deleted file mode 100644 index fbaf69e19f209..0000000000000 --- a/node_modules/minizlib/index.js +++ /dev/null @@ -1,348 +0,0 @@ -'use strict' - -const assert = require('assert') -const Buffer = require('buffer').Buffer -const realZlib = require('zlib') - -const constants = exports.constants = require('./constants.js') -const Minipass = require('minipass') - -const OriginalBufferConcat = Buffer.concat - -const _superWrite = Symbol('_superWrite') -class ZlibError extends Error { - constructor (err) { - super('zlib: ' + err.message) - this.code = err.code - this.errno = err.errno - /* istanbul ignore if */ - if (!this.code) - this.code = 'ZLIB_ERROR' - - this.message = 'zlib: ' + err.message - Error.captureStackTrace(this, this.constructor) - } - - get name () { - return 'ZlibError' - } -} - -// the Zlib class they all inherit from -// This thing manages the queue of requests, and returns -// true or false if there is anything in the queue when -// you call the .write() method. -const _opts = Symbol('opts') -const _flushFlag = Symbol('flushFlag') -const _finishFlushFlag = Symbol('finishFlushFlag') -const _fullFlushFlag = Symbol('fullFlushFlag') -const _handle = Symbol('handle') -const _onError = Symbol('onError') -const _sawError = Symbol('sawError') -const _level = Symbol('level') -const _strategy = Symbol('strategy') -const _ended = Symbol('ended') -const _defaultFullFlush = Symbol('_defaultFullFlush') - -class ZlibBase extends Minipass { - constructor (opts, mode) { - if (!opts || typeof opts !== 'object') - throw new TypeError('invalid options for ZlibBase constructor') - - super(opts) - this[_sawError] = false - this[_ended] = false - this[_opts] = opts - - this[_flushFlag] = opts.flush - this[_finishFlushFlag] = opts.finishFlush - // this will throw if any options are invalid for the class selected - try { - this[_handle] = new realZlib[mode](opts) - } catch (er) { - // make sure that all errors get decorated properly - throw new ZlibError(er) - } - - this[_onError] = (err) => { - // no sense raising multiple errors, since we abort on the first one. - if (this[_sawError]) - return - - this[_sawError] = true - - // there is no way to cleanly recover. - // continuing only obscures problems. - this.close() - this.emit('error', err) - } - - this[_handle].on('error', er => this[_onError](new ZlibError(er))) - this.once('end', () => this.close) - } - - close () { - if (this[_handle]) { - this[_handle].close() - this[_handle] = null - this.emit('close') - } - } - - reset () { - if (!this[_sawError]) { - assert(this[_handle], 'zlib binding closed') - return this[_handle].reset() - } - } - - flush (flushFlag) { - if (this.ended) - return - - if (typeof flushFlag !== 'number') - flushFlag = this[_fullFlushFlag] - this.write(Object.assign(Buffer.alloc(0), { [_flushFlag]: flushFlag })) - } - - end (chunk, encoding, cb) { - if (chunk) - this.write(chunk, encoding) - this.flush(this[_finishFlushFlag]) - this[_ended] = true - return super.end(null, null, cb) - } - - get ended () { - return this[_ended] - } - - write (chunk, encoding, cb) { - // process the chunk using the sync process - // then super.write() all the outputted chunks - if (typeof encoding === 'function') - cb = encoding, encoding = 'utf8' - - if (typeof chunk === 'string') - chunk = Buffer.from(chunk, encoding) - - if (this[_sawError]) - return - assert(this[_handle], 'zlib binding closed') - - // _processChunk tries to .close() the native handle after it's done, so we - // intercept that by temporarily making it a no-op. - const nativeHandle = this[_handle]._handle - const originalNativeClose = nativeHandle.close - nativeHandle.close = () => {} - const originalClose = this[_handle].close - this[_handle].close = () => {} - // It also calls `Buffer.concat()` at the end, which may be convenient - // for some, but which we are not interested in as it slows us down. - Buffer.concat = (args) => args - let result - try { - const flushFlag = typeof chunk[_flushFlag] === 'number' - ? chunk[_flushFlag] : this[_flushFlag] - result = this[_handle]._processChunk(chunk, flushFlag) - // if we don't throw, reset it back how it was - Buffer.concat = OriginalBufferConcat - } catch (err) { - // or if we do, put Buffer.concat() back before we emit error - // Error events call into user code, which may call Buffer.concat() - Buffer.concat = OriginalBufferConcat - this[_onError](new ZlibError(err)) - } finally { - if (this[_handle]) { - // Core zlib resets `_handle` to null after attempting to close the - // native handle. Our no-op handler prevented actual closure, but we - // need to restore the `._handle` property. - this[_handle]._handle = nativeHandle - nativeHandle.close = originalNativeClose - this[_handle].close = originalClose - // `_processChunk()` adds an 'error' listener. If we don't remove it - // after each call, these handlers start piling up. - this[_handle].removeAllListeners('error') - // make sure OUR error listener is still attached tho - } - } - - if (this[_handle]) - this[_handle].on('error', er => this[_onError](new ZlibError(er))) - - let writeReturn - if (result) { - if (Array.isArray(result) && result.length > 0) { - // The first buffer is always `handle._outBuffer`, which would be - // re-used for later invocations; so, we always have to copy that one. - writeReturn = this[_superWrite](Buffer.from(result[0])) - for (let i = 1; i < result.length; i++) { - writeReturn = this[_superWrite](result[i]) - } - } else { - writeReturn = this[_superWrite](Buffer.from(result)) - } - } - - if (cb) - cb() - return writeReturn - } - - [_superWrite] (data) { - return super.write(data) - } -} - -class Zlib extends ZlibBase { - constructor (opts, mode) { - opts = opts || {} - - opts.flush = opts.flush || constants.Z_NO_FLUSH - opts.finishFlush = opts.finishFlush || constants.Z_FINISH - super(opts, mode) - - this[_fullFlushFlag] = constants.Z_FULL_FLUSH - this[_level] = opts.level - this[_strategy] = opts.strategy - } - - params (level, strategy) { - if (this[_sawError]) - return - - if (!this[_handle]) - throw new Error('cannot switch params when binding is closed') - - // no way to test this without also not supporting params at all - /* istanbul ignore if */ - if (!this[_handle].params) - throw new Error('not supported in this implementation') - - if (this[_level] !== level || this[_strategy] !== strategy) { - this.flush(constants.Z_SYNC_FLUSH) - assert(this[_handle], 'zlib binding closed') - // .params() calls .flush(), but the latter is always async in the - // core zlib. We override .flush() temporarily to intercept that and - // flush synchronously. - const origFlush = this[_handle].flush - this[_handle].flush = (flushFlag, cb) => { - this.flush(flushFlag) - cb() - } - try { - this[_handle].params(level, strategy) - } finally { - this[_handle].flush = origFlush - } - /* istanbul ignore else */ - if (this[_handle]) { - this[_level] = level - this[_strategy] = strategy - } - } - } -} - -// minimal 2-byte header -class Deflate extends Zlib { - constructor (opts) { - super(opts, 'Deflate') - } -} - -class Inflate extends Zlib { - constructor (opts) { - super(opts, 'Inflate') - } -} - -// gzip - bigger header, same deflate compression -const _portable = Symbol('_portable') -class Gzip extends Zlib { - constructor (opts) { - super(opts, 'Gzip') - this[_portable] = opts && !!opts.portable - } - - [_superWrite] (data) { - if (!this[_portable]) - return super[_superWrite](data) - - // we'll always get the header emitted in one first chunk - // overwrite the OS indicator byte with 0xFF - this[_portable] = false - data[9] = 255 - return super[_superWrite](data) - } -} - -class Gunzip extends Zlib { - constructor (opts) { - super(opts, 'Gunzip') - } -} - -// raw - no header -class DeflateRaw extends Zlib { - constructor (opts) { - super(opts, 'DeflateRaw') - } -} - -class InflateRaw extends Zlib { - constructor (opts) { - super(opts, 'InflateRaw') - } -} - -// auto-detect header. -class Unzip extends Zlib { - constructor (opts) { - super(opts, 'Unzip') - } -} - -class Brotli extends ZlibBase { - constructor (opts, mode) { - opts = opts || {} - - opts.flush = opts.flush || constants.BROTLI_OPERATION_PROCESS - opts.finishFlush = opts.finishFlush || constants.BROTLI_OPERATION_FINISH - - super(opts, mode) - - this[_fullFlushFlag] = constants.BROTLI_OPERATION_FLUSH - } -} - -class BrotliCompress extends Brotli { - constructor (opts) { - super(opts, 'BrotliCompress') - } -} - -class BrotliDecompress extends Brotli { - constructor (opts) { - super(opts, 'BrotliDecompress') - } -} - -exports.Deflate = Deflate -exports.Inflate = Inflate -exports.Gzip = Gzip -exports.Gunzip = Gunzip -exports.DeflateRaw = DeflateRaw -exports.InflateRaw = InflateRaw -exports.Unzip = Unzip -/* istanbul ignore else */ -if (typeof realZlib.BrotliCompress === 'function') { - exports.BrotliCompress = BrotliCompress - exports.BrotliDecompress = BrotliDecompress -} else { - exports.BrotliCompress = exports.BrotliDecompress = class { - constructor () { - throw new Error('Brotli is not supported in this version of Node.js') - } - } -} diff --git a/node_modules/minizlib/package.json b/node_modules/minizlib/package.json index 98825a549f3fd..dceaed923d3db 100644 --- a/node_modules/minizlib/package.json +++ b/node_modules/minizlib/package.json @@ -1,17 +1,20 @@ { "name": "minizlib", - "version": "2.1.2", + "version": "3.1.0", "description": "A small fast zlib stream built on [minipass](http://npm.im/minipass) and Node.js's zlib binding.", - "main": "index.js", + "main": "./dist/commonjs/index.js", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "scripts": { - "test": "tap test/*.js --100 -J", + "prepare": "tshy", + "pretest": "npm run prepare", + "test": "tap", "preversion": "npm test", "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" + "prepublishOnly": "git push origin --follow-tags", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" }, "repository": { "type": "git", @@ -30,13 +33,48 @@ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", "license": "MIT", "devDependencies": { - "tap": "^14.6.9" + "@types/node": "^24.5.2", + "tap": "^21.1.0", + "tshy": "^3.0.2", + "typedoc": "^0.28.1" }, "files": [ - "index.js", - "constants.js" + "dist" ], "engines": { - "node": ">= 8" - } + "node": ">= 18" + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "types": "./dist/commonjs/index.d.ts", + "type": "module", + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "module": "./dist/esm/index.js" } diff --git a/node_modules/mkdirp-infer-owner/LICENSE b/node_modules/mkdirp-infer-owner/LICENSE deleted file mode 100644 index 05eeeb88c2ef4..0000000000000 --- a/node_modules/mkdirp-infer-owner/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/mkdirp-infer-owner/index.js b/node_modules/mkdirp-infer-owner/index.js deleted file mode 100644 index 750743f51a9f9..0000000000000 --- a/node_modules/mkdirp-infer-owner/index.js +++ /dev/null @@ -1,26 +0,0 @@ -const inferOwner = require('infer-owner') -const mkdirp = require('mkdirp') -const {promisify} = require('util') -const chownr = promisify(require('chownr')) - -const platform = process.env.__TESTING_MKDIRP_INFER_OWNER_PLATFORM__ - || process.platform -const isWindows = platform === 'win32' -const isRoot = process.getuid && process.getuid() === 0 -const doChown = !isWindows && isRoot - -module.exports = !doChown ? (path, opts) => mkdirp(path, opts) - : (path, opts) => inferOwner(path).then(({uid, gid}) => - mkdirp(path, opts).then(made => - uid !== 0 || gid !== process.getgid() - ? chownr(made || path, uid, gid).then(() => made) - : made)) - -module.exports.sync = !doChown ? (path, opts) => mkdirp.sync(path, opts) - : (path, opts) => { - const {uid, gid} = inferOwner.sync(path) - const made = mkdirp.sync(path) - if (uid !== 0 || gid !== process.getgid()) - chownr.sync(made || path, uid, gid) - return made - } diff --git a/node_modules/mkdirp-infer-owner/package.json b/node_modules/mkdirp-infer-owner/package.json deleted file mode 100644 index 1f67ad0edf501..0000000000000 --- a/node_modules/mkdirp-infer-owner/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "mkdirp-infer-owner", - "version": "2.0.0", - "files": [ - "index.js" - ], - "description": "mkdirp, but chown to the owner of the containing folder if possible and necessary", - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", - "license": "ISC", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "snap": "tap" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "require-inject": "^1.4.4", - "tap": "^14.10.6" - }, - "dependencies": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/isaacs/mkdirp-infer-owner" - }, - "engines": { - "node": ">=10" - } -} diff --git a/node_modules/mkdirp/LICENSE b/node_modules/mkdirp/LICENSE deleted file mode 100644 index 13fcd15f0e0be..0000000000000 --- a/node_modules/mkdirp/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me) - -This project is free software released under the MIT license: - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/node_modules/mkdirp/bin/cmd.js b/node_modules/mkdirp/bin/cmd.js deleted file mode 100755 index 6e0aa8dc4667b..0000000000000 --- a/node_modules/mkdirp/bin/cmd.js +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env node - -const usage = () => ` -usage: mkdirp [DIR1,DIR2..] {OPTIONS} - - Create each supplied directory including any necessary parent directories - that don't yet exist. - - If the directory already exists, do nothing. - -OPTIONS are: - - -m<mode> If a directory needs to be created, set the mode as an octal - --mode=<mode> permission string. - - -v --version Print the mkdirp version number - - -h --help Print this helpful banner - - -p --print Print the first directories created for each path provided - - --manual Use manual implementation, even if native is available -` - -const dirs = [] -const opts = {} -let print = false -let dashdash = false -let manual = false -for (const arg of process.argv.slice(2)) { - if (dashdash) - dirs.push(arg) - else if (arg === '--') - dashdash = true - else if (arg === '--manual') - manual = true - else if (/^-h/.test(arg) || /^--help/.test(arg)) { - console.log(usage()) - process.exit(0) - } else if (arg === '-v' || arg === '--version') { - console.log(require('../package.json').version) - process.exit(0) - } else if (arg === '-p' || arg === '--print') { - print = true - } else if (/^-m/.test(arg) || /^--mode=/.test(arg)) { - const mode = parseInt(arg.replace(/^(-m|--mode=)/, ''), 8) - if (isNaN(mode)) { - console.error(`invalid mode argument: ${arg}\nMust be an octal number.`) - process.exit(1) - } - opts.mode = mode - } else - dirs.push(arg) -} - -const mkdirp = require('../') -const impl = manual ? mkdirp.manual : mkdirp -if (dirs.length === 0) - console.error(usage()) - -Promise.all(dirs.map(dir => impl(dir, opts))) - .then(made => print ? made.forEach(m => m && console.log(m)) : null) - .catch(er => { - console.error(er.message) - if (er.code) - console.error(' code: ' + er.code) - process.exit(1) - }) diff --git a/node_modules/mkdirp/index.js b/node_modules/mkdirp/index.js deleted file mode 100644 index ad7a16c9f45d9..0000000000000 --- a/node_modules/mkdirp/index.js +++ /dev/null @@ -1,31 +0,0 @@ -const optsArg = require('./lib/opts-arg.js') -const pathArg = require('./lib/path-arg.js') - -const {mkdirpNative, mkdirpNativeSync} = require('./lib/mkdirp-native.js') -const {mkdirpManual, mkdirpManualSync} = require('./lib/mkdirp-manual.js') -const {useNative, useNativeSync} = require('./lib/use-native.js') - - -const mkdirp = (path, opts) => { - path = pathArg(path) - opts = optsArg(opts) - return useNative(opts) - ? mkdirpNative(path, opts) - : mkdirpManual(path, opts) -} - -const mkdirpSync = (path, opts) => { - path = pathArg(path) - opts = optsArg(opts) - return useNativeSync(opts) - ? mkdirpNativeSync(path, opts) - : mkdirpManualSync(path, opts) -} - -mkdirp.sync = mkdirpSync -mkdirp.native = (path, opts) => mkdirpNative(pathArg(path), optsArg(opts)) -mkdirp.manual = (path, opts) => mkdirpManual(pathArg(path), optsArg(opts)) -mkdirp.nativeSync = (path, opts) => mkdirpNativeSync(pathArg(path), optsArg(opts)) -mkdirp.manualSync = (path, opts) => mkdirpManualSync(pathArg(path), optsArg(opts)) - -module.exports = mkdirp diff --git a/node_modules/mkdirp/lib/find-made.js b/node_modules/mkdirp/lib/find-made.js deleted file mode 100644 index 022e492c085da..0000000000000 --- a/node_modules/mkdirp/lib/find-made.js +++ /dev/null @@ -1,29 +0,0 @@ -const {dirname} = require('path') - -const findMade = (opts, parent, path = undefined) => { - // we never want the 'made' return value to be a root directory - if (path === parent) - return Promise.resolve() - - return opts.statAsync(parent).then( - st => st.isDirectory() ? path : undefined, // will fail later - er => er.code === 'ENOENT' - ? findMade(opts, dirname(parent), parent) - : undefined - ) -} - -const findMadeSync = (opts, parent, path = undefined) => { - if (path === parent) - return undefined - - try { - return opts.statSync(parent).isDirectory() ? path : undefined - } catch (er) { - return er.code === 'ENOENT' - ? findMadeSync(opts, dirname(parent), parent) - : undefined - } -} - -module.exports = {findMade, findMadeSync} diff --git a/node_modules/mkdirp/lib/mkdirp-manual.js b/node_modules/mkdirp/lib/mkdirp-manual.js deleted file mode 100644 index 2eb18cd64eb79..0000000000000 --- a/node_modules/mkdirp/lib/mkdirp-manual.js +++ /dev/null @@ -1,64 +0,0 @@ -const {dirname} = require('path') - -const mkdirpManual = (path, opts, made) => { - opts.recursive = false - const parent = dirname(path) - if (parent === path) { - return opts.mkdirAsync(path, opts).catch(er => { - // swallowed by recursive implementation on posix systems - // any other error is a failure - if (er.code !== 'EISDIR') - throw er - }) - } - - return opts.mkdirAsync(path, opts).then(() => made || path, er => { - if (er.code === 'ENOENT') - return mkdirpManual(parent, opts) - .then(made => mkdirpManual(path, opts, made)) - if (er.code !== 'EEXIST' && er.code !== 'EROFS') - throw er - return opts.statAsync(path).then(st => { - if (st.isDirectory()) - return made - else - throw er - }, () => { throw er }) - }) -} - -const mkdirpManualSync = (path, opts, made) => { - const parent = dirname(path) - opts.recursive = false - - if (parent === path) { - try { - return opts.mkdirSync(path, opts) - } catch (er) { - // swallowed by recursive implementation on posix systems - // any other error is a failure - if (er.code !== 'EISDIR') - throw er - else - return - } - } - - try { - opts.mkdirSync(path, opts) - return made || path - } catch (er) { - if (er.code === 'ENOENT') - return mkdirpManualSync(path, opts, mkdirpManualSync(parent, opts, made)) - if (er.code !== 'EEXIST' && er.code !== 'EROFS') - throw er - try { - if (!opts.statSync(path).isDirectory()) - throw er - } catch (_) { - throw er - } - } -} - -module.exports = {mkdirpManual, mkdirpManualSync} diff --git a/node_modules/mkdirp/lib/mkdirp-native.js b/node_modules/mkdirp/lib/mkdirp-native.js deleted file mode 100644 index c7a6b69800f62..0000000000000 --- a/node_modules/mkdirp/lib/mkdirp-native.js +++ /dev/null @@ -1,39 +0,0 @@ -const {dirname} = require('path') -const {findMade, findMadeSync} = require('./find-made.js') -const {mkdirpManual, mkdirpManualSync} = require('./mkdirp-manual.js') - -const mkdirpNative = (path, opts) => { - opts.recursive = true - const parent = dirname(path) - if (parent === path) - return opts.mkdirAsync(path, opts) - - return findMade(opts, path).then(made => - opts.mkdirAsync(path, opts).then(() => made) - .catch(er => { - if (er.code === 'ENOENT') - return mkdirpManual(path, opts) - else - throw er - })) -} - -const mkdirpNativeSync = (path, opts) => { - opts.recursive = true - const parent = dirname(path) - if (parent === path) - return opts.mkdirSync(path, opts) - - const made = findMadeSync(opts, path) - try { - opts.mkdirSync(path, opts) - return made - } catch (er) { - if (er.code === 'ENOENT') - return mkdirpManualSync(path, opts) - else - throw er - } -} - -module.exports = {mkdirpNative, mkdirpNativeSync} diff --git a/node_modules/mkdirp/lib/opts-arg.js b/node_modules/mkdirp/lib/opts-arg.js deleted file mode 100644 index 2fa4833faacc7..0000000000000 --- a/node_modules/mkdirp/lib/opts-arg.js +++ /dev/null @@ -1,23 +0,0 @@ -const { promisify } = require('util') -const fs = require('fs') -const optsArg = opts => { - if (!opts) - opts = { mode: 0o777, fs } - else if (typeof opts === 'object') - opts = { mode: 0o777, fs, ...opts } - else if (typeof opts === 'number') - opts = { mode: opts, fs } - else if (typeof opts === 'string') - opts = { mode: parseInt(opts, 8), fs } - else - throw new TypeError('invalid options argument') - - opts.mkdir = opts.mkdir || opts.fs.mkdir || fs.mkdir - opts.mkdirAsync = promisify(opts.mkdir) - opts.stat = opts.stat || opts.fs.stat || fs.stat - opts.statAsync = promisify(opts.stat) - opts.statSync = opts.statSync || opts.fs.statSync || fs.statSync - opts.mkdirSync = opts.mkdirSync || opts.fs.mkdirSync || fs.mkdirSync - return opts -} -module.exports = optsArg diff --git a/node_modules/mkdirp/lib/path-arg.js b/node_modules/mkdirp/lib/path-arg.js deleted file mode 100644 index cc07de5a6f992..0000000000000 --- a/node_modules/mkdirp/lib/path-arg.js +++ /dev/null @@ -1,29 +0,0 @@ -const platform = process.env.__TESTING_MKDIRP_PLATFORM__ || process.platform -const { resolve, parse } = require('path') -const pathArg = path => { - if (/\0/.test(path)) { - // simulate same failure that node raises - throw Object.assign( - new TypeError('path must be a string without null bytes'), - { - path, - code: 'ERR_INVALID_ARG_VALUE', - } - ) - } - - path = resolve(path) - if (platform === 'win32') { - const badWinChars = /[*|"<>?:]/ - const {root} = parse(path) - if (badWinChars.test(path.substr(root.length))) { - throw Object.assign(new Error('Illegal characters in path.'), { - path, - code: 'EINVAL', - }) - } - } - - return path -} -module.exports = pathArg diff --git a/node_modules/mkdirp/lib/use-native.js b/node_modules/mkdirp/lib/use-native.js deleted file mode 100644 index 079361de19fd8..0000000000000 --- a/node_modules/mkdirp/lib/use-native.js +++ /dev/null @@ -1,10 +0,0 @@ -const fs = require('fs') - -const version = process.env.__TESTING_MKDIRP_NODE_VERSION__ || process.version -const versArr = version.replace(/^v/, '').split('.') -const hasNative = +versArr[0] > 10 || +versArr[0] === 10 && +versArr[1] >= 12 - -const useNative = !hasNative ? () => false : opts => opts.mkdir === fs.mkdir -const useNativeSync = !hasNative ? () => false : opts => opts.mkdirSync === fs.mkdirSync - -module.exports = {useNative, useNativeSync} diff --git a/node_modules/mkdirp/package.json b/node_modules/mkdirp/package.json deleted file mode 100644 index 2913ed09bddd6..0000000000000 --- a/node_modules/mkdirp/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "mkdirp", - "description": "Recursively mkdir, like `mkdir -p`", - "version": "1.0.4", - "main": "index.js", - "keywords": [ - "mkdir", - "directory", - "make dir", - "make", - "dir", - "recursive", - "native" - ], - "repository": { - "type": "git", - "url": "https://github.com/isaacs/node-mkdirp.git" - }, - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true, - "coverage-map": "map.js" - }, - "devDependencies": { - "require-inject": "^1.4.4", - "tap": "^14.10.7" - }, - "bin": "bin/cmd.js", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "files": [ - "bin", - "lib", - "index.js" - ] -} diff --git a/node_modules/mkdirp/readme.markdown b/node_modules/mkdirp/readme.markdown deleted file mode 100644 index 827de5905230a..0000000000000 --- a/node_modules/mkdirp/readme.markdown +++ /dev/null @@ -1,266 +0,0 @@ -# mkdirp - -Like `mkdir -p`, but in Node.js! - -Now with a modern API and no\* bugs! - -<small>\* may contain some bugs</small> - -# example - -## pow.js - -```js -const mkdirp = require('mkdirp') - -// return value is a Promise resolving to the first directory created -mkdirp('/tmp/foo/bar/baz').then(made => - console.log(`made directories, starting with ${made}`)) -``` - -Output (where `/tmp/foo` already exists) - -``` -made directories, starting with /tmp/foo/bar -``` - -Or, if you don't have time to wait around for promises: - -```js -const mkdirp = require('mkdirp') - -// return value is the first directory created -const made = mkdirp.sync('/tmp/foo/bar/baz') -console.log(`made directories, starting with ${made}`) -``` - -And now /tmp/foo/bar/baz exists, huzzah! - -# methods - -```js -const mkdirp = require('mkdirp') -``` - -## mkdirp(dir, [opts]) -> Promise<String | undefined> - -Create a new directory and any necessary subdirectories at `dir` with octal -permission string `opts.mode`. If `opts` is a string or number, it will be -treated as the `opts.mode`. - -If `opts.mode` isn't specified, it defaults to `0o777 & -(~process.umask())`. - -Promise resolves to first directory `made` that had to be created, or -`undefined` if everything already exists. Promise rejects if any errors -are encountered. Note that, in the case of promise rejection, some -directories _may_ have been created, as recursive directory creation is not -an atomic operation. - -You can optionally pass in an alternate `fs` implementation by passing in -`opts.fs`. Your implementation should have `opts.fs.mkdir(path, opts, cb)` -and `opts.fs.stat(path, cb)`. - -You can also override just one or the other of `mkdir` and `stat` by -passing in `opts.stat` or `opts.mkdir`, or providing an `fs` option that -only overrides one of these. - -## mkdirp.sync(dir, opts) -> String|null - -Synchronously create a new directory and any necessary subdirectories at -`dir` with octal permission string `opts.mode`. If `opts` is a string or -number, it will be treated as the `opts.mode`. - -If `opts.mode` isn't specified, it defaults to `0o777 & -(~process.umask())`. - -Returns the first directory that had to be created, or undefined if -everything already exists. - -You can optionally pass in an alternate `fs` implementation by passing in -`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` -and `opts.fs.statSync(path)`. - -You can also override just one or the other of `mkdirSync` and `statSync` -by passing in `opts.statSync` or `opts.mkdirSync`, or providing an `fs` -option that only overrides one of these. - -## mkdirp.manual, mkdirp.manualSync - -Use the manual implementation (not the native one). This is the default -when the native implementation is not available or the stat/mkdir -implementation is overridden. - -## mkdirp.native, mkdirp.nativeSync - -Use the native implementation (not the manual one). This is the default -when the native implementation is available and stat/mkdir are not -overridden. - -# implementation - -On Node.js v10.12.0 and above, use the native `fs.mkdir(p, -{recursive:true})` option, unless `fs.mkdir`/`fs.mkdirSync` has been -overridden by an option. - -## native implementation - -- If the path is a root directory, then pass it to the underlying - implementation and return the result/error. (In this case, it'll either - succeed or fail, but we aren't actually creating any dirs.) -- Walk up the path statting each directory, to find the first path that - will be created, `made`. -- Call `fs.mkdir(path, { recursive: true })` (or `fs.mkdirSync`) -- If error, raise it to the caller. -- Return `made`. - -## manual implementation - -- Call underlying `fs.mkdir` implementation, with `recursive: false` -- If error: - - If path is a root directory, raise to the caller and do not handle it - - If ENOENT, mkdirp parent dir, store result as `made` - - stat(path) - - If error, raise original `mkdir` error - - If directory, return `made` - - Else, raise original `mkdir` error -- else - - return `undefined` if a root dir, or `made` if set, or `path` - -## windows vs unix caveat - -On Windows file systems, attempts to create a root directory (ie, a drive -letter or root UNC path) will fail. If the root directory exists, then it -will fail with `EPERM`. If the root directory does not exist, then it will -fail with `ENOENT`. - -On posix file systems, attempts to create a root directory (in recursive -mode) will succeed silently, as it is treated like just another directory -that already exists. (In non-recursive mode, of course, it fails with -`EEXIST`.) - -In order to preserve this system-specific behavior (and because it's not as -if we can create the parent of a root directory anyway), attempts to create -a root directory are passed directly to the `fs` implementation, and any -errors encountered are not handled. - -## native error caveat - -The native implementation (as of at least Node.js v13.4.0) does not provide -appropriate errors in some cases (see -[nodejs/node#31481](https://github.com/nodejs/node/issues/31481) and -[nodejs/node#28015](https://github.com/nodejs/node/issues/28015)). - -In order to work around this issue, the native implementation will fall -back to the manual implementation if an `ENOENT` error is encountered. - -# choosing a recursive mkdir implementation - -There are a few to choose from! Use the one that suits your needs best :D - -## use `fs.mkdir(path, {recursive: true}, cb)` if: - -- You wish to optimize performance even at the expense of other factors. -- You don't need to know the first dir created. -- You are ok with getting `ENOENT` as the error when some other problem is - the actual cause. -- You can limit your platforms to Node.js v10.12 and above. -- You're ok with using callbacks instead of promises. -- You don't need/want a CLI. -- You don't need to override the `fs` methods in use. - -## use this module (mkdirp 1.x) if: - -- You need to know the first directory that was created. -- You wish to use the native implementation if available, but fall back - when it's not. -- You prefer promise-returning APIs to callback-taking APIs. -- You want more useful error messages than the native recursive mkdir - provides (at least as of Node.js v13.4), and are ok with re-trying on - `ENOENT` to achieve this. -- You need (or at least, are ok with) a CLI. -- You need to override the `fs` methods in use. - -## use [`make-dir`](http://npm.im/make-dir) if: - -- You do not need to know the first dir created (and wish to save a few - `stat` calls when using the native implementation for this reason). -- You wish to use the native implementation if available, but fall back - when it's not. -- You prefer promise-returning APIs to callback-taking APIs. -- You are ok with occasionally getting `ENOENT` errors for failures that - are actually related to something other than a missing file system entry. -- You don't need/want a CLI. -- You need to override the `fs` methods in use. - -## use mkdirp 0.x if: - -- You need to know the first directory that was created. -- You need (or at least, are ok with) a CLI. -- You need to override the `fs` methods in use. -- You're ok with using callbacks instead of promises. -- You are not running on Windows, where the root-level ENOENT errors can - lead to infinite regress. -- You think vinyl just sounds warmer and richer for some weird reason. -- You are supporting truly ancient Node.js versions, before even the advent - of a `Promise` language primitive. (Please don't. You deserve better.) - -# cli - -This package also ships with a `mkdirp` command. - -``` -$ mkdirp -h - -usage: mkdirp [DIR1,DIR2..] {OPTIONS} - - Create each supplied directory including any necessary parent directories - that don't yet exist. - - If the directory already exists, do nothing. - -OPTIONS are: - - -m<mode> If a directory needs to be created, set the mode as an octal - --mode=<mode> permission string. - - -v --version Print the mkdirp version number - - -h --help Print this helpful banner - - -p --print Print the first directories created for each path provided - - --manual Use manual implementation, even if native is available -``` - -# install - -With [npm](http://npmjs.org) do: - -``` -npm install mkdirp -``` - -to get the library locally, or - -``` -npm install -g mkdirp -``` - -to get the command everywhere, or - -``` -npx mkdirp ... -``` - -to run the command without installing it globally. - -# platform support - -This module works on node v8, but only v10 and above are officially -supported, as Node v8 reached its LTS end of life 2020-01-01, which is in -the past, as of this writing. - -# license - -MIT diff --git a/node_modules/ms/readme.md b/node_modules/ms/readme.md deleted file mode 100644 index 0fc1abb3b8e30..0000000000000 --- a/node_modules/ms/readme.md +++ /dev/null @@ -1,59 +0,0 @@ -# ms - -![CI](https://github.com/vercel/ms/workflows/CI/badge.svg) - -Use this package to easily convert various time formats to milliseconds. - -## Examples - -```js -ms('2 days') // 172800000 -ms('1d') // 86400000 -ms('10h') // 36000000 -ms('2.5 hrs') // 9000000 -ms('2h') // 7200000 -ms('1m') // 60000 -ms('5s') // 5000 -ms('1y') // 31557600000 -ms('100') // 100 -ms('-3 days') // -259200000 -ms('-1h') // -3600000 -ms('-200') // -200 -``` - -### Convert from Milliseconds - -```js -ms(60000) // "1m" -ms(2 * 60000) // "2m" -ms(-3 * 60000) // "-3m" -ms(ms('10 hours')) // "10h" -``` - -### Time Format Written-Out - -```js -ms(60000, { long: true }) // "1 minute" -ms(2 * 60000, { long: true }) // "2 minutes" -ms(-3 * 60000, { long: true }) // "-3 minutes" -ms(ms('10 hours'), { long: true }) // "10 hours" -``` - -## Features - -- Works both in [Node.js](https://nodejs.org) and in the browser -- If a number is supplied to `ms`, a string with a unit is returned -- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`) -- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned - -## Related Packages - -- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time. - -## Caught a Bug? - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device -2. Link the package to the global module directory: `npm link` -3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms! - -As always, you can run the tests using: `npm test` diff --git a/node_modules/mute-stream/lib/index.js b/node_modules/mute-stream/lib/index.js new file mode 100644 index 0000000000000..368f727e2c3ed --- /dev/null +++ b/node_modules/mute-stream/lib/index.js @@ -0,0 +1,142 @@ +const Stream = require('stream') + +class MuteStream extends Stream { + #isTTY = null + + constructor (opts = {}) { + super(opts) + this.writable = this.readable = true + this.muted = false + this.on('pipe', this._onpipe) + this.replace = opts.replace + + // For readline-type situations + // This much at the start of a line being redrawn after a ctrl char + // is seen (such as backspace) won't be redrawn as the replacement + this._prompt = opts.prompt || null + this._hadControl = false + } + + #destSrc (key, def) { + if (this._dest) { + return this._dest[key] + } + if (this._src) { + return this._src[key] + } + return def + } + + #proxy (method, ...args) { + if (typeof this._dest?.[method] === 'function') { + this._dest[method](...args) + } + if (typeof this._src?.[method] === 'function') { + this._src[method](...args) + } + } + + get isTTY () { + if (this.#isTTY !== null) { + return this.#isTTY + } + return this.#destSrc('isTTY', false) + } + + // basically just get replace the getter/setter with a regular value + set isTTY (val) { + this.#isTTY = val + } + + get rows () { + return this.#destSrc('rows') + } + + get columns () { + return this.#destSrc('columns') + } + + mute () { + this.muted = true + } + + unmute () { + this.muted = false + } + + _onpipe (src) { + this._src = src + } + + pipe (dest, options) { + this._dest = dest + return super.pipe(dest, options) + } + + pause () { + if (this._src) { + return this._src.pause() + } + } + + resume () { + if (this._src) { + return this._src.resume() + } + } + + write (c) { + if (this.muted) { + if (!this.replace) { + return true + } + // eslint-disable-next-line no-control-regex + if (c.match(/^\u001b/)) { + if (c.indexOf(this._prompt) === 0) { + c = c.slice(this._prompt.length) + c = c.replace(/./g, this.replace) + c = this._prompt + c + } + this._hadControl = true + return this.emit('data', c) + } else { + if (this._prompt && this._hadControl && + c.indexOf(this._prompt) === 0) { + this._hadControl = false + this.emit('data', this._prompt) + c = c.slice(this._prompt.length) + } + c = c.toString().replace(/./g, this.replace) + } + } + this.emit('data', c) + } + + end (c) { + if (this.muted) { + if (c && this.replace) { + c = c.toString().replace(/./g, this.replace) + } else { + c = null + } + } + if (c) { + this.emit('data', c) + } + this.emit('end') + } + + destroy (...args) { + return this.#proxy('destroy', ...args) + } + + destroySoon (...args) { + return this.#proxy('destroySoon', ...args) + } + + close (...args) { + return this.#proxy('close', ...args) + } +} + +module.exports = MuteStream diff --git a/node_modules/mute-stream/mute.js b/node_modules/mute-stream/mute.js deleted file mode 100644 index a24fc09975bb3..0000000000000 --- a/node_modules/mute-stream/mute.js +++ /dev/null @@ -1,145 +0,0 @@ -var Stream = require('stream') - -module.exports = MuteStream - -// var out = new MuteStream(process.stdout) -// argument auto-pipes -function MuteStream (opts) { - Stream.apply(this) - opts = opts || {} - this.writable = this.readable = true - this.muted = false - this.on('pipe', this._onpipe) - this.replace = opts.replace - - // For readline-type situations - // This much at the start of a line being redrawn after a ctrl char - // is seen (such as backspace) won't be redrawn as the replacement - this._prompt = opts.prompt || null - this._hadControl = false -} - -MuteStream.prototype = Object.create(Stream.prototype) - -Object.defineProperty(MuteStream.prototype, 'constructor', { - value: MuteStream, - enumerable: false -}) - -MuteStream.prototype.mute = function () { - this.muted = true -} - -MuteStream.prototype.unmute = function () { - this.muted = false -} - -Object.defineProperty(MuteStream.prototype, '_onpipe', { - value: onPipe, - enumerable: false, - writable: true, - configurable: true -}) - -function onPipe (src) { - this._src = src -} - -Object.defineProperty(MuteStream.prototype, 'isTTY', { - get: getIsTTY, - set: setIsTTY, - enumerable: true, - configurable: true -}) - -function getIsTTY () { - return( (this._dest) ? this._dest.isTTY - : (this._src) ? this._src.isTTY - : false - ) -} - -// basically just get replace the getter/setter with a regular value -function setIsTTY (isTTY) { - Object.defineProperty(this, 'isTTY', { - value: isTTY, - enumerable: true, - writable: true, - configurable: true - }) -} - -Object.defineProperty(MuteStream.prototype, 'rows', { - get: function () { - return( this._dest ? this._dest.rows - : this._src ? this._src.rows - : undefined ) - }, enumerable: true, configurable: true }) - -Object.defineProperty(MuteStream.prototype, 'columns', { - get: function () { - return( this._dest ? this._dest.columns - : this._src ? this._src.columns - : undefined ) - }, enumerable: true, configurable: true }) - - -MuteStream.prototype.pipe = function (dest, options) { - this._dest = dest - return Stream.prototype.pipe.call(this, dest, options) -} - -MuteStream.prototype.pause = function () { - if (this._src) return this._src.pause() -} - -MuteStream.prototype.resume = function () { - if (this._src) return this._src.resume() -} - -MuteStream.prototype.write = function (c) { - if (this.muted) { - if (!this.replace) return true - if (c.match(/^\u001b/)) { - if(c.indexOf(this._prompt) === 0) { - c = c.substr(this._prompt.length); - c = c.replace(/./g, this.replace); - c = this._prompt + c; - } - this._hadControl = true - return this.emit('data', c) - } else { - if (this._prompt && this._hadControl && - c.indexOf(this._prompt) === 0) { - this._hadControl = false - this.emit('data', this._prompt) - c = c.substr(this._prompt.length) - } - c = c.toString().replace(/./g, this.replace) - } - } - this.emit('data', c) -} - -MuteStream.prototype.end = function (c) { - if (this.muted) { - if (c && this.replace) { - c = c.toString().replace(/./g, this.replace) - } else { - c = null - } - } - if (c) this.emit('data', c) - this.emit('end') -} - -function proxy (fn) { return function () { - var d = this._dest - var s = this._src - if (d && d[fn]) d[fn].apply(d, arguments) - if (s && s[fn]) s[fn].apply(s, arguments) -}} - -MuteStream.prototype.destroy = proxy('destroy') -MuteStream.prototype.destroySoon = proxy('destroySoon') -MuteStream.prototype.close = proxy('close') diff --git a/node_modules/mute-stream/package.json b/node_modules/mute-stream/package.json index 56ebb363b9251..25e0af473d276 100644 --- a/node_modules/mute-stream/package.json +++ b/node_modules/mute-stream/package.json @@ -1,29 +1,54 @@ { "name": "mute-stream", - "version": "0.0.8", - "main": "mute.js", - "directories": { - "test": "test" - }, + "version": "3.0.0", + "main": "lib/index.js", "devDependencies": { - "tap": "^12.1.1" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, "scripts": { - "test": "tap test/*.js --cov" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "git://github.com/isaacs/mute-stream" + "url": "git+https://github.com/npm/mute-stream.git" }, "keywords": [ "mute", "stream", "pipe" ], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "license": "ISC", "description": "Bytes go in, but they don't come out (when muted).", "files": [ - "mute.js" - ] + "bin/", + "lib/" + ], + "tap": { + "statements": 70, + "branches": 60, + "functions": 81, + "lines": 70, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + } } diff --git a/node_modules/negotiator/HISTORY.md b/node_modules/negotiator/HISTORY.md index a9a544914c43b..63d537d3f6811 100644 --- a/node_modules/negotiator/HISTORY.md +++ b/node_modules/negotiator/HISTORY.md @@ -1,3 +1,9 @@ +1.0.0 / 2024-08-31 +================== + + * Drop support for node <18 + * Added an option preferred encodings array #59 + 0.6.3 / 2022-01-22 ================== diff --git a/node_modules/negotiator/index.js b/node_modules/negotiator/index.js index 4788264b16c9f..4f51315d6af4b 100644 --- a/node_modules/negotiator/index.js +++ b/node_modules/negotiator/index.js @@ -44,13 +44,14 @@ Negotiator.prototype.charsets = function charsets(available) { return preferredCharsets(this.request.headers['accept-charset'], available); }; -Negotiator.prototype.encoding = function encoding(available) { - var set = this.encodings(available); +Negotiator.prototype.encoding = function encoding(available, opts) { + var set = this.encodings(available, opts); return set && set[0]; }; -Negotiator.prototype.encodings = function encodings(available) { - return preferredEncodings(this.request.headers['accept-encoding'], available); +Negotiator.prototype.encodings = function encodings(available, options) { + var opts = options || {}; + return preferredEncodings(this.request.headers['accept-encoding'], available, opts.preferred); }; Negotiator.prototype.language = function language(available) { diff --git a/node_modules/negotiator/lib/encoding.js b/node_modules/negotiator/lib/encoding.js index 8432cd77b8a96..9ebb633d67743 100644 --- a/node_modules/negotiator/lib/encoding.js +++ b/node_modules/negotiator/lib/encoding.js @@ -96,7 +96,7 @@ function parseEncoding(str, i) { */ function getEncodingPriority(encoding, accepted, index) { - var priority = {o: -1, q: 0, s: 0}; + var priority = {encoding: encoding, o: -1, q: 0, s: 0}; for (var i = 0; i < accepted.length; i++) { var spec = specify(encoding, accepted[i], index); @@ -123,6 +123,7 @@ function specify(encoding, spec, index) { } return { + encoding: encoding, i: index, o: spec.i, q: spec.q, @@ -135,14 +136,34 @@ function specify(encoding, spec, index) { * @public */ -function preferredEncodings(accept, provided) { +function preferredEncodings(accept, provided, preferred) { var accepts = parseAcceptEncoding(accept || ''); + var comparator = preferred ? function comparator (a, b) { + if (a.q !== b.q) { + return b.q - a.q // higher quality first + } + + var aPreferred = preferred.indexOf(a.encoding) + var bPreferred = preferred.indexOf(b.encoding) + + if (aPreferred === -1 && bPreferred === -1) { + // consider the original specifity/order + return (b.s - a.s) || (a.o - b.o) || (a.i - b.i) + } + + if (aPreferred !== -1 && bPreferred !== -1) { + return aPreferred - bPreferred // consider the preferred order + } + + return aPreferred === -1 ? 1 : -1 // preferred first + } : compareSpecs; + if (!provided) { // sorted list of all encodings return accepts .filter(isQuality) - .sort(compareSpecs) + .sort(comparator) .map(getFullEncoding); } @@ -151,7 +172,7 @@ function preferredEncodings(accept, provided) { }); // sorted list of accepted encodings - return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) { + return priorities.filter(isQuality).sort(comparator).map(function getEncoding(priority) { return provided[priorities.indexOf(priority)]; }); } @@ -162,7 +183,7 @@ function preferredEncodings(accept, provided) { */ function compareSpecs(a, b) { - return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0; + return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i); } /** diff --git a/node_modules/negotiator/lib/mediaType.js b/node_modules/negotiator/lib/mediaType.js index 67309dd75f1b6..8e402ea88394c 100644 --- a/node_modules/negotiator/lib/mediaType.js +++ b/node_modules/negotiator/lib/mediaType.js @@ -69,7 +69,7 @@ function parseMediaType(str, i) { // get the value, unwrapping quotes var value = val && val[0] === '"' && val[val.length - 1] === '"' - ? val.substr(1, val.length - 2) + ? val.slice(1, -1) : val; if (key === 'q') { @@ -238,8 +238,8 @@ function splitKeyValuePair(str) { if (index === -1) { key = str; } else { - key = str.substr(0, index); - val = str.substr(index + 1); + key = str.slice(0, index); + val = str.slice(index + 1); } return [key, val]; diff --git a/node_modules/negotiator/package.json b/node_modules/negotiator/package.json index 297635f6d3417..e4bdc1ef4f748 100644 --- a/node_modules/negotiator/package.json +++ b/node_modules/negotiator/package.json @@ -1,7 +1,7 @@ { "name": "negotiator", "description": "HTTP content negotiation", - "version": "0.6.3", + "version": "1.0.0", "contributors": [ "Douglas Christopher Wilson <doug@somethingdoug.com>", "Federico Romero <federico.romero@outboxlabs.com>", @@ -36,6 +36,7 @@ "scripts": { "lint": "eslint .", "test": "mocha --reporter spec --check-leaks --bail test/", + "test:debug": "mocha --reporter spec --check-leaks --inspect --inspect-brk test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test" } diff --git a/node_modules/node-gyp/.release-please-manifest.json b/node_modules/node-gyp/.release-please-manifest.json new file mode 100644 index 0000000000000..41c2c8154a015 --- /dev/null +++ b/node_modules/node-gyp/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "12.2.0" +} diff --git a/node_modules/node-gyp/CODE_OF_CONDUCT.md b/node_modules/node-gyp/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000..4c211405596cb --- /dev/null +++ b/node_modules/node-gyp/CODE_OF_CONDUCT.md @@ -0,0 +1,4 @@ +# Code of Conduct + +* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md) +* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/master/Moderation-Policy.md) diff --git a/node_modules/node-gyp/CONTRIBUTING.md b/node_modules/node-gyp/CONTRIBUTING.md index c1c50eab4e58b..618fb6ae9e03a 100644 --- a/node_modules/node-gyp/CONTRIBUTING.md +++ b/node_modules/node-gyp/CONTRIBUTING.md @@ -1,9 +1,17 @@ # Contributing to node-gyp +## Making changes to gyp-next + +Changes in the subfolder `gyp/` should be submitted to the +[`gyp-next`][] repository first. The `gyp/` folder is regularly +synced from [`gyp-next`][] with GitHub Actions workflow +[`update-gyp-next.yml`](.github/workflows/update-gyp-next.yml), +and any changes in this folder would be overridden by the workflow. + ## Code of Conduct Please read the -[Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md) +[Code of Conduct](https://github.com/nodejs/admin/blob/main/CODE_OF_CONDUCT.md) which explains the minimum behavior expectations for node-gyp contributors. <a id="developers-certificate-of-origin"></a> @@ -32,3 +40,5 @@ By making a contribution to this project, I certify that: personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. + +[`gyp-next`]: https://github.com/nodejs/gyp-next diff --git a/node_modules/node-gyp/addon.gypi b/node_modules/node-gyp/addon.gypi index 9327b0d722e74..4f112df81c771 100644 --- a/node_modules/node-gyp/addon.gypi +++ b/node_modules/node-gyp/addon.gypi @@ -103,22 +103,41 @@ '-Wl,-bimport:<(node_exp_file)' ], }], + [ 'OS=="os400"', { + 'ldflags': [ + '-Wl,-bimport:<(node_exp_file)' + ], + }], [ 'OS=="zos"', { - 'cflags': [ - '-q64', - '-Wc,DLL', - '-qlonglong', - '-qenum=int', - '-qxclang=-fexec-charset=ISO8859-1' + 'conditions': [ + [ '"<!(echo $CC)" != "clang" and \ + "<!(echo $CC)" != "ibm-clang64" and \ + "<!(echo $CC)" != "ibm-clang"', { + 'cflags': [ + '-q64', + '-Wc,DLL', + '-qlonglong', + '-qenum=int', + '-qxclang=-fexec-charset=ISO8859-1' + ], + 'ldflags': [ + '-q64', + '<(node_exp_file)', + ], + }, { + 'cflags': [ + '-m64', + ], + 'ldflags': [ + '-m64', + '<(node_exp_file)', + ], + }], ], 'defines': [ - '_ALL_SOURCE=1', + '_ALL_SOURCE', 'MAP_FAILED=-1', - '_UNIX03_SOURCE=1' - ], - 'ldflags': [ - '-q64', - '<(node_exp_file)' + '_UNIX03_SOURCE', ], }], [ 'OS=="win"', { @@ -160,7 +179,7 @@ '-loleaut32.lib', '-luuid.lib', '-lodbc32.lib', - '-lDelayImp.lib', + '-ldelayimp.lib', '-l"<(node_lib_file)"' ], 'msvs_disabled_warnings': [ @@ -176,7 +195,7 @@ '_FILE_OFFSET_BITS=64' ], }], - [ 'OS in "freebsd openbsd netbsd solaris android" or \ + [ 'OS in "freebsd openbsd netbsd solaris android openharmony" or \ (OS=="linux" and target_arch!="ia32")', { 'cflags': [ '-fPIC' ], }], diff --git a/node_modules/node-gyp/bin/node-gyp.js b/node_modules/node-gyp/bin/node-gyp.js index 8652ea21eceeb..5393a5c8e1e71 100755 --- a/node_modules/node-gyp/bin/node-gyp.js +++ b/node_modules/node-gyp/bin/node-gyp.js @@ -6,7 +6,7 @@ process.title = 'node-gyp' const envPaths = require('env-paths') const gyp = require('../') -const log = require('npmlog') +const log = require('../lib/log') const os = require('os') /** @@ -14,11 +14,11 @@ const os = require('os') */ const prog = gyp() -var completed = false +let completed = false prog.parseArgv(process.argv) prog.devDir = prog.opts.devdir -var homeDir = os.homedir() +const homeDir = os.homedir() if (prog.devDir) { prog.devDir = prog.devDir.replace(/^~/, homeDir) } else if (homeDir) { @@ -32,9 +32,9 @@ if (prog.devDir) { if (prog.todo.length === 0) { if (~process.argv.indexOf('-v') || ~process.argv.indexOf('--version')) { - console.log('v%s', prog.version) + log.stdout('v%s', prog.version) } else { - console.log('%s', prog.usage()) + log.stdout('%s', prog.usage()) } process.exit(0) } @@ -48,11 +48,11 @@ log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform, * Change dir if -C/--directory was passed. */ -var dir = prog.opts.directory +const dir = prog.opts.directory if (dir) { - var fs = require('fs') + const fs = require('fs') try { - var stat = fs.statSync(dir) + const stat = fs.statSync(dir) if (stat.isDirectory()) { log.info('chdir', dir) process.chdir(dir) @@ -68,8 +68,8 @@ if (dir) { } } -function run () { - var command = prog.todo.shift() +async function run () { + const command = prog.todo.shift() if (!command) { // done! completed = true @@ -77,30 +77,28 @@ function run () { return } - prog.commands[command.name](command.args, function (err) { - if (err) { - log.error(command.name + ' error') - log.error('stack', err.stack) - errorMessage() - log.error('not ok') - return process.exit(1) - } + try { + const args = await prog.commands[command.name](command.args) ?? [] + if (command.name === 'list') { - var versions = arguments[1] - if (versions.length > 0) { - versions.forEach(function (version) { - console.log(version) - }) + if (args.length) { + args.forEach((version) => log.stdout(version)) } else { - console.log('No node development files installed. Use `node-gyp install` to install a version.') + log.stdout('No node development files installed. Use `node-gyp install` to install a version.') } - } else if (arguments.length >= 2) { - console.log.apply(console, [].slice.call(arguments, 1)) + } else if (args.length >= 1) { + log.stdout(...args.slice(1)) } // now run the next command in the queue - process.nextTick(run) - }) + return run() + } catch (err) { + log.error(command.name + ' error') + log.error('stack', err.stack) + errorMessage() + log.error('not ok') + return process.exit(1) + } } process.on('exit', function (code) { @@ -120,13 +118,20 @@ process.on('uncaughtException', function (err) { function errorMessage () { // copied from npm's lib/utils/error-handler.js - var os = require('os') + const os = require('os') log.error('System', os.type() + ' ' + os.release()) log.error('command', process.argv .map(JSON.stringify).join(' ')) log.error('cwd', process.cwd()) log.error('node -v', process.version) log.error('node-gyp -v', 'v' + prog.package.version) + // print the npm package version + for (const env of ['npm_package_name', 'npm_package_version']) { + const value = process.env[env] + if (value != null) { + log.error(`$${env}`, value) + } + } } function issueMessage () { diff --git a/node_modules/node-gyp/docs/Error-pre-versions-of-node-cannot-be-installed.md b/node_modules/node-gyp/docs/Error-pre-versions-of-node-cannot-be-installed.md deleted file mode 100644 index c1e1158d70190..0000000000000 --- a/node_modules/node-gyp/docs/Error-pre-versions-of-node-cannot-be-installed.md +++ /dev/null @@ -1,94 +0,0 @@ -When using `node-gyp` you might see an error like this when attempting to compile/install a node.js native addon: - -``` -$ npm install bcrypt -npm http GET https://registry.npmjs.org/bcrypt/0.7.5 -npm http 304 https://registry.npmjs.org/bcrypt/0.7.5 -npm http GET https://registry.npmjs.org/bindings/1.0.0 -npm http 304 https://registry.npmjs.org/bindings/1.0.0 - -> bcrypt@0.7.5 install /home/ubuntu/public/song-swap/node_modules/bcrypt -> node-gyp rebuild - -gyp ERR! configure error -gyp ERR! stack Error: "pre" versions of node cannot be installed, use the --nodedir flag instead -gyp ERR! stack at install (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/install.js:69:16) -gyp ERR! stack at Object.self.commands.(anonymous function) [as install] (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/node-gyp.js:56:37) -gyp ERR! stack at getNodeDir (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:219:20) -gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:105:9 -gyp ERR! stack at ChildProcess.exithandler (child_process.js:630:7) -gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:99:17) -gyp ERR! stack at maybeClose (child_process.js:730:16) -gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:797:5) -gyp ERR! System Linux 3.5.0-21-generic -gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild" -gyp ERR! cwd /home/ubuntu/public/song-swap/node_modules/bcrypt -gyp ERR! node -v v0.11.2-pre -gyp ERR! node-gyp -v v0.9.5 -gyp ERR! not ok -npm ERR! bcrypt@0.7.5 install: `node-gyp rebuild` -npm ERR! `sh "-c" "node-gyp rebuild"` failed with 1 -npm ERR! -npm ERR! Failed at the bcrypt@0.7.5 install script. -npm ERR! This is most likely a problem with the bcrypt package, -npm ERR! not with npm itself. -npm ERR! Tell the author that this fails on your system: -npm ERR! node-gyp rebuild -npm ERR! You can get their info via: -npm ERR! npm owner ls bcrypt -npm ERR! There is likely additional logging output above. - -npm ERR! System Linux 3.5.0-21-generic -npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install" "bcrypt" -npm ERR! cwd /home/ubuntu/public/song-swap -npm ERR! node -v v0.11.2-pre -npm ERR! npm -v 1.2.18 -npm ERR! code ELIFECYCLE -npm ERR! -npm ERR! Additional logging details can be found in: -npm ERR! /home/ubuntu/public/song-swap/npm-debug.log -npm ERR! not ok code 0 -``` - -The main error here is: - -``` -Error: "pre" versions of node cannot be installed, use the --nodedir flag instead -``` - -This error is caused when you attempt to compile a native addon using a version of node.js with `-pre` at the end of the version number: - -``` bash -$ node -v -v0.10.4-pre -``` - -## How to avoid (the short answer) - -To avoid this error completely just use a stable release of node.js. i.e. `v0.10.4`, and __not__ `v0.10.4-pre`. - -## How to fix (the long answer) - -This error happens because `node-gyp` does not know what header files were used to compile your "pre" version of node, and therefore it needs you to specify the node source code directory path using the `--nodedir` flag. - -For example, if I compiled my development ("pre") version of node.js using the source code in `/Users/nrajlich/node`, then I could invoke `node-gyp` like: - -``` bash -$ node-gyp rebuild --nodedir=/Users/nrajlich/node -``` - -Or install an native addon through `npm` like: - -``` bash -$ npm install bcrypt --nodedir=/Users/nrajlich/node -``` - -### Always use `--nodedir` - -__Note:__ This is for advanced users who use `-pre` versions of node more often than tagged releases. - -If you're invoking `node-gyp` through `npm`, then you can leverage `npm`'s configuration system and not have to specify the `--nodedir` flag all the time: - -``` bash -$ npm config set nodedir /Users/nrajlich/node -``` \ No newline at end of file diff --git a/node_modules/node-gyp/docs/Force-npm-to-use-global-node-gyp.md b/node_modules/node-gyp/docs/Force-npm-to-use-global-node-gyp.md deleted file mode 100644 index c6304e490a75d..0000000000000 --- a/node_modules/node-gyp/docs/Force-npm-to-use-global-node-gyp.md +++ /dev/null @@ -1,47 +0,0 @@ -# Force npm to use global installed node-gyp - -**Note: These instructions only work with npm 6 or older. For a solution that works with npm 8 (or older), see [Updating-npm-bundled-node-gyp.md](Updating-npm-bundled-node-gyp.md).** - -[Many issues](https://github.com/nodejs/node-gyp/labels/ERR%21%20node-gyp%20-v%20%3C%3D%20v5.1.0) are opened by users who are -not running a [current version of node-gyp](https://github.com/nodejs/node-gyp/releases). - -npm bundles its own, internal, copy of node-gyp located at `npm/node_modules`, within npm's private dependencies which are separate from *globally* accessible packages. Therefore this internal copy of node-gyp is independent from any globally installed copy of node-gyp that -may have been installed via `npm install -g node-gyp`. - -So npm's internal copy of node-gyp **isn't** stored inside *global* `node_modules` and thus isn't available for use as a standalone package. npm uses it's *internal* copy of `node-gyp` to automatically build native addons. - -When you install a _new_ version of node-gyp outside of npm, it'll go into your *global* `node_modules`, but not under the `npm/node_modules` (where internal copy of node-gyp is stored). So it will get into your `$PATH` and you will be able to use this globally installed version (**but not internal node-gyp of npm**) as any other globally installed package. - -The catch is that npm **won't** use global version unless you tell it to, it'll keep on using the **internal one**. You need to instruct it to by setting the `node_gyp` config variable (which goes into your `~/.npmrc`). You do this by running the `npm config set` command as below. Then npm will use the command in the path you supply whenever it needs to build a native addon. - -**Important**: You also need to remember to unset this when you upgrade npm with a newer version of node-gyp, or you have to manually keep your globally installed node-gyp to date. See "Undo" below. - -## Linux and macOS -``` -npm install --global node-gyp@latest -npm config set node_gyp $(npm prefix -g)/lib/node_modules/node-gyp/bin/node-gyp.js -``` - -`sudo` may be required for the first command if you get a permission error. - -## Windows - -### Windows Command Prompt -``` -npm install --global node-gyp@latest -for /f "delims=" %P in ('npm prefix -g') do npm config set node_gyp "%P\node_modules\node-gyp\bin\node-gyp.js" -``` - -### Powershell -``` -npm install --global node-gyp@latest -npm prefix -g | % {npm config set node_gyp "$_\node_modules\node-gyp\bin\node-gyp.js"} -``` - -## Undo -**Beware** if you don't unset the `node_gyp` config option, npm will continue to use the globally installed version of node-gyp rather than the one it ships with, which may end up being newer. - -``` -npm config delete node_gyp -npm uninstall --global node-gyp -``` diff --git a/node_modules/node-gyp/docs/Home.md b/node_modules/node-gyp/docs/Home.md deleted file mode 100644 index fe099868b2822..0000000000000 --- a/node_modules/node-gyp/docs/Home.md +++ /dev/null @@ -1,7 +0,0 @@ -Welcome to the node-gyp wiki! - - * [["binding.gyp" files out in the wild]] - * [[Linking to OpenSSL]] - * [[Common Issues]] - * [[Updating npm's bundled node-gyp]] - * [[Error: "pre" versions of node cannot be installed]] diff --git a/node_modules/node-gyp/docs/Linking-to-OpenSSL.md b/node_modules/node-gyp/docs/Linking-to-OpenSSL.md deleted file mode 100644 index ec809299958ca..0000000000000 --- a/node_modules/node-gyp/docs/Linking-to-OpenSSL.md +++ /dev/null @@ -1,86 +0,0 @@ -A handful of native addons require linking to OpenSSL in one way or another. This introduces a small challenge since node will sometimes bundle OpenSSL statically (the default for node >= v0.8.x), or sometimes dynamically link to the system OpenSSL (default for node <= v0.6.x). - -Good native addons should account for both scenarios. It's recommended that you use the `binding.gyp` file provided below as a starting-point for any addon that needs to use OpenSSL: - -``` python -{ - 'variables': { - # node v0.6.x doesn't give us its build variables, - # but on Unix it was only possible to use the system OpenSSL library, - # so default the variable to "true", v0.8.x node and up will overwrite it. - 'node_shared_openssl%': 'true' - }, - 'targets': [ - { - 'target_name': 'binding', - 'sources': [ - 'src/binding.cc' - ], - 'conditions': [ - ['node_shared_openssl=="false"', { - # so when "node_shared_openssl" is "false", then OpenSSL has been - # bundled into the node executable. So we need to include the same - # header files that were used when building node. - 'include_dirs': [ - '<(node_root_dir)/deps/openssl/openssl/include' - ], - "conditions" : [ - ["target_arch=='ia32'", { - "include_dirs": [ "<(node_root_dir)/deps/openssl/config/piii" ] - }], - ["target_arch=='x64'", { - "include_dirs": [ "<(node_root_dir)/deps/openssl/config/k8" ] - }], - ["target_arch=='arm'", { - "include_dirs": [ "<(node_root_dir)/deps/openssl/config/arm" ] - }] - ] - }] - ] - } - ] -} -``` - -This ensures that when OpenSSL is statically linked into `node` then, the bundled OpenSSL headers are included, but when the system OpenSSL is in use, then only those headers will be used. - -## Windows? - -As you can see this baseline `binding.gyp` file only accounts for the Unix scenario. Currently on Windows the situation is a little less ideal. On Windows, OpenSSL is _always_ statically compiled into the `node` executable, so ideally it would be possible to use that copy of OpenSSL when building native addons. - -Unfortunately it doesn't seem like that is possible at the moment, as there would need to be tweaks made to the generated `node.lib` file to include the openssl glue functions, or a new `openssl.lib` file would need to be created during the node build. I'm not sure which is the easiest/most feasible. - -In the meantime, one possible solution is using another copy of OpenSSL, which is what [`node-bcrypt`](https://github.com/ncb000gt/node.bcrypt.js) currently does. Adding something like this to your `binding.gyp` file's `"conditions"` block would enable this: - -``` python - [ 'OS=="win"', { - 'conditions': [ - # "openssl_root" is the directory on Windows of the OpenSSL files. - # Check the "target_arch" variable to set good default values for - # both 64-bit and 32-bit builds of the module. - ['target_arch=="x64"', { - 'variables': { - 'openssl_root%': 'C:/OpenSSL-Win64' - }, - }, { - 'variables': { - 'openssl_root%': 'C:/OpenSSL-Win32' - }, - }], - ], - 'libraries': [ - '-l<(openssl_root)/lib/libeay32.lib', - ], - 'include_dirs': [ - '<(openssl_root)/include', - ], - }] -``` - -Now you can direct your users to install OpenSSL on Windows from here (be sure to tell them to install the 64-bit version if they're compiling against a 64-bit version of node): http://slproweb.com/products/Win32OpenSSL.html - -Also note that both `node-gyp` and `npm` allow you to overwrite that default `openssl_root` variable on the command line: - -``` bash -$ node-gyp rebuild --openssl-root="C:\Users\Nathan\Desktop\openssl" -``` \ No newline at end of file diff --git a/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md b/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md deleted file mode 100644 index 1d91af6bb26d5..0000000000000 --- a/node_modules/node-gyp/docs/Updating-npm-bundled-node-gyp.md +++ /dev/null @@ -1,72 +0,0 @@ -# Updating the npm-bundled version of node-gyp - -**Note: These instructions are (only) tested and known to work with npm 8 and older.** - -**Note: These instructions will be undone if you reinstall or upgrade npm or node! For a more permanent (and simpler) solution, see [Force-npm-to-use-global-node-gyp.md](Force-npm-to-use-global-node-gyp.md). (npm 6 or older only!)** - -[Many issues](https://github.com/nodejs/node-gyp/labels/ERR%21%20node-gyp%20-v%20%3C%3D%20v5.1.0) are opened by users who are -not running a [current version of node-gyp](https://github.com/nodejs/node-gyp/releases). - -`npm` bundles its own, internal, copy of `node-gyp`. This internal copy is independent of any globally installed copy of node-gyp that -may have been installed via `npm install -g node-gyp`. - -This means that while `node-gyp` doesn't get installed into your `$PATH` by default, npm still keeps its own copy to invoke when you -attempt to `npm install` a native add-on. - -Sometimes, you may need to update npm's internal node-gyp to a newer version than what is installed. A simple `npm install -g node-gyp` -_won't_ do the trick since npm will still continue to use its internal copy over the global one. - -So instead: - -## Version of npm - -We need to start by knowing your version of `npm`: -```bash -npm --version -``` - -## Linux, macOS, Solaris, etc. - -Unix is easy. Just run the following command. - -If your npm is version ___7 or 8___, do: -```bash -$ npm explore npm/node_modules/@npmcli/run-script -g -- npm_config_global=false npm install node-gyp@latest -``` - -Else if your npm is version ___less than 7___, do: -```bash -$ npm explore npm/node_modules/npm-lifecycle -g -- npm install node-gyp@latest -``` - -If the command fails with a permissions error, please try `sudo` and then the command. - -## Windows - -Windows is a bit trickier, since `npm` might be installed to the "Program Files" directory, which needs admin privileges in order to -modify on current Windows. Therefore, run the following commands __inside a `cmd.exe` started with "Run as Administrator"__: - -First we need to find the location of `node`. If you don't already know the location that `node.exe` got installed to, then run: -```bash -$ where node -``` - -Now `cd` to the directory that `node.exe` is contained in e.g.: -```bash -$ cd "C:\Program Files\nodejs" -``` - -If your npm version is ___7 or 8___, do: -```bash -cd node_modules\npm\node_modules\@npmcli\run-script -``` - -Else if your npm version is ___less than 7___, do: -```bash -cd node_modules\npm\node_modules\npm-lifecycle -``` - -Finish by running: -```bash -$ npm install node-gyp@latest -``` diff --git a/node_modules/node-gyp/docs/binding.gyp-files-in-the-wild.md b/node_modules/node-gyp/docs/binding.gyp-files-in-the-wild.md deleted file mode 100644 index 795d2fd2ec618..0000000000000 --- a/node_modules/node-gyp/docs/binding.gyp-files-in-the-wild.md +++ /dev/null @@ -1,49 +0,0 @@ -This page contains links to some examples of existing `binding.gyp` files that other node modules are using. Take a look at them for inspiration. - -To add to this page, just add the link to the project's `binding.gyp` file below: - - * [ons](https://github.com/XadillaX/aliyun-ons/blob/master/binding.gyp) - * [thmclrx](https://github.com/XadillaX/thmclrx/blob/master/binding.gyp) - * [libxmljs](https://github.com/polotek/libxmljs/blob/master/binding.gyp) - * [node-buffertools](https://github.com/bnoordhuis/node-buffertools/blob/master/binding.gyp) - * [node-canvas](https://github.com/LearnBoost/node-canvas/blob/master/binding.gyp) - * [node-ffi](https://github.com/rbranson/node-ffi/blob/master/binding.gyp) + [libffi](https://github.com/rbranson/node-ffi/blob/master/deps/libffi/libffi.gyp) - * [node-time](https://github.com/TooTallNate/node-time/blob/master/binding.gyp) - * [node-sass](https://github.com/sass/node-sass/blob/master/binding.gyp) + [libsass](https://github.com/sass/node-sass/blob/master/src/libsass.gyp) - * [node-serialport](https://github.com/voodootikigod/node-serialport/blob/master/binding.gyp) - * [node-weak](https://github.com/TooTallNate/node-weak/blob/master/binding.gyp) - * [pty.js](https://github.com/chjj/pty.js/blob/master/binding.gyp) - * [ref](https://github.com/TooTallNate/ref/blob/master/binding.gyp) - * [appjs](https://github.com/milani/appjs/blob/master/binding.gyp) - * [nwm](https://github.com/mixu/nwm/blob/master/binding.gyp) - * [bcrypt](https://github.com/ncb000gt/node.bcrypt.js/blob/master/binding.gyp) - * [nk-mysql](https://github.com/mmod/nodamysql/blob/master/binding.gyp) - * [nk-xrm-installer](https://github.com/mmod/nk-xrm-installer/blob/master/binding.gyp) + [includable.gypi](https://github.com/mmod/nk-xrm-installer/blob/master/includable.gypi) + [unpack.py](https://github.com/mmod/nk-xrm-installer/blob/master/unpack.py) + [disburse.py](https://github.com/mmod/nk-xrm-installer/blob/master/disburse.py) - <sub>.py files above provide complete reference for examples of fetching source via http, extracting, and moving files.</sub> - * [node-memwatch](https://github.com/lloyd/node-memwatch/blob/master/binding.gyp) - * [node-ip2location](https://github.com/bolgovr/node-ip2location/blob/master/binding.gyp) - * [node-midi](https://github.com/justinlatimer/node-midi/blob/master/binding.gyp) - * [node-sqlite3](https://github.com/developmentseed/node-sqlite3/blob/master/binding.gyp) + [libsqlite3](https://github.com/developmentseed/node-sqlite3/blob/master/deps/sqlite3.gyp) - * [node-zipfile](https://github.com/mapbox/node-zipfile/blob/master/binding.gyp) - * [node-mapnik](https://github.com/mapnik/node-mapnik/blob/master/binding.gyp) - * [node-inotify](https://github.com/c4milo/node-inotify/blob/master/binding.gyp) - * [v8-profiler](https://github.com/c4milo/v8-profiler/blob/master/binding.gyp) - * [airtunes](https://github.com/radioline/node_airtunes/blob/master/binding.gyp) - * [node-fann](https://github.com/c4milo/node-fann/blob/master/binding.gyp) - * [node-talib](https://github.com/oransel/node-talib/blob/master/binding.gyp) - * [node-leveldown](https://github.com/rvagg/node-leveldown/blob/master/binding.gyp) + [leveldb.gyp](https://github.com/rvagg/node-leveldown/blob/master/deps/leveldb/leveldb.gyp) + [snappy.gyp](https://github.com/rvagg/node-leveldown/blob/master/deps/snappy/snappy.gyp) - * [node-expat](https://github.com/astro/node-expat/blob/master/binding.gyp) + [libexpat](https://github.com/astro/node-expat/blob/master/deps/libexpat/libexpat.gyp) - * [node-openvg-canvas](https://github.com/luismreis/node-openvg-canvas/blob/master/binding.gyp) + [node-openvg](https://github.com/luismreis/node-openvg/blob/master/binding.gyp) - * [node-cryptopp](https://github.com/BatikhSouri/node-cryptopp/blob/master/binding.gyp) - * [topcube](https://github.com/creationix/topcube/blob/master/binding.gyp) - * [node-osmium](https://github.com/osmcode/node-osmium/blob/master/binding.gyp) - * [node-osrm](https://github.com/DennisOSRM/node-osrm) - * [node-oracle](https://github.com/joeferner/node-oracle/blob/master/binding.gyp) - * [node-process-list](https://github.com/ReklatsMasters/node-process-list/blob/master/binding.gyp) - * [node-nanomsg](https://github.com/nickdesaulniers/node-nanomsg/blob/master/binding.gyp) - * [Ghostscript4JS](https://github.com/NickNaso/ghostscript4js/blob/master/binding.gyp) - * [nodecv](https://github.com/xudafeng/nodecv/blob/master/binding.gyp) - * [magick-cli](https://github.com/NickNaso/magick-cli/blob/master/binding.gyp) - * [sharp](https://github.com/lovell/sharp/blob/master/binding.gyp) - * [krb5](https://github.com/adaltas/node-krb5/blob/master/binding.gyp) - * [node-heapdump](https://github.com/bnoordhuis/node-heapdump/blob/master/binding.gyp) diff --git a/node_modules/node-gyp/eslint.config.js b/node_modules/node-gyp/eslint.config.js new file mode 100644 index 0000000000000..5212dc93d5304 --- /dev/null +++ b/node_modules/node-gyp/eslint.config.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = require('neostandard')({}) diff --git a/node_modules/node-gyp/gyp/.flake8 b/node_modules/node-gyp/gyp/.flake8 deleted file mode 100644 index ea0c7680ef87b..0000000000000 --- a/node_modules/node-gyp/gyp/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -max-complexity = 101 -max-line-length = 88 -extend-ignore = E203 # whitespace before ':' to agree with psf/black diff --git a/node_modules/node-gyp/gyp/.release-please-manifest.json b/node_modules/node-gyp/gyp/.release-please-manifest.json new file mode 100644 index 0000000000000..c825abab69803 --- /dev/null +++ b/node_modules/node-gyp/gyp/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.21.1" +} diff --git a/node_modules/node-gyp/gyp/AUTHORS b/node_modules/node-gyp/gyp/AUTHORS deleted file mode 100644 index f49a357b9ed10..0000000000000 --- a/node_modules/node-gyp/gyp/AUTHORS +++ /dev/null @@ -1,16 +0,0 @@ -# Names should be added to this file like so: -# Name or Organization <email address> - -Google Inc. <*@google.com> -Bloomberg Finance L.P. <*@bloomberg.net> -IBM Inc. <*@*.ibm.com> -Yandex LLC <*@yandex-team.ru> - -Steven Knight <knight@baldmt.com> -Ryan Norton <rnorton10@gmail.com> -David J. Sankel <david@sankelsoftware.com> -Eric N. Vander Weele <ericvw@gmail.com> -Tom Freudenberg <th.freudenberg@gmail.com> -Julien Brianceau <jbriance@cisco.com> -Refael Ackermann <refack@gmail.com> -Ujjwal Sharma <ryzokuken@disroot.org> diff --git a/node_modules/node-gyp/gyp/CODE_OF_CONDUCT.md b/node_modules/node-gyp/gyp/CODE_OF_CONDUCT.md deleted file mode 100644 index d724027fd9aad..0000000000000 --- a/node_modules/node-gyp/gyp/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,4 +0,0 @@ -# Code of Conduct - -* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md) -* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/HEAD/Moderation-Policy.md) diff --git a/node_modules/node-gyp/gyp/CONTRIBUTING.md b/node_modules/node-gyp/gyp/CONTRIBUTING.md deleted file mode 100644 index 1a0bcde2b48d8..0000000000000 --- a/node_modules/node-gyp/gyp/CONTRIBUTING.md +++ /dev/null @@ -1,32 +0,0 @@ -# Contributing to gyp-next - -## Code of Conduct - -This project is bound to the [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md). - -<a id="developers-certificate-of-origin"></a> -## Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -* (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -* (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -* (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -* (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. diff --git a/node_modules/node-gyp/gyp/data/ninja/build.ninja b/node_modules/node-gyp/gyp/data/ninja/build.ninja new file mode 100644 index 0000000000000..2400dbb1f0dab --- /dev/null +++ b/node_modules/node-gyp/gyp/data/ninja/build.ninja @@ -0,0 +1,4 @@ +rule cc + command = cc $in $out + +build my.out: cc my.in diff --git a/node_modules/node-gyp/gyp/docs/GypVsCMake.md b/node_modules/node-gyp/gyp/docs/GypVsCMake.md new file mode 100644 index 0000000000000..6d659a6123b66 --- /dev/null +++ b/node_modules/node-gyp/gyp/docs/GypVsCMake.md @@ -0,0 +1,116 @@ +# vs. CMake + +GYP was originally created to generate native IDE project files (Visual Studio, Xcode) for building [Chromium](http://www.chromim.org). + +The functionality of GYP is very similar to the [CMake](http://www.cmake.org) +build tool. Bradley Nelson wrote up the following description of why the team +created GYP instead of using CMake. The text below is copied from +http://www.mail-archive.com/webkit-dev@lists.webkit.org/msg11029.html + +``` + +Re: [webkit-dev] CMake as a build system? +Bradley Nelson +Mon, 19 Apr 2010 22:38:30 -0700 + +Here's the innards of an email with a laundry list of stuff I came up with a +while back on the gyp-developers list in response to Mike Craddick regarding +what motivated gyp's development, since we were aware of cmake at the time +(we'd even started a speculative port): + + +I did an exploratory port of portions of Chromium to cmake (I think I got as +far as net, base, sandbox, and part of webkit). +There were a number of motivations, not all of which would apply to other +projects. Also, some of the design of gyp was informed by experience at +Google with large projects built wholly from source, leading to features +absent from cmake, but not strictly required for Chromium. + +1. Ability to incrementally transition on Windows. It took us about 6 months +to switch fully to gyp. Previous attempts to move to scons had taken a long +time and failed, due to the requirement to transition while in flight. For a +substantial period of time, we had a hybrid of checked in vcproj and gyp generated +vcproj. To this day we still have a good number of GUIDs pinned in the gyp files, +because different parts of our release pipeline have leftover assumptions +regarding manipulating the raw sln/vcprojs. This transition occurred from +the bottom up, largely because modules like base were easier to convert, and +had a lower churn rate. During early stages of the transition, the majority +of the team wasn't even aware they were using gyp, as it integrated into +their existing workflow, and only affected modules that had been converted. + +2. Generation of a more 'normal' vcproj file. Gyp attempts, particularly on +Windows, to generate vcprojs which resemble hand generated projects. It +doesn't generate any Makefile type projects, but instead produces msvs +Custom Build Steps and Custom Build Rules. This makes the resulting projects +easier to understand from the IDE and avoids parts of the IDE that simply +don't function correctly if you use Makefile projects. Our early hope with +gyp was to support the least common denominator of features present in each +of the platform specific project file formats, rather than falling back on +generated Makefiles/shell scripts to emulate some common abstraction. CMake by +comparison makes a good faith attempt to use native project features, but +falls back on generated scripts in order to preserve the same semantics on +each platforms. + +3. Abstraction on the level of project settings, rather than command line +flags. In gyp's syntax you can add nearly any option present in a hand +generated xcode/vcproj file. This allows you to use abstractions built into +the IDEs rather than reverse engineering them possibly incorrectly for +things like: manifest generation, precompiled headers, bundle generation. +When somebody wants to use a particular menu option from msvs, I'm able to +do a web search on the name of the setting from the IDE and provide them +with a gyp stanza that does the equivalent. In many cases, not all project +file constructs correspond to command line flags. + +4. Strong notion of module public/private interface. Gyp allows targets to +publish a set of direct_dependent_settings, specifying things like +include_dirs, defines, platforms specific settings, etc. This means that +when module A depends on module B, it automatically acquires the right build +settings without module A being filled with assumptions/knowledge of exactly +how module B is built. Additionally, all of the transitive dependencies of +module B are pulled in. This avoids their being a single top level view of +the project, rather each gyp file expresses knowledge about its immediate +neighbors. This keep local knowledge local. CMake effectively has a large +shared global namespace. + +5. Cross platform generation. CMake is not able to generate all project +files on all platforms. For example xcode projects cannot be generated from +windows (cmake uses mac specific libraries to do project generation). This +means that for instance generating a tarball containing pregenerated +projects for all platforms is hard with Cmake (requires distribution to +several machine types). + +6. Gyp has rudimentary cross compile support. Currently we've added enough +functionality to gyp to support x86 -> arm cross compiles. Last I checked +this functionality wasn't present in cmake. (This occurred later). + + +That being said there are a number of drawbacks currently to gyp: + +1. Because platform specific settings are expressed at the project file +level (rather than the command line level). Settings which might otherwise +be shared in common between platforms (flags to gcc on mac/linux), end up +being repeated twice. Though in fairness there is actually less sharing here +than you'd think. include_dirs and defines actually represent 90% of what +can be typically shared. + +2. CMake may be more mature, having been applied to a broader range of +projects. There a number of 'tool modules' for cmake, which are shared in a +common community. + +3. gyp currently makes some nasty assumptions about the availability of +chromium's hermetic copy of cygwin on windows. This causes you to either +have to special case a number of rules, or swallow this copy of cygwin as a +build time dependency. + +4. CMake includes a fairly readable imperative language. Currently Gyp has a +somewhat poorly specified declarative language (variable expansion happens +in sometimes weird and counter-intuitive ways). In fairness though, gyp assumes +that external python scripts can be used as an escape hatch. Also gyp avoids +a lot of the things you'd need imperative code for, by having a nice target +settings publication mechanism. + +5. (Feature/drawback depending on personal preference). Gyp's syntax is +DEEPLY nested. It suffers from all of Lisp's advantages and drawbacks. + +-BradN +``` diff --git a/node_modules/node-gyp/gyp/docs/Hacking.md b/node_modules/node-gyp/gyp/docs/Hacking.md new file mode 100644 index 0000000000000..156d485b5b82d --- /dev/null +++ b/node_modules/node-gyp/gyp/docs/Hacking.md @@ -0,0 +1,46 @@ +# Hacking + +## Getting the sources + +Git is required to hack on anything, you can set up a git clone of GYP +as follows: + +``` +mkdir foo +cd foo +git clone git@github.com:nodejs/gyp-next.git +cd gyp +``` + +(this will clone gyp underneath it into `foo/gyp`. +`foo` can be any directory name you want. Once you've done that, +you can use the repo like anything other Git repo. + +## Testing your change + +GYP has a suite of tests which you can run with the provided test driver +to make sure your changes aren't breaking anything important. + +You run the test driver with e.g. + +``` sh +$ python -m pip install --upgrade pip +$ pip install --editable ".[dev]" +$ python -m pytest +``` + +See [Testing](Testing.md) for more details on the test framework. + +Note that it can be handy to look at the project files output by the tests +to diagnose problems. The easiest way to do that is by kindly asking the +test driver to leave the temporary directories it creates in-place. +This is done by setting the environment variable "PRESERVE", e.g. + +``` +set PRESERVE=all # On Windows +export PRESERVE=all # On saner platforms. +``` + +## Reviewing your change + +All changes to GYP must be code reviewed before submission. diff --git a/node_modules/node-gyp/gyp/docs/InputFormatReference.md b/node_modules/node-gyp/gyp/docs/InputFormatReference.md new file mode 100644 index 0000000000000..4b114f2debca4 --- /dev/null +++ b/node_modules/node-gyp/gyp/docs/InputFormatReference.md @@ -0,0 +1,1083 @@ +# Input Format Reference + +## Primitive Types + +The following primitive types are found within input files: + + * String values, which may be represented by enclosing them in + `'single quotes'` or `"double quotes"`. By convention, single + quotes are used. + * Integer values, which are represented in decimal without any special + decoration. Integers are fairly rare in input files, but have a few + applications in boolean contexts, where the convention is to + represent true values with `1` and false with `0`. + * Lists, which are represented as a sequence of items separated by + commas (`,`) within square brackets (`[` and `]`). A list may + contain any other primitive types, including other lists. + Generally, each item of a list must be of the same type as all other + items in the list, but in some cases (such as within `conditions` + sections), the list structure is more tightly specified. A trailing + comma is permitted. + + This example list contains three string values. + + ``` + [ 'Generate', 'Your', 'Projects', ] + ``` + + * Dictionaries, which map keys to values. All keys are strings. + Values may be of any other primitive type, including other + dictionaries. A dictionary is enclosed within curly braces (`{` and + `}`). Keys precede values, separated by a colon (`:`). Successive + dictionary entries are separated by commas (`,`). A trailing comma + is permitted. It is an error for keys to be duplicated within a + single dictionary as written in an input file, although keys may + replace other keys during [merging](#Merging). + + This example dictionary maps each of three keys to different values. + + ``` + { + 'inputs': ['version.c.in'], + 'outputs': ['version.c'], + 'process_outputs_as_sources': 1, + } + ``` + +## Overall Structure + +A GYP input file is organized as structured data. At the root scope of +each `.gyp` or `.gypi` (include) file is a dictionary. The keys and +values of this dictionary, along with any descendants contained within +the values, provide the data contained within the file. This data is +given meaning by interpreting specific key names and their associated +values in specific ways (see [Settings Keys](#Settings_Keys)). + +### Comments (#) + +Within an input file, a comment is introduced by a pound sign (`#`) not +within a string. Any text following the pound sign, up until the end of +the line, is treated as a comment. + +#### Example + +``` +{ + 'school_supplies': [ + 'Marble composition book', + 'Sharp #2 pencil', + 'Safety scissors', # You still shouldn't run with these + ], +} +``` + +In this example, the # in `'Sharp #2 pencil'` is not taken as +introducing a comment because it occurs within a string, but the text +after `'Safety scissors'` is treated as a comment having no impact on +the data within the file. + +## Merging + +### Merge Basics (=, ?, +) + +Many operations on GYP input files occurs by merging dictionary and list +items together. During merge operations, it is important to recognize +the distinction between source and destination values. Items from the +source value are merged into the destination, which leaves the source +unchanged and the destination modified by the source. A dictionary may +only be merged into another dictionary, and a list may only be merged +into another list. + + * When merging a dictionary, for each key in the source: + * If the key does not exist in the destination dictionary, insert it + and copy the associated value directly. + * If the key does exist: + * If the associated value is a dictionary, perform the dictionary + merging procedure using the source's and destination's value + dictionaries. + * If the associated value is a list, perform the list merging + procedure using the source's and destination's value lists. + * If the associated value is a string or integer, the destination + value is replaced by the source value. + * When merging a list, merge according to the suffix appended to the + key name, if the list is a value within a dictionary. + * If the key ends with an equals sign (`=`), the policy is for the + source list to completely replace the destination list if it + exists. _Mnemonic: `=` for assignment._ + * If the key ends with a question mark (`?`), the policy is for the + source list to be set as the destination list only if the key is + not already present in the destination. _Mnemonic: `?` for + conditional assignment_. + * If the key ends with a plus sign (`+`), the policy is for the + source list contents to be prepended to the destination list. + _Mnemonic: `+` for addition or concatenation._ + * If the list key is undecorated, the policy is for the source list + contents to be appended to the destination list. This is the + default list merge policy. + +#### Example + +Source dictionary: + +``` +{ + 'include_dirs+': [ + 'shared_stuff/public', + ], + 'link_settings': { + 'libraries': [ + '-lshared_stuff', + ], + }, + 'test': 1, +} +``` + +Destination dictionary: + +``` +{ + 'target_name': 'hello', + 'sources': [ + 'kitty.cc', + ], + 'include_dirs': [ + 'headers', + ], + 'link_settings': { + 'libraries': [ + '-lm', + ], + 'library_dirs': [ + '/usr/lib', + ], + }, + 'test': 0, +} +``` + +Merged dictionary: + +``` +{ + 'target_name': 'hello', + 'sources': [ + 'kitty.cc', + ], + 'include_dirs': [ + 'shared_stuff/public', # Merged, list item prepended due to include_dirs+ + 'headers', + ], + 'link_settings': { + 'libraries': [ + '-lm', + '-lshared_stuff', # Merged, list item appended + ], + 'library_dirs': [ + '/usr/lib', + ], + }, + 'test': 1, # Merged, int value replaced +} +``` + +## Pathname Relativization + +In a `.gyp` or `.gypi` file, many string values are treated as pathnames +relative to the file in which they are defined. + +String values associated with the following keys, or contained within +lists associated with the following keys, are treated as pathnames: + + * destination + * files + * include\_dirs + * inputs + * libraries + * library\_dirs + * outputs + * sources + * mac\_bundle\_resources + * mac\_framework\_dirs + * msvs\_cygwin\_dirs + * msvs\_props + +Additionally, string values associated with keys ending in the following +suffixes, or contained within lists associated with keys ending in the +following suffixes, are treated as pathnames: + + * `_dir` + * `_dirs` + * `_file` + * `_files` + * `_path` + * `_paths` + +However, any string value beginning with any of these characters is +excluded from pathname relativization: + + * `/` for identifying absolute paths. + * `$` for introducing build system variable expansions. + * `-` to support specifying such items as `-llib`, meaning “library + `lib` in the library search path.” + * `<`, `>`, and `!` for GYP expansions. + +When merging such relative pathnames, they are adjusted so that they can +remain valid relative pathnames, despite being relative to a new home. + +#### Example + +Source dictionary from `../build/common.gypi`: + +``` +{ + 'include_dirs': ['include'], # Treated as relative to ../build + 'library_dirs': ['lib'], # Treated as relative to ../build + 'libraries': ['-lz'], # Not treated as a pathname, begins with a dash + 'defines': ['NDEBUG'], # defines does not contain pathnames +} +``` + +Target dictionary, from `base.gyp`: + +``` +{ + 'sources': ['string_util.cc'], +} +``` + +Merged dictionary: + +``` +{ + 'sources': ['string_util.cc'], + 'include_dirs': ['../build/include'], + 'library_dirs': ['../build/lib'], + 'libraries': ['-lz'], + 'defines': ['NDEBUG'], +} +``` + +Because of pathname relativization, after the merge is complete, all of +the pathnames in the merged dictionary are valid relative to the +directory containing `base.gyp`. + +## List Singletons + +Some list items are treated as singletons, and the list merge process +will enforce special rules when merging them. At present, any string +item in a list that does not begin with a dash (`-`) is treated as a +singleton, although **this is subject to change.** When appending or +prepending a singleton to a list, if the item is already in the list, +only the earlier instance is retained in the merged list. + +#### Example + +Source dictionary: + +``` +{ + 'defines': [ + 'EXPERIMENT=1', + 'NDEBUG', + ], +} +``` + +Destination dictionary: + +``` +{ + 'defines': [ + 'NDEBUG', + 'USE_THREADS', + ], +} +``` + +Merged dictionary: + +``` +{ + 'defines': [ + 'NDEBUG', + 'USE_THREADS', + 'EXPERIMENT=1', # Note that NDEBUG is not appended after this. + ], +} +``` + +## Including Other Files + +If the `-I` (`--include`) argument was used to invoke GYP, any files +specified will be implicitly merged into the root dictionary of all +`.gyp` files. + +An [includes](#includes) section may be placed anywhere within a +`.gyp` or `.gypi` (include) file. `includes` sections contain lists of +other files to include. They are processed sequentially and merged into +the enclosing dictionary at the point that the `includes` section was +found. `includes` sections at the root of a `.gyp` file dictionary are +merged after any `-I` includes from the command line. + +[includes](#includes) sections are processed immediately after a file is +loaded, even before [variable and conditional +processing](#Variables_and_Conditionals), so it is not possible to +include a file based on a [variable reference](#Variable_Expansions). +While it would be useful to be able to include files based on variable +expansions, it is most likely more useful to allow included files access +to variables set by the files that included them. + +An [includes](#includes) section may, however, be placed within a +[conditional](#Conditionals) section. The included file itself will +be loaded unconditionally, but its dictionary will be discarded if the +associated condition is not true. + +## Variables and Conditionals + +### Variables + +There are three main types of variables within GYP. + + * Predefined variables. By convention, these are named with + `CAPITAL_LETTERS`. Predefined variables are set automatically by + GYP. They may be overridden, but it is not advisable to do so. See + [Predefined Variables](#Predefined_Variables) for a list of + variables that GYP provides. + * User-defined variables. Within any dictionary, a key named + `variables` can be provided, containing a mapping between variable + names (keys) and their contents (values), which may be strings, + integers, or lists of strings. By convention, user-defined + variables are named with `lowercase_letters`. + * Automatic variables. Within any dictionary, any key with a string + value has a corresponding automatic variable whose name is the same + as the key name with an underscore (`_`) prefixed. For example, if + your dictionary contains `type: 'static_library'`, an automatic + variable named `_type` will be provided, and its value will be a + string, `'static_library'`. + +Variables are inherited from enclosing scopes. + +### Providing Default Values for Variables (%) + +Within a `variables` section, keys named with percent sign (`%`) +suffixes mean that the variable should be set only if it is undefined at +the time it is processed. This can be used to provide defaults for +variables that would otherwise be undefined, so that they may reliably +be used in [variable expansion or conditional +processing](#Variables_and_Conditionals). + +### Predefined Variables + +Each GYP generator module provides defaults for the following variables: + + * `OS`: The name of the operating system that the generator produces + output for. Common values for values for `OS` are: + + * `'linux'` + * `'mac'` + * `'win'` + + But other values may be encountered and this list should not be + considered exhaustive. The `gypd` (debug) generator module does not + provide a predefined value for `OS`. When invoking GYP with the + `gypd` module, if a value for `OS` is needed, it must be provided on + the command line, such as `gyp -f gypd -DOS=mac`. + + GYP generators also provide defaults for these variables. They may + be expressed in terms of variables used by the build system that + they generate for, often in `$(VARIABLE)` format. For example, the + GYP `PRODUCT_DIR` variable maps to the Xcode `BUILT_PRODUCTS_DIR` + variable, so `PRODUCT_DIR` is defined by the Xcode generator as + `$(BUILT_PRODUCTS_DIR)`. + * `EXECUTABLE_PREFIX`: A prefix, if any, applied to executable names. + Usually this will be an empty string. + * `EXECUTABLE_SUFFIX`: A suffix, if any, applied to executable names. + On Windows, this will be `.exe`, elsewhere, it will usually be an + empty string. + * `INTERMEDIATE_DIR`: A directory that can be used to place + intermediate build results in. `INTERMEDIATE_DIR` is only + guaranteed to be accessible within a single target (See targets). + This variable is most useful within the context of rules and actions + (See rules, See actions). Compare with `SHARED_INTERMEDIATE_DIR`. + * `PRODUCT_DIR`: The directory in which the primary output of each + target, such as executables and libraries, is placed. + * `RULE_INPUT_ROOT`: The base name for the input file (e.g. "`foo`"). + See Rules. + * `RULE_INPUT_EXT`: The file extension for the input file (e.g. + "`.cc`"). See Rules. + * `RULE_INPUT_NAME`: Full name of the input file (e.g. "`foo.cc`"). + See Rules. + * `RULE_INPUT_PATH`: Full path to the input file (e.g. + "`/bar/foo.cc`"). See Rules. + * `SHARED_INTERMEDIATE_DIR`: A directory that can be used to place + intermediate build results in, and have them be accessible to other + targets. Unlike `INTERMEDIATE_DIR`, each target in a project, + possibly spanning multiple `.gyp` files, shares the same + `SHARED_INTERMEDIATE_DIR`. + +The following additional predefined variables may be available under +certain circumstances: + + * `DEPTH`. When GYP is invoked with a `--depth` argument, when + processing any `.gyp` file, `DEPTH` will be a relative path from the + `.gyp` file to the directory specified by the `--depth` argument. + +### User-Defined Variables + +A user-defined variable may be defined in terms of other variables, but +not other variables that have definitions provided in the same scope. + +### Variable Expansions (<, >, <@, >@) + +GYP provides two forms of variable expansions, “early” or “pre” +expansions, and “late,” “post,” or “target” expansions. They have +similar syntax, differing only in the character used to introduce them. + + * Early expansions are introduced by a less-than (`<`) character. + _Mnemonic: the arrow points to the left, earlier on a timeline._ + * Late expansions are introduced by a less-than (`>`) character. + _Mnemonic: the arrow points to the right, later on a timeline._ + +The difference the two phases of expansion is described in [Early and +Late Phases](#Early_and_Late_Phases). + +These characters were chosen based upon the requirement that they not +conflict with the variable format used natively by build systems. While +the dollar sign (`$`) is the most natural fit for variable expansions, +its use was ruled out because most build systems already use that +character for their own variable expansions. Using different characters +means that no escaping mechanism was needed to differentiate between GYP +variables and build system variables, and writing build system variables +into GYP files is not cumbersome. + +Variables may contain lists or strings, and variable expansions may +occur in list or string context. There are variant forms of variable +expansions that may be used to determine how each type of variable is to +be expanded in each context. + + * When a variable is referenced by `<(VAR)` or `>(VAR)`: + * If `VAR` is a string, the variable reference within the string is + replaced by variable's string value. + * If `VAR` is a list, the variable reference within the string is + replaced by a string containing the concatenation of all of the + variable’s list items. Generally, the items are joined with + spaces between each, but the specific behavior is + generator-specific. The precise encoding used by any generator + should be one that would allow each list item to be treated as a + separate argument when used as program arguments on the system + that the generator produces output for. + * When a variable is referenced by `<@(VAR)` or `>@(VAR)`: + * The expansion must occur in list context. + * The list item must be `'<@(VAR)'` or `'>@(VAR)'` exactly. + * If `VAR` is a list, each of its elements are inserted into the + list in which expansion is taking place, replacing the list item + containing the variable reference. + * If `VAR` is a string, the string is converted to a list which is + inserted into the list in which expansion is taking place as + above. The conversion into a list is generator-specific, but + generally, spaces in the string are taken as separators between + list items. The specific method of converting the string to a + list should be the inverse of the encoding method used to expand + list variables in string context, above. + +GYP treats references to undefined variables as errors. + +### Command Expansions (<!, <!@) + +Command expansions function similarly to variable expansions, but +instead of resolving variable references, they cause GYP to execute a +command at generation time and use the command’s output as the +replacement. Command expansions are introduced by a less than and +exclamation mark (`<!`). + +In a command expansion, the entire string contained within the +parentheses is passed to the system’s shell. The command’s output is +assigned to a string value that may subsequently be expanded in list +context in the same way as variable expansions if an `@` character is +used. + +In addition, command expansions (unlike other variable expansions) may +include nested variable expansions. So something like this is allowed: + +``` +'variables' : [ + 'foo': '<!(echo Build Date <!(date))', +], +``` + +expands to: + +``` +'variables' : [ + 'foo': 'Build Date 02:10:38 PM Fri Jul 24, 2009 -0700 PDT', +], +``` + +You may also put commands into arrays in order to quote arguments (but +note that you need to use a different string quoting character): + +``` +'variables' : [ + 'files': '<!(["ls", "-1", "Filename With Spaces"])', +], +``` + +GYP treats command failures (as indicated by a nonzero exit status) +during command expansion as errors. + +#### Example + +``` +{ + 'sources': [ + '!(echo filename with space.cc)', + ], + 'libraries': [ + '!@(pkg-config --libs-only-l apr-1)', + ], +} +``` + +might expand to: + +``` +{ + 'sources': [ + 'filename with space.cc', # no @, expands into a single string + ], + 'libraries': [ # @ was used, so there's a separate list item for each lib + '-lapr-1', + '-lpthread', + ], +} +``` + +## Conditionals + +Conditionals use the same set of variables used for variable expansion. +As with variable expansion, there are two phases of conditional +evaluation: + + * “Early” or “pre” conditional evaluation, introduced in + [conditions](#conditions) sections. + * “Late,” “post,” or “target” conditional evaluation, introduced in + [target\_conditions](#target_conditions) sections. + +The syntax for each type is identical, they differ only in the key name +used to identify them and the timing of their evaluation. A more +complete description of syntax and use is provided in +[conditions](#conditions). + +The difference the two phases of evaluation is described in [Early and +Late Phases](#Early_and_Late_Phases). + +## Timing of Variable Expansion and Conditional Evaluation + +### Early and Late Phases + +GYP performs two phases of variable expansion and conditional evaluation: + + * The “early” or “pre” phase operates on [conditions](#conditions) + sections and the `<` form of [variable + expansions](#Variable_Expansions). + * The “late,” “post,” or “target” phase operates on + [target\_conditions](#target_conditions) sections, the `>` form + of [variable expansions](#Variable_Expansions), + and on the `!` form of [command + expansions](#Command_Expansions_(!,_!@)). + +These two phases are provided because there are some circumstances in +which each is desirable. + +The “early” phase is appropriate for most expansions and evaluations. +“Early” expansions and evaluations may be performed anywhere within any +`.gyp` or `.gypi` file. + +The “late” phase is appropriate when expansion or evaluation must be +deferred until a specific section has been merged into target context. +“Late” expansions and evaluations only occur within `targets` sections +and their descendants. The typical use case for a late-phase expansion +is to provide, in some globally-included `.gypi` file, distinct +behaviors depending on the specifics of a target. + +#### Example + +Given this input: + +``` +{ + 'target_defaults': { + 'target_conditions': [ + ['_type=="shared_library"', {'cflags': ['-fPIC']}], + ], + }, + 'targets': [ + { + 'target_name': 'sharing_is_caring', + 'type': 'shared_library', + }, + { + 'target_name': 'static_in_the_attic', + 'type': 'static_library', + }, + ] +} +``` + +The conditional needs to be evaluated only in target context; it is +nonsense outside of target context because no `_type` variable is +defined. [target\_conditions](#target_conditions) allows evaluation +to be deferred until after the [targets](#targets) sections are +merged into their copies of [target\_defaults](#target_defaults). +The resulting targets, after “late” phase processing: + +``` +{ + 'targets': [ + { + 'target_name': 'sharing_is_caring', + 'type': 'shared_library', + 'cflags': ['-fPIC'], + }, + { + 'target_name': 'static_in_the_attic', + 'type': 'static_library', + }, + ] +} +``` + +### Expansion and Evaluation Performed Simultaneously + +During any expansion and evaluation phase, both expansion and evaluation +are performed simultaneously. The process for handling variable +expansions and conditional evaluation within a dictionary is: + + * Load [automatic variables](#Variables) (those with leading + underscores). + * If a [variables](#variables) section is present, recurse into its + dictionary. This allows [conditionals](#Conditionals) to be + present within the `variables` dictionary. + * Load [Variables user-defined variables](#User-Defined) from the + [variables](#variables) section. + * For each string value in the dictionary, perform [variable + expansion](#Variable_Expansions) and, if operating + during the “late” phase, [command + expansions](#Command_Expansions). + * Reload [automatic variables](#Variables) and [Variables + user-defined variables](#User-Defined) because the variable + expansion step may have resulted in changes to the automatic + variables. + * If a [conditions](#conditions) or + [target\_conditions](#target_conditions) section (depending on + phase) is present, recurse into its dictionary. This is done after + variable expansion so that conditionals may take advantage of + expanded automatic variables. + * Evaluate [conditionals](#Conditionals). + * Reload [automatic variables](#Variables) and [Variables + user-defined variables](#User-Defined) because the conditional + evaluation step may have resulted in changes to the automatic + variables. + * Recurse into child dictionaries or lists that have not yet been + processed. + +One quirk of this ordering is that you cannot expect a +[variables](#variables) section within a dictionary’s +[conditional](#Conditionals) to be effective in the dictionary +itself, but the added variables will be effective in any child +dictionaries or lists. It is thought to be far more worthwhile to +provide resolved [automatic variables](#Variables) to +[conditional](#Conditionals) sections, though. As a workaround, to +conditionalize variable values, place a [conditions](#conditions) or +[target\_conditions](#target_conditions) section within the +[variables](#variables) section. + +## Dependencies and Dependents + +In GYP, “dependents” are targets that rely on other targets, called +“dependencies.” Dependents declare their reliance with a special +section within their target dictionary, +[dependencies](#dependencies). + +### Dependent Settings + +It is useful for targets to “advertise” settings to their dependents. +For example, a target might require that all of its dependents add +certain directories to their include paths, link against special +libraries, or define certain preprocessor macros. GYP allows these +cases to be handled gracefully with “dependent settings” sections. +There are three types of such sections: + + * [direct\_dependent\_settings](#direct_dependent_settings), which + advertises settings to a target's direct dependents only. + * [all\_dependent\_settings](#all_dependnet_settings), which + advertises settings to all of a target's dependents, both direct and + indirect. + * [link\_settings](#link_settings), which contains settings that + should be applied when a target’s object files are used as linker + input. + +Furthermore, in some cases, a target needs to pass its dependencies’ +settings on to its own dependents. This might happen when a target’s +own public header files include header files provided by its dependency. +[export\_dependent\_settings](#export_dependent_settings) allows a +target to declare dependencies for which +[direct\_dependent\_settings](#direct_dependent_settings) should be +passed through to its own dependents. + +Dependent settings processing merges a copy of the relevant dependent +settings dictionary from a dependency into its relevant dependent +targets. + +In most instances, +[direct\_dependent\_settings](#direct_dependent_settings) will be +used. There are very few cases where +[all\_dependent\_settings](#all_dependent_settings) is actually +correct; in most of the cases where it is tempting to use, it would be +preferable to declare +[export\_dependent\_settings](#export_dependent_settings). Most +[libraries](#libraries) and [library\_dirs](#library_dirs) +sections should be placed within [link\_settings](#link_settings) +sections. + +#### Example + +Given: + +``` +{ + 'targets': [ + { + 'target_name': 'cruncher', + 'type': 'static_library', + 'sources': ['cruncher.cc'], + 'direct_dependent_settings': { + 'include_dirs': ['.'], # dependents need to find cruncher.h. + }, + 'link_settings': { + 'libraries': ['-lm'], # cruncher.cc does math. + }, + }, + { + 'target_name': 'cruncher_test', + 'type': 'executable', + 'dependencies': ['cruncher'], + 'sources': ['cruncher_test.cc'], + }, + ], +} +``` + +After dependent settings processing, the dictionary for `cruncher_test` +will be: + +``` +{ + 'target_name': 'cruncher_test', + 'type': 'executable', + 'dependencies': ['cruncher'], # implies linking against cruncher + 'sources': ['cruncher_test.cc'], + 'include_dirs': ['.'] + 'libraries': ['-lm'], +}, +``` + +If `cruncher` was declared as a `shared_library` instead of a +`static_library`, the `cruncher_test` target would not contain `-lm`, +but instead, `cruncher` itself would link against `-lm`. + +## Linking Dependencies + +The precise meaning of a dependency relationship varies with the +[types](#type) of the [targets](#targets) at either end of the +relationship. In GYP, a dependency relationship can indicate two things +about how targets relate to each other: + + * Whether the dependent target needs to link against the dependency. + * Whether the dependency target needs to be built prior to the + dependent. If the former case is true, this case must be true as + well. + +The analysis of the first item is complicated by the differences between +static and shared libraries. + + * Static libraries are simply collections of object files (`.o` or + `.obj`) that are used as inputs to a linker (`ld` or `link.exe`). + Static libraries don't link against other libraries, they’re + collected together and used when eventually linking a shared library + or executable. + * Shared libraries are linker output and must undergo symbol + resolution. They must link against other libraries (static or + shared) in order to facilitate symbol resolution. They may be used + as libraries in subsequent link steps. + * Executables are also linker output, and also undergo symbol + resolution. Like shared libraries, they must link against static + and shared libraries to facilitate symbol resolution. They may not + be reused as linker inputs in subsequent link steps. + +Accordingly, GYP performs an operation referred to as “static library +dependency adjustment,” in which it makes each linker output target +(shared libraries and executables) link against the static libraries it +depends on, either directly or indirectly. Because the linkable targets +link against these static libraries, they are also made direct +dependents of the static libraries. + +As part of this process, GYP is also able to remove the direct +dependency relationships between two static library targets, as a +dependent static library does not actually need to link against a +dependency static library. This removal facilitates speedier builds +under some build systems, as they are now free to build the two targets +in parallel. The removal of this dependency is incorrect in some cases, +such as when the dependency target contains [rules](#rules) or +[actions](#actions) that generate header files required by the +dependent target. In such cases, the dependency target, the one +providing the side-effect files, must declare itself as a +[hard\_dependency](#hard_dependency). This setting instructs GYP to +not remove the dependency link between two static library targets in its +generated output. + +## Loading Files to Resolve Dependencies + +When GYP runs, it loads all `.gyp` files needed to resolve dependencies +found in [dependencies](#dependencies) sections. These files are not +merged into the files that reference them, but they may contain special +sections that are merged into dependent target dictionaries. + +## Build Configurations + +Explain this. + +## List Filters + +GYP allows list items to be filtered by “exclusions” and “patterns.” +Any list containing string values in a dictionary may have this +filtering applied. For the purposes of this section, a list modified by +exclusions or patterns is referred to as a “base list”, in contrast to +the “exclusion list” and “pattern list” that operates on it. + + * For a base list identified by key name `key`, the `key!` list + provides exclusions. + * For a base list identified by key name `key`, the `key/` list + provides regular expression pattern-based filtering. + +Both `key!` and `key/` may be present. The `key!` exclusion list will +be processed first, followed by the `key/` pattern list. + +Exclusion lists are most powerful when used in conjunction with +[conditionals](#Conditionals). + +## Exclusion Lists (!) + +An exclusion list provides a way to remove items from the related list +based on exact matching. Any item found in an exclusion list will be +removed from the corresponding base list. + +#### Example + +This example excludes files from the `sources` based on the setting of +the `OS` variable. + +``` +{ + 'sources:' [ + 'mac_util.mm', + 'win_util.cc', + ], + 'conditions': [ + ['OS=="mac"', {'sources!': ['win_util.cc']}], + ['OS=="win"', {'sources!': ['mac_util.cc']}], + ], +} +``` + +## Pattern Lists (/) + +Pattern lists are similar to, but more powerful than, [exclusion +lists](#Exclusion_Lists_(!)). Each item in a pattern list is itself +a two-element list. The first item is a string, either `'include'` or +`'exclude'`, specifying the action to take. The second item is a string +specifying a regular expression. Any item in the base list matching the +regular expression pattern will either be included or excluded, based on +the action specified. + +Items in a pattern list are processed in sequence, and an excluded item +that is later included will not be removed from the list (unless it is +subsequently excluded again.) + +Pattern lists are processed after [exclusion +lists](#Exclusion_Lists_(!)), so it is possible for a pattern list to +re-include items previously excluded by an exclusion list. + +Nothing is actually removed from a base list until all items in an +[exclusion list](#Exclusion_Lists_(!)) and pattern list have been +evaluated. This allows items to retain their correct position relative +to one another even after being excluded and subsequently included. + +#### Example + +In this example, a uniform naming scheme is adopted for +platform-specific files. + +``` +{ + 'sources': [ + 'io_posix.cc', + 'io_win.cc', + 'launcher_mac.cc', + 'main.cc', + 'platform_util_linux.cc', + 'platform_util_mac.mm', + ], + 'sources/': [ + ['exclude', '_win\\.cc$'], + ], + 'conditions': [ + ['OS!="linux"', {'sources/': [['exclude', '_linux\\.cc$']]}], + ['OS!="mac"', {'sources/': [['exclude', '_mac\\.cc|mm?$']]}], + ['OS=="win"', {'sources/': [ + ['include', '_win\\.cc$'], + ['exclude', '_posix\\.cc$'], + ]}], + ], +} +``` + +After the pattern list is applied, `sources` will have the following +values, depending on the setting of `OS`: + + * When `OS` is `linux`: `['io_posix.cc', 'main.cc', + 'platform_util_linux.cc']` + * When `OS` is `mac`: `['io_posix.cc', 'launcher_mac.cc', 'main.cc', + 'platform_util_mac.mm']` + * When `OS` is `win`: `['io_win.cc', 'main.cc', + 'platform_util_win.cc']` + +Note that when `OS` is `win`, the `include` for `_win.cc` files is +processed after the `exclude` matching the same pattern, because the +`sources/` list participates in [merging](#Merging) during +[conditional evaluation](#Conditonals) just like any other list +would. This guarantees that the `_win.cc` files, previously +unconditionally excluded, will be re-included when `OS` is `win`. + +## Locating Excluded Items + +In some cases, a GYP generator needs to access to items that were +excluded by an [exclusion list](#Exclusion_Lists_(!)) or [pattern +list](#Pattern_Lists_(/)). When GYP excludes items during processing +of either of these list types, it places the results in an `_excluded` +list. In the example above, when `OS` is `mac`, `sources_excluded` +would be set to `['io_win.cc', 'platform_util_linux.cc']`. Some GYP +generators use this feature to display excluded files in the project +files they generate for the convenience of users, who may wish to refer +to other implementations. + +## Processing Order + +GYP uses a defined and predictable order to execute the various steps +performed between loading files and generating output. + + * Load files. + * Load `.gyp` files. Merge any [command-line + includes](#Including_Other_Files) into each `.gyp` file’s root + dictionary. As [includes](#Including_Other_Files) are found, + load them as well and [merge](#Merging) them into the scope in + which the [includes](#includes) section was found. + * Perform [“early” or “pre”](#Early_and_Late_Phases) [variable + expansion and conditional + evaluation](#Variables_and_Conditionals). + * [Merge](#Merging) each [target’s](#targets) dictionary into + the `.gyp` file’s root [target\_defaults](#target_defaults) + dictionary. + * Scan each [target](#targets) for + [dependencies](#dependencies), and repeat the above steps for + any newly-referenced `.gyp` files not yet loaded. + * Scan each [target](#targets) for wildcard + [dependencies](#dependencies), expanding the wildcards. + * Process [dependent settings](#Dependent_Settings). These + sections are processed, in order: + * [all\_dependent\_settings](#all_dependent_settings) + * [direct\_dependent\_settings](#direct_dependent_settings) + * [link\_dependent\_settings](#link_dependent_settings) + * Perform [static library dependency + adjustment](#Linking_Dependencies). + * Perform [“late,” “post,” or “target”](#Early_and_Late_Phases) + [variable expansion and conditional + evaluation](#Variables_and_Conditionals) on [target](#targets) + dictionaries. + * Merge [target](#targets) settings into + [configurations](#configurations) as appropriate. + * Process [exclusion and pattern + lists](#List_Exclusions_and_Patterns). + +## Settings Keys + +### Settings that may appear anywhere + +#### conditions + +_List of `condition` items_ + +A `conditions` section introduces a subdictionary that is only merged +into the enclosing scope based on the evaluation of a conditional +expression. Each `condition` within a `conditions` list is itself a +list of at least two items: + + 1. A string containing the conditional expression itself. Conditional + expressions may take the following forms: + * For string values, `var=="value"` and `var!="value"` to test + equality and inequality. For example, `'OS=="linux"'` is true + when the `OS` variable is set to `"linux"`. + * For integer values, `var==value`, `var!=value`, `var<value`, + `var<=value`, `var>=value`, and `var>value`, to test equality and + several common forms of inequality. For example, + `'chromium_code==0'` is true when the `chromium_code` variable is + set to `0`. + * It is an error for a conditional expression to reference any + undefined variable. + 1. A dictionary containing the subdictionary to be merged into the + enclosing scope if the conditional expression evaluates to true. + +These two items can be followed by any number of similar two items that +will be evaluated if the previous conditional expression does not +evaluate to true. + +An additional optional dictionary can be appended to this sequence of +two items. This optional dictionary will be merged into the enclosing +scope if none of the conditional expressions evaluate to true. + +Within a `conditions` section, each item is processed sequentially, so +it is possible to predict the order in which operations will occur. + +There is no restriction on nesting `conditions` sections. + +`conditions` sections are very similar to `target_conditions` sections. +See target\_conditions. + +#### Example + +``` +{ + 'sources': [ + 'common.cc', + ], + 'conditions': [ + ['OS=="mac"', {'sources': ['mac_util.mm']}], + ['OS=="win"', {'sources': ['win_main.cc']}, {'sources': ['posix_main.cc']}], + ['OS=="mac"', {'sources': ['mac_impl.mm']}, + 'OS=="win"', {'sources': ['win_impl.cc']}, + {'sources': ['default_impl.cc']} + ], + ], +} +``` + +Given this input, the `sources` list will take on different values based +on the `OS` variable. + + * If `OS` is `"mac"`, `sources` will contain `['common.cc', + 'mac_util.mm', 'posix_main.cc', 'mac_impl.mm']`. + * If `OS` is `"win"`, `sources` will contain `['common.cc', + 'win_main.cc', 'win_impl.cc']`. + * If `OS` is any other value such as `"linux"`, `sources` will contain + `['common.cc', 'posix_main.cc', 'default_impl.cc']`. diff --git a/node_modules/node-gyp/gyp/docs/LanguageSpecification.md b/node_modules/node-gyp/gyp/docs/LanguageSpecification.md new file mode 100644 index 0000000000000..f8fff097ab73f --- /dev/null +++ b/node_modules/node-gyp/gyp/docs/LanguageSpecification.md @@ -0,0 +1,430 @@ +# Language Specification + +## Objective + +Create a tool for the Chromium project that generates native Visual Studio, +Xcode and SCons and/or make build files from a platform-independent input +format. Make the input format as reasonably general as possible without +spending extra time trying to "get everything right," except where not doing so +would likely lead Chromium to an eventual dead end. When in doubt, do what +Chromium needs and don't worry about generalizing the solution. + +## Background + +Numerous other projects, both inside and outside Google, have tried to +create a simple, universal cross-platform build representation that +still allows sufficient per-platform flexibility to accommodate +irreconcilable differences. The fact that no obvious working candidate +exists that meets Chromium's requirements indicates this is probably a +tougher problem than it appears at first glance. We aim to succeed by +creating a tool that is highly specific to Chromium's specific use case, +not to the general case of design a completely platform-independent tool +for expressing any possible build. + +The Mac has the most sophisticated model for application development +through an IDE. Consequently, we will use the Xcode model as the +starting point (the input file format must handle Chromium's use of +Xcode seamlessly) and adapt the design as necessary for the other +platforms. + +## Overview + +The overall design has the following characteristics: + + * Input configurations are specified in files with the suffix `.gyp`. + * Each `.gyp` file specifies how to build the targets for the + "component" defined by that file. + * Each `.gyp` file generates one or more output files appropriate to + the platform: + * On Mac, a `.gyp` file generates one Xcode .xcodeproj bundle with + information about how its targets are built. + * On Windows, a `.gyp` file generates one Visual Studio .sln file, + and one Visual Studio .vcproj file per target. + * On Linux, a `.gyp` file generates one SCons file and/or one + Makefile per target + * The `.gyp` file syntax is a Python data structure. + * Use of arbitrary Python in `.gyp` files is forbidden. + * Use of eval() with restricted globals and locals on `.gyp` file + contents restricts the input to an evaluated expression, not + arbitrary Python statements. + * All input is expected to comply with JSON, with two exceptions: + the # character (not inside strings) begins a comment that lasts + until the end of the line, and trailing commas are permitted at + the end of list and dict contents. + * Input data is a dictionary of keywords and values. + * "Invalid" keywords on any given data structure are not illegal, + they're just ignored. + * TODO: providing warnings on use of illegal keywords would help + users catch typos. Figure out something nice to do with this. + +## Detailed Design + +Some up-front design principles/thoughts/TODOs: + + * Re-use keywords consistently. + * Keywords that allow configuration of a platform-specific concept get + prefixed appropriately: + * Examples: `msvs_disabled_warnings`, `xcode_framework_dirs` + * The input syntax is declarative and data-driven. + * This gets enforced by using Python `eval()` (which only evaluates + an expression) instead of `exec` (which executes arbitrary python) + * Semantic meanings of specific keyword values get deferred until all + are read and the configuration is being evaluated to spit out the + appropriate file(s) + * Source file lists: + * Are flat lists. Any imposed ordering within the `.gyp` file (e.g. + alphabetically) is purely by convention and for developer + convenience. When source files are linked or archived together, + it is expected that this will occur in the order that files are + listed in the `.gyp` file. + * Source file lists contain no mechanism for by-hand folder + configuration (`Filter` tags in Visual Studio, `Groups` in Xcode) + * A folder hierarchy is created automatically that mirrors the file + system + +### Example + +``` +{ + 'target_defaults': { + 'defines': [ + 'U_STATIC_IMPLEMENTATION', + ['LOGFILE', 'foo.log',], + ], + 'include_dirs': [ + '..', + ], + }, + 'targets': [ + { + 'target_name': 'foo', + 'type': 'static_library', + 'sources': [ + 'foo/src/foo.cc', + 'foo/src/foo_main.cc', + ], + 'include_dirs': [ + 'foo', + 'foo/include', + ], + 'conditions': [ + [ 'OS==mac', { 'sources': [ 'platform_test_mac.mm' ] } ] + ], + 'direct_dependent_settings': { + 'defines': [ + 'UNIT_TEST', + ], + 'include_dirs': [ + 'foo', + 'foo/include', + ], + }, + }, + ], +} +``` + +### Structural Elements + +### Top-level Dictionary + +This is the single dictionary in the `.gyp` file that defines the +targets and how they're to be built. + +The following keywords are meaningful within the top-level dictionary +definition: + +| *Keyword* | *Description* | +|:------------------|:------------------| +| `conditions` | A conditional section that may contain other items that can be present in a top-level dictionary, on a conditional basis. See the "Conditionals" section below. | +| `includes` | A list of `.gypi` files to be included in the top-level dictionary. | +| `target_defaults` | A dictionary of default settings to be inherited by all targets in the top-level dictionary. See the "Settings keywords" section below. | +| `targets` | A list of target specifications. See the "targets" below. | +| `variables` | A dictionary containing variable definitions. Each key in this dictionary is the name of a variable, and each value must be a string value that the variable is to be set to. | + +### targets + +A list of dictionaries defining targets to be built by the files +generated from this `.gyp` file. + +Targets may contain `includes`, `conditions`, and `variables` sections +as permitted in the root dictionary. The following additional keywords +have structural meaning for target definitions: + +| *Keyword* | *Description* | +|:---------------------------- |:------------------------------------------| +| `actions` | A list of special custom actions to perform on a specific input file, or files, to produce output files. See the "Actions" section below. | +| `all_dependent_settings` | A dictionary of settings to be applied to all dependents of the target, transitively. This includes direct dependents and the entire set of their dependents, and so on. This section may contain anything found within a `target` dictionary, except `configurations`, `target_name`, and `type` sections. Compare `direct_dependent_settings` and `link_settings`. | +| `configurations` | A list of dictionaries defining build configurations for the target. See the "Configurations" section below. | +| `copies` | A list of copy actions to perform. See the "Copies" section below. | +| `defines` | A list of preprocessor definitions to be passed on the command line to the C/C++ compiler (via `-D` or `/D` options). | +| `dependencies` | A list of targets on which this target depends. Targets in other `.gyp` files are specified as `../path/to/other.gyp:target_we_want`. | +| `direct_dependent_settings` | A dictionary of settings to be applied to other targets that depend on this target. These settings will only be applied to direct dependents. This section may contain anything found within a `target` dictionary, except `configurations`, `target_name`, and `type` sections. Compare with `all_dependent_settings` and `link_settings`. | +| `include_dirs` | A list of include directories to be passed on the command line to the C/C++ compiler (via `-I` or `/I` options). | +| `libraries` | A list of list of libraries (and/or frameworks) on which this target depends. | +| `link_settings` | A dictionary of settings to be applied to targets in which this target's contents are linked. `executable` and `shared_library` targets are linkable, so if they depend on a non-linkable target such as a `static_library`, they will adopt its `link_settings`. This section can contain anything found within a `target` dictionary, except `configurations`, `target_name`, and `type` sections. Compare `all_dependent_settings` and `direct_dependent_settings`. | +| `rules` | A special custom action to perform on a list of input files, to produce output files. See the "Rules" section below. | +| `sources` | A list of source files that are used to build this target or which should otherwise show up in the IDE for this target. In practice, we expect this list to be a union of all files necessary to build the target on all platforms, as well as other related files that aren't actually used for building, like README files. | +| `target_conditions` | Like `conditions`, but evaluation is delayed until the settings have been merged into an actual target. `target_conditions` may be used to place conditionals into a `target_defaults` section but have them still depend on specific target settings. | +| `target_name` | The name of a target being defined. | +| `type` | The type of target being defined. This field currently supports `executable`, `static_library`, `shared_library`, and `none`. The `none` target type is useful when producing output which is not linked. For example, converting raw translation files into resources or documentation into platform specific help files. | +| `msvs_props` | A list of Visual Studio property sheets (`.vsprops` files) to be used to build the target. | +| `xcode_config_file` | An Xcode configuration (`.xcconfig` file) to be used to build the target. | +| `xcode_framework_dirs` | A list of framework directories be used to build the target. | + +You can affect the way that lists/dictionaries are merged together (for +example the way a list in target\_defaults interacts with the same named +list in the target itself) with a couple of special characters, which +are covered in [Merge +Basics](InputFormatReference#Merge_Basics_(=,_?,_+).md) and [List +Filters](InputFormatReference#List_Filters.md) on the +InputFormatReference page. + +### configurations + +`configurations` sections may be found within `targets` or +`target_defaults` sections. The `configurations` section is a list of +dictionaries specifying different build configurations. Because +configurations are implemented as lists, it is not currently possible to +override aspects of configurations that are imported into a target from +a `target_defaults` section. + +NOTE: It is extremely important that each target within a project define +the same set of configurations. This continues to apply even when a +project spans across multiple `.gyp` files. + +A configuration dictionary may contain anything that can be found within +a target dictionary, except for `actions`, `all_dependent_settings`, +`configurations`, `dependencies`, `direct_dependent_settings`, +`libraries`, `link_settings`, `sources`, `target_name`, and `type`. + +Configuration dictionaries may also contain these elements: + +| *Keyword* | *Description* | +|:---------------------|:----------------------------------------------------| +| `configuration_name` | Required attribute. The name of the configuration. | + +### Conditionals + +Conditionals may appear within any dictionary in a `.gyp` file. There +are two tpes of conditionals, which differ only in the timing of their +processing. `conditions` sections are processed shortly after loading +`.gyp` files, and `target_conditions` sections are processed after all +dependencies have been computed. + +A conditional section is introduced with a `conditions` or +`target_conditions` dictionary keyword, and is composed of a list. Each +list contains two or three elements. The first two elements, which are +always required, are the conditional expression to evaluate and a +dictionary containing settings to merge into the dictionary containing +the `conditions` or `target_conditions` section if the expression +evaluates to true. The third, optional, list element is a dictionary to +merge if the expression evaluates to false. + +The `eval()` of the expression string takes place in the context of +global and/or local dictionaries that constructed from the `.gyp` input +data, and overrides the `__builtin__` dictionary, to prevent the +execution of arbitrary Python code. + +### Actions + +An `actions` section provides a list of custom build actions to perform +on inputs, producing outputs. The `actions` section is organized as a +list. Each item in the list is a dictionary having the following form: + +| *Keyword* | *Type* | *Description* | +|:--------------|:-------|:-----------------------------| +| `action_name` | string | The name of the action. Depending on how actions are implemented in the various generators, some may desire or require this property to be set to a unique name; others may ignore this property entirely. | +| `inputs` | list | A list of pathnames treated as inputs to the custom action. | +| `outputs` | list | A list of pathnames that the custom action produces. | +| `action` | list | A command line invocation used to produce `outputs` from `inputs`. For maximum cross-platform compatibility, invocations that require a Python interpreter should be specified with a first element `"python"`. This will enable generators for environments with specialized Python installations to be able to perform the action in an appropriate Python environment. | +| `message` | string | A message to be displayed to the user by the build system when the action is run. | + +Build environments will compare `inputs` and `outputs`. If any `output` +is missing or is outdated relative to any `input`, the custom action +will be invoked. If all `outputs` are present and newer than all +`inputs`, the `outputs` are considered up-to-date and the action need +not be invoked. + +Actions are implemented in Xcode as shell script build phases performed +prior to the compilation phase. In the Visual Studio generator, actions +appear files with a `FileConfiguration` containing a custom +`VCCustomBuildTool` specifying the remainder of the inputs, the outputs, +and the action. + +Combined with variable expansions, actions can be quite powerful. Here +is an example action that leverages variable expansions to minimize +duplication of pathnames: + +``` + 'sources': [ + # libraries.cc is generated by the js2c action below. + '<(INTERMEDIATE_DIR)/libraries.cc', + ], + 'actions': [ + { + 'variables': { + 'core_library_files': [ + 'src/runtime.js', + 'src/v8natives.js', + 'src/macros.py', + ], + }, + 'action_name': 'js2c', + 'inputs': [ + 'tools/js2c.py', + '<@(core_library_files)', + ], + 'outputs': [ + '<(INTERMEDIATE_DIR)/libraries.cc', + '<(INTERMEDIATE_DIR)/libraries-empty.cc', + ], + 'action': ['python', 'tools/js2c.py', '<@(_outputs)', 'CORE', '<@(core_library_files)'], + }, + ], +``` + +### Rules + +A `rules` section provides custom build action to perform on inputs, producing +outputs. The `rules` section is organized as a list. Each item in the list is +a dictionary having the following form: + +| *Keyword* | *Type* | *Description* | +|:------------|:-------|:-----------------------------------------| +| `rule_name` | string | The name of the rule. Depending on how Rules are implemented in the various generators, some may desire or require this property to be set to a unique name; others may ignore this property entirely. | +| `extension` | string | All source files of the current target with the given extension will be treated successively as inputs to the rule. | +| `inputs` | list | Additional dependencies of the rule. | +| `outputs` | list | A list of pathnames that the rule produces. Has access to `RULE_INPUT_` variables (see below). | +| `action` | list | A command line invocation used to produce `outputs` from `inputs`. For maximum cross-platform compatibility, invocations that require a Python interpreter should be specified with a first element `"python"`. This will enable generators for environments with specialized Python installations to be able to perform the action in an appropriate Python environment. Has access to `RULE_INPUT_` variables (see below). | +| `message` | string | A message to be displayed to the user by the build system when the action is run. Has access to `RULE_INPUT_` variables (see below). | + +There are several variables available to `outputs`, `action`, and `message`. + +| *Variable* | *Description* | +|:---------------------|:------------------------------------| +| `RULE_INPUT_PATH` | The full path to the current input. | +| `RULE_INPUT_DIRNAME` | The directory of the current input. | +| `RULE_INPUT_NAME` | The file name of the current input. | +| `RULE_INPUT_ROOT` | The file name of the current input without extension. | +| `RULE_INPUT_EXT` | The file name extension of the current input. | + +Rules can be thought of as Action generators. For each source selected +by `extension` an special action is created. This action starts out with +the same `inputs`, `outputs`, `action`, and `message` as the rule. The +source is added to the action's `inputs`. The `outputs`, `action`, and +`message` are then handled the same but with the additional variables. +If the `_output` variable is used in the `action` or `message` the +`RULE_INPUT_` variables in `output` will be expanded for the current +source. + +### Copies + +A `copies` section provides a simple means of copying files. The +`copies` section is organized as a list. Each item in the list is a +dictionary having the following form: + +| *Keyword* | *Type* | *Description* | +|:--------------|:-------|:------------------------------| +| `destination` | string | The directory into which the `files` will be copied. | +| `files` | list | A list of files to be copied. | + +The copies will be created in `destination` and have the same file name +as the file they are copied from. Even if the `files` are from multiple +directories they will all be copied into the `destination` directory. +Each `destination` file has an implicit build dependency on the file it +is copied from. + +### Generated Xcode .pbxproj Files + +We derive the following things in a `project.pbxproj` plist file within +an `.xcodeproj` bundle from the above input file formats as follows: + + * `Group hierarchy`: This is generated in a fixed format with contents + derived from the input files. There is no provision for the user to + specify additional groups or create a custom hierarchy. + * `Configuration group`: This will be used with the + `xcode_config_file` property above, if needed. + * `Source group`: The union of the `sources` lists of all `targets` + after applying appropriate `conditions`. The resulting list is + sorted and put into a group hierarchy that matches the layout of + the directory tree on disk, with a root of // (the top of the + hierarchy). + * `Frameworks group`: Taken directly from `libraries` value for the + target, after applying appropriate conditions. + * `Projects group`: References to other `.xcodeproj` bundles that + are needed by the `.xcodeproj` in which the group is contained. + * `Products group`: Output from the various targets. + * `Project References`: + * `Project Configurations`: + * Per-`.xcodeproj` file settings are not supported, all settings are + applied at the target level. + * `Targets`: + * `Phases`: Copy sources, link with libraries/frameworks, ... + * `Target Configurations`: Specified by input. + * `Dependencies`: (local and remote) + +### Generated Visual Studio .vcproj Files + +We derive the following sections in a `.vcproj` file from the above +input file formats as follows: + + * `VisualStudioProject`: + * `Platforms`: + * `ToolFiles`: + * `Configurations`: + * `Configuration`: + * `References`: + * `Files`: + * `Filter`: + * `File`: + * `FileConfiguration`: + * `Tool`: + * `Globals`: + +### Generated Visual Studio .sln Files + +We derive the following sections in a `.sln` file from the above input +file formats as follows: + + * `Projects`: + * `WebsiteProperties`: + * `ProjectDependencies`: + * `Global`: + * `SolutionConfigurationPlatforms`: + * `ProjectConfigurationPlatforms`: + * `SolutionProperties`: + * `NestedProjects`: + +## Caveats + +Notes/Question from very first prototype draft of the language. +Make sure these issues are addressed somewhere before deleting. + + * Libraries are easy, application abstraction is harder + * Applications involves resource compilation + * Applications involve many inputs + * Applications include transitive closure of dependencies + * Specific use cases like cc\_library + * Mac compiles more than just .c/.cpp files (specifically, .m and .mm + files) + * Compiler options vary by: + * File type + * Target type + * Individual file + * Files may have custom settings per file per platform, but we probably + don't care or need to support this in gyp. + * Will all linked non-Chromium projects always use the same versions of every + subsystem? + * Variants are difficult. We've identified the following variants (some + specific to Chromium, some typical of other projects in the same ballpark): + * Target platform + * V8 vs. JSC + * Debug vs. Release + * Toolchain (VS version, gcc, version) + * Host platform + * L10N + * Vendor + * Purify / Valgrind + * Will everyone upgrade VS at once? + * What does a dylib dependency mean? diff --git a/node_modules/node-gyp/gyp/docs/Testing.md b/node_modules/node-gyp/gyp/docs/Testing.md new file mode 100644 index 0000000000000..a52031e88819a --- /dev/null +++ b/node_modules/node-gyp/gyp/docs/Testing.md @@ -0,0 +1,450 @@ +# Testing + +NOTE: this document is outdated and needs to be updated. Read with your own discretion. + +## Introduction + +This document describes the GYP testing infrastructure, +as provided by the `TestGyp.py` module. + +These tests emphasize testing the _behavior_ of the +various GYP-generated build configurations: +Visual Studio, Xcode, SCons, Make, etc. +The goal is _not_ to test the output of the GYP generators by, +for example, comparing a GYP-generated Makefile +against a set of known "golden" Makefiles +(although the testing infrastructure could +be used to write those kinds of tests). +The idea is that the generated build configuration files +could be completely written to add a feature or fix a bug +so long as they continue to support the functional behaviors +defined by the tests: building programs, shared libraries, etc. + +## "Hello, world!" GYP test configuration + +Here is an actual test configuration, +a simple build of a C program to print `"Hello, world!"`. + +``` + $ ls -l test/hello + total 20 + -rw-r--r-- 1 knight knight 312 Jul 30 20:22 gyptest-all.py + -rw-r--r-- 1 knight knight 307 Jul 30 20:22 gyptest-default.py + -rwxr-xr-x 1 knight knight 326 Jul 30 20:22 gyptest-target.py + -rw-r--r-- 1 knight knight 98 Jul 30 20:22 hello.c + -rw-r--r-- 1 knight knight 142 Jul 30 20:22 hello.gyp + $ +``` + +The `gyptest-*.py` files are three separate tests (test scripts) +that use this configuration. The first one, `gyptest-all.py`, +looks like this: + +``` + #!/usr/bin/env python + + """ + Verifies simplest-possible build of a "Hello, world!" program + using an explicit build target of 'all'. + """ + + import TestGyp + + test = TestGyp.TestGyp() + + test.run_gyp('hello.gyp') + + test.build_all('hello.gyp') + + test.run_built_executable('hello', stdout="Hello, world!\n") + + test.pass_test() +``` + +The test script above runs GYP against the specified input file +(`hello.gyp`) to generate a build configuration. +It then tries to build the `'all'` target +(or its equivalent) using the generated build configuration. +Last, it verifies that the build worked as expected +by running the executable program (`hello`) +that was just presumably built by the generated configuration, +and verifies that the output from the program +matches the expected `stdout` string (`"Hello, world!\n"`). + +Which configuration is generated +(i.e., which build tool to test) +is specified when the test is run; +see the next section. + +Surrounding the functional parts of the test +described above are the header, +which should be basically the same for each test +(modulo a different description in the docstring): + +``` + #!/usr/bin/env python + + """ + Verifies simplest-possible build of a "Hello, world!" program + using an explicit build target of 'all'. + """ + + import TestGyp + + test = TestGyp.TestGyp() +``` + +Similarly, the footer should be the same in every test: + +``` + test.pass_test() +``` + +## Running tests + +Test scripts are run by the `gyptest.py` script. +You can specify (an) explicit test script(s) to run: + +``` + $ python gyptest.py test/hello/gyptest-all.py + PYTHONPATH=/home/knight/src/gyp/trunk/test/lib + TESTGYP_FORMAT=scons + /usr/bin/python test/hello/gyptest-all.py + PASSED + $ +``` + +If you specify a directory, all test scripts +(scripts prefixed with `gyptest-`) underneath +the directory will be run: + +``` + $ python gyptest.py test/hello + PYTHONPATH=/home/knight/src/gyp/trunk/test/lib + TESTGYP_FORMAT=scons + /usr/bin/python test/hello/gyptest-all.py + PASSED + /usr/bin/python test/hello/gyptest-default.py + PASSED + /usr/bin/python test/hello/gyptest-target.py + PASSED + $ +``` + +Or you can specify the `-a` option to run all scripts +in the tree: + +``` + $ python gyptest.py -a + PYTHONPATH=/home/knight/src/gyp/trunk/test/lib + TESTGYP_FORMAT=scons + /usr/bin/python test/configurations/gyptest-configurations.py + PASSED + /usr/bin/python test/defines/gyptest-defines.py + PASSED + . + . + . + . + /usr/bin/python test/variables/gyptest-commands.py + PASSED + $ +``` + +If any tests fail during the run, +the `gyptest.py` script will report them in a +summary at the end. + +## Debugging tests + +Tests that create intermediate output do so under the gyp/out/testworkarea +directory. On test completion, intermediate output is cleaned up. To preserve +this output, set the environment variable PRESERVE=1. This can be handy to +inspect intermediate data when debugging a test. + +You can also set PRESERVE\_PASS=1, PRESERVE\_FAIL=1 or PRESERVE\_NO\_RESULT=1 +to preserve output for tests that fall into one of those categories. + +# Specifying the format (build tool) to use + +By default, the `gyptest.py` script will generate configurations for +the "primary" supported build tool for the platform you're on: +Visual Studio on Windows, +Xcode on Mac, +and (currently) SCons on Linux. +An alternate format (build tool) may be specified +using the `-f` option: + +``` + $ python gyptest.py -f make test/hello/gyptest-all.py + PYTHONPATH=/home/knight/src/gyp/trunk/test/lib + TESTGYP_FORMAT=make + /usr/bin/python test/hello/gyptest-all.py + PASSED + $ +``` + +Multiple tools may be specified in a single pass as +a comma-separated list: + +``` + $ python gyptest.py -f make,scons test/hello/gyptest-all.py + PYTHONPATH=/home/knight/src/gyp/trunk/test/lib + TESTGYP_FORMAT=make + /usr/bin/python test/hello/gyptest-all.py + PASSED + TESTGYP_FORMAT=scons + /usr/bin/python test/hello/gyptest-all.py + PASSED + $ +``` + +## Test script functions and methods + +The `TestGyp` class contains a lot of functionality +intended to make it easy to write tests. +This section describes the most useful pieces for GYP testing. + +(The `TestGyp` class is actually a subclass of more generic +`TestCommon` and `TestCmd` base classes +that contain even more functionality than is +described here.) + +### Initialization + +The standard initialization formula is: + +``` + import TestGyp + test = TestGyp.TestGyp() +``` + +This copies the contents of the directory tree in which +the test script lives to a temporary directory for execution, +and arranges for the temporary directory's removal on exit. + +By default, any comparisons of output or file contents +must be exact matches for the test to pass. +If you need to use regular expressions for matches, +a useful alternative initialization is: + +``` + import TestGyp + test = TestGyp.TestGyp(match = TestGyp.match_re, + diff = TestGyp.diff_re)` +``` + +### Running GYP + +The canonical invocation is to simply specify the `.gyp` file to be executed: + +``` + test.run_gyp('file.gyp') +``` + +Additional GYP arguments may be specified: + +``` + test.run_gyp('file.gyp', arguments=['arg1', 'arg2', ...]) +``` + +To execute GYP from a subdirectory (where, presumably, the specified file +lives): + +``` + test.run_gyp('file.gyp', chdir='subdir') +``` + +### Running the build tool + +Running the build tool requires passing in a `.gyp` file, which may be used to +calculate the name of a specific build configuration file (such as a MSVS +solution file corresponding to the `.gyp` file). + +There are several different `.build_*()` methods for invoking different types +of builds. + +To invoke a build tool with an explicit `all` target (or equivalent): + +``` + test.build_all('file.gyp') +``` + +To invoke a build tool with its default behavior (for example, executing `make` +with no targets specified): + +``` + test.build_default('file.gyp') +``` + +To invoke a build tool with an explicit specified target: + +``` + test.build_target('file.gyp', 'target') +``` + +### Running executables + +The most useful method executes a program built by the GYP-generated +configuration: + +``` + test.run_built_executable('program') +``` + +The `.run_built_executable()` method will account for the actual built target +output location for the build tool being tested, as well as tack on any +necessary executable file suffix for the platform (for example `.exe` on +Windows). + +`stdout=` and `stderr=` keyword arguments specify expected standard output and +error output, respectively. Failure to match these (if specified) will cause +the test to fail. An explicit `None` value will suppress that verification: + +``` + test.run_built_executable('program', + stdout="expect this output\n", + stderr=None) +``` + +Note that the default values are `stdout=None` and `stderr=''` (that is, no +check for standard output, and error output must be empty). + +Arbitrary executables (not necessarily those built by GYP) can be executed with +the lower-level `.run()` method: + +``` + test.run('program') +``` + +The program must be in the local directory (that is, the temporary directory +for test execution) or be an absolute path name. + +### Fetching command output + +``` + test.stdout() +``` + +Returns the standard output from the most recent executed command (including +`.run_gyp()`, `.build_*()`, or `.run*()` methods). + +``` + test.stderr() +``` + +Returns the error output from the most recent executed command (including +`.run_gyp()`, `.build_*()`, or `.run*()` methods). + +### Verifying existence or non-existence of files or directories + +``` + test.must_exist('file_or_dir') +``` + +Verifies that the specified file or directory exists, and fails the test if it +doesn't. + +``` + test.must_not_exist('file_or_dir') +``` + +Verifies that the specified file or directory does not exist, and fails the +test if it does. + +### Verifying file contents + +``` + test.must_match('file', 'expected content\n') +``` + +Verifies that the content of the specified file match the expected string, and +fails the test if it does not. By default, the match must be exact, but +line-by-line regular expressions may be used if the `TestGyp` object was +initialized with `TestGyp.match_re`. + +``` + test.must_not_match('file', 'expected content\n') +``` + +Verifies that the content of the specified file does _not_ match the expected +string, and fails the test if it does. By default, the match must be exact, +but line-by-line regular expressions may be used if the `TestGyp` object was +initialized with `TestGyp.match_re`. + +``` + test.must_contain('file', 'substring') +``` + +Verifies that the specified file contains the specified substring, and fails +the test if it does not. + +``` + test.must_not_contain('file', 'substring') +``` + +Verifies that the specified file does not contain the specified substring, and +fails the test if it does. + +``` + test.must_contain_all_lines(output, lines) +``` + +Verifies that the output string contains all of the "lines" in the specified +list of lines. In practice, the lines can be any substring and need not be +`\n`-terminated lines per se. If any line is missing, the test fails. + +``` + test.must_not_contain_any_lines(output, lines) +``` + +Verifies that the output string does _not_ contain any of the "lines" in the +specified list of lines. In practice, the lines can be any substring and need +not be `\n`-terminated lines per se. If any line exists in the output string, +the test fails. + +``` + test.must_contain_any_line(output, lines) +``` + +Verifies that the output string contains at least one of the "lines" in the +specified list of lines. In practice, the lines can be any substring and need +not be `\n`-terminated lines per se. If none of the specified lines is present, +the test fails. + +### Reading file contents + +``` + test.read('file') +``` + +Returns the contents of the specified file. Directory elements contained in a +list will be joined: + +``` + test.read(['subdir', 'file']) +``` + +### Test success or failure + +``` + test.fail_test() +``` + +Fails the test, reporting `FAILED` on standard output and exiting with an exit +status of `1`. + +``` + test.pass_test() +``` + +Passes the test, reporting `PASSED` on standard output and exiting with an exit +status of `0`. + +``` + test.no_result() +``` + +Indicates the test had no valid result (i.e., the conditions could not be +tested because of an external factor like a full file system). Reports `NO +RESULT` on standard output and exits with a status of `2`. diff --git a/node_modules/node-gyp/gyp/docs/UserDocumentation.md b/node_modules/node-gyp/gyp/docs/UserDocumentation.md new file mode 100644 index 0000000000000..b9d412e1c847b --- /dev/null +++ b/node_modules/node-gyp/gyp/docs/UserDocumentation.md @@ -0,0 +1,965 @@ +# User Documentation + +## Introduction + +This document is intended to provide a user-level guide to GYP. The +emphasis here is on how to use GYP to accomplish specific tasks, not on +the complete technical language specification. (For that, see the +[LanguageSpecification](LanguageSpecification.md).) + +The document below starts with some overviews to provide context: an +overview of the structure of a `.gyp` file itself, an overview of a +typical executable-program target in a `.gyp` file, an an overview of a +typical library target in a `.gyp` file. + +After the overviews, there are examples of `gyp` patterns for different +common use cases. + +## Skeleton of a typical Chromium .gyp file + +Here is the skeleton of a typical `.gyp` file in the Chromium tree: + +``` + { + 'variables': { + . + . + . + }, + 'includes': [ + '../build/common.gypi', + ], + 'target_defaults': { + . + . + . + }, + 'targets': [ + { + 'target_name': 'target_1', + . + . + . + }, + { + 'target_name': 'target_2', + . + . + . + }, + ], + 'conditions': [ + ['OS=="linux"', { + 'targets': [ + { + 'target_name': 'linux_target_3', + . + . + . + }, + ], + }], + ['OS=="win"', { + 'targets': [ + { + 'target_name': 'windows_target_4', + . + . + . + }, + ], + }, { # OS != "win" + 'targets': [ + { + 'target_name': 'non_windows_target_5', + . + . + . + }, + }], + ], + } +``` + +The entire file just contains a Python dictionary. (It's actually JSON, +with two small Pythonic deviations: comments are introduced with `#`, +and a `,` (comma)) is legal after the last element in a list or +dictionary.) + +The top-level pieces in the `.gyp` file are as follows: + +`'variables'`: Definitions of variables that can be interpolated and +used in various other parts of the file. + +`'includes'`: A list of of other files that will be included in this +file. By convention, included files have the suffix `.gypi` (gyp +include). + +`'target_defaults'`: Settings that will apply to _all_ of the targets +defined in this `.gyp` file. + +`'targets'`: The list of targets for which this `.gyp` file can +generate builds. Each target is a dictionary that contains settings +describing all the information necessary to build the target. + +`'conditions'`: A list of condition specifications that can modify the +contents of the items in the global dictionary defined by this `.gyp` +file based on the values of different variables. As implied by the +above example, the most common use of a `conditions` section in the +top-level dictionary is to add platform-specific targets to the +`targets` list. + +## Skeleton of a typical executable target in a .gyp file + +The most straightforward target is probably a simple executable program. +Here is an example `executable` target that demonstrates the features +that should cover most simple uses of gyp: + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': 'executable', + 'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65', + 'dependencies': [ + 'xyzzy', + '../bar/bar.gyp:bar', + ], + 'defines': [ + 'DEFINE_FOO', + 'DEFINE_A_VALUE=value', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'file1.cc', + 'file2.cc', + ], + 'conditions': [ + ['OS=="linux"', { + 'defines': [ + 'LINUX_DEFINE', + ], + 'include_dirs': [ + 'include/linux', + ], + }], + ['OS=="win"', { + 'defines': [ + 'WINDOWS_SPECIFIC_DEFINE', + ], + }, { # OS != "win", + 'defines': [ + 'NON_WINDOWS_DEFINE', + ], + }] + ], + }, + ], + } +``` + +The top-level settings in the target include: + +`'target_name'`: The name by which the target should be known, which +should be unique across all `.gyp` files. This name will be used as the +project name in the generated Visual Studio solution, as the target name +in the generated XCode configuration, and as the alias for building this +target from the command line of the generated SCons configuration. + +`'type'`: Set to `executable`, logically enough. + +`'msvs_guid'`: THIS IS ONLY TRANSITIONAL. This is a hard-coded GUID +values that will be used in the generated Visual Studio solution +file(s). This allows us to check in a `chrome.sln` file that +interoperates with gyp-generated project files. Once everything in +Chromium is being generated by gyp, it will no longer be important that +the GUIDs stay constant across invocations, and we'll likely get rid of +these settings, + +`'dependencies'`: This lists other targets that this target depends on. +The gyp-generated files will guarantee that the other targets are built +before this target. Any library targets in the `dependencies` list will +be linked with this target. The various settings (`defines`, +`include_dirs`, etc.) listed in the `direct_dependent_settings` sections +of the targets in this list will be applied to how _this_ target is +built and linked. See the more complete discussion of +`direct_dependent_settings`, below. + +`'defines'`: The C preprocessor definitions that will be passed in on +compilation command lines (using `-D` or `/D` options). + +`'include_dirs'`: The directories in which included header files live. +These will be passed in on compilation command lines (using `-I` or `/I` +options). + +`'sources'`: The source files for this target. + +`'conditions'`: A block of conditions that will be evaluated to update +the different settings in the target dictionary. + +## Skeleton of a typical library target in a .gyp file + +The vast majority of targets are libraries. Here is an example of a +library target including the additional features that should cover most +needs of libraries: + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': '<(library)' + 'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65', + 'dependencies': [ + 'xyzzy', + '../bar/bar.gyp:bar', + ], + 'defines': [ + 'DEFINE_FOO', + 'DEFINE_A_VALUE=value', + ], + 'include_dirs': [ + '..', + ], + 'direct_dependent_settings': { + 'defines': [ + 'DEFINE_FOO', + 'DEFINE_ADDITIONAL', + ], + 'linkflags': [ + ], + }, + 'export_dependent_settings': [ + '../bar/bar.gyp:bar', + ], + 'sources': [ + 'file1.cc', + 'file2.cc', + ], + 'conditions': [ + ['OS=="linux"', { + 'defines': [ + 'LINUX_DEFINE', + ], + 'include_dirs': [ + 'include/linux', + ], + ], + ['OS=="win"', { + 'defines': [ + 'WINDOWS_SPECIFIC_DEFINE', + ], + }, { # OS != "win", + 'defines': [ + 'NON_WINDOWS_DEFINE', + ], + }] + ], + ], + } +``` + +The possible entries in a library target are largely the same as those +that can be specified for an executable target (`defines`, +`include_dirs`, etc.). The differences include: + +`'type'`: This should almost always be set to '<(library)', which allows +the user to define at gyp time whether libraries are to be built static +or shared. (On Linux, at least, linking with shared libraries saves +significant link time.) If it's necessary to pin down the type of +library to be built, the `type` can be set explicitly to +`static_library` or `shared_library`. + +`'direct_dependent_settings'`: This defines the settings that will be +applied to other targets that _directly depend_ on this target--that is, +that list _this_ target in their `'dependencies'` setting. This is +where you list the `defines`, `include_dirs`, `cflags` and `linkflags` +that other targets that compile or link against this target need to +build consistently. + +`'export_dependent_settings'`: This lists the targets whose +`direct_dependent_settings` should be "passed on" to other targets that +use (depend on) this target. `TODO: expand on this description.` + +## Use Cases + +These use cases are intended to cover the most common actions performed +by developers using GYP. + +Note that these examples are _not_ fully-functioning, self-contained +examples (or else they'd be way too long). Each example mostly contains +just the keywords and settings relevant to the example, with perhaps a +few extra keywords for context. The intent is to try to show the +specific pieces you need to pay attention to when doing something. +[NOTE: if practical use shows that these examples are confusing without +additional context, please add what's necessary to clarify things.] + +### Add new source files + +There are similar but slightly different patterns for adding a +platform-independent source file vs. adding a source file that only +builds on some of the supported platforms. + +#### Add a source file that builds on all platforms + +**Simplest possible case**: You are adding a file(s) that builds on all +platforms. + +Just add the file(s) to the `sources` list of the appropriate dictionary +in the `targets` list: + +``` + { + 'targets': [ + { + 'target_name': 'my_target', + 'type': 'executable', + 'sources': [ + '../other/file_1.cc', + 'new_file.cc', + 'subdir/file3.cc', + ], + }, + ], + }, +``` + +File path names are relative to the directory in which the `.gyp` file lives. + +Keep the list sorted alphabetically (unless there's a really, really, +_really_ good reason not to). + +#### Add a platform-specific source file + +##### Your platform-specific file is named `*_linux.{ext}`, `*_mac.{ext}`, `*_posix.{ext}` or `*_win.{ext}` + +The simplest way to add a platform-specific source file, assuming you're +adding a completely new file and get to name it, is to use one of the +following standard suffixes: + + * `_linux` (e.g. `foo_linux.cc`) + * `_mac` (e.g. `foo_mac.cc`) + * `_posix` (e.g. `foo_posix.cc`) + * `_win` (e.g. `foo_win.cc`) + +Simply add the file to the `sources` list of the appropriate dict within +the `targets` list, like you would any other source file. + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': 'executable', + 'sources': [ + 'independent.cc', + 'specific_win.cc', + ], + }, + ], + }, +``` + +The Chromium `.gyp` files all have appropriate `conditions` entries to +filter out the files that aren't appropriate for the current platform. +In the above example, the `specific_win.cc` file will be removed +automatically from the source-list on non-Windows builds. + +##### Your platform-specific file does not use an already-defined pattern + +If your platform-specific file does not contain a +`*_{linux,mac,posix,win}` substring (or some other pattern that's +already in the `conditions` for the target), and you can't change the +file name, there are two patterns that can be used. + +**Preferred**: Add the file to the `sources` list of the appropriate +dictionary within the `targets` list. Add an appropriate `conditions` +section to exclude the specific files name: + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': 'executable', + 'sources': [ + 'linux_specific.cc', + ], + 'conditions': [ + ['OS != "linux"', { + 'sources!': [ + # Linux-only; exclude on other platforms. + 'linux_specific.cc', + ] + }[, + ], + }, + ], + }, +``` + +Despite the duplicate listing, the above is generally preferred because +the `sources` list contains a useful global list of all sources on all +platforms with consistent sorting on all platforms. + +**Non-preferred**: In some situations, however, it might make sense to +list a platform-specific file only in a `conditions` section that +specifically _includes_ it in the `sources` list: + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': 'executable', + 'sources': [], + ['OS == "linux"', { + 'sources': [ + # Only add to sources list on Linux. + 'linux_specific.cc', + ] + }], + }, + ], + }, +``` + +The above two examples end up generating equivalent builds, with the +small exception that the `sources` lists will list the files in +different orders. (The first example defines explicitly where +`linux_specific.cc` appears in the list--perhaps in in the +middle--whereas the second example will always tack it on to the end of +the list.) + +**Including or excluding files using patterns**: There are more +complicated ways to construct a `sources` list based on patterns. See +`TODO` below. + +### Add a new executable + +An executable program is probably the most straightforward type of +target, since all it typically needs is a list of source files, some +compiler/linker settings (probably varied by platform), and some library +targets on which it depends and which must be used in the final link. + +#### Add an executable that builds on all platforms + +Add a dictionary defining the new executable target to the `targets` +list in the appropriate `.gyp` file. Example: + +``` + { + 'targets': [ + { + 'target_name': 'new_unit_tests', + 'type': 'executable', + 'defines': [ + 'FOO', + ], + 'include_dirs': [ + '..', + ], + 'dependencies': [ + 'other_target_in_this_file', + 'other_gyp2:target_in_other_gyp2', + ], + 'sources': [ + 'new_additional_source.cc', + 'new_unit_tests.cc', + ], + }, + ], + } +``` + +#### Add a platform-specific executable + +Add a dictionary defining the new executable target to the `targets` +list within an appropriate `conditions` block for the platform. The +`conditions` block should be a sibling to the top-level `targets` list: + +``` + { + 'targets': [ + ], + 'conditions': [ + ['OS=="win"', { + 'targets': [ + { + 'target_name': 'new_unit_tests', + 'type': 'executable', + 'defines': [ + 'FOO', + ], + 'include_dirs': [ + '..', + ], + 'dependencies': [ + 'other_target_in_this_file', + 'other_gyp2:target_in_other_gyp2', + ], + 'sources': [ + 'new_additional_source.cc', + 'new_unit_tests.cc', + ], + }, + ], + }], + ], + } +``` + +### Add settings to a target + +There are several different types of settings that can be defined for +any given target. + +#### Add new preprocessor definitions (`-D` or `/D` flags) + +New preprocessor definitions are added by the `defines` setting: + +``` + { + 'targets': [ + { + 'target_name': 'existing_target', + 'defines': [ + 'FOO', + 'BAR=some_value', + ], + }, + ], + }, +``` + +These may be specified directly in a target's settings, as in the above +example, or in a `conditions` section. + +#### Add a new include directory (`-I` or `/I` flags) + +New include directories are added by the `include_dirs` setting: + +``` + { + 'targets': [ + { + 'target_name': 'existing_target', + 'include_dirs': [ + '..', + 'include', + ], + }, + ], + }, +``` + +These may be specified directly in a target's settings, as in the above +example, or in a `conditions` section. + +#### Add new compiler flags + +Specific compiler flags can be added with the `cflags` setting: + +``` + { + 'targets': [ + { + 'target_name': 'existing_target', + 'conditions': [ + ['OS=="win"', { + 'cflags': [ + '/WX', + ], + }, { # OS != "win" + 'cflags': [ + '-Werror', + ], + }], + ], + }, + ], + }, +``` + +Because these flags will be specific to the actual compiler involved, +they will almost always be only set within a `conditions` section. + +#### Add new linker flags + +Setting linker flags is OS-specific. On linux and most non-mac posix +systems, they can be added with the `ldflags` setting: + +``` + { + 'targets': [ + { + 'target_name': 'existing_target', + 'conditions': [ + ['OS=="linux"', { + 'ldflags': [ + '-pthread', + ], + }], + ], + }, + ], + }, +``` + +Because these flags will be specific to the actual linker involved, +they will almost always be only set within a `conditions` section. + +On OS X, linker settings are set via `xcode_settings`, on Windows via +`msvs_settings`. + +#### Exclude settings on a platform + +Any given settings keyword (`defines`, `include_dirs`, etc.) has a +corresponding form with a trailing `!` (exclamation point) to remove +values from a setting. One useful example of this is to remove the +Linux `-Werror` flag from the global settings defined in +`build/common.gypi`: + +``` + { + 'targets': [ + { + 'target_name': 'third_party_target', + 'conditions': [ + ['OS=="linux"', { + 'cflags!': [ + '-Werror', + ], + }], + ], + }, + ], + }, +``` + +### Cross-compiling + +GYP has some (relatively limited) support for cross-compiling. + +If the variable `GYP_CROSSCOMPILE` or one of the toolchain-related +variables (like `CC_host` or `CC_target`) is set, GYP will think that +you wish to do a cross-compile. + +When cross-compiling, each target can be part of a "host" build, a +"target" build, or both. By default, the target is assumed to be (only) +part of the "target" build. The 'toolsets' property can be set on a +target to change the default. + +A target's dependencies are assumed to match the build type (so, if A +depends on B, by default that means that a target build of A depends on +a target build of B). You can explicitly depend on targets across +toolchains by specifying "#host" or "#target" in the dependencies list. +If GYP is not doing a cross-compile, the "#host" and "#target" will be +stripped as needed, so nothing breaks. + +### Add a new library + +TODO: write intro + +#### Add a library that builds on all platforms + +Add the a dictionary defining the new library target to the `targets` +list in the appropriate `.gyp` file. Example: + +``` + { + 'targets': [ + { + 'target_name': 'new_library', + 'type': '<(library)', + 'defines': [ + 'FOO', + 'BAR=some_value', + ], + 'include_dirs': [ + '..', + ], + 'dependencies': [ + 'other_target_in_this_file', + 'other_gyp2:target_in_other_gyp2', + ], + 'direct_dependent_settings': { + 'include_dirs': '.', + }, + 'export_dependent_settings': [ + 'other_target_in_this_file', + ], + 'sources': [ + 'new_additional_source.cc', + 'new_library.cc', + ], + }, + ], + } +``` + +The use of the `<(library)` variable above should be the default `type` +setting for most library targets, as it allows the developer to choose, +at `gyp` time, whether to build with static or shared libraries. +(Building with shared libraries saves a _lot_ of link time on Linux.) + +It may be necessary to build a specific library as a fixed type. Is so, +the `type` field can be hard-wired appropriately. For a static library: + +``` + 'type': 'static_library', +``` + +For a shared library: + +``` + 'type': 'shared_library', +``` + +#### Add a platform-specific library + +Add a dictionary defining the new library target to the `targets` list +within a `conditions` block that's a sibling to the top-level `targets` +list: + +``` + { + 'targets': [ + ], + 'conditions': [ + ['OS=="win"', { + 'targets': [ + { + 'target_name': 'new_library', + 'type': '<(library)', + 'defines': [ + 'FOO', + 'BAR=some_value', + ], + 'include_dirs': [ + '..', + ], + 'dependencies': [ + 'other_target_in_this_file', + 'other_gyp2:target_in_other_gyp2', + ], + 'direct_dependent_settings': { + 'include_dirs': '.', + }, + 'export_dependent_settings': [ + 'other_target_in_this_file', + ], + 'sources': [ + 'new_additional_source.cc', + 'new_library.cc', + ], + }, + ], + }], + ], + } +``` + +### Dependencies between targets + +GYP provides useful primitives for establishing dependencies between +targets, which need to be configured in the following situations. + +#### Linking with another library target + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'dependencies': [ + 'libbar', + ], + }, + { + 'target_name': 'libbar', + 'type': '<(library)', + 'sources': [ + ], + }, + ], + } +``` + +Note that if the library target is in a different `.gyp` file, you have +to specify the path to other `.gyp` file, relative to this `.gyp` file's +directory: + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'dependencies': [ + '../bar/bar.gyp:libbar', + ], + }, + ], + } +``` + +Adding a library often involves updating multiple `.gyp` files, adding +the target to the appropriate `.gyp` file (possibly a newly-added `.gyp` +file), and updating targets in the other `.gyp` files that depend on +(link with) the new library. + +#### Compiling with necessary flags for a library target dependency + +We need to build a library (often a third-party library) with specific +preprocessor definitions or command-line flags, and need to ensure that +targets that depend on the library build with the same settings. This +situation is handled by a `direct_dependent_settings` block: + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': 'executable', + 'dependencies': [ + 'libbar', + ], + }, + { + 'target_name': 'libbar', + 'type': '<(library)', + 'defines': [ + 'LOCAL_DEFINE_FOR_LIBBAR', + 'DEFINE_TO_USE_LIBBAR', + ], + 'include_dirs': [ + '..', + 'include/libbar', + ], + 'direct_dependent_settings': { + 'defines': [ + 'DEFINE_TO_USE_LIBBAR', + ], + 'include_dirs': [ + 'include/libbar', + ], + }, + }, + ], + } +``` + +In the above example, the sources of the `foo` executable will be +compiled with the options `-DDEFINE_TO_USE_LIBBAR -Iinclude/libbar`, +because of those settings' being listed in the +`direct_dependent_settings` block. + +Note that these settings will likely need to be replicated in the +settings for the library target itself, so that the library will build +with the same options. This does not prevent the target from defining +additional options for its "internal" use when compiling its own source +files. (In the above example, these are the `LOCAL_DEFINE_FOR_LIBBAR` +define, and the `..` entry in the `include_dirs` list.) + +#### When a library depends on an additional library at final link time + +``` + { + 'targets': [ + { + 'target_name': 'foo', + 'type': 'executable', + 'dependencies': [ + 'libbar', + ], + }, + { + 'target_name': 'libbar', + 'type': '<(library)', + 'dependencies': [ + 'libother' + ], + 'export_dependent_settings': [ + 'libother' + ], + }, + { + 'target_name': 'libother', + 'type': '<(library)', + 'direct_dependent_settings': { + 'defines': [ + 'DEFINE_FOR_LIBOTHER', + ], + 'include_dirs': [ + 'include/libother', + ], + }, + }, + ], + } +``` + +### Support for Mac OS X bundles + +gyp supports building bundles on OS X (.app, .framework, .bundle, etc). +Here is an example of this: + +``` + { + 'target_name': 'test_app', + 'product_name': 'Test App Gyp', + 'type': 'executable', + 'mac_bundle': 1, + 'sources': [ + 'main.m', + 'TestAppAppDelegate.h', + 'TestAppAppDelegate.m', + ], + 'mac_bundle_resources': [ + 'TestApp/English.lproj/InfoPlist.strings', + 'TestApp/English.lproj/MainMenu.xib', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework', + ], + }, + 'xcode_settings': { + 'INFOPLIST_FILE': 'TestApp/TestApp-Info.plist', + }, + }, +``` + +The `mac_bundle` key tells gyp that this target should be a bundle. +`executable` targets get extension `.app` by default, `shared_library` +targets get `.framework` – but you can change the bundle extensions by +setting `product_extension` if you want. Files listed in +`mac_bundle_resources` will be copied to the bundle's `Resource` folder +of the bundle. You can also set +`process_outputs_as_mac_bundle_resources` to 1 in actions and rules to +let the output of actions and rules be added to that folder (similar to +`process_outputs_as_sources`). If `product_name` is not set, the bundle +will be named after `target_name`as usual. + +### Move files (refactoring) + +TODO + +### Custom build steps + +TODO + +#### Adding an explicit build step to generate specific files + +TODO + +#### Adding a rule to handle files with a new suffix + +TODO + +### Build flavors + +TODO diff --git a/node_modules/node-gyp/gyp/gyp_main.py b/node_modules/node-gyp/gyp/gyp_main.py index f23dcdf882d1b..bf16987485146 100755 --- a/node_modules/node-gyp/gyp/gyp_main.py +++ b/node_modules/node-gyp/gyp/gyp_main.py @@ -5,8 +5,8 @@ # found in the LICENSE file. import os -import sys import subprocess +import sys def IsCygwin(): diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py index d6b189760cef9..9149f404a5ade 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py @@ -32,20 +32,20 @@ def cmp(x, y): def MakeGuid(name, seed="msvs_new"): """Returns a GUID for the specified target name. - Args: - name: Target name. - seed: Seed for MD5 hash. - Returns: - A GUID-line string calculated from the name and seed. - - This generates something which looks like a GUID, but depends only on the - name and seed. This means the same name/seed will always generate the same - GUID, so that projects and solutions which refer to each other can explicitly - determine the GUID to refer to explicitly. It also means that the GUID will - not change when the project for a target is rebuilt. - """ - # Calculate a MD5 signature for the seed and name. - d = hashlib.md5((str(seed) + str(name)).encode("utf-8")).hexdigest().upper() + Args: + name: Target name. + seed: Seed for SHA-256 hash. + Returns: + A GUID-line string calculated from the name and seed. + + This generates something which looks like a GUID, but depends only on the + name and seed. This means the same name/seed will always generate the same + GUID, so that projects and solutions which refer to each other can explicitly + determine the GUID to refer to explicitly. It also means that the GUID will + not change when the project for a target is rebuilt. + """ + # Calculate a SHA-256 signature for the seed and name. + d = hashlib.sha256((str(seed) + str(name)).encode("utf-8")).hexdigest().upper() # Convert most of the signature to GUID form (discard the rest) guid = ( "{" @@ -78,15 +78,15 @@ class MSVSFolder(MSVSSolutionEntry): def __init__(self, path, name=None, entries=None, guid=None, items=None): """Initializes the folder. - Args: - path: Full path to the folder. - name: Name of the folder. - entries: List of folder entries to nest inside this folder. May contain - Folder or Project objects. May be None, if the folder is empty. - guid: GUID to use for folder, if not None. - items: List of solution items to include in the folder project. May be - None, if the folder does not directly contain items. - """ + Args: + path: Full path to the folder. + name: Name of the folder. + entries: List of folder entries to nest inside this folder. May contain + Folder or Project objects. May be None, if the folder is empty. + guid: GUID to use for folder, if not None. + items: List of solution items to include in the folder project. May be + None, if the folder does not directly contain items. + """ if name: self.name = name else: @@ -128,19 +128,19 @@ def __init__( ): """Initializes the project. - Args: - path: Absolute path to the project file. - name: Name of project. If None, the name will be the same as the base - name of the project file. - dependencies: List of other Project objects this project is dependent - upon, if not None. - guid: GUID to use for project, if not None. - spec: Dictionary specifying how to build this project. - build_file: Filename of the .gyp file that the vcproj file comes from. - config_platform_overrides: optional dict of configuration platforms to - used in place of the default for this target. - fixpath_prefix: the path used to adjust the behavior of _fixpath - """ + Args: + path: Absolute path to the project file. + name: Name of project. If None, the name will be the same as the base + name of the project file. + dependencies: List of other Project objects this project is dependent + upon, if not None. + guid: GUID to use for project, if not None. + spec: Dictionary specifying how to build this project. + build_file: Filename of the .gyp file that the vcproj file comes from. + config_platform_overrides: optional dict of configuration platforms to + used in place of the default for this target. + fixpath_prefix: the path used to adjust the behavior of _fixpath + """ self.path = path self.guid = guid self.spec = spec @@ -195,16 +195,16 @@ def __init__( ): """Initializes the solution. - Args: - path: Path to solution file. - version: Format version to emit. - entries: List of entries in solution. May contain Folder or Project - objects. May be None, if the folder is empty. - variants: List of build variant strings. If none, a default list will - be used. - websiteProperties: Flag to decide if the website properties section - is generated. - """ + Args: + path: Path to solution file. + version: Format version to emit. + entries: List of entries in solution. May contain Folder or Project + objects. May be None, if the folder is empty. + variants: List of build variant strings. If none, a default list will + be used. + websiteProperties: Flag to decide if the website properties section + is generated. + """ self.path = path self.websiteProperties = websiteProperties self.version = version @@ -230,9 +230,9 @@ def __init__( def Write(self, writer=gyp.common.WriteOnDiff): """Writes the solution file to disk. - Raises: - IndexError: An entry appears multiple times. - """ + Raises: + IndexError: An entry appears multiple times. + """ # Walk the entry tree and collect all the folders and projects. all_entries = set() entries_to_check = self.entries[:] @@ -285,19 +285,17 @@ def Write(self, writer=gyp.common.WriteOnDiff): "\tEndProjectSection\r\n" ) - if isinstance(e, MSVSFolder): - if e.items: - f.write("\tProjectSection(SolutionItems) = preProject\r\n") - for i in e.items: - f.write(f"\t\t{i} = {i}\r\n") - f.write("\tEndProjectSection\r\n") + if isinstance(e, MSVSFolder) and e.items: + f.write("\tProjectSection(SolutionItems) = preProject\r\n") + for i in e.items: + f.write(f"\t\t{i} = {i}\r\n") + f.write("\tEndProjectSection\r\n") - if isinstance(e, MSVSProject): - if e.dependencies: - f.write("\tProjectSection(ProjectDependencies) = postProject\r\n") - for d in e.dependencies: - f.write(f"\t\t{d.get_guid()} = {d.get_guid()}\r\n") - f.write("\tEndProjectSection\r\n") + if isinstance(e, MSVSProject) and e.dependencies: + f.write("\tProjectSection(ProjectDependencies) = postProject\r\n") + for d in e.dependencies: + f.write(f"\t\t{d.get_guid()} = {d.get_guid()}\r\n") + f.write("\tEndProjectSection\r\n") f.write("EndProject\r\n") @@ -353,7 +351,7 @@ def Write(self, writer=gyp.common.WriteOnDiff): # Folder mappings # Omit this section if there are no folders - if any([e.entries for e in all_entries if isinstance(e, MSVSFolder)]): + if any(e.entries for e in all_entries if isinstance(e, MSVSFolder)): f.write("\tGlobalSection(NestedProjects) = preSolution\r\n") for e in all_entries: if not isinstance(e, MSVSFolder): diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py index f0cfabe834909..17bb2bbdb8a55 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py @@ -4,7 +4,7 @@ """Visual Studio project reader/writer.""" -import gyp.easy_xml as easy_xml +from gyp import easy_xml # ------------------------------------------------------------------------------ @@ -15,19 +15,19 @@ class Tool: def __init__(self, name, attrs=None): """Initializes the tool. - Args: - name: Tool name. - attrs: Dict of tool attributes; may be None. - """ + Args: + name: Tool name. + attrs: Dict of tool attributes; may be None. + """ self._attrs = attrs or {} self._attrs["Name"] = name def _GetSpecification(self): """Creates an element for the tool. - Returns: - A new xml.dom.Element for the tool. - """ + Returns: + A new xml.dom.Element for the tool. + """ return ["Tool", self._attrs] @@ -37,10 +37,10 @@ class Filter: def __init__(self, name, contents=None): """Initializes the folder. - Args: - name: Filter (folder) name. - contents: List of filenames and/or Filter objects contained. - """ + Args: + name: Filter (folder) name. + contents: List of filenames and/or Filter objects contained. + """ self.name = name self.contents = list(contents or []) @@ -54,13 +54,13 @@ class Writer: def __init__(self, project_path, version, name, guid=None, platforms=None): """Initializes the project. - Args: - project_path: Path to the project file. - version: Format version to emit. - name: Name of the project. - guid: GUID to use for project, if not None. - platforms: Array of string, the supported platforms. If null, ['Win32'] - """ + Args: + project_path: Path to the project file. + version: Format version to emit. + name: Name of the project. + guid: GUID to use for project, if not None. + platforms: Array of string, the supported platforms. If null, ['Win32'] + """ self.project_path = project_path self.version = version self.name = name @@ -79,26 +79,26 @@ def __init__(self, project_path, version, name, guid=None, platforms=None): self.files_section = ["Files"] # Keep a dict keyed on filename to speed up access. - self.files_dict = dict() + self.files_dict = {} def AddToolFile(self, path): """Adds a tool file to the project. - Args: - path: Relative path from project to tool file. - """ + Args: + path: Relative path from project to tool file. + """ self.tool_files_section.append(["ToolFile", {"RelativePath": path}]) def _GetSpecForConfiguration(self, config_type, config_name, attrs, tools): """Returns the specification for a configuration. - Args: - config_type: Type of configuration node. - config_name: Configuration name. - attrs: Dict of configuration attributes; may be None. - tools: List of tools (strings or Tool objects); may be None. - Returns: - """ + Args: + config_type: Type of configuration node. + config_name: Configuration name. + attrs: Dict of configuration attributes; may be None. + tools: List of tools (strings or Tool objects); may be None. + Returns: + """ # Handle defaults if not attrs: attrs = {} @@ -122,23 +122,23 @@ def _GetSpecForConfiguration(self, config_type, config_name, attrs, tools): def AddConfig(self, name, attrs=None, tools=None): """Adds a configuration to the project. - Args: - name: Configuration name. - attrs: Dict of configuration attributes; may be None. - tools: List of tools (strings or Tool objects); may be None. - """ + Args: + name: Configuration name. + attrs: Dict of configuration attributes; may be None. + tools: List of tools (strings or Tool objects); may be None. + """ spec = self._GetSpecForConfiguration("Configuration", name, attrs, tools) self.configurations_section.append(spec) def _AddFilesToNode(self, parent, files): """Adds files and/or filters to the parent node. - Args: - parent: Destination node - files: A list of Filter objects and/or relative paths to files. + Args: + parent: Destination node + files: A list of Filter objects and/or relative paths to files. - Will call itself recursively, if the files list contains Filter objects. - """ + Will call itself recursively, if the files list contains Filter objects. + """ for f in files: if isinstance(f, Filter): node = ["Filter", {"Name": f.name}] @@ -151,13 +151,13 @@ def _AddFilesToNode(self, parent, files): def AddFiles(self, files): """Adds files to the project. - Args: - files: A list of Filter objects and/or relative paths to files. + Args: + files: A list of Filter objects and/or relative paths to files. - This makes a copy of the file/filter tree at the time of this call. If you - later add files to a Filter object which was passed into a previous call - to AddFiles(), it will not be reflected in this project. - """ + This makes a copy of the file/filter tree at the time of this call. If you + later add files to a Filter object which was passed into a previous call + to AddFiles(), it will not be reflected in this project. + """ self._AddFilesToNode(self.files_section, files) # TODO(rspangler) This also doesn't handle adding files to an existing # filter. That is, it doesn't merge the trees. @@ -165,15 +165,15 @@ def AddFiles(self, files): def AddFileConfig(self, path, config, attrs=None, tools=None): """Adds a configuration to a file. - Args: - path: Relative path to the file. - config: Name of configuration to add. - attrs: Dict of configuration attributes; may be None. - tools: List of tools (strings or Tool objects); may be None. + Args: + path: Relative path to the file. + config: Name of configuration to add. + attrs: Dict of configuration attributes; may be None. + tools: List of tools (strings or Tool objects); may be None. - Raises: - ValueError: Relative path does not match any file added via AddFiles(). - """ + Raises: + ValueError: Relative path does not match any file added via AddFiles(). + """ # Find the file node with the right relative path parent = self.files_dict.get(path) if not parent: diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py index e89a971a3bb4f..155fc3a1cbc69 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py @@ -35,10 +35,10 @@ class _Tool: """Represents a tool used by MSVS or MSBuild. - Attributes: - msvs_name: The name of the tool in MSVS. - msbuild_name: The name of the tool in MSBuild. - """ + Attributes: + msvs_name: The name of the tool in MSVS. + msbuild_name: The name of the tool in MSBuild. + """ def __init__(self, msvs_name, msbuild_name): self.msvs_name = msvs_name @@ -48,11 +48,11 @@ def __init__(self, msvs_name, msbuild_name): def _AddTool(tool): """Adds a tool to the four dictionaries used to process settings. - This only defines the tool. Each setting also needs to be added. + This only defines the tool. Each setting also needs to be added. - Args: - tool: The _Tool object to be added. - """ + Args: + tool: The _Tool object to be added. + """ _msvs_validators[tool.msvs_name] = {} _msbuild_validators[tool.msbuild_name] = {} _msvs_to_msbuild_converters[tool.msvs_name] = {} @@ -70,35 +70,35 @@ class _Type: def ValidateMSVS(self, value): """Verifies that the value is legal for MSVS. - Args: - value: the value to check for this type. + Args: + value: the value to check for this type. - Raises: - ValueError if value is not valid for MSVS. - """ + Raises: + ValueError if value is not valid for MSVS. + """ def ValidateMSBuild(self, value): """Verifies that the value is legal for MSBuild. - Args: - value: the value to check for this type. + Args: + value: the value to check for this type. - Raises: - ValueError if value is not valid for MSBuild. - """ + Raises: + ValueError if value is not valid for MSBuild. + """ def ConvertToMSBuild(self, value): """Returns the MSBuild equivalent of the MSVS value given. - Args: - value: the MSVS value to convert. + Args: + value: the MSVS value to convert. - Returns: - the MSBuild equivalent. + Returns: + the MSBuild equivalent. - Raises: - ValueError if value is not valid. - """ + Raises: + ValueError if value is not valid. + """ return value @@ -141,7 +141,7 @@ class _Boolean(_Type): """Boolean settings, can have the values 'false' or 'true'.""" def _Validate(self, value): - if value != "true" and value != "false": + if value not in {"true", "false"}: raise ValueError("expected bool; got %r" % value) def ValidateMSVS(self, value): @@ -171,22 +171,22 @@ def ValidateMSBuild(self, value): int(value, self._msbuild_base) def ConvertToMSBuild(self, value): - msbuild_format = (self._msbuild_base == 10) and "%d" or "0x%04x" + msbuild_format = ((self._msbuild_base == 10) and "%d") or "0x%04x" return msbuild_format % int(value) class _Enumeration(_Type): """Type of settings that is an enumeration. - In MSVS, the values are indexes like '0', '1', and '2'. - MSBuild uses text labels that are more representative, like 'Win32'. + In MSVS, the values are indexes like '0', '1', and '2'. + MSBuild uses text labels that are more representative, like 'Win32'. - Constructor args: - label_list: an array of MSBuild labels that correspond to the MSVS index. - In the rare cases where MSVS has skipped an index value, None is - used in the array to indicate the unused spot. - new: an array of labels that are new to MSBuild. - """ + Constructor args: + label_list: an array of MSBuild labels that correspond to the MSVS index. + In the rare cases where MSVS has skipped an index value, None is + used in the array to indicate the unused spot. + new: an array of labels that are new to MSBuild. + """ def __init__(self, label_list, new=None): _Type.__init__(self) @@ -234,23 +234,23 @@ def ConvertToMSBuild(self, value): def _Same(tool, name, setting_type): """Defines a setting that has the same name in MSVS and MSBuild. - Args: - tool: a dictionary that gives the names of the tool for MSVS and MSBuild. - name: the name of the setting. - setting_type: the type of this setting. - """ + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + name: the name of the setting. + setting_type: the type of this setting. + """ _Renamed(tool, name, name, setting_type) def _Renamed(tool, msvs_name, msbuild_name, setting_type): """Defines a setting for which the name has changed. - Args: - tool: a dictionary that gives the names of the tool for MSVS and MSBuild. - msvs_name: the name of the MSVS setting. - msbuild_name: the name of the MSBuild setting. - setting_type: the type of this setting. - """ + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + msvs_name: the name of the MSVS setting. + msbuild_name: the name of the MSBuild setting. + setting_type: the type of this setting. + """ def _Translate(value, msbuild_settings): msbuild_tool_settings = _GetMSBuildToolSettings(msbuild_settings, tool) @@ -272,13 +272,13 @@ def _MovedAndRenamed( ): """Defines a setting that may have moved to a new section. - Args: - tool: a dictionary that gives the names of the tool for MSVS and MSBuild. - msvs_settings_name: the MSVS name of the setting. - msbuild_tool_name: the name of the MSBuild tool to place the setting under. - msbuild_settings_name: the MSBuild name of the setting. - setting_type: the type of this setting. - """ + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + msvs_settings_name: the MSVS name of the setting. + msbuild_tool_name: the name of the MSBuild tool to place the setting under. + msbuild_settings_name: the MSBuild name of the setting. + setting_type: the type of this setting. + """ def _Translate(value, msbuild_settings): tool_settings = msbuild_settings.setdefault(msbuild_tool_name, {}) @@ -293,11 +293,11 @@ def _Translate(value, msbuild_settings): def _MSVSOnly(tool, name, setting_type): """Defines a setting that is only found in MSVS. - Args: - tool: a dictionary that gives the names of the tool for MSVS and MSBuild. - name: the name of the setting. - setting_type: the type of this setting. - """ + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + name: the name of the setting. + setting_type: the type of this setting. + """ def _Translate(unused_value, unused_msbuild_settings): # Since this is for MSVS only settings, no translation will happen. @@ -310,11 +310,11 @@ def _Translate(unused_value, unused_msbuild_settings): def _MSBuildOnly(tool, name, setting_type): """Defines a setting that is only found in MSBuild. - Args: - tool: a dictionary that gives the names of the tool for MSVS and MSBuild. - name: the name of the setting. - setting_type: the type of this setting. - """ + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + name: the name of the setting. + setting_type: the type of this setting. + """ def _Translate(value, msbuild_settings): # Let msbuild-only properties get translated as-is from msvs_settings. @@ -328,11 +328,11 @@ def _Translate(value, msbuild_settings): def _ConvertedToAdditionalOption(tool, msvs_name, flag): """Defines a setting that's handled via a command line option in MSBuild. - Args: - tool: a dictionary that gives the names of the tool for MSVS and MSBuild. - msvs_name: the name of the MSVS setting that if 'true' becomes a flag - flag: the flag to insert at the end of the AdditionalOptions - """ + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + msvs_name: the name of the MSVS setting that if 'true' becomes a flag + flag: the flag to insert at the end of the AdditionalOptions + """ def _Translate(value, msbuild_settings): if value == "true": @@ -384,20 +384,19 @@ def _Translate(value, msbuild_settings): def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr): """Verify that 'setting' is valid if it is generated from an exclusion list. - If the setting appears to be generated from an exclusion list, the root name - is checked. + If the setting appears to be generated from an exclusion list, the root name + is checked. - Args: - setting: A string that is the setting name to validate - settings: A dictionary where the keys are valid settings - error_msg: The message to emit in the event of error - stderr: The stream receiving the error messages. - """ + Args: + setting: A string that is the setting name to validate + settings: A dictionary where the keys are valid settings + error_msg: The message to emit in the event of error + stderr: The stream receiving the error messages. + """ # This may be unrecognized because it's an exclusion list. If the # setting name has the _excluded suffix, then check the root name. unrecognized = True - m = re.match(_EXCLUDED_SUFFIX_RE, setting) - if m: + if m := re.match(_EXCLUDED_SUFFIX_RE, setting): root_setting = m.group(1) unrecognized = root_setting not in settings @@ -409,11 +408,11 @@ def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr): def FixVCMacroSlashes(s): """Replace macros which have excessive following slashes. - These macros are known to have a built-in trailing slash. Furthermore, many - scripts hiccup on processing paths with extra slashes in the middle. + These macros are known to have a built-in trailing slash. Furthermore, many + scripts hiccup on processing paths with extra slashes in the middle. - This list is probably not exhaustive. Add as needed. - """ + This list is probably not exhaustive. Add as needed. + """ if "$" in s: s = fix_vc_macro_slashes_regex.sub(r"\1", s) return s @@ -422,8 +421,8 @@ def FixVCMacroSlashes(s): def ConvertVCMacrosToMSBuild(s): """Convert the MSVS macros found in the string to the MSBuild equivalent. - This list is probably not exhaustive. Add as needed. - """ + This list is probably not exhaustive. Add as needed. + """ if "$" in s: replace_map = { "$(ConfigurationName)": "$(Configuration)", @@ -445,16 +444,16 @@ def ConvertVCMacrosToMSBuild(s): def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): """Converts MSVS settings (VS2008 and earlier) to MSBuild settings (VS2010+). - Args: - msvs_settings: A dictionary. The key is the tool name. The values are - themselves dictionaries of settings and their values. - stderr: The stream receiving the error messages. + Args: + msvs_settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. - Returns: - A dictionary of MSBuild settings. The key is either the MSBuild tool name - or the empty string (for the global settings). The values are themselves - dictionaries of settings and their values. - """ + Returns: + A dictionary of MSBuild settings. The key is either the MSBuild tool name + or the empty string (for the global settings). The values are themselves + dictionaries of settings and their values. + """ msbuild_settings = {} for msvs_tool_name, msvs_tool_settings in msvs_settings.items(): if msvs_tool_name in _msvs_to_msbuild_converters: @@ -493,36 +492,36 @@ def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): def ValidateMSVSSettings(settings, stderr=sys.stderr): """Validates that the names of the settings are valid for MSVS. - Args: - settings: A dictionary. The key is the tool name. The values are - themselves dictionaries of settings and their values. - stderr: The stream receiving the error messages. - """ + Args: + settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + """ _ValidateSettings(_msvs_validators, settings, stderr) def ValidateMSBuildSettings(settings, stderr=sys.stderr): """Validates that the names of the settings are valid for MSBuild. - Args: - settings: A dictionary. The key is the tool name. The values are - themselves dictionaries of settings and their values. - stderr: The stream receiving the error messages. - """ + Args: + settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + """ _ValidateSettings(_msbuild_validators, settings, stderr) def _ValidateSettings(validators, settings, stderr): """Validates that the settings are valid for MSBuild or MSVS. - We currently only validate the names of the settings, not their values. + We currently only validate the names of the settings, not their values. - Args: - validators: A dictionary of tools and their validators. - settings: A dictionary. The key is the tool name. The values are - themselves dictionaries of settings and their values. - stderr: The stream receiving the error messages. - """ + Args: + validators: A dictionary of tools and their validators. + settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + """ for tool_name in settings: if tool_name in validators: tool_validators = validators[tool_name] @@ -638,7 +637,9 @@ def _ValidateSettings(validators, settings, stderr): ), ) # /RTC1 _Same( - _compile, "BrowseInformation", _Enumeration(["false", "true", "true"]) # /FR + _compile, + "BrowseInformation", + _Enumeration(["false", "true", "true"]), # /FR ) # /Fr _Same( _compile, @@ -696,7 +697,9 @@ def _ValidateSettings(validators, settings, stderr): _Enumeration(["false", "Sync", "Async"], new=["SyncCThrow"]), # /EHsc # /EHa ) # /EHs _Same( - _compile, "FavorSizeOrSpeed", _Enumeration(["Neither", "Speed", "Size"]) # /Ot + _compile, + "FavorSizeOrSpeed", + _Enumeration(["Neither", "Speed", "Size"]), # /Ot ) # /Os _Same( _compile, @@ -793,6 +796,8 @@ def _ValidateSettings(validators, settings, stderr): _compile, "CompileAsManaged", _Enumeration([], new=["false", "true"]) ) # /clr _MSBuildOnly(_compile, "CreateHotpatchableImage", _boolean) # /hotpatch +_MSBuildOnly(_compile, "LanguageStandard", _string) +_MSBuildOnly(_compile, "LanguageStandard_C", _string) _MSBuildOnly(_compile, "MultiProcessorCompilation", _boolean) # /MP _MSBuildOnly(_compile, "PreprocessOutputPath", _string) # /Fi _MSBuildOnly(_compile, "ProcessorNumber", _integer) # the number of processors @@ -907,7 +912,9 @@ def _ValidateSettings(validators, settings, stderr): ) # /MACHINE:X64 _Same( - _link, "AssemblyDebug", _Enumeration(["", "true", "false"]) # /ASSEMBLYDEBUG + _link, + "AssemblyDebug", + _Enumeration(["", "true", "false"]), # /ASSEMBLYDEBUG ) # /ASSEMBLYDEBUG:DISABLE _Same( _link, @@ -1157,17 +1164,23 @@ def _ValidateSettings(validators, settings, stderr): _MSBuildOnly(_midl, "ApplicationConfigurationMode", _boolean) # /app_config _MSBuildOnly(_midl, "ClientStubFile", _file_name) # /cstub _MSBuildOnly( - _midl, "GenerateClientFiles", _Enumeration([], new=["Stub", "None"]) # /client stub + _midl, + "GenerateClientFiles", + _Enumeration([], new=["Stub", "None"]), # /client stub ) # /client none _MSBuildOnly( - _midl, "GenerateServerFiles", _Enumeration([], new=["Stub", "None"]) # /client stub + _midl, + "GenerateServerFiles", + _Enumeration([], new=["Stub", "None"]), # /client stub ) # /client none _MSBuildOnly(_midl, "LocaleID", _integer) # /lcid DECIMAL _MSBuildOnly(_midl, "ServerStubFile", _file_name) # /sstub _MSBuildOnly(_midl, "SuppressCompilerWarnings", _boolean) # /no_warn _MSBuildOnly(_midl, "TrackerLogDirectory", _folder_name) _MSBuildOnly( - _midl, "TypeLibFormat", _Enumeration([], new=["NewFormat", "OldFormat"]) # /newtlb + _midl, + "TypeLibFormat", + _Enumeration([], new=["NewFormat", "OldFormat"]), # /newtlb ) # /oldtlb diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py index 6ca09687ad7f1..0e661995fbcd9 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py @@ -7,10 +7,10 @@ """Unit tests for the MSVSSettings.py file.""" import unittest -import gyp.MSVSSettings as MSVSSettings - from io import StringIO +from gyp import MSVSSettings + class TestSequenceFunctions(unittest.TestCase): def setUp(self): @@ -1143,47 +1143,47 @@ def testConvertToMSBuildSettings_full_synthetic(self): def testConvertToMSBuildSettings_actual(self): """Tests the conversion of an actual project. - A VS2008 project with most of the options defined was created through the - VS2008 IDE. It was then converted to VS2010. The tool settings found in - the .vcproj and .vcxproj files were converted to the two dictionaries - msvs_settings and expected_msbuild_settings. + A VS2008 project with most of the options defined was created through the + VS2008 IDE. It was then converted to VS2010. The tool settings found in + the .vcproj and .vcxproj files were converted to the two dictionaries + msvs_settings and expected_msbuild_settings. - Note that for many settings, the VS2010 converter adds macros like - %(AdditionalIncludeDirectories) to make sure than inherited values are - included. Since the Gyp projects we generate do not use inheritance, - we removed these macros. They were: - ClCompile: - AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)' - AdditionalOptions: ' %(AdditionalOptions)' - AdditionalUsingDirectories: ';%(AdditionalUsingDirectories)' - DisableSpecificWarnings: ';%(DisableSpecificWarnings)', - ForcedIncludeFiles: ';%(ForcedIncludeFiles)', - ForcedUsingFiles: ';%(ForcedUsingFiles)', - PreprocessorDefinitions: ';%(PreprocessorDefinitions)', - UndefinePreprocessorDefinitions: - ';%(UndefinePreprocessorDefinitions)', - Link: - AdditionalDependencies: ';%(AdditionalDependencies)', - AdditionalLibraryDirectories: ';%(AdditionalLibraryDirectories)', - AdditionalManifestDependencies: - ';%(AdditionalManifestDependencies)', - AdditionalOptions: ' %(AdditionalOptions)', - AddModuleNamesToAssembly: ';%(AddModuleNamesToAssembly)', - AssemblyLinkResource: ';%(AssemblyLinkResource)', - DelayLoadDLLs: ';%(DelayLoadDLLs)', - EmbedManagedResourceFile: ';%(EmbedManagedResourceFile)', - ForceSymbolReferences: ';%(ForceSymbolReferences)', - IgnoreSpecificDefaultLibraries: - ';%(IgnoreSpecificDefaultLibraries)', - ResourceCompile: - AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)', - AdditionalOptions: ' %(AdditionalOptions)', - PreprocessorDefinitions: ';%(PreprocessorDefinitions)', - Manifest: - AdditionalManifestFiles: ';%(AdditionalManifestFiles)', - AdditionalOptions: ' %(AdditionalOptions)', - InputResourceManifests: ';%(InputResourceManifests)', - """ + Note that for many settings, the VS2010 converter adds macros like + %(AdditionalIncludeDirectories) to make sure than inherited values are + included. Since the Gyp projects we generate do not use inheritance, + we removed these macros. They were: + ClCompile: + AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)' + AdditionalOptions: ' %(AdditionalOptions)' + AdditionalUsingDirectories: ';%(AdditionalUsingDirectories)' + DisableSpecificWarnings: ';%(DisableSpecificWarnings)', + ForcedIncludeFiles: ';%(ForcedIncludeFiles)', + ForcedUsingFiles: ';%(ForcedUsingFiles)', + PreprocessorDefinitions: ';%(PreprocessorDefinitions)', + UndefinePreprocessorDefinitions: + ';%(UndefinePreprocessorDefinitions)', + Link: + AdditionalDependencies: ';%(AdditionalDependencies)', + AdditionalLibraryDirectories: ';%(AdditionalLibraryDirectories)', + AdditionalManifestDependencies: + ';%(AdditionalManifestDependencies)', + AdditionalOptions: ' %(AdditionalOptions)', + AddModuleNamesToAssembly: ';%(AddModuleNamesToAssembly)', + AssemblyLinkResource: ';%(AssemblyLinkResource)', + DelayLoadDLLs: ';%(DelayLoadDLLs)', + EmbedManagedResourceFile: ';%(EmbedManagedResourceFile)', + ForceSymbolReferences: ';%(ForceSymbolReferences)', + IgnoreSpecificDefaultLibraries: + ';%(IgnoreSpecificDefaultLibraries)', + ResourceCompile: + AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)', + AdditionalOptions: ' %(AdditionalOptions)', + PreprocessorDefinitions: ';%(PreprocessorDefinitions)', + Manifest: + AdditionalManifestFiles: ';%(AdditionalManifestFiles)', + AdditionalOptions: ' %(AdditionalOptions)', + InputResourceManifests: ';%(InputResourceManifests)', + """ msvs_settings = { "VCCLCompilerTool": { "AdditionalIncludeDirectories": "dir1", @@ -1346,8 +1346,7 @@ def testConvertToMSBuildSettings_actual(self): "EmbedManifest": "false", "GenerateCatalogFiles": "true", "InputResourceManifests": "asfsfdafs", - "ManifestResourceFile": - "$(IntDir)\\$(TargetFileName).embed.manifest.resfdsf", + "ManifestResourceFile": "$(IntDir)\\$(TargetFileName).embed.manifest.resfdsf", # noqa: E501 "OutputManifestFile": "$(TargetPath).manifestdfs", "RegistrarScriptFile": "sdfsfd", "ReplacementsFile": "sdffsd", @@ -1531,8 +1530,7 @@ def testConvertToMSBuildSettings_actual(self): "LinkIncremental": "", }, "ManifestResourceCompile": { - "ResourceOutputFileName": - "$(IntDir)$(TargetFileName).embed.manifest.resfdsf" + "ResourceOutputFileName": "$(IntDir)$(TargetFileName).embed.manifest.resfdsf" # noqa: E501 }, } self.maxDiff = 9999 # on failure display a long diff diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py index 2e5c811bdde32..61ca37c12d09d 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py @@ -4,7 +4,7 @@ """Visual Studio project reader/writer.""" -import gyp.easy_xml as easy_xml +from gyp import easy_xml class Writer: @@ -13,10 +13,10 @@ class Writer: def __init__(self, tool_file_path, name): """Initializes the tool file. - Args: - tool_file_path: Path to the tool file. - name: Name of the tool file. - """ + Args: + tool_file_path: Path to the tool file. + name: Name of the tool file. + """ self.tool_file_path = tool_file_path self.name = name self.rules_section = ["Rules"] @@ -26,14 +26,14 @@ def AddCustomBuildRule( ): """Adds a rule to the tool file. - Args: - name: Name of the rule. - description: Description of the rule. - cmd: Command line of the rule. - additional_dependencies: other files which may trigger the rule. - outputs: outputs of the rule. - extensions: extensions handled by the rule. - """ + Args: + name: Name of the rule. + description: Description of the rule. + cmd: Command line of the rule. + additional_dependencies: other files which may trigger the rule. + outputs: outputs of the rule. + extensions: extensions handled by the rule. + """ rule = [ "CustomBuildRule", { diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py index e580c00fb76d3..b93613bd1d2e4 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py @@ -8,19 +8,18 @@ import re import socket # for gethostname -import gyp.easy_xml as easy_xml - +from gyp import easy_xml # ------------------------------------------------------------------------------ def _FindCommandInPath(command): """If there are no slashes in the command given, this function - searches the PATH env to find the given command, and converts it - to an absolute path. We have to do this because MSVS is looking - for an actual file to launch a debugger on, not just a command - line. Note that this happens at GYP time, so anything needing to - be built needs to have a full path.""" + searches the PATH env to find the given command, and converts it + to an absolute path. We have to do this because MSVS is looking + for an actual file to launch a debugger on, not just a command + line. Note that this happens at GYP time, so anything needing to + be built needs to have a full path.""" if "/" in command or "\\" in command: # If the command already has path elements (either relative or # absolute), then assume it is constructed properly. @@ -59,11 +58,11 @@ class Writer: def __init__(self, user_file_path, version, name): """Initializes the user file. - Args: - user_file_path: Path to the user file. - version: Version info. - name: Name of the user file. - """ + Args: + user_file_path: Path to the user file. + version: Version info. + name: Name of the user file. + """ self.user_file_path = user_file_path self.version = version self.name = name @@ -72,9 +71,9 @@ def __init__(self, user_file_path, version, name): def AddConfig(self, name): """Adds a configuration to the project. - Args: - name: Configuration name. - """ + Args: + name: Configuration name. + """ self.configurations[name] = ["Configuration", {"Name": name}] def AddDebugSettings( @@ -82,12 +81,12 @@ def AddDebugSettings( ): """Adds a DebugSettings node to the user file for a particular config. - Args: - command: command line to run. First element in the list is the - executable. All elements of the command will be quoted if - necessary. - working_directory: other files which may trigger the rule. (optional) - """ + Args: + command: command line to run. First element in the list is the + executable. All elements of the command will be quoted if + necessary. + working_directory: other files which may trigger the rule. (optional) + """ command = _QuoteWin32CommandLineArgs(command) abs_command = _FindCommandInPath(command[0]) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py index 36bb782bd319a..5a1b4ae3198d6 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py @@ -7,7 +7,6 @@ import copy import os - # A dictionary mapping supported target types to extensions. TARGET_TYPE_EXT = { "executable": "exe", @@ -30,13 +29,13 @@ def _GetLargePdbShimCcPath(): def _DeepCopySomeKeys(in_dict, keys): """Performs a partial deep-copy on |in_dict|, only copying the keys in |keys|. - Arguments: - in_dict: The dictionary to copy. - keys: The keys to be copied. If a key is in this list and doesn't exist in - |in_dict| this is not an error. - Returns: - The partially deep-copied dictionary. - """ + Arguments: + in_dict: The dictionary to copy. + keys: The keys to be copied. If a key is in this list and doesn't exist in + |in_dict| this is not an error. + Returns: + The partially deep-copied dictionary. + """ d = {} for key in keys: if key not in in_dict: @@ -48,12 +47,12 @@ def _DeepCopySomeKeys(in_dict, keys): def _SuffixName(name, suffix): """Add a suffix to the end of a target. - Arguments: - name: name of the target (foo#target) - suffix: the suffix to be added - Returns: - Target name with suffix added (foo_suffix#target) - """ + Arguments: + name: name of the target (foo#target) + suffix: the suffix to be added + Returns: + Target name with suffix added (foo_suffix#target) + """ parts = name.rsplit("#", 1) parts[0] = f"{parts[0]}_{suffix}" return "#".join(parts) @@ -62,24 +61,24 @@ def _SuffixName(name, suffix): def _ShardName(name, number): """Add a shard number to the end of a target. - Arguments: - name: name of the target (foo#target) - number: shard number - Returns: - Target name with shard added (foo_1#target) - """ + Arguments: + name: name of the target (foo#target) + number: shard number + Returns: + Target name with shard added (foo_1#target) + """ return _SuffixName(name, str(number)) def ShardTargets(target_list, target_dicts): """Shard some targets apart to work around the linkers limits. - Arguments: - target_list: List of target pairs: 'base/base.gyp:base'. - target_dicts: Dict of target properties keyed on target pair. - Returns: - Tuple of the new sharded versions of the inputs. - """ + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + Returns: + Tuple of the new sharded versions of the inputs. + """ # Gather the targets to shard, and how many pieces. targets_to_shard = {} for t in target_dicts: @@ -129,22 +128,22 @@ def ShardTargets(target_list, target_dicts): def _GetPdbPath(target_dict, config_name, vars): """Returns the path to the PDB file that will be generated by a given - configuration. - - The lookup proceeds as follows: - - Look for an explicit path in the VCLinkerTool configuration block. - - Look for an 'msvs_large_pdb_path' variable. - - Use '<(PRODUCT_DIR)/<(product_name).(exe|dll).pdb' if 'product_name' is - specified. - - Use '<(PRODUCT_DIR)/<(target_name).(exe|dll).pdb'. - - Arguments: - target_dict: The target dictionary to be searched. - config_name: The name of the configuration of interest. - vars: A dictionary of common GYP variables with generator-specific values. - Returns: - The path of the corresponding PDB file. - """ + configuration. + + The lookup proceeds as follows: + - Look for an explicit path in the VCLinkerTool configuration block. + - Look for an 'msvs_large_pdb_path' variable. + - Use '<(PRODUCT_DIR)/<(product_name).(exe|dll).pdb' if 'product_name' is + specified. + - Use '<(PRODUCT_DIR)/<(target_name).(exe|dll).pdb'. + + Arguments: + target_dict: The target dictionary to be searched. + config_name: The name of the configuration of interest. + vars: A dictionary of common GYP variables with generator-specific values. + Returns: + The path of the corresponding PDB file. + """ config = target_dict["configurations"][config_name] msvs = config.setdefault("msvs_settings", {}) @@ -169,16 +168,16 @@ def _GetPdbPath(target_dict, config_name, vars): def InsertLargePdbShims(target_list, target_dicts, vars): """Insert a shim target that forces the linker to use 4KB pagesize PDBs. - This is a workaround for targets with PDBs greater than 1GB in size, the - limit for the 1KB pagesize PDBs created by the linker by default. + This is a workaround for targets with PDBs greater than 1GB in size, the + limit for the 1KB pagesize PDBs created by the linker by default. - Arguments: - target_list: List of target pairs: 'base/base.gyp:base'. - target_dicts: Dict of target properties keyed on target pair. - vars: A dictionary of common GYP variables with generator-specific values. - Returns: - Tuple of the shimmed version of the inputs. - """ + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + vars: A dictionary of common GYP variables with generator-specific values. + Returns: + Tuple of the shimmed version of the inputs. + """ # Determine which targets need shimming. targets_to_shim = [] for t in target_dicts: diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py index 8d7f21e82dd2f..2d8e4ceab9a94 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py @@ -5,11 +5,11 @@ """Handle version information related to Visual Stuio.""" import errno +import glob import os import re import subprocess import sys -import glob def JoinPath(*args): @@ -69,24 +69,24 @@ def UsesVcxproj(self): def ProjectExtension(self): """Returns the file extension for the project.""" - return self.uses_vcxproj and ".vcxproj" or ".vcproj" + return (self.uses_vcxproj and ".vcxproj") or ".vcproj" def Path(self): """Returns the path to Visual Studio installation.""" return self.path def ToolPath(self, tool): - """Returns the path to a given compiler tool. """ + """Returns the path to a given compiler tool.""" return os.path.normpath(os.path.join(self.path, "VC/bin", tool)) def DefaultToolset(self): """Returns the msbuild toolset version that will be used in the absence - of a user override.""" + of a user override.""" return self.default_toolset def _SetupScriptInternal(self, target_arch): """Returns a command (with arguments) to be used to set up the - environment.""" + environment.""" assert target_arch in ("x86", "x64"), "target_arch not supported" # If WindowsSDKDir is set and SetEnv.Cmd exists then we are using the # depot_tools build tools and should run SetEnv.Cmd to set up the @@ -154,16 +154,16 @@ def SetupScript(self, target_arch): def _RegistryQueryBase(sysdir, key, value): """Use reg.exe to read a particular key. - While ideally we might use the win32 module, we would like gyp to be - python neutral, so for instance cygwin python lacks this module. + While ideally we might use the win32 module, we would like gyp to be + python neutral, so for instance cygwin python lacks this module. - Arguments: - sysdir: The system subdirectory to attempt to launch reg.exe from. - key: The registry key to read from. - value: The particular value to read. - Return: - stdout from reg.exe, or None for failure. - """ + Arguments: + sysdir: The system subdirectory to attempt to launch reg.exe from. + key: The registry key to read from. + value: The particular value to read. + Return: + stdout from reg.exe, or None for failure. + """ # Skip if not on Windows or Python Win32 setup issue if sys.platform not in ("win32", "cygwin"): return None @@ -184,20 +184,20 @@ def _RegistryQueryBase(sysdir, key, value): def _RegistryQuery(key, value=None): r"""Use reg.exe to read a particular key through _RegistryQueryBase. - First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If - that fails, it falls back to System32. Sysnative is available on Vista and - up and available on Windows Server 2003 and XP through KB patch 942589. Note - that Sysnative will always fail if using 64-bit python due to it being a - virtual directory and System32 will work correctly in the first place. + First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If + that fails, it falls back to System32. Sysnative is available on Vista and + up and available on Windows Server 2003 and XP through KB patch 942589. Note + that Sysnative will always fail if using 64-bit python due to it being a + virtual directory and System32 will work correctly in the first place. - KB 942589 - http://support.microsoft.com/kb/942589/en-us. + KB 942589 - http://support.microsoft.com/kb/942589/en-us. - Arguments: - key: The registry key. - value: The particular registry value to read (optional). - Return: - stdout from reg.exe, or None for failure. - """ + Arguments: + key: The registry key. + value: The particular registry value to read (optional). + Return: + stdout from reg.exe, or None for failure. + """ text = None try: text = _RegistryQueryBase("Sysnative", key, value) @@ -212,14 +212,15 @@ def _RegistryQuery(key, value=None): def _RegistryGetValueUsingWinReg(key, value): """Use the _winreg module to obtain the value of a registry key. - Args: - key: The registry key. - value: The particular registry value to read. - Return: - contents of the registry key's value, or None on failure. Throws - ImportError if winreg is unavailable. - """ - from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx + Args: + key: The registry key. + value: The particular registry value to read. + Return: + contents of the registry key's value, or None on failure. Throws + ImportError if winreg is unavailable. + """ + from winreg import HKEY_LOCAL_MACHINE, OpenKey, QueryValueEx # noqa: PLC0415 + try: root, subkey = key.split("\\", 1) assert root == "HKLM" # Only need HKLM for now. @@ -232,17 +233,17 @@ def _RegistryGetValueUsingWinReg(key, value): def _RegistryGetValue(key, value): """Use _winreg or reg.exe to obtain the value of a registry key. - Using _winreg is preferable because it solves an issue on some corporate - environments where access to reg.exe is locked down. However, we still need - to fallback to reg.exe for the case where the _winreg module is not available - (for example in cygwin python). - - Args: - key: The registry key. - value: The particular registry value to read. - Return: - contents of the registry key's value, or None on failure. - """ + Using _winreg is preferable because it solves an issue on some corporate + environments where access to reg.exe is locked down. However, we still need + to fallback to reg.exe for the case where the _winreg module is not available + (for example in cygwin python). + + Args: + key: The registry key. + value: The particular registry value to read. + Return: + contents of the registry key's value, or None on failure. + """ try: return _RegistryGetValueUsingWinReg(key, value) except ImportError: @@ -262,13 +263,25 @@ def _RegistryGetValue(key, value): def _CreateVersion(name, path, sdk_based=False): """Sets up MSVS project generation. - Setup is based off the GYP_MSVS_VERSION environment variable or whatever is - autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is - passed in that doesn't match a value in versions python will throw a error. - """ + Setup is based off the GYP_MSVS_VERSION environment variable or whatever is + autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is + passed in that doesn't match a value in versions python will throw a error. + """ if path: path = os.path.normpath(path) versions = { + "2026": VisualStudioVersion( + "2026", + "Visual Studio 2026", + solution_version="12.00", + project_version="18.0", + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset="v145", + compatible_sdks=["v8.1", "v10.0"], + ), "2022": VisualStudioVersion( "2022", "Visual Studio 2022", @@ -435,22 +448,22 @@ def _ConvertToCygpath(path): def _DetectVisualStudioVersions(versions_to_check, force_express): """Collect the list of installed visual studio versions. - Returns: - A list of visual studio versions installed in descending order of - usage preference. - Base this on the registry and a quick check if devenv.exe exists. - Possibilities are: - 2005(e) - Visual Studio 2005 (8) - 2008(e) - Visual Studio 2008 (9) - 2010(e) - Visual Studio 2010 (10) - 2012(e) - Visual Studio 2012 (11) - 2013(e) - Visual Studio 2013 (12) - 2015 - Visual Studio 2015 (14) - 2017 - Visual Studio 2017 (15) - 2019 - Visual Studio 2019 (16) - 2022 - Visual Studio 2022 (17) - Where (e) is e for express editions of MSVS and blank otherwise. - """ + Returns: + A list of visual studio versions installed in descending order of + usage preference. + Base this on the registry and a quick check if devenv.exe exists. + Possibilities are: + 2005(e) - Visual Studio 2005 (8) + 2008(e) - Visual Studio 2008 (9) + 2010(e) - Visual Studio 2010 (10) + 2012(e) - Visual Studio 2012 (11) + 2013(e) - Visual Studio 2013 (12) + 2015 - Visual Studio 2015 (14) + 2017 - Visual Studio 2017 (15) + 2019 - Visual Studio 2019 (16) + 2022 - Visual Studio 2022 (17) + Where (e) is e for express editions of MSVS and blank otherwise. + """ version_to_year = { "8.0": "2005", "9.0": "2008", @@ -461,6 +474,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): "15.0": "2017", "16.0": "2019", "17.0": "2022", + "18.0": "2026", } versions = [] for version in versions_to_check: @@ -527,16 +541,27 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): def SelectVisualStudioVersion(version="auto", allow_fallback=True): """Select which version of Visual Studio projects to generate. - Arguments: - version: Hook to allow caller to force a particular version (vs auto). - Returns: - An object representing a visual studio project format version. - """ + Arguments: + version: Hook to allow caller to force a particular version (vs auto). + Returns: + An object representing a visual studio project format version. + """ # In auto mode, check environment variable for override. if version == "auto": version = os.environ.get("GYP_MSVS_VERSION", "auto") version_map = { - "auto": ("17.0", "16.0", "15.0", "14.0", "12.0", "10.0", "9.0", "8.0", "11.0"), + "auto": ( + "18.0", + "17.0", + "16.0", + "15.0", + "14.0", + "12.0", + "10.0", + "9.0", + "8.0", + "11.0", + ), "2005": ("8.0",), "2005e": ("8.0",), "2008": ("9.0",), @@ -551,9 +576,9 @@ def SelectVisualStudioVersion(version="auto", allow_fallback=True): "2017": ("15.0",), "2019": ("16.0",), "2022": ("17.0",), + "2026": ("18.0",), } - override_path = os.environ.get("GYP_MSVS_OVERRIDE_PATH") - if override_path: + if override_path := os.environ.get("GYP_MSVS_OVERRIDE_PATH"): msvs_version = os.environ.get("GYP_MSVS_VERSION") if not msvs_version: raise ValueError( diff --git a/node_modules/node-gyp/gyp/pylib/gyp/__init__.py b/node_modules/node-gyp/gyp/pylib/gyp/__init__.py index 6790ef96a1959..3a70cf076c8b4 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/__init__.py @@ -4,15 +4,17 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import annotations -import copy -import gyp.input import argparse +import copy import os.path import re import shlex import sys import traceback + +import gyp.input from gyp.common import GypError # Default debug modes for GYP @@ -24,6 +26,20 @@ DEBUG_INCLUDES = "includes" +def EscapeForCString(string: bytes | str) -> str: + if isinstance(string, str): + string = string.encode(encoding="utf8") + + backslash_or_double_quote = {ord("\\"), ord('"')} + result = "" + for char in string: + if char in backslash_or_double_quote or not 32 <= char < 127: + result += "\\%03o" % char + else: + result += chr(char) + return result + + def DebugOutput(mode, message, *args): if "all" in gyp.debug or mode in gyp.debug: ctx = ("unknown", 0, "unknown") @@ -62,11 +78,11 @@ def Load( circular_check=True, ): """ - Loads one or more specified build files. - default_variables and includes will be copied before use. - Returns the generator for the specified format and the - data returned by loading the specified build files. - """ + Loads one or more specified build files. + default_variables and includes will be copied before use. + Returns the generator for the specified format and the + data returned by loading the specified build files. + """ if params is None: params = {} @@ -100,9 +116,24 @@ def Load( # These parameters are passed in order (as opposed to by key) # because ActivePython cannot handle key parameters to __import__. generator = __import__(generator_name, globals(), locals(), generator_name) - for (key, val) in generator.generator_default_variables.items(): + for key, val in generator.generator_default_variables.items(): default_variables.setdefault(key, val) + output_dir = params["options"].generator_output or params["options"].toplevel_dir + if default_variables["GENERATOR"] == "ninja": + product_dir_abs = os.path.join( + output_dir, "out", default_variables.get("build_type", "default") + ) + else: + product_dir_abs = os.path.join( + output_dir, default_variables["CONFIGURATION_NAME"] + ) + + default_variables.setdefault("PRODUCT_DIR_ABS", product_dir_abs) + default_variables.setdefault( + "PRODUCT_DIR_ABS_CSTR", EscapeForCString(product_dir_abs) + ) + # Give the generator the opportunity to set additional variables based on # the params it will receive in the output phase. if getattr(generator, "CalculateVariables", None): @@ -155,10 +186,10 @@ def Load( def NameValueListToDict(name_value_list): """ - Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary - of the pairs. If a string is simply NAME, then the value in the dictionary - is set to True. If VALUE can be converted to an integer, it is. - """ + Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary + of the pairs. If a string is simply NAME, then the value in the dictionary + is set to True. If VALUE can be converted to an integer, it is. + """ result = {} for item in name_value_list: tokens = item.split("=", 1) @@ -177,8 +208,7 @@ def NameValueListToDict(name_value_list): def ShlexEnv(env_name): - flags = os.environ.get(env_name, []) - if flags: + if flags := os.environ.get(env_name) or []: flags = shlex.split(flags) return flags @@ -192,13 +222,13 @@ def FormatOpt(opt, value): def RegenerateAppendFlag(flag, values, predicate, env_name, options): """Regenerate a list of command line flags, for an option of action='append'. - The |env_name|, if given, is checked in the environment and used to generate - an initial list of options, then the options that were specified on the - command line (given in |values|) are appended. This matches the handling of - environment variables and command line flags where command line flags override - the environment, while not requiring the environment to be set when the flags - are used again. - """ + The |env_name|, if given, is checked in the environment and used to generate + an initial list of options, then the options that were specified on the + command line (given in |values|) are appended. This matches the handling of + environment variables and command line flags where command line flags override + the environment, while not requiring the environment to be set when the flags + are used again. + """ flags = [] if options.use_environment and env_name: for flag_value in ShlexEnv(env_name): @@ -214,14 +244,14 @@ def RegenerateAppendFlag(flag, values, predicate, env_name, options): def RegenerateFlags(options): """Given a parsed options object, and taking the environment variables into - account, returns a list of flags that should regenerate an equivalent options - object (even in the absence of the environment variables.) + account, returns a list of flags that should regenerate an equivalent options + object (even in the absence of the environment variables.) - Any path options will be normalized relative to depth. + Any path options will be normalized relative to depth. - The format flag is not included, as it is assumed the calling generator will - set that as appropriate. - """ + The format flag is not included, as it is assumed the calling generator will + set that as appropriate. + """ def FixPath(path): path = gyp.common.FixIfRelativePath(path, options.depth) @@ -238,7 +268,7 @@ def Noop(value): for name, metadata in options._regeneration_metadata.items(): opt = metadata["opt"] value = getattr(options, name) - value_predicate = metadata["type"] == "path" and FixPath or Noop + value_predicate = (metadata["type"] == "path" and FixPath) or Noop action = metadata["action"] env_name = metadata["env_name"] if action == "append": @@ -279,15 +309,15 @@ def __init__(self, usage): def add_argument(self, *args, **kw): """Add an option to the parser. - This accepts the same arguments as ArgumentParser.add_argument, plus the - following: - regenerate: can be set to False to prevent this option from being included - in regeneration. - env_name: name of environment variable that additional values for this - option come from. - type: adds type='path', to tell the regenerator that the values of - this option need to be made relative to options.depth - """ + This accepts the same arguments as ArgumentParser.add_argument, plus the + following: + regenerate: can be set to False to prevent this option from being included + in regeneration. + env_name: name of environment variable that additional values for this + option come from. + type: adds type='path', to tell the regenerator that the values of + this option need to be made relative to options.depth + """ env_name = kw.pop("env_name", None) if "dest" in kw and kw.pop("regenerate", True): dest = kw["dest"] @@ -315,7 +345,7 @@ def parse_args(self, *args): def gyp_main(args): my_name = os.path.basename(sys.argv[0]) - usage = "usage: %(prog)s [options ...] [build_file ...]" + usage = "%(prog)s [options ...] [build_file ...]" parser = RegeneratableOptionParser(usage=usage.replace("%s", "%(prog)s")) parser.add_argument( @@ -333,7 +363,7 @@ def gyp_main(args): action="store", env_name="GYP_CONFIG_DIR", default=None, - help="The location for configuration files like " "include.gypi.", + help="The location for configuration files like include.gypi.", ) parser.add_argument( "-d", @@ -451,8 +481,20 @@ def gyp_main(args): metavar="TARGET", help="include only TARGET and its deep dependencies", ) + parser.add_argument( + "-V", + "--version", + dest="version", + action="store_true", + help="Show the version and exit.", + ) options, build_files_arg = parser.parse_args(args) + if options.version: + import pkg_resources # noqa: PLC0415 + + print(f"v{pkg_resources.get_distribution('gyp-next').version}") + return 0 build_files = build_files_arg # Set up the configuration directory (defaults to ~/.gyp) @@ -486,19 +528,18 @@ def gyp_main(args): # If no format was given on the command line, then check the env variable. generate_formats = [] if options.use_environment: - generate_formats = os.environ.get("GYP_GENERATORS", []) + generate_formats = os.environ.get("GYP_GENERATORS") or [] if generate_formats: generate_formats = re.split(r"[\s,]", generate_formats) if generate_formats: options.formats = generate_formats + # Nothing in the variable, default based on platform. + elif sys.platform == "darwin": + options.formats = ["xcode"] + elif sys.platform in ("win32", "cygwin"): + options.formats = ["msvs"] else: - # Nothing in the variable, default based on platform. - if sys.platform == "darwin": - options.formats = ["xcode"] - elif sys.platform in ("win32", "cygwin"): - options.formats = ["msvs"] - else: - options.formats = ["make"] + options.formats = ["make"] if not options.generator_output and options.use_environment: g_o = os.environ.get("GYP_GENERATOR_OUTPUT") @@ -598,7 +639,7 @@ def gyp_main(args): if options.generator_flags: gen_flags += options.generator_flags generator_flags = NameValueListToDict(gen_flags) - if DEBUG_GENERAL in gyp.debug.keys(): + if DEBUG_GENERAL in gyp.debug: DebugOutput(DEBUG_GENERAL, "generator_flags: %s", generator_flags) # Generate all requested formats (use a set in case we got one format request @@ -657,7 +698,7 @@ def main(args): return 1 -# NOTE: setuptools generated console_scripts calls function with no arguments +# NOTE: console_scripts calls this function with no arguments def script_main(): return main(sys.argv[1:]) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/common.py b/node_modules/node-gyp/gyp/pylib/gyp/common.py index 9213fcc5e82bb..223ce47b0032f 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/common.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/common.py @@ -6,10 +6,10 @@ import filecmp import os.path import re -import tempfile -import sys +import shlex import subprocess - +import sys +import tempfile from collections.abc import MutableSet @@ -31,10 +31,8 @@ def __call__(self, *args): class GypError(Exception): """Error class representing an error, which is to be presented - to the user. The main entry point will catch and display this. - """ - - pass + to the user. The main entry point will catch and display this. + """ def ExceptionAppend(e, msg): @@ -49,9 +47,9 @@ def ExceptionAppend(e, msg): def FindQualifiedTargets(target, qualified_list): """ - Given a list of qualified targets, return the qualified targets for the - specified |target|. - """ + Given a list of qualified targets, return the qualified targets for the + specified |target|. + """ return [t for t in qualified_list if ParseQualifiedTarget(t)[1] == target] @@ -116,7 +114,7 @@ def BuildFile(fully_qualified_target): def GetEnvironFallback(var_list, default): """Look up a key in the environment, with fallback to secondary keys - and finally falling back to a default value.""" + and finally falling back to a default value.""" for var in var_list: if var in os.environ: return os.environ[var] @@ -144,20 +142,16 @@ def RelativePath(path, relative_to, follow_path_symlink=True): # symlink, this option has no effect. # Convert to normalized (and therefore absolute paths). - if follow_path_symlink: - path = os.path.realpath(path) - else: - path = os.path.abspath(path) + path = os.path.realpath(path) if follow_path_symlink else os.path.abspath(path) relative_to = os.path.realpath(relative_to) # On Windows, we can't create a relative path to a different drive, so just # use the absolute path. - if sys.platform == "win32": - if ( - os.path.splitdrive(path)[0].lower() - != os.path.splitdrive(relative_to)[0].lower() - ): - return path + if sys.platform == "win32" and ( + os.path.splitdrive(path)[0].lower() + != os.path.splitdrive(relative_to)[0].lower() + ): + return path # Split the paths into components. path_split = path.split(os.path.sep) @@ -183,11 +177,11 @@ def RelativePath(path, relative_to, follow_path_symlink=True): @memoize def InvertRelativePath(path, toplevel_dir=None): """Given a path like foo/bar that is relative to toplevel_dir, return - the inverse relative path back to the toplevel_dir. + the inverse relative path back to the toplevel_dir. - E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) - should always produce the empty string, unless the path contains symlinks. - """ + E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) + should always produce the empty string, unless the path contains symlinks. + """ if not path: return path toplevel_dir = "." if toplevel_dir is None else toplevel_dir @@ -267,20 +261,17 @@ def UnrelativePath(path, relative_to): def EncodePOSIXShellArgument(argument): """Encodes |argument| suitably for consumption by POSIX shells. - argument may be quoted and escaped as necessary to ensure that POSIX shells - treat the returned value as a literal representing the argument passed to - this function. Parameter (variable) expansions beginning with $ are allowed - to remain intact without escaping the $, to allow the argument to contain - references to variables to be expanded by the shell. - """ + argument may be quoted and escaped as necessary to ensure that POSIX shells + treat the returned value as a literal representing the argument passed to + this function. Parameter (variable) expansions beginning with $ are allowed + to remain intact without escaping the $, to allow the argument to contain + references to variables to be expanded by the shell. + """ if not isinstance(argument, str): argument = str(argument) - if _quote.search(argument): - quote = '"' - else: - quote = "" + quote = '"' if _quote.search(argument) else "" encoded = quote + re.sub(_escape, r"\\\1", argument) + quote @@ -290,9 +281,9 @@ def EncodePOSIXShellArgument(argument): def EncodePOSIXShellList(list): """Encodes |list| suitably for consumption by POSIX shells. - Returns EncodePOSIXShellArgument for each item in list, and joins them - together using the space character as an argument separator. - """ + Returns EncodePOSIXShellArgument for each item in list, and joins them + together using the space character as an argument separator. + """ encoded_arguments = [] for argument in list: @@ -320,14 +311,12 @@ def DeepDependencyTargets(target_dicts, roots): def BuildFileTargets(target_list, build_file): - """From a target_list, returns the subset from the specified build_file. - """ + """From a target_list, returns the subset from the specified build_file.""" return [p for p in target_list if BuildFile(p) == build_file] def AllTargets(target_list, target_dicts, build_file): - """Returns all targets (direct and dependencies) for the specified build_file. - """ + """Returns all targets (direct and dependencies) for the specified build_file.""" bftargets = BuildFileTargets(target_list, build_file) deptargets = DeepDependencyTargets(target_dicts, bftargets) return bftargets + deptargets @@ -336,12 +325,12 @@ def AllTargets(target_list, target_dicts, build_file): def WriteOnDiff(filename): """Write to a file only if the new contents differ. - Arguments: - filename: name of the file to potentially write to. - Returns: - A file like object which will write to temporary file and only overwrite - the target if it differs (on close). - """ + Arguments: + filename: name of the file to potentially write to. + Returns: + A file like object which will write to temporary file and only overwrite + the target if it differs (on close). + """ class Writer: """Wrapper around file which only covers the target if it differs.""" @@ -430,7 +419,70 @@ def EnsureDirExists(path): pass -def GetFlavor(params): +def GetCompilerPredefines(): # -> dict + cmd = [] + defines = {} + + # shlex.split() will eat '\' in posix mode, but + # setting posix=False will preserve extra '"' cause CreateProcess fail on Windows + # this makes '\' in %CC_target% and %CFLAGS% work + def replace_sep(s): + return s.replace(os.sep, "/") if os.sep != "/" else s + + if CC := os.environ.get("CC_target") or os.environ.get("CC"): + cmd += shlex.split(replace_sep(CC)) + if CFLAGS := os.environ.get("CFLAGS"): + cmd += shlex.split(replace_sep(CFLAGS)) + elif CXX := os.environ.get("CXX_target") or os.environ.get("CXX"): + cmd += shlex.split(replace_sep(CXX)) + if CXXFLAGS := os.environ.get("CXXFLAGS"): + cmd += shlex.split(replace_sep(CXXFLAGS)) + else: + return defines + + if sys.platform == "win32": + fd, input = tempfile.mkstemp(suffix=".c") + real_cmd = [*cmd, "-dM", "-E", "-x", "c", input] + try: + os.close(fd) + stdout = subprocess.run( + real_cmd, shell=True, capture_output=True, check=True + ).stdout + except subprocess.CalledProcessError as e: + print( + "Warning: failed to get compiler predefines\n" + "cmd: %s\n" + "status: %d" % (e.cmd, e.returncode), + file=sys.stderr, + ) + return defines + finally: + os.unlink(input) + else: + input = "/dev/null" + real_cmd = [*cmd, "-dM", "-E", "-x", "c", input] + try: + stdout = subprocess.run( + real_cmd, shell=False, capture_output=True, check=True + ).stdout + except subprocess.CalledProcessError as e: + print( + "Warning: failed to get compiler predefines\n" + "cmd: %s\n" + "status: %d" % (e.cmd, e.returncode), + file=sys.stderr, + ) + return defines + + lines = stdout.decode("utf-8").replace("\r\n", "\n").split("\n") + for line in lines: + if (line or "").startswith("#define "): + _, key, *value = line.split(" ") + defines[key] = " ".join(value) + return defines + + +def GetFlavorByPlatform(): """Returns |params.flavor| if it's set, the system's default flavor else.""" flavors = { "cygwin": "win", @@ -438,8 +490,6 @@ def GetFlavor(params): "darwin": "mac", } - if "flavor" in params: - return params["flavor"] if sys.platform in flavors: return flavors[sys.platform] if sys.platform.startswith("sunos"): @@ -454,18 +504,38 @@ def GetFlavor(params): return "aix" if sys.platform.startswith(("os390", "zos")): return "zos" + if sys.platform == "os400": + return "os400" return "linux" +def GetFlavor(params): + if "flavor" in params: + return params["flavor"] + + defines = GetCompilerPredefines() + if "__EMSCRIPTEN__" in defines: + return "emscripten" + if "__wasm__" in defines: + return "wasi" if "__wasi__" in defines else "wasm" + + return GetFlavorByPlatform() + + def CopyTool(flavor, out_path, generator_flags={}): """Finds (flock|mac|win)_tool.gyp in the gyp directory and copies it - to |out_path|.""" + to |out_path|.""" # aix and solaris just need flock emulation. mac and win use more complicated # support scripts. - prefix = {"aix": "flock", "solaris": "flock", "mac": "mac", "win": "win"}.get( - flavor, None - ) + prefix = { + "aix": "flock", + "os400": "flock", + "solaris": "flock", + "mac": "mac", + "ios": "mac", + "win": "win", + }.get(flavor, None) if not prefix: return @@ -511,7 +581,8 @@ def uniquer(seq, idfun=lambda x: x): # Based on http://code.activestate.com/recipes/576694/. -class OrderedSet(MutableSet): +class OrderedSet(MutableSet): # noqa: PLW1641 + # TODO (cclauss): Fix eq-without-hash ruff rule PLW1641 def __init__(self, iterable=None): self.end = end = [] end += [None, end, end] # sentinel node for doubly linked list @@ -589,24 +660,24 @@ def __str__(self): def TopologicallySorted(graph, get_edges): r"""Topologically sort based on a user provided edge definition. - Args: - graph: A list of node names. - get_edges: A function mapping from node name to a hashable collection - of node names which this node has outgoing edges to. - Returns: - A list containing all of the node in graph in topological order. - It is assumed that calling get_edges once for each node and caching is - cheaper than repeatedly calling get_edges. - Raises: - CycleError in the event of a cycle. - Example: - graph = {'a': '$(b) $(c)', 'b': 'hi', 'c': '$(b)'} - def GetEdges(node): - return re.findall(r'\$\(([^))]\)', graph[node]) - print TopologicallySorted(graph.keys(), GetEdges) - ==> - ['a', 'c', b'] - """ + Args: + graph: A list of node names. + get_edges: A function mapping from node name to a hashable collection + of node names which this node has outgoing edges to. + Returns: + A list containing all of the node in graph in topological order. + It is assumed that calling get_edges once for each node and caching is + cheaper than repeatedly calling get_edges. + Raises: + CycleError in the event of a cycle. + Example: + graph = {'a': '$(b) $(c)', 'b': 'hi', 'c': '$(b)'} + def GetEdges(node): + return re.findall(r'\$\(([^))]\)', graph[node]) + print TopologicallySorted(graph.keys(), GetEdges) + ==> + ['a', 'c', b'] + """ get_edges = memoize(get_edges) visited = set() visiting = set() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/common_test.py b/node_modules/node-gyp/gyp/pylib/gyp/common_test.py index 05344085ad3b1..b5988816c04a2 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/common_test.py @@ -6,9 +6,13 @@ """Unit tests for the common.py file.""" -import gyp.common -import unittest +import os +import subprocess import sys +import unittest +from unittest.mock import MagicMock, patch + +import gyp.common class TestTopologicallySorted(unittest.TestCase): @@ -24,9 +28,12 @@ def test_Valid(self): def GetEdge(node): return tuple(graph[node]) - self.assertEqual( - gyp.common.TopologicallySorted(graph.keys(), GetEdge), ["a", "c", "d", "b"] - ) + assert gyp.common.TopologicallySorted(graph.keys(), GetEdge) == [ + "a", + "c", + "d", + "b", + ] def test_Cycle(self): """Test that an exception is thrown on a cyclic graph.""" @@ -58,7 +65,7 @@ def tearDown(self): def assertFlavor(self, expected, argument, param): sys.platform = argument - self.assertEqual(expected, gyp.common.GetFlavor(param)) + assert expected == gyp.common.GetFlavor(param) def test_platform_default(self): self.assertFlavor("freebsd", "freebsd9", {}) @@ -73,6 +80,107 @@ def test_platform_default(self): def test_param(self): self.assertFlavor("foobar", "linux2", {"flavor": "foobar"}) + class MockCommunicate: + def __init__(self, stdout): + self.stdout = stdout + + def decode(self, encoding): + return self.stdout + + @patch("os.close") + @patch("os.unlink") + @patch("tempfile.mkstemp") + def test_GetCompilerPredefines(self, mock_mkstemp, mock_unlink, mock_close): + mock_close.return_value = None + mock_unlink.return_value = None + mock_mkstemp.return_value = (0, "temp.c") + + def mock_run(env, defines_stdout, expected_cmd, throws=False): + with patch("subprocess.run") as mock_run: + expected_input = "temp.c" if sys.platform == "win32" else "/dev/null" + if throws: + mock_run.side_effect = subprocess.CalledProcessError( + returncode=1, + cmd=[*expected_cmd, "-dM", "-E", "-x", "c", expected_input], + ) + else: + mock_process = MagicMock() + mock_process.returncode = 0 + mock_process.stdout = TestGetFlavor.MockCommunicate(defines_stdout) + mock_run.return_value = mock_process + with patch.dict(os.environ, env): + try: + defines = gyp.common.GetCompilerPredefines() + except Exception as e: + self.fail(f"GetCompilerPredefines raised an exception: {e}") + flavor = gyp.common.GetFlavor({}) + if env.get("CC_target") or env.get("CC"): + mock_run.assert_called_with( + [*expected_cmd, "-dM", "-E", "-x", "c", expected_input], + shell=sys.platform == "win32", + capture_output=True, + check=True, + ) + return [defines, flavor] + + [defines0, _] = mock_run({"CC": "cl.exe"}, "", ["cl.exe"], True) + assert defines0 == {} + + [defines1, _] = mock_run({}, "", []) + assert defines1 == {} + + [defines2, flavor2] = mock_run( + {"CC_target": "/opt/wasi-sdk/bin/clang"}, + "#define __wasm__ 1\n#define __wasi__ 1\n", + ["/opt/wasi-sdk/bin/clang"], + ) + assert defines2 == {"__wasm__": "1", "__wasi__": "1"} + assert flavor2 == "wasi" + + [defines3, flavor3] = mock_run( + {"CC_target": "/opt/wasi-sdk/bin/clang --target=wasm32"}, + "#define __wasm__ 1\n", + ["/opt/wasi-sdk/bin/clang", "--target=wasm32"], + ) + assert defines3 == {"__wasm__": "1"} + assert flavor3 == "wasm" + + [defines4, flavor4] = mock_run( + {"CC_target": "/emsdk/upstream/emscripten/emcc"}, + "#define __EMSCRIPTEN__ 1\n", + ["/emsdk/upstream/emscripten/emcc"], + ) + assert defines4 == {"__EMSCRIPTEN__": "1"} + assert flavor4 == "emscripten" + + # Test path which include white space + [defines5, flavor5] = mock_run( + { + "CC_target": '"/Users/Toyo Li/wasi-sdk/bin/clang" -O3', + "CFLAGS": "--target=wasm32-wasi-threads -pthread", + }, + "#define __wasm__ 1\n#define __wasi__ 1\n#define _REENTRANT 1\n", + [ + "/Users/Toyo Li/wasi-sdk/bin/clang", + "-O3", + "--target=wasm32-wasi-threads", + "-pthread", + ], + ) + assert defines5 == {"__wasm__": "1", "__wasi__": "1", "_REENTRANT": "1"} + assert flavor5 == "wasi" + + original_sep = os.sep + os.sep = "\\" + [defines6, flavor6] = mock_run( + {"CC_target": '"C:\\Program Files\\wasi-sdk\\clang.exe"'}, + "#define __wasm__ 1\n#define __wasi__ 1\n", + ["C:/Program Files/wasi-sdk/clang.exe"], + ) + os.sep = original_sep + assert defines6 == {"__wasm__": "1", "__wasi__": "1"} + assert flavor6 == "wasi" + if __name__ == "__main__": unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py index bda1a47468ae2..a5d95153eca72 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py @@ -2,51 +2,51 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import sys -import re -import os import locale +import os +import re +import sys from functools import reduce def XmlToString(content, encoding="utf-8", pretty=False): - """ Writes the XML content to disk, touching the file only if it has changed. - - Visual Studio files have a lot of pre-defined structures. This function makes - it easy to represent these structures as Python data structures, instead of - having to create a lot of function calls. - - Each XML element of the content is represented as a list composed of: - 1. The name of the element, a string, - 2. The attributes of the element, a dictionary (optional), and - 3+. The content of the element, if any. Strings are simple text nodes and - lists are child elements. - - Example 1: - <test/> - becomes - ['test'] - - Example 2: - <myelement a='value1' b='value2'> - <childtype>This is</childtype> - <childtype>it!</childtype> - </myelement> - - becomes - ['myelement', {'a':'value1', 'b':'value2'}, - ['childtype', 'This is'], - ['childtype', 'it!'], - ] - - Args: - content: The structured content to be converted. - encoding: The encoding to report on the first XML line. - pretty: True if we want pretty printing with indents and new lines. - - Returns: - The XML content as a string. - """ + """Writes the XML content to disk, touching the file only if it has changed. + + Visual Studio files have a lot of pre-defined structures. This function makes + it easy to represent these structures as Python data structures, instead of + having to create a lot of function calls. + + Each XML element of the content is represented as a list composed of: + 1. The name of the element, a string, + 2. The attributes of the element, a dictionary (optional), and + 3+. The content of the element, if any. Strings are simple text nodes and + lists are child elements. + + Example 1: + <test/> + becomes + ['test'] + + Example 2: + <myelement a='value1' b='value2'> + <childtype>This is</childtype> + <childtype>it!</childtype> + </myelement> + + becomes + ['myelement', {'a':'value1', 'b':'value2'}, + ['childtype', 'This is'], + ['childtype', 'it!'], + ] + + Args: + content: The structured content to be converted. + encoding: The encoding to report on the first XML line. + pretty: True if we want pretty printing with indents and new lines. + + Returns: + The XML content as a string. + """ # We create a huge list of all the elements of the file. xml_parts = ['<?xml version="1.0" encoding="%s"?>' % encoding] if pretty: @@ -58,14 +58,14 @@ def XmlToString(content, encoding="utf-8", pretty=False): def _ConstructContentList(xml_parts, specification, pretty, level=0): - """ Appends the XML parts corresponding to the specification. - - Args: - xml_parts: A list of XML parts to be appended to. - specification: The specification of the element. See EasyXml docs. - pretty: True if we want pretty printing with indents and new lines. - level: Indentation level. - """ + """Appends the XML parts corresponding to the specification. + + Args: + xml_parts: A list of XML parts to be appended to. + specification: The specification of the element. See EasyXml docs. + pretty: True if we want pretty printing with indents and new lines. + level: Indentation level. + """ # The first item in a specification is the name of the element. if pretty: indentation = " " * level @@ -107,21 +107,26 @@ def _ConstructContentList(xml_parts, specification, pretty, level=0): xml_parts.append("/>%s" % new_line) -def WriteXmlIfChanged(content, path, encoding="utf-8", pretty=False, - win32=(sys.platform == "win32")): - """ Writes the XML content to disk, touching the file only if it has changed. +def WriteXmlIfChanged( + content, path, encoding="utf-8", pretty=False, win32=(sys.platform == "win32") +): + """Writes the XML content to disk, touching the file only if it has changed. - Args: - content: The structured content to be written. - path: Location of the file. - encoding: The encoding to report on the first line of the XML file. - pretty: True if we want pretty printing with indents and new lines. - """ + Args: + content: The structured content to be written. + path: Location of the file. + encoding: The encoding to report on the first line of the XML file. + pretty: True if we want pretty printing with indents and new lines. + """ xml_string = XmlToString(content, encoding, pretty) if win32 and os.linesep != "\r\n": xml_string = xml_string.replace("\n", "\r\n") - default_encoding = locale.getdefaultlocale()[1] + try: # getdefaultlocale() was removed in Python 3.11 + default_encoding = locale.getdefaultlocale()[1] + except AttributeError: + default_encoding = locale.getencoding() + if default_encoding and default_encoding.upper() != encoding.upper(): xml_string = xml_string.encode(encoding) @@ -153,7 +158,7 @@ def WriteXmlIfChanged(content, path, encoding="utf-8", pretty=False, def _XmlEscape(value, attr=False): - """ Escape a string for inclusion in XML.""" + """Escape a string for inclusion in XML.""" def replace(match): m = match.string[match.start() : match.end()] diff --git a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py index 342f693a329d2..29f5dad5a6e90 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py @@ -4,13 +4,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" Unit tests for the easy_xml.py file. """ +"""Unit tests for the easy_xml.py file.""" -import gyp.easy_xml as easy_xml import unittest - from io import StringIO +from gyp import easy_xml + class TestSequenceFunctions(unittest.TestCase): def setUp(self): @@ -76,6 +76,8 @@ def test_EasyXml_complex(self): '\'Debug|Win32\'" Label="Configuration">' "<ConfigurationType>Application</ConfigurationType>" "<CharacterSet>Unicode</CharacterSet>" + "<SpectreMitigation>SpectreLoadCF</SpectreMitigation>" + "<VCToolsVersion>14.36.32532</VCToolsVersion>" "</PropertyGroup>" "</Project>" ) @@ -99,6 +101,8 @@ def test_EasyXml_complex(self): }, ["ConfigurationType", "Application"], ["CharacterSet", "Unicode"], + ["SpectreMitigation", "SpectreLoadCF"], + ["VCToolsVersion", "14.36.32532"], ], ] ) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py index 1cb98152638b8..0754aff26fe7c 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py @@ -41,7 +41,7 @@ def ExecFlock(self, lockfile, *cmd_list): # with EBADF, that's why we use this F_SETLK # hack instead. fd = os.open(lockfile, os.O_WRONLY | os.O_NOCTTY | os.O_CREAT, 0o666) - if sys.platform.startswith("aix"): + if sys.platform.startswith("aix") or sys.platform == "os400": # Python on AIX is compiled with LARGEFILE support, which changes the # struct size. op = struct.pack("hhIllqq", fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py index f15df00c36373..420c4e49ebc19 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py @@ -62,12 +62,12 @@ then the "all" target includes "b1" and "b2". """ - -import gyp.common import json import os import posixpath +import gyp.common + debug = False found_dependency_string = "Found dependency" @@ -129,8 +129,8 @@ def _ToGypPath(path): def _ResolveParent(path, base_path_components): """Resolves |path|, which starts with at least one '../'. Returns an empty - string if the path shouldn't be considered. See _AddSources() for a - description of |base_path_components|.""" + string if the path shouldn't be considered. See _AddSources() for a + description of |base_path_components|.""" depth = 0 while path.startswith("../"): depth += 1 @@ -150,14 +150,14 @@ def _ResolveParent(path, base_path_components): def _AddSources(sources, base_path, base_path_components, result): """Extracts valid sources from |sources| and adds them to |result|. Each - source file is relative to |base_path|, but may contain '..'. To make - resolving '..' easier |base_path_components| contains each of the - directories in |base_path|. Additionally each source may contain variables. - Such sources are ignored as it is assumed dependencies on them are expressed - and tracked in some other means.""" + source file is relative to |base_path|, but may contain '..'. To make + resolving '..' easier |base_path_components| contains each of the + directories in |base_path|. Additionally each source may contain variables. + Such sources are ignored as it is assumed dependencies on them are expressed + and tracked in some other means.""" # NOTE: gyp paths are always posix style. for source in sources: - if not len(source) or source.startswith("!!!") or source.startswith("$"): + if not len(source) or source.startswith(("!!!", "$")): continue # variable expansion may lead to //. org_source = source @@ -217,23 +217,23 @@ def _ExtractSources(target, target_dict, toplevel_dir): class Target: """Holds information about a particular target: - deps: set of Targets this Target depends upon. This is not recursive, only the - direct dependent Targets. - match_status: one of the MatchStatus values. - back_deps: set of Targets that have a dependency on this Target. - visited: used during iteration to indicate whether we've visited this target. - This is used for two iterations, once in building the set of Targets and - again in _GetBuildTargets(). - name: fully qualified name of the target. - requires_build: True if the target type is such that it needs to be built. - See _DoesTargetTypeRequireBuild for details. - added_to_compile_targets: used when determining if the target was added to the - set of targets that needs to be built. - in_roots: true if this target is a descendant of one of the root nodes. - is_executable: true if the type of target is executable. - is_static_library: true if the type of target is static_library. - is_or_has_linked_ancestor: true if the target does a link (eg executable), or - if there is a target in back_deps that does a link.""" + deps: set of Targets this Target depends upon. This is not recursive, only the + direct dependent Targets. + match_status: one of the MatchStatus values. + back_deps: set of Targets that have a dependency on this Target. + visited: used during iteration to indicate whether we've visited this target. + This is used for two iterations, once in building the set of Targets and + again in _GetBuildTargets(). + name: fully qualified name of the target. + requires_build: True if the target type is such that it needs to be built. + See _DoesTargetTypeRequireBuild for details. + added_to_compile_targets: used when determining if the target was added to the + set of targets that needs to be built. + in_roots: true if this target is a descendant of one of the root nodes. + is_executable: true if the type of target is executable. + is_static_library: true if the type of target is static_library. + is_or_has_linked_ancestor: true if the target does a link (eg executable), or + if there is a target in back_deps that does a link.""" def __init__(self, name): self.deps = set() @@ -253,8 +253,8 @@ def __init__(self, name): class Config: """Details what we're looking for - files: set of files to search for - targets: see file description for details.""" + files: set of files to search for + targets: see file description for details.""" def __init__(self): self.files = [] @@ -264,7 +264,7 @@ def __init__(self): def Init(self, params): """Initializes Config. This is a separate method as it raises an exception - if there is a parse error.""" + if there is a parse error.""" generator_flags = params.get("generator_flags", {}) config_path = generator_flags.get("config_path", None) if not config_path: @@ -288,8 +288,8 @@ def Init(self, params): def _WasBuildFileModified(build_file, data, files, toplevel_dir): """Returns true if the build file |build_file| is either in |files| or - one of the files included by |build_file| is in |files|. |toplevel_dir| is - the root of the source tree.""" + one of the files included by |build_file| is in |files|. |toplevel_dir| is + the root of the source tree.""" if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files: if debug: print("gyp file modified", build_file) @@ -318,8 +318,8 @@ def _WasBuildFileModified(build_file, data, files, toplevel_dir): def _GetOrCreateTargetByName(targets, target_name): """Creates or returns the Target at targets[target_name]. If there is no - Target for |target_name| one is created. Returns a tuple of whether a new - Target was created and the Target.""" + Target for |target_name| one is created. Returns a tuple of whether a new + Target was created and the Target.""" if target_name in targets: return False, targets[target_name] target = Target(target_name) @@ -339,13 +339,13 @@ def _DoesTargetTypeRequireBuild(target_dict): def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, build_files): """Returns a tuple of the following: - . A dictionary mapping from fully qualified name to Target. - . A list of the targets that have a source file in |files|. - . Targets that constitute the 'all' target. See description at top of file - for details on the 'all' target. - This sets the |match_status| of the targets that contain any of the source - files in |files| to MATCH_STATUS_MATCHES. - |toplevel_dir| is the root of the source tree.""" + . A dictionary mapping from fully qualified name to Target. + . A list of the targets that have a source file in |files|. + . Targets that constitute the 'all' target. See description at top of file + for details on the 'all' target. + This sets the |match_status| of the targets that contain any of the source + files in |files| to MATCH_STATUS_MATCHES. + |toplevel_dir| is the root of the source tree.""" # Maps from target name to Target. name_to_target = {} @@ -378,9 +378,10 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, build target_type = target_dicts[target_name]["type"] target.is_executable = target_type == "executable" target.is_static_library = target_type == "static_library" - target.is_or_has_linked_ancestor = ( - target_type == "executable" or target_type == "shared_library" - ) + target.is_or_has_linked_ancestor = target_type in { + "executable", + "shared_library", + } build_file = gyp.common.ParseQualifiedTarget(target_name)[0] if build_file not in build_file_in_files: @@ -426,34 +427,34 @@ def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, build def _GetUnqualifiedToTargetMapping(all_targets, to_find): """Returns a tuple of the following: - . mapping (dictionary) from unqualified name to Target for all the - Targets in |to_find|. - . any target names not found. If this is empty all targets were found.""" + . mapping (dictionary) from unqualified name to Target for all the + Targets in |to_find|. + . any target names not found. If this is empty all targets were found.""" result = {} if not to_find: return {}, [] to_find = set(to_find) - for target_name in all_targets.keys(): + for target_name in all_targets: extracted = gyp.common.ParseQualifiedTarget(target_name) if len(extracted) > 1 and extracted[1] in to_find: to_find.remove(extracted[1]) result[extracted[1]] = all_targets[target_name] if not to_find: return result, [] - return result, [x for x in to_find] + return result, list(to_find) def _DoesTargetDependOnMatchingTargets(target): """Returns true if |target| or any of its dependencies is one of the - targets containing the files supplied as input to analyzer. This updates - |matches| of the Targets as it recurses. - target: the Target to look for.""" + targets containing the files supplied as input to analyzer. This updates + |matches| of the Targets as it recurses. + target: the Target to look for.""" if target.match_status == MATCH_STATUS_DOESNT_MATCH: return False - if ( - target.match_status == MATCH_STATUS_MATCHES - or target.match_status == MATCH_STATUS_MATCHES_BY_DEPENDENCY - ): + if target.match_status in { + MATCH_STATUS_MATCHES, + MATCH_STATUS_MATCHES_BY_DEPENDENCY, + }: return True for dep in target.deps: if _DoesTargetDependOnMatchingTargets(dep): @@ -466,9 +467,9 @@ def _DoesTargetDependOnMatchingTargets(target): def _GetTargetsDependingOnMatchingTargets(possible_targets): """Returns the list of Targets in |possible_targets| that depend (either - directly on indirectly) on at least one of the targets containing the files - supplied as input to analyzer. - possible_targets: targets to search from.""" + directly on indirectly) on at least one of the targets containing the files + supplied as input to analyzer. + possible_targets: targets to search from.""" found = [] print("Targets that matched by dependency:") for target in possible_targets: @@ -479,11 +480,11 @@ def _GetTargetsDependingOnMatchingTargets(possible_targets): def _AddCompileTargets(target, roots, add_if_no_ancestor, result): """Recurses through all targets that depend on |target|, adding all targets - that need to be built (and are in |roots|) to |result|. - roots: set of root targets. - add_if_no_ancestor: If true and there are no ancestors of |target| then add - |target| to |result|. |target| must still be in |roots|. - result: targets that need to be built are added here.""" + that need to be built (and are in |roots|) to |result|. + roots: set of root targets. + add_if_no_ancestor: If true and there are no ancestors of |target| then add + |target| to |result|. |target| must still be in |roots|. + result: targets that need to be built are added here.""" if target.visited: return @@ -536,8 +537,8 @@ def _AddCompileTargets(target, roots, add_if_no_ancestor, result): def _GetCompileTargets(matching_targets, supplied_targets): """Returns the set of Targets that require a build. - matching_targets: targets that changed and need to be built. - supplied_targets: set of targets supplied to analyzer to search from.""" + matching_targets: targets that changed and need to be built. + supplied_targets: set of targets supplied to analyzer to search from.""" result = set() for target in matching_targets: print("finding compile targets for match", target.name) @@ -591,7 +592,7 @@ def _WriteOutput(params, **values): def _WasGypIncludeFileModified(params, files): """Returns true if one of the files in |files| is in the set of included - files.""" + files.""" if params["options"].includes: for include in params["options"].includes: if _ToGypPath(os.path.normpath(include)) in files: @@ -607,7 +608,7 @@ def _NamesNotIn(names, mapping): def _LookupTargets(names, mapping): """Returns a list of the mapping[name] for each value in |names| that is in - |mapping|.""" + |mapping|.""" return [mapping[name] for name in names if name in mapping] @@ -683,11 +684,9 @@ def find_matching_test_target_names(self): ) test_target_names_contains_all = "all" in self._test_target_names if test_target_names_contains_all: - test_targets = [ - x for x in (set(test_targets_no_all) | set(self._root_targets)) - ] + test_targets = list(set(test_targets_no_all) | set(self._root_targets)) else: - test_targets = [x for x in test_targets_no_all] + test_targets = list(test_targets_no_all) print("supplied test_targets") for target_name in self._test_target_names: print("\t", target_name) @@ -701,10 +700,10 @@ def find_matching_test_target_names(self): ) & set(self._root_targets) if matching_test_targets_contains_all: # Remove any of the targets for all that were not explicitly supplied, - # 'all' is subsequentely added to the matching names below. - matching_test_targets = [ - x for x in (set(matching_test_targets) & set(test_targets_no_all)) - ] + # 'all' is subsequently added to the matching names below. + matching_test_targets = list( + set(matching_test_targets) & set(test_targets_no_all) + ) print("matched test_targets") for target in matching_test_targets: print("\t", target.name) @@ -729,9 +728,7 @@ def find_matching_compile_target_names(self): self._supplied_target_names_no_all(), self._unqualified_mapping ) if "all" in self._supplied_target_names(): - supplied_targets = [ - x for x in (set(supplied_targets) | set(self._root_targets)) - ] + supplied_targets = list(set(supplied_targets) | set(self._root_targets)) print("Supplied test_targets & compile_targets") for target in supplied_targets: print("\t", target.name) @@ -751,7 +748,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if not config.files: raise Exception( - "Must specify files to analyze via config_path generator " "flag" + "Must specify files to analyze via config_path generator flag" ) toplevel_dir = _ToGypPath(os.path.abspath(params["options"].toplevel_dir)) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py index cdf1a4832cf1a..5d5cae2afbf66 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py @@ -15,13 +15,14 @@ # Try to avoid setting global variables where possible. -import gyp -import gyp.common -import gyp.generator.make as make # Reuse global functions from make backend. import os import re import subprocess +import gyp +import gyp.common +from gyp.generator import make # Reuse global functions from make backend. + generator_default_variables = { "OS": "android", "EXECUTABLE_PREFIX": "", @@ -176,9 +177,7 @@ def Write( self.WriteLn("LOCAL_IS_HOST_MODULE := true") self.WriteLn("LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)") elif sdk_version > 0: - self.WriteLn( - "LOCAL_MODULE_TARGET_ARCH := " "$(TARGET_$(GYP_VAR_PREFIX)ARCH)" - ) + self.WriteLn("LOCAL_MODULE_TARGET_ARCH := $(TARGET_$(GYP_VAR_PREFIX)ARCH)") self.WriteLn("LOCAL_SDK_VERSION := %s" % sdk_version) # Grab output directories; needed for Actions and Rules. @@ -379,7 +378,7 @@ def WriteRules(self, rules, extra_sources, extra_outputs): inputs = rule.get("inputs") for rule_source in rule.get("rule_sources", []): (rule_source_dirname, rule_source_basename) = os.path.split(rule_source) - (rule_source_root, rule_source_ext) = os.path.splitext( + (rule_source_root, _rule_source_ext) = os.path.splitext( rule_source_basename ) @@ -587,11 +586,11 @@ def WriteSources(self, spec, configs, extra_sources): local_files = [] for source in sources: (root, ext) = os.path.splitext(source) - if "$(gyp_shared_intermediate_dir)" in source: - extra_sources.append(source) - elif "$(gyp_intermediate_dir)" in source: - extra_sources.append(source) - elif IsCPPExtension(ext) and ext != local_cpp_extension: + if ( + "$(gyp_shared_intermediate_dir)" in source + or "$(gyp_intermediate_dir)" in source + or (IsCPPExtension(ext) and ext != local_cpp_extension) + ): extra_sources.append(source) else: local_files.append(os.path.normpath(os.path.join(self.path, source))) @@ -697,7 +696,7 @@ def ComputeOutputParts(self, spec): target, ) - if self.type != "static_library" and self.type != "shared_library": + if self.type not in {"static_library", "shared_library"}: target_prefix = spec.get("product_prefix", target_prefix) target = spec.get("product_name", target) product_ext = spec.get("product_extension") @@ -730,19 +729,17 @@ def ComputeOutput(self, spec): path = "$($(GYP_HOST_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES)" else: path = "$($(GYP_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)" + # Other targets just get built into their intermediate dir. + elif self.toolset == "host": + path = ( + "$(call intermediates-dir-for,%s,%s,true,," + "$(GYP_HOST_VAR_PREFIX))" % (self.android_class, self.android_module) + ) else: - # Other targets just get built into their intermediate dir. - if self.toolset == "host": - path = ( - "$(call intermediates-dir-for,%s,%s,true,," - "$(GYP_HOST_VAR_PREFIX))" - % (self.android_class, self.android_module) - ) - else: - path = "$(call intermediates-dir-for,{},{},,,$(GYP_VAR_PREFIX))".format( - self.android_class, - self.android_module, - ) + path = ( + f"$(call intermediates-dir-for,{self.android_class}," + f"{self.android_module},,,$(GYP_VAR_PREFIX))" + ) assert spec.get("product_dir") is None # TODO: not supported? return os.path.join(path, self.ComputeOutputBasename(spec)) @@ -769,7 +766,7 @@ def ExtractIncludesFromCFlags(self, cflags): Args: cflags: A list of compiler flags, which may be mixed with "-I.." Returns: - A tuple of lists: (clean_clfags, include_paths). "-I.." is trimmed. + A tuple of lists: (clean_cflags, include_paths). "-I.." is trimmed. """ clean_cflags = [] include_paths = [] @@ -901,8 +898,7 @@ def WriteTarget( if self.type != "none": self.WriteTargetFlags(spec, configs, link_deps) - settings = spec.get("aosp_build_settings", {}) - if settings: + if settings := spec.get("aosp_build_settings", {}): self.WriteLn("### Set directly by aosp_build_settings.") for k, v in settings.items(): if isinstance(v, list): @@ -1003,9 +999,9 @@ def LocalPathify(self, path): # - i.e. that the resulting path is still inside the project tree. The # path may legitimately have ended up containing just $(LOCAL_PATH), though, # so we don't look for a slash. - assert local_path.startswith( - "$(LOCAL_PATH)" - ), f"Path {path} attempts to escape from gyp path {self.path} !)" + assert local_path.startswith("$(LOCAL_PATH)"), ( + f"Path {path} attempts to escape from gyp path {self.path} !)" + ) return local_path def ExpandInputRoot(self, template, expansion, dirname): @@ -1047,9 +1043,9 @@ def CalculateMakefilePath(build_file, base_name): base_path = gyp.common.RelativePath(os.path.dirname(build_file), options.depth) # We write the file in the base_path directory. output_file = os.path.join(options.depth, base_path, base_name) - assert ( - not options.generator_output - ), "The Android backend does not support options.generator_output." + assert not options.generator_output, ( + "The Android backend does not support options.generator_output." + ) base_path = gyp.common.RelativePath( os.path.dirname(build_file), options.toplevel_dir ) @@ -1069,9 +1065,9 @@ def CalculateMakefilePath(build_file, base_name): makefile_name = "GypAndroid" + options.suffix + ".mk" makefile_path = os.path.join(options.toplevel_dir, makefile_name) - assert ( - not options.generator_output - ), "The Android backend does not support options.generator_output." + assert not options.generator_output, ( + "The Android backend does not support options.generator_output." + ) gyp.common.EnsureDirExists(makefile_path) root_makefile = open(makefile_path, "w") diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py index c95d18415cdb3..dc9ea39acb7fc 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py @@ -28,11 +28,11 @@ CMakeLists.txt file. """ - import multiprocessing import os import signal import subprocess + import gyp.common import gyp.xcode_emulation @@ -96,14 +96,14 @@ def Linkable(filename): def NormjoinPathForceCMakeSource(base_path, rel_path): """Resolves rel_path against base_path and returns the result. - If rel_path is an absolute path it is returned unchanged. - Otherwise it is resolved against base_path and normalized. - If the result is a relative path, it is forced to be relative to the - CMakeLists.txt. - """ + If rel_path is an absolute path it is returned unchanged. + Otherwise it is resolved against base_path and normalized. + If the result is a relative path, it is forced to be relative to the + CMakeLists.txt. + """ if os.path.isabs(rel_path): return rel_path - if any([rel_path.startswith(var) for var in FULL_PATH_VARS]): + if any(rel_path.startswith(var) for var in FULL_PATH_VARS): return rel_path # TODO: do we need to check base_path for absolute variables as well? return os.path.join( @@ -113,10 +113,10 @@ def NormjoinPathForceCMakeSource(base_path, rel_path): def NormjoinPath(base_path, rel_path): """Resolves rel_path against base_path and returns the result. - TODO: what is this really used for? - If rel_path begins with '$' it is returned unchanged. - Otherwise it is resolved against base_path if relative, then normalized. - """ + TODO: what is this really used for? + If rel_path begins with '$' it is returned unchanged. + Otherwise it is resolved against base_path if relative, then normalized. + """ if rel_path.startswith("$") and not rel_path.startswith("${configuration}"): return rel_path return os.path.normpath(os.path.join(base_path, rel_path)) @@ -125,19 +125,19 @@ def NormjoinPath(base_path, rel_path): def CMakeStringEscape(a): """Escapes the string 'a' for use inside a CMake string. - This means escaping - '\' otherwise it may be seen as modifying the next character - '"' otherwise it will end the string - ';' otherwise the string becomes a list + This means escaping + '\' otherwise it may be seen as modifying the next character + '"' otherwise it will end the string + ';' otherwise the string becomes a list - The following do not need to be escaped - '#' when the lexer is in string state, this does not start a comment + The following do not need to be escaped + '#' when the lexer is in string state, this does not start a comment - The following are yet unknown - '$' generator variables (like ${obj}) must not be escaped, - but text $ should be escaped - what is wanted is to know which $ come from generator variables - """ + The following are yet unknown + '$' generator variables (like ${obj}) must not be escaped, + but text $ should be escaped + what is wanted is to know which $ come from generator variables + """ return a.replace("\\", "\\\\").replace(";", "\\;").replace('"', '\\"') @@ -236,25 +236,25 @@ def __init__(self, command, modifier, property_modifier): def StringToCMakeTargetName(a): """Converts the given string 'a' to a valid CMake target name. - All invalid characters are replaced by '_'. - Invalid for cmake: ' ', '/', '(', ')', '"' - Invalid for make: ':' - Invalid for unknown reasons but cause failures: '.' - """ + All invalid characters are replaced by '_'. + Invalid for cmake: ' ', '/', '(', ')', '"' + Invalid for make: ':' + Invalid for unknown reasons but cause failures: '.' + """ return a.translate(_maketrans(' /():."', "_______")) def WriteActions(target_name, actions, extra_sources, extra_deps, path_to_gyp, output): """Write CMake for the 'actions' in the target. - Args: - target_name: the name of the CMake target being generated. - actions: the Gyp 'actions' dict for this target. - extra_sources: [(<cmake_src>, <src>)] to append with generated source files. - extra_deps: [<cmake_taget>] to append with generated targets. - path_to_gyp: relative path from CMakeLists.txt being generated to - the Gyp file in which the target being generated is defined. - """ + Args: + target_name: the name of the CMake target being generated. + actions: the Gyp 'actions' dict for this target. + extra_sources: [(<cmake_src>, <src>)] to append with generated source files. + extra_deps: [<cmake_target>] to append with generated targets. + path_to_gyp: relative path from CMakeLists.txt being generated to + the Gyp file in which the target being generated is defined. + """ for action in actions: action_name = StringToCMakeTargetName(action["action_name"]) action_target_name = f"{target_name}__{action_name}" @@ -328,7 +328,7 @@ def WriteActions(target_name, actions, extra_sources, extra_deps, path_to_gyp, o def NormjoinRulePathForceCMakeSource(base_path, rel_path, rule_source): if rel_path.startswith(("${RULE_INPUT_PATH}", "${RULE_INPUT_DIRNAME}")): - if any([rule_source.startswith(var) for var in FULL_PATH_VARS]): + if any(rule_source.startswith(var) for var in FULL_PATH_VARS): return rel_path return NormjoinPathForceCMakeSource(base_path, rel_path) @@ -336,14 +336,14 @@ def NormjoinRulePathForceCMakeSource(base_path, rel_path, rule_source): def WriteRules(target_name, rules, extra_sources, extra_deps, path_to_gyp, output): """Write CMake for the 'rules' in the target. - Args: - target_name: the name of the CMake target being generated. - actions: the Gyp 'actions' dict for this target. - extra_sources: [(<cmake_src>, <src>)] to append with generated source files. - extra_deps: [<cmake_taget>] to append with generated targets. - path_to_gyp: relative path from CMakeLists.txt being generated to - the Gyp file in which the target being generated is defined. - """ + Args: + target_name: the name of the CMake target being generated. + actions: the Gyp 'actions' dict for this target. + extra_sources: [(<cmake_src>, <src>)] to append with generated source files. + extra_deps: [<cmake_target>] to append with generated targets. + path_to_gyp: relative path from CMakeLists.txt being generated to + the Gyp file in which the target being generated is defined. + """ for rule in rules: rule_name = StringToCMakeTargetName(target_name + "__" + rule["rule_name"]) @@ -454,13 +454,13 @@ def WriteRules(target_name, rules, extra_sources, extra_deps, path_to_gyp, outpu def WriteCopies(target_name, copies, extra_deps, path_to_gyp, output): """Write CMake for the 'copies' in the target. - Args: - target_name: the name of the CMake target being generated. - actions: the Gyp 'actions' dict for this target. - extra_deps: [<cmake_taget>] to append with generated targets. - path_to_gyp: relative path from CMakeLists.txt being generated to - the Gyp file in which the target being generated is defined. - """ + Args: + target_name: the name of the CMake target being generated. + actions: the Gyp 'actions' dict for this target. + extra_deps: [<cmake_target>] to append with generated targets. + path_to_gyp: relative path from CMakeLists.txt being generated to + the Gyp file in which the target being generated is defined. + """ copy_name = target_name + "__copies" # CMake gets upset with custom targets with OUTPUT which specify no output. @@ -584,26 +584,26 @@ def CreateCMakeTargetFullName(qualified_target): class CMakeNamer: """Converts Gyp target names into CMake target names. - CMake requires that target names be globally unique. One way to ensure - this is to fully qualify the names of the targets. Unfortunately, this - ends up with all targets looking like "chrome_chrome_gyp_chrome" instead - of just "chrome". If this generator were only interested in building, it - would be possible to fully qualify all target names, then create - unqualified target names which depend on all qualified targets which - should have had that name. This is more or less what the 'make' generator - does with aliases. However, one goal of this generator is to create CMake - files for use with IDEs, and fully qualified names are not as user - friendly. + CMake requires that target names be globally unique. One way to ensure + this is to fully qualify the names of the targets. Unfortunately, this + ends up with all targets looking like "chrome_chrome_gyp_chrome" instead + of just "chrome". If this generator were only interested in building, it + would be possible to fully qualify all target names, then create + unqualified target names which depend on all qualified targets which + should have had that name. This is more or less what the 'make' generator + does with aliases. However, one goal of this generator is to create CMake + files for use with IDEs, and fully qualified names are not as user + friendly. - Since target name collision is rare, we do the above only when required. + Since target name collision is rare, we do the above only when required. - Toolset variants are always qualified from the base, as this is required for - building. However, it also makes sense for an IDE, as it is possible for - defines to be different. - """ + Toolset variants are always qualified from the base, as this is required for + building. However, it also makes sense for an IDE, as it is possible for + defines to be different. + """ def __init__(self, target_list): - self.cmake_target_base_names_conficting = set() + self.cmake_target_base_names_conflicting = set() cmake_target_base_names_seen = set() for qualified_target in target_list: @@ -612,11 +612,11 @@ def __init__(self, target_list): if cmake_target_base_name not in cmake_target_base_names_seen: cmake_target_base_names_seen.add(cmake_target_base_name) else: - self.cmake_target_base_names_conficting.add(cmake_target_base_name) + self.cmake_target_base_names_conflicting.add(cmake_target_base_name) def CreateCMakeTargetName(self, qualified_target): base_name = CreateCMakeTargetBaseName(qualified_target) - if base_name in self.cmake_target_base_names_conficting: + if base_name in self.cmake_target_base_names_conflicting: return CreateCMakeTargetFullName(qualified_target) return base_name @@ -809,8 +809,7 @@ def WriteTarget( # link directories to targets defined after it is called. # As a result, link_directories must come before the target definition. # CMake unfortunately has no means of removing entries from LINK_DIRECTORIES. - library_dirs = config.get("library_dirs") - if library_dirs is not None: + if (library_dirs := config.get("library_dirs")) is not None: output.write("link_directories(") for library_dir in library_dirs: output.write(" ") @@ -929,10 +928,7 @@ def WriteTarget( product_prefix = spec.get("product_prefix", default_product_prefix) product_name = spec.get("product_name", default_product_name) product_ext = spec.get("product_extension") - if product_ext: - product_ext = "." + product_ext - else: - product_ext = default_product_ext + product_ext = "." + product_ext if product_ext else default_product_ext SetTargetProperty(output, cmake_target_name, "PREFIX", product_prefix) SetTargetProperty( @@ -1297,8 +1293,7 @@ def CallGenerateOutputForConfig(arglist): def GenerateOutput(target_list, target_dicts, data, params): - user_config = params.get("generator_flags", {}).get("config", None) - if user_config: + if user_config := params.get("generator_flags", {}).get("config", None): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: config_names = target_dicts[target_list[0]]["configurations"] diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py index f330a04dea4c5..1361aeca48d0c 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py @@ -2,11 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import gyp.common -import gyp.xcode_emulation import json import os +import gyp.common +import gyp.xcode_emulation + generator_additional_non_configuration_keys = [] generator_additional_path_sections = [] generator_extra_sources_for_rules = [] @@ -34,7 +35,7 @@ def IsMac(params): - return "mac" == gyp.common.GetFlavor(params) + return gyp.common.GetFlavor(params) == "mac" def CalculateVariables(default_variables, params): @@ -93,13 +94,13 @@ def resolve(filename): gyp.common.EncodePOSIXShellArgument(file), ) ) - commands.append(dict(command=command, directory=output_dir, file=file)) + commands.append({"command": command, "directory": output_dir, "file": file}) def GenerateOutput(target_list, target_dicts, data, params): per_config_commands = {} for qualified_target, target in target_dicts.items(): - build_file, target_name, toolset = gyp.common.ParseQualifiedTarget( + build_file, _target_name, _toolset = gyp.common.ParseQualifiedTarget( qualified_target ) if IsMac(params): @@ -108,7 +109,14 @@ def GenerateOutput(target_list, target_dicts, data, params): cwd = os.path.dirname(build_file) AddCommandsForTarget(cwd, target, params, per_config_commands) - output_dir = params["generator_flags"].get("output_dir", "out") + output_dir = None + try: + # generator_output can be `None` on Windows machines, or even not + # defined in other cases + output_dir = params.get("options").generator_output + except AttributeError: + pass + output_dir = output_dir or params["generator_flags"].get("output_dir", "out") for configuration_name, commands in per_config_commands.items(): filename = os.path.join(output_dir, configuration_name, "compile_commands.json") gyp.common.EnsureDirExists(filename) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py index 99d5c1fd69db3..c919674024e69 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py @@ -3,11 +3,12 @@ # found in the LICENSE file. +import json import os + import gyp import gyp.common import gyp.msvs_emulation -import json generator_supports_multiple_toolsets = True @@ -55,7 +56,7 @@ def CalculateVariables(default_variables, params): def CalculateGeneratorInputInfo(params): """Calculate the generator specific info that gets fed to input (called by - gyp).""" + gyp).""" generator_flags = params.get("generator_flags", {}) if generator_flags.get("adjust_static_libraries", False): global generator_wants_static_library_dependencies_adjusted diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py index 1ff0dc83ae200..685cd08c964b9 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py @@ -17,14 +17,15 @@ This generator has no automated tests, so expect it to be broken. """ -from xml.sax.saxutils import escape import os.path +import shlex import subprocess +import xml.etree.ElementTree as ET +from xml.sax.saxutils import escape + import gyp import gyp.common import gyp.msvs_emulation -import shlex -import xml.etree.cElementTree as ET generator_wants_static_library_dependencies_adjusted = False @@ -68,7 +69,7 @@ def CalculateVariables(default_variables, params): def CalculateGeneratorInputInfo(params): """Calculate the generator specific info that gets fed to input (called by - gyp).""" + gyp).""" generator_flags = params.get("generator_flags", {}) if generator_flags.get("adjust_static_libraries", False): global generator_wants_static_library_dependencies_adjusted @@ -85,10 +86,10 @@ def GetAllIncludeDirectories( ): """Calculate the set of include directories to be used. - Returns: - A list including all the include_dir's specified for every target followed - by any include directories that were added as cflag compiler options. - """ + Returns: + A list including all the include_dir's specified for every target followed + by any include directories that were added as cflag compiler options. + """ gyp_includes_set = set() compiler_includes_list = [] @@ -177,11 +178,11 @@ def GetAllIncludeDirectories( def GetCompilerPath(target_list, data, options): """Determine a command that can be used to invoke the compiler. - Returns: - If this is a gyp project that has explicit make settings, try to determine - the compiler from that. Otherwise, see if a compiler was specified via the - CC_target environment variable. - """ + Returns: + If this is a gyp project that has explicit make settings, try to determine + the compiler from that. Otherwise, see if a compiler was specified via the + CC_target environment variable. + """ # First, see if the compiler is configured in make's settings. build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) make_global_settings_dict = data[build_file].get("make_global_settings", {}) @@ -201,10 +202,10 @@ def GetCompilerPath(target_list, data, options): def GetAllDefines(target_list, target_dicts, data, config_name, params, compiler_path): """Calculate the defines for a project. - Returns: - A dict that includes explicit defines declared in gyp files along with all - of the default defines that the compiler uses. - """ + Returns: + A dict that includes explicit defines declared in gyp files along with all + of the default defines that the compiler uses. + """ # Get defines declared in the gyp files. all_defines = {} @@ -248,10 +249,7 @@ def GetAllDefines(target_list, target_dicts, data, config_name, params, compiler continue cpp_line_parts = cpp_line.split(" ", 2) key = cpp_line_parts[1] - if len(cpp_line_parts) >= 3: - val = cpp_line_parts[2] - else: - val = "1" + val = cpp_line_parts[2] if len(cpp_line_parts) >= 3 else "1" all_defines[key] = val return all_defines @@ -375,8 +373,8 @@ def GenerateClasspathFile( target_list, target_dicts, toplevel_dir, toplevel_build, out_name ): """Generates a classpath file suitable for symbol navigation and code - completion of Java code (such as in Android projects) by finding all - .java and .jar files used as action inputs.""" + completion of Java code (such as in Android projects) by finding all + .java and .jar files used as action inputs.""" gyp.common.EnsureDirExists(out_name) result = ET.Element("classpath") @@ -453,8 +451,7 @@ def GenerateOutput(target_list, target_dicts, data, params): if params["options"].generator_output: raise NotImplementedError("--generator_output not implemented for eclipse") - user_config = params.get("generator_flags", {}).get("config", None) - if user_config: + if user_config := params.get("generator_flags", {}).get("config", None): GenerateOutputForConfig(target_list, target_dicts, data, params, user_config) else: config_names = target_dicts[target_list[0]]["configurations"] diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py index 4171704c47a4b..89af24a201b10 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py @@ -30,10 +30,9 @@ to change. """ - -import gyp.common import pprint +import gyp.common # These variables should just be spit back out as variable references. _generator_identity_variables = [ @@ -74,7 +73,7 @@ def GenerateOutput(target_list, target_dicts, data, params): output_files = {} for qualified_target in target_list: - [input_file, target] = gyp.common.ParseQualifiedTarget(qualified_target)[0:2] + [input_file, _target] = gyp.common.ParseQualifiedTarget(qualified_target)[0:2] if input_file[-4:] != ".gyp": continue diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py index 82a07ddc6577b..72d22ff32b92d 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py @@ -13,11 +13,9 @@ The expected usage is "gyp -f gypsh -D OS=desired_os". """ - import code import sys - # All of this stuff about generator variables was lovingly ripped from gypd.py. # That module has a much better description of what's going on and why. _generator_identity_variables = [ @@ -49,10 +47,9 @@ def GenerateOutput(target_list, target_dicts, data, params): # Use a banner that looks like the stock Python one and like what # code.interact uses by default, but tack on something to indicate what # locals are available, and identify gypsh. - banner = "Python {} on {}\nlocals.keys() = {}\ngypsh".format( - sys.version, - sys.platform, - repr(sorted(locals.keys())), + banner = ( + f"Python {sys.version} on {sys.platform}\nlocals.keys() = " + f"{sorted(locals.keys())!r}\ngypsh" ) code.interact(banner, local=locals) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py index c595f20fe2df1..16b6f4e80b119 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py @@ -22,16 +22,17 @@ # the side to keep the files readable. +import hashlib import os import re import subprocess +import sys + import gyp import gyp.common import gyp.xcode_emulation from gyp.common import GetEnvironFallback -import hashlib - generator_default_variables = { "EXECUTABLE_PREFIX": "", "EXECUTABLE_SUFFIX": "", @@ -50,7 +51,7 @@ } # Make supports multiple toolsets -generator_supports_multiple_toolsets = True +generator_supports_multiple_toolsets = gyp.common.CrossCompileRequested() # Request sorted dependencies in the order from dependents to dependencies. generator_wants_sorted_dependencies = False @@ -77,7 +78,7 @@ def CalculateVariables(default_variables, params): # Copy additional generator configuration data from Xcode, which is shared # by the Mac Make generator. - import gyp.generator.xcode as xcode_generator + import gyp.generator.xcode as xcode_generator # noqa: PLC0415 global generator_additional_non_configuration_keys generator_additional_non_configuration_keys = getattr( @@ -99,6 +100,9 @@ def CalculateVariables(default_variables, params): default_variables.setdefault("OS", operating_system) if flavor == "aix": default_variables.setdefault("SHARED_LIB_SUFFIX", ".a") + elif flavor == "zos": + default_variables.setdefault("SHARED_LIB_SUFFIX", ".x") + COMPILABLE_EXTENSIONS.update({".pli": "pli"}) else: default_variables.setdefault("SHARED_LIB_SUFFIX", ".so") default_variables.setdefault("SHARED_LIB_DIR", "$(builddir)/lib.$(TOOLSET)") @@ -154,6 +158,31 @@ def CalculateGeneratorInputInfo(params): quiet_cmd_link = LINK($(TOOLSET)) $@ cmd_link = $(LINK.$(TOOLSET)) -o $@ $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,--start-group $(LD_INPUTS) $(LIBS) -Wl,--end-group +# Note: this does not handle spaces in paths +define xargs + $(1) $(word 1,$(2)) +$(if $(word 2,$(2)),$(call xargs,$(1),$(wordlist 2,$(words $(2)),$(2)))) +endef + +define write-to-file + @: >$(1) +$(call xargs,@printf "%s\\n" >>$(1),$(2)) +endef + +OBJ_FILE_LIST := ar-file-list + +define create_archive + rm -f $(1) $(1).$(OBJ_FILE_LIST); mkdir -p `dirname $(1)` + $(call write-to-file,$(1).$(OBJ_FILE_LIST),$(filter %.o,$(2))) + $(AR.$(TOOLSET)) crs $(1) @$(1).$(OBJ_FILE_LIST) +endef + +define create_thin_archive + rm -f $(1) $(OBJ_FILE_LIST); mkdir -p `dirname $(1)` + $(call write-to-file,$(1).$(OBJ_FILE_LIST),$(filter %.o,$(2))) + $(AR.$(TOOLSET)) crsT $(1) @$(1).$(OBJ_FILE_LIST) +endef + # We support two kinds of shared objects (.so): # 1) shared_library, which is just bundling together many dependent libraries # into a link line. @@ -179,7 +208,7 @@ def CalculateGeneratorInputInfo(params): LINK_COMMANDS_MAC = """\ quiet_cmd_alink = LIBTOOL-STATIC $@ -cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^) +cmd_alink = rm -f $@ && %(python)s gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %%.o,$^) quiet_cmd_link = LINK($(TOOLSET)) $@ cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) @@ -189,7 +218,7 @@ def CalculateGeneratorInputInfo(params): quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) -""" # noqa: E501 +""" % {"python": sys.executable} # noqa: E501 LINK_COMMANDS_ANDROID = """\ quiet_cmd_alink = AR($(TOOLSET)) $@ @@ -198,6 +227,31 @@ def CalculateGeneratorInputInfo(params): quiet_cmd_alink_thin = AR($(TOOLSET)) $@ cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) +# Note: this does not handle spaces in paths +define xargs + $(1) $(word 1,$(2)) +$(if $(word 2,$(2)),$(call xargs,$(1),$(wordlist 2,$(words $(2)),$(2)))) +endef + +define write-to-file + @: >$(1) +$(call xargs,@printf "%s\\n" >>$(1),$(2)) +endef + +OBJ_FILE_LIST := ar-file-list + +define create_archive + rm -f $(1) $(1).$(OBJ_FILE_LIST); mkdir -p `dirname $(1)` + $(call write-to-file,$(1).$(OBJ_FILE_LIST),$(filter %.o,$(2))) + $(AR.$(TOOLSET)) crs $(1) @$(1).$(OBJ_FILE_LIST) +endef + +define create_thin_archive + rm -f $(1) $(OBJ_FILE_LIST); mkdir -p `dirname $(1)` + $(call write-to-file,$(1).$(OBJ_FILE_LIST),$(filter %.o,$(2))) + $(AR.$(TOOLSET)) crsT $(1) @$(1).$(OBJ_FILE_LIST) +endef + # Due to circular dependencies between libraries :(, we wrap the # special "figure out circular dependencies" flags around the entire # input list during linking. @@ -237,6 +291,24 @@ def CalculateGeneratorInputInfo(params): """ # noqa: E501 +LINK_COMMANDS_OS400 = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) -X64 crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) -X64 crs $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) +""" # noqa: E501 + + LINK_COMMANDS_OS390 = """\ quiet_cmd_alink = AR($(TOOLSET)) $@ cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) @@ -248,10 +320,10 @@ def CalculateGeneratorInputInfo(params): cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) -Wl,DLL +cmd_solink = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) -Wl,DLL +cmd_solink_module = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) """ # noqa: E501 @@ -307,7 +379,8 @@ def CalculateGeneratorInputInfo(params): CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS) LINK.target ?= %(LINK.target)s LDFLAGS.target ?= $(LDFLAGS) -AR.target ?= $(AR) +AR.target ?= %(AR.target)s +PLI.target ?= %(PLI.target)s # C++ apps need to be linked with g++. LINK ?= $(CXX.target) @@ -321,6 +394,7 @@ def CalculateGeneratorInputInfo(params): LINK.host ?= %(LINK.host)s LDFLAGS.host ?= $(LDFLAGS_host) AR.host ?= %(AR.host)s +PLI.host ?= %(PLI.host)s # Define a dir function that can handle spaces. # http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions @@ -369,13 +443,27 @@ def CalculateGeneratorInputInfo(params): define fixup_dep # The depfile may not exist if the input file didn't have any #includes. touch $(depfile).raw -# Fixup path as in (1). -sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) +# Fixup path as in (1).""" + + ( + r""" +sed -e "s|^$(notdir $@)|$@|" -re 's/\\\\([^$$])/\/\1/g' $(depfile).raw >> $(depfile)""" + if sys.platform == "win32" + else r""" +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)""" + ) + + r""" # Add extra rules as in (2). # We remove slashes and replace spaces with new lines; # remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ +# delete the first line and append a colon to the remaining lines.""" + + ( + """ +sed -e 's/\\\\\\\\$$//' -e 's/\\\\\\\\/\\//g' -e 'y| |\\n|' $(depfile).raw |\\""" + if sys.platform == "win32" + else """ +sed -e 's|\\\\||' -e 'y| |\\n|' $(depfile).raw |\\""" + ) + + r""" grep -v '^$$' |\ sed -e 1d -e 's|$$|:|' \ >> $(depfile) @@ -400,6 +488,9 @@ def CalculateGeneratorInputInfo(params): # send stderr to /dev/null to ignore messages when linking directories. cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp %(copy_archive_args)s "$<" "$@") +quiet_cmd_symlink = SYMLINK $@ +cmd_symlink = ln -sf "$<" "$@" + %(link_commands)s """ # noqa: E501 r""" @@ -524,14 +615,14 @@ def CalculateGeneratorInputInfo(params): # Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd # already. quiet_cmd_mac_tool = MACTOOL $(4) $< -cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@" +cmd_mac_tool = %(python)s gyp-mac-tool $(4) $< "$@" quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@ -cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) +cmd_mac_package_framework = %(python)s gyp-mac-tool package-framework "$@" $(4) quiet_cmd_infoplist = INFOPLIST $@ cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@" -""" # noqa: E501 +""" % {"python": sys.executable} # noqa: E501 def WriteRootHeaderSuffixRules(writer): @@ -555,6 +646,15 @@ def WriteRootHeaderSuffixRules(writer): writer.write("\n") +SHARED_HEADER_OS390_COMMANDS = """ +PLIFLAGS.target ?= -qlp=64 -qlimits=extname=31 $(PLIFLAGS) +PLIFLAGS.host ?= -qlp=64 -qlimits=extname=31 $(PLIFLAGS) + +quiet_cmd_pli = PLI($(TOOLSET)) $@ +cmd_pli = $(PLI.$(TOOLSET)) $(GYP_PLIFLAGS) $(PLIFLAGS.$(TOOLSET)) -c $< && \ + if [ -f $(notdir $@) ]; then /bin/cp $(notdir $@) $@; else true; fi +""" + SHARED_HEADER_SUFFIX_RULES_COMMENT1 = """\ # Suffix rules, putting all outputs into $(obj). """ @@ -596,10 +696,7 @@ def WriteRootHeaderSuffixRules(writer): def Compilable(filename): """Return true if the file is compilable (should be in OBJS).""" - for res in (filename.endswith(e) for e in COMPILABLE_EXTENSIONS): - if res: - return True - return False + return any(res for res in (filename.endswith(e) for e in COMPILABLE_EXTENSIONS)) def Linkable(filename): @@ -643,6 +740,12 @@ def QuoteIfNecessary(string): return string +def replace_sep(string): + if sys.platform == "win32": + string = string.replace("\\\\", "/").replace("\\", "/") + return string + + def StringToMakefileVariable(string): """Convert a string to a value that is acceptable as a make variable name.""" return re.sub("[^a-zA-Z0-9_]", "_", string) @@ -693,7 +796,7 @@ def __init__(self, generator_flags, flavor): self.suffix_rules_objdir2 = {} # Generate suffix rules for all compilable extensions. - for ext in COMPILABLE_EXTENSIONS.keys(): + for ext, value in COMPILABLE_EXTENSIONS.items(): # Suffix rules for source folder. self.suffix_rules_srcdir.update( { @@ -702,7 +805,7 @@ def __init__(self, generator_flags, flavor): $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD \t@$(call do_cmd,%s,1) """ - % (ext, COMPILABLE_EXTENSIONS[ext]) + % (ext, value) ) } ) @@ -715,7 +818,7 @@ def __init__(self, generator_flags, flavor): $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD \t@$(call do_cmd,%s,1) """ - % (ext, COMPILABLE_EXTENSIONS[ext]) + % (ext, value) ) } ) @@ -726,7 +829,7 @@ def __init__(self, generator_flags, flavor): $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD \t@$(call do_cmd,%s,1) """ - % (ext, COMPILABLE_EXTENSIONS[ext]) + % (ext, value) ) } ) @@ -777,7 +880,7 @@ def Write( self.output = self.ComputeMacBundleOutput(spec) self.output_binary = self.ComputeMacBundleBinaryOutput(spec) else: - self.output = self.output_binary = self.ComputeOutput(spec) + self.output = self.output_binary = replace_sep(self.ComputeOutput(spec)) self.is_standalone_static_library = bool( spec.get("standalone_static_library", 0) @@ -903,7 +1006,7 @@ def WriteSubMake(self, output_filename, makefile_path, targets, build_dir): # sub-project dir (see test/subdirectory/gyptest-subdir-all.py). self.WriteLn( "export builddir_name ?= %s" - % os.path.join(os.path.dirname(output_filename), build_dir) + % replace_sep(os.path.join(os.path.dirname(output_filename), build_dir)) ) self.WriteLn(".PHONY: all") self.WriteLn("all:") @@ -981,12 +1084,20 @@ def WriteActions( # libraries, but until everything is made cross-compile safe, also use # target libraries. # TODO(piman): when everything is cross-compile safe, remove lib.target - self.WriteLn( - "cmd_%s = LD_LIBRARY_PATH=$(builddir)/lib.host:" - "$(builddir)/lib.target:$$LD_LIBRARY_PATH; " - "export LD_LIBRARY_PATH; " - "%s%s" % (name, cd_action, command) - ) + if self.flavor in {"zos", "aix"}: + self.WriteLn( + "cmd_%s = LIBPATH=$(builddir)/lib.host:" + "$(builddir)/lib.target:$$LIBPATH; " + "export LIBPATH; " + "%s%s" % (name, cd_action, command) + ) + else: + self.WriteLn( + "cmd_%s = LD_LIBRARY_PATH=$(builddir)/lib.host:" + "$(builddir)/lib.target:$$LD_LIBRARY_PATH; " + "export LD_LIBRARY_PATH; " + "%s%s" % (name, cd_action, command) + ) self.WriteLn() outputs = [self.Absolutify(o) for o in outputs] # The makefile rules are all relative to the top dir, but the gyp actions @@ -1058,7 +1169,7 @@ def WriteRules( for rule_source in rule.get("rule_sources", []): dirs = set() (rule_source_dirname, rule_source_basename) = os.path.split(rule_source) - (rule_source_root, rule_source_ext) = os.path.splitext( + (rule_source_root, _rule_source_ext) = os.path.splitext( rule_source_basename ) @@ -1336,9 +1447,7 @@ def WriteSources( for obj in objs: assert " " not in obj, "Spaces in object filenames not supported (%s)" % obj - self.WriteLn( - "# Add to the list of files we specially track " "dependencies for." - ) + self.WriteLn("# Add to the list of files we specially track dependencies for.") self.WriteLn("all_deps += $(OBJS)") self.WriteLn() @@ -1347,7 +1456,7 @@ def WriteSources( self.WriteMakeRule( ["$(OBJS)"], deps, - comment="Make sure our dependencies are built " "before any of us.", + comment="Make sure our dependencies are built before any of us.", order_only=True, ) @@ -1358,12 +1467,11 @@ def WriteSources( self.WriteMakeRule( ["$(OBJS)"], extra_outputs, - comment="Make sure our actions/rules run " "before any of us.", + comment="Make sure our actions/rules run before any of us.", order_only=True, ) - pchdeps = precompiled_header.GetObjDependencies(compilable, objs) - if pchdeps: + if pchdeps := precompiled_header.GetObjDependencies(compilable, objs): self.WriteLn("# Dependencies from obj files to their precompiled headers") for source, obj, gch in pchdeps: self.WriteLn(f"{obj}: {gch}") @@ -1396,7 +1504,8 @@ def WriteSources( "$(OBJS): GYP_OBJCFLAGS := " "$(DEFS_$(BUILDTYPE)) " "$(INCS_$(BUILDTYPE)) " - "%s " % precompiled_header.GetInclude("m") + "%s " + % precompiled_header.GetInclude("m") + "$(CFLAGS_$(BUILDTYPE)) " "$(CFLAGS_C_$(BUILDTYPE)) " "$(CFLAGS_OBJC_$(BUILDTYPE))" @@ -1405,7 +1514,8 @@ def WriteSources( "$(OBJS): GYP_OBJCXXFLAGS := " "$(DEFS_$(BUILDTYPE)) " "$(INCS_$(BUILDTYPE)) " - "%s " % precompiled_header.GetInclude("mm") + "%s " + % precompiled_header.GetInclude("mm") + "$(CFLAGS_$(BUILDTYPE)) " "$(CFLAGS_CC_$(BUILDTYPE)) " "$(CFLAGS_OBJCC_$(BUILDTYPE))" @@ -1480,6 +1590,8 @@ def ComputeOutputBasename(self, spec): target_prefix = "lib" if self.flavor == "aix": target_ext = ".a" + elif self.flavor == "zos": + target_ext = ".x" else: target_ext = ".so" elif self.type == "none": @@ -1495,8 +1607,7 @@ def ComputeOutputBasename(self, spec): target_prefix = spec.get("product_prefix", target_prefix) target = spec.get("product_name", target) - product_ext = spec.get("product_extension") - if product_ext: + if product_ext := spec.get("product_extension"): target_ext = "." + product_ext return target_prefix + target + target_ext @@ -1560,6 +1671,14 @@ def ComputeDeps(self, spec): # link_deps.extend(spec.get('libraries', [])) return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps)) + def GetSharedObjectFromSidedeck(self, sidedeck): + """Return the shared object files based on sidedeck""" + return re.sub(r"\.x$", ".so", sidedeck) + + def GetUnversionedSidedeckFromSidedeck(self, sidedeck): + """Return the shared object files based on sidedeck""" + return re.sub(r"\.\d+\.x$", ".x", sidedeck) + def WriteDependencyOnExtraOutputs(self, target, extra_outputs): self.WriteMakeRule( [self.output_binary], @@ -1586,7 +1705,7 @@ def WriteTarget( self.WriteMakeRule( extra_outputs, deps, - comment=("Preserve order dependency of " "special output on deps."), + comment=("Preserve order dependency of special output on deps."), order_only=True, ) @@ -1625,7 +1744,8 @@ def WriteTarget( # into the link command, so we need lots of escaping. ldflags.append(r"-Wl,-rpath=\$$ORIGIN/") ldflags.append(r"-Wl,-rpath-link=\$(builddir)/") - library_dirs = config.get("library_dirs", []) + if library_dirs := config.get("library_dirs", []): + library_dirs = [Sourceify(self.Absolutify(i)) for i in library_dirs] ldflags += [("-L%s" % library_dir) for library_dir in library_dirs] self.WriteList(ldflags, "LDFLAGS_%s" % configname) if self.flavor == "mac": @@ -1666,13 +1786,13 @@ def WriteTarget( # using ":=". self.WriteSortedXcodeEnv(self.output, self.GetSortedXcodePostbuildEnv()) - for configname in target_postbuilds: + for configname, value in target_postbuilds.items(): self.WriteLn( "%s: TARGET_POSTBUILDS_%s := %s" % ( QuoteSpaces(self.output), configname, - gyp.common.EncodePOSIXShellList(target_postbuilds[configname]), + gyp.common.EncodePOSIXShellList(value), ) ) @@ -1721,7 +1841,7 @@ def WriteTarget( # Since this target depends on binary and resources which are in # nested subfolders, the framework directory will be older than # its dependencies usually. To prevent this rule from executing - # on every build (expensive, especially with postbuilds), expliclity + # on every build (expensive, especially with postbuilds), explicitly # update the time on the framework directory. self.WriteLn("\t@touch -c %s" % QuoteSpaces(self.output)) @@ -1731,7 +1851,7 @@ def WriteTarget( "on the bundle, not the binary (target '%s')" % self.target ) assert "product_dir" not in spec, ( - "Postbuilds do not work with " "custom product_dir" + "Postbuilds do not work with custom product_dir" ) if self.type == "executable": @@ -1768,12 +1888,25 @@ def WriteTarget( self.flavor not in ("mac", "openbsd", "netbsd", "win") and not self.is_standalone_static_library ): - self.WriteDoCmd( + if self.flavor in ("linux", "android", "openharmony"): + self.WriteMakeRule( + [self.output_binary], + link_deps, + actions=["$(call create_thin_archive,$@,$^)"], + ) + else: + self.WriteDoCmd( + [self.output_binary], + link_deps, + "alink_thin", + part_of_all, + postbuilds=postbuilds, + ) + elif self.flavor in ("linux", "android", "openharmony"): + self.WriteMakeRule( [self.output_binary], link_deps, - "alink_thin", - part_of_all, - postbuilds=postbuilds, + actions=["$(call create_archive,$@,$^)"], ) else: self.WriteDoCmd( @@ -1798,6 +1931,17 @@ def WriteTarget( part_of_all, postbuilds=postbuilds, ) + # z/OS has a .so target as well as a sidedeck .x target + if self.flavor == "zos": + self.WriteLn( + "%s: %s" + % ( + QuoteSpaces( + self.GetSharedObjectFromSidedeck(self.output_binary) + ), + QuoteSpaces(self.output_binary), + ) + ) elif self.type == "loadable_module": for link_dep in link_deps: assert " " not in link_dep, ( @@ -1855,17 +1999,16 @@ def WriteTarget( else: file_desc = "executable" install_path = self._InstallableTargetInstallPath() - installable_deps = [self.output] + installable_deps = [] + if self.flavor != "zos": + installable_deps.append(self.output) if ( self.flavor == "mac" and "product_dir" not in spec and self.toolset == "target" ): # On mac, products are created in install_path immediately. - assert install_path == self.output, "{} != {}".format( - install_path, - self.output, - ) + assert install_path == self.output, f"{install_path} != {self.output}" # Point the target alias to the final binary output. self.WriteMakeRule( @@ -1880,15 +2023,49 @@ def WriteTarget( comment="Copy this to the %s output path." % file_desc, part_of_all=part_of_all, ) - installable_deps.append(install_path) - if self.output != self.alias and self.alias != self.target: + if self.flavor != "zos": + installable_deps.append(install_path) + if self.flavor == "zos" and self.type == "shared_library": + # lib.target/libnode.so has a dependency on $(obj).target/libnode.so + self.WriteDoCmd( + [self.GetSharedObjectFromSidedeck(install_path)], + [self.GetSharedObjectFromSidedeck(self.output)], + "copy", + comment="Copy this to the %s output path." % file_desc, + part_of_all=part_of_all, + ) + # Create a symlink of libnode.x to libnode.version.x + self.WriteDoCmd( + [self.GetUnversionedSidedeckFromSidedeck(install_path)], + [install_path], + "symlink", + comment="Symlnk this to the %s output path." % file_desc, + part_of_all=part_of_all, + ) + # Place libnode.version.so and libnode.x symlink in lib.target dir + installable_deps.append(self.GetSharedObjectFromSidedeck(install_path)) + installable_deps.append( + self.GetUnversionedSidedeckFromSidedeck(install_path) + ) + if self.alias not in (self.output, self.target): self.WriteMakeRule( [self.alias], installable_deps, comment="Short alias for building this %s." % file_desc, phony=True, ) - if part_of_all: + if self.flavor == "zos" and self.type == "shared_library": + # Make sure that .x symlink target is run + self.WriteMakeRule( + ["all"], + [ + self.GetUnversionedSidedeckFromSidedeck(install_path), + self.GetSharedObjectFromSidedeck(install_path), + ], + comment='Add %s to "all" target.' % file_desc, + phony=True, + ) + elif part_of_all: self.WriteMakeRule( ["all"], [install_path], @@ -1905,7 +2082,7 @@ def WriteList(self, value_list, variable=None, prefix="", quoter=QuoteIfNecessar """ values = "" if value_list: - value_list = [quoter(prefix + value) for value in value_list] + value_list = [replace_sep(quoter(prefix + value)) for value in value_list] values = " \\\n\t" + " \\\n\t".join(value_list) self.fp.write(f"{variable} :={values}\n\n") @@ -1992,7 +2169,7 @@ def WriteMakeRule( # - The multi-output rule will have an do-nothing recipe. # Hash the target name to avoid generating overlong filenames. - cmddigest = hashlib.sha1( + cmddigest = hashlib.sha256( (command or self.target).encode("utf-8") ).hexdigest() intermediate = "%s.intermediate" % cmddigest @@ -2184,6 +2361,9 @@ def _InstallableTargetInstallPath(self): # # Install all shared libs into a common directory (per toolset) for # # convenient access with LD_LIBRARY_PATH. # return "$(builddir)/lib.%s/%s" % (self.toolset, self.alias) + if self.flavor == "zos" and self.type == "shared_library": + return "$(builddir)/lib.%s/%s" % (self.toolset, self.alias) + return "$(builddir)/" + self.alias @@ -2208,9 +2388,15 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files) "\t$(call do_cmd,regen_makefile)\n\n" % { "makefile_name": makefile_name, - "deps": " ".join(SourceifyAndQuoteSpaces(bf) for bf in build_files), - "cmd": gyp.common.EncodePOSIXShellList( - [gyp_binary, "-fmake"] + gyp.RegenerateFlags(options) + build_files_args + "deps": replace_sep( + " ".join(sorted(SourceifyAndQuoteSpaces(bf) for bf in build_files)) + ), + "cmd": replace_sep( + gyp.common.EncodePOSIXShellList( + [gyp_binary, "-fmake"] + + gyp.RegenerateFlags(options) + + build_files_args + ) ), } ) @@ -2274,34 +2460,55 @@ def CalculateMakefilePath(build_file, base_name): makefile_path = os.path.join( options.toplevel_dir, options.generator_output, makefile_name ) - srcdir = gyp.common.RelativePath(srcdir, options.generator_output) + srcdir = replace_sep(gyp.common.RelativePath(srcdir, options.generator_output)) srcdir_prefix = "$(srcdir)/" flock_command = "flock" copy_archive_arguments = "-af" makedep_arguments = "-MMD" + + # wasm-ld doesn't support --start-group/--end-group + link_commands = LINK_COMMANDS_LINUX + if flavor in ["wasi", "wasm"]: + link_commands = link_commands.replace(" -Wl,--start-group", "").replace( + " -Wl,--end-group", "" + ) + + CC_target = replace_sep(GetEnvironFallback(("CC_target", "CC"), "$(CC)")) + AR_target = replace_sep(GetEnvironFallback(("AR_target", "AR"), "$(AR)")) + CXX_target = replace_sep(GetEnvironFallback(("CXX_target", "CXX"), "$(CXX)")) + LINK_target = replace_sep(GetEnvironFallback(("LINK_target", "LINK"), "$(LINK)")) + PLI_target = replace_sep(GetEnvironFallback(("PLI_target", "PLI"), "pli")) + CC_host = replace_sep(GetEnvironFallback(("CC_host", "CC"), "gcc")) + AR_host = replace_sep(GetEnvironFallback(("AR_host", "AR"), "ar")) + CXX_host = replace_sep(GetEnvironFallback(("CXX_host", "CXX"), "g++")) + LINK_host = replace_sep(GetEnvironFallback(("LINK_host", "LINK"), "$(CXX.host)")) + PLI_host = replace_sep(GetEnvironFallback(("PLI_host", "PLI"), "pli")) + header_params = { "default_target": default_target, "builddir": builddir_name, "default_configuration": default_configuration, "flock": flock_command, "flock_index": 1, - "link_commands": LINK_COMMANDS_LINUX, + "link_commands": link_commands, "extra_commands": "", "srcdir": srcdir, "copy_archive_args": copy_archive_arguments, "makedep_args": makedep_arguments, - "CC.target": GetEnvironFallback(("CC_target", "CC"), "$(CC)"), - "AR.target": GetEnvironFallback(("AR_target", "AR"), "$(AR)"), - "CXX.target": GetEnvironFallback(("CXX_target", "CXX"), "$(CXX)"), - "LINK.target": GetEnvironFallback(("LINK_target", "LINK"), "$(LINK)"), - "CC.host": GetEnvironFallback(("CC_host", "CC"), "gcc"), - "AR.host": GetEnvironFallback(("AR_host", "AR"), "ar"), - "CXX.host": GetEnvironFallback(("CXX_host", "CXX"), "g++"), - "LINK.host": GetEnvironFallback(("LINK_host", "LINK"), "$(CXX.host)"), + "CC.target": CC_target, + "AR.target": AR_target, + "CXX.target": CXX_target, + "LINK.target": LINK_target, + "PLI.target": PLI_target, + "CC.host": CC_host, + "AR.host": AR_host, + "CXX.host": CXX_host, + "LINK.host": LINK_host, + "PLI.host": PLI_host, } if flavor == "mac": - flock_command = "./gyp-mac-tool flock" + flock_command = "%s gyp-mac-tool flock" % sys.executable header_params.update( { "flock": flock_command, @@ -2314,16 +2521,36 @@ def CalculateMakefilePath(build_file, base_name): header_params.update({"link_commands": LINK_COMMANDS_ANDROID}) elif flavor == "zos": copy_archive_arguments = "-fPR" - makedep_arguments = "-qmakedep=gcc" + CC_target = GetEnvironFallback(("CC_target", "CC"), "njsc") + makedep_arguments = "-MMD" + if CC_target == "clang": + CC_host = GetEnvironFallback(("CC_host", "CC"), "clang") + CXX_target = GetEnvironFallback(("CXX_target", "CXX"), "clang++") + CXX_host = GetEnvironFallback(("CXX_host", "CXX"), "clang++") + elif CC_target == "ibm-clang64": + CC_host = GetEnvironFallback(("CC_host", "CC"), "ibm-clang64") + CXX_target = GetEnvironFallback(("CXX_target", "CXX"), "ibm-clang++64") + CXX_host = GetEnvironFallback(("CXX_host", "CXX"), "ibm-clang++64") + elif CC_target == "ibm-clang": + CC_host = GetEnvironFallback(("CC_host", "CC"), "ibm-clang") + CXX_target = GetEnvironFallback(("CXX_target", "CXX"), "ibm-clang++") + CXX_host = GetEnvironFallback(("CXX_host", "CXX"), "ibm-clang++") + else: + # Node.js versions prior to v18: + makedep_arguments = "-qmakedep=gcc" + CC_host = GetEnvironFallback(("CC_host", "CC"), "njsc") + CXX_target = GetEnvironFallback(("CXX_target", "CXX"), "njsc++") + CXX_host = GetEnvironFallback(("CXX_host", "CXX"), "njsc++") header_params.update( { "copy_archive_args": copy_archive_arguments, "makedep_args": makedep_arguments, "link_commands": LINK_COMMANDS_OS390, - "CC.target": GetEnvironFallback(("CC_target", "CC"), "njsc"), - "CXX.target": GetEnvironFallback(("CXX_target", "CXX"), "njsc++"), - "CC.host": GetEnvironFallback(("CC_host", "CC"), "njsc"), - "CXX.host": GetEnvironFallback(("CXX_host", "CXX"), "njsc++"), + "extra_commands": SHARED_HEADER_OS390_COMMANDS, + "CC.target": CC_target, + "CXX.target": CXX_target, + "CC.host": CC_host, + "CXX.host": CXX_host, } ) elif flavor == "solaris": @@ -2331,7 +2558,7 @@ def CalculateMakefilePath(build_file, base_name): header_params.update( { "copy_archive_args": copy_archive_arguments, - "flock": "./gyp-flock-tool flock", + "flock": "%s gyp-flock-tool flock" % sys.executable, "flock_index": 2, } ) @@ -2347,7 +2574,17 @@ def CalculateMakefilePath(build_file, base_name): { "copy_archive_args": copy_archive_arguments, "link_commands": LINK_COMMANDS_AIX, - "flock": "./gyp-flock-tool flock", + "flock": "%s gyp-flock-tool flock" % sys.executable, + "flock_index": 2, + } + ) + elif flavor == "os400": + copy_archive_arguments = "-pPRf" + header_params.update( + { + "copy_archive_args": copy_archive_arguments, + "link_commands": LINK_COMMANDS_OS400, + "flock": "%s gyp-flock-tool flock" % sys.executable, "flock_index": 2, } ) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py index 8308fa8433352..0f14c055049ad 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py @@ -9,22 +9,21 @@ import re import subprocess import sys - from collections import OrderedDict import gyp.common -import gyp.easy_xml as easy_xml import gyp.generator.ninja as ninja_generator -import gyp.MSVSNew as MSVSNew -import gyp.MSVSProject as MSVSProject -import gyp.MSVSSettings as MSVSSettings -import gyp.MSVSToolFile as MSVSToolFile -import gyp.MSVSUserFile as MSVSUserFile -import gyp.MSVSUtil as MSVSUtil -import gyp.MSVSVersion as MSVSVersion -from gyp.common import GypError -from gyp.common import OrderedSet - +from gyp import ( + MSVSNew, + MSVSProject, + MSVSSettings, + MSVSToolFile, + MSVSUserFile, + MSVSUtil, + MSVSVersion, + easy_xml, +) +from gyp.common import GypError, OrderedSet # Regular expression for validating Visual Studio GUIDs. If the GUID # contains lowercase hex letters, MSVS will be fine. However, @@ -137,15 +136,15 @@ def _GetDomainAndUserName(): def _NormalizedSource(source): """Normalize the path. - But not if that gets rid of a variable, as this may expand to something - larger than one directory. + But not if that gets rid of a variable, as this may expand to something + larger than one directory. - Arguments: - source: The path to be normalize.d + Arguments: + source: The path to be normalize.d - Returns: - The normalized path. - """ + Returns: + The normalized path. + """ normalized = os.path.normpath(source) if source.count("$") == normalized.count("$"): source = normalized @@ -155,16 +154,16 @@ def _NormalizedSource(source): def _FixPath(path, separator="\\"): """Convert paths to a form that will make sense in a vcproj file. - Arguments: - path: The path to convert, may contain / etc. - Returns: - The path with all slashes made into backslashes. - """ + Arguments: + path: The path to convert, may contain / etc. + Returns: + The path with all slashes made into backslashes. + """ if ( fixpath_prefix and path and not os.path.isabs(path) - and not path[0] == "$" + and path[0] != "$" and not _IsWindowsAbsPath(path) ): path = os.path.join(fixpath_prefix, path) @@ -180,12 +179,12 @@ def _FixPath(path, separator="\\"): def _IsWindowsAbsPath(path): """ - On Cygwin systems Python needs a little help determining if a path - is an absolute Windows path or not, so that - it does not treat those as relative, which results in bad paths like: - '..\\C:\\<some path>\\some_source_code_file.cc' - """ - return path.startswith("c:") or path.startswith("C:") + On Cygwin systems Python needs a little help determining if a path + is an absolute Windows path or not, so that + it does not treat those as relative, which results in bad paths like: + '..\\C:\\<some path>\\some_source_code_file.cc' + """ + return path.startswith(("c:", "C:")) def _FixPaths(paths, separator="\\"): @@ -198,22 +197,22 @@ def _ConvertSourcesToFilterHierarchy( ): """Converts a list split source file paths into a vcproj folder hierarchy. - Arguments: - sources: A list of source file paths split. - prefix: A list of source file path layers meant to apply to each of sources. - excluded: A set of excluded files. - msvs_version: A MSVSVersion object. - - Returns: - A hierarchy of filenames and MSVSProject.Filter objects that matches the - layout of the source tree. - For example: - _ConvertSourcesToFilterHierarchy([['a', 'bob1.c'], ['b', 'bob2.c']], - prefix=['joe']) - --> - [MSVSProject.Filter('a', contents=['joe\\a\\bob1.c']), - MSVSProject.Filter('b', contents=['joe\\b\\bob2.c'])] - """ + Arguments: + sources: A list of source file paths split. + prefix: A list of source file path layers meant to apply to each of sources. + excluded: A set of excluded files. + msvs_version: A MSVSVersion object. + + Returns: + A hierarchy of filenames and MSVSProject.Filter objects that matches the + layout of the source tree. + For example: + _ConvertSourcesToFilterHierarchy([['a', 'bob1.c'], ['b', 'bob2.c']], + prefix=['joe']) + --> + [MSVSProject.Filter('a', contents=['joe\\a\\bob1.c']), + MSVSProject.Filter('b', contents=['joe\\b\\bob2.c'])] + """ if not prefix: prefix = [] result = [] @@ -276,19 +275,19 @@ def _ToolAppend(tools, tool_name, setting, value, only_if_unset=False): def _ToolSetOrAppend(tools, tool_name, setting, value, only_if_unset=False): # TODO(bradnelson): ugly hack, fix this more generally!!! if "Directories" in setting or "Dependencies" in setting: - if type(value) == str: + if isinstance(value, str): value = value.replace("/", "\\") else: value = [i.replace("/", "\\") for i in value] if not tools.get(tool_name): - tools[tool_name] = dict() + tools[tool_name] = {} tool = tools[tool_name] - if "CompileAsWinRT" == setting: + if setting == "CompileAsWinRT": return if tool.get(setting): if only_if_unset: return - if type(tool[setting]) == list and type(value) == list: + if isinstance(tool[setting], list) and isinstance(value, list): tool[setting] += value else: raise TypeError( @@ -362,7 +361,6 @@ def _ConfigWindowsTargetPlatformVersion(config_data, version): def _BuildCommandLineForRuleRaw( spec, cmd, cygwin_shell, has_input_path, quote_cmd, do_setup_env ): - if [x for x in cmd if "$(InputDir)" in x]: input_dir_preamble = ( "set INPUTDIR=$(InputDir)\n" @@ -412,10 +410,7 @@ def _BuildCommandLineForRuleRaw( return input_dir_preamble + cmd else: # Convert cat --> type to mimic unix. - if cmd[0] == "cat": - command = ["type"] - else: - command = [cmd[0].replace("/", "\\")] + command = ["type"] if cmd[0] == "cat" else [cmd[0].replace("/", "\\")] # Add call before command to ensure that commands can be tied together one # after the other without aborting in Incredibuild, since IB makes a bat # file out of the raw command string, and some commands (like python) are @@ -423,18 +418,21 @@ def _BuildCommandLineForRuleRaw( command.insert(0, "call") # Fix the paths # TODO(quote): This is a really ugly heuristic, and will miss path fixing - # for arguments like "--arg=path" or "/opt:path". - # If the argument starts with a slash or dash, it's probably a command line - # switch + # for arguments like "--arg=path", arg=path, or "/opt:path". + # If the argument starts with a slash or dash, or contains an equal sign, + # it's probably a command line switch. # Return the path with forward slashes because the command using it might # not support backslashes. - arguments = [i if (i[:1] in "/-") else _FixPath(i, "/") for i in cmd[1:]] + arguments = [ + i if (i[:1] in "/-" or "=" in i) else _FixPath(i, "/") for i in cmd[1:] + ] arguments = [i.replace("$(InputDir)", "%INPUTDIR%") for i in arguments] arguments = [MSVSSettings.FixVCMacroSlashes(i) for i in arguments] if quote_cmd: # Support a mode for using cmd directly. # Convert any paths to native form (first element is used directly). # TODO(quote): regularize quoting path names throughout the module + command[1] = '"%s"' % command[1] arguments = ['"%s"' % i for i in arguments] # Collapse into a single command. return input_dir_preamble + " ".join(command + arguments) @@ -459,17 +457,17 @@ def _BuildCommandLineForRule(spec, rule, has_input_path, do_setup_env): def _AddActionStep(actions_dict, inputs, outputs, description, command): """Merge action into an existing list of actions. - Care must be taken so that actions which have overlapping inputs either don't - get assigned to the same input, or get collapsed into one. - - Arguments: - actions_dict: dictionary keyed on input name, which maps to a list of - dicts describing the actions attached to that input file. - inputs: list of inputs - outputs: list of outputs - description: description of the action - command: command line to execute - """ + Care must be taken so that actions which have overlapping inputs either don't + get assigned to the same input, or get collapsed into one. + + Arguments: + actions_dict: dictionary keyed on input name, which maps to a list of + dicts describing the actions attached to that input file. + inputs: list of inputs + outputs: list of outputs + description: description of the action + command: command line to execute + """ # Require there to be at least one input (call sites will ensure this). assert inputs @@ -496,15 +494,15 @@ def _AddCustomBuildToolForMSVS( ): """Add a custom build tool to execute something. - Arguments: - p: the target project - spec: the target project dict - primary_input: input file to attach the build tool to - inputs: list of inputs - outputs: list of outputs - description: description of the action - cmd: command line to execute - """ + Arguments: + p: the target project + spec: the target project dict + primary_input: input file to attach the build tool to + inputs: list of inputs + outputs: list of outputs + description: description of the action + cmd: command line to execute + """ inputs = _FixPaths(inputs) outputs = _FixPaths(outputs) tool = MSVSProject.Tool( @@ -526,12 +524,12 @@ def _AddCustomBuildToolForMSVS( def _AddAccumulatedActionsToMSVS(p, spec, actions_dict): """Add actions accumulated into an actions_dict, merging as needed. - Arguments: - p: the target project - spec: the target project dict - actions_dict: dictionary keyed on input name, which maps to a list of - dicts describing the actions attached to that input file. - """ + Arguments: + p: the target project + spec: the target project dict + actions_dict: dictionary keyed on input name, which maps to a list of + dicts describing the actions attached to that input file. + """ for primary_input in actions_dict: inputs = OrderedSet() outputs = OrderedSet() @@ -559,12 +557,12 @@ def _AddAccumulatedActionsToMSVS(p, spec, actions_dict): def _RuleExpandPath(path, input_file): """Given the input file to which a rule applied, string substitute a path. - Arguments: - path: a path to string expand - input_file: the file to which the rule applied. - Returns: - The string substituted path. - """ + Arguments: + path: a path to string expand + input_file: the file to which the rule applied. + Returns: + The string substituted path. + """ path = path.replace( "$(InputName)", os.path.splitext(os.path.split(input_file)[1])[0] ) @@ -580,24 +578,24 @@ def _RuleExpandPath(path, input_file): def _FindRuleTriggerFiles(rule, sources): """Find the list of files which a particular rule applies to. - Arguments: - rule: the rule in question - sources: the set of all known source files for this project - Returns: - The list of sources that trigger a particular rule. - """ + Arguments: + rule: the rule in question + sources: the set of all known source files for this project + Returns: + The list of sources that trigger a particular rule. + """ return rule.get("rule_sources", []) def _RuleInputsAndOutputs(rule, trigger_file): """Find the inputs and outputs generated by a rule. - Arguments: - rule: the rule in question. - trigger_file: the main trigger for this rule. - Returns: - The pair of (inputs, outputs) involved in this rule. - """ + Arguments: + rule: the rule in question. + trigger_file: the main trigger for this rule. + Returns: + The pair of (inputs, outputs) involved in this rule. + """ raw_inputs = _FixPaths(rule.get("inputs", [])) raw_outputs = _FixPaths(rule.get("outputs", [])) inputs = OrderedSet() @@ -613,13 +611,13 @@ def _RuleInputsAndOutputs(rule, trigger_file): def _GenerateNativeRulesForMSVS(p, rules, output_dir, spec, options): """Generate a native rules file. - Arguments: - p: the target project - rules: the set of rules to include - output_dir: the directory in which the project/gyp resides - spec: the project dict - options: global generator options - """ + Arguments: + p: the target project + rules: the set of rules to include + output_dir: the directory in which the project/gyp resides + spec: the project dict + options: global generator options + """ rules_filename = "{}{}.rules".format(spec["target_name"], options.suffix) rules_file = MSVSToolFile.Writer( os.path.join(output_dir, rules_filename), spec["target_name"] @@ -658,14 +656,14 @@ def _Cygwinify(path): def _GenerateExternalRules(rules, output_dir, spec, sources, options, actions_to_add): """Generate an external makefile to do a set of rules. - Arguments: - rules: the list of rules to include - output_dir: path containing project and gyp files - spec: project specification data - sources: set of sources known - options: global generator options - actions_to_add: The list of actions we will add to. - """ + Arguments: + rules: the list of rules to include + output_dir: path containing project and gyp files + spec: project specification data + sources: set of sources known + options: global generator options + actions_to_add: The list of actions we will add to. + """ filename = "{}_rules{}.mk".format(spec["target_name"], options.suffix) mk_file = gyp.common.WriteOnDiff(os.path.join(output_dir, filename)) # Find cygwin style versions of some paths. @@ -684,7 +682,7 @@ def _GenerateExternalRules(rules, output_dir, spec, sources, options, actions_to all_outputs.update(OrderedSet(outputs)) # Only use one target from each rule as the dependency for # 'all' so we don't try to build each rule multiple times. - first_outputs.append(list(outputs)[0]) + first_outputs.append(next(iter(outputs))) # Get the unique output directories for this rule. output_dirs = [os.path.split(i)[0] for i in outputs] for od in output_dirs: @@ -743,17 +741,17 @@ def _GenerateExternalRules(rules, output_dir, spec, sources, options, actions_to def _EscapeEnvironmentVariableExpansion(s): """Escapes % characters. - Escapes any % characters so that Windows-style environment variable - expansions will leave them alone. - See http://connect.microsoft.com/VisualStudio/feedback/details/106127/cl-d-name-text-containing-percentage-characters-doesnt-compile - to understand why we have to do this. + Escapes any % characters so that Windows-style environment variable + expansions will leave them alone. + See http://connect.microsoft.com/VisualStudio/feedback/details/106127/cl-d-name-text-containing-percentage-characters-doesnt-compile + to understand why we have to do this. - Args: - s: The string to be escaped. + Args: + s: The string to be escaped. - Returns: - The escaped string. - """ # noqa: E731,E123,E501 + Returns: + The escaped string. + """ s = s.replace("%", "%%") return s @@ -764,17 +762,17 @@ def _EscapeEnvironmentVariableExpansion(s): def _EscapeCommandLineArgumentForMSVS(s): """Escapes a Windows command-line argument. - So that the Win32 CommandLineToArgv function will turn the escaped result back - into the original string. - See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx - ("Parsing C++ Command-Line Arguments") to understand why we have to do - this. + So that the Win32 CommandLineToArgv function will turn the escaped result back + into the original string. + See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + ("Parsing C++ Command-Line Arguments") to understand why we have to do + this. - Args: - s: the string to be escaped. - Returns: - the escaped string. - """ + Args: + s: the string to be escaped. + Returns: + the escaped string. + """ def _Replace(match): # For a literal quote, CommandLineToArgv requires an odd number of @@ -795,24 +793,24 @@ def _Replace(match): def _EscapeVCProjCommandLineArgListItem(s): """Escapes command line arguments for MSVS. - The VCProj format stores string lists in a single string using commas and - semi-colons as separators, which must be quoted if they are to be - interpreted literally. However, command-line arguments may already have - quotes, and the VCProj parser is ignorant of the backslash escaping - convention used by CommandLineToArgv, so the command-line quotes and the - VCProj quotes may not be the same quotes. So to store a general - command-line argument in a VCProj list, we need to parse the existing - quoting according to VCProj's convention and quote any delimiters that are - not already quoted by that convention. The quotes that we add will also be - seen by CommandLineToArgv, so if backslashes precede them then we also have - to escape those backslashes according to the CommandLineToArgv - convention. - - Args: - s: the string to be escaped. - Returns: - the escaped string. - """ + The VCProj format stores string lists in a single string using commas and + semi-colons as separators, which must be quoted if they are to be + interpreted literally. However, command-line arguments may already have + quotes, and the VCProj parser is ignorant of the backslash escaping + convention used by CommandLineToArgv, so the command-line quotes and the + VCProj quotes may not be the same quotes. So to store a general + command-line argument in a VCProj list, we need to parse the existing + quoting according to VCProj's convention and quote any delimiters that are + not already quoted by that convention. The quotes that we add will also be + seen by CommandLineToArgv, so if backslashes precede them then we also have + to escape those backslashes according to the CommandLineToArgv + convention. + + Args: + s: the string to be escaped. + Returns: + the escaped string. + """ def _Replace(match): # For a non-literal quote, CommandLineToArgv requires an even number of @@ -896,15 +894,15 @@ def _GenerateRulesForMSVS( ): """Generate all the rules for a particular project. - Arguments: - p: the project - output_dir: directory to emit rules to - options: global options passed to the generator - spec: the specification for this project - sources: the set of all known source files in this project - excluded_sources: the set of sources excluded from normal processing - actions_to_add: deferred list of actions to add in - """ + Arguments: + p: the project + output_dir: directory to emit rules to + options: global options passed to the generator + spec: the specification for this project + sources: the set of all known source files in this project + excluded_sources: the set of sources excluded from normal processing + actions_to_add: deferred list of actions to add in + """ rules = spec.get("rules", []) rules_native = [r for r in rules if not int(r.get("msvs_external_rule", 0))] rules_external = [r for r in rules if int(r.get("msvs_external_rule", 0))] @@ -946,12 +944,12 @@ def _AdjustSourcesForRules(rules, sources, excluded_sources, is_msbuild): def _FilterActionsFromExcluded(excluded_sources, actions_to_add): """Take inputs with actions attached out of the list of exclusions. - Arguments: - excluded_sources: list of source files not to be built. - actions_to_add: dict of actions keyed on source file they're attached to. - Returns: - excluded_sources with files that have actions attached removed. - """ + Arguments: + excluded_sources: list of source files not to be built. + actions_to_add: dict of actions keyed on source file they're attached to. + Returns: + excluded_sources with files that have actions attached removed. + """ must_keep = OrderedSet(_FixPaths(actions_to_add.keys())) return [s for s in excluded_sources if s not in must_keep] @@ -963,14 +961,14 @@ def _GetDefaultConfiguration(spec): def _GetGuidOfProject(proj_path, spec): """Get the guid for the project. - Arguments: - proj_path: Path of the vcproj or vcxproj file to generate. - spec: The target dictionary containing the properties of the target. - Returns: - the guid. - Raises: - ValueError: if the specified GUID is invalid. - """ + Arguments: + proj_path: Path of the vcproj or vcxproj file to generate. + spec: The target dictionary containing the properties of the target. + Returns: + the guid. + Raises: + ValueError: if the specified GUID is invalid. + """ # Pluck out the default configuration. default_config = _GetDefaultConfiguration(spec) # Decide the guid of the project. @@ -989,13 +987,13 @@ def _GetGuidOfProject(proj_path, spec): def _GetMsbuildToolsetOfProject(proj_path, spec, version): """Get the platform toolset for the project. - Arguments: - proj_path: Path of the vcproj or vcxproj file to generate. - spec: The target dictionary containing the properties of the target. - version: The MSVSVersion object. - Returns: - the platform toolset string or None. - """ + Arguments: + proj_path: Path of the vcproj or vcxproj file to generate. + spec: The target dictionary containing the properties of the target. + version: The MSVSVersion object. + Returns: + the platform toolset string or None. + """ # Pluck out the default configuration. default_config = _GetDefaultConfiguration(spec) toolset = default_config.get("msbuild_toolset") @@ -1009,14 +1007,14 @@ def _GetMsbuildToolsetOfProject(proj_path, spec, version): def _GenerateProject(project, options, version, generator_flags, spec): """Generates a vcproj file. - Arguments: - project: the MSVSProject object. - options: global generator options. - version: the MSVSVersion object. - generator_flags: dict of generator-specific flags. - Returns: - A list of source files that cannot be found on disk. - """ + Arguments: + project: the MSVSProject object. + options: global generator options. + version: the MSVSVersion object. + generator_flags: dict of generator-specific flags. + Returns: + A list of source files that cannot be found on disk. + """ default_config = _GetDefaultConfiguration(project.spec) # Skip emitting anything if told to with msvs_existing_vcproj option. @@ -1032,12 +1030,12 @@ def _GenerateProject(project, options, version, generator_flags, spec): def _GenerateMSVSProject(project, options, version, generator_flags): """Generates a .vcproj file. It may create .rules and .user files too. - Arguments: - project: The project object we will generate the file for. - options: Global options passed to the generator. - version: The VisualStudioVersion object. - generator_flags: dict of generator-specific flags. - """ + Arguments: + project: The project object we will generate the file for. + options: Global options passed to the generator. + version: The VisualStudioVersion object. + generator_flags: dict of generator-specific flags. + """ spec = project.spec gyp.common.EnsureDirExists(project.path) @@ -1094,11 +1092,11 @@ def _GenerateMSVSProject(project, options, version, generator_flags): def _GetUniquePlatforms(spec): """Returns the list of unique platforms for this spec, e.g ['win32', ...]. - Arguments: - spec: The target dictionary containing the properties of the target. - Returns: - The MSVSUserFile object created. - """ + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + The MSVSUserFile object created. + """ # Gather list of unique platforms. platforms = OrderedSet() for configuration in spec["configurations"]: @@ -1110,14 +1108,14 @@ def _GetUniquePlatforms(spec): def _CreateMSVSUserFile(proj_path, version, spec): """Generates a .user file for the user running this Gyp program. - Arguments: - proj_path: The path of the project file being created. The .user file - shares the same path (with an appropriate suffix). - version: The VisualStudioVersion object. - spec: The target dictionary containing the properties of the target. - Returns: - The MSVSUserFile object created. - """ + Arguments: + proj_path: The path of the project file being created. The .user file + shares the same path (with an appropriate suffix). + version: The VisualStudioVersion object. + spec: The target dictionary containing the properties of the target. + Returns: + The MSVSUserFile object created. + """ (domain, username) = _GetDomainAndUserName() vcuser_filename = ".".join([proj_path, domain, username, "user"]) user_file = MSVSUserFile.Writer(vcuser_filename, version, spec["target_name"]) @@ -1127,14 +1125,14 @@ def _CreateMSVSUserFile(proj_path, version, spec): def _GetMSVSConfigurationType(spec, build_file): """Returns the configuration type for this project. - It's a number defined by Microsoft. May raise an exception. + It's a number defined by Microsoft. May raise an exception. - Args: - spec: The target dictionary containing the properties of the target. - build_file: The path of the gyp file. - Returns: - An integer, the configuration type. - """ + Args: + spec: The target dictionary containing the properties of the target. + build_file: The path of the gyp file. + Returns: + An integer, the configuration type. + """ try: config_type = { "executable": "1", # .exe @@ -1161,17 +1159,17 @@ def _GetMSVSConfigurationType(spec, build_file): def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config): """Adds a configuration to the MSVS project. - Many settings in a vcproj file are specific to a configuration. This - function the main part of the vcproj file that's configuration specific. - - Arguments: - p: The target project being generated. - spec: The target dictionary containing the properties of the target. - config_type: The configuration type, a number as defined by Microsoft. - config_name: The name of the configuration. - config: The dictionary that defines the special processing to be done - for this configuration. - """ + Many settings in a vcproj file are specific to a configuration. This + function the main part of the vcproj file that's configuration specific. + + Arguments: + p: The target project being generated. + spec: The target dictionary containing the properties of the target. + config_type: The configuration type, a number as defined by Microsoft. + config_name: The name of the configuration. + config: The dictionary that defines the special processing to be done + for this configuration. + """ # Get the information for this configuration include_dirs, midl_include_dirs, resource_include_dirs = _GetIncludeDirs(config) libraries = _GetLibraries(spec) @@ -1186,7 +1184,7 @@ def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config): precompiled_header = config.get("msvs_precompiled_header") # Prepare the list of tools as a dictionary. - tools = dict() + tools = {} # Add in user specified msvs_settings. msvs_settings = config.get("msvs_settings", {}) MSVSSettings.ValidateMSVSSettings(msvs_settings) @@ -1251,12 +1249,12 @@ def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config): def _GetIncludeDirs(config): """Returns the list of directories to be used for #include directives. - Arguments: - config: The dictionary that defines the special processing to be done - for this configuration. - Returns: - The list of directory paths. - """ + Arguments: + config: The dictionary that defines the special processing to be done + for this configuration. + Returns: + The list of directory paths. + """ # TODO(bradnelson): include_dirs should really be flexible enough not to # require this sort of thing. include_dirs = config.get("include_dirs", []) + config.get( @@ -1275,12 +1273,12 @@ def _GetIncludeDirs(config): def _GetLibraryDirs(config): """Returns the list of directories to be used for library search paths. - Arguments: - config: The dictionary that defines the special processing to be done - for this configuration. - Returns: - The list of directory paths. - """ + Arguments: + config: The dictionary that defines the special processing to be done + for this configuration. + Returns: + The list of directory paths. + """ library_dirs = config.get("library_dirs", []) library_dirs = _FixPaths(library_dirs) @@ -1290,11 +1288,11 @@ def _GetLibraryDirs(config): def _GetLibraries(spec): """Returns the list of libraries for this configuration. - Arguments: - spec: The target dictionary containing the properties of the target. - Returns: - The list of directory paths. - """ + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + The list of directory paths. + """ libraries = spec.get("libraries", []) # Strip out -l, as it is not used on windows (but is needed so we can pass # in libraries that are assumed to be in the default library path). @@ -1316,14 +1314,14 @@ def _GetLibraries(spec): def _GetOutputFilePathAndTool(spec, msbuild): """Returns the path and tool to use for this target. - Figures out the path of the file this spec will create and the name of - the VC tool that will create it. + Figures out the path of the file this spec will create and the name of + the VC tool that will create it. - Arguments: - spec: The target dictionary containing the properties of the target. - Returns: - A triple of (file path, name of the vc tool, name of the msbuild tool) - """ + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + A triple of (file path, name of the vc tool, name of the msbuild tool) + """ # Select a name for the output file. out_file = "" vc_tool = "" @@ -1355,17 +1353,16 @@ def _GetOutputFilePathAndTool(spec, msbuild): def _GetOutputTargetExt(spec): """Returns the extension for this target, including the dot - If product_extension is specified, set target_extension to this to avoid - MSB8012, returns None otherwise. Ignores any target_extension settings in - the input files. - - Arguments: - spec: The target dictionary containing the properties of the target. - Returns: - A string with the extension, or None - """ - target_extension = spec.get("product_extension") - if target_extension: + If product_extension is specified, set target_extension to this to avoid + MSB8012, returns None otherwise. Ignores any target_extension settings in + the input files. + + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + A string with the extension, or None + """ + if target_extension := spec.get("product_extension"): return "." + target_extension return None @@ -1373,18 +1370,15 @@ def _GetOutputTargetExt(spec): def _GetDefines(config): """Returns the list of preprocessor definitions for this configuration. - Arguments: - config: The dictionary that defines the special processing to be done - for this configuration. - Returns: - The list of preprocessor definitions. - """ + Arguments: + config: The dictionary that defines the special processing to be done + for this configuration. + Returns: + The list of preprocessor definitions. + """ defines = [] for d in config.get("defines", []): - if type(d) == list: - fd = "=".join([str(dpart) for dpart in d]) - else: - fd = str(d) + fd = "=".join([str(dpart) for dpart in d]) if isinstance(d, list) else str(d) defines.append(fd) return defines @@ -1415,17 +1409,17 @@ def _GetModuleDefinition(spec): def _ConvertToolsToExpectedForm(tools): """Convert tools to a form expected by Visual Studio. - Arguments: - tools: A dictionary of settings; the tool name is the key. - Returns: - A list of Tool objects. - """ + Arguments: + tools: A dictionary of settings; the tool name is the key. + Returns: + A list of Tool objects. + """ tool_list = [] for tool, settings in tools.items(): # Collapse settings with lists. settings_fixed = {} for setting, value in settings.items(): - if type(value) == list: + if isinstance(value, list): if ( tool == "VCLinkerTool" and setting == "AdditionalDependencies" ) or setting == "AdditionalOptions": @@ -1442,15 +1436,15 @@ def _ConvertToolsToExpectedForm(tools): def _AddConfigurationToMSVS(p, spec, tools, config, config_type, config_name): """Add to the project file the configuration specified by config. - Arguments: - p: The target project being generated. - spec: the target project dict. - tools: A dictionary of settings; the tool name is the key. - config: The dictionary that defines the special processing to be done - for this configuration. - config_type: The configuration type, a number as defined by Microsoft. - config_name: The name of the configuration. - """ + Arguments: + p: The target project being generated. + spec: the target project dict. + tools: A dictionary of settings; the tool name is the key. + config: The dictionary that defines the special processing to be done + for this configuration. + config_type: The configuration type, a number as defined by Microsoft. + config_name: The name of the configuration. + """ attributes = _GetMSVSAttributes(spec, config, config_type) # Add in this configuration. tool_list = _ConvertToolsToExpectedForm(tools) @@ -1491,18 +1485,18 @@ def _AddNormalizedSources(sources_set, sources_array): def _PrepareListOfSources(spec, generator_flags, gyp_file): """Prepare list of sources and excluded sources. - Besides the sources specified directly in the spec, adds the gyp file so - that a change to it will cause a re-compile. Also adds appropriate sources - for actions and copies. Assumes later stage will un-exclude files which - have custom build steps attached. - - Arguments: - spec: The target dictionary containing the properties of the target. - gyp_file: The name of the gyp file. - Returns: - A pair of (list of sources, list of excluded sources). - The sources will be relative to the gyp file. - """ + Besides the sources specified directly in the spec, adds the gyp file so + that a change to it will cause a re-compile. Also adds appropriate sources + for actions and copies. Assumes later stage will un-exclude files which + have custom build steps attached. + + Arguments: + spec: The target dictionary containing the properties of the target. + gyp_file: The name of the gyp file. + Returns: + A pair of (list of sources, list of excluded sources). + The sources will be relative to the gyp file. + """ sources = OrderedSet() _AddNormalizedSources(sources, spec.get("sources", [])) excluded_sources = OrderedSet() @@ -1532,19 +1526,19 @@ def _AdjustSourcesAndConvertToFilterHierarchy( ): """Adjusts the list of sources and excluded sources. - Also converts the sets to lists. - - Arguments: - spec: The target dictionary containing the properties of the target. - options: Global generator options. - gyp_dir: The path to the gyp file being processed. - sources: A set of sources to be included for this project. - excluded_sources: A set of sources to be excluded for this project. - version: A MSVSVersion object. - Returns: - A trio of (list of sources, list of excluded sources, - path of excluded IDL file) - """ + Also converts the sets to lists. + + Arguments: + spec: The target dictionary containing the properties of the target. + options: Global generator options. + gyp_dir: The path to the gyp file being processed. + sources: A set of sources to be included for this project. + excluded_sources: A set of sources to be excluded for this project. + version: A MSVSVersion object. + Returns: + A trio of (list of sources, list of excluded sources, + path of excluded IDL file) + """ # Exclude excluded sources coming into the generator. excluded_sources.update(OrderedSet(spec.get("sources_excluded", []))) # Add excluded sources into sources for good measure. @@ -1575,10 +1569,10 @@ def _AdjustSourcesAndConvertToFilterHierarchy( # such as ../../src/modules/module1 etc. if version.UsesVcxproj(): while ( - all([isinstance(s, MSVSProject.Filter) for s in sources]) + all(isinstance(s, MSVSProject.Filter) for s in sources) and len({s.name for s in sources}) == 1 ): - assert all([len(s.contents) == 1 for s in sources]) + assert all(len(s.contents) == 1 for s in sources) sources = [s.contents[0] for s in sources] else: while len(sources) == 1 and isinstance(sources[0], MSVSProject.Filter): @@ -1595,10 +1589,7 @@ def _IdlFilesHandledNonNatively(spec, sources): if rule["extension"] == "idl" and int(rule.get("msvs_external_rule", 0)): using_idl = True break - if using_idl: - excluded_idl = [i for i in sources if i.endswith(".idl")] - else: - excluded_idl = [] + excluded_idl = [i for i in sources if i.endswith(".idl")] if using_idl else [] return excluded_idl @@ -1675,7 +1666,7 @@ def _HandlePreCompiledHeaders(p, sources, spec): p.AddFileConfig( source, _ConfigFullName(config_name, config), {}, tools=[tool] ) - basename, extension = os.path.splitext(source) + _basename, extension = os.path.splitext(source) if extension == ".c": extensions_excluded_from_precompile = [".cc", ".cpp", ".cxx"] else: @@ -1686,7 +1677,7 @@ def DisableForSourceTree(source_tree): if isinstance(source, MSVSProject.Filter): DisableForSourceTree(source.contents) else: - basename, extension = os.path.splitext(source) + _basename, extension = os.path.splitext(source) if extension in extensions_excluded_from_precompile: for config_name, config in spec["configurations"].items(): tool = MSVSProject.Tool( @@ -1783,11 +1774,9 @@ def _GetCopies(spec): outer_dir = posixpath.split(src_bare)[1] fixed_dst = _FixPath(dst) full_dst = f'"{fixed_dst}\\{outer_dir}\\"' - cmd = 'mkdir {} 2>nul & cd "{}" && xcopy /e /f /y "{}" {}'.format( - full_dst, - _FixPath(base_dir), - outer_dir, - full_dst, + cmd = ( + f'mkdir {full_dst} 2>nul & cd "{_FixPath(base_dir)}" ' + f'&& xcopy /e /f /y "{outer_dir}" {full_dst}' ) copies.append( ( @@ -1799,10 +1788,9 @@ def _GetCopies(spec): ) else: fix_dst = _FixPath(cpy["destination"]) - cmd = 'mkdir "{}" 2>nul & set ERRORLEVEL=0 & copy /Y "{}" "{}"'.format( - fix_dst, - _FixPath(src), - _FixPath(dst), + cmd = ( + f'mkdir "{fix_dst}" 2>nul & set ERRORLEVEL=0 & ' + f'copy /Y "{_FixPath(src)}" "{_FixPath(dst)}"' ) copies.append(([src], [dst], cmd, f"Copying {src} to {fix_dst}")) return copies @@ -1816,7 +1804,7 @@ def _GetPathDict(root, path): parent, folder = os.path.split(path) parent_dict = _GetPathDict(root, parent) if folder not in parent_dict: - parent_dict[folder] = dict() + parent_dict[folder] = {} return parent_dict[folder] @@ -1824,7 +1812,7 @@ def _DictsToFolders(base_path, bucket, flat): # Convert to folders recursively. children = [] for folder, contents in bucket.items(): - if type(contents) == dict: + if isinstance(contents, dict): folder_children = _DictsToFolders( os.path.join(base_path, folder), contents, flat ) @@ -1846,9 +1834,13 @@ def _CollapseSingles(parent, node): # Recursively explorer the tree of dicts looking for projects which are # the sole item in a folder which has the same name as the project. Bring # such projects up one level. - if type(node) == dict and len(node) == 1 and next(iter(node)) == parent + ".vcproj": + if ( + isinstance(node, dict) + and len(node) == 1 + and next(iter(node)) == parent + ".vcproj" + ): return node[next(iter(node))] - if type(node) != dict: + if not isinstance(node, dict): return node for child in node: node[child] = _CollapseSingles(child, node[child]) @@ -1868,7 +1860,7 @@ def _GatherSolutionFolders(sln_projects, project_objects, flat): # Walk down from the top until we hit a folder that has more than one entry. # In practice, this strips the top-level "src/" dir from the hierarchy in # the solution. - while len(root) == 1 and type(root[next(iter(root))]) == dict: + while len(root) == 1 and isinstance(root[next(iter(root))], dict): root = root[next(iter(root))] # Collapse singles. root = _CollapseSingles("", root) @@ -1904,10 +1896,8 @@ def _GetPlatformOverridesOfProject(spec): for config_name, c in spec["configurations"].items(): config_fullname = _ConfigFullName(config_name, c) platform = c.get("msvs_target_platform", _ConfigPlatform(c)) - fixed_config_fullname = "{}|{}".format( - _ConfigBaseName(config_name, _ConfigPlatform(c)), - platform, - ) + base_name = _ConfigBaseName(config_name, _ConfigPlatform(c)) + fixed_config_fullname = f"{base_name}|{platform}" if spec["toolset"] == "host" and generator_supports_multiple_toolsets: fixed_config_fullname = f"{config_name}|x64" config_platform_overrides[config_fullname] = fixed_config_fullname @@ -1917,14 +1907,14 @@ def _GetPlatformOverridesOfProject(spec): def _CreateProjectObjects(target_list, target_dicts, options, msvs_version): """Create a MSVSProject object for the targets found in target list. - Arguments: - target_list: the list of targets to generate project objects for. - target_dicts: the dictionary of specifications. - options: global generator options. - msvs_version: the MSVSVersion object. - Returns: - A set of created projects, keyed by target. - """ + Arguments: + target_list: the list of targets to generate project objects for. + target_dicts: the dictionary of specifications. + options: global generator options. + msvs_version: the MSVSVersion object. + Returns: + A set of created projects, keyed by target. + """ global fixpath_prefix # Generate each project. projects = {} @@ -1968,15 +1958,15 @@ def _CreateProjectObjects(target_list, target_dicts, options, msvs_version): def _InitNinjaFlavor(params, target_list, target_dicts): """Initialize targets for the ninja flavor. - This sets up the necessary variables in the targets to generate msvs projects - that use ninja as an external builder. The variables in the spec are only set - if they have not been set. This allows individual specs to override the - default values initialized here. - Arguments: - params: Params provided to the generator. - target_list: List of target pairs: 'base/base.gyp:base'. - target_dicts: Dict of target properties keyed on target pair. - """ + This sets up the necessary variables in the targets to generate msvs projects + that use ninja as an external builder. The variables in the spec are only set + if they have not been set. This allows individual specs to override the + default values initialized here. + Arguments: + params: Params provided to the generator. + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + """ for qualified_target in target_list: spec = target_dicts[qualified_target] if spec.get("msvs_external_builder"): @@ -2087,12 +2077,12 @@ def CalculateGeneratorInputInfo(params): def GenerateOutput(target_list, target_dicts, data, params): """Generate .sln and .vcproj files. - This is the entry point for this generator. - Arguments: - target_list: List of target pairs: 'base/base.gyp:base'. - target_dicts: Dict of target properties keyed on target pair. - data: Dictionary containing per .gyp data. - """ + This is the entry point for this generator. + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + data: Dictionary containing per .gyp data. + """ global fixpath_prefix options = params["options"] @@ -2186,14 +2176,14 @@ def _GenerateMSBuildFiltersFile( ): """Generate the filters file. - This file is used by Visual Studio to organize the presentation of source - files into folders. + This file is used by Visual Studio to organize the presentation of source + files into folders. - Arguments: - filters_path: The path of the file to be created. - source_files: The hierarchical structure of all the sources. - extension_to_rule_name: A dictionary mapping file extensions to rules. - """ + Arguments: + filters_path: The path of the file to be created. + source_files: The hierarchical structure of all the sources. + extension_to_rule_name: A dictionary mapping file extensions to rules. + """ filter_group = [] source_group = [] _AppendFiltersForMSBuild( @@ -2234,14 +2224,14 @@ def _AppendFiltersForMSBuild( ): """Creates the list of filters and sources to be added in the filter file. - Args: - parent_filter_name: The name of the filter under which the sources are - found. - sources: The hierarchy of filters and sources to process. - extension_to_rule_name: A dictionary mapping file extensions to rules. - filter_group: The list to which filter entries will be appended. - source_group: The list to which source entries will be appended. - """ + Args: + parent_filter_name: The name of the filter under which the sources are + found. + sources: The hierarchy of filters and sources to process. + extension_to_rule_name: A dictionary mapping file extensions to rules. + filter_group: The list to which filter entries will be appended. + source_group: The list to which source entries will be appended. + """ for source in sources: if isinstance(source, MSVSProject.Filter): # We have a sub-filter. Create the name of that sub-filter. @@ -2285,13 +2275,13 @@ def _MapFileToMsBuildSourceType( ): """Returns the group and element type of the source file. - Arguments: - source: The source file name. - extension_to_rule_name: A dictionary mapping file extensions to rules. + Arguments: + source: The source file name. + extension_to_rule_name: A dictionary mapping file extensions to rules. - Returns: - A pair of (group this file should be part of, the label of element) - """ + Returns: + A pair of (group this file should be part of, the label of element) + """ _, ext = os.path.splitext(source) ext = ext.lower() if ext in extension_to_rule_name: @@ -2379,22 +2369,22 @@ def _GenerateRulesForMSBuild( class MSBuildRule: """Used to store information used to generate an MSBuild rule. - Attributes: - rule_name: The rule name, sanitized to use in XML. - target_name: The name of the target. - after_targets: The name of the AfterTargets element. - before_targets: The name of the BeforeTargets element. - depends_on: The name of the DependsOn element. - compute_output: The name of the ComputeOutput element. - dirs_to_make: The name of the DirsToMake element. - inputs: The name of the _inputs element. - tlog: The name of the _tlog element. - extension: The extension this rule applies to. - description: The message displayed when this rule is invoked. - additional_dependencies: A string listing additional dependencies. - outputs: The outputs of this rule. - command: The command used to run the rule. - """ + Attributes: + rule_name: The rule name, sanitized to use in XML. + target_name: The name of the target. + after_targets: The name of the AfterTargets element. + before_targets: The name of the BeforeTargets element. + depends_on: The name of the DependsOn element. + compute_output: The name of the ComputeOutput element. + dirs_to_make: The name of the DirsToMake element. + inputs: The name of the _inputs element. + tlog: The name of the _tlog element. + extension: The extension this rule applies to. + description: The message displayed when this rule is invoked. + additional_dependencies: A string listing additional dependencies. + outputs: The outputs of this rule. + command: The command used to run the rule. + """ def __init__(self, rule, spec): self.display_name = rule["rule_name"] @@ -2516,7 +2506,7 @@ def _GenerateMSBuildRuleTargetsFile(targets_path, msbuild_rules): rule_name = rule.rule_name target_outputs = "%%(%s.Outputs)" % rule_name target_inputs = ( - "%%(%s.Identity);%%(%s.AdditionalDependencies);" "$(MSBuildProjectFile)" + "%%(%s.Identity);%%(%s.AdditionalDependencies);$(MSBuildProjectFile)" ) % (rule_name, rule_name) rule_inputs = "%%(%s.Identity)" % rule_name extension_condition = ( @@ -2919,7 +2909,7 @@ def _GetConfigurationCondition(name, settings, spec): def _GetMSBuildProjectConfigurations(configurations, spec): group = ["ItemGroup", {"Label": "ProjectConfigurations"}] - for (name, settings) in sorted(configurations.items()): + for name, settings in sorted(configurations.items()): configuration, platform = _GetConfigurationAndPlatform(name, settings, spec) designation = f"{configuration}|{platform}" group.append( @@ -3010,18 +3000,27 @@ def _GetMSBuildConfigurationDetails(spec, build_file): msbuild_attributes = _GetMSBuildAttributes(spec, settings, build_file) condition = _GetConfigurationCondition(name, settings, spec) character_set = msbuild_attributes.get("CharacterSet") + vctools_version = msbuild_attributes.get("VCToolsVersion") config_type = msbuild_attributes.get("ConfigurationType") _AddConditionalProperty(properties, condition, "ConfigurationType", config_type) + spectre_mitigation = msbuild_attributes.get("SpectreMitigation") + if spectre_mitigation: + _AddConditionalProperty( + properties, condition, "SpectreMitigation", spectre_mitigation + ) if config_type == "Driver": _AddConditionalProperty(properties, condition, "DriverType", "WDM") _AddConditionalProperty( properties, condition, "TargetVersion", _ConfigTargetVersion(settings) ) - if character_set: - if "msvs_enable_winrt" not in spec: - _AddConditionalProperty( - properties, condition, "CharacterSet", character_set - ) + if character_set and "msvs_enable_winrt" not in spec: + _AddConditionalProperty( + properties, condition, "CharacterSet", character_set + ) + if vctools_version and "msvs_enable_winrt" not in spec: + _AddConditionalProperty( + properties, condition, "VCToolsVersion", vctools_version + ) return _GetMSBuildPropertyGroup(spec, "Configuration", properties) @@ -3101,6 +3100,8 @@ def _ConvertMSVSBuildAttributes(spec, config, build_file): msbuild_attributes[a] = _ConvertMSVSCharacterSet(msvs_attributes[a]) elif a == "ConfigurationType": msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a]) + elif a == "SpectreMitigation" or a == "VCToolsVersion": + msbuild_attributes[a] = msvs_attributes[a] else: print("Warning: Do not know how to convert MSVS attribute " + a) return msbuild_attributes @@ -3166,8 +3167,7 @@ def _GetMSBuildAttributes(spec, config, build_file): "windows_driver": "Link", "static_library": "Lib", } - msbuild_tool = msbuild_tool_map.get(spec["type"]) - if msbuild_tool: + if msbuild_tool := msbuild_tool_map.get(spec["type"]): msbuild_settings = config["finalized_msbuild_settings"] out_file = msbuild_settings[msbuild_tool].get("OutputFile") if out_file: @@ -3184,8 +3184,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): # there are actions. # TODO(jeanluc) Handle the equivalent of setting 'CYGWIN=nontsec'. new_paths = [] - cygwin_dirs = spec.get("msvs_cygwin_dirs", ["."])[0] - if cygwin_dirs: + if cygwin_dirs := spec.get("msvs_cygwin_dirs", ["."])[0]: cyg_path = "$(MSBuildProjectDirectory)\\%s\\bin\\" % _FixPath(cygwin_dirs) new_paths.append(cyg_path) # TODO(jeanluc) Change the convention to have both a cygwin_dir and a @@ -3196,7 +3195,7 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): new_paths = "$(ExecutablePath);" + ";".join(new_paths) properties = {} - for (name, configuration) in sorted(configurations.items()): + for name, configuration in sorted(configurations.items()): condition = _GetConfigurationCondition(name, configuration, spec) attributes = _GetMSBuildAttributes(spec, configuration, build_file) msbuild_settings = configuration["finalized_msbuild_settings"] @@ -3235,14 +3234,14 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): def _AddConditionalProperty(properties, condition, name, value): """Adds a property / conditional value pair to a dictionary. - Arguments: - properties: The dictionary to be modified. The key is the name of the - property. The value is itself a dictionary; its key is the value and - the value a list of condition for which this value is true. - condition: The condition under which the named property has the value. - name: The name of the property. - value: The value of the property. - """ + Arguments: + properties: The dictionary to be modified. The key is the name of the + property. The value is itself a dictionary; its key is the value and + the value a list of condition for which this value is true. + condition: The condition under which the named property has the value. + name: The name of the property. + value: The value of the property. + """ if name not in properties: properties[name] = {} values = properties[name] @@ -3259,20 +3258,20 @@ def _AddConditionalProperty(properties, condition, name, value): def _GetMSBuildPropertyGroup(spec, label, properties): """Returns a PropertyGroup definition for the specified properties. - Arguments: - spec: The target project dict. - label: An optional label for the PropertyGroup. - properties: The dictionary to be converted. The key is the name of the - property. The value is itself a dictionary; its key is the value and - the value a list of condition for which this value is true. - """ + Arguments: + spec: The target project dict. + label: An optional label for the PropertyGroup. + properties: The dictionary to be converted. The key is the name of the + property. The value is itself a dictionary; its key is the value and + the value a list of condition for which this value is true. + """ group = ["PropertyGroup"] if label: group.append({"Label": label}) num_configurations = len(spec["configurations"]) def GetEdges(node): - # Use a definition of edges such that user_of_variable -> used_varible. + # Use a definition of edges such that user_of_variable -> used_variable. # This happens to be easier in this case, since a variable's # definition contains all variables it references in a single string. edges = set() @@ -3314,7 +3313,7 @@ def GetEdges(node): def _GetMSBuildToolSettingsSections(spec, configurations): groups = [] - for (name, configuration) in sorted(configurations.items()): + for name, configuration in sorted(configurations.items()): msbuild_settings = configuration["finalized_msbuild_settings"] group = [ "ItemDefinitionGroup", @@ -3323,15 +3322,14 @@ def _GetMSBuildToolSettingsSections(spec, configurations): for tool_name, tool_settings in sorted(msbuild_settings.items()): # Skip the tool named '' which is a holder of global settings handled # by _GetMSBuildConfigurationGlobalProperties. - if tool_name: - if tool_settings: - tool = [tool_name] - for name, value in sorted(tool_settings.items()): - formatted_value = _GetValueFormattedForMSBuild( - tool_name, name, value - ) - tool.append([name, formatted_value]) - group.append(tool) + if tool_name and tool_settings: + tool = [tool_name] + for name, value in sorted(tool_settings.items()): + formatted_value = _GetValueFormattedForMSBuild( + tool_name, name, value + ) + tool.append([name, formatted_value]) + group.append(tool) groups.append(group) return groups @@ -3371,7 +3369,6 @@ def _FinalizeMSBuildSettings(spec, configuration): prebuild = configuration.get("msvs_prebuild") postbuild = configuration.get("msvs_postbuild") def_file = _GetModuleDefinition(spec) - precompiled_header = configuration.get("msvs_precompiled_header") # Add the information to the appropriate tool # TODO(jeanluc) We could optimize and generate these settings only if @@ -3409,8 +3406,12 @@ def _FinalizeMSBuildSettings(spec, configuration): msbuild_settings, "ClCompile", "DisableSpecificWarnings", disabled_warnings ) # Turn on precompiled headers if appropriate. - if precompiled_header: - precompiled_header = os.path.split(precompiled_header)[1] + if precompiled_header := configuration.get("msvs_precompiled_header"): + # While MSVC works with just file name eg. "v8_pch.h", ClangCL requires + # the full path eg. "tools/msvs/pch/v8_pch.h" to find the file. + # P.S. Only ClangCL defines msbuild_toolset, for MSVC it is None. + if configuration.get("msbuild_toolset") != "ClangCL": + precompiled_header = os.path.split(precompiled_header)[1] _ToolAppend(msbuild_settings, "ClCompile", "PrecompiledHeader", "Use") _ToolAppend( msbuild_settings, "ClCompile", "PrecompiledHeaderFile", precompiled_header @@ -3440,7 +3441,7 @@ def _FinalizeMSBuildSettings(spec, configuration): def _GetValueFormattedForMSBuild(tool_name, name, value): - if type(value) == list: + if isinstance(value, list): # For some settings, VS2010 does not automatically extends the settings # TODO(jeanluc) Is this what we want? if name in [ @@ -3459,10 +3460,7 @@ def _GetValueFormattedForMSBuild(tool_name, name, value): "Link": ["AdditionalOptions"], "Lib": ["AdditionalOptions"], } - if tool_name in exceptions and name in exceptions[tool_name]: - char = " " - else: - char = ";" + char = " " if name in exceptions.get(tool_name, []) else ";" formatted_value = char.join( [MSVSSettings.ConvertVCMacrosToMSBuild(i) for i in value] ) @@ -3474,25 +3472,24 @@ def _GetValueFormattedForMSBuild(tool_name, name, value): def _VerifySourcesExist(sources, root_dir): """Verifies that all source files exist on disk. - Checks that all regular source files, i.e. not created at run time, - exist on disk. Missing files cause needless recompilation but no otherwise - visible errors. + Checks that all regular source files, i.e. not created at run time, + exist on disk. Missing files cause needless recompilation but no otherwise + visible errors. - Arguments: - sources: A recursive list of Filter/file names. - root_dir: The root directory for the relative path names. - Returns: - A list of source files that cannot be found on disk. - """ + Arguments: + sources: A recursive list of Filter/file names. + root_dir: The root directory for the relative path names. + Returns: + A list of source files that cannot be found on disk. + """ missing_sources = [] for source in sources: if isinstance(source, MSVSProject.Filter): missing_sources.extend(_VerifySourcesExist(source.contents, root_dir)) - else: - if "$" not in source: - full_path = os.path.join(root_dir, source) - if not os.path.exists(full_path): - missing_sources.append(full_path) + elif "$" not in source: + full_path = os.path.join(root_dir, source) + if not os.path.exists(full_path): + missing_sources.append(full_path) return missing_sources @@ -3562,75 +3559,70 @@ def _AddSources2( sources_handled_by_action, list_excluded, ) - else: - if source not in sources_handled_by_action: - detail = [] - excluded_configurations = exclusions.get(source, []) - if len(excluded_configurations) == len(spec["configurations"]): - detail.append(["ExcludedFromBuild", "true"]) - else: - for config_name, configuration in sorted(excluded_configurations): - condition = _GetConfigurationCondition( - config_name, configuration - ) - detail.append( - ["ExcludedFromBuild", {"Condition": condition}, "true"] - ) - # Add precompile if needed - for config_name, configuration in spec["configurations"].items(): - precompiled_source = configuration.get( - "msvs_precompiled_source", "" + elif source not in sources_handled_by_action: + detail = [] + excluded_configurations = exclusions.get(source, []) + if len(excluded_configurations) == len(spec["configurations"]): + detail.append(["ExcludedFromBuild", "true"]) + else: + for config_name, configuration in sorted(excluded_configurations): + condition = _GetConfigurationCondition(config_name, configuration) + detail.append( + ["ExcludedFromBuild", {"Condition": condition}, "true"] ) - if precompiled_source != "": - precompiled_source = _FixPath(precompiled_source) - if not extensions_excluded_from_precompile: - # If the precompiled header is generated by a C source, - # we must not try to use it for C++ sources, - # and vice versa. - basename, extension = os.path.splitext(precompiled_source) - if extension == ".c": - extensions_excluded_from_precompile = [ - ".cc", - ".cpp", - ".cxx", - ] - else: - extensions_excluded_from_precompile = [".c"] - - if precompiled_source == source: - condition = _GetConfigurationCondition( - config_name, configuration, spec - ) - detail.append( - ["PrecompiledHeader", {"Condition": condition}, "Create"] - ) - else: - # Turn off precompiled header usage for source files of a - # different type than the file that generated the - # precompiled header. - for extension in extensions_excluded_from_precompile: - if source.endswith(extension): - detail.append(["PrecompiledHeader", ""]) - detail.append(["ForcedIncludeFiles", ""]) - - group, element = _MapFileToMsBuildSourceType( - source, - rule_dependencies, - extension_to_rule_name, - _GetUniquePlatforms(spec), - spec["toolset"], - ) - if group == "compile" and not os.path.isabs(source): - # Add an <ObjectFileName> value to support duplicate source - # file basenames, except for absolute paths to avoid paths - # with more than 260 characters. - file_name = os.path.splitext(source)[0] + ".obj" - if file_name.startswith("..\\"): - file_name = re.sub(r"^(\.\.\\)+", "", file_name) - elif file_name.startswith("$("): - file_name = re.sub(r"^\$\([^)]+\)\\", "", file_name) - detail.append(["ObjectFileName", "$(IntDir)\\" + file_name]) - grouped_sources[group].append([element, {"Include": source}] + detail) + # Add precompile if needed + for config_name, configuration in spec["configurations"].items(): + precompiled_source = configuration.get("msvs_precompiled_source", "") + if precompiled_source != "": + precompiled_source = _FixPath(precompiled_source) + if not extensions_excluded_from_precompile: + # If the precompiled header is generated by a C source, + # we must not try to use it for C++ sources, + # and vice versa. + _basename, extension = os.path.splitext(precompiled_source) + if extension == ".c": + extensions_excluded_from_precompile = [ + ".cc", + ".cpp", + ".cxx", + ] + else: + extensions_excluded_from_precompile = [".c"] + + if precompiled_source == source: + condition = _GetConfigurationCondition( + config_name, configuration, spec + ) + detail.append( + ["PrecompiledHeader", {"Condition": condition}, "Create"] + ) + else: + # Turn off precompiled header usage for source files of a + # different type than the file that generated the + # precompiled header. + for extension in extensions_excluded_from_precompile: + if source.endswith(extension): + detail.append(["PrecompiledHeader", ""]) + detail.append(["ForcedIncludeFiles", ""]) + + group, element = _MapFileToMsBuildSourceType( + source, + rule_dependencies, + extension_to_rule_name, + _GetUniquePlatforms(spec), + spec["toolset"], + ) + if group == "compile" and not os.path.isabs(source): + # Add an <ObjectFileName> value to support duplicate source + # file basenames, except for absolute paths to avoid paths + # with more than 260 characters. + file_name = os.path.splitext(source)[0] + ".obj" + if file_name.startswith("..\\"): + file_name = re.sub(r"^(\.\.\\)+", "", file_name) + elif file_name.startswith("$("): + file_name = re.sub(r"^\$\([^)]+\)\\", "", file_name) + detail.append(["ObjectFileName", "$(IntDir)\\" + file_name]) + grouped_sources[group].append([element, {"Include": source}] + detail) def _GetMSBuildProjectReferences(project): @@ -3828,15 +3820,15 @@ def _GenerateMSBuildProject(project, options, version, generator_flags, spec): def _GetMSBuildExternalBuilderTargets(spec): """Return a list of MSBuild targets for external builders. - The "Build" and "Clean" targets are always generated. If the spec contains - 'msvs_external_builder_clcompile_cmd', then the "ClCompile" target will also - be generated, to support building selected C/C++ files. + The "Build" and "Clean" targets are always generated. If the spec contains + 'msvs_external_builder_clcompile_cmd', then the "ClCompile" target will also + be generated, to support building selected C/C++ files. - Arguments: - spec: The gyp target spec. - Returns: - List of MSBuild 'Target' specs. - """ + Arguments: + spec: The gyp target spec. + Returns: + List of MSBuild 'Target' specs. + """ build_cmd = _BuildCommandLineForRuleRaw( spec, spec["msvs_external_builder_build_cmd"], False, False, False, False ) @@ -3884,14 +3876,14 @@ def _GetMSBuildExtensionTargets(targets_files_of_rules): def _GenerateActionsForMSBuild(spec, actions_to_add): """Add actions accumulated into an actions_to_add, merging as needed. - Arguments: - spec: the target project dict - actions_to_add: dictionary keyed on input name, which maps to a list of - dicts describing the actions attached to that input file. + Arguments: + spec: the target project dict + actions_to_add: dictionary keyed on input name, which maps to a list of + dicts describing the actions attached to that input file. - Returns: - A pair of (action specification, the sources handled by this action). - """ + Returns: + A pair of (action specification, the sources handled by this action). + """ sources_handled_by_action = OrderedSet() actions_spec = [] for primary_input, actions in actions_to_add.items(): diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py index e80b57f06a130..e3c4758696c40 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py @@ -3,13 +3,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" Unit tests for the msvs.py file. """ +"""Unit tests for the msvs.py file.""" -import gyp.generator.msvs as msvs import unittest - from io import StringIO +from gyp.generator import msvs + class TestSequenceFunctions(unittest.TestCase): def setUp(self): diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py index d173bf2299011..4eac6cdb2707d 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py @@ -5,24 +5,24 @@ import collections import copy +import ctypes import hashlib import json import multiprocessing import os.path import re +import shutil import signal import subprocess import sys +from io import StringIO + import gyp import gyp.common import gyp.msvs_emulation -import gyp.MSVSUtil as MSVSUtil import gyp.xcode_emulation - -from io import StringIO - +from gyp import MSVSUtil, ninja_syntax from gyp.common import GetEnvironFallback -import gyp.ninja_syntax as ninja_syntax generator_default_variables = { "EXECUTABLE_PREFIX": "", @@ -264,8 +264,7 @@ def ExpandSpecial(self, path, product_dir=None): dir. """ - PRODUCT_DIR = "$!PRODUCT_DIR" - if PRODUCT_DIR in path: + if (PRODUCT_DIR := "$!PRODUCT_DIR") in path: if product_dir: path = path.replace(PRODUCT_DIR, product_dir) else: @@ -273,8 +272,7 @@ def ExpandSpecial(self, path, product_dir=None): path = path.replace(PRODUCT_DIR + "\\", "") path = path.replace(PRODUCT_DIR, ".") - INTERMEDIATE_DIR = "$!INTERMEDIATE_DIR" - if INTERMEDIATE_DIR in path: + if (INTERMEDIATE_DIR := "$!INTERMEDIATE_DIR") in path: int_dir = self.GypPathToUniqueOutput("gen") # GypPathToUniqueOutput generates a path relative to the product dir, # so insert product_dir in front if it is provided. @@ -811,9 +809,8 @@ def cygwin_munge(path): outputs = [self.GypPathToNinja(o, env) for o in outputs] if self.flavor == "win": # WriteNewNinjaRule uses unique_name to create a rsp file on win. - extra_bindings.append( - ("unique_name", hashlib.md5(outputs[0]).hexdigest()) - ) + unique_name = hashlib.sha256(outputs[0].encode("utf-8")).hexdigest() + extra_bindings.append(("unique_name", unique_name)) self.ninja.build( outputs, @@ -1305,7 +1302,7 @@ def WritePchTargets(self, ninja_file, pch_commands): ninja_file.build(gch, cmd, input, variables=[(var_name, lang_flag)]) def WriteLink(self, spec, config_name, config, link_deps, compile_deps): - """Write out a link step. Fills out target.binary. """ + """Write out a link step. Fills out target.binary.""" if self.flavor != "mac" or len(self.archs) == 1: return self.WriteLinkForArch( self.ninja, spec, config_name, config, link_deps, compile_deps @@ -1349,7 +1346,7 @@ def WriteLink(self, spec, config_name, config, link_deps, compile_deps): def WriteLinkForArch( self, ninja_file, spec, config_name, config, link_deps, compile_deps, arch=None ): - """Write out a link step. Fills out target.binary. """ + """Write out a link step. Fills out target.binary.""" command = { "executable": "link", "loadable_module": "solink_module", @@ -1464,7 +1461,7 @@ def WriteLinkForArch( # Respect environment variables related to build, but target-specific # flags can still override them. ldflags = env_ldflags + config.get("ldflags", []) - if is_executable and len(solibs): + if is_executable and solibs: rpath = "lib/" if self.toolset != "target": rpath += self.toolset @@ -1554,7 +1551,7 @@ def WriteLinkForArch( if pdbname: output = [output, pdbname] - if len(solibs): + if solibs: extra_bindings.append( ("solibs", gyp.common.EncodePOSIXShellList(sorted(solibs))) ) @@ -1583,7 +1580,7 @@ def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): elif spec["type"] == "static_library": self.target.binary = self.ComputeOutput(spec) if ( - self.flavor not in ("mac", "openbsd", "netbsd", "win") + self.flavor not in ("ios", "mac", "netbsd", "openbsd", "win") and not self.is_standalone_static_library ): self.ninja.build( @@ -1757,11 +1754,9 @@ def GetPostbuildCommand(self, spec, output, output_binary, is_command_start): + " && ".join([ninja_syntax.escape(command) for command in postbuilds]) ) command_string = ( - commands - + "); G=$$?; " + commands + "); G=$$?; " # Remove the final output if any postbuild failed. - "((exit $$G) || rm -rf %s) " % output - + "&& exit $$G)" + "((exit $$G) || rm -rf %s) " % output + "&& exit $$G)" ) if is_command_start: return "(" + command_string + " && " @@ -1815,10 +1810,7 @@ def ComputeOutputFileName(self, spec, type=None): "executable": default_variables["EXECUTABLE_SUFFIX"], } extension = spec.get("product_extension") - if extension: - extension = "." + extension - else: - extension = DEFAULT_EXTENSION.get(type, "") + extension = "." + extension if extension else DEFAULT_EXTENSION.get(type, "") if "product_name" in spec: # If we were given an explicit name, use that. @@ -1953,7 +1945,8 @@ def WriteNewNinjaRule( ) else: rspfile_content = gyp.msvs_emulation.EncodeRspFileList( - args, win_shell_flags.quote) + args, win_shell_flags.quote + ) command = ( "%s gyp-win-tool action-wrapper $arch " % sys.executable + rspfile @@ -1999,7 +1992,7 @@ def CalculateVariables(default_variables, params): # Copy additional generator configuration data from Xcode, which is shared # by the Mac Ninja generator. - import gyp.generator.xcode as xcode_generator + import gyp.generator.xcode as xcode_generator # noqa: PLC0415 generator_additional_non_configuration_keys = getattr( xcode_generator, "generator_additional_non_configuration_keys", [] @@ -2022,7 +2015,7 @@ def CalculateVariables(default_variables, params): # Copy additional generator configuration data from VS, which is shared # by the Windows Ninja generator. - import gyp.generator.msvs as msvs_generator + import gyp.generator.msvs as msvs_generator # noqa: PLC0415 generator_additional_non_configuration_keys = getattr( msvs_generator, "generator_additional_non_configuration_keys", [] @@ -2079,20 +2072,17 @@ def OpenOutput(path, mode="w"): def CommandWithWrapper(cmd, wrappers, prog): - wrapper = wrappers.get(cmd, "") - if wrapper: + if wrapper := wrappers.get(cmd, ""): return wrapper + " " + prog return prog def GetDefaultConcurrentLinks(): """Returns a best-guess for a number of concurrent links.""" - pool_size = int(os.environ.get("GYP_LINK_CONCURRENCY", 0)) - if pool_size: + if pool_size := int(os.environ.get("GYP_LINK_CONCURRENCY") or 0): return pool_size if sys.platform in ("win32", "cygwin"): - import ctypes class MEMORYSTATUSEX(ctypes.Structure): _fields_ = [ @@ -2112,9 +2102,9 @@ class MEMORYSTATUSEX(ctypes.Structure): ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat)) # VS 2015 uses 20% more working set than VS 2013 and can consume all RAM - # on a 64 GB machine. - mem_limit = max(1, stat.ullTotalPhys // (5 * (2 ** 30))) # total / 5GB - hard_cap = max(1, int(os.environ.get("GYP_LINK_CONCURRENCY_MAX", 2 ** 32))) + # on a 64 GiB machine. + mem_limit = max(1, stat.ullTotalPhys // (5 * (2**30))) # total / 5GiB + hard_cap = max(1, int(os.environ.get("GYP_LINK_CONCURRENCY_MAX") or 2**32)) return min(mem_limit, hard_cap) elif sys.platform.startswith("linux"): if os.path.exists("/proc/meminfo"): @@ -2125,14 +2115,14 @@ class MEMORYSTATUSEX(ctypes.Structure): if not match: continue # Allow 8Gb per link on Linux because Gold is quite memory hungry - return max(1, int(match.group(1)) // (8 * (2 ** 20))) + return max(1, int(match.group(1)) // (8 * (2**20))) return 1 elif sys.platform == "darwin": try: avail_bytes = int(subprocess.check_output(["sysctl", "-n", "hw.memsize"])) # A static library debug build of Chromium's unit_tests takes ~2.7GB, so # 4GB per ld process allows for some more bloat. - return max(1, avail_bytes // (4 * (2 ** 30))) # total / 4GB + return max(1, avail_bytes // (4 * (2**30))) # total / 4GB except subprocess.CalledProcessError: return 1 else: @@ -2213,6 +2203,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name options = params["options"] flavor = gyp.common.GetFlavor(params) generator_flags = params.get("generator_flags", {}) + generate_compile_commands = generator_flags.get("compile_commands", False) # build_dir: relative path from source root to our output files. # e.g. "out/Debug" @@ -2308,8 +2299,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name key_prefix = re.sub(r"\.HOST$", ".host", key_prefix) wrappers[key_prefix] = os.path.join(build_to_root, value) - mac_toolchain_dir = generator_flags.get("mac_toolchain_dir", None) - if mac_toolchain_dir: + if mac_toolchain_dir := generator_flags.get("mac_toolchain_dir", None): wrappers["LINK"] = "export DEVELOPER_DIR='%s' &&" % mac_toolchain_dir if flavor == "win": @@ -2420,8 +2410,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name "cc_s", description="CC $out", command=( - "$cc $defines $includes $cflags $cflags_c " - "$cflags_pch_c -c $in -o $out" + "$cc $defines $includes $cflags $cflags_c $cflags_pch_c -c $in -o $out" ), ) master_ninja.rule( @@ -2496,7 +2485,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name ), ) - if flavor != "mac" and flavor != "win": + if flavor not in ("ios", "mac", "win"): master_ninja.rule( "alink", description="AR $out", @@ -2532,11 +2521,10 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name "solink", description="SOLINK $lib", restat=True, - command=mtime_preserving_solink_base - % {"suffix": "@$link_file_list"}, # noqa: E501 + command=mtime_preserving_solink_base % {"suffix": "@$link_file_list"}, rspfile="$link_file_list", rspfile_content=( - "-Wl,--whole-archive $in $solibs -Wl," "--no-whole-archive $libs" + "-Wl,--whole-archive $in $solibs -Wl,--no-whole-archive $libs" ), pool="link_pool", ) @@ -2596,9 +2584,9 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name "alink", description="LIBTOOL-STATIC $out, POSTBUILDS", command="rm -f $out && " - "./gyp-mac-tool filter-libtool libtool $libtool_flags " + "%s gyp-mac-tool filter-libtool libtool $libtool_flags " "-static -o $out $in" - "$postbuilds", + "$postbuilds" % sys.executable, ) master_ninja.rule( "lipo", @@ -2685,7 +2673,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name master_ninja.rule( "link", description="LINK $out, POSTBUILDS", - command=("$ld $ldflags -o $out " "$in $solibs $libs$postbuilds"), + command=("$ld $ldflags -o $out $in $solibs $libs$postbuilds"), pool="link_pool", ) master_ninja.rule( @@ -2699,41 +2687,44 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name master_ninja.rule( "copy_infoplist", description="COPY INFOPLIST $in", - command="$env ./gyp-mac-tool copy-info-plist $in $out $binary $keys", + command="$env %s gyp-mac-tool copy-info-plist $in $out $binary $keys" + % sys.executable, ) master_ninja.rule( "merge_infoplist", description="MERGE INFOPLISTS $in", - command="$env ./gyp-mac-tool merge-info-plist $out $in", + command="$env %s gyp-mac-tool merge-info-plist $out $in" % sys.executable, ) master_ninja.rule( "compile_xcassets", description="COMPILE XCASSETS $in", - command="$env ./gyp-mac-tool compile-xcassets $keys $in", + command="$env %s gyp-mac-tool compile-xcassets $keys $in" % sys.executable, ) master_ninja.rule( "compile_ios_framework_headers", description="COMPILE HEADER MAPS AND COPY FRAMEWORK HEADERS $in", - command="$env ./gyp-mac-tool compile-ios-framework-header-map $out " - "$framework $in && $env ./gyp-mac-tool " - "copy-ios-framework-headers $framework $copy_headers", + command="$env %(python)s gyp-mac-tool compile-ios-framework-header-map " + "$out $framework $in && $env %(python)s gyp-mac-tool " + "copy-ios-framework-headers $framework $copy_headers" + % {"python": sys.executable}, ) master_ninja.rule( "mac_tool", description="MACTOOL $mactool_cmd $in", - command="$env ./gyp-mac-tool $mactool_cmd $in $out $binary", + command="$env %s gyp-mac-tool $mactool_cmd $in $out $binary" + % sys.executable, ) master_ninja.rule( "package_framework", description="PACKAGE FRAMEWORK $out, POSTBUILDS", - command="./gyp-mac-tool package-framework $out $version$postbuilds " - "&& touch $out", + command="%s gyp-mac-tool package-framework $out $version$postbuilds " + "&& touch $out" % sys.executable, ) master_ninja.rule( "package_ios_framework", description="PACKAGE IOS FRAMEWORK $out, POSTBUILDS", - command="./gyp-mac-tool package-ios-framework $out $postbuilds " - "&& touch $out", + command="%s gyp-mac-tool package-ios-framework $out $postbuilds " + "&& touch $out" % sys.executable, ) if flavor == "win": master_ninja.rule( @@ -2811,7 +2802,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name build_file, name, toolset ) qualified_target_for_hash = qualified_target_for_hash.encode("utf-8") - hash_for_rules = hashlib.md5(qualified_target_for_hash).hexdigest() + hash_for_rules = hashlib.sha256(qualified_target_for_hash).hexdigest() base_path = os.path.dirname(build_file) obj = "obj" @@ -2881,6 +2872,35 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name master_ninja_file.close() + if generate_compile_commands: + compile_db = GenerateCompileDBWithNinja(toplevel_build) + compile_db_file = OpenOutput( + os.path.join(toplevel_build, "compile_commands.json") + ) + compile_db_file.write(json.dumps(compile_db, indent=2)) + compile_db_file.close() + + +def GenerateCompileDBWithNinja(path, targets=["all"]): + """Generates a compile database using ninja. + + Args: + path: The build directory to generate a compile database for. + targets: Additional targets to pass to ninja. + + Returns: + List of the contents of the compile database. + """ + ninja_path = shutil.which("ninja") + if ninja_path is None: + raise Exception("ninja not found in PATH") + json_compile_db = subprocess.check_output( + [ninja_path, "-C", path] + + targets + + ["-t", "compdb", "cc", "cxx", "objc", "objcxx"] + ) + return json.loads(json_compile_db) + def PerformBuild(data, configurations, params): options = params["options"] diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py index 7d180685b21cf..616bc7aaf015a 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py @@ -4,12 +4,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" Unit tests for the ninja.py file. """ +"""Unit tests for the ninja.py file.""" import sys import unittest +from pathlib import Path -import gyp.generator.ninja as ninja +from gyp.generator import ninja class TestPrefixesAndSuffixes(unittest.TestCase): @@ -50,6 +51,17 @@ def test_BinaryNamesLinux(self): writer.ComputeOutputFileName(spec, "static_library").endswith(".a") ) + def test_GenerateCompileDBWithNinja(self): + build_dir = ( + Path(__file__).resolve().parent.parent.parent.parent / "data" / "ninja" + ) + compile_db = ninja.GenerateCompileDBWithNinja(build_dir) + assert len(compile_db) == 1 + assert compile_db[0]["directory"] == str(build_dir) + assert compile_db[0]["command"] == "cc my.in my.out" + assert compile_db[0]["file"] == "my.in" + assert compile_db[0]["output"] == "my.out" + if __name__ == "__main__": unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py index 2f4d17e514e43..db4b45d1a04d2 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py @@ -3,19 +3,19 @@ # found in the LICENSE file. -import filecmp -import gyp.common -import gyp.xcodeproj_file -import gyp.xcode_ninja import errno +import filecmp import os -import sys import posixpath import re import shutil import subprocess +import sys import tempfile +import gyp.common +import gyp.xcode_ninja +import gyp.xcodeproj_file # Project files generated by this module will use _intermediate_var as a # custom Xcode setting whose value is a DerivedSources-like directory that's @@ -439,7 +439,7 @@ def Finalize2(self, xcode_targets, xcode_target_to_target_dict): # it opens the project file, which will result in unnecessary diffs. # TODO(mark): This is evil because it relies on internal knowledge of # PBXProject._other_pbxprojects. - for other_pbxproject in self.project._other_pbxprojects.keys(): + for other_pbxproject in self.project._other_pbxprojects: self.project.AddOrGetProjectReference(other_pbxproject) self.project.SortRemoteProductReferences() @@ -531,7 +531,7 @@ def AddSourceToTarget(source, type, pbxp, xct): library_extensions = ["a", "dylib", "framework", "o"] basename = posixpath.basename(source) - (root, ext) = posixpath.splitext(basename) + (_root, ext) = posixpath.splitext(basename) if ext: ext = ext[1:].lower() @@ -564,12 +564,12 @@ def AddHeaderToTarget(header, pbxp, xct, is_public): def ExpandXcodeVariables(string, expansions): """Expands Xcode-style $(VARIABLES) in string per the expansions dict. - In some rare cases, it is appropriate to expand Xcode variables when a - project file is generated. For any substring $(VAR) in string, if VAR is a - key in the expansions dict, $(VAR) will be replaced with expansions[VAR]. - Any $(VAR) substring in string for which VAR is not a key in the expansions - dict will remain in the returned string. - """ + In some rare cases, it is appropriate to expand Xcode variables when a + project file is generated. For any substring $(VAR) in string, if VAR is a + key in the expansions dict, $(VAR) will be replaced with expansions[VAR]. + Any $(VAR) substring in string for which VAR is not a key in the expansions + dict will remain in the returned string. + """ matches = _xcode_variable_re.findall(string) if matches is None: @@ -592,9 +592,9 @@ def ExpandXcodeVariables(string, expansions): def EscapeXcodeDefine(s): """We must escape the defines that we give to XCode so that it knows not to - split on spaces and to respect backslash and quote literals. However, we - must not quote the define, or Xcode will incorrectly interpret variables - especially $(inherited).""" + split on spaces and to respect backslash and quote literals. However, we + must not quote the define, or Xcode will incorrectly interpret variables + especially $(inherited).""" return re.sub(_xcode_define_re, r"\\\1", s) @@ -679,9 +679,9 @@ def GenerateOutput(target_list, target_dicts, data, params): project_attributes["BuildIndependentTargetsInParallel"] = "YES" if upgrade_check_project_version: project_attributes["LastUpgradeCheck"] = upgrade_check_project_version - project_attributes[ - "LastTestingUpgradeCheck" - ] = upgrade_check_project_version + project_attributes["LastTestingUpgradeCheck"] = ( + upgrade_check_project_version + ) project_attributes["LastSwiftUpdateCheck"] = upgrade_check_project_version pbxp.SetProperty("attributes", project_attributes) @@ -696,7 +696,7 @@ def GenerateOutput(target_list, target_dicts, data, params): xcode_targets = {} xcode_target_to_target_dict = {} for qualified_target in target_list: - [build_file, target_name, toolset] = gyp.common.ParseQualifiedTarget( + [build_file, target_name, _toolset] = gyp.common.ParseQualifiedTarget( qualified_target ) @@ -734,8 +734,7 @@ def GenerateOutput(target_list, target_dicts, data, params): "loadable_module+xcuitest": "com.apple.product-type.bundle.ui-testing", "shared_library+bundle": "com.apple.product-type.framework", "executable+extension+bundle": "com.apple.product-type.app-extension", - "executable+watch+extension+bundle": - "com.apple.product-type.watchkit-extension", + "executable+watch+extension+bundle": "com.apple.product-type.watchkit-extension", # noqa: E501 "executable+watch+bundle": "com.apple.product-type.application.watchapp", "mac_kernel_extension+bundle": "com.apple.product-type.kernel-extension", } @@ -780,8 +779,7 @@ def GenerateOutput(target_list, target_dicts, data, params): type_bundle_key += "+watch+extension+bundle" elif is_watch_app: assert is_bundle, ( - "ios_watch_app flag requires mac_bundle " - "(target %s)" % target_name + "ios_watch_app flag requires mac_bundle (target %s)" % target_name ) type_bundle_key += "+watch+bundle" elif is_bundle: @@ -793,7 +791,7 @@ def GenerateOutput(target_list, target_dicts, data, params): except KeyError as e: gyp.common.ExceptionAppend( e, - "-- unknown product type while " "writing target %s" % target_name, + "-- unknown product type while writing target %s" % target_name, ) raise else: @@ -959,7 +957,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # would-be additional inputs are newer than the output. Modifying # the source tree - even just modification times - feels dirty. # 6564240 Xcode "custom script" build rules always dump all environment - # variables. This is a low-prioroty problem and is not a + # variables. This is a low-priority problem and is not a # show-stopper. rules_by_ext = {} for rule in spec_rules: @@ -1103,7 +1101,7 @@ def GenerateOutput(target_list, target_dicts, data, params): eol = " \\" makefile.write(f" {concrete_output}{eol}\n") - for (rule_source, concrete_outputs, message, action) in zip( + for rule_source, concrete_outputs, message, action in zip( rule["rule_sources"], concrete_outputs_by_rule_source, messages, @@ -1118,10 +1116,7 @@ def GenerateOutput(target_list, target_dicts, data, params): for concrete_output_index, concrete_output in enumerate( concrete_outputs ): - if concrete_output_index == 0: - bol = "" - else: - bol = " " + bol = "" if concrete_output_index == 0 else " " makefile.write(f"{bol}{concrete_output} \\\n") concrete_output_dir = posixpath.dirname(concrete_output) @@ -1220,7 +1215,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # Add "sources". for source in spec.get("sources", []): - (source_root, source_extension) = posixpath.splitext(source) + (_source_root, source_extension) = posixpath.splitext(source) if source_extension[1:] not in rules_by_ext: # AddSourceToTarget will add the file to a root group if it's not # already there. @@ -1232,7 +1227,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # it's a bundle of any type. if is_bundle: for resource in tgt_mac_bundle_resources: - (resource_root, resource_extension) = posixpath.splitext(resource) + (_resource_root, resource_extension) = posixpath.splitext(resource) if resource_extension[1:] not in rules_by_ext: AddResourceToTarget(resource, pbxp, xct) else: diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py index 49772d1f4d810..bfd8c587a3175 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py @@ -4,11 +4,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" Unit tests for the xcode.py file. """ +"""Unit tests for the xcode.py file.""" -import gyp.generator.xcode as xcode -import unittest import sys +import unittest + +from gyp.generator import xcode class TestEscapeXcodeDefine(unittest.TestCase): diff --git a/node_modules/node-gyp/gyp/pylib/gyp/input.py b/node_modules/node-gyp/gyp/pylib/gyp/input.py index 354958bfb2ab5..f3a5e168f2075 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/input.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/input.py @@ -4,9 +4,6 @@ import ast - -import gyp.common -import gyp.simple_copy import multiprocessing import os.path import re @@ -16,9 +13,12 @@ import sys import threading import traceback -from distutils.version import StrictVersion -from gyp.common import GypError -from gyp.common import OrderedSet + +from packaging.version import Version + +import gyp.common +import gyp.simple_copy +from gyp.common import GypError, OrderedSet # A list of types that are treated as linkable. linkable_types = [ @@ -139,21 +139,21 @@ def IsPathSection(section): def GetIncludedBuildFiles(build_file_path, aux_data, included=None): """Return a list of all build files included into build_file_path. - The returned list will contain build_file_path as well as all other files - that it included, either directly or indirectly. Note that the list may - contain files that were included into a conditional section that evaluated - to false and was not merged into build_file_path's dict. + The returned list will contain build_file_path as well as all other files + that it included, either directly or indirectly. Note that the list may + contain files that were included into a conditional section that evaluated + to false and was not merged into build_file_path's dict. - aux_data is a dict containing a key for each build file or included build - file. Those keys provide access to dicts whose "included" keys contain - lists of all other files included by the build file. + aux_data is a dict containing a key for each build file or included build + file. Those keys provide access to dicts whose "included" keys contain + lists of all other files included by the build file. - included should be left at its default None value by external callers. It - is used for recursion. + included should be left at its default None value by external callers. It + is used for recursion. - The returned list will not contain any duplicate entries. Each build file - in the list will be relative to the current directory. - """ + The returned list will not contain any duplicate entries. Each build file + in the list will be relative to the current directory. + """ if included is None: included = [] @@ -171,10 +171,10 @@ def GetIncludedBuildFiles(build_file_path, aux_data, included=None): def CheckedEval(file_contents): """Return the eval of a gyp file. - The gyp file is restricted to dictionaries and lists only, and - repeated keys are not allowed. - Note that this is slower than eval() is. - """ + The gyp file is restricted to dictionaries and lists only, and + repeated keys are not allowed. + Note that this is slower than eval() is. + """ syntax_tree = ast.parse(file_contents) assert isinstance(syntax_tree, ast.Module) @@ -225,7 +225,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, is_target, check return data[build_file_path] if os.path.exists(build_file_path): - build_file_contents = open(build_file_path, encoding='utf-8').read() + build_file_contents = open(build_file_path, encoding="utf-8").read() else: raise GypError(f"{build_file_path} not found (cwd: {os.getcwd()})") @@ -242,7 +242,7 @@ def LoadOneBuildFile(build_file_path, data, aux_data, includes, is_target, check gyp.common.ExceptionAppend(e, "while reading " + build_file_path) raise - if type(build_file_data) is not dict: + if not isinstance(build_file_data, dict): raise GypError("%s does not evaluate to a dictionary." % build_file_path) data[build_file_path] = build_file_data @@ -303,20 +303,20 @@ def LoadBuildFileIncludesIntoDict( # Recurse into subdictionaries. for k, v in subdict.items(): - if type(v) is dict: + if isinstance(v, dict): LoadBuildFileIncludesIntoDict(v, subdict_path, data, aux_data, None, check) - elif type(v) is list: + elif isinstance(v, list): LoadBuildFileIncludesIntoList(v, subdict_path, data, aux_data, check) # This recurses into lists so that it can look for dicts. def LoadBuildFileIncludesIntoList(sublist, sublist_path, data, aux_data, check): for item in sublist: - if type(item) is dict: + if isinstance(item, dict): LoadBuildFileIncludesIntoDict( item, sublist_path, data, aux_data, None, check ) - elif type(item) is list: + elif isinstance(item, list): LoadBuildFileIncludesIntoList(item, sublist_path, data, aux_data, check) @@ -350,9 +350,9 @@ def ProcessToolsetsInDict(data): data["targets"] = new_target_list if "conditions" in data: for condition in data["conditions"]: - if type(condition) is list: + if isinstance(condition, list): for condition_dict in condition[1:]: - if type(condition_dict) is dict: + if isinstance(condition_dict, dict): ProcessToolsetsInDict(condition_dict) @@ -508,9 +508,9 @@ def CallLoadTargetBuildFile( ): """Wrapper around LoadTargetBuildFile for parallel processing. - This wrapper is used when LoadTargetBuildFile is executed in - a worker process. - """ + This wrapper is used when LoadTargetBuildFile is executed in + a worker process. + """ try: signal.signal(signal.SIGINT, signal.SIG_IGN) @@ -559,10 +559,10 @@ class ParallelProcessingError(Exception): class ParallelState: """Class to keep track of state when processing input files in parallel. - If build files are loaded in parallel, use this to keep track of - state during farming out and processing parallel jobs. It's stored - in a global so that the callback function can have access to it. - """ + If build files are loaded in parallel, use this to keep track of + state during farming out and processing parallel jobs. It's stored + in a global so that the callback function can have access to it. + """ def __init__(self): # The multiprocessing pool. @@ -584,8 +584,7 @@ def __init__(self): self.error = False def LoadTargetBuildFileCallback(self, result): - """Handle the results of running LoadTargetBuildFile in another process. - """ + """Handle the results of running LoadTargetBuildFile in another process.""" self.condition.acquire() if not result: self.error = True @@ -692,9 +691,9 @@ def FindEnclosingBracketGroup(input_str): def IsStrCanonicalInt(string): """Returns True if |string| is in its canonical integer form. - The canonical form is such that str(int(string)) == string. - """ - if type(string) is str: + The canonical form is such that str(int(string)) == string. + """ + if isinstance(string, str): # This function is called a lot so for maximum performance, avoid # involving regexps which would otherwise make the code much # shorter. Regexps would need twice the time of this function. @@ -744,7 +743,7 @@ def IsStrCanonicalInt(string): def FixupPlatformCommand(cmd): if sys.platform == "win32": - if type(cmd) is list: + if isinstance(cmd, list): cmd = [re.sub("^cat ", "type ", cmd[0])] + cmd[1:] else: cmd = re.sub("^cat ", "type ", cmd) @@ -870,10 +869,9 @@ def ExpandVariables(input, phase, variables, build_file): # This works around actions/rules which have more inputs than will # fit on the command line. if file_list: - if type(contents) is list: - contents_list = contents - else: - contents_list = contents.split(" ") + contents_list = ( + contents if isinstance(contents, list) else contents.split(" ") + ) replacement = contents_list[0] if os.path.isabs(replacement): raise GypError('| cannot handle absolute paths, got "%s"' % replacement) @@ -936,7 +934,6 @@ def ExpandVariables(input, phase, variables, build_file): os.chdir(build_file_dir) sys.path.append(os.getcwd()) try: - parsed_contents = shlex.split(contents) try: py_module = __import__(parsed_contents[0]) @@ -961,13 +958,13 @@ def ExpandVariables(input, phase, variables, build_file): # Fix up command with platform specific workarounds. contents = FixupPlatformCommand(contents) try: - p = subprocess.Popen( + # stderr will be printed no matter what + result = subprocess.run( contents, - shell=use_shell, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - stdin=subprocess.PIPE, + shell=use_shell, cwd=build_file_dir, + check=False, ) except Exception as e: raise GypError( @@ -975,19 +972,12 @@ def ExpandVariables(input, phase, variables, build_file): % (e, contents, build_file) ) - p_stdout, p_stderr = p.communicate("") - p_stdout = p_stdout.decode("utf-8") - p_stderr = p_stderr.decode("utf-8") - - if p.wait() != 0 or p_stderr: - sys.stderr.write(p_stderr) - # Simulate check_call behavior, since check_call only exists - # in python 2.5 and later. + if result.returncode > 0: raise GypError( "Call to '%s' returned exit status %d while in %s." - % (contents, p.returncode, build_file) + % (contents, result.returncode, build_file) ) - replacement = p_stdout.rstrip() + replacement = result.stdout.decode("utf-8").rstrip() cached_command_results[cache_key] = replacement else: @@ -999,29 +989,26 @@ def ExpandVariables(input, phase, variables, build_file): ) replacement = cached_value - else: - if contents not in variables: - if contents[-1] in ["!", "/"]: - # In order to allow cross-compiles (nacl) to happen more naturally, - # we will allow references to >(sources/) etc. to resolve to - # and empty list if undefined. This allows actions to: - # 'action!': [ - # '>@(_sources!)', - # ], - # 'action/': [ - # '>@(_sources/)', - # ], - replacement = [] - else: - raise GypError( - "Undefined variable " + contents + " in " + build_file - ) + elif contents not in variables: + if contents[-1] in ["!", "/"]: + # In order to allow cross-compiles (nacl) to happen more naturally, + # we will allow references to >(sources/) etc. to resolve to + # and empty list if undefined. This allows actions to: + # 'action!': [ + # '>@(_sources!)', + # ], + # 'action/': [ + # '>@(_sources/)', + # ], + replacement = [] else: - replacement = variables[contents] + raise GypError("Undefined variable " + contents + " in " + build_file) + else: + replacement = variables[contents] if isinstance(replacement, bytes) and not isinstance(replacement, str): replacement = replacement.decode("utf-8") # done on Python 3 only - if type(replacement) is list: + if isinstance(replacement, list): for item in replacement: if isinstance(item, bytes) and not isinstance(item, str): item = item.decode("utf-8") # done on Python 3 only @@ -1052,7 +1039,7 @@ def ExpandVariables(input, phase, variables, build_file): # Expanding in list context. It's guaranteed that there's only one # replacement to do in |input_str| and that it's this replacement. See # above. - if type(replacement) is list: + if isinstance(replacement, list): # If it's already a list, make a copy. output = replacement[:] else: @@ -1061,7 +1048,7 @@ def ExpandVariables(input, phase, variables, build_file): else: # Expanding in string context. encoded_replacement = "" - if type(replacement) is list: + if isinstance(replacement, list): # When expanding a list into string context, turn the list items # into a string in a way that will work with a subprocess call. # @@ -1083,7 +1070,7 @@ def ExpandVariables(input, phase, variables, build_file): if output == input: gyp.DebugOutput( gyp.DEBUG_VARIABLES, - "Found only identity matches on %r, avoiding infinite " "recursion.", + "Found only identity matches on %r, avoiding infinite recursion.", output, ) else: @@ -1091,8 +1078,8 @@ def ExpandVariables(input, phase, variables, build_file): # expanding local variables (variables defined in the same # variables block as this one). gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output) - if type(output) is list: - if output and type(output[0]) is list: + if isinstance(output, list): + if output and isinstance(output[0], list): # Leave output alone if it's a list of lists. # We don't want such lists to be stringified. pass @@ -1107,7 +1094,7 @@ def ExpandVariables(input, phase, variables, build_file): output = ExpandVariables(output, phase, variables, build_file) # Convert all strings that are canonically-represented integers into integers. - if type(output) is list: + if isinstance(output, list): for index, outstr in enumerate(output): if IsStrCanonicalInt(outstr): output[index] = int(outstr) @@ -1124,8 +1111,8 @@ def ExpandVariables(input, phase, variables, build_file): def EvalCondition(condition, conditions_key, phase, variables, build_file): """Returns the dict that should be used or None if the result was - that nothing should be used.""" - if type(condition) is not list: + that nothing should be used.""" + if not isinstance(condition, list): raise GypError(conditions_key + " must be a list") if len(condition) < 2: # It's possible that condition[0] won't work in which case this @@ -1143,20 +1130,18 @@ def EvalCondition(condition, conditions_key, phase, variables, build_file): while i < len(condition): cond_expr = condition[i] true_dict = condition[i + 1] - if type(true_dict) is not dict: + if not isinstance(true_dict, dict): raise GypError( - "{} {} must be followed by a dictionary, not {}".format( - conditions_key, cond_expr, type(true_dict) - ) + f"{conditions_key} {cond_expr} must be followed by a dictionary, " + f"not {type(true_dict)}" ) - if len(condition) > i + 2 and type(condition[i + 2]) is dict: + if len(condition) > i + 2 and isinstance(condition[i + 2], dict): false_dict = condition[i + 2] i = i + 3 if i != len(condition): raise GypError( - "{} {} has {} unexpected trailing items".format( - conditions_key, cond_expr, len(condition) - i - ) + f"{conditions_key} {cond_expr} has " + f"{len(condition) - i} unexpected trailing items" ) else: false_dict = None @@ -1171,7 +1156,7 @@ def EvalCondition(condition, conditions_key, phase, variables, build_file): def EvalSingleCondition(cond_expr, true_dict, false_dict, phase, variables, build_file): """Returns true_dict if cond_expr evaluates to true, and false_dict - otherwise.""" + otherwise.""" # Do expansions on the condition itself. Since the condition can naturally # contain variable references without needing to resort to GYP expansion # syntax, this is of dubious value for variables, but someone might want to @@ -1190,7 +1175,7 @@ def EvalSingleCondition(cond_expr, true_dict, false_dict, phase, variables, buil else: ast_code = compile(cond_expr_expanded, "<string>", "eval") cached_conditions_asts[cond_expr_expanded] = ast_code - env = {"__builtins__": {}, "v": StrictVersion} + env = {"__builtins__": {}, "v": Version} if eval(ast_code, env, variables): return true_dict return false_dict @@ -1251,7 +1236,7 @@ def ProcessConditionsInDict(the_dict, phase, variables, build_file): ) if merge_dict is not None: - # Expand variables and nested conditinals in the merge_dict before + # Expand variables and nested conditionals in the merge_dict before # merging it. ProcessVariablesAndConditionsInDict( merge_dict, phase, variables, build_file @@ -1301,10 +1286,10 @@ def ProcessVariablesAndConditionsInDict( ): """Handle all variable and command expansion and conditional evaluation. - This function is the public entry point for all variable expansions and - conditional evaluations. The variables_in dictionary will not be modified - by this function. - """ + This function is the public entry point for all variable expansions and + conditional evaluations. The variables_in dictionary will not be modified + by this function. + """ # Make a copy of the variables_in dict that can be modified during the # loading of automatics and the loading of the variables dict. @@ -1332,7 +1317,7 @@ def ProcessVariablesAndConditionsInDict( for key, value in the_dict.items(): # Skip "variables", which was already processed if present. - if key != "variables" and type(value) is str: + if key != "variables" and isinstance(value, str): expanded = ExpandVariables(value, phase, variables, build_file) if type(expanded) not in (str, int): raise ValueError( @@ -1395,21 +1380,21 @@ def ProcessVariablesAndConditionsInDict( for key, value in the_dict.items(): # Skip "variables" and string values, which were already processed if # present. - if key == "variables" or type(value) is str: + if key == "variables" or isinstance(value, str): continue - if type(value) is dict: + if isinstance(value, dict): # Pass a copy of the variables dict so that subdicts can't influence # parents. ProcessVariablesAndConditionsInDict( value, phase, variables, build_file, key ) - elif type(value) is list: + elif isinstance(value, list): # The list itself can't influence the variables dict, and # ProcessVariablesAndConditionsInList will make copies of the variables # dict if it needs to pass it to something that can influence it. No # copy is necessary here. ProcessVariablesAndConditionsInList(value, phase, variables, build_file) - elif type(value) is not int: + elif not isinstance(value, int): raise TypeError("Unknown type " + value.__class__.__name__ + " for " + key) @@ -1418,17 +1403,17 @@ def ProcessVariablesAndConditionsInList(the_list, phase, variables, build_file): index = 0 while index < len(the_list): item = the_list[index] - if type(item) is dict: + if isinstance(item, dict): # Make a copy of the variables dict so that it won't influence anything # outside of its own scope. ProcessVariablesAndConditionsInDict(item, phase, variables, build_file) - elif type(item) is list: + elif isinstance(item, list): ProcessVariablesAndConditionsInList(item, phase, variables, build_file) - elif type(item) is str: + elif isinstance(item, str): expanded = ExpandVariables(item, phase, variables, build_file) if type(expanded) in (str, int): the_list[index] = expanded - elif type(expanded) is list: + elif isinstance(expanded, list): the_list[index : index + 1] = expanded index += len(expanded) @@ -1443,7 +1428,7 @@ def ProcessVariablesAndConditionsInList(the_list, phase, variables, build_file): + " at " + index ) - elif type(item) is not int: + elif not isinstance(item, int): raise TypeError( "Unknown type " + item.__class__.__name__ + " at index " + index ) @@ -1453,15 +1438,15 @@ def ProcessVariablesAndConditionsInList(the_list, phase, variables, build_file): def BuildTargetsDict(data): """Builds a dict mapping fully-qualified target names to their target dicts. - |data| is a dict mapping loaded build files by pathname relative to the - current directory. Values in |data| are build file contents. For each - |data| value with a "targets" key, the value of the "targets" key is taken - as a list containing target dicts. Each target's fully-qualified name is - constructed from the pathname of the build file (|data| key) and its - "target_name" property. These fully-qualified names are used as the keys - in the returned dict. These keys provide access to the target dicts, - the dicts in the "targets" lists. - """ + |data| is a dict mapping loaded build files by pathname relative to the + current directory. Values in |data| are build file contents. For each + |data| value with a "targets" key, the value of the "targets" key is taken + as a list containing target dicts. Each target's fully-qualified name is + constructed from the pathname of the build file (|data| key) and its + "target_name" property. These fully-qualified names are used as the keys + in the returned dict. These keys provide access to the target dicts, + the dicts in the "targets" lists. + """ targets = {} for build_file in data["target_build_files"]: @@ -1479,13 +1464,13 @@ def BuildTargetsDict(data): def QualifyDependencies(targets): """Make dependency links fully-qualified relative to the current directory. - |targets| is a dict mapping fully-qualified target names to their target - dicts. For each target in this dict, keys known to contain dependency - links are examined, and any dependencies referenced will be rewritten - so that they are fully-qualified and relative to the current directory. - All rewritten dependencies are suitable for use as keys to |targets| or a - similar dict. - """ + |targets| is a dict mapping fully-qualified target names to their target + dicts. For each target in this dict, keys known to contain dependency + links are examined, and any dependencies referenced will be rewritten + so that they are fully-qualified and relative to the current directory. + All rewritten dependencies are suitable for use as keys to |targets| or a + similar dict. + """ all_dependency_sections = [ dep + op for dep in dependency_sections for op in ("", "!", "/") @@ -1528,18 +1513,18 @@ def QualifyDependencies(targets): def ExpandWildcardDependencies(targets, data): """Expands dependencies specified as build_file:*. - For each target in |targets|, examines sections containing links to other - targets. If any such section contains a link of the form build_file:*, it - is taken as a wildcard link, and is expanded to list each target in - build_file. The |data| dict provides access to build file dicts. + For each target in |targets|, examines sections containing links to other + targets. If any such section contains a link of the form build_file:*, it + is taken as a wildcard link, and is expanded to list each target in + build_file. The |data| dict provides access to build file dicts. - Any target that does not wish to be included by wildcard can provide an - optional "suppress_wildcard" key in its target dict. When present and - true, a wildcard dependency link will not include such targets. + Any target that does not wish to be included by wildcard can provide an + optional "suppress_wildcard" key in its target dict. When present and + true, a wildcard dependency link will not include such targets. - All dependency names, including the keys to |targets| and the values in each - dependency list, must be qualified when this function is called. - """ + All dependency names, including the keys to |targets| and the values in each + dependency list, must be qualified when this function is called. + """ for target, target_dict in targets.items(): target_build_file = gyp.common.BuildFile(target) @@ -1585,16 +1570,10 @@ def ExpandWildcardDependencies(targets, data): if int(dependency_target_dict.get("suppress_wildcard", False)): continue dependency_target_name = dependency_target_dict["target_name"] - if ( - dependency_target != "*" - and dependency_target != dependency_target_name - ): + if dependency_target not in {"*", dependency_target_name}: continue dependency_target_toolset = dependency_target_dict["toolset"] - if ( - dependency_toolset != "*" - and dependency_toolset != dependency_target_toolset - ): + if dependency_toolset not in {"*", dependency_target_toolset}: continue dependency = gyp.common.QualifiedTarget( dependency_build_file, @@ -1615,7 +1594,7 @@ def Unify(items): def RemoveDuplicateDependencies(targets): """Makes sure every dependency appears only once in all targets's dependency - lists.""" + lists.""" for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) @@ -1631,26 +1610,21 @@ def Filter(items, item): def RemoveSelfDependencies(targets): """Remove self dependencies from targets that have the prune_self_dependency - variable set.""" + variable set.""" for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) if dependencies: for t in dependencies: - if t == target_name: - if ( - targets[t] - .get("variables", {}) - .get("prune_self_dependency", 0) - ): - target_dict[dependency_key] = Filter( - dependencies, target_name - ) + if t == target_name and ( + targets[t].get("variables", {}).get("prune_self_dependency", 0) + ): + target_dict[dependency_key] = Filter(dependencies, target_name) def RemoveLinkDependenciesFromNoneTargets(targets): """Remove dependencies having the 'link_dependency' attribute from the 'none' - targets.""" + targets.""" for target_name, target_dict in targets.items(): for dependency_key in dependency_sections: dependencies = target_dict.get(dependency_key, []) @@ -1666,11 +1640,11 @@ def RemoveLinkDependenciesFromNoneTargets(targets): class DependencyGraphNode: """ - Attributes: - ref: A reference to an object that this DependencyGraphNode represents. - dependencies: List of DependencyGraphNodes on which this one depends. - dependents: List of DependencyGraphNodes that depend on this one. - """ + Attributes: + ref: A reference to an object that this DependencyGraphNode represents. + dependencies: List of DependencyGraphNodes on which this one depends. + dependents: List of DependencyGraphNodes that depend on this one. + """ class CircularException(GypError): pass @@ -1736,8 +1710,8 @@ def ExtractNodeRef(node): def FindCycles(self): """ - Returns a list of cycles in the graph, where each cycle is its own list. - """ + Returns a list of cycles in the graph, where each cycle is its own list. + """ results = [] visited = set() @@ -1768,21 +1742,21 @@ def DirectDependencies(self, dependencies=None): def _AddImportedDependencies(self, targets, dependencies=None): """Given a list of direct dependencies, adds indirect dependencies that - other dependencies have declared to export their settings. - - This method does not operate on self. Rather, it operates on the list - of dependencies in the |dependencies| argument. For each dependency in - that list, if any declares that it exports the settings of one of its - own dependencies, those dependencies whose settings are "passed through" - are added to the list. As new items are added to the list, they too will - be processed, so it is possible to import settings through multiple levels - of dependencies. - - This method is not terribly useful on its own, it depends on being - "primed" with a list of direct dependencies such as one provided by - DirectDependencies. DirectAndImportedDependencies is intended to be the - public entry point. - """ + other dependencies have declared to export their settings. + + This method does not operate on self. Rather, it operates on the list + of dependencies in the |dependencies| argument. For each dependency in + that list, if any declares that it exports the settings of one of its + own dependencies, those dependencies whose settings are "passed through" + are added to the list. As new items are added to the list, they too will + be processed, so it is possible to import settings through multiple levels + of dependencies. + + This method is not terribly useful on its own, it depends on being + "primed" with a list of direct dependencies such as one provided by + DirectDependencies. DirectAndImportedDependencies is intended to be the + public entry point. + """ if dependencies is None: dependencies = [] @@ -1810,9 +1784,9 @@ def _AddImportedDependencies(self, targets, dependencies=None): def DirectAndImportedDependencies(self, targets, dependencies=None): """Returns a list of a target's direct dependencies and all indirect - dependencies that a dependency has advertised settings should be exported - through the dependency for. - """ + dependencies that a dependency has advertised settings should be exported + through the dependency for. + """ dependencies = self.DirectDependencies(dependencies) return self._AddImportedDependencies(targets, dependencies) @@ -1838,19 +1812,19 @@ def _LinkDependenciesInternal( self, targets, include_shared_libraries, dependencies=None, initial=True ): """Returns an OrderedSet of dependency targets that are linked - into this target. + into this target. - This function has a split personality, depending on the setting of - |initial|. Outside callers should always leave |initial| at its default - setting. + This function has a split personality, depending on the setting of + |initial|. Outside callers should always leave |initial| at its default + setting. - When adding a target to the list of dependencies, this function will - recurse into itself with |initial| set to False, to collect dependencies - that are linked into the linkable target for which the list is being built. + When adding a target to the list of dependencies, this function will + recurse into itself with |initial| set to False, to collect dependencies + that are linked into the linkable target for which the list is being built. - If |include_shared_libraries| is False, the resulting dependencies will not - include shared_library targets that are linked into this target. - """ + If |include_shared_libraries| is False, the resulting dependencies will not + include shared_library targets that are linked into this target. + """ if dependencies is None: # Using a list to get ordered output and a set to do fast "is it # already added" checks. @@ -1932,9 +1906,9 @@ def _LinkDependenciesInternal( def DependenciesForLinkSettings(self, targets): """ - Returns a list of dependency targets whose link_settings should be merged - into this target. - """ + Returns a list of dependency targets whose link_settings should be merged + into this target. + """ # TODO(sbaig) Currently, chrome depends on the bug that shared libraries' # link_settings are propagated. So for now, we will allow it, unless the @@ -1947,8 +1921,8 @@ def DependenciesForLinkSettings(self, targets): def DependenciesToLinkAgainst(self, targets): """ - Returns a list of dependency targets that are linked into this target. - """ + Returns a list of dependency targets that are linked into this target. + """ return self._LinkDependenciesInternal(targets, True) @@ -2245,23 +2219,20 @@ def is_in_set_or_list(x, s, items): singleton = False if type(item) in (str, int): # The cheap and easy case. - if is_paths: - to_item = MakePathRelative(to_file, fro_file, item) - else: - to_item = item + to_item = MakePathRelative(to_file, fro_file, item) if is_paths else item - if not (type(item) is str and item.startswith("-")): + if not (isinstance(item, str) and item.startswith("-")): # Any string that doesn't begin with a "-" is a singleton - it can # only appear once in a list, to be enforced by the list merge append # or prepend. singleton = True - elif type(item) is dict: + elif isinstance(item, dict): # Make a copy of the dictionary, continuing to look for paths to fix. # The other intelligent aspects of merge processing won't apply because # item is being merged into an empty dict. to_item = {} MergeDicts(to_item, item, to_file, fro_file) - elif type(item) is list: + elif isinstance(item, list): # Recurse, making a copy of the list. If the list contains any # descendant dicts, path fixing will occur. Note that here, custom # values for is_paths and append are dropped; those are only to be @@ -2330,12 +2301,12 @@ def MergeDicts(to, fro, to_file, fro_file): to[k] = MakePathRelative(to_file, fro_file, v) else: to[k] = v - elif type(v) is dict: + elif isinstance(v, dict): # Recurse, guaranteeing copies will be made of objects that require it. if k not in to: to[k] = {} MergeDicts(to[k], v, to_file, fro_file) - elif type(v) is list: + elif isinstance(v, list): # Lists in dicts can be merged with different policies, depending on # how the key in the "from" dict (k, the from-key) is written. # @@ -2379,7 +2350,7 @@ def MergeDicts(to, fro, to_file, fro_file): # If the key ends in "?", the list will only be merged if it doesn't # already exist. continue - elif type(to[list_base]) is not list: + elif not isinstance(to[list_base], list): # This may not have been checked above if merging in a list with an # extension character. raise TypeError( @@ -2464,7 +2435,7 @@ def SetUpConfigurations(target, target_dict): merged_configurations = {} configs = target_dict["configurations"] - for (configuration, old_configuration_dict) in configs.items(): + for configuration, old_configuration_dict in configs.items(): # Skip abstract configurations (saves work only). if old_configuration_dict.get("abstract"): continue @@ -2472,12 +2443,9 @@ def SetUpConfigurations(target, target_dict): # Get the inheritance relationship right by making a copy of the target # dict. new_configuration_dict = {} - for (key, target_val) in target_dict.items(): + for key, target_val in target_dict.items(): key_ext = key[-1:] - if key_ext in key_suffixes: - key_base = key[:-1] - else: - key_base = key + key_base = key[:-1] if key_ext in key_suffixes else key if key_base not in non_configuration_keys: new_configuration_dict[key] = gyp.simple_copy.deepcopy(target_val) @@ -2489,11 +2457,8 @@ def SetUpConfigurations(target, target_dict): merged_configurations[configuration] = new_configuration_dict # Put the new configurations back into the target dict as a configuration. - for configuration in merged_configurations.keys(): - target_dict["configurations"][configuration] = merged_configurations[ - configuration - ] - + for configuration, value in merged_configurations.items(): + target_dict["configurations"][configuration] = value # Now drop all the abstract ones. configs = target_dict["configurations"] target_dict["configurations"] = { @@ -2506,19 +2471,16 @@ def SetUpConfigurations(target, target_dict): delete_keys = [] for key in target_dict: key_ext = key[-1:] - if key_ext in key_suffixes: - key_base = key[:-1] - else: - key_base = key + key_base = key[:-1] if key_ext in key_suffixes else key if key_base not in non_configuration_keys: delete_keys.append(key) for key in delete_keys: del target_dict[key] # Check the configurations to see if they contain invalid keys. - for configuration in target_dict["configurations"].keys(): + for configuration in target_dict["configurations"]: configuration_dict = target_dict["configurations"][configuration] - for key in configuration_dict.keys(): + for key in configuration_dict: if key in invalid_configuration_keys: raise GypError( "%s not allowed in the %s configuration, found in " @@ -2529,25 +2491,25 @@ def SetUpConfigurations(target, target_dict): def ProcessListFiltersInDict(name, the_dict): """Process regular expression and exclusion-based filters on lists. - An exclusion list is in a dict key named with a trailing "!", like - "sources!". Every item in such a list is removed from the associated - main list, which in this example, would be "sources". Removed items are - placed into a "sources_excluded" list in the dict. - - Regular expression (regex) filters are contained in dict keys named with a - trailing "/", such as "sources/" to operate on the "sources" list. Regex - filters in a dict take the form: - 'sources/': [ ['exclude', '_(linux|mac|win)\\.cc$'], - ['include', '_mac\\.cc$'] ], - The first filter says to exclude all files ending in _linux.cc, _mac.cc, and - _win.cc. The second filter then includes all files ending in _mac.cc that - are now or were once in the "sources" list. Items matching an "exclude" - filter are subject to the same processing as would occur if they were listed - by name in an exclusion list (ending in "!"). Items matching an "include" - filter are brought back into the main list if previously excluded by an - exclusion list or exclusion regex filter. Subsequent matching "exclude" - patterns can still cause items to be excluded after matching an "include". - """ + An exclusion list is in a dict key named with a trailing "!", like + "sources!". Every item in such a list is removed from the associated + main list, which in this example, would be "sources". Removed items are + placed into a "sources_excluded" list in the dict. + + Regular expression (regex) filters are contained in dict keys named with a + trailing "/", such as "sources/" to operate on the "sources" list. Regex + filters in a dict take the form: + 'sources/': [ ['exclude', '_(linux|mac|win)\\.cc$'], + ['include', '_mac\\.cc$'] ], + The first filter says to exclude all files ending in _linux.cc, _mac.cc, and + _win.cc. The second filter then includes all files ending in _mac.cc that + are now or were once in the "sources" list. Items matching an "exclude" + filter are subject to the same processing as would occur if they were listed + by name in an exclusion list (ending in "!"). Items matching an "include" + filter are brought back into the main list if previously excluded by an + exclusion list or exclusion regex filter. Subsequent matching "exclude" + patterns can still cause items to be excluded after matching an "include". + """ # Look through the dictionary for any lists whose keys end in "!" or "/". # These are lists that will be treated as exclude lists and regular @@ -2560,11 +2522,13 @@ def ProcessListFiltersInDict(name, the_dict): lists = [] del_lists = [] for key, value in the_dict.items(): + if not key: + continue operation = key[-1] - if operation != "!" and operation != "/": + if operation not in {"!", "/"}: continue - if type(value) is not list: + if not isinstance(value, list): raise ValueError( name + " key " + key + " must be list, not " + value.__class__.__name__ ) @@ -2577,7 +2541,7 @@ def ProcessListFiltersInDict(name, the_dict): del_lists.append(key) continue - if type(the_dict[list_key]) is not list: + if not isinstance(the_dict[list_key], list): value = the_dict[list_key] raise ValueError( name @@ -2690,29 +2654,29 @@ def ProcessListFiltersInDict(name, the_dict): # Now recurse into subdicts and lists that may contain dicts. for key, value in the_dict.items(): - if type(value) is dict: + if isinstance(value, dict): ProcessListFiltersInDict(key, value) - elif type(value) is list: + elif isinstance(value, list): ProcessListFiltersInList(key, value) def ProcessListFiltersInList(name, the_list): for item in the_list: - if type(item) is dict: + if isinstance(item, dict): ProcessListFiltersInDict(name, item) - elif type(item) is list: + elif isinstance(item, list): ProcessListFiltersInList(name, item) def ValidateTargetType(target, target_dict): """Ensures the 'type' field on the target is one of the known types. - Arguments: - target: string, name of target. - target_dict: dict, target spec. + Arguments: + target: string, name of target. + target_dict: dict, target spec. - Raises an exception on error. - """ + Raises an exception on error. + """ VALID_TARGET_TYPES = ( "executable", "loadable_module", @@ -2740,14 +2704,14 @@ def ValidateTargetType(target, target_dict): def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): """Ensures that the rules sections in target_dict are valid and consistent, - and determines which sources they apply to. + and determines which sources they apply to. - Arguments: - target: string, name of target. - target_dict: dict, target spec containing "rules" and "sources" lists. - extra_sources_for_rules: a list of keys to scan for rule matches in - addition to 'sources'. - """ + Arguments: + target: string, name of target. + target_dict: dict, target spec containing "rules" and "sources" lists. + extra_sources_for_rules: a list of keys to scan for rule matches in + addition to 'sources'. + """ # Dicts to map between values found in rules' 'rule_name' and 'extension' # keys and the rule dicts themselves. @@ -2759,9 +2723,7 @@ def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): # Make sure that there's no conflict among rule names and extensions. rule_name = rule["rule_name"] if rule_name in rule_names: - raise GypError( - f"rule {rule_name} exists in duplicate, target {target}" - ) + raise GypError(f"rule {rule_name} exists in duplicate, target {target}") rule_names[rule_name] = rule rule_extension = rule["extension"] @@ -2795,7 +2757,7 @@ def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): source_keys.extend(extra_sources_for_rules) for source_key in source_keys: for source in target_dict.get(source_key, []): - (source_root, source_extension) = os.path.splitext(source) + (_source_root, source_extension) = os.path.splitext(source) if source_extension.startswith("."): source_extension = source_extension[1:] if source_extension == rule_extension: @@ -2810,7 +2772,7 @@ def ValidateRunAsInTarget(target, target_dict, build_file): run_as = target_dict.get("run_as") if not run_as: return - if type(run_as) is not dict: + if not isinstance(run_as, dict): raise GypError( "The 'run_as' in target %s from file %s should be a " "dictionary." % (target_name, build_file) @@ -2821,19 +2783,19 @@ def ValidateRunAsInTarget(target, target_dict, build_file): "The 'run_as' in target %s from file %s must have an " "'action' section." % (target_name, build_file) ) - if type(action) is not list: + if not isinstance(action, list): raise GypError( "The 'action' for 'run_as' in target %s from file %s " "must be a list." % (target_name, build_file) ) working_directory = run_as.get("working_directory") - if working_directory and type(working_directory) is not str: + if working_directory and not isinstance(working_directory, str): raise GypError( "The 'working_directory' for 'run_as' in target %s " "in file %s should be a string." % (target_name, build_file) ) environment = run_as.get("environment") - if environment and type(environment) is not dict: + if environment and not isinstance(environment, dict): raise GypError( "The 'environment' for 'run_as' in target %s " "in file %s should be a dictionary." % (target_name, build_file) @@ -2860,33 +2822,31 @@ def ValidateActionsInTarget(target, target_dict, build_file): def TurnIntIntoStrInDict(the_dict): - """Given dict the_dict, recursively converts all integers into strings. - """ + """Given dict the_dict, recursively converts all integers into strings.""" # Use items instead of iteritems because there's no need to try to look at # reinserted keys and their associated values. for k, v in the_dict.items(): - if type(v) is int: + if isinstance(v, int): v = str(v) the_dict[k] = v - elif type(v) is dict: + elif isinstance(v, dict): TurnIntIntoStrInDict(v) - elif type(v) is list: + elif isinstance(v, list): TurnIntIntoStrInList(v) - if type(k) is int: + if isinstance(k, int): del the_dict[k] the_dict[str(k)] = v def TurnIntIntoStrInList(the_list): - """Given list the_list, recursively converts all integers into strings. - """ + """Given list the_list, recursively converts all integers into strings.""" for index, item in enumerate(the_list): - if type(item) is int: + if isinstance(item, int): the_list[index] = str(item) - elif type(item) is dict: + elif isinstance(item, dict): TurnIntIntoStrInDict(item) - elif type(item) is list: + elif isinstance(item, list): TurnIntIntoStrInList(item) @@ -2927,9 +2887,9 @@ def PruneUnwantedTargets(targets, flat_list, dependency_nodes, root_targets, dat def VerifyNoCollidingTargets(targets): """Verify that no two targets in the same directory share the same name. - Arguments: - targets: A list of targets in the form 'path/to/file.gyp:target_name'. - """ + Arguments: + targets: A list of targets in the form 'path/to/file.gyp:target_name'. + """ # Keep a dict going from 'subdirectory:target_name' to 'foo.gyp'. used = {} for target in targets: @@ -3041,8 +3001,8 @@ def Load( del target_dict[key] ProcessListFiltersInDict(target_name, tmp_dict) # Write the results back to |target_dict|. - for key in tmp_dict: - target_dict[key] = tmp_dict[key] + for key, value in tmp_dict.items(): + target_dict[key] = value # Make sure every dependency appears at most once. RemoveDuplicateDependencies(targets) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/input_test.py b/node_modules/node-gyp/gyp/pylib/gyp/input_test.py index a18f72e9ebb0a..ff8c8fbecc3e5 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/input_test.py @@ -6,9 +6,10 @@ """Unit tests for the input.py file.""" -import gyp.input import unittest +import gyp.input + class TestFindCycles(unittest.TestCase): def setUp(self): diff --git a/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py index 59647c9a89034..3710178e110ae 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py @@ -8,7 +8,6 @@ These functions are executed via gyp-mac-tool when using the Makefile generator. """ - import fcntl import fnmatch import glob @@ -25,14 +24,13 @@ def main(args): executor = MacTool() - exit_code = executor.Dispatch(args) - if exit_code is not None: + if (exit_code := executor.Dispatch(args)) is not None: sys.exit(exit_code) class MacTool: """This class performs all the Mac tooling steps. The methods can either be - executed directly, or dispatched from an argument list.""" + executed directly, or dispatched from an argument list.""" def Dispatch(self, args): """Dispatches a string command to a method.""" @@ -48,7 +46,7 @@ def _CommandifyName(self, name_string): def ExecCopyBundleResource(self, source, dest, convert_to_binary): """Copies a resource file to the bundle/Resources directory, performing any - necessary compilation on each resource.""" + necessary compilation on each resource.""" convert_to_binary = convert_to_binary == "True" extension = os.path.splitext(source)[1].lower() if os.path.isdir(source): @@ -59,9 +57,7 @@ def ExecCopyBundleResource(self, source, dest, convert_to_binary): if os.path.exists(dest): shutil.rmtree(dest) shutil.copytree(source, dest) - elif extension == ".xib": - return self._CopyXIBFile(source, dest) - elif extension == ".storyboard": + elif extension in {".xib", ".storyboard"}: return self._CopyXIBFile(source, dest) elif extension == ".strings" and not convert_to_binary: self._CopyStringsFile(source, dest) @@ -70,7 +66,7 @@ def ExecCopyBundleResource(self, source, dest, convert_to_binary): os.unlink(dest) shutil.copy(source, dest) - if convert_to_binary and extension in (".plist", ".strings"): + if convert_to_binary and extension in {".plist", ".strings"}: self._ConvertToBinary(dest) def _CopyXIBFile(self, source, dest): @@ -144,7 +140,7 @@ def _CopyStringsFile(self, source, dest): # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing # semicolon in dictionary. # on invalid files. Do the same kind of validation. - import CoreFoundation + import CoreFoundation # noqa: PLC0415 with open(source, "rb") as in_file: s = in_file.read() @@ -158,17 +154,15 @@ def _CopyStringsFile(self, source, dest): def _DetectInputEncoding(self, file_name): """Reads the first few bytes from file_name and tries to guess the text - encoding. Returns None as a guess if it can't detect it.""" + encoding. Returns None as a guess if it can't detect it.""" with open(file_name, "rb") as fp: try: header = fp.read(3) except Exception: return None - if header.startswith(b"\xFE\xFF"): + if header.startswith((b"\xfe\xff", b"\xff\xfe")): return "UTF-16" - elif header.startswith(b"\xFF\xFE"): - return "UTF-16" - elif header.startswith(b"\xEF\xBB\xBF"): + elif header.startswith(b"\xef\xbb\xbf"): return "UTF-8" else: return None @@ -259,9 +253,9 @@ def ExecFlock(self, lockfile, *cmd_list): def ExecFilterLibtool(self, *cmd_list): """Calls libtool and filters out '/path/to/libtool: file: foo.o has no - symbols'.""" + symbols'.""" libtool_re = re.compile( - r"^.*libtool: (?:for architecture: \S* )?" r"file: .* has no symbols$" + r"^.*libtool: (?:for architecture: \S* )?file: .* has no symbols$" ) libtool_re5 = re.compile( r"^.*libtool: warning for library: " @@ -308,7 +302,7 @@ def ExecPackageIosFramework(self, framework): def ExecPackageFramework(self, framework, version): """Takes a path to Something.framework and the Current version of that and - sets up all the symlinks.""" + sets up all the symlinks.""" # Find the name of the binary based on the part before the ".framework". binary = os.path.basename(framework).split(".")[0] @@ -337,7 +331,7 @@ def ExecPackageFramework(self, framework, version): def _Relink(self, dest, link): """Creates a symlink to |dest| named |link|. If |link| already exists, - it is overwritten.""" + it is overwritten.""" if os.path.lexists(link): os.remove(link) os.symlink(dest, link) @@ -362,14 +356,14 @@ def ExecCopyIosFrameworkHeaders(self, framework, *copy_headers): def ExecCompileXcassets(self, keys, *inputs): """Compiles multiple .xcassets files into a single .car file. - This invokes 'actool' to compile all the inputs .xcassets files. The - |keys| arguments is a json-encoded dictionary of extra arguments to - pass to 'actool' when the asset catalogs contains an application icon - or a launch image. + This invokes 'actool' to compile all the inputs .xcassets files. The + |keys| arguments is a json-encoded dictionary of extra arguments to + pass to 'actool' when the asset catalogs contains an application icon + or a launch image. - Note that 'actool' does not create the Assets.car file if the asset - catalogs does not contains imageset. - """ + Note that 'actool' does not create the Assets.car file if the asset + catalogs does not contains imageset. + """ command_line = [ "xcrun", "actool", @@ -442,13 +436,13 @@ def ExecMergeInfoPlist(self, output, *inputs): def ExecCodeSignBundle(self, key, entitlements, provisioning, path, preserve): """Code sign a bundle. - This function tries to code sign an iOS bundle, following the same - algorithm as Xcode: - 1. pick the provisioning profile that best match the bundle identifier, - and copy it into the bundle as embedded.mobileprovision, - 2. copy Entitlements.plist from user or SDK next to the bundle, - 3. code sign the bundle. - """ + This function tries to code sign an iOS bundle, following the same + algorithm as Xcode: + 1. pick the provisioning profile that best match the bundle identifier, + and copy it into the bundle as embedded.mobileprovision, + 2. copy Entitlements.plist from user or SDK next to the bundle, + 3. code sign the bundle. + """ substitutions, overrides = self._InstallProvisioningProfile( provisioning, self._GetCFBundleIdentifier() ) @@ -467,16 +461,16 @@ def ExecCodeSignBundle(self, key, entitlements, provisioning, path, preserve): def _InstallProvisioningProfile(self, profile, bundle_identifier): """Installs embedded.mobileprovision into the bundle. - Args: - profile: string, optional, short name of the .mobileprovision file - to use, if empty or the file is missing, the best file installed - will be used - bundle_identifier: string, value of CFBundleIdentifier from Info.plist + Args: + profile: string, optional, short name of the .mobileprovision file + to use, if empty or the file is missing, the best file installed + will be used + bundle_identifier: string, value of CFBundleIdentifier from Info.plist - Returns: - A tuple containing two dictionary: variables substitutions and values - to overrides when generating the entitlements file. - """ + Returns: + A tuple containing two dictionary: variables substitutions and values + to overrides when generating the entitlements file. + """ source_path, provisioning_data, team_id = self._FindProvisioningProfile( profile, bundle_identifier ) @@ -492,24 +486,24 @@ def _InstallProvisioningProfile(self, profile, bundle_identifier): def _FindProvisioningProfile(self, profile, bundle_identifier): """Finds the .mobileprovision file to use for signing the bundle. - Checks all the installed provisioning profiles (or if the user specified - the PROVISIONING_PROFILE variable, only consult it) and select the most - specific that correspond to the bundle identifier. + Checks all the installed provisioning profiles (or if the user specified + the PROVISIONING_PROFILE variable, only consult it) and select the most + specific that correspond to the bundle identifier. - Args: - profile: string, optional, short name of the .mobileprovision file - to use, if empty or the file is missing, the best file installed - will be used - bundle_identifier: string, value of CFBundleIdentifier from Info.plist + Args: + profile: string, optional, short name of the .mobileprovision file + to use, if empty or the file is missing, the best file installed + will be used + bundle_identifier: string, value of CFBundleIdentifier from Info.plist - Returns: - A tuple of the path to the selected provisioning profile, the data of - the embedded plist in the provisioning profile and the team identifier - to use for code signing. + Returns: + A tuple of the path to the selected provisioning profile, the data of + the embedded plist in the provisioning profile and the team identifier + to use for code signing. - Raises: - SystemExit: if no .mobileprovision can be used to sign the bundle. - """ + Raises: + SystemExit: if no .mobileprovision can be used to sign the bundle. + """ profiles_dir = os.path.join( os.environ["HOME"], "Library", "MobileDevice", "Provisioning Profiles" ) @@ -557,12 +551,12 @@ def _FindProvisioningProfile(self, profile, bundle_identifier): def _LoadProvisioningProfile(self, profile_path): """Extracts the plist embedded in a provisioning profile. - Args: - profile_path: string, path to the .mobileprovision file + Args: + profile_path: string, path to the .mobileprovision file - Returns: - Content of the plist embedded in the provisioning profile as a dictionary. - """ + Returns: + Content of the plist embedded in the provisioning profile as a dictionary. + """ with tempfile.NamedTemporaryFile() as temp: subprocess.check_call( ["security", "cms", "-D", "-i", profile_path, "-o", temp.name] @@ -585,16 +579,16 @@ def _MergePlist(self, merged_plist, plist): def _LoadPlistMaybeBinary(self, plist_path): """Loads into a memory a plist possibly encoded in binary format. - This is a wrapper around plistlib.readPlist that tries to convert the - plist to the XML format if it can't be parsed (assuming that it is in - the binary format). + This is a wrapper around plistlib.readPlist that tries to convert the + plist to the XML format if it can't be parsed (assuming that it is in + the binary format). - Args: - plist_path: string, path to a plist file, in XML or binary format + Args: + plist_path: string, path to a plist file, in XML or binary format - Returns: - Content of the plist as a dictionary. - """ + Returns: + Content of the plist as a dictionary. + """ try: # First, try to read the file using plistlib that only supports XML, # and if an exception is raised, convert a temporary copy to XML and @@ -610,13 +604,13 @@ def _LoadPlistMaybeBinary(self, plist_path): def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix): """Constructs a dictionary of variable substitutions for Entitlements.plist. - Args: - bundle_identifier: string, value of CFBundleIdentifier from Info.plist - app_identifier_prefix: string, value for AppIdentifierPrefix + Args: + bundle_identifier: string, value of CFBundleIdentifier from Info.plist + app_identifier_prefix: string, value for AppIdentifierPrefix - Returns: - Dictionary of substitutions to apply when generating Entitlements.plist. - """ + Returns: + Dictionary of substitutions to apply when generating Entitlements.plist. + """ return { "CFBundleIdentifier": bundle_identifier, "AppIdentifierPrefix": app_identifier_prefix, @@ -625,9 +619,9 @@ def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix): def _GetCFBundleIdentifier(self): """Extracts CFBundleIdentifier value from Info.plist in the bundle. - Returns: - Value of CFBundleIdentifier in the Info.plist located in the bundle. - """ + Returns: + Value of CFBundleIdentifier in the Info.plist located in the bundle. + """ info_plist_path = os.path.join( os.environ["TARGET_BUILD_DIR"], os.environ["INFOPLIST_PATH"] ) @@ -637,19 +631,19 @@ def _GetCFBundleIdentifier(self): def _InstallEntitlements(self, entitlements, substitutions, overrides): """Generates and install the ${BundleName}.xcent entitlements file. - Expands variables "$(variable)" pattern in the source entitlements file, - add extra entitlements defined in the .mobileprovision file and the copy - the generated plist to "${BundlePath}.xcent". + Expands variables "$(variable)" pattern in the source entitlements file, + add extra entitlements defined in the .mobileprovision file and the copy + the generated plist to "${BundlePath}.xcent". - Args: - entitlements: string, optional, path to the Entitlements.plist template - to use, defaults to "${SDKROOT}/Entitlements.plist" - substitutions: dictionary, variable substitutions - overrides: dictionary, values to add to the entitlements + Args: + entitlements: string, optional, path to the Entitlements.plist template + to use, defaults to "${SDKROOT}/Entitlements.plist" + substitutions: dictionary, variable substitutions + overrides: dictionary, values to add to the entitlements - Returns: - Path to the generated entitlements file. - """ + Returns: + Path to the generated entitlements file. + """ source_path = entitlements target_path = os.path.join( os.environ["BUILT_PRODUCTS_DIR"], os.environ["PRODUCT_NAME"] + ".xcent" @@ -669,15 +663,15 @@ def _InstallEntitlements(self, entitlements, substitutions, overrides): def _ExpandVariables(self, data, substitutions): """Expands variables "$(variable)" in data. - Args: - data: object, can be either string, list or dictionary - substitutions: dictionary, variable substitutions to perform + Args: + data: object, can be either string, list or dictionary + substitutions: dictionary, variable substitutions to perform - Returns: - Copy of data where each references to "$(variable)" has been replaced - by the corresponding value found in substitutions, or left intact if - the key was not found. - """ + Returns: + Copy of data where each references to "$(variable)" has been replaced + by the corresponding value found in substitutions, or left intact if + the key was not found. + """ if isinstance(data, str): for key, value in substitutions.items(): data = data.replace("$(%s)" % key, value) @@ -696,15 +690,15 @@ def NextGreaterPowerOf2(x): def WriteHmap(output_name, filelist): """Generates a header map based on |filelist|. - Per Mark Mentovai: - A header map is structured essentially as a hash table, keyed by names used - in #includes, and providing pathnames to the actual files. + Per Mark Mentovai: + A header map is structured essentially as a hash table, keyed by names used + in #includes, and providing pathnames to the actual files. - The implementation below and the comment above comes from inspecting: - http://www.opensource.apple.com/source/distcc/distcc-2503/distcc_dist/include_server/headermap.py?txt - while also looking at the implementation in clang in: - https://llvm.org/svn/llvm-project/cfe/trunk/lib/Lex/HeaderMap.cpp - """ + The implementation below and the comment above comes from inspecting: + http://www.opensource.apple.com/source/distcc/distcc-2503/distcc_dist/include_server/headermap.py?txt + while also looking at the implementation in clang in: + https://llvm.org/svn/llvm-project/cfe/trunk/lib/Lex/HeaderMap.cpp + """ magic = 1751998832 version = 1 _reserved = 0 diff --git a/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py b/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py index 5b9c2712e091b..7c461a8fdf72d 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py @@ -7,15 +7,15 @@ build systems, primarily ninja. """ -import collections import os import re import subprocess import sys +from collections import namedtuple -from gyp.common import OrderedSet import gyp.MSVSUtil import gyp.MSVSVersion +from gyp.common import OrderedSet windows_quoter_regex = re.compile(r'(\\*)"') @@ -74,8 +74,7 @@ def EncodeRspFileList(args, quote_cmd): program = call + " " + os.path.normpath(program) else: program = os.path.normpath(args[0]) - return (program + " " - + " ".join(QuoteForRspFile(arg, quote_cmd) for arg in args[1:])) + return program + " " + " ".join(QuoteForRspFile(arg, quote_cmd) for arg in args[1:]) def _GenericRetrieve(root, default, path): @@ -93,7 +92,7 @@ def _AddPrefix(element, prefix): if element is None: return element # Note, not Iterable because we don't want to handle strings like that. - if isinstance(element, list) or isinstance(element, tuple): + if isinstance(element, (list, tuple)): return [prefix + e for e in element] else: return prefix + element @@ -105,7 +104,7 @@ def _DoRemapping(element, map): if map is not None and element is not None: if not callable(map): map = map.get # Assume it's a dict, otherwise a callable to do the remap. - if isinstance(element, list) or isinstance(element, tuple): + if isinstance(element, (list, tuple)): element = filter(None, [map(elem) for elem in element]) else: element = map(element) @@ -117,7 +116,7 @@ def _AppendOrReturn(append, element): then add |element| to it, adding each item in |element| if it's a list or tuple.""" if append is not None and element is not None: - if isinstance(element, list) or isinstance(element, tuple): + if isinstance(element, (list, tuple)): append.extend(element) else: append.append(element) @@ -183,7 +182,7 @@ def ExtractSharedMSVSSystemIncludes(configs, generator_flags): expanded_system_includes = OrderedSet( [ExpandMacros(include, env) for include in all_system_includes] ) - if any(["$" in include for include in expanded_system_includes]): + if any("$" in include for include in expanded_system_includes): # Some path relies on target-specific variables, bail. return None @@ -247,18 +246,13 @@ def GetExtension(self): the target type. """ ext = self.spec.get("product_extension", None) - if ext: - return ext - return gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "") + return ext or gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec["type"], "") def GetVSMacroEnv(self, base_to_build=None, config=None): """Get a dict of variables mapping internal VS macro names to their gyp equivalents.""" target_arch = self.GetArch(config) - if target_arch == "x86": - target_platform = "Win32" - else: - target_platform = target_arch + target_platform = "Win32" if target_arch == "x86" else target_arch target_name = self.spec.get("product_prefix", "") + self.spec.get( "product_name", self.spec["target_name"] ) @@ -628,8 +622,7 @@ def GetDefFile(self, gyp_to_build_path): def _GetDefFileAsLdflags(self, ldflags, gyp_to_build_path): """.def files get implicitly converted to a ModuleDefinitionFile for the linker in the VS generator. Emulate that behaviour here.""" - def_file = self.GetDefFile(gyp_to_build_path) - if def_file: + if def_file := self.GetDefFile(gyp_to_build_path): ldflags.append('/DEF:"%s"' % def_file) def GetPGDName(self, config, expand_special): @@ -677,14 +670,11 @@ def GetLdflags( ) ld("DelayLoadDLLs", prefix="/DELAYLOAD:") ld("TreatLinkerWarningAsErrors", prefix="/WX", map={"true": "", "false": ":NO"}) - out = self.GetOutputName(config, expand_special) - if out: + if out := self.GetOutputName(config, expand_special): ldflags.append("/OUT:" + out) - pdb = self.GetPDBName(config, expand_special, output_name + ".pdb") - if pdb: + if pdb := self.GetPDBName(config, expand_special, output_name + ".pdb"): ldflags.append("/PDB:" + pdb) - pgd = self.GetPGDName(config, expand_special) - if pgd: + if pgd := self.GetPGDName(config, expand_special): ldflags.append("/PGD:" + pgd) map_file = self.GetMapFileName(config, expand_special) ld("GenerateMapFile", map={"true": "/MAP:" + map_file if map_file else "/MAP"}) @@ -738,10 +728,7 @@ def GetLdflags( # TODO(scottmg): This should sort of be somewhere else (not really a flag). ld("AdditionalDependencies", prefix="") - if self.GetArch(config) == "x86": - safeseh_default = "true" - else: - safeseh_default = None + safeseh_default = "true" if self.GetArch(config) == "x86" else None ld( "ImageHasSafeExceptionHandlers", map={"false": ":NO", "true": ""}, @@ -836,17 +823,15 @@ def _GetLdManifestFlags( ("VCLinkerTool", "UACUIAccess"), config, default="false" ) - inner = """ + level = execution_level_map[execution_level] + inner = f""" <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> - <requestedExecutionLevel level='{}' uiAccess='{}' /> + <requestedExecutionLevel level='{level}' uiAccess='{ui_access}' /> </requestedPrivileges> </security> -</trustInfo>""".format( - execution_level_map[execution_level], - ui_access, - ) +</trustInfo>""" else: inner = "" @@ -941,34 +926,34 @@ def BuildCygwinBashCommandLine(self, args, path_to_base): ) return cmd - RuleShellFlags = collections.namedtuple("RuleShellFlags", ["cygwin", "quote"]) + RuleShellFlags = namedtuple("RuleShellFlags", ["cygwin", "quote"]) # noqa: PYI024 def GetRuleShellFlags(self, rule): """Return RuleShellFlags about how the given rule should be run. This includes whether it should run under cygwin (msvs_cygwin_shell), and whether the commands should be quoted (msvs_quote_cmd).""" # If the variable is unset, or set to 1 we use cygwin - cygwin = int(rule.get("msvs_cygwin_shell", - self.spec.get("msvs_cygwin_shell", 1))) != 0 + cygwin = ( + int(rule.get("msvs_cygwin_shell", self.spec.get("msvs_cygwin_shell", 1))) + != 0 + ) # Default to quoting. There's only a few special instances where the # target command uses non-standard command line parsing and handle quotes # and quote escaping differently. quote_cmd = int(rule.get("msvs_quote_cmd", 1)) - assert quote_cmd != 0 or cygwin != 1, \ - "msvs_quote_cmd=0 only applicable for msvs_cygwin_shell=0" + assert quote_cmd != 0 or cygwin != 1, ( + "msvs_quote_cmd=0 only applicable for msvs_cygwin_shell=0" + ) return MsvsSettings.RuleShellFlags(cygwin, quote_cmd) def _HasExplicitRuleForExtension(self, spec, extension): """Determine if there's an explicit rule for a particular extension.""" - for rule in spec.get("rules", []): - if rule["extension"] == extension: - return True - return False + return any(rule["extension"] == extension for rule in spec.get("rules", [])) def _HasExplicitIdlActions(self, spec): """Determine if an action should not run midl for .idl files.""" return any( - [action.get("explicit_idl_action", 0) for action in spec.get("actions", [])] + action.get("explicit_idl_action", 0) for action in spec.get("actions", []) ) def HasExplicitIdlRulesOrActions(self, spec): @@ -1146,8 +1131,7 @@ def _ExtractImportantEnvironment(output_of_set): for required in ("SYSTEMROOT", "TEMP", "TMP"): if required not in env: raise Exception( - 'Environment variable "%s" ' - "required to be set to valid path" % required + 'Environment variable "%s" required to be set to valid path' % required ) return env diff --git a/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py b/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py index 729cec0636273..8b026642fc5ef 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py @@ -17,8 +17,8 @@ class Error(Exception): def deepcopy(x): """Deep copy operation on gyp objects such as strings, ints, dicts - and lists. More than twice as fast as copy.deepcopy but much less - generic.""" + and lists. More than twice as fast as copy.deepcopy but much less + generic.""" try: return _deepcopy_dispatch[type(x)](x) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py index 638eee4002941..43665577bddda 100755 --- a/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py @@ -9,13 +9,12 @@ These functions are executed via gyp-win-tool when using the ninja generator. """ - import os import re import shutil -import subprocess import stat import string +import subprocess import sys BASE_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -27,18 +26,17 @@ def main(args): executor = WinTool() - exit_code = executor.Dispatch(args) - if exit_code is not None: + if (exit_code := executor.Dispatch(args)) is not None: sys.exit(exit_code) class WinTool: """This class performs all the Windows tooling steps. The methods can either - be executed directly, or dispatched from an argument list.""" + be executed directly, or dispatched from an argument list.""" def _UseSeparateMspdbsrv(self, env, args): """Allows to use a unique instance of mspdbsrv.exe per linker instead of a - shared one.""" + shared one.""" if len(args) < 1: raise Exception("Not enough arguments") @@ -115,9 +113,9 @@ def _on_error(fn, path, excinfo): def ExecLinkWrapper(self, arch, use_separate_mspdbsrv, *args): """Filter diagnostic output from link that looks like: - ' Creating library ui.dll.lib and object ui.dll.exp' - This happens when there are exports from the dll or exe. - """ + ' Creating library ui.dll.lib and object ui.dll.exp' + This happens when there are exports from the dll or exe. + """ env = self._GetEnv(arch) if use_separate_mspdbsrv == "True": self._UseSeparateMspdbsrv(env, args) @@ -159,10 +157,10 @@ def ExecLinkWithManifests( mt, rc, intermediate_manifest, - *manifests + *manifests, ): """A wrapper for handling creating a manifest resource and then executing - a link command.""" + a link command.""" # The 'normal' way to do manifests is to have link generate a manifest # based on gathering dependencies from the object files, then merge that # manifest with other manifests supplied as sources, convert the merged @@ -219,11 +217,10 @@ def ExecLinkWithManifests( our_manifest = "%(out)s.manifest" % variables # Load and normalize the manifests. mt.exe sometimes removes whitespace, # and sometimes doesn't unfortunately. - with open(our_manifest) as our_f: - with open(assert_manifest) as assert_f: - translator = str.maketrans('', '', string.whitespace) - our_data = our_f.read().translate(translator) - assert_data = assert_f.read().translate(translator) + with open(our_manifest) as our_f, open(assert_manifest) as assert_f: + translator = str.maketrans("", "", string.whitespace) + our_data = our_f.read().translate(translator) + assert_data = assert_f.read().translate(translator) if our_data != assert_data: os.unlink(out) @@ -247,8 +244,8 @@ def dump(filename): def ExecManifestWrapper(self, arch, *args): """Run manifest tool with environment set. Strip out undesirable warning - (some XML blocks are recognized by the OS loader, but not the manifest - tool).""" + (some XML blocks are recognized by the OS loader, but not the manifest + tool).""" env = self._GetEnv(arch) popen = subprocess.Popen( args, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT @@ -261,8 +258,8 @@ def ExecManifestWrapper(self, arch, *args): def ExecManifestToRc(self, arch, *args): """Creates a resource file pointing a SxS assembly manifest. - |args| is tuple containing path to resource file, path to manifest file - and resource name which can be "1" (for executables) or "2" (for DLLs).""" + |args| is tuple containing path to resource file, path to manifest file + and resource name which can be "1" (for executables) or "2" (for DLLs).""" manifest_path, resource_path, resource_name = args with open(resource_path, "w") as output: output.write( @@ -272,8 +269,8 @@ def ExecManifestToRc(self, arch, *args): def ExecMidlWrapper(self, arch, outdir, tlb, h, dlldata, iid, proxy, idl, *flags): """Filter noisy filenames output from MIDL compile step that isn't - quietable via command line flags. - """ + quietable via command line flags. + """ args = ( ["midl", "/nologo"] + list(flags) @@ -329,7 +326,7 @@ def ExecAsmWrapper(self, arch, *args): def ExecRcWrapper(self, arch, *args): """Filter logo banner from invocations of rc.exe. Older versions of RC - don't support the /nologo flag.""" + don't support the /nologo flag.""" env = self._GetEnv(arch) popen = subprocess.Popen( args, shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT @@ -346,7 +343,7 @@ def ExecRcWrapper(self, arch, *args): def ExecActionWrapper(self, arch, rspfile, *dir): """Runs an action command line from a response file using the environment - for |arch|. If |dir| is supplied, use that as the working directory.""" + for |arch|. If |dir| is supplied, use that as the working directory.""" env = self._GetEnv(arch) # TODO(scottmg): This is a temporary hack to get some specific variables # through to actions that are set after gyp-time. http://crbug.com/333738. @@ -359,7 +356,7 @@ def ExecActionWrapper(self, arch, rspfile, *dir): def ExecClCompile(self, project_dir, selected_files): """Executed by msvs-ninja projects when the 'ClCompile' target is used to - build selected C/C++ files.""" + build selected C/C++ files.""" project_dir = os.path.relpath(project_dir, BASE_DIR) selected_files = selected_files.split(";") ninja_targets = [ diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py index a75d8eeab7bda..d13eaa9af240b 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py @@ -7,15 +7,15 @@ other build systems, such as make and ninja. """ - import copy -import gyp.common import os import os.path import re import shlex import subprocess import sys + +import gyp.common from gyp.common import GypError # Populated lazily by XcodeVersion, for efficiency, and to fix an issue when @@ -30,7 +30,7 @@ def XcodeArchsVariableMapping(archs, archs_including_64_bit=None): """Constructs a dictionary with expansion for $(ARCHS_STANDARD) variable, - and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT).""" + and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT).""" mapping = {"$(ARCHS_STANDARD)": archs} if archs_including_64_bit: mapping["$(ARCHS_STANDARD_INCLUDING_64_BIT)"] = archs_including_64_bit @@ -39,10 +39,10 @@ def XcodeArchsVariableMapping(archs, archs_including_64_bit=None): class XcodeArchsDefault: """A class to resolve ARCHS variable from xcode_settings, resolving Xcode - macros and implementing filtering by VALID_ARCHS. The expansion of macros - depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and - on the version of Xcode. - """ + macros and implementing filtering by VALID_ARCHS. The expansion of macros + depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and + on the version of Xcode. + """ # Match variable like $(ARCHS_STANDARD). variable_pattern = re.compile(r"\$\([a-zA-Z_][a-zA-Z0-9_]*\)$") @@ -81,8 +81,8 @@ def _ExpandArchs(self, archs, sdkroot): def ActiveArchs(self, archs, valid_archs, sdkroot): """Expands variables references in ARCHS, and filter by VALID_ARCHS if it - is defined (if not set, Xcode accept any value in ARCHS, otherwise, only - values present in VALID_ARCHS are kept).""" + is defined (if not set, Xcode accept any value in ARCHS, otherwise, only + values present in VALID_ARCHS are kept).""" expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or "") if valid_archs: filtered_archs = [] @@ -95,24 +95,24 @@ def ActiveArchs(self, archs, valid_archs, sdkroot): def GetXcodeArchsDefault(): """Returns the |XcodeArchsDefault| object to use to expand ARCHS for the - installed version of Xcode. The default values used by Xcode for ARCHS - and the expansion of the variables depends on the version of Xcode used. + installed version of Xcode. The default values used by Xcode for ARCHS + and the expansion of the variables depends on the version of Xcode used. - For all version anterior to Xcode 5.0 or posterior to Xcode 5.1 included - uses $(ARCHS_STANDARD) if ARCHS is unset, while Xcode 5.0 to 5.0.2 uses - $(ARCHS_STANDARD_INCLUDING_64_BIT). This variable was added to Xcode 5.0 - and deprecated with Xcode 5.1. + For all version anterior to Xcode 5.0 or posterior to Xcode 5.1 included + uses $(ARCHS_STANDARD) if ARCHS is unset, while Xcode 5.0 to 5.0.2 uses + $(ARCHS_STANDARD_INCLUDING_64_BIT). This variable was added to Xcode 5.0 + and deprecated with Xcode 5.1. - For "macosx" SDKROOT, all version starting with Xcode 5.0 includes 64-bit - architecture as part of $(ARCHS_STANDARD) and default to only building it. + For "macosx" SDKROOT, all version starting with Xcode 5.0 includes 64-bit + architecture as part of $(ARCHS_STANDARD) and default to only building it. - For "iphoneos" and "iphonesimulator" SDKROOT, 64-bit architectures are part - of $(ARCHS_STANDARD_INCLUDING_64_BIT) from Xcode 5.0. From Xcode 5.1, they - are also part of $(ARCHS_STANDARD). + For "iphoneos" and "iphonesimulator" SDKROOT, 64-bit architectures are part + of $(ARCHS_STANDARD_INCLUDING_64_BIT) from Xcode 5.0. From Xcode 5.1, they + are also part of $(ARCHS_STANDARD). - All these rules are coded in the construction of the |XcodeArchsDefault| - object to use depending on the version of Xcode detected. The object is - for performance reason.""" + All these rules are coded in the construction of the |XcodeArchsDefault| + object to use depending on the version of Xcode detected. The object is + for performance reason.""" global XCODE_ARCHS_DEFAULT_CACHE if XCODE_ARCHS_DEFAULT_CACHE: return XCODE_ARCHS_DEFAULT_CACHE @@ -189,8 +189,8 @@ def __init__(self, spec): def _ConvertConditionalKeys(self, configname): """Converts or warns on conditional keys. Xcode supports conditional keys, - such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation - with some keys converted while the rest force a warning.""" + such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation + with some keys converted while the rest force a warning.""" settings = self.xcode_settings[configname] conditional_keys = [key for key in settings if key.endswith("]")] for key in conditional_keys: @@ -255,13 +255,13 @@ def _IsIosWatchApp(self): def GetFrameworkVersion(self): """Returns the framework version of the current target. Only valid for - bundles.""" + bundles.""" assert self._IsBundle() return self.GetPerTargetSetting("FRAMEWORK_VERSION", default="A") def GetWrapperExtension(self): """Returns the bundle extension (.app, .framework, .plugin, etc). Only - valid for bundles.""" + valid for bundles.""" assert self._IsBundle() if self.spec["type"] in ("loadable_module", "shared_library"): default_wrapper_extension = { @@ -296,13 +296,13 @@ def GetFullProductName(self): def GetWrapperName(self): """Returns the directory name of the bundle represented by this target. - Only valid for bundles.""" + Only valid for bundles.""" assert self._IsBundle() return self.GetProductName() + self.GetWrapperExtension() def GetBundleContentsFolderPath(self): """Returns the qualified path to the bundle's contents folder. E.g. - Chromium.app/Contents or Foo.bundle/Versions/A. Only valid for bundles.""" + Chromium.app/Contents or Foo.bundle/Versions/A. Only valid for bundles.""" if self.isIOS: return self.GetWrapperName() assert self._IsBundle() @@ -316,7 +316,7 @@ def GetBundleContentsFolderPath(self): def GetBundleResourceFolder(self): """Returns the qualified path to the bundle's resource folder. E.g. - Chromium.app/Contents/Resources. Only valid for bundles.""" + Chromium.app/Contents/Resources. Only valid for bundles.""" assert self._IsBundle() if self.isIOS: return self.GetBundleContentsFolderPath() @@ -324,7 +324,7 @@ def GetBundleResourceFolder(self): def GetBundleExecutableFolderPath(self): """Returns the qualified path to the bundle's executables folder. E.g. - Chromium.app/Contents/MacOS. Only valid for bundles.""" + Chromium.app/Contents/MacOS. Only valid for bundles.""" assert self._IsBundle() if self.spec["type"] in ("shared_library") or self.isIOS: return self.GetBundleContentsFolderPath() @@ -333,25 +333,25 @@ def GetBundleExecutableFolderPath(self): def GetBundleJavaFolderPath(self): """Returns the qualified path to the bundle's Java resource folder. - E.g. Chromium.app/Contents/Resources/Java. Only valid for bundles.""" + E.g. Chromium.app/Contents/Resources/Java. Only valid for bundles.""" assert self._IsBundle() return os.path.join(self.GetBundleResourceFolder(), "Java") def GetBundleFrameworksFolderPath(self): """Returns the qualified path to the bundle's frameworks folder. E.g, - Chromium.app/Contents/Frameworks. Only valid for bundles.""" + Chromium.app/Contents/Frameworks. Only valid for bundles.""" assert self._IsBundle() return os.path.join(self.GetBundleContentsFolderPath(), "Frameworks") def GetBundleSharedFrameworksFolderPath(self): """Returns the qualified path to the bundle's frameworks folder. E.g, - Chromium.app/Contents/SharedFrameworks. Only valid for bundles.""" + Chromium.app/Contents/SharedFrameworks. Only valid for bundles.""" assert self._IsBundle() return os.path.join(self.GetBundleContentsFolderPath(), "SharedFrameworks") def GetBundleSharedSupportFolderPath(self): """Returns the qualified path to the bundle's shared support folder. E.g, - Chromium.app/Contents/SharedSupport. Only valid for bundles.""" + Chromium.app/Contents/SharedSupport. Only valid for bundles.""" assert self._IsBundle() if self.spec["type"] == "shared_library": return self.GetBundleResourceFolder() @@ -360,19 +360,19 @@ def GetBundleSharedSupportFolderPath(self): def GetBundlePlugInsFolderPath(self): """Returns the qualified path to the bundle's plugins folder. E.g, - Chromium.app/Contents/PlugIns. Only valid for bundles.""" + Chromium.app/Contents/PlugIns. Only valid for bundles.""" assert self._IsBundle() return os.path.join(self.GetBundleContentsFolderPath(), "PlugIns") def GetBundleXPCServicesFolderPath(self): """Returns the qualified path to the bundle's XPC services folder. E.g, - Chromium.app/Contents/XPCServices. Only valid for bundles.""" + Chromium.app/Contents/XPCServices. Only valid for bundles.""" assert self._IsBundle() return os.path.join(self.GetBundleContentsFolderPath(), "XPCServices") def GetBundlePlistPath(self): """Returns the qualified path to the bundle's plist file. E.g. - Chromium.app/Contents/Info.plist. Only valid for bundles.""" + Chromium.app/Contents/Info.plist. Only valid for bundles.""" assert self._IsBundle() if ( self.spec["type"] in ("executable", "loadable_module") @@ -438,7 +438,7 @@ def GetMachOType(self): def _GetBundleBinaryPath(self): """Returns the name of the bundle binary of by this target. - E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles.""" + E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles.""" assert self._IsBundle() return os.path.join( self.GetBundleExecutableFolderPath(), self.GetExecutableName() @@ -469,19 +469,16 @@ def _GetStandaloneExecutablePrefix(self): def _GetStandaloneBinaryPath(self): """Returns the name of the non-bundle binary represented by this target. - E.g. hello_world. Only valid for non-bundles.""" + E.g. hello_world. Only valid for non-bundles.""" assert not self._IsBundle() - assert self.spec["type"] in ( + assert self.spec["type"] in { "executable", "shared_library", "static_library", "loadable_module", - ), ("Unexpected type %s" % self.spec["type"]) + }, "Unexpected type %s" % self.spec["type"] target = self.spec["target_name"] - if self.spec["type"] == "static_library": - if target[:3] == "lib": - target = target[3:] - elif self.spec["type"] in ("loadable_module", "shared_library"): + if self.spec["type"] in {"loadable_module", "shared_library", "static_library"}: if target[:3] == "lib": target = target[3:] @@ -492,7 +489,7 @@ def _GetStandaloneBinaryPath(self): def GetExecutableName(self): """Returns the executable name of the bundle represented by this target. - E.g. Chromium.""" + E.g. Chromium.""" if self._IsBundle(): return self.spec.get("product_name", self.spec["target_name"]) else: @@ -500,7 +497,7 @@ def GetExecutableName(self): def GetExecutablePath(self): """Returns the qualified path to the primary executable of the bundle - represented by this target. E.g. Chromium.app/Contents/MacOS/Chromium.""" + represented by this target. E.g. Chromium.app/Contents/MacOS/Chromium.""" if self._IsBundle(): return self._GetBundleBinaryPath() else: @@ -523,7 +520,7 @@ def _GetSdkVersionInfoItem(self, sdk, infoitem): # most sensible route and should still do the right thing. try: return GetStdoutQuiet(["xcrun", "--sdk", sdk, infoitem]) - except GypError: + except (GypError, OSError): pass def _SdkRoot(self, configname): @@ -570,7 +567,7 @@ def _AppendPlatformVersionMinFlags(self, lst): def GetCflags(self, configname, arch=None): """Returns flags that need to be added to .c, .cc, .m, and .mm - compilations.""" + compilations.""" # This functions (and the similar ones below) do not offer complete # emulation of all xcode_settings keys. They're implemented on demand. @@ -579,7 +576,8 @@ def GetCflags(self, configname, arch=None): sdk_root = self._SdkPath() if "SDKROOT" in self._Settings() and sdk_root: - cflags.append("-isysroot %s" % sdk_root) + cflags.append("-isysroot") + cflags.append(sdk_root) if self.header_map_path: cflags.append("-I%s" % self.header_map_path) @@ -664,7 +662,8 @@ def GetCflags(self, configname, arch=None): # TODO: Supporting fat binaries will be annoying. self._WarnUnimplemented("ARCHS") archs = ["i386"] - cflags.append("-arch " + archs[0]) + cflags.append("-arch") + cflags.append(archs[0]) if archs[0] in ("i386", "x86_64"): if self._Test("GCC_ENABLE_SSE3_EXTENSIONS", "YES", default="NO"): @@ -685,10 +684,7 @@ def GetCflags(self, configname, arch=None): if platform_root: cflags.append("-F" + platform_root + "/Developer/Library/Frameworks/") - if sdk_root: - framework_root = sdk_root - else: - framework_root = "" + framework_root = sdk_root if sdk_root else "" config = self.spec["configurations"][self.configname] framework_dirs = config.get("mac_framework_dirs", []) for directory in framework_dirs: @@ -866,7 +862,7 @@ def GetInstallName(self): def _MapLinkerFlagFilename(self, ldflag, gyp_to_build_path): """Checks if ldflag contains a filename and if so remaps it from - gyp-directory-relative to build-directory-relative.""" + gyp-directory-relative to build-directory-relative.""" # This list is expanded on demand. # They get matched as: # -exported_symbols_list file @@ -898,13 +894,13 @@ def _MapLinkerFlagFilename(self, ldflag, gyp_to_build_path): def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): """Returns flags that need to be passed to the linker. - Args: - configname: The name of the configuration to get ld flags for. - product_dir: The directory where products such static and dynamic - libraries are placed. This is added to the library search path. - gyp_to_build_path: A function that converts paths relative to the - current gyp file to paths relative to the build directory. - """ + Args: + configname: The name of the configuration to get ld flags for. + product_dir: The directory where products such static and dynamic + libraries are placed. This is added to the library search path. + gyp_to_build_path: A function that converts paths relative to the + current gyp file to paths relative to the build directory. + """ self.configname = configname ldflags = [] @@ -927,17 +923,15 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): self._AppendPlatformVersionMinFlags(ldflags) if "SDKROOT" in self._Settings() and self._SdkPath(): - ldflags.append("-isysroot " + self._SdkPath()) + ldflags.append("-isysroot") + ldflags.append(self._SdkPath()) for library_path in self._Settings().get("LIBRARY_SEARCH_PATHS", []): ldflags.append("-L" + gyp_to_build_path(library_path)) if "ORDER_FILE" in self._Settings(): - ldflags.append( - "-Wl,-order_file " - + "-Wl," - + gyp_to_build_path(self._Settings()["ORDER_FILE"]) - ) + ldflags.append("-Wl,-order_file") + ldflags.append("-Wl," + gyp_to_build_path(self._Settings()["ORDER_FILE"])) if not gyp.common.CrossCompileRequested(): if arch is not None: @@ -949,7 +943,9 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): # TODO: Supporting fat binaries will be annoying. self._WarnUnimplemented("ARCHS") archs = ["i386"] - ldflags.append("-arch " + archs[0]) + # Avoid quoting the space between -arch and the arch name + ldflags.append("-arch") + ldflags.append(archs[0]) # Xcode adds the product directory by default. # Rewrite -L. to -L./ to work around http://www.openradar.me/25313838 @@ -957,7 +953,8 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): install_name = self.GetInstallName() if install_name and self.spec["type"] != "loadable_module": - ldflags.append("-install_name " + install_name.replace(" ", r"\ ")) + ldflags.append("-install_name") + ldflags.append(install_name.replace(" ", r"\ ")) for rpath in self._Settings().get("LD_RUNPATH_SEARCH_PATHS", []): ldflags.append("-Wl,-rpath," + rpath) @@ -974,7 +971,8 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): platform_root = self._XcodePlatformPath(configname) if sdk_root and platform_root: ldflags.append("-F" + platform_root + "/Developer/Library/Frameworks/") - ldflags.append("-framework XCTest") + ldflags.append("-framework") + ldflags.append("XCTest") is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension() if sdk_root and is_extension: @@ -990,7 +988,8 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): + "/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit" ) else: - ldflags.append("-e _NSExtensionMain") + ldflags.append("-e") + ldflags.append("_NSExtensionMain") ldflags.append("-fapplication-extension") self._Appendf(ldflags, "CLANG_CXX_LIBRARY", "-stdlib=%s") @@ -1001,9 +1000,9 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): def GetLibtoolflags(self, configname): """Returns flags that need to be passed to the static linker. - Args: - configname: The name of the configuration to get ld flags for. - """ + Args: + configname: The name of the configuration to get ld flags for. + """ self.configname = configname libtoolflags = [] @@ -1016,7 +1015,7 @@ def GetLibtoolflags(self, configname): def GetPerTargetSettings(self): """Gets a list of all the per-target settings. This will only fetch keys - whose values are the same across all configurations.""" + whose values are the same across all configurations.""" first_pass = True result = {} for configname in sorted(self.xcode_settings.keys()): @@ -1039,7 +1038,7 @@ def GetPerConfigSetting(self, setting, configname, default=None): def GetPerTargetSetting(self, setting, default=None): """Tries to get xcode_settings.setting from spec. Assumes that the setting - has the same value in all configurations and throws otherwise.""" + has the same value in all configurations and throws otherwise.""" is_first_pass = True result = None for configname in sorted(self.xcode_settings.keys()): @@ -1057,15 +1056,14 @@ def GetPerTargetSetting(self, setting, default=None): def _GetStripPostbuilds(self, configname, output_binary, quiet): """Returns a list of shell commands that contain the shell commands - necessary to strip this target's binary. These should be run as postbuilds - before the actual postbuilds run.""" + necessary to strip this target's binary. These should be run as postbuilds + before the actual postbuilds run.""" self.configname = configname result = [] if self._Test("DEPLOYMENT_POSTPROCESSING", "YES", default="NO") and self._Test( "STRIP_INSTALLED_PRODUCT", "YES", default="NO" ): - default_strip_style = "debugging" if ( self.spec["type"] == "loadable_module" or self._IsIosAppExtension() @@ -1092,8 +1090,8 @@ def _GetStripPostbuilds(self, configname, output_binary, quiet): def _GetDebugInfoPostbuilds(self, configname, output, output_binary, quiet): """Returns a list of shell commands that contain the shell commands - necessary to massage this target's debug information. These should be run - as postbuilds before the actual postbuilds run.""" + necessary to massage this target's debug information. These should be run + as postbuilds before the actual postbuilds run.""" self.configname = configname # For static libraries, no dSYMs are created. @@ -1114,7 +1112,7 @@ def _GetDebugInfoPostbuilds(self, configname, output, output_binary, quiet): def _GetTargetPostbuilds(self, configname, output, output_binary, quiet=False): """Returns a list of shell commands that contain the shell commands - to run as postbuilds for this target, before the actual postbuilds.""" + to run as postbuilds for this target, before the actual postbuilds.""" # dSYMs need to build before stripping happens. return self._GetDebugInfoPostbuilds( configname, output, output_binary, quiet @@ -1122,11 +1120,10 @@ def _GetTargetPostbuilds(self, configname, output, output_binary, quiet=False): def _GetIOSPostbuilds(self, configname, output_binary): """Return a shell command to codesign the iOS output binary so it can - be deployed to a device. This should be run as the very last step of the - build.""" + be deployed to a device. This should be run as the very last step of the + build.""" if not ( - self.isIOS - and (self.spec["type"] == "executable" or self._IsXCTest()) + (self.isIOS and (self.spec["type"] == "executable" or self._IsXCTest())) or self.IsIosFramework() ): return [] @@ -1172,8 +1169,9 @@ def _GetIOSPostbuilds(self, configname, output_binary): # Then re-sign everything with 'preserve=True' postbuilds.extend( [ - '%s code-sign-bundle "%s" "%s" "%s" "%s" %s' + '%s %s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + sys.executable, os.path.join("${TARGET_BUILD_DIR}", "gyp-mac-tool"), key, settings.get("CODE_SIGN_ENTITLEMENTS", ""), @@ -1188,8 +1186,9 @@ def _GetIOSPostbuilds(self, configname, output_binary): for target in targets: postbuilds.extend( [ - '%s code-sign-bundle "%s" "%s" "%s" "%s" %s' + '%s %s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + sys.executable, os.path.join("${TARGET_BUILD_DIR}", "gyp-mac-tool"), key, settings.get("CODE_SIGN_ENTITLEMENTS", ""), @@ -1202,8 +1201,9 @@ def _GetIOSPostbuilds(self, configname, output_binary): postbuilds.extend( [ - '%s code-sign-bundle "%s" "%s" "%s" "%s" %s' + '%s %s code-sign-bundle "%s" "%s" "%s" "%s" %s' % ( + sys.executable, os.path.join("${TARGET_BUILD_DIR}", "gyp-mac-tool"), key, settings.get("CODE_SIGN_ENTITLEMENTS", ""), @@ -1237,7 +1237,7 @@ def AddImplicitPostbuilds( self, configname, output, output_binary, postbuilds=[], quiet=False ): """Returns a list of shell commands that should run before and after - |postbuilds|.""" + |postbuilds|.""" assert output_binary is not None pre = self._GetTargetPostbuilds(configname, output, output_binary, quiet) post = self._GetIOSPostbuilds(configname, output_binary) @@ -1248,10 +1248,7 @@ def _AdjustLibrary(self, library, config_name=None): l_flag = "-framework " + os.path.splitext(os.path.basename(library))[0] else: m = self.library_re.match(library) - if m: - l_flag = "-l" + m.group(1) - else: - l_flag = library + l_flag = "-l" + m.group(1) if m else library sdk_root = self._SdkPath(config_name) if not sdk_root: @@ -1276,8 +1273,8 @@ def _AdjustLibrary(self, library, config_name=None): def AdjustLibraries(self, libraries, config_name=None): """Transforms entries like 'Cocoa.framework' in libraries into entries like - '-framework Cocoa', 'libcrypto.dylib' into '-lcrypto', etc. - """ + '-framework Cocoa', 'libcrypto.dylib' into '-lcrypto', etc. + """ libraries = [self._AdjustLibrary(library, config_name) for library in libraries] return libraries @@ -1342,20 +1339,19 @@ def GetExtraPlistItems(self, configname=None): def _DefaultSdkRoot(self): """Returns the default SDKROOT to use. - Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode - project, then the environment variable was empty. Starting with this - version, Xcode uses the name of the newest SDK installed. - """ + Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode + project, then the environment variable was empty. Starting with this + version, Xcode uses the name of the newest SDK installed. + """ xcode_version, _ = XcodeVersion() if xcode_version < "0500": return "" default_sdk_path = self._XcodeSdkPath("") - default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path) - if default_sdk_root: + if default_sdk_root := XcodeSettings._sdk_root_cache.get(default_sdk_path): return default_sdk_root try: all_sdks = GetStdout(["xcodebuild", "-showsdks"]) - except GypError: + except (GypError, OSError): # If xcodebuild fails, there will be no valid SDKs return "" for line in all_sdks.splitlines(): @@ -1371,39 +1367,39 @@ def _DefaultSdkRoot(self): class MacPrefixHeader: """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. - This feature consists of several pieces: - * If GCC_PREFIX_HEADER is present, all compilations in that project get an - additional |-include path_to_prefix_header| cflag. - * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is - instead compiled, and all other compilations in the project get an - additional |-include path_to_compiled_header| instead. - + Compiled prefix headers have the extension gch. There is one gch file for - every language used in the project (c, cc, m, mm), since gch files for - different languages aren't compatible. - + gch files themselves are built with the target's normal cflags, but they - obviously don't get the |-include| flag. Instead, they need a -x flag that - describes their language. - + All o files in the target need to depend on the gch file, to make sure - it's built before any o file is built. - - This class helps with some of these tasks, but it needs help from the build - system for writing dependencies to the gch files, for writing build commands - for the gch files, and for figuring out the location of the gch files. - """ + This feature consists of several pieces: + * If GCC_PREFIX_HEADER is present, all compilations in that project get an + additional |-include path_to_prefix_header| cflag. + * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is + instead compiled, and all other compilations in the project get an + additional |-include path_to_compiled_header| instead. + + Compiled prefix headers have the extension gch. There is one gch file for + every language used in the project (c, cc, m, mm), since gch files for + different languages aren't compatible. + + gch files themselves are built with the target's normal cflags, but they + obviously don't get the |-include| flag. Instead, they need a -x flag that + describes their language. + + All o files in the target need to depend on the gch file, to make sure + it's built before any o file is built. + + This class helps with some of these tasks, but it needs help from the build + system for writing dependencies to the gch files, for writing build commands + for the gch files, and for figuring out the location of the gch files. + """ def __init__( self, xcode_settings, gyp_path_to_build_path, gyp_path_to_build_output ): """If xcode_settings is None, all methods on this class are no-ops. - Args: - gyp_path_to_build_path: A function that takes a gyp-relative path, - and returns a path relative to the build directory. - gyp_path_to_build_output: A function that takes a gyp-relative path and - a language code ('c', 'cc', 'm', or 'mm'), and that returns a path - to where the output of precompiling that path for that language - should be placed (without the trailing '.gch'). - """ + Args: + gyp_path_to_build_path: A function that takes a gyp-relative path, + and returns a path relative to the build directory. + gyp_path_to_build_output: A function that takes a gyp-relative path and + a language code ('c', 'cc', 'm', or 'mm'), and that returns a path + to where the output of precompiling that path for that language + should be placed (without the trailing '.gch'). + """ # This doesn't support per-configuration prefix headers. Good enough # for now. self.header = None @@ -1448,9 +1444,9 @@ def _Gch(self, lang, arch): def GetObjDependencies(self, sources, objs, arch=None): """Given a list of source files and the corresponding object files, returns - a list of (source, object, gch) tuples, where |gch| is the build-directory - relative path to the gch file each object file depends on. |compilable[i]| - has to be the source file belonging to |objs[i]|.""" + a list of (source, object, gch) tuples, where |gch| is the build-directory + relative path to the gch file each object file depends on. |compilable[i]| + has to be the source file belonging to |objs[i]|.""" if not self.header or not self.compile_headers: return [] @@ -1471,8 +1467,8 @@ def GetObjDependencies(self, sources, objs, arch=None): def GetPchBuildCommands(self, arch=None): """Returns [(path_to_gch, language_flag, language, header)]. - |path_to_gch| and |header| are relative to the build directory. - """ + |path_to_gch| and |header| are relative to the build directory. + """ if not self.header or not self.compile_headers: return [] return [ @@ -1509,7 +1505,8 @@ def XcodeVersion(): raise GypError("xcodebuild returned unexpected results") version = version_list[0].split()[-1] # Last word on first line build = version_list[-1].split()[-1] # Last word on last line - except GypError: # Xcode not installed so look for XCode Command Line Tools + except (GypError, OSError): + # Xcode not installed so look for XCode Command Line Tools version = CLTVersion() # macOS Catalina returns 11.0.0.0.1.1567737322 if not version: raise GypError("No Xcode or CLT version detected!") @@ -1537,26 +1534,28 @@ def CLTVersion(): FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI" MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables" - regex = re.compile("version: (?P<version>.+)") + regex = re.compile(r"version: (?P<version>.+)") for key in [MAVERICKS_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID]: try: output = GetStdout(["/usr/sbin/pkgutil", "--pkg-info", key]) - return re.search(regex, output).groupdict()["version"] - except GypError: + if m := re.search(regex, output): + return m.groupdict()["version"] + except (GypError, OSError): continue - regex = re.compile(r'Command Line Tools for Xcode\s+(?P<version>\S+)') + regex = re.compile(r"Command Line Tools for Xcode\s+(?P<version>\S+)") try: output = GetStdout(["/usr/sbin/softwareupdate", "--history"]) - return re.search(regex, output).groupdict()["version"] - except GypError: + if m := re.search(regex, output): + return m.groupdict()["version"] + except (GypError, OSError): return None def GetStdoutQuiet(cmdlist): """Returns the content of standard output returned by invoking |cmdlist|. - Ignores the stderr. - Raises |GypError| if the command return with a non-zero return code.""" + Ignores the stderr. + Raises |GypError| if the command return with a non-zero return code.""" job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = job.communicate()[0].decode("utf-8") if job.returncode != 0: @@ -1566,7 +1565,7 @@ def GetStdoutQuiet(cmdlist): def GetStdout(cmdlist): """Returns the content of standard output returned by invoking |cmdlist|. - Raises |GypError| if the command return with a non-zero return code.""" + Raises |GypError| if the command return with a non-zero return code.""" job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE) out = job.communicate()[0].decode("utf-8") if job.returncode != 0: @@ -1577,9 +1576,9 @@ def GetStdout(cmdlist): def MergeGlobalXcodeSettingsToSpec(global_dict, spec): """Merges the global xcode_settings dictionary into each configuration of the - target represented by spec. For keys that are both in the global and the local - xcode_settings dict, the local key gets precedence. - """ + target represented by spec. For keys that are both in the global and the local + xcode_settings dict, the local key gets precedence. + """ # The xcode generator special-cases global xcode_settings and does something # that amounts to merging in the global xcode_settings into each local # xcode_settings dict. @@ -1594,9 +1593,9 @@ def MergeGlobalXcodeSettingsToSpec(global_dict, spec): def IsMacBundle(flavor, spec): """Returns if |spec| should be treated as a bundle. - Bundles are directories with a certain subdirectory structure, instead of - just a single file. Bundle rules do not produce a binary but also package - resources into that directory.""" + Bundles are directories with a certain subdirectory structure, instead of + just a single file. Bundle rules do not produce a binary but also package + resources into that directory.""" is_mac_bundle = ( int(spec.get("mac_xctest_bundle", 0)) != 0 or int(spec.get("mac_xcuitest_bundle", 0)) != 0 @@ -1613,14 +1612,14 @@ def IsMacBundle(flavor, spec): def GetMacBundleResources(product_dir, xcode_settings, resources): """Yields (output, resource) pairs for every resource in |resources|. - Only call this for mac bundle targets. - - Args: - product_dir: Path to the directory containing the output bundle, - relative to the build directory. - xcode_settings: The XcodeSettings of the current target. - resources: A list of bundle resources, relative to the build directory. - """ + Only call this for mac bundle targets. + + Args: + product_dir: Path to the directory containing the output bundle, + relative to the build directory. + xcode_settings: The XcodeSettings of the current target. + resources: A list of bundle resources, relative to the build directory. + """ dest = os.path.join(product_dir, xcode_settings.GetBundleResourceFolder()) for res in resources: output = dest @@ -1651,24 +1650,24 @@ def GetMacBundleResources(product_dir, xcode_settings, resources): def GetMacInfoPlist(product_dir, xcode_settings, gyp_path_to_build_path): """Returns (info_plist, dest_plist, defines, extra_env), where: - * |info_plist| is the source plist path, relative to the - build directory, - * |dest_plist| is the destination plist path, relative to the - build directory, - * |defines| is a list of preprocessor defines (empty if the plist - shouldn't be preprocessed, - * |extra_env| is a dict of env variables that should be exported when - invoking |mac_tool copy-info-plist|. - - Only call this for mac bundle targets. - - Args: - product_dir: Path to the directory containing the output bundle, - relative to the build directory. - xcode_settings: The XcodeSettings of the current target. - gyp_to_build_path: A function that converts paths relative to the - current gyp file to paths relative to the build directory. - """ + * |info_plist| is the source plist path, relative to the + build directory, + * |dest_plist| is the destination plist path, relative to the + build directory, + * |defines| is a list of preprocessor defines (empty if the plist + shouldn't be preprocessed, + * |extra_env| is a dict of env variables that should be exported when + invoking |mac_tool copy-info-plist|. + + Only call this for mac bundle targets. + + Args: + product_dir: Path to the directory containing the output bundle, + relative to the build directory. + xcode_settings: The XcodeSettings of the current target. + gyp_to_build_path: A function that converts paths relative to the + current gyp file to paths relative to the build directory. + """ info_plist = xcode_settings.GetPerTargetSetting("INFOPLIST_FILE") if not info_plist: return None, None, [], {} @@ -1706,18 +1705,18 @@ def _GetXcodeEnv( xcode_settings, built_products_dir, srcroot, configuration, additional_settings=None ): """Return the environment variables that Xcode would set. See - http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW153 - for a full list. - - Args: - xcode_settings: An XcodeSettings object. If this is None, this function - returns an empty dict. - built_products_dir: Absolute path to the built products dir. - srcroot: Absolute path to the source root. - configuration: The build configuration name. - additional_settings: An optional dict with more values to add to the - result. - """ + http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW153 + for a full list. + + Args: + xcode_settings: An XcodeSettings object. If this is None, this function + returns an empty dict. + built_products_dir: Absolute path to the built products dir. + srcroot: Absolute path to the source root. + configuration: The build configuration name. + additional_settings: An optional dict with more values to add to the + result. + """ if not xcode_settings: return {} @@ -1771,27 +1770,25 @@ def _GetXcodeEnv( ) env["CONTENTS_FOLDER_PATH"] = xcode_settings.GetBundleContentsFolderPath() env["EXECUTABLE_FOLDER_PATH"] = xcode_settings.GetBundleExecutableFolderPath() - env[ - "UNLOCALIZED_RESOURCES_FOLDER_PATH" - ] = xcode_settings.GetBundleResourceFolder() + env["UNLOCALIZED_RESOURCES_FOLDER_PATH"] = ( + xcode_settings.GetBundleResourceFolder() + ) env["JAVA_FOLDER_PATH"] = xcode_settings.GetBundleJavaFolderPath() env["FRAMEWORKS_FOLDER_PATH"] = xcode_settings.GetBundleFrameworksFolderPath() - env[ - "SHARED_FRAMEWORKS_FOLDER_PATH" - ] = xcode_settings.GetBundleSharedFrameworksFolderPath() - env[ - "SHARED_SUPPORT_FOLDER_PATH" - ] = xcode_settings.GetBundleSharedSupportFolderPath() + env["SHARED_FRAMEWORKS_FOLDER_PATH"] = ( + xcode_settings.GetBundleSharedFrameworksFolderPath() + ) + env["SHARED_SUPPORT_FOLDER_PATH"] = ( + xcode_settings.GetBundleSharedSupportFolderPath() + ) env["PLUGINS_FOLDER_PATH"] = xcode_settings.GetBundlePlugInsFolderPath() env["XPCSERVICES_FOLDER_PATH"] = xcode_settings.GetBundleXPCServicesFolderPath() env["INFOPLIST_PATH"] = xcode_settings.GetBundlePlistPath() env["WRAPPER_NAME"] = xcode_settings.GetWrapperName() - install_name = xcode_settings.GetInstallName() - if install_name: + if install_name := xcode_settings.GetInstallName(): env["LD_DYLIB_INSTALL_NAME"] = install_name - install_name_base = xcode_settings.GetInstallNameBase() - if install_name_base: + if install_name_base := xcode_settings.GetInstallNameBase(): env["DYLIB_INSTALL_NAME_BASE"] = install_name_base xcode_version, _ = XcodeVersion() if xcode_version >= "0500" and not env.get("SDKROOT"): @@ -1819,8 +1816,8 @@ def _GetXcodeEnv( def _NormalizeEnvVarReferences(str): """Takes a string containing variable references in the form ${FOO}, $(FOO), - or $FOO, and returns a string with all variable references in the form ${FOO}. - """ + or $FOO, and returns a string with all variable references in the form ${FOO}. + """ # $FOO -> ${FOO} str = re.sub(r"\$([a-zA-Z_][a-zA-Z0-9_]*)", r"${\1}", str) @@ -1836,9 +1833,9 @@ def _NormalizeEnvVarReferences(str): def ExpandEnvVars(string, expansions): """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the - expansions list. If the variable expands to something that references - another variable, this variable is expanded as well if it's in env -- - until no variables present in env are left.""" + expansions list. If the variable expands to something that references + another variable, this variable is expanded as well if it's in env -- + until no variables present in env are left.""" for k, v in reversed(expansions): string = string.replace("${" + k + "}", v) string = string.replace("$(" + k + ")", v) @@ -1848,18 +1845,18 @@ def ExpandEnvVars(string, expansions): def _TopologicallySortedEnvVarKeys(env): """Takes a dict |env| whose values are strings that can refer to other keys, - for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of - env such that key2 is after key1 in L if env[key2] refers to env[key1]. + for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of + env such that key2 is after key1 in L if env[key2] refers to env[key1]. - Throws an Exception in case of dependency cycles. - """ + Throws an Exception in case of dependency cycles. + """ # Since environment variables can refer to other variables, the evaluation # order is important. Below is the logic to compute the dependency graph # and sort it. regex = re.compile(r"\$\{([a-zA-Z0-9\-_]+)\}") def GetEdges(node): - # Use a definition of edges such that user_of_variable -> used_varible. + # Use a definition of edges such that user_of_variable -> used_variable. # This happens to be easier in this case, since a variable's # definition contains all variables it references in a single string. # We can then reverse the result of the topological sort at the end. @@ -1893,7 +1890,7 @@ def GetSortedXcodeEnv( def GetSpecPostbuildCommands(spec, quiet=False): """Returns the list of postbuilds explicitly defined on |spec|, in a form - executable by a shell.""" + executable by a shell.""" postbuilds = [] for postbuild in spec.get("postbuilds", []): if not quiet: @@ -1907,7 +1904,7 @@ def GetSpecPostbuildCommands(spec, quiet=False): def _HasIOSTarget(targets): """Returns true if any target contains the iOS specific key - IPHONEOS_DEPLOYMENT_TARGET.""" + IPHONEOS_DEPLOYMENT_TARGET.""" for target_dict in targets.values(): for config in target_dict["configurations"].values(): if config.get("xcode_settings", {}).get("IPHONEOS_DEPLOYMENT_TARGET"): @@ -1917,7 +1914,7 @@ def _HasIOSTarget(targets): def _AddIOSDeviceConfigurations(targets): """Clone all targets and append -iphoneos to the name. Configure these targets - to build for iOS devices and use correct architectures for those builds.""" + to build for iOS devices and use correct architectures for those builds.""" for target_dict in targets.values(): toolset = target_dict["toolset"] configs = target_dict["configurations"] @@ -1933,7 +1930,7 @@ def _AddIOSDeviceConfigurations(targets): def CloneConfigurationForDeviceAndEmulator(target_dicts): """If |target_dicts| contains any iOS targets, automatically create -iphoneos - targets for iOS device builds.""" + targets for iOS device builds.""" if _HasIOSTarget(target_dicts): return _AddIOSDeviceConfigurations(target_dicts) return target_dicts diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation_test.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation_test.py new file mode 100644 index 0000000000000..03cbbaea84601 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation_test.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +"""Unit tests for the xcode_emulation.py file.""" + +import sys +import unittest + +from gyp.xcode_emulation import XcodeSettings + + +class TestXcodeSettings(unittest.TestCase): + def setUp(self): + if sys.platform != "darwin": + self.skipTest("This test only runs on macOS") + + def test_GetCflags(self): + target = { + "type": "static_library", + "configurations": { + "Release": {}, + }, + } + configuration_name = "Release" + xcode_settings = XcodeSettings(target) + cflags = xcode_settings.GetCflags(configuration_name, "arm64") + + # Do not quote `-arch arm64` with spaces in one string. + self.assertEqual( + cflags, + ["-fasm-blocks", "-mpascal-strings", "-Os", "-gdwarf-2", "-arch", "arm64"], + ) + + def GypToBuildPath(self, path): + return path + + def test_GetLdflags(self): + target = { + "type": "static_library", + "configurations": { + "Release": {}, + }, + } + configuration_name = "Release" + xcode_settings = XcodeSettings(target) + ldflags = xcode_settings.GetLdflags( + configuration_name, "PRODUCT_DIR", self.GypToBuildPath, "arm64" + ) + + # Do not quote `-arch arm64` with spaces in one string. + self.assertEqual(ldflags, ["-arch", "arm64", "-LPRODUCT_DIR"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py index bb74eacbeaf4a..a133fdbe8b4f5 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py @@ -13,15 +13,16 @@ """ import errno -import gyp.generator.ninja import os import re import xml.sax.saxutils +import gyp.generator.ninja + def _WriteWorkspace(main_gyp, sources_gyp, params): - """ Create a workspace to wrap main and sources gyp paths. """ - (build_file_root, build_file_ext) = os.path.splitext(main_gyp) + """Create a workspace to wrap main and sources gyp paths.""" + (build_file_root, _build_file_ext) = os.path.splitext(main_gyp) workspace_path = build_file_root + ".xcworkspace" options = params["options"] if options.generator_output: @@ -56,7 +57,7 @@ def _WriteWorkspace(main_gyp, sources_gyp, params): def _TargetFromSpec(old_spec, params): - """ Create fake target for xcode-ninja wrapper. """ + """Create fake target for xcode-ninja wrapper.""" # Determine ninja top level build dir (e.g. /path/to/out). ninja_toplevel = None jobs = 0 @@ -69,12 +70,11 @@ def _TargetFromSpec(old_spec, params): target_name = old_spec.get("target_name") product_name = old_spec.get("product_name", target_name) - product_extension = old_spec.get("product_extension") ninja_target = {} ninja_target["target_name"] = target_name ninja_target["product_name"] = product_name - if product_extension: + if product_extension := old_spec.get("product_extension"): ninja_target["product_extension"] = product_extension ninja_target["toolset"] = old_spec.get("toolset") ninja_target["default_configuration"] = old_spec.get("default_configuration") @@ -102,9 +102,9 @@ def _TargetFromSpec(old_spec, params): new_xcode_settings[key] = old_xcode_settings[key] ninja_target["configurations"][config] = {} - ninja_target["configurations"][config][ - "xcode_settings" - ] = new_xcode_settings + ninja_target["configurations"][config]["xcode_settings"] = ( + new_xcode_settings + ) ninja_target["mac_bundle"] = old_spec.get("mac_bundle", 0) ninja_target["mac_xctest_bundle"] = old_spec.get("mac_xctest_bundle", 0) @@ -137,13 +137,13 @@ def _TargetFromSpec(old_spec, params): def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec): """Limit targets for Xcode wrapper. - Xcode sometimes performs poorly with too many targets, so only include - proper executable targets, with filters to customize. - Arguments: - target_extras: Regular expression to always add, matching any target. - executable_target_pattern: Regular expression limiting executable targets. - spec: Specifications for target. - """ + Xcode sometimes performs poorly with too many targets, so only include + proper executable targets, with filters to customize. + Arguments: + target_extras: Regular expression to always add, matching any target. + executable_target_pattern: Regular expression limiting executable targets. + spec: Specifications for target. + """ target_name = spec.get("target_name") # Always include targets matching target_extras. if target_extras is not None and re.search(target_extras, target_name): @@ -154,7 +154,6 @@ def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec): spec.get("type", "") == "executable" and spec.get("product_extension", "") != "bundle" ): - # If there is a filter and the target does not match, exclude the target. if executable_target_pattern is not None: if not re.search(executable_target_pattern, target_name): @@ -166,14 +165,14 @@ def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec): def CreateWrapper(target_list, target_dicts, data, params): """Initialize targets for the ninja wrapper. - This sets up the necessary variables in the targets to generate Xcode projects - that use ninja as an external builder. - Arguments: - target_list: List of target pairs: 'base/base.gyp:base'. - target_dicts: Dict of target properties keyed on target pair. - data: Dict of flattened build files keyed on gyp path. - params: Dict of global options for gyp. - """ + This sets up the necessary variables in the targets to generate Xcode projects + that use ninja as an external builder. + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + data: Dict of flattened build files keyed on gyp path. + params: Dict of global options for gyp. + """ orig_gyp = params["build_files"][0] for gyp_name, gyp_dict in data.items(): if gyp_name == orig_gyp: diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py b/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py index 076eea3721117..2004518dcbce9 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py @@ -74,7 +74,7 @@ PBXBuildFile appears extraneous, but there's actually one reason for this: file-specific compiler flags are added to the PBXBuildFile object so as to allow a single file to be a member of multiple targets while having distinct -compiler flags for each. These flags can be modified in the Xcode applciation +compiler flags for each. These flags can be modified in the Xcode application in the "Build" tab of a File Info window. When a project is open in the Xcode application, Xcode will rewrite it. As @@ -137,14 +137,15 @@ a project file is output. """ -import gyp.common -from functools import cmp_to_key import hashlib -from operator import attrgetter import posixpath import re import struct import sys +from functools import cmp_to_key +from operator import attrgetter + +import gyp.common def cmp(x, y): @@ -175,15 +176,14 @@ def cmp(x, y): def SourceTreeAndPathFromPath(input_path): """Given input_path, returns a tuple with sourceTree and path values. - Examples: - input_path (source_tree, output_path) - '$(VAR)/path' ('VAR', 'path') - '$(VAR)' ('VAR', None) - 'path' (None, 'path') - """ + Examples: + input_path (source_tree, output_path) + '$(VAR)/path' ('VAR', 'path') + '$(VAR)' ('VAR', None) + 'path' (None, 'path') + """ - source_group_match = _path_leading_variable.match(input_path) - if source_group_match: + if source_group_match := _path_leading_variable.match(input_path): source_tree = source_group_match.group(1) output_path = source_group_match.group(3) # This may be None. else: @@ -200,70 +200,70 @@ def ConvertVariablesToShellSyntax(input_string): class XCObject: """The abstract base of all class types used in Xcode project files. - Class variables: - _schema: A dictionary defining the properties of this class. The keys to - _schema are string property keys as used in project files. Values - are a list of four or five elements: - [ is_list, property_type, is_strong, is_required, default ] - is_list: True if the property described is a list, as opposed - to a single element. - property_type: The type to use as the value of the property, - or if is_list is True, the type to use for each - element of the value's list. property_type must - be an XCObject subclass, or one of the built-in - types str, int, or dict. - is_strong: If property_type is an XCObject subclass, is_strong - is True to assert that this class "owns," or serves - as parent, to the property value (or, if is_list is - True, values). is_strong must be False if - property_type is not an XCObject subclass. - is_required: True if the property is required for the class. - Note that is_required being True does not preclude - an empty string ("", in the case of property_type - str) or list ([], in the case of is_list True) from - being set for the property. - default: Optional. If is_required is True, default may be set - to provide a default value for objects that do not supply - their own value. If is_required is True and default - is not provided, users of the class must supply their own - value for the property. - Note that although the values of the array are expressed in - boolean terms, subclasses provide values as integers to conserve - horizontal space. - _should_print_single_line: False in XCObject. Subclasses whose objects - should be written to the project file in the - alternate single-line format, such as - PBXFileReference and PBXBuildFile, should - set this to True. - _encode_transforms: Used by _EncodeString to encode unprintable characters. - The index into this list is the ordinal of the - character to transform; each value is a string - used to represent the character in the output. XCObject - provides an _encode_transforms list suitable for most - XCObject subclasses. - _alternate_encode_transforms: Provided for subclasses that wish to use - the alternate encoding rules. Xcode seems - to use these rules when printing objects in - single-line format. Subclasses that desire - this behavior should set _encode_transforms - to _alternate_encode_transforms. - _hashables: A list of XCObject subclasses that can be hashed by ComputeIDs - to construct this object's ID. Most classes that need custom - hashing behavior should do it by overriding Hashables, - but in some cases an object's parent may wish to push a - hashable value into its child, and it can do so by appending - to _hashables. - Attributes: - id: The object's identifier, a 24-character uppercase hexadecimal string. - Usually, objects being created should not set id until the entire - project file structure is built. At that point, UpdateIDs() should - be called on the root object to assign deterministic values for id to - each object in the tree. - parent: The object's parent. This is set by a parent XCObject when a child - object is added to it. - _properties: The object's property dictionary. An object's properties are - described by its class' _schema variable. - """ + Class variables: + _schema: A dictionary defining the properties of this class. The keys to + _schema are string property keys as used in project files. Values + are a list of four or five elements: + [ is_list, property_type, is_strong, is_required, default ] + is_list: True if the property described is a list, as opposed + to a single element. + property_type: The type to use as the value of the property, + or if is_list is True, the type to use for each + element of the value's list. property_type must + be an XCObject subclass, or one of the built-in + types str, int, or dict. + is_strong: If property_type is an XCObject subclass, is_strong + is True to assert that this class "owns," or serves + as parent, to the property value (or, if is_list is + True, values). is_strong must be False if + property_type is not an XCObject subclass. + is_required: True if the property is required for the class. + Note that is_required being True does not preclude + an empty string ("", in the case of property_type + str) or list ([], in the case of is_list True) from + being set for the property. + default: Optional. If is_required is True, default may be set + to provide a default value for objects that do not supply + their own value. If is_required is True and default + is not provided, users of the class must supply their own + value for the property. + Note that although the values of the array are expressed in + boolean terms, subclasses provide values as integers to conserve + horizontal space. + _should_print_single_line: False in XCObject. Subclasses whose objects + should be written to the project file in the + alternate single-line format, such as + PBXFileReference and PBXBuildFile, should + set this to True. + _encode_transforms: Used by _EncodeString to encode unprintable characters. + The index into this list is the ordinal of the + character to transform; each value is a string + used to represent the character in the output. XCObject + provides an _encode_transforms list suitable for most + XCObject subclasses. + _alternate_encode_transforms: Provided for subclasses that wish to use + the alternate encoding rules. Xcode seems + to use these rules when printing objects in + single-line format. Subclasses that desire + this behavior should set _encode_transforms + to _alternate_encode_transforms. + _hashables: A list of XCObject subclasses that can be hashed by ComputeIDs + to construct this object's ID. Most classes that need custom + hashing behavior should do it by overriding Hashables, + but in some cases an object's parent may wish to push a + hashable value into its child, and it can do so by appending + to _hashables. + Attributes: + id: The object's identifier, a 24-character uppercase hexadecimal string. + Usually, objects being created should not set id until the entire + project file structure is built. At that point, UpdateIDs() should + be called on the root object to assign deterministic values for id to + each object in the tree. + parent: The object's parent. This is set by a parent XCObject when a child + object is added to it. + _properties: The object's property dictionary. An object's properties are + described by its class' _schema variable. + """ _schema = {} _should_print_single_line = False @@ -305,12 +305,12 @@ def __repr__(self): def Copy(self): """Make a copy of this object. - The new object will have its own copy of lists and dicts. Any XCObject - objects owned by this object (marked "strong") will be copied in the - new object, even those found in lists. If this object has any weak - references to other XCObjects, the same references are added to the new - object without making a copy. - """ + The new object will have its own copy of lists and dicts. Any XCObject + objects owned by this object (marked "strong") will be copied in the + new object, even those found in lists. If this object has any weak + references to other XCObjects, the same references are added to the new + object without making a copy. + """ that = self.__class__(id=self.id, parent=self.parent) for key, value in self._properties.items(): @@ -359,9 +359,9 @@ def Copy(self): def Name(self): """Return the name corresponding to an object. - Not all objects necessarily need to be nameable, and not all that do have - a "name" property. Override as needed. - """ + Not all objects necessarily need to be nameable, and not all that do have + a "name" property. Override as needed. + """ # If the schema indicates that "name" is required, try to access the # property even if it doesn't exist. This will result in a KeyError @@ -377,20 +377,19 @@ def Name(self): def Comment(self): """Return a comment string for the object. - Most objects just use their name as the comment, but PBXProject uses - different values. + Most objects just use their name as the comment, but PBXProject uses + different values. - The returned comment is not escaped and does not have any comment marker - strings applied to it. - """ + The returned comment is not escaped and does not have any comment marker + strings applied to it. + """ return self.Name() def Hashables(self): hashables = [self.__class__.__name__] - name = self.Name() - if name is not None: + if (name := self.Name()) is not None: hashables.append(name) hashables.extend(self._hashables) @@ -403,26 +402,26 @@ def HashablesForChild(self): def ComputeIDs(self, recursive=True, overwrite=True, seed_hash=None): """Set "id" properties deterministically. - An object's "id" property is set based on a hash of its class type and - name, as well as the class type and name of all ancestor objects. As - such, it is only advisable to call ComputeIDs once an entire project file - tree is built. + An object's "id" property is set based on a hash of its class type and + name, as well as the class type and name of all ancestor objects. As + such, it is only advisable to call ComputeIDs once an entire project file + tree is built. - If recursive is True, recurse into all descendant objects and update their - hashes. + If recursive is True, recurse into all descendant objects and update their + hashes. - If overwrite is True, any existing value set in the "id" property will be - replaced. - """ + If overwrite is True, any existing value set in the "id" property will be + replaced. + """ def _HashUpdate(hash, data): """Update hash with data's length and contents. - If the hash were updated only with the value of data, it would be - possible for clowns to induce collisions by manipulating the names of - their objects. By adding the length, it's exceedingly less likely that - ID collisions will be encountered, intentionally or not. - """ + If the hash were updated only with the value of data, it would be + possible for clowns to induce collisions by manipulating the names of + their objects. By adding the length, it's exceedingly less likely that + ID collisions will be encountered, intentionally or not. + """ hash.update(struct.pack(">i", len(data))) if isinstance(data, str): @@ -430,7 +429,7 @@ def _HashUpdate(hash, data): hash.update(data) if seed_hash is None: - seed_hash = hashlib.sha1() + seed_hash = hashlib.sha256() hash = seed_hash.copy() @@ -460,13 +459,12 @@ def _HashUpdate(hash, data): digest_int_count = hash.digest_size // 4 digest_ints = struct.unpack(">" + "I" * digest_int_count, hash.digest()) id_ints = [0, 0, 0] - for index in range(0, digest_int_count): + for index in range(digest_int_count): id_ints[index % 3] ^= digest_ints[index] self.id = "%08X%08X%08X" % tuple(id_ints) def EnsureNoIDCollisions(self): - """Verifies that no two objects have the same ID. Checks all descendants. - """ + """Verifies that no two objects have the same ID. Checks all descendants.""" ids = {} descendants = self.Descendants() @@ -489,7 +487,7 @@ def Children(self): children = [] for property, attributes in self._schema.items(): - (is_list, property_type, is_strong) = attributes[0:3] + (is_list, _property_type, is_strong) = attributes[0:3] if is_strong and property in self._properties: if not is_list: children.append(self._properties[property]) @@ -499,8 +497,8 @@ def Children(self): def Descendants(self): """Returns a list of all of this object's descendants, including this - object. - """ + object. + """ children = self.Children() descendants = [self] @@ -516,8 +514,8 @@ def PBXProjectAncestor(self): def _EncodeComment(self, comment): """Encodes a comment to be placed in the project file output, mimicking - Xcode behavior. - """ + Xcode behavior. + """ # This mimics Xcode behavior by wrapping the comment in "/*" and "*/". If # the string already contains a "*/", it is turned into "(*)/". This keeps @@ -544,8 +542,8 @@ def _EncodeTransform(self, match): def _EncodeString(self, value): """Encodes a string to be placed in the project file output, mimicking - Xcode behavior. - """ + Xcode behavior. + """ # Use quotation marks when any character outside of the range A-Z, a-z, 0-9, # $ (dollar sign), . (period), and _ (underscore) is present. Also use @@ -586,18 +584,18 @@ def _XCPrint(self, file, tabs, line): def _XCPrintableValue(self, tabs, value, flatten_list=False): """Returns a representation of value that may be printed in a project file, - mimicking Xcode's behavior. + mimicking Xcode's behavior. - _XCPrintableValue can handle str and int values, XCObjects (which are - made printable by returning their id property), and list and dict objects - composed of any of the above types. When printing a list or dict, and - _should_print_single_line is False, the tabs parameter is used to determine - how much to indent the lines corresponding to the items in the list or - dict. + _XCPrintableValue can handle str and int values, XCObjects (which are + made printable by returning their id property), and list and dict objects + composed of any of the above types. When printing a list or dict, and + _should_print_single_line is False, the tabs parameter is used to determine + how much to indent the lines corresponding to the items in the list or + dict. - If flatten_list is True, single-element lists will be transformed into - strings. - """ + If flatten_list is True, single-element lists will be transformed into + strings. + """ printable = "" comment = None @@ -658,12 +656,12 @@ def _XCPrintableValue(self, tabs, value, flatten_list=False): def _XCKVPrint(self, file, tabs, key, value): """Prints a key and value, members of an XCObject's _properties dictionary, - to file. + to file. - tabs is an int identifying the indentation level. If the class' - _should_print_single_line variable is True, tabs is ignored and the - key-value pair will be followed by a space insead of a newline. - """ + tabs is an int identifying the indentation level. If the class' + _should_print_single_line variable is True, tabs is ignored and the + key-value pair will be followed by a space instead of a newline. + """ if self._should_print_single_line: printable = "" @@ -721,8 +719,8 @@ def _XCKVPrint(self, file, tabs, key, value): def Print(self, file=sys.stdout): """Prints a reprentation of this object to file, adhering to Xcode output - formatting. - """ + formatting. + """ self.VerifyHasRequiredProperties() @@ -760,15 +758,15 @@ def Print(self, file=sys.stdout): def UpdateProperties(self, properties, do_copy=False): """Merge the supplied properties into the _properties dictionary. - The input properties must adhere to the class schema or a KeyError or - TypeError exception will be raised. If adding an object of an XCObject - subclass and the schema indicates a strong relationship, the object's - parent will be set to this object. + The input properties must adhere to the class schema or a KeyError or + TypeError exception will be raised. If adding an object of an XCObject + subclass and the schema indicates a strong relationship, the object's + parent will be set to this object. - If do_copy is True, then lists, dicts, strong-owned XCObjects, and - strong-owned XCObjects in lists will be copied instead of having their - references added. - """ + If do_copy is True, then lists, dicts, strong-owned XCObjects, and + strong-owned XCObjects in lists will be copied instead of having their + references added. + """ if properties is None: return @@ -781,7 +779,7 @@ def UpdateProperties(self, properties, do_copy=False): # Make sure the property conforms to the schema. (is_list, property_type, is_strong) = self._schema[property][0:3] if is_list: - if value.__class__ != list: + if not isinstance(value, list): raise TypeError( property + " of " @@ -791,7 +789,7 @@ def UpdateProperties(self, properties, do_copy=False): ) for item in value: if not isinstance(item, property_type) and not ( - isinstance(item, str) and property_type == str + isinstance(item, str) and isinstance(property_type, str) ): # Accept unicode where str is specified. str is treated as # UTF-8-encoded. @@ -806,7 +804,7 @@ def UpdateProperties(self, properties, do_copy=False): + item.__class__.__name__ ) elif not isinstance(value, property_type) and not ( - isinstance(value, str) and property_type == str + isinstance(value, str) and isinstance(property_type, str) ): # Accept unicode where str is specified. str is treated as # UTF-8-encoded. @@ -909,23 +907,23 @@ def AppendProperty(self, key, value): def VerifyHasRequiredProperties(self): """Ensure that all properties identified as required by the schema are - set. - """ + set. + """ # TODO(mark): A stronger verification mechanism is needed. Some # subclasses need to perform validation beyond what the schema can enforce. for property, attributes in self._schema.items(): - (is_list, property_type, is_strong, is_required) = attributes[0:4] + (_is_list, _property_type, _is_strong, is_required) = attributes[0:4] if is_required and property not in self._properties: raise KeyError(self.__class__.__name__ + " requires " + property) def _SetDefaultsFromSchema(self): """Assign object default values according to the schema. This will not - overwrite properties that have already been set.""" + overwrite properties that have already been set.""" defaults = {} for property, attributes in self._schema.items(): - (is_list, property_type, is_strong, is_required) = attributes[0:4] + (_is_list, _property_type, _is_strong, is_required) = attributes[0:4] if ( is_required and len(attributes) >= 5 @@ -943,7 +941,7 @@ def _SetDefaultsFromSchema(self): class XCHierarchicalElement(XCObject): """Abstract base for PBXGroup and PBXFileReference. Not represented in a - project file.""" + project file.""" # TODO(mark): Do name and path belong here? Probably so. # If path is set and name is not, name may have a default value. Name will @@ -971,7 +969,7 @@ def __init__(self, properties=None, id=None, parent=None): if "path" in self._properties and "name" not in self._properties: path = self._properties["path"] name = posixpath.basename(path) - if name != "" and path != name: + if name not in ("", path): self.SetProperty("name", name) if "path" in self._properties and ( @@ -1009,27 +1007,27 @@ def Name(self): def Hashables(self): """Custom hashables for XCHierarchicalElements. - XCHierarchicalElements are special. Generally, their hashes shouldn't - change if the paths don't change. The normal XCObject implementation of - Hashables adds a hashable for each object, which means that if - the hierarchical structure changes (possibly due to changes caused when - TakeOverOnlyChild runs and encounters slight changes in the hierarchy), - the hashes will change. For example, if a project file initially contains - a/b/f1 and a/b becomes collapsed into a/b, f1 will have a single parent - a/b. If someone later adds a/f2 to the project file, a/b can no longer be - collapsed, and f1 winds up with parent b and grandparent a. That would - be sufficient to change f1's hash. - - To counteract this problem, hashables for all XCHierarchicalElements except - for the main group (which has neither a name nor a path) are taken to be - just the set of path components. Because hashables are inherited from - parents, this provides assurance that a/b/f1 has the same set of hashables - whether its parent is b or a/b. - - The main group is a special case. As it is permitted to have no name or - path, it is permitted to use the standard XCObject hash mechanism. This - is not considered a problem because there can be only one main group. - """ + XCHierarchicalElements are special. Generally, their hashes shouldn't + change if the paths don't change. The normal XCObject implementation of + Hashables adds a hashable for each object, which means that if + the hierarchical structure changes (possibly due to changes caused when + TakeOverOnlyChild runs and encounters slight changes in the hierarchy), + the hashes will change. For example, if a project file initially contains + a/b/f1 and a/b becomes collapsed into a/b, f1 will have a single parent + a/b. If someone later adds a/f2 to the project file, a/b can no longer be + collapsed, and f1 winds up with parent b and grandparent a. That would + be sufficient to change f1's hash. + + To counteract this problem, hashables for all XCHierarchicalElements except + for the main group (which has neither a name nor a path) are taken to be + just the set of path components. Because hashables are inherited from + parents, this provides assurance that a/b/f1 has the same set of hashables + whether its parent is b or a/b. + + The main group is a special case. As it is permitted to have no name or + path, it is permitted to use the standard XCObject hash mechanism. This + is not considered a problem because there can be only one main group. + """ if self == self.PBXProjectAncestor()._properties["mainGroup"]: # super @@ -1050,8 +1048,7 @@ def Hashables(self): # including paths with a sourceTree, they'll still inherit their parents' # hashables, even though the paths aren't relative to their parents. This # is not expected to be much of a problem in practice. - path = self.PathFromSourceTreeAndPath() - if path is not None: + if (path := self.PathFromSourceTreeAndPath()) is not None: components = path.split(posixpath.sep) for component in components: hashables.append(self.__class__.__name__ + ".path") @@ -1159,12 +1156,12 @@ def FullPath(self): class PBXGroup(XCHierarchicalElement): """ - Attributes: - _children_by_path: Maps pathnames of children of this PBXGroup to the - actual child XCHierarchicalElement objects. - _variant_children_by_name_and_path: Maps (name, path) tuples of - PBXVariantGroup children to the actual child PBXVariantGroup objects. - """ + Attributes: + _children_by_path: Maps pathnames of children of this PBXGroup to the + actual child XCHierarchicalElement objects. + _variant_children_by_name_and_path: Maps (name, path) tuples of + PBXVariantGroup children to the actual child PBXVariantGroup objects. + """ _schema = XCHierarchicalElement._schema.copy() _schema.update( @@ -1283,20 +1280,20 @@ def GetChildByRemoteObject(self, remote_object): def AddOrGetFileByPath(self, path, hierarchical): """Returns an existing or new file reference corresponding to path. - If hierarchical is True, this method will create or use the necessary - hierarchical group structure corresponding to path. Otherwise, it will - look in and create an item in the current group only. + If hierarchical is True, this method will create or use the necessary + hierarchical group structure corresponding to path. Otherwise, it will + look in and create an item in the current group only. - If an existing matching reference is found, it is returned, otherwise, a - new one will be created, added to the correct group, and returned. + If an existing matching reference is found, it is returned, otherwise, a + new one will be created, added to the correct group, and returned. - If path identifies a directory by virtue of carrying a trailing slash, - this method returns a PBXFileReference of "folder" type. If path - identifies a variant, by virtue of it identifying a file inside a directory - with an ".lproj" extension, this method returns a PBXVariantGroup - containing the variant named by path, and possibly other variants. For - all other paths, a "normal" PBXFileReference will be returned. - """ + If path identifies a directory by virtue of carrying a trailing slash, + this method returns a PBXFileReference of "folder" type. If path + identifies a variant, by virtue of it identifying a file inside a directory + with an ".lproj" extension, this method returns a PBXVariantGroup + containing the variant named by path, and possibly other variants. For + all other paths, a "normal" PBXFileReference will be returned. + """ # Adding or getting a directory? Directories end with a trailing slash. is_dir = False @@ -1381,15 +1378,15 @@ def AddOrGetFileByPath(self, path, hierarchical): def AddOrGetVariantGroupByNameAndPath(self, name, path): """Returns an existing or new PBXVariantGroup for name and path. - If a PBXVariantGroup identified by the name and path arguments is already - present as a child of this object, it is returned. Otherwise, a new - PBXVariantGroup with the correct properties is created, added as a child, - and returned. + If a PBXVariantGroup identified by the name and path arguments is already + present as a child of this object, it is returned. Otherwise, a new + PBXVariantGroup with the correct properties is created, added as a child, + and returned. - This method will generally be called by AddOrGetFileByPath, which knows - when to create a variant group based on the structure of the pathnames - passed to it. - """ + This method will generally be called by AddOrGetFileByPath, which knows + when to create a variant group based on the structure of the pathnames + passed to it. + """ key = (name, path) if key in self._variant_children_by_name_and_path: @@ -1407,19 +1404,19 @@ def AddOrGetVariantGroupByNameAndPath(self, name, path): def TakeOverOnlyChild(self, recurse=False): """If this PBXGroup has only one child and it's also a PBXGroup, take - it over by making all of its children this object's children. - - This function will continue to take over only children when those children - are groups. If there are three PBXGroups representing a, b, and c, with - c inside b and b inside a, and a and b have no other children, this will - result in a taking over both b and c, forming a PBXGroup for a/b/c. - - If recurse is True, this function will recurse into children and ask them - to collapse themselves by taking over only children as well. Assuming - an example hierarchy with files at a/b/c/d1, a/b/c/d2, and a/b/c/d3/e/f - (d1, d2, and f are files, the rest are groups), recursion will result in - a group for a/b/c containing a group for d3/e. - """ + it over by making all of its children this object's children. + + This function will continue to take over only children when those children + are groups. If there are three PBXGroups representing a, b, and c, with + c inside b and b inside a, and a and b have no other children, this will + result in a taking over both b and c, forming a PBXGroup for a/b/c. + + If recurse is True, this function will recurse into children and ask them + to collapse themselves by taking over only children as well. Assuming + an example hierarchy with files at a/b/c/d1, a/b/c/d2, and a/b/c/d3/e/f + (d1, d2, and f are files, the rest are groups), recursion will result in + a group for a/b/c containing a group for d3/e. + """ # At this stage, check that child class types are PBXGroup exactly, # instead of using isinstance. The only subclass of PBXGroup, @@ -1619,7 +1616,7 @@ def __init__(self, properties=None, id=None, parent=None): prop_name = "lastKnownFileType" else: basename = posixpath.basename(self._properties["path"]) - (root, ext) = posixpath.splitext(basename) + (_root, ext) = posixpath.splitext(basename) # Check the map using a lowercase extension. # TODO(mark): Maybe it should try with the original case first and fall # back to lowercase, in case there are any instances where case @@ -1640,7 +1637,6 @@ class PBXVariantGroup(PBXGroup, XCFileLikeElement): """PBXVariantGroup is used by Xcode to represent localizations.""" # No additions to the schema relative to PBXGroup. - pass # PBXReferenceProxy is also an XCFileLikeElement subclass. It is defined below @@ -1719,16 +1715,16 @@ def DefaultConfiguration(self): def HasBuildSetting(self, key): """Determines the state of a build setting in all XCBuildConfiguration - child objects. + child objects. - If all child objects have key in their build settings, and the value is the - same in all child objects, returns 1. + If all child objects have key in their build settings, and the value is the + same in all child objects, returns 1. - If no child objects have the key in their build settings, returns 0. + If no child objects have the key in their build settings, returns 0. - If some, but not all, child objects have the key in their build settings, - or if any children have different values for the key, returns -1. - """ + If some, but not all, child objects have the key in their build settings, + or if any children have different values for the key, returns -1. + """ has = None value = None @@ -1754,9 +1750,9 @@ def HasBuildSetting(self, key): def GetBuildSetting(self, key): """Gets the build setting for key. - All child XCConfiguration objects must have the same value set for the - setting, or a ValueError will be raised. - """ + All child XCConfiguration objects must have the same value set for the + setting, or a ValueError will be raised. + """ # TODO(mark): This is wrong for build settings that are lists. The list # contents should be compared (and a list copy returned?) @@ -1766,39 +1762,37 @@ def GetBuildSetting(self, key): configuration_value = configuration.GetBuildSetting(key) if value is None: value = configuration_value - else: - if value != configuration_value: - raise ValueError("Variant values for " + key) + elif value != configuration_value: + raise ValueError("Variant values for " + key) return value def SetBuildSetting(self, key, value): """Sets the build setting for key to value in all child - XCBuildConfiguration objects. - """ + XCBuildConfiguration objects. + """ for configuration in self._properties["buildConfigurations"]: configuration.SetBuildSetting(key, value) def AppendBuildSetting(self, key, value): """Appends value to the build setting for key, which is treated as a list, - in all child XCBuildConfiguration objects. - """ + in all child XCBuildConfiguration objects. + """ for configuration in self._properties["buildConfigurations"]: configuration.AppendBuildSetting(key, value) def DelBuildSetting(self, key): """Deletes the build setting key from all child XCBuildConfiguration - objects. - """ + objects. + """ for configuration in self._properties["buildConfigurations"]: configuration.DelBuildSetting(key) def SetBaseConfiguration(self, value): - """Sets the build configuration in all child XCBuildConfiguration objects. - """ + """Sets the build configuration in all child XCBuildConfiguration objects.""" for configuration in self._properties["buildConfigurations"]: configuration.SetBaseConfiguration(value) @@ -1838,14 +1832,14 @@ def Hashables(self): class XCBuildPhase(XCObject): """Abstract base for build phase classes. Not represented in a project - file. + file. - Attributes: - _files_by_path: A dict mapping each path of a child in the files list by - path (keys) to the corresponding PBXBuildFile children (values). - _files_by_xcfilelikeelement: A dict mapping each XCFileLikeElement (keys) - to the corresponding PBXBuildFile children (values). - """ + Attributes: + _files_by_path: A dict mapping each path of a child in the files list by + path (keys) to the corresponding PBXBuildFile children (values). + _files_by_xcfilelikeelement: A dict mapping each XCFileLikeElement (keys) + to the corresponding PBXBuildFile children (values). + """ # TODO(mark): Some build phase types, like PBXShellScriptBuildPhase, don't # actually have a "files" list. XCBuildPhase should not have "files" but @@ -1884,8 +1878,8 @@ def FileGroup(self, path): def _AddPathToDict(self, pbxbuildfile, path): """Adds path to the dict tracking paths belonging to this build phase. - If the path is already a member of this build phase, raises an exception. - """ + If the path is already a member of this build phase, raises an exception. + """ if path in self._files_by_path: raise ValueError("Found multiple build files with path " + path) @@ -1894,28 +1888,28 @@ def _AddPathToDict(self, pbxbuildfile, path): def _AddBuildFileToDicts(self, pbxbuildfile, path=None): """Maintains the _files_by_path and _files_by_xcfilelikeelement dicts. - If path is specified, then it is the path that is being added to the - phase, and pbxbuildfile must contain either a PBXFileReference directly - referencing that path, or it must contain a PBXVariantGroup that itself - contains a PBXFileReference referencing the path. - - If path is not specified, either the PBXFileReference's path or the paths - of all children of the PBXVariantGroup are taken as being added to the - phase. - - If the path is already present in the phase, raises an exception. - - If the PBXFileReference or PBXVariantGroup referenced by pbxbuildfile - are already present in the phase, referenced by a different PBXBuildFile - object, raises an exception. This does not raise an exception when - a PBXFileReference or PBXVariantGroup reappear and are referenced by the - same PBXBuildFile that has already introduced them, because in the case - of PBXVariantGroup objects, they may correspond to multiple paths that are - not all added simultaneously. When this situation occurs, the path needs - to be added to _files_by_path, but nothing needs to change in - _files_by_xcfilelikeelement, and the caller should have avoided adding - the PBXBuildFile if it is already present in the list of children. - """ + If path is specified, then it is the path that is being added to the + phase, and pbxbuildfile must contain either a PBXFileReference directly + referencing that path, or it must contain a PBXVariantGroup that itself + contains a PBXFileReference referencing the path. + + If path is not specified, either the PBXFileReference's path or the paths + of all children of the PBXVariantGroup are taken as being added to the + phase. + + If the path is already present in the phase, raises an exception. + + If the PBXFileReference or PBXVariantGroup referenced by pbxbuildfile + are already present in the phase, referenced by a different PBXBuildFile + object, raises an exception. This does not raise an exception when + a PBXFileReference or PBXVariantGroup reappear and are referenced by the + same PBXBuildFile that has already introduced them, because in the case + of PBXVariantGroup objects, they may correspond to multiple paths that are + not all added simultaneously. When this situation occurs, the path needs + to be added to _files_by_path, but nothing needs to change in + _files_by_xcfilelikeelement, and the caller should have avoided adding + the PBXBuildFile if it is already present in the list of children. + """ xcfilelikeelement = pbxbuildfile._properties["fileRef"] @@ -1924,14 +1918,13 @@ def _AddBuildFileToDicts(self, pbxbuildfile, path=None): # It's best when the caller provides the path. if isinstance(xcfilelikeelement, PBXVariantGroup): paths.append(path) + # If the caller didn't provide a path, there can be either multiple + # paths (PBXVariantGroup) or one. + elif isinstance(xcfilelikeelement, PBXVariantGroup): + for variant in xcfilelikeelement._properties["children"]: + paths.append(variant.FullPath()) else: - # If the caller didn't provide a path, there can be either multiple - # paths (PBXVariantGroup) or one. - if isinstance(xcfilelikeelement, PBXVariantGroup): - for variant in xcfilelikeelement._properties["children"]: - paths.append(variant.FullPath()) - else: - paths.append(xcfilelikeelement.FullPath()) + paths.append(xcfilelikeelement.FullPath()) # Add the paths first, because if something's going to raise, the # messages provided by _AddPathToDict are more useful owing to its @@ -2017,7 +2010,7 @@ def Name(self): return "Frameworks" def FileGroup(self, path): - (root, ext) = posixpath.splitext(path) + (_root, ext) = posixpath.splitext(path) if ext != "": ext = ext[1:].lower() if ext == "o": @@ -2107,12 +2100,11 @@ def FileGroup(self, path): def SetDestination(self, path): """Set the dstSubfolderSpec and dstPath properties from path. - path may be specified in the same notation used for XCHierarchicalElements, - specifically, "$(DIR)/path". - """ + path may be specified in the same notation used for XCHierarchicalElements, + specifically, "$(DIR)/path". + """ - path_tree_match = self.path_tree_re.search(path) - if path_tree_match: + if path_tree_match := self.path_tree_re.search(path): path_tree = path_tree_match.group(1) if path_tree in self.path_tree_first_to_subfolder: subfolder = self.path_tree_first_to_subfolder[path_tree] @@ -2184,9 +2176,7 @@ def SetDestination(self, path): subfolder = 0 relative_path = path[1:] else: - raise ValueError( - f"Can't use path {path} in a {self.__class__.__name__}" - ) + raise ValueError(f"Can't use path {path} in a {self.__class__.__name__}") self._properties["dstPath"] = relative_path self._properties["dstSubfolderSpec"] = subfolder @@ -2355,9 +2345,8 @@ def __init__( # property was supplied, set "productName" if it is not present. Also set # the "PRODUCT_NAME" build setting in each configuration, but only if # the setting is not present in any build configuration. - if "name" in self._properties: - if "productName" not in self._properties: - self.SetProperty("productName", self._properties["name"]) + if "name" in self._properties and "productName" not in self._properties: + self.SetProperty("productName", self._properties["name"]) if "productName" in self._properties: if "buildConfigurationList" in self._properties: @@ -2537,9 +2526,9 @@ def __init__( # loadable modules, but there's precedent: Python loadable modules on # Mac OS X use an .so extension. if self._properties["productType"] == "com.googlecode.gyp.xcode.bundle": - self._properties[ - "productType" - ] = "com.apple.product-type.library.dynamic" + self._properties["productType"] = ( + "com.apple.product-type.library.dynamic" + ) self.SetBuildSetting("MACH_O_TYPE", "mh_bundle") self.SetBuildSetting("DYLIB_CURRENT_VERSION", "") self.SetBuildSetting("DYLIB_COMPATIBILITY_VERSION", "") @@ -2548,12 +2537,12 @@ def __init__( if ( self._properties["productType"] - == "com.apple.product-type-bundle.unit.test" - or self._properties["productType"] - == "com.apple.product-type-bundle.ui-testing" - ): - if force_extension is None: - force_extension = suffix[1:] + in { + "com.apple.product-type-bundle.unit.test", + "com.apple.product-type-bundle.ui-testing", + } + ) and force_extension is None: + force_extension = suffix[1:] if force_extension is not None: # If it's a wrapper (bundle), set WRAPPER_EXTENSION. @@ -2636,10 +2625,13 @@ def HeadersPhase(self): # frameworks phases, if any. insert_at = len(self._properties["buildPhases"]) for index, phase in enumerate(self._properties["buildPhases"]): - if ( - isinstance(phase, PBXResourcesBuildPhase) - or isinstance(phase, PBXSourcesBuildPhase) - or isinstance(phase, PBXFrameworksBuildPhase) + if isinstance( + phase, + ( + PBXResourcesBuildPhase, + PBXSourcesBuildPhase, + PBXFrameworksBuildPhase, + ), ): insert_at = index break @@ -2658,9 +2650,7 @@ def ResourcesPhase(self): # phases, if any. insert_at = len(self._properties["buildPhases"]) for index, phase in enumerate(self._properties["buildPhases"]): - if isinstance(phase, PBXSourcesBuildPhase) or isinstance( - phase, PBXFrameworksBuildPhase - ): + if isinstance(phase, (PBXSourcesBuildPhase, PBXFrameworksBuildPhase)): insert_at = index break @@ -2701,8 +2691,8 @@ def AddDependency(self, other): other._properties["productType"] == static_library_type or ( ( - other._properties["productType"] == shared_library_type - or other._properties["productType"] == framework_type + other._properties["productType"] + in {shared_library_type, framework_type} ) and ( (not other.HasBuildSetting("MACH_O_TYPE")) @@ -2711,7 +2701,6 @@ def AddDependency(self, other): ) ) ): - file_ref = other.GetProperty("productReference") pbxproject = self.PBXProjectAncestor() @@ -2737,13 +2726,13 @@ class PBXProject(XCContainerPortal): # PBXContainerItemProxy. """ - Attributes: - path: "sample.xcodeproj". TODO(mark) Document me! - _other_pbxprojects: A dictionary, keyed by other PBXProject objects. Each - value is a reference to the dict in the - projectReferences list associated with the keyed - PBXProject. - """ + Attributes: + path: "sample.xcodeproj". TODO(mark) Document me! + _other_pbxprojects: A dictionary, keyed by other PBXProject objects. Each + value is a reference to the dict in the + projectReferences list associated with the keyed + PBXProject. + """ _schema = XCContainerPortal._schema.copy() _schema.update( @@ -2770,7 +2759,7 @@ def __init__(self, properties=None, id=None, parent=None, path=None): self.path = path self._other_pbxprojects = {} # super - return XCContainerPortal.__init__(self, properties, id, parent) + XCContainerPortal.__init__(self, properties, id, parent) def Name(self): name = self.path @@ -2838,17 +2827,17 @@ def ProjectsGroup(self): def RootGroupForPath(self, path): """Returns a PBXGroup child of this object to which path should be added. - This method is intended to choose between SourceGroup and - IntermediatesGroup on the basis of whether path is present in a source - directory or an intermediates directory. For the purposes of this - determination, any path located within a derived file directory such as - PROJECT_DERIVED_FILE_DIR is treated as being in an intermediates - directory. + This method is intended to choose between SourceGroup and + IntermediatesGroup on the basis of whether path is present in a source + directory or an intermediates directory. For the purposes of this + determination, any path located within a derived file directory such as + PROJECT_DERIVED_FILE_DIR is treated as being in an intermediates + directory. - The returned value is a two-element tuple. The first element is the - PBXGroup, and the second element specifies whether that group should be - organized hierarchically (True) or as a single flat list (False). - """ + The returned value is a two-element tuple. The first element is the + PBXGroup, and the second element specifies whether that group should be + organized hierarchically (True) or as a single flat list (False). + """ # TODO(mark): make this a class variable and bind to self on call? # Also, this list is nowhere near exhaustive. @@ -2874,11 +2863,11 @@ def RootGroupForPath(self, path): def AddOrGetFileInRootGroup(self, path): """Returns a PBXFileReference corresponding to path in the correct group - according to RootGroupForPath's heuristics. + according to RootGroupForPath's heuristics. - If an existing PBXFileReference for path exists, it will be returned. - Otherwise, one will be created and returned. - """ + If an existing PBXFileReference for path exists, it will be returned. + Otherwise, one will be created and returned. + """ (group, hierarchical) = self.RootGroupForPath(path) return group.AddOrGetFileByPath(path, hierarchical) @@ -2928,17 +2917,17 @@ def SortGroups(self): def AddOrGetProjectReference(self, other_pbxproject): """Add a reference to another project file (via PBXProject object) to this - one. + one. - Returns [ProductGroup, ProjectRef]. ProductGroup is a PBXGroup object in - this project file that contains a PBXReferenceProxy object for each - product of each PBXNativeTarget in the other project file. ProjectRef is - a PBXFileReference to the other project file. + Returns [ProductGroup, ProjectRef]. ProductGroup is a PBXGroup object in + this project file that contains a PBXReferenceProxy object for each + product of each PBXNativeTarget in the other project file. ProjectRef is + a PBXFileReference to the other project file. - If this project file already references the other project file, the - existing ProductGroup and ProjectRef are returned. The ProductGroup will - still be updated if necessary. - """ + If this project file already references the other project file, the + existing ProductGroup and ProjectRef are returned. The ProductGroup will + still be updated if necessary. + """ if "projectReferences" not in self._properties: self._properties["projectReferences"] = [] @@ -2990,10 +2979,10 @@ def AddOrGetProjectReference(self, other_pbxproject): # Xcode seems to sort this list case-insensitively self._properties["projectReferences"] = sorted( self._properties["projectReferences"], - key=lambda x: x["ProjectRef"].Name().lower + key=lambda x: x["ProjectRef"].Name().lower(), ) else: - # The link already exists. Pull out the relevnt data. + # The link already exists. Pull out the relevant data. project_ref_dict = self._other_pbxprojects[other_pbxproject] product_group = project_ref_dict["ProductGroup"] project_ref = project_ref_dict["ProjectRef"] @@ -3015,11 +3004,8 @@ def _AllSymrootsUnique(self, target, inherit_unique_symroot): # define an explicit value for 'SYMROOT'. symroots = self._DefinedSymroots(target) for s in self._DefinedSymroots(target): - if ( - s is not None - and not self._IsUniqueSymrootForTarget(s) - or s is None - and not inherit_unique_symroot + if (s is not None and not self._IsUniqueSymrootForTarget(s)) or ( + s is None and not inherit_unique_symroot ): return False return True if symroots else inherit_unique_symroot @@ -3123,7 +3109,8 @@ def CompareProducts(x, y, remote_products): product_group._properties["children"] = sorted( product_group._properties["children"], key=cmp_to_key( - lambda x, y, rp=remote_products: CompareProducts(x, y, rp)), + lambda x, y, rp=remote_products: CompareProducts(x, y, rp) + ), ) @@ -3157,9 +3144,7 @@ def Print(self, file=sys.stdout): self._XCPrint(file, 0, "{ ") else: self._XCPrint(file, 0, "{\n") - for property, value in sorted( - self._properties.items() - ): + for property, value in sorted(self._properties.items()): if property == "objects": self._PrintObjects(file) else: @@ -3185,9 +3170,7 @@ def _PrintObjects(self, file): for class_name in sorted(objects_by_class): self._XCPrint(file, 0, "\n") self._XCPrint(file, 0, "/* Begin " + class_name + " section */\n") - for object in sorted( - objects_by_class[class_name], key=attrgetter("id") - ): + for object in sorted(objects_by_class[class_name], key=attrgetter("id")): object.Print(file) self._XCPrint(file, 0, "/* End " + class_name + " section */\n") diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py b/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py index 530196366946d..d7e3b5a95604f 100644 --- a/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +++ b/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py @@ -9,7 +9,6 @@ TODO(bradnelson): Consider dropping this when we drop XP support. """ - import xml.dom.minidom diff --git a/node_modules/node-gyp/gyp/pylib/packaging/LICENSE b/node_modules/node-gyp/gyp/pylib/packaging/LICENSE new file mode 100644 index 0000000000000..6f62d44e4ef73 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/LICENSE @@ -0,0 +1,3 @@ +This software is made available under the terms of *either* of the licenses +found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made +under the terms of *both* these licenses. diff --git a/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.APACHE b/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.APACHE new file mode 100644 index 0000000000000..f433b1a53f5b8 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.BSD b/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.BSD new file mode 100644 index 0000000000000..42ce7b75c92fb --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/LICENSE.BSD @@ -0,0 +1,23 @@ +Copyright (c) Donald Stufft and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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/node_modules/node-gyp/gyp/pylib/packaging/__init__.py b/node_modules/node-gyp/gyp/pylib/packaging/__init__.py new file mode 100644 index 0000000000000..5fd91838316fb --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/__init__.py @@ -0,0 +1,15 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "23.3.dev0" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD-2-Clause or Apache-2.0" +__copyright__ = "2014 %s" % __author__ diff --git a/node_modules/node-gyp/gyp/pylib/packaging/_elffile.py b/node_modules/node-gyp/gyp/pylib/packaging/_elffile.py new file mode 100644 index 0000000000000..cb33e10556ba1 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/_elffile.py @@ -0,0 +1,107 @@ +""" +ELF file parser. + +This provides a class ``ELFFile`` that parses an ELF executable in a similar +interface to ``ZipFile``. Only the read interface is implemented. + +Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca +ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html +""" + +import enum +import os +import struct +from typing import IO, Optional, Tuple + + +class ELFInvalid(ValueError): + pass + + +class EIClass(enum.IntEnum): + C32 = 1 + C64 = 2 + + +class EIData(enum.IntEnum): + Lsb = 1 + Msb = 2 + + +class EMachine(enum.IntEnum): + I386 = 3 + S390 = 22 + Arm = 40 + X8664 = 62 + AArc64 = 183 + + +class ELFFile: + """ + Representation of an ELF executable. + """ + + def __init__(self, f: IO[bytes]) -> None: + self._f = f + + try: + ident = self._read("16B") + except struct.error: + raise ELFInvalid("unable to parse identification") + if (magic := bytes(ident[:4])) != b"\x7fELF": + raise ELFInvalid(f"invalid magic: {magic!r}") + + self.capacity = ident[4] # Format for program header (bitness). + self.encoding = ident[5] # Data structure encoding (endianness). + + try: + # e_fmt: Format for program header. + # p_fmt: Format for section header. + # p_idx: Indexes to find p_type, p_offset, and p_filesz. + e_fmt, self._p_fmt, self._p_idx = { + (1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)), # 32-bit LSB. + (1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB. + (2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)), # 64-bit LSB. + (2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB. + }[(self.capacity, self.encoding)] + except KeyError: + raise ELFInvalid( + f"unrecognized capacity ({self.capacity}) or " + f"encoding ({self.encoding})" + ) + + try: + ( + _, + self.machine, # Architecture type. + _, + _, + self._e_phoff, # Offset of program header. + _, + self.flags, # Processor-specific flags. + _, + self._e_phentsize, # Size of section. + self._e_phnum, # Number of sections. + ) = self._read(e_fmt) + except struct.error as e: + raise ELFInvalid("unable to parse machine and section information") from e + + def _read(self, fmt: str) -> Tuple[int, ...]: + return struct.unpack(fmt, self._f.read(struct.calcsize(fmt))) + + @property + def interpreter(self) -> Optional[str]: + """ + The path recorded in the ``PT_INTERP`` section header. + """ + for index in range(self._e_phnum): + self._f.seek(self._e_phoff + self._e_phentsize * index) + try: + data = self._read(self._p_fmt) + except struct.error: + continue + if data[self._p_idx[0]] != 3: # Not PT_INTERP. + continue + self._f.seek(data[self._p_idx[1]]) + return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0") + return None diff --git a/node_modules/node-gyp/gyp/pylib/packaging/_manylinux.py b/node_modules/node-gyp/gyp/pylib/packaging/_manylinux.py new file mode 100644 index 0000000000000..3705d50db9193 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/_manylinux.py @@ -0,0 +1,252 @@ +import collections +import contextlib +import functools +import os +import re +import sys +import warnings +from typing import Dict, Generator, Iterator, NamedTuple, Optional, Sequence, Tuple + +from ._elffile import EIClass, EIData, ELFFile, EMachine + +EF_ARM_ABIMASK = 0xFF000000 +EF_ARM_ABI_VER5 = 0x05000000 +EF_ARM_ABI_FLOAT_HARD = 0x00000400 + + +# `os.PathLike` not a generic type until Python 3.9, so sticking with `str` +# as the type for `path` until then. +@contextlib.contextmanager +def _parse_elf(path: str) -> Generator[Optional[ELFFile], None, None]: + try: + with open(path, "rb") as f: + yield ELFFile(f) + except (OSError, TypeError, ValueError): + yield None + + +def _is_linux_armhf(executable: str) -> bool: + # hard-float ABI can be detected from the ELF header of the running + # process + # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf + with _parse_elf(executable) as f: + return ( + f is not None + and f.capacity == EIClass.C32 + and f.encoding == EIData.Lsb + and f.machine == EMachine.Arm + and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5 + and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD + ) + + +def _is_linux_i686(executable: str) -> bool: + with _parse_elf(executable) as f: + return ( + f is not None + and f.capacity == EIClass.C32 + and f.encoding == EIData.Lsb + and f.machine == EMachine.I386 + ) + + +def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool: + if "armv7l" in archs: + return _is_linux_armhf(executable) + if "i686" in archs: + return _is_linux_i686(executable) + allowed_archs = {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x", "loongarch64"} + return any(arch in allowed_archs for arch in archs) + + +# If glibc ever changes its major version, we need to know what the last +# minor version was, so we can build the complete list of all versions. +# For now, guess what the highest minor version might be, assume it will +# be 50 for testing. Once this actually happens, update the dictionary +# with the actual value. +_LAST_GLIBC_MINOR: Dict[int, int] = collections.defaultdict(lambda: 50) + + +class _GLibCVersion(NamedTuple): + major: int + minor: int + + +def _glibc_version_string_confstr() -> Optional[str]: + """ + Primary implementation of glibc_version_string using os.confstr. + """ + # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely + # to be broken or missing. This strategy is used in the standard library + # platform module. + # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183 + try: + # Should be a string like "glibc 2.17". + version_string: str = getattr(os, "confstr")("CS_GNU_LIBC_VERSION") + assert version_string is not None + _, version = version_string.rsplit() + except (AssertionError, AttributeError, OSError, ValueError): + # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... + return None + return version + + +def _glibc_version_string_ctypes() -> Optional[str]: + """ + Fallback implementation of glibc_version_string using ctypes. + """ + try: + import ctypes + except ImportError: + return None + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + # + # We must also handle the special case where the executable is not a + # dynamically linked executable. This can occur when using musl libc, + # for example. In this situation, dlopen() will error, leading to an + # OSError. Interestingly, at least in the case of musl, there is no + # errno set on the OSError. The single string argument used to construct + # OSError comes from libc itself and is therefore not portable to + # hard code here. In any case, failure to call dlopen() means we + # can proceed, so we bail on our attempt. + try: + process_namespace = ctypes.CDLL(None) + except OSError: + return None + + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str: str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +def _glibc_version_string() -> Optional[str]: + """Returns glibc version string, or None if not using glibc.""" + return _glibc_version_string_confstr() or _glibc_version_string_ctypes() + + +def _parse_glibc_version(version_str: str) -> Tuple[int, int]: + """Parse glibc version. + + We use a regexp instead of str.split because we want to discard any + random junk that might come after the minor version -- this might happen + in patched/forked versions of glibc (e.g. Linaro's version of glibc + uses version strings like "2.20-2014.11"). See gh-3588. + """ + m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str) + if not m: + warnings.warn( + f"Expected glibc version with 2 components major.minor," + f" got: {version_str}", + RuntimeWarning, + ) + return -1, -1 + return int(m.group("major")), int(m.group("minor")) + + +@functools.lru_cache() +def _get_glibc_version() -> Tuple[int, int]: + version_str = _glibc_version_string() + if version_str is None: + return (-1, -1) + return _parse_glibc_version(version_str) + + +# From PEP 513, PEP 600 +def _is_compatible(arch: str, version: _GLibCVersion) -> bool: + sys_glibc = _get_glibc_version() + if sys_glibc < version: + return False + # Check for presence of _manylinux module. + try: + import _manylinux # noqa + except ImportError: + return True + if hasattr(_manylinux, "manylinux_compatible"): + result = _manylinux.manylinux_compatible(version[0], version[1], arch) + if result is not None: + return bool(result) + return True + if version == _GLibCVersion(2, 5): + if hasattr(_manylinux, "manylinux1_compatible"): + return bool(_manylinux.manylinux1_compatible) + if version == _GLibCVersion(2, 12): + if hasattr(_manylinux, "manylinux2010_compatible"): + return bool(_manylinux.manylinux2010_compatible) + if version == _GLibCVersion(2, 17): + if hasattr(_manylinux, "manylinux2014_compatible"): + return bool(_manylinux.manylinux2014_compatible) + return True + + +_LEGACY_MANYLINUX_MAP = { + # CentOS 7 w/ glibc 2.17 (PEP 599) + (2, 17): "manylinux2014", + # CentOS 6 w/ glibc 2.12 (PEP 571) + (2, 12): "manylinux2010", + # CentOS 5 w/ glibc 2.5 (PEP 513) + (2, 5): "manylinux1", +} + + +def platform_tags(archs: Sequence[str]) -> Iterator[str]: + """Generate manylinux tags compatible to the current platform. + + :param archs: Sequence of compatible architectures. + The first one shall be the closest to the actual architecture and be the part of + platform tag after the ``linux_`` prefix, e.g. ``x86_64``. + The ``linux_`` prefix is assumed as a prerequisite for the current platform to + be manylinux-compatible. + + :returns: An iterator of compatible manylinux tags. + """ + if not _have_compatible_abi(sys.executable, archs): + return + # Oldest glibc to be supported regardless of architecture is (2, 17). + too_old_glibc2 = _GLibCVersion(2, 16) + if set(archs) & {"x86_64", "i686"}: + # On x86/i686 also oldest glibc to be supported is (2, 5). + too_old_glibc2 = _GLibCVersion(2, 4) + current_glibc = _GLibCVersion(*_get_glibc_version()) + glibc_max_list = [current_glibc] + # We can assume compatibility across glibc major versions. + # https://sourceware.org/bugzilla/show_bug.cgi?id=24636 + # + # Build a list of maximum glibc versions so that we can + # output the canonical list of all glibc from current_glibc + # down to too_old_glibc2, including all intermediary versions. + for glibc_major in range(current_glibc.major - 1, 1, -1): + glibc_minor = _LAST_GLIBC_MINOR[glibc_major] + glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor)) + for arch in archs: + for glibc_max in glibc_max_list: + if glibc_max.major == too_old_glibc2.major: + min_minor = too_old_glibc2.minor + else: + # For other glibc major versions oldest supported is (x, 0). + min_minor = -1 + for glibc_minor in range(glibc_max.minor, min_minor, -1): + glibc_version = _GLibCVersion(glibc_max.major, glibc_minor) + tag = "manylinux_{}_{}".format(*glibc_version) + if _is_compatible(arch, glibc_version): + yield f"{tag}_{arch}" + # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags. + if glibc_version in _LEGACY_MANYLINUX_MAP: + legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version] + if _is_compatible(arch, glibc_version): + yield f"{legacy_tag}_{arch}" diff --git a/node_modules/node-gyp/gyp/pylib/packaging/_musllinux.py b/node_modules/node-gyp/gyp/pylib/packaging/_musllinux.py new file mode 100644 index 0000000000000..86419df9d7087 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/_musllinux.py @@ -0,0 +1,83 @@ +"""PEP 656 support. + +This module implements logic to detect if the currently running Python is +linked against musl, and what musl version is used. +""" + +import functools +import re +import subprocess +import sys +from typing import Iterator, NamedTuple, Optional, Sequence + +from ._elffile import ELFFile + + +class _MuslVersion(NamedTuple): + major: int + minor: int + + +def _parse_musl_version(output: str) -> Optional[_MuslVersion]: + lines = [n for n in (n.strip() for n in output.splitlines()) if n] + if len(lines) < 2 or lines[0][:4] != "musl": + return None + m = re.match(r"Version (\d+)\.(\d+)", lines[1]) + if not m: + return None + return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2))) + + +@functools.lru_cache() +def _get_musl_version(executable: str) -> Optional[_MuslVersion]: + """Detect currently-running musl runtime version. + + This is done by checking the specified executable's dynamic linking + information, and invoking the loader to parse its output for a version + string. If the loader is musl, the output would be something like:: + + musl libc (x86_64) + Version 1.2.2 + Dynamic Program Loader + """ + try: + with open(executable, "rb") as f: + ld = ELFFile(f).interpreter + except (OSError, TypeError, ValueError): + return None + if ld is None or "musl" not in ld: + return None + proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True) + return _parse_musl_version(proc.stderr) + + +def platform_tags(archs: Sequence[str]) -> Iterator[str]: + """Generate musllinux tags compatible to the current platform. + + :param archs: Sequence of compatible architectures. + The first one shall be the closest to the actual architecture and be the part of + platform tag after the ``linux_`` prefix, e.g. ``x86_64``. + The ``linux_`` prefix is assumed as a prerequisite for the current platform to + be musllinux-compatible. + + :returns: An iterator of compatible musllinux tags. + """ + sys_musl = _get_musl_version(sys.executable) + if sys_musl is None: # Python not dynamically linked against musl. + return + for arch in archs: + for minor in range(sys_musl.minor, -1, -1): + yield f"musllinux_{sys_musl.major}_{minor}_{arch}" + + +if __name__ == "__main__": # pragma: no cover + import sysconfig + + plat = sysconfig.get_platform() + assert plat.startswith("linux-"), "not linux" + + print("plat:", plat) + print("musl:", _get_musl_version(sys.executable)) + print("tags:", end=" ") + for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])): + print(t, end="\n ") diff --git a/node_modules/node-gyp/gyp/pylib/packaging/_parser.py b/node_modules/node-gyp/gyp/pylib/packaging/_parser.py new file mode 100644 index 0000000000000..4576981c2dd75 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/_parser.py @@ -0,0 +1,359 @@ +"""Handwritten parser of dependency specifiers. + +The docstring for each __parse_* function contains ENBF-inspired grammar representing +the implementation. +""" + +import ast +from typing import Any, List, NamedTuple, Optional, Tuple, Union + +from ._tokenizer import DEFAULT_RULES, Tokenizer + + +class Node: + def __init__(self, value: str) -> None: + self.value = value + + def __str__(self) -> str: + return self.value + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}('{self}')>" + + def serialize(self) -> str: + raise NotImplementedError + + +class Variable(Node): + def serialize(self) -> str: + return str(self) + + +class Value(Node): + def serialize(self) -> str: + return f'"{self}"' + + +class Op(Node): + def serialize(self) -> str: + return str(self) + + +MarkerVar = Union[Variable, Value] +MarkerItem = Tuple[MarkerVar, Op, MarkerVar] +# MarkerAtom = Union[MarkerItem, List["MarkerAtom"]] +# MarkerList = List[Union["MarkerList", MarkerAtom, str]] +# mypy does not support recursive type definition +# https://github.com/python/mypy/issues/731 +MarkerAtom = Any +MarkerList = List[Any] + + +class ParsedRequirement(NamedTuple): + name: str + url: str + extras: List[str] + specifier: str + marker: Optional[MarkerList] + + +# -------------------------------------------------------------------------------------- +# Recursive descent parser for dependency specifier +# -------------------------------------------------------------------------------------- +def parse_requirement(source: str) -> ParsedRequirement: + return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES)) + + +def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement: + """ + requirement = WS? IDENTIFIER WS? extras WS? requirement_details + """ + tokenizer.consume("WS") + + name_token = tokenizer.expect( + "IDENTIFIER", expected="package name at the start of dependency specifier" + ) + name = name_token.text + tokenizer.consume("WS") + + extras = _parse_extras(tokenizer) + tokenizer.consume("WS") + + url, specifier, marker = _parse_requirement_details(tokenizer) + tokenizer.expect("END", expected="end of dependency specifier") + + return ParsedRequirement(name, url, extras, specifier, marker) + + +def _parse_requirement_details( + tokenizer: Tokenizer, +) -> Tuple[str, str, Optional[MarkerList]]: + """ + requirement_details = AT URL (WS requirement_marker?)? + | specifier WS? (requirement_marker)? + """ + + specifier = "" + url = "" + marker = None + + if tokenizer.check("AT"): + tokenizer.read() + tokenizer.consume("WS") + + url_start = tokenizer.position + url = tokenizer.expect("URL", expected="URL after @").text + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + tokenizer.expect("WS", expected="whitespace after URL") + + # The input might end after whitespace. + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + marker = _parse_requirement_marker( + tokenizer, span_start=url_start, after="URL and whitespace" + ) + else: + specifier_start = tokenizer.position + specifier = _parse_specifier(tokenizer) + tokenizer.consume("WS") + + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + marker = _parse_requirement_marker( + tokenizer, + span_start=specifier_start, + after=( + "version specifier" + if specifier + else "name and no valid version specifier" + ), + ) + + return (url, specifier, marker) + + +def _parse_requirement_marker( + tokenizer: Tokenizer, *, span_start: int, after: str +) -> MarkerList: + """ + requirement_marker = SEMICOLON marker WS? + """ + + if not tokenizer.check("SEMICOLON"): + tokenizer.raise_syntax_error( + f"Expected end or semicolon (after {after})", + span_start=span_start, + ) + tokenizer.read() + + marker = _parse_marker(tokenizer) + tokenizer.consume("WS") + + return marker + + +def _parse_extras(tokenizer: Tokenizer) -> List[str]: + """ + extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)? + """ + if not tokenizer.check("LEFT_BRACKET", peek=True): + return [] + + with tokenizer.enclosing_tokens( + "LEFT_BRACKET", + "RIGHT_BRACKET", + around="extras", + ): + tokenizer.consume("WS") + extras = _parse_extras_list(tokenizer) + tokenizer.consume("WS") + + return extras + + +def _parse_extras_list(tokenizer: Tokenizer) -> List[str]: + """ + extras_list = identifier (wsp* ',' wsp* identifier)* + """ + extras: List[str] = [] + + if not tokenizer.check("IDENTIFIER"): + return extras + + extras.append(tokenizer.read().text) + + while True: + tokenizer.consume("WS") + if tokenizer.check("IDENTIFIER", peek=True): + tokenizer.raise_syntax_error("Expected comma between extra names") + elif not tokenizer.check("COMMA"): + break + + tokenizer.read() + tokenizer.consume("WS") + + extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma") + extras.append(extra_token.text) + + return extras + + +def _parse_specifier(tokenizer: Tokenizer) -> str: + """ + specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS + | WS? version_many WS? + """ + with tokenizer.enclosing_tokens( + "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", + around="version specifier", + ): + tokenizer.consume("WS") + parsed_specifiers = _parse_version_many(tokenizer) + tokenizer.consume("WS") + + return parsed_specifiers + + +def _parse_version_many(tokenizer: Tokenizer) -> str: + """ + version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)? + """ + parsed_specifiers = "" + while tokenizer.check("SPECIFIER"): + span_start = tokenizer.position + parsed_specifiers += tokenizer.read().text + if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True): + tokenizer.raise_syntax_error( + ".* suffix can only be used with `==` or `!=` operators", + span_start=span_start, + span_end=tokenizer.position + 1, + ) + if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True): + tokenizer.raise_syntax_error( + "Local version label can only be used with `==` or `!=` operators", + span_start=span_start, + span_end=tokenizer.position, + ) + tokenizer.consume("WS") + if not tokenizer.check("COMMA"): + break + parsed_specifiers += tokenizer.read().text + tokenizer.consume("WS") + + return parsed_specifiers + + +# -------------------------------------------------------------------------------------- +# Recursive descent parser for marker expression +# -------------------------------------------------------------------------------------- +def parse_marker(source: str) -> MarkerList: + return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES)) + + +def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList: + retval = _parse_marker(tokenizer) + tokenizer.expect("END", expected="end of marker expression") + return retval + + +def _parse_marker(tokenizer: Tokenizer) -> MarkerList: + """ + marker = marker_atom (BOOLOP marker_atom)+ + """ + expression = [_parse_marker_atom(tokenizer)] + while tokenizer.check("BOOLOP"): + token = tokenizer.read() + expr_right = _parse_marker_atom(tokenizer) + expression.extend((token.text, expr_right)) + return expression + + +def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom: + """ + marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS? + | WS? marker_item WS? + """ + + tokenizer.consume("WS") + if tokenizer.check("LEFT_PARENTHESIS", peek=True): + with tokenizer.enclosing_tokens( + "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", + around="marker expression", + ): + tokenizer.consume("WS") + marker: MarkerAtom = _parse_marker(tokenizer) + tokenizer.consume("WS") + else: + marker = _parse_marker_item(tokenizer) + tokenizer.consume("WS") + return marker + + +def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem: + """ + marker_item = WS? marker_var WS? marker_op WS? marker_var WS? + """ + tokenizer.consume("WS") + marker_var_left = _parse_marker_var(tokenizer) + tokenizer.consume("WS") + marker_op = _parse_marker_op(tokenizer) + tokenizer.consume("WS") + marker_var_right = _parse_marker_var(tokenizer) + tokenizer.consume("WS") + return (marker_var_left, marker_op, marker_var_right) + + +def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar: + """ + marker_var = VARIABLE | QUOTED_STRING + """ + if tokenizer.check("VARIABLE"): + return process_env_var(tokenizer.read().text.replace(".", "_")) + elif tokenizer.check("QUOTED_STRING"): + return process_python_str(tokenizer.read().text) + else: + tokenizer.raise_syntax_error( + message="Expected a marker variable or quoted string" + ) + + +def process_env_var(env_var: str) -> Variable: + if ( + env_var == "platform_python_implementation" + or env_var == "python_implementation" + ): + return Variable("platform_python_implementation") + else: + return Variable(env_var) + + +def process_python_str(python_str: str) -> Value: + value = ast.literal_eval(python_str) + return Value(str(value)) + + +def _parse_marker_op(tokenizer: Tokenizer) -> Op: + """ + marker_op = IN | NOT IN | OP + """ + if tokenizer.check("IN"): + tokenizer.read() + return Op("in") + elif tokenizer.check("NOT"): + tokenizer.read() + tokenizer.expect("WS", expected="whitespace after 'not'") + tokenizer.expect("IN", expected="'in' after 'not'") + return Op("not in") + elif tokenizer.check("OP"): + return Op(tokenizer.read().text) + else: + return tokenizer.raise_syntax_error( + "Expected marker operator, one of " + "<=, <, !=, ==, >=, >, ~=, ===, in, not in" + ) diff --git a/node_modules/node-gyp/gyp/pylib/packaging/_structures.py b/node_modules/node-gyp/gyp/pylib/packaging/_structures.py new file mode 100644 index 0000000000000..90a6465f9682c --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/_structures.py @@ -0,0 +1,61 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + + +class InfinityType: + def __repr__(self) -> str: + return "Infinity" + + def __hash__(self) -> int: + return hash(repr(self)) + + def __lt__(self, other: object) -> bool: + return False + + def __le__(self, other: object) -> bool: + return False + + def __eq__(self, other: object) -> bool: + return isinstance(other, self.__class__) + + def __gt__(self, other: object) -> bool: + return True + + def __ge__(self, other: object) -> bool: + return True + + def __neg__(self: object) -> "NegativeInfinityType": + return NegativeInfinity + + +Infinity = InfinityType() + + +class NegativeInfinityType: + def __repr__(self) -> str: + return "-Infinity" + + def __hash__(self) -> int: + return hash(repr(self)) + + def __lt__(self, other: object) -> bool: + return True + + def __le__(self, other: object) -> bool: + return True + + def __eq__(self, other: object) -> bool: + return isinstance(other, self.__class__) + + def __gt__(self, other: object) -> bool: + return False + + def __ge__(self, other: object) -> bool: + return False + + def __neg__(self: object) -> InfinityType: + return Infinity + + +NegativeInfinity = NegativeInfinityType() diff --git a/node_modules/node-gyp/gyp/pylib/packaging/_tokenizer.py b/node_modules/node-gyp/gyp/pylib/packaging/_tokenizer.py new file mode 100644 index 0000000000000..dd0d648d49a7c --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/_tokenizer.py @@ -0,0 +1,192 @@ +import contextlib +import re +from dataclasses import dataclass +from typing import Dict, Iterator, NoReturn, Optional, Tuple, Union + +from .specifiers import Specifier + + +@dataclass +class Token: + name: str + text: str + position: int + + +class ParserSyntaxError(Exception): + """The provided source text could not be parsed correctly.""" + + def __init__( + self, + message: str, + *, + source: str, + span: Tuple[int, int], + ) -> None: + self.span = span + self.message = message + self.source = source + + super().__init__() + + def __str__(self) -> str: + marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^" + return "\n ".join([self.message, self.source, marker]) + + +DEFAULT_RULES: "Dict[str, Union[str, re.Pattern[str]]]" = { + "LEFT_PARENTHESIS": r"\(", + "RIGHT_PARENTHESIS": r"\)", + "LEFT_BRACKET": r"\[", + "RIGHT_BRACKET": r"\]", + "SEMICOLON": r";", + "COMMA": r",", + "QUOTED_STRING": re.compile( + r""" + ( + ('[^']*') + | + ("[^"]*") + ) + """, + re.VERBOSE, + ), + "OP": r"(===|==|~=|!=|<=|>=|<|>)", + "BOOLOP": r"\b(or|and)\b", + "IN": r"\bin\b", + "NOT": r"\bnot\b", + "VARIABLE": re.compile( + r""" + \b( + python_version + |python_full_version + |os[._]name + |sys[._]platform + |platform_(release|system) + |platform[._](version|machine|python_implementation) + |python_implementation + |implementation_(name|version) + |extra + )\b + """, + re.VERBOSE, + ), + "SPECIFIER": re.compile( + Specifier._operator_regex_str + Specifier._version_regex_str, + re.VERBOSE | re.IGNORECASE, + ), + "AT": r"\@", + "URL": r"[^ \t]+", + "IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b", + "VERSION_PREFIX_TRAIL": r"\.\*", + "VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*", + "WS": r"[ \t]+", + "END": r"$", +} + + +class Tokenizer: + """Context-sensitive token parsing. + + Provides methods to examine the input stream to check whether the next token + matches. + """ + + def __init__( + self, + source: str, + *, + rules: "Dict[str, Union[str, re.Pattern[str]]]", + ) -> None: + self.source = source + self.rules: Dict[str, re.Pattern[str]] = { + name: re.compile(pattern) for name, pattern in rules.items() + } + self.next_token: Optional[Token] = None + self.position = 0 + + def consume(self, name: str) -> None: + """Move beyond provided token name, if at current position.""" + if self.check(name): + self.read() + + def check(self, name: str, *, peek: bool = False) -> bool: + """Check whether the next token has the provided name. + + By default, if the check succeeds, the token *must* be read before + another check. If `peek` is set to `True`, the token is not loaded and + would need to be checked again. + """ + assert ( + self.next_token is None + ), f"Cannot check for {name!r}, already have {self.next_token!r}" + assert name in self.rules, f"Unknown token name: {name!r}" + + expression = self.rules[name] + + match = expression.match(self.source, self.position) + if match is None: + return False + if not peek: + self.next_token = Token(name, match[0], self.position) + return True + + def expect(self, name: str, *, expected: str) -> Token: + """Expect a certain token name next, failing with a syntax error otherwise. + + The token is *not* read. + """ + if not self.check(name): + raise self.raise_syntax_error(f"Expected {expected}") + return self.read() + + def read(self) -> Token: + """Consume the next token and return it.""" + token = self.next_token + assert token is not None + + self.position += len(token.text) + self.next_token = None + + return token + + def raise_syntax_error( + self, + message: str, + *, + span_start: Optional[int] = None, + span_end: Optional[int] = None, + ) -> NoReturn: + """Raise ParserSyntaxError at the given position.""" + span = ( + self.position if span_start is None else span_start, + self.position if span_end is None else span_end, + ) + raise ParserSyntaxError( + message, + source=self.source, + span=span, + ) + + @contextlib.contextmanager + def enclosing_tokens( + self, open_token: str, close_token: str, *, around: str + ) -> Iterator[None]: + if self.check(open_token): + open_position = self.position + self.read() + else: + open_position = None + + yield + + if open_position is None: + return + + if not self.check(close_token): + self.raise_syntax_error( + f"Expected matching {close_token} for {open_token}, after {around}", + span_start=open_position, + ) + + self.read() diff --git a/node_modules/node-gyp/gyp/pylib/packaging/markers.py b/node_modules/node-gyp/gyp/pylib/packaging/markers.py new file mode 100644 index 0000000000000..7e4d150208eec --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/markers.py @@ -0,0 +1,251 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import operator +import os +import platform +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple, Union + +from ._parser import ( + MarkerAtom, + MarkerList, + Op, + Value, + Variable, + parse_marker as _parse_marker, +) +from ._tokenizer import ParserSyntaxError +from .specifiers import InvalidSpecifier, Specifier +from .utils import canonicalize_name + +__all__ = [ + "InvalidMarker", + "UndefinedComparison", + "UndefinedEnvironmentName", + "Marker", + "default_environment", +] + +Operator = Callable[[str, str], bool] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +def _normalize_extra_values(results: Any) -> Any: + """ + Normalize extra values. + """ + if isinstance(results[0], tuple): + lhs, op, rhs = results[0] + if isinstance(lhs, Variable) and lhs.value == "extra": + normalized_extra = canonicalize_name(rhs.value) + rhs = Value(normalized_extra) + elif isinstance(rhs, Variable) and rhs.value == "extra": + normalized_extra = canonicalize_name(lhs.value) + lhs = Value(normalized_extra) + results[0] = lhs, op, rhs + return results + + +def _format_marker( + marker: Union[List[str], MarkerAtom, str], first: Optional[bool] = True +) -> str: + + assert isinstance(marker, (list, tuple, str)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if ( + isinstance(marker, list) + and len(marker) == 1 + and isinstance(marker[0], (list, tuple)) + ): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators: Dict[str, Operator] = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs: str, op: Op, rhs: str) -> bool: + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs, prereleases=True) + + oper: Optional[Operator] = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison(f"Undefined {op!r} on {lhs!r} and {rhs!r}.") + + return oper(lhs, rhs) + + +def _normalize(*values: str, key: str) -> Tuple[str, ...]: + # PEP 685 – Comparison of extra names for optional distribution dependencies + # https://peps.python.org/pep-0685/ + # > When comparing extra names, tools MUST normalize the names being + # > compared using the semantics outlined in PEP 503 for names + if key == "extra": + return tuple(canonicalize_name(v) for v in values) + + # other environment markers don't have such standards + return values + + +def _evaluate_markers(markers: MarkerList, environment: Dict[str, str]) -> bool: + groups: List[List[bool]] = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, str)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + environment_key = lhs.value + lhs_value = environment[environment_key] + rhs_value = rhs.value + else: + lhs_value = lhs.value + environment_key = rhs.value + rhs_value = environment[environment_key] + + lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info: "sys._version_info") -> str: + version = "{0.major}.{0.minor}.{0.micro}".format(info) + if (kind := info.releaselevel) != "final": + version += kind[0] + str(info.serial) + return version + + +def default_environment() -> Dict[str, str]: + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": ".".join(platform.python_version_tuple()[:2]), + "sys_platform": sys.platform, + } + + +class Marker: + def __init__(self, marker: str) -> None: + # Note: We create a Marker object without calling this constructor in + # packaging.requirements.Requirement. If any additional logic is + # added here, make sure to mirror/adapt Requirement. + try: + self._markers = _normalize_extra_values(_parse_marker(marker)) + # The attribute `_markers` can be described in terms of a recursive type: + # MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]] + # + # For example, the following expression: + # python_version > "3.6" or (python_version == "3.6" and os_name == "unix") + # + # is parsed into: + # [ + # (<Variable('python_version')>, <Op('>')>, <Value('3.6')>), + # 'and', + # [ + # (<Variable('python_version')>, <Op('==')>, <Value('3.6')>), + # 'or', + # (<Variable('os_name')>, <Op('==')>, <Value('unix')>) + # ] + # ] + except ParserSyntaxError as e: + raise InvalidMarker(str(e)) from e + + def __str__(self) -> str: + return _format_marker(self._markers) + + def __repr__(self) -> str: + return f"<Marker('{self}')>" + + def __hash__(self) -> int: + return hash((self.__class__.__name__, str(self))) + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, Marker): + return NotImplemented + + return str(self) == str(other) + + def evaluate(self, environment: Optional[Dict[str, str]] = None) -> bool: + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + current_environment["extra"] = "" + if environment is not None: + current_environment.update(environment) + # The API used to allow setting extra to None. We need to handle this + # case for backwards compatibility. + if current_environment["extra"] is None: + current_environment["extra"] = "" + + return _evaluate_markers(self._markers, current_environment) diff --git a/node_modules/node-gyp/gyp/pylib/packaging/metadata.py b/node_modules/node-gyp/gyp/pylib/packaging/metadata.py new file mode 100644 index 0000000000000..43f5c5b30df97 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/metadata.py @@ -0,0 +1,824 @@ +import email.feedparser +import email.header +import email.message +import email.parser +import email.policy +import sys +import typing +from typing import ( + Any, + Callable, + Dict, + Generic, + List, + Optional, + Tuple, + Type, + Union, + cast, +) + +from . import requirements, specifiers, utils, version as version_module + +T = typing.TypeVar("T") +if sys.version_info[:2] >= (3, 8): # pragma: no cover + from typing import Literal, TypedDict +else: # pragma: no cover + if typing.TYPE_CHECKING: + from typing_extensions import Literal, TypedDict + else: + try: + from typing_extensions import Literal, TypedDict + except ImportError: + + class Literal: + def __init_subclass__(*_args, **_kwargs): + pass + + class TypedDict: + def __init_subclass__(*_args, **_kwargs): + pass + + +try: + ExceptionGroup +except NameError: # pragma: no cover + + class ExceptionGroup(Exception): # noqa: N818 + """A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11. + + If :external:exc:`ExceptionGroup` is already defined by Python itself, + that version is used instead. + """ + + message: str + exceptions: List[Exception] + + def __init__(self, message: str, exceptions: List[Exception]) -> None: + self.message = message + self.exceptions = exceptions + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})" + +else: # pragma: no cover + ExceptionGroup = ExceptionGroup + + +class InvalidMetadata(ValueError): + """A metadata field contains invalid data.""" + + field: str + """The name of the field that contains invalid data.""" + + def __init__(self, field: str, message: str) -> None: + self.field = field + super().__init__(message) + + +# The RawMetadata class attempts to make as few assumptions about the underlying +# serialization formats as possible. The idea is that as long as a serialization +# formats offer some very basic primitives in *some* way then we can support +# serializing to and from that format. +class RawMetadata(TypedDict, total=False): + """A dictionary of raw core metadata. + + Each field in core metadata maps to a key of this dictionary (when data is + provided). The key is lower-case and underscores are used instead of dashes + compared to the equivalent core metadata field. Any core metadata field that + can be specified multiple times or can hold multiple values in a single + field have a key with a plural name. See :class:`Metadata` whose attributes + match the keys of this dictionary. + + Core metadata fields that can be specified multiple times are stored as a + list or dict depending on which is appropriate for the field. Any fields + which hold multiple values in a single field are stored as a list. + + """ + + # Metadata 1.0 - PEP 241 + metadata_version: str + name: str + version: str + platforms: List[str] + summary: str + description: str + keywords: List[str] + home_page: str + author: str + author_email: str + license: str + + # Metadata 1.1 - PEP 314 + supported_platforms: List[str] + download_url: str + classifiers: List[str] + requires: List[str] + provides: List[str] + obsoletes: List[str] + + # Metadata 1.2 - PEP 345 + maintainer: str + maintainer_email: str + requires_dist: List[str] + provides_dist: List[str] + obsoletes_dist: List[str] + requires_python: str + requires_external: List[str] + project_urls: Dict[str, str] + + # Metadata 2.0 + # PEP 426 attempted to completely revamp the metadata format + # but got stuck without ever being able to build consensus on + # it and ultimately ended up withdrawn. + # + # However, a number of tools had started emitting METADATA with + # `2.0` Metadata-Version, so for historical reasons, this version + # was skipped. + + # Metadata 2.1 - PEP 566 + description_content_type: str + provides_extra: List[str] + + # Metadata 2.2 - PEP 643 + dynamic: List[str] + + # Metadata 2.3 - PEP 685 + # No new fields were added in PEP 685, just some edge case were + # tightened up to provide better interoperability. + + +_STRING_FIELDS = { + "author", + "author_email", + "description", + "description_content_type", + "download_url", + "home_page", + "license", + "maintainer", + "maintainer_email", + "metadata_version", + "name", + "requires_python", + "summary", + "version", +} + +_LIST_FIELDS = { + "classifiers", + "dynamic", + "obsoletes", + "obsoletes_dist", + "platforms", + "provides", + "provides_dist", + "provides_extra", + "requires", + "requires_dist", + "requires_external", + "supported_platforms", +} + +_DICT_FIELDS = { + "project_urls", +} + + +def _parse_keywords(data: str) -> List[str]: + """Split a string of comma-separate keyboards into a list of keywords.""" + return [k.strip() for k in data.split(",")] + + +def _parse_project_urls(data: List[str]) -> Dict[str, str]: + """Parse a list of label/URL string pairings separated by a comma.""" + urls = {} + for pair in data: + # Our logic is slightly tricky here as we want to try and do + # *something* reasonable with malformed data. + # + # The main thing that we have to worry about, is data that does + # not have a ',' at all to split the label from the Value. There + # isn't a singular right answer here, and we will fail validation + # later on (if the caller is validating) so it doesn't *really* + # matter, but since the missing value has to be an empty str + # and our return value is dict[str, str], if we let the key + # be the missing value, then they'd have multiple '' values that + # overwrite each other in a accumulating dict. + # + # The other potential issue is that it's possible to have the + # same label multiple times in the metadata, with no solid "right" + # answer with what to do in that case. As such, we'll do the only + # thing we can, which is treat the field as unparsable and add it + # to our list of unparsed fields. + parts = [p.strip() for p in pair.split(",", 1)] + parts.extend([""] * (max(0, 2 - len(parts)))) # Ensure 2 items + + # TODO: The spec doesn't say anything about if the keys should be + # considered case sensitive or not... logically they should + # be case-preserving and case-insensitive, but doing that + # would open up more cases where we might have duplicate + # entries. + label, url = parts + if label in urls: + # The label already exists in our set of urls, so this field + # is unparsable, and we can just add the whole thing to our + # unparsable data and stop processing it. + raise KeyError("duplicate labels in project urls") + urls[label] = url + + return urls + + +def _get_payload(msg: email.message.Message, source: Union[bytes, str]) -> str: + """Get the body of the message.""" + # If our source is a str, then our caller has managed encodings for us, + # and we don't need to deal with it. + if isinstance(source, str): + payload: str = msg.get_payload() + return payload + # If our source is a bytes, then we're managing the encoding and we need + # to deal with it. + else: + bpayload: bytes = msg.get_payload(decode=True) + try: + return bpayload.decode("utf8", "strict") + except UnicodeDecodeError: + raise ValueError("payload in an invalid encoding") + + +# The various parse_FORMAT functions here are intended to be as lenient as +# possible in their parsing, while still returning a correctly typed +# RawMetadata. +# +# To aid in this, we also generally want to do as little touching of the +# data as possible, except where there are possibly some historic holdovers +# that make valid data awkward to work with. +# +# While this is a lower level, intermediate format than our ``Metadata`` +# class, some light touch ups can make a massive difference in usability. + +# Map METADATA fields to RawMetadata. +_EMAIL_TO_RAW_MAPPING = { + "author": "author", + "author-email": "author_email", + "classifier": "classifiers", + "description": "description", + "description-content-type": "description_content_type", + "download-url": "download_url", + "dynamic": "dynamic", + "home-page": "home_page", + "keywords": "keywords", + "license": "license", + "maintainer": "maintainer", + "maintainer-email": "maintainer_email", + "metadata-version": "metadata_version", + "name": "name", + "obsoletes": "obsoletes", + "obsoletes-dist": "obsoletes_dist", + "platform": "platforms", + "project-url": "project_urls", + "provides": "provides", + "provides-dist": "provides_dist", + "provides-extra": "provides_extra", + "requires": "requires", + "requires-dist": "requires_dist", + "requires-external": "requires_external", + "requires-python": "requires_python", + "summary": "summary", + "supported-platform": "supported_platforms", + "version": "version", +} +_RAW_TO_EMAIL_MAPPING = {raw: email for email, raw in _EMAIL_TO_RAW_MAPPING.items()} + + +def parse_email(data: Union[bytes, str]) -> Tuple[RawMetadata, Dict[str, List[str]]]: + """Parse a distribution's metadata stored as email headers (e.g. from ``METADATA``). + + This function returns a two-item tuple of dicts. The first dict is of + recognized fields from the core metadata specification. Fields that can be + parsed and translated into Python's built-in types are converted + appropriately. All other fields are left as-is. Fields that are allowed to + appear multiple times are stored as lists. + + The second dict contains all other fields from the metadata. This includes + any unrecognized fields. It also includes any fields which are expected to + be parsed into a built-in type but were not formatted appropriately. Finally, + any fields that are expected to appear only once but are repeated are + included in this dict. + + """ + raw: Dict[str, Union[str, List[str], Dict[str, str]]] = {} + unparsed: Dict[str, List[str]] = {} + + if isinstance(data, str): + parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data) + else: + parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data) + + # We have to wrap parsed.keys() in a set, because in the case of multiple + # values for a key (a list), the key will appear multiple times in the + # list of keys, but we're avoiding that by using get_all(). + for name in frozenset(parsed.keys()): + # Header names in RFC are case insensitive, so we'll normalize to all + # lower case to make comparisons easier. + name = name.lower() + + # We use get_all() here, even for fields that aren't multiple use, + # because otherwise someone could have e.g. two Name fields, and we + # would just silently ignore it rather than doing something about it. + headers = parsed.get_all(name) or [] + + # The way the email module works when parsing bytes is that it + # unconditionally decodes the bytes as ascii using the surrogateescape + # handler. When you pull that data back out (such as with get_all() ), + # it looks to see if the str has any surrogate escapes, and if it does + # it wraps it in a Header object instead of returning the string. + # + # As such, we'll look for those Header objects, and fix up the encoding. + value = [] + # Flag if we have run into any issues processing the headers, thus + # signalling that the data belongs in 'unparsed'. + valid_encoding = True + for h in headers: + # It's unclear if this can return more types than just a Header or + # a str, so we'll just assert here to make sure. + assert isinstance(h, (email.header.Header, str)) + + # If it's a header object, we need to do our little dance to get + # the real data out of it. In cases where there is invalid data + # we're going to end up with mojibake, but there's no obvious, good + # way around that without reimplementing parts of the Header object + # ourselves. + # + # That should be fine since, if mojibacked happens, this key is + # going into the unparsed dict anyways. + if isinstance(h, email.header.Header): + # The Header object stores it's data as chunks, and each chunk + # can be independently encoded, so we'll need to check each + # of them. + chunks: List[Tuple[bytes, Optional[str]]] = [] + for bin, encoding in email.header.decode_header(h): + try: + bin.decode("utf8", "strict") + except UnicodeDecodeError: + # Enable mojibake. + encoding = "latin1" + valid_encoding = False + else: + encoding = "utf8" + chunks.append((bin, encoding)) + + # Turn our chunks back into a Header object, then let that + # Header object do the right thing to turn them into a + # string for us. + value.append(str(email.header.make_header(chunks))) + # This is already a string, so just add it. + else: + value.append(h) + + # We've processed all of our values to get them into a list of str, + # but we may have mojibake data, in which case this is an unparsed + # field. + if not valid_encoding: + unparsed[name] = value + continue + + raw_name = _EMAIL_TO_RAW_MAPPING.get(name) + if raw_name is None: + # This is a bit of a weird situation, we've encountered a key that + # we don't know what it means, so we don't know whether it's meant + # to be a list or not. + # + # Since we can't really tell one way or another, we'll just leave it + # as a list, even though it may be a single item list, because that's + # what makes the most sense for email headers. + unparsed[name] = value + continue + + # If this is one of our string fields, then we'll check to see if our + # value is a list of a single item. If it is then we'll assume that + # it was emitted as a single string, and unwrap the str from inside + # the list. + # + # If it's any other kind of data, then we haven't the faintest clue + # what we should parse it as, and we have to just add it to our list + # of unparsed stuff. + if raw_name in _STRING_FIELDS and len(value) == 1: + raw[raw_name] = value[0] + # If this is one of our list of string fields, then we can just assign + # the value, since email *only* has strings, and our get_all() call + # above ensures that this is a list. + elif raw_name in _LIST_FIELDS: + raw[raw_name] = value + # Special Case: Keywords + # The keywords field is implemented in the metadata spec as a str, + # but it conceptually is a list of strings, and is serialized using + # ", ".join(keywords), so we'll do some light data massaging to turn + # this into what it logically is. + elif raw_name == "keywords" and len(value) == 1: + raw[raw_name] = _parse_keywords(value[0]) + # Special Case: Project-URL + # The project urls is implemented in the metadata spec as a list of + # specially-formatted strings that represent a key and a value, which + # is fundamentally a mapping, however the email format doesn't support + # mappings in a sane way, so it was crammed into a list of strings + # instead. + # + # We will do a little light data massaging to turn this into a map as + # it logically should be. + elif raw_name == "project_urls": + try: + raw[raw_name] = _parse_project_urls(value) + except KeyError: + unparsed[name] = value + # Nothing that we've done has managed to parse this, so it'll just + # throw it in our unparsable data and move on. + else: + unparsed[name] = value + + # We need to support getting the Description from the message payload in + # addition to getting it from the the headers. This does mean, though, there + # is the possibility of it being set both ways, in which case we put both + # in 'unparsed' since we don't know which is right. + try: + payload = _get_payload(parsed, data) + except ValueError: + unparsed.setdefault("description", []).append( + parsed.get_payload(decode=isinstance(data, bytes)) + ) + else: + if payload: + # Check to see if we've already got a description, if so then both + # it, and this body move to unparsable. + if "description" in raw: + description_header = cast(str, raw.pop("description")) + unparsed.setdefault("description", []).extend( + [description_header, payload] + ) + elif "description" in unparsed: + unparsed["description"].append(payload) + else: + raw["description"] = payload + + # We need to cast our `raw` to a metadata, because a TypedDict only support + # literal key names, but we're computing our key names on purpose, but the + # way this function is implemented, our `TypedDict` can only have valid key + # names. + return cast(RawMetadata, raw), unparsed + + +_NOT_FOUND = object() + + +# Keep the two values in sync. +_VALID_METADATA_VERSIONS = ["1.0", "1.1", "1.2", "2.1", "2.2", "2.3"] +_MetadataVersion = Literal["1.0", "1.1", "1.2", "2.1", "2.2", "2.3"] + +_REQUIRED_ATTRS = frozenset(["metadata_version", "name", "version"]) + + +class _Validator(Generic[T]): + """Validate a metadata field. + + All _process_*() methods correspond to a core metadata field. The method is + called with the field's raw value. If the raw value is valid it is returned + in its "enriched" form (e.g. ``version.Version`` for the ``Version`` field). + If the raw value is invalid, :exc:`InvalidMetadata` is raised (with a cause + as appropriate). + """ + + name: str + raw_name: str + added: _MetadataVersion + + def __init__( + self, + *, + added: _MetadataVersion = "1.0", + ) -> None: + self.added = added + + def __set_name__(self, _owner: "Metadata", name: str) -> None: + self.name = name + self.raw_name = _RAW_TO_EMAIL_MAPPING[name] + + def __get__(self, instance: "Metadata", _owner: Type["Metadata"]) -> T: + # With Python 3.8, the caching can be replaced with functools.cached_property(). + # No need to check the cache as attribute lookup will resolve into the + # instance's __dict__ before __get__ is called. + cache = instance.__dict__ + value = instance._raw.get(self.name) + + # To make the _process_* methods easier, we'll check if the value is None + # and if this field is NOT a required attribute, and if both of those + # things are true, we'll skip the the converter. This will mean that the + # converters never have to deal with the None union. + if self.name in _REQUIRED_ATTRS or value is not None: + try: + converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}") + except AttributeError: + pass + else: + value = converter(value) + + cache[self.name] = value + try: + del instance._raw[self.name] # type: ignore[misc] + except KeyError: + pass + + return cast(T, value) + + def _invalid_metadata( + self, msg: str, cause: Optional[Exception] = None + ) -> InvalidMetadata: + exc = InvalidMetadata( + self.raw_name, msg.format_map({"field": repr(self.raw_name)}) + ) + exc.__cause__ = cause + return exc + + def _process_metadata_version(self, value: str) -> _MetadataVersion: + # Implicitly makes Metadata-Version required. + if value not in _VALID_METADATA_VERSIONS: + raise self._invalid_metadata(f"{value!r} is not a valid metadata version") + return cast(_MetadataVersion, value) + + def _process_name(self, value: str) -> str: + if not value: + raise self._invalid_metadata("{field} is a required field") + # Validate the name as a side-effect. + try: + utils.canonicalize_name(value, validate=True) + except utils.InvalidName as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {{field}}", cause=exc + ) + else: + return value + + def _process_version(self, value: str) -> version_module.Version: + if not value: + raise self._invalid_metadata("{field} is a required field") + try: + return version_module.parse(value) + except version_module.InvalidVersion as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {{field}}", cause=exc + ) + + def _process_summary(self, value: str) -> str: + """Check the field contains no newlines.""" + if "\n" in value: + raise self._invalid_metadata("{field} must be a single line") + return value + + def _process_description_content_type(self, value: str) -> str: + content_types = {"text/plain", "text/x-rst", "text/markdown"} + message = email.message.EmailMessage() + message["content-type"] = value + + content_type, parameters = ( + # Defaults to `text/plain` if parsing failed. + message.get_content_type().lower(), + message["content-type"].params, + ) + # Check if content-type is valid or defaulted to `text/plain` and thus was + # not parseable. + if content_type not in content_types or content_type not in value.lower(): + raise self._invalid_metadata( + f"{{field}} must be one of {list(content_types)}, not {value!r}" + ) + + if (charset := parameters.get("charset", "UTF-8")) != "UTF-8": + raise self._invalid_metadata( + f"{{field}} can only specify the UTF-8 charset, not {list(charset)}" + ) + + markdown_variants = {"GFM", "CommonMark"} + variant = parameters.get("variant", "GFM") # Use an acceptable default. + if content_type == "text/markdown" and variant not in markdown_variants: + raise self._invalid_metadata( + f"valid Markdown variants for {{field}} are {list(markdown_variants)}, " + f"not {variant!r}", + ) + return value + + def _process_dynamic(self, value: List[str]) -> List[str]: + for dynamic_field in map(str.lower, value): + if dynamic_field in {"name", "version", "metadata-version"}: + raise self._invalid_metadata( + f"{value!r} is not allowed as a dynamic field" + ) + elif dynamic_field not in _EMAIL_TO_RAW_MAPPING: + raise self._invalid_metadata(f"{value!r} is not a valid dynamic field") + return list(map(str.lower, value)) + + def _process_provides_extra( + self, + value: List[str], + ) -> List[utils.NormalizedName]: + normalized_names = [] + try: + for name in value: + normalized_names.append(utils.canonicalize_name(name, validate=True)) + except utils.InvalidName as exc: + raise self._invalid_metadata( + f"{name!r} is invalid for {{field}}", cause=exc + ) + else: + return normalized_names + + def _process_requires_python(self, value: str) -> specifiers.SpecifierSet: + try: + return specifiers.SpecifierSet(value) + except specifiers.InvalidSpecifier as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {{field}}", cause=exc + ) + + def _process_requires_dist( + self, + value: List[str], + ) -> List[requirements.Requirement]: + reqs = [] + try: + for req in value: + reqs.append(requirements.Requirement(req)) + except requirements.InvalidRequirement as exc: + raise self._invalid_metadata(f"{req!r} is invalid for {{field}}", cause=exc) + else: + return reqs + + +class Metadata: + """Representation of distribution metadata. + + Compared to :class:`RawMetadata`, this class provides objects representing + metadata fields instead of only using built-in types. Any invalid metadata + will cause :exc:`InvalidMetadata` to be raised (with a + :py:attr:`~BaseException.__cause__` attribute as appropriate). + """ + + _raw: RawMetadata + + @classmethod + def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> "Metadata": + """Create an instance from :class:`RawMetadata`. + + If *validate* is true, all metadata will be validated. All exceptions + related to validation will be gathered and raised as an :class:`ExceptionGroup`. + """ + ins = cls() + ins._raw = data.copy() # Mutations occur due to caching enriched values. + + if validate: + exceptions: List[Exception] = [] + try: + metadata_version = ins.metadata_version + metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version) + except InvalidMetadata as metadata_version_exc: + exceptions.append(metadata_version_exc) + metadata_version = None + + # Make sure to check for the fields that are present, the required + # fields (so their absence can be reported). + fields_to_check = frozenset(ins._raw) | _REQUIRED_ATTRS + # Remove fields that have already been checked. + fields_to_check -= {"metadata_version"} + + for key in fields_to_check: + try: + if metadata_version: + # Can't use getattr() as that triggers descriptor protocol which + # will fail due to no value for the instance argument. + try: + field_metadata_version = cls.__dict__[key].added + except KeyError: + exc = InvalidMetadata(key, f"unrecognized field: {key!r}") + exceptions.append(exc) + continue + field_age = _VALID_METADATA_VERSIONS.index( + field_metadata_version + ) + if field_age > metadata_age: + field = _RAW_TO_EMAIL_MAPPING[key] + exc = InvalidMetadata( + field, + "{field} introduced in metadata version " + "{field_metadata_version}, not {metadata_version}", + ) + exceptions.append(exc) + continue + getattr(ins, key) + except InvalidMetadata as exc: + exceptions.append(exc) + + if exceptions: + raise ExceptionGroup("invalid metadata", exceptions) + + return ins + + @classmethod + def from_email( + cls, data: Union[bytes, str], *, validate: bool = True + ) -> "Metadata": + """Parse metadata from email headers. + + If *validate* is true, the metadata will be validated. All exceptions + related to validation will be gathered and raised as an :class:`ExceptionGroup`. + """ + raw, unparsed = parse_email(data) + + if validate: + exceptions: list[Exception] = [] + for unparsed_key in unparsed: + if unparsed_key in _EMAIL_TO_RAW_MAPPING: + message = f"{unparsed_key!r} has invalid data" + else: + message = f"unrecognized field: {unparsed_key!r}" + exceptions.append(InvalidMetadata(unparsed_key, message)) + + if exceptions: + raise ExceptionGroup("unparsed", exceptions) + + try: + return cls.from_raw(raw, validate=validate) + except ExceptionGroup as exc_group: + raise ExceptionGroup( + "invalid or unparsed metadata", exc_group.exceptions + ) from None + + metadata_version: _Validator[_MetadataVersion] = _Validator() + """:external:ref:`core-metadata-metadata-version` + (required; validated to be a valid metadata version)""" + name: _Validator[str] = _Validator() + """:external:ref:`core-metadata-name` + (required; validated using :func:`~packaging.utils.canonicalize_name` and its + *validate* parameter)""" + version: _Validator[version_module.Version] = _Validator() + """:external:ref:`core-metadata-version` (required)""" + dynamic: _Validator[Optional[List[str]]] = _Validator( + added="2.2", + ) + """:external:ref:`core-metadata-dynamic` + (validated against core metadata field names and lowercased)""" + platforms: _Validator[Optional[List[str]]] = _Validator() + """:external:ref:`core-metadata-platform`""" + supported_platforms: _Validator[Optional[List[str]]] = _Validator(added="1.1") + """:external:ref:`core-metadata-supported-platform`""" + summary: _Validator[Optional[str]] = _Validator() + """:external:ref:`core-metadata-summary` (validated to contain no newlines)""" + description: _Validator[Optional[str]] = _Validator() # TODO 2.1: can be in body + """:external:ref:`core-metadata-description`""" + description_content_type: _Validator[Optional[str]] = _Validator(added="2.1") + """:external:ref:`core-metadata-description-content-type` (validated)""" + keywords: _Validator[Optional[List[str]]] = _Validator() + """:external:ref:`core-metadata-keywords`""" + home_page: _Validator[Optional[str]] = _Validator() + """:external:ref:`core-metadata-home-page`""" + download_url: _Validator[Optional[str]] = _Validator(added="1.1") + """:external:ref:`core-metadata-download-url`""" + author: _Validator[Optional[str]] = _Validator() + """:external:ref:`core-metadata-author`""" + author_email: _Validator[Optional[str]] = _Validator() + """:external:ref:`core-metadata-author-email`""" + maintainer: _Validator[Optional[str]] = _Validator(added="1.2") + """:external:ref:`core-metadata-maintainer`""" + maintainer_email: _Validator[Optional[str]] = _Validator(added="1.2") + """:external:ref:`core-metadata-maintainer-email`""" + license: _Validator[Optional[str]] = _Validator() + """:external:ref:`core-metadata-license`""" + classifiers: _Validator[Optional[List[str]]] = _Validator(added="1.1") + """:external:ref:`core-metadata-classifier`""" + requires_dist: _Validator[Optional[List[requirements.Requirement]]] = _Validator( + added="1.2" + ) + """:external:ref:`core-metadata-requires-dist`""" + requires_python: _Validator[Optional[specifiers.SpecifierSet]] = _Validator( + added="1.2" + ) + """:external:ref:`core-metadata-requires-python`""" + # Because `Requires-External` allows for non-PEP 440 version specifiers, we + # don't do any processing on the values. + requires_external: _Validator[Optional[List[str]]] = _Validator(added="1.2") + """:external:ref:`core-metadata-requires-external`""" + project_urls: _Validator[Optional[Dict[str, str]]] = _Validator(added="1.2") + """:external:ref:`core-metadata-project-url`""" + # PEP 685 lets us raise an error if an extra doesn't pass `Name` validation + # regardless of metadata version. + provides_extra: _Validator[Optional[List[utils.NormalizedName]]] = _Validator( + added="2.1", + ) + """:external:ref:`core-metadata-provides-extra`""" + provides_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2") + """:external:ref:`core-metadata-provides-dist`""" + obsoletes_dist: _Validator[Optional[List[str]]] = _Validator(added="1.2") + """:external:ref:`core-metadata-obsoletes-dist`""" + requires: _Validator[Optional[List[str]]] = _Validator(added="1.1") + """``Requires`` (deprecated)""" + provides: _Validator[Optional[List[str]]] = _Validator(added="1.1") + """``Provides`` (deprecated)""" + obsoletes: _Validator[Optional[List[str]]] = _Validator(added="1.1") + """``Obsoletes`` (deprecated)""" diff --git a/node_modules/node-gyp/gyp/pylib/packaging/py.typed b/node_modules/node-gyp/gyp/pylib/packaging/py.typed new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/node_modules/node-gyp/gyp/pylib/packaging/requirements.py b/node_modules/node-gyp/gyp/pylib/packaging/requirements.py new file mode 100644 index 0000000000000..0c00eba331b73 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/requirements.py @@ -0,0 +1,90 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from typing import Any, Iterator, Optional, Set + +from ._parser import parse_requirement as _parse_requirement +from ._tokenizer import ParserSyntaxError +from .markers import Marker, _normalize_extra_values +from .specifiers import SpecifierSet +from .utils import canonicalize_name + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +class Requirement: + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string: str) -> None: + try: + parsed = _parse_requirement(requirement_string) + except ParserSyntaxError as e: + raise InvalidRequirement(str(e)) from e + + self.name: str = parsed.name + self.url: Optional[str] = parsed.url or None + self.extras: Set[str] = set(parsed.extras if parsed.extras else []) + self.specifier: SpecifierSet = SpecifierSet(parsed.specifier) + self.marker: Optional[Marker] = None + if parsed.marker is not None: + self.marker = Marker.__new__(Marker) + self.marker._markers = _normalize_extra_values(parsed.marker) + + def _iter_parts(self, name: str) -> Iterator[str]: + yield name + + if self.extras: + formatted_extras = ",".join(sorted(self.extras)) + yield f"[{formatted_extras}]" + + if self.specifier: + yield str(self.specifier) + + if self.url: + yield f"@ {self.url}" + if self.marker: + yield " " + + if self.marker: + yield f"; {self.marker}" + + def __str__(self) -> str: + return "".join(self._iter_parts(self.name)) + + def __repr__(self) -> str: + return f"<Requirement('{self}')>" + + def __hash__(self) -> int: + return hash( + ( + self.__class__.__name__, + *self._iter_parts(canonicalize_name(self.name)), + ) + ) + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, Requirement): + return NotImplemented + + return ( + canonicalize_name(self.name) == canonicalize_name(other.name) + and self.extras == other.extras + and self.specifier == other.specifier + and self.url == other.url + and self.marker == other.marker + ) diff --git a/node_modules/node-gyp/gyp/pylib/packaging/specifiers.py b/node_modules/node-gyp/gyp/pylib/packaging/specifiers.py new file mode 100644 index 0000000000000..94448327ae2d4 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/specifiers.py @@ -0,0 +1,1030 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +""" +.. testsetup:: + + from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier + from packaging.version import Version +""" + +import abc +import itertools +import re +from typing import ( + Callable, + Iterable, + Iterator, + List, + Optional, + Set, + Tuple, + TypeVar, + Union, +) + +from .utils import canonicalize_version +from .version import Version + +UnparsedVersion = Union[Version, str] +UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) +CallableOperator = Callable[[Version, str], bool] + + +def _coerce_version(version: UnparsedVersion) -> Version: + if not isinstance(version, Version): + version = Version(version) + return version + + +class InvalidSpecifier(ValueError): + """ + Raised when attempting to create a :class:`Specifier` with a specifier + string that is invalid. + + >>> Specifier("lolwat") + Traceback (most recent call last): + ... + packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat' + """ + + +class BaseSpecifier(metaclass=abc.ABCMeta): + @abc.abstractmethod + def __str__(self) -> str: + """ + Returns the str representation of this Specifier-like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self) -> int: + """ + Returns a hash value for this Specifier-like object. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Returns a boolean representing whether or not the two Specifier-like + objects are equal. + + :param other: The other object to check against. + """ + + @property + @abc.abstractmethod + def prereleases(self) -> Optional[bool]: + """Whether or not pre-releases as a whole are allowed. + + This can be set to either ``True`` or ``False`` to explicitly enable or disable + prereleases or it can be set to ``None`` (the default) to use default semantics. + """ + + @prereleases.setter + def prereleases(self, value: bool) -> None: + """Setter for :attr:`prereleases`. + + :param value: The value to set. + """ + + @abc.abstractmethod + def contains(self, item: str, prereleases: Optional[bool] = None) -> bool: + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter( + self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None + ) -> Iterator[UnparsedVersionVar]: + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class Specifier(BaseSpecifier): + """This class abstracts handling of version specifiers. + + .. tip:: + + It is generally not required to instantiate this manually. You should instead + prefer to work with :class:`SpecifierSet` instead, which can parse + comma-separated version specifiers (which is what package metadata contains). + """ + + _operator_regex_str = r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + """ + _version_regex_str = r""" + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s;)]* # The arbitrary version can be just about anything, + # we match everything except for whitespace, a + # semi-colon for marker support, and a closing paren + # since versions can be enclosed in them. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + + # You cannot use a wild card and a pre-release, post-release, a dev or + # local version together so group them with a | and make them optional. + (?: + \.\* # Wild card syntax of .* + | + (?: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + + _regex = re.compile( + r"^\s*" + _operator_regex_str + _version_regex_str + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None: + """Initialize a Specifier instance. + + :param spec: + The string representation of a specifier which will be parsed and + normalized before use. + :param prereleases: + This tells the specifier if it should accept prerelease versions if + applicable or not. The default of ``None`` will autodetect it from the + given specifiers. + :raises InvalidSpecifier: + If the given specifier is invalid (i.e. bad syntax). + """ + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier(f"Invalid specifier: '{spec}'") + + self._spec: Tuple[str, str] = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + # https://github.com/python/mypy/pull/13475#pullrequestreview-1079784515 + @property # type: ignore[override] + def prereleases(self) -> bool: + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if Version(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value: bool) -> None: + self._prereleases = value + + @property + def operator(self) -> str: + """The operator of this specifier. + + >>> Specifier("==1.2.3").operator + '==' + """ + return self._spec[0] + + @property + def version(self) -> str: + """The version of this specifier. + + >>> Specifier("==1.2.3").version + '1.2.3' + """ + return self._spec[1] + + def __repr__(self) -> str: + """A representation of the Specifier that shows all internal state. + + >>> Specifier('>=1.0.0') + <Specifier('>=1.0.0')> + >>> Specifier('>=1.0.0', prereleases=False) + <Specifier('>=1.0.0', prereleases=False)> + >>> Specifier('>=1.0.0', prereleases=True) + <Specifier('>=1.0.0', prereleases=True)> + """ + pre = ( + f", prereleases={self.prereleases!r}" + if self._prereleases is not None + else "" + ) + + return f"<{self.__class__.__name__}({str(self)!r}{pre})>" + + def __str__(self) -> str: + """A string representation of the Specifier that can be round-tripped. + + >>> str(Specifier('>=1.0.0')) + '>=1.0.0' + >>> str(Specifier('>=1.0.0', prereleases=False)) + '>=1.0.0' + """ + return "{}{}".format(*self._spec) + + @property + def _canonical_spec(self) -> Tuple[str, str]: + canonical_version = canonicalize_version( + self._spec[1], + strip_trailing_zero=(self._spec[0] != "~="), + ) + return self._spec[0], canonical_version + + def __hash__(self) -> int: + return hash(self._canonical_spec) + + def __eq__(self, other: object) -> bool: + """Whether or not the two Specifier-like objects are equal. + + :param other: The other object to check against. + + The value of :attr:`prereleases` is ignored. + + >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0") + True + >>> (Specifier("==1.2.3", prereleases=False) == + ... Specifier("==1.2.3", prereleases=True)) + True + >>> Specifier("==1.2.3") == "==1.2.3" + True + >>> Specifier("==1.2.3") == Specifier("==1.2.4") + False + >>> Specifier("==1.2.3") == Specifier("~=1.2.3") + False + """ + if isinstance(other, str): + try: + other = self.__class__(str(other)) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._canonical_spec == other._canonical_spec + + def _get_operator(self, op: str) -> CallableOperator: + operator_callable: CallableOperator = getattr( + self, f"_compare_{self._operators[op]}" + ) + return operator_callable + + def _compare_compatible(self, prospective: Version, spec: str) -> bool: + + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore suffix segments. + prefix = _version_join( + list(itertools.takewhile(_is_not_suffix, _version_split(spec)))[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return self._get_operator(">=")(prospective, spec) and self._get_operator("==")( + prospective, prefix + ) + + def _compare_equal(self, prospective: Version, spec: str) -> bool: + + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + normalized_prospective = canonicalize_version( + prospective.public, strip_trailing_zero=False + ) + # Get the normalized version string ignoring the trailing .* + normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False) + # Split the spec out by bangs and dots, and pretend that there is + # an implicit dot in between a release segment and a pre-release segment. + split_spec = _version_split(normalized_spec) + + # Split the prospective version out by bangs and dots, and pretend + # that there is an implicit dot in between a release segment and + # a pre-release segment. + split_prospective = _version_split(normalized_prospective) + + # 0-pad the prospective version before shortening it to get the correct + # shortened version. + padded_prospective, _ = _pad_version(split_prospective, split_spec) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + shortened_prospective = padded_prospective[: len(split_spec)] + + return shortened_prospective == split_spec + else: + # Convert our spec string into a Version + spec_version = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec_version.local: + prospective = Version(prospective.public) + + return prospective == spec_version + + def _compare_not_equal(self, prospective: Version, spec: str) -> bool: + return not self._compare_equal(prospective, spec) + + def _compare_less_than_equal(self, prospective: Version, spec: str) -> bool: + + # NB: Local version identifiers are NOT permitted in the version + # specifier, so local version labels can be universally removed from + # the prospective version. + return Version(prospective.public) <= Version(spec) + + def _compare_greater_than_equal(self, prospective: Version, spec: str) -> bool: + + # NB: Local version identifiers are NOT permitted in the version + # specifier, so local version labels can be universally removed from + # the prospective version. + return Version(prospective.public) >= Version(spec) + + def _compare_less_than(self, prospective: Version, spec_str: str) -> bool: + + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec_str) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + def _compare_greater_than(self, prospective: Version, spec_str: str) -> bool: + + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec_str) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is technically greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective: Version, spec: str) -> bool: + return str(prospective).lower() == str(spec).lower() + + def __contains__(self, item: Union[str, Version]) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: The item to check for. + + This is used for the ``in`` operator and behaves the same as + :meth:`contains` with no ``prereleases`` argument passed. + + >>> "1.2.3" in Specifier(">=1.2.3") + True + >>> Version("1.2.3") in Specifier(">=1.2.3") + True + >>> "1.0.0" in Specifier(">=1.2.3") + False + >>> "1.3.0a1" in Specifier(">=1.2.3") + False + >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True) + True + """ + return self.contains(item) + + def contains( + self, item: UnparsedVersion, prereleases: Optional[bool] = None + ) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: + The item to check for, which can be a version string or a + :class:`Version` instance. + :param prereleases: + Whether or not to match prereleases with this Specifier. If set to + ``None`` (the default), it uses :attr:`prereleases` to determine + whether or not prereleases are allowed. + + >>> Specifier(">=1.2.3").contains("1.2.3") + True + >>> Specifier(">=1.2.3").contains(Version("1.2.3")) + True + >>> Specifier(">=1.2.3").contains("1.0.0") + False + >>> Specifier(">=1.2.3").contains("1.3.0a1") + False + >>> Specifier(">=1.2.3", prereleases=True).contains("1.3.0a1") + True + >>> Specifier(">=1.2.3").contains("1.3.0a1", prereleases=True) + True + """ + + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version, this allows us to have a shortcut for + # "2.0" in Specifier(">=2") + normalized_item = _coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if normalized_item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + operator_callable: CallableOperator = self._get_operator(self.operator) + return operator_callable(normalized_item, self.version) + + def filter( + self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None + ) -> Iterator[UnparsedVersionVar]: + """Filter items in the given iterable, that match the specifier. + + :param iterable: + An iterable that can contain version strings and :class:`Version` instances. + The items in the iterable will be filtered according to the specifier. + :param prereleases: + Whether or not to allow prereleases in the returned iterator. If set to + ``None`` (the default), it will be intelligently decide whether to allow + prereleases or not (based on the :attr:`prereleases` attribute, and + whether the only versions matching are prereleases). + + This method is smarter than just ``filter(Specifier().contains, [...])`` + because it implements the rule from :pep:`440` that a prerelease item + SHOULD be accepted if no other versions match the given specifier. + + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) + ['1.3'] + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")])) + ['1.2.3', '1.3', <Version('1.4')>] + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"])) + ['1.5a1'] + >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + """ + + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = _coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later in case nothing + # else matches this specifier. + if parsed_version.is_prerelease and not ( + prereleases or self.prereleases + ): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version: str) -> List[str]: + """Split version into components. + + The split components are intended for version comparison. The logic does + not attempt to retain the original version string, so joining the + components back with :func:`_version_join` may not produce the original + version string. + """ + result: List[str] = [] + + epoch, _, rest = version.rpartition("!") + result.append(epoch or "0") + + for item in rest.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _version_join(components: List[str]) -> str: + """Join split version components into a version string. + + This function assumes the input came from :func:`_version_split`, where the + first component must be the epoch (either empty or numeric), and all other + components numeric. + """ + epoch, *rest = components + return f"{epoch}!{'.'.join(rest)}" + + +def _is_not_suffix(segment: str) -> bool: + return not any( + segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc", "post") + ) + + +def _pad_version(left: List[str], right: List[str]) -> Tuple[List[str], List[str]]: + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]) :]) + right_split.append(right[len(right_split[0]) :]) + + # Insert our padding + left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0]))) + right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0]))) + + return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split))) + + +class SpecifierSet(BaseSpecifier): + """This class abstracts handling of a set of version specifiers. + + It can be passed a single specifier (``>=3.0``), a comma-separated list of + specifiers (``>=3.0,!=3.1``), or no specifier at all. + """ + + def __init__( + self, specifiers: str = "", prereleases: Optional[bool] = None + ) -> None: + """Initialize a SpecifierSet instance. + + :param specifiers: + The string representation of a specifier or a comma-separated list of + specifiers which will be parsed and normalized before use. + :param prereleases: + This tells the SpecifierSet if it should accept prerelease versions if + applicable or not. The default of ``None`` will autodetect it from the + given specifiers. + + :raises InvalidSpecifier: + If the given ``specifiers`` are not parseable than this exception will be + raised. + """ + + # Split on `,` to break each individual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier. + parsed: Set[Specifier] = set() + for specifier in split_specifiers: + parsed.add(Specifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + @property + def prereleases(self) -> Optional[bool]: + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value: bool) -> None: + self._prereleases = value + + def __repr__(self) -> str: + """A representation of the specifier set that shows all internal state. + + Note that the ordering of the individual specifiers within the set may not + match the input string. + + >>> SpecifierSet('>=1.0.0,!=2.0.0') + <SpecifierSet('!=2.0.0,>=1.0.0')> + >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False) + <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=False)> + >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True) + <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=True)> + """ + pre = ( + f", prereleases={self.prereleases!r}" + if self._prereleases is not None + else "" + ) + + return f"<SpecifierSet({str(self)!r}{pre})>" + + def __str__(self) -> str: + """A string representation of the specifier set that can be round-tripped. + + Note that the ordering of the individual specifiers within the set may not + match the input string. + + >>> str(SpecifierSet(">=1.0.0,!=1.0.1")) + '!=1.0.1,>=1.0.0' + >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False)) + '!=1.0.1,>=1.0.0' + """ + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self) -> int: + return hash(self._specs) + + def __and__(self, other: Union["SpecifierSet", str]) -> "SpecifierSet": + """Return a SpecifierSet which is a combination of the two sets. + + :param other: The other object to combine with. + + >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1' + <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')> + >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1') + <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')> + """ + if isinstance(other, str): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other: object) -> bool: + """Whether or not the two SpecifierSet-like objects are equal. + + :param other: The other object to check against. + + The value of :attr:`prereleases` is ignored. + + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) == + ... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)) + True + >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1" + True + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2") + False + """ + if isinstance(other, (str, Specifier)): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __len__(self) -> int: + """Returns the number of specifiers in this specifier set.""" + return len(self._specs) + + def __iter__(self) -> Iterator[Specifier]: + """ + Returns an iterator over all the underlying :class:`Specifier` instances + in this specifier set. + + >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str) + [<Specifier('!=1.0.1')>, <Specifier('>=1.0.0')>] + """ + return iter(self._specs) + + def __contains__(self, item: UnparsedVersion) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: The item to check for. + + This is used for the ``in`` operator and behaves the same as + :meth:`contains` with no ``prereleases`` argument passed. + + >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1") + False + >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1") + False + >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True) + True + """ + return self.contains(item) + + def contains( + self, + item: UnparsedVersion, + prereleases: Optional[bool] = None, + installed: Optional[bool] = None, + ) -> bool: + """Return whether or not the item is contained in this SpecifierSet. + + :param item: + The item to check for, which can be a version string or a + :class:`Version` instance. + :param prereleases: + Whether or not to match prereleases with this SpecifierSet. If set to + ``None`` (the default), it uses :attr:`prereleases` to determine + whether or not prereleases are allowed. + + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3") + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3")) + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True).contains("1.3.0a1") + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True) + True + """ + # Ensure that our item is a Version instance. + if not isinstance(item, Version): + item = Version(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + if installed and item.is_prerelease: + item = Version(item.base_version) + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all(s.contains(item, prereleases=prereleases) for s in self._specs) + + def filter( + self, iterable: Iterable[UnparsedVersionVar], prereleases: Optional[bool] = None + ) -> Iterator[UnparsedVersionVar]: + """Filter items in the given iterable, that match the specifiers in this set. + + :param iterable: + An iterable that can contain version strings and :class:`Version` instances. + The items in the iterable will be filtered according to the specifier. + :param prereleases: + Whether or not to allow prereleases in the returned iterator. If set to + ``None`` (the default), it will be intelligently decide whether to allow + prereleases or not (based on the :attr:`prereleases` attribute, and + whether the only versions matching are prereleases). + + This method is smarter than just ``filter(SpecifierSet(...).contains, [...])`` + because it implements the rule from :pep:`440` that a prerelease item + SHOULD be accepted if no other versions match the given specifier. + + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) + ['1.3'] + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")])) + ['1.3', <Version('1.4')>] + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"])) + [] + >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + + An "empty" SpecifierSet will filter items based on the presence of prerelease + versions in the set. + + >>> list(SpecifierSet("").filter(["1.3", "1.5a1"])) + ['1.3'] + >>> list(SpecifierSet("").filter(["1.5a1"])) + ['1.5a1'] + >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + """ + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iter(iterable) + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases. + else: + filtered: List[UnparsedVersionVar] = [] + found_prereleases: List[UnparsedVersionVar] = [] + + for item in iterable: + parsed_version = _coerce_version(item) + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return iter(found_prereleases) + + return iter(filtered) diff --git a/node_modules/node-gyp/gyp/pylib/packaging/tags.py b/node_modules/node-gyp/gyp/pylib/packaging/tags.py new file mode 100644 index 0000000000000..37f33b1ef849e --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/tags.py @@ -0,0 +1,553 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import logging +import platform +import struct +import subprocess +import sys +import sysconfig +from importlib.machinery import EXTENSION_SUFFIXES +from typing import ( + Dict, + FrozenSet, + Iterable, + Iterator, + List, + Optional, + Sequence, + Tuple, + Union, + cast, +) + +from . import _manylinux, _musllinux + +logger = logging.getLogger(__name__) + +PythonVersion = Sequence[int] +MacVersion = Tuple[int, int] + +INTERPRETER_SHORT_NAMES: Dict[str, str] = { + "python": "py", # Generic. + "cpython": "cp", + "pypy": "pp", + "ironpython": "ip", + "jython": "jy", +} + + +_32_BIT_INTERPRETER = struct.calcsize("P") == 4 + + +class Tag: + """ + A representation of the tag triple for a wheel. + + Instances are considered immutable and thus are hashable. Equality checking + is also supported. + """ + + __slots__ = ["_interpreter", "_abi", "_platform", "_hash"] + + def __init__(self, interpreter: str, abi: str, platform: str) -> None: + self._interpreter = interpreter.lower() + self._abi = abi.lower() + self._platform = platform.lower() + # The __hash__ of every single element in a Set[Tag] will be evaluated each time + # that a set calls its `.disjoint()` method, which may be called hundreds of + # times when scanning a page of links for packages with tags matching that + # Set[Tag]. Pre-computing the value here produces significant speedups for + # downstream consumers. + self._hash = hash((self._interpreter, self._abi, self._platform)) + + @property + def interpreter(self) -> str: + return self._interpreter + + @property + def abi(self) -> str: + return self._abi + + @property + def platform(self) -> str: + return self._platform + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Tag): + return NotImplemented + + return ( + (self._hash == other._hash) # Short-circuit ASAP for perf reasons. + and (self._platform == other._platform) + and (self._abi == other._abi) + and (self._interpreter == other._interpreter) + ) + + def __hash__(self) -> int: + return self._hash + + def __str__(self) -> str: + return f"{self._interpreter}-{self._abi}-{self._platform}" + + def __repr__(self) -> str: + return f"<{self} @ {id(self)}>" + + +def parse_tag(tag: str) -> FrozenSet[Tag]: + """ + Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag instances. + + Returning a set is required due to the possibility that the tag is a + compressed tag set. + """ + tags = set() + interpreters, abis, platforms = tag.split("-") + for interpreter in interpreters.split("."): + for abi in abis.split("."): + for platform_ in platforms.split("."): + tags.add(Tag(interpreter, abi, platform_)) + return frozenset(tags) + + +def _get_config_var(name: str, warn: bool = False) -> Union[int, str, None]: + value: Union[int, str, None] = sysconfig.get_config_var(name) + if value is None and warn: + logger.debug( + "Config variable '%s' is unset, Python ABI tag may be incorrect", name + ) + return value + + +def _normalize_string(string: str) -> str: + return string.replace(".", "_").replace("-", "_").replace(" ", "_") + + +def _abi3_applies(python_version: PythonVersion) -> bool: + """ + Determine if the Python version supports abi3. + + PEP 384 was first implemented in Python 3.2. + """ + return len(python_version) > 1 and tuple(python_version) >= (3, 2) + + +def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> List[str]: + py_version = tuple(py_version) # To allow for version comparison. + abis = [] + version = _version_nodot(py_version[:2]) + debug = pymalloc = ucs4 = "" + with_debug = _get_config_var("Py_DEBUG", warn) + has_refcount = hasattr(sys, "gettotalrefcount") + # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled + # extension modules is the best option. + # https://github.com/pypa/pip/issues/3383#issuecomment-173267692 + has_ext = "_d.pyd" in EXTENSION_SUFFIXES + if with_debug or (with_debug is None and (has_refcount or has_ext)): + debug = "d" + if py_version < (3, 8): + with_pymalloc = _get_config_var("WITH_PYMALLOC", warn) + if with_pymalloc or with_pymalloc is None: + pymalloc = "m" + if py_version < (3, 3): + unicode_size = _get_config_var("Py_UNICODE_SIZE", warn) + if unicode_size == 4 or ( + unicode_size is None and sys.maxunicode == 0x10FFFF + ): + ucs4 = "u" + elif debug: + # Debug builds can also load "normal" extension modules. + # We can also assume no UCS-4 or pymalloc requirement. + abis.append(f"cp{version}") + abis.insert( + 0, + "cp{version}{debug}{pymalloc}{ucs4}".format( + version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4 + ), + ) + return abis + + +def cpython_tags( + python_version: Optional[PythonVersion] = None, + abis: Optional[Iterable[str]] = None, + platforms: Optional[Iterable[str]] = None, + *, + warn: bool = False, +) -> Iterator[Tag]: + """ + Yields the tags for a CPython interpreter. + + The tags consist of: + - cp<python_version>-<abi>-<platform> + - cp<python_version>-abi3-<platform> + - cp<python_version>-none-<platform> + - cp<less than python_version>-abi3-<platform> # Older Python versions down to 3.2. + + If python_version only specifies a major version then user-provided ABIs and + the 'none' ABItag will be used. + + If 'abi3' or 'none' are specified in 'abis' then they will be yielded at + their normal position and not at the beginning. + """ + if not python_version: + python_version = sys.version_info[:2] + + interpreter = f"cp{_version_nodot(python_version[:2])}" + + if abis is None: + if len(python_version) > 1: + abis = _cpython_abis(python_version, warn) + else: + abis = [] + abis = list(abis) + # 'abi3' and 'none' are explicitly handled later. + for explicit_abi in ("abi3", "none"): + try: + abis.remove(explicit_abi) + except ValueError: + pass + + platforms = list(platforms or platform_tags()) + for abi in abis: + for platform_ in platforms: + yield Tag(interpreter, abi, platform_) + if _abi3_applies(python_version): + yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms) + yield from (Tag(interpreter, "none", platform_) for platform_ in platforms) + + if _abi3_applies(python_version): + for minor_version in range(python_version[1] - 1, 1, -1): + for platform_ in platforms: + interpreter = "cp{version}".format( + version=_version_nodot((python_version[0], minor_version)) + ) + yield Tag(interpreter, "abi3", platform_) + + +def _generic_abi() -> List[str]: + """ + Return the ABI tag based on EXT_SUFFIX. + """ + # The following are examples of `EXT_SUFFIX`. + # We want to keep the parts which are related to the ABI and remove the + # parts which are related to the platform: + # - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310 + # - mac: '.cpython-310-darwin.so' => cp310 + # - win: '.cp310-win_amd64.pyd' => cp310 + # - win: '.pyd' => cp37 (uses _cpython_abis()) + # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73 + # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib' + # => graalpy_38_native + + ext_suffix = _get_config_var("EXT_SUFFIX", warn=True) + if not isinstance(ext_suffix, str) or ext_suffix[0] != ".": + raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") + parts = ext_suffix.split(".") + if len(parts) < 3: + # CPython3.7 and earlier uses ".pyd" on Windows. + return _cpython_abis(sys.version_info[:2]) + soabi = parts[1] + if soabi.startswith("cpython"): + # non-windows + abi = "cp" + soabi.split("-")[1] + elif soabi.startswith("cp"): + # windows + abi = soabi.split("-")[0] + elif soabi.startswith("pypy"): + abi = "-".join(soabi.split("-")[:2]) + elif soabi.startswith("graalpy"): + abi = "-".join(soabi.split("-")[:3]) + elif soabi: + # pyston, ironpython, others? + abi = soabi + else: + return [] + return [_normalize_string(abi)] + + +def generic_tags( + interpreter: Optional[str] = None, + abis: Optional[Iterable[str]] = None, + platforms: Optional[Iterable[str]] = None, + *, + warn: bool = False, +) -> Iterator[Tag]: + """ + Yields the tags for a generic interpreter. + + The tags consist of: + - <interpreter>-<abi>-<platform> + + The "none" ABI will be added if it was not explicitly provided. + """ + if not interpreter: + interp_name = interpreter_name() + interp_version = interpreter_version(warn=warn) + interpreter = "".join([interp_name, interp_version]) + if abis is None: + abis = _generic_abi() + else: + abis = list(abis) + platforms = list(platforms or platform_tags()) + if "none" not in abis: + abis.append("none") + for abi in abis: + for platform_ in platforms: + yield Tag(interpreter, abi, platform_) + + +def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]: + """ + Yields Python versions in descending order. + + After the latest version, the major-only version will be yielded, and then + all previous versions of that major version. + """ + if len(py_version) > 1: + yield f"py{_version_nodot(py_version[:2])}" + yield f"py{py_version[0]}" + if len(py_version) > 1: + for minor in range(py_version[1] - 1, -1, -1): + yield f"py{_version_nodot((py_version[0], minor))}" + + +def compatible_tags( + python_version: Optional[PythonVersion] = None, + interpreter: Optional[str] = None, + platforms: Optional[Iterable[str]] = None, +) -> Iterator[Tag]: + """ + Yields the sequence of tags that are compatible with a specific version of Python. + + The tags consist of: + - py*-none-<platform> + - <interpreter>-none-any # ... if `interpreter` is provided. + - py*-none-any + """ + if not python_version: + python_version = sys.version_info[:2] + platforms = list(platforms or platform_tags()) + for version in _py_interpreter_range(python_version): + for platform_ in platforms: + yield Tag(version, "none", platform_) + if interpreter: + yield Tag(interpreter, "none", "any") + for version in _py_interpreter_range(python_version): + yield Tag(version, "none", "any") + + +def _mac_arch(arch: str, is_32bit: bool = _32_BIT_INTERPRETER) -> str: + if not is_32bit: + return arch + + if arch.startswith("ppc"): + return "ppc" + + return "i386" + + +def _mac_binary_formats(version: MacVersion, cpu_arch: str) -> List[str]: + formats = [cpu_arch] + if cpu_arch == "x86_64": + if version < (10, 4): + return [] + formats.extend(["intel", "fat64", "fat32"]) + + elif cpu_arch == "i386": + if version < (10, 4): + return [] + formats.extend(["intel", "fat32", "fat"]) + + elif cpu_arch == "ppc64": + # TODO: Need to care about 32-bit PPC for ppc64 through 10.2? + if version > (10, 5) or version < (10, 4): + return [] + formats.append("fat64") + + elif cpu_arch == "ppc": + if version > (10, 6): + return [] + formats.extend(["fat32", "fat"]) + + if cpu_arch in {"arm64", "x86_64"}: + formats.append("universal2") + + if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}: + formats.append("universal") + + return formats + + +def mac_platforms( + version: Optional[MacVersion] = None, arch: Optional[str] = None +) -> Iterator[str]: + """ + Yields the platform tags for a macOS system. + + The `version` parameter is a two-item tuple specifying the macOS version to + generate platform tags for. The `arch` parameter is the CPU architecture to + generate platform tags for. Both parameters default to the appropriate value + for the current system. + """ + version_str, _, cpu_arch = platform.mac_ver() + if version is None: + version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2]))) + if version == (10, 16): + # When built against an older macOS SDK, Python will report macOS 10.16 + # instead of the real version. + version_str = subprocess.run( + [ + sys.executable, + "-sS", + "-c", + "import platform; print(platform.mac_ver()[0])", + ], + check=True, + env={"SYSTEM_VERSION_COMPAT": "0"}, + stdout=subprocess.PIPE, + text=True, + ).stdout + version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2]))) + else: + version = version + if arch is None: + arch = _mac_arch(cpu_arch) + else: + arch = arch + + if (10, 0) <= version and version < (11, 0): + # Prior to Mac OS 11, each yearly release of Mac OS bumped the + # "minor" version number. The major version was always 10. + for minor_version in range(version[1], -1, -1): + compat_version = 10, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=10, minor=minor_version, binary_format=binary_format + ) + + if version >= (11, 0): + # Starting with Mac OS 11, each yearly release bumps the major version + # number. The minor versions are now the midyear updates. + for major_version in range(version[0], 10, -1): + compat_version = major_version, 0 + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=major_version, minor=0, binary_format=binary_format + ) + + if version >= (11, 0): + # Mac OS 11 on x86_64 is compatible with binaries from previous releases. + # Arm64 support was introduced in 11.0, so no Arm binaries from previous + # releases exist. + # + # However, the "universal2" binary format can have a + # macOS version earlier than 11.0 when the x86_64 part of the binary supports + # that version of macOS. + if arch == "x86_64": + for minor_version in range(16, 3, -1): + compat_version = 10, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=compat_version[0], + minor=compat_version[1], + binary_format=binary_format, + ) + else: + for minor_version in range(16, 3, -1): + compat_version = 10, minor_version + binary_format = "universal2" + yield "macosx_{major}_{minor}_{binary_format}".format( + major=compat_version[0], + minor=compat_version[1], + binary_format=binary_format, + ) + + +def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]: + linux = _normalize_string(sysconfig.get_platform()) + if not linux.startswith("linux_"): + # we should never be here, just yield the sysconfig one and return + yield linux + return + if is_32bit: + if linux == "linux_x86_64": + linux = "linux_i686" + elif linux == "linux_aarch64": + linux = "linux_armv8l" + _, arch = linux.split("_", 1) + archs = {"armv8l": ["armv8l", "armv7l"]}.get(arch, [arch]) + yield from _manylinux.platform_tags(archs) + yield from _musllinux.platform_tags(archs) + for arch in archs: + yield f"linux_{arch}" + + +def _generic_platforms() -> Iterator[str]: + yield _normalize_string(sysconfig.get_platform()) + + +def platform_tags() -> Iterator[str]: + """ + Provides the platform tags for this installation. + """ + if platform.system() == "Darwin": + return mac_platforms() + elif platform.system() == "Linux": + return _linux_platforms() + else: + return _generic_platforms() + + +def interpreter_name() -> str: + """ + Returns the name of the running interpreter. + + Some implementations have a reserved, two-letter abbreviation which will + be returned when appropriate. + """ + name = sys.implementation.name + return INTERPRETER_SHORT_NAMES.get(name) or name + + +def interpreter_version(*, warn: bool = False) -> str: + """ + Returns the version of the running interpreter. + """ + version = _get_config_var("py_version_nodot", warn=warn) + if version: + version = str(version) + else: + version = _version_nodot(sys.version_info[:2]) + return version + + +def _version_nodot(version: PythonVersion) -> str: + return "".join(map(str, version)) + + +def sys_tags(*, warn: bool = False) -> Iterator[Tag]: + """ + Returns the sequence of tag triples for the running interpreter. + + The order of the sequence corresponds to priority order for the + interpreter, from most to least important. + """ + + interp_name = interpreter_name() + if interp_name == "cp": + yield from cpython_tags(warn=warn) + else: + yield from generic_tags() + + if interp_name == "pp": + interp = "pp3" + elif interp_name == "cp": + interp = "cp" + interpreter_version(warn=warn) + else: + interp = None + yield from compatible_tags(interpreter=interp) diff --git a/node_modules/node-gyp/gyp/pylib/packaging/utils.py b/node_modules/node-gyp/gyp/pylib/packaging/utils.py new file mode 100644 index 0000000000000..c2c2f75aa8062 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/utils.py @@ -0,0 +1,172 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import re +from typing import FrozenSet, NewType, Tuple, Union, cast + +from .tags import Tag, parse_tag +from .version import InvalidVersion, Version + +BuildTag = Union[Tuple[()], Tuple[int, str]] +NormalizedName = NewType("NormalizedName", str) + + +class InvalidName(ValueError): + """ + An invalid distribution name; users should refer to the packaging user guide. + """ + + +class InvalidWheelFilename(ValueError): + """ + An invalid wheel filename was found, users should refer to PEP 427. + """ + + +class InvalidSdistFilename(ValueError): + """ + An invalid sdist filename was found, users should refer to the packaging user guide. + """ + + +# Core metadata spec for `Name` +_validate_regex = re.compile( + r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE +) +_canonicalize_regex = re.compile(r"[-_.]+") +_normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$") +# PEP 427: The build number must start with a digit. +_build_tag_regex = re.compile(r"(\d+)(.*)") + + +def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName: + if validate and not _validate_regex.match(name): + raise InvalidName(f"name is invalid: {name!r}") + # This is taken from PEP 503. + value = _canonicalize_regex.sub("-", name).lower() + return cast(NormalizedName, value) + + +def is_normalized_name(name: str) -> bool: + return _normalized_regex.match(name) is not None + + +def canonicalize_version( + version: Union[Version, str], *, strip_trailing_zero: bool = True +) -> str: + """ + This is very similar to Version.__str__, but has one subtle difference + with the way it handles the release segment. + """ + if isinstance(version, str): + try: + parsed = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + else: + parsed = version + + parts = [] + + # Epoch + if parsed.epoch != 0: + parts.append(f"{parsed.epoch}!") + + # Release segment + release_segment = ".".join(str(x) for x in parsed.release) + if strip_trailing_zero: + # NB: This strips trailing '.0's to normalize + release_segment = re.sub(r"(\.0)+$", "", release_segment) + parts.append(release_segment) + + # Pre-release + if parsed.pre is not None: + parts.append("".join(str(x) for x in parsed.pre)) + + # Post-release + if parsed.post is not None: + parts.append(f".post{parsed.post}") + + # Development release + if parsed.dev is not None: + parts.append(f".dev{parsed.dev}") + + # Local version segment + if parsed.local is not None: + parts.append(f"+{parsed.local}") + + return "".join(parts) + + +def parse_wheel_filename( + filename: str, +) -> Tuple[NormalizedName, Version, BuildTag, FrozenSet[Tag]]: + if not filename.endswith(".whl"): + raise InvalidWheelFilename( + f"Invalid wheel filename (extension must be '.whl'): {filename}" + ) + + filename = filename[:-4] + dashes = filename.count("-") + if dashes not in (4, 5): + raise InvalidWheelFilename( + f"Invalid wheel filename (wrong number of parts): {filename}" + ) + + parts = filename.split("-", dashes - 2) + name_part = parts[0] + # See PEP 427 for the rules on escaping the project name. + if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None: + raise InvalidWheelFilename(f"Invalid project name: {filename}") + name = canonicalize_name(name_part) + + try: + version = Version(parts[1]) + except InvalidVersion as e: + raise InvalidWheelFilename( + f"Invalid wheel filename (invalid version): {filename}" + ) from e + + if dashes == 5: + build_part = parts[2] + build_match = _build_tag_regex.match(build_part) + if build_match is None: + raise InvalidWheelFilename( + f"Invalid build number: {build_part} in '{filename}'" + ) + build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2))) + else: + build = () + tags = parse_tag(parts[-1]) + return (name, version, build, tags) + + +def parse_sdist_filename(filename: str) -> Tuple[NormalizedName, Version]: + if filename.endswith(".tar.gz"): + file_stem = filename[: -len(".tar.gz")] + elif filename.endswith(".zip"): + file_stem = filename[: -len(".zip")] + else: + raise InvalidSdistFilename( + f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):" + f" {filename}" + ) + + # We are requiring a PEP 440 version, which cannot contain dashes, + # so we split on the last dash. + name_part, sep, version_part = file_stem.rpartition("-") + if not sep: + raise InvalidSdistFilename(f"Invalid sdist filename: {filename}") + + name = canonicalize_name(name_part) + + try: + version = Version(version_part) + except InvalidVersion as e: + raise InvalidSdistFilename( + f"Invalid sdist filename (invalid version): {filename}" + ) from e + + return (name, version) diff --git a/node_modules/node-gyp/gyp/pylib/packaging/version.py b/node_modules/node-gyp/gyp/pylib/packaging/version.py new file mode 100644 index 0000000000000..5faab9bd0dcf2 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/packaging/version.py @@ -0,0 +1,563 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +""" +.. testsetup:: + + from packaging.version import parse, Version +""" + +import itertools +import re +from typing import Any, Callable, NamedTuple, Optional, SupportsInt, Tuple, Union + +from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType + +__all__ = ["VERSION_PATTERN", "parse", "Version", "InvalidVersion"] + +LocalType = Tuple[Union[int, str], ...] + +CmpPrePostDevType = Union[InfinityType, NegativeInfinityType, Tuple[str, int]] +CmpLocalType = Union[ + NegativeInfinityType, + Tuple[Union[Tuple[int, str], Tuple[NegativeInfinityType, Union[int, str]]], ...], +] +CmpKey = Tuple[ + int, + Tuple[int, ...], + CmpPrePostDevType, + CmpPrePostDevType, + CmpPrePostDevType, + CmpLocalType, +] +VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool] + + +class _Version(NamedTuple): + epoch: int + release: Tuple[int, ...] + dev: Optional[Tuple[str, int]] + pre: Optional[Tuple[str, int]] + post: Optional[Tuple[str, int]] + local: Optional[LocalType] + + +def parse(version: str) -> "Version": + """Parse the given version string. + + >>> parse('1.0.dev1') + <Version('1.0.dev1')> + + :param version: The version string to parse. + :raises InvalidVersion: When the version string is not a valid version. + """ + return Version(version) + + +class InvalidVersion(ValueError): + """Raised when a version string is not a valid version. + + >>> Version("invalid") + Traceback (most recent call last): + ... + packaging.version.InvalidVersion: Invalid version: 'invalid' + """ + + +class _BaseVersion: + _key: Tuple[Any, ...] + + def __hash__(self) -> int: + return hash(self._key) + + # Please keep the duplicated `isinstance` check + # in the six comparisons hereunder + # unless you find a way to avoid adding overhead function calls. + def __lt__(self, other: "_BaseVersion") -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key < other._key + + def __le__(self, other: "_BaseVersion") -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key <= other._key + + def __eq__(self, other: object) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key == other._key + + def __ge__(self, other: "_BaseVersion") -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key >= other._key + + def __gt__(self, other: "_BaseVersion") -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key > other._key + + def __ne__(self, other: object) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key != other._key + + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +_VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>alpha|a|beta|b|preview|pre|c|rc) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + +VERSION_PATTERN = _VERSION_PATTERN +""" +A string containing the regular expression used to match a valid version. + +The pattern is not anchored at either end, and is intended for embedding in larger +expressions (for example, matching a version number as part of a file name). The +regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE`` +flags set. + +:meta hide-value: +""" + + +class Version(_BaseVersion): + """This class abstracts handling of a project's versions. + + A :class:`Version` instance is comparison aware and can be compared and + sorted using the standard Python interfaces. + + >>> v1 = Version("1.0a5") + >>> v2 = Version("1.0") + >>> v1 + <Version('1.0a5')> + >>> v2 + <Version('1.0')> + >>> v1 < v2 + True + >>> v1 == v2 + False + >>> v1 > v2 + False + >>> v1 >= v2 + False + >>> v1 <= v2 + True + """ + + _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) + _key: CmpKey + + def __init__(self, version: str) -> None: + """Initialize a Version object. + + :param version: + The string representation of a version which will be parsed and normalized + before use. + :raises InvalidVersion: + If the ``version`` does not conform to PEP 440 in any way then this + exception will be raised. + """ + + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion(f"Invalid version: '{version}'") + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")), + post=_parse_letter_version( + match.group("post_l"), match.group("post_n1") or match.group("post_n2") + ), + dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self) -> str: + """A representation of the Version that shows all internal state. + + >>> Version('1.0.0') + <Version('1.0.0')> + """ + return f"<Version('{self}')>" + + def __str__(self) -> str: + """A string representation of the version that can be rounded-tripped. + + >>> str(Version("1.0a5")) + '1.0a5' + """ + parts = [] + + # Epoch + if self.epoch != 0: + parts.append(f"{self.epoch}!") + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) + + # Post-release + if self.post is not None: + parts.append(f".post{self.post}") + + # Development release + if self.dev is not None: + parts.append(f".dev{self.dev}") + + # Local version segment + if self.local is not None: + parts.append(f"+{self.local}") + + return "".join(parts) + + @property + def epoch(self) -> int: + """The epoch of the version. + + >>> Version("2.0.0").epoch + 0 + >>> Version("1!2.0.0").epoch + 1 + """ + return self._version.epoch + + @property + def release(self) -> Tuple[int, ...]: + """The components of the "release" segment of the version. + + >>> Version("1.2.3").release + (1, 2, 3) + >>> Version("2.0.0").release + (2, 0, 0) + >>> Version("1!2.0.0.post0").release + (2, 0, 0) + + Includes trailing zeroes but not the epoch or any pre-release / development / + post-release suffixes. + """ + return self._version.release + + @property + def pre(self) -> Optional[Tuple[str, int]]: + """The pre-release segment of the version. + + >>> print(Version("1.2.3").pre) + None + >>> Version("1.2.3a1").pre + ('a', 1) + >>> Version("1.2.3b1").pre + ('b', 1) + >>> Version("1.2.3rc1").pre + ('rc', 1) + """ + return self._version.pre + + @property + def post(self) -> Optional[int]: + """The post-release number of the version. + + >>> print(Version("1.2.3").post) + None + >>> Version("1.2.3.post1").post + 1 + """ + return self._version.post[1] if self._version.post else None + + @property + def dev(self) -> Optional[int]: + """The development number of the version. + + >>> print(Version("1.2.3").dev) + None + >>> Version("1.2.3.dev1").dev + 1 + """ + return self._version.dev[1] if self._version.dev else None + + @property + def local(self) -> Optional[str]: + """The local version segment of the version. + + >>> print(Version("1.2.3").local) + None + >>> Version("1.2.3+abc").local + 'abc' + """ + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + + @property + def public(self) -> str: + """The public portion of the version. + + >>> Version("1.2.3").public + '1.2.3' + >>> Version("1.2.3+abc").public + '1.2.3' + >>> Version("1.2.3+abc.dev1").public + '1.2.3' + """ + return str(self).split("+", 1)[0] + + @property + def base_version(self) -> str: + """The "base version" of the version. + + >>> Version("1.2.3").base_version + '1.2.3' + >>> Version("1.2.3+abc").base_version + '1.2.3' + >>> Version("1!1.2.3+abc.dev1").base_version + '1!1.2.3' + + The "base version" is the public version of the project without any pre or post + release markers. + """ + parts = [] + + # Epoch + if self.epoch != 0: + parts.append(f"{self.epoch}!") + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + return "".join(parts) + + @property + def is_prerelease(self) -> bool: + """Whether this version is a pre-release. + + >>> Version("1.2.3").is_prerelease + False + >>> Version("1.2.3a1").is_prerelease + True + >>> Version("1.2.3b1").is_prerelease + True + >>> Version("1.2.3rc1").is_prerelease + True + >>> Version("1.2.3dev1").is_prerelease + True + """ + return self.dev is not None or self.pre is not None + + @property + def is_postrelease(self) -> bool: + """Whether this version is a post-release. + + >>> Version("1.2.3").is_postrelease + False + >>> Version("1.2.3.post1").is_postrelease + True + """ + return self.post is not None + + @property + def is_devrelease(self) -> bool: + """Whether this version is a development release. + + >>> Version("1.2.3").is_devrelease + False + >>> Version("1.2.3.dev1").is_devrelease + True + """ + return self.dev is not None + + @property + def major(self) -> int: + """The first item of :attr:`release` or ``0`` if unavailable. + + >>> Version("1.2.3").major + 1 + """ + return self.release[0] if len(self.release) >= 1 else 0 + + @property + def minor(self) -> int: + """The second item of :attr:`release` or ``0`` if unavailable. + + >>> Version("1.2.3").minor + 2 + >>> Version("1").minor + 0 + """ + return self.release[1] if len(self.release) >= 2 else 0 + + @property + def micro(self) -> int: + """The third item of :attr:`release` or ``0`` if unavailable. + + >>> Version("1.2.3").micro + 3 + >>> Version("1").micro + 0 + """ + return self.release[2] if len(self.release) >= 3 else 0 + + +def _parse_letter_version( + letter: Optional[str], number: Union[str, bytes, SupportsInt, None] +) -> Optional[Tuple[str, int]]: + + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + return None + + +_local_version_separators = re.compile(r"[\._-]") + + +def _parse_local_version(local: Optional[str]) -> Optional[LocalType]: + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_separators.split(local) + ) + return None + + +def _cmpkey( + epoch: int, + release: Tuple[int, ...], + pre: Optional[Tuple[str, int]], + post: Optional[Tuple[str, int]], + dev: Optional[Tuple[str, int]], + local: Optional[LocalType], +) -> CmpKey: + + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + _release = tuple( + reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + _pre: CmpPrePostDevType = NegativeInfinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + _pre = Infinity + else: + _pre = pre + + # Versions without a post segment should sort before those with one. + if post is None: + _post: CmpPrePostDevType = NegativeInfinity + + else: + _post = post + + # Versions without a development segment should sort after those with one. + if dev is None: + _dev: CmpPrePostDevType = Infinity + + else: + _dev = dev + + if local is None: + # Versions without a local segment should sort before those with one. + _local: CmpLocalType = NegativeInfinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + _local = tuple( + (i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local + ) + + return epoch, _release, _pre, _post, _dev, _local diff --git a/node_modules/node-gyp/gyp/pyproject.toml b/node_modules/node-gyp/gyp/pyproject.toml new file mode 100644 index 0000000000000..fa30c8cf96da6 --- /dev/null +++ b/node_modules/node-gyp/gyp/pyproject.toml @@ -0,0 +1,114 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "gyp-next" +version = "0.21.1" +authors = [ + { name="Node.js contributors", email="ryzokuken@disroot.org" }, +] +description = "A fork of the GYP build system for use in the Node.js projects" +readme = "README.md" +license = { file="LICENSE" } +requires-python = ">=3.8" +dependencies = ["packaging>=24.0", "setuptools>=69.5.1"] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] + +[project.optional-dependencies] +dev = ["pytest", "ruff"] + +[project.scripts] +gyp = "gyp:script_main" + +[project.urls] +"Homepage" = "https://github.com/nodejs/gyp-next" + +[tool.ruff] +extend-exclude = ["pylib/packaging"] +line-length = 88 + +[tool.ruff.lint] +select = [ + "C4", # flake8-comprehensions + "C90", # McCabe cyclomatic complexity + "DTZ", # flake8-datetimez + "E", # pycodestyle + "F", # Pyflakes + "G", # flake8-logging-format + "ICN", # flake8-import-conventions + "INT", # flake8-gettext + "PL", # Pylint + "PYI", # flake8-pyi + "RSE", # flake8-raise + "RUF", # Ruff-specific rules + "T10", # flake8-debugger + "TCH", # flake8-type-checking + "TID", # flake8-tidy-imports + "UP", # pyupgrade + "W", # pycodestyle + "YTT", # flake8-2020 + # "A", # flake8-builtins + # "ANN", # flake8-annotations + # "ARG", # flake8-unused-arguments + # "B", # flake8-bugbear + # "BLE", # flake8-blind-except + # "COM", # flake8-commas + # "D", # pydocstyle + # "DJ", # flake8-django + # "EM", # flake8-errmsg + # "ERA", # eradicate + # "EXE", # flake8-executable + # "FBT", # flake8-boolean-trap + # "I", # isort + # "INP", # flake8-no-pep420 + # "ISC", # flake8-implicit-str-concat + # "N", # pep8-naming + # "NPY", # NumPy-specific rules + # "PD", # pandas-vet + # "PGH", # pygrep-hooks + # "PIE", # flake8-pie + # "PT", # flake8-pytest-style + # "PTH", # flake8-use-pathlib + # "Q", # flake8-quotes + # "RET", # flake8-return + # "S", # flake8-bandit + # "SIM", # flake8-simplify + # "SLF", # flake8-self + # "T20", # flake8-print + # "TRY", # tryceratops +] +ignore = [ + "PLR1714", + "PLW0603", + "PLW2901", + "RUF005", + "RUF012", + "UP031", +] + +[tool.ruff.lint.mccabe] +max-complexity = 101 + +[tool.ruff.lint.pylint] +allow-magic-value-types = ["float", "int", "str"] +max-args = 11 +max-branches = 108 +max-returns = 10 +max-statements = 286 + +[tool.setuptools] +package-dir = {"" = "pylib"} +packages = ["gyp", "gyp.generator"] diff --git a/node_modules/node-gyp/gyp/release-please-config.json b/node_modules/node-gyp/gyp/release-please-config.json new file mode 100644 index 0000000000000..b6cad32a2dd0e --- /dev/null +++ b/node_modules/node-gyp/gyp/release-please-config.json @@ -0,0 +1,11 @@ +{ + "last-release-sha": "78756421b0d7bb335992a9c7d26ba3cc8b619708", + "packages": { + ".": { + "release-type": "python", + "package-name": "gyp-next", + "bump-minor-pre-major": true, + "include-component-in-tag": false + } + } +} diff --git a/node_modules/node-gyp/gyp/requirements_dev.txt b/node_modules/node-gyp/gyp/requirements_dev.txt deleted file mode 100644 index 28ecacab60293..0000000000000 --- a/node_modules/node-gyp/gyp/requirements_dev.txt +++ /dev/null @@ -1,2 +0,0 @@ -flake8 -pytest diff --git a/node_modules/node-gyp/gyp/setup.py b/node_modules/node-gyp/gyp/setup.py deleted file mode 100644 index cf9d7d2e56c49..0000000000000 --- a/node_modules/node-gyp/gyp/setup.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2009 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -from os import path - -from setuptools import setup - -here = path.abspath(path.dirname(__file__)) -# Get the long description from the README file -with open(path.join(here, "README.md")) as in_file: - long_description = in_file.read() - -setup( - name="gyp-next", - version="0.10.0", - description="A fork of the GYP build system for use in the Node.js projects", - long_description=long_description, - long_description_content_type="text/markdown", - author="Node.js contributors", - author_email="ryzokuken@disroot.org", - url="https://github.com/nodejs/gyp-next", - package_dir={"": "pylib"}, - packages=["gyp", "gyp.generator"], - entry_points={"console_scripts": ["gyp=gyp:script_main"]}, - python_requires=">=3.6", - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - ], -) diff --git a/node_modules/node-gyp/gyp/test_gyp.py b/node_modules/node-gyp/gyp/test_gyp.py index 9ba264170f43a..70c81ae8ca3bf 100755 --- a/node_modules/node-gyp/gyp/test_gyp.py +++ b/node_modules/node-gyp/gyp/test_gyp.py @@ -5,7 +5,6 @@ """gyptest.py -- test runner for GYP tests.""" - import argparse import os import platform @@ -116,6 +115,7 @@ def main(argv=None): else: format_list = { "aix5": ["make"], + "os400": ["make"], "freebsd7": ["make"], "freebsd8": ["make"], "openbsd5": ["make"], @@ -147,13 +147,13 @@ def print_configuration_info(): print("Test configuration:") if sys.platform == "darwin": sys.path.append(os.path.abspath("test/lib")) - import TestMac + import TestMac # noqa: PLC0415 print(f" Mac {platform.mac_ver()[0]} {platform.mac_ver()[2]}") print(f" Xcode {TestMac.Xcode.Version()}") elif sys.platform == "win32": sys.path.append(os.path.abspath("pylib")) - import gyp.MSVSVersion + import gyp.MSVSVersion # noqa: PLC0415 print(" Win %s %s\n" % platform.win32_ver()[0:2]) print(" MSVS %s" % gyp.MSVSVersion.SelectVisualStudioVersion().Description()) diff --git a/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec b/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec deleted file mode 100644 index 85e2e268a51b7..0000000000000 --- a/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec +++ /dev/null @@ -1,27 +0,0 @@ -/* - gyp.pbfilespec - GYP source file spec for Xcode 3 - - There is not much documentation available regarding the format - of .pbfilespec files. As a starting point, see for instance the - outdated documentation at: - http://maxao.free.fr/xcode-plugin-interface/specifications.html - and the files in: - /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/ - - Place this file in directory: - ~/Library/Application Support/Developer/Shared/Xcode/Specifications/ -*/ - -( - { - Identifier = sourcecode.gyp; - BasedOn = sourcecode; - Name = "GYP Files"; - Extensions = ("gyp", "gypi"); - MIMETypes = ("text/gyp"); - Language = "xcode.lang.gyp"; - IsTextFile = YES; - IsSourceFile = YES; - } -) diff --git a/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec b/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec deleted file mode 100644 index 3b3506d319e0f..0000000000000 --- a/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec +++ /dev/null @@ -1,226 +0,0 @@ -/* - Copyright (c) 2011 Google Inc. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. - - gyp.xclangspec - GYP language specification for Xcode 3 - - There is not much documentation available regarding the format - of .xclangspec files. As a starting point, see for instance the - outdated documentation at: - http://maxao.free.fr/xcode-plugin-interface/specifications.html - and the files in: - /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/ - - Place this file in directory: - ~/Library/Application Support/Developer/Shared/Xcode/Specifications/ -*/ - -( - - { - Identifier = "xcode.lang.gyp.keyword"; - Syntax = { - Words = ( - "and", - "or", - "<!", - "<", - ); - Type = "xcode.syntax.keyword"; - }; - }, - - { - Identifier = "xcode.lang.gyp.target.declarator"; - Syntax = { - Words = ( - "'target_name'", - ); - Type = "xcode.syntax.identifier.type"; - }; - }, - - { - Identifier = "xcode.lang.gyp.string.singlequote"; - Syntax = { - IncludeRules = ( - "xcode.lang.string", - "xcode.lang.gyp.keyword", - "xcode.lang.number", - ); - Start = "'"; - End = "'"; - }; - }, - - { - Identifier = "xcode.lang.gyp.comma"; - Syntax = { - Words = ( ",", ); - - }; - }, - - { - Identifier = "xcode.lang.gyp"; - Description = "GYP Coloring"; - BasedOn = "xcode.lang.simpleColoring"; - IncludeInMenu = YES; - Name = "GYP"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer.toplevel"; - IncludeRules = ( - "xcode.lang.gyp.dictionary", - ); - Type = "xcode.syntax.plain"; - }; - }, - - // The following rule returns tokens to the other rules - { - Identifier = "xcode.lang.gyp.lexer"; - Syntax = { - IncludeRules = ( - "xcode.lang.gyp.comment", - "xcode.lang.string", - 'xcode.lang.gyp.targetname.declarator', - "xcode.lang.gyp.string.singlequote", - "xcode.lang.number", - "xcode.lang.gyp.comma", - ); - }; - }, - - { - Identifier = "xcode.lang.gyp.lexer.toplevel"; - Syntax = { - IncludeRules = ( - "xcode.lang.gyp.comment", - ); - }; - }, - - { - Identifier = "xcode.lang.gyp.assignment"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Rules = ( - "xcode.lang.gyp.assignment.lhs", - ":", - "xcode.lang.gyp.assignment.rhs", - ); - }; - - }, - - { - Identifier = "xcode.lang.gyp.target.declaration"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Rules = ( - "xcode.lang.gyp.target.declarator", - ":", - "xcode.lang.gyp.target.name", - ); - }; - }, - - { - Identifier = "xcode.lang.gyp.target.name"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Rules = ( - "xcode.lang.gyp.string.singlequote", - ); - Type = "xcode.syntax.definition.function"; - }; - }, - - { - Identifier = "xcode.lang.gyp.assignment.lhs"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Rules = ( - "xcode.lang.gyp.string.singlequote", - ); - Type = "xcode.syntax.identifier.type"; - }; - }, - - { - Identifier = "xcode.lang.gyp.assignment.rhs"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Rules = ( - "xcode.lang.gyp.string.singlequote?", - "xcode.lang.gyp.array?", - "xcode.lang.gyp.dictionary?", - "xcode.lang.number?", - ); - }; - }, - - { - Identifier = "xcode.lang.gyp.dictionary"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Start = "{"; - End = "}"; - Foldable = YES; - Recursive = YES; - IncludeRules = ( - "xcode.lang.gyp.target.declaration", - "xcode.lang.gyp.assignment", - ); - }; - }, - - { - Identifier = "xcode.lang.gyp.array"; - Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; - Start = "["; - End = "]"; - Foldable = YES; - Recursive = YES; - IncludeRules = ( - "xcode.lang.gyp.array", - "xcode.lang.gyp.dictionary", - "xcode.lang.gyp.string.singlequote", - ); - }; - }, - - { - Identifier = "xcode.lang.gyp.todo.mark"; - Syntax = { - StartChars = "T"; - Match = ( - "^\(TODO\(.*\):[ \t]+.*\)$", // include "TODO: " in the markers list - ); - // This is the order of captures. All of the match strings above need the same order. - CaptureTypes = ( - "xcode.syntax.mark" - ); - Type = "xcode.syntax.comment"; - }; - }, - - { - Identifier = "xcode.lang.gyp.comment"; - BasedOn = "xcode.lang.comment"; // for text macros - Syntax = { - Start = "#"; - End = "\n"; - IncludeRules = ( - "xcode.lang.url", - "xcode.lang.url.mail", - "xcode.lang.comment.mark", - "xcode.lang.gyp.todo.mark", - ); - Type = "xcode.syntax.comment"; - }; - }, -) diff --git a/node_modules/node-gyp/gyp/tools/emacs/gyp-tests.el b/node_modules/node-gyp/gyp/tools/emacs/gyp-tests.el deleted file mode 100644 index 07afc58a93b11..0000000000000 --- a/node_modules/node-gyp/gyp/tools/emacs/gyp-tests.el +++ /dev/null @@ -1,63 +0,0 @@ -;;; gyp-tests.el - unit tests for gyp-mode. - -;; Copyright (c) 2012 Google Inc. All rights reserved. -;; Use of this source code is governed by a BSD-style license that can be -;; found in the LICENSE file. - -;; The recommended way to run these tests is to run them from the command-line, -;; with the run-unit-tests.sh script. - -(require 'cl) -(require 'ert) -(require 'gyp) - -(defconst samples (directory-files "testdata" t ".gyp$") - "List of golden samples to check") - -(defun fontify (filename) - (with-temp-buffer - (insert-file-contents-literally filename) - (gyp-mode) - (font-lock-fontify-buffer) - (buffer-string))) - -(defun read-golden-sample (filename) - (with-temp-buffer - (insert-file-contents-literally (concat filename ".fontified")) - (read (current-buffer)))) - -(defun equivalent-face (face) - "For the purposes of face comparison, we're not interested in the - differences between certain faces. For example, the difference between - font-lock-comment-delimiter and font-lock-comment-face." - (cl-case face - ((font-lock-comment-delimiter-face) font-lock-comment-face) - (t face))) - -(defun text-face-properties (s) - "Extract the text properties from s" - (let ((result (list t))) - (dotimes (i (length s)) - (setq result (cons (equivalent-face (get-text-property i 'face s)) - result))) - (nreverse result))) - -(ert-deftest test-golden-samples () - "Check that fontification produces the same results as the golden samples" - (dolist (sample samples) - (let ((golden (read-golden-sample sample)) - (fontified (fontify sample))) - (should (equal golden fontified)) - (should (equal (text-face-properties golden) - (text-face-properties fontified)))))) - -(defun create-golden-sample (filename) - "Create a golden sample by fontifying filename and writing out the printable - representation of the fontified buffer (with text properties) to the - FILENAME.fontified" - (with-temp-file (concat filename ".fontified") - (print (fontify filename) (current-buffer)))) - -(defun create-golden-samples () - "Recreate the golden samples" - (dolist (sample samples) (create-golden-sample sample))) diff --git a/node_modules/node-gyp/gyp/tools/emacs/gyp.el b/node_modules/node-gyp/gyp/tools/emacs/gyp.el deleted file mode 100644 index 042ff3a925cf0..0000000000000 --- a/node_modules/node-gyp/gyp/tools/emacs/gyp.el +++ /dev/null @@ -1,275 +0,0 @@ -;;; gyp.el - font-lock-mode support for gyp files. - -;; Copyright (c) 2012 Google Inc. All rights reserved. -;; Use of this source code is governed by a BSD-style license that can be -;; found in the LICENSE file. - -;; Put this somewhere in your load-path and -;; (require 'gyp) - -(require 'python) -(require 'cl) - -(when (string-match "python-mode.el" (symbol-file 'python-mode 'defun)) - (error (concat "python-mode must be loaded from python.el (bundled with " - "recent emacsen), not from the older and less maintained " - "python-mode.el"))) - -(defadvice python-indent-calculate-levels (after gyp-outdent-closing-parens - activate) - "De-indent closing parens, braces, and brackets in gyp-mode." - (when (and (eq major-mode 'gyp-mode) - (string-match "^ *[])}][],)}]* *$" - (buffer-substring-no-properties - (line-beginning-position) (line-end-position)))) - (setf (first python-indent-levels) - (- (first python-indent-levels) python-continuation-offset)))) - -(defadvice python-indent-guess-indent-offset (around - gyp-indent-guess-indent-offset - activate) - "Guess correct indent offset in gyp-mode." - (or (and (not (eq major-mode 'gyp-mode)) - ad-do-it) - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - ;; Find first line ending with an opening brace that is not a comment. - (or (and (re-search-forward "\\(^[[{]$\\|^.*[^#].*[[{]$\\)") - (forward-line) - (/= (current-indentation) 0) - (set (make-local-variable 'python-indent-offset) - (current-indentation)) - (set (make-local-variable 'python-continuation-offset) - (current-indentation))) - (message "Can't guess gyp indent offset, using default: %s" - python-continuation-offset)))))) - -(define-derived-mode gyp-mode python-mode "Gyp" - "Major mode for editing .gyp files. See http://code.google.com/p/gyp/" - ;; gyp-parse-history is a stack of (POSITION . PARSE-STATE) tuples, - ;; with greater positions at the top of the stack. PARSE-STATE - ;; is a list of section symbols (see gyp-section-name and gyp-parse-to) - ;; with most nested section symbol at the front of the list. - (set (make-local-variable 'gyp-parse-history) '((1 . (list)))) - (gyp-add-font-lock-keywords)) - -(defun gyp-set-indentation () - "Hook function to configure python indentation to suit gyp mode." - (set (make-local-variable 'python-indent-offset) 2) - (set (make-local-variable 'python-continuation-offset) 2) - (set (make-local-variable 'python-indent-guess-indent-offset) t) - (python-indent-guess-indent-offset)) - -(add-hook 'gyp-mode-hook 'gyp-set-indentation) - -(add-to-list 'auto-mode-alist '("\\.gyp\\'" . gyp-mode)) -(add-to-list 'auto-mode-alist '("\\.gypi\\'" . gyp-mode)) -(add-to-list 'auto-mode-alist '("/\\.gclient\\'" . gyp-mode)) - -;;; Font-lock support - -(defconst gyp-dependencies-regexp - (regexp-opt (list "dependencies" "export_dependent_settings")) - "Regular expression to introduce 'dependencies' section") - -(defconst gyp-sources-regexp - (regexp-opt (list "action" "files" "include_dirs" "includes" "inputs" - "libraries" "outputs" "sources")) - "Regular expression to introduce 'sources' sections") - -(defconst gyp-conditions-regexp - (regexp-opt (list "conditions" "target_conditions")) - "Regular expression to introduce conditions sections") - -(defconst gyp-variables-regexp - "^variables" - "Regular expression to introduce variables sections") - -(defconst gyp-defines-regexp - "^defines" - "Regular expression to introduce 'defines' sections") - -(defconst gyp-targets-regexp - "^targets" - "Regular expression to introduce 'targets' sections") - -(defun gyp-section-name (section) - "Map the sections we are interested in from SECTION to symbol. - - SECTION is a string from the buffer that introduces a section. The result is - a symbol representing the kind of section. - - This allows us to treat (for the purposes of font-lock) several different - section names as the same kind of section. For example, a 'sources section - can be introduced by the 'sources', 'inputs', 'outputs' keyword. - - 'other is the default section kind when a more specific match is not made." - (cond ((string-match-p gyp-dependencies-regexp section) 'dependencies) - ((string-match-p gyp-sources-regexp section) 'sources) - ((string-match-p gyp-variables-regexp section) 'variables) - ((string-match-p gyp-conditions-regexp section) 'conditions) - ((string-match-p gyp-targets-regexp section) 'targets) - ((string-match-p gyp-defines-regexp section) 'defines) - (t 'other))) - -(defun gyp-invalidate-parse-states-after (target-point) - "Erase any parse information after target-point." - (while (> (caar gyp-parse-history) target-point) - (setq gyp-parse-history (cdr gyp-parse-history)))) - -(defun gyp-parse-point () - "The point of the last parse state added by gyp-parse-to." - (caar gyp-parse-history)) - -(defun gyp-parse-sections () - "A list of section symbols holding at the last parse state point." - (cdar gyp-parse-history)) - -(defun gyp-inside-dictionary-p () - "Predicate returning true if the parser is inside a dictionary." - (not (eq (cadar gyp-parse-history) 'list))) - -(defun gyp-add-parse-history (point sections) - "Add parse state SECTIONS to the parse history at POINT so that parsing can be - resumed instantly." - (while (>= (caar gyp-parse-history) point) - (setq gyp-parse-history (cdr gyp-parse-history))) - (setq gyp-parse-history (cons (cons point sections) gyp-parse-history))) - -(defun gyp-parse-to (target-point) - "Parses from (point) to TARGET-POINT adding the parse state information to - gyp-parse-state-history. Parsing stops if TARGET-POINT is reached or if a - string literal has been parsed. Returns nil if no further parsing can be - done, otherwise returns the position of the start of a parsed string, leaving - the point at the end of the string." - (let ((parsing t) - string-start) - (while parsing - (setq string-start nil) - ;; Parse up to a character that starts a sexp, or if the nesting - ;; level decreases. - (let ((state (parse-partial-sexp (gyp-parse-point) - target-point - -1 - t)) - (sections (gyp-parse-sections))) - (if (= (nth 0 state) -1) - (setq sections (cdr sections)) ; pop out a level - (cond ((looking-at-p "['\"]") ; a string - (setq string-start (point)) - (goto-char (scan-sexps (point) 1)) - (if (gyp-inside-dictionary-p) - ;; Look for sections inside a dictionary - (let ((section (gyp-section-name - (buffer-substring-no-properties - (+ 1 string-start) - (- (point) 1))))) - (setq sections (cons section (cdr sections))))) - ;; Stop after the string so it can be fontified. - (setq target-point (point))) - ((looking-at-p "{") - ;; Inside a dictionary. Increase nesting. - (forward-char 1) - (setq sections (cons 'unknown sections))) - ((looking-at-p "\\[") - ;; Inside a list. Increase nesting - (forward-char 1) - (setq sections (cons 'list sections))) - ((not (eobp)) - ;; other - (forward-char 1)))) - (gyp-add-parse-history (point) sections) - (setq parsing (< (point) target-point)))) - string-start)) - -(defun gyp-section-at-point () - "Transform the last parse state, which is a list of nested sections and return - the section symbol that should be used to determine font-lock information for - the string. Can return nil indicating the string should not have any attached - section." - (let ((sections (gyp-parse-sections))) - (cond - ((eq (car sections) 'conditions) - ;; conditions can occur in a variables section, but we still want to - ;; highlight it as a keyword. - nil) - ((and (eq (car sections) 'list) - (eq (cadr sections) 'list)) - ;; conditions and sources can have items in [[ ]] - (caddr sections)) - (t (cadr sections))))) - -(defun gyp-section-match (limit) - "Parse from (point) to LIMIT returning by means of match data what was - matched. The group of the match indicates what style font-lock should apply. - See also `gyp-add-font-lock-keywords'." - (gyp-invalidate-parse-states-after (point)) - (let ((group nil) - (string-start t)) - (while (and (< (point) limit) - (not group) - string-start) - (setq string-start (gyp-parse-to limit)) - (if string-start - (setq group (cl-case (gyp-section-at-point) - ('dependencies 1) - ('variables 2) - ('conditions 2) - ('sources 3) - ('defines 4) - (nil nil))))) - (if group - (progn - ;; Set the match data to indicate to the font-lock mechanism the - ;; highlighting to be performed. - (set-match-data (append (list string-start (point)) - (make-list (* (1- group) 2) nil) - (list (1+ string-start) (1- (point))))) - t)))) - -;;; Please see http://code.google.com/p/gyp/wiki/GypLanguageSpecification for -;;; canonical list of keywords. -(defun gyp-add-font-lock-keywords () - "Add gyp-mode keywords to font-lock mechanism." - ;; TODO(jknotten): Move all the keyword highlighting into gyp-section-match - ;; so that we can do the font-locking in a single font-lock pass. - (font-lock-add-keywords - nil - (list - ;; Top-level keywords - (list (concat "['\"]\\(" - (regexp-opt (list "action" "action_name" "actions" "cflags" - "cflags_cc" "conditions" "configurations" - "copies" "defines" "dependencies" "destination" - "direct_dependent_settings" - "export_dependent_settings" "extension" "files" - "include_dirs" "includes" "inputs" "ldflags" "libraries" - "link_settings" "mac_bundle" "message" - "msvs_external_rule" "outputs" "product_name" - "process_outputs_as_sources" "rules" "rule_name" - "sources" "suppress_wildcard" - "target_conditions" "target_defaults" - "target_defines" "target_name" "toolsets" - "targets" "type" "variables" "xcode_settings")) - "[!/+=]?\\)") 1 'font-lock-keyword-face t) - ;; Type of target - (list (concat "['\"]\\(" - (regexp-opt (list "loadable_module" "static_library" - "shared_library" "executable" "none")) - "\\)") 1 'font-lock-type-face t) - (list "\\(?:target\\|action\\)_name['\"]\\s-*:\\s-*['\"]\\([^ '\"]*\\)" 1 - 'font-lock-function-name-face t) - (list 'gyp-section-match - (list 1 'font-lock-function-name-face t t) ; dependencies - (list 2 'font-lock-variable-name-face t t) ; variables, conditions - (list 3 'font-lock-constant-face t t) ; sources - (list 4 'font-lock-preprocessor-face t t)) ; preprocessor - ;; Variable expansion - (list "<@?(\\([^\n )]+\\))" 1 'font-lock-variable-name-face t) - ;; Command expansion - (list "<!@?(\\([^\n )]+\\))" 1 'font-lock-variable-name-face t) - ))) - -(provide 'gyp) diff --git a/node_modules/node-gyp/gyp/tools/emacs/run-unit-tests.sh b/node_modules/node-gyp/gyp/tools/emacs/run-unit-tests.sh deleted file mode 100755 index 6e62b9b28cbce..0000000000000 --- a/node_modules/node-gyp/gyp/tools/emacs/run-unit-tests.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -emacs --no-site-file --no-init-file --batch \ - --load ert.el --load gyp.el --load gyp-tests.el \ - -f ert-run-tests-batch-and-exit diff --git a/node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp b/node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp deleted file mode 100644 index 29300fe1b89fd..0000000000000 --- a/node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp +++ /dev/null @@ -1,1105 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'variables': { - 'chromium_code': 1, - # Override to dynamically link the PulseAudio library. - 'use_pulseaudio%': 0, - # Override to dynamically link the cras (ChromeOS audio) library. - 'use_cras%': 0, - }, - 'targets': [ - { - 'target_name': 'media', - 'type': '<(component)', - 'dependencies': [ - 'yuv_convert', - '../base/base.gyp:base', - '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - '../build/temp_gyp/googleurl.gyp:googleurl', - '../crypto/crypto.gyp:crypto', - '../third_party/openmax/openmax.gyp:il', - '../ui/ui.gyp:ui', - ], - 'defines': [ - 'MEDIA_IMPLEMENTATION', - ], - 'include_dirs': [ - '..', - ], - 'sources': [ - 'audio/android/audio_manager_android.cc', - 'audio/android/audio_manager_android.h', - 'audio/android/audio_track_output_android.cc', - 'audio/android/audio_track_output_android.h', - 'audio/android/opensles_input.cc', - 'audio/android/opensles_input.h', - 'audio/android/opensles_output.cc', - 'audio/android/opensles_output.h', - 'audio/async_socket_io_handler.h', - 'audio/async_socket_io_handler_posix.cc', - 'audio/async_socket_io_handler_win.cc', - 'audio/audio_buffers_state.cc', - 'audio/audio_buffers_state.h', - 'audio/audio_io.h', - 'audio/audio_input_controller.cc', - 'audio/audio_input_controller.h', - 'audio/audio_input_stream_impl.cc', - 'audio/audio_input_stream_impl.h', - 'audio/audio_device_name.cc', - 'audio/audio_device_name.h', - 'audio/audio_manager.cc', - 'audio/audio_manager.h', - 'audio/audio_manager_base.cc', - 'audio/audio_manager_base.h', - 'audio/audio_output_controller.cc', - 'audio/audio_output_controller.h', - 'audio/audio_output_dispatcher.cc', - 'audio/audio_output_dispatcher.h', - 'audio/audio_output_dispatcher_impl.cc', - 'audio/audio_output_dispatcher_impl.h', - 'audio/audio_output_mixer.cc', - 'audio/audio_output_mixer.h', - 'audio/audio_output_proxy.cc', - 'audio/audio_output_proxy.h', - 'audio/audio_parameters.cc', - 'audio/audio_parameters.h', - 'audio/audio_util.cc', - 'audio/audio_util.h', - 'audio/cross_process_notification.cc', - 'audio/cross_process_notification.h', - 'audio/cross_process_notification_win.cc', - 'audio/cross_process_notification_posix.cc', - 'audio/fake_audio_input_stream.cc', - 'audio/fake_audio_input_stream.h', - 'audio/fake_audio_output_stream.cc', - 'audio/fake_audio_output_stream.h', - 'audio/linux/audio_manager_linux.cc', - 'audio/linux/audio_manager_linux.h', - 'audio/linux/alsa_input.cc', - 'audio/linux/alsa_input.h', - 'audio/linux/alsa_output.cc', - 'audio/linux/alsa_output.h', - 'audio/linux/alsa_util.cc', - 'audio/linux/alsa_util.h', - 'audio/linux/alsa_wrapper.cc', - 'audio/linux/alsa_wrapper.h', - 'audio/linux/cras_output.cc', - 'audio/linux/cras_output.h', - 'audio/openbsd/audio_manager_openbsd.cc', - 'audio/openbsd/audio_manager_openbsd.h', - 'audio/mac/audio_input_mac.cc', - 'audio/mac/audio_input_mac.h', - 'audio/mac/audio_low_latency_input_mac.cc', - 'audio/mac/audio_low_latency_input_mac.h', - 'audio/mac/audio_low_latency_output_mac.cc', - 'audio/mac/audio_low_latency_output_mac.h', - 'audio/mac/audio_manager_mac.cc', - 'audio/mac/audio_manager_mac.h', - 'audio/mac/audio_output_mac.cc', - 'audio/mac/audio_output_mac.h', - 'audio/null_audio_sink.cc', - 'audio/null_audio_sink.h', - 'audio/pulse/pulse_output.cc', - 'audio/pulse/pulse_output.h', - 'audio/sample_rates.cc', - 'audio/sample_rates.h', - 'audio/simple_sources.cc', - 'audio/simple_sources.h', - 'audio/win/audio_low_latency_input_win.cc', - 'audio/win/audio_low_latency_input_win.h', - 'audio/win/audio_low_latency_output_win.cc', - 'audio/win/audio_low_latency_output_win.h', - 'audio/win/audio_manager_win.cc', - 'audio/win/audio_manager_win.h', - 'audio/win/avrt_wrapper_win.cc', - 'audio/win/avrt_wrapper_win.h', - 'audio/win/device_enumeration_win.cc', - 'audio/win/device_enumeration_win.h', - 'audio/win/wavein_input_win.cc', - 'audio/win/wavein_input_win.h', - 'audio/win/waveout_output_win.cc', - 'audio/win/waveout_output_win.h', - 'base/android/media_jni_registrar.cc', - 'base/android/media_jni_registrar.h', - 'base/audio_decoder.cc', - 'base/audio_decoder.h', - 'base/audio_decoder_config.cc', - 'base/audio_decoder_config.h', - 'base/audio_renderer.h', - 'base/audio_renderer_mixer.cc', - 'base/audio_renderer_mixer.h', - 'base/audio_renderer_mixer_input.cc', - 'base/audio_renderer_mixer_input.h', - 'base/bitstream_buffer.h', - 'base/buffers.cc', - 'base/buffers.h', - 'base/byte_queue.cc', - 'base/byte_queue.h', - 'base/channel_layout.cc', - 'base/channel_layout.h', - 'base/clock.cc', - 'base/clock.h', - 'base/composite_filter.cc', - 'base/composite_filter.h', - 'base/data_buffer.cc', - 'base/data_buffer.h', - 'base/data_source.cc', - 'base/data_source.h', - 'base/decoder_buffer.cc', - 'base/decoder_buffer.h', - 'base/decrypt_config.cc', - 'base/decrypt_config.h', - 'base/decryptor.h', - 'base/decryptor_client.h', - 'base/demuxer.cc', - 'base/demuxer.h', - 'base/demuxer_stream.cc', - 'base/demuxer_stream.h', - 'base/djb2.cc', - 'base/djb2.h', - 'base/filter_collection.cc', - 'base/filter_collection.h', - 'base/filter_host.h', - 'base/filters.cc', - 'base/filters.h', - 'base/h264_bitstream_converter.cc', - 'base/h264_bitstream_converter.h', - 'base/media.h', - 'base/media_android.cc', - 'base/media_export.h', - 'base/media_log.cc', - 'base/media_log.h', - 'base/media_log_event.h', - 'base/media_posix.cc', - 'base/media_switches.cc', - 'base/media_switches.h', - 'base/media_win.cc', - 'base/message_loop_factory.cc', - 'base/message_loop_factory.h', - 'base/pipeline.cc', - 'base/pipeline.h', - 'base/pipeline_status.cc', - 'base/pipeline_status.h', - 'base/ranges.cc', - 'base/ranges.h', - 'base/seekable_buffer.cc', - 'base/seekable_buffer.h', - 'base/state_matrix.cc', - 'base/state_matrix.h', - 'base/stream_parser.cc', - 'base/stream_parser.h', - 'base/stream_parser_buffer.cc', - 'base/stream_parser_buffer.h', - 'base/video_decoder.cc', - 'base/video_decoder.h', - 'base/video_decoder_config.cc', - 'base/video_decoder_config.h', - 'base/video_frame.cc', - 'base/video_frame.h', - 'base/video_renderer.h', - 'base/video_util.cc', - 'base/video_util.h', - 'crypto/aes_decryptor.cc', - 'crypto/aes_decryptor.h', - 'ffmpeg/ffmpeg_common.cc', - 'ffmpeg/ffmpeg_common.h', - 'ffmpeg/file_protocol.cc', - 'ffmpeg/file_protocol.h', - 'filters/audio_file_reader.cc', - 'filters/audio_file_reader.h', - 'filters/audio_renderer_algorithm.cc', - 'filters/audio_renderer_algorithm.h', - 'filters/audio_renderer_impl.cc', - 'filters/audio_renderer_impl.h', - 'filters/bitstream_converter.cc', - 'filters/bitstream_converter.h', - 'filters/chunk_demuxer.cc', - 'filters/chunk_demuxer.h', - 'filters/chunk_demuxer_client.h', - 'filters/dummy_demuxer.cc', - 'filters/dummy_demuxer.h', - 'filters/ffmpeg_audio_decoder.cc', - 'filters/ffmpeg_audio_decoder.h', - 'filters/ffmpeg_demuxer.cc', - 'filters/ffmpeg_demuxer.h', - 'filters/ffmpeg_h264_bitstream_converter.cc', - 'filters/ffmpeg_h264_bitstream_converter.h', - 'filters/ffmpeg_glue.cc', - 'filters/ffmpeg_glue.h', - 'filters/ffmpeg_video_decoder.cc', - 'filters/ffmpeg_video_decoder.h', - 'filters/file_data_source.cc', - 'filters/file_data_source.h', - 'filters/gpu_video_decoder.cc', - 'filters/gpu_video_decoder.h', - 'filters/in_memory_url_protocol.cc', - 'filters/in_memory_url_protocol.h', - 'filters/source_buffer_stream.cc', - 'filters/source_buffer_stream.h', - 'filters/video_frame_generator.cc', - 'filters/video_frame_generator.h', - 'filters/video_renderer_base.cc', - 'filters/video_renderer_base.h', - 'video/capture/fake_video_capture_device.cc', - 'video/capture/fake_video_capture_device.h', - 'video/capture/linux/video_capture_device_linux.cc', - 'video/capture/linux/video_capture_device_linux.h', - 'video/capture/mac/video_capture_device_mac.h', - 'video/capture/mac/video_capture_device_mac.mm', - 'video/capture/mac/video_capture_device_qtkit_mac.h', - 'video/capture/mac/video_capture_device_qtkit_mac.mm', - 'video/capture/video_capture.h', - 'video/capture/video_capture_device.h', - 'video/capture/video_capture_device_dummy.cc', - 'video/capture/video_capture_device_dummy.h', - 'video/capture/video_capture_proxy.cc', - 'video/capture/video_capture_proxy.h', - 'video/capture/video_capture_types.h', - 'video/capture/win/filter_base_win.cc', - 'video/capture/win/filter_base_win.h', - 'video/capture/win/pin_base_win.cc', - 'video/capture/win/pin_base_win.h', - 'video/capture/win/sink_filter_observer_win.h', - 'video/capture/win/sink_filter_win.cc', - 'video/capture/win/sink_filter_win.h', - 'video/capture/win/sink_input_pin_win.cc', - 'video/capture/win/sink_input_pin_win.h', - 'video/capture/win/video_capture_device_win.cc', - 'video/capture/win/video_capture_device_win.h', - 'video/picture.cc', - 'video/picture.h', - 'video/video_decode_accelerator.cc', - 'video/video_decode_accelerator.h', - 'webm/webm_constants.h', - 'webm/webm_cluster_parser.cc', - 'webm/webm_cluster_parser.h', - 'webm/webm_content_encodings.cc', - 'webm/webm_content_encodings.h', - 'webm/webm_content_encodings_client.cc', - 'webm/webm_content_encodings_client.h', - 'webm/webm_info_parser.cc', - 'webm/webm_info_parser.h', - 'webm/webm_parser.cc', - 'webm/webm_parser.h', - 'webm/webm_stream_parser.cc', - 'webm/webm_stream_parser.h', - 'webm/webm_tracks_parser.cc', - 'webm/webm_tracks_parser.h', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '..', - ], - }, - 'conditions': [ - # Android doesn't use ffmpeg, so make the dependency conditional - # and exclude the sources which depend on ffmpeg. - ['OS != "android"', { - 'dependencies': [ - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - }], - ['OS == "android"', { - 'sources!': [ - 'base/media_posix.cc', - 'ffmpeg/ffmpeg_common.cc', - 'ffmpeg/ffmpeg_common.h', - 'ffmpeg/file_protocol.cc', - 'ffmpeg/file_protocol.h', - 'filters/audio_file_reader.cc', - 'filters/audio_file_reader.h', - 'filters/bitstream_converter.cc', - 'filters/bitstream_converter.h', - 'filters/chunk_demuxer.cc', - 'filters/chunk_demuxer.h', - 'filters/chunk_demuxer_client.h', - 'filters/ffmpeg_audio_decoder.cc', - 'filters/ffmpeg_audio_decoder.h', - 'filters/ffmpeg_demuxer.cc', - 'filters/ffmpeg_demuxer.h', - 'filters/ffmpeg_h264_bitstream_converter.cc', - 'filters/ffmpeg_h264_bitstream_converter.h', - 'filters/ffmpeg_glue.cc', - 'filters/ffmpeg_glue.h', - 'filters/ffmpeg_video_decoder.cc', - 'filters/ffmpeg_video_decoder.h', - 'filters/gpu_video_decoder.cc', - 'filters/gpu_video_decoder.h', - 'webm/webm_cluster_parser.cc', - 'webm/webm_cluster_parser.h', - 'webm/webm_stream_parser.cc', - 'webm/webm_stream_parser.h', - ], - }], - # The below 'android' condition were added temporarily and should be - # removed in downstream, because there is no Java environment setup in - # upstream yet. - ['OS == "android"', { - 'sources!':[ - 'audio/android/audio_track_output_android.cc', - ], - 'sources':[ - 'audio/android/audio_track_output_stub_android.cc', - ], - 'link_settings': { - 'libraries': [ - '-lOpenSLES', - ], - }, - }], - ['OS=="linux" or OS=="freebsd" or OS=="solaris"', { - 'link_settings': { - 'libraries': [ - '-lasound', - ], - }, - }], - ['OS=="openbsd"', { - 'sources/': [ ['exclude', '/alsa_' ], - ['exclude', '/audio_manager_linux' ] ], - 'link_settings': { - 'libraries': [ - ], - }, - }], - ['OS!="openbsd"', { - 'sources!': [ - 'audio/openbsd/audio_manager_openbsd.cc', - 'audio/openbsd/audio_manager_openbsd.h', - ], - }], - ['OS=="linux"', { - 'variables': { - 'conditions': [ - ['sysroot!=""', { - 'pkg-config': '../build/linux/pkg-config-wrapper "<(sysroot)" "<(target_arch)"', - }, { - 'pkg-config': 'pkg-config' - }], - ], - }, - 'conditions': [ - ['use_cras == 1', { - 'cflags': [ - '<!@(<(pkg-config) --cflags libcras)', - ], - 'link_settings': { - 'libraries': [ - '<!@(<(pkg-config) --libs libcras)', - ], - }, - 'defines': [ - 'USE_CRAS', - ], - }, { # else: use_cras == 0 - 'sources!': [ - 'audio/linux/cras_output.cc', - 'audio/linux/cras_output.h', - ], - }], - ], - }], - ['os_posix == 1', { - 'conditions': [ - ['use_pulseaudio == 1', { - 'cflags': [ - '<!@(pkg-config --cflags libpulse)', - ], - 'link_settings': { - 'libraries': [ - '<!@(pkg-config --libs-only-l libpulse)', - ], - }, - 'defines': [ - 'USE_PULSEAUDIO', - ], - }, { # else: use_pulseaudio == 0 - 'sources!': [ - 'audio/pulse/pulse_output.cc', - 'audio/pulse/pulse_output.h', - ], - }], - ], - }], - ['os_posix == 1 and OS != "android"', { - # Video capture isn't supported in Android yet. - 'sources!': [ - 'video/capture/video_capture_device_dummy.cc', - 'video/capture/video_capture_device_dummy.h', - ], - }], - ['OS=="mac"', { - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/AudioUnit.framework', - '$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework', - '$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework', - '$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework', - '$(SDKROOT)/System/Library/Frameworks/QTKit.framework', - ], - }, - }], - ['OS=="win"', { - 'sources!': [ - 'audio/pulse/pulse_output.cc', - 'audio/pulse/pulse_output.h', - 'video/capture/video_capture_device_dummy.cc', - 'video/capture/video_capture_device_dummy.h', - ], - }], - ['proprietary_codecs==1 or branding=="Chrome"', { - 'sources': [ - 'mp4/avc.cc', - 'mp4/avc.h', - 'mp4/box_definitions.cc', - 'mp4/box_definitions.h', - 'mp4/box_reader.cc', - 'mp4/box_reader.h', - 'mp4/cenc.cc', - 'mp4/cenc.h', - 'mp4/mp4_stream_parser.cc', - 'mp4/mp4_stream_parser.h', - 'mp4/offset_byte_queue.cc', - 'mp4/offset_byte_queue.h', - 'mp4/track_run_iterator.cc', - 'mp4/track_run_iterator.h', - ], - }], - ], - }, - { - 'target_name': 'yuv_convert', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'conditions': [ - ['order_profiling != 0', { - 'target_conditions' : [ - ['_toolset=="target"', { - 'cflags!': [ '-finstrument-functions' ], - }], - ], - }], - [ 'target_arch == "ia32" or target_arch == "x64"', { - 'dependencies': [ - 'yuv_convert_simd_x86', - ], - }], - [ 'target_arch == "arm"', { - 'dependencies': [ - 'yuv_convert_simd_arm', - ], - }], - ], - 'sources': [ - 'base/yuv_convert.cc', - 'base/yuv_convert.h', - ], - }, - { - 'target_name': 'yuv_convert_simd_x86', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'sources': [ - 'base/simd/convert_rgb_to_yuv_c.cc', - 'base/simd/convert_rgb_to_yuv_sse2.cc', - 'base/simd/convert_rgb_to_yuv_ssse3.asm', - 'base/simd/convert_rgb_to_yuv_ssse3.cc', - 'base/simd/convert_rgb_to_yuv_ssse3.inc', - 'base/simd/convert_yuv_to_rgb_c.cc', - 'base/simd/convert_yuv_to_rgb_x86.cc', - 'base/simd/convert_yuv_to_rgb_mmx.asm', - 'base/simd/convert_yuv_to_rgb_mmx.inc', - 'base/simd/convert_yuv_to_rgb_sse.asm', - 'base/simd/filter_yuv.h', - 'base/simd/filter_yuv_c.cc', - 'base/simd/filter_yuv_mmx.cc', - 'base/simd/filter_yuv_sse2.cc', - 'base/simd/linear_scale_yuv_to_rgb_mmx.asm', - 'base/simd/linear_scale_yuv_to_rgb_mmx.inc', - 'base/simd/linear_scale_yuv_to_rgb_sse.asm', - 'base/simd/scale_yuv_to_rgb_mmx.asm', - 'base/simd/scale_yuv_to_rgb_mmx.inc', - 'base/simd/scale_yuv_to_rgb_sse.asm', - 'base/simd/yuv_to_rgb_table.cc', - 'base/simd/yuv_to_rgb_table.h', - ], - 'conditions': [ - ['order_profiling != 0', { - 'target_conditions' : [ - ['_toolset=="target"', { - 'cflags!': [ '-finstrument-functions' ], - }], - ], - }], - [ 'target_arch == "x64"', { - # Source files optimized for X64 systems. - 'sources': [ - 'base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm', - 'base/simd/scale_yuv_to_rgb_sse2_x64.asm', - ], - }], - [ 'os_posix == 1 and OS != "mac" and OS != "android"', { - 'cflags': [ - '-msse2', - ], - }], - [ 'OS == "mac"', { - 'configurations': { - 'Debug': { - 'xcode_settings': { - # gcc on the mac builds horribly unoptimized sse code in debug - # mode. Since this is rarely going to be debugged, run with full - # optimizations in Debug as well as Release. - 'GCC_OPTIMIZATION_LEVEL': '3', # -O3 - }, - }, - }, - }], - [ 'OS=="win"', { - 'variables': { - 'yasm_flags': [ - '-DWIN32', - '-DMSVC', - '-DCHROMIUM', - '-Isimd', - ], - }, - }], - [ 'OS=="mac"', { - 'variables': { - 'yasm_flags': [ - '-DPREFIX', - '-DMACHO', - '-DCHROMIUM', - '-Isimd', - ], - }, - }], - [ 'os_posix==1 and OS!="mac"', { - 'variables': { - 'conditions': [ - [ 'target_arch=="ia32"', { - 'yasm_flags': [ - '-DX86_32', - '-DELF', - '-DCHROMIUM', - '-Isimd', - ], - }, { - 'yasm_flags': [ - '-DARCH_X86_64', - '-DELF', - '-DPIC', - '-DCHROMIUM', - '-Isimd', - ], - }], - ], - }, - }], - ], - 'variables': { - 'yasm_output_path': '<(SHARED_INTERMEDIATE_DIR)/media', - }, - 'msvs_2010_disable_uldi_when_referenced': 1, - 'includes': [ - '../third_party/yasm/yasm_compile.gypi', - ], - }, - { - 'target_name': 'yuv_convert_simd_arm', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'sources': [ - 'base/simd/convert_rgb_to_yuv_c.cc', - 'base/simd/convert_rgb_to_yuv.h', - 'base/simd/convert_yuv_to_rgb_c.cc', - 'base/simd/convert_yuv_to_rgb.h', - 'base/simd/filter_yuv.h', - 'base/simd/filter_yuv_c.cc', - 'base/simd/yuv_to_rgb_table.cc', - 'base/simd/yuv_to_rgb_table.h', - ], - }, - { - 'target_name': 'media_unittests', - 'type': 'executable', - 'dependencies': [ - 'media', - 'media_test_support', - 'yuv_convert', - '../base/base.gyp:base', - '../base/base.gyp:base_i18n', - '../base/base.gyp:test_support_base', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - '../ui/ui.gyp:ui', - ], - 'sources': [ - 'audio/async_socket_io_handler_unittest.cc', - 'audio/audio_input_controller_unittest.cc', - 'audio/audio_input_device_unittest.cc', - 'audio/audio_input_unittest.cc', - 'audio/audio_input_volume_unittest.cc', - 'audio/audio_low_latency_input_output_unittest.cc', - 'audio/audio_output_controller_unittest.cc', - 'audio/audio_output_proxy_unittest.cc', - 'audio/audio_parameters_unittest.cc', - 'audio/audio_util_unittest.cc', - 'audio/cross_process_notification_unittest.cc', - 'audio/linux/alsa_output_unittest.cc', - 'audio/mac/audio_low_latency_input_mac_unittest.cc', - 'audio/mac/audio_output_mac_unittest.cc', - 'audio/simple_sources_unittest.cc', - 'audio/win/audio_low_latency_input_win_unittest.cc', - 'audio/win/audio_low_latency_output_win_unittest.cc', - 'audio/win/audio_output_win_unittest.cc', - 'base/audio_renderer_mixer_unittest.cc', - 'base/audio_renderer_mixer_input_unittest.cc', - 'base/buffers_unittest.cc', - 'base/clock_unittest.cc', - 'base/composite_filter_unittest.cc', - 'base/data_buffer_unittest.cc', - 'base/decoder_buffer_unittest.cc', - 'base/djb2_unittest.cc', - 'base/fake_audio_render_callback.cc', - 'base/fake_audio_render_callback.h', - 'base/filter_collection_unittest.cc', - 'base/h264_bitstream_converter_unittest.cc', - 'base/pipeline_unittest.cc', - 'base/ranges_unittest.cc', - 'base/run_all_unittests.cc', - 'base/seekable_buffer_unittest.cc', - 'base/state_matrix_unittest.cc', - 'base/test_data_util.cc', - 'base/test_data_util.h', - 'base/video_frame_unittest.cc', - 'base/video_util_unittest.cc', - 'base/yuv_convert_unittest.cc', - 'crypto/aes_decryptor_unittest.cc', - 'ffmpeg/ffmpeg_common_unittest.cc', - 'filters/audio_renderer_algorithm_unittest.cc', - 'filters/audio_renderer_impl_unittest.cc', - 'filters/bitstream_converter_unittest.cc', - 'filters/chunk_demuxer_unittest.cc', - 'filters/ffmpeg_audio_decoder_unittest.cc', - 'filters/ffmpeg_decoder_unittest.h', - 'filters/ffmpeg_demuxer_unittest.cc', - 'filters/ffmpeg_glue_unittest.cc', - 'filters/ffmpeg_h264_bitstream_converter_unittest.cc', - 'filters/ffmpeg_video_decoder_unittest.cc', - 'filters/file_data_source_unittest.cc', - 'filters/pipeline_integration_test.cc', - 'filters/pipeline_integration_test_base.cc', - 'filters/source_buffer_stream_unittest.cc', - 'filters/video_renderer_base_unittest.cc', - 'video/capture/video_capture_device_unittest.cc', - 'webm/cluster_builder.cc', - 'webm/cluster_builder.h', - 'webm/webm_cluster_parser_unittest.cc', - 'webm/webm_content_encodings_client_unittest.cc', - 'webm/webm_parser_unittest.cc', - ], - 'conditions': [ - ['os_posix==1 and OS!="mac"', { - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }], - ['OS != "android"', { - 'dependencies': [ - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - }], - ['OS == "android"', { - 'sources!': [ - 'audio/audio_input_volume_unittest.cc', - 'base/test_data_util.cc', - 'base/test_data_util.h', - 'ffmpeg/ffmpeg_common_unittest.cc', - 'filters/ffmpeg_audio_decoder_unittest.cc', - 'filters/bitstream_converter_unittest.cc', - 'filters/chunk_demuxer_unittest.cc', - 'filters/ffmpeg_demuxer_unittest.cc', - 'filters/ffmpeg_glue_unittest.cc', - 'filters/ffmpeg_h264_bitstream_converter_unittest.cc', - 'filters/ffmpeg_video_decoder_unittest.cc', - 'filters/pipeline_integration_test.cc', - 'filters/pipeline_integration_test_base.cc', - 'mp4/mp4_stream_parser_unittest.cc', - 'webm/webm_cluster_parser_unittest.cc', - ], - }], - ['OS == "linux"', { - 'conditions': [ - ['use_cras == 1', { - 'sources': [ - 'audio/linux/cras_output_unittest.cc', - ], - 'defines': [ - 'USE_CRAS', - ], - }], - ], - }], - [ 'target_arch=="ia32" or target_arch=="x64"', { - 'sources': [ - 'base/simd/convert_rgb_to_yuv_unittest.cc', - ], - }], - ['proprietary_codecs==1 or branding=="Chrome"', { - 'sources': [ - 'mp4/avc_unittest.cc', - 'mp4/box_reader_unittest.cc', - 'mp4/mp4_stream_parser_unittest.cc', - 'mp4/offset_byte_queue_unittest.cc', - ], - }], - ], - }, - { - 'target_name': 'media_test_support', - 'type': 'static_library', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - ], - 'sources': [ - 'audio/test_audio_input_controller_factory.cc', - 'audio/test_audio_input_controller_factory.h', - 'base/mock_callback.cc', - 'base/mock_callback.h', - 'base/mock_data_source_host.cc', - 'base/mock_data_source_host.h', - 'base/mock_demuxer_host.cc', - 'base/mock_demuxer_host.h', - 'base/mock_filter_host.cc', - 'base/mock_filter_host.h', - 'base/mock_filters.cc', - 'base/mock_filters.h', - ], - }, - { - 'target_name': 'scaler_bench', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../skia/skia.gyp:skia', - ], - 'sources': [ - 'tools/scaler_bench/scaler_bench.cc', - ], - }, - { - 'target_name': 'qt_faststart', - 'type': 'executable', - 'sources': [ - 'tools/qt_faststart/qt_faststart.c' - ], - }, - { - 'target_name': 'seek_tester', - 'type': 'executable', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - ], - 'sources': [ - 'tools/seek_tester/seek_tester.cc', - ], - }, - ], - 'conditions': [ - ['OS=="win"', { - 'targets': [ - { - 'target_name': 'player_wtl', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - '../ui/ui.gyp:ui', - ], - 'include_dirs': [ - '<(DEPTH)/third_party/wtl/include', - ], - 'sources': [ - 'tools/player_wtl/list.h', - 'tools/player_wtl/mainfrm.h', - 'tools/player_wtl/movie.cc', - 'tools/player_wtl/movie.h', - 'tools/player_wtl/player_wtl.cc', - 'tools/player_wtl/player_wtl.rc', - 'tools/player_wtl/props.h', - 'tools/player_wtl/seek.h', - 'tools/player_wtl/resource.h', - 'tools/player_wtl/view.h', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS - }, - }, - 'defines': [ - '_CRT_SECURE_NO_WARNINGS=1', - ], - }, - ], - }], - ['OS == "win" or toolkit_uses_gtk == 1', { - 'targets': [ - { - 'target_name': 'shader_bench', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../ui/gl/gl.gyp:gl', - ], - 'sources': [ - 'tools/shader_bench/shader_bench.cc', - 'tools/shader_bench/cpu_color_painter.cc', - 'tools/shader_bench/cpu_color_painter.h', - 'tools/shader_bench/gpu_color_painter.cc', - 'tools/shader_bench/gpu_color_painter.h', - 'tools/shader_bench/gpu_painter.cc', - 'tools/shader_bench/gpu_painter.h', - 'tools/shader_bench/painter.cc', - 'tools/shader_bench/painter.h', - 'tools/shader_bench/window.cc', - 'tools/shader_bench/window.h', - ], - 'conditions': [ - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - '../build/linux/system.gyp:gtk', - ], - 'sources': [ - 'tools/shader_bench/window_linux.cc', - ], - }], - ['OS=="win"', { - 'dependencies': [ - '../third_party/angle/src/build_angle.gyp:libEGL', - '../third_party/angle/src/build_angle.gyp:libGLESv2', - ], - 'sources': [ - 'tools/shader_bench/window_win.cc', - ], - }], - ], - }, - ], - }], - ['OS == "linux" and target_arch != "arm"', { - 'targets': [ - { - 'target_name': 'tile_render_bench', - 'type': 'executable', - 'dependencies': [ - '../base/base.gyp:base', - '../ui/gl/gl.gyp:gl', - ], - 'libraries': [ - '-lGL', - '-ldl', - ], - 'sources': [ - 'tools/tile_render_bench/tile_render_bench.cc', - ], - }, - ], - }], - ['os_posix == 1 and OS != "mac" and OS != "android"', { - 'targets': [ - { - 'target_name': 'player_x11', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../ui/gl/gl.gyp:gl', - ], - 'link_settings': { - 'libraries': [ - '-ldl', - '-lX11', - '-lXrender', - '-lXext', - ], - }, - 'sources': [ - 'tools/player_x11/data_source_logger.cc', - 'tools/player_x11/data_source_logger.h', - 'tools/player_x11/gl_video_renderer.cc', - 'tools/player_x11/gl_video_renderer.h', - 'tools/player_x11/player_x11.cc', - 'tools/player_x11/x11_video_renderer.cc', - 'tools/player_x11/x11_video_renderer.h', - ], - }, - ], - }], - ['OS == "android"', { - 'targets': [ - { - 'target_name': 'player_android', - 'type': 'static_library', - 'sources': [ - 'base/android/media_player_bridge.cc', - 'base/android/media_player_bridge.h', - ], - 'dependencies': [ - '../base/base.gyp:base', - ], - 'include_dirs': [ - '<(SHARED_INTERMEDIATE_DIR)/media', - ], - 'actions': [ - { - 'action_name': 'generate-jni-headers', - 'inputs': [ - '../base/android/jni_generator/jni_generator.py', - 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', - ], - 'outputs': [ - '<(SHARED_INTERMEDIATE_DIR)/media/jni/media_player_listener_jni.h', - ], - 'action': [ - 'python', - '<(DEPTH)/base/android/jni_generator/jni_generator.py', - '-o', - '<@(_inputs)', - '<@(_outputs)', - ], - }, - ], - }, - { - 'target_name': 'media_java', - 'type': 'none', - 'dependencies': [ '../base/base.gyp:base_java' ], - 'variables': { - 'package_name': 'media', - 'java_in_dir': 'base/android/java', - }, - 'includes': [ '../build/java.gypi' ], - }, - - ], - }, { # OS != "android"' - # Android does not use ffmpeg, so disable the targets which require it. - 'targets': [ - { - 'target_name': 'ffmpeg_unittests', - 'type': 'executable', - 'dependencies': [ - 'media', - 'media_test_support', - '../base/base.gyp:base', - '../base/base.gyp:base_i18n', - '../base/base.gyp:test_support_base', - '../base/base.gyp:test_support_perf', - '../testing/gtest.gyp:gtest', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'ffmpeg/ffmpeg_unittest.cc', - ], - 'conditions': [ - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - # Needed for the following #include chain: - # base/run_all_unittests.cc - # ../base/test_suite.h - # gtk/gtk.h - '../build/linux/system.gyp:gtk', - ], - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }], - ], - }, - { - 'target_name': 'ffmpeg_regression_tests', - 'type': 'executable', - 'dependencies': [ - 'media', - 'media_test_support', - '../base/base.gyp:test_support_base', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'base/test_data_util.cc', - 'base/run_all_unittests.cc', - 'ffmpeg/ffmpeg_regression_tests.cc', - 'filters/pipeline_integration_test_base.cc', - ], - 'conditions': [ - ['os_posix==1 and OS!="mac"', { - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }], - ], - }, - { - 'target_name': 'ffmpeg_tests', - 'type': 'executable', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'test/ffmpeg_tests/ffmpeg_tests.cc', - ], - }, - { - 'target_name': 'media_bench', - 'type': 'executable', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'tools/media_bench/media_bench.cc', - ], - }, - ], - }] - ], -} diff --git a/node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp.fontified b/node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp.fontified deleted file mode 100644 index 962b7b2c43abe..0000000000000 --- a/node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp.fontified +++ /dev/null @@ -1,1107 +0,0 @@ - -#("# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -{ - 'variables': { - 'chromium_code': 1, - # Override to dynamically link the PulseAudio library. - 'use_pulseaudio%': 0, - # Override to dynamically link the cras (ChromeOS audio) library. - 'use_cras%': 0, - }, - 'targets': [ - { - 'target_name': 'media', - 'type': '<(component)', - 'dependencies': [ - 'yuv_convert', - '../base/base.gyp:base', - '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - '../build/temp_gyp/googleurl.gyp:googleurl', - '../crypto/crypto.gyp:crypto', - '../third_party/openmax/openmax.gyp:il', - '../ui/ui.gyp:ui', - ], - 'defines': [ - 'MEDIA_IMPLEMENTATION', - ], - 'include_dirs': [ - '..', - ], - 'sources': [ - 'audio/android/audio_manager_android.cc', - 'audio/android/audio_manager_android.h', - 'audio/android/audio_track_output_android.cc', - 'audio/android/audio_track_output_android.h', - 'audio/android/opensles_input.cc', - 'audio/android/opensles_input.h', - 'audio/android/opensles_output.cc', - 'audio/android/opensles_output.h', - 'audio/async_socket_io_handler.h', - 'audio/async_socket_io_handler_posix.cc', - 'audio/async_socket_io_handler_win.cc', - 'audio/audio_buffers_state.cc', - 'audio/audio_buffers_state.h', - 'audio/audio_io.h', - 'audio/audio_input_controller.cc', - 'audio/audio_input_controller.h', - 'audio/audio_input_stream_impl.cc', - 'audio/audio_input_stream_impl.h', - 'audio/audio_device_name.cc', - 'audio/audio_device_name.h', - 'audio/audio_manager.cc', - 'audio/audio_manager.h', - 'audio/audio_manager_base.cc', - 'audio/audio_manager_base.h', - 'audio/audio_output_controller.cc', - 'audio/audio_output_controller.h', - 'audio/audio_output_dispatcher.cc', - 'audio/audio_output_dispatcher.h', - 'audio/audio_output_dispatcher_impl.cc', - 'audio/audio_output_dispatcher_impl.h', - 'audio/audio_output_mixer.cc', - 'audio/audio_output_mixer.h', - 'audio/audio_output_proxy.cc', - 'audio/audio_output_proxy.h', - 'audio/audio_parameters.cc', - 'audio/audio_parameters.h', - 'audio/audio_util.cc', - 'audio/audio_util.h', - 'audio/cross_process_notification.cc', - 'audio/cross_process_notification.h', - 'audio/cross_process_notification_win.cc', - 'audio/cross_process_notification_posix.cc', - 'audio/fake_audio_input_stream.cc', - 'audio/fake_audio_input_stream.h', - 'audio/fake_audio_output_stream.cc', - 'audio/fake_audio_output_stream.h', - 'audio/linux/audio_manager_linux.cc', - 'audio/linux/audio_manager_linux.h', - 'audio/linux/alsa_input.cc', - 'audio/linux/alsa_input.h', - 'audio/linux/alsa_output.cc', - 'audio/linux/alsa_output.h', - 'audio/linux/alsa_util.cc', - 'audio/linux/alsa_util.h', - 'audio/linux/alsa_wrapper.cc', - 'audio/linux/alsa_wrapper.h', - 'audio/linux/cras_output.cc', - 'audio/linux/cras_output.h', - 'audio/openbsd/audio_manager_openbsd.cc', - 'audio/openbsd/audio_manager_openbsd.h', - 'audio/mac/audio_input_mac.cc', - 'audio/mac/audio_input_mac.h', - 'audio/mac/audio_low_latency_input_mac.cc', - 'audio/mac/audio_low_latency_input_mac.h', - 'audio/mac/audio_low_latency_output_mac.cc', - 'audio/mac/audio_low_latency_output_mac.h', - 'audio/mac/audio_manager_mac.cc', - 'audio/mac/audio_manager_mac.h', - 'audio/mac/audio_output_mac.cc', - 'audio/mac/audio_output_mac.h', - 'audio/null_audio_sink.cc', - 'audio/null_audio_sink.h', - 'audio/pulse/pulse_output.cc', - 'audio/pulse/pulse_output.h', - 'audio/sample_rates.cc', - 'audio/sample_rates.h', - 'audio/simple_sources.cc', - 'audio/simple_sources.h', - 'audio/win/audio_low_latency_input_win.cc', - 'audio/win/audio_low_latency_input_win.h', - 'audio/win/audio_low_latency_output_win.cc', - 'audio/win/audio_low_latency_output_win.h', - 'audio/win/audio_manager_win.cc', - 'audio/win/audio_manager_win.h', - 'audio/win/avrt_wrapper_win.cc', - 'audio/win/avrt_wrapper_win.h', - 'audio/win/device_enumeration_win.cc', - 'audio/win/device_enumeration_win.h', - 'audio/win/wavein_input_win.cc', - 'audio/win/wavein_input_win.h', - 'audio/win/waveout_output_win.cc', - 'audio/win/waveout_output_win.h', - 'base/android/media_jni_registrar.cc', - 'base/android/media_jni_registrar.h', - 'base/audio_decoder.cc', - 'base/audio_decoder.h', - 'base/audio_decoder_config.cc', - 'base/audio_decoder_config.h', - 'base/audio_renderer.h', - 'base/audio_renderer_mixer.cc', - 'base/audio_renderer_mixer.h', - 'base/audio_renderer_mixer_input.cc', - 'base/audio_renderer_mixer_input.h', - 'base/bitstream_buffer.h', - 'base/buffers.cc', - 'base/buffers.h', - 'base/byte_queue.cc', - 'base/byte_queue.h', - 'base/channel_layout.cc', - 'base/channel_layout.h', - 'base/clock.cc', - 'base/clock.h', - 'base/composite_filter.cc', - 'base/composite_filter.h', - 'base/data_buffer.cc', - 'base/data_buffer.h', - 'base/data_source.cc', - 'base/data_source.h', - 'base/decoder_buffer.cc', - 'base/decoder_buffer.h', - 'base/decrypt_config.cc', - 'base/decrypt_config.h', - 'base/decryptor.h', - 'base/decryptor_client.h', - 'base/demuxer.cc', - 'base/demuxer.h', - 'base/demuxer_stream.cc', - 'base/demuxer_stream.h', - 'base/djb2.cc', - 'base/djb2.h', - 'base/filter_collection.cc', - 'base/filter_collection.h', - 'base/filter_host.h', - 'base/filters.cc', - 'base/filters.h', - 'base/h264_bitstream_converter.cc', - 'base/h264_bitstream_converter.h', - 'base/media.h', - 'base/media_android.cc', - 'base/media_export.h', - 'base/media_log.cc', - 'base/media_log.h', - 'base/media_log_event.h', - 'base/media_posix.cc', - 'base/media_switches.cc', - 'base/media_switches.h', - 'base/media_win.cc', - 'base/message_loop_factory.cc', - 'base/message_loop_factory.h', - 'base/pipeline.cc', - 'base/pipeline.h', - 'base/pipeline_status.cc', - 'base/pipeline_status.h', - 'base/ranges.cc', - 'base/ranges.h', - 'base/seekable_buffer.cc', - 'base/seekable_buffer.h', - 'base/state_matrix.cc', - 'base/state_matrix.h', - 'base/stream_parser.cc', - 'base/stream_parser.h', - 'base/stream_parser_buffer.cc', - 'base/stream_parser_buffer.h', - 'base/video_decoder.cc', - 'base/video_decoder.h', - 'base/video_decoder_config.cc', - 'base/video_decoder_config.h', - 'base/video_frame.cc', - 'base/video_frame.h', - 'base/video_renderer.h', - 'base/video_util.cc', - 'base/video_util.h', - 'crypto/aes_decryptor.cc', - 'crypto/aes_decryptor.h', - 'ffmpeg/ffmpeg_common.cc', - 'ffmpeg/ffmpeg_common.h', - 'ffmpeg/file_protocol.cc', - 'ffmpeg/file_protocol.h', - 'filters/audio_file_reader.cc', - 'filters/audio_file_reader.h', - 'filters/audio_renderer_algorithm.cc', - 'filters/audio_renderer_algorithm.h', - 'filters/audio_renderer_impl.cc', - 'filters/audio_renderer_impl.h', - 'filters/bitstream_converter.cc', - 'filters/bitstream_converter.h', - 'filters/chunk_demuxer.cc', - 'filters/chunk_demuxer.h', - 'filters/chunk_demuxer_client.h', - 'filters/dummy_demuxer.cc', - 'filters/dummy_demuxer.h', - 'filters/ffmpeg_audio_decoder.cc', - 'filters/ffmpeg_audio_decoder.h', - 'filters/ffmpeg_demuxer.cc', - 'filters/ffmpeg_demuxer.h', - 'filters/ffmpeg_h264_bitstream_converter.cc', - 'filters/ffmpeg_h264_bitstream_converter.h', - 'filters/ffmpeg_glue.cc', - 'filters/ffmpeg_glue.h', - 'filters/ffmpeg_video_decoder.cc', - 'filters/ffmpeg_video_decoder.h', - 'filters/file_data_source.cc', - 'filters/file_data_source.h', - 'filters/gpu_video_decoder.cc', - 'filters/gpu_video_decoder.h', - 'filters/in_memory_url_protocol.cc', - 'filters/in_memory_url_protocol.h', - 'filters/source_buffer_stream.cc', - 'filters/source_buffer_stream.h', - 'filters/video_frame_generator.cc', - 'filters/video_frame_generator.h', - 'filters/video_renderer_base.cc', - 'filters/video_renderer_base.h', - 'video/capture/fake_video_capture_device.cc', - 'video/capture/fake_video_capture_device.h', - 'video/capture/linux/video_capture_device_linux.cc', - 'video/capture/linux/video_capture_device_linux.h', - 'video/capture/mac/video_capture_device_mac.h', - 'video/capture/mac/video_capture_device_mac.mm', - 'video/capture/mac/video_capture_device_qtkit_mac.h', - 'video/capture/mac/video_capture_device_qtkit_mac.mm', - 'video/capture/video_capture.h', - 'video/capture/video_capture_device.h', - 'video/capture/video_capture_device_dummy.cc', - 'video/capture/video_capture_device_dummy.h', - 'video/capture/video_capture_proxy.cc', - 'video/capture/video_capture_proxy.h', - 'video/capture/video_capture_types.h', - 'video/capture/win/filter_base_win.cc', - 'video/capture/win/filter_base_win.h', - 'video/capture/win/pin_base_win.cc', - 'video/capture/win/pin_base_win.h', - 'video/capture/win/sink_filter_observer_win.h', - 'video/capture/win/sink_filter_win.cc', - 'video/capture/win/sink_filter_win.h', - 'video/capture/win/sink_input_pin_win.cc', - 'video/capture/win/sink_input_pin_win.h', - 'video/capture/win/video_capture_device_win.cc', - 'video/capture/win/video_capture_device_win.h', - 'video/picture.cc', - 'video/picture.h', - 'video/video_decode_accelerator.cc', - 'video/video_decode_accelerator.h', - 'webm/webm_constants.h', - 'webm/webm_cluster_parser.cc', - 'webm/webm_cluster_parser.h', - 'webm/webm_content_encodings.cc', - 'webm/webm_content_encodings.h', - 'webm/webm_content_encodings_client.cc', - 'webm/webm_content_encodings_client.h', - 'webm/webm_info_parser.cc', - 'webm/webm_info_parser.h', - 'webm/webm_parser.cc', - 'webm/webm_parser.h', - 'webm/webm_stream_parser.cc', - 'webm/webm_stream_parser.h', - 'webm/webm_tracks_parser.cc', - 'webm/webm_tracks_parser.h', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '..', - ], - }, - 'conditions': [ - # Android doesn't use ffmpeg, so make the dependency conditional - # and exclude the sources which depend on ffmpeg. - ['OS != \"android\"', { - 'dependencies': [ - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - }], - ['OS == \"android\"', { - 'sources!': [ - 'base/media_posix.cc', - 'ffmpeg/ffmpeg_common.cc', - 'ffmpeg/ffmpeg_common.h', - 'ffmpeg/file_protocol.cc', - 'ffmpeg/file_protocol.h', - 'filters/audio_file_reader.cc', - 'filters/audio_file_reader.h', - 'filters/bitstream_converter.cc', - 'filters/bitstream_converter.h', - 'filters/chunk_demuxer.cc', - 'filters/chunk_demuxer.h', - 'filters/chunk_demuxer_client.h', - 'filters/ffmpeg_audio_decoder.cc', - 'filters/ffmpeg_audio_decoder.h', - 'filters/ffmpeg_demuxer.cc', - 'filters/ffmpeg_demuxer.h', - 'filters/ffmpeg_h264_bitstream_converter.cc', - 'filters/ffmpeg_h264_bitstream_converter.h', - 'filters/ffmpeg_glue.cc', - 'filters/ffmpeg_glue.h', - 'filters/ffmpeg_video_decoder.cc', - 'filters/ffmpeg_video_decoder.h', - 'filters/gpu_video_decoder.cc', - 'filters/gpu_video_decoder.h', - 'webm/webm_cluster_parser.cc', - 'webm/webm_cluster_parser.h', - 'webm/webm_stream_parser.cc', - 'webm/webm_stream_parser.h', - ], - }], - # The below 'android' condition were added temporarily and should be - # removed in downstream, because there is no Java environment setup in - # upstream yet. - ['OS == \"android\"', { - 'sources!':[ - 'audio/android/audio_track_output_android.cc', - ], - 'sources':[ - 'audio/android/audio_track_output_stub_android.cc', - ], - 'link_settings': { - 'libraries': [ - '-lOpenSLES', - ], - }, - }], - ['OS==\"linux\" or OS==\"freebsd\" or OS==\"solaris\"', { - 'link_settings': { - 'libraries': [ - '-lasound', - ], - }, - }], - ['OS==\"openbsd\"', { - 'sources/': [ ['exclude', '/alsa_' ], - ['exclude', '/audio_manager_linux' ] ], - 'link_settings': { - 'libraries': [ - ], - }, - }], - ['OS!=\"openbsd\"', { - 'sources!': [ - 'audio/openbsd/audio_manager_openbsd.cc', - 'audio/openbsd/audio_manager_openbsd.h', - ], - }], - ['OS==\"linux\"', { - 'variables': { - 'conditions': [ - ['sysroot!=\"\"', { - 'pkg-config': '../build/linux/pkg-config-wrapper \"<(sysroot)\" \"<(target_arch)\"', - }, { - 'pkg-config': 'pkg-config' - }], - ], - }, - 'conditions': [ - ['use_cras == 1', { - 'cflags': [ - '<!@(<(pkg-config) --cflags libcras)', - ], - 'link_settings': { - 'libraries': [ - '<!@(<(pkg-config) --libs libcras)', - ], - }, - 'defines': [ - 'USE_CRAS', - ], - }, { # else: use_cras == 0 - 'sources!': [ - 'audio/linux/cras_output.cc', - 'audio/linux/cras_output.h', - ], - }], - ], - }], - ['os_posix == 1', { - 'conditions': [ - ['use_pulseaudio == 1', { - 'cflags': [ - '<!@(pkg-config --cflags libpulse)', - ], - 'link_settings': { - 'libraries': [ - '<!@(pkg-config --libs-only-l libpulse)', - ], - }, - 'defines': [ - 'USE_PULSEAUDIO', - ], - }, { # else: use_pulseaudio == 0 - 'sources!': [ - 'audio/pulse/pulse_output.cc', - 'audio/pulse/pulse_output.h', - ], - }], - ], - }], - ['os_posix == 1 and OS != \"android\"', { - # Video capture isn't supported in Android yet. - 'sources!': [ - 'video/capture/video_capture_device_dummy.cc', - 'video/capture/video_capture_device_dummy.h', - ], - }], - ['OS==\"mac\"', { - 'link_settings': { - 'libraries': [ - '$(SDKROOT)/System/Library/Frameworks/AudioUnit.framework', - '$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework', - '$(SDKROOT)/System/Library/Frameworks/CoreAudio.framework', - '$(SDKROOT)/System/Library/Frameworks/CoreVideo.framework', - '$(SDKROOT)/System/Library/Frameworks/QTKit.framework', - ], - }, - }], - ['OS==\"win\"', { - 'sources!': [ - 'audio/pulse/pulse_output.cc', - 'audio/pulse/pulse_output.h', - 'video/capture/video_capture_device_dummy.cc', - 'video/capture/video_capture_device_dummy.h', - ], - }], - ['proprietary_codecs==1 or branding==\"Chrome\"', { - 'sources': [ - 'mp4/avc.cc', - 'mp4/avc.h', - 'mp4/box_definitions.cc', - 'mp4/box_definitions.h', - 'mp4/box_reader.cc', - 'mp4/box_reader.h', - 'mp4/cenc.cc', - 'mp4/cenc.h', - 'mp4/mp4_stream_parser.cc', - 'mp4/mp4_stream_parser.h', - 'mp4/offset_byte_queue.cc', - 'mp4/offset_byte_queue.h', - 'mp4/track_run_iterator.cc', - 'mp4/track_run_iterator.h', - ], - }], - ], - }, - { - 'target_name': 'yuv_convert', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'conditions': [ - ['order_profiling != 0', { - 'target_conditions' : [ - ['_toolset==\"target\"', { - 'cflags!': [ '-finstrument-functions' ], - }], - ], - }], - [ 'target_arch == \"ia32\" or target_arch == \"x64\"', { - 'dependencies': [ - 'yuv_convert_simd_x86', - ], - }], - [ 'target_arch == \"arm\"', { - 'dependencies': [ - 'yuv_convert_simd_arm', - ], - }], - ], - 'sources': [ - 'base/yuv_convert.cc', - 'base/yuv_convert.h', - ], - }, - { - 'target_name': 'yuv_convert_simd_x86', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'sources': [ - 'base/simd/convert_rgb_to_yuv_c.cc', - 'base/simd/convert_rgb_to_yuv_sse2.cc', - 'base/simd/convert_rgb_to_yuv_ssse3.asm', - 'base/simd/convert_rgb_to_yuv_ssse3.cc', - 'base/simd/convert_rgb_to_yuv_ssse3.inc', - 'base/simd/convert_yuv_to_rgb_c.cc', - 'base/simd/convert_yuv_to_rgb_x86.cc', - 'base/simd/convert_yuv_to_rgb_mmx.asm', - 'base/simd/convert_yuv_to_rgb_mmx.inc', - 'base/simd/convert_yuv_to_rgb_sse.asm', - 'base/simd/filter_yuv.h', - 'base/simd/filter_yuv_c.cc', - 'base/simd/filter_yuv_mmx.cc', - 'base/simd/filter_yuv_sse2.cc', - 'base/simd/linear_scale_yuv_to_rgb_mmx.asm', - 'base/simd/linear_scale_yuv_to_rgb_mmx.inc', - 'base/simd/linear_scale_yuv_to_rgb_sse.asm', - 'base/simd/scale_yuv_to_rgb_mmx.asm', - 'base/simd/scale_yuv_to_rgb_mmx.inc', - 'base/simd/scale_yuv_to_rgb_sse.asm', - 'base/simd/yuv_to_rgb_table.cc', - 'base/simd/yuv_to_rgb_table.h', - ], - 'conditions': [ - ['order_profiling != 0', { - 'target_conditions' : [ - ['_toolset==\"target\"', { - 'cflags!': [ '-finstrument-functions' ], - }], - ], - }], - [ 'target_arch == \"x64\"', { - # Source files optimized for X64 systems. - 'sources': [ - 'base/simd/linear_scale_yuv_to_rgb_mmx_x64.asm', - 'base/simd/scale_yuv_to_rgb_sse2_x64.asm', - ], - }], - [ 'os_posix == 1 and OS != \"mac\" and OS != \"android\"', { - 'cflags': [ - '-msse2', - ], - }], - [ 'OS == \"mac\"', { - 'configurations': { - 'Debug': { - 'xcode_settings': { - # gcc on the mac builds horribly unoptimized sse code in debug - # mode. Since this is rarely going to be debugged, run with full - # optimizations in Debug as well as Release. - 'GCC_OPTIMIZATION_LEVEL': '3', # -O3 - }, - }, - }, - }], - [ 'OS==\"win\"', { - 'variables': { - 'yasm_flags': [ - '-DWIN32', - '-DMSVC', - '-DCHROMIUM', - '-Isimd', - ], - }, - }], - [ 'OS==\"mac\"', { - 'variables': { - 'yasm_flags': [ - '-DPREFIX', - '-DMACHO', - '-DCHROMIUM', - '-Isimd', - ], - }, - }], - [ 'os_posix==1 and OS!=\"mac\"', { - 'variables': { - 'conditions': [ - [ 'target_arch==\"ia32\"', { - 'yasm_flags': [ - '-DX86_32', - '-DELF', - '-DCHROMIUM', - '-Isimd', - ], - }, { - 'yasm_flags': [ - '-DARCH_X86_64', - '-DELF', - '-DPIC', - '-DCHROMIUM', - '-Isimd', - ], - }], - ], - }, - }], - ], - 'variables': { - 'yasm_output_path': '<(SHARED_INTERMEDIATE_DIR)/media', - }, - 'msvs_2010_disable_uldi_when_referenced': 1, - 'includes': [ - '../third_party/yasm/yasm_compile.gypi', - ], - }, - { - 'target_name': 'yuv_convert_simd_arm', - 'type': 'static_library', - 'include_dirs': [ - '..', - ], - 'sources': [ - 'base/simd/convert_rgb_to_yuv_c.cc', - 'base/simd/convert_rgb_to_yuv.h', - 'base/simd/convert_yuv_to_rgb_c.cc', - 'base/simd/convert_yuv_to_rgb.h', - 'base/simd/filter_yuv.h', - 'base/simd/filter_yuv_c.cc', - 'base/simd/yuv_to_rgb_table.cc', - 'base/simd/yuv_to_rgb_table.h', - ], - }, - { - 'target_name': 'media_unittests', - 'type': 'executable', - 'dependencies': [ - 'media', - 'media_test_support', - 'yuv_convert', - '../base/base.gyp:base', - '../base/base.gyp:base_i18n', - '../base/base.gyp:test_support_base', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - '../ui/ui.gyp:ui', - ], - 'sources': [ - 'audio/async_socket_io_handler_unittest.cc', - 'audio/audio_input_controller_unittest.cc', - 'audio/audio_input_device_unittest.cc', - 'audio/audio_input_unittest.cc', - 'audio/audio_input_volume_unittest.cc', - 'audio/audio_low_latency_input_output_unittest.cc', - 'audio/audio_output_controller_unittest.cc', - 'audio/audio_output_proxy_unittest.cc', - 'audio/audio_parameters_unittest.cc', - 'audio/audio_util_unittest.cc', - 'audio/cross_process_notification_unittest.cc', - 'audio/linux/alsa_output_unittest.cc', - 'audio/mac/audio_low_latency_input_mac_unittest.cc', - 'audio/mac/audio_output_mac_unittest.cc', - 'audio/simple_sources_unittest.cc', - 'audio/win/audio_low_latency_input_win_unittest.cc', - 'audio/win/audio_low_latency_output_win_unittest.cc', - 'audio/win/audio_output_win_unittest.cc', - 'base/audio_renderer_mixer_unittest.cc', - 'base/audio_renderer_mixer_input_unittest.cc', - 'base/buffers_unittest.cc', - 'base/clock_unittest.cc', - 'base/composite_filter_unittest.cc', - 'base/data_buffer_unittest.cc', - 'base/decoder_buffer_unittest.cc', - 'base/djb2_unittest.cc', - 'base/fake_audio_render_callback.cc', - 'base/fake_audio_render_callback.h', - 'base/filter_collection_unittest.cc', - 'base/h264_bitstream_converter_unittest.cc', - 'base/pipeline_unittest.cc', - 'base/ranges_unittest.cc', - 'base/run_all_unittests.cc', - 'base/seekable_buffer_unittest.cc', - 'base/state_matrix_unittest.cc', - 'base/test_data_util.cc', - 'base/test_data_util.h', - 'base/video_frame_unittest.cc', - 'base/video_util_unittest.cc', - 'base/yuv_convert_unittest.cc', - 'crypto/aes_decryptor_unittest.cc', - 'ffmpeg/ffmpeg_common_unittest.cc', - 'filters/audio_renderer_algorithm_unittest.cc', - 'filters/audio_renderer_impl_unittest.cc', - 'filters/bitstream_converter_unittest.cc', - 'filters/chunk_demuxer_unittest.cc', - 'filters/ffmpeg_audio_decoder_unittest.cc', - 'filters/ffmpeg_decoder_unittest.h', - 'filters/ffmpeg_demuxer_unittest.cc', - 'filters/ffmpeg_glue_unittest.cc', - 'filters/ffmpeg_h264_bitstream_converter_unittest.cc', - 'filters/ffmpeg_video_decoder_unittest.cc', - 'filters/file_data_source_unittest.cc', - 'filters/pipeline_integration_test.cc', - 'filters/pipeline_integration_test_base.cc', - 'filters/source_buffer_stream_unittest.cc', - 'filters/video_renderer_base_unittest.cc', - 'video/capture/video_capture_device_unittest.cc', - 'webm/cluster_builder.cc', - 'webm/cluster_builder.h', - 'webm/webm_cluster_parser_unittest.cc', - 'webm/webm_content_encodings_client_unittest.cc', - 'webm/webm_parser_unittest.cc', - ], - 'conditions': [ - ['os_posix==1 and OS!=\"mac\"', { - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }], - ['OS != \"android\"', { - 'dependencies': [ - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - }], - ['OS == \"android\"', { - 'sources!': [ - 'audio/audio_input_volume_unittest.cc', - 'base/test_data_util.cc', - 'base/test_data_util.h', - 'ffmpeg/ffmpeg_common_unittest.cc', - 'filters/ffmpeg_audio_decoder_unittest.cc', - 'filters/bitstream_converter_unittest.cc', - 'filters/chunk_demuxer_unittest.cc', - 'filters/ffmpeg_demuxer_unittest.cc', - 'filters/ffmpeg_glue_unittest.cc', - 'filters/ffmpeg_h264_bitstream_converter_unittest.cc', - 'filters/ffmpeg_video_decoder_unittest.cc', - 'filters/pipeline_integration_test.cc', - 'filters/pipeline_integration_test_base.cc', - 'mp4/mp4_stream_parser_unittest.cc', - 'webm/webm_cluster_parser_unittest.cc', - ], - }], - ['OS == \"linux\"', { - 'conditions': [ - ['use_cras == 1', { - 'sources': [ - 'audio/linux/cras_output_unittest.cc', - ], - 'defines': [ - 'USE_CRAS', - ], - }], - ], - }], - [ 'target_arch==\"ia32\" or target_arch==\"x64\"', { - 'sources': [ - 'base/simd/convert_rgb_to_yuv_unittest.cc', - ], - }], - ['proprietary_codecs==1 or branding==\"Chrome\"', { - 'sources': [ - 'mp4/avc_unittest.cc', - 'mp4/box_reader_unittest.cc', - 'mp4/mp4_stream_parser_unittest.cc', - 'mp4/offset_byte_queue_unittest.cc', - ], - }], - ], - }, - { - 'target_name': 'media_test_support', - 'type': 'static_library', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - ], - 'sources': [ - 'audio/test_audio_input_controller_factory.cc', - 'audio/test_audio_input_controller_factory.h', - 'base/mock_callback.cc', - 'base/mock_callback.h', - 'base/mock_data_source_host.cc', - 'base/mock_data_source_host.h', - 'base/mock_demuxer_host.cc', - 'base/mock_demuxer_host.h', - 'base/mock_filter_host.cc', - 'base/mock_filter_host.h', - 'base/mock_filters.cc', - 'base/mock_filters.h', - ], - }, - { - 'target_name': 'scaler_bench', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../skia/skia.gyp:skia', - ], - 'sources': [ - 'tools/scaler_bench/scaler_bench.cc', - ], - }, - { - 'target_name': 'qt_faststart', - 'type': 'executable', - 'sources': [ - 'tools/qt_faststart/qt_faststart.c' - ], - }, - { - 'target_name': 'seek_tester', - 'type': 'executable', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - ], - 'sources': [ - 'tools/seek_tester/seek_tester.cc', - ], - }, - ], - 'conditions': [ - ['OS==\"win\"', { - 'targets': [ - { - 'target_name': 'player_wtl', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - '../ui/ui.gyp:ui', - ], - 'include_dirs': [ - '<(DEPTH)/third_party/wtl/include', - ], - 'sources': [ - 'tools/player_wtl/list.h', - 'tools/player_wtl/mainfrm.h', - 'tools/player_wtl/movie.cc', - 'tools/player_wtl/movie.h', - 'tools/player_wtl/player_wtl.cc', - 'tools/player_wtl/player_wtl.rc', - 'tools/player_wtl/props.h', - 'tools/player_wtl/seek.h', - 'tools/player_wtl/resource.h', - 'tools/player_wtl/view.h', - ], - 'msvs_settings': { - 'VCLinkerTool': { - 'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS - }, - }, - 'defines': [ - '_CRT_SECURE_NO_WARNINGS=1', - ], - }, - ], - }], - ['OS == \"win\" or toolkit_uses_gtk == 1', { - 'targets': [ - { - 'target_name': 'shader_bench', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../ui/gl/gl.gyp:gl', - ], - 'sources': [ - 'tools/shader_bench/shader_bench.cc', - 'tools/shader_bench/cpu_color_painter.cc', - 'tools/shader_bench/cpu_color_painter.h', - 'tools/shader_bench/gpu_color_painter.cc', - 'tools/shader_bench/gpu_color_painter.h', - 'tools/shader_bench/gpu_painter.cc', - 'tools/shader_bench/gpu_painter.h', - 'tools/shader_bench/painter.cc', - 'tools/shader_bench/painter.h', - 'tools/shader_bench/window.cc', - 'tools/shader_bench/window.h', - ], - 'conditions': [ - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - '../build/linux/system.gyp:gtk', - ], - 'sources': [ - 'tools/shader_bench/window_linux.cc', - ], - }], - ['OS==\"win\"', { - 'dependencies': [ - '../third_party/angle/src/build_angle.gyp:libEGL', - '../third_party/angle/src/build_angle.gyp:libGLESv2', - ], - 'sources': [ - 'tools/shader_bench/window_win.cc', - ], - }], - ], - }, - ], - }], - ['OS == \"linux\" and target_arch != \"arm\"', { - 'targets': [ - { - 'target_name': 'tile_render_bench', - 'type': 'executable', - 'dependencies': [ - '../base/base.gyp:base', - '../ui/gl/gl.gyp:gl', - ], - 'libraries': [ - '-lGL', - '-ldl', - ], - 'sources': [ - 'tools/tile_render_bench/tile_render_bench.cc', - ], - }, - ], - }], - ['os_posix == 1 and OS != \"mac\" and OS != \"android\"', { - 'targets': [ - { - 'target_name': 'player_x11', - 'type': 'executable', - 'dependencies': [ - 'media', - 'yuv_convert', - '../base/base.gyp:base', - '../ui/gl/gl.gyp:gl', - ], - 'link_settings': { - 'libraries': [ - '-ldl', - '-lX11', - '-lXrender', - '-lXext', - ], - }, - 'sources': [ - 'tools/player_x11/data_source_logger.cc', - 'tools/player_x11/data_source_logger.h', - 'tools/player_x11/gl_video_renderer.cc', - 'tools/player_x11/gl_video_renderer.h', - 'tools/player_x11/player_x11.cc', - 'tools/player_x11/x11_video_renderer.cc', - 'tools/player_x11/x11_video_renderer.h', - ], - }, - ], - }], - ['OS == \"android\"', { - 'targets': [ - { - 'target_name': 'player_android', - 'type': 'static_library', - 'sources': [ - 'base/android/media_player_bridge.cc', - 'base/android/media_player_bridge.h', - ], - 'dependencies': [ - '../base/base.gyp:base', - ], - 'include_dirs': [ - '<(SHARED_INTERMEDIATE_DIR)/media', - ], - 'actions': [ - { - 'action_name': 'generate-jni-headers', - 'inputs': [ - '../base/android/jni_generator/jni_generator.py', - 'base/android/java/src/org/chromium/media/MediaPlayerListener.java', - ], - 'outputs': [ - '<(SHARED_INTERMEDIATE_DIR)/media/jni/media_player_listener_jni.h', - ], - 'action': [ - 'python', - '<(DEPTH)/base/android/jni_generator/jni_generator.py', - '-o', - '<@(_inputs)', - '<@(_outputs)', - ], - }, - ], - }, - { - 'target_name': 'media_java', - 'type': 'none', - 'dependencies': [ '../base/base.gyp:base_java' ], - 'variables': { - 'package_name': 'media', - 'java_in_dir': 'base/android/java', - }, - 'includes': [ '../build/java.gypi' ], - }, - - ], - }, { # OS != \"android\"' - # Android does not use ffmpeg, so disable the targets which require it. - 'targets': [ - { - 'target_name': 'ffmpeg_unittests', - 'type': 'executable', - 'dependencies': [ - 'media', - 'media_test_support', - '../base/base.gyp:base', - '../base/base.gyp:base_i18n', - '../base/base.gyp:test_support_base', - '../base/base.gyp:test_support_perf', - '../testing/gtest.gyp:gtest', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'ffmpeg/ffmpeg_unittest.cc', - ], - 'conditions': [ - ['toolkit_uses_gtk == 1', { - 'dependencies': [ - # Needed for the following #include chain: - # base/run_all_unittests.cc - # ../base/test_suite.h - # gtk/gtk.h - '../build/linux/system.gyp:gtk', - ], - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }], - ], - }, - { - 'target_name': 'ffmpeg_regression_tests', - 'type': 'executable', - 'dependencies': [ - 'media', - 'media_test_support', - '../base/base.gyp:test_support_base', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'base/test_data_util.cc', - 'base/run_all_unittests.cc', - 'ffmpeg/ffmpeg_regression_tests.cc', - 'filters/pipeline_integration_test_base.cc', - ], - 'conditions': [ - ['os_posix==1 and OS!=\"mac\"', { - 'conditions': [ - ['linux_use_tcmalloc==1', { - 'dependencies': [ - '../base/allocator/allocator.gyp:allocator', - ], - }], - ], - }], - ], - }, - { - 'target_name': 'ffmpeg_tests', - 'type': 'executable', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'test/ffmpeg_tests/ffmpeg_tests.cc', - ], - }, - { - 'target_name': 'media_bench', - 'type': 'executable', - 'dependencies': [ - 'media', - '../base/base.gyp:base', - '../third_party/ffmpeg/ffmpeg.gyp:ffmpeg', - ], - 'sources': [ - 'tools/media_bench/media_bench.cc', - ], - }, - ], - }] - ], -} -" 0 64 (face font-lock-comment-face) 64 137 (face font-lock-comment-face) 137 166 (face font-lock-comment-face) 166 171 nil 171 172 (face font-lock-string-face) 172 181 (face font-lock-keyword-face) 181 182 (face font-lock-string-face) 182 190 nil 190 191 (face font-lock-string-face) 191 204 (face font-lock-variable-name-face) 204 205 (face font-lock-string-face) 205 214 nil 214 269 (face font-lock-comment-face) 269 273 nil 273 274 (face font-lock-string-face) 274 289 (face font-lock-variable-name-face) 289 290 (face font-lock-string-face) 290 299 nil 299 365 (face font-lock-comment-face) 365 369 nil 369 370 (face font-lock-string-face) 370 379 (face font-lock-variable-name-face) 379 380 (face font-lock-string-face) 380 392 nil 392 393 (face font-lock-string-face) 393 400 (face font-lock-keyword-face) 400 401 (face font-lock-string-face) 401 417 nil 417 418 (face font-lock-string-face) 418 429 (face font-lock-keyword-face) 429 430 (face font-lock-string-face) 430 432 nil 432 433 (face font-lock-string-face) 433 438 (face font-lock-function-name-face) 438 439 (face font-lock-string-face) 439 447 nil 447 448 (face font-lock-string-face) 448 452 (face font-lock-keyword-face) 452 453 (face font-lock-string-face) 453 455 nil 455 458 (face font-lock-string-face) 458 467 (face font-lock-variable-name-face) 467 469 (face font-lock-string-face) 469 477 nil 477 478 (face font-lock-string-face) 478 490 (face font-lock-keyword-face) 490 491 (face font-lock-string-face) 491 503 nil 503 504 (face font-lock-string-face) 504 515 (face font-lock-function-name-face) 515 516 (face font-lock-string-face) 516 526 nil 526 527 (face font-lock-string-face) 527 548 (face font-lock-function-name-face) 548 549 (face font-lock-string-face) 549 559 nil 559 560 (face font-lock-string-face) 560 643 (face font-lock-function-name-face) 643 644 (face font-lock-string-face) 644 654 nil 654 655 (face font-lock-string-face) 655 696 (face font-lock-function-name-face) 696 697 (face font-lock-string-face) 697 707 nil 707 708 (face font-lock-string-face) 708 735 (face font-lock-function-name-face) 735 736 (face font-lock-string-face) 736 746 nil 746 747 (face font-lock-string-face) 747 784 (face font-lock-function-name-face) 784 785 (face font-lock-string-face) 785 795 nil 795 796 (face font-lock-string-face) 796 811 (face font-lock-function-name-face) 811 812 (face font-lock-string-face) 812 829 nil 829 830 (face font-lock-string-face) 830 837 (face font-lock-keyword-face) 837 838 (face font-lock-string-face) 838 850 nil 850 851 (face font-lock-string-face) 851 871 (face font-lock-preprocessor-face) 871 872 (face font-lock-string-face) 872 889 nil 889 890 (face font-lock-string-face) 890 902 (face font-lock-keyword-face) 902 903 (face font-lock-string-face) 903 915 nil 915 916 (face font-lock-string-face) 916 918 (face font-lock-constant-face) 918 919 (face font-lock-string-face) 919 936 nil 936 937 (face font-lock-string-face) 937 944 (face font-lock-keyword-face) 944 945 (face font-lock-string-face) 945 957 nil 957 958 (face font-lock-string-face) 958 996 (face font-lock-constant-face) 996 997 (face font-lock-string-face) 997 1007 nil 1007 1008 (face font-lock-string-face) 1008 1045 (face font-lock-constant-face) 1045 1046 (face font-lock-string-face) 1046 1056 nil 1056 1057 (face font-lock-string-face) 1057 1100 (face font-lock-constant-face) 1100 1101 (face font-lock-string-face) 1101 1111 nil 1111 1112 (face font-lock-string-face) 1112 1154 (face font-lock-constant-face) 1154 1155 (face font-lock-string-face) 1155 1165 nil 1165 1166 (face font-lock-string-face) 1166 1197 (face font-lock-constant-face) 1197 1198 (face font-lock-string-face) 1198 1208 nil 1208 1209 (face font-lock-string-face) 1209 1239 (face font-lock-constant-face) 1239 1240 (face font-lock-string-face) 1240 1250 nil 1250 1251 (face font-lock-string-face) 1251 1283 (face font-lock-constant-face) 1283 1284 (face font-lock-string-face) 1284 1294 nil 1294 1295 (face font-lock-string-face) 1295 1326 (face font-lock-constant-face) 1326 1327 (face font-lock-string-face) 1327 1337 nil 1337 1338 (face font-lock-string-face) 1338 1369 (face font-lock-constant-face) 1369 1370 (face font-lock-string-face) 1370 1380 nil 1380 1381 (face font-lock-string-face) 1381 1419 (face font-lock-constant-face) 1419 1420 (face font-lock-string-face) 1420 1430 nil 1430 1431 (face font-lock-string-face) 1431 1467 (face font-lock-constant-face) 1467 1468 (face font-lock-string-face) 1468 1478 nil 1478 1479 (face font-lock-string-face) 1479 1507 (face font-lock-constant-face) 1507 1508 (face font-lock-string-face) 1508 1518 nil 1518 1519 (face font-lock-string-face) 1519 1546 (face font-lock-constant-face) 1546 1547 (face font-lock-string-face) 1547 1557 nil 1557 1558 (face font-lock-string-face) 1558 1574 (face font-lock-constant-face) 1574 1575 (face font-lock-string-face) 1575 1585 nil 1585 1586 (face font-lock-string-face) 1586 1617 (face font-lock-constant-face) 1617 1618 (face font-lock-string-face) 1618 1628 nil 1628 1629 (face font-lock-string-face) 1629 1659 (face font-lock-constant-face) 1659 1660 (face font-lock-string-face) 1660 1670 nil 1670 1671 (face font-lock-string-face) 1671 1703 (face font-lock-constant-face) 1703 1704 (face font-lock-string-face) 1704 1714 nil 1714 1715 (face font-lock-string-face) 1715 1746 (face font-lock-constant-face) 1746 1747 (face font-lock-string-face) 1747 1757 nil 1757 1758 (face font-lock-string-face) 1758 1784 (face font-lock-constant-face) 1784 1785 (face font-lock-string-face) 1785 1795 nil 1795 1796 (face font-lock-string-face) 1796 1821 (face font-lock-constant-face) 1821 1822 (face font-lock-string-face) 1822 1832 nil 1832 1833 (face font-lock-string-face) 1833 1855 (face font-lock-constant-face) 1855 1856 (face font-lock-string-face) 1856 1866 nil 1866 1867 (face font-lock-string-face) 1867 1888 (face font-lock-constant-face) 1888 1889 (face font-lock-string-face) 1889 1899 nil 1899 1900 (face font-lock-string-face) 1900 1927 (face font-lock-constant-face) 1927 1928 (face font-lock-string-face) 1928 1938 nil 1938 1939 (face font-lock-string-face) 1939 1965 (face font-lock-constant-face) 1965 1966 (face font-lock-string-face) 1966 1976 nil 1976 1977 (face font-lock-string-face) 1977 2009 (face font-lock-constant-face) 2009 2010 (face font-lock-string-face) 2010 2020 nil 2020 2021 (face font-lock-string-face) 2021 2052 (face font-lock-constant-face) 2052 2053 (face font-lock-string-face) 2053 2063 nil 2063 2064 (face font-lock-string-face) 2064 2096 (face font-lock-constant-face) 2096 2097 (face font-lock-string-face) 2097 2107 nil 2107 2108 (face font-lock-string-face) 2108 2139 (face font-lock-constant-face) 2139 2140 (face font-lock-string-face) 2140 2150 nil 2150 2151 (face font-lock-string-face) 2151 2188 (face font-lock-constant-face) 2188 2189 (face font-lock-string-face) 2189 2199 nil 2199 2200 (face font-lock-string-face) 2200 2236 (face font-lock-constant-face) 2236 2237 (face font-lock-string-face) 2237 2247 nil 2247 2248 (face font-lock-string-face) 2248 2275 (face font-lock-constant-face) 2275 2276 (face font-lock-string-face) 2276 2286 nil 2286 2287 (face font-lock-string-face) 2287 2313 (face font-lock-constant-face) 2313 2314 (face font-lock-string-face) 2314 2324 nil 2324 2325 (face font-lock-string-face) 2325 2352 (face font-lock-constant-face) 2352 2353 (face font-lock-string-face) 2353 2363 nil 2363 2364 (face font-lock-string-face) 2364 2390 (face font-lock-constant-face) 2390 2391 (face font-lock-string-face) 2391 2401 nil 2401 2402 (face font-lock-string-face) 2402 2427 (face font-lock-constant-face) 2427 2428 (face font-lock-string-face) 2428 2438 nil 2438 2439 (face font-lock-string-face) 2439 2463 (face font-lock-constant-face) 2463 2464 (face font-lock-string-face) 2464 2474 nil 2474 2475 (face font-lock-string-face) 2475 2494 (face font-lock-constant-face) 2494 2495 (face font-lock-string-face) 2495 2505 nil 2505 2506 (face font-lock-string-face) 2506 2524 (face font-lock-constant-face) 2524 2525 (face font-lock-string-face) 2525 2535 nil 2535 2536 (face font-lock-string-face) 2536 2571 (face font-lock-constant-face) 2571 2572 (face font-lock-string-face) 2572 2582 nil 2582 2583 (face font-lock-string-face) 2583 2617 (face font-lock-constant-face) 2617 2618 (face font-lock-string-face) 2618 2628 nil 2628 2629 (face font-lock-string-face) 2629 2668 (face font-lock-constant-face) 2668 2669 (face font-lock-string-face) 2669 2679 nil 2679 2680 (face font-lock-string-face) 2680 2721 (face font-lock-constant-face) 2721 2722 (face font-lock-string-face) 2722 2732 nil 2732 2733 (face font-lock-string-face) 2733 2765 (face font-lock-constant-face) 2765 2766 (face font-lock-string-face) 2766 2776 nil 2776 2777 (face font-lock-string-face) 2777 2808 (face font-lock-constant-face) 2808 2809 (face font-lock-string-face) 2809 2819 nil 2819 2820 (face font-lock-string-face) 2820 2853 (face font-lock-constant-face) 2853 2854 (face font-lock-string-face) 2854 2864 nil 2864 2865 (face font-lock-string-face) 2865 2897 (face font-lock-constant-face) 2897 2898 (face font-lock-string-face) 2898 2908 nil 2908 2909 (face font-lock-string-face) 2909 2943 (face font-lock-constant-face) 2943 2944 (face font-lock-string-face) 2944 2954 nil 2954 2955 (face font-lock-string-face) 2955 2988 (face font-lock-constant-face) 2988 2989 (face font-lock-string-face) 2989 2999 nil 2999 3000 (face font-lock-string-face) 3000 3025 (face font-lock-constant-face) 3025 3026 (face font-lock-string-face) 3026 3036 nil 3036 3037 (face font-lock-string-face) 3037 3061 (face font-lock-constant-face) 3061 3062 (face font-lock-string-face) 3062 3072 nil 3072 3073 (face font-lock-string-face) 3073 3099 (face font-lock-constant-face) 3099 3100 (face font-lock-string-face) 3100 3110 nil 3110 3111 (face font-lock-string-face) 3111 3136 (face font-lock-constant-face) 3136 3137 (face font-lock-string-face) 3137 3147 nil 3147 3148 (face font-lock-string-face) 3148 3172 (face font-lock-constant-face) 3172 3173 (face font-lock-string-face) 3173 3183 nil 3183 3184 (face font-lock-string-face) 3184 3207 (face font-lock-constant-face) 3207 3208 (face font-lock-string-face) 3208 3218 nil 3218 3219 (face font-lock-string-face) 3219 3246 (face font-lock-constant-face) 3246 3247 (face font-lock-string-face) 3247 3257 nil 3257 3258 (face font-lock-string-face) 3258 3284 (face font-lock-constant-face) 3284 3285 (face font-lock-string-face) 3285 3295 nil 3295 3296 (face font-lock-string-face) 3296 3322 (face font-lock-constant-face) 3322 3323 (face font-lock-string-face) 3323 3333 nil 3333 3334 (face font-lock-string-face) 3334 3359 (face font-lock-constant-face) 3359 3360 (face font-lock-string-face) 3360 3370 nil 3370 3371 (face font-lock-string-face) 3371 3409 (face font-lock-constant-face) 3409 3410 (face font-lock-string-face) 3410 3420 nil 3420 3421 (face font-lock-string-face) 3421 3458 (face font-lock-constant-face) 3458 3459 (face font-lock-string-face) 3459 3469 nil 3469 3470 (face font-lock-string-face) 3470 3498 (face font-lock-constant-face) 3498 3499 (face font-lock-string-face) 3499 3509 nil 3509 3510 (face font-lock-string-face) 3510 3537 (face font-lock-constant-face) 3537 3538 (face font-lock-string-face) 3538 3548 nil 3548 3549 (face font-lock-string-face) 3549 3589 (face font-lock-constant-face) 3589 3590 (face font-lock-string-face) 3590 3600 nil 3600 3601 (face font-lock-string-face) 3601 3640 (face font-lock-constant-face) 3640 3641 (face font-lock-string-face) 3641 3651 nil 3651 3652 (face font-lock-string-face) 3652 3693 (face font-lock-constant-face) 3693 3694 (face font-lock-string-face) 3694 3704 nil 3704 3705 (face font-lock-string-face) 3705 3745 (face font-lock-constant-face) 3745 3746 (face font-lock-string-face) 3746 3756 nil 3756 3757 (face font-lock-string-face) 3757 3787 (face font-lock-constant-face) 3787 3788 (face font-lock-string-face) 3788 3798 nil 3798 3799 (face font-lock-string-face) 3799 3828 (face font-lock-constant-face) 3828 3829 (face font-lock-string-face) 3829 3839 nil 3839 3840 (face font-lock-string-face) 3840 3869 (face font-lock-constant-face) 3869 3870 (face font-lock-string-face) 3870 3880 nil 3880 3881 (face font-lock-string-face) 3881 3909 (face font-lock-constant-face) 3909 3910 (face font-lock-string-face) 3910 3920 nil 3920 3921 (face font-lock-string-face) 3921 3945 (face font-lock-constant-face) 3945 3946 (face font-lock-string-face) 3946 3956 nil 3956 3957 (face font-lock-string-face) 3957 3980 (face font-lock-constant-face) 3980 3981 (face font-lock-string-face) 3981 3991 nil 3991 3992 (face font-lock-string-face) 3992 4019 (face font-lock-constant-face) 4019 4020 (face font-lock-string-face) 4020 4030 nil 4030 4031 (face font-lock-string-face) 4031 4057 (face font-lock-constant-face) 4057 4058 (face font-lock-string-face) 4058 4068 nil 4068 4069 (face font-lock-string-face) 4069 4090 (face font-lock-constant-face) 4090 4091 (face font-lock-string-face) 4091 4101 nil 4101 4102 (face font-lock-string-face) 4102 4122 (face font-lock-constant-face) 4122 4123 (face font-lock-string-face) 4123 4133 nil 4133 4134 (face font-lock-string-face) 4134 4157 (face font-lock-constant-face) 4157 4158 (face font-lock-string-face) 4158 4168 nil 4168 4169 (face font-lock-string-face) 4169 4191 (face font-lock-constant-face) 4191 4192 (face font-lock-string-face) 4192 4202 nil 4202 4203 (face font-lock-string-face) 4203 4243 (face font-lock-constant-face) 4243 4244 (face font-lock-string-face) 4244 4254 nil 4254 4255 (face font-lock-string-face) 4255 4294 (face font-lock-constant-face) 4294 4295 (face font-lock-string-face) 4295 4305 nil 4305 4306 (face font-lock-string-face) 4306 4347 (face font-lock-constant-face) 4347 4348 (face font-lock-string-face) 4348 4358 nil 4358 4359 (face font-lock-string-face) 4359 4399 (face font-lock-constant-face) 4399 4400 (face font-lock-string-face) 4400 4410 nil 4410 4411 (face font-lock-string-face) 4411 4441 (face font-lock-constant-face) 4441 4442 (face font-lock-string-face) 4442 4452 nil 4452 4453 (face font-lock-string-face) 4453 4482 (face font-lock-constant-face) 4482 4483 (face font-lock-string-face) 4483 4493 nil 4493 4494 (face font-lock-string-face) 4494 4523 (face font-lock-constant-face) 4523 4524 (face font-lock-string-face) 4524 4534 nil 4534 4535 (face font-lock-string-face) 4535 4563 (face font-lock-constant-face) 4563 4564 (face font-lock-string-face) 4564 4574 nil 4574 4575 (face font-lock-string-face) 4575 4610 (face font-lock-constant-face) 4610 4611 (face font-lock-string-face) 4611 4621 nil 4621 4622 (face font-lock-string-face) 4622 4656 (face font-lock-constant-face) 4656 4657 (face font-lock-string-face) 4657 4667 nil 4667 4668 (face font-lock-string-face) 4668 4697 (face font-lock-constant-face) 4697 4698 (face font-lock-string-face) 4698 4708 nil 4708 4709 (face font-lock-string-face) 4709 4737 (face font-lock-constant-face) 4737 4738 (face font-lock-string-face) 4738 4748 nil 4748 4749 (face font-lock-string-face) 4749 4780 (face font-lock-constant-face) 4780 4781 (face font-lock-string-face) 4781 4791 nil 4791 4792 (face font-lock-string-face) 4792 4822 (face font-lock-constant-face) 4822 4823 (face font-lock-string-face) 4823 4833 nil 4833 4834 (face font-lock-string-face) 4834 4869 (face font-lock-constant-face) 4869 4870 (face font-lock-string-face) 4870 4880 nil 4880 4881 (face font-lock-string-face) 4881 4915 (face font-lock-constant-face) 4915 4916 (face font-lock-string-face) 4916 4926 nil 4926 4927 (face font-lock-string-face) 4927 4948 (face font-lock-constant-face) 4948 4949 (face font-lock-string-face) 4949 4959 nil 4959 4960 (face font-lock-string-face) 4960 4980 (face font-lock-constant-face) 4980 4981 (face font-lock-string-face) 4981 4991 nil 4991 4992 (face font-lock-string-face) 4992 5020 (face font-lock-constant-face) 5020 5021 (face font-lock-string-face) 5021 5031 nil 5031 5032 (face font-lock-string-face) 5032 5059 (face font-lock-constant-face) 5059 5060 (face font-lock-string-face) 5060 5070 nil 5070 5071 (face font-lock-string-face) 5071 5092 (face font-lock-constant-face) 5092 5093 (face font-lock-string-face) 5093 5103 nil 5103 5104 (face font-lock-string-face) 5104 5132 (face font-lock-constant-face) 5132 5133 (face font-lock-string-face) 5133 5143 nil 5143 5144 (face font-lock-string-face) 5144 5171 (face font-lock-constant-face) 5171 5172 (face font-lock-string-face) 5172 5182 nil 5182 5183 (face font-lock-string-face) 5183 5217 (face font-lock-constant-face) 5217 5218 (face font-lock-string-face) 5218 5228 nil 5228 5229 (face font-lock-string-face) 5229 5262 (face font-lock-constant-face) 5262 5263 (face font-lock-string-face) 5263 5273 nil 5273 5274 (face font-lock-string-face) 5274 5297 (face font-lock-constant-face) 5297 5298 (face font-lock-string-face) 5298 5308 nil 5308 5309 (face font-lock-string-face) 5309 5324 (face font-lock-constant-face) 5324 5325 (face font-lock-string-face) 5325 5335 nil 5335 5336 (face font-lock-string-face) 5336 5350 (face font-lock-constant-face) 5350 5351 (face font-lock-string-face) 5351 5361 nil 5361 5362 (face font-lock-string-face) 5362 5380 (face font-lock-constant-face) 5380 5381 (face font-lock-string-face) 5381 5391 nil 5391 5392 (face font-lock-string-face) 5392 5409 (face font-lock-constant-face) 5409 5410 (face font-lock-string-face) 5410 5420 nil 5420 5421 (face font-lock-string-face) 5421 5443 (face font-lock-constant-face) 5443 5444 (face font-lock-string-face) 5444 5454 nil 5454 5455 (face font-lock-string-face) 5455 5476 (face font-lock-constant-face) 5476 5477 (face font-lock-string-face) 5477 5487 nil 5487 5488 (face font-lock-string-face) 5488 5501 (face font-lock-constant-face) 5501 5502 (face font-lock-string-face) 5502 5512 nil 5512 5513 (face font-lock-string-face) 5513 5525 (face font-lock-constant-face) 5525 5526 (face font-lock-string-face) 5526 5536 nil 5536 5537 (face font-lock-string-face) 5537 5561 (face font-lock-constant-face) 5561 5562 (face font-lock-string-face) 5562 5572 nil 5572 5573 (face font-lock-string-face) 5573 5596 (face font-lock-constant-face) 5596 5597 (face font-lock-string-face) 5597 5607 nil 5607 5608 (face font-lock-string-face) 5608 5627 (face font-lock-constant-face) 5627 5628 (face font-lock-string-face) 5628 5638 nil 5638 5639 (face font-lock-string-face) 5639 5657 (face font-lock-constant-face) 5657 5658 (face font-lock-string-face) 5658 5668 nil 5668 5669 (face font-lock-string-face) 5669 5688 (face font-lock-constant-face) 5688 5689 (face font-lock-string-face) 5689 5699 nil 5699 5700 (face font-lock-string-face) 5700 5718 (face font-lock-constant-face) 5718 5719 (face font-lock-string-face) 5719 5729 nil 5729 5730 (face font-lock-string-face) 5730 5752 (face font-lock-constant-face) 5752 5753 (face font-lock-string-face) 5753 5763 nil 5763 5764 (face font-lock-string-face) 5764 5785 (face font-lock-constant-face) 5785 5786 (face font-lock-string-face) 5786 5796 nil 5796 5797 (face font-lock-string-face) 5797 5819 (face font-lock-constant-face) 5819 5820 (face font-lock-string-face) 5820 5830 nil 5830 5831 (face font-lock-string-face) 5831 5852 (face font-lock-constant-face) 5852 5853 (face font-lock-string-face) 5853 5863 nil 5863 5864 (face font-lock-string-face) 5864 5880 (face font-lock-constant-face) 5880 5881 (face font-lock-string-face) 5881 5891 nil 5891 5892 (face font-lock-string-face) 5892 5915 (face font-lock-constant-face) 5915 5916 (face font-lock-string-face) 5916 5926 nil 5926 5927 (face font-lock-string-face) 5927 5942 (face font-lock-constant-face) 5942 5943 (face font-lock-string-face) 5943 5953 nil 5953 5954 (face font-lock-string-face) 5954 5968 (face font-lock-constant-face) 5968 5969 (face font-lock-string-face) 5969 5979 nil 5979 5980 (face font-lock-string-face) 5980 6002 (face font-lock-constant-face) 6002 6003 (face font-lock-string-face) 6003 6013 nil 6013 6014 (face font-lock-string-face) 6014 6035 (face font-lock-constant-face) 6035 6036 (face font-lock-string-face) 6036 6046 nil 6046 6047 (face font-lock-string-face) 6047 6059 (face font-lock-constant-face) 6059 6060 (face font-lock-string-face) 6060 6070 nil 6070 6071 (face font-lock-string-face) 6071 6082 (face font-lock-constant-face) 6082 6083 (face font-lock-string-face) 6083 6093 nil 6093 6094 (face font-lock-string-face) 6094 6119 (face font-lock-constant-face) 6119 6120 (face font-lock-string-face) 6120 6130 nil 6130 6131 (face font-lock-string-face) 6131 6155 (face font-lock-constant-face) 6155 6156 (face font-lock-string-face) 6156 6166 nil 6166 6167 (face font-lock-string-face) 6167 6185 (face font-lock-constant-face) 6185 6186 (face font-lock-string-face) 6186 6196 nil 6196 6197 (face font-lock-string-face) 6197 6212 (face font-lock-constant-face) 6212 6213 (face font-lock-string-face) 6213 6223 nil 6223 6224 (face font-lock-string-face) 6224 6238 (face font-lock-constant-face) 6238 6239 (face font-lock-string-face) 6239 6249 nil 6249 6250 (face font-lock-string-face) 6250 6282 (face font-lock-constant-face) 6282 6283 (face font-lock-string-face) 6283 6293 nil 6293 6294 (face font-lock-string-face) 6294 6325 (face font-lock-constant-face) 6325 6326 (face font-lock-string-face) 6326 6336 nil 6336 6337 (face font-lock-string-face) 6337 6349 (face font-lock-constant-face) 6349 6350 (face font-lock-string-face) 6350 6360 nil 6360 6361 (face font-lock-string-face) 6361 6382 (face font-lock-constant-face) 6382 6383 (face font-lock-string-face) 6383 6393 nil 6393 6394 (face font-lock-string-face) 6394 6413 (face font-lock-constant-face) 6413 6414 (face font-lock-string-face) 6414 6424 nil 6424 6425 (face font-lock-string-face) 6425 6442 (face font-lock-constant-face) 6442 6443 (face font-lock-string-face) 6443 6453 nil 6453 6454 (face font-lock-string-face) 6454 6470 (face font-lock-constant-face) 6470 6471 (face font-lock-string-face) 6471 6481 nil 6481 6482 (face font-lock-string-face) 6482 6504 (face font-lock-constant-face) 6504 6505 (face font-lock-string-face) 6505 6515 nil 6515 6516 (face font-lock-string-face) 6516 6535 (face font-lock-constant-face) 6535 6536 (face font-lock-string-face) 6536 6546 nil 6546 6547 (face font-lock-string-face) 6547 6569 (face font-lock-constant-face) 6569 6570 (face font-lock-string-face) 6570 6580 nil 6580 6581 (face font-lock-string-face) 6581 6602 (face font-lock-constant-face) 6602 6603 (face font-lock-string-face) 6603 6613 nil 6613 6614 (face font-lock-string-face) 6614 6631 (face font-lock-constant-face) 6631 6632 (face font-lock-string-face) 6632 6642 nil 6642 6643 (face font-lock-string-face) 6643 6671 (face font-lock-constant-face) 6671 6672 (face font-lock-string-face) 6672 6682 nil 6682 6683 (face font-lock-string-face) 6683 6710 (face font-lock-constant-face) 6710 6711 (face font-lock-string-face) 6711 6721 nil 6721 6722 (face font-lock-string-face) 6722 6738 (face font-lock-constant-face) 6738 6739 (face font-lock-string-face) 6739 6749 nil 6749 6750 (face font-lock-string-face) 6750 6765 (face font-lock-constant-face) 6765 6766 (face font-lock-string-face) 6766 6776 nil 6776 6777 (face font-lock-string-face) 6777 6800 (face font-lock-constant-face) 6800 6801 (face font-lock-string-face) 6801 6811 nil 6811 6812 (face font-lock-string-face) 6812 6834 (face font-lock-constant-face) 6834 6835 (face font-lock-string-face) 6835 6845 nil 6845 6846 (face font-lock-string-face) 6846 6860 (face font-lock-constant-face) 6860 6861 (face font-lock-string-face) 6861 6871 nil 6871 6872 (face font-lock-string-face) 6872 6885 (face font-lock-constant-face) 6885 6886 (face font-lock-string-face) 6886 6896 nil 6896 6897 (face font-lock-string-face) 6897 6920 (face font-lock-constant-face) 6920 6921 (face font-lock-string-face) 6921 6931 nil 6931 6932 (face font-lock-string-face) 6932 6954 (face font-lock-constant-face) 6954 6955 (face font-lock-string-face) 6955 6965 nil 6965 6966 (face font-lock-string-face) 6966 6986 (face font-lock-constant-face) 6986 6987 (face font-lock-string-face) 6987 6997 nil 6997 6998 (face font-lock-string-face) 6998 7017 (face font-lock-constant-face) 7017 7018 (face font-lock-string-face) 7018 7028 nil 7028 7029 (face font-lock-string-face) 7029 7050 (face font-lock-constant-face) 7050 7051 (face font-lock-string-face) 7051 7061 nil 7061 7062 (face font-lock-string-face) 7062 7082 (face font-lock-constant-face) 7082 7083 (face font-lock-string-face) 7083 7093 nil 7093 7094 (face font-lock-string-face) 7094 7122 (face font-lock-constant-face) 7122 7123 (face font-lock-string-face) 7123 7133 nil 7133 7134 (face font-lock-string-face) 7134 7161 (face font-lock-constant-face) 7161 7162 (face font-lock-string-face) 7162 7172 nil 7172 7173 (face font-lock-string-face) 7173 7194 (face font-lock-constant-face) 7194 7195 (face font-lock-string-face) 7195 7205 nil 7205 7206 (face font-lock-string-face) 7206 7226 (face font-lock-constant-face) 7226 7227 (face font-lock-string-face) 7227 7237 nil 7237 7238 (face font-lock-string-face) 7238 7266 (face font-lock-constant-face) 7266 7267 (face font-lock-string-face) 7267 7277 nil 7277 7278 (face font-lock-string-face) 7278 7305 (face font-lock-constant-face) 7305 7306 (face font-lock-string-face) 7306 7316 nil 7316 7317 (face font-lock-string-face) 7317 7336 (face font-lock-constant-face) 7336 7337 (face font-lock-string-face) 7337 7347 nil 7347 7348 (face font-lock-string-face) 7348 7366 (face font-lock-constant-face) 7366 7367 (face font-lock-string-face) 7367 7377 nil 7377 7378 (face font-lock-string-face) 7378 7399 (face font-lock-constant-face) 7399 7400 (face font-lock-string-face) 7400 7410 nil 7410 7411 (face font-lock-string-face) 7411 7429 (face font-lock-constant-face) 7429 7430 (face font-lock-string-face) 7430 7440 nil 7440 7441 (face font-lock-string-face) 7441 7458 (face font-lock-constant-face) 7458 7459 (face font-lock-string-face) 7459 7469 nil 7469 7470 (face font-lock-string-face) 7470 7493 (face font-lock-constant-face) 7493 7494 (face font-lock-string-face) 7494 7504 nil 7504 7505 (face font-lock-string-face) 7505 7527 (face font-lock-constant-face) 7527 7528 (face font-lock-string-face) 7528 7538 nil 7538 7539 (face font-lock-string-face) 7539 7562 (face font-lock-constant-face) 7562 7563 (face font-lock-string-face) 7563 7573 nil 7573 7574 (face font-lock-string-face) 7574 7596 (face font-lock-constant-face) 7596 7597 (face font-lock-string-face) 7597 7607 nil 7607 7608 (face font-lock-string-face) 7608 7631 (face font-lock-constant-face) 7631 7632 (face font-lock-string-face) 7632 7642 nil 7642 7643 (face font-lock-string-face) 7643 7665 (face font-lock-constant-face) 7665 7666 (face font-lock-string-face) 7666 7676 nil 7676 7677 (face font-lock-string-face) 7677 7705 (face font-lock-constant-face) 7705 7706 (face font-lock-string-face) 7706 7716 nil 7716 7717 (face font-lock-string-face) 7717 7744 (face font-lock-constant-face) 7744 7745 (face font-lock-string-face) 7745 7755 nil 7755 7756 (face font-lock-string-face) 7756 7791 (face font-lock-constant-face) 7791 7792 (face font-lock-string-face) 7792 7802 nil 7802 7803 (face font-lock-string-face) 7803 7837 (face font-lock-constant-face) 7837 7838 (face font-lock-string-face) 7838 7848 nil 7848 7849 (face font-lock-string-face) 7849 7879 (face font-lock-constant-face) 7879 7880 (face font-lock-string-face) 7880 7890 nil 7890 7891 (face font-lock-string-face) 7891 7920 (face font-lock-constant-face) 7920 7921 (face font-lock-string-face) 7921 7931 nil 7931 7932 (face font-lock-string-face) 7932 7962 (face font-lock-constant-face) 7962 7963 (face font-lock-string-face) 7963 7973 nil 7973 7974 (face font-lock-string-face) 7974 8003 (face font-lock-constant-face) 8003 8004 (face font-lock-string-face) 8004 8014 nil 8014 8015 (face font-lock-string-face) 8015 8039 (face font-lock-constant-face) 8039 8040 (face font-lock-string-face) 8040 8050 nil 8050 8051 (face font-lock-string-face) 8051 8074 (face font-lock-constant-face) 8074 8075 (face font-lock-string-face) 8075 8085 nil 8085 8086 (face font-lock-string-face) 8086 8116 (face font-lock-constant-face) 8116 8117 (face font-lock-string-face) 8117 8127 nil 8127 8128 (face font-lock-string-face) 8128 8152 (face font-lock-constant-face) 8152 8153 (face font-lock-string-face) 8153 8163 nil 8163 8164 (face font-lock-string-face) 8164 8187 (face font-lock-constant-face) 8187 8188 (face font-lock-string-face) 8188 8198 nil 8198 8199 (face font-lock-string-face) 8199 8230 (face font-lock-constant-face) 8230 8231 (face font-lock-string-face) 8231 8241 nil 8241 8242 (face font-lock-string-face) 8242 8272 (face font-lock-constant-face) 8272 8273 (face font-lock-string-face) 8273 8283 nil 8283 8284 (face font-lock-string-face) 8284 8309 (face font-lock-constant-face) 8309 8310 (face font-lock-string-face) 8310 8320 nil 8320 8321 (face font-lock-string-face) 8321 8345 (face font-lock-constant-face) 8345 8346 (face font-lock-string-face) 8346 8356 nil 8356 8357 (face font-lock-string-face) 8357 8399 (face font-lock-constant-face) 8399 8400 (face font-lock-string-face) 8400 8410 nil 8410 8411 (face font-lock-string-face) 8411 8452 (face font-lock-constant-face) 8452 8453 (face font-lock-string-face) 8453 8463 nil 8463 8464 (face font-lock-string-face) 8464 8486 (face font-lock-constant-face) 8486 8487 (face font-lock-string-face) 8487 8497 nil 8497 8498 (face font-lock-string-face) 8498 8519 (face font-lock-constant-face) 8519 8520 (face font-lock-string-face) 8520 8530 nil 8530 8531 (face font-lock-string-face) 8531 8562 (face font-lock-constant-face) 8562 8563 (face font-lock-string-face) 8563 8573 nil 8573 8574 (face font-lock-string-face) 8574 8604 (face font-lock-constant-face) 8604 8605 (face font-lock-string-face) 8605 8615 nil 8615 8616 (face font-lock-string-face) 8616 8643 (face font-lock-constant-face) 8643 8644 (face font-lock-string-face) 8644 8654 nil 8654 8655 (face font-lock-string-face) 8655 8681 (face font-lock-constant-face) 8681 8682 (face font-lock-string-face) 8682 8692 nil 8692 8693 (face font-lock-string-face) 8693 8721 (face font-lock-constant-face) 8721 8722 (face font-lock-string-face) 8722 8732 nil 8732 8733 (face font-lock-string-face) 8733 8760 (face font-lock-constant-face) 8760 8761 (face font-lock-string-face) 8761 8771 nil 8771 8772 (face font-lock-string-face) 8772 8805 (face font-lock-constant-face) 8805 8806 (face font-lock-string-face) 8806 8816 nil 8816 8817 (face font-lock-string-face) 8817 8849 (face font-lock-constant-face) 8849 8850 (face font-lock-string-face) 8850 8860 nil 8860 8861 (face font-lock-string-face) 8861 8892 (face font-lock-constant-face) 8892 8893 (face font-lock-string-face) 8893 8903 nil 8903 8904 (face font-lock-string-face) 8904 8934 (face font-lock-constant-face) 8934 8935 (face font-lock-string-face) 8935 8945 nil 8945 8946 (face font-lock-string-face) 8946 8978 (face font-lock-constant-face) 8978 8979 (face font-lock-string-face) 8979 8989 nil 8989 8990 (face font-lock-string-face) 8990 9021 (face font-lock-constant-face) 9021 9022 (face font-lock-string-face) 9022 9032 nil 9032 9033 (face font-lock-string-face) 9033 9063 (face font-lock-constant-face) 9063 9064 (face font-lock-string-face) 9064 9074 nil 9074 9075 (face font-lock-string-face) 9075 9104 (face font-lock-constant-face) 9104 9105 (face font-lock-string-face) 9105 9115 nil 9115 9116 (face font-lock-string-face) 9116 9158 (face font-lock-constant-face) 9158 9159 (face font-lock-string-face) 9159 9169 nil 9169 9170 (face font-lock-string-face) 9170 9211 (face font-lock-constant-face) 9211 9212 (face font-lock-string-face) 9212 9222 nil 9222 9223 (face font-lock-string-face) 9223 9272 (face font-lock-constant-face) 9272 9273 (face font-lock-string-face) 9273 9283 nil 9283 9284 (face font-lock-string-face) 9284 9332 (face font-lock-constant-face) 9332 9333 (face font-lock-string-face) 9333 9343 nil 9343 9344 (face font-lock-string-face) 9344 9388 (face font-lock-constant-face) 9388 9389 (face font-lock-string-face) 9389 9399 nil 9399 9400 (face font-lock-string-face) 9400 9445 (face font-lock-constant-face) 9445 9446 (face font-lock-string-face) 9446 9456 nil 9456 9457 (face font-lock-string-face) 9457 9507 (face font-lock-constant-face) 9507 9508 (face font-lock-string-face) 9508 9518 nil 9518 9519 (face font-lock-string-face) 9519 9570 (face font-lock-constant-face) 9570 9571 (face font-lock-string-face) 9571 9581 nil 9581 9582 (face font-lock-string-face) 9582 9611 (face font-lock-constant-face) 9611 9612 (face font-lock-string-face) 9612 9622 nil 9622 9623 (face font-lock-string-face) 9623 9659 (face font-lock-constant-face) 9659 9660 (face font-lock-string-face) 9660 9670 nil 9670 9671 (face font-lock-string-face) 9671 9714 (face font-lock-constant-face) 9714 9715 (face font-lock-string-face) 9715 9725 nil 9725 9726 (face font-lock-string-face) 9726 9768 (face font-lock-constant-face) 9768 9769 (face font-lock-string-face) 9769 9779 nil 9779 9780 (face font-lock-string-face) 9780 9816 (face font-lock-constant-face) 9816 9817 (face font-lock-string-face) 9817 9827 nil 9827 9828 (face font-lock-string-face) 9828 9863 (face font-lock-constant-face) 9863 9864 (face font-lock-string-face) 9864 9874 nil 9874 9875 (face font-lock-string-face) 9875 9910 (face font-lock-constant-face) 9910 9911 (face font-lock-string-face) 9911 9921 nil 9921 9922 (face font-lock-string-face) 9922 9958 (face font-lock-constant-face) 9958 9959 (face font-lock-string-face) 9959 9969 nil 9969 9970 (face font-lock-string-face) 9970 10005 (face font-lock-constant-face) 10005 10006 (face font-lock-string-face) 10006 10016 nil 10016 10017 (face font-lock-string-face) 10017 10050 (face font-lock-constant-face) 10050 10051 (face font-lock-string-face) 10051 10061 nil 10061 10062 (face font-lock-string-face) 10062 10094 (face font-lock-constant-face) 10094 10095 (face font-lock-string-face) 10095 10105 nil 10105 10106 (face font-lock-string-face) 10106 10150 (face font-lock-constant-face) 10150 10151 (face font-lock-string-face) 10151 10161 nil 10161 10162 (face font-lock-string-face) 10162 10198 (face font-lock-constant-face) 10198 10199 (face font-lock-string-face) 10199 10209 nil 10209 10210 (face font-lock-string-face) 10210 10245 (face font-lock-constant-face) 10245 10246 (face font-lock-string-face) 10246 10256 nil 10256 10257 (face font-lock-string-face) 10257 10296 (face font-lock-constant-face) 10296 10297 (face font-lock-string-face) 10297 10307 nil 10307 10308 (face font-lock-string-face) 10308 10346 (face font-lock-constant-face) 10346 10347 (face font-lock-string-face) 10347 10357 nil 10357 10358 (face font-lock-string-face) 10358 10403 (face font-lock-constant-face) 10403 10404 (face font-lock-string-face) 10404 10414 nil 10414 10415 (face font-lock-string-face) 10415 10459 (face font-lock-constant-face) 10459 10460 (face font-lock-string-face) 10460 10470 nil 10470 10471 (face font-lock-string-face) 10471 10487 (face font-lock-constant-face) 10487 10488 (face font-lock-string-face) 10488 10498 nil 10498 10499 (face font-lock-string-face) 10499 10514 (face font-lock-constant-face) 10514 10515 (face font-lock-string-face) 10515 10525 nil 10525 10526 (face font-lock-string-face) 10526 10559 (face font-lock-constant-face) 10559 10560 (face font-lock-string-face) 10560 10570 nil 10570 10571 (face font-lock-string-face) 10571 10603 (face font-lock-constant-face) 10603 10604 (face font-lock-string-face) 10604 10614 nil 10614 10615 (face font-lock-string-face) 10615 10636 (face font-lock-constant-face) 10636 10637 (face font-lock-string-face) 10637 10647 nil 10647 10648 (face font-lock-string-face) 10648 10675 (face font-lock-constant-face) 10675 10676 (face font-lock-string-face) 10676 10686 nil 10686 10687 (face font-lock-string-face) 10687 10713 (face font-lock-constant-face) 10713 10714 (face font-lock-string-face) 10714 10724 nil 10724 10725 (face font-lock-string-face) 10725 10755 (face font-lock-constant-face) 10755 10756 (face font-lock-string-face) 10756 10766 nil 10766 10767 (face font-lock-string-face) 10767 10796 (face font-lock-constant-face) 10796 10797 (face font-lock-string-face) 10797 10807 nil 10807 10808 (face font-lock-string-face) 10808 10845 (face font-lock-constant-face) 10845 10846 (face font-lock-string-face) 10846 10856 nil 10856 10857 (face font-lock-string-face) 10857 10893 (face font-lock-constant-face) 10893 10894 (face font-lock-string-face) 10894 10904 nil 10904 10905 (face font-lock-string-face) 10905 10929 (face font-lock-constant-face) 10929 10930 (face font-lock-string-face) 10930 10940 nil 10940 10941 (face font-lock-string-face) 10941 10964 (face font-lock-constant-face) 10964 10965 (face font-lock-string-face) 10965 10975 nil 10975 10976 (face font-lock-string-face) 10976 10995 (face font-lock-constant-face) 10995 10996 (face font-lock-string-face) 10996 11006 nil 11006 11007 (face font-lock-string-face) 11007 11025 (face font-lock-constant-face) 11025 11026 (face font-lock-string-face) 11026 11036 nil 11036 11037 (face font-lock-string-face) 11037 11063 (face font-lock-constant-face) 11063 11064 (face font-lock-string-face) 11064 11074 nil 11074 11075 (face font-lock-string-face) 11075 11100 (face font-lock-constant-face) 11100 11101 (face font-lock-string-face) 11101 11111 nil 11111 11112 (face font-lock-string-face) 11112 11138 (face font-lock-constant-face) 11138 11139 (face font-lock-string-face) 11139 11149 nil 11149 11150 (face font-lock-string-face) 11150 11175 (face font-lock-constant-face) 11175 11176 (face font-lock-string-face) 11176 11193 nil 11193 11194 (face font-lock-string-face) 11194 11219 (face font-lock-keyword-face) 11219 11220 (face font-lock-string-face) 11220 11232 nil 11232 11233 (face font-lock-string-face) 11233 11245 (face font-lock-keyword-face) 11245 11246 (face font-lock-string-face) 11246 11260 nil 11260 11261 (face font-lock-string-face) 11261 11263 (face font-lock-constant-face) 11263 11264 (face font-lock-string-face) 11264 11292 nil 11292 11293 (face font-lock-string-face) 11293 11303 (face font-lock-keyword-face) 11303 11304 (face font-lock-string-face) 11304 11316 nil 11316 11381 (face font-lock-comment-face) 11381 11389 nil 11389 11439 (face font-lock-comment-face) 11439 11448 nil 11448 11449 (face font-lock-string-face) 11449 11464 (face font-lock-variable-name-face) 11464 11465 (face font-lock-string-face) 11465 11479 nil 11479 11480 (face font-lock-string-face) 11480 11492 (face font-lock-keyword-face) 11492 11493 (face font-lock-string-face) 11493 11509 nil 11509 11510 (face font-lock-string-face) 11510 11549 (face font-lock-function-name-face) 11549 11550 (face font-lock-string-face) 11550 11586 nil 11586 11587 (face font-lock-string-face) 11587 11602 (face font-lock-variable-name-face) 11602 11603 (face font-lock-string-face) 11603 11617 nil 11617 11618 (face font-lock-string-face) 11618 11626 (face font-lock-keyword-face) 11626 11627 (face font-lock-string-face) 11627 11643 nil 11643 11644 (face font-lock-string-face) 11644 11663 (face font-lock-constant-face) 11663 11664 (face font-lock-string-face) 11664 11678 nil 11678 11679 (face font-lock-string-face) 11679 11702 (face font-lock-constant-face) 11702 11703 (face font-lock-string-face) 11703 11717 nil 11717 11718 (face font-lock-string-face) 11718 11740 (face font-lock-constant-face) 11740 11741 (face font-lock-string-face) 11741 11755 nil 11755 11756 (face font-lock-string-face) 11756 11779 (face font-lock-constant-face) 11779 11780 (face font-lock-string-face) 11780 11794 nil 11794 11795 (face font-lock-string-face) 11795 11817 (face font-lock-constant-face) 11817 11818 (face font-lock-string-face) 11818 11832 nil 11832 11833 (face font-lock-string-face) 11833 11861 (face font-lock-constant-face) 11861 11862 (face font-lock-string-face) 11862 11876 nil 11876 11877 (face font-lock-string-face) 11877 11904 (face font-lock-constant-face) 11904 11905 (face font-lock-string-face) 11905 11919 nil 11919 11920 (face font-lock-string-face) 11920 11950 (face font-lock-constant-face) 11950 11951 (face font-lock-string-face) 11951 11965 nil 11965 11966 (face font-lock-string-face) 11966 11995 (face font-lock-constant-face) 11995 11996 (face font-lock-string-face) 11996 12010 nil 12010 12011 (face font-lock-string-face) 12011 12035 (face font-lock-constant-face) 12035 12036 (face font-lock-string-face) 12036 12050 nil 12050 12051 (face font-lock-string-face) 12051 12074 (face font-lock-constant-face) 12074 12075 (face font-lock-string-face) 12075 12089 nil 12089 12090 (face font-lock-string-face) 12090 12120 (face font-lock-constant-face) 12120 12121 (face font-lock-string-face) 12121 12135 nil 12135 12136 (face font-lock-string-face) 12136 12167 (face font-lock-constant-face) 12167 12168 (face font-lock-string-face) 12168 12182 nil 12182 12183 (face font-lock-string-face) 12183 12213 (face font-lock-constant-face) 12213 12214 (face font-lock-string-face) 12214 12228 nil 12228 12229 (face font-lock-string-face) 12229 12254 (face font-lock-constant-face) 12254 12255 (face font-lock-string-face) 12255 12269 nil 12269 12270 (face font-lock-string-face) 12270 12294 (face font-lock-constant-face) 12294 12295 (face font-lock-string-face) 12295 12309 nil 12309 12310 (face font-lock-string-face) 12310 12352 (face font-lock-constant-face) 12352 12353 (face font-lock-string-face) 12353 12367 nil 12367 12368 (face font-lock-string-face) 12368 12409 (face font-lock-constant-face) 12409 12410 (face font-lock-string-face) 12410 12424 nil 12424 12425 (face font-lock-string-face) 12425 12447 (face font-lock-constant-face) 12447 12448 (face font-lock-string-face) 12448 12462 nil 12462 12463 (face font-lock-string-face) 12463 12484 (face font-lock-constant-face) 12484 12485 (face font-lock-string-face) 12485 12499 nil 12499 12500 (face font-lock-string-face) 12500 12531 (face font-lock-constant-face) 12531 12532 (face font-lock-string-face) 12532 12546 nil 12546 12547 (face font-lock-string-face) 12547 12577 (face font-lock-constant-face) 12577 12578 (face font-lock-string-face) 12578 12592 nil 12592 12593 (face font-lock-string-face) 12593 12621 (face font-lock-constant-face) 12621 12622 (face font-lock-string-face) 12622 12636 nil 12636 12637 (face font-lock-string-face) 12637 12664 (face font-lock-constant-face) 12664 12665 (face font-lock-string-face) 12665 12679 nil 12679 12680 (face font-lock-string-face) 12680 12707 (face font-lock-constant-face) 12707 12708 (face font-lock-string-face) 12708 12722 nil 12722 12723 (face font-lock-string-face) 12723 12749 (face font-lock-constant-face) 12749 12750 (face font-lock-string-face) 12750 12764 nil 12764 12765 (face font-lock-string-face) 12765 12791 (face font-lock-constant-face) 12791 12792 (face font-lock-string-face) 12792 12806 nil 12806 12807 (face font-lock-string-face) 12807 12832 (face font-lock-constant-face) 12832 12833 (face font-lock-string-face) 12833 12868 nil 12868 12937 (face font-lock-comment-face) 12937 12945 nil 12945 13016 (face font-lock-comment-face) 13016 13024 nil 13024 13040 (face font-lock-comment-face) 13040 13049 nil 13049 13050 (face font-lock-string-face) 13050 13065 (face font-lock-variable-name-face) 13065 13066 (face font-lock-string-face) 13066 13080 nil 13080 13081 (face font-lock-string-face) 13081 13089 (face font-lock-keyword-face) 13089 13090 (face font-lock-string-face) 13090 13105 nil 13105 13106 (face font-lock-string-face) 13106 13149 (face font-lock-constant-face) 13149 13150 (face font-lock-string-face) 13150 13175 nil 13175 13176 (face font-lock-string-face) 13176 13183 (face font-lock-keyword-face) 13183 13184 (face font-lock-string-face) 13184 13199 nil 13199 13200 (face font-lock-string-face) 13200 13248 (face font-lock-constant-face) 13248 13249 (face font-lock-string-face) 13249 13274 nil 13274 13275 (face font-lock-string-face) 13275 13288 (face font-lock-keyword-face) 13288 13289 (face font-lock-string-face) 13289 13305 nil 13305 13306 (face font-lock-string-face) 13306 13315 (face font-lock-keyword-face) 13315 13316 (face font-lock-string-face) 13316 13334 nil 13334 13335 (face font-lock-string-face) 13335 13345 (face font-lock-constant-face) 13345 13346 (face font-lock-string-face) 13346 13397 nil 13397 13398 (face font-lock-string-face) 13398 13443 (face font-lock-variable-name-face) 13443 13444 (face font-lock-string-face) 13444 13458 nil 13458 13459 (face font-lock-string-face) 13459 13472 (face font-lock-keyword-face) 13472 13473 (face font-lock-string-face) 13473 13489 nil 13489 13490 (face font-lock-string-face) 13490 13499 (face font-lock-keyword-face) 13499 13500 (face font-lock-string-face) 13500 13518 nil 13518 13519 (face font-lock-string-face) 13519 13527 (face font-lock-constant-face) 13527 13528 (face font-lock-string-face) 13528 13579 nil 13579 13580 (face font-lock-string-face) 13580 13593 (face font-lock-variable-name-face) 13593 13594 (face font-lock-string-face) 13594 13608 nil 13608 13609 (face font-lock-string-face) 13609 13617 (face font-lock-keyword-face) 13617 13618 (face font-lock-string-face) 13618 13623 nil 13623 13624 (face font-lock-string-face) 13624 13631 (face font-lock-constant-face) 13631 13632 (face font-lock-string-face) 13632 13634 nil 13634 13635 (face font-lock-string-face) 13635 13641 (face font-lock-constant-face) 13641 13642 (face font-lock-string-face) 13642 13671 nil 13671 13672 (face font-lock-string-face) 13672 13679 (face font-lock-constant-face) 13679 13680 (face font-lock-string-face) 13680 13682 nil 13682 13683 (face font-lock-string-face) 13683 13703 (face font-lock-constant-face) 13703 13704 (face font-lock-string-face) 13704 13720 nil 13720 13721 (face font-lock-string-face) 13721 13734 (face font-lock-keyword-face) 13734 13735 (face font-lock-string-face) 13735 13751 nil 13751 13752 (face font-lock-string-face) 13752 13761 (face font-lock-keyword-face) 13761 13762 (face font-lock-string-face) 13762 13815 nil 13815 13816 (face font-lock-string-face) 13816 13829 (face font-lock-variable-name-face) 13829 13830 (face font-lock-string-face) 13830 13844 nil 13844 13845 (face font-lock-string-face) 13845 13853 (face font-lock-keyword-face) 13853 13854 (face font-lock-string-face) 13854 13870 nil 13870 13871 (face font-lock-string-face) 13871 13909 (face font-lock-constant-face) 13909 13910 (face font-lock-string-face) 13910 13924 nil 13924 13925 (face font-lock-string-face) 13925 13962 (face font-lock-constant-face) 13962 13963 (face font-lock-string-face) 13963 13999 nil 13999 14000 (face font-lock-string-face) 14000 14011 (face font-lock-variable-name-face) 14011 14012 (face font-lock-string-face) 14012 14026 nil 14026 14027 (face font-lock-string-face) 14027 14036 (face font-lock-keyword-face) 14036 14037 (face font-lock-string-face) 14037 14053 nil 14053 14054 (face font-lock-string-face) 14054 14064 (face font-lock-keyword-face) 14064 14065 (face font-lock-string-face) 14065 14084 nil 14084 14085 (face font-lock-string-face) 14085 14096 (face font-lock-variable-name-face) 14096 14097 (face font-lock-string-face) 14097 14117 nil 14117 14129 (face font-lock-string-face) 14129 14131 nil 14131 14169 (face font-lock-string-face) 14169 14176 (face font-lock-variable-name-face) 14176 14182 (face font-lock-string-face) 14182 14193 (face font-lock-variable-name-face) 14193 14196 (face font-lock-string-face) 14196 14233 nil 14233 14245 (face font-lock-string-face) 14245 14247 nil 14247 14259 (face font-lock-string-face) 14259 14316 nil 14316 14317 (face font-lock-string-face) 14317 14327 (face font-lock-keyword-face) 14327 14328 (face font-lock-string-face) 14328 14345 nil 14345 14346 (face font-lock-string-face) 14346 14359 (face font-lock-variable-name-face) 14359 14360 (face font-lock-string-face) 14360 14378 nil 14378 14379 (face font-lock-string-face) 14379 14385 (face font-lock-keyword-face) 14385 14386 (face font-lock-string-face) 14386 14406 nil 14406 14411 (face font-lock-string-face) 14411 14413 (face font-lock-variable-name-face) 14413 14423 (face font-lock-variable-name-face) 14423 14443 (face font-lock-string-face) 14443 14476 nil 14476 14477 (face font-lock-string-face) 14477 14490 (face font-lock-keyword-face) 14490 14491 (face font-lock-string-face) 14491 14511 nil 14511 14512 (face font-lock-string-face) 14512 14521 (face font-lock-keyword-face) 14521 14522 (face font-lock-string-face) 14522 14544 nil 14544 14545 (face font-lock-string-face) 14545 14549 (face font-lock-constant-face) 14549 14551 (face font-lock-variable-name-face) 14551 14561 (face font-lock-variable-name-face) 14561 14578 (face font-lock-constant-face) 14578 14579 (face font-lock-string-face) 14579 14631 nil 14631 14632 (face font-lock-string-face) 14632 14639 (face font-lock-keyword-face) 14639 14640 (face font-lock-string-face) 14640 14660 nil 14660 14661 (face font-lock-string-face) 14661 14669 (face font-lock-preprocessor-face) 14669 14670 (face font-lock-string-face) 14670 14707 nil 14707 14729 (face font-lock-comment-face) 14729 14743 nil 14743 14744 (face font-lock-string-face) 14744 14752 (face font-lock-keyword-face) 14752 14753 (face font-lock-string-face) 14753 14773 nil 14773 14774 (face font-lock-string-face) 14774 14800 (face font-lock-constant-face) 14800 14801 (face font-lock-string-face) 14801 14819 nil 14819 14820 (face font-lock-string-face) 14820 14845 (face font-lock-constant-face) 14845 14846 (face font-lock-string-face) 14846 14915 nil 14915 14916 (face font-lock-string-face) 14916 14929 (face font-lock-variable-name-face) 14929 14930 (face font-lock-string-face) 14930 14944 nil 14944 14945 (face font-lock-string-face) 14945 14955 (face font-lock-keyword-face) 14955 14956 (face font-lock-string-face) 14956 14973 nil 14973 14974 (face font-lock-string-face) 14974 14993 (face font-lock-variable-name-face) 14993 14994 (face font-lock-string-face) 14994 15012 nil 15012 15013 (face font-lock-string-face) 15013 15019 (face font-lock-keyword-face) 15019 15020 (face font-lock-string-face) 15020 15040 nil 15040 15075 (face font-lock-string-face) 15075 15108 nil 15108 15109 (face font-lock-string-face) 15109 15122 (face font-lock-keyword-face) 15122 15123 (face font-lock-string-face) 15123 15143 nil 15143 15144 (face font-lock-string-face) 15144 15153 (face font-lock-keyword-face) 15153 15154 (face font-lock-string-face) 15154 15176 nil 15176 15177 (face font-lock-string-face) 15177 15215 (face font-lock-constant-face) 15215 15216 (face font-lock-string-face) 15216 15268 nil 15268 15269 (face font-lock-string-face) 15269 15276 (face font-lock-keyword-face) 15276 15277 (face font-lock-string-face) 15277 15297 nil 15297 15298 (face font-lock-string-face) 15298 15312 (face font-lock-preprocessor-face) 15312 15313 (face font-lock-string-face) 15313 15350 nil 15350 15378 (face font-lock-comment-face) 15378 15392 nil 15392 15393 (face font-lock-string-face) 15393 15401 (face font-lock-keyword-face) 15401 15402 (face font-lock-string-face) 15402 15422 nil 15422 15423 (face font-lock-string-face) 15423 15450 (face font-lock-constant-face) 15450 15451 (face font-lock-string-face) 15451 15469 nil 15469 15470 (face font-lock-string-face) 15470 15496 (face font-lock-constant-face) 15496 15497 (face font-lock-string-face) 15497 15566 nil 15566 15567 (face font-lock-string-face) 15567 15600 (face font-lock-variable-name-face) 15600 15601 (face font-lock-string-face) 15601 15615 nil 15615 15663 (face font-lock-comment-face) 15663 15673 nil 15673 15674 (face font-lock-string-face) 15674 15682 (face font-lock-keyword-face) 15682 15683 (face font-lock-string-face) 15683 15699 nil 15699 15700 (face font-lock-string-face) 15700 15743 (face font-lock-constant-face) 15743 15744 (face font-lock-string-face) 15744 15758 nil 15758 15759 (face font-lock-string-face) 15759 15801 (face font-lock-constant-face) 15801 15802 (face font-lock-string-face) 15802 15838 nil 15838 15839 (face font-lock-string-face) 15839 15848 (face font-lock-variable-name-face) 15848 15849 (face font-lock-string-face) 15849 15863 nil 15863 15864 (face font-lock-string-face) 15864 15877 (face font-lock-keyword-face) 15877 15878 (face font-lock-string-face) 15878 15894 nil 15894 15895 (face font-lock-string-face) 15895 15904 (face font-lock-keyword-face) 15904 15905 (face font-lock-string-face) 15905 15923 nil 15923 15924 (face font-lock-string-face) 15924 15980 (face font-lock-constant-face) 15980 15981 (face font-lock-string-face) 15981 15997 nil 15997 15998 (face font-lock-string-face) 15998 16057 (face font-lock-constant-face) 16057 16058 (face font-lock-string-face) 16058 16074 nil 16074 16075 (face font-lock-string-face) 16075 16131 (face font-lock-constant-face) 16131 16132 (face font-lock-string-face) 16132 16148 nil 16148 16149 (face font-lock-string-face) 16149 16205 (face font-lock-constant-face) 16205 16206 (face font-lock-string-face) 16206 16222 nil 16222 16223 (face font-lock-string-face) 16223 16275 (face font-lock-constant-face) 16275 16276 (face font-lock-string-face) 16276 16327 nil 16327 16328 (face font-lock-string-face) 16328 16337 (face font-lock-variable-name-face) 16337 16338 (face font-lock-string-face) 16338 16352 nil 16352 16353 (face font-lock-string-face) 16353 16361 (face font-lock-keyword-face) 16361 16362 (face font-lock-string-face) 16362 16378 nil 16378 16379 (face font-lock-string-face) 16379 16406 (face font-lock-constant-face) 16406 16407 (face font-lock-string-face) 16407 16421 nil 16421 16422 (face font-lock-string-face) 16422 16448 (face font-lock-constant-face) 16448 16449 (face font-lock-string-face) 16449 16463 nil 16463 16464 (face font-lock-string-face) 16464 16507 (face font-lock-constant-face) 16507 16508 (face font-lock-string-face) 16508 16522 nil 16522 16523 (face font-lock-string-face) 16523 16565 (face font-lock-constant-face) 16565 16566 (face font-lock-string-face) 16566 16602 nil 16602 16603 (face font-lock-string-face) 16603 16646 (face font-lock-variable-name-face) 16646 16647 (face font-lock-string-face) 16647 16661 nil 16661 16662 (face font-lock-string-face) 16662 16669 (face font-lock-keyword-face) 16669 16670 (face font-lock-string-face) 16670 16686 nil 16686 16687 (face font-lock-string-face) 16687 16697 (face font-lock-constant-face) 16697 16698 (face font-lock-string-face) 16698 16712 nil 16712 16713 (face font-lock-string-face) 16713 16722 (face font-lock-constant-face) 16722 16723 (face font-lock-string-face) 16723 16737 nil 16737 16738 (face font-lock-string-face) 16738 16760 (face font-lock-constant-face) 16760 16761 (face font-lock-string-face) 16761 16775 nil 16775 16776 (face font-lock-string-face) 16776 16797 (face font-lock-constant-face) 16797 16798 (face font-lock-string-face) 16798 16812 nil 16812 16813 (face font-lock-string-face) 16813 16830 (face font-lock-constant-face) 16830 16831 (face font-lock-string-face) 16831 16845 nil 16845 16846 (face font-lock-string-face) 16846 16862 (face font-lock-constant-face) 16862 16863 (face font-lock-string-face) 16863 16877 nil 16877 16878 (face font-lock-string-face) 16878 16889 (face font-lock-constant-face) 16889 16890 (face font-lock-string-face) 16890 16904 nil 16904 16905 (face font-lock-string-face) 16905 16915 (face font-lock-constant-face) 16915 16916 (face font-lock-string-face) 16916 16930 nil 16930 16931 (face font-lock-string-face) 16931 16955 (face font-lock-constant-face) 16955 16956 (face font-lock-string-face) 16956 16970 nil 16970 16971 (face font-lock-string-face) 16971 16994 (face font-lock-constant-face) 16994 16995 (face font-lock-string-face) 16995 17009 nil 17009 17010 (face font-lock-string-face) 17010 17034 (face font-lock-constant-face) 17034 17035 (face font-lock-string-face) 17035 17049 nil 17049 17050 (face font-lock-string-face) 17050 17073 (face font-lock-constant-face) 17073 17074 (face font-lock-string-face) 17074 17088 nil 17088 17089 (face font-lock-string-face) 17089 17114 (face font-lock-constant-face) 17114 17115 (face font-lock-string-face) 17115 17129 nil 17129 17130 (face font-lock-string-face) 17130 17154 (face font-lock-constant-face) 17154 17155 (face font-lock-string-face) 17155 17210 nil 17210 17211 (face font-lock-string-face) 17211 17222 (face font-lock-keyword-face) 17222 17223 (face font-lock-string-face) 17223 17225 nil 17225 17226 (face font-lock-string-face) 17226 17237 (face font-lock-function-name-face) 17237 17238 (face font-lock-string-face) 17238 17246 nil 17246 17247 (face font-lock-string-face) 17247 17251 (face font-lock-keyword-face) 17251 17252 (face font-lock-string-face) 17252 17254 nil 17254 17255 (face font-lock-string-face) 17255 17269 (face font-lock-type-face) 17269 17270 (face font-lock-string-face) 17270 17278 nil 17278 17279 (face font-lock-string-face) 17279 17291 (face font-lock-keyword-face) 17291 17292 (face font-lock-string-face) 17292 17304 nil 17304 17305 (face font-lock-string-face) 17305 17307 (face font-lock-constant-face) 17307 17308 (face font-lock-string-face) 17308 17325 nil 17325 17326 (face font-lock-string-face) 17326 17336 (face font-lock-keyword-face) 17336 17337 (face font-lock-string-face) 17337 17350 nil 17350 17351 (face font-lock-string-face) 17351 17371 (face font-lock-variable-name-face) 17371 17372 (face font-lock-string-face) 17372 17386 nil 17386 17387 (face font-lock-string-face) 17387 17404 (face font-lock-keyword-face) 17404 17405 (face font-lock-string-face) 17405 17423 nil 17423 17424 (face font-lock-string-face) 17424 17442 (face font-lock-variable-name-face) 17442 17443 (face font-lock-string-face) 17443 17461 nil 17461 17462 (face font-lock-string-face) 17462 17469 (face font-lock-keyword-face) 17469 17470 (face font-lock-string-face) 17470 17474 nil 17474 17498 (face font-lock-string-face) 17498 17553 nil 17553 17554 (face font-lock-string-face) 17554 17599 (face font-lock-variable-name-face) 17599 17600 (face font-lock-string-face) 17600 17614 nil 17614 17615 (face font-lock-string-face) 17615 17627 (face font-lock-keyword-face) 17627 17628 (face font-lock-string-face) 17628 17644 nil 17644 17645 (face font-lock-string-face) 17645 17665 (face font-lock-function-name-face) 17665 17666 (face font-lock-string-face) 17666 17703 nil 17703 17704 (face font-lock-string-face) 17704 17724 (face font-lock-variable-name-face) 17724 17725 (face font-lock-string-face) 17725 17739 nil 17739 17740 (face font-lock-string-face) 17740 17752 (face font-lock-keyword-face) 17752 17753 (face font-lock-string-face) 17753 17769 nil 17769 17770 (face font-lock-string-face) 17770 17790 (face font-lock-function-name-face) 17790 17791 (face font-lock-string-face) 17791 17833 nil 17833 17834 (face font-lock-string-face) 17834 17841 (face font-lock-keyword-face) 17841 17842 (face font-lock-string-face) 17842 17854 nil 17854 17855 (face font-lock-string-face) 17855 17874 (face font-lock-constant-face) 17874 17875 (face font-lock-string-face) 17875 17885 nil 17885 17886 (face font-lock-string-face) 17886 17904 (face font-lock-constant-face) 17904 17905 (face font-lock-string-face) 17905 17935 nil 17935 17936 (face font-lock-string-face) 17936 17947 (face font-lock-keyword-face) 17947 17948 (face font-lock-string-face) 17948 17950 nil 17950 17951 (face font-lock-string-face) 17951 17971 (face font-lock-function-name-face) 17971 17972 (face font-lock-string-face) 17972 17980 nil 17980 17981 (face font-lock-string-face) 17981 17985 (face font-lock-keyword-face) 17985 17986 (face font-lock-string-face) 17986 17988 nil 17988 17989 (face font-lock-string-face) 17989 18003 (face font-lock-type-face) 18003 18004 (face font-lock-string-face) 18004 18012 nil 18012 18013 (face font-lock-string-face) 18013 18025 (face font-lock-keyword-face) 18025 18026 (face font-lock-string-face) 18026 18038 nil 18038 18039 (face font-lock-string-face) 18039 18041 (face font-lock-constant-face) 18041 18042 (face font-lock-string-face) 18042 18059 nil 18059 18060 (face font-lock-string-face) 18060 18067 (face font-lock-keyword-face) 18067 18068 (face font-lock-string-face) 18068 18080 nil 18080 18081 (face font-lock-string-face) 18081 18114 (face font-lock-constant-face) 18114 18115 (face font-lock-string-face) 18115 18125 nil 18125 18126 (face font-lock-string-face) 18126 18162 (face font-lock-constant-face) 18162 18163 (face font-lock-string-face) 18163 18173 nil 18173 18174 (face font-lock-string-face) 18174 18212 (face font-lock-constant-face) 18212 18213 (face font-lock-string-face) 18213 18223 nil 18223 18224 (face font-lock-string-face) 18224 18261 (face font-lock-constant-face) 18261 18262 (face font-lock-string-face) 18262 18272 nil 18272 18273 (face font-lock-string-face) 18273 18311 (face font-lock-constant-face) 18311 18312 (face font-lock-string-face) 18312 18322 nil 18322 18323 (face font-lock-string-face) 18323 18356 (face font-lock-constant-face) 18356 18357 (face font-lock-string-face) 18357 18367 nil 18367 18368 (face font-lock-string-face) 18368 18403 (face font-lock-constant-face) 18403 18404 (face font-lock-string-face) 18404 18414 nil 18414 18415 (face font-lock-string-face) 18415 18451 (face font-lock-constant-face) 18451 18452 (face font-lock-string-face) 18452 18462 nil 18462 18463 (face font-lock-string-face) 18463 18499 (face font-lock-constant-face) 18499 18500 (face font-lock-string-face) 18500 18510 nil 18510 18511 (face font-lock-string-face) 18511 18547 (face font-lock-constant-face) 18547 18548 (face font-lock-string-face) 18548 18558 nil 18558 18559 (face font-lock-string-face) 18559 18581 (face font-lock-constant-face) 18581 18582 (face font-lock-string-face) 18582 18592 nil 18592 18593 (face font-lock-string-face) 18593 18618 (face font-lock-constant-face) 18618 18619 (face font-lock-string-face) 18619 18629 nil 18629 18630 (face font-lock-string-face) 18630 18657 (face font-lock-constant-face) 18657 18658 (face font-lock-string-face) 18658 18668 nil 18668 18669 (face font-lock-string-face) 18669 18697 (face font-lock-constant-face) 18697 18698 (face font-lock-string-face) 18698 18708 nil 18708 18709 (face font-lock-string-face) 18709 18750 (face font-lock-constant-face) 18750 18751 (face font-lock-string-face) 18751 18761 nil 18761 18762 (face font-lock-string-face) 18762 18803 (face font-lock-constant-face) 18803 18804 (face font-lock-string-face) 18804 18814 nil 18814 18815 (face font-lock-string-face) 18815 18856 (face font-lock-constant-face) 18856 18857 (face font-lock-string-face) 18857 18867 nil 18867 18868 (face font-lock-string-face) 18868 18902 (face font-lock-constant-face) 18902 18903 (face font-lock-string-face) 18903 18913 nil 18913 18914 (face font-lock-string-face) 18914 18948 (face font-lock-constant-face) 18948 18949 (face font-lock-string-face) 18949 18959 nil 18959 18960 (face font-lock-string-face) 18960 18994 (face font-lock-constant-face) 18994 18995 (face font-lock-string-face) 18995 19005 nil 19005 19006 (face font-lock-string-face) 19006 19035 (face font-lock-constant-face) 19035 19036 (face font-lock-string-face) 19036 19046 nil 19046 19047 (face font-lock-string-face) 19047 19075 (face font-lock-constant-face) 19075 19076 (face font-lock-string-face) 19076 19093 nil 19093 19094 (face font-lock-string-face) 19094 19104 (face font-lock-keyword-face) 19104 19105 (face font-lock-string-face) 19105 19118 nil 19118 19119 (face font-lock-string-face) 19119 19139 (face font-lock-variable-name-face) 19139 19140 (face font-lock-string-face) 19140 19154 nil 19154 19155 (face font-lock-string-face) 19155 19172 (face font-lock-keyword-face) 19172 19173 (face font-lock-string-face) 19173 19191 nil 19191 19192 (face font-lock-string-face) 19192 19210 (face font-lock-variable-name-face) 19210 19211 (face font-lock-string-face) 19211 19229 nil 19229 19230 (face font-lock-string-face) 19230 19237 (face font-lock-keyword-face) 19237 19238 (face font-lock-string-face) 19238 19242 nil 19242 19266 (face font-lock-string-face) 19266 19321 nil 19321 19322 (face font-lock-string-face) 19322 19342 (face font-lock-variable-name-face) 19342 19343 (face font-lock-string-face) 19343 19357 nil 19357 19399 (face font-lock-comment-face) 19399 19409 nil 19409 19410 (face font-lock-string-face) 19410 19417 (face font-lock-keyword-face) 19417 19418 (face font-lock-string-face) 19418 19434 nil 19434 19435 (face font-lock-string-face) 19435 19480 (face font-lock-constant-face) 19480 19481 (face font-lock-string-face) 19481 19495 nil 19495 19496 (face font-lock-string-face) 19496 19535 (face font-lock-constant-face) 19535 19536 (face font-lock-string-face) 19536 19573 nil 19573 19574 (face font-lock-string-face) 19574 19623 (face font-lock-variable-name-face) 19623 19624 (face font-lock-string-face) 19624 19638 nil 19638 19639 (face font-lock-string-face) 19639 19645 (face font-lock-keyword-face) 19645 19646 (face font-lock-string-face) 19646 19662 nil 19662 19670 (face font-lock-string-face) 19670 19707 nil 19707 19708 (face font-lock-string-face) 19708 19719 (face font-lock-variable-name-face) 19719 19720 (face font-lock-string-face) 19720 19734 nil 19734 19735 (face font-lock-string-face) 19735 19749 (face font-lock-keyword-face) 19749 19750 (face font-lock-string-face) 19750 19766 nil 19766 19773 (face font-lock-string-face) 19773 19791 nil 19791 19792 (face font-lock-string-face) 19792 19806 (face font-lock-keyword-face) 19806 19807 (face font-lock-string-face) 19807 19827 nil 19827 19890 (face font-lock-comment-face) 19890 19906 nil 19906 19971 (face font-lock-comment-face) 19971 19987 nil 19987 20032 (face font-lock-comment-face) 20032 20048 nil 20048 20072 (face font-lock-string-face) 20072 20074 nil 20074 20077 (face font-lock-string-face) 20077 20080 nil 20080 20086 (face font-lock-comment-face) 20086 20155 nil 20155 20156 (face font-lock-string-face) 20156 20165 (face font-lock-variable-name-face) 20165 20166 (face font-lock-string-face) 20166 20180 nil 20180 20181 (face font-lock-string-face) 20181 20190 (face font-lock-keyword-face) 20190 20191 (face font-lock-string-face) 20191 20207 nil 20207 20208 (face font-lock-string-face) 20208 20218 (face font-lock-variable-name-face) 20218 20219 (face font-lock-string-face) 20219 20237 nil 20237 20246 (face font-lock-string-face) 20246 20262 nil 20262 20270 (face font-lock-string-face) 20270 20286 nil 20286 20298 (face font-lock-string-face) 20298 20314 nil 20314 20322 (face font-lock-string-face) 20322 20374 nil 20374 20375 (face font-lock-string-face) 20375 20384 (face font-lock-variable-name-face) 20384 20385 (face font-lock-string-face) 20385 20399 nil 20399 20400 (face font-lock-string-face) 20400 20409 (face font-lock-keyword-face) 20409 20410 (face font-lock-string-face) 20410 20426 nil 20426 20427 (face font-lock-string-face) 20427 20437 (face font-lock-variable-name-face) 20437 20438 (face font-lock-string-face) 20438 20456 nil 20456 20466 (face font-lock-string-face) 20466 20482 nil 20482 20491 (face font-lock-string-face) 20491 20507 nil 20507 20519 (face font-lock-string-face) 20519 20535 nil 20535 20543 (face font-lock-string-face) 20543 20595 nil 20595 20596 (face font-lock-string-face) 20596 20621 (face font-lock-variable-name-face) 20621 20622 (face font-lock-string-face) 20622 20636 nil 20636 20637 (face font-lock-string-face) 20637 20646 (face font-lock-keyword-face) 20646 20647 (face font-lock-string-face) 20647 20663 nil 20663 20664 (face font-lock-string-face) 20664 20674 (face font-lock-keyword-face) 20674 20675 (face font-lock-string-face) 20675 20695 nil 20695 20696 (face font-lock-string-face) 20696 20715 (face font-lock-variable-name-face) 20715 20716 (face font-lock-string-face) 20716 20736 nil 20736 20748 (face font-lock-string-face) 20748 20770 nil 20770 20780 (face font-lock-string-face) 20780 20800 nil 20800 20807 (face font-lock-string-face) 20807 20827 nil 20827 20839 (face font-lock-string-face) 20839 20859 nil 20859 20867 (face font-lock-string-face) 20867 20923 nil 20923 20935 (face font-lock-string-face) 20935 20957 nil 20957 20972 (face font-lock-string-face) 20972 20992 nil 20992 20999 (face font-lock-string-face) 20999 21019 nil 21019 21026 (face font-lock-string-face) 21026 21046 nil 21046 21058 (face font-lock-string-face) 21058 21078 nil 21078 21086 (face font-lock-string-face) 21086 21180 nil 21180 21181 (face font-lock-string-face) 21181 21190 (face font-lock-keyword-face) 21190 21191 (face font-lock-string-face) 21191 21203 nil 21203 21204 (face font-lock-string-face) 21204 21220 (face font-lock-variable-name-face) 21220 21221 (face font-lock-string-face) 21221 21223 nil 21223 21224 (face font-lock-string-face) 21224 21256 (face font-lock-variable-name-face) 21256 21257 (face font-lock-string-face) 21257 21274 nil 21274 21314 (face font-lock-string-face) 21314 21325 nil 21325 21326 (face font-lock-string-face) 21326 21334 (face font-lock-keyword-face) 21334 21335 (face font-lock-string-face) 21335 21347 nil 21347 21348 (face font-lock-string-face) 21348 21385 (face font-lock-constant-face) 21385 21386 (face font-lock-string-face) 21386 21416 nil 21416 21417 (face font-lock-string-face) 21417 21428 (face font-lock-keyword-face) 21428 21429 (face font-lock-string-face) 21429 21431 nil 21431 21432 (face font-lock-string-face) 21432 21452 (face font-lock-function-name-face) 21452 21453 (face font-lock-string-face) 21453 21461 nil 21461 21462 (face font-lock-string-face) 21462 21466 (face font-lock-keyword-face) 21466 21467 (face font-lock-string-face) 21467 21469 nil 21469 21470 (face font-lock-string-face) 21470 21484 (face font-lock-type-face) 21484 21485 (face font-lock-string-face) 21485 21493 nil 21493 21494 (face font-lock-string-face) 21494 21506 (face font-lock-keyword-face) 21506 21507 (face font-lock-string-face) 21507 21519 nil 21519 21520 (face font-lock-string-face) 21520 21522 (face font-lock-constant-face) 21522 21523 (face font-lock-string-face) 21523 21540 nil 21540 21541 (face font-lock-string-face) 21541 21548 (face font-lock-keyword-face) 21548 21549 (face font-lock-string-face) 21549 21561 nil 21561 21562 (face font-lock-string-face) 21562 21595 (face font-lock-constant-face) 21595 21596 (face font-lock-string-face) 21596 21606 nil 21606 21607 (face font-lock-string-face) 21607 21637 (face font-lock-constant-face) 21637 21638 (face font-lock-string-face) 21638 21648 nil 21648 21649 (face font-lock-string-face) 21649 21682 (face font-lock-constant-face) 21682 21683 (face font-lock-string-face) 21683 21693 nil 21693 21694 (face font-lock-string-face) 21694 21724 (face font-lock-constant-face) 21724 21725 (face font-lock-string-face) 21725 21735 nil 21735 21736 (face font-lock-string-face) 21736 21758 (face font-lock-constant-face) 21758 21759 (face font-lock-string-face) 21759 21769 nil 21769 21770 (face font-lock-string-face) 21770 21795 (face font-lock-constant-face) 21795 21796 (face font-lock-string-face) 21796 21806 nil 21806 21807 (face font-lock-string-face) 21807 21836 (face font-lock-constant-face) 21836 21837 (face font-lock-string-face) 21837 21847 nil 21847 21848 (face font-lock-string-face) 21848 21876 (face font-lock-constant-face) 21876 21877 (face font-lock-string-face) 21877 21907 nil 21907 21908 (face font-lock-string-face) 21908 21919 (face font-lock-keyword-face) 21919 21920 (face font-lock-string-face) 21920 21922 nil 21922 21923 (face font-lock-string-face) 21923 21938 (face font-lock-function-name-face) 21938 21939 (face font-lock-string-face) 21939 21947 nil 21947 21948 (face font-lock-string-face) 21948 21952 (face font-lock-keyword-face) 21952 21953 (face font-lock-string-face) 21953 21955 nil 21955 21956 (face font-lock-string-face) 21956 21966 (face font-lock-type-face) 21966 21967 (face font-lock-string-face) 21967 21975 nil 21975 21976 (face font-lock-string-face) 21976 21988 (face font-lock-keyword-face) 21988 21989 (face font-lock-string-face) 21989 22001 nil 22001 22002 (face font-lock-string-face) 22002 22007 (face font-lock-function-name-face) 22007 22008 (face font-lock-string-face) 22008 22018 nil 22018 22019 (face font-lock-string-face) 22019 22037 (face font-lock-function-name-face) 22037 22038 (face font-lock-string-face) 22038 22048 nil 22048 22049 (face font-lock-string-face) 22049 22060 (face font-lock-function-name-face) 22060 22061 (face font-lock-string-face) 22061 22071 nil 22071 22072 (face font-lock-string-face) 22072 22093 (face font-lock-function-name-face) 22093 22094 (face font-lock-string-face) 22094 22104 nil 22104 22105 (face font-lock-string-face) 22105 22131 (face font-lock-function-name-face) 22131 22132 (face font-lock-string-face) 22132 22142 nil 22142 22143 (face font-lock-string-face) 22143 22177 (face font-lock-function-name-face) 22177 22178 (face font-lock-string-face) 22178 22188 nil 22188 22189 (face font-lock-string-face) 22189 22215 (face font-lock-function-name-face) 22215 22216 (face font-lock-string-face) 22216 22226 nil 22226 22227 (face font-lock-string-face) 22227 22253 (face font-lock-function-name-face) 22253 22254 (face font-lock-string-face) 22254 22264 nil 22264 22265 (face font-lock-string-face) 22265 22280 (face font-lock-function-name-face) 22280 22281 (face font-lock-string-face) 22281 22298 nil 22298 22299 (face font-lock-string-face) 22299 22306 (face font-lock-keyword-face) 22306 22307 (face font-lock-string-face) 22307 22319 nil 22319 22320 (face font-lock-string-face) 22320 22361 (face font-lock-constant-face) 22361 22362 (face font-lock-string-face) 22362 22372 nil 22372 22373 (face font-lock-string-face) 22373 22413 (face font-lock-constant-face) 22413 22414 (face font-lock-string-face) 22414 22424 nil 22424 22425 (face font-lock-string-face) 22425 22461 (face font-lock-constant-face) 22461 22462 (face font-lock-string-face) 22462 22472 nil 22472 22473 (face font-lock-string-face) 22473 22502 (face font-lock-constant-face) 22502 22503 (face font-lock-string-face) 22503 22513 nil 22513 22514 (face font-lock-string-face) 22514 22550 (face font-lock-constant-face) 22550 22551 (face font-lock-string-face) 22551 22561 nil 22561 22562 (face font-lock-string-face) 22562 22610 (face font-lock-constant-face) 22610 22611 (face font-lock-string-face) 22611 22621 nil 22621 22622 (face font-lock-string-face) 22622 22663 (face font-lock-constant-face) 22663 22664 (face font-lock-string-face) 22664 22674 nil 22674 22675 (face font-lock-string-face) 22675 22711 (face font-lock-constant-face) 22711 22712 (face font-lock-string-face) 22712 22722 nil 22722 22723 (face font-lock-string-face) 22723 22757 (face font-lock-constant-face) 22757 22758 (face font-lock-string-face) 22758 22768 nil 22768 22769 (face font-lock-string-face) 22769 22797 (face font-lock-constant-face) 22797 22798 (face font-lock-string-face) 22798 22808 nil 22808 22809 (face font-lock-string-face) 22809 22853 (face font-lock-constant-face) 22853 22854 (face font-lock-string-face) 22854 22864 nil 22864 22865 (face font-lock-string-face) 22865 22900 (face font-lock-constant-face) 22900 22901 (face font-lock-string-face) 22901 22911 nil 22911 22912 (face font-lock-string-face) 22912 22961 (face font-lock-constant-face) 22961 22962 (face font-lock-string-face) 22962 22972 nil 22972 22973 (face font-lock-string-face) 22973 23011 (face font-lock-constant-face) 23011 23012 (face font-lock-string-face) 23012 23022 nil 23022 23023 (face font-lock-string-face) 23023 23055 (face font-lock-constant-face) 23055 23056 (face font-lock-string-face) 23056 23066 nil 23066 23067 (face font-lock-string-face) 23067 23116 (face font-lock-constant-face) 23116 23117 (face font-lock-string-face) 23117 23127 nil 23127 23128 (face font-lock-string-face) 23128 23178 (face font-lock-constant-face) 23178 23179 (face font-lock-string-face) 23179 23189 nil 23189 23190 (face font-lock-string-face) 23190 23228 (face font-lock-constant-face) 23228 23229 (face font-lock-string-face) 23229 23239 nil 23239 23240 (face font-lock-string-face) 23240 23277 (face font-lock-constant-face) 23277 23278 (face font-lock-string-face) 23278 23288 nil 23288 23289 (face font-lock-string-face) 23289 23332 (face font-lock-constant-face) 23332 23333 (face font-lock-string-face) 23333 23343 nil 23343 23344 (face font-lock-string-face) 23344 23368 (face font-lock-constant-face) 23368 23369 (face font-lock-string-face) 23369 23379 nil 23379 23380 (face font-lock-string-face) 23380 23402 (face font-lock-constant-face) 23402 23403 (face font-lock-string-face) 23403 23413 nil 23413 23414 (face font-lock-string-face) 23414 23447 (face font-lock-constant-face) 23447 23448 (face font-lock-string-face) 23448 23458 nil 23458 23459 (face font-lock-string-face) 23459 23487 (face font-lock-constant-face) 23487 23488 (face font-lock-string-face) 23488 23498 nil 23498 23499 (face font-lock-string-face) 23499 23530 (face font-lock-constant-face) 23530 23531 (face font-lock-string-face) 23531 23541 nil 23541 23542 (face font-lock-string-face) 23542 23563 (face font-lock-constant-face) 23563 23564 (face font-lock-string-face) 23564 23574 nil 23574 23575 (face font-lock-string-face) 23575 23609 (face font-lock-constant-face) 23609 23610 (face font-lock-string-face) 23610 23620 nil 23620 23621 (face font-lock-string-face) 23621 23654 (face font-lock-constant-face) 23654 23655 (face font-lock-string-face) 23655 23665 nil 23665 23666 (face font-lock-string-face) 23666 23700 (face font-lock-constant-face) 23700 23701 (face font-lock-string-face) 23701 23711 nil 23711 23712 (face font-lock-string-face) 23712 23753 (face font-lock-constant-face) 23753 23754 (face font-lock-string-face) 23754 23764 nil 23764 23765 (face font-lock-string-face) 23765 23790 (face font-lock-constant-face) 23790 23791 (face font-lock-string-face) 23791 23801 nil 23801 23802 (face font-lock-string-face) 23802 23825 (face font-lock-constant-face) 23825 23826 (face font-lock-string-face) 23826 23836 nil 23836 23837 (face font-lock-string-face) 23837 23862 (face font-lock-constant-face) 23862 23863 (face font-lock-string-face) 23863 23873 nil 23873 23874 (face font-lock-string-face) 23874 23906 (face font-lock-constant-face) 23906 23907 (face font-lock-string-face) 23907 23917 nil 23917 23918 (face font-lock-string-face) 23918 23947 (face font-lock-constant-face) 23947 23948 (face font-lock-string-face) 23948 23958 nil 23958 23959 (face font-lock-string-face) 23959 23981 (face font-lock-constant-face) 23981 23982 (face font-lock-string-face) 23982 23992 nil 23992 23993 (face font-lock-string-face) 23993 24014 (face font-lock-constant-face) 24014 24015 (face font-lock-string-face) 24015 24025 nil 24025 24026 (face font-lock-string-face) 24026 24054 (face font-lock-constant-face) 24054 24055 (face font-lock-string-face) 24055 24065 nil 24065 24066 (face font-lock-string-face) 24066 24093 (face font-lock-constant-face) 24093 24094 (face font-lock-string-face) 24094 24104 nil 24104 24105 (face font-lock-string-face) 24105 24133 (face font-lock-constant-face) 24133 24134 (face font-lock-string-face) 24134 24144 nil 24144 24145 (face font-lock-string-face) 24145 24177 (face font-lock-constant-face) 24177 24178 (face font-lock-string-face) 24178 24188 nil 24188 24189 (face font-lock-string-face) 24189 24221 (face font-lock-constant-face) 24221 24222 (face font-lock-string-face) 24222 24232 nil 24232 24233 (face font-lock-string-face) 24233 24277 (face font-lock-constant-face) 24277 24278 (face font-lock-string-face) 24278 24288 nil 24288 24289 (face font-lock-string-face) 24289 24328 (face font-lock-constant-face) 24328 24329 (face font-lock-string-face) 24329 24339 nil 24339 24340 (face font-lock-string-face) 24340 24379 (face font-lock-constant-face) 24379 24380 (face font-lock-string-face) 24380 24390 nil 24390 24391 (face font-lock-string-face) 24391 24424 (face font-lock-constant-face) 24424 24425 (face font-lock-string-face) 24425 24435 nil 24435 24436 (face font-lock-string-face) 24436 24476 (face font-lock-constant-face) 24476 24477 (face font-lock-string-face) 24477 24487 nil 24487 24488 (face font-lock-string-face) 24488 24521 (face font-lock-constant-face) 24521 24522 (face font-lock-string-face) 24522 24532 nil 24532 24533 (face font-lock-string-face) 24533 24567 (face font-lock-constant-face) 24567 24568 (face font-lock-string-face) 24568 24578 nil 24578 24579 (face font-lock-string-face) 24579 24610 (face font-lock-constant-face) 24610 24611 (face font-lock-string-face) 24611 24621 nil 24621 24622 (face font-lock-string-face) 24622 24673 (face font-lock-constant-face) 24673 24674 (face font-lock-string-face) 24674 24684 nil 24684 24685 (face font-lock-string-face) 24685 24725 (face font-lock-constant-face) 24725 24726 (face font-lock-string-face) 24726 24736 nil 24736 24737 (face font-lock-string-face) 24737 24773 (face font-lock-constant-face) 24773 24774 (face font-lock-string-face) 24774 24784 nil 24784 24785 (face font-lock-string-face) 24785 24821 (face font-lock-constant-face) 24821 24822 (face font-lock-string-face) 24822 24832 nil 24832 24833 (face font-lock-string-face) 24833 24874 (face font-lock-constant-face) 24874 24875 (face font-lock-string-face) 24875 24885 nil 24885 24886 (face font-lock-string-face) 24886 24926 (face font-lock-constant-face) 24926 24927 (face font-lock-string-face) 24927 24937 nil 24937 24938 (face font-lock-string-face) 24938 24977 (face font-lock-constant-face) 24977 24978 (face font-lock-string-face) 24978 24988 nil 24988 24989 (face font-lock-string-face) 24989 25035 (face font-lock-constant-face) 25035 25036 (face font-lock-string-face) 25036 25046 nil 25046 25047 (face font-lock-string-face) 25047 25070 (face font-lock-constant-face) 25070 25071 (face font-lock-string-face) 25071 25081 nil 25081 25082 (face font-lock-string-face) 25082 25104 (face font-lock-constant-face) 25104 25105 (face font-lock-string-face) 25105 25115 nil 25115 25116 (face font-lock-string-face) 25116 25152 (face font-lock-constant-face) 25152 25153 (face font-lock-string-face) 25153 25163 nil 25163 25164 (face font-lock-string-face) 25164 25210 (face font-lock-constant-face) 25210 25211 (face font-lock-string-face) 25211 25221 nil 25221 25222 (face font-lock-string-face) 25222 25250 (face font-lock-constant-face) 25250 25251 (face font-lock-string-face) 25251 25268 nil 25268 25269 (face font-lock-string-face) 25269 25279 (face font-lock-keyword-face) 25279 25280 (face font-lock-string-face) 25280 25293 nil 25293 25294 (face font-lock-string-face) 25294 25319 (face font-lock-variable-name-face) 25319 25320 (face font-lock-string-face) 25320 25334 nil 25334 25335 (face font-lock-string-face) 25335 25345 (face font-lock-keyword-face) 25345 25346 (face font-lock-string-face) 25346 25363 nil 25363 25364 (face font-lock-string-face) 25364 25385 (face font-lock-variable-name-face) 25385 25386 (face font-lock-string-face) 25386 25404 nil 25404 25405 (face font-lock-string-face) 25405 25417 (face font-lock-keyword-face) 25417 25418 (face font-lock-string-face) 25418 25438 nil 25438 25439 (face font-lock-string-face) 25439 25480 (face font-lock-function-name-face) 25480 25481 (face font-lock-string-face) 25481 25550 nil 25550 25551 (face font-lock-string-face) 25551 25566 (face font-lock-variable-name-face) 25566 25567 (face font-lock-string-face) 25567 25581 nil 25581 25582 (face font-lock-string-face) 25582 25594 (face font-lock-keyword-face) 25594 25595 (face font-lock-string-face) 25595 25611 nil 25611 25612 (face font-lock-string-face) 25612 25651 (face font-lock-function-name-face) 25651 25652 (face font-lock-string-face) 25652 25688 nil 25688 25689 (face font-lock-string-face) 25689 25704 (face font-lock-variable-name-face) 25704 25705 (face font-lock-string-face) 25705 25719 nil 25719 25720 (face font-lock-string-face) 25720 25728 (face font-lock-keyword-face) 25728 25729 (face font-lock-string-face) 25729 25745 nil 25745 25746 (face font-lock-string-face) 25746 25782 (face font-lock-constant-face) 25782 25783 (face font-lock-string-face) 25783 25797 nil 25797 25798 (face font-lock-string-face) 25798 25820 (face font-lock-constant-face) 25820 25821 (face font-lock-string-face) 25821 25835 nil 25835 25836 (face font-lock-string-face) 25836 25857 (face font-lock-constant-face) 25857 25858 (face font-lock-string-face) 25858 25872 nil 25872 25873 (face font-lock-string-face) 25873 25905 (face font-lock-constant-face) 25905 25906 (face font-lock-string-face) 25906 25920 nil 25920 25921 (face font-lock-string-face) 25921 25961 (face font-lock-constant-face) 25961 25962 (face font-lock-string-face) 25962 25976 nil 25976 25977 (face font-lock-string-face) 25977 26016 (face font-lock-constant-face) 26016 26017 (face font-lock-string-face) 26017 26031 nil 26031 26032 (face font-lock-string-face) 26032 26065 (face font-lock-constant-face) 26065 26066 (face font-lock-string-face) 26066 26080 nil 26080 26081 (face font-lock-string-face) 26081 26115 (face font-lock-constant-face) 26115 26116 (face font-lock-string-face) 26116 26130 nil 26130 26131 (face font-lock-string-face) 26131 26162 (face font-lock-constant-face) 26162 26163 (face font-lock-string-face) 26163 26177 nil 26177 26178 (face font-lock-string-face) 26178 26229 (face font-lock-constant-face) 26229 26230 (face font-lock-string-face) 26230 26244 nil 26244 26245 (face font-lock-string-face) 26245 26285 (face font-lock-constant-face) 26285 26286 (face font-lock-string-face) 26286 26300 nil 26300 26301 (face font-lock-string-face) 26301 26337 (face font-lock-constant-face) 26337 26338 (face font-lock-string-face) 26338 26352 nil 26352 26353 (face font-lock-string-face) 26353 26394 (face font-lock-constant-face) 26394 26395 (face font-lock-string-face) 26395 26409 nil 26409 26410 (face font-lock-string-face) 26410 26443 (face font-lock-constant-face) 26443 26444 (face font-lock-string-face) 26444 26458 nil 26458 26459 (face font-lock-string-face) 26459 26495 (face font-lock-constant-face) 26495 26496 (face font-lock-string-face) 26496 26532 nil 26532 26533 (face font-lock-string-face) 26533 26546 (face font-lock-variable-name-face) 26546 26547 (face font-lock-string-face) 26547 26561 nil 26561 26562 (face font-lock-string-face) 26562 26572 (face font-lock-keyword-face) 26572 26573 (face font-lock-string-face) 26573 26590 nil 26590 26591 (face font-lock-string-face) 26591 26604 (face font-lock-variable-name-face) 26604 26605 (face font-lock-string-face) 26605 26623 nil 26623 26624 (face font-lock-string-face) 26624 26631 (face font-lock-keyword-face) 26631 26632 (face font-lock-string-face) 26632 26652 nil 26652 26653 (face font-lock-string-face) 26653 26688 (face font-lock-constant-face) 26688 26689 (face font-lock-string-face) 26689 26722 nil 26722 26723 (face font-lock-string-face) 26723 26730 (face font-lock-keyword-face) 26730 26731 (face font-lock-string-face) 26731 26751 nil 26751 26752 (face font-lock-string-face) 26752 26760 (face font-lock-preprocessor-face) 26760 26761 (face font-lock-string-face) 26761 26831 nil 26831 26832 (face font-lock-string-face) 26832 26873 (face font-lock-variable-name-face) 26873 26874 (face font-lock-string-face) 26874 26888 nil 26888 26889 (face font-lock-string-face) 26889 26896 (face font-lock-keyword-face) 26896 26897 (face font-lock-string-face) 26897 26913 nil 26913 26914 (face font-lock-string-face) 26914 26954 (face font-lock-constant-face) 26954 26955 (face font-lock-string-face) 26955 26991 nil 26991 26992 (face font-lock-string-face) 26992 27035 (face font-lock-variable-name-face) 27035 27036 (face font-lock-string-face) 27036 27050 nil 27050 27051 (face font-lock-string-face) 27051 27058 (face font-lock-keyword-face) 27058 27059 (face font-lock-string-face) 27059 27075 nil 27075 27076 (face font-lock-string-face) 27076 27095 (face font-lock-constant-face) 27095 27096 (face font-lock-string-face) 27096 27110 nil 27110 27111 (face font-lock-string-face) 27111 27137 (face font-lock-constant-face) 27137 27138 (face font-lock-string-face) 27138 27152 nil 27152 27153 (face font-lock-string-face) 27153 27186 (face font-lock-constant-face) 27186 27187 (face font-lock-string-face) 27187 27201 nil 27201 27202 (face font-lock-string-face) 27202 27235 (face font-lock-constant-face) 27235 27236 (face font-lock-string-face) 27236 27291 nil 27291 27292 (face font-lock-string-face) 27292 27303 (face font-lock-keyword-face) 27303 27304 (face font-lock-string-face) 27304 27306 nil 27306 27307 (face font-lock-string-face) 27307 27325 (face font-lock-function-name-face) 27325 27326 (face font-lock-string-face) 27326 27334 nil 27334 27335 (face font-lock-string-face) 27335 27339 (face font-lock-keyword-face) 27339 27340 (face font-lock-string-face) 27340 27342 nil 27342 27343 (face font-lock-string-face) 27343 27357 (face font-lock-type-face) 27357 27358 (face font-lock-string-face) 27358 27366 nil 27366 27367 (face font-lock-string-face) 27367 27379 (face font-lock-keyword-face) 27379 27380 (face font-lock-string-face) 27380 27392 nil 27392 27393 (face font-lock-string-face) 27393 27398 (face font-lock-function-name-face) 27398 27399 (face font-lock-string-face) 27399 27409 nil 27409 27410 (face font-lock-string-face) 27410 27431 (face font-lock-function-name-face) 27431 27432 (face font-lock-string-face) 27432 27442 nil 27442 27443 (face font-lock-string-face) 27443 27469 (face font-lock-function-name-face) 27469 27470 (face font-lock-string-face) 27470 27480 nil 27480 27481 (face font-lock-string-face) 27481 27507 (face font-lock-function-name-face) 27507 27508 (face font-lock-string-face) 27508 27525 nil 27525 27526 (face font-lock-string-face) 27526 27533 (face font-lock-keyword-face) 27533 27534 (face font-lock-string-face) 27534 27546 nil 27546 27547 (face font-lock-string-face) 27547 27591 (face font-lock-constant-face) 27591 27592 (face font-lock-string-face) 27592 27602 nil 27602 27603 (face font-lock-string-face) 27603 27646 (face font-lock-constant-face) 27646 27647 (face font-lock-string-face) 27647 27657 nil 27657 27658 (face font-lock-string-face) 27658 27679 (face font-lock-constant-face) 27679 27680 (face font-lock-string-face) 27680 27690 nil 27690 27691 (face font-lock-string-face) 27691 27711 (face font-lock-constant-face) 27711 27712 (face font-lock-string-face) 27712 27722 nil 27722 27723 (face font-lock-string-face) 27723 27752 (face font-lock-constant-face) 27752 27753 (face font-lock-string-face) 27753 27763 nil 27763 27764 (face font-lock-string-face) 27764 27792 (face font-lock-constant-face) 27792 27793 (face font-lock-string-face) 27793 27803 nil 27803 27804 (face font-lock-string-face) 27804 27829 (face font-lock-constant-face) 27829 27830 (face font-lock-string-face) 27830 27840 nil 27840 27841 (face font-lock-string-face) 27841 27865 (face font-lock-constant-face) 27865 27866 (face font-lock-string-face) 27866 27876 nil 27876 27877 (face font-lock-string-face) 27877 27901 (face font-lock-constant-face) 27901 27902 (face font-lock-string-face) 27902 27912 nil 27912 27913 (face font-lock-string-face) 27913 27936 (face font-lock-constant-face) 27936 27937 (face font-lock-string-face) 27937 27947 nil 27947 27948 (face font-lock-string-face) 27948 27968 (face font-lock-constant-face) 27968 27969 (face font-lock-string-face) 27969 27979 nil 27979 27980 (face font-lock-string-face) 27980 27999 (face font-lock-constant-face) 27999 28000 (face font-lock-string-face) 28000 28030 nil 28030 28031 (face font-lock-string-face) 28031 28042 (face font-lock-keyword-face) 28042 28043 (face font-lock-string-face) 28043 28045 nil 28045 28046 (face font-lock-string-face) 28046 28058 (face font-lock-function-name-face) 28058 28059 (face font-lock-string-face) 28059 28067 nil 28067 28068 (face font-lock-string-face) 28068 28072 (face font-lock-keyword-face) 28072 28073 (face font-lock-string-face) 28073 28075 nil 28075 28076 (face font-lock-string-face) 28076 28086 (face font-lock-type-face) 28086 28087 (face font-lock-string-face) 28087 28095 nil 28095 28096 (face font-lock-string-face) 28096 28108 (face font-lock-keyword-face) 28108 28109 (face font-lock-string-face) 28109 28121 nil 28121 28122 (face font-lock-string-face) 28122 28127 (face font-lock-function-name-face) 28127 28128 (face font-lock-string-face) 28128 28138 nil 28138 28139 (face font-lock-string-face) 28139 28150 (face font-lock-function-name-face) 28150 28151 (face font-lock-string-face) 28151 28161 nil 28161 28162 (face font-lock-string-face) 28162 28183 (face font-lock-function-name-face) 28183 28184 (face font-lock-string-face) 28184 28194 nil 28194 28195 (face font-lock-string-face) 28195 28216 (face font-lock-function-name-face) 28216 28217 (face font-lock-string-face) 28217 28234 nil 28234 28235 (face font-lock-string-face) 28235 28242 (face font-lock-keyword-face) 28242 28243 (face font-lock-string-face) 28243 28255 nil 28255 28256 (face font-lock-string-face) 28256 28290 (face font-lock-constant-face) 28290 28291 (face font-lock-string-face) 28291 28321 nil 28321 28322 (face font-lock-string-face) 28322 28333 (face font-lock-keyword-face) 28333 28334 (face font-lock-string-face) 28334 28336 nil 28336 28337 (face font-lock-string-face) 28337 28349 (face font-lock-function-name-face) 28349 28350 (face font-lock-string-face) 28350 28358 nil 28358 28359 (face font-lock-string-face) 28359 28363 (face font-lock-keyword-face) 28363 28364 (face font-lock-string-face) 28364 28366 nil 28366 28367 (face font-lock-string-face) 28367 28377 (face font-lock-type-face) 28377 28378 (face font-lock-string-face) 28378 28386 nil 28386 28387 (face font-lock-string-face) 28387 28394 (face font-lock-keyword-face) 28394 28395 (face font-lock-string-face) 28395 28407 nil 28407 28408 (face font-lock-string-face) 28408 28441 (face font-lock-constant-face) 28441 28442 (face font-lock-string-face) 28442 28471 nil 28471 28472 (face font-lock-string-face) 28472 28483 (face font-lock-keyword-face) 28483 28484 (face font-lock-string-face) 28484 28486 nil 28486 28487 (face font-lock-string-face) 28487 28498 (face font-lock-function-name-face) 28498 28499 (face font-lock-string-face) 28499 28507 nil 28507 28508 (face font-lock-string-face) 28508 28512 (face font-lock-keyword-face) 28512 28513 (face font-lock-string-face) 28513 28515 nil 28515 28516 (face font-lock-string-face) 28516 28526 (face font-lock-type-face) 28526 28527 (face font-lock-string-face) 28527 28535 nil 28535 28536 (face font-lock-string-face) 28536 28548 (face font-lock-keyword-face) 28548 28549 (face font-lock-string-face) 28549 28561 nil 28561 28562 (face font-lock-string-face) 28562 28567 (face font-lock-function-name-face) 28567 28568 (face font-lock-string-face) 28568 28578 nil 28578 28579 (face font-lock-string-face) 28579 28600 (face font-lock-function-name-face) 28600 28601 (face font-lock-string-face) 28601 28618 nil 28618 28619 (face font-lock-string-face) 28619 28626 (face font-lock-keyword-face) 28626 28627 (face font-lock-string-face) 28627 28639 nil 28639 28640 (face font-lock-string-face) 28640 28672 (face font-lock-constant-face) 28672 28673 (face font-lock-string-face) 28673 28698 nil 28698 28699 (face font-lock-string-face) 28699 28709 (face font-lock-keyword-face) 28709 28710 (face font-lock-string-face) 28710 28719 nil 28719 28720 (face font-lock-string-face) 28720 28729 (face font-lock-variable-name-face) 28729 28730 (face font-lock-string-face) 28730 28740 nil 28740 28741 (face font-lock-string-face) 28741 28748 (face font-lock-keyword-face) 28748 28749 (face font-lock-string-face) 28749 28773 nil 28773 28774 (face font-lock-string-face) 28774 28785 (face font-lock-keyword-face) 28785 28786 (face font-lock-string-face) 28786 28788 nil 28788 28789 (face font-lock-string-face) 28789 28799 (face font-lock-function-name-face) 28799 28800 (face font-lock-string-face) 28800 28812 nil 28812 28813 (face font-lock-string-face) 28813 28817 (face font-lock-keyword-face) 28817 28818 (face font-lock-string-face) 28818 28820 nil 28820 28821 (face font-lock-string-face) 28821 28831 (face font-lock-type-face) 28831 28832 (face font-lock-string-face) 28832 28844 nil 28844 28845 (face font-lock-string-face) 28845 28857 (face font-lock-keyword-face) 28857 28858 (face font-lock-string-face) 28858 28874 nil 28874 28875 (face font-lock-string-face) 28875 28880 (face font-lock-function-name-face) 28880 28881 (face font-lock-string-face) 28881 28895 nil 28895 28896 (face font-lock-string-face) 28896 28907 (face font-lock-function-name-face) 28907 28908 (face font-lock-string-face) 28908 28922 nil 28922 28923 (face font-lock-string-face) 28923 28944 (face font-lock-function-name-face) 28944 28945 (face font-lock-string-face) 28945 28959 nil 28959 28960 (face font-lock-string-face) 28960 29043 (face font-lock-function-name-face) 29043 29044 (face font-lock-string-face) 29044 29058 nil 29058 29059 (face font-lock-string-face) 29059 29074 (face font-lock-function-name-face) 29074 29075 (face font-lock-string-face) 29075 29100 nil 29100 29101 (face font-lock-string-face) 29101 29113 (face font-lock-keyword-face) 29113 29114 (face font-lock-string-face) 29114 29130 nil 29130 29131 (face font-lock-string-face) 29131 29133 (face font-lock-constant-face) 29133 29138 (face font-lock-variable-name-face) 29138 29163 (face font-lock-constant-face) 29163 29164 (face font-lock-string-face) 29164 29189 nil 29189 29190 (face font-lock-string-face) 29190 29197 (face font-lock-keyword-face) 29197 29198 (face font-lock-string-face) 29198 29214 nil 29214 29215 (face font-lock-string-face) 29215 29238 (face font-lock-constant-face) 29238 29239 (face font-lock-string-face) 29239 29253 nil 29253 29254 (face font-lock-string-face) 29254 29280 (face font-lock-constant-face) 29280 29281 (face font-lock-string-face) 29281 29295 nil 29295 29296 (face font-lock-string-face) 29296 29321 (face font-lock-constant-face) 29321 29322 (face font-lock-string-face) 29322 29336 nil 29336 29337 (face font-lock-string-face) 29337 29361 (face font-lock-constant-face) 29361 29362 (face font-lock-string-face) 29362 29376 nil 29376 29377 (face font-lock-string-face) 29377 29407 (face font-lock-constant-face) 29407 29408 (face font-lock-string-face) 29408 29422 nil 29422 29423 (face font-lock-string-face) 29423 29453 (face font-lock-constant-face) 29453 29454 (face font-lock-string-face) 29454 29468 nil 29468 29469 (face font-lock-string-face) 29469 29493 (face font-lock-constant-face) 29493 29494 (face font-lock-string-face) 29494 29508 nil 29508 29509 (face font-lock-string-face) 29509 29532 (face font-lock-constant-face) 29532 29533 (face font-lock-string-face) 29533 29547 nil 29547 29548 (face font-lock-string-face) 29548 29575 (face font-lock-constant-face) 29575 29576 (face font-lock-string-face) 29576 29590 nil 29590 29591 (face font-lock-string-face) 29591 29614 (face font-lock-constant-face) 29614 29615 (face font-lock-string-face) 29615 29640 nil 29640 29655 (face font-lock-string-face) 29655 29671 nil 29671 29685 (face font-lock-string-face) 29685 29703 nil 29703 29714 (face font-lock-string-face) 29714 29716 nil 29716 29719 (face font-lock-string-face) 29719 29729 nil 29729 29754 (face font-lock-comment-face) 29754 29792 nil 29792 29793 (face font-lock-string-face) 29793 29800 (face font-lock-keyword-face) 29800 29801 (face font-lock-string-face) 29801 29817 nil 29817 29818 (face font-lock-string-face) 29818 29843 (face font-lock-preprocessor-face) 29843 29844 (face font-lock-string-face) 29844 29892 nil 29892 29893 (face font-lock-string-face) 29893 29929 (face font-lock-variable-name-face) 29929 29930 (face font-lock-string-face) 29930 29940 nil 29940 29941 (face font-lock-string-face) 29941 29948 (face font-lock-keyword-face) 29948 29949 (face font-lock-string-face) 29949 29973 nil 29973 29974 (face font-lock-string-face) 29974 29985 (face font-lock-keyword-face) 29985 29986 (face font-lock-string-face) 29986 29988 nil 29988 29989 (face font-lock-string-face) 29989 30001 (face font-lock-function-name-face) 30001 30002 (face font-lock-string-face) 30002 30014 nil 30014 30015 (face font-lock-string-face) 30015 30019 (face font-lock-keyword-face) 30019 30020 (face font-lock-string-face) 30020 30022 nil 30022 30023 (face font-lock-string-face) 30023 30033 (face font-lock-type-face) 30033 30034 (face font-lock-string-face) 30034 30046 nil 30046 30047 (face font-lock-string-face) 30047 30059 (face font-lock-keyword-face) 30059 30060 (face font-lock-string-face) 30060 30076 nil 30076 30077 (face font-lock-string-face) 30077 30082 (face font-lock-function-name-face) 30082 30083 (face font-lock-string-face) 30083 30097 nil 30097 30098 (face font-lock-string-face) 30098 30109 (face font-lock-function-name-face) 30109 30110 (face font-lock-string-face) 30110 30124 nil 30124 30125 (face font-lock-string-face) 30125 30146 (face font-lock-function-name-face) 30146 30147 (face font-lock-string-face) 30147 30161 nil 30161 30162 (face font-lock-string-face) 30162 30180 (face font-lock-function-name-face) 30180 30181 (face font-lock-string-face) 30181 30206 nil 30206 30207 (face font-lock-string-face) 30207 30214 (face font-lock-keyword-face) 30214 30215 (face font-lock-string-face) 30215 30231 nil 30231 30232 (face font-lock-string-face) 30232 30266 (face font-lock-constant-face) 30266 30267 (face font-lock-string-face) 30267 30281 nil 30281 30282 (face font-lock-string-face) 30282 30321 (face font-lock-constant-face) 30321 30322 (face font-lock-string-face) 30322 30336 nil 30336 30337 (face font-lock-string-face) 30337 30375 (face font-lock-constant-face) 30375 30376 (face font-lock-string-face) 30376 30390 nil 30390 30391 (face font-lock-string-face) 30391 30430 (face font-lock-constant-face) 30430 30431 (face font-lock-string-face) 30431 30445 nil 30445 30446 (face font-lock-string-face) 30446 30484 (face font-lock-constant-face) 30484 30485 (face font-lock-string-face) 30485 30499 nil 30499 30500 (face font-lock-string-face) 30500 30533 (face font-lock-constant-face) 30533 30534 (face font-lock-string-face) 30534 30548 nil 30548 30549 (face font-lock-string-face) 30549 30581 (face font-lock-constant-face) 30581 30582 (face font-lock-string-face) 30582 30596 nil 30596 30597 (face font-lock-string-face) 30597 30626 (face font-lock-constant-face) 30626 30627 (face font-lock-string-face) 30627 30641 nil 30641 30642 (face font-lock-string-face) 30642 30670 (face font-lock-constant-face) 30670 30671 (face font-lock-string-face) 30671 30685 nil 30685 30686 (face font-lock-string-face) 30686 30714 (face font-lock-constant-face) 30714 30715 (face font-lock-string-face) 30715 30729 nil 30729 30730 (face font-lock-string-face) 30730 30757 (face font-lock-constant-face) 30757 30758 (face font-lock-string-face) 30758 30783 nil 30783 30784 (face font-lock-string-face) 30784 30794 (face font-lock-keyword-face) 30794 30795 (face font-lock-string-face) 30795 30812 nil 30812 30813 (face font-lock-string-face) 30813 30834 (face font-lock-variable-name-face) 30834 30835 (face font-lock-string-face) 30835 30853 nil 30853 30854 (face font-lock-string-face) 30854 30866 (face font-lock-keyword-face) 30866 30867 (face font-lock-string-face) 30867 30887 nil 30887 30888 (face font-lock-string-face) 30888 30917 (face font-lock-function-name-face) 30917 30918 (face font-lock-string-face) 30918 30951 nil 30951 30952 (face font-lock-string-face) 30952 30959 (face font-lock-keyword-face) 30959 30960 (face font-lock-string-face) 30960 30980 nil 30980 30981 (face font-lock-string-face) 30981 31015 (face font-lock-constant-face) 31015 31016 (face font-lock-string-face) 31016 31064 nil 31064 31065 (face font-lock-string-face) 31065 31074 (face font-lock-variable-name-face) 31074 31075 (face font-lock-string-face) 31075 31093 nil 31093 31094 (face font-lock-string-face) 31094 31106 (face font-lock-keyword-face) 31106 31107 (face font-lock-string-face) 31107 31127 nil 31127 31128 (face font-lock-string-face) 31128 31175 (face font-lock-function-name-face) 31175 31176 (face font-lock-string-face) 31176 31194 nil 31194 31195 (face font-lock-string-face) 31195 31245 (face font-lock-function-name-face) 31245 31246 (face font-lock-string-face) 31246 31279 nil 31279 31280 (face font-lock-string-face) 31280 31287 (face font-lock-keyword-face) 31287 31288 (face font-lock-string-face) 31288 31308 nil 31308 31309 (face font-lock-string-face) 31309 31341 (face font-lock-constant-face) 31341 31342 (face font-lock-string-face) 31342 31423 nil 31423 31424 (face font-lock-string-face) 31424 31462 (face font-lock-variable-name-face) 31462 31463 (face font-lock-string-face) 31463 31473 nil 31473 31474 (face font-lock-string-face) 31474 31481 (face font-lock-keyword-face) 31481 31482 (face font-lock-string-face) 31482 31506 nil 31506 31507 (face font-lock-string-face) 31507 31518 (face font-lock-keyword-face) 31518 31519 (face font-lock-string-face) 31519 31521 nil 31521 31522 (face font-lock-string-face) 31522 31539 (face font-lock-function-name-face) 31539 31540 (face font-lock-string-face) 31540 31552 nil 31552 31553 (face font-lock-string-face) 31553 31557 (face font-lock-keyword-face) 31557 31558 (face font-lock-string-face) 31558 31560 nil 31560 31561 (face font-lock-string-face) 31561 31571 (face font-lock-type-face) 31571 31572 (face font-lock-string-face) 31572 31584 nil 31584 31585 (face font-lock-string-face) 31585 31597 (face font-lock-keyword-face) 31597 31598 (face font-lock-string-face) 31598 31614 nil 31614 31615 (face font-lock-string-face) 31615 31636 (face font-lock-function-name-face) 31636 31637 (face font-lock-string-face) 31637 31651 nil 31651 31652 (face font-lock-string-face) 31652 31670 (face font-lock-function-name-face) 31670 31671 (face font-lock-string-face) 31671 31696 nil 31696 31697 (face font-lock-string-face) 31697 31706 (face font-lock-keyword-face) 31706 31707 (face font-lock-string-face) 31707 31723 nil 31723 31724 (face font-lock-string-face) 31724 31728 (face font-lock-constant-face) 31728 31729 (face font-lock-string-face) 31729 31743 nil 31743 31744 (face font-lock-string-face) 31744 31748 (face font-lock-constant-face) 31748 31749 (face font-lock-string-face) 31749 31774 nil 31774 31775 (face font-lock-string-face) 31775 31782 (face font-lock-keyword-face) 31782 31783 (face font-lock-string-face) 31783 31799 nil 31799 31800 (face font-lock-string-face) 31800 31844 (face font-lock-constant-face) 31844 31845 (face font-lock-string-face) 31845 31893 nil 31893 31894 (face font-lock-string-face) 31894 31943 (face font-lock-variable-name-face) 31943 31944 (face font-lock-string-face) 31944 31954 nil 31954 31955 (face font-lock-string-face) 31955 31962 (face font-lock-keyword-face) 31962 31963 (face font-lock-string-face) 31963 31987 nil 31987 31988 (face font-lock-string-face) 31988 31999 (face font-lock-keyword-face) 31999 32000 (face font-lock-string-face) 32000 32002 nil 32002 32003 (face font-lock-string-face) 32003 32013 (face font-lock-function-name-face) 32013 32014 (face font-lock-string-face) 32014 32026 nil 32026 32027 (face font-lock-string-face) 32027 32031 (face font-lock-keyword-face) 32031 32032 (face font-lock-string-face) 32032 32034 nil 32034 32035 (face font-lock-string-face) 32035 32045 (face font-lock-type-face) 32045 32046 (face font-lock-string-face) 32046 32058 nil 32058 32059 (face font-lock-string-face) 32059 32071 (face font-lock-keyword-face) 32071 32072 (face font-lock-string-face) 32072 32088 nil 32088 32089 (face font-lock-string-face) 32089 32094 (face font-lock-function-name-face) 32094 32095 (face font-lock-string-face) 32095 32109 nil 32109 32110 (face font-lock-string-face) 32110 32121 (face font-lock-function-name-face) 32121 32122 (face font-lock-string-face) 32122 32136 nil 32136 32137 (face font-lock-string-face) 32137 32158 (face font-lock-function-name-face) 32158 32159 (face font-lock-string-face) 32159 32173 nil 32173 32174 (face font-lock-string-face) 32174 32192 (face font-lock-function-name-face) 32192 32193 (face font-lock-string-face) 32193 32218 nil 32218 32219 (face font-lock-string-face) 32219 32232 (face font-lock-keyword-face) 32232 32233 (face font-lock-string-face) 32233 32249 nil 32249 32250 (face font-lock-string-face) 32250 32259 (face font-lock-keyword-face) 32259 32260 (face font-lock-string-face) 32260 32278 nil 32278 32279 (face font-lock-string-face) 32279 32283 (face font-lock-constant-face) 32283 32284 (face font-lock-string-face) 32284 32300 nil 32300 32301 (face font-lock-string-face) 32301 32306 (face font-lock-constant-face) 32306 32307 (face font-lock-string-face) 32307 32323 nil 32323 32324 (face font-lock-string-face) 32324 32333 (face font-lock-constant-face) 32333 32334 (face font-lock-string-face) 32334 32350 nil 32350 32351 (face font-lock-string-face) 32351 32357 (face font-lock-constant-face) 32357 32358 (face font-lock-string-face) 32358 32398 nil 32398 32399 (face font-lock-string-face) 32399 32406 (face font-lock-keyword-face) 32406 32407 (face font-lock-string-face) 32407 32423 nil 32423 32424 (face font-lock-string-face) 32424 32462 (face font-lock-constant-face) 32462 32463 (face font-lock-string-face) 32463 32477 nil 32477 32478 (face font-lock-string-face) 32478 32515 (face font-lock-constant-face) 32515 32516 (face font-lock-string-face) 32516 32530 nil 32530 32531 (face font-lock-string-face) 32531 32568 (face font-lock-constant-face) 32568 32569 (face font-lock-string-face) 32569 32583 nil 32583 32584 (face font-lock-string-face) 32584 32620 (face font-lock-constant-face) 32620 32621 (face font-lock-string-face) 32621 32635 nil 32635 32636 (face font-lock-string-face) 32636 32666 (face font-lock-constant-face) 32666 32667 (face font-lock-string-face) 32667 32681 nil 32681 32682 (face font-lock-string-face) 32682 32720 (face font-lock-constant-face) 32720 32721 (face font-lock-string-face) 32721 32735 nil 32735 32736 (face font-lock-string-face) 32736 32773 (face font-lock-constant-face) 32773 32774 (face font-lock-string-face) 32774 32822 nil 32822 32823 (face font-lock-string-face) 32823 32838 (face font-lock-variable-name-face) 32838 32839 (face font-lock-string-face) 32839 32849 nil 32849 32850 (face font-lock-string-face) 32850 32857 (face font-lock-keyword-face) 32857 32858 (face font-lock-string-face) 32858 32882 nil 32882 32883 (face font-lock-string-face) 32883 32894 (face font-lock-keyword-face) 32894 32895 (face font-lock-string-face) 32895 32897 nil 32897 32898 (face font-lock-string-face) 32898 32912 (face font-lock-function-name-face) 32912 32913 (face font-lock-string-face) 32913 32925 nil 32925 32926 (face font-lock-string-face) 32926 32930 (face font-lock-keyword-face) 32930 32931 (face font-lock-string-face) 32931 32933 nil 32933 32934 (face font-lock-string-face) 32934 32948 (face font-lock-type-face) 32948 32949 (face font-lock-string-face) 32949 32961 nil 32961 32962 (face font-lock-string-face) 32962 32969 (face font-lock-keyword-face) 32969 32970 (face font-lock-string-face) 32970 32986 nil 32986 32987 (face font-lock-string-face) 32987 33022 (face font-lock-constant-face) 33022 33023 (face font-lock-string-face) 33023 33037 nil 33037 33038 (face font-lock-string-face) 33038 33072 (face font-lock-constant-face) 33072 33073 (face font-lock-string-face) 33073 33098 nil 33098 33099 (face font-lock-string-face) 33099 33111 (face font-lock-keyword-face) 33111 33112 (face font-lock-string-face) 33112 33128 nil 33128 33129 (face font-lock-string-face) 33129 33150 (face font-lock-function-name-face) 33150 33151 (face font-lock-string-face) 33151 33176 nil 33176 33177 (face font-lock-string-face) 33177 33189 (face font-lock-keyword-face) 33189 33190 (face font-lock-string-face) 33190 33206 nil 33206 33207 (face font-lock-string-face) 33207 33209 (face font-lock-constant-face) 33209 33232 (face font-lock-variable-name-face) 33232 33239 (face font-lock-constant-face) 33239 33240 (face font-lock-string-face) 33240 33265 nil 33265 33266 (face font-lock-string-face) 33266 33273 (face font-lock-keyword-face) 33273 33274 (face font-lock-string-face) 33274 33306 nil 33306 33307 (face font-lock-string-face) 33307 33318 (face font-lock-keyword-face) 33318 33319 (face font-lock-string-face) 33319 33321 nil 33321 33322 (face font-lock-string-face) 33322 33342 (face font-lock-function-name-face) 33342 33343 (face font-lock-string-face) 33343 33359 nil 33359 33360 (face font-lock-string-face) 33360 33366 (face font-lock-keyword-face) 33366 33367 (face font-lock-string-face) 33367 33387 nil 33387 33388 (face font-lock-string-face) 33388 33434 (face font-lock-constant-face) 33434 33435 (face font-lock-string-face) 33435 33453 nil 33453 33454 (face font-lock-string-face) 33454 33519 (face font-lock-constant-face) 33519 33520 (face font-lock-string-face) 33520 33553 nil 33553 33554 (face font-lock-string-face) 33554 33561 (face font-lock-keyword-face) 33561 33562 (face font-lock-string-face) 33562 33582 nil 33582 33583 (face font-lock-string-face) 33583 33585 (face font-lock-constant-face) 33585 33608 (face font-lock-variable-name-face) 33608 33647 (face font-lock-constant-face) 33647 33648 (face font-lock-string-face) 33648 33681 nil 33681 33682 (face font-lock-string-face) 33682 33688 (face font-lock-keyword-face) 33688 33689 (face font-lock-string-face) 33689 33709 nil 33709 33710 (face font-lock-string-face) 33710 33716 (face font-lock-constant-face) 33716 33717 (face font-lock-string-face) 33717 33735 nil 33735 33736 (face font-lock-string-face) 33736 33738 (face font-lock-constant-face) 33738 33743 (face font-lock-variable-name-face) 33743 33788 (face font-lock-constant-face) 33788 33789 (face font-lock-string-face) 33789 33807 nil 33807 33808 (face font-lock-string-face) 33808 33810 (face font-lock-constant-face) 33810 33811 (face font-lock-string-face) 33811 33829 nil 33829 33830 (face font-lock-string-face) 33830 33833 (face font-lock-constant-face) 33833 33840 (face font-lock-variable-name-face) 33840 33841 (face font-lock-constant-face) 33841 33842 (face font-lock-string-face) 33842 33860 nil 33860 33861 (face font-lock-string-face) 33861 33864 (face font-lock-constant-face) 33864 33872 (face font-lock-variable-name-face) 33872 33873 (face font-lock-constant-face) 33873 33874 (face font-lock-string-face) 33874 33952 nil 33952 33953 (face font-lock-string-face) 33953 33964 (face font-lock-keyword-face) 33964 33965 (face font-lock-string-face) 33965 33967 nil 33967 33968 (face font-lock-string-face) 33968 33978 (face font-lock-function-name-face) 33978 33979 (face font-lock-string-face) 33979 33991 nil 33991 33992 (face font-lock-string-face) 33992 33996 (face font-lock-keyword-face) 33996 33997 (face font-lock-string-face) 33997 33999 nil 33999 34000 (face font-lock-string-face) 34000 34004 (face font-lock-type-face) 34004 34005 (face font-lock-string-face) 34005 34017 nil 34017 34018 (face font-lock-string-face) 34018 34030 (face font-lock-keyword-face) 34030 34031 (face font-lock-string-face) 34031 34035 nil 34035 34036 (face font-lock-string-face) 34036 34062 (face font-lock-function-name-face) 34062 34063 (face font-lock-string-face) 34063 34077 nil 34077 34078 (face font-lock-string-face) 34078 34087 (face font-lock-keyword-face) 34087 34088 (face font-lock-string-face) 34088 34104 nil 34104 34105 (face font-lock-string-face) 34105 34117 (face font-lock-variable-name-face) 34117 34118 (face font-lock-string-face) 34118 34120 nil 34120 34121 (face font-lock-string-face) 34121 34126 (face font-lock-variable-name-face) 34126 34127 (face font-lock-string-face) 34127 34141 nil 34141 34142 (face font-lock-string-face) 34142 34153 (face font-lock-variable-name-face) 34153 34154 (face font-lock-string-face) 34154 34156 nil 34156 34157 (face font-lock-string-face) 34157 34174 (face font-lock-variable-name-face) 34174 34175 (face font-lock-string-face) 34175 34200 nil 34200 34201 (face font-lock-string-face) 34201 34209 (face font-lock-keyword-face) 34209 34210 (face font-lock-string-face) 34210 34214 nil 34214 34215 (face font-lock-string-face) 34215 34233 (face font-lock-constant-face) 34233 34234 (face font-lock-string-face) 34234 34268 nil 34268 34287 (face font-lock-comment-face) 34287 34293 nil 34293 34365 (face font-lock-comment-face) 34365 34371 nil 34371 34372 (face font-lock-string-face) 34372 34379 (face font-lock-keyword-face) 34379 34380 (face font-lock-string-face) 34380 34404 nil 34404 34405 (face font-lock-string-face) 34405 34416 (face font-lock-keyword-face) 34416 34417 (face font-lock-string-face) 34417 34419 nil 34419 34420 (face font-lock-string-face) 34420 34436 (face font-lock-function-name-face) 34436 34437 (face font-lock-string-face) 34437 34449 nil 34449 34450 (face font-lock-string-face) 34450 34454 (face font-lock-keyword-face) 34454 34455 (face font-lock-string-face) 34455 34457 nil 34457 34458 (face font-lock-string-face) 34458 34468 (face font-lock-type-face) 34468 34469 (face font-lock-string-face) 34469 34481 nil 34481 34482 (face font-lock-string-face) 34482 34494 (face font-lock-keyword-face) 34494 34495 (face font-lock-string-face) 34495 34511 nil 34511 34512 (face font-lock-string-face) 34512 34517 (face font-lock-function-name-face) 34517 34518 (face font-lock-string-face) 34518 34532 nil 34532 34533 (face font-lock-string-face) 34533 34551 (face font-lock-function-name-face) 34551 34552 (face font-lock-string-face) 34552 34566 nil 34566 34567 (face font-lock-string-face) 34567 34588 (face font-lock-function-name-face) 34588 34589 (face font-lock-string-face) 34589 34603 nil 34603 34604 (face font-lock-string-face) 34604 34630 (face font-lock-function-name-face) 34630 34631 (face font-lock-string-face) 34631 34645 nil 34645 34646 (face font-lock-string-face) 34646 34680 (face font-lock-function-name-face) 34680 34681 (face font-lock-string-face) 34681 34695 nil 34695 34696 (face font-lock-string-face) 34696 34730 (face font-lock-function-name-face) 34730 34731 (face font-lock-string-face) 34731 34745 nil 34745 34746 (face font-lock-string-face) 34746 34772 (face font-lock-function-name-face) 34772 34773 (face font-lock-string-face) 34773 34787 nil 34787 34788 (face font-lock-string-face) 34788 34827 (face font-lock-function-name-face) 34827 34828 (face font-lock-string-face) 34828 34853 nil 34853 34854 (face font-lock-string-face) 34854 34861 (face font-lock-keyword-face) 34861 34862 (face font-lock-string-face) 34862 34878 nil 34878 34879 (face font-lock-string-face) 34879 34904 (face font-lock-constant-face) 34904 34905 (face font-lock-string-face) 34905 34930 nil 34930 34931 (face font-lock-string-face) 34931 34941 (face font-lock-keyword-face) 34941 34942 (face font-lock-string-face) 34942 34959 nil 34959 34960 (face font-lock-string-face) 34960 34981 (face font-lock-variable-name-face) 34981 34982 (face font-lock-string-face) 34982 35000 nil 35000 35001 (face font-lock-string-face) 35001 35013 (face font-lock-keyword-face) 35013 35014 (face font-lock-string-face) 35014 35034 nil 35034 35077 (face font-lock-comment-face) 35077 35093 nil 35093 35123 (face font-lock-comment-face) 35123 35139 nil 35139 35164 (face font-lock-comment-face) 35164 35180 nil 35180 35194 (face font-lock-comment-face) 35194 35210 nil 35210 35211 (face font-lock-string-face) 35211 35240 (face font-lock-function-name-face) 35240 35241 (face font-lock-string-face) 35241 35274 nil 35274 35275 (face font-lock-string-face) 35275 35285 (face font-lock-keyword-face) 35285 35286 (face font-lock-string-face) 35286 35307 nil 35307 35308 (face font-lock-string-face) 35308 35329 (face font-lock-variable-name-face) 35329 35330 (face font-lock-string-face) 35330 35352 nil 35352 35353 (face font-lock-string-face) 35353 35365 (face font-lock-keyword-face) 35365 35366 (face font-lock-string-face) 35366 35390 nil 35390 35391 (face font-lock-string-face) 35391 35432 (face font-lock-function-name-face) 35432 35433 (face font-lock-string-face) 35433 35553 nil 35553 35554 (face font-lock-string-face) 35554 35565 (face font-lock-keyword-face) 35565 35566 (face font-lock-string-face) 35566 35568 nil 35568 35569 (face font-lock-string-face) 35569 35592 (face font-lock-function-name-face) 35592 35593 (face font-lock-string-face) 35593 35605 nil 35605 35606 (face font-lock-string-face) 35606 35610 (face font-lock-keyword-face) 35610 35611 (face font-lock-string-face) 35611 35613 nil 35613 35614 (face font-lock-string-face) 35614 35624 (face font-lock-type-face) 35624 35625 (face font-lock-string-face) 35625 35637 nil 35637 35638 (face font-lock-string-face) 35638 35650 (face font-lock-keyword-face) 35650 35651 (face font-lock-string-face) 35651 35667 nil 35667 35668 (face font-lock-string-face) 35668 35673 (face font-lock-function-name-face) 35673 35674 (face font-lock-string-face) 35674 35688 nil 35688 35689 (face font-lock-string-face) 35689 35707 (face font-lock-function-name-face) 35707 35708 (face font-lock-string-face) 35708 35722 nil 35722 35723 (face font-lock-string-face) 35723 35757 (face font-lock-function-name-face) 35757 35758 (face font-lock-string-face) 35758 35772 nil 35772 35773 (face font-lock-string-face) 35773 35799 (face font-lock-function-name-face) 35799 35800 (face font-lock-string-face) 35800 35814 nil 35814 35815 (face font-lock-string-face) 35815 35841 (face font-lock-function-name-face) 35841 35842 (face font-lock-string-face) 35842 35856 nil 35856 35857 (face font-lock-string-face) 35857 35896 (face font-lock-function-name-face) 35896 35897 (face font-lock-string-face) 35897 35922 nil 35922 35923 (face font-lock-string-face) 35923 35930 (face font-lock-keyword-face) 35930 35931 (face font-lock-string-face) 35931 35947 nil 35947 35948 (face font-lock-string-face) 35948 35970 (face font-lock-constant-face) 35970 35971 (face font-lock-string-face) 35971 35985 nil 35985 35986 (face font-lock-string-face) 35986 36011 (face font-lock-constant-face) 36011 36012 (face font-lock-string-face) 36012 36026 nil 36026 36027 (face font-lock-string-face) 36027 36060 (face font-lock-constant-face) 36060 36061 (face font-lock-string-face) 36061 36075 nil 36075 36076 (face font-lock-string-face) 36076 36117 (face font-lock-constant-face) 36117 36118 (face font-lock-string-face) 36118 36143 nil 36143 36144 (face font-lock-string-face) 36144 36154 (face font-lock-keyword-face) 36154 36155 (face font-lock-string-face) 36155 36172 nil 36172 36173 (face font-lock-string-face) 36173 36198 (face font-lock-variable-name-face) 36198 36199 (face font-lock-string-face) 36199 36217 nil 36217 36218 (face font-lock-string-face) 36218 36228 (face font-lock-keyword-face) 36228 36229 (face font-lock-string-face) 36229 36250 nil 36250 36251 (face font-lock-string-face) 36251 36272 (face font-lock-variable-name-face) 36272 36273 (face font-lock-string-face) 36273 36295 nil 36295 36296 (face font-lock-string-face) 36296 36308 (face font-lock-keyword-face) 36308 36309 (face font-lock-string-face) 36309 36333 nil 36333 36334 (face font-lock-string-face) 36334 36375 (face font-lock-function-name-face) 36375 36376 (face font-lock-string-face) 36376 36496 nil 36496 36497 (face font-lock-string-face) 36497 36508 (face font-lock-keyword-face) 36508 36509 (face font-lock-string-face) 36509 36511 nil 36511 36512 (face font-lock-string-face) 36512 36524 (face font-lock-function-name-face) 36524 36525 (face font-lock-string-face) 36525 36537 nil 36537 36538 (face font-lock-string-face) 36538 36542 (face font-lock-keyword-face) 36542 36543 (face font-lock-string-face) 36543 36545 nil 36545 36546 (face font-lock-string-face) 36546 36556 (face font-lock-type-face) 36556 36557 (face font-lock-string-face) 36557 36569 nil 36569 36570 (face font-lock-string-face) 36570 36582 (face font-lock-keyword-face) 36582 36583 (face font-lock-string-face) 36583 36599 nil 36599 36600 (face font-lock-string-face) 36600 36605 (face font-lock-function-name-face) 36605 36606 (face font-lock-string-face) 36606 36620 nil 36620 36621 (face font-lock-string-face) 36621 36642 (face font-lock-function-name-face) 36642 36643 (face font-lock-string-face) 36643 36657 nil 36657 36658 (face font-lock-string-face) 36658 36697 (face font-lock-function-name-face) 36697 36698 (face font-lock-string-face) 36698 36723 nil 36723 36724 (face font-lock-string-face) 36724 36731 (face font-lock-keyword-face) 36731 36732 (face font-lock-string-face) 36732 36748 nil 36748 36749 (face font-lock-string-face) 36749 36782 (face font-lock-constant-face) 36782 36783 (face font-lock-string-face) 36783 36829 nil 36829 36830 (face font-lock-string-face) 36830 36841 (face font-lock-keyword-face) 36841 36842 (face font-lock-string-face) 36842 36844 nil 36844 36845 (face font-lock-string-face) 36845 36856 (face font-lock-function-name-face) 36856 36857 (face font-lock-string-face) 36857 36869 nil 36869 36870 (face font-lock-string-face) 36870 36874 (face font-lock-keyword-face) 36874 36875 (face font-lock-string-face) 36875 36877 nil 36877 36878 (face font-lock-string-face) 36878 36888 (face font-lock-type-face) 36888 36889 (face font-lock-string-face) 36889 36901 nil 36901 36902 (face font-lock-string-face) 36902 36914 (face font-lock-keyword-face) 36914 36915 (face font-lock-string-face) 36915 36931 nil 36931 36932 (face font-lock-string-face) 36932 36937 (face font-lock-function-name-face) 36937 36938 (face font-lock-string-face) 36938 36952 nil 36952 36953 (face font-lock-string-face) 36953 36974 (face font-lock-function-name-face) 36974 36975 (face font-lock-string-face) 36975 36989 nil 36989 36990 (face font-lock-string-face) 36990 37029 (face font-lock-function-name-face) 37029 37030 (face font-lock-string-face) 37030 37055 nil 37055 37056 (face font-lock-string-face) 37056 37063 (face font-lock-keyword-face) 37063 37064 (face font-lock-string-face) 37064 37080 nil 37080 37081 (face font-lock-string-face) 37081 37113 (face font-lock-constant-face) 37113 37114 (face font-lock-string-face) 37114 37163 nil) diff --git a/node_modules/node-gyp/gyp/tools/graphviz.py b/node_modules/node-gyp/gyp/tools/graphviz.py deleted file mode 100755 index f19426b69faa6..0000000000000 --- a/node_modules/node-gyp/gyp/tools/graphviz.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2011 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Using the JSON dumped by the dump-dependency-json generator, -generate input suitable for graphviz to render a dependency graph of -targets.""" - - -import collections -import json -import sys - - -def ParseTarget(target): - target, _, suffix = target.partition("#") - filename, _, target = target.partition(":") - return filename, target, suffix - - -def LoadEdges(filename, targets): - """Load the edges map from the dump file, and filter it to only - show targets in |targets| and their depedendents.""" - - file = open("dump.json") - edges = json.load(file) - file.close() - - # Copy out only the edges we're interested in from the full edge list. - target_edges = {} - to_visit = targets[:] - while to_visit: - src = to_visit.pop() - if src in target_edges: - continue - target_edges[src] = edges[src] - to_visit.extend(edges[src]) - - return target_edges - - -def WriteGraph(edges): - """Print a graphviz graph to stdout. - |edges| is a map of target to a list of other targets it depends on.""" - - # Bucket targets by file. - files = collections.defaultdict(list) - for src, dst in edges.items(): - build_file, target_name, toolset = ParseTarget(src) - files[build_file].append(src) - - print("digraph D {") - print(" fontsize=8") # Used by subgraphs. - print(" node [fontsize=8]") - - # Output nodes by file. We must first write out each node within - # its file grouping before writing out any edges that may refer - # to those nodes. - for filename, targets in files.items(): - if len(targets) == 1: - # If there's only one node for this file, simplify - # the display by making it a box without an internal node. - target = targets[0] - build_file, target_name, toolset = ParseTarget(target) - print( - f' "{target}" [shape=box, label="{filename}\\n{target_name}"]' - ) - else: - # Group multiple nodes together in a subgraph. - print(' subgraph "cluster_%s" {' % filename) - print(' label = "%s"' % filename) - for target in targets: - build_file, target_name, toolset = ParseTarget(target) - print(f' "{target}" [label="{target_name}"]') - print(" }") - - # Now that we've placed all the nodes within subgraphs, output all - # the edges between nodes. - for src, dsts in edges.items(): - for dst in dsts: - print(f' "{src}" -> "{dst}"') - - print("}") - - -def main(): - if len(sys.argv) < 2: - print(__doc__, file=sys.stderr) - print(file=sys.stderr) - print("usage: %s target1 target2..." % (sys.argv[0]), file=sys.stderr) - return 1 - - edges = LoadEdges("dump.json", sys.argv[1:]) - - WriteGraph(edges) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/tools/pretty_gyp.py b/node_modules/node-gyp/gyp/tools/pretty_gyp.py deleted file mode 100755 index 4ffa44455181c..0000000000000 --- a/node_modules/node-gyp/gyp/tools/pretty_gyp.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Pretty-prints the contents of a GYP file.""" - - -import sys -import re - - -# Regex to remove comments when we're counting braces. -COMMENT_RE = re.compile(r"\s*#.*") - -# Regex to remove quoted strings when we're counting braces. -# It takes into account quoted quotes, and makes sure that the quotes match. -# NOTE: It does not handle quotes that span more than one line, or -# cases where an escaped quote is preceded by an escaped backslash. -QUOTE_RE_STR = r'(?P<q>[\'"])(.*?)(?<![^\\][\\])(?P=q)' -QUOTE_RE = re.compile(QUOTE_RE_STR) - - -def comment_replace(matchobj): - return matchobj.group(1) + matchobj.group(2) + "#" * len(matchobj.group(3)) - - -def mask_comments(input): - """Mask the quoted strings so we skip braces inside quoted strings.""" - search_re = re.compile(r"(.*?)(#)(.*)") - return [search_re.sub(comment_replace, line) for line in input] - - -def quote_replace(matchobj): - return "{}{}{}{}".format( - matchobj.group(1), - matchobj.group(2), - "x" * len(matchobj.group(3)), - matchobj.group(2), - ) - - -def mask_quotes(input): - """Mask the quoted strings so we skip braces inside quoted strings.""" - search_re = re.compile(r"(.*?)" + QUOTE_RE_STR) - return [search_re.sub(quote_replace, line) for line in input] - - -def do_split(input, masked_input, search_re): - output = [] - mask_output = [] - for (line, masked_line) in zip(input, masked_input): - m = search_re.match(masked_line) - while m: - split = len(m.group(1)) - line = line[:split] + r"\n" + line[split:] - masked_line = masked_line[:split] + r"\n" + masked_line[split:] - m = search_re.match(masked_line) - output.extend(line.split(r"\n")) - mask_output.extend(masked_line.split(r"\n")) - return (output, mask_output) - - -def split_double_braces(input): - """Masks out the quotes and comments, and then splits appropriate - lines (lines that matche the double_*_brace re's above) before - indenting them below. - - These are used to split lines which have multiple braces on them, so - that the indentation looks prettier when all laid out (e.g. closing - braces make a nice diagonal line). - """ - double_open_brace_re = re.compile(r"(.*?[\[\{\(,])(\s*)([\[\{\(])") - double_close_brace_re = re.compile(r"(.*?[\]\}\)],?)(\s*)([\]\}\)])") - - masked_input = mask_quotes(input) - masked_input = mask_comments(masked_input) - - (output, mask_output) = do_split(input, masked_input, double_open_brace_re) - (output, mask_output) = do_split(output, mask_output, double_close_brace_re) - - return output - - -def count_braces(line): - """keeps track of the number of braces on a given line and returns the result. - - It starts at zero and subtracts for closed braces, and adds for open braces. - """ - open_braces = ["[", "(", "{"] - close_braces = ["]", ")", "}"] - closing_prefix_re = re.compile(r"(.*?[^\s\]\}\)]+.*?)([\]\}\)],?)\s*$") - cnt = 0 - stripline = COMMENT_RE.sub(r"", line) - stripline = QUOTE_RE.sub(r"''", stripline) - for char in stripline: - for brace in open_braces: - if char == brace: - cnt += 1 - for brace in close_braces: - if char == brace: - cnt -= 1 - - after = False - if cnt > 0: - after = True - - # This catches the special case of a closing brace having something - # other than just whitespace ahead of it -- we don't want to - # unindent that until after this line is printed so it stays with - # the previous indentation level. - if cnt < 0 and closing_prefix_re.match(stripline): - after = True - return (cnt, after) - - -def prettyprint_input(lines): - """Does the main work of indenting the input based on the brace counts.""" - indent = 0 - basic_offset = 2 - for line in lines: - if COMMENT_RE.match(line): - print(line) - else: - line = line.strip("\r\n\t ") # Otherwise doesn't strip \r on Unix. - if len(line) > 0: - (brace_diff, after) = count_braces(line) - if brace_diff != 0: - if after: - print(" " * (basic_offset * indent) + line) - indent += brace_diff - else: - indent += brace_diff - print(" " * (basic_offset * indent) + line) - else: - print(" " * (basic_offset * indent) + line) - else: - print("") - - -def main(): - if len(sys.argv) > 1: - data = open(sys.argv[1]).read().splitlines() - else: - data = sys.stdin.read().splitlines() - # Split up the double braces. - lines = split_double_braces(data) - - # Indent and print the output. - prettyprint_input(lines) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/tools/pretty_sln.py b/node_modules/node-gyp/gyp/tools/pretty_sln.py deleted file mode 100755 index 6ca0cd12a7ba0..0000000000000 --- a/node_modules/node-gyp/gyp/tools/pretty_sln.py +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Prints the information in a sln file in a diffable way. - - It first outputs each projects in alphabetical order with their - dependencies. - - Then it outputs a possible build order. -""" - - -import os -import re -import sys -import pretty_vcproj - -__author__ = "nsylvain (Nicolas Sylvain)" - - -def BuildProject(project, built, projects, deps): - # if all dependencies are done, we can build it, otherwise we try to build the - # dependency. - # This is not infinite-recursion proof. - for dep in deps[project]: - if dep not in built: - BuildProject(dep, built, projects, deps) - print(project) - built.append(project) - - -def ParseSolution(solution_file): - # All projects, their clsid and paths. - projects = dict() - - # A list of dependencies associated with a project. - dependencies = dict() - - # Regular expressions that matches the SLN format. - # The first line of a project definition. - begin_project = re.compile( - r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942' - r'}"\) = "(.*)", "(.*)", "(.*)"$' - ) - # The last line of a project definition. - end_project = re.compile("^EndProject$") - # The first line of a dependency list. - begin_dep = re.compile(r"ProjectSection\(ProjectDependencies\) = postProject$") - # The last line of a dependency list. - end_dep = re.compile("EndProjectSection$") - # A line describing a dependency. - dep_line = re.compile(" *({.*}) = ({.*})$") - - in_deps = False - solution = open(solution_file) - for line in solution: - results = begin_project.search(line) - if results: - # Hack to remove icu because the diff is too different. - if results.group(1).find("icu") != -1: - continue - # We remove "_gyp" from the names because it helps to diff them. - current_project = results.group(1).replace("_gyp", "") - projects[current_project] = [ - results.group(2).replace("_gyp", ""), - results.group(3), - results.group(2), - ] - dependencies[current_project] = [] - continue - - results = end_project.search(line) - if results: - current_project = None - continue - - results = begin_dep.search(line) - if results: - in_deps = True - continue - - results = end_dep.search(line) - if results: - in_deps = False - continue - - results = dep_line.search(line) - if results and in_deps and current_project: - dependencies[current_project].append(results.group(1)) - continue - - # Change all dependencies clsid to name instead. - for project in dependencies: - # For each dependencies in this project - new_dep_array = [] - for dep in dependencies[project]: - # Look for the project name matching this cldis - for project_info in projects: - if projects[project_info][1] == dep: - new_dep_array.append(project_info) - dependencies[project] = sorted(new_dep_array) - - return (projects, dependencies) - - -def PrintDependencies(projects, deps): - print("---------------------------------------") - print("Dependencies for all projects") - print("---------------------------------------") - print("-- --") - - for (project, dep_list) in sorted(deps.items()): - print("Project : %s" % project) - print("Path : %s" % projects[project][0]) - if dep_list: - for dep in dep_list: - print(" - %s" % dep) - print("") - - print("-- --") - - -def PrintBuildOrder(projects, deps): - print("---------------------------------------") - print("Build order ") - print("---------------------------------------") - print("-- --") - - built = [] - for (project, _) in sorted(deps.items()): - if project not in built: - BuildProject(project, built, projects, deps) - - print("-- --") - - -def PrintVCProj(projects): - - for project in projects: - print("-------------------------------------") - print("-------------------------------------") - print(project) - print(project) - print(project) - print("-------------------------------------") - print("-------------------------------------") - - project_path = os.path.abspath( - os.path.join(os.path.dirname(sys.argv[1]), projects[project][2]) - ) - - pretty = pretty_vcproj - argv = [ - "", - project_path, - "$(SolutionDir)=%s\\" % os.path.dirname(sys.argv[1]), - ] - argv.extend(sys.argv[3:]) - pretty.main(argv) - - -def main(): - # check if we have exactly 1 parameter. - if len(sys.argv) < 2: - print('Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0]) - return 1 - - (projects, deps) = ParseSolution(sys.argv[1]) - PrintDependencies(projects, deps) - PrintBuildOrder(projects, deps) - - if "--recursive" in sys.argv: - PrintVCProj(projects) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/tools/pretty_vcproj.py b/node_modules/node-gyp/gyp/tools/pretty_vcproj.py deleted file mode 100755 index 00d32debda51f..0000000000000 --- a/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2012 Google Inc. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Make the format of a vcproj really pretty. - - This script normalize and sort an xml. It also fetches all the properties - inside linked vsprops and include them explicitly in the vcproj. - - It outputs the resulting xml to stdout. -""" - - -import os -import sys - -from xml.dom.minidom import parse -from xml.dom.minidom import Node - -__author__ = "nsylvain (Nicolas Sylvain)" -ARGUMENTS = None -REPLACEMENTS = dict() - - -def cmp(x, y): - return (x > y) - (x < y) - - -class CmpTuple: - """Compare function between 2 tuple.""" - - def __call__(self, x, y): - return cmp(x[0], y[0]) - - -class CmpNode: - """Compare function between 2 xml nodes.""" - - def __call__(self, x, y): - def get_string(node): - node_string = "node" - node_string += node.nodeName - if node.nodeValue: - node_string += node.nodeValue - - if node.attributes: - # We first sort by name, if present. - node_string += node.getAttribute("Name") - - all_nodes = [] - for (name, value) in node.attributes.items(): - all_nodes.append((name, value)) - - all_nodes.sort(CmpTuple()) - for (name, value) in all_nodes: - node_string += name - node_string += value - - return node_string - - return cmp(get_string(x), get_string(y)) - - -def PrettyPrintNode(node, indent=0): - if node.nodeType == Node.TEXT_NODE: - if node.data.strip(): - print("{}{}".format(" " * indent, node.data.strip())) - return - - if node.childNodes: - node.normalize() - # Get the number of attributes - attr_count = 0 - if node.attributes: - attr_count = node.attributes.length - - # Print the main tag - if attr_count == 0: - print("{}<{}>".format(" " * indent, node.nodeName)) - else: - print("{}<{}".format(" " * indent, node.nodeName)) - - all_attributes = [] - for (name, value) in node.attributes.items(): - all_attributes.append((name, value)) - all_attributes.sort(CmpTuple()) - for (name, value) in all_attributes: - print('{} {}="{}"'.format(" " * indent, name, value)) - print("%s>" % (" " * indent)) - if node.nodeValue: - print("{} {}".format(" " * indent, node.nodeValue)) - - for sub_node in node.childNodes: - PrettyPrintNode(sub_node, indent=indent + 2) - print("{}</{}>".format(" " * indent, node.nodeName)) - - -def FlattenFilter(node): - """Returns a list of all the node and sub nodes.""" - node_list = [] - - if node.attributes and node.getAttribute("Name") == "_excluded_files": - # We don't add the "_excluded_files" filter. - return [] - - for current in node.childNodes: - if current.nodeName == "Filter": - node_list.extend(FlattenFilter(current)) - else: - node_list.append(current) - - return node_list - - -def FixFilenames(filenames, current_directory): - new_list = [] - for filename in filenames: - if filename: - for key in REPLACEMENTS: - filename = filename.replace(key, REPLACEMENTS[key]) - os.chdir(current_directory) - filename = filename.strip("\"' ") - if filename.startswith("$"): - new_list.append(filename) - else: - new_list.append(os.path.abspath(filename)) - return new_list - - -def AbsoluteNode(node): - """Makes all the properties we know about in this node absolute.""" - if node.attributes: - for (name, value) in node.attributes.items(): - if name in [ - "InheritedPropertySheets", - "RelativePath", - "AdditionalIncludeDirectories", - "IntermediateDirectory", - "OutputDirectory", - "AdditionalLibraryDirectories", - ]: - # We want to fix up these paths - path_list = value.split(";") - new_list = FixFilenames(path_list, os.path.dirname(ARGUMENTS[1])) - node.setAttribute(name, ";".join(new_list)) - if not value: - node.removeAttribute(name) - - -def CleanupVcproj(node): - """For each sub node, we call recursively this function.""" - for sub_node in node.childNodes: - AbsoluteNode(sub_node) - CleanupVcproj(sub_node) - - # Normalize the node, and remove all extraneous whitespaces. - for sub_node in node.childNodes: - if sub_node.nodeType == Node.TEXT_NODE: - sub_node.data = sub_node.data.replace("\r", "") - sub_node.data = sub_node.data.replace("\n", "") - sub_node.data = sub_node.data.rstrip() - - # Fix all the semicolon separated attributes to be sorted, and we also - # remove the dups. - if node.attributes: - for (name, value) in node.attributes.items(): - sorted_list = sorted(value.split(";")) - unique_list = [] - for i in sorted_list: - if not unique_list.count(i): - unique_list.append(i) - node.setAttribute(name, ";".join(unique_list)) - if not value: - node.removeAttribute(name) - - if node.childNodes: - node.normalize() - - # For each node, take a copy, and remove it from the list. - node_array = [] - while node.childNodes and node.childNodes[0]: - # Take a copy of the node and remove it from the list. - current = node.childNodes[0] - node.removeChild(current) - - # If the child is a filter, we want to append all its children - # to this same list. - if current.nodeName == "Filter": - node_array.extend(FlattenFilter(current)) - else: - node_array.append(current) - - # Sort the list. - node_array.sort(CmpNode()) - - # Insert the nodes in the correct order. - for new_node in node_array: - # But don't append empty tool node. - if new_node.nodeName == "Tool": - if new_node.attributes and new_node.attributes.length == 1: - # This one was empty. - continue - if new_node.nodeName == "UserMacro": - continue - node.appendChild(new_node) - - -def GetConfiguationNodes(vcproj): - # TODO(nsylvain): Find a better way to navigate the xml. - nodes = [] - for node in vcproj.childNodes: - if node.nodeName == "Configurations": - for sub_node in node.childNodes: - if sub_node.nodeName == "Configuration": - nodes.append(sub_node) - - return nodes - - -def GetChildrenVsprops(filename): - dom = parse(filename) - if dom.documentElement.attributes: - vsprops = dom.documentElement.getAttribute("InheritedPropertySheets") - return FixFilenames(vsprops.split(";"), os.path.dirname(filename)) - return [] - - -def SeekToNode(node1, child2): - # A text node does not have properties. - if child2.nodeType == Node.TEXT_NODE: - return None - - # Get the name of the current node. - current_name = child2.getAttribute("Name") - if not current_name: - # There is no name. We don't know how to merge. - return None - - # Look through all the nodes to find a match. - for sub_node in node1.childNodes: - if sub_node.nodeName == child2.nodeName: - name = sub_node.getAttribute("Name") - if name == current_name: - return sub_node - - # No match. We give up. - return None - - -def MergeAttributes(node1, node2): - # No attributes to merge? - if not node2.attributes: - return - - for (name, value2) in node2.attributes.items(): - # Don't merge the 'Name' attribute. - if name == "Name": - continue - value1 = node1.getAttribute(name) - if value1: - # The attribute exist in the main node. If it's equal, we leave it - # untouched, otherwise we concatenate it. - if value1 != value2: - node1.setAttribute(name, ";".join([value1, value2])) - else: - # The attribute does not exist in the main node. We append this one. - node1.setAttribute(name, value2) - - # If the attribute was a property sheet attributes, we remove it, since - # they are useless. - if name == "InheritedPropertySheets": - node1.removeAttribute(name) - - -def MergeProperties(node1, node2): - MergeAttributes(node1, node2) - for child2 in node2.childNodes: - child1 = SeekToNode(node1, child2) - if child1: - MergeProperties(child1, child2) - else: - node1.appendChild(child2.cloneNode(True)) - - -def main(argv): - """Main function of this vcproj prettifier.""" - global ARGUMENTS - ARGUMENTS = argv - - # check if we have exactly 1 parameter. - if len(argv) < 2: - print( - 'Usage: %s "c:\\path\\to\\vcproj.vcproj" [key1=value1] ' - "[key2=value2]" % argv[0] - ) - return 1 - - # Parse the keys - for i in range(2, len(argv)): - (key, value) = argv[i].split("=") - REPLACEMENTS[key] = value - - # Open the vcproj and parse the xml. - dom = parse(argv[1]) - - # First thing we need to do is find the Configuration Node and merge them - # with the vsprops they include. - for configuration_node in GetConfiguationNodes(dom.documentElement): - # Get the property sheets associated with this configuration. - vsprops = configuration_node.getAttribute("InheritedPropertySheets") - - # Fix the filenames to be absolute. - vsprops_list = FixFilenames( - vsprops.strip().split(";"), os.path.dirname(argv[1]) - ) - - # Extend the list of vsprops with all vsprops contained in the current - # vsprops. - for current_vsprops in vsprops_list: - vsprops_list.extend(GetChildrenVsprops(current_vsprops)) - - # Now that we have all the vsprops, we need to merge them. - for current_vsprops in vsprops_list: - MergeProperties(configuration_node, parse(current_vsprops).documentElement) - - # Now that everything is merged, we need to cleanup the xml. - CleanupVcproj(dom.documentElement) - - # Finally, we use the prett xml function to print the vcproj back to the - # user. - # print dom.toprettyxml(newl="\n") - PrettyPrintNode(dom.documentElement) - return 0 - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/node_modules/node-gyp/lib/build.js b/node_modules/node-gyp/lib/build.js index c2388fb348cc5..00a0abe691adc 100644 --- a/node_modules/node-gyp/lib/build.js +++ b/node_modules/node-gyp/lib/build.js @@ -1,16 +1,19 @@ 'use strict' -const fs = require('graceful-fs') +const gracefulFs = require('graceful-fs') +const fs = gracefulFs.promises const path = require('path') -const glob = require('glob') -const log = require('npmlog') +const { glob } = require('tinyglobby') +const log = require('./log') const which = require('which') const win = process.platform === 'win32' -function build (gyp, argv, callback) { - var platformMake = 'make' +async function build (gyp, argv) { + let platformMake = 'make' if (process.platform === 'aix') { platformMake = 'gmake' + } else if (process.platform === 'os400') { + platformMake = 'gmake' } else if (process.platform.indexOf('bsd') !== -1) { platformMake = 'gmake' } else if (win && argv.length > 0) { @@ -19,143 +22,148 @@ function build (gyp, argv, callback) { }) } - var makeCommand = gyp.opts.make || process.env.MAKE || platformMake - var command = win ? 'msbuild' : makeCommand - var jobs = gyp.opts.jobs || process.env.JOBS - var buildType - var config - var arch - var nodeDir - var guessedSolution + const makeCommand = gyp.opts.make || process.env.MAKE || platformMake + let command = win ? 'msbuild' : makeCommand + const jobs = gyp.opts.jobs || process.env.JOBS + let buildType + let config + let arch + let nodeDir + let guessedSolution + let python + let buildBinsDir - loadConfigGypi() + await loadConfigGypi() /** * Load the "config.gypi" file that was generated during "configure". */ - function loadConfigGypi () { - var configPath = path.resolve('build', 'config.gypi') - - fs.readFile(configPath, 'utf8', function (err, data) { - if (err) { - if (err.code === 'ENOENT') { - callback(new Error('You must run `node-gyp configure` first!')) - } else { - callback(err) - } - return + async function loadConfigGypi () { + let data + try { + const configPath = path.resolve('build', 'config.gypi') + data = await fs.readFile(configPath, 'utf8') + } catch (err) { + if (err.code === 'ENOENT') { + throw new Error('You must run `node-gyp configure` first!') + } else { + throw err } - config = JSON.parse(data.replace(/#.+\n/, '')) + } - // get the 'arch', 'buildType', and 'nodeDir' vars from the config - buildType = config.target_defaults.default_configuration - arch = config.variables.target_arch - nodeDir = config.variables.nodedir + config = JSON.parse(data.replace(/#.+\n/, '')) - if ('debug' in gyp.opts) { - buildType = gyp.opts.debug ? 'Debug' : 'Release' - } - if (!buildType) { - buildType = 'Release' - } + // get the 'arch', 'buildType', and 'nodeDir' vars from the config + buildType = config.target_defaults.default_configuration + arch = config.variables.target_arch + nodeDir = config.variables.nodedir + python = config.variables.python + + if ('debug' in gyp.opts) { + buildType = gyp.opts.debug ? 'Debug' : 'Release' + } + if (!buildType) { + buildType = 'Release' + } - log.verbose('build type', buildType) - log.verbose('architecture', arch) - log.verbose('node dev dir', nodeDir) + log.verbose('build type', buildType) + log.verbose('architecture', arch) + log.verbose('node dev dir', nodeDir) + log.verbose('python', python) - if (win) { - findSolutionFile() - } else { - doWhich() - } - }) + if (win) { + await findSolutionFile() + } else { + await doWhich() + } } /** * On Windows, find the first build/*.sln file. */ - function findSolutionFile () { - glob('build/*.sln', function (err, files) { - if (err) { - return callback(err) - } - if (files.length === 0) { - return callback(new Error('Could not find *.sln file. Did you run "configure"?')) + async function findSolutionFile () { + const files = await glob('build/*.sln', { expandDirectories: false }) + if (files.length === 0) { + if (gracefulFs.existsSync('build/Makefile') || + (await glob('build/*.mk', { expandDirectories: false })).length !== 0) { + command = makeCommand + await doWhich(false) + return + } else { + throw new Error('Could not find *.sln file or Makefile. Did you run "configure"?') } - guessedSolution = files[0] - log.verbose('found first Solution file', guessedSolution) - doWhich() - }) + } + guessedSolution = files[0] + log.verbose('found first Solution file', guessedSolution) + await doWhich(true) } /** * Uses node-which to locate the msbuild / make executable. */ - function doWhich () { + async function doWhich (msvs) { // On Windows use msbuild provided by node-gyp configure - if (win) { + if (msvs) { if (!config.variables.msbuild_path) { - return callback(new Error( - 'MSBuild is not set, please run `node-gyp configure`.')) + throw new Error('MSBuild is not set, please run `node-gyp configure`.') } command = config.variables.msbuild_path log.verbose('using MSBuild:', command) - doBuild() + await doBuild(msvs) return } + // First make sure we have the build command in the PATH - which(command, function (err, execPath) { - if (err) { - // Some other error or 'make' not found on Unix, report that to the user - callback(err) - return - } - log.verbose('`which` succeeded for `' + command + '`', execPath) - doBuild() - }) + const execPath = await which(command) + log.verbose('`which` succeeded for `' + command + '`', execPath) + await doBuild(msvs) } /** * Actually spawn the process and compile the module. */ - function doBuild () { + async function doBuild (msvs) { // Enable Verbose build - var verbose = log.levels[log.level] <= log.levels.verbose - var j + const verbose = log.logger.isVisible('verbose') + let j - if (!win && verbose) { + if (!msvs && verbose) { argv.push('V=1') } - if (win && !verbose) { + if (msvs && !verbose) { argv.push('/clp:Verbosity=minimal') } - if (win) { + if (msvs) { // Turn off the Microsoft logo on Windows argv.push('/nologo') + // No lingering msbuild processes and open file handles + argv.push('/nodeReuse:false') } // Specify the build type, Release by default - if (win) { + if (msvs) { // Convert .gypi config target_arch to MSBuild /Platform // Since there are many ways to state '32-bit Intel', default to it. // N.B. msbuild's Condition string equality tests are case-insensitive. - var archLower = arch.toLowerCase() - var p = archLower === 'x64' ? 'x64' - : (archLower === 'arm' ? 'ARM' - : (archLower === 'arm64' ? 'ARM64' : 'Win32')) + const archLower = arch.toLowerCase() + const p = archLower === 'x64' + ? 'x64' + : (archLower === 'arm' + ? 'ARM' + : (archLower === 'arm64' ? 'ARM64' : 'Win32')) argv.push('/p:Configuration=' + buildType + ';Platform=' + p) if (jobs) { j = parseInt(jobs, 10) if (!isNaN(j) && j > 0) { argv.push('/m:' + j) } else if (jobs.toUpperCase() === 'MAX') { - argv.push('/m:' + require('os').cpus().length) + argv.push('/m:' + require('os').availableParallelism()) } } } else { @@ -170,14 +178,14 @@ function build (gyp, argv, callback) { argv.push(j) } else if (jobs.toUpperCase() === 'MAX') { argv.push('--jobs') - argv.push(require('os').cpus().length) + argv.push(require('os').availableParallelism()) } } } - if (win) { + if (msvs) { // did the user specify their own .sln file? - var hasSln = argv.some(function (arg) { + const hasSln = argv.some(function (arg) { return path.extname(arg) === '.sln' }) if (!hasSln) { @@ -185,18 +193,36 @@ function build (gyp, argv, callback) { } } - var proc = gyp.spawn(command, argv) - proc.on('exit', onExit) - } - - function onExit (code, signal) { - if (code !== 0) { - return callback(new Error('`' + command + '` failed with exit code: ' + code)) - } - if (signal) { - return callback(new Error('`' + command + '` got signal: ' + signal)) + if (!win) { + // Add build-time dependency symlinks (such as Python) to PATH + buildBinsDir = path.resolve('build', 'node_gyp_bins') + process.env.PATH = `${buildBinsDir}:${process.env.PATH}` + await fs.mkdir(buildBinsDir, { recursive: true }) + const symlinkDestination = path.join(buildBinsDir, 'python3') + try { + await fs.unlink(symlinkDestination) + } catch (err) { + if (err.code !== 'ENOENT') throw err + } + await fs.symlink(python, symlinkDestination) + log.verbose('bin symlinks', `created symlink to "${python}" in "${buildBinsDir}" and added to PATH`) } - callback() + + const proc = gyp.spawn(command, argv) + await new Promise((resolve, reject) => proc.on('exit', async (code, signal) => { + if (buildBinsDir) { + // Clean up the build-time dependency symlinks: + await fs.rm(buildBinsDir, { recursive: true, maxRetries: 3 }) + } + + if (code !== 0) { + return reject(new Error('`' + command + '` failed with exit code: ' + code)) + } + if (signal) { + return reject(new Error('`' + command + '` got signal: ' + signal)) + } + resolve() + })) } } diff --git a/node_modules/node-gyp/lib/clean.js b/node_modules/node-gyp/lib/clean.js index dbfa4dbb99d3c..479c374f10fa2 100644 --- a/node_modules/node-gyp/lib/clean.js +++ b/node_modules/node-gyp/lib/clean.js @@ -1,14 +1,14 @@ 'use strict' -const rm = require('rimraf') -const log = require('npmlog') +const fs = require('graceful-fs').promises +const log = require('./log') -function clean (gyp, argv, callback) { +async function clean (gyp, argv) { // Remove the 'build' dir - var buildDir = 'build' + const buildDir = 'build' log.verbose('clean', 'removing "%s" directory', buildDir) - rm(buildDir, callback) + await fs.rm(buildDir, { recursive: true, force: true, maxRetries: 3 }) } module.exports = clean diff --git a/node_modules/node-gyp/lib/configure.js b/node_modules/node-gyp/lib/configure.js index 17a6487fa9caf..ee672cfbf26c2 100644 --- a/node_modules/node-gyp/lib/configure.js +++ b/node_modules/node-gyp/lib/configure.js @@ -1,46 +1,62 @@ 'use strict' -const fs = require('graceful-fs') +const { promises: fs, readFileSync } = require('graceful-fs') const path = require('path') -const log = require('npmlog') +const log = require('./log') const os = require('os') const processRelease = require('./process-release') const win = process.platform === 'win32' const findNodeDirectory = require('./find-node-directory') -const createConfigGypi = require('./create-config-gypi') -const msgFormat = require('util').format -var findPython = require('./find-python') -if (win) { - var findVisualStudio = require('./find-visualstudio') -} - -function configure (gyp, argv, callback) { - var python - var buildDir = path.resolve('build') - var configNames = ['config.gypi', 'common.gypi'] - var configs = [] - var nodeDir - var release = processRelease(argv, gyp, process.version, process.release) - - findPython(gyp.opts.python, function (err, found) { - if (err) { - callback(err) - } else { - python = found - getNodeDir() - } - }) - - function getNodeDir () { +const { createConfigGypi } = require('./create-config-gypi') +const { format: msgFormat } = require('util') +const { findAccessibleSync } = require('./util') +const { findPython } = require('./find-python') +const { findVisualStudio } = win ? require('./find-visualstudio') : {} + +const majorRe = /^#define NODE_MAJOR_VERSION (\d+)/m +const minorRe = /^#define NODE_MINOR_VERSION (\d+)/m +const patchRe = /^#define NODE_PATCH_VERSION (\d+)/m + +async function configure (gyp, argv) { + const buildDir = path.resolve('build') + const configNames = ['config.gypi', 'common.gypi'] + const configs = [] + let nodeDir + const release = processRelease(argv, gyp, process.version, process.release) + + const python = await findPython(gyp.opts.python) + return getNodeDir() + + async function getNodeDir () { // 'python' should be set by now process.env.PYTHON = python + if (!gyp.opts.nodedir && + process.config.variables.use_prefix_to_find_headers) { + // check if the headers can be found using the prefix specified + // at build time. Use them if they match the version expected + const prefix = process.config.variables.node_prefix + let availVersion + try { + const nodeVersionH = readFileSync(path.join(prefix, + 'include', 'node', 'node_version.h'), { encoding: 'utf8' }) + const major = nodeVersionH.match(majorRe)[1] + const minor = nodeVersionH.match(minorRe)[1] + const patch = nodeVersionH.match(patchRe)[1] + availVersion = major + '.' + minor + '.' + patch + } catch {} + if (availVersion === release.version) { + // ok version matches, use the headers + gyp.opts.nodedir = prefix + log.verbose('using local node headers based on prefix', + 'setting nodedir to ' + gyp.opts.nodedir) + } + } + if (gyp.opts.nodedir) { // --nodedir was specified. use that for the dev files nodeDir = gyp.opts.nodedir.replace(/^~/, os.homedir()) - log.verbose('get node dir', 'compiling against specified --nodedir dev files: %s', nodeDir) - createBuildDir() } else { // if no --nodedir specified, ensure node dependencies are installed if ('v' + release.version !== process.version) { @@ -53,86 +69,86 @@ function configure (gyp, argv, callback) { if (!release.semver) { // could not parse the version string with semver - return callback(new Error('Invalid version number: ' + release.version)) + throw new Error('Invalid version number: ' + release.version) } // If the tarball option is set, always remove and reinstall the headers // into devdir. Otherwise only install if they're not already there. gyp.opts.ensure = !gyp.opts.tarball - gyp.commands.install([release.version], function (err) { - if (err) { - return callback(err) - } - log.verbose('get node dir', 'target node version installed:', release.versionDir) - nodeDir = path.resolve(gyp.devDir, release.versionDir) - createBuildDir() - }) + await gyp.commands.install([release.version]) + + log.verbose('get node dir', 'target node version installed:', release.versionDir) + nodeDir = path.resolve(gyp.devDir, release.versionDir) } + + return createBuildDir() } - function createBuildDir () { + async function createBuildDir () { log.verbose('build dir', 'attempting to create "build" dir: %s', buildDir) - fs.mkdir(buildDir, { recursive: true }, function (err, isNew) { - if (err) { - return callback(err) + + const isNew = await fs.mkdir(buildDir, { recursive: true }) + log.verbose( + 'build dir', '"build" dir needed to be created?', isNew ? 'Yes' : 'No' + ) + if (win) { + let usingMakeGenerator = false + for (let i = argv.length - 1; i >= 0; --i) { + const arg = argv[i] + if (arg === '-f' || arg === '--format') { + const format = argv[i + 1] + if (typeof format === 'string' && format.startsWith('make')) { + usingMakeGenerator = true + break + } + } else if (arg.startsWith('--format=make')) { + usingMakeGenerator = true + break + } } - log.verbose( - 'build dir', '"build" dir needed to be created?', isNew ? 'Yes' : 'No' - ) - if (win) { - findVisualStudio(release.semver, gyp.opts.msvs_version, - createConfigFile) - } else { - createConfigFile() + let vsInfo = {} + if (!usingMakeGenerator) { + vsInfo = await findVisualStudio(release.semver, gyp.opts['msvs-version']) } - }) + return createConfigFile(vsInfo) + } + return createConfigFile(null) } - function createConfigFile (err, vsInfo) { - if (err) { - return callback(err) - } - if (process.platform === 'win32') { + async function createConfigFile (vsInfo) { + if (win) { process.env.GYP_MSVS_VERSION = Math.min(vsInfo.versionYear, 2015) process.env.GYP_MSVS_OVERRIDE_PATH = vsInfo.path } - createConfigGypi({ gyp, buildDir, nodeDir, vsInfo }).then(configPath => { - configs.push(configPath) - findConfigs() - }).catch(err => { - callback(err) - }) + const configPath = await createConfigGypi({ gyp, buildDir, nodeDir, vsInfo, python }) + configs.push(configPath) + return findConfigs() } - function findConfigs () { - var name = configNames.shift() + async function findConfigs () { + const name = configNames.shift() if (!name) { return runGyp() } - var fullPath = path.resolve(name) + const fullPath = path.resolve(name) log.verbose(name, 'checking for gypi file: %s', fullPath) - fs.stat(fullPath, function (err) { - if (err) { - if (err.code === 'ENOENT') { - findConfigs() // check next gypi filename - } else { - callback(err) - } - } else { - log.verbose(name, 'found gypi file') - configs.push(fullPath) - findConfigs() + try { + await fs.stat(fullPath) + log.verbose(name, 'found gypi file') + configs.push(fullPath) + } catch (err) { + // ENOENT will check next gypi filename + if (err.code !== 'ENOENT') { + throw err } - }) - } - - function runGyp (err) { - if (err) { - return callback(err) } + return findConfigs() + } + + async function runGyp () { if (!~argv.indexOf('-f') && !~argv.indexOf('--format')) { if (win) { log.verbose('gyp', 'gyp format was not specified; forcing "msvs"') @@ -152,13 +168,15 @@ function configure (gyp, argv, callback) { // For AIX and z/OS we need to set up the path to the exports file // which contains the symbols needed for linking. - var nodeExpFile - if (process.platform === 'aix' || process.platform === 'os390') { - var ext = process.platform === 'aix' ? 'exp' : 'x' - var nodeRootDir = findNodeDirectory() - var candidates - - if (process.platform === 'aix') { + let nodeExpFile + let nodeRootDir + let candidates + let logprefix = 'find exports file' + if (process.platform === 'aix' || process.platform === 'os390' || process.platform === 'os400') { + const ext = process.platform === 'os390' ? 'x' : 'exp' + nodeRootDir = findNodeDirectory() + + if (process.platform === 'aix' || process.platform === 'os400') { candidates = [ 'include/node/node', 'out/Release/node', @@ -179,118 +197,132 @@ function configure (gyp, argv, callback) { }) } - var logprefix = 'find exports file' nodeExpFile = findAccessibleSync(logprefix, nodeRootDir, candidates) if (nodeExpFile !== undefined) { log.verbose(logprefix, 'Found exports file: %s', nodeExpFile) } else { - var msg = msgFormat('Could not find node.%s file in %s', ext, nodeRootDir) + const msg = msgFormat('Could not find node.%s file in %s', ext, nodeRootDir) log.error(logprefix, 'Could not find exports file') - return callback(new Error(msg)) + throw new Error(msg) } } - // this logic ported from the old `gyp_addon` python file - var gypScript = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py') - var addonGypi = path.resolve(__dirname, '..', 'addon.gypi') - var commonGypi = path.resolve(nodeDir, 'include/node/common.gypi') - fs.stat(commonGypi, function (err) { - if (err) { - commonGypi = path.resolve(nodeDir, 'common.gypi') - } - - var outputDir = 'build' - if (win) { - // Windows expects an absolute path - outputDir = buildDir + // For z/OS we need to set up the path to zoslib include directory, + // which contains headers included in v8config.h. + let zoslibIncDir + if (process.platform === 'os390') { + logprefix = "find zoslib's zos-base.h:" + let msg + let zoslibIncPath = process.env.ZOSLIB_INCLUDES + if (zoslibIncPath) { + zoslibIncPath = findAccessibleSync(logprefix, zoslibIncPath, ['zos-base.h']) + if (zoslibIncPath === undefined) { + msg = msgFormat('Could not find zos-base.h file in the directory set ' + + 'in ZOSLIB_INCLUDES environment variable: %s; set it ' + + 'to the correct path, or unset it to search %s', process.env.ZOSLIB_INCLUDES, nodeRootDir) + } + } else { + candidates = [ + 'include/node/zoslib/zos-base.h', + 'include/zoslib/zos-base.h', + 'zoslib/include/zos-base.h', + 'install/include/node/zoslib/zos-base.h' + ] + zoslibIncPath = findAccessibleSync(logprefix, nodeRootDir, candidates) + if (zoslibIncPath === undefined) { + msg = msgFormat('Could not find any of %s in directory %s; set ' + + 'environmant variable ZOSLIB_INCLUDES to the path ' + + 'that contains zos-base.h', candidates.toString(), nodeRootDir) + } } - var nodeGypDir = path.resolve(__dirname, '..') - - var nodeLibFile = path.join(nodeDir, - !gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)', - release.name + '.lib') - - argv.push('-I', addonGypi) - argv.push('-I', commonGypi) - argv.push('-Dlibrary=shared_library') - argv.push('-Dvisibility=default') - argv.push('-Dnode_root_dir=' + nodeDir) - if (process.platform === 'aix' || process.platform === 'os390') { - argv.push('-Dnode_exp_file=' + nodeExpFile) + if (zoslibIncPath !== undefined) { + zoslibIncDir = path.dirname(zoslibIncPath) + log.verbose(logprefix, "Found zoslib's zos-base.h in: %s", zoslibIncDir) + } else if (release.version.split('.')[0] >= 16) { + // zoslib is only shipped in Node v16 and above. + log.error(logprefix, msg) + throw new Error(msg) } - argv.push('-Dnode_gyp_dir=' + nodeGypDir) + } - // Do this to keep Cygwin environments happy, else the unescaped '\' gets eaten up, - // resulting in bad paths, Ex c:parentFolderfolderanotherFolder instead of c:\parentFolder\folder\anotherFolder - if (win) { - nodeLibFile = nodeLibFile.replace(/\\/g, '\\\\') - } - argv.push('-Dnode_lib_file=' + nodeLibFile) - argv.push('-Dmodule_root_dir=' + process.cwd()) - argv.push('-Dnode_engine=' + - (gyp.opts.node_engine || process.jsEngine || 'v8')) - argv.push('--depth=.') - argv.push('--no-parallel') + // this logic ported from the old `gyp_addon` python file + const gypScript = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py') + const addonGypi = path.resolve(__dirname, '..', 'addon.gypi') + let commonGypi = path.resolve(nodeDir, 'include/node/common.gypi') + try { + await fs.stat(commonGypi) + } catch (err) { + commonGypi = path.resolve(nodeDir, 'common.gypi') + } - // tell gyp to write the Makefile/Solution files into output_dir - argv.push('--generator-output', outputDir) + let outputDir = 'build' + if (win) { + // Windows expects an absolute path + outputDir = buildDir + } + const nodeGypDir = path.resolve(__dirname, '..') + + let nodeLibFile = path.join(nodeDir, + !gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)', + release.name + '.lib') + + argv.push('-I', addonGypi) + argv.push('-I', commonGypi) + argv.push('-Dlibrary=shared_library') + argv.push('-Dvisibility=default') + argv.push('-Dnode_root_dir=' + nodeDir) + if (process.platform === 'aix' || process.platform === 'os390' || process.platform === 'os400') { + argv.push('-Dnode_exp_file=' + nodeExpFile) + if (process.platform === 'os390' && zoslibIncDir) { + argv.push('-Dzoslib_include_dir=' + zoslibIncDir) + } + } + argv.push('-Dnode_gyp_dir=' + nodeGypDir) - // tell make to write its output into the same dir - argv.push('-Goutput_dir=.') + // Do this to keep Cygwin environments happy, else the unescaped '\' gets eaten up, + // resulting in bad paths, Ex c:parentFolderfolderanotherFolder instead of c:\parentFolder\folder\anotherFolder + if (win) { + nodeLibFile = nodeLibFile.replace(/\\/g, '\\\\') + } + argv.push('-Dnode_lib_file=' + nodeLibFile) + argv.push('-Dmodule_root_dir=' + process.cwd()) + argv.push('-Dnode_engine=' + + (gyp.opts.node_engine || process.jsEngine || 'v8')) + argv.push('--depth=.') + argv.push('--no-parallel') - // enforce use of the "binding.gyp" file - argv.unshift('binding.gyp') + // tell gyp to write the Makefile/Solution files into output_dir + argv.push('--generator-output', outputDir) - // execute `gyp` from the current target nodedir - argv.unshift(gypScript) + // tell make to write its output into the same dir + argv.push('-Goutput_dir=.') - // make sure python uses files that came with this particular node package - var pypath = [path.join(__dirname, '..', 'gyp', 'pylib')] - if (process.env.PYTHONPATH) { - pypath.push(process.env.PYTHONPATH) - } - process.env.PYTHONPATH = pypath.join(win ? ';' : ':') + // enforce use of the "binding.gyp" file + argv.unshift('binding.gyp') - var cp = gyp.spawn(python, argv) - cp.on('exit', onCpExit) - }) - } + // execute `gyp` from the current target nodedir + argv.unshift(gypScript) - function onCpExit (code) { - if (code !== 0) { - callback(new Error('`gyp` failed with exit code: ' + code)) - } else { - // we're done - callback() + // make sure python uses files that came with this particular node package + const pypath = [path.join(__dirname, '..', 'gyp', 'pylib')] + if (process.env.PYTHONPATH) { + pypath.push(process.env.PYTHONPATH) } - } -} + process.env.PYTHONPATH = pypath.join(win ? ';' : ':') -/** - * Returns the first file or directory from an array of candidates that is - * readable by the current user, or undefined if none of the candidates are - * readable. - */ -function findAccessibleSync (logprefix, dir, candidates) { - for (var next = 0; next < candidates.length; next++) { - var candidate = path.resolve(dir, candidates[next]) - try { - var fd = fs.openSync(candidate, 'r') - } catch (e) { - // this candidate was not found or not readable, do nothing - log.silly(logprefix, 'Could not open %s: %s', candidate, e.message) - continue - } - fs.closeSync(fd) - log.silly(logprefix, 'Found readable %s', candidate) - return candidate + await new Promise((resolve, reject) => { + const cp = gyp.spawn(python, argv) + cp.on('exit', (code) => { + if (code !== 0) { + reject(new Error('`gyp` failed with exit code: ' + code)) + } else { + // we're done + resolve() + } + }) + }) } - - return undefined } module.exports = configure -module.exports.test = { - findAccessibleSync: findAccessibleSync -} module.exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module' diff --git a/node_modules/node-gyp/lib/create-config-gypi.js b/node_modules/node-gyp/lib/create-config-gypi.js index ced4911502733..01a820e9f2f31 100644 --- a/node_modules/node-gyp/lib/create-config-gypi.js +++ b/node_modules/node-gyp/lib/create-config-gypi.js @@ -1,7 +1,7 @@ 'use strict' -const fs = require('graceful-fs') -const log = require('npmlog') +const fs = require('graceful-fs').promises +const log = require('./log') const path = require('path') function parseConfigGypi (config) { @@ -24,7 +24,7 @@ async function getBaseConfigGypi ({ gyp, nodeDir }) { if (shouldReadConfigGypi && nodeDir) { try { const baseConfigGypiPath = path.resolve(nodeDir, 'include/node/config.gypi') - const baseConfigGypi = await fs.promises.readFile(baseConfigGypiPath) + const baseConfigGypi = await fs.readFile(baseConfigGypiPath) return parseConfigGypi(baseConfigGypi.toString()) } catch (err) { log.warn('read config.gypi', err.message) @@ -35,7 +35,7 @@ async function getBaseConfigGypi ({ gyp, nodeDir }) { return JSON.parse(JSON.stringify(process.config)) } -async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo }) { +async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo, python }) { const config = await getBaseConfigGypi({ gyp, nodeDir }) if (!config.target_defaults) { config.target_defaults = {} @@ -75,6 +75,9 @@ async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo }) { // set the node development directory variables.nodedir = nodeDir + // set the configured Python path + variables.python = python + // disable -T "thin" static archives by default variables.standalone_static_library = gyp.opts.thin ? 0 : 1 @@ -93,6 +96,9 @@ async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo }) { } } variables.msbuild_path = vsInfo.msBuild + if (config.variables.clang === 1) { + config.variables.clang = 0 + } } // loop through the rest of the opts and add the unknown ones as variables. @@ -112,13 +118,13 @@ async function getCurrentConfigGypi ({ gyp, nodeDir, vsInfo }) { return config } -async function createConfigGypi ({ gyp, buildDir, nodeDir, vsInfo }) { +async function createConfigGypi ({ gyp, buildDir, nodeDir, vsInfo, python }) { const configFilename = 'config.gypi' const configPath = path.resolve(buildDir, configFilename) log.verbose('build/' + configFilename, 'creating config file') - const config = await getCurrentConfigGypi({ gyp, nodeDir, vsInfo }) + const config = await getCurrentConfigGypi({ gyp, nodeDir, vsInfo, python }) // ensures that any boolean values in config.gypi get stringified function boolsToString (k, v) { @@ -135,13 +141,13 @@ async function createConfigGypi ({ gyp, buildDir, nodeDir, vsInfo }) { const json = JSON.stringify(config, boolsToString, 2) log.verbose('build/' + configFilename, 'writing out config file: %s', configPath) - await fs.promises.writeFile(configPath, [prefix, json, ''].join('\n')) + await fs.writeFile(configPath, [prefix, json, ''].join('\n')) return configPath } -module.exports = createConfigGypi -module.exports.test = { - parseConfigGypi: parseConfigGypi, - getCurrentConfigGypi: getCurrentConfigGypi +module.exports = { + createConfigGypi, + parseConfigGypi, + getCurrentConfigGypi } diff --git a/node_modules/node-gyp/lib/download.js b/node_modules/node-gyp/lib/download.js new file mode 100644 index 0000000000000..ed0aa37f44116 --- /dev/null +++ b/node_modules/node-gyp/lib/download.js @@ -0,0 +1,39 @@ +const fetch = require('make-fetch-happen') +const { promises: fs } = require('graceful-fs') +const log = require('./log') + +async function download (gyp, url) { + log.http('GET', url) + + const requestOpts = { + headers: { + 'User-Agent': `node-gyp v${gyp.version} (node ${process.version})`, + Connection: 'keep-alive' + }, + proxy: gyp.opts.proxy, + noProxy: gyp.opts.noproxy + } + + const cafile = gyp.opts.cafile + if (cafile) { + requestOpts.ca = await readCAFile(cafile) + } + + const res = await fetch(url, requestOpts) + log.http(res.status, res.url) + + return res +} + +async function readCAFile (filename) { + // The CA file can contain multiple certificates so split on certificate + // boundaries. [\S\s]*? is used to match everything including newlines. + const ca = await fs.readFile(filename, 'utf8') + const re = /(-----BEGIN CERTIFICATE-----[\S\s]*?-----END CERTIFICATE-----)/g + return ca.match(re) +} + +module.exports = { + download, + readCAFile +} diff --git a/node_modules/node-gyp/lib/find-node-directory.js b/node_modules/node-gyp/lib/find-node-directory.js index 0dd781a6cfae8..8838b81d33899 100644 --- a/node_modules/node-gyp/lib/find-node-directory.js +++ b/node_modules/node-gyp/lib/find-node-directory.js @@ -1,7 +1,7 @@ 'use strict' const path = require('path') -const log = require('npmlog') +const log = require('./log') function findNodeDirectory (scriptLocation, processObj) { // set dirname and process if not passed in @@ -14,10 +14,10 @@ function findNodeDirectory (scriptLocation, processObj) { } // Have a look to see what is above us, to try and work out where we are - var npmParentDirectory = path.join(scriptLocation, '../../../..') + const npmParentDirectory = path.join(scriptLocation, '../../../..') log.verbose('node-gyp root', 'npm_parent_directory is ' + path.basename(npmParentDirectory)) - var nodeRootDir = '' + let nodeRootDir = '' log.verbose('node-gyp root', 'Finding node root directory') if (path.basename(npmParentDirectory) === 'deps') { @@ -41,8 +41,8 @@ function findNodeDirectory (scriptLocation, processObj) { } else { // We don't know where we are, try working it out from the location // of the node binary - var nodeDir = path.dirname(processObj.execPath) - var directoryUp = path.basename(nodeDir) + const nodeDir = path.dirname(processObj.execPath) + const directoryUp = path.basename(nodeDir) if (directoryUp === 'bin') { nodeRootDir = path.join(nodeDir, '..') } else if (directoryUp === 'Release' || directoryUp === 'Debug') { diff --git a/node_modules/node-gyp/lib/find-python.js b/node_modules/node-gyp/lib/find-python.js index a445e825b9d7e..273b5957b4992 100644 --- a/node_modules/node-gyp/lib/find-python.js +++ b/node_modules/node-gyp/lib/find-python.js @@ -1,11 +1,15 @@ 'use strict' -const log = require('npmlog') +const log = require('./log') const semver = require('semver') -const cp = require('child_process') -const extend = require('util')._extend // eslint-disable-line +const { execFile } = require('./util') const win = process.platform === 'win32' -const logWithPrefix = require('./util').logWithPrefix + +function getOsUserInfo () { + try { + return require('os').userInfo().username + } catch {} +} const systemDrive = process.env.SystemDrive || 'C:' const username = process.env.USERNAME || process.env.USER || getOsUserInfo() @@ -15,7 +19,7 @@ const programFiles = process.env.ProgramW6432 || process.env.ProgramFiles || `${ const programFilesX86 = process.env['ProgramFiles(x86)'] || `${programFiles} (x86)` const winDefaultLocationsArray = [] -for (const majorMinor of ['39', '38', '37', '36']) { +for (const majorMinor of ['311', '310', '39', '38']) { if (foundLocalAppData) { winDefaultLocationsArray.push( `${localAppData}\\Programs\\Python\\Python${majorMinor}\\python.exe`, @@ -33,45 +37,39 @@ for (const majorMinor of ['39', '38', '37', '36']) { } } -function getOsUserInfo () { - try { - return require('os').userInfo().username - } catch (e) {} -} - -function PythonFinder (configPython, callback) { - this.callback = callback - this.configPython = configPython - this.errorLog = [] -} +class PythonFinder { + static findPython = (...args) => new PythonFinder(...args).findPython() -PythonFinder.prototype = { - log: logWithPrefix(log, 'find Python'), - argsExecutable: ['-c', 'import sys; print(sys.executable);'], - argsVersion: ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);'], - semverRange: '>=3.6.0', + log = log.withPrefix('find Python') + argsExecutable = ['-c', 'import sys; sys.stdout.buffer.write(sys.executable.encode(\'utf-8\'));'] + argsVersion = ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);'] + semverRange = '>=3.6.0' // These can be overridden for testing: - execFile: cp.execFile, - env: process.env, - win: win, - pyLauncher: 'py.exe', - winDefaultLocations: winDefaultLocationsArray, + execFile = execFile + env = process.env + win = win + pyLauncher = 'py.exe' + winDefaultLocations = winDefaultLocationsArray + + constructor (configPython) { + this.configPython = configPython + this.errorLog = [] + } // Logs a message at verbose level, but also saves it to be displayed later // at error level if an error occurs. This should help diagnose the problem. - addLog: function addLog (message) { + addLog (message) { this.log.verbose(message) this.errorLog.push(message) - }, + } // Find Python by trying a sequence of possibilities. // Ignore errors, keep trying until Python is found. - findPython: function findPython () { - const SKIP = 0; const FAIL = 1 - var toCheck = getChecks.apply(this) - - function getChecks () { + async findPython () { + const SKIP = 0 + const FAIL = 1 + const toCheck = (() => { if (this.env.NODE_GYP_FORCE_PYTHON) { return [{ before: () => { @@ -80,26 +78,20 @@ PythonFinder.prototype = { this.addLog('- process.env.NODE_GYP_FORCE_PYTHON is ' + `"${this.env.NODE_GYP_FORCE_PYTHON}"`) }, - check: this.checkCommand, - arg: this.env.NODE_GYP_FORCE_PYTHON + check: () => this.checkCommand(this.env.NODE_GYP_FORCE_PYTHON) }] } - var checks = [ + const checks = [ { before: () => { if (!this.configPython) { - this.addLog( - 'Python is not set from command line or npm configuration') + this.addLog('--python was not set on the command line') return SKIP } - this.addLog('checking Python explicitly set from command line or ' + - 'npm configuration') - this.addLog('- "--python=" or "npm config get python" is ' + - `"${this.configPython}"`) + this.addLog(`--python=${this.configPython} was set on the command line`) }, - check: this.checkCommand, - arg: this.configPython + check: () => this.checkCommand(this.configPython) }, { before: () => { @@ -112,78 +104,69 @@ PythonFinder.prototype = { 'variable PYTHON') this.addLog(`- process.env.PYTHON is "${this.env.PYTHON}"`) }, - check: this.checkCommand, - arg: this.env.PYTHON - }, + check: () => this.checkCommand(this.env.PYTHON) + } + ] + + if (this.win) { + checks.push({ + before: () => { + this.addLog( + 'checking if the py launcher can be used to find Python 3') + }, + check: () => this.checkPyLauncher() + }) + } + + checks.push(...[ { before: () => { this.addLog('checking if "python3" can be used') }, - check: this.checkCommand, - arg: 'python3' + check: () => this.checkCommand('python3') }, { before: () => { this.addLog('checking if "python" can be used') }, - check: this.checkCommand, - arg: 'python' + check: () => this.checkCommand('python') } - ] + ]) if (this.win) { - for (var i = 0; i < this.winDefaultLocations.length; ++i) { + for (let i = 0; i < this.winDefaultLocations.length; ++i) { const location = this.winDefaultLocations[i] checks.push({ - before: () => { - this.addLog('checking if Python is ' + - `${location}`) - }, - check: this.checkExecPath, - arg: location + before: () => this.addLog(`checking if Python is ${location}`), + check: () => this.checkExecPath(location) }) } - checks.push({ - before: () => { - this.addLog( - 'checking if the py launcher can be used to find Python 3') - }, - check: this.checkPyLauncher - }) } return checks - } - - function runChecks (err) { - this.log.silly('runChecks: err = %j', (err && err.stack) || err) + })() - const check = toCheck.shift() - if (!check) { - return this.fail() - } - - const before = check.before.apply(this) + for (const check of toCheck) { + const before = check.before() if (before === SKIP) { - return runChecks.apply(this) + continue } if (before === FAIL) { return this.fail() } - - const args = [runChecks.bind(this)] - if (check.arg) { - args.unshift(check.arg) + try { + return await check.check() + } catch (err) { + this.log.silly('runChecks: err = %j', (err && err.stack) || err) } - check.check.apply(this, args) } - runChecks.apply(this) - }, + return this.fail() + } // Check if command is a valid Python to use. // Will exit the Python finder on success. // If on Windows, run in a CMD shell to support BAT/CMD launchers. - checkCommand: function checkCommand (command, errorCallback) { - var exec = command - var args = this.argsExecutable - var shell = false + async checkCommand (command) { + let exec = command + let args = this.argsExecutable + let shell = false if (this.win) { // Arguments have to be manually quoted exec = `"${exec}"` @@ -192,19 +175,19 @@ PythonFinder.prototype = { } this.log.verbose(`- executing "${command}" to get executable path`) - this.run(exec, args, shell, function (err, execPath) { - // Possible outcomes: - // - Error: not in PATH, not executable or execution fails - // - Gibberish: the next command to check version will fail - // - Absolute path to executable - if (err) { - this.addLog(`- "${command}" is not in PATH or produced an error`) - return errorCallback(err) - } + // Possible outcomes: + // - Error: not in PATH, not executable or execution fails + // - Gibberish: the next command to check version will fail + // - Absolute path to executable + try { + const execPath = await this.run(exec, args, shell) this.addLog(`- executable path is "${execPath}"`) - this.checkExecPath(execPath, errorCallback) - }.bind(this)) - }, + return this.checkExecPath(execPath) + } catch (err) { + this.addLog(`- "${command}" is not in PATH or produced an error`) + throw err + } + } // Check if the py launcher can find a valid Python to use. // Will exit the Python finder on success. @@ -216,97 +199,86 @@ PythonFinder.prototype = { // the first command line argument. Since "py.exe -3" would be an invalid // executable for "execFile", we have to use the launcher to figure out // where the actual "python.exe" executable is located. - checkPyLauncher: function checkPyLauncher (errorCallback) { - this.log.verbose( - `- executing "${this.pyLauncher}" to get Python 3 executable path`) - this.run(this.pyLauncher, ['-3', ...this.argsExecutable], false, - function (err, execPath) { - // Possible outcomes: same as checkCommand - if (err) { - this.addLog( - `- "${this.pyLauncher}" is not in PATH or produced an error`) - return errorCallback(err) - } - this.addLog(`- executable path is "${execPath}"`) - this.checkExecPath(execPath, errorCallback) - }.bind(this)) - }, + async checkPyLauncher () { + this.log.verbose(`- executing "${this.pyLauncher}" to get Python 3 executable path`) + // Possible outcomes: same as checkCommand + try { + const execPath = await this.run(this.pyLauncher, ['-3', ...this.argsExecutable], false) + this.addLog(`- executable path is "${execPath}"`) + return this.checkExecPath(execPath) + } catch (err) { + this.addLog(`- "${this.pyLauncher}" is not in PATH or produced an error`) + throw err + } + } // Check if a Python executable is the correct version to use. // Will exit the Python finder on success. - checkExecPath: function checkExecPath (execPath, errorCallback) { + async checkExecPath (execPath) { this.log.verbose(`- executing "${execPath}" to get version`) - this.run(execPath, this.argsVersion, false, function (err, version) { - // Possible outcomes: - // - Error: executable can not be run (likely meaning the command wasn't - // a Python executable and the previous command produced gibberish) - // - Gibberish: somehow the last command produced an executable path, - // this will fail when verifying the version - // - Version of the Python executable - if (err) { - this.addLog(`- "${execPath}" could not be run`) - return errorCallback(err) - } + // Possible outcomes: + // - Error: executable can not be run (likely meaning the command wasn't + // a Python executable and the previous command produced gibberish) + // - Gibberish: somehow the last command produced an executable path, + // this will fail when verifying the version + // - Version of the Python executable + try { + const version = await this.run(execPath, this.argsVersion, false) this.addLog(`- version is "${version}"`) const range = new semver.Range(this.semverRange) - var valid = false + let valid = false try { valid = range.test(version) } catch (err) { this.log.silly('range.test() threw:\n%s', err.stack) this.addLog(`- "${execPath}" does not have a valid version`) this.addLog('- is it a Python executable?') - return errorCallback(err) + throw err } - if (!valid) { this.addLog(`- version is ${version} - should be ${this.semverRange}`) this.addLog('- THIS VERSION OF PYTHON IS NOT SUPPORTED') - return errorCallback(new Error( - `Found unsupported Python version ${version}`)) + throw new Error(`Found unsupported Python version ${version}`) } - this.succeed(execPath, version) - }.bind(this)) - }, + return this.succeed(execPath, version) + } catch (err) { + this.addLog(`- "${execPath}" could not be run`) + throw err + } + } // Run an executable or shell command, trimming the output. - run: function run (exec, args, shell, callback) { - var env = extend({}, this.env) + async run (exec, args, shell) { + const env = Object.assign({}, this.env) env.TERM = 'dumb' - const opts = { env: env, shell: shell } + const opts = { env, shell } this.log.silly('execFile: exec = %j', exec) this.log.silly('execFile: args = %j', args) this.log.silly('execFile: opts = %j', opts) try { - this.execFile(exec, args, opts, execFileCallback.bind(this)) - } catch (err) { - this.log.silly('execFile: threw:\n%s', err.stack) - return callback(err) - } - - function execFileCallback (err, stdout, stderr) { + const [err, stdout, stderr] = await this.execFile(exec, args, opts) this.log.silly('execFile result: err = %j', (err && err.stack) || err) this.log.silly('execFile result: stdout = %j', stdout) this.log.silly('execFile result: stderr = %j', stderr) - if (err) { - return callback(err) - } - const execPath = stdout.trim() - callback(null, execPath) + return stdout.trim() + } catch (err) { + this.log.silly('execFile: threw:\n%s', err.stack) + throw err } - }, + } - succeed: function succeed (execPath, version) { + succeed (execPath, version) { this.log.info(`using Python version ${version} found at "${execPath}"`) - process.nextTick(this.callback.bind(null, null, execPath)) - }, + return execPath + } - fail: function fail () { + fail () { const errorLog = this.errorLog.join('\n') - const pathExample = this.win ? 'C:\\Path\\To\\python.exe' + const pathExample = this.win + ? 'C:\\Path\\To\\python.exe' : '/path/to/pythonexecutable' // For Windows 80 col console, use up to the column before the one marked // with X (total 79 chars including logger prefix, 58 chars usable here): @@ -319,26 +291,14 @@ PythonFinder.prototype = { `- Use the switch --python="${pathExample}"`, ' (accepted by both node-gyp and npm)', '- Set the environment variable PYTHON', - '- Set the npm configuration variable python:', - ` npm config set python "${pathExample}"`, 'For more information consult the documentation at:', 'https://github.com/nodejs/node-gyp#installation', '**********************************************************' ].join('\n') this.log.error(`\n${errorLog}\n\n${info}\n`) - process.nextTick(this.callback.bind(null, new Error( - 'Could not find any Python installation to use'))) + throw new Error('Could not find any Python installation to use') } } -function findPython (configPython, callback) { - var finder = new PythonFinder(configPython, callback) - finder.findPython() -} - -module.exports = findPython -module.exports.test = { - PythonFinder: PythonFinder, - findPython: findPython -} +module.exports = PythonFinder diff --git a/node_modules/node-gyp/lib/find-visualstudio.js b/node_modules/node-gyp/lib/find-visualstudio.js index 64af7be3460ef..22fc4013f905f 100644 --- a/node_modules/node-gyp/lib/find-visualstudio.js +++ b/node_modules/node-gyp/lib/find-visualstudio.js @@ -1,43 +1,36 @@ 'use strict' -const log = require('npmlog') -const execFile = require('child_process').execFile -const fs = require('fs') -const path = require('path').win32 -const logWithPrefix = require('./util').logWithPrefix -const regSearchKeys = require('./util').regSearchKeys - -function findVisualStudio (nodeSemver, configMsvsVersion, callback) { - const finder = new VisualStudioFinder(nodeSemver, configMsvsVersion, - callback) - finder.findVisualStudio() -} +const log = require('./log') +const { existsSync } = require('fs') +const { win32: path } = require('path') +const { regSearchKeys, execFile } = require('./util') -function VisualStudioFinder (nodeSemver, configMsvsVersion, callback) { - this.nodeSemver = nodeSemver - this.configMsvsVersion = configMsvsVersion - this.callback = callback - this.errorLog = [] - this.validVersions = [] -} +class VisualStudioFinder { + static findVisualStudio = (...args) => new VisualStudioFinder(...args).findVisualStudio() -VisualStudioFinder.prototype = { - log: logWithPrefix(log, 'find VS'), + log = log.withPrefix('find VS') - regSearchKeys: regSearchKeys, + regSearchKeys = regSearchKeys + + constructor (nodeSemver, configMsvsVersion) { + this.nodeSemver = nodeSemver + this.configMsvsVersion = configMsvsVersion + this.errorLog = [] + this.validVersions = [] + } // Logs a message at verbose level, but also saves it to be displayed later // at error level if an error occurs. This should help diagnose the problem. - addLog: function addLog (message) { + addLog (message) { this.log.verbose(message) this.errorLog.push(message) - }, + } - findVisualStudio: function findVisualStudio () { + async findVisualStudio () { this.configVersionYear = null this.configPath = null if (this.configMsvsVersion) { - this.addLog('msvs_version was set from command line or npm config') + this.addLog(`--msvs_version=${this.configMsvsVersion} was set on the command line`) if (this.configMsvsVersion.match(/^\d{4}$/)) { this.configVersionYear = parseInt(this.configMsvsVersion, 10) this.addLog( @@ -48,7 +41,7 @@ VisualStudioFinder.prototype = { `- looking for Visual Studio installed in "${this.configPath}"`) } } else { - this.addLog('msvs_version not set from command line or npm config') + this.addLog('--msvs_version was not set on the command line') } if (process.env.VCINSTALLDIR) { @@ -60,32 +53,35 @@ VisualStudioFinder.prototype = { this.addLog('VCINSTALLDIR not set, not running in VS Command Prompt') } - this.findVisualStudio2017OrNewer((info) => { + const checks = [ + () => this.findVisualStudio2019OrNewerFromSpecifiedLocation(), + () => this.findVisualStudio2019OrNewerUsingSetupModule(), + () => this.findVisualStudio2019OrNewer(), + () => this.findVisualStudio2017FromSpecifiedLocation(), + () => this.findVisualStudio2017UsingSetupModule(), + () => this.findVisualStudio2017(), + () => this.findVisualStudio2015(), + () => this.findVisualStudio2013() + ] + + for (const check of checks) { + const info = await check() if (info) { return this.succeed(info) } - this.findVisualStudio2015((info) => { - if (info) { - return this.succeed(info) - } - this.findVisualStudio2013((info) => { - if (info) { - return this.succeed(info) - } - this.fail() - }) - }) - }) - }, + } - succeed: function succeed (info) { + return this.fail() + } + + succeed (info) { this.log.info(`using VS${info.versionYear} (${info.version}) found at:` + `\n"${info.path}"` + '\nrun with --verbose for detailed information') - process.nextTick(this.callback.bind(null, null, info)) - }, + return info + } - fail: function fail () { + fail () { if (this.configMsvsVersion && this.envVcInstallDir) { this.errorLog.push( 'msvs_version does not match this VS Command Prompt or the', @@ -119,17 +115,134 @@ VisualStudioFinder.prototype = { ].join('\n') this.log.error(`\n${errorLog}\n\n${infoLog}\n`) - process.nextTick(this.callback.bind(null, new Error( - 'Could not find any Visual Studio installation to use'))) - }, + throw new Error('Could not find any Visual Studio installation to use') + } + + async findVisualStudio2019OrNewerFromSpecifiedLocation () { + return this.findVSFromSpecifiedLocation([2019, 2022, 2026]) + } + + async findVisualStudio2017FromSpecifiedLocation () { + if (this.nodeSemver.major >= 22) { + this.addLog( + 'not looking for VS2017 as it is only supported up to Node.js 21') + return null + } + return this.findVSFromSpecifiedLocation([2017]) + } + + async findVSFromSpecifiedLocation (supportedYears) { + if (!this.envVcInstallDir) { + return null + } + const info = { + path: path.resolve(this.envVcInstallDir), + // Assume the version specified by the user is correct. + // Since Visual Studio 2015, the Developer Command Prompt sets the + // VSCMD_VER environment variable which contains the version information + // for Visual Studio. + // https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022 + version: process.env.VSCMD_VER, + packages: [ + 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', + 'Microsoft.VisualStudio.Component.VC.Tools.ARM64', + // Assume MSBuild exists. It will be checked in processing. + 'Microsoft.VisualStudio.VC.MSBuild.Base' + ] + } + + // Is there a better way to get SDK information? + const envWindowsSDKVersion = process.env.WindowsSDKVersion + const sdkVersionMatched = envWindowsSDKVersion?.match(/^(\d+)\.(\d+)\.(\d+)\..*/) + if (sdkVersionMatched) { + info.packages.push(`Microsoft.VisualStudio.Component.Windows10SDK.${sdkVersionMatched[3]}.Desktop`) + } + // pass for further processing + return this.processData([info], supportedYears) + } + + async findVisualStudio2019OrNewerUsingSetupModule () { + return this.findNewVSUsingSetupModule([2019, 2022, 2026]) + } + + async findVisualStudio2017UsingSetupModule () { + if (this.nodeSemver.major >= 22) { + this.addLog( + 'not looking for VS2017 as it is only supported up to Node.js 21') + return null + } + return this.findNewVSUsingSetupModule([2017]) + } + + async findNewVSUsingSetupModule (supportedYears) { + const ps = path.join(process.env.SystemRoot, 'System32', + 'WindowsPowerShell', 'v1.0', 'powershell.exe') + const vcInstallDir = this.envVcInstallDir + + const checkModuleArgs = [ + '-NoProfile', + '-Command', + '&{@(Get-Module -ListAvailable -Name VSSetup).Version.ToString()}' + ] + this.log.silly('Running', ps, checkModuleArgs) + const [cErr] = await this.execFile(ps, checkModuleArgs) + if (cErr) { + this.addLog('VSSetup module doesn\'t seem to exist. You can install it via: "Install-Module VSSetup -Scope CurrentUser"') + this.log.silly('VSSetup error = %j', cErr && (cErr.stack || cErr)) + return null + } + const filterArg = vcInstallDir !== undefined ? `| where {$_.InstallationPath -eq '${vcInstallDir}' }` : '' + const psArgs = [ + '-NoProfile', + '-Command', + `&{Get-VSSetupInstance ${filterArg} | ConvertTo-Json -Depth 3}` + ] + + this.log.silly('Running', ps, psArgs) + const [err, stdout, stderr] = await this.execFile(ps, psArgs) + let parsedData = this.parseData(err, stdout, stderr) + if (parsedData === null) { + return null + } + this.log.silly('Parsed data', parsedData) + if (!Array.isArray(parsedData)) { + // if there are only 1 result, then Powershell will output non-array + parsedData = [parsedData] + } + // normalize output + parsedData = parsedData.map((info) => { + info.path = info.InstallationPath + info.version = `${info.InstallationVersion.Major}.${info.InstallationVersion.Minor}.${info.InstallationVersion.Build}.${info.InstallationVersion.Revision}` + info.packages = info.Packages.map((p) => p.Id) + return info + }) + // pass for further processing + return this.processData(parsedData, supportedYears) + } + + // Invoke the PowerShell script to get information about Visual Studio 2019 + // or newer installations + async findVisualStudio2019OrNewer () { + return this.findNewVS([2019, 2022, 2026]) + } + + // Invoke the PowerShell script to get information about Visual Studio 2017 + async findVisualStudio2017 () { + if (this.nodeSemver.major >= 22) { + this.addLog( + 'not looking for VS2017 as it is only supported up to Node.js 21') + return null + } + return this.findNewVS([2017]) + } // Invoke the PowerShell script to get information about Visual Studio 2017 // or newer installations - findVisualStudio2017OrNewer: function findVisualStudio2017OrNewer (cb) { - var ps = path.join(process.env.SystemRoot, 'System32', + async findNewVS (supportedYears) { + const ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') - var csFile = path.join(__dirname, 'Find-VisualStudio.cs') - var psArgs = [ + const csFile = path.join(__dirname, 'Find-VisualStudio.cs') + const psArgs = [ '-ExecutionPolicy', 'Unrestricted', '-NoProfile', @@ -138,30 +251,38 @@ VisualStudioFinder.prototype = { ] this.log.silly('Running', ps, psArgs) - var child = execFile(ps, psArgs, { encoding: 'utf8' }, - (err, stdout, stderr) => { - this.parseData(err, stdout, stderr, cb) - }) - child.stdin.end() - }, - - // Parse the output of the PowerShell script and look for an installation - // of Visual Studio 2017 or newer to use - parseData: function parseData (err, stdout, stderr, cb) { + const [err, stdout, stderr] = await this.execFile(ps, psArgs) + const parsedData = this.parseData(err, stdout, stderr, { checkIsArray: true }) + if (parsedData === null) { + return null + } + return this.processData(parsedData, supportedYears) + } + + // Parse the output of the PowerShell script, make sanity checks + parseData (err, stdout, stderr, sanityCheckOptions) { + const defaultOptions = { + checkIsArray: false + } + + // Merging provided options with the default options + const sanityOptions = { ...defaultOptions, ...sanityCheckOptions } + this.log.silly('PS stderr = %j', stderr) - const failPowershell = () => { + const failPowershell = (failureDetails) => { this.addLog( - 'could not use PowerShell to find Visual Studio 2017 or newer, try re-running with \'--loglevel silly\' for more details') - cb(null) + `could not use PowerShell to find Visual Studio 2017 or newer, try re-running with '--loglevel silly' for more details. \n + Failure details: ${failureDetails}`) + return null } if (err) { this.log.silly('PS err = %j', err && (err.stack || err)) - return failPowershell() + return failPowershell(`${err}`.substring(0, 40)) } - var vsInfo + let vsInfo try { vsInfo = JSON.parse(stdout) } catch (e) { @@ -170,15 +291,20 @@ VisualStudioFinder.prototype = { return failPowershell() } - if (!Array.isArray(vsInfo)) { + if (sanityOptions.checkIsArray && !Array.isArray(vsInfo)) { this.log.silly('PS stdout = %j', stdout) - return failPowershell() + return failPowershell('Expected array as output of the PS script') } + return vsInfo + } + // Process parsed data containing information about VS installations + // Look for the required parts, extract and output them back + processData (vsInfo, supportedYears) { vsInfo = vsInfo.map((info) => { this.log.silly(`processing installation: "${info.path}"`) info.path = path.resolve(info.path) - var ret = this.getVersionInfo(info) + const ret = this.getVersionInfo(info) ret.path = info.path ret.msBuild = this.getMSBuild(info, ret.versionYear) ret.toolset = this.getToolset(info, ret.versionYear) @@ -188,18 +314,19 @@ VisualStudioFinder.prototype = { this.log.silly('vsInfo:', vsInfo) // Remove future versions or errors parsing version number + // Also remove any unsupported versions vsInfo = vsInfo.filter((info) => { - if (info.versionYear) { + if (info.versionYear && supportedYears.indexOf(info.versionYear) !== -1) { return true } - this.addLog(`unknown version "${info.version}" found at "${info.path}"`) + this.addLog(`${info.versionYear ? 'unsupported' : 'unknown'} version "${info.version}" found at "${info.path}"`) return false }) // Sort to place newer versions first vsInfo.sort((a, b) => b.versionYear - a.versionYear) - for (var i = 0; i < vsInfo.length; ++i) { + for (let i = 0; i < vsInfo.length; ++i) { const info = vsInfo[i] this.addLog(`checking VS${info.versionYear} (${info.version}) found ` + `at:\n"${info.path}"`) @@ -229,23 +356,23 @@ VisualStudioFinder.prototype = { continue } - return cb(info) + return info } this.addLog( 'could not find a version of Visual Studio 2017 or newer to use') - cb(null) - }, + return null + } // Helper - process version information - getVersionInfo: function getVersionInfo (info) { - const match = /^(\d+)\.(\d+)\..*/.exec(info.version) + getVersionInfo (info) { + const match = /^(\d+)\.(\d+)(?:\..*)?/.exec(info.version) if (!match) { this.log.silly('- failed to parse version:', info.version) return {} } this.log.silly('- version match = %j', match) - var ret = { + const ret = { version: info.version, versionMajor: parseInt(match[1], 10), versionMinor: parseInt(match[2], 10) @@ -262,38 +389,66 @@ VisualStudioFinder.prototype = { ret.versionYear = 2022 return ret } + if (ret.versionMajor === 18) { + ret.versionYear = 2026 + return ret + } this.log.silly('- unsupported version:', ret.versionMajor) return {} - }, + } + + msBuildPathExists (path) { + return existsSync(path) + } // Helper - process MSBuild information - getMSBuild: function getMSBuild (info, versionYear) { + getMSBuild (info, versionYear) { const pkg = 'Microsoft.VisualStudio.VC.MSBuild.Base' const msbuildPath = path.join(info.path, 'MSBuild', 'Current', 'Bin', 'MSBuild.exe') + const msbuildPathArm64 = path.join(info.path, 'MSBuild', 'Current', 'Bin', 'arm64', 'MSBuild.exe') if (info.packages.indexOf(pkg) !== -1) { this.log.silly('- found VC.MSBuild.Base') if (versionYear === 2017) { return path.join(info.path, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe') } if (versionYear === 2019) { - return msbuildPath + if (process.arch === 'arm64' && this.msBuildPathExists(msbuildPathArm64)) { + return msbuildPathArm64 + } else { + return msbuildPath + } } } - // visual studio 2022 don't has msbuild pkg - if (fs.existsSync(msbuildPath)) { + /** + * Visual Studio 2022 doesn't have the MSBuild package. + * Support for compiling _on_ ARM64 was added in MSVC 14.32.31326, + * so let's leverage it if the user has an ARM64 device. + */ + if (process.arch === 'arm64' && this.msBuildPathExists(msbuildPathArm64)) { + return msbuildPathArm64 + } else if (this.msBuildPathExists(msbuildPath)) { return msbuildPath } return null - }, + } // Helper - process toolset information - getToolset: function getToolset (info, versionYear) { - const pkg = 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64' + getToolset (info, versionYear) { + const vcToolsArm64 = 'VC.Tools.ARM64' + const pkgArm64 = `Microsoft.VisualStudio.Component.${vcToolsArm64}` + const vcToolsX64 = 'VC.Tools.x86.x64' + const pkgX64 = `Microsoft.VisualStudio.Component.${vcToolsX64}` const express = 'Microsoft.VisualStudio.WDExpress' - if (info.packages.indexOf(pkg) !== -1) { - this.log.silly('- found VC.Tools.x86.x64') - } else if (info.packages.indexOf(express) !== -1) { + if (process.arch === 'arm64' && info.packages.includes(pkgArm64)) { + this.log.silly(`- found ${vcToolsArm64}`) + } else if (info.packages.includes(pkgX64)) { + if (process.arch === 'arm64') { + this.addLog(`- found ${vcToolsX64} on ARM64 platform. Expect less performance and/or link failure with ARM64 binary.`) + } else { + this.log.silly(`- found ${vcToolsX64}`) + } + } else if (info.packages.includes(express)) { this.log.silly('- found Visual Studio Express (looking for toolset)') } else { return null @@ -305,62 +460,70 @@ VisualStudioFinder.prototype = { return 'v142' } else if (versionYear === 2022) { return 'v143' + } else if (versionYear === 2026) { + return 'v145' } this.log.silly('- invalid versionYear:', versionYear) return null - }, + } // Helper - process Windows SDK information - getSDK: function getSDK (info) { + getSDK (info) { const win8SDK = 'Microsoft.VisualStudio.Component.Windows81SDK' const win10SDKPrefix = 'Microsoft.VisualStudio.Component.Windows10SDK.' + const win11SDKPrefix = 'Microsoft.VisualStudio.Component.Windows11SDK.' - var Win10SDKVer = 0 + let Win10or11SDKVer = 0 info.packages.forEach((pkg) => { - if (!pkg.startsWith(win10SDKPrefix)) { + if (!pkg.startsWith(win10SDKPrefix) && !pkg.startsWith(win11SDKPrefix)) { return } const parts = pkg.split('.') if (parts.length > 5 && parts[5] !== 'Desktop') { - this.log.silly('- ignoring non-Desktop Win10SDK:', pkg) + this.log.silly('- ignoring non-Desktop Win10/11SDK:', pkg) return } const foundSdkVer = parseInt(parts[4], 10) if (isNaN(foundSdkVer)) { // Microsoft.VisualStudio.Component.Windows10SDK.IpOverUsb - this.log.silly('- failed to parse Win10SDK number:', pkg) + this.log.silly('- failed to parse Win10/11SDK number:', pkg) return } - this.log.silly('- found Win10SDK:', foundSdkVer) - Win10SDKVer = Math.max(Win10SDKVer, foundSdkVer) + this.log.silly('- found Win10/11SDK:', foundSdkVer) + Win10or11SDKVer = Math.max(Win10or11SDKVer, foundSdkVer) }) - if (Win10SDKVer !== 0) { - return `10.0.${Win10SDKVer}.0` + if (Win10or11SDKVer !== 0) { + return `10.0.${Win10or11SDKVer}.0` } else if (info.packages.indexOf(win8SDK) !== -1) { this.log.silly('- found Win8SDK') return '8.1' } return null - }, + } // Find an installation of Visual Studio 2015 to use - findVisualStudio2015: function findVisualStudio2015 (cb) { + async findVisualStudio2015 () { + if (this.nodeSemver.major >= 19) { + this.addLog( + 'not looking for VS2015 as it is only supported up to Node.js 18') + return null + } return this.findOldVS({ version: '14.0', versionMajor: 14, versionMinor: 0, versionYear: 2015, toolset: 'v140' - }, cb) - }, + }) + } // Find an installation of Visual Studio 2013 to use - findVisualStudio2013: function findVisualStudio2013 (cb) { + async findVisualStudio2013 () { if (this.nodeSemver.major >= 9) { this.addLog( 'not looking for VS2013 as it is only supported up to Node.js 8') - return cb(null) + return null } return this.findOldVS({ version: '12.0', @@ -368,55 +531,52 @@ VisualStudioFinder.prototype = { versionMinor: 0, versionYear: 2013, toolset: 'v120' - }, cb) - }, + }) + } // Helper - common code for VS2013 and VS2015 - findOldVS: function findOldVS (info, cb) { + async findOldVS (info) { const regVC7 = ['HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7', 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7'] const regMSBuild = 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions' this.addLog(`looking for Visual Studio ${info.versionYear}`) - this.regSearchKeys(regVC7, info.version, [], (err, res) => { - if (err) { - this.addLog('- not found') - return cb(null) - } - + try { + let res = await this.regSearchKeys(regVC7, info.version, []) const vsPath = path.resolve(res, '..') this.addLog(`- found in "${vsPath}"`) - const msBuildRegOpts = process.arch === 'ia32' ? [] : ['/reg:32'] - this.regSearchKeys([`${regMSBuild}\\${info.version}`], - 'MSBuildToolsPath', msBuildRegOpts, (err, res) => { - if (err) { - this.addLog( - '- could not find MSBuild in registry for this version') - return cb(null) - } - - const msBuild = path.join(res, 'MSBuild.exe') - this.addLog(`- MSBuild in "${msBuild}"`) - - if (!this.checkConfigVersion(info.versionYear, vsPath)) { - return cb(null) - } - - info.path = vsPath - info.msBuild = msBuild - info.sdk = null - cb(info) - }) - }) - }, + + try { + res = await this.regSearchKeys([`${regMSBuild}\\${info.version}`], 'MSBuildToolsPath', msBuildRegOpts) + } catch (err) { + this.addLog('- could not find MSBuild in registry for this version') + return null + } + + const msBuild = path.join(res, 'MSBuild.exe') + this.addLog(`- MSBuild in "${msBuild}"`) + + if (!this.checkConfigVersion(info.versionYear, vsPath)) { + return null + } + + info.path = vsPath + info.msBuild = msBuild + info.sdk = null + return info + } catch (err) { + this.addLog('- not found') + return null + } + } // After finding a usable version of Visual Studio: // - add it to validVersions to be displayed at the end if a specific // version was requested and not found; // - check if this is the version that was requested. // - check if this matches the Visual Studio Command Prompt - checkConfigVersion: function checkConfigVersion (versionYear, vsPath) { + checkConfigVersion (versionYear, vsPath) { this.validVersions.push(versionYear) this.validVersions.push(vsPath) @@ -437,10 +597,10 @@ VisualStudioFinder.prototype = { return true } -} -module.exports = findVisualStudio -module.exports.test = { - VisualStudioFinder: VisualStudioFinder, - findVisualStudio: findVisualStudio + async execFile (exec, args) { + return await execFile(exec, args, { encoding: 'utf8' }) + } } + +module.exports = VisualStudioFinder diff --git a/node_modules/node-gyp/lib/install.js b/node_modules/node-gyp/lib/install.js index 99f6d8592a3fd..3580cdd003b21 100644 --- a/node_modules/node-gyp/lib/install.js +++ b/node_modules/node-gyp/lib/install.js @@ -1,25 +1,26 @@ 'use strict' -const fs = require('graceful-fs') +const { createWriteStream, promises: fs } = require('graceful-fs') const os = require('os') +const { backOff } = require('exponential-backoff') const tar = require('tar') const path = require('path') -const util = require('util') -const stream = require('stream') +const { Transform, promises: { pipeline } } = require('stream') const crypto = require('crypto') -const log = require('npmlog') +const log = require('./log') const semver = require('semver') -const fetch = require('make-fetch-happen') +const { download } = require('./download') const processRelease = require('./process-release') -const win = process.platform === 'win32' -const streamPipeline = util.promisify(stream.pipeline) -/** - * @param {typeof import('graceful-fs')} fs - */ +const win = process.platform === 'win32' -async function install (fs, gyp, argv) { +async function install (gyp, argv) { + log.stdout() const release = processRelease(argv, gyp, process.version, process.release) + // Detecting target_arch based on logic from create-cnfig-gyp.js. Used on Windows only. + const arch = win ? (gyp.opts.target_arch || gyp.opts.arch || process.arch || 'ia32') : '' + // Used to prevent downloading tarball if only new node.lib is required on Windows. + let shouldDownloadTarball = true // Determine which node dev files version we are installing log.verbose('install', 'input version string %j', release.version) @@ -54,7 +55,7 @@ async function install (fs, gyp, argv) { if (gyp.opts.ensure) { log.verbose('install', '--ensure was passed, so won\'t reinstall if already installed') try { - await fs.promises.stat(devDir) + await fs.stat(devDir) } catch (err) { if (err.code === 'ENOENT') { log.verbose('install', 'version not already installed, continuing with install', release.version) @@ -72,7 +73,7 @@ async function install (fs, gyp, argv) { const installVersionFile = path.resolve(devDir, 'installVersion') let installVersion = 0 try { - const ver = await fs.promises.readFile(installVersionFile, 'ascii') + const ver = await fs.readFile(installVersionFile, 'ascii') installVersion = parseInt(ver, 10) || 0 } catch (err) { if (err.code !== 'ENOENT') { @@ -90,6 +91,26 @@ async function install (fs, gyp, argv) { } } log.verbose('install', 'version is good') + if (win) { + log.verbose('on Windows; need to check node.lib') + const nodeLibPath = path.resolve(devDir, arch, 'node.lib') + try { + await fs.stat(nodeLibPath) + } catch (err) { + if (err.code === 'ENOENT') { + log.verbose('install', `version not already installed for ${arch}, continuing with install`, release.version) + try { + shouldDownloadTarball = false + return await go() + } catch (err) { + return rollback(err) + } + } else if (err.code === 'EACCES') { + return eaccesFallback(err) + } + throw err + } + } } else { try { return await go() @@ -98,15 +119,49 @@ async function install (fs, gyp, argv) { } } + async function copyDirectory (src, dest) { + try { + await fs.stat(src) + } catch { + throw new Error(`Missing source directory for copy: ${src}`) + } + await fs.mkdir(dest, { recursive: true }) + const entries = await fs.readdir(src, { withFileTypes: true }) + for (const entry of entries) { + if (entry.isDirectory()) { + await copyDirectory(path.join(src, entry.name), path.join(dest, entry.name)) + } else if (entry.isFile()) { + // with parallel installs, copying files may cause file errors on + // Windows so use an exponential backoff to resolve collisions + await backOff(async () => { + try { + await fs.copyFile(path.join(src, entry.name), path.join(dest, entry.name)) + } catch (err) { + // if ensure, check if file already exists and that's good enough + if (gyp.opts.ensure && err.code === 'EBUSY') { + try { + await fs.stat(path.join(dest, entry.name)) + return + } catch {} + } + throw err + } + }) + } else { + throw new Error('Unexpected file directory entry type') + } + } + } + async function go () { - log.verbose('ensuring nodedir is created', devDir) + log.verbose('ensuring devDir is created', devDir) // first create the dir for the node dev files try { - const created = await fs.promises.mkdir(devDir, { recursive: true }) + const created = await fs.mkdir(devDir, { recursive: true }) if (created) { - log.verbose('created nodedir', created) + log.verbose('created devDir', created) } } catch (err) { if (err.code === 'EACCES') { @@ -118,6 +173,7 @@ async function install (fs, gyp, argv) { // now download the node tarball const tarPath = gyp.opts.tarball + let extractErrors = false let extractCount = 0 const contentShasums = {} const expectShasums = {} @@ -136,71 +192,98 @@ async function install (fs, gyp, argv) { return isValid } - // download the tarball and extract! + function onwarn (code, message) { + extractErrors = true + log.error('error while extracting tarball', code, message) + } - if (tarPath) { - await tar.extract({ - file: tarPath, - strip: 1, - filter: isValid, - cwd: devDir - }) - } else { - try { - const res = await download(gyp, release.tarballUrl) + // download the tarball and extract! + // Omitted on Windows if only new node.lib is required - if (res.status !== 200) { - throw new Error(`${res.status} response downloading ${release.tarballUrl}`) - } + // there can be file errors from tar if parallel installs + // are happening (not uncommon with multiple native modules) so + // extract the tarball to a temp directory first and then copy over + const tarExtractDir = await fs.mkdtemp(path.join(os.tmpdir(), 'node-gyp-tmp-')) - await streamPipeline( - res.body, - // content checksum - new ShaSum((_, checksum) => { - const filename = path.basename(release.tarballUrl).trim() - contentShasums[filename] = checksum - log.verbose('content checksum', filename, checksum) - }), - tar.extract({ + try { + if (shouldDownloadTarball) { + if (tarPath) { + await tar.extract({ + file: tarPath, strip: 1, - cwd: devDir, - filter: isValid + filter: isValid, + onwarn, + cwd: tarExtractDir }) - ) - } catch (err) { - // something went wrong downloading the tarball? - if (err.code === 'ENOTFOUND') { - throw new Error('This is most likely not a problem with node-gyp or the package itself and\n' + - 'is related to network connectivity. In most cases you are behind a proxy or have bad \n' + - 'network settings.') + } else { + try { + const res = await download(gyp, release.tarballUrl) + + if (res.status !== 200) { + throw new Error(`${res.status} response downloading ${release.tarballUrl}`) + } + + await pipeline( + res.body, + // content checksum + new ShaSum((_, checksum) => { + const filename = path.basename(release.tarballUrl).trim() + contentShasums[filename] = checksum + log.verbose('content checksum', filename, checksum) + }), + tar.extract({ + strip: 1, + cwd: tarExtractDir, + filter: isValid, + onwarn + }) + ) + } catch (err) { + // something went wrong downloading the tarball? + if (err.code === 'ENOTFOUND') { + throw new Error('This is most likely not a problem with node-gyp or the package itself and\n' + + 'is related to network connectivity. In most cases you are behind a proxy or have bad \n' + + 'network settings.') + } + throw err + } } - throw err - } - } - // invoked after the tarball has finished being extracted - if (extractCount === 0) { - throw new Error('There was a fatal problem while downloading/extracting the tarball') - } + // invoked after the tarball has finished being extracted + if (extractErrors || extractCount === 0) { + throw new Error('There was a fatal problem while downloading/extracting the tarball') + } - log.verbose('tarball', 'done parsing tarball') + log.verbose('tarball', 'done parsing tarball') + } - const installVersionPath = path.resolve(devDir, 'installVersion') - await Promise.all([ + const installVersionPath = path.resolve(tarExtractDir, 'installVersion') + await Promise.all([ // need to download node.lib - ...(win ? downloadNodeLib() : []), - // write the "installVersion" file - fs.promises.writeFile(installVersionPath, gyp.package.installVersion + '\n'), - // Only download SHASUMS.txt if we downloaded something in need of SHA verification - ...(!tarPath || win ? [downloadShasums()] : []) - ]) - - log.verbose('download contents checksum', JSON.stringify(contentShasums)) - // check content shasums - for (const k in contentShasums) { - log.verbose('validating download checksum for ' + k, '(%s == %s)', contentShasums[k], expectShasums[k]) - if (contentShasums[k] !== expectShasums[k]) { - throw new Error(k + ' local checksum ' + contentShasums[k] + ' not match remote ' + expectShasums[k]) + ...(win ? [downloadNodeLib()] : []), + // write the "installVersion" file + fs.writeFile(installVersionPath, gyp.package.installVersion + '\n'), + // Only download SHASUMS.txt if we downloaded something in need of SHA verification + ...(!tarPath || win ? [downloadShasums()] : []) + ]) + + log.verbose('download contents checksum', JSON.stringify(contentShasums)) + // check content shasums + for (const k in contentShasums) { + log.verbose('validating download checksum for ' + k, '(%s == %s)', contentShasums[k], expectShasums[k]) + if (contentShasums[k] !== expectShasums[k]) { + throw new Error(k + ' local checksum ' + contentShasums[k] + ' not match remote ' + expectShasums[k]) + } + } + + // copy over the files from the temp tarball extract directory to devDir + await copyDirectory(tarExtractDir, devDir) + } finally { + try { + // try to cleanup temp dir + await fs.rm(tarExtractDir, { recursive: true, maxRetries: 3 }) + } catch { + log.warn('failed to clean up temp tarball extract directory') } } @@ -228,43 +311,33 @@ async function install (fs, gyp, argv) { log.verbose('checksum data', JSON.stringify(expectShasums)) } - function downloadNodeLib () { + async function downloadNodeLib () { log.verbose('on Windows; need to download `' + release.name + '.lib`...') - const archs = ['ia32', 'x64', 'arm64'] - return archs.map(async (arch) => { - const dir = path.resolve(devDir, arch) - const targetLibPath = path.resolve(dir, release.name + '.lib') - const { libUrl, libPath } = release[arch] - const name = `${arch} ${release.name}.lib` - log.verbose(name, 'dir', dir) - log.verbose(name, 'url', libUrl) - - await fs.promises.mkdir(dir, { recursive: true }) - log.verbose('streaming', name, 'to:', targetLibPath) - - const res = await download(gyp, libUrl) - - if (res.status === 403 || res.status === 404) { - if (arch === 'arm64') { - // Arm64 is a newer platform on Windows and not all node distributions provide it. - log.verbose(`${name} was not found in ${libUrl}`) - } else { - log.warn(`${name} was not found in ${libUrl}`) - } - return - } else if (res.status !== 200) { - throw new Error(`${res.status} status code downloading ${name}`) - } + const dir = path.resolve(tarExtractDir, arch) + const targetLibPath = path.resolve(dir, release.name + '.lib') + const { libUrl, libPath } = release[arch] + const name = `${arch} ${release.name}.lib` + log.verbose(name, 'dir', dir) + log.verbose(name, 'url', libUrl) + + await fs.mkdir(dir, { recursive: true }) + log.verbose('streaming', name, 'to:', targetLibPath) - return streamPipeline( - res.body, - new ShaSum((_, checksum) => { - contentShasums[libPath] = checksum - log.verbose('content checksum', libPath, checksum) - }), - fs.createWriteStream(targetLibPath) - ) - }) + const res = await download(gyp, libUrl) + + // Since only required node.lib is downloaded throw error if it is not fetched + if (res.status !== 200) { + throw new Error(`${res.status} status code downloading ${name}`) + } + + return pipeline( + res.body, + new ShaSum((_, checksum) => { + contentShasums[libPath] = checksum + log.verbose('content checksum', libPath, checksum) + }), + createWriteStream(targetLibPath) + ) } // downloadNodeLib() } // go() @@ -281,7 +354,7 @@ async function install (fs, gyp, argv) { async function rollback (err) { log.warn('install', 'got an error, rolling back install') // roll-back the install if anything went wrong - await util.promisify(gyp.commands.remove)([release.versionDir]) + await gyp.commands.remove([release.versionDir]) throw err } @@ -312,11 +385,11 @@ async function install (fs, gyp, argv) { log.verbose('tmpdir == cwd', 'automatically will remove dev files after to save disk space') gyp.todo.push({ name: 'remove', args: argv }) } - return util.promisify(gyp.commands.install)([noretry].concat(argv)) + return gyp.commands.install([noretry].concat(argv)) } } -class ShaSum extends stream.Transform { +class ShaSum extends Transform { constructor (callback) { super() this._callback = callback @@ -334,43 +407,5 @@ class ShaSum extends stream.Transform { } } -async function download (gyp, url) { - log.http('GET', url) - - const requestOpts = { - headers: { - 'User-Agent': `node-gyp v${gyp.version} (node ${process.version})`, - Connection: 'keep-alive' - }, - proxy: gyp.opts.proxy, - noProxy: gyp.opts.noproxy - } - - const cafile = gyp.opts.cafile - if (cafile) { - requestOpts.ca = await readCAFile(cafile) - } - - const res = await fetch(url, requestOpts) - log.http(res.status, res.url) - - return res -} - -async function readCAFile (filename) { - // The CA file can contain multiple certificates so split on certificate - // boundaries. [\S\s]*? is used to match everything including newlines. - const ca = await fs.promises.readFile(filename, 'utf8') - const re = /(-----BEGIN CERTIFICATE-----[\S\s]*?-----END CERTIFICATE-----)/g - return ca.match(re) -} - -module.exports = function (gyp, argv, callback) { - install(fs, gyp, argv).then(callback.bind(undefined, null), callback) -} -module.exports.test = { - download, - install, - readCAFile -} +module.exports = install module.exports.usage = 'Install node development files for the specified node version.' diff --git a/node_modules/node-gyp/lib/list.js b/node_modules/node-gyp/lib/list.js index 405ebc0d88959..36889ad4f71e2 100644 --- a/node_modules/node-gyp/lib/list.js +++ b/node_modules/node-gyp/lib/list.js @@ -1,26 +1,25 @@ 'use strict' -const fs = require('graceful-fs') -const log = require('npmlog') +const fs = require('graceful-fs').promises +const log = require('./log') -function list (gyp, args, callback) { - var devDir = gyp.devDir +async function list (gyp, args) { + const devDir = gyp.devDir log.verbose('list', 'using node-gyp dir:', devDir) - fs.readdir(devDir, onreaddir) - - function onreaddir (err, versions) { - if (err && err.code !== 'ENOENT') { - return callback(err) + let versions = [] + try { + const dir = await fs.readdir(devDir) + if (Array.isArray(dir)) { + versions = dir.filter((v) => v !== 'current') } - - if (Array.isArray(versions)) { - versions = versions.filter(function (v) { return v !== 'current' }) - } else { - versions = [] + } catch (err) { + if (err && err.code !== 'ENOENT') { + throw err } - callback(null, versions) } + + return versions } module.exports = list diff --git a/node_modules/node-gyp/lib/log.js b/node_modules/node-gyp/lib/log.js new file mode 100644 index 0000000000000..36fa2487f5ce1 --- /dev/null +++ b/node_modules/node-gyp/lib/log.js @@ -0,0 +1,168 @@ +'use strict' + +const { log } = require('proc-log') +const { format } = require('util') + +// helper to emit log messages with a predefined prefix +const withPrefix = (prefix) => log.LEVELS.reduce((acc, level) => { + acc[level] = (...args) => log[level](prefix, ...args) + return acc +}, {}) + +// very basic ansi color generator +const COLORS = { + wrap: (str, colors) => { + const codes = colors.filter(c => typeof c === 'number') + return `\x1b[${codes.join(';')}m${str}\x1b[0m` + }, + inverse: 7, + fg: { + black: 30, + red: 31, + green: 32, + yellow: 33, + blue: 34, + magenta: 35, + cyan: 36, + white: 37 + }, + bg: { + black: 40, + red: 41, + green: 42, + yellow: 43, + blue: 44, + magenta: 45, + cyan: 46, + white: 47 + } +} + +class Logger { + #buffer = [] + #paused = null + #level = null + #stream = null + + // ordered from loudest to quietest + #levels = [{ + id: 'silly', + display: 'sill', + style: { inverse: true } + }, { + id: 'verbose', + display: 'verb', + style: { fg: 'cyan', bg: 'black' } + }, { + id: 'info', + style: { fg: 'green' } + }, { + id: 'http', + style: { fg: 'green', bg: 'black' } + }, { + id: 'notice', + style: { fg: 'cyan', bg: 'black' } + }, { + id: 'warn', + display: 'WARN', + style: { fg: 'black', bg: 'yellow' } + }, { + id: 'error', + display: 'ERR!', + style: { fg: 'red', bg: 'black' } + }] + + constructor (stream) { + process.on('log', (...args) => this.#onLog(...args)) + this.#levels = new Map(this.#levels.map((level, index) => [level.id, { ...level, index }])) + this.level = 'info' + this.stream = stream + log.pause() + } + + get stream () { + return this.#stream + } + + set stream (stream) { + this.#stream = stream + } + + get level () { + return this.#levels.get(this.#level) ?? null + } + + set level (level) { + this.#level = this.#levels.get(level)?.id ?? null + } + + isVisible (level) { + return this.level?.index <= this.#levels.get(level)?.index ?? -1 + } + + #onLog (...args) { + const [level] = args + + if (level === 'pause') { + this.#paused = true + return + } + + if (level === 'resume') { + this.#paused = false + this.#buffer.forEach((b) => this.#log(...b)) + this.#buffer.length = 0 + return + } + + if (this.#paused) { + this.#buffer.push(args) + return + } + + this.#log(...args) + } + + #color (str, { fg, bg, inverse }) { + if (!this.#stream?.isTTY) { + return str + } + + return COLORS.wrap(str, [ + COLORS.fg[fg], + COLORS.bg[bg], + inverse && COLORS.inverse + ]) + } + + #log (levelId, msgPrefix, ...args) { + if (!this.isVisible(levelId) || typeof this.#stream?.write !== 'function') { + return + } + + const level = this.#levels.get(levelId) + + const prefixParts = [ + this.#color('gyp', { fg: 'white', bg: 'black' }), + this.#color(level.display ?? level.id, level.style) + ] + if (msgPrefix) { + prefixParts.push(this.#color(msgPrefix, { fg: 'magenta' })) + } + + const prefix = prefixParts.join(' ').trim() + ' ' + const lines = format(...args).split(/\r?\n/).map(l => prefix + l.trim()) + + this.#stream.write(lines.join('\n') + '\n') + } +} + +// used to suppress logs in tests +const NULL_LOGGER = !!process.env.NODE_GYP_NULL_LOGGER + +module.exports = { + logger: new Logger(NULL_LOGGER ? null : process.stderr), + stdout: NULL_LOGGER ? () => {} : (...args) => console.log(...args), + withPrefix, + ...log +} diff --git a/node_modules/node-gyp/lib/node-gyp.js b/node_modules/node-gyp/lib/node-gyp.js index e492ec1026d9d..dafce99d49e35 100644 --- a/node_modules/node-gyp/lib/node-gyp.js +++ b/node_modules/node-gyp/lib/node-gyp.js @@ -2,10 +2,10 @@ const path = require('path') const nopt = require('nopt') -const log = require('npmlog') +const log = require('./log') const childProcess = require('child_process') -const EE = require('events').EventEmitter -const inherits = require('util').inherits +const { EventEmitter } = require('events') + const commands = [ // Module build commands 'build', @@ -17,199 +17,183 @@ const commands = [ 'list', 'remove' ] -const aliases = { - ls: 'list', - rm: 'remove' -} - -// differentiate node-gyp's logs from npm's -log.heading = 'gyp' - -function gyp () { - return new Gyp() -} -function Gyp () { - var self = this +class Gyp extends EventEmitter { + /** + * Export the contents of the package.json. + */ + package = require('../package.json') + + /** + * nopt configuration definitions + */ + configDefs = { + help: Boolean, // everywhere + arch: String, // 'configure' + cafile: String, // 'install' + debug: Boolean, // 'build' + directory: String, // bin + make: String, // 'build' + 'msvs-version': String, // 'configure' + ensure: Boolean, // 'install' + solution: String, // 'build' (windows only) + proxy: String, // 'install' + noproxy: String, // 'install' + devdir: String, // everywhere + nodedir: String, // 'configure' + loglevel: String, // everywhere + python: String, // 'configure' + 'dist-url': String, // 'install' + tarball: String, // 'install' + jobs: String, // 'build' + thin: String, // 'configure' + 'force-process-config': Boolean // 'configure' + } - this.devDir = '' - this.commands = {} + /** + * nopt shorthands + */ + shorthands = { + release: '--no-debug', + C: '--directory', + debug: '--debug', + j: '--jobs', + silly: '--loglevel=silly', + verbose: '--loglevel=verbose', + silent: '--loglevel=silent' + } - commands.forEach(function (command) { - self.commands[command] = function (argv, callback) { - log.verbose('command', command, argv) - return require('./' + command)(self, argv, callback) - } - }) -} -inherits(Gyp, EE) -exports.Gyp = Gyp -var proto = Gyp.prototype - -/** - * Export the contents of the package.json. - */ - -proto.package = require('../package.json') - -/** - * nopt configuration definitions - */ - -proto.configDefs = { - help: Boolean, // everywhere - arch: String, // 'configure' - cafile: String, // 'install' - debug: Boolean, // 'build' - directory: String, // bin - make: String, // 'build' - msvs_version: String, // 'configure' - ensure: Boolean, // 'install' - solution: String, // 'build' (windows only) - proxy: String, // 'install' - noproxy: String, // 'install' - devdir: String, // everywhere - nodedir: String, // 'configure' - loglevel: String, // everywhere - python: String, // 'configure' - 'dist-url': String, // 'install' - tarball: String, // 'install' - jobs: String, // 'build' - thin: String, // 'configure' - 'force-process-config': Boolean // 'configure' -} + /** + * expose the command aliases for the bin file to use. + */ + aliases = { + ls: 'list', + rm: 'remove' + } -/** - * nopt shorthands - */ - -proto.shorthands = { - release: '--no-debug', - C: '--directory', - debug: '--debug', - j: '--jobs', - silly: '--loglevel=silly', - verbose: '--loglevel=verbose', - silent: '--loglevel=silent' -} + constructor (...args) { + super(...args) -/** - * expose the command aliases for the bin file to use. - */ + this.devDir = '' -proto.aliases = aliases + this.commands = commands.reduce((acc, command) => { + acc[command] = (argv) => require('./' + command)(this, argv) + return acc + }, {}) -/** - * Parses the given argv array and sets the 'opts', - * 'argv' and 'command' properties. - */ + Object.defineProperty(this, 'version', { + enumerable: true, + get: function () { return this.package.version } + }) + } -proto.parseArgv = function parseOpts (argv) { - this.opts = nopt(this.configDefs, this.shorthands, argv) - this.argv = this.opts.argv.remain.slice() + /** + * Parses the given argv array and sets the 'opts', + * 'argv' and 'command' properties. + */ + parseArgv (argv) { + this.opts = nopt(this.configDefs, this.shorthands, argv) + this.argv = this.opts.argv.remain.slice() - var commands = this.todo = [] + const commands = this.todo = [] - // create a copy of the argv array with aliases mapped - argv = this.argv.map(function (arg) { + // create a copy of the argv array with aliases mapped + argv = this.argv.map((arg) => { // is this an alias? - if (arg in this.aliases) { - arg = this.aliases[arg] - } - return arg - }, this) - - // process the mapped args into "command" objects ("name" and "args" props) - argv.slice().forEach(function (arg) { - if (arg in this.commands) { - var args = argv.splice(0, argv.indexOf(arg)) - argv.shift() - if (commands.length > 0) { - commands[commands.length - 1].args = args + if (arg in this.aliases) { + arg = this.aliases[arg] } - commands.push({ name: arg, args: [] }) + return arg + }) + + // process the mapped args into "command" objects ("name" and "args" props) + argv.slice().forEach((arg) => { + if (arg in this.commands) { + const args = argv.splice(0, argv.indexOf(arg)) + argv.shift() + if (commands.length > 0) { + commands[commands.length - 1].args = args + } + commands.push({ name: arg, args: [] }) + } + }) + if (commands.length > 0) { + commands[commands.length - 1].args = argv.splice(0) } - }, this) - if (commands.length > 0) { - commands[commands.length - 1].args = argv.splice(0) - } - // support for inheriting config env variables from npm - var npmConfigPrefix = 'npm_config_' - Object.keys(process.env).forEach(function (name) { - if (name.indexOf(npmConfigPrefix) !== 0) { - return - } - var val = process.env[name] - if (name === npmConfigPrefix + 'loglevel') { - log.level = val - } else { + // support for inheriting config env variables from npm + // npm will set environment variables in the following forms: + // - `npm_config_<key>` for values from npm's own config. Setting arbitrary + // options on npm's config was deprecated in npm v11 but node-gyp still + // supports it for backwards compatibility. + // See https://github.com/nodejs/node-gyp/issues/3156 + // - `npm_package_config_node_gyp_<key>` for values from the `config` object + // in package.json. This is the preferred way to set options for node-gyp + // since npm v11. The `node_gyp_` prefix is used to avoid conflicts with + // other tools. + // The `npm_package_config_node_gyp_` prefix will take precedence over + // `npm_config_` keys. + const npmConfigPrefix = /^npm_config_/i + const npmPackageConfigPrefix = /^npm_package_config_node_gyp_/i + + const configEnvKeys = Object.keys(process.env) + .filter((k) => npmConfigPrefix.test(k) || npmPackageConfigPrefix.test(k)) + // sort so that npm_package_config_node_gyp_ keys come last and will override + .sort((a) => npmConfigPrefix.test(a) ? -1 : 1) + + for (const key of configEnvKeys) { // add the user-defined options to the config - name = name.substring(npmConfigPrefix.length) + const name = npmConfigPrefix.test(key) + ? key.replace(npmConfigPrefix, '') + : key.replace(npmPackageConfigPrefix, '') // gyp@741b7f1 enters an infinite loop when it encounters // zero-length options so ensure those don't get through. if (name) { // convert names like force_process_config to force-process-config - if (name.includes('_')) { - name = name.replace(/_/g, '-') - } - this.opts[name] = val + // and convert to lowercase + this.opts[name.replaceAll('_', '-').toLowerCase()] = process.env[key] } } - }, this) - if (this.opts.loglevel) { - log.level = this.opts.loglevel + if (this.opts.loglevel) { + log.logger.level = this.opts.loglevel + delete this.opts.loglevel + } + log.resume() } - log.resume() -} - -/** - * Spawns a child process and emits a 'spawn' event. - */ -proto.spawn = function spawn (command, args, opts) { - if (!opts) { - opts = {} - } - if (!opts.silent && !opts.stdio) { - opts.stdio = [0, 1, 2] + /** + * Spawns a child process and emits a 'spawn' event. + */ + spawn (command, args, opts) { + if (!opts) { + opts = {} + } + if (!opts.silent && !opts.stdio) { + opts.stdio = [0, 1, 2] + } + const cp = childProcess.spawn(command, args, opts) + log.info('spawn', command) + log.info('spawn args', args) + return cp } - var cp = childProcess.spawn(command, args, opts) - log.info('spawn', command) - log.info('spawn args', args) - return cp -} -/** - * Returns the usage instructions for node-gyp. - */ - -proto.usage = function usage () { - var str = [ - '', - ' Usage: node-gyp <command> [options]', - '', - ' where <command> is one of:', - commands.map(function (c) { - return ' - ' + c + ' - ' + require('./' + c).usage - }).join('\n'), - '', - 'node-gyp@' + this.version + ' ' + path.resolve(__dirname, '..'), - 'node@' + process.versions.node - ].join('\n') - return str + /** + * Returns the usage instructions for node-gyp. + */ + usage () { + return [ + '', + ' Usage: node-gyp <command> [options]', + '', + ' where <command> is one of:', + commands.map((c) => ' - ' + c + ' - ' + require('./' + c).usage).join('\n'), + '', + 'node-gyp@' + this.version + ' ' + path.resolve(__dirname, '..'), + 'node@' + process.versions.node + ].join('\n') + } } -/** - * Version number getter. - */ - -Object.defineProperty(proto, 'version', { - get: function () { - return this.package.version - }, - enumerable: true -}) - -module.exports = exports = gyp +module.exports = () => new Gyp() +module.exports.Gyp = Gyp diff --git a/node_modules/node-gyp/lib/process-release.js b/node_modules/node-gyp/lib/process-release.js index 95b55e4426dee..b92e8d5b83312 100644 --- a/node_modules/node-gyp/lib/process-release.js +++ b/node_modules/node-gyp/lib/process-release.js @@ -1,11 +1,11 @@ -/* eslint-disable node/no-deprecated-api */ +/* eslint-disable n/no-deprecated-api */ 'use strict' const semver = require('semver') const url = require('url') const path = require('path') -const log = require('npmlog') +const log = require('./log') // versions where -headers.tar.gz started shipping const headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42' @@ -17,29 +17,28 @@ const bitsreV3 = /\/win-(x86|ia32|x64)\// // io.js v3.x.x shipped with "ia32" bu // file names. Inputs come from command-line switches (--target, --dist-url), // `process.version` and `process.release` where it exists. function processRelease (argv, gyp, defaultVersion, defaultRelease) { - var version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion - var versionSemver = semver.parse(version) - var overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl - var isDefaultVersion - var isNamedForLegacyIojs - var name - var distBaseUrl - var baseUrl - var libUrl32 - var libUrl64 - var libUrlArm64 - var tarballUrl - var canGetHeaders + let version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion + const versionSemver = semver.parse(version) + let overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl + let isNamedForLegacyIojs + let name + let distBaseUrl + let baseUrl + let libUrl32 + let libUrl64 + let libUrlArm64 + let tarballUrl + let canGetHeaders if (!versionSemver) { // not a valid semver string, nothing we can do - return { version: version } + return { version } } // flatten version into String version = versionSemver.version // defaultVersion should come from process.version so ought to be valid semver - isDefaultVersion = version === semver.parse(defaultVersion).version + const isDefaultVersion = version === semver.parse(defaultVersion).version // can't use process.release if we're using --target=x.y.z if (!isDefaultVersion) { @@ -101,24 +100,24 @@ function processRelease (argv, gyp, defaultVersion, defaultRelease) { } return { - version: version, + version, semver: versionSemver, - name: name, - baseUrl: baseUrl, - tarballUrl: tarballUrl, + name, + baseUrl, + tarballUrl, shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'), versionDir: (name !== 'node' ? name + '-' : '') + version, ia32: { libUrl: libUrl32, - libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl32).path)) + libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrl32).pathname)) }, x64: { libUrl: libUrl64, - libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl64).path)) + libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrl64).pathname)) }, arm64: { libUrl: libUrlArm64, - libPath: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrlArm64).path)) + libPath: normalizePath(path.relative(new URL(baseUrl).pathname, new URL(libUrlArm64).pathname)) } } } @@ -128,8 +127,8 @@ function normalizePath (p) { } function resolveLibUrl (name, defaultUrl, arch, versionMajor) { - var base = url.resolve(defaultUrl, './') - var hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl)) + const base = url.resolve(defaultUrl, './') + const hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl)) if (!hasLibUrl) { // let's assume it's a baseUrl then diff --git a/node_modules/node-gyp/lib/rebuild.js b/node_modules/node-gyp/lib/rebuild.js index a1c5b27cbe56a..609817665e2db 100644 --- a/node_modules/node-gyp/lib/rebuild.js +++ b/node_modules/node-gyp/lib/rebuild.js @@ -1,12 +1,11 @@ 'use strict' -function rebuild (gyp, argv, callback) { +async function rebuild (gyp, argv) { gyp.todo.push( { name: 'clean', args: [] } , { name: 'configure', args: argv } , { name: 'build', args: [] } ) - process.nextTick(callback) } module.exports = rebuild diff --git a/node_modules/node-gyp/lib/remove.js b/node_modules/node-gyp/lib/remove.js index 8c945e5659001..55736f71d97c5 100644 --- a/node_modules/node-gyp/lib/remove.js +++ b/node_modules/node-gyp/lib/remove.js @@ -1,46 +1,43 @@ 'use strict' -const fs = require('fs') -const rm = require('rimraf') +const fs = require('graceful-fs').promises const path = require('path') -const log = require('npmlog') +const log = require('./log') const semver = require('semver') -function remove (gyp, argv, callback) { - var devDir = gyp.devDir +async function remove (gyp, argv) { + const devDir = gyp.devDir log.verbose('remove', 'using node-gyp dir:', devDir) // get the user-specified version to remove - var version = argv[0] || gyp.opts.target + let version = argv[0] || gyp.opts.target log.verbose('remove', 'removing target version:', version) if (!version) { - return callback(new Error('You must specify a version number to remove. Ex: "' + process.version + '"')) + throw new Error('You must specify a version number to remove. Ex: "' + process.version + '"') } - var versionSemver = semver.parse(version) + const versionSemver = semver.parse(version) if (versionSemver) { // flatten the version Array into a String version = versionSemver.version } - var versionPath = path.resolve(gyp.devDir, version) + const versionPath = path.resolve(gyp.devDir, version) log.verbose('remove', 'removing development files for version:', version) // first check if its even installed - fs.stat(versionPath, function (err) { - if (err) { - if (err.code === 'ENOENT') { - callback(null, 'version was already uninstalled: ' + version) - } else { - callback(err) - } - return + try { + await fs.stat(versionPath) + } catch (err) { + if (err.code === 'ENOENT') { + return 'version was already uninstalled: ' + version } - // Go ahead and delete the dir - rm(versionPath, callback) - }) + throw err + } + + await fs.rm(versionPath, { recursive: true, force: true, maxRetries: 3 }) } -module.exports = exports = remove +module.exports = remove module.exports.usage = 'Removes the node development files for the specified version' diff --git a/node_modules/node-gyp/lib/util.js b/node_modules/node-gyp/lib/util.js index 3e23c628e6ad7..3f6aeeb7dcb43 100644 --- a/node_modules/node-gyp/lib/util.js +++ b/node_modules/node-gyp/lib/util.js @@ -1,64 +1,81 @@ 'use strict' -const log = require('npmlog') -const execFile = require('child_process').execFile +const cp = require('child_process') const path = require('path') +const { openSync, closeSync } = require('graceful-fs') +const log = require('./log') -function logWithPrefix (log, prefix) { - function setPrefix (logFunction) { - return (...args) => logFunction.apply(null, [ prefix, ...args ]) // eslint-disable-line - } - return { - silly: setPrefix(log.silly), - verbose: setPrefix(log.verbose), - info: setPrefix(log.info), - warn: setPrefix(log.warn), - error: setPrefix(log.error) - } -} +const execFile = async (...args) => new Promise((resolve) => { + const child = cp.execFile(...args, (...a) => resolve(a)) + child.stdin.end() +}) -function regGetValue (key, value, addOpts, cb) { +async function regGetValue (key, value, addOpts) { const outReValue = value.replace(/\W/g, '.') const outRe = new RegExp(`^\\s+${outReValue}\\s+REG_\\w+\\s+(\\S.*)$`, 'im') const reg = path.join(process.env.SystemRoot, 'System32', 'reg.exe') const regArgs = ['query', key, '/v', value].concat(addOpts) log.silly('reg', 'running', reg, regArgs) - const child = execFile(reg, regArgs, { encoding: 'utf8' }, - function (err, stdout, stderr) { - log.silly('reg', 'reg.exe stdout = %j', stdout) - if (err || stderr.trim() !== '') { - log.silly('reg', 'reg.exe err = %j', err && (err.stack || err)) - log.silly('reg', 'reg.exe stderr = %j', stderr) - return cb(err, stderr) - } + const [err, stdout, stderr] = await execFile(reg, regArgs, { encoding: 'utf8' }) - const result = outRe.exec(stdout) - if (!result) { - log.silly('reg', 'error parsing stdout') - return cb(new Error('Could not parse output of reg.exe')) - } - log.silly('reg', 'found: %j', result[1]) - cb(null, result[1]) - }) - child.stdin.end() + log.silly('reg', 'reg.exe stdout = %j', stdout) + if (err || stderr.trim() !== '') { + log.silly('reg', 'reg.exe err = %j', err && (err.stack || err)) + log.silly('reg', 'reg.exe stderr = %j', stderr) + if (err) { + throw err + } + throw new Error(stderr) + } + + const result = outRe.exec(stdout) + if (!result) { + log.silly('reg', 'error parsing stdout') + throw new Error('Could not parse output of reg.exe') + } + + log.silly('reg', 'found: %j', result[1]) + return result[1] +} + +async function regSearchKeys (keys, value, addOpts) { + for (const key of keys) { + try { + return await regGetValue(key, value, addOpts) + } catch { + continue + } + } } -function regSearchKeys (keys, value, addOpts, cb) { - var i = 0 - const search = () => { - log.silly('reg-search', 'looking for %j in %j', value, keys[i]) - regGetValue(keys[i], value, addOpts, (err, res) => { - ++i - if (err && i < keys.length) { return search() } - cb(err, res) - }) +/** + * Returns the first file or directory from an array of candidates that is + * readable by the current user, or undefined if none of the candidates are + * readable. + */ +function findAccessibleSync (logprefix, dir, candidates) { + for (let next = 0; next < candidates.length; next++) { + const candidate = path.resolve(dir, candidates[next]) + let fd + try { + fd = openSync(candidate, 'r') + } catch (e) { + // this candidate was not found or not readable, do nothing + log.silly(logprefix, 'Could not open %s: %s', candidate, e.message) + continue + } + closeSync(fd) + log.silly(logprefix, 'Found readable %s', candidate) + return candidate } - search() + + return undefined } module.exports = { - logWithPrefix: logWithPrefix, - regGetValue: regGetValue, - regSearchKeys: regSearchKeys + execFile, + regGetValue, + regSearchKeys, + findAccessibleSync } diff --git a/node_modules/node-gyp/macOS_Catalina.md b/node_modules/node-gyp/macOS_Catalina.md deleted file mode 100644 index 4fe0f29b21eb5..0000000000000 --- a/node_modules/node-gyp/macOS_Catalina.md +++ /dev/null @@ -1,104 +0,0 @@ -# Installation notes for macOS Catalina (v10.15) - -_This document specifically refers to upgrades from previous versions of macOS to Catalina (10.15). It should be removed from the source repository when Catalina ceases to be the latest macOS version or when future Catalina versions no longer raise these issues._ - -**Both upgrading to macOS Catalina and running a Software Update in Catalina may cause normal `node-gyp` installations to fail. This might manifest as the following error during `npm install`:** - -```console -gyp: No Xcode or CLT version detected! -``` - -## node-gyp v7 - -The newest release of `node-gyp` should solve this problem. If you are using `node-gyp` directly then you should be able to install v7 and use it as-is. - -If you need to use `node-gyp` from within `npm` (e.g. through `npm install`), you will have to install `node-gyp` (either globally with `-g` or to a predictable location) and tell `npm` where the new version is. Either use: - -* `npm config set node_gyp <path to node-gyp>`; or -* run `npm` with an environment variable prefix: `npm_config_node_gyp=<path to node-gyp> npm install` - -Where "path to node-gyp" is to the `node-gyp` executable which may be a symlink in your global bin directory (e.g. `/usr/local/bin/node-gyp`), or a path to the `node-gyp` installation directory and the `bin/node-gyp.js` file within it (e.g. `/usr/local/lib/node_modules/node-gyp/bin/node-gyp.js`). - -**If you use `npm config set` to change your global `node_gyp` you are responsible for keeping it up to date and can't rely on `npm` to give you a newer version when available.** Use `npm config delete node_gyp` to unset this configuration option. - -## Fixing Catalina for older versions of `node-gyp` - -### Is my Mac running macOS Catalina? -Let's first make sure that your Mac is running Catalina: -``` -% sw_vers - ProductName: Mac OS X - ProductVersion: 10.15 - BuildVersion: 19A602 -``` -If `ProductVersion` is less then `10.15` then this document is not for you. Normal install docs for `node-gyp` on macOS can be found at https://github.com/nodejs/node-gyp#on-macos - - -### The acid test -To see if `Xcode Command Line Tools` is installed in a way that will work with `node-gyp`, run: -``` -curl -sL https://github.com/nodejs/node-gyp/raw/master/macOS_Catalina_acid_test.sh | bash -``` - -If test succeeded, _you are done_! You should be ready to [install](https://github.com/nodejs/node-gyp#installation) `node-gyp`. - -If test failed, there is a problem with your Xcode Command Line Tools installation. [Continue to Solutions](#Solutions). - -### Solutions -There are three ways to install the Xcode libraries `node-gyp` needs on macOS. People running Catalina have had success with some but not others in a way that has been unpredictable. - -1. With the full Xcode (~7.6 GB download) from the `App Store` app. -2. With the _much_ smaller Xcode Command Line Tools via `xcode-select --install` -3. With the _much_ smaller Xcode Command Line Tools via manual download. **For people running the latest version of Catalina (10.15.2 at the time of this writing), this has worked when the other two solutions haven't.** - -### Installing `node-gyp` using the full Xcode -1. `xcodebuild -version` should show `Xcode 11.1` or later. - * If not, then install/upgrade Xcode from the App Store app. -2. Open the Xcode app and... - * Under __Preferences > Locations__ select the tools if their location is empty. - * Allow Xcode app to do an essential install of the most recent compiler tools. -3. Once all installations are _complete_, quit out of Xcode. -4. `sudo xcodebuild -license accept` # If you agree with the licensing terms. -5. `softwareupdate -l` # No listing is a good sign. - * If Xcode or Tools upgrades are listed, use "Software Upgrade" to install them. -6. `xcode-select -version` # Should return `xcode-select version 2370` or later. -7. `xcode-select -print-path` # Should return `/Applications/Xcode.app/Contents/Developer` -8. Try the [_acid test_ steps above](#The-acid-test) to see if your Mac is ready. -9. If the _acid test_ does _not_ pass then... -10. `sudo xcode-select --reset` # Enter root password. No output is normal. -11. Repeat step 7 above. Is the path different this time? Repeat the _acid test_. - -### Installing `node-gyp` using the Xcode Command Line Tools via `xcode-select --install` -1. If the _acid test_ has not succeeded, then try `xcode-select --install` -2. If the installation command returns `xcode-select: error: command line tools are already installed, use "Software Update" to install updates`, continue to [remove and reinstall](#i-did-all-that-and-the-acid-test-still-does-not-pass--) -3. Wait until the install process is _complete_. -4. `softwareupdate -l` # No listing is a good sign. - * If Xcode or Tools upgrades are listed, use "Software Update" to install them. -5. `xcode-select -version` # Should return `xcode-select version 2370` or later. -6. `xcode-select -print-path` # Should return `/Library/Developer/CommandLineTools` -7. Try the [_acid test_ steps above](#The-acid-test) to see if your Mac is ready. -8. If the _acid test_ does _not_ pass then... -9. `sudo xcode-select --reset` # Enter root password. No output is normal. -10. Repeat step 5 above. Is the path different this time? Repeat the _acid test_. - -### Installing `node-gyp` using the Xcode Command Line Tools via manual download -1. Download the appropriate version of the "Command Line Tools for Xcode" for your version of Catalina from <https://developer.apple.com/download/more/>. As of MacOS 10.15.5, that's [Command_Line_Tools_for_Xcode_11.5.dmg](https://download.developer.apple.com/Developer_Tools/Command_Line_Tools_for_Xcode_11.5/Command_Line_Tools_for_Xcode_11.5.dmg) -2. Install the package. -3. Run the [_acid test_ steps above](#The-acid-test). - -### I did all that and the acid test still does not pass :-( -1. `sudo rm -rf $(xcode-select -print-path)` # Enter root password. No output is normal. -2. `sudo rm -rf /Library/Developer/CommandLineTools` # Enter root password. -3. `sudo xcode-select --reset` -4. `xcode-select --install` -5. If the [_acid test_ steps above](#The-acid-test) still does _not_ pass then... -6. `npm explore npm -g -- npm install node-gyp@latest` -7. `npm explore npm -g -- npm explore npm-lifecycle -- npm install node-gyp@latest` -8. If the _acid test_ still does _not_ pass then... -9. Add a comment to https://github.com/nodejs/node-gyp/issues/1927 so we can improve. - -Lessons learned from: -* https://github.com/nodejs/node-gyp/issues/1779 -* https://github.com/nodejs/node-gyp/issues/1861 -* https://github.com/nodejs/node-gyp/issues/1927 and elsewhere -* Thanks to @rrrix for discovering Solution 3 diff --git a/node_modules/node-gyp/node_modules/brace-expansion/LICENSE b/node_modules/node-gyp/node_modules/brace-expansion/LICENSE deleted file mode 100644 index de3226673c387..0000000000000 --- a/node_modules/node-gyp/node_modules/brace-expansion/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/node_modules/node-gyp/node_modules/brace-expansion/index.js b/node_modules/node-gyp/node_modules/brace-expansion/index.js deleted file mode 100644 index 0478be81eabc2..0000000000000 --- a/node_modules/node-gyp/node_modules/brace-expansion/index.js +++ /dev/null @@ -1,201 +0,0 @@ -var concatMap = require('concat-map'); -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - diff --git a/node_modules/node-gyp/node_modules/brace-expansion/package.json b/node_modules/node-gyp/node_modules/brace-expansion/package.json deleted file mode 100644 index a18faa8fd67b8..0000000000000 --- a/node_modules/node-gyp/node_modules/brace-expansion/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "brace-expansion", - "description": "Brace expansion as known from sh/bash", - "version": "1.1.11", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/brace-expansion.git" - }, - "homepage": "https://github.com/juliangruber/brace-expansion", - "main": "index.js", - "scripts": { - "test": "tape test/*.js", - "gentest": "bash test/generate.sh", - "bench": "matcha test/perf/bench.js" - }, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "keywords": [], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/node_modules/node-gyp/node_modules/glob/LICENSE b/node_modules/node-gyp/node_modules/glob/LICENSE deleted file mode 100644 index 42ca266df1d52..0000000000000 --- a/node_modules/node-gyp/node_modules/glob/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -## Glob Logo - -Glob's logo created by Tanya Brassie <http://tanyabrassie.com/>, licensed -under a Creative Commons Attribution-ShareAlike 4.0 International License -https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/node-gyp/node_modules/glob/common.js b/node_modules/node-gyp/node_modules/glob/common.js deleted file mode 100644 index 424c46e1dab1b..0000000000000 --- a/node_modules/node-gyp/node_modules/glob/common.js +++ /dev/null @@ -1,238 +0,0 @@ -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var fs = require("fs") -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") -var Minimatch = minimatch.Minimatch - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - self.fs = options.fs || fs - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = false - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} diff --git a/node_modules/node-gyp/node_modules/glob/glob.js b/node_modules/node-gyp/node_modules/glob/glob.js deleted file mode 100644 index 37a4d7e60775a..0000000000000 --- a/node_modules/node-gyp/node_modules/glob/glob.js +++ /dev/null @@ -1,790 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var globSync = require('./sync.js') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {<filename>: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) - e = abs - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - self.fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - self.fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - self.fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return self.fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -} diff --git a/node_modules/node-gyp/node_modules/glob/package.json b/node_modules/node-gyp/node_modules/glob/package.json deleted file mode 100644 index 5940b649b7e65..0000000000000 --- a/node_modules/node-gyp/node_modules/glob/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "name": "glob", - "description": "a little globber", - "version": "7.2.3", - "publishConfig": { - "tag": "v7-legacy" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "main": "glob.js", - "files": [ - "glob.js", - "sync.js", - "common.js" - ], - "engines": { - "node": "*" - }, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "devDependencies": { - "memfs": "^3.2.0", - "mkdirp": "0", - "rimraf": "^2.2.8", - "tap": "^15.0.6", - "tick": "0.0.6" - }, - "tap": { - "before": "test/00-setup.js", - "after": "test/zz-cleanup.js", - "jobs": 1 - }, - "scripts": { - "prepublish": "npm run benchclean", - "profclean": "rm -f v8.log profile.txt", - "test": "tap", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", - "bench": "bash benchmark.sh", - "prof": "bash prof.sh && cat profile.txt", - "benchclean": "node benchclean.js" - }, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } -} diff --git a/node_modules/node-gyp/node_modules/glob/sync.js b/node_modules/node-gyp/node_modules/glob/sync.js deleted file mode 100644 index 2c4f480192d28..0000000000000 --- a/node_modules/node-gyp/node_modules/glob/sync.js +++ /dev/null @@ -1,486 +0,0 @@ -module.exports = globSync -globSync.GlobSync = GlobSync - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert.ok(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert.ok(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) { - e = abs - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, this.fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = this.fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} diff --git a/node_modules/node-gyp/node_modules/minimatch/LICENSE b/node_modules/node-gyp/node_modules/minimatch/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/node-gyp/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/node-gyp/node_modules/minimatch/minimatch.js b/node_modules/node-gyp/node_modules/minimatch/minimatch.js deleted file mode 100644 index fda45ade7cfc3..0000000000000 --- a/node_modules/node-gyp/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,947 +0,0 @@ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = (function () { try { return require('path') } catch (e) {}}()) || { - sep: '/' -} -minimatch.sep = path.sep - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - b = b || {} - var t = {} - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch - } - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - m.Minimatch.defaults = function defaults (options) { - return orig.defaults(ext(def, options)).Minimatch - } - - m.filter = function filter (pattern, options) { - return orig.filter(pattern, ext(def, options)) - } - - m.defaults = function defaults (options) { - return orig.defaults(ext(def, options)) - } - - m.makeRe = function makeRe (pattern, options) { - return orig.makeRe(pattern, ext(def, options)) - } - - m.braceExpand = function braceExpand (pattern, options) { - return orig.braceExpand(pattern, ext(def, options)) - } - - m.match = function (list, pattern, options) { - return orig.match(list, pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - assertValidPattern(pattern) - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - assertValidPattern(pattern) - - if (!options) options = {} - - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (!options.allowWindowsEscape && path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - this.partial = !!options.partial - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - assertValidPattern(pattern) - - // Thanks to Yeting Li <https://github.com/yetingli> for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -var MAX_PATTERN_LENGTH = 1024 * 64 -var assertValidPattern = function (pattern) { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern') - } - - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long') - } -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - assertValidPattern(pattern) - - var options = this.options - - // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR - else - pattern = '*' - } - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - /* istanbul ignore next */ - case '/': { - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - } - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:<pattern>)<type> - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '[': case '.': case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) /* istanbul ignore next - should be impossible */ { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) /* istanbul ignore next - should be impossible */ { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = function match (f, partial) { - if (typeof partial === 'undefined') partial = this.partial - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - /* istanbul ignore if */ - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - /* istanbul ignore if */ - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - hit = f === p - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else /* istanbul ignore else */ if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - return (fi === fl - 1) && (file[fi] === '') - } - - // should be unreachable. - /* istanbul ignore next */ - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} diff --git a/node_modules/node-gyp/node_modules/minimatch/package.json b/node_modules/node-gyp/node_modules/minimatch/package.json deleted file mode 100644 index 566efdfe45cb8..0000000000000 --- a/node_modules/node-gyp/node_modules/minimatch/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "3.1.2", - "publishConfig": { - "tag": "v3-legacy" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "minimatch.js", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "engines": { - "node": "*" - }, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "devDependencies": { - "tap": "^15.1.6" - }, - "license": "ISC", - "files": [ - "minimatch.js" - ] -} diff --git a/node_modules/node-gyp/package.json b/node_modules/node-gyp/package.json index e795db1834538..f5dcf156decf0 100644 --- a/node_modules/node-gyp/package.json +++ b/node_modules/node-gyp/package.json @@ -11,8 +11,8 @@ "bindings", "gyp" ], - "version": "9.0.0", - "installVersion": 9, + "version": "12.2.0", + "installVersion": 11, "author": "Nathan Rajlich <nathan@tootallnate.net> (http://tootallnate.net)", "repository": { "type": "git", @@ -23,28 +23,30 @@ "main": "./lib/node-gyp.js", "dependencies": { "env-paths": "^2.2.0", - "glob": "^7.1.4", + "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "which": "^6.0.0" }, "engines": { - "node": "^12.22 || ^14.13 || >=16" + "node": "^20.17.0 || >=22.9.0" }, "devDependencies": { "bindings": "^1.5.0", - "nan": "^2.14.2", - "require-inject": "^1.4.4", - "standard": "^14.3.4", - "tap": "^12.7.0" + "cross-env": "^10.1.0", + "eslint": "^9.39.1", + "mocha": "^11.7.5", + "nan": "^2.23.1", + "neostandard": "^0.12.2", + "require-inject": "^1.4.4" }, "scripts": { - "lint": "standard */*.js test/**/*.js", - "test": "npm run lint && tap --timeout=120 test/test-*" + "lint": "eslint \"*/*.js\" \"test/**/*.js\" \".github/**/*.js\"", + "test": "cross-env NODE_GYP_NULL_LOGGER=true mocha --timeout 30000 test/test-download.js test/test-*" } } diff --git a/node_modules/node-gyp/release-please-config.json b/node_modules/node-gyp/release-please-config.json new file mode 100644 index 0000000000000..94b8f8110e881 --- /dev/null +++ b/node_modules/node-gyp/release-please-config.json @@ -0,0 +1,40 @@ +{ + "packages": { + ".": { + "include-component-in-tag": false, + "release-type": "node", + "changelog-sections": [ + { "type": "feat", "section": "Features", "hidden": false }, + { "type": "fix", "section": "Bug Fixes", "hidden": false }, + { "type": "bin", "section": "Core", "hidden": false }, + { "type": "gyp", "section": "Core", "hidden": false }, + { "type": "lib", "section": "Core", "hidden": false }, + { "type": "src", "section": "Core", "hidden": false }, + { "type": "test", "section": "Tests", "hidden": false }, + { "type": "build", "section": "Core", "hidden": false }, + { "type": "clean", "section": "Core", "hidden": false }, + { "type": "configure", "section": "Core", "hidden": false }, + { "type": "install", "section": "Core", "hidden": false }, + { "type": "list", "section": "Core", "hidden": false }, + { "type": "rebuild", "section": "Core", "hidden": false }, + { "type": "remove", "section": "Core", "hidden": false }, + { "type": "deps", "section": "Core", "hidden": false }, + { "type": "python", "section": "Core", "hidden": false }, + { "type": "lin", "section": "Core", "hidden": false }, + { "type": "linux", "section": "Core", "hidden": false }, + { "type": "mac", "section": "Core", "hidden": false }, + { "type": "macos", "section": "Core", "hidden": false }, + { "type": "win", "section": "Core", "hidden": false }, + { "type": "windows", "section": "Core", "hidden": false }, + { "type": "zos", "section": "Core", "hidden": false }, + { "type": "doc", "section": "Doc", "hidden": false }, + { "type": "docs", "section": "Doc", "hidden": false }, + { "type": "readme", "section": "Doc", "hidden": false }, + { "type": "chore", "section": "Miscellaneous", "hidden": false }, + { "type": "refactor", "section": "Miscellaneous", "hidden": false }, + { "type": "ci", "section": "Miscellaneous", "hidden": false }, + { "type": "meta", "section": "Miscellaneous", "hidden": false } + ] + } + } +} diff --git a/node_modules/node-gyp/src/win_delay_load_hook.cc b/node_modules/node-gyp/src/win_delay_load_hook.cc index 169f8029f10fd..63e197706d466 100644 --- a/node_modules/node-gyp/src/win_delay_load_hook.cc +++ b/node_modules/node-gyp/src/win_delay_load_hook.cc @@ -28,7 +28,9 @@ static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) { if (_stricmp(info->szDll, HOST_BINARY) != 0) return NULL; - m = GetModuleHandle(NULL); + // try for libnode.dll to compat node.js that using 'vcbuild.bat dll' + m = GetModuleHandle(TEXT("libnode.dll")); + if (m == NULL) m = GetModuleHandle(NULL); return (FARPROC) m; } diff --git a/node_modules/node-gyp/test/common.js b/node_modules/node-gyp/test/common.js deleted file mode 100644 index b714ee29029d3..0000000000000 --- a/node_modules/node-gyp/test/common.js +++ /dev/null @@ -1,3 +0,0 @@ -const envPaths = require('env-paths') - -module.exports.devDir = () => envPaths('node-gyp', { suffix: '' }).cache diff --git a/node_modules/node-gyp/test/fixtures/VS_2017_BuildTools_minimal.txt b/node_modules/node-gyp/test/fixtures/VS_2017_BuildTools_minimal.txt deleted file mode 100644 index 244f6b0798240..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2017_BuildTools_minimal.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools","version":"15.9.28307.665","packages":["Microsoft.VisualStudio.Product.BuildTools","Microsoft.VisualStudio.Component.VC.CoreIde","Microsoft.VisualStudio.VC.Ide.Pro","Microsoft.VisualStudio.VC.Ide.Pro.Resources","Microsoft.VisualStudio.VC.Templates.Pro","Microsoft.VisualStudio.VC.Templates.Pro.Resources","Microsoft.VisualStudio.VC.Items.Pro","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Reduced","Microsoft.VisualStudio.VC.Ide.MDD","Microsoft.VisualStudio.VC.Ide.x64","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Express","Microsoft.VisualStudio.PackageGroup.Debugger.Script","Microsoft.VisualStudio.JavaScript.LanguageService","Microsoft.VisualStudio.JavaScript.LanguageService.Resources","Microsoft.VisualStudio.Debugger.Script.Msi","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.VC.Ide.WinXPlus","Microsoft.VisualStudio.VC.Ide.Dskx","Microsoft.VisualStudio.VC.Ide.Dskx.Resources","Microsoft.VisualStudio.VC.Ide.Core","Microsoft.VisualStudio.VC.Ide.Core.Resources","Microsoft.VisualStudio.VC.Ide.Base","Microsoft.VisualStudio.VC.Ide.LanguageService","Microsoft.VisualStudio.VC.Ide.ResourceEditor","Microsoft.VisualStudio.VC.Ide.ResourceEditor.Resources","Microsoft.VisualStudio.VC.Ide.ProjectSystem","Microsoft.VisualStudio.VC.Ide.ProjectSystem.Resources","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine.Resources","Microsoft.VisualStudio.VC.Ide.LanguageService.Resources","Microsoft.VisualStudio.VC.Ide.Base.Resources","Microsoft.VisualStudio.PackageGroup.Core","Microsoft.VisualStudio.TestTools.TeamFoundationClient","Microsoft.VisualStudio.PackageGroup.Debugger.Core","Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost","Microsoft.VisualStudio.VC.Ide.Debugger","Microsoft.VisualStudio.VC.Ide.Debugger.Resources","Microsoft.VisualStudio.VC.Ide.Common","Microsoft.VisualStudio.VC.Ide.Common.Resources","Microsoft.VisualStudio.Debugger.Parallel","Microsoft.VisualStudio.Debugger.Parallel.Resources","Microsoft.VisualStudio.Debugger.CollectionAgents","Microsoft.VisualStudio.Debugger.Managed","Microsoft.CodeAnalysis.VisualStudio.Setup.Resources","Microsoft.CodeAnalysis.VisualStudio.Setup","Microsoft.CodeAnalysis.ExpressionEvaluator.Resources","Microsoft.CodeAnalysis.ExpressionEvaluator","Microsoft.VisualStudio.Debugger.Managed.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger","Microsoft.VisualStudio.VC.MSVCDis","Microsoft.VisualStudio.ScriptedHost","Microsoft.VisualStudio.ScriptedHost.Targeted","Microsoft.VisualStudio.ScriptedHost.Resources","Microsoft.IntelliTrace.DiagnosticsHub","Microsoft.VisualStudio.Debugger.Resources","Microsoft.PackageGroup.ClientDiagnostics","Microsoft.VisualStudio.AppResponsiveness","Microsoft.VisualStudio.AppResponsiveness.Targeted","Microsoft.VisualStudio.AppResponsiveness.Resources","Microsoft.VisualStudio.ClientDiagnostics","Microsoft.VisualStudio.ClientDiagnostics.Targeted","Microsoft.VisualStudio.ClientDiagnostics.Resources","Microsoft.VisualStudio.PackageGroup.CommunityCore","Microsoft.VisualStudio.ProjectSystem.Full","Microsoft.VisualStudio.ProjectSystem","Microsoft.VisualStudio.Community.x86","Microsoft.VisualStudio.Community.x64","Microsoft.VisualStudio.Community","Microsoft.IntelliTrace.CollectorCab","Microsoft.VisualStudio.Community.Resources","Microsoft.VisualStudio.WebSiteProject.DTE","Microsoft.MSHtml","Microsoft.VisualStudio.Community.Msi.Resources","Microsoft.VisualStudio.Community.Msi","Microsoft.VisualStudio.MinShell.Interop.Msi","Microsoft.VisualStudio.PackageGroup.CoreEditor","PortableFacades","Microsoft.VisualStudio.VirtualTree","Microsoft.VisualStudio.PackageGroup.Progression","Microsoft.VisualStudio.PerformanceProvider","Microsoft.VisualStudio.GraphModel","Microsoft.VisualStudio.GraphProvider","Microsoft.DiaSymReader","Microsoft.VisualStudio.TextMateGrammars","Microsoft.VisualStudio.PackageGroup.TeamExplorer","Microsoft.TeamFoundation.OfficeIntegration","Microsoft.TeamFoundation.OfficeIntegration.Resources","Microsoft.VisualStudio.TeamExplorer","Microsoft.ServiceHub","Microsoft.VisualStudio.ProjectServices","Microsoft.VisualStudio.SLNX.VSIX","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.PackageGroup.MinShell","Microsoft.VisualStudio.MinShell.Msi","Microsoft.VisualStudio.MinShell.Msi.Resources","Microsoft.VisualStudio.MinShell.Interop","Microsoft.VisualStudio.Log","Microsoft.VisualStudio.Log.Targeted","Microsoft.VisualStudio.Log.Resources","Microsoft.VisualStudio.Finalizer","Microsoft.VisualStudio.CoreEditor","Microsoft.VisualStudio.Connected","Microsoft.VisualStudio.Connected.Resources","Microsoft.VisualStudio.MinShell","Microsoft.VisualStudio.MinShell.Platform","Microsoft.VisualStudio.MinShell.Platform.Resources","Microsoft.VisualStudio.MefHosting","Microsoft.VisualStudio.MefHosting.Resources","Microsoft.VisualStudio.Initializer","Microsoft.VisualStudio.ExtensionManager","Microsoft.VisualStudio.Editors","Microsoft.Net.4.TargetingPack","Microsoft.VisualStudio.Component.Windows10SDK.17134","Win10SDK_10.0.17134","Microsoft.VisualStudio.Component.VC.Tools.x86.x64","Microsoft.VisualCpp.CodeAnalysis.Extensions","Microsoft.VisualCpp.CodeAnalysis.Extensions.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86.Resources","Microsoft.VisualCpp.CodeAnalysis.Extensions.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64.Resources","Microsoft.VisualStudio.Component.Static.Analysis.Tools","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX86","Microsoft.VisualCpp.VCTip.HostX64.TargetX86","Microsoft.VisualCpp.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX64","Microsoft.VisualCpp.VCTip.HostX64.TargetX64","Microsoft.VisualCpp.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX64","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.PGO.X86","Microsoft.VisualCpp.PGO.X64","Microsoft.VisualCpp.PGO.Headers","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.CRT.Headers","Microsoft.VisualStudio.VC.MSBuild.X86","Microsoft.VisualStudio.VC.MSBuild.X64","Microsoft.VS.VC.MSBuild.X64.Resources","Microsoft.VisualStudio.VC.MSBuild.Base","Microsoft.VisualStudio.VC.MSBuild.Base.Resources","Microsoft.VisualStudio.VC.MSBuild.ARM","Microsoft.VisualStudio.Workload.MSBuildTools","Microsoft.VisualStudio.Component.CoreBuildTools","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.BuildTools.Resources","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.Build.Dependencies","Microsoft.Build.FileTracker.Msi","Microsoft.Component.MSBuild","Microsoft.PythonTools.BuildCore.Vsix","Microsoft.NuGet.Build.Tasks","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.CodeAnalysis.Compilers.Resources","Microsoft.CodeAnalysis.Compilers","Microsoft.Net.PackageGroup.4.6.1.Redist","Microsoft.VisualStudio.NativeImageSupport","Microsoft.Build"]}] diff --git a/node_modules/node-gyp/test/fixtures/VS_2017_Community_workload.txt b/node_modules/node-gyp/test/fixtures/VS_2017_Community_workload.txt deleted file mode 100644 index dd5e77dafb9df..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2017_Community_workload.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community","version":"15.9.28307.665","packages":["Microsoft.VisualStudio.Component.Windows10SDK.IpOverUsb","Win10SDK_IpOverUsb","Microsoft.VisualStudio.Component.VC.ATL.ARM64","Microsoft.VisualCpp.ATL.ARM64","Microsoft.VisualStudio.Component.VC.ATL.ARM","Microsoft.VisualCpp.ATL.ARM","Microsoft.VisualStudio.Component.VC.Tools.ARM","Microsoft.VisualCpp.Tools.HostX64.TargetX86.Resources","Microsoft.VisualStudio.Graphics.Analyzer.Resources","Microsoft.Icecap.Analysis","Microsoft.VisualCpp.CRT.Redist.arm.OneCore.Desktop","Microsoft.VisualCpp.CRT.arm.Store","Microsoft.VisualCpp.CRT.arm.Desktop","Microsoft.VisualStudio.PackageGroup.VC.Tools.x64.ARM","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetarm","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetARM.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetARM","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetARM.Resources","Microsoft.VisualCpp.Premium.Tools.ARM.Base","Microsoft.VisualCpp.Premium.Tools.ARM.Base.Resources","Microsoft.VisualCpp.PGO.ARM","Microsoft.VisualCpp.Tools.HostX64.TargetX64","Microsoft.VisualStudio.Product.Community","Microsoft.VisualCpp.Tools.Hostx86.Targetarm","Microsoft.VisualStudio.Component.VC.Tools.ARM64","Microsoft.VisualStudio.VC.MSBuild.Arm64","Microsoft.VisualCpp.CRT.Redist.ARM64.OneCore.Desktop","Microsoft.VisualCpp.VCTip.HostX64.TargetX64","Microsoft.VisualCpp.CRT.ARM64.OneCore.Desktop","Microsoft.VisualCpp.CRT.ARM64.Store","Microsoft.VisualCpp.CRT.ARM64.Desktop","Microsoft.VisualCpp.Tools.HostX64.TargetX64.Resources","Microsoft.Icecap.Analysis.Resources","Microsoft.VisualCpp.VCTip.hostX86.targetARM","Microsoft.VisualStudio.PackageGroup.VC.Tools.x64.ARM64","Microsoft.VisualCpp.Tools.Core","Microsoft.VisualCpp.PGO.ARM64","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetarm64","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetARM64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetARM64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetARM64.Resources","Microsoft.VisualCpp.Premium.Tools.ARM64.Base","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.Tools.HostX86.TargetARM.Resources","Microsoft.VisualCpp.CRT.Redist.ARM64","Microsoft.VisualCpp.CRT.arm.OneCore.Desktop","Microsoft.VisualCpp.CodeAnalysis.Extensions.X86","Microsoft.VisualCpp.CodeAnalysis.Extensions.X64","Microsoft.VisualCpp.VCTip.HostX64.TargetX86","Component.WixToolset.VisualStudioExtension.Dev15","WixToolset.VisualStudioExtension.Dev15","Microsoft.VisualCpp.MFC.X64","Microsoft.VisualCpp.ATL.Headers","Microsoft.VisualStudio.Component.VC.CMake.Project","Microsoft.VisualStudio.VC.CMake","Microsoft.VisualStudio.VC.CMake.Project","Microsoft.VisualStudio.Component.Windows10SDK.17763","Microsoft.VisualStudio.VC.MSBuild.Base.Resources","MLGen","Microsoft.VisualStudio.Graphics.Analyzer","Microsoft.VisualStudio.Component.TestTools.Core","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.VisualStudio.NuGet.Licenses","SQLCommon","Microsoft.VisualStudio.VC.MSBuild.X86","Microsoft.VisualCpp.Tools.HostX64.TargetARM","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64.Resources","Microsoft.VisualCpp.HTMLHelpWorkshop.Msi","Microsoft.Icecap.Collection.Msi.Resources","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.VCTip.hostX64.targetARM","Microsoft.VisualStudio.VC.Ide.Dskx.Resources","Microsoft.VisualStudio.VC.Templates.UnitTest","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CPP","Microsoft.VisualStudio.VC.Ide.Core","Microsoft.VisualStudio.Graphics.Appid","Microsoft.VisualCpp.ATL.Source","Microsoft.VisualStudio.VC.Ide.Core.Resources","Microsoft.VisualStudio.Debugger.ImmersiveActivateHelper.Msi","Microsoft.VisualStudio.Debugger.JustInTime","Microsoft.DiagnosticsHub.CpuSampling","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Common","Microsoft.VisualStudio.TestTools.TP.Legacy.Common.Res","Microsoft.VisualStudio.ProTools.Resources","Microsoft.VisualStudio.Community.Msi","Microsoft.VisualCpp.Tools.HostX64.TargetARM.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Agent","Microsoft.Component.MSBuild","Microsoft.VisualStudio.Graphics.Msi","Microsoft.VisualStudio.WebToolsExtensions","Microsoft.VisualCpp.Tools.Hostx86.Targetarm64","Microsoft.VisualStudio.TextTemplating.MSBuild","Microsoft.VisualCpp.VCTip.hostX86.targetARM64","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine","Microsoft.VisualCpp.Tools.HostX86.TargetARM64.Resources","Microsoft.VisualStudio.RazorExtension","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualCpp.MFC.Source","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualStudio.VC.MSBuild.X64","Microsoft.VisualStudio.VC.Items.Pro","Microsoft.VisualStudio.Graphics.Viewers","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86.Resources","Microsoft.VisualCpp.MFC.Redist.X86","Microsoft.VisualStudio.WebToolsExtensions.Chip","Microsoft.DiagnosticsHub.Runtime.Resources","Microsoft.DiagnosticsHub.CpuSampling.Targeted","Microsoft.VisualStudio.VC.Ide.LanguageService.Resources","Microsoft.VisualStudio.Component.VC.DiagnosticTools","Microsoft.VisualCpp.MFC.Redist.X64","Microsoft.VisualStudio.PackageGroup.TestTools.Native","Microsoft.VisualStudio.Graphics.Viewers.Resources","Microsoft.VisualCpp.MFC.MBCS","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Component.TextTemplating","Win10SDK_10.0.17763","Microsoft.VisualStudio.VC.Ide.Base.Resources","Microsoft.VisualCpp.MFC.MBCS.X64","Microsoft.VisualStudio.PackageGroup.TestTools.CodeCoverage","Microsoft.VisualStudio.Graphics.EnableTools","Microsoft.VisualStudio.Graphics.Appid.Resources","Microsoft.VisualStudio.VC.MSBuild.Base","Microsoft.VisualStudio.VC.MSBuild.ARM","Microsoft.VisualCpp.MFC.Headers","Microsoft.VisualCpp.CRT.Redist.x86.OneCore.Desktop","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualStudio.VC.Ide.Base","Microsoft.VisualStudio.Graphics.Analyzer.Targeted","Microsoft.VisualCpp.CRT.Headers","Microsoft.DiagnosticsHub.Runtime.Targeted","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86","Microsoft.VisualCpp.Tools.HostX64.TargetARM64","Microsoft.VisualCpp.VCTip.hostX64.targetARM64","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86.Resources","Microsoft.Icecap.Collection.Msi","Microsoft.VisualCpp.ATL.X86","Microsoft.VisualCpp.Tools.HostX64.TargetARM64.Resources","Microsoft.VisualStudio.Component.VC.ATLMFC","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.Icecap.Collection.Msi.Resources.Targeted","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86","Microsoft.VisualStudio.Component.Graphics.Tools","Microsoft.VisualStudio.WebTools.Resources","Microsoft.VisualCpp.ATL.X64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86.Resources","Microsoft.VisualStudio.Component.Graphics.Win81","Microsoft.VisualStudio.VC.Ide.MDD","Microsoft.VisualStudio.VC.Ide.ResourceEditor","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64","Microsoft.Icecap.Analysis.Resources.Targeted","Microsoft.VisualStudio.Debugger.Script.Msi","Microsoft.VisualStudio.Component.VC.CoreIde","Microsoft.VisualStudio.VC.Ide.MFC.Resources","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualStudio.TextTemplating.Core","Microsoft.VisualStudio.JavaScript.LanguageService","Microsoft.VisualStudio.VC.Ide.ResourceEditor.Resources","Microsoft.VisualStudio.VC.Ide.ProjectSystem.Resources","Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest","Microsoft.VisualStudio.VC.Ide.ProjectSystem","Microsoft.VisualStudio.VC.Ide.Dskx","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.CredentialProvider","Microsoft.VisualStudio.VC.Templates.Desktop","Microsoft.VisualStudio.VC.Ide.Pro.Resources","Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core","Microsoft.VisualStudio.TextTemplating.Integration","Microsoft.VisualStudio.Component.NuGet","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Reduced","Microsoft.VisualCpp.PGO.Headers","Microsoft.DiagnosticsHub.Collection","Microsoft.Icecap.Collection.Msi.Targeted","Microsoft.VisualStudio.VC.Ide.LanguageService","Microsoft.VisualStudio.WebTools.WSP.FSA","Microsoft.VisualStudio.Graphics.Msi","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualStudio.Branding.Community","Microsoft.VisualStudio.VC.Ide.x64","Microsoft.VisualStudio.WebToolsExtensions.Common","Microsoft.VisualStudio.WebTools.MSBuild","Microsoft.VisualStudio.NuGet.Core","Microsoft.DiagnosticsHub.Collection.Service","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine.Resources","Microsoft.CodeAnalysis.ExpressionEvaluator","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VS.VC.MSBuild.X64.Resources","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips.Resources","Microsoft.VisualStudio.VC.Ide.WinXPlus","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.Net.4.TargetingPack","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualStudio.VC.Ide.Debugger.Resources","Microsoft.DiaSymReader.Native","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.TestTools.TeamFoundationClient","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.VC.Ide.Common","Microsoft.VisualStudio.Community.Extra.Resources","Microsoft.VisualStudio.Component.Roslyn.LanguageServices","Microsoft.DiagnosticsHub.Collection.StopService.Install","Microsoft.VisualStudio.InteractiveWindow","Microsoft.PackageGroup.DiagnosticsHub.Platform","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.VC.Ide.Common.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX86","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.Community.Extra","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Msi","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.TestTools","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core.Resources","Microsoft.VisualStudio.PackageGroup.TestTools.Core","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.Component.VC.Tools.x86.x64","Microsoft.VisualStudio.TestTools.Pex.Common","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.Legacy","Microsoft.VisualStudio.PackageGroup.MinShell.Interop","Microsoft.CodeAnalysis.ExpressionEvaluator.Resources","Microsoft.VisualCpp.CodeAnalysis.Extensions","Microsoft.VisualStudio.PackageGroup.CoreEditor","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.VisualStudio.ScriptedHost.Targeted","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Professional","Microsoft.VisualStudio.Debugger.Resources","Microsoft.VisualStudio.Debugger.Parallel","Microsoft.VisualStudio.Debugger.Parallel.Resources","Microsoft.VisualCpp.PGO.X64","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.GraphModel","Microsoft.VisualStudio.PackageGroup.TestTools.DataCollectors","sqlsysclrtypes","Microsoft.VisualStudio.ProTools","Component.Microsoft.VisualStudio.RazorExtension","Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI","Microsoft.Build.Dependencies","Microsoft.VisualStudio.WebTools.WSP.FSA.Resources","Microsoft.VisualStudio.Component.Static.Analysis.Tools","Microsoft.VisualStudio.VC.Ide.ATL.Resources","Microsoft.VisualStudio.VC.Templates.UnitTest.Resources","Microsoft.VisualStudio.Debugger.Managed","Microsoft.VisualStudio.Workload.NativeDesktop","Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest","Microsoft.VisualStudio.Debugger.JustInTime.Msi","Microsoft.Net.PackageGroup.4.6.1.Redist","Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost","sqlsysclrtypes","Microsoft.VisualStudio.Debugger.Managed.Resources","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Common","Microsoft.VisualStudio.VC.Ide.Debugger","Microsoft.VisualStudio.AppResponsiveness","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.TestTools.TestWIExtension","Microsoft.VisualStudio.VC.Ide.Pro","Microsoft.VisualStudio.PackageGroup.Debugger.Core","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Express","Microsoft.VisualStudio.WebTools","Microsoft.VisualStudio.Component.VC.Redist.14.Latest","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.TextTemplating.Integration.Resources","Microsoft.VisualStudio.Debugger.CollectionAgents","Microsoft.VisualStudio.Debugger","Microsoft.VisualStudio.PackageGroup.Debugger.Script","Microsoft.VisualStudio.VC.MSVCDis","Microsoft.VisualStudio.ScriptedHost","Microsoft.VisualStudio.ClientDiagnostics.Targeted","Microsoft.VisualStudio.ScriptedHost.Resources","Microsoft.TeamFoundation.OfficeIntegration.Resources","Microsoft.IntelliTrace.DiagnosticsHub","Microsoft.VisualStudio.JavaScript.LanguageService.Resources","Microsoft.VisualStudio.VC.Ide.TestAdapterForGoogleTest","Microsoft.VisualStudio.PackageGroup.Community","Microsoft.VisualStudio.ClientDiagnostics","Microsoft.VisualStudio.Component.Windows10SDK.17134","Microsoft.VisualStudio.PackageGroup.Core","PortableFacades","Microsoft.DiaSymReader","Microsoft.DiagnosticsHub.Runtime","Microsoft.VisualStudio.Component.CoreEditor","Microsoft.VisualStudio.AppResponsiveness.Targeted","Microsoft.VisualStudio.AppResponsiveness.Resources","Microsoft.VisualStudio.Community","Microsoft.TeamFoundation.OfficeIntegration","Microsoft.VisualStudio.WebSiteProject.DTE","Microsoft.VisualStudio.ClientDiagnostics.Resources","Microsoft.VisualStudio.ProjectSystem.Full","Microsoft.VisualStudio.ProjectSystem","Microsoft.VisualCpp.Tools.Common.UtilsPrereq","Microsoft.IntelliTrace.CollectorCab","Microsoft.VisualStudio.Community.Resources","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.ServiceHub","Microsoft.VisualStudio.Editors","Microsoft.VisualStudio.TeamExplorer","Microsoft.CodeAnalysis.VisualStudio.InteractiveComponents.Resources","Microsoft.VisualStudio.MinShell.Interop.Msi","Microsoft.VisualStudio.GraphProvider","Microsoft.CodeAnalysis.VisualStudio.InteractiveComponents","Microsoft.CodeAnalysis.VisualStudio.Setup.Interactive.Resources","Microsoft.CodeAnalysis.VisualStudio.Setup.Resources","Microsoft.VisualStudio.Community.x86","Microsoft.VisualStudio.Community.x64","Microsoft.CodeAnalysis.VisualStudio.Setup","Microsoft.NuGet.Build.Tasks","Microsoft.PackageGroup.ClientDiagnostics","Microsoft.CodeAnalysis.Compilers.Resources","Microsoft.CodeAnalysis.Compilers","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.VisualStudio.PackageGroup.CommunityCore","Microsoft.Build","Microsoft.VisualStudio.VC.Ide.TestAdapterForBoostTest","Microsoft.VisualStudio.VC.Ide.ATL","Microsoft.VisualStudio.TextMateGrammars","Microsoft.VisualStudio.Workload.CoreEditor","Microsoft.VisualStudio.MinShell.Interop","Microsoft.Build.FileTracker.Msi","Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core","Microsoft.MSHtml","Microsoft.VisualStudio.Community.Msi.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips","Microsoft.VisualStudio.Devenv.Msi","Microsoft.VisualStudio.Component.VC.ATL","Microsoft.VisualStudio.VC.Templates.Pro","Microsoft.VisualCpp.CRT.Redist.x64.OneCore.Desktop","Microsoft.VisualStudio.SLNX.VSIX","Microsoft.VisualStudio.CoreEditor","Win10SDK_10.0.17134","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.Component.Debugger.JustInTime","Microsoft.VisualStudio.VC.Ide.MFC","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.Finalizer","Microsoft.VisualStudio.VirtualTree","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.ProjectServices","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.MinShell","Microsoft.VisualStudio.PackageGroup.Progression","Microsoft.VisualStudio.PerformanceProvider","Microsoft.VisualStudio.Connected.Resources","Microsoft.VisualStudio.Log","Microsoft.VisualStudio.PackageGroup.TeamExplorer","Microsoft.VisualStudio.Log.Targeted","Microsoft.VisualStudio.MinShell.Platform","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.VC.Templates.Pro.Resources","Microsoft.VisualStudio.Devenv","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualStudio.Devenv.Resources","Microsoft.VisualStudio.MinShell.Platform.Resources","Microsoft.VisualStudio.Connected","Microsoft.VisualStudio.MefHosting","Microsoft.DiagnosticsHub.Collection.StopService.Uninstall","Microsoft.VisualStudio.PackageGroup.MinShell","Microsoft.VisualStudio.MefHosting.Resources","Microsoft.VisualCpp.MFC.X86","Microsoft.VisualStudio.Log.Resources","Microsoft.Icecap.Analysis.Targeted","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.PGO.X86","Microsoft.VisualStudio.ExtensionManager","Microsoft.VisualStudio.MinShell.x86","Microsoft.VisualStudio.MinShell.Msi","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.LanguageServer","Microsoft.VisualStudio.NativeImageSupport","Microsoft.VisualStudio.MinShell.Msi.Resources","Microsoft.VisualStudio.Devenv.Config","Microsoft.VisualStudio.MinShell.Resources","Microsoft.VisualStudio.Initializer","Microsoft.Net.PackageGroup.4.6.Redist"]}] diff --git a/node_modules/node-gyp/test/fixtures/VS_2017_Express.txt b/node_modules/node-gyp/test/fixtures/VS_2017_Express.txt deleted file mode 100644 index c4b3b5f2b0163..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2017_Express.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\WDExpress","version":"15.9.28307.858","packages":["Microsoft.VisualStudio.Product.WDExpress","Microsoft.VisualStudio.Workload.WDExpress","Microsoft.VisualStudio.Component.Windows10SDK.17763","MLGen","Win10SDK_10.0.17763","Microsoft.VisualStudio.Component.Windows10SDK.14393","Win10SDK_10.0.14393.795","Microsoft.VisualStudio.VC.Items.Pro","Microsoft.VisualStudio.VC.Ide.Pro","Microsoft.VisualStudio.VC.Ide.Pro.Resources","Microsoft.VisualStudio.Component.VC.Tools.ARM64","Microsoft.VisualStudio.VC.MSBuild.Arm64","Microsoft.VisualCpp.CRT.Redist.ARM64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.ARM64","Microsoft.VisualCpp.CRT.ARM64.OneCore.Desktop","Microsoft.VisualCpp.CRT.ARM64.Store","Microsoft.VisualCpp.CRT.ARM64.Desktop","Microsoft.VisualCpp.Tools.Hostx86.Targetarm64","Microsoft.VisualCpp.VCTip.hostX86.targetARM64","Microsoft.VisualCpp.Tools.HostX86.TargetARM64.Resources","Microsoft.VisualStudio.Component.VC.Tools.ARM","Microsoft.VisualCpp.Tools.Hostx86.Targetarm","Microsoft.VisualCpp.VCTip.hostX86.targetARM","Microsoft.VisualCpp.Tools.HostX86.TargetARM.Resources","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.arm.OneCore.Desktop","Microsoft.VisualCpp.CRT.arm.OneCore.Desktop","Microsoft.VisualCpp.CRT.arm.Store","Microsoft.VisualCpp.CRT.arm.Desktop","Microsoft.VisualStudio.VC.Templates.UnitTest","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CPP","Microsoft.VisualStudio.VC.Templates.UnitTest.Resources","Microsoft.VisualStudio.VC.Templates.Desktop","Microsoft.VisualStudio.VC.Templates.Pro","Microsoft.VisualStudio.VC.Templates.Pro.Resources","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Express","Microsoft.VisualStudio.PackageGroup.Debugger.Script","Microsoft.VisualStudio.JavaScript.LanguageService","Microsoft.VisualStudio.JavaScript.LanguageService.Resources","Microsoft.VisualStudio.Debugger.Script.Msi","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.VC.MSBuild.X64","Microsoft.VS.VC.MSBuild.X64.Resources","Microsoft.VisualStudio.VC.MSBuild.ARM","Microsoft.VisualStudio.VC.MSBuild.X86","Microsoft.VisualStudio.VC.MSBuild.Base","Microsoft.VisualStudio.VC.MSBuild.Base.Resources","Microsoft.VisualStudio.VC.Ide.WinXPlus","Microsoft.VisualStudio.VC.Ide.Dskx","Microsoft.VisualStudio.VC.Ide.Dskx.Resources","Microsoft.VisualStudio.VC.Ide.Core","Microsoft.VisualStudio.VC.Ide.Core.Resources","Microsoft.VisualStudio.VC.Ide.Base","Microsoft.VisualStudio.VC.Ide.Base.Resources","Microsoft.VisualStudio.Component.VC.CLI.Support","Microsoft.VisualCpp.CLI.X86","Microsoft.VisualCpp.CLI.X64","Microsoft.VisualCpp.CLI.Source","Microsoft.VisualCpp.CLI.ARM64","Microsoft.VisualCpp.CLI.ARM","Microsoft.VisualStudio.VC.Templates.CLR","Microsoft.VisualStudio.VC.Ide.LanguageService","Microsoft.VisualStudio.VC.Ide.ResourceEditor","Microsoft.VisualStudio.VC.Ide.ResourceEditor.Resources","Microsoft.VisualStudio.VC.Ide.ProjectSystem","Microsoft.VisualStudio.VC.Ide.ProjectSystem.Resources","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine.Resources","Microsoft.VisualStudio.VC.Ide.LanguageService.Resources","Microsoft.VisualStudio.VC.Templates.CLR.Resources","Microsoft.Component.VC.Runtime.OSSupport","Microsoft.Windows.UniversalCRT.Tools.Msi","Microsoft.Windows.UniversalCRT.Tools.Msi","Microsoft.Windows.UniversalCRT.ExtensionSDK.Msi","Microsoft.Windows.UniversalCRT.HeadersLibsSources.Msi","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.CRT.Headers","Microsoft.Component.HelpViewer","Microsoft.HelpViewer","Microsoft.VisualStudio.Help.Configuration.Msi","Microsoft.VisualStudio.Component.SQL.DataSources","Microsoft.VisualStudio.Component.SQL.SSDT","Microsoft.VisualStudio.Component.SQL.CMDUtils","sqlcmdlnutils","Microsoft.VisualStudio.Component.Common.Azure.Tools","Microsoft.VisualStudio.Azure.CommonAzureTools","SSDT","Microsoft.VisualStudio.Component.SQL.ADAL","sql_adalsql","Microsoft.VisualStudio.Component.NuGet","Microsoft.CredentialProvider","Microsoft.VisualStudio.NuGet.Licenses","Microsoft.VisualStudio.Component.SQL.LocalDB.Runtime","Microsoft.VisualStudio.Component.SQL.NCLI","sqllocaldb","sqlncli","Microsoft.VisualStudio.Component.EntityFramework","Microsoft.VisualStudio.PackageGroup.DslRuntime","Microsoft.VisualStudio.Dsl.Core","Microsoft.VisualStudio.Dsl.GraphObject","Microsoft.VisualStudio.Dsl.Core.Resources","Microsoft.VisualStudio.EntityFrameworkTools","Microsoft.VisualStudio.EntityFrameworkTools.Msi","Microsoft.VisualStudio.Component.Roslyn.LanguageServices","Microsoft.VisualStudio.InteractiveWindow","Microsoft.DiaSymReader.Native","Microsoft.VisualStudio.Component.Static.Analysis.Tools","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.CodeAnalysis.VisualStudio.InteractiveComponents.Resources","Microsoft.CodeAnalysis.VisualStudio.InteractiveComponents","Microsoft.CodeAnalysis.VisualStudio.Setup.Interactive.Resources","Microsoft.Net.ComponentGroup.TargetingPacks.Common","Microsoft.Net.Component.4.6.TargetingPack","Microsoft.Net.4.6.TargetingPack","Microsoft.Net.Component.4.5.2.TargetingPack","Microsoft.Net.4.5.2.TargetingPack","Microsoft.Net.Component.4.5.1.TargetingPack","Microsoft.Net.4.5.1.TargetingPack","Microsoft.Net.Component.4.5.TargetingPack","Microsoft.Net.4.5.TargetingPack","Microsoft.Net.Component.4.TargetingPack","Microsoft.Net.4.TargetingPack","Microsoft.Net.ComponentGroup.DevelopmentPrerequisites","Microsoft.Net.Component.4.6.1.TargetingPack","Microsoft.Net.4.6.1.TargetingPack","Microsoft.Net.Cumulative.TargetingPack.Resources","Microsoft.Net.Component.4.6.1.SDK","Microsoft.Net.4.6.1.SDK","Microsoft.VisualStudio.Component.TextTemplating","Microsoft.VisualStudio.TextTemplating.MSBuild","Microsoft.VisualStudio.TextTemplating.Integration","Microsoft.VisualStudio.TextTemplating.Core","Microsoft.VisualStudio.TextTemplating.Integration.Resources","Microsoft.VisualStudio.Component.VisualStudioData","Microsoft.VisualStudio.Component.SQL.CLR","Microsoft.VisualStudio.ProTools","sqlsysclrtypes","sqlsysclrtypes","SQLCommon","Microsoft.VisualStudio.ProTools.Resources","Microsoft.VisualStudio.XamlDiagnostics","Microsoft.VisualStudio.XamlDiagnostics.Resources","Microsoft.VisualStudio.XamlDesigner","Microsoft.VisualStudio.XamlDesigner.Resources","Microsoft.VisualStudio.XamlDesigner.Executables","Microsoft.VisualStudio.XamlShared","Microsoft.VisualStudio.XamlShared.Resources","Microsoft.VisualStudio.PackageGroup.TestTools.Managed","Microsoft.VisualStudio.PackageGroup.IntelliTrace.Core","Microsoft.IntelliTrace.Core","Microsoft.IntelliTrace.Core.Targeted","Microsoft.IntelliTrace.ProfilerProxy.Msi.x64","Microsoft.IntelliTrace.ProfilerProxy.Msi","Microsoft.VisualStudio.NuGet.Core","Microsoft.VisualStudio.TestWindow.SourceBasedTestDiscovery","Microsoft.VisualStudio.TestWindow.Dotnet","Microsoft.VisualStudio.TestTools.TestGeneration","Microsoft.VisualStudio.PackageGroup.TestTools.CodeCoverage","Microsoft.VisualStudio.PackageGroup.TestTools.Enterprise","Microsoft.VisualStudio.PackageGroup.TestTools.MSTestV2.Managed","Microsoft.VisualStudio.TestTools.MSTestV2.WizardExtension.UnitTest","Microsoft.VisualStudio.PackageGroup.TestTools.Core","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.TestTools.Pex.Common","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.Legacy","Microsoft.VisualStudio.PackageGroup.MinShell.Interop","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Msi","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Common","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.TestTools","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Professional","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Common","Microsoft.VisualStudio.TestTools.TP.Legacy.Common.Res","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Agent","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.TestTools.TestWIExtension","Microsoft.VisualStudio.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.PackageGroup.TestTools.DataCollectors","Microsoft.Component.ClickOnce","Microsoft.VisualStudio.PackageGroup.ClickOnce.MSBuild","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.ClickOnce.SignTool.Msi","Microsoft.SQL.ClickOnceBootstrapper.Msi","Microsoft.Net.ClickOnceBootstrapper","Microsoft.ClickOnce.BootStrapper.Msi.Resources","Microsoft.ClickOnce.BootStrapper.Msi","Microsoft.VisualStudio.WebTools.WSP.FSA","Microsoft.VisualStudio.WebTools.WSP.FSA.Resources","Microsoft.VisualStudio.PackageGroup.Community","Microsoft.VisualStudio.Community.Extra.Resources","Microsoft.VisualStudio.Community.Extra","Microsoft.VisualStudio.PackageGroup.Core","Microsoft.VisualStudio.TestTools.TeamFoundationClient","Microsoft.VisualStudio.PackageGroup.Debugger.Core","Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost","Microsoft.VisualStudio.VC.Ide.Debugger","Microsoft.VisualStudio.VC.Ide.Debugger.Resources","Microsoft.VisualStudio.VC.Ide.Common","Microsoft.VisualStudio.VC.Ide.Common.Resources","Microsoft.VisualStudio.Debugger.Parallel","Microsoft.VisualStudio.Debugger.Parallel.Resources","Microsoft.VisualStudio.Debugger.CollectionAgents","Microsoft.VisualStudio.Debugger.Managed","Microsoft.CodeAnalysis.VisualStudio.Setup.Resources","Microsoft.CodeAnalysis.VisualStudio.Setup","Microsoft.CodeAnalysis.ExpressionEvaluator.Resources","Microsoft.CodeAnalysis.ExpressionEvaluator","Microsoft.VisualStudio.Debugger.Managed.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger","Microsoft.VisualStudio.VC.MSVCDis","Microsoft.VisualStudio.ScriptedHost","Microsoft.VisualStudio.ScriptedHost.Targeted","Microsoft.VisualStudio.ScriptedHost.Resources","Microsoft.IntelliTrace.DiagnosticsHub","Microsoft.VisualStudio.Debugger.Resources","Microsoft.PackageGroup.ClientDiagnostics","Microsoft.VisualStudio.AppResponsiveness","Microsoft.VisualStudio.AppResponsiveness.Targeted","Microsoft.VisualStudio.AppResponsiveness.Resources","Microsoft.VisualStudio.ClientDiagnostics","Microsoft.VisualStudio.ClientDiagnostics.Targeted","Microsoft.VisualStudio.ClientDiagnostics.Resources","Microsoft.VisualStudio.PackageGroup.CommunityCore","Microsoft.VisualStudio.ProjectSystem.Full","Microsoft.VisualStudio.ProjectSystem","Microsoft.VisualStudio.Community.x86","Microsoft.VisualStudio.Community.x64","Microsoft.VisualStudio.Community","Microsoft.IntelliTrace.CollectorCab","Microsoft.VisualStudio.Community.Resources","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.VisualStudio.WebSiteProject.DTE","Microsoft.MSHtml","Microsoft.VisualStudio.Community.Msi.Resources","Microsoft.VisualStudio.Community.Msi","Microsoft.VisualStudio.MinShell.Interop.Msi","Microsoft.VisualStudio.Editors","Microsoft.VisualStudio.ClickOnce.Resources","Microsoft.VisualStudio.ClickOnce","Microsoft.Component.MSBuild","Microsoft.NuGet.Build.Tasks","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.CodeAnalysis.Compilers.Resources","Microsoft.CodeAnalysis.Compilers","Microsoft.Net.PackageGroup.4.6.1.Redist","Microsoft.VisualStudio.TemplateEngine","Microsoft.VisualStudio.WebToolsExtensions.Common","Microsoft.NET.Sdk","Microsoft.VisualStudio.PackageGroup.TestTools.Templates.Managed","Microsoft.VisualStudio.TestTools.Templates.Managed","Microsoft.VisualStudio.TestTools.Templates.Managed.Resources","Microsoft.VisualStudio.Templates.VB.MSTestv2.Desktop.UnitTest","Microsoft.VisualStudio.Templates.CS.MSTestv2.Desktop.UnitTest","Microsoft.VisualStudio.Templates.VB.Wpf","Microsoft.VisualStudio.Templates.VB.Wpf.Resources","Microsoft.VisualStudio.Templates.VB.Winforms","Microsoft.VisualStudio.Templates.VB.ManagedCore","Microsoft.VisualStudio.Templates.VB.Shared","Microsoft.VisualStudio.Templates.VB.Shared.Resources","Microsoft.VisualStudio.Templates.VB.ManagedCore.Resources","Microsoft.VisualStudio.Templates.CS.GettingStarted.Desktop.Package","Microsoft.VisualStudio.Templates.GetStarted.Desktop.Setup","Microsoft.VisualStudio.Templates.CS.GettingStarted.Console.Package","Microsoft.VisualStudio.Templates.GetStarted.Resources","Microsoft.VisualStudio.Templates.GetStarted.Common.Setup","Microsoft.VisualStudio.Templates.GetStarted.Console.Setup","Microsoft.VisualStudio.Templates.CS.Wpf","Microsoft.VisualStudio.Templates.CS.Wpf.Resources","Microsoft.VisualStudio.Templates.CS.Winforms","Microsoft.VisualStudio.Templates.CS.ManagedCore","Microsoft.VisualStudio.Templates.CS.Shared","Microsoft.VisualStudio.Templates.Editorconfig.Wizard.Setup","Templates.Editorconfig.SolutionFile.Setup","Microsoft.VisualStudio.Templates.CS.Shared.Resources","Microsoft.VisualStudio.Templates.CS.ManagedCore.Resources","Microsoft.VisualStudio.Component.CoreEditor","Microsoft.VisualStudio.PackageGroup.CoreEditor","PortableFacades","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.VirtualTree","Microsoft.VisualStudio.PackageGroup.Progression","Microsoft.VisualStudio.PerformanceProvider","Microsoft.VisualStudio.GraphModel","Microsoft.VisualStudio.GraphProvider","Microsoft.DiaSymReader","Microsoft.Build.Dependencies","Microsoft.Build.FileTracker.Msi","Microsoft.Build","Microsoft.VisualStudio.TextMateGrammars","Microsoft.VisualStudio.PackageGroup.TeamExplorer","Microsoft.TeamFoundation.OfficeIntegration","Microsoft.TeamFoundation.OfficeIntegration.Resources","Microsoft.VisualStudio.TeamExplorer","Microsoft.ServiceHub","Microsoft.VisualStudio.ProjectServices","Microsoft.VisualStudio.SLNX.VSIX","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.PackageGroup.MinShell","Microsoft.VisualStudio.MinShell.Interop","Microsoft.VisualStudio.Log","Microsoft.VisualStudio.Log.Targeted","Microsoft.VisualStudio.Log.Resources","Microsoft.VisualStudio.Finalizer","Microsoft.VisualStudio.WDExpress","Microsoft.VisualStudio.WDExpress.Resources","Microsoft.VisualStudio.CoreEditor","Microsoft.VisualStudio.Connected","Microsoft.VisualStudio.Connected.Resources","Microsoft.VisualStudio.MinShell","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.MinShell.Platform","Microsoft.VisualStudio.MinShell.Platform.Resources","Microsoft.VisualStudio.MefHosting","Microsoft.VisualStudio.MefHosting.Resources","Microsoft.VisualStudio.Initializer","Microsoft.VisualStudio.ExtensionManager","Microsoft.VisualStudio.MinShell.x86","Microsoft.VisualStudio.NativeImageSupport","Microsoft.VisualStudio.MinShell.Msi","Microsoft.VisualStudio.MinShell.Msi.Resources","Microsoft.VisualStudio.LanguageServer","Microsoft.VisualStudio.MinShell.Resources","Microsoft.Net.PackageGroup.4.6.Redist","Microsoft.VisualStudio.Branding.WDExpress"]}] diff --git a/node_modules/node-gyp/test/fixtures/VS_2017_Unusable.txt b/node_modules/node-gyp/test/fixtures/VS_2017_Unusable.txt deleted file mode 100644 index fc0a257f44783..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2017_Unusable.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildToolsUnusable","version":"15.9.28307.665","packages":["Microsoft.VisualStudio.Product.BuildTools","Microsoft.VisualStudio.Component.Windows10SDK.17134","Win10SDK_10.0.17134","Microsoft.VisualStudio.Component.VC.Tools.x86.x64","Microsoft.VisualCpp.CodeAnalysis.Extensions","Microsoft.VisualCpp.CodeAnalysis.Extensions.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86.Resources","Microsoft.VisualCpp.CodeAnalysis.Extensions.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64.Resources","Microsoft.VisualStudio.Component.Static.Analysis.Tools","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX86","Microsoft.VisualCpp.VCTip.HostX64.TargetX86","Microsoft.VisualCpp.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX64","Microsoft.VisualCpp.VCTip.HostX64.TargetX64","Microsoft.VisualCpp.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX64","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.PGO.X86","Microsoft.VisualCpp.PGO.X64","Microsoft.VisualCpp.PGO.Headers","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.CRT.Headers","Microsoft.VisualStudio.Workload.MSBuildTools","Microsoft.VisualStudio.Component.CoreBuildTools","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.BuildTools.Resources","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.Build.Dependencies","Microsoft.Build.FileTracker.Msi","Microsoft.Component.MSBuild","Microsoft.PythonTools.BuildCore.Vsix","Microsoft.NuGet.Build.Tasks","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.CodeAnalysis.Compilers.Resources","Microsoft.CodeAnalysis.Compilers","Microsoft.Net.PackageGroup.4.6.1.Redist","Microsoft.Net.4.6.1.FullRedist.NonThreshold","Microsoft.Windows.UniversalCRT.Msu.81","Microsoft.VisualStudio.NativeImageSupport","Microsoft.Build"]}] diff --git a/node_modules/node-gyp/test/fixtures/VS_2019_BuildTools_minimal.txt b/node_modules/node-gyp/test/fixtures/VS_2019_BuildTools_minimal.txt deleted file mode 100644 index f07d254164882..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2019_BuildTools_minimal.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools","version":"16.1.28922.388","packages":["Microsoft.VisualStudio.Product.BuildTools","Microsoft.VisualStudio.Component.VC.CoreIde","Microsoft.VisualStudio.VC.Ide.Pro","Microsoft.VisualStudio.VC.Ide.Pro.Resources","Microsoft.VisualStudio.VC.Templates.Pro","Microsoft.VisualStudio.VC.Templates.Pro.Resources","Microsoft.VisualStudio.VC.Items.Pro","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Reduced","Microsoft.VisualStudio.VC.Ide.MDD","Microsoft.VisualStudio.PackageGroup.Core","Microsoft.VisualStudio.CodeSense.Community","Microsoft.VisualStudio.TestTools.TeamFoundationClient","Microsoft.PackageGroup.ClientDiagnostics","Microsoft.VisualStudio.AppResponsiveness","Microsoft.VisualStudio.AppResponsiveness.Targeted","Microsoft.VisualStudio.AppResponsiveness.Resources","Microsoft.VisualStudio.ClientDiagnostics","Microsoft.VisualStudio.ClientDiagnostics.Targeted","Microsoft.VisualStudio.ClientDiagnostics.Resources","Microsoft.VisualStudio.PackageGroup.CommunityCore","Microsoft.VisualStudio.ProjectSystem.Full","Microsoft.VisualStudio.ProjectSystem","Microsoft.VisualStudio.Community.x86","Microsoft.VisualStudio.Community.x64","Microsoft.VisualStudio.Community","Microsoft.IntelliTrace.CollectorCab","Microsoft.VisualStudio.Community.Resources","Microsoft.VisualStudio.WebSiteProject.DTE","Microsoft.MSHtml","Microsoft.VisualStudio.Platform.CallHierarchy","Microsoft.VisualStudio.Community.Msi.Resources","Microsoft.VisualStudio.Community.Msi","Microsoft.VisualStudio.MinShell.Interop.Msi","Microsoft.VisualStudio.PackageGroup.CoreEditor","Microsoft.VisualStudio.VirtualTree","Microsoft.VisualStudio.PackageGroup.Progression","Microsoft.VisualStudio.PerformanceProvider","Microsoft.VisualStudio.GraphModel","Microsoft.VisualStudio.GraphProvider","Microsoft.VisualStudio.TextMateGrammars","Microsoft.VisualStudio.PackageGroup.TeamExplorer.Common","Microsoft.VisualStudio.TeamExplorer","Microsoft.ServiceHub","Microsoft.VisualStudio.ProjectServices","Microsoft.VisualStudio.OpenFolder.VSIX","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.PackageGroup.MinShell","Microsoft.VisualStudio.MinShell.Msi","Microsoft.VisualStudio.MinShell.Msi.Resources","Microsoft.VisualStudio.MinShell.Interop","Microsoft.VisualStudio.Log","Microsoft.VisualStudio.Log.Targeted","Microsoft.VisualStudio.Log.Resources","Microsoft.VisualStudio.Finalizer","Microsoft.VisualStudio.CoreEditor","Microsoft.VisualStudio.Platform.NavigateTo","Microsoft.VisualStudio.Connected","Microsoft.VisualStudio.Connected.Resources","Microsoft.VisualStudio.VC.Ide.x64","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Express","Microsoft.VisualStudio.PackageGroup.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Msi","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.VC.Ide.WinXPlus","Microsoft.VisualStudio.VC.Ide.Dskx","Microsoft.VisualStudio.VC.Ide.Dskx.Resources","Microsoft.VisualStudio.VC.Ide.Base","Microsoft.VisualStudio.VC.Ide.LanguageService","Microsoft.VisualStudio.VC.Ide.Core","Microsoft.VisualStudio.VisualC.Logging","Microsoft.VisualStudio.VC.Ide.Core.Resources","Microsoft.VisualStudio.VC.Ide.VCPkgDatabase","Microsoft.VisualStudio.VC.Ide.ResourceEditor","Microsoft.VisualStudio.VC.Ide.ResourceEditor.Resources","Microsoft.VisualStudio.VC.Ide.ProjectSystem","Microsoft.VisualStudio.VC.Ide.ProjectSystem.Resources","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine.Resources","Microsoft.VisualStudio.VC.Ide.LanguageService.Resources","Microsoft.VisualStudio.VC.Ide.Base.Resources","Microsoft.Net.4.TargetingPack","Microsoft.VisualStudio.PackageGroup.Debugger.Core","Microsoft.VisualStudio.PackageGroup.Debugger.TimeTravel.Record","Microsoft.VisualStudio.Debugger.TimeTravel.Runtime","Microsoft.VisualStudio.Debugger.TimeTravel.Runtime","Microsoft.VisualStudio.Debugger.TimeTravel.Agent","Microsoft.VisualStudio.Debugger.TimeTravel.Record","Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost","Microsoft.VisualStudio.VC.Ide.Debugger","Microsoft.VisualStudio.VC.Ide.Debugger.Concord","Microsoft.VisualStudio.VC.Ide.Debugger.Concord.Resources","Microsoft.VisualStudio.VC.Ide.Debugger.Resources","Microsoft.VisualStudio.VC.Ide.Common","Microsoft.VisualStudio.VC.Ide.Common.Resources","Microsoft.VisualStudio.Debugger.Parallel","Microsoft.VisualStudio.Debugger.Parallel.Resources","Microsoft.VisualStudio.Debugger.CollectionAgents","Microsoft.VisualStudio.Debugger.Managed","Microsoft.DiaSymReader","Microsoft.CodeAnalysis.ExpressionEvaluator","Microsoft.VisualStudio.Debugger.Concord.Managed","Microsoft.VisualStudio.Debugger.Concord.Managed.Resources","Microsoft.VisualStudio.Debugger.Managed.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger","Microsoft.VisualStudio.PerfLib","Microsoft.VisualStudio.Debugger.Package.DiagHub.Client.VSx86","Microsoft.VisualStudio.Debugger.Remote.DiagHub.Client","Microsoft.VisualStudio.Debugger.Remote.DiagHub.Client","Microsoft.VisualStudio.VC.MSVCDis","Microsoft.VisualStudio.ScriptedHost","Microsoft.VisualStudio.ScriptedHost.Targeted","Microsoft.VisualStudio.ScriptedHost.Resources","Microsoft.VisualStudio.Editors","Microsoft.IntelliTrace.DiagnosticsHub","Microsoft.VisualStudio.MinShell","Microsoft.VisualStudio.MinShell.Platform","Microsoft.VisualStudio.MinShell.Platform.Resources","Microsoft.VisualStudio.MefHosting","Microsoft.VisualStudio.MefHosting.Resources","Microsoft.VisualStudio.Initializer","Microsoft.VisualStudio.ExtensionManager","Microsoft.VisualStudio.Platform.Editor","Microsoft.VisualStudio.Debugger.Concord","Microsoft.VisualStudio.Debugger.Concord.Resources","Microsoft.VisualStudio.Debugger.Resources","Microsoft.CodeAnalysis.VisualStudio.Setup","Microsoft.VisualStudio.Component.Windows10SDK.17134","Win10SDK_10.0.17134","Microsoft.VisualStudio.Component.VC.Tools.x86.x64","Microsoft.VisualCpp.CodeAnalysis.Extensions","Microsoft.VisualCpp.CodeAnalysis.Extensions.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86.Resources","Microsoft.VisualCpp.CodeAnalysis.Extensions.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64.Resources","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX86","Microsoft.VisualCpp.VCTip.HostX64.TargetX86","Microsoft.VisualCpp.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX64","Microsoft.VisualCpp.VCTip.HostX64.TargetX64","Microsoft.VisualCpp.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX64","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.PGO.X86","Microsoft.VisualCpp.PGO.X64","Microsoft.VisualCpp.PGO.Headers","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.CRT.Headers","Microsoft.VisualStudio.VC.MSBuild.x86.v142","Microsoft.VisualStudio.VC.MSBuild.X86","Microsoft.VisualStudio.VC.MSBuild.X64.v142","Microsoft.VisualStudio.VC.MSBuild.X64","Microsoft.VS.VC.MSBuild.X64.Resources","Microsoft.VisualStudio.VC.MSBuild.ARM.v142","Microsoft.VisualStudio.VC.MSBuild.ARM","Microsoft.VisualStudio.VC.MSBuild.Base","Microsoft.VisualStudio.VC.MSBuild.Base.Resources","Microsoft.VisualStudio.Workload.MSBuildTools","Microsoft.VisualStudio.Component.CoreBuildTools","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.BuildTools.Resources","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.Build.Dependencies","Microsoft.Build.FileTracker.Msi","Microsoft.Component.MSBuild","Microsoft.PythonTools.BuildCore.Vsix","Microsoft.NuGet.Build.Tasks","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.CodeAnalysis.Compilers","Microsoft.Net.PackageGroup.4.7.2.Redist","Microsoft.VisualStudio.NativeImageSupport","Microsoft.Build","Microsoft.VisualStudio.PackageGroup.NuGet","Microsoft.VisualStudio.NuGet.BuildTools"]}] diff --git a/node_modules/node-gyp/test/fixtures/VS_2019_Community_workload.txt b/node_modules/node-gyp/test/fixtures/VS_2019_Community_workload.txt deleted file mode 100644 index 50071c25f189e..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2019_Community_workload.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community","version":"16.1.28922.388","packages":["Microsoft.VisualStudio.Workload.NativeDesktop","Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest","Microsoft.VisualStudio.VC.Ide.TestAdapterForGoogleTest","Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest","Microsoft.VisualStudio.VC.Ide.TestAdapterForBoostTest","Microsoft.VisualStudio.Component.VC.ATL","Microsoft.VisualStudio.VC.Ide.ATL","Microsoft.VisualStudio.VC.Ide.ATL.Resources","Microsoft.VisualCpp.ATL.X86","Microsoft.VisualCpp.ATL.X64","Microsoft.VisualCpp.ATL.Source","Microsoft.VisualCpp.ATL.Headers","Microsoft.VisualStudio.Component.VC.CMake.Project","Microsoft.VisualStudio.VC.CMake","Microsoft.VisualStudio.VC.CMake.Project","Microsoft.VisualStudio.VC.ExternalBuildFramework","Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core","Microsoft.VisualStudio.PackageGroup.TestTools.Native","Microsoft.VisualStudio.Component.VC.Redist.14.Latest","Microsoft.VisualStudio.VC.Templates.UnitTest","Microsoft.VisualStudio.VC.UnitTest.Desktop.Build.Core","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CPP","Microsoft.VisualStudio.VC.Templates.UnitTest.Resources","Microsoft.VisualStudio.VC.Templates.Desktop","Microsoft.VisualStudio.Component.Debugger.JustInTime","Microsoft.VisualStudio.Debugger.ImmersiveActivateHelper.Msi","Microsoft.VisualStudio.Debugger.JustInTime","Microsoft.VisualStudio.Debugger.JustInTime.Msi","Microsoft.VisualStudio.Component.Windows10SDK.17763","Win10SDK_10.0.17763","Microsoft.VisualStudio.Component.VC.DiagnosticTools","Microsoft.VisualStudio.Component.Graphics.Tools","Microsoft.VisualStudio.Component.VC.Tools.x86.x64","Microsoft.VisualCpp.CodeAnalysis.Extensions","Microsoft.VisualCpp.CodeAnalysis.Extensions.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86.Resources","Microsoft.VisualCpp.CodeAnalysis.Extensions.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX86","Microsoft.VisualCpp.VCTip.HostX64.TargetX86","Microsoft.VisualCpp.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX64","Microsoft.VisualCpp.VCTip.HostX64.TargetX64","Microsoft.VisualCpp.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX64","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.PGO.X86","Microsoft.VisualCpp.PGO.X64","Microsoft.VisualCpp.PGO.Headers","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x64.OneCore.Desktop","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualCpp.CRT.Headers","Microsoft.VisualStudio.Graphics.Viewers","Microsoft.VisualStudio.Graphics.Viewers.Resources","Microsoft.VisualStudio.Graphics.Msi","Microsoft.VisualStudio.Graphics.Msi","Microsoft.VisualStudio.Graphics.Analyzer","Microsoft.VisualStudio.Graphics.Analyzer.Targeted","Microsoft.VisualStudio.Graphics.Analyzer.Resources","Microsoft.VisualStudio.Graphics.Appid","Microsoft.VisualStudio.Graphics.Appid.Resources","Microsoft.VisualStudio.Component.VC.CoreIde","Microsoft.VisualStudio.VC.Ide.Pro","Microsoft.VisualStudio.VC.Ide.Pro.Resources","Microsoft.VisualStudio.VC.Templates.Pro","Microsoft.VisualStudio.VC.Templates.Pro.Resources","Microsoft.VisualStudio.VC.Items.Pro","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Reduced","Microsoft.VisualStudio.VC.Ide.x64","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Express","Microsoft.VisualStudio.VC.MSBuild.X64.v142","Microsoft.VisualStudio.VC.MSBuild.X64","Microsoft.VS.VC.MSBuild.X64.Resources","Microsoft.VisualStudio.VC.MSBuild.ARM.v142","Microsoft.VisualStudio.VC.MSBuild.ARM","Microsoft.VisualStudio.VC.MSBuild.x86.v142","Microsoft.VisualStudio.VC.MSBuild.X86","Microsoft.VisualStudio.VC.MSBuild.Base","Microsoft.VisualStudio.VC.MSBuild.Base.Resources","Microsoft.VisualStudio.VC.Ide.WinXPlus","Microsoft.VisualStudio.VC.Ide.Dskx","Microsoft.VisualStudio.VC.Ide.Dskx.Resources","Microsoft.VisualStudio.VC.Ide.Base","Microsoft.VisualStudio.VC.Ide.LanguageService","Microsoft.VisualStudio.VC.Ide.Core","Microsoft.VisualStudio.VC.Ide.Core.Resources","Microsoft.VisualStudio.VC.Ide.VCPkgDatabase","Microsoft.VisualStudio.VC.Ide.ProjectSystem","Microsoft.VisualStudio.VC.Ide.ProjectSystem.Resources","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine.Resources","Microsoft.VisualStudio.VC.Ide.LanguageService.Resources","Microsoft.VisualStudio.VC.Ide.Base.Resources","Component.Microsoft.VisualStudio.LiveShare","Microsoft.VisualStudio.LiveShare","Microsoft.Icecap.Analysis","Microsoft.Icecap.Analysis.Targeted","Microsoft.Icecap.Analysis.Resources","Microsoft.Icecap.Analysis.Resources.Targeted","Microsoft.Icecap.Collection.Msi","Microsoft.Icecap.Collection.Msi.Targeted","Microsoft.Icecap.Collection.Msi.Resources","Microsoft.Icecap.Collection.Msi.Resources.Targeted","Microsoft.DiagnosticsHub.Instrumentation","Microsoft.DiagnosticsHub.CpuSampling.ExternalDependencies","Microsoft.DiagnosticsHub.CpuSampling","Microsoft.DiagnosticsHub.CpuSampling.Targeted","Microsoft.PackageGroup.DiagnosticsHub.Platform","Microsoft.DiagnosticsHub.Runtime.ExternalDependencies","Microsoft.DiagnosticsHub.Runtime.ExternalDependencies.Targeted","Microsoft.DiagnosticsHub.Collection.ExternalDependencies.x64","Microsoft.DiagnosticsHub.Collection.StopService.Uninstall","Microsoft.DiagnosticsHub.Runtime","Microsoft.DiagnosticsHub.Runtime.Targeted","Microsoft.DiagnosticsHub.Collection","Microsoft.DiagnosticsHub.Collection.Service","Microsoft.DiagnosticsHub.Collection.StopService.Install","Microsoft.VisualStudio.Component.IntelliCode","Microsoft.VisualStudio.IntelliCode","Microsoft.Net.4.TargetingPack","Microsoft.VisualStudio.VC.Ide.ResourceEditor","Microsoft.VisualStudio.VC.Ide.ResourceEditor.Resources","Microsoft.VisualStudio.PackageGroup.TestTools.CodeCoverage","Microsoft.VisualStudio.PackageGroup.TestTools.Core","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.TestTools.Pex.Common","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.Legacy","Microsoft.VisualStudio.PackageGroup.MinShell.Interop","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Msi","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Common","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.TestTools","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Professional","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Common","Microsoft.VisualStudio.TestTools.TP.Legacy.Common.Res","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Agent","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.TestTools.TestWIExtension","Microsoft.VisualStudio.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.PackageGroup.TestTools.DataCollectors","Microsoft.VisualStudio.LiveShareApi","Microsoft.VisualStudio.Component.TextTemplating","Microsoft.VisualStudio.TextTemplating.MSBuild","Microsoft.VisualStudio.TextTemplating.Integration","Microsoft.VisualStudio.TextTemplating.Core","Microsoft.VisualStudio.TextTemplating.Integration.Resources","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.Component.MSBuild","Microsoft.NuGet.Build.Tasks","Microsoft.DiagnosticsHub.KB2882822.Win7","Microsoft.VisualStudio.PackageGroup.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Msi","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions","Microsoft.VisualStudio.ProTools","sqlsysclrtypes","sqlsysclrtypes","SQLCommon","Microsoft.VisualStudio.ProTools.Resources","Microsoft.VisualStudio.WebToolsExtensions","Microsoft.VisualStudio.WebTools","Microsoft.VisualStudio.WebTools.Resources","Microsoft.VisualStudio.WebTools.MSBuild","Microsoft.VisualStudio.WebTools.WSP.FSA","Microsoft.VisualStudio.WebTools.WSP.FSA.Resources","Microsoft.VisualStudio.VC.Ide.MDD","Microsoft.VisualStudio.VisualC.Logging","Microsoft.WebTools.Shared","Microsoft.WebTools.DotNet.Core.ItemTemplates","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.Windows.UniversalCRT.Msu.7","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.CodeAnalysis.Compilers","Microsoft.VisualStudio.Component.NuGet","Microsoft.CredentialProvider","Microsoft.VisualStudio.NuGet.PowershellBindingRedirect","Microsoft.VisualStudio.NuGet.Licenses","Microsoft.VisualStudio.PackageGroup.Community","Microsoft.VisualStudio.Community.Extra.Resources","Microsoft.VisualStudio.Community.Extra","Microsoft.VisualStudio.PackageGroup.Core","Microsoft.VisualStudio.CodeSense.Community","Microsoft.VisualStudio.TestTools.TeamFoundationClient","Microsoft.VisualStudio.PackageGroup.Debugger.Core","Microsoft.VisualStudio.PackageGroup.Debugger.TimeTravel.Record","Microsoft.VisualStudio.Debugger.TimeTravel.Runtime","Microsoft.VisualStudio.Debugger.TimeTravel.Runtime","Microsoft.VisualStudio.Debugger.TimeTravel.Agent","Microsoft.VisualStudio.Debugger.TimeTravel.Record","Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost","Microsoft.VisualStudio.VC.Ide.Debugger","Microsoft.VisualStudio.VC.Ide.Debugger.Concord","Microsoft.VisualStudio.VC.Ide.Debugger.Concord.Resources","Microsoft.VisualStudio.VC.Ide.Debugger.Resources","Microsoft.VisualStudio.VC.Ide.Common","Microsoft.VisualStudio.VC.Ide.Common.Resources","Microsoft.VisualStudio.Debugger.Parallel","Microsoft.VisualStudio.Debugger.Parallel.Resources","Microsoft.VisualStudio.Debugger.CollectionAgents","Microsoft.VisualStudio.Debugger.Managed","Microsoft.CodeAnalysis.VisualStudio.Setup","Microsoft.CodeAnalysis.ExpressionEvaluator","Microsoft.VisualStudio.Debugger.Concord.Managed","Microsoft.VisualStudio.Debugger.Concord.Managed.Resources","Microsoft.VisualStudio.Debugger.Managed.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Remote.DbgHelp.Win8","Microsoft.VisualStudio.Debugger.Concord.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Remote.DbgHelp.Win8","Microsoft.VisualStudio.Debugger.Concord.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger","Microsoft.VisualStudio.Debugger.Package.DiagHub.Client.VSx86","Microsoft.VisualStudio.Debugger.Remote.DiagHub.Client","Microsoft.VisualStudio.Debugger.Remote.DiagHub.Client","Microsoft.VisualStudio.Debugger.DbgHelp.Win8","Microsoft.VisualStudio.VC.MSVCDis","Microsoft.VisualStudio.ScriptedHost","Microsoft.VisualStudio.ScriptedHost.Targeted","Microsoft.VisualStudio.ScriptedHost.Resources","Microsoft.IntelliTrace.DiagnosticsHub","Microsoft.VisualStudio.Debugger.Concord","Microsoft.VisualStudio.Debugger.Concord.Resources","Microsoft.VisualStudio.Debugger.Resources","Microsoft.PackageGroup.ClientDiagnostics","Microsoft.VisualStudio.AppResponsiveness","Microsoft.VisualStudio.AppResponsiveness.Targeted","Microsoft.VisualStudio.AppResponsiveness.Resources","Microsoft.VisualStudio.ClientDiagnostics","Microsoft.VisualStudio.ClientDiagnostics.Targeted","Microsoft.VisualStudio.ClientDiagnostics.Resources","Microsoft.VisualStudio.PackageGroup.CommunityCore","Microsoft.VisualStudio.ProjectSystem.Full","Microsoft.VisualStudio.ProjectSystem","Microsoft.VisualStudio.Community.x86","Microsoft.VisualStudio.Community.x64","Microsoft.VisualStudio.Community","Microsoft.IntelliTrace.CollectorCab","Microsoft.VisualStudio.Community.Resources","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.VisualStudio.WebSiteProject.DTE","Microsoft.MSHtml","Microsoft.VisualStudio.Platform.CallHierarchy","Microsoft.VisualStudio.Community.Msi.Resources","Microsoft.VisualStudio.Community.Msi","Microsoft.VisualStudio.Devenv.Msi","Microsoft.VisualStudio.MinShell.Interop.Msi","Microsoft.VisualStudio.Editors","Microsoft.VisualStudio.Product.Community","Microsoft.VisualStudio.Workload.CoreEditor","Microsoft.VisualStudio.Component.CoreEditor","Microsoft.VisualStudio.PackageGroup.CoreEditor","Microsoft.VisualCpp.Tools.Common.UtilsPrereq","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.VirtualTree","Microsoft.VisualStudio.PackageGroup.Progression","Microsoft.VisualStudio.PerformanceProvider","Microsoft.VisualStudio.GraphModel","Microsoft.VisualStudio.GraphProvider","Microsoft.DiaSymReader","Microsoft.Build.Dependencies","Microsoft.Build.FileTracker.Msi","Microsoft.Build","Microsoft.VisualStudio.PackageGroup.NuGet","Microsoft.VisualStudio.NuGet.Core","Microsoft.VisualStudio.TextMateGrammars","Microsoft.VisualStudio.PackageGroup.TeamExplorer.Common","Microsoft.VisualStudio.TeamExplorer","Microsoft.ServiceHub","Microsoft.VisualStudio.ProjectServices","Microsoft.VisualStudio.OpenFolder.VSIX","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.PackageGroup.MinShell","Microsoft.VisualStudio.MinShell.Interop","Microsoft.VisualStudio.Log","Microsoft.VisualStudio.Log.Targeted","Microsoft.VisualStudio.Log.Resources","Microsoft.VisualStudio.Finalizer","Microsoft.VisualStudio.Devenv","Microsoft.VisualStudio.Devenv.Resources","Microsoft.VisualStudio.CoreEditor","Microsoft.VisualStudio.Platform.NavigateTo","Microsoft.VisualStudio.Connected","Microsoft.VisualStudio.PerfLib","Microsoft.VisualStudio.Connected.Resources","Microsoft.VisualStudio.MinShell","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.MinShell.Platform","Microsoft.VisualStudio.MinShell.Platform.Resources","Microsoft.VisualStudio.MefHosting","Microsoft.VisualStudio.MefHosting.Resources","Microsoft.VisualStudio.Initializer","Microsoft.VisualStudio.ExtensionManager","Microsoft.VisualStudio.Platform.Editor","Microsoft.VisualStudio.MinShell.x86","Microsoft.VisualStudio.NativeImageSupport","Microsoft.VisualStudio.MinShell.Msi","Microsoft.VisualStudio.MinShell.Msi.Resources","Microsoft.VisualStudio.LanguageServer","Microsoft.VisualStudio.Devenv.Config","Microsoft.VisualStudio.MinShell.Resources","Microsoft.Net.PackageGroup.4.7.2.Redist","Microsoft.Net.4.7.2.FullRedist","Microsoft.VisualStudio.Branding.Community"]}] diff --git a/node_modules/node-gyp/test/fixtures/VS_2019_Preview.txt b/node_modules/node-gyp/test/fixtures/VS_2019_Preview.txt deleted file mode 100644 index 806509e7ce865..0000000000000 --- a/node_modules/node-gyp/test/fixtures/VS_2019_Preview.txt +++ /dev/null @@ -1 +0,0 @@ -[{"path":"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Preview","version":"16.0.28608.199","packages":["Microsoft.VisualStudio.Product.Enterprise","Microsoft.VisualStudio.Workload.NativeDesktop","Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest","Microsoft.VisualStudio.VC.Ide.TestAdapterForGoogleTest","Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest","Microsoft.VisualStudio.VC.Ide.TestAdapterForBoostTest","Microsoft.VisualStudio.Component.VC.ATL","Microsoft.VisualStudio.VC.Ide.ATL","Microsoft.VisualStudio.VC.Ide.ATL.Resources","Microsoft.VisualCpp.ATL.X86","Microsoft.VisualCpp.ATL.X64","Microsoft.VisualCpp.ATL.Source","Microsoft.VisualCpp.ATL.Headers","Microsoft.VisualStudio.Component.VC.CMake.Project","Microsoft.VisualStudio.VC.CMake","Microsoft.VisualStudio.VC.CMake.Project","Microsoft.VisualStudio.VC.ExternalBuildFramework","Microsoft.VisualStudio.Component.VC.DiagnosticTools","Microsoft.VisualStudio.Component.Graphics.Tools","Microsoft.VisualStudio.Graphics.Viewers","Microsoft.VisualStudio.Graphics.Viewers.Resources","Microsoft.VisualStudio.Graphics.EnableTools","Microsoft.VisualStudio.Graphics.Msi","Microsoft.VisualStudio.Graphics.Msi","Microsoft.VisualStudio.Graphics.Analyzer","Microsoft.VisualStudio.Graphics.Analyzer.Targeted","Microsoft.VisualStudio.Graphics.Analyzer.Resources","Microsoft.VisualStudio.Graphics.Appid","Microsoft.VisualStudio.Graphics.Appid.Resources","Microsoft.VisualStudio.Component.Windows10SDK.17763","Win10SDK_10.0.17763","Microsoft.VisualStudio.Component.VC.Tools.x86.x64","Microsoft.VisualCpp.CodeAnalysis.Extensions","Microsoft.VisualCpp.CodeAnalysis.Extensions.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X86.Resources","Microsoft.VisualCpp.CodeAnalysis.Extensions.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64","Microsoft.VisualCpp.CodeAnalysis.ConcurrencyCheck.X64.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX86","Microsoft.VisualCpp.VCTip.HostX64.TargetX86","Microsoft.VisualCpp.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Tools.HostX64.TargetX64","Microsoft.VisualCpp.VCTip.HostX64.TargetX64","Microsoft.VisualCpp.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX64","Microsoft.VisualCpp.Premium.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX86.Resources","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64","Microsoft.VisualCpp.Premium.Tools.HostX64.TargetX64.Resources","Microsoft.VisualCpp.PGO.X86","Microsoft.VisualCpp.PGO.X64","Microsoft.VisualCpp.PGO.Headers","Microsoft.VisualCpp.CRT.x86.Store","Microsoft.VisualCpp.CRT.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.x64.Store","Microsoft.VisualCpp.CRT.x64.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x86.OneCore.Desktop","Microsoft.VisualCpp.CRT.Redist.x64.OneCore.Desktop","Microsoft.VisualStudio.PackageGroup.VC.Tools.x86","Microsoft.VisualCpp.Tools.HostX86.TargetX64","Microsoft.VisualCpp.VCTip.hostX86.targetX64","Microsoft.VisualCpp.Tools.Hostx86.Targetx64.Resources","Microsoft.VisualCpp.Tools.HostX86.TargetX86","Microsoft.VisualCpp.VCTip.hostX86.targetX86","Microsoft.VisualCpp.Tools.HostX86.TargetX86.Resources","Microsoft.VisualCpp.Tools.Core.Resources","Microsoft.VisualCpp.Tools.Core.x86","Microsoft.VisualCpp.DIA.SDK","Microsoft.VisualCpp.CRT.x86.Desktop","Microsoft.VisualCpp.CRT.x64.Desktop","Microsoft.VisualCpp.CRT.Source","Microsoft.VisualCpp.CRT.Redist.X86","Microsoft.VisualCpp.CRT.Redist.X64","Microsoft.VisualCpp.CRT.Redist.Resources","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.RuntimeDebug.14","Microsoft.VisualCpp.CRT.Headers","Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core","Microsoft.VisualStudio.PackageGroup.TestTools.Native","Microsoft.VisualStudio.ComponentGroup.ArchitectureTools.Native","Microsoft.VisualStudio.Component.ClassDesigner","Microsoft.VisualStudio.ClassDesigner","Microsoft.VisualStudio.ClassDesigner.Resources","Microsoft.VisualStudio.Component.VC.Redist.14.Latest","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualCpp.Redist.14.Latest","Microsoft.VisualStudio.VC.Templates.UnitTest","Microsoft.VisualStudio.VC.UnitTest.Desktop.Build.Core","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CPP","Microsoft.VisualStudio.VC.Templates.UnitTest.Resources","Microsoft.VisualStudio.VC.Templates.Desktop","Microsoft.VisualStudio.Component.VC.CoreIde","Microsoft.VisualStudio.VC.Ide.Pro","Microsoft.VisualStudio.VC.Ide.Pro.Resources","Microsoft.VisualStudio.VC.Templates.Pro","Microsoft.VisualStudio.VC.Templates.Pro.Resources","Microsoft.VisualStudio.VC.Items.Pro","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Reduced","Microsoft.VisualStudio.VC.Ide.x64","Microsoft.VisualStudio.PackageGroup.VC.CoreIDE.Express","Microsoft.VisualStudio.VC.MSBuild.X64.v142","Microsoft.VisualStudio.VC.MSBuild.X64","Microsoft.VS.VC.MSBuild.X64.Resources","Microsoft.VisualStudio.VC.MSBuild.ARM.v142","Microsoft.VisualStudio.VC.MSBuild.ARM","Microsoft.VisualStudio.VC.MSBuild.x86.v142","Microsoft.VisualStudio.VC.MSBuild.X86","Microsoft.VisualStudio.VC.MSBuild.Base","Microsoft.VisualStudio.VC.MSBuild.Base.Resources","Microsoft.VisualStudio.VC.Ide.WinXPlus","Microsoft.VisualStudio.VC.Ide.Dskx","Microsoft.VisualStudio.VC.Ide.Dskx.Resources","Microsoft.VisualStudio.VC.Ide.Base","Microsoft.VisualStudio.VC.Ide.LanguageService","Microsoft.VisualStudio.VC.Ide.Core","Microsoft.VisualStudio.VC.Ide.Core.Resources","Microsoft.VisualStudio.VC.Ide.VCPkgDatabase","Microsoft.VisualStudio.VC.Ide.Progression.Enterprise","Microsoft.VisualStudio.VC.Ide.ProjectSystem","Microsoft.VisualStudio.VC.Ide.ProjectSystem.Resources","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine","Microsoft.VisualStudio.VC.Ide.Core.VCProjectEngine.Resources","Microsoft.VisualStudio.VC.Ide.LanguageService.Resources","Microsoft.VisualStudio.VC.Ide.Base.Resources","Microsoft.VisualStudio.Component.CodeMap","Microsoft.VisualStudio.Component.GraphDocument","Microsoft.VisualStudio.Vmp","Microsoft.VisualStudio.GraphDocument","Microsoft.VisualStudio.GraphDocument.Resources","Microsoft.VisualStudio.CodeMap","Microsoft.VisualStudio.Component.SQL.LocalDB.Runtime","Microsoft.VisualStudio.Component.SQL.NCLI","sqllocaldb","sqlncli","Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions","Microsoft.VisualStudio.WebToolsExtensions","Microsoft.VisualStudio.WebTools","Microsoft.VisualStudio.WebTools.Resources","Microsoft.VisualStudio.WebTools.MSBuild","Microsoft.VisualStudio.PackageGroup.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Msi","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.Debugger.Script.Resources","Microsoft.VisualStudio.VC.Ide.MDD","Microsoft.VisualStudio.Component.NuGet","Microsoft.CredentialProvider","Component.Microsoft.VisualStudio.LiveShare","Microsoft.VisualStudio.LiveShare","Microsoft.VisualStudio.Component.Debugger.JustInTime","Microsoft.VisualStudio.Debugger.ImmersiveActivateHelper.Msi","Microsoft.VisualStudio.Debugger.JustInTime","Microsoft.VisualStudio.Debugger.JustInTime.Msi","Microsoft.VisualStudio.Component.IntelliTrace.FrontEnd","Microsoft.IntelliTrace.DiagnosticsHubAgent.Targeted","Microsoft.IntelliTrace.Debugger","Microsoft.IntelliTrace.Debugger.Targeted","Microsoft.IntelliTrace.FrontEnd","Microsoft.DiagnosticsHub.Instrumentation","Microsoft.DiagnosticsHub.CpuSampling","Microsoft.DiagnosticsHub.CpuSampling.Targeted","Microsoft.PackageGroup.DiagnosticsHub.Platform","Microsoft.DiagnosticsHub.Collection.StopService.Uninstall","Microsoft.DiagnosticsHub.Runtime","Microsoft.DiagnosticsHub.Runtime.Targeted","Microsoft.DiagnosticsHub.Runtime.Resources","Microsoft.DiagnosticsHub.Collection","Microsoft.DiagnosticsHub.Collection.Service","Microsoft.DiagnosticsHub.Collection.StopService.Install","Microsoft.VisualStudio.Dsl.GraphObject","Microsoft.Net.4.TargetingPack","Microsoft.VisualStudio.VC.Ide.ResourceEditor","Microsoft.VisualStudio.VC.Ide.ResourceEditor.Resources","Microsoft.VisualStudio.NuGet.Licenses","Microsoft.WebTools.Shared","Microsoft.VisualStudio.WebToolsExtensions.DotNet.Core.ItemTemplates","Microsoft.VisualStudio.Component.TextTemplating","Microsoft.VisualStudio.TextTemplating.MSBuild","Microsoft.VisualStudio.TextTemplating.Integration","Microsoft.VisualStudio.TextTemplating.Core","Microsoft.VisualStudio.TextTemplating.Integration.Resources","Microsoft.VisualStudio.ProTools","sqlsysclrtypes","sqlsysclrtypes","SQLCommon","Microsoft.VisualStudio.ProTools.Resources","Microsoft.VisualStudio.NuGet.Core","Microsoft.VisualStudio.PackageGroup.TestTools.CodeCoverage","Microsoft.VisualStudio.PackageGroup.IntelliTrace.Core","Microsoft.IntelliTrace.Core","Microsoft.IntelliTrace.Core.Concord","Microsoft.IntelliTrace.Core.Targeted","Microsoft.IntelliTrace.ProfilerProxy.Msi.x64","Microsoft.IntelliTrace.ProfilerProxy.Msi","Microsoft.VisualStudio.TestTools.DynamicCodeCoverage","Microsoft.VisualStudio.TestTools.CodeCoverage.Msi","Microsoft.VisualStudio.TestTools.CodeCoverage","Microsoft.Icecap.Analysis","Microsoft.Icecap.Analysis.Targeted","Microsoft.Icecap.Analysis.Resources","Microsoft.Icecap.Analysis.Resources.Targeted","Microsoft.Icecap.Collection.Msi","Microsoft.Icecap.Collection.Msi.Targeted","Microsoft.Icecap.Collection.Msi.Resources","Microsoft.Icecap.Collection.Msi.Resources.Targeted","Microsoft.VisualStudio.PackageGroup.TestTools.Core","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.TestTools.TestPlatform.V1.CLI","Microsoft.VisualStudio.TestTools.Pex.Common","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.Legacy","Microsoft.VisualStudio.PackageGroup.MinShell.Interop","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Msi","Microsoft.VisualStudio.TestTools.TP.Legacy.Tips.Common","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Tips.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.TestTools","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Remote","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Professional","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core.Premium","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Common","Microsoft.VisualStudio.TestTools.TP.Legacy.Common.Res","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Core.Resources","Microsoft.VisualStudio.TestTools.TestPlatform.Legacy.Agent","Microsoft.VisualStudio.PackageGroup.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.TestTools.TestWIExtension","Microsoft.VisualStudio.TestTools.TestPlatform.IDE","Microsoft.VisualStudio.PackageGroup.TestTools.DataCollectors","Microsoft.VisualStudio.TestTools.NE.Msi.Targeted","Microsoft.VisualStudio.TestTools.NetworkEmulation","Microsoft.VisualStudio.TestTools.DataCollectors","Microsoft.VisualCpp.CRT.ClickOnce.Msi","Microsoft.VisualStudio.WebTools.WSP.FSA","Microsoft.VisualStudio.WebTools.WSP.FSA.Resources","Microsoft.VisualStudio.Component.Static.Analysis.Tools","Microsoft.VisualCpp.Redist.14","Microsoft.VisualCpp.Redist.14","Microsoft.VisualStudio.StaticAnalysis","Microsoft.VisualStudio.StaticAnalysis.Resources","Microsoft.VisualStudio.PackageGroup.Community","Microsoft.VisualStudio.Community.Extra.Resources","Microsoft.VisualStudio.Community.Extra","Microsoft.VisualStudio.PackageGroup.Core","Microsoft.VisualStudio.CodeSense","Microsoft.VisualStudio.CodeSense.Community","Microsoft.VisualStudio.TestTools.TeamFoundationClient","Microsoft.VisualStudio.PackageGroup.Debugger.Core","Microsoft.VisualStudio.PackageGroup.Debugger.TimeTravel.Record","Microsoft.VisualStudio.Debugger.TimeTravel.Runtime","Microsoft.VisualStudio.Debugger.TimeTravel.Runtime","Microsoft.VisualStudio.Debugger.TimeTravel.Agent","Microsoft.VisualStudio.Debugger.TimeTravel.Record","Microsoft.VisualStudio.Debugger.VSCodeDebuggerHost","Microsoft.VisualStudio.VC.Ide.Debugger","Microsoft.VisualStudio.VC.Ide.Debugger.Concord","Microsoft.VisualStudio.VC.Ide.Debugger.Concord.Resources","Microsoft.VisualStudio.VC.Ide.Debugger.Resources","Microsoft.VisualStudio.VC.Ide.Common","Microsoft.VisualStudio.VC.Ide.Common.Resources","Microsoft.VisualStudio.Debugger.Parallel","Microsoft.VisualStudio.Debugger.Parallel.Resources","Microsoft.VisualStudio.Debugger.CollectionAgents","Microsoft.VisualStudio.Debugger.Managed","Microsoft.VisualStudio.Debugger.Concord.Managed","Microsoft.VisualStudio.Debugger.Concord.Managed.Resources","Microsoft.VisualStudio.Debugger.Managed.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote","Microsoft.VisualStudio.Debugger.Concord.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger.Remote.Resources","Microsoft.VisualStudio.Debugger","Microsoft.VisualStudio.Debugger.Package.DiagHub.Client.VSx86","Microsoft.VisualStudio.Debugger.Remote.DiagHub.Client","Microsoft.VisualStudio.Debugger.Remote.DiagHub.Client","Microsoft.VisualStudio.VC.MSVCDis","Microsoft.VisualStudio.ScriptedHost","Microsoft.VisualStudio.ScriptedHost.Targeted","Microsoft.VisualStudio.ScriptedHost.Resources","Microsoft.IntelliTrace.DiagnosticsHub","Microsoft.VisualStudio.Debugger.Concord","Microsoft.VisualStudio.Debugger.Concord.Resources","Microsoft.VisualStudio.Debugger.Resources","Microsoft.PackageGroup.ClientDiagnostics","Microsoft.VisualStudio.AppResponsiveness","Microsoft.VisualStudio.AppResponsiveness.Targeted","Microsoft.VisualStudio.AppResponsiveness.Resources","Microsoft.VisualStudio.ClientDiagnostics","Microsoft.VisualStudio.ClientDiagnostics.Targeted","Microsoft.VisualStudio.ClientDiagnostics.Resources","Microsoft.VisualStudio.PackageGroup.ProfessionalCore","Microsoft.VisualStudio.Professional","Microsoft.VisualStudio.Professional.Msi","Microsoft.VisualStudio.PackageGroup.EnterpriseCore","Microsoft.VisualStudio.Enterprise.Msi","Microsoft.VisualStudio.Enterprise","Microsoft.ShDocVw","Microsoft.VisualStudio.PackageGroup.CommunityCore","Microsoft.VisualStudio.ProjectSystem.Full","Microsoft.VisualStudio.ProjectSystem","Microsoft.VisualStudio.Community.x86","Microsoft.VisualStudio.Community.x64","Microsoft.VisualStudio.Community","Microsoft.IntelliTrace.CollectorCab","Microsoft.VisualStudio.Community.Resources","Microsoft.VisualStudio.WebSiteProject.DTE","Microsoft.MSHtml","Microsoft.VisualStudio.Platform.CallHierarchy","Microsoft.VisualStudio.Community.Msi.Resources","Microsoft.VisualStudio.Community.Msi","Microsoft.VisualStudio.Devenv.Msi","Microsoft.VisualStudio.MinShell.Interop.Msi","Microsoft.VisualStudio.Editors","Microsoft.VisualStudio.Net.Eula.Resources","Microsoft.CodeAnalysis.ExpressionEvaluator","Microsoft.CodeAnalysis.VisualStudio.Setup","Microsoft.Component.MSBuild","Microsoft.NuGet.Build.Tasks","Microsoft.VisualStudio.Component.Roslyn.Compiler","Microsoft.CodeAnalysis.Compilers","Microsoft.VisualStudio.Workload.CoreEditor","Microsoft.VisualStudio.Component.CoreEditor","Microsoft.VisualStudio.PackageGroup.CoreEditor","Microsoft.VisualCpp.Tools.Common.UtilsPrereq","Microsoft.VisualCpp.Tools.Common.Utils","Microsoft.VisualCpp.Tools.Common.Utils.Resources","Microsoft.VisualStudio.PackageGroup.VsDevCmd","Microsoft.VisualStudio.VsDevCmd.Ext.NetFxSdk","Microsoft.VisualStudio.VsDevCmd.Core.WinSdk","Microsoft.VisualStudio.VsDevCmd.Core.DotNet","Microsoft.VisualStudio.VC.DevCmd","Microsoft.VisualStudio.VC.DevCmd.Resources","Microsoft.VisualStudio.VirtualTree","Microsoft.VisualStudio.PackageGroup.Progression","Microsoft.VisualStudio.PerformanceProvider","Microsoft.VisualStudio.GraphModel","Microsoft.VisualStudio.GraphProvider","Microsoft.DiaSymReader","Microsoft.Build.Dependencies","Microsoft.Build.FileTracker.Msi","Microsoft.Build","Microsoft.VisualStudio.TextMateGrammars","Microsoft.VisualStudio.PackageGroup.TeamExplorer.Common","Microsoft.VisualStudio.TeamExplorer","Microsoft.ServiceHub","Microsoft.VisualStudio.ProjectServices","Microsoft.VisualStudio.SLNX.VSIX","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.FileHandler.Msi","Microsoft.VisualStudio.PackageGroup.MinShell","Microsoft.VisualStudio.MinShell.Interop","Microsoft.VisualStudio.Log","Microsoft.VisualStudio.Log.Targeted","Microsoft.VisualStudio.Log.Resources","Microsoft.VisualStudio.Finalizer","Microsoft.VisualStudio.Devenv","Microsoft.VisualStudio.Devenv.Resources","Microsoft.VisualStudio.CoreEditor","Microsoft.VisualStudio.Platform.NavigateTo","Microsoft.VisualStudio.Connected","Microsoft.VisualStudio.Connected.Resources","Microsoft.VisualStudio.MinShell","Microsoft.VisualStudio.Setup.Configuration","Microsoft.VisualStudio.Platform.Search","Microsoft.VisualStudio.MinShell.Platform","Microsoft.VisualStudio.MinShell.Platform.Resources","Microsoft.VisualStudio.MefHosting","Microsoft.VisualStudio.MefHosting.Resources","Microsoft.VisualStudio.Initializer","Microsoft.VisualStudio.ExtensionManager","Microsoft.VisualStudio.Platform.Editor","Microsoft.VisualStudio.MinShell.x86","Microsoft.VisualStudio.NativeImageSupport","Microsoft.VisualStudio.MinShell.Msi","Microsoft.VisualStudio.MinShell.Msi.Resources","Microsoft.VisualStudio.LanguageServer","Microsoft.VisualStudio.Devenv.Config","Microsoft.VisualStudio.MinShell.Resources","Microsoft.Net.PackageGroup.4.7.2.Redist","Microsoft.VisualStudio.Branding.Enterprise"]}] diff --git a/node_modules/node-gyp/test/fixtures/ca-bundle.crt b/node_modules/node-gyp/test/fixtures/ca-bundle.crt deleted file mode 100644 index fb1dea98a78c8..0000000000000 --- a/node_modules/node-gyp/test/fixtures/ca-bundle.crt +++ /dev/null @@ -1,40 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDJjCCAg4CAhnOMA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQU3Ryb25n -TG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRowGAYDVQQDDBFjYS5zdHJv -bmdsb29wLmNvbTAeFw0xNTEyMDgyMzM1MzNaFw00MzA0MjQyMzM1MzNaMBkxFzAV -BgNVBAMMDnN0cm9uZ2xvb3AuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAwOYI7OZ2FX/YjRgLZoDQlbPc5UZXU/j0e1wwiJNPtPEax9Y5Uoza0Pnt -Ikzkc2SfvQ+IJrhXo385tI0W5juuqbHnE7UrjUuPjUX6NHevkxcs/flmjan5wnZM -cPsGhH71WDuUEEflvZihf2Se2x+xgZtMhc5XGmVmRuZFYKvkgUhA2/w8/QrK+jPT -n9QRJxZjWNh2RBdC1B7u4jffSmOSUljYFH1I2eTeY+Rdi6YUIYSU9gEoZxsv3Tia -SomfMF5jt2Mouo6MzA+IhLvvFjcrcph1Qxgi9RkfdCMMd+Ipm9YWELkyG1bDRpQy -0iyHD4gvVsAqz1Y2KdRSdc3Kt+nTqwIDAQABoxkwFzAVBgNVHREEDjAMhwQAAAAA -hwR/AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAhy4J0hML3NgmDRHdL5/iTucBe22Mf -jJjg2aifD1S187dHm+Il4qZNO2plWwAhN0h704f+8wpsaALxUvBIu6nvlvcMP5PH -jGN5JLe2Km3UaPvYOQU2SgacLilu+uBcIo2JSHLV6O7ziqUj5Gior6YxDLCtEZie -Ea8aX5/YjuACtEMJ1JjRqjgkM66XAoUe0E8onOK3FgTIO3tGoTJwRp0zS50pFuP0 -PsZtT04ck6mmXEXXknNoAyBCvPypfms9OHqcUIW9fiQnrGbS/Ri4QSQYj0DtFk/1 -na4fY1gf3zTHxH8259b/TOOaPfTnCEsOQtjUrWNR4xhmVZ+HJy4yytUW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDbzCCAlcCAmm6MA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNVBAYTAlVTMQswCQYD -VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQU3Ryb25n -TG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRowGAYDVQQDDBFjYS5zdHJv -bmdsb29wLmNvbTAeFw0xNTEyMDgyMzM1MzNaFw00MzA0MjQyMzM1MzNaMH0xCzAJ -BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZ -MBcGA1UECgwQU3Ryb25nTG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRow -GAYDVQQDDBFjYS5zdHJvbmdsb29wLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANfj86jkvvYDjHBgiqWhk9Cj+bqiMq3MqnV0CBO4iuK33Fo6XssE -H+yVdXlIBFbFe6t655MdBVOR2Sfj7WqNh96vhu6PyDHiwcQlTaiLU6nhIed1J4Wv -lvnJHFmp8Wbtx5AgLT4UYu03ftvXEl2DLi3vhSL2tRM1ebXHB/KPbRWkb25DPX0P -foOHot3f2dgNe2x6kponf7E/QDmAu3s7Nlkfh+ryDhgGU7wocXEhXbprNqRqOGNo -xbXgUI+/9XDxYT/7Gn5LF/fPjtN+aB0SKMnTsDhprVlZie83mlqJ46fOOrR+vrsQ -mi/1m/TadrARtZoIExC/cQRdVM05EK4tUa8CAwEAATANBgkqhkiG9w0BAQsFAAOC -AQEAQ7k5WhyhDTIGYCNzRnrMHWSzGqa1y4tJMW06wafJNRqTm1cthq1ibc6Hfq5a -K10K0qMcgauRTfQ1MWrVCTW/KnJ1vkhiTOH+RvxapGn84gSaRmV6KZen0+gMsgae -KEGe/3Hn+PmDVV+PTamHgPACfpTww38WHIe/7Ce9gHfG7MZ8cKHNZhDy0IAYPln+ -YRwMLd7JNQffHAbWb2CE1mcea4H/12U8JZW5tHCF6y9V+7IuDzqwIrLKcW3lG17n -VUG6ODF/Ryqn3V5X+TL91YyXi6c34y34IpC7MQDV/67U7+5Bp5CfeDPWW2wVSrW+ -uGZtfEvhbNm6m2i4UNmpCXxUZQ== ------END CERTIFICATE----- diff --git a/node_modules/node-gyp/test/fixtures/ca.crt b/node_modules/node-gyp/test/fixtures/ca.crt deleted file mode 100644 index aaf97575b18b4..0000000000000 --- a/node_modules/node-gyp/test/fixtures/ca.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDZDCCAkwCCQCAzfCLqrJvuTANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV -UzELMAkGA1UECAwCQ0ExEDAOBgNVBAoMB05vZGUuanMxETAPBgNVBAsMCG5vZGUt -Z3lwMRIwEAYDVQQDDAlsb2NhbGhvc3QxHzAdBgkqhkiG9w0BCQEWEGJ1aWxkQG5v -ZGVqcy5vcmcwHhcNMTkwNjIyMDYyMjMzWhcNMjIwNDExMDYyMjMzWjB0MQswCQYD -VQQGEwJVUzELMAkGA1UECAwCQ0ExEDAOBgNVBAoMB05vZGUuanMxETAPBgNVBAsM -CG5vZGUtZ3lwMRIwEAYDVQQDDAlsb2NhbGhvc3QxHzAdBgkqhkiG9w0BCQEWEGJ1 -aWxkQG5vZGVqcy5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDS -CHjvtVW4HdbbUwZ/ZV9s6U4x0KSoyNQrsCZjB8kRpFPe50DS5mfmu2SNBGYKRgzk -4QEEwFB9N2o8YTWsCefSRl6ti4ToPZqulU4hhRKYrEGtMJcRzi3IN7s200JaO3UH -01Su8ruO0NESb5zEU1Ykfh8Lub8TGEAINmgI61d/5d5Aq3kDjUHQJt1Ekw03Ylnu -juQyCGZxLxnngu0mIvwzyL/UeeUgsfQLzvppUk6In7tC1zzMjSPWo0c8qu6KvrW4 -bKYnkZkzdQifzbpO5ERMEsh5HWq0uHa6+dgcVHFvlhdqF4Uat87ygNplVf0txsZB -MNVqbz1k6xkZYMnzDoydAgMBAAEwDQYJKoZIhvcNAQELBQADggEBADspZGtKpWxy -J1W3FA1aeQhMvequQTcMRz4avkm4K4HfTdV1iVD4CbvdezBphouBlyLVLDFJP7RZ -m7dBJVgBwnxufoFLne8cR2MGqDRoySbFT1AtDJdxabE6Fg+QGUpgOQfeBJ6ANlSB -+qJ+HG4QA+Ouh5hxz9mgYwkIsMUABHiwENdZ/kT8Edw4xKgd3uH0YP4iiePMD66c -rzW3uXH5J1jnKgBlpxtog4P6dHCcoq+PZJ17W5bdXNyqC1LPzQqniZ2BNcEZ4ix3 -slAZAOWD1zLLGJhBPMV1fa0sHNBWc6oicr3YK/IDb0cp9kiLvnUu1pHy+LWQGqtC -rceJuGsnJEQ= ------END CERTIFICATE----- diff --git a/node_modules/node-gyp/test/fixtures/nodedir/include/node/config.gypi b/node_modules/node-gyp/test/fixtures/nodedir/include/node/config.gypi deleted file mode 100644 index e767534082f8c..0000000000000 --- a/node_modules/node-gyp/test/fixtures/nodedir/include/node/config.gypi +++ /dev/null @@ -1,6 +0,0 @@ -# Test configuration -{ - 'variables': { - 'build_with_electron': true - } -} diff --git a/node_modules/node-gyp/test/fixtures/server.crt b/node_modules/node-gyp/test/fixtures/server.crt deleted file mode 100644 index 5d0c440e0788a..0000000000000 --- a/node_modules/node-gyp/test/fixtures/server.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDYjCCAkoCCQCSlmGR7KzZGTANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV -UzELMAkGA1UECAwCQ0ExEDAOBgNVBAoMB05vZGUuanMxETAPBgNVBAsMCG5vZGUt -Z3lwMRIwEAYDVQQDDAlsb2NhbGhvc3QxHzAdBgkqhkiG9w0BCQEWEGJ1aWxkQG5v -ZGVqcy5vcmcwHhcNMTkwNjIyMDYyNTU1WhcNMjkwNjE5MDYyNTU1WjByMQswCQYD -VQQGEwJVUzELMAkGA1UECAwCQ0ExEDAOBgNVBAoMB05vZGUuanMxETAPBgNVBAsM -CG5vZGUtZ3lwMRIwEAYDVQQDDAlsb2NhbGhvc3QxHTAbBgkqhkiG9w0BCQEWDmJ1 -aWxkQGlvanMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6S1E -2WchgmbJYqCnpN7310ZgHjIOqeJe6MpSue2u6z6mTNd5izgvQNaANmn3xLFCS5zs -uZaTvdPYPkcmSQzb1YcZSUYnAxZifjYARc6kb5GSBl3q+O70ELyFrimXfZ4JI+bd -IG9KiHY17DlvZZZj/csGYVWWg0mkeH3O5LPX6/DXQVh/9+gZ02/cdIBCAtZHQwqx -7tF/qZA/kD4GZNFpU1DYHzf9H6g9htoCqmNHQWrV2T9yFybt6mbZp9kglBmyKYCc -7hmQnb7N/mHn1yIuwhBsirCJTfKH86gN81u8M3+SVHA2VUHDllcNhpDWlmInXA+I -tHdGZHCp95ohqpCPgQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCdvYj6CD0ZLwT2 -3t1r+deC3TJuHlNVSeKeT7wIfFnh2FW5riGV0q/w6eXPLTHjuiS6YmpAAbdNUgX/ -sq64FqI2RLpX6pgY5yB0SKopMcJxMLKqmF4zHpIHxtYN5EmN3PR0vehneBR/nZ2T -3ikvWD5JeXlm7Dfw+tjijdxM/sEoDWErGup4mMKMd1s5s830p+ITJUa50d0DLFdH -mqPSbUZF8mMPwGJd+nu1Ht3gTLtK7+gYJgGtXMJmGC0Qg77EJHDB2NbotgDGNmSU -1H9BpAeFHHIcbh2Rr7kkTvnh/c03vFe+CsDZmezcmRpRzW1fKj3YbfqBxU4XwJrL -a5T/N9xU ------END CERTIFICATE----- diff --git a/node_modules/node-gyp/test/fixtures/server.key b/node_modules/node-gyp/test/fixtures/server.key deleted file mode 100644 index a8447391e02e2..0000000000000 --- a/node_modules/node-gyp/test/fixtures/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA6S1E2WchgmbJYqCnpN7310ZgHjIOqeJe6MpSue2u6z6mTNd5 -izgvQNaANmn3xLFCS5zsuZaTvdPYPkcmSQzb1YcZSUYnAxZifjYARc6kb5GSBl3q -+O70ELyFrimXfZ4JI+bdIG9KiHY17DlvZZZj/csGYVWWg0mkeH3O5LPX6/DXQVh/ -9+gZ02/cdIBCAtZHQwqx7tF/qZA/kD4GZNFpU1DYHzf9H6g9htoCqmNHQWrV2T9y -Fybt6mbZp9kglBmyKYCc7hmQnb7N/mHn1yIuwhBsirCJTfKH86gN81u8M3+SVHA2 -VUHDllcNhpDWlmInXA+ItHdGZHCp95ohqpCPgQIDAQABAoIBABW8R4ewalo6dJlB -+n6O3jFt+PW3mtBRLqGqgm2cb0q0a1IMX+MPWLBFjmwEErl+AH0F4rcmBx2Ryr17 -amEy1qcf0caXyHksNAApznqzWXag7iizxnxv4cZRnHBwphNqkNWM5p3oYd04j6w2 -amDg1O9KZozaKo6QZclpiMiezwjKG+PVZLT8p7afswjv+yDWPDByhlcGiye9QD1T -VuZ0QCoXp6N/8JxW0gdkLp9NqFvGeGFzJ5h6L+d7A6BWw8akXrBRHHcKkyvVYBfd -myhSzSK4FPFMaxaEY/65FlVSyAO6ezGm3Umx4g7mkFjLdwKWaIOjkBkPeFgl3Pp4 -7Lo5X3UCgYEA/FrrIwmEU5ayulBVScEMKeavu5eNY4r0Sqbpov2oyTdYe8G49Pzy -ryMXfunY43moLKpajGwgTKRGvdqFtK08AAkaCssiAPkP3rZuZvMTF4sLo/vlWrjP -3er+tUqj22BzXi5XV0BAvH8Y3TL8KQ3he/8JxDvkC811/DQ9Y/Da3U8CgYEA7Itw -UM37URma08Bj9VTMoL9ZCyURewX+ZLDb2+O8sXGXJs28i1RkE6PTBlnRmedn+Jjk -byzQ5Cs5wA5uMbhYTA7kgXOs1bvgQqmlLmyL6FfHkucoMhr2Di7VeGf4OxE26JZ8 -JdY4+1MOyI3A2rR8WU+GmHxy0ay4K2xe6W0vsi8CgYBoGLEKIPDe8jkDtgOYivOT -jT9MaLXALB+dc8DIpU4swpHTaxP6qyUIrbcReTEolJSU6Ci16BxiwRkVU8D3yMYJ -VbfSX/zE3fh37FUaToa/nXHN0SjJBZdpeXhcHE//PIgaf48zxKNvnhYJmPB/luQ+ -m/PRaMsnOzfCM2JniYEe7QKBgGwjnxhB4tgDtaWCue/pcZc3gzS2IJS2e8N6mzie -l6Ajhu+FdOHZldrotUuc+la61OxwsVYmDeWR4VftAPGYDj3PPSX1RRl9R5wSRGLB -2wBASQvew6CMdNqtDIh8N56BUzHnwh/mHKzBHuwO6hDSHFsUITtLAY7bwGKRq55Z -fUmfAoGBANOYFyoJoDLcl+Jd750lyqfCifcGtkRdmZMtrPXaYnD8ZGme9vz1vsK/ -4iUkV3mi7Z9s1LXMa/tPPfKdVhCM1PXost3/si0+u1Bz5yKqEPXlyy2ltpIVyGu8 -yiy7y75asp8Iii/1cgtwyp9+VeSif8wJ+MHQoGdGxvAQP80R3EjF ------END RSA PRIVATE KEY----- diff --git a/node_modules/node-gyp/test/fixtures/test-charmap.py b/node_modules/node-gyp/test/fixtures/test-charmap.py deleted file mode 100644 index 63aa77bb482ef..0000000000000 --- a/node_modules/node-gyp/test/fixtures/test-charmap.py +++ /dev/null @@ -1,31 +0,0 @@ -import sys -import locale - -try: - reload(sys) -except NameError: # Python 3 - pass - - -def main(): - encoding = locale.getdefaultlocale()[1] - if not encoding: - return False - - try: - sys.setdefaultencoding(encoding) - except AttributeError: # Python 3 - pass - - textmap = { - "cp936": "\u4e2d\u6587", - "cp1252": "Lat\u012Bna", - "cp932": "\u306b\u307b\u3093\u3054", - } - if encoding in textmap: - print(textmap[encoding]) - return True - - -if __name__ == "__main__": - print(main()) diff --git a/node_modules/node-gyp/test/process-exec-sync.js b/node_modules/node-gyp/test/process-exec-sync.js deleted file mode 100644 index 21763bc26de10..0000000000000 --- a/node_modules/node-gyp/test/process-exec-sync.js +++ /dev/null @@ -1,140 +0,0 @@ -'use strict' - -const fs = require('graceful-fs') -const childProcess = require('child_process') - -function startsWith (str, search, pos) { - if (String.prototype.startsWith) { - return str.startsWith(search, pos) - } - - return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search -} - -function processExecSync (file, args, options) { - var child, error, timeout, tmpdir, command - command = makeCommand(file, args) - - /* - this function emulates child_process.execSync for legacy node <= 0.10.x - derived from https://github.com/gvarsanyi/sync-exec/blob/master/js/sync-exec.js - */ - - options = options || {} - // init timeout - timeout = Date.now() + options.timeout - // init tmpdir - var osTempBase = '/tmp' - var os = determineOS() - osTempBase = '/tmp' - - if (process.env.TMP) { - osTempBase = process.env.TMP - } - - if (osTempBase[osTempBase.length - 1] !== '/') { - osTempBase += '/' - } - - tmpdir = osTempBase + 'processExecSync.' + Date.now() + Math.random() - fs.mkdirSync(tmpdir) - - // init command - if (os === 'linux') { - command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + - '/stderr); echo $? > ' + tmpdir + '/status' - } else { - command = '(' + command + ' > ' + tmpdir + '/stdout 2> ' + tmpdir + - '/stderr) | echo %errorlevel% > ' + tmpdir + '/status | exit' - } - - // init child - child = childProcess.exec(command, options) - - var maxTry = 100000 // increases the test time by 6 seconds on win-2016-node-0.10 - var tryCount = 0 - while (tryCount < maxTry) { - try { - var x = fs.readFileSync(tmpdir + '/status') - if (x.toString() === '0') { - break - } - } catch (ignore) {} - tryCount++ - if (Date.now() > timeout) { - error = child - break - } - } - - ['stdout', 'stderr', 'status'].forEach(function (file) { - child[file] = fs.readFileSync(tmpdir + '/' + file, options.encoding) - setTimeout(unlinkFile, 500, tmpdir + '/' + file) - }) - - child.status = Number(child.status) - if (child.status !== 0) { - error = child - } - - try { - fs.rmdirSync(tmpdir) - } catch (ignore) {} - if (error) { - throw error - } - return child.stdout -} - -function makeCommand (file, args) { - var command, quote - command = file - if (args.length > 0) { - for (var i in args) { - command = command + ' ' - if (args[i][0] === '-') { - command = command + args[i] - } else { - if (!quote) { - command = command + '"' - quote = true - } - command = command + args[i] - if (quote) { - if (args.length === (parseInt(i) + 1)) { - command = command + '"' - } - } - } - } - } - return command -} - -function determineOS () { - var os = '' - var tmpVar = '' - if (process.env.OSTYPE) { - tmpVar = process.env.OSTYPE - } else if (process.env.OS) { - tmpVar = process.env.OS - } else { - // default is linux - tmpVar = 'linux' - } - - if (startsWith(tmpVar, 'linux')) { - os = 'linux' - } - if (startsWith(tmpVar, 'win')) { - os = 'win' - } - - return os -} - -function unlinkFile (file) { - fs.unlinkSync(file) -} - -module.exports = processExecSync diff --git a/node_modules/node-gyp/test/simple-proxy.js b/node_modules/node-gyp/test/simple-proxy.js deleted file mode 100644 index cb0dfcfec7edc..0000000000000 --- a/node_modules/node-gyp/test/simple-proxy.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict' - -const http = require('http') -const https = require('https') -const server = http.createServer(handler) -const port = +process.argv[2] -const prefix = process.argv[3] -const upstream = process.argv[4] -var calls = 0 - -server.listen(port) - -function handler (req, res) { - if (req.url.indexOf(prefix) !== 0) { - throw new Error('request url [' + req.url + '] does not start with [' + prefix + ']') - } - - var upstreamUrl = upstream + req.url.substring(prefix.length) - https.get(upstreamUrl, function (ures) { - ures.on('end', function () { - if (++calls === 2) { - server.close() - } - }) - ures.pipe(res) - }) -} diff --git a/node_modules/node-gyp/test/test-addon.js b/node_modules/node-gyp/test/test-addon.js deleted file mode 100644 index f79eff73c169e..0000000000000 --- a/node_modules/node-gyp/test/test-addon.js +++ /dev/null @@ -1,150 +0,0 @@ -'use strict' - -const test = require('tap').test -const path = require('path') -const fs = require('graceful-fs') -const childProcess = require('child_process') -const os = require('os') -const addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') -const nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') -const execFileSync = childProcess.execFileSync || require('./process-exec-sync') -const execFile = childProcess.execFile - -function runHello (hostProcess) { - if (!hostProcess) { - hostProcess = process.execPath - } - var testCode = "console.log(require('hello_world').hello())" - return execFileSync(hostProcess, ['-e', testCode], { cwd: __dirname }).toString() -} - -function getEncoding () { - var code = 'import locale;print(locale.getdefaultlocale()[1])' - return execFileSync('python', ['-c', code]).toString().trim() -} - -function checkCharmapValid () { - var data - try { - data = execFileSync('python', ['fixtures/test-charmap.py'], - { cwd: __dirname }) - } catch (err) { - return false - } - var lines = data.toString().trim().split('\n') - return lines.pop() === 'True' -} - -test('build simple addon', function (t) { - t.plan(3) - - // Set the loglevel otherwise the output disappears when run via 'npm test' - var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length - 1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - t.strictEqual(runHello().trim(), 'world') - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') -}) - -test('build simple addon in path with non-ascii characters', function (t) { - t.plan(1) - - if (!checkCharmapValid()) { - return t.skip('python console app can\'t encode non-ascii character.') - } - - var testDirNames = { - cp936: '文件夹', - cp1252: 'Latīna', - cp932: 'フォルダ' - } - // Select non-ascii characters by current encoding - var testDirName = testDirNames[getEncoding()] - // If encoding is UTF-8 or other then no need to test - if (!testDirName) { - return t.skip('no need to test') - } - - t.plan(3) - - var data - var configPath = path.join(addonPath, 'build', 'config.gypi') - try { - data = fs.readFileSync(configPath, 'utf8') - } catch (err) { - t.error(err) - return - } - var config = JSON.parse(data.replace(/#.+\n/, '')) - var nodeDir = config.variables.nodedir - var testNodeDir = path.join(addonPath, testDirName) - // Create symbol link to path with non-ascii characters - try { - fs.symlinkSync(nodeDir, testNodeDir, 'dir') - } catch (err) { - switch (err.code) { - case 'EEXIST': break - case 'EPERM': - t.error(err, 'Please try to running console as an administrator') - return - default: - t.error(err) - return - } - } - - var cmd = [ - nodeGyp, - 'rebuild', - '-C', - addonPath, - '--loglevel=verbose', - '-nodedir=' + testNodeDir - ] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { - try { - fs.unlink(testNodeDir) - } catch (err) { - t.error(err) - } - - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length - 1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - t.strictEqual(runHello().trim(), 'world') - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') -}) - -test('addon works with renamed host executable', function (t) { - // No `fs.copyFileSync` before node8. - if (process.version.substr(1).split('.')[0] < 8) { - t.skip('skipping test for old node version') - t.end() - return - } - - t.plan(3) - - var notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath)) - fs.copyFileSync(process.execPath, notNodePath) - - var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] - var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { - var logLines = stderr.toString().trim().split(/\r?\n/) - var lastLine = logLines[logLines.length - 1] - t.strictEqual(err, null) - t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') - t.strictEqual(runHello(notNodePath).trim(), 'world') - fs.unlinkSync(notNodePath) - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') -}) diff --git a/node_modules/node-gyp/test/test-configure-python.js b/node_modules/node-gyp/test/test-configure-python.js deleted file mode 100644 index 4290e7af1bb1c..0000000000000 --- a/node_modules/node-gyp/test/test-configure-python.js +++ /dev/null @@ -1,82 +0,0 @@ -'use strict' - -const test = require('tap').test -const path = require('path') -const devDir = require('./common').devDir() -const gyp = require('../lib/node-gyp') -const requireInject = require('require-inject') -const configure = requireInject('../lib/configure', { - 'graceful-fs': { - openSync: function () { return 0 }, - closeSync: function () { }, - writeFile: function (file, data, cb) { cb() }, - stat: function (file, cb) { cb(null, {}) }, - mkdir: function (dir, options, cb) { cb() }, - promises: { - writeFile: function (file, data) { return Promise.resolve(null) } - } - } -}) - -const EXPECTED_PYPATH = path.join(__dirname, '..', 'gyp', 'pylib') -const SEPARATOR = process.platform === 'win32' ? ';' : ':' -const SPAWN_RESULT = { on: function () { } } - -require('npmlog').level = 'warn' - -test('configure PYTHONPATH with no existing env', function (t) { - t.plan(1) - - delete process.env.PYTHONPATH - - var prog = gyp() - prog.parseArgv([]) - prog.spawn = function () { - t.equal(process.env.PYTHONPATH, EXPECTED_PYPATH) - return SPAWN_RESULT - } - prog.devDir = devDir - configure(prog, [], t.fail) -}) - -test('configure PYTHONPATH with existing env of one dir', function (t) { - t.plan(2) - - var existingPath = path.join('a', 'b') - process.env.PYTHONPATH = existingPath - - var prog = gyp() - prog.parseArgv([]) - prog.spawn = function () { - t.equal(process.env.PYTHONPATH, [EXPECTED_PYPATH, existingPath].join(SEPARATOR)) - - var dirs = process.env.PYTHONPATH.split(SEPARATOR) - t.deepEqual(dirs, [EXPECTED_PYPATH, existingPath]) - - return SPAWN_RESULT - } - prog.devDir = devDir - configure(prog, [], t.fail) -}) - -test('configure PYTHONPATH with existing env of multiple dirs', function (t) { - t.plan(2) - - var pythonDir1 = path.join('a', 'b') - var pythonDir2 = path.join('b', 'c') - var existingPath = [pythonDir1, pythonDir2].join(SEPARATOR) - process.env.PYTHONPATH = existingPath - - var prog = gyp() - prog.parseArgv([]) - prog.spawn = function () { - t.equal(process.env.PYTHONPATH, [EXPECTED_PYPATH, existingPath].join(SEPARATOR)) - - var dirs = process.env.PYTHONPATH.split(SEPARATOR) - t.deepEqual(dirs, [EXPECTED_PYPATH, pythonDir1, pythonDir2]) - - return SPAWN_RESULT - } - prog.devDir = devDir - configure(prog, [], t.fail) -}) diff --git a/node_modules/node-gyp/test/test-create-config-gypi.js b/node_modules/node-gyp/test/test-create-config-gypi.js deleted file mode 100644 index eeac73fab1dcc..0000000000000 --- a/node_modules/node-gyp/test/test-create-config-gypi.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict' - -const path = require('path') -const { test } = require('tap') -const gyp = require('../lib/node-gyp') -const createConfigGypi = require('../lib/create-config-gypi') -const { parseConfigGypi, getCurrentConfigGypi } = createConfigGypi.test - -test('config.gypi with no options', async function (t) { - t.plan(2) - - const prog = gyp() - prog.parseArgv([]) - - const config = await getCurrentConfigGypi({ gyp: prog, vsInfo: {} }) - t.equal(config.target_defaults.default_configuration, 'Release') - t.equal(config.variables.target_arch, process.arch) -}) - -test('config.gypi with --debug', async function (t) { - t.plan(1) - - const prog = gyp() - prog.parseArgv(['_', '_', '--debug']) - - const config = await getCurrentConfigGypi({ gyp: prog, vsInfo: {} }) - t.equal(config.target_defaults.default_configuration, 'Debug') -}) - -test('config.gypi with custom options', async function (t) { - t.plan(1) - - const prog = gyp() - prog.parseArgv(['_', '_', '--shared-libxml2']) - - const config = await getCurrentConfigGypi({ gyp: prog, vsInfo: {} }) - t.equal(config.variables.shared_libxml2, true) -}) - -test('config.gypi with nodedir', async function (t) { - t.plan(1) - - const nodeDir = path.join(__dirname, 'fixtures', 'nodedir') - - const prog = gyp() - prog.parseArgv(['_', '_', `--nodedir=${nodeDir}`]) - - const config = await getCurrentConfigGypi({ gyp: prog, nodeDir, vsInfo: {} }) - t.equal(config.variables.build_with_electron, true) -}) - -test('config.gypi with --force-process-config', async function (t) { - t.plan(1) - - const nodeDir = path.join(__dirname, 'fixtures', 'nodedir') - - const prog = gyp() - prog.parseArgv(['_', '_', '--force-process-config', `--nodedir=${nodeDir}`]) - - const config = await getCurrentConfigGypi({ gyp: prog, nodeDir, vsInfo: {} }) - t.equal(config.variables.build_with_electron, undefined) -}) - -test('config.gypi parsing', function (t) { - t.plan(1) - - const str = "# Some comments\n{'variables': {'multiline': 'A'\n'B'}}" - const config = parseConfigGypi(str) - t.deepEqual(config, { variables: { multiline: 'AB' } }) -}) diff --git a/node_modules/node-gyp/test/test-download.js b/node_modules/node-gyp/test/test-download.js deleted file mode 100644 index 71a3c0d092dfe..0000000000000 --- a/node_modules/node-gyp/test/test-download.js +++ /dev/null @@ -1,207 +0,0 @@ -'use strict' - -const { test } = require('tap') -const fs = require('fs') -const path = require('path') -const util = require('util') -const http = require('http') -const https = require('https') -const install = require('../lib/install') -const semver = require('semver') -const devDir = require('./common').devDir() -const rimraf = require('rimraf') -const gyp = require('../lib/node-gyp') -const log = require('npmlog') - -log.level = 'warn' - -test('download over http', async (t) => { - t.plan(2) - - const server = http.createServer((req, res) => { - t.strictEqual(req.headers['user-agent'], `node-gyp v42 (node ${process.version})`) - res.end('ok') - }) - - t.tearDown(() => new Promise((resolve) => server.close(resolve))) - - const host = 'localhost' - await new Promise((resolve) => server.listen(0, host, resolve)) - const { port } = server.address() - const gyp = { - opts: {}, - version: '42' - } - const url = `http://${host}:${port}` - const res = await install.test.download(gyp, url) - t.strictEqual(await res.text(), 'ok') -}) - -test('download over https with custom ca', async (t) => { - t.plan(3) - - const cafile = path.join(__dirname, '/fixtures/ca.crt') - const [cert, key, ca] = await Promise.all([ - fs.promises.readFile(path.join(__dirname, 'fixtures/server.crt'), 'utf8'), - fs.promises.readFile(path.join(__dirname, 'fixtures/server.key'), 'utf8'), - install.test.readCAFile(cafile) - ]) - - t.strictEqual(ca.length, 1) - - const options = { ca: ca, cert: cert, key: key } - const server = https.createServer(options, (req, res) => { - t.strictEqual(req.headers['user-agent'], `node-gyp v42 (node ${process.version})`) - res.end('ok') - }) - - t.tearDown(() => new Promise((resolve) => server.close(resolve))) - - server.on('clientError', (err) => { throw err }) - - const host = 'localhost' - await new Promise((resolve) => server.listen(0, host, resolve)) - const { port } = server.address() - const gyp = { - opts: { cafile }, - version: '42' - } - const url = `https://${host}:${port}` - const res = await install.test.download(gyp, url) - t.strictEqual(await res.text(), 'ok') -}) - -test('download over http with proxy', async (t) => { - t.plan(2) - - const server = http.createServer((_, res) => { - res.end('ok') - }) - - const pserver = http.createServer((req, res) => { - t.strictEqual(req.headers['user-agent'], `node-gyp v42 (node ${process.version})`) - res.end('proxy ok') - }) - - t.tearDown(() => Promise.all([ - new Promise((resolve) => server.close(resolve)), - new Promise((resolve) => pserver.close(resolve)) - ])) - - const host = 'localhost' - await new Promise((resolve) => server.listen(0, host, resolve)) - const { port } = server.address() - await new Promise((resolve) => pserver.listen(port + 1, host, resolve)) - const gyp = { - opts: { - proxy: `http://${host}:${port + 1}`, - noproxy: 'bad' - }, - version: '42' - } - const url = `http://${host}:${port}` - const res = await install.test.download(gyp, url) - t.strictEqual(await res.text(), 'proxy ok') -}) - -test('download over http with noproxy', async (t) => { - t.plan(2) - - const server = http.createServer((req, res) => { - t.strictEqual(req.headers['user-agent'], `node-gyp v42 (node ${process.version})`) - res.end('ok') - }) - - const pserver = http.createServer((_, res) => { - res.end('proxy ok') - }) - - t.tearDown(() => Promise.all([ - new Promise((resolve) => server.close(resolve)), - new Promise((resolve) => pserver.close(resolve)) - ])) - - const host = 'localhost' - await new Promise((resolve) => server.listen(0, host, resolve)) - const { port } = server.address() - await new Promise((resolve) => pserver.listen(port + 1, host, resolve)) - const gyp = { - opts: { - proxy: `http://${host}:${port + 1}`, - noproxy: host - }, - version: '42' - } - const url = `http://${host}:${port}` - const res = await install.test.download(gyp, url) - t.strictEqual(await res.text(), 'ok') -}) - -test('download with missing cafile', async (t) => { - t.plan(1) - const gyp = { - opts: { cafile: 'no.such.file' } - } - try { - await install.test.download(gyp, {}, 'http://bad/') - } catch (e) { - t.ok(/no.such.file/.test(e.message)) - } -}) - -test('check certificate splitting', async (t) => { - const cas = await install.test.readCAFile(path.join(__dirname, 'fixtures/ca-bundle.crt')) - t.plan(2) - t.strictEqual(cas.length, 2) - t.notStrictEqual(cas[0], cas[1]) -}) - -// only run this test if we are running a version of Node with predictable version path behavior - -test('download headers (actual)', async (t) => { - if (process.env.FAST_TEST || - process.release.name !== 'node' || - semver.prerelease(process.version) !== null || - semver.satisfies(process.version, '<10')) { - return t.skip('Skipping actual download of headers due to test environment configuration') - } - - t.plan(12) - - const expectedDir = path.join(devDir, process.version.replace(/^v/, '')) - await util.promisify(rimraf)(expectedDir) - - const prog = gyp() - prog.parseArgv([]) - prog.devDir = devDir - log.level = 'warn' - await util.promisify(install)(prog, []) - - const data = await fs.promises.readFile(path.join(expectedDir, 'installVersion'), 'utf8') - t.strictEqual(data, '9\n', 'correct installVersion') - - const list = await fs.promises.readdir(path.join(expectedDir, 'include/node')) - t.ok(list.includes('common.gypi')) - t.ok(list.includes('config.gypi')) - t.ok(list.includes('node.h')) - t.ok(list.includes('node_version.h')) - t.ok(list.includes('openssl')) - t.ok(list.includes('uv')) - t.ok(list.includes('uv.h')) - t.ok(list.includes('v8-platform.h')) - t.ok(list.includes('v8.h')) - t.ok(list.includes('zlib.h')) - - const lines = (await fs.promises.readFile(path.join(expectedDir, 'include/node/node_version.h'), 'utf8')).split('\n') - - // extract the 3 version parts from the defines to build a valid version string and - // and check them against our current env version - const version = ['major', 'minor', 'patch'].reduce((version, type) => { - const re = new RegExp(`^#define\\sNODE_${type.toUpperCase()}_VERSION`) - const line = lines.find((l) => re.test(l)) - const i = line ? parseInt(line.replace(/^[^0-9]+([0-9]+).*$/, '$1'), 10) : 'ERROR' - return `${version}${type !== 'major' ? '.' : 'v'}${i}` - }, '') - - t.strictEqual(version, process.version) -}) diff --git a/node_modules/node-gyp/test/test-find-accessible-sync.js b/node_modules/node-gyp/test/test-find-accessible-sync.js deleted file mode 100644 index 0a2e584c4fb33..0000000000000 --- a/node_modules/node-gyp/test/test-find-accessible-sync.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict' - -const test = require('tap').test -const path = require('path') -const requireInject = require('require-inject') -const configure = requireInject('../lib/configure', { - 'graceful-fs': { - closeSync: function () { return undefined }, - openSync: function (path) { - if (readableFiles.some(function (f) { return f === path })) { - return 0 - } else { - var error = new Error('ENOENT - not found') - throw error - } - } - } -}) - -const dir = path.sep + 'testdir' -const readableFile = 'readable_file' -const anotherReadableFile = 'another_readable_file' -const readableFileInDir = 'somedir' + path.sep + readableFile -const readableFiles = [ - path.resolve(dir, readableFile), - path.resolve(dir, anotherReadableFile), - path.resolve(dir, readableFileInDir) -] - -test('find accessible - empty array', function (t) { - t.plan(1) - - var candidates = [] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, undefined) -}) - -test('find accessible - single item array, readable', function (t) { - t.plan(1) - - var candidates = [readableFile] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, path.resolve(dir, readableFile)) -}) - -test('find accessible - single item array, readable in subdir', function (t) { - t.plan(1) - - var candidates = [readableFileInDir] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, path.resolve(dir, readableFileInDir)) -}) - -test('find accessible - single item array, unreadable', function (t) { - t.plan(1) - - var candidates = ['unreadable_file'] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, undefined) -}) - -test('find accessible - multi item array, no matches', function (t) { - t.plan(1) - - var candidates = ['non_existent_file', 'unreadable_file'] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, undefined) -}) - -test('find accessible - multi item array, single match', function (t) { - t.plan(1) - - var candidates = ['non_existent_file', readableFile] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, path.resolve(dir, readableFile)) -}) - -test('find accessible - multi item array, return first match', function (t) { - t.plan(1) - - var candidates = ['non_existent_file', anotherReadableFile, readableFile] - var found = configure.test.findAccessibleSync('test', dir, candidates) - t.strictEqual(found, path.resolve(dir, anotherReadableFile)) -}) diff --git a/node_modules/node-gyp/test/test-find-node-directory.js b/node_modules/node-gyp/test/test-find-node-directory.js deleted file mode 100644 index f1380d162ae7c..0000000000000 --- a/node_modules/node-gyp/test/test-find-node-directory.js +++ /dev/null @@ -1,119 +0,0 @@ -'use strict' - -const test = require('tap').test -const path = require('path') -const findNodeDirectory = require('../lib/find-node-directory') - -const platforms = ['darwin', 'freebsd', 'linux', 'sunos', 'win32', 'aix'] - -// we should find the directory based on the directory -// the script is running in and it should match the layout -// in a build tree where npm is installed in -// .... /deps/npm -test('test find-node-directory - node install', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] } - t.equal( - findNodeDirectory('/x/deps/npm/node_modules/node-gyp/lib', processObj), - path.join('/x')) - } -}) - -// we should find the directory based on the directory -// the script is running in and it should match the layout -// in an installed tree where npm is installed in -// .... /lib/node_modules/npm or .../node_modules/npm -// depending on the patform -test('test find-node-directory - node build', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] } - if (platforms[next] === 'win32') { - t.equal( - findNodeDirectory('/y/node_modules/npm/node_modules/node-gyp/lib', - processObj), path.join('/y')) - } else { - t.equal( - findNodeDirectory('/y/lib/node_modules/npm/node_modules/node-gyp/lib', - processObj), path.join('/y')) - } - } -}) - -// we should find the directory based on the execPath -// for node and match because it was in the bin directory -test('test find-node-directory - node in bin directory', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] } - t.equal( - findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj), - path.join('/x/y')) - } -}) - -// we should find the directory based on the execPath -// for node and match because it was in the Release directory -test('test find-node-directory - node in build release dir', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj - if (platforms[next] === 'win32') { - processObj = { execPath: '/x/y/Release/node', platform: platforms[next] } - } else { - processObj = { - execPath: '/x/y/out/Release/node', - platform: platforms[next] - } - } - - t.equal( - findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj), - path.join('/x/y')) - } -}) - -// we should find the directory based on the execPath -// for node and match because it was in the Debug directory -test('test find-node-directory - node in Debug release dir', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj - if (platforms[next] === 'win32') { - processObj = { execPath: '/a/b/Debug/node', platform: platforms[next] } - } else { - processObj = { execPath: '/a/b/out/Debug/node', platform: platforms[next] } - } - - t.equal( - findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj), - path.join('/a/b')) - } -}) - -// we should not find it as it will not match based on the execPath nor -// the directory from which the script is running -test('test find-node-directory - not found', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj = { execPath: '/x/y/z/y', platform: next } - t.equal(findNodeDirectory('/a/b/c/d', processObj), '') - } -}) - -// we should find the directory based on the directory -// the script is running in and it should match the layout -// in a build tree where npm is installed in -// .... /deps/npm -// same test as above but make sure additional directory entries -// don't cause an issue -test('test find-node-directory - node install', function (t) { - t.plan(platforms.length) - for (var next = 0; next < platforms.length; next++) { - var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] } - t.equal( - findNodeDirectory('/x/y/z/a/b/c/deps/npm/node_modules/node-gyp/lib', - processObj), path.join('/x/y/z/a/b/c')) - } -}) diff --git a/node_modules/node-gyp/test/test-find-python.js b/node_modules/node-gyp/test/test-find-python.js deleted file mode 100644 index 67d0b2664f0b1..0000000000000 --- a/node_modules/node-gyp/test/test-find-python.js +++ /dev/null @@ -1,226 +0,0 @@ -'use strict' - -delete process.env.PYTHON - -const test = require('tap').test -const findPython = require('../lib/find-python') -const execFile = require('child_process').execFile -const PythonFinder = findPython.test.PythonFinder - -require('npmlog').level = 'warn' - -test('find python', function (t) { - t.plan(4) - - findPython.test.findPython(null, function (err, found) { - t.strictEqual(err, null) - var proc = execFile(found, ['-V'], function (err, stdout, stderr) { - t.strictEqual(err, null) - t.ok(/Python 3/.test(stdout)) - t.strictEqual(stderr, '') - }) - proc.stdout.setEncoding('utf-8') - proc.stderr.setEncoding('utf-8') - }) -}) - -function poison (object, property) { - function fail () { - console.error(Error(`Property ${property} should not have been accessed.`)) - process.abort() - } - var descriptor = { - configurable: false, - enumerable: false, - get: fail, - set: fail - } - Object.defineProperty(object, property, descriptor) -} - -function TestPythonFinder () { - PythonFinder.apply(this, arguments) -} -TestPythonFinder.prototype = Object.create(PythonFinder.prototype) -// Silence npmlog - remove for debugging -TestPythonFinder.prototype.log = { - silly: () => {}, - verbose: () => {}, - info: () => {}, - warn: () => {}, - error: () => {} -} -delete TestPythonFinder.prototype.env.NODE_GYP_FORCE_PYTHON - -test('find python - python', function (t) { - t.plan(6) - - var f = new TestPythonFinder('python', done) - f.execFile = function (program, args, opts, cb) { - f.execFile = function (program, args, opts, cb) { - poison(f, 'execFile') - t.strictEqual(program, '/path/python') - t.ok(/sys\.version_info/.test(args[1])) - cb(null, '3.9.1') - } - t.strictEqual(program, - process.platform === 'win32' ? '"python"' : 'python') - t.ok(/sys\.executable/.test(args[1])) - cb(null, '/path/python') - } - f.findPython() - - function done (err, python) { - t.strictEqual(err, null) - t.strictEqual(python, '/path/python') - } -}) - -test('find python - python too old', function (t) { - t.plan(2) - - var f = new TestPythonFinder(null, done) - f.execFile = function (program, args, opts, cb) { - if (/sys\.executable/.test(args[args.length - 1])) { - cb(null, '/path/python') - } else if (/sys\.version_info/.test(args[args.length - 1])) { - cb(null, '2.3.4') - } else { - t.fail() - } - } - f.findPython() - - function done (err) { - t.ok(/Could not find any Python/.test(err)) - t.ok(/not supported/i.test(f.errorLog)) - } -}) - -test('find python - no python', function (t) { - t.plan(2) - - var f = new TestPythonFinder(null, done) - f.execFile = function (program, args, opts, cb) { - if (/sys\.executable/.test(args[args.length - 1])) { - cb(new Error('not found')) - } else if (/sys\.version_info/.test(args[args.length - 1])) { - cb(new Error('not a Python executable')) - } else { - t.fail() - } - } - f.findPython() - - function done (err) { - t.ok(/Could not find any Python/.test(err)) - t.ok(/not in PATH/.test(f.errorLog)) - } -}) - -test('find python - no python2, no python, unix', function (t) { - t.plan(2) - - var f = new TestPythonFinder(null, done) - f.checkPyLauncher = t.fail - f.win = false - - f.execFile = function (program, args, opts, cb) { - if (/sys\.executable/.test(args[args.length - 1])) { - cb(new Error('not found')) - } else { - t.fail() - } - } - f.findPython() - - function done (err) { - t.ok(/Could not find any Python/.test(err)) - t.ok(/not in PATH/.test(f.errorLog)) - } -}) - -test('find python - no python, use python launcher', function (t) { - t.plan(4) - - var f = new TestPythonFinder(null, done) - f.win = true - - f.execFile = function (program, args, opts, cb) { - if (program === 'py.exe') { - t.notEqual(args.indexOf('-3'), -1) - t.notEqual(args.indexOf('-c'), -1) - return cb(null, 'Z:\\snake.exe') - } - if (/sys\.executable/.test(args[args.length - 1])) { - cb(new Error('not found')) - } else if (f.winDefaultLocations.includes(program)) { - cb(new Error('not found')) - } else if (/sys\.version_info/.test(args[args.length - 1])) { - if (program === 'Z:\\snake.exe') { - cb(null, '3.9.0') - } else { - t.fail() - } - } else { - t.fail() - } - } - f.findPython() - - function done (err, python) { - t.strictEqual(err, null) - t.strictEqual(python, 'Z:\\snake.exe') - } -}) - -test('find python - no python, no python launcher, good guess', function (t) { - t.plan(2) - - var f = new TestPythonFinder(null, done) - f.win = true - const expectedProgram = f.winDefaultLocations[0] - - f.execFile = function (program, args, opts, cb) { - if (program === 'py.exe') { - return cb(new Error('not found')) - } - if (/sys\.executable/.test(args[args.length - 1])) { - cb(new Error('not found')) - } else if (program === expectedProgram && - /sys\.version_info/.test(args[args.length - 1])) { - cb(null, '3.7.3') - } else { - t.fail() - } - } - f.findPython() - - function done (err, python) { - t.strictEqual(err, null) - t.ok(python === expectedProgram) - } -}) - -test('find python - no python, no python launcher, bad guess', function (t) { - t.plan(2) - - var f = new TestPythonFinder(null, done) - f.win = true - - f.execFile = function (program, args, opts, cb) { - if (/sys\.executable/.test(args[args.length - 1])) { - cb(new Error('not found')) - } else if (/sys\.version_info/.test(args[args.length - 1])) { - cb(new Error('not a Python executable')) - } else { - t.fail() - } - } - f.findPython() - - function done (err) { - t.ok(/Could not find any Python/.test(err)) - t.ok(/not in PATH/.test(f.errorLog)) - } -}) diff --git a/node_modules/node-gyp/test/test-find-visualstudio.js b/node_modules/node-gyp/test/test-find-visualstudio.js deleted file mode 100644 index 1327cf8841111..0000000000000 --- a/node_modules/node-gyp/test/test-find-visualstudio.js +++ /dev/null @@ -1,676 +0,0 @@ -'use strict' - -const test = require('tap').test -const fs = require('fs') -const path = require('path') -const findVisualStudio = require('../lib/find-visualstudio') -const VisualStudioFinder = findVisualStudio.test.VisualStudioFinder - -const semverV1 = { major: 1, minor: 0, patch: 0 } - -delete process.env.VCINSTALLDIR - -function poison (object, property) { - function fail () { - console.error(Error(`Property ${property} should not have been accessed.`)) - process.abort() - } - var descriptor = { - configurable: false, - enumerable: false, - get: fail, - set: fail - } - Object.defineProperty(object, property, descriptor) -} - -function TestVisualStudioFinder () { VisualStudioFinder.apply(this, arguments) } -TestVisualStudioFinder.prototype = Object.create(VisualStudioFinder.prototype) -// Silence npmlog - remove for debugging -TestVisualStudioFinder.prototype.log = { - silly: () => {}, - verbose: () => {}, - info: () => {}, - warn: () => {}, - error: () => {} -} - -test('VS2013', function (t) { - t.plan(4) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\MSBuild12\\MSBuild.exe', - path: 'C:\\VS2013', - sdk: null, - toolset: 'v120', - version: '12.0', - versionMajor: 12, - versionMinor: 0, - versionYear: 2013 - }) - }) - - finder.findVisualStudio2017OrNewer = (cb) => { - finder.parseData(new Error(), '', '', cb) - } - finder.regSearchKeys = (keys, value, addOpts, cb) => { - for (var i = 0; i < keys.length; ++i) { - const fullName = `${keys[i]}\\${value}` - switch (fullName) { - case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - continue - case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0': - t.pass(`expected search for registry value ${fullName}`) - return cb(null, 'C:\\VS2013\\VC\\') - case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\12.0\\MSBuildToolsPath': - t.pass(`expected search for registry value ${fullName}`) - return cb(null, 'C:\\MSBuild12\\') - default: - t.fail(`unexpected search for registry value ${fullName}`) - } - } - return cb(new Error()) - } - finder.findVisualStudio() -}) - -test('VS2013 should not be found on new node versions', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder({ - major: 10, - minor: 0, - patch: 0 - }, null, (err, info) => { - t.ok(/find .* Visual Studio/i.test(err), 'expect error') - t.false(info, 'no data') - }) - - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.regSearchKeys = (keys, value, addOpts, cb) => { - for (var i = 0; i < keys.length; ++i) { - const fullName = `${keys[i]}\\${value}` - switch (fullName) { - case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - continue - default: - t.fail(`unexpected search for registry value ${fullName}`) - } - } - return cb(new Error()) - } - finder.findVisualStudio() -}) - -test('VS2015', function (t) { - t.plan(4) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\MSBuild14\\MSBuild.exe', - path: 'C:\\VS2015', - sdk: null, - toolset: 'v140', - version: '14.0', - versionMajor: 14, - versionMinor: 0, - versionYear: 2015 - }) - }) - - finder.findVisualStudio2017OrNewer = (cb) => { - finder.parseData(new Error(), '', '', cb) - } - finder.regSearchKeys = (keys, value, addOpts, cb) => { - for (var i = 0; i < keys.length; ++i) { - const fullName = `${keys[i]}\\${value}` - switch (fullName) { - case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - t.pass(`expected search for registry value ${fullName}`) - return cb(null, 'C:\\VS2015\\VC\\') - case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\14.0\\MSBuildToolsPath': - t.pass(`expected search for registry value ${fullName}`) - return cb(null, 'C:\\MSBuild14\\') - default: - t.fail(`unexpected search for registry value ${fullName}`) - } - } - return cb(new Error()) - } - finder.findVisualStudio() -}) - -test('error from PowerShell', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - finder.parseData(new Error(), '', '', (info) => { - t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('empty output from PowerShell', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - finder.parseData(null, '', '', (info) => { - t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('output from PowerShell not JSON', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - finder.parseData(null, 'AAAABBBB', '', (info) => { - t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('wrong JSON from PowerShell', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - finder.parseData(null, '{}', '', (info) => { - t.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('empty JSON from PowerShell', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - finder.parseData(null, '[]', '', (info) => { - t.ok(/find .* Visual Studio/i.test(finder.errorLog[0]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('future version', function (t) { - t.plan(3) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - finder.parseData(null, JSON.stringify([{ - packages: [ - 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64', - 'Microsoft.VisualStudio.Component.Windows10SDK.17763', - 'Microsoft.VisualStudio.VC.MSBuild.Base' - ], - path: 'C:\\VS', - version: '9999.9999.9999.9999' - }]), '', (info) => { - t.ok(/unknown version/i.test(finder.errorLog[0]), 'expect error') - t.ok(/find .* Visual Studio/i.test(finder.errorLog[1]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('single unusable VS2017', function (t) { - t.plan(3) - - const finder = new TestVisualStudioFinder(semverV1, null, null) - - const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', (info) => { - t.ok(/checking/i.test(finder.errorLog[0]), 'expect error') - t.ok(/find .* Visual Studio/i.test(finder.errorLog[2]), 'expect error') - t.false(info, 'no data') - }) -}) - -test('minimal VS2017 Build Tools', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\' + - 'BuildTools\\MSBuild\\15.0\\Bin\\MSBuild.exe', - path: - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools', - sdk: '10.0.17134.0', - toolset: 'v141', - version: '15.9.28307.665', - versionMajor: 15, - versionMinor: 9, - versionYear: 2017 - }) - }) - - poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', - 'VS_2017_BuildTools_minimal.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.findVisualStudio() -}) - -test('VS2017 Community with C++ workload', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\' + - 'Community\\MSBuild\\15.0\\Bin\\MSBuild.exe', - path: - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community', - sdk: '10.0.17763.0', - toolset: 'v141', - version: '15.9.28307.665', - versionMajor: 15, - versionMinor: 9, - versionYear: 2017 - }) - }) - - poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', - 'VS_2017_Community_workload.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.findVisualStudio() -}) - -test('VS2017 Express', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\' + - 'WDExpress\\MSBuild\\15.0\\Bin\\MSBuild.exe', - path: - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\WDExpress', - sdk: '10.0.17763.0', - toolset: 'v141', - version: '15.9.28307.858', - versionMajor: 15, - versionMinor: 9, - versionYear: 2017 - }) - }) - - poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', 'VS_2017_Express.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.findVisualStudio() -}) - -test('VS2019 Preview with C++ workload', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\' + - 'Preview\\MSBuild\\Current\\Bin\\MSBuild.exe', - path: - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Preview', - sdk: '10.0.17763.0', - toolset: 'v142', - version: '16.0.28608.199', - versionMajor: 16, - versionMinor: 0, - versionYear: 2019 - }) - }) - - poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', - 'VS_2019_Preview.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.findVisualStudio() -}) - -test('minimal VS2019 Build Tools', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\' + - 'BuildTools\\MSBuild\\Current\\Bin\\MSBuild.exe', - path: - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools', - sdk: '10.0.17134.0', - toolset: 'v142', - version: '16.1.28922.388', - versionMajor: 16, - versionMinor: 1, - versionYear: 2019 - }) - }) - - poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', - 'VS_2019_BuildTools_minimal.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.findVisualStudio() -}) - -test('VS2019 Community with C++ workload', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info, { - msBuild: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\' + - 'Community\\MSBuild\\Current\\Bin\\MSBuild.exe', - path: - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community', - sdk: '10.0.17763.0', - toolset: 'v142', - version: '16.1.28922.388', - versionMajor: 16, - versionMinor: 1, - versionYear: 2019 - }) - }) - - poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = (cb) => { - const file = path.join(__dirname, 'fixtures', - 'VS_2019_Community_workload.txt') - const data = fs.readFileSync(file) - finder.parseData(null, data, '', cb) - } - finder.findVisualStudio() -}) - -function allVsVersions (t, finder) { - finder.findVisualStudio2017OrNewer = (cb) => { - const data0 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2017_Unusable.txt'))) - const data1 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2017_BuildTools_minimal.txt'))) - const data2 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2017_Community_workload.txt'))) - const data3 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2017_Express.txt'))) - const data4 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2019_Preview.txt'))) - const data5 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2019_BuildTools_minimal.txt'))) - const data6 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', - 'VS_2019_Community_workload.txt'))) - const data = JSON.stringify(data0.concat(data1, data2, data3, data4, - data5, data6)) - finder.parseData(null, data, '', cb) - } - finder.regSearchKeys = (keys, value, addOpts, cb) => { - for (var i = 0; i < keys.length; ++i) { - const fullName = `${keys[i]}\\${value}` - switch (fullName) { - case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0': - continue - case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\12.0': - return cb(null, 'C:\\VS2013\\VC\\') - case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\12.0\\MSBuildToolsPath': - return cb(null, 'C:\\MSBuild12\\') - case 'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0': - return cb(null, 'C:\\VS2015\\VC\\') - case 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions\\14.0\\MSBuildToolsPath': - return cb(null, 'C:\\MSBuild14\\') - default: - t.fail(`unexpected search for registry value ${fullName}`) - } - } - return cb(new Error()) - } -} - -test('fail when looking for invalid path', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, 'AABB', (err, info) => { - t.ok(/find .* Visual Studio/i.test(err), 'expect error') - t.false(info, 'no data') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2013 by version number', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, '2013', (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.versionYear, 2013) - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2013 by installation path', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2013', - (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, 'C:\\VS2013') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2015 by version number', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, '2015', (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.versionYear, 2015) - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2015 by installation path', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2015', - (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, 'C:\\VS2015') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2017 by version number', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, '2017', (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.versionYear, 2017) - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2017 by installation path', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community', - (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2019 by version number', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, '2019', (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.versionYear, 2019) - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('look for VS2019 by installation path', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools', - (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('msvs_version match should be case insensitive', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, - 'c:\\program files (x86)\\microsoft visual studio\\2019\\BUILDTOOLS', - (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('latest version should be found by default', function (t) { - t.plan(2) - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.versionYear, 2019) - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('run on a usable VS Command Prompt', function (t) { - t.plan(2) - - process.env.VCINSTALLDIR = 'C:\\VS2015\\VC' - // VSINSTALLDIR is not defined on Visual C++ Build Tools 2015 - delete process.env.VSINSTALLDIR - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, 'C:\\VS2015') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('VCINSTALLDIR match should be case insensitive', function (t) { - t.plan(2) - - process.env.VCINSTALLDIR = - 'c:\\program files (x86)\\microsoft visual studio\\2019\\BUILDTOOLS\\VC' - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('run on a unusable VS Command Prompt', function (t) { - t.plan(2) - - process.env.VCINSTALLDIR = - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildToolsUnusable\\VC' - - const finder = new TestVisualStudioFinder(semverV1, null, (err, info) => { - t.ok(/find .* Visual Studio/i.test(err), 'expect error') - t.false(info, 'no data') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('run on a VS Command Prompt with matching msvs_version', function (t) { - t.plan(2) - - process.env.VCINSTALLDIR = 'C:\\VS2015\\VC' - - const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2015', - (err, info) => { - t.strictEqual(err, null) - t.deepEqual(info.path, 'C:\\VS2015') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) - -test('run on a VS Command Prompt with mismatched msvs_version', function (t) { - t.plan(2) - - process.env.VCINSTALLDIR = - 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC' - - const finder = new TestVisualStudioFinder(semverV1, 'C:\\VS2015', - (err, info) => { - t.ok(/find .* Visual Studio/i.test(err), 'expect error') - t.false(info, 'no data') - }) - - allVsVersions(t, finder) - finder.findVisualStudio() -}) diff --git a/node_modules/node-gyp/test/test-install.js b/node_modules/node-gyp/test/test-install.js deleted file mode 100644 index 5039dc992eb47..0000000000000 --- a/node_modules/node-gyp/test/test-install.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' - -const { test } = require('tap') -const { test: { install } } = require('../lib/install') -const log = require('npmlog') - -log.level = 'error' // we expect a warning - -test('EACCES retry once', async (t) => { - t.plan(3) - - const fs = { - promises: { - stat (_) { - const err = new Error() - err.code = 'EACCES' - t.ok(true) - throw err - } - } - } - - const Gyp = { - devDir: __dirname, - opts: { - ensure: true - }, - commands: { - install (argv, cb) { - install(fs, Gyp, argv).then(cb, cb) - }, - remove (_, cb) { - cb() - } - } - } - - try { - await install(fs, Gyp, []) - } catch (err) { - t.ok(true) - if (/"pre" versions of node cannot be installed/.test(err.message)) { - t.ok(true) - } - } -}) diff --git a/node_modules/node-gyp/test/test-options.js b/node_modules/node-gyp/test/test-options.js deleted file mode 100644 index 8a634f0e0955d..0000000000000 --- a/node_modules/node-gyp/test/test-options.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict' - -const test = require('tap').test -const gyp = require('../lib/node-gyp') - -test('options in environment', (t) => { - t.plan(1) - - // `npm test` dumps a ton of npm_config_* variables in the environment. - Object.keys(process.env) - .filter((key) => /^npm_config_/.test(key)) - .forEach((key) => { delete process.env[key] }) - - // in some platforms, certain keys are stubborn and cannot be removed - const keys = Object.keys(process.env) - .filter((key) => /^npm_config_/.test(key)) - .map((key) => key.substring('npm_config_'.length)) - .concat('argv', 'x') - - // Zero-length keys should get filtered out. - process.env.npm_config_ = '42' - // Other keys should get added. - process.env.npm_config_x = '42' - // Except loglevel. - process.env.npm_config_loglevel = 'debug' - - const g = gyp() - g.parseArgv(['rebuild']) // Also sets opts.argv. - - t.deepEqual(Object.keys(g.opts).sort(), keys.sort()) -}) - -test('options with spaces in environment', (t) => { - t.plan(1) - - process.env.npm_config_force_process_config = 'true' - - const g = gyp() - g.parseArgv(['rebuild']) // Also sets opts.argv. - - t.equal(g.opts['force-process-config'], 'true') -}) diff --git a/node_modules/node-gyp/test/test-process-release.js b/node_modules/node-gyp/test/test-process-release.js deleted file mode 100644 index c3ee0703c532f..0000000000000 --- a/node_modules/node-gyp/test/test-process-release.js +++ /dev/null @@ -1,434 +0,0 @@ -'use strict' - -const test = require('tap').test -const processRelease = require('../lib/process-release') - -test('test process release - process.version = 0.8.20', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v0.8.20', null) - - t.equal(release.semver.version, '0.8.20') - delete release.semver - - t.deepEqual(release, { - version: '0.8.20', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.8.20/', - tarballUrl: 'https://nodejs.org/dist/v0.8.20/node-v0.8.20.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.8.20/SHASUMS256.txt', - versionDir: '0.8.20', - ia32: { libUrl: 'https://nodejs.org/dist/v0.8.20/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.8.20/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.8.20/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -test('test process release - process.version = 0.10.21', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v0.10.21', null) - - t.equal(release.semver.version, '0.10.21') - delete release.semver - - t.deepEqual(release, { - version: '0.10.21', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.10.21/', - tarballUrl: 'https://nodejs.org/dist/v0.10.21/node-v0.10.21.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.10.21/SHASUMS256.txt', - versionDir: '0.10.21', - ia32: { libUrl: 'https://nodejs.org/dist/v0.10.21/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.10.21/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.10.21/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -// prior to -headers.tar.gz -test('test process release - process.version = 0.12.9', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v0.12.9', null) - - t.equal(release.semver.version, '0.12.9') - delete release.semver - - t.deepEqual(release, { - version: '0.12.9', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.12.9/', - tarballUrl: 'https://nodejs.org/dist/v0.12.9/node-v0.12.9.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.12.9/SHASUMS256.txt', - versionDir: '0.12.9', - ia32: { libUrl: 'https://nodejs.org/dist/v0.12.9/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.12.9/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.12.9/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -// prior to -headers.tar.gz -test('test process release - process.version = 0.10.41', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v0.10.41', null) - - t.equal(release.semver.version, '0.10.41') - delete release.semver - - t.deepEqual(release, { - version: '0.10.41', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.10.41/', - tarballUrl: 'https://nodejs.org/dist/v0.10.41/node-v0.10.41.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.10.41/SHASUMS256.txt', - versionDir: '0.10.41', - ia32: { libUrl: 'https://nodejs.org/dist/v0.10.41/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.10.41/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.10.41/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -// has -headers.tar.gz -test('test process release - process.release ~ node@0.10.42', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v0.10.42', null) - - t.equal(release.semver.version, '0.10.42') - delete release.semver - - t.deepEqual(release, { - version: '0.10.42', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.10.42/', - tarballUrl: 'https://nodejs.org/dist/v0.10.42/node-v0.10.42-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.10.42/SHASUMS256.txt', - versionDir: '0.10.42', - ia32: { libUrl: 'https://nodejs.org/dist/v0.10.42/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.10.42/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.10.42/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -// has -headers.tar.gz -test('test process release - process.release ~ node@0.12.10', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v0.12.10', null) - - t.equal(release.semver.version, '0.12.10') - delete release.semver - - t.deepEqual(release, { - version: '0.12.10', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.12.10/', - tarballUrl: 'https://nodejs.org/dist/v0.12.10/node-v0.12.10-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.12.10/SHASUMS256.txt', - versionDir: '0.12.10', - ia32: { libUrl: 'https://nodejs.org/dist/v0.12.10/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.12.10/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.12.10/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@4.1.23', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v4.1.23', { - name: 'node', - headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.1.23') - delete release.semver - - t.deepEqual(release, { - version: '4.1.23', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v4.1.23/', - tarballUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v4.1.23/SHASUMS256.txt', - versionDir: '4.1.23', - ia32: { libUrl: 'https://nodejs.org/dist/v4.1.23/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v4.1.23/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v4.1.23/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@4.1.23 / corp build', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v4.1.23', { - name: 'node', - headersUrl: 'https://some.custom.location/node-v4.1.23-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.1.23') - delete release.semver - - t.deepEqual(release, { - version: '4.1.23', - name: 'node', - baseUrl: 'https://some.custom.location/', - tarballUrl: 'https://some.custom.location/node-v4.1.23-headers.tar.gz', - shasumsUrl: 'https://some.custom.location/SHASUMS256.txt', - versionDir: '4.1.23', - ia32: { libUrl: 'https://some.custom.location/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://some.custom.location/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://some.custom.location/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@12.8.0 Windows', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v12.8.0', { - name: 'node', - sourceUrl: 'https://nodejs.org/download/release/v12.8.0/node-v12.8.0.tar.gz', - headersUrl: 'https://nodejs.org/download/release/v12.8.0/node-v12.8.0-headers.tar.gz', - libUrl: 'https://nodejs.org/download/release/v12.8.0/win-x64/node.lib' - }) - - t.equal(release.semver.version, '12.8.0') - delete release.semver - - t.deepEqual(release, { - version: '12.8.0', - name: 'node', - baseUrl: 'https://nodejs.org/download/release/v12.8.0/', - tarballUrl: 'https://nodejs.org/download/release/v12.8.0/node-v12.8.0-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/download/release/v12.8.0/SHASUMS256.txt', - versionDir: '12.8.0', - ia32: { libUrl: 'https://nodejs.org/download/release/v12.8.0/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://nodejs.org/download/release/v12.8.0/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/download/release/v12.8.0/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@12.8.0 Windows ARM64', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v12.8.0', { - name: 'node', - sourceUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/node-v12.8.0.tar.gz', - headersUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/node-v12.8.0-headers.tar.gz', - libUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/win-arm64/node.lib' - }) - - t.equal(release.semver.version, '12.8.0') - delete release.semver - - t.deepEqual(release, { - version: '12.8.0', - name: 'node', - baseUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/', - tarballUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/node-v12.8.0-headers.tar.gz', - shasumsUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/SHASUMS256.txt', - versionDir: '12.8.0', - ia32: { libUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@4.1.23 --target=0.10.40', function (t) { - t.plan(2) - - var release = processRelease([], { opts: { target: '0.10.40' } }, 'v4.1.23', { - name: 'node', - headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' - }) - - t.equal(release.semver.version, '0.10.40') - delete release.semver - - t.deepEqual(release, { - version: '0.10.40', - name: 'node', - baseUrl: 'https://nodejs.org/dist/v0.10.40/', - tarballUrl: 'https://nodejs.org/dist/v0.10.40/node-v0.10.40.tar.gz', - shasumsUrl: 'https://nodejs.org/dist/v0.10.40/SHASUMS256.txt', - versionDir: '0.10.40', - ia32: { libUrl: 'https://nodejs.org/dist/v0.10.40/node.lib', libPath: 'node.lib' }, - x64: { libUrl: 'https://nodejs.org/dist/v0.10.40/x64/node.lib', libPath: 'x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/dist/v0.10.40/arm64/node.lib', libPath: 'arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@4.1.23 --dist-url=https://foo.bar/baz', function (t) { - t.plan(2) - - var release = processRelease([], { opts: { 'dist-url': 'https://foo.bar/baz' } }, 'v4.1.23', { - name: 'node', - headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.1.23') - delete release.semver - - t.deepEqual(release, { - version: '4.1.23', - name: 'node', - baseUrl: 'https://foo.bar/baz/v4.1.23/', - tarballUrl: 'https://foo.bar/baz/v4.1.23/node-v4.1.23-headers.tar.gz', - shasumsUrl: 'https://foo.bar/baz/v4.1.23/SHASUMS256.txt', - versionDir: '4.1.23', - ia32: { libUrl: 'https://foo.bar/baz/v4.1.23/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://foo.bar/baz/v4.1.23/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://foo.bar/baz/v4.1.23/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ frankenstein@4.1.23', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v4.1.23', { - name: 'frankenstein', - headersUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.1.23') - delete release.semver - - t.deepEqual(release, { - version: '4.1.23', - name: 'frankenstein', - baseUrl: 'https://frankensteinjs.org/dist/v4.1.23/', - tarballUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23-headers.tar.gz', - shasumsUrl: 'https://frankensteinjs.org/dist/v4.1.23/SHASUMS256.txt', - versionDir: 'frankenstein-4.1.23', - ia32: { libUrl: 'https://frankensteinjs.org/dist/v4.1.23/win-x86/frankenstein.lib', libPath: 'win-x86/frankenstein.lib' }, - x64: { libUrl: 'https://frankensteinjs.org/dist/v4.1.23/win-x64/frankenstein.lib', libPath: 'win-x64/frankenstein.lib' }, - arm64: { libUrl: 'https://frankensteinjs.org/dist/v4.1.23/win-arm64/frankenstein.lib', libPath: 'win-arm64/frankenstein.lib' } - }) -}) - -test('test process release - process.release ~ frankenstein@4.1.23 --dist-url=http://foo.bar/baz/', function (t) { - t.plan(2) - - var release = processRelease([], { opts: { 'dist-url': 'http://foo.bar/baz/' } }, 'v4.1.23', { - name: 'frankenstein', - headersUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23.tar.gz' - }) - - t.equal(release.semver.version, '4.1.23') - delete release.semver - - t.deepEqual(release, { - version: '4.1.23', - name: 'frankenstein', - baseUrl: 'http://foo.bar/baz/v4.1.23/', - tarballUrl: 'http://foo.bar/baz/v4.1.23/frankenstein-v4.1.23-headers.tar.gz', - shasumsUrl: 'http://foo.bar/baz/v4.1.23/SHASUMS256.txt', - versionDir: 'frankenstein-4.1.23', - ia32: { libUrl: 'http://foo.bar/baz/v4.1.23/win-x86/frankenstein.lib', libPath: 'win-x86/frankenstein.lib' }, - x64: { libUrl: 'http://foo.bar/baz/v4.1.23/win-x64/frankenstein.lib', libPath: 'win-x64/frankenstein.lib' }, - arm64: { libUrl: 'http://foo.bar/baz/v4.1.23/win-arm64/frankenstein.lib', libPath: 'win-arm64/frankenstein.lib' } - }) -}) - -test('test process release - process.release ~ node@4.0.0-rc.4', function (t) { - t.plan(2) - - var release = processRelease([], { opts: {} }, 'v4.0.0-rc.4', { - name: 'node', - headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.0.0-rc.4') - delete release.semver - - t.deepEqual(release, { - version: '4.0.0-rc.4', - name: 'node', - baseUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/', - tarballUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/SHASUMS256.txt', - versionDir: '4.0.0-rc.4', - ia32: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@4.0.0-rc.4 passed as argv[0]', function (t) { - t.plan(2) - - // note the missing 'v' on the arg, it should normalise when checking - // whether we're on the default or not - var release = processRelease(['4.0.0-rc.4'], { opts: {} }, 'v4.0.0-rc.4', { - name: 'node', - headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.0.0-rc.4') - delete release.semver - - t.deepEqual(release, { - version: '4.0.0-rc.4', - name: 'node', - baseUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/', - tarballUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/SHASUMS256.txt', - versionDir: '4.0.0-rc.4', - ia32: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - process.release ~ node@4.0.0-rc.4 - bogus string passed as argv[0]', function (t) { - t.plan(2) - - // additional arguments can be passed in on the commandline that should be ignored if they - // are not specifying a valid version @ position 0 - var release = processRelease(['this is no version!'], { opts: {} }, 'v4.0.0-rc.4', { - name: 'node', - headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.0.0-rc.4') - delete release.semver - - t.deepEqual(release, { - version: '4.0.0-rc.4', - name: 'node', - baseUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/', - tarballUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz', - shasumsUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/SHASUMS256.txt', - versionDir: '4.0.0-rc.4', - ia32: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) -}) - -test('test process release - NODEJS_ORG_MIRROR', function (t) { - t.plan(2) - - process.env.NODEJS_ORG_MIRROR = 'http://foo.bar' - - var release = processRelease([], { opts: {} }, 'v4.1.23', { - name: 'node', - headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' - }) - - t.equal(release.semver.version, '4.1.23') - delete release.semver - - t.deepEqual(release, { - version: '4.1.23', - name: 'node', - baseUrl: 'http://foo.bar/v4.1.23/', - tarballUrl: 'http://foo.bar/v4.1.23/node-v4.1.23-headers.tar.gz', - shasumsUrl: 'http://foo.bar/v4.1.23/SHASUMS256.txt', - versionDir: '4.1.23', - ia32: { libUrl: 'http://foo.bar/v4.1.23/win-x86/node.lib', libPath: 'win-x86/node.lib' }, - x64: { libUrl: 'http://foo.bar/v4.1.23/win-x64/node.lib', libPath: 'win-x64/node.lib' }, - arm64: { libUrl: 'http://foo.bar/v4.1.23/win-arm64/node.lib', libPath: 'win-arm64/node.lib' } - }) - - delete process.env.NODEJS_ORG_MIRROR -}) diff --git a/node_modules/node-gyp/update-gyp.py b/node_modules/node-gyp/update-gyp.py deleted file mode 100755 index bb84f071a61d3..0000000000000 --- a/node_modules/node-gyp/update-gyp.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os -import shutil -import subprocess -import tarfile -import tempfile -import urllib.request - -BASE_URL = "https://github.com/nodejs/gyp-next/archive/" -CHECKOUT_PATH = os.path.dirname(os.path.realpath(__file__)) -CHECKOUT_GYP_PATH = os.path.join(CHECKOUT_PATH, "gyp") - -parser = argparse.ArgumentParser() -parser.add_argument("tag", help="gyp tag to update to") -args = parser.parse_args() - -tar_url = BASE_URL + args.tag + ".tar.gz" - -changed_files = subprocess.check_output(["git", "diff", "--name-only"]).strip() -if changed_files: - raise Exception("Can't update gyp while you have uncommitted changes in node-gyp") - -with tempfile.TemporaryDirectory() as tmp_dir: - tar_file = os.path.join(tmp_dir, "gyp.tar.gz") - unzip_target = os.path.join(tmp_dir, "gyp") - with open(tar_file, "wb") as f: - print("Downloading gyp-next@" + args.tag + " into temporary directory...") - print("From: " + tar_url) - with urllib.request.urlopen(tar_url) as in_file: - f.write(in_file.read()) - - print("Unzipping...") - with tarfile.open(tar_file, "r:gz") as tar_ref: - tar_ref.extractall(unzip_target) - - print("Moving to current checkout (" + CHECKOUT_PATH + ")...") - if os.path.exists(CHECKOUT_GYP_PATH): - shutil.rmtree(CHECKOUT_GYP_PATH) - shutil.move( - os.path.join(unzip_target, os.listdir(unzip_target)[0]), CHECKOUT_GYP_PATH - ) - -subprocess.check_output(["git", "add", "gyp"], cwd=CHECKOUT_PATH) -subprocess.check_output(["git", "commit", "-m", "feat(gyp): update gyp to " + args.tag]) diff --git a/node_modules/nopt/bin/nopt.js b/node_modules/nopt/bin/nopt.js index 3232d4c570fdc..6ed2082064b5e 100755 --- a/node_modules/nopt/bin/nopt.js +++ b/node_modules/nopt/bin/nopt.js @@ -1,54 +1,29 @@ #!/usr/bin/env node -var nopt = require("../lib/nopt") - , path = require("path") - , types = { num: Number - , bool: Boolean - , help: Boolean - , list: Array - , "num-list": [Number, Array] - , "str-list": [String, Array] - , "bool-list": [Boolean, Array] - , str: String - , clear: Boolean - , config: Boolean - , length: Number - , file: path - } - , shorthands = { s: [ "--str", "astring" ] - , b: [ "--bool" ] - , nb: [ "--no-bool" ] - , tft: [ "--bool-list", "--no-bool-list", "--bool-list", "true" ] - , "?": ["--help"] - , h: ["--help"] - , H: ["--help"] - , n: [ "--num", "125" ] - , c: ["--config"] - , l: ["--length"] - , f: ["--file"] - } - , parsed = nopt( types - , shorthands - , process.argv - , 2 ) - -console.log("parsed", parsed) - -if (parsed.help) { - console.log("") - console.log("nopt cli tester") - console.log("") - console.log("types") - console.log(Object.keys(types).map(function M (t) { - var type = types[t] - if (Array.isArray(type)) { - return [t, type.map(function (type) { return type.name })] - } - return [t, type && type.name] - }).reduce(function (s, i) { - s[i[0]] = i[1] - return s - }, {})) - console.log("") - console.log("shorthands") - console.log(shorthands) -} +const nopt = require('../lib/nopt') +const path = require('path') +console.log('parsed', nopt({ + num: Number, + bool: Boolean, + help: Boolean, + list: Array, + 'num-list': [Number, Array], + 'str-list': [String, Array], + 'bool-list': [Boolean, Array], + str: String, + clear: Boolean, + config: Boolean, + length: Number, + file: path, +}, { + s: ['--str', 'astring'], + b: ['--bool'], + nb: ['--no-bool'], + tft: ['--bool-list', '--no-bool-list', '--bool-list', 'true'], + '?': ['--help'], + h: ['--help'], + H: ['--help'], + n: ['--num', '125'], + c: ['--config'], + l: ['--length'], + f: ['--file'], +}, process.argv, 2)) diff --git a/node_modules/nopt/lib/debug.js b/node_modules/nopt/lib/debug.js new file mode 100644 index 0000000000000..544ab382ca85c --- /dev/null +++ b/node_modules/nopt/lib/debug.js @@ -0,0 +1,5 @@ +/* istanbul ignore next */ +module.exports = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG + // eslint-disable-next-line no-console + ? (...a) => console.error(...a) + : () => {} diff --git a/node_modules/nopt/lib/nopt-lib.js b/node_modules/nopt/lib/nopt-lib.js new file mode 100644 index 0000000000000..441c9cc30377a --- /dev/null +++ b/node_modules/nopt/lib/nopt-lib.js @@ -0,0 +1,514 @@ +const abbrev = require('abbrev') +const debug = require('./debug') +const defaultTypeDefs = require('./type-defs') + +const hasOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k) + +const getType = (k, { types, dynamicTypes }) => { + let hasType = hasOwn(types, k) + let type = types[k] + if (!hasType && typeof dynamicTypes === 'function') { + const matchedType = dynamicTypes(k) + if (matchedType !== undefined) { + type = matchedType + hasType = true + } + } + return [hasType, type] +} + +const isTypeDef = (type, def) => def && type === def +const hasTypeDef = (type, def) => def && type.indexOf(def) !== -1 +const doesNotHaveTypeDef = (type, def) => def && !hasTypeDef(type, def) + +function nopt (args, { + types, + shorthands, + typeDefs, + invalidHandler, // opt is configured but its value does not validate against given type + unknownHandler, // opt is not configured + abbrevHandler, // opt is being expanded via abbrev + typeDefault, + dynamicTypes, +} = {}) { + debug(types, shorthands, args, typeDefs) + + const data = {} + const argv = { + remain: [], + cooked: args, + original: args.slice(0), + } + + parse(args, data, argv.remain, { + typeDefs, types, dynamicTypes, shorthands, unknownHandler, abbrevHandler, + }) + + // now data is full + clean(data, { types, dynamicTypes, typeDefs, invalidHandler, typeDefault }) + data.argv = argv + + Object.defineProperty(data.argv, 'toString', { + value: function () { + return this.original.map(JSON.stringify).join(' ') + }, + enumerable: false, + }) + + return data +} + +function clean (data, { + types = {}, + typeDefs = {}, + dynamicTypes, + invalidHandler, + typeDefault, +} = {}) { + const StringType = typeDefs.String?.type + const NumberType = typeDefs.Number?.type + const ArrayType = typeDefs.Array?.type + const BooleanType = typeDefs.Boolean?.type + const DateType = typeDefs.Date?.type + + const hasTypeDefault = typeof typeDefault !== 'undefined' + if (!hasTypeDefault) { + typeDefault = [false, true, null] + if (StringType) { + typeDefault.push(StringType) + } + if (ArrayType) { + typeDefault.push(ArrayType) + } + } + + const remove = {} + + Object.keys(data).forEach((k) => { + if (k === 'argv') { + return + } + let val = data[k] + debug('val=%j', val) + const isArray = Array.isArray(val) + let [hasType, rawType] = getType(k, { types, dynamicTypes }) + let type = rawType + if (!isArray) { + val = [val] + } + if (!type) { + type = typeDefault + } + if (isTypeDef(type, ArrayType)) { + type = typeDefault.concat(ArrayType) + } + if (!Array.isArray(type)) { + type = [type] + } + + debug('val=%j', val) + debug('types=', type) + val = val.map((v) => { + // if it's an unknown value, then parse false/true/null/numbers/dates + if (typeof v === 'string') { + debug('string %j', v) + v = v.trim() + if ((v === 'null' && ~type.indexOf(null)) + || (v === 'true' && + (~type.indexOf(true) || hasTypeDef(type, BooleanType))) + || (v === 'false' && + (~type.indexOf(false) || hasTypeDef(type, BooleanType)))) { + v = JSON.parse(v) + debug('jsonable %j', v) + } else if (hasTypeDef(type, NumberType) && !isNaN(v)) { + debug('convert to number', v) + v = +v + } else if (hasTypeDef(type, DateType) && !isNaN(Date.parse(v))) { + debug('convert to date', v) + v = new Date(v) + } + } + + if (!hasType) { + if (!hasTypeDefault) { + return v + } + // if the default type has been passed in then we want to validate the + // unknown data key instead of bailing out earlier. we also set the raw + // type which is passed to the invalid handler so that it can be + // determined if during validation if it is unknown vs invalid + rawType = typeDefault + } + + // allow `--no-blah` to set 'blah' to null if null is allowed + if (v === false && ~type.indexOf(null) && + !(~type.indexOf(false) || hasTypeDef(type, BooleanType))) { + v = null + } + + const d = {} + d[k] = v + debug('prevalidated val', d, v, rawType) + if (!validate(d, k, v, rawType, { typeDefs })) { + if (invalidHandler) { + invalidHandler(k, v, rawType, data) + } else if (invalidHandler !== false) { + debug('invalid: ' + k + '=' + v, rawType) + } + return remove + } + debug('validated v', d, v, rawType) + return d[k] + }).filter((v) => v !== remove) + + // if we allow Array specifically, then an empty array is how we + // express 'no value here', not null. Allow it. + if (!val.length && doesNotHaveTypeDef(type, ArrayType)) { + debug('VAL HAS NO LENGTH, DELETE IT', val, k, type.indexOf(ArrayType)) + delete data[k] + } else if (isArray) { + debug(isArray, data[k], val) + data[k] = val + } else { + data[k] = val[0] + } + + debug('k=%s val=%j', k, val, data[k]) + }) +} + +function validate (data, k, val, type, { typeDefs } = {}) { + const ArrayType = typeDefs?.Array?.type + // arrays are lists of types. + if (Array.isArray(type)) { + for (let i = 0, l = type.length; i < l; i++) { + if (isTypeDef(type[i], ArrayType)) { + continue + } + if (validate(data, k, val, type[i], { typeDefs })) { + return true + } + } + delete data[k] + return false + } + + // an array of anything? + if (isTypeDef(type, ArrayType)) { + return true + } + + // Original comment: + // NaN is poisonous. Means that something is not allowed. + // New comment: Changing this to an isNaN check breaks a lot of tests. + // Something is being assumed here that is not actually what happens in + // practice. Fixing it is outside the scope of getting linting to pass in + // this repo. Leaving as-is for now. + /* eslint-disable-next-line no-self-compare */ + if (type !== type) { + debug('Poison NaN', k, val, type) + delete data[k] + return false + } + + // explicit list of values + if (val === type) { + debug('Explicitly allowed %j', val) + data[k] = val + return true + } + + // now go through the list of typeDefs, validate against each one. + let ok = false + const types = Object.keys(typeDefs) + for (let i = 0, l = types.length; i < l; i++) { + debug('test type %j %j %j', k, val, types[i]) + const t = typeDefs[types[i]] + if (t && ( + (type && type.name && t.type && t.type.name) ? + (type.name === t.type.name) : + (type === t.type) + )) { + const d = {} + ok = t.validate(d, k, val) !== false + val = d[k] + if (ok) { + data[k] = val + break + } + } + } + debug('OK? %j (%j %j %j)', ok, k, val, types[types.length - 1]) + + if (!ok) { + delete data[k] + } + return ok +} + +function parse (args, data, remain, { + types = {}, + typeDefs = {}, + shorthands = {}, + dynamicTypes, + unknownHandler, + abbrevHandler, +} = {}) { + const StringType = typeDefs.String?.type + const NumberType = typeDefs.Number?.type + const ArrayType = typeDefs.Array?.type + const BooleanType = typeDefs.Boolean?.type + + debug('parse', args, data, remain) + + const abbrevs = abbrev(Object.keys(types)) + debug('abbrevs=%j', abbrevs) + const shortAbbr = abbrev(Object.keys(shorthands)) + + for (let i = 0; i < args.length; i++) { + let arg = args[i] + debug('arg', arg) + + if (arg.match(/^-{2,}$/)) { + // done with keys. + // the rest are args. + remain.push.apply(remain, args.slice(i + 1)) + args[i] = '--' + break + } + let hadEq = false + if (arg.charAt(0) === '-' && arg.length > 1) { + const at = arg.indexOf('=') + if (at > -1) { + hadEq = true + const v = arg.slice(at + 1) + arg = arg.slice(0, at) + args.splice(i, 1, arg, v) + } + + // see if it's a shorthand + // if so, splice and back up to re-parse it. + const shRes = resolveShort(arg, shortAbbr, abbrevs, { shorthands, abbrevHandler }) + debug('arg=%j shRes=%j', arg, shRes) + if (shRes) { + args.splice.apply(args, [i, 1].concat(shRes)) + if (arg !== shRes[0]) { + i-- + continue + } + } + arg = arg.replace(/^-+/, '') + let no = null + while (arg.toLowerCase().indexOf('no-') === 0) { + no = !no + arg = arg.slice(3) + } + + // abbrev includes the original full string in its abbrev list + if (abbrevs[arg] && abbrevs[arg] !== arg) { + if (abbrevHandler) { + abbrevHandler(arg, abbrevs[arg]) + } else if (abbrevHandler !== false) { + debug(`abbrev: ${arg} -> ${abbrevs[arg]}`) + } + arg = abbrevs[arg] + } + + let [hasType, argType] = getType(arg, { types, dynamicTypes }) + let isTypeArray = Array.isArray(argType) + if (isTypeArray && argType.length === 1) { + isTypeArray = false + argType = argType[0] + } + + let isArray = isTypeDef(argType, ArrayType) || + isTypeArray && hasTypeDef(argType, ArrayType) + + // allow unknown things to be arrays if specified multiple times. + if (!hasType && hasOwn(data, arg)) { + if (!Array.isArray(data[arg])) { + data[arg] = [data[arg]] + } + isArray = true + } + + let val + let la = args[i + 1] + + const isBool = typeof no === 'boolean' || + isTypeDef(argType, BooleanType) || + isTypeArray && hasTypeDef(argType, BooleanType) || + (typeof argType === 'undefined' && !hadEq) || + (la === 'false' && + (argType === null || + isTypeArray && ~argType.indexOf(null))) + + if (typeof argType === 'undefined') { + // la is going to unexpectedly be parsed outside the context of this arg + const hangingLa = !hadEq && la && !la?.startsWith('-') && !['true', 'false'].includes(la) + if (unknownHandler) { + if (hangingLa) { + unknownHandler(arg, la) + } else { + unknownHandler(arg) + } + } else if (unknownHandler !== false) { + debug(`unknown: ${arg}`) + if (hangingLa) { + debug(`unknown: ${la} parsed as normal opt`) + } + } + } + + if (isBool) { + // just set and move along + val = !no + // however, also support --bool true or --bool false + if (la === 'true' || la === 'false') { + val = JSON.parse(la) + la = null + if (no) { + val = !val + } + i++ + } + + // also support "foo":[Boolean, "bar"] and "--foo bar" + if (isTypeArray && la) { + if (~argType.indexOf(la)) { + // an explicit type + val = la + i++ + } else if (la === 'null' && ~argType.indexOf(null)) { + // null allowed + val = null + i++ + } else if (!la.match(/^-{2,}[^-]/) && + !isNaN(la) && + hasTypeDef(argType, NumberType)) { + // number + val = +la + i++ + } else if (!la.match(/^-[^-]/) && hasTypeDef(argType, StringType)) { + // string + val = la + i++ + } + } + + if (isArray) { + (data[arg] = data[arg] || []).push(val) + } else { + data[arg] = val + } + + continue + } + + if (isTypeDef(argType, StringType)) { + if (la === undefined) { + la = '' + } else if (la.match(/^-{1,2}[^-]+/)) { + la = '' + i-- + } + } + + if (la && la.match(/^-{2,}$/)) { + la = undefined + i-- + } + + val = la === undefined ? true : la + if (isArray) { + (data[arg] = data[arg] || []).push(val) + } else { + data[arg] = val + } + + i++ + continue + } + remain.push(arg) + } +} + +const SINGLES = Symbol('singles') +const singleCharacters = (arg, shorthands) => { + let singles = shorthands[SINGLES] + if (!singles) { + singles = Object.keys(shorthands).filter((s) => s.length === 1).reduce((l, r) => { + l[r] = true + return l + }, {}) + shorthands[SINGLES] = singles + debug('shorthand singles', singles) + } + const chrs = arg.split('').filter((c) => singles[c]) + return chrs.join('') === arg ? chrs : null +} + +function resolveShort (arg, ...rest) { + const { abbrevHandler, types = {}, shorthands = {} } = rest.length ? rest.pop() : {} + const shortAbbr = rest[0] ?? abbrev(Object.keys(shorthands)) + const abbrevs = rest[1] ?? abbrev(Object.keys(types)) + + // handle single-char shorthands glommed together, like + // npm ls -glp, but only if there is one dash, and only if + // all of the chars are single-char shorthands, and it's + // not a match to some other abbrev. + arg = arg.replace(/^-+/, '') + + // if it's an exact known option, then don't go any further + if (abbrevs[arg] === arg) { + return null + } + + // if it's an exact known shortopt, same deal + if (shorthands[arg]) { + // make it an array, if it's a list of words + if (shorthands[arg] && !Array.isArray(shorthands[arg])) { + shorthands[arg] = shorthands[arg].split(/\s+/) + } + + return shorthands[arg] + } + + // first check to see if this arg is a set of single-char shorthands + const chrs = singleCharacters(arg, shorthands) + if (chrs) { + return chrs.map((c) => shorthands[c]).reduce((l, r) => l.concat(r), []) + } + + // if it's an arg abbrev, and not a literal shorthand, then prefer the arg + if (abbrevs[arg] && !shorthands[arg]) { + return null + } + + // if it's an abbr for a shorthand, then use that + // exact match has already happened so we don't need to account for that here + if (shortAbbr[arg]) { + if (abbrevHandler) { + abbrevHandler(arg, shortAbbr[arg]) + } else if (abbrevHandler !== false) { + debug(`abbrev: ${arg} -> ${shortAbbr[arg]}`) + } + arg = shortAbbr[arg] + } + + // make it an array, if it's a list of words + if (shorthands[arg] && !Array.isArray(shorthands[arg])) { + shorthands[arg] = shorthands[arg].split(/\s+/) + } + + return shorthands[arg] +} + +module.exports = { + nopt, + clean, + parse, + validate, + resolveShort, + typeDefs: defaultTypeDefs, +} diff --git a/node_modules/nopt/lib/nopt.js b/node_modules/nopt/lib/nopt.js index ecfa5da933683..9a24342b374aa 100644 --- a/node_modules/nopt/lib/nopt.js +++ b/node_modules/nopt/lib/nopt.js @@ -1,441 +1,34 @@ -// info about each config option. +const lib = require('./nopt-lib') +const defaultTypeDefs = require('./type-defs') -var debug = process.env.DEBUG_NOPT || process.env.NOPT_DEBUG - ? function () { console.error.apply(console, arguments) } - : function () {} - -var url = require("url") - , path = require("path") - , Stream = require("stream").Stream - , abbrev = require("abbrev") - , os = require("os") +// This is the version of nopt's API that requires setting typeDefs and invalidHandler +// on the required `nopt` object since it is a singleton. To not do a breaking change +// an API that requires all options be passed in is located in `nopt-lib.js` and +// exported here as lib. +// TODO(breaking): make API only work in non-singleton mode module.exports = exports = nopt exports.clean = clean - -exports.typeDefs = - { String : { type: String, validate: validateString } - , Boolean : { type: Boolean, validate: validateBoolean } - , url : { type: url, validate: validateUrl } - , Number : { type: Number, validate: validateNumber } - , path : { type: path, validate: validatePath } - , Stream : { type: Stream, validate: validateStream } - , Date : { type: Date, validate: validateDate } - } - -function nopt (types, shorthands, args, slice) { - args = args || process.argv - types = types || {} - shorthands = shorthands || {} - if (typeof slice !== "number") slice = 2 - - debug(types, shorthands, args, slice) - - args = args.slice(slice) - var data = {} - , key - , argv = { - remain: [], - cooked: args, - original: args.slice(0) - } - - parse(args, data, argv.remain, types, shorthands) - // now data is full - clean(data, types, exports.typeDefs) - data.argv = argv - Object.defineProperty(data.argv, 'toString', { value: function () { - return this.original.map(JSON.stringify).join(" ") - }, enumerable: false }) - return data -} - -function clean (data, types, typeDefs) { - typeDefs = typeDefs || exports.typeDefs - var remove = {} - , typeDefault = [false, true, null, String, Array] - - Object.keys(data).forEach(function (k) { - if (k === "argv") return - var val = data[k] - , isArray = Array.isArray(val) - , type = types[k] - if (!isArray) val = [val] - if (!type) type = typeDefault - if (type === Array) type = typeDefault.concat(Array) - if (!Array.isArray(type)) type = [type] - - debug("val=%j", val) - debug("types=", type) - val = val.map(function (val) { - // if it's an unknown value, then parse false/true/null/numbers/dates - if (typeof val === "string") { - debug("string %j", val) - val = val.trim() - if ((val === "null" && ~type.indexOf(null)) - || (val === "true" && - (~type.indexOf(true) || ~type.indexOf(Boolean))) - || (val === "false" && - (~type.indexOf(false) || ~type.indexOf(Boolean)))) { - val = JSON.parse(val) - debug("jsonable %j", val) - } else if (~type.indexOf(Number) && !isNaN(val)) { - debug("convert to number", val) - val = +val - } else if (~type.indexOf(Date) && !isNaN(Date.parse(val))) { - debug("convert to date", val) - val = new Date(val) - } - } - - if (!types.hasOwnProperty(k)) { - return val - } - - // allow `--no-blah` to set 'blah' to null if null is allowed - if (val === false && ~type.indexOf(null) && - !(~type.indexOf(false) || ~type.indexOf(Boolean))) { - val = null - } - - var d = {} - d[k] = val - debug("prevalidated val", d, val, types[k]) - if (!validate(d, k, val, types[k], typeDefs)) { - if (exports.invalidHandler) { - exports.invalidHandler(k, val, types[k], data) - } else if (exports.invalidHandler !== false) { - debug("invalid: "+k+"="+val, types[k]) - } - return remove - } - debug("validated val", d, val, types[k]) - return d[k] - }).filter(function (val) { return val !== remove }) - - // if we allow Array specifically, then an empty array is how we - // express 'no value here', not null. Allow it. - if (!val.length && type.indexOf(Array) === -1) { - debug('VAL HAS NO LENGTH, DELETE IT', val, k, type.indexOf(Array)) - delete data[k] - } - else if (isArray) { - debug(isArray, data[k], val) - data[k] = val - } else data[k] = val[0] - - debug("k=%s val=%j", k, val, data[k]) +exports.typeDefs = defaultTypeDefs +exports.lib = lib + +function nopt (types, shorthands, args = process.argv, slice = 2) { + return lib.nopt(args.slice(slice), { + types: types || {}, + shorthands: shorthands || {}, + typeDefs: exports.typeDefs, + invalidHandler: exports.invalidHandler, + unknownHandler: exports.unknownHandler, + abbrevHandler: exports.abbrevHandler, }) } -function validateString (data, k, val) { - data[k] = String(val) -} - -function validatePath (data, k, val) { - if (val === true) return false - if (val === null) return true - - val = String(val) - - var isWin = process.platform === 'win32' - , homePattern = isWin ? /^~(\/|\\)/ : /^~\// - , home = os.homedir() - - if (home && val.match(homePattern)) { - data[k] = path.resolve(home, val.substr(2)) - } else { - data[k] = path.resolve(val) - } - return true -} - -function validateNumber (data, k, val) { - debug("validate Number %j %j %j", k, val, isNaN(val)) - if (isNaN(val)) return false - data[k] = +val -} - -function validateDate (data, k, val) { - var s = Date.parse(val) - debug("validate Date %j %j %j", k, val, s) - if (isNaN(s)) return false - data[k] = new Date(val) -} - -function validateBoolean (data, k, val) { - if (val instanceof Boolean) val = val.valueOf() - else if (typeof val === "string") { - if (!isNaN(val)) val = !!(+val) - else if (val === "null" || val === "false") val = false - else val = true - } else val = !!val - data[k] = val -} - -function validateUrl (data, k, val) { - val = url.parse(String(val)) - if (!val.host) return false - data[k] = val.href -} - -function validateStream (data, k, val) { - if (!(val instanceof Stream)) return false - data[k] = val -} - -function validate (data, k, val, type, typeDefs) { - // arrays are lists of types. - if (Array.isArray(type)) { - for (var i = 0, l = type.length; i < l; i ++) { - if (type[i] === Array) continue - if (validate(data, k, val, type[i], typeDefs)) return true - } - delete data[k] - return false - } - - // an array of anything? - if (type === Array) return true - - // NaN is poisonous. Means that something is not allowed. - if (type !== type) { - debug("Poison NaN", k, val, type) - delete data[k] - return false - } - - // explicit list of values - if (val === type) { - debug("Explicitly allowed %j", val) - // if (isArray) (data[k] = data[k] || []).push(val) - // else data[k] = val - data[k] = val - return true - } - - // now go through the list of typeDefs, validate against each one. - var ok = false - , types = Object.keys(typeDefs) - for (var i = 0, l = types.length; i < l; i ++) { - debug("test type %j %j %j", k, val, types[i]) - var t = typeDefs[types[i]] - if (t && - ((type && type.name && t.type && t.type.name) ? (type.name === t.type.name) : (type === t.type))) { - var d = {} - ok = false !== t.validate(d, k, val) - val = d[k] - if (ok) { - // if (isArray) (data[k] = data[k] || []).push(val) - // else data[k] = val - data[k] = val - break - } - } - } - debug("OK? %j (%j %j %j)", ok, k, val, types[i]) - - if (!ok) delete data[k] - return ok -} - -function parse (args, data, remain, types, shorthands) { - debug("parse", args, data, remain) - - var key = null - , abbrevs = abbrev(Object.keys(types)) - , shortAbbr = abbrev(Object.keys(shorthands)) - - for (var i = 0; i < args.length; i ++) { - var arg = args[i] - debug("arg", arg) - - if (arg.match(/^-{2,}$/)) { - // done with keys. - // the rest are args. - remain.push.apply(remain, args.slice(i + 1)) - args[i] = "--" - break - } - var hadEq = false - if (arg.charAt(0) === "-" && arg.length > 1) { - var at = arg.indexOf('=') - if (at > -1) { - hadEq = true - var v = arg.substr(at + 1) - arg = arg.substr(0, at) - args.splice(i, 1, arg, v) - } - - // see if it's a shorthand - // if so, splice and back up to re-parse it. - var shRes = resolveShort(arg, shorthands, shortAbbr, abbrevs) - debug("arg=%j shRes=%j", arg, shRes) - if (shRes) { - debug(arg, shRes) - args.splice.apply(args, [i, 1].concat(shRes)) - if (arg !== shRes[0]) { - i -- - continue - } - } - arg = arg.replace(/^-+/, "") - var no = null - while (arg.toLowerCase().indexOf("no-") === 0) { - no = !no - arg = arg.substr(3) - } - - if (abbrevs[arg]) arg = abbrevs[arg] - - var argType = types[arg] - var isTypeArray = Array.isArray(argType) - if (isTypeArray && argType.length === 1) { - isTypeArray = false - argType = argType[0] - } - - var isArray = argType === Array || - isTypeArray && argType.indexOf(Array) !== -1 - - // allow unknown things to be arrays if specified multiple times. - if (!types.hasOwnProperty(arg) && data.hasOwnProperty(arg)) { - if (!Array.isArray(data[arg])) - data[arg] = [data[arg]] - isArray = true - } - - var val - , la = args[i + 1] - - var isBool = typeof no === 'boolean' || - argType === Boolean || - isTypeArray && argType.indexOf(Boolean) !== -1 || - (typeof argType === 'undefined' && !hadEq) || - (la === "false" && - (argType === null || - isTypeArray && ~argType.indexOf(null))) - - if (isBool) { - // just set and move along - val = !no - // however, also support --bool true or --bool false - if (la === "true" || la === "false") { - val = JSON.parse(la) - la = null - if (no) val = !val - i ++ - } - - // also support "foo":[Boolean, "bar"] and "--foo bar" - if (isTypeArray && la) { - if (~argType.indexOf(la)) { - // an explicit type - val = la - i ++ - } else if ( la === "null" && ~argType.indexOf(null) ) { - // null allowed - val = null - i ++ - } else if ( !la.match(/^-{2,}[^-]/) && - !isNaN(la) && - ~argType.indexOf(Number) ) { - // number - val = +la - i ++ - } else if ( !la.match(/^-[^-]/) && ~argType.indexOf(String) ) { - // string - val = la - i ++ - } - } - - if (isArray) (data[arg] = data[arg] || []).push(val) - else data[arg] = val - - continue - } - - if (argType === String) { - if (la === undefined) { - la = "" - } else if (la.match(/^-{1,2}[^-]+/)) { - la = "" - i -- - } - } - - if (la && la.match(/^-{2,}$/)) { - la = undefined - i -- - } - - val = la === undefined ? true : la - if (isArray) (data[arg] = data[arg] || []).push(val) - else data[arg] = val - - i ++ - continue - } - remain.push(arg) - } -} - -function resolveShort (arg, shorthands, shortAbbr, abbrevs) { - // handle single-char shorthands glommed together, like - // npm ls -glp, but only if there is one dash, and only if - // all of the chars are single-char shorthands, and it's - // not a match to some other abbrev. - arg = arg.replace(/^-+/, '') - - // if it's an exact known option, then don't go any further - if (abbrevs[arg] === arg) - return null - - // if it's an exact known shortopt, same deal - if (shorthands[arg]) { - // make it an array, if it's a list of words - if (shorthands[arg] && !Array.isArray(shorthands[arg])) - shorthands[arg] = shorthands[arg].split(/\s+/) - - return shorthands[arg] - } - - // first check to see if this arg is a set of single-char shorthands - var singles = shorthands.___singles - if (!singles) { - singles = Object.keys(shorthands).filter(function (s) { - return s.length === 1 - }).reduce(function (l,r) { - l[r] = true - return l - }, {}) - shorthands.___singles = singles - debug('shorthand singles', singles) - } - - var chrs = arg.split("").filter(function (c) { - return singles[c] +function clean (data, types, typeDefs = exports.typeDefs) { + return lib.clean(data, { + types: types || {}, + typeDefs, + invalidHandler: exports.invalidHandler, + unknownHandler: exports.unknownHandler, + abbrevHandler: exports.abbrevHandler, }) - - if (chrs.join("") === arg) return chrs.map(function (c) { - return shorthands[c] - }).reduce(function (l, r) { - return l.concat(r) - }, []) - - - // if it's an arg abbrev, and not a literal shorthand, then prefer the arg - if (abbrevs[arg] && !shorthands[arg]) - return null - - // if it's an abbr for a shorthand, then use that - if (shortAbbr[arg]) - arg = shortAbbr[arg] - - // make it an array, if it's a list of words - if (shorthands[arg] && !Array.isArray(shorthands[arg])) - shorthands[arg] = shorthands[arg].split(/\s+/) - - return shorthands[arg] } diff --git a/node_modules/nopt/lib/type-defs.js b/node_modules/nopt/lib/type-defs.js new file mode 100644 index 0000000000000..608352ee248cc --- /dev/null +++ b/node_modules/nopt/lib/type-defs.js @@ -0,0 +1,91 @@ +const url = require('url') +const path = require('path') +const Stream = require('stream').Stream +const os = require('os') +const debug = require('./debug') + +function validateString (data, k, val) { + data[k] = String(val) +} + +function validatePath (data, k, val) { + if (val === true) { + return false + } + if (val === null) { + return true + } + + val = String(val) + + const isWin = process.platform === 'win32' + const homePattern = isWin ? /^~(\/|\\)/ : /^~\// + const home = os.homedir() + + if (home && val.match(homePattern)) { + data[k] = path.resolve(home, val.slice(2)) + } else { + data[k] = path.resolve(val) + } + return true +} + +function validateNumber (data, k, val) { + debug('validate Number %j %j %j', k, val, isNaN(val)) + if (isNaN(val)) { + return false + } + data[k] = +val +} + +function validateDate (data, k, val) { + const s = Date.parse(val) + debug('validate Date %j %j %j', k, val, s) + if (isNaN(s)) { + return false + } + data[k] = new Date(val) +} + +function validateBoolean (data, k, val) { + if (typeof val === 'string') { + if (!isNaN(val)) { + val = !!(+val) + } else if (val === 'null' || val === 'false') { + val = false + } else { + val = true + } + } else { + val = !!val + } + data[k] = val +} + +function validateUrl (data, k, val) { + // Changing this would be a breaking change in the npm cli + /* eslint-disable-next-line node/no-deprecated-api */ + val = url.parse(String(val)) + if (!val.host) { + return false + } + data[k] = val.href +} + +function validateStream (data, k, val) { + if (!(val instanceof Stream)) { + return false + } + data[k] = val +} + +module.exports = { + String: { type: String, validate: validateString }, + Boolean: { type: Boolean, validate: validateBoolean }, + url: { type: url, validate: validateUrl }, + Number: { type: Number, validate: validateNumber }, + path: { type: path, validate: validatePath }, + Stream: { type: Stream, validate: validateStream }, + Date: { type: Date, validate: validateDate }, + Array: { type: Array }, +} diff --git a/node_modules/nopt/package.json b/node_modules/nopt/package.json index 12ed02da5a832..bb91642931009 100644 --- a/node_modules/nopt/package.json +++ b/node_modules/nopt/package.json @@ -1,34 +1,52 @@ { "name": "nopt", - "version": "5.0.0", + "version": "9.0.0", "description": "Option parsing for Node, supporting types, shorthands, etc. Used by npm.", - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "main": "lib/nopt.js", "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "test": "tap test/*.js" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/nopt.git" + "url": "git+https://github.com/npm/nopt.git" }, "bin": { "nopt": "bin/nopt.js" }, "license": "ISC", "dependencies": { - "abbrev": "1" + "abbrev": "^4.0.0" }, "devDependencies": { - "tap": "^14.10.6" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "engines": { - "node": ">=6" + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "windowsCI": false, + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/normalize-package-data/LICENSE b/node_modules/normalize-package-data/LICENSE deleted file mode 100644 index 19d1364a8ac08..0000000000000 --- a/node_modules/normalize-package-data/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -This package contains code originally written by Isaac Z. Schlueter. -Used with permission. - -Copyright (c) Meryn Stol ("Author") -All rights reserved. - -The BSD License - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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/node_modules/normalize-package-data/lib/extract_description.js b/node_modules/normalize-package-data/lib/extract_description.js deleted file mode 100644 index bf9896812e5f5..0000000000000 --- a/node_modules/normalize-package-data/lib/extract_description.js +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = extractDescription - -// Extracts description from contents of a readme file in markdown format -function extractDescription (d) { - if (!d) { - return - } - if (d === 'ERROR: No README data found!') { - return - } - // the first block of text before the first heading - // that isn't the first line heading - d = d.trim().split('\n') - for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s++) { - ; - } - var l = d.length - for (var e = s + 1; e < l && d[e].trim(); e++) { - ; - } - return d.slice(s, e).join(' ').trim() -} diff --git a/node_modules/normalize-package-data/lib/fixer.js b/node_modules/normalize-package-data/lib/fixer.js deleted file mode 100644 index 0846f2c045a6e..0000000000000 --- a/node_modules/normalize-package-data/lib/fixer.js +++ /dev/null @@ -1,475 +0,0 @@ -var isValidSemver = require('semver/functions/valid') -var cleanSemver = require('semver/functions/clean') -var validateLicense = require('validate-npm-package-license') -var hostedGitInfo = require('hosted-git-info') -var isBuiltinModule = require('is-core-module') -var depTypes = ['dependencies', 'devDependencies', 'optionalDependencies'] -var extractDescription = require('./extract_description') -var url = require('url') -var typos = require('./typos.json') - -var isEmail = str => str.includes('@') && (str.indexOf('@') < str.lastIndexOf('.')) - -module.exports = { - // default warning function - warn: function () {}, - - fixRepositoryField: function (data) { - if (data.repositories) { - this.warn('repositories') - data.repository = data.repositories[0] - } - if (!data.repository) { - return this.warn('missingRepository') - } - if (typeof data.repository === 'string') { - data.repository = { - type: 'git', - url: data.repository, - } - } - var r = data.repository.url || '' - if (r) { - var hosted = hostedGitInfo.fromUrl(r) - if (hosted) { - r = data.repository.url - = hosted.getDefaultRepresentation() === 'shortcut' ? hosted.https() : hosted.toString() - } - } - - if (r.match(/github.com\/[^/]+\/[^/]+\.git\.git$/)) { - this.warn('brokenGitUrl', r) - } - }, - - fixTypos: function (data) { - Object.keys(typos.topLevel).forEach(function (d) { - if (Object.prototype.hasOwnProperty.call(data, d)) { - this.warn('typo', d, typos.topLevel[d]) - } - }, this) - }, - - fixScriptsField: function (data) { - if (!data.scripts) { - return - } - if (typeof data.scripts !== 'object') { - this.warn('nonObjectScripts') - delete data.scripts - return - } - Object.keys(data.scripts).forEach(function (k) { - if (typeof data.scripts[k] !== 'string') { - this.warn('nonStringScript') - delete data.scripts[k] - } else if (typos.script[k] && !data.scripts[typos.script[k]]) { - this.warn('typo', k, typos.script[k], 'scripts') - } - }, this) - }, - - fixFilesField: function (data) { - var files = data.files - if (files && !Array.isArray(files)) { - this.warn('nonArrayFiles') - delete data.files - } else if (data.files) { - data.files = data.files.filter(function (file) { - if (!file || typeof file !== 'string') { - this.warn('invalidFilename', file) - return false - } else { - return true - } - }, this) - } - }, - - fixBinField: function (data) { - if (!data.bin) { - return - } - if (typeof data.bin === 'string') { - var b = {} - var match - if (match = data.name.match(/^@[^/]+[/](.*)$/)) { - b[match[1]] = data.bin - } else { - b[data.name] = data.bin - } - data.bin = b - } - }, - - fixManField: function (data) { - if (!data.man) { - return - } - if (typeof data.man === 'string') { - data.man = [data.man] - } - }, - fixBundleDependenciesField: function (data) { - var bdd = 'bundledDependencies' - var bd = 'bundleDependencies' - if (data[bdd] && !data[bd]) { - data[bd] = data[bdd] - delete data[bdd] - } - if (data[bd] && !Array.isArray(data[bd])) { - this.warn('nonArrayBundleDependencies') - delete data[bd] - } else if (data[bd]) { - data[bd] = data[bd].filter(function (bd) { - if (!bd || typeof bd !== 'string') { - this.warn('nonStringBundleDependency', bd) - return false - } else { - if (!data.dependencies) { - data.dependencies = {} - } - if (!Object.prototype.hasOwnProperty.call(data.dependencies, bd)) { - this.warn('nonDependencyBundleDependency', bd) - data.dependencies[bd] = '*' - } - return true - } - }, this) - } - }, - - fixDependencies: function (data, strict) { - objectifyDeps(data, this.warn) - addOptionalDepsToDeps(data, this.warn) - this.fixBundleDependenciesField(data) - - ;['dependencies', 'devDependencies'].forEach(function (deps) { - if (!(deps in data)) { - return - } - if (!data[deps] || typeof data[deps] !== 'object') { - this.warn('nonObjectDependencies', deps) - delete data[deps] - return - } - Object.keys(data[deps]).forEach(function (d) { - var r = data[deps][d] - if (typeof r !== 'string') { - this.warn('nonStringDependency', d, JSON.stringify(r)) - delete data[deps][d] - } - var hosted = hostedGitInfo.fromUrl(data[deps][d]) - if (hosted) { - data[deps][d] = hosted.toString() - } - }, this) - }, this) - }, - - fixModulesField: function (data) { - if (data.modules) { - this.warn('deprecatedModules') - delete data.modules - } - }, - - fixKeywordsField: function (data) { - if (typeof data.keywords === 'string') { - data.keywords = data.keywords.split(/,\s+/) - } - if (data.keywords && !Array.isArray(data.keywords)) { - delete data.keywords - this.warn('nonArrayKeywords') - } else if (data.keywords) { - data.keywords = data.keywords.filter(function (kw) { - if (typeof kw !== 'string' || !kw) { - this.warn('nonStringKeyword') - return false - } else { - return true - } - }, this) - } - }, - - fixVersionField: function (data, strict) { - // allow "loose" semver 1.0 versions in non-strict mode - // enforce strict semver 2.0 compliance in strict mode - var loose = !strict - if (!data.version) { - data.version = '' - return true - } - if (!isValidSemver(data.version, loose)) { - throw new Error('Invalid version: "' + data.version + '"') - } - data.version = cleanSemver(data.version, loose) - return true - }, - - fixPeople: function (data) { - modifyPeople(data, unParsePerson) - modifyPeople(data, parsePerson) - }, - - fixNameField: function (data, options) { - if (typeof options === 'boolean') { - options = { strict: options } - } else if (typeof options === 'undefined') { - options = {} - } - var strict = options.strict - if (!data.name && !strict) { - data.name = '' - return - } - if (typeof data.name !== 'string') { - throw new Error('name field must be a string.') - } - if (!strict) { - data.name = data.name.trim() - } - ensureValidName(data.name, strict, options.allowLegacyCase) - if (isBuiltinModule(data.name)) { - this.warn('conflictingName', data.name) - } - }, - - fixDescriptionField: function (data) { - if (data.description && typeof data.description !== 'string') { - this.warn('nonStringDescription') - delete data.description - } - if (data.readme && !data.description) { - data.description = extractDescription(data.readme) - } - if (data.description === undefined) { - delete data.description - } - if (!data.description) { - this.warn('missingDescription') - } - }, - - fixReadmeField: function (data) { - if (!data.readme) { - this.warn('missingReadme') - data.readme = 'ERROR: No README data found!' - } - }, - - fixBugsField: function (data) { - if (!data.bugs && data.repository && data.repository.url) { - var hosted = hostedGitInfo.fromUrl(data.repository.url) - if (hosted && hosted.bugs()) { - data.bugs = { url: hosted.bugs() } - } - } else if (data.bugs) { - if (typeof data.bugs === 'string') { - if (isEmail(data.bugs)) { - data.bugs = { email: data.bugs } - /* eslint-disable-next-line node/no-deprecated-api */ - } else if (url.parse(data.bugs).protocol) { - data.bugs = { url: data.bugs } - } else { - this.warn('nonEmailUrlBugsString') - } - } else { - bugsTypos(data.bugs, this.warn) - var oldBugs = data.bugs - data.bugs = {} - if (oldBugs.url) { - /* eslint-disable-next-line node/no-deprecated-api */ - if (typeof (oldBugs.url) === 'string' && url.parse(oldBugs.url).protocol) { - data.bugs.url = oldBugs.url - } else { - this.warn('nonUrlBugsUrlField') - } - } - if (oldBugs.email) { - if (typeof (oldBugs.email) === 'string' && isEmail(oldBugs.email)) { - data.bugs.email = oldBugs.email - } else { - this.warn('nonEmailBugsEmailField') - } - } - } - if (!data.bugs.email && !data.bugs.url) { - delete data.bugs - this.warn('emptyNormalizedBugs') - } - } - }, - - fixHomepageField: function (data) { - if (!data.homepage && data.repository && data.repository.url) { - var hosted = hostedGitInfo.fromUrl(data.repository.url) - if (hosted && hosted.docs()) { - data.homepage = hosted.docs() - } - } - if (!data.homepage) { - return - } - - if (typeof data.homepage !== 'string') { - this.warn('nonUrlHomepage') - return delete data.homepage - } - /* eslint-disable-next-line node/no-deprecated-api */ - if (!url.parse(data.homepage).protocol) { - data.homepage = 'http://' + data.homepage - } - }, - - fixLicenseField: function (data) { - const license = data.license || data.licence - if (!license) { - return this.warn('missingLicense') - } - if ( - typeof (license) !== 'string' || - license.length < 1 || - license.trim() === '' - ) { - return this.warn('invalidLicense') - } - if (!validateLicense(license).validForNewPackages) { - return this.warn('invalidLicense') - } - }, -} - -function isValidScopedPackageName (spec) { - if (spec.charAt(0) !== '@') { - return false - } - - var rest = spec.slice(1).split('/') - if (rest.length !== 2) { - return false - } - - return rest[0] && rest[1] && - rest[0] === encodeURIComponent(rest[0]) && - rest[1] === encodeURIComponent(rest[1]) -} - -function isCorrectlyEncodedName (spec) { - return !spec.match(/[/@\s+%:]/) && - spec === encodeURIComponent(spec) -} - -function ensureValidName (name, strict, allowLegacyCase) { - if (name.charAt(0) === '.' || - !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) || - (strict && (!allowLegacyCase) && name !== name.toLowerCase()) || - name.toLowerCase() === 'node_modules' || - name.toLowerCase() === 'favicon.ico') { - throw new Error('Invalid name: ' + JSON.stringify(name)) - } -} - -function modifyPeople (data, fn) { - if (data.author) { - data.author = fn(data.author) - }['maintainers', 'contributors'].forEach(function (set) { - if (!Array.isArray(data[set])) { - return - } - data[set] = data[set].map(fn) - }) - return data -} - -function unParsePerson (person) { - if (typeof person === 'string') { - return person - } - var name = person.name || '' - var u = person.url || person.web - var url = u ? (' (' + u + ')') : '' - var e = person.email || person.mail - var email = e ? (' <' + e + '>') : '' - return name + email + url -} - -function parsePerson (person) { - if (typeof person !== 'string') { - return person - } - var name = person.match(/^([^(<]+)/) - var url = person.match(/\(([^()]+)\)/) - var email = person.match(/<([^<>]+)>/) - var obj = {} - if (name && name[0].trim()) { - obj.name = name[0].trim() - } - if (email) { - obj.email = email[1] - } - if (url) { - obj.url = url[1] - } - return obj -} - -function addOptionalDepsToDeps (data, warn) { - var o = data.optionalDependencies - if (!o) { - return - } - var d = data.dependencies || {} - Object.keys(o).forEach(function (k) { - d[k] = o[k] - }) - data.dependencies = d -} - -function depObjectify (deps, type, warn) { - if (!deps) { - return {} - } - if (typeof deps === 'string') { - deps = deps.trim().split(/[\n\r\s\t ,]+/) - } - if (!Array.isArray(deps)) { - return deps - } - warn('deprecatedArrayDependencies', type) - var o = {} - deps.filter(function (d) { - return typeof d === 'string' - }).forEach(function (d) { - d = d.trim().split(/(:?[@\s><=])/) - var dn = d.shift() - var dv = d.join('') - dv = dv.trim() - dv = dv.replace(/^@/, '') - o[dn] = dv - }) - return o -} - -function objectifyDeps (data, warn) { - depTypes.forEach(function (type) { - if (!data[type]) { - return - } - data[type] = depObjectify(data[type], type, warn) - }) -} - -function bugsTypos (bugs, warn) { - if (!bugs) { - return - } - Object.keys(bugs).forEach(function (k) { - if (typos.bugs[k]) { - warn('typo', k, typos.bugs[k], 'bugs') - bugs[typos.bugs[k]] = bugs[k] - delete bugs[k] - } - }) -} diff --git a/node_modules/normalize-package-data/lib/make_warning.js b/node_modules/normalize-package-data/lib/make_warning.js deleted file mode 100644 index 3be9c86539952..0000000000000 --- a/node_modules/normalize-package-data/lib/make_warning.js +++ /dev/null @@ -1,22 +0,0 @@ -var util = require('util') -var messages = require('./warning_messages.json') - -module.exports = function () { - var args = Array.prototype.slice.call(arguments, 0) - var warningName = args.shift() - if (warningName === 'typo') { - return makeTypoWarning.apply(null, args) - } else { - var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'" - args.unshift(msgTemplate) - return util.format.apply(null, args) - } -} - -function makeTypoWarning (providedName, probableName, field) { - if (field) { - providedName = field + "['" + providedName + "']" - probableName = field + "['" + probableName + "']" - } - return util.format(messages.typo, providedName, probableName) -} diff --git a/node_modules/normalize-package-data/lib/normalize.js b/node_modules/normalize-package-data/lib/normalize.js deleted file mode 100644 index bf71d2c1e2235..0000000000000 --- a/node_modules/normalize-package-data/lib/normalize.js +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = normalize - -var fixer = require('./fixer') -normalize.fixer = fixer - -var makeWarning = require('./make_warning') - -var fieldsToFix = ['name', 'version', 'description', 'repository', 'modules', 'scripts', - 'files', 'bin', 'man', 'bugs', 'keywords', 'readme', 'homepage', 'license'] -var otherThingsToFix = ['dependencies', 'people', 'typos'] - -var thingsToFix = fieldsToFix.map(function (fieldName) { - return ucFirst(fieldName) + 'Field' -}) -// two ways to do this in CoffeeScript on only one line, sub-70 chars: -// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field" -// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix) -thingsToFix = thingsToFix.concat(otherThingsToFix) - -function normalize (data, warn, strict) { - if (warn === true) { - warn = null - strict = true - } - if (!strict) { - strict = false - } - if (!warn || data.private) { - warn = function (msg) { /* noop */ } - } - - if (data.scripts && - data.scripts.install === 'node-gyp rebuild' && - !data.scripts.preinstall) { - data.gypfile = true - } - fixer.warn = function () { - warn(makeWarning.apply(null, arguments)) - } - thingsToFix.forEach(function (thingName) { - fixer['fix' + ucFirst(thingName)](data, strict) - }) - data._id = data.name + '@' + data.version -} - -function ucFirst (string) { - return string.charAt(0).toUpperCase() + string.slice(1) -} diff --git a/node_modules/normalize-package-data/lib/safe_format.js b/node_modules/normalize-package-data/lib/safe_format.js deleted file mode 100644 index 5fc888e5450cd..0000000000000 --- a/node_modules/normalize-package-data/lib/safe_format.js +++ /dev/null @@ -1,11 +0,0 @@ -var util = require('util') - -module.exports = function () { - var args = Array.prototype.slice.call(arguments, 0) - args.forEach(function (arg) { - if (!arg) { - throw new TypeError('Bad arguments.') - } - }) - return util.format.apply(null, arguments) -} diff --git a/node_modules/normalize-package-data/lib/typos.json b/node_modules/normalize-package-data/lib/typos.json deleted file mode 100644 index 7f9dd283b30ff..0000000000000 --- a/node_modules/normalize-package-data/lib/typos.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "topLevel": { - "dependancies": "dependencies" - ,"dependecies": "dependencies" - ,"depdenencies": "dependencies" - ,"devEependencies": "devDependencies" - ,"depends": "dependencies" - ,"dev-dependencies": "devDependencies" - ,"devDependences": "devDependencies" - ,"devDepenencies": "devDependencies" - ,"devdependencies": "devDependencies" - ,"repostitory": "repository" - ,"repo": "repository" - ,"prefereGlobal": "preferGlobal" - ,"hompage": "homepage" - ,"hampage": "homepage" - ,"autohr": "author" - ,"autor": "author" - ,"contributers": "contributors" - ,"publicationConfig": "publishConfig" - ,"script": "scripts" - }, - "bugs": { "web": "url", "name": "url" }, - "script": { "server": "start", "tests": "test" } -} diff --git a/node_modules/normalize-package-data/lib/warning_messages.json b/node_modules/normalize-package-data/lib/warning_messages.json deleted file mode 100644 index 4890f506ed965..0000000000000 --- a/node_modules/normalize-package-data/lib/warning_messages.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "repositories": "'repositories' (plural) Not supported. Please pick one as the 'repository' field" - ,"missingRepository": "No repository field." - ,"brokenGitUrl": "Probably broken git url: %s" - ,"nonObjectScripts": "scripts must be an object" - ,"nonStringScript": "script values must be string commands" - ,"nonArrayFiles": "Invalid 'files' member" - ,"invalidFilename": "Invalid filename in 'files' list: %s" - ,"nonArrayBundleDependencies": "Invalid 'bundleDependencies' list. Must be array of package names" - ,"nonStringBundleDependency": "Invalid bundleDependencies member: %s" - ,"nonDependencyBundleDependency": "Non-dependency in bundleDependencies: %s" - ,"nonObjectDependencies": "%s field must be an object" - ,"nonStringDependency": "Invalid dependency: %s %s" - ,"deprecatedArrayDependencies": "specifying %s as array is deprecated" - ,"deprecatedModules": "modules field is deprecated" - ,"nonArrayKeywords": "keywords should be an array of strings" - ,"nonStringKeyword": "keywords should be an array of strings" - ,"conflictingName": "%s is also the name of a node core module." - ,"nonStringDescription": "'description' field should be a string" - ,"missingDescription": "No description" - ,"missingReadme": "No README data" - ,"missingLicense": "No license field." - ,"nonEmailUrlBugsString": "Bug string field must be url, email, or {email,url}" - ,"nonUrlBugsUrlField": "bugs.url field must be a string url. Deleted." - ,"nonEmailBugsEmailField": "bugs.email field must be a string email. Deleted." - ,"emptyNormalizedBugs": "Normalized value of bugs field is an empty object. Deleted." - ,"nonUrlHomepage": "homepage field must be a string url. Deleted." - ,"invalidLicense": "license should be a valid SPDX license expression" - ,"typo": "%s should probably be %s." -} diff --git a/node_modules/normalize-package-data/package.json b/node_modules/normalize-package-data/package.json deleted file mode 100644 index a6f1244eb5a25..0000000000000 --- a/node_modules/normalize-package-data/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "normalize-package-data", - "version": "4.0.0", - "author": "GitHub Inc.", - "description": "Normalizes data that can be found in package.json files.", - "license": "BSD-2-Clause", - "repository": { - "type": "git", - "url": "git://github.com/npm/normalize-package-data.git" - }, - "main": "lib/normalize.js", - "scripts": { - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "preversion": "npm test", - "test": "tap", - "npmclilint": "npmcli-lint", - "lint": "eslint '**/*.js'", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint", - "postsnap": "npm run lintfix --", - "postlint": "npm-template-check", - "template-copy": "npm-template-copy --force", - "snap": "tap" - }, - "dependencies": { - "hosted-git-info": "^5.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "devDependencies": { - "@npmcli/template-oss": "^2.9.2", - "tap": "^15.0.9" - }, - "files": [ - "bin", - "lib" - ], - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - }, - "templateOSS": { - "version": "2.9.2" - }, - "tap": { - "branches": 86, - "functions": 92, - "lines": 86, - "statements": 86 - } -} diff --git a/node_modules/npm-audit-report/lib/colors.js b/node_modules/npm-audit-report/lib/colors.js index 2fbf5c36093de..e6688f2f1c8c6 100644 --- a/node_modules/npm-audit-report/lib/colors.js +++ b/node_modules/npm-audit-report/lib/colors.js @@ -1,16 +1,14 @@ -const chalk = require('chalk') -module.exports = color => { - const identity = x => x - const green = color ? s => chalk.green.bold(s) : identity - const red = color ? s => chalk.red.bold(s) : identity - const magenta = color ? s => chalk.magenta.bold(s) : identity - const yellow = color ? s => chalk.yellow.bold(s) : identity - const white = color ? s => chalk.bold(s) : identity +module.exports = (chalk) => { + const green = s => chalk.green.bold(s) + const red = s => chalk.red.bold(s) + const magenta = s => chalk.magenta.bold(s) + const yellow = s => chalk.yellow.bold(s) + const white = s => chalk.bold(s) const severity = (sev, s) => sev.toLowerCase() === 'moderate' ? yellow(s || sev) : sev.toLowerCase() === 'high' ? red(s || sev) : sev.toLowerCase() === 'critical' ? magenta(s || sev) : white(s || sev) - const dim = color ? s => chalk.dim(s) : identity + const dim = s => chalk.dim(s) return { dim, diff --git a/node_modules/npm-audit-report/lib/index.js b/node_modules/npm-audit-report/lib/index.js index 63063f92526a1..d0ced01efefec 100644 --- a/node_modules/npm-audit-report/lib/index.js +++ b/node_modules/npm-audit-report/lib/index.js @@ -12,7 +12,7 @@ const exitCode = require('./exit-code.js') module.exports = Object.assign((data, options = {}) => { const { reporter = 'install', - color = true, + chalk, unicode = true, indent = 2, } = options @@ -35,7 +35,7 @@ module.exports = Object.assign((data, options = {}) => { } return { - report: reporters[reporter](data, { color, unicode, indent }), + report: reporters[reporter](data, { chalk, unicode, indent }), exitCode: exitCode(data, auditLevel), } }, { reporters }) diff --git a/node_modules/npm-audit-report/lib/reporters/detail.js b/node_modules/npm-audit-report/lib/reporters/detail.js index ba2f013836d9d..6dde8ec88de44 100644 --- a/node_modules/npm-audit-report/lib/reporters/detail.js +++ b/node_modules/npm-audit-report/lib/reporters/detail.js @@ -3,14 +3,14 @@ const colors = require('../colors.js') const install = require('./install.js') -module.exports = (data, { color }) => { - const summary = install.summary(data, { color }) +module.exports = (data, { chalk }) => { + const summary = install.summary(data, { chalk }) const none = data.metadata.vulnerabilities.total === 0 - return none ? summary : fullReport(data, { color, summary }) + return none ? summary : fullReport(data, { chalk, summary }) } -const fullReport = (data, { color, summary }) => { - const c = colors(color) +const fullReport = (data, { chalk, summary }) => { + const c = colors(chalk) const output = [c.white('# npm audit report'), ''] const printed = new Set() diff --git a/node_modules/npm-audit-report/lib/reporters/install.js b/node_modules/npm-audit-report/lib/reporters/install.js index cb8a249691e29..0a1e82533e657 100644 --- a/node_modules/npm-audit-report/lib/reporters/install.js +++ b/node_modules/npm-audit-report/lib/reporters/install.js @@ -1,7 +1,7 @@ const colors = require('../colors.js') -const calculate = (data, { color }) => { - const c = colors(color) +const calculate = (data, { chalk }) => { + const c = colors(chalk) const output = [] const { metadata: { vulnerabilities } } = data const vulnCount = vulnerabilities.total diff --git a/node_modules/npm-audit-report/package.json b/node_modules/npm-audit-report/package.json index 8749c14582fa9..ff79f72499713 100644 --- a/node_modules/npm-audit-report/package.json +++ b/node_modules/npm-audit-report/package.json @@ -1,23 +1,25 @@ { "name": "npm-audit-report", - "version": "3.0.0", + "version": "7.0.0", "description": "Given a response from the npm security api, render it into a variety of security reports", "main": "lib/index.js", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "posttest": "npm run lint" + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { "check-coverage": true, - "coverage-map": "map.js" + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "keywords": [ "npm", @@ -27,13 +29,10 @@ ], "author": "GitHub Inc.", "license": "ISC", - "dependencies": { - "chalk": "^4.0.0" - }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.1.2", - "require-inject": "^1.4.4", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "chalk": "^5.2.0", "tap": "^16.0.0" }, "directories": { @@ -42,7 +41,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/npm-audit-report.git" + "url": "git+https://github.com/npm/npm-audit-report.git" }, "bugs": { "url": "https://github.com/npm/npm-audit-report/issues" @@ -50,14 +49,14 @@ "homepage": "https://github.com/npm/npm-audit-report#readme", "files": [ "bin/", - "lib/", - "reporters" + "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.1.2" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/npm-bundled/index.js b/node_modules/npm-bundled/index.js deleted file mode 100644 index 378ddc4c5ddb2..0000000000000 --- a/node_modules/npm-bundled/index.js +++ /dev/null @@ -1,251 +0,0 @@ -'use strict' - -// walk the tree of deps starting from the top level list of bundled deps -// Any deps at the top level that are depended on by a bundled dep that -// does not have that dep in its own node_modules folder are considered -// bundled deps as well. This list of names can be passed to npm-packlist -// as the "bundled" argument. Additionally, packageJsonCache is shared so -// packlist doesn't have to re-read files already consumed in this pass - -const fs = require('fs') -const path = require('path') -const EE = require('events').EventEmitter -// we don't care about the package bins, but we share a pj cache -// with other modules that DO care about it, so keep it nice. -const normalizePackageBin = require('npm-normalize-package-bin') - -class BundleWalker extends EE { - constructor (opt) { - opt = opt || {} - super(opt) - this.path = path.resolve(opt.path || process.cwd()) - - this.parent = opt.parent || null - if (this.parent) { - this.result = this.parent.result - // only collect results in node_modules folders at the top level - // since the node_modules in a bundled dep is included always - if (!this.parent.parent) { - const base = path.basename(this.path) - const scope = path.basename(path.dirname(this.path)) - this.result.add(/^@/.test(scope) ? scope + '/' + base : base) - } - this.root = this.parent.root - this.packageJsonCache = this.parent.packageJsonCache - } else { - this.result = new Set() - this.root = this.path - this.packageJsonCache = opt.packageJsonCache || new Map() - } - - this.seen = new Set() - this.didDone = false - this.children = 0 - this.node_modules = [] - this.package = null - this.bundle = null - } - - addListener (ev, fn) { - return this.on(ev, fn) - } - - on (ev, fn) { - const ret = super.on(ev, fn) - if (ev === 'done' && this.didDone) { - this.emit('done', this.result) - } - return ret - } - - done () { - if (!this.didDone) { - this.didDone = true - if (!this.parent) { - const res = Array.from(this.result) - this.result = res - this.emit('done', res) - } else { - this.emit('done') - } - } - } - - start () { - const pj = path.resolve(this.path, 'package.json') - if (this.packageJsonCache.has(pj)) - this.onPackage(this.packageJsonCache.get(pj)) - else - this.readPackageJson(pj) - return this - } - - readPackageJson (pj) { - fs.readFile(pj, (er, data) => - er ? this.done() : this.onPackageJson(pj, data)) - } - - onPackageJson (pj, data) { - try { - this.package = normalizePackageBin(JSON.parse(data + '')) - } catch (er) { - return this.done() - } - this.packageJsonCache.set(pj, this.package) - this.onPackage(this.package) - } - - allDepsBundled (pkg) { - return Object.keys(pkg.dependencies || {}).concat( - Object.keys(pkg.optionalDependencies || {})) - } - - onPackage (pkg) { - // all deps are bundled if we got here as a child. - // otherwise, only bundle bundledDeps - // Get a unique-ified array with a short-lived Set - const bdRaw = this.parent ? this.allDepsBundled(pkg) - : pkg.bundleDependencies || pkg.bundledDependencies || [] - - const bd = Array.from(new Set( - Array.isArray(bdRaw) ? bdRaw - : bdRaw === true ? this.allDepsBundled(pkg) - : Object.keys(bdRaw))) - - if (!bd.length) - return this.done() - - this.bundle = bd - const nm = this.path + '/node_modules' - this.readModules() - } - - readModules () { - readdirNodeModules(this.path + '/node_modules', (er, nm) => - er ? this.onReaddir([]) : this.onReaddir(nm)) - } - - onReaddir (nm) { - // keep track of what we have, in case children need it - this.node_modules = nm - - this.bundle.forEach(dep => this.childDep(dep)) - if (this.children === 0) - this.done() - } - - childDep (dep) { - if (this.node_modules.indexOf(dep) !== -1) { - if (!this.seen.has(dep)) { - this.seen.add(dep) - this.child(dep) - } - } else if (this.parent) { - this.parent.childDep(dep) - } - } - - child (dep) { - const p = this.path + '/node_modules/' + dep - this.children += 1 - const child = new BundleWalker({ - path: p, - parent: this - }) - child.on('done', _ => { - if (--this.children === 0) - this.done() - }) - child.start() - } -} - -class BundleWalkerSync extends BundleWalker { - constructor (opt) { - super(opt) - } - - start () { - super.start() - this.done() - return this - } - - readPackageJson (pj) { - try { - this.onPackageJson(pj, fs.readFileSync(pj)) - } catch (er) {} - return this - } - - readModules () { - try { - this.onReaddir(readdirNodeModulesSync(this.path + '/node_modules')) - } catch (er) { - this.onReaddir([]) - } - } - - child (dep) { - new BundleWalkerSync({ - path: this.path + '/node_modules/' + dep, - parent: this - }).start() - } -} - -const readdirNodeModules = (nm, cb) => { - fs.readdir(nm, (er, set) => { - if (er) - cb(er) - else { - const scopes = set.filter(f => /^@/.test(f)) - if (!scopes.length) - cb(null, set) - else { - const unscoped = set.filter(f => !/^@/.test(f)) - let count = scopes.length - scopes.forEach(scope => { - fs.readdir(nm + '/' + scope, (er, pkgs) => { - if (er || !pkgs.length) - unscoped.push(scope) - else - unscoped.push.apply(unscoped, pkgs.map(p => scope + '/' + p)) - if (--count === 0) - cb(null, unscoped) - }) - }) - } - } - }) -} - -const readdirNodeModulesSync = nm => { - const set = fs.readdirSync(nm) - const unscoped = set.filter(f => !/^@/.test(f)) - const scopes = set.filter(f => /^@/.test(f)).map(scope => { - try { - const pkgs = fs.readdirSync(nm + '/' + scope) - return pkgs.length ? pkgs.map(p => scope + '/' + p) : [scope] - } catch (er) { - return [scope] - } - }).reduce((a, b) => a.concat(b), []) - return unscoped.concat(scopes) -} - -const walk = (options, callback) => { - const p = new Promise((resolve, reject) => { - new BundleWalker(options).on('done', resolve).on('error', reject).start() - }) - return callback ? p.then(res => callback(null, res), callback) : p -} - -const walkSync = options => { - return new BundleWalkerSync(options).start().result -} - -module.exports = walk -walk.sync = walkSync -walk.BundleWalker = BundleWalker -walk.BundleWalkerSync = BundleWalkerSync diff --git a/node_modules/npm-bundled/lib/index.js b/node_modules/npm-bundled/lib/index.js new file mode 100644 index 0000000000000..f5ee0bb3ea765 --- /dev/null +++ b/node_modules/npm-bundled/lib/index.js @@ -0,0 +1,254 @@ +'use strict' + +// walk the tree of deps starting from the top level list of bundled deps +// Any deps at the top level that are depended on by a bundled dep that +// does not have that dep in its own node_modules folder are considered +// bundled deps as well. This list of names can be passed to npm-packlist +// as the "bundled" argument. Additionally, packageJsonCache is shared so +// packlist doesn't have to re-read files already consumed in this pass + +const fs = require('fs') +const path = require('path') +const EE = require('events').EventEmitter +// we don't care about the package bins, but we share a pj cache +// with other modules that DO care about it, so keep it nice. +const normalizePackageBin = require('npm-normalize-package-bin') + +class BundleWalker extends EE { + constructor (opt) { + opt = opt || {} + super(opt) + this.path = path.resolve(opt.path || process.cwd()) + + this.parent = opt.parent || null + if (this.parent) { + this.result = this.parent.result + // only collect results in node_modules folders at the top level + // since the node_modules in a bundled dep is included always + if (!this.parent.parent) { + const base = path.basename(this.path) + const scope = path.basename(path.dirname(this.path)) + this.result.add(/^@/.test(scope) ? scope + '/' + base : base) + } + this.root = this.parent.root + this.packageJsonCache = this.parent.packageJsonCache + } else { + this.result = new Set() + this.root = this.path + this.packageJsonCache = opt.packageJsonCache || new Map() + } + + this.seen = new Set() + this.didDone = false + this.children = 0 + this.node_modules = [] + this.package = null + this.bundle = null + } + + addListener (ev, fn) { + return this.on(ev, fn) + } + + on (ev, fn) { + const ret = super.on(ev, fn) + if (ev === 'done' && this.didDone) { + this.emit('done', this.result) + } + return ret + } + + done () { + if (!this.didDone) { + this.didDone = true + if (!this.parent) { + const res = Array.from(this.result) + this.result = res + this.emit('done', res) + } else { + this.emit('done') + } + } + } + + start () { + const pj = path.resolve(this.path, 'package.json') + if (this.packageJsonCache.has(pj)) { + this.onPackage(this.packageJsonCache.get(pj)) + } else { + this.readPackageJson(pj) + } + return this + } + + readPackageJson (pj) { + fs.readFile(pj, (er, data) => + er ? this.done() : this.onPackageJson(pj, data)) + } + + onPackageJson (pj, data) { + try { + this.package = normalizePackageBin(JSON.parse(data + '')) + } catch (er) { + return this.done() + } + this.packageJsonCache.set(pj, this.package) + this.onPackage(this.package) + } + + allDepsBundled (pkg) { + return Object.keys(pkg.dependencies || {}).concat( + Object.keys(pkg.optionalDependencies || {})) + } + + onPackage (pkg) { + // all deps are bundled if we got here as a child. + // otherwise, only bundle bundledDeps + // Get a unique-ified array with a short-lived Set + const bdRaw = this.parent ? this.allDepsBundled(pkg) + : pkg.bundleDependencies || pkg.bundledDependencies || [] + + const bd = Array.from(new Set( + Array.isArray(bdRaw) ? bdRaw + : bdRaw === true ? this.allDepsBundled(pkg) + : Object.keys(bdRaw))) + + if (!bd.length) { + return this.done() + } + + this.bundle = bd + this.readModules() + } + + readModules () { + readdirNodeModules(this.path + '/node_modules', (er, nm) => + er ? this.onReaddir([]) : this.onReaddir(nm)) + } + + onReaddir (nm) { + // keep track of what we have, in case children need it + this.node_modules = nm + + this.bundle.forEach(dep => this.childDep(dep)) + if (this.children === 0) { + this.done() + } + } + + childDep (dep) { + if (this.node_modules.indexOf(dep) !== -1) { + if (!this.seen.has(dep)) { + this.seen.add(dep) + this.child(dep) + } + } else if (this.parent) { + this.parent.childDep(dep) + } + } + + child (dep) { + const p = this.path + '/node_modules/' + dep + this.children += 1 + const child = new BundleWalker({ + path: p, + parent: this, + }) + child.on('done', () => { + if (--this.children === 0) { + this.done() + } + }) + child.start() + } +} + +class BundleWalkerSync extends BundleWalker { + start () { + super.start() + this.done() + return this + } + + readPackageJson (pj) { + try { + this.onPackageJson(pj, fs.readFileSync(pj)) + } catch { + // empty catch + } + return this + } + + readModules () { + try { + this.onReaddir(readdirNodeModulesSync(this.path + '/node_modules')) + } catch { + this.onReaddir([]) + } + } + + child (dep) { + new BundleWalkerSync({ + path: this.path + '/node_modules/' + dep, + parent: this, + }).start() + } +} + +const readdirNodeModules = (nm, cb) => { + fs.readdir(nm, (er, set) => { + if (er) { + cb(er) + } else { + const scopes = set.filter(f => /^@/.test(f)) + if (!scopes.length) { + cb(null, set) + } else { + const unscoped = set.filter(f => !/^@/.test(f)) + let count = scopes.length + scopes.forEach(scope => { + fs.readdir(nm + '/' + scope, (readdirEr, pkgs) => { + if (readdirEr || !pkgs.length) { + unscoped.push(scope) + } else { + unscoped.push.apply(unscoped, pkgs.map(p => scope + '/' + p)) + } + if (--count === 0) { + cb(null, unscoped) + } + }) + }) + } + } + }) +} + +const readdirNodeModulesSync = nm => { + const set = fs.readdirSync(nm) + const unscoped = set.filter(f => !/^@/.test(f)) + const scopes = set.filter(f => /^@/.test(f)).map(scope => { + try { + const pkgs = fs.readdirSync(nm + '/' + scope) + return pkgs.length ? pkgs.map(p => scope + '/' + p) : [scope] + } catch (er) { + return [scope] + } + }).reduce((a, b) => a.concat(b), []) + return unscoped.concat(scopes) +} + +const walk = (options, callback) => { + const p = new Promise((resolve, reject) => { + new BundleWalker(options).on('done', resolve).on('error', reject).start() + }) + return callback ? p.then(res => callback(null, res), callback) : p +} + +const walkSync = options => { + return new BundleWalkerSync(options).start().result +} + +module.exports = walk +walk.sync = walkSync +walk.BundleWalker = BundleWalker +walk.BundleWalkerSync = BundleWalkerSync diff --git a/node_modules/npm-bundled/package.json b/node_modules/npm-bundled/package.json index cf20e297b0b63..1fa4bdc72c593 100644 --- a/node_modules/npm-bundled/package.json +++ b/node_modules/npm-bundled/package.json @@ -1,30 +1,49 @@ { "name": "npm-bundled", - "version": "1.1.2", + "version": "5.0.0", "description": "list things in node_modules that are bundledDependencies, or transitive dependencies thereof", - "main": "index.js", + "main": "lib/index.js", "repository": { "type": "git", "url": "git+https://github.com/npm/npm-bundled.git" }, - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "license": "ISC", "devDependencies": { - "mkdirp": "^0.5.1", - "mutate-fs": "^1.1.0", - "rimraf": "^2.6.1", - "tap": "^12.0.1" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "mutate-fs": "^2.1.1", + "tap": "^16.3.0" }, "scripts": { - "test": "tap test/*.js -J --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "files": [ - "index.js" + "bin/", + "lib/" ], "dependencies": { - "npm-normalize-package-bin": "^1.0.1" + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/npm-install-checks/lib/current-env.js b/node_modules/npm-install-checks/lib/current-env.js new file mode 100644 index 0000000000000..31f154aac59b3 --- /dev/null +++ b/node_modules/npm-install-checks/lib/current-env.js @@ -0,0 +1,91 @@ +const process = require('node:process') +const nodeOs = require('node:os') +const fs = require('node:fs') + +function isMusl (file) { + return file.includes('libc.musl-') || file.includes('ld-musl-') +} + +function os () { + return process.platform +} + +function cpu () { + return process.arch +} + +const LDD_PATH = '/usr/bin/ldd' +function getFamilyFromFilesystem () { + try { + const content = fs.readFileSync(LDD_PATH, 'utf-8') + if (content.includes('musl')) { + return 'musl' + } + if (content.includes('GNU C Library')) { + return 'glibc' + } + return null + } catch { + return undefined + } +} + +function getFamilyFromReport () { + const originalExclude = process.report.excludeNetwork + process.report.excludeNetwork = true + const report = process.report.getReport() + process.report.excludeNetwork = originalExclude + if (report.header?.glibcVersionRuntime) { + family = 'glibc' + } else if (Array.isArray(report.sharedObjects) && report.sharedObjects.some(isMusl)) { + family = 'musl' + } else { + family = null + } + return family +} + +let family +function libc (osName) { + if (osName !== 'linux') { + return undefined + } + if (family === undefined) { + family = getFamilyFromFilesystem() + if (family === undefined) { + family = getFamilyFromReport() + } + } + return family +} + +function devEngines (env = {}) { + const osName = env.os || os() + return { + cpu: { + name: env.cpu || cpu(), + }, + libc: { + name: env.libc || libc(osName), + }, + os: { + name: osName, + version: env.osVersion || nodeOs.release(), + }, + packageManager: { + name: 'npm', + version: env.npmVersion, + }, + runtime: { + name: 'node', + version: env.nodeVersion || process.version, + }, + } +} + +module.exports = { + cpu, + libc, + os, + devEngines, +} diff --git a/node_modules/npm-install-checks/lib/dev-engines.js b/node_modules/npm-install-checks/lib/dev-engines.js new file mode 100644 index 0000000000000..2c483349ae70a --- /dev/null +++ b/node_modules/npm-install-checks/lib/dev-engines.js @@ -0,0 +1,145 @@ +const satisfies = require('semver/functions/satisfies') +const validRange = require('semver/ranges/valid') + +const recognizedOnFail = [ + 'ignore', + 'warn', + 'error', + 'download', +] + +const recognizedProperties = [ + 'name', + 'version', + 'onFail', +] + +const recognizedEngines = [ + 'packageManager', + 'runtime', + 'cpu', + 'libc', + 'os', +] + +/** checks a devEngine dependency */ +function checkDependency (wanted, current, opts) { + const { engine } = opts + + if ((typeof wanted !== 'object' || wanted === null) || Array.isArray(wanted)) { + throw new Error(`Invalid non-object value for "${engine}"`) + } + + const properties = Object.keys(wanted) + + for (const prop of properties) { + if (!recognizedProperties.includes(prop)) { + throw new Error(`Invalid property "${prop}" for "${engine}"`) + } + } + + if (!properties.includes('name')) { + throw new Error(`Missing "name" property for "${engine}"`) + } + + if (typeof wanted.name !== 'string') { + throw new Error(`Invalid non-string value for "name" within "${engine}"`) + } + + if (typeof current.name !== 'string' || current.name === '') { + throw new Error(`Unable to determine "name" for "${engine}"`) + } + + if (properties.includes('onFail')) { + if (typeof wanted.onFail !== 'string') { + throw new Error(`Invalid non-string value for "onFail" within "${engine}"`) + } + if (!recognizedOnFail.includes(wanted.onFail)) { + throw new Error(`Invalid onFail value "${wanted.onFail}" for "${engine}"`) + } + } + + if (wanted.name !== current.name) { + return new Error( + `Invalid name "${wanted.name}" does not match "${current.name}" for "${engine}"` + ) + } + + if (properties.includes('version')) { + if (typeof wanted.version !== 'string') { + throw new Error(`Invalid non-string value for "version" within "${engine}"`) + } + if (typeof current.version !== 'string' || current.version === '') { + throw new Error(`Unable to determine "version" for "${engine}" "${wanted.name}"`) + } + if (validRange(wanted.version)) { + if (!satisfies(current.version, wanted.version, opts.semver)) { + return new Error( + // eslint-disable-next-line max-len + `Invalid semver version "${wanted.version}" does not match "${current.version}" for "${engine}"` + ) + } + } else if (wanted.version !== current.version) { + return new Error( + `Invalid version "${wanted.version}" does not match "${current.version}" for "${engine}"` + ) + } + } +} + +/** checks devEngines package property and returns array of warnings / errors */ +function checkDevEngines (wanted, current = {}, opts = {}) { + if ((typeof wanted !== 'object' || wanted === null) || Array.isArray(wanted)) { + throw new Error(`Invalid non-object value for "devEngines"`) + } + + const errors = [] + + for (const engine of Object.keys(wanted)) { + if (!recognizedEngines.includes(engine)) { + throw new Error(`Invalid property "devEngines.${engine}"`) + } + const dependencyAsAuthored = wanted[engine] + const dependencies = [dependencyAsAuthored].flat() + const currentEngine = current[engine] || {} + + // this accounts for empty array eg { runtime: [] } and ignores it + if (dependencies.length === 0) { + continue + } + + const depErrors = [] + for (const dep of dependencies) { + const result = checkDependency(dep, currentEngine, { ...opts, engine }) + if (result) { + depErrors.push(result) + } + } + + const invalid = depErrors.length === dependencies.length + + if (invalid) { + const lastDependency = dependencies[dependencies.length - 1] + let onFail = lastDependency.onFail || 'error' + if (onFail === 'download') { + onFail = 'error' + } + + const err = Object.assign(new Error(`Invalid devEngines.${engine}`), { + errors: depErrors, + engine, + isWarn: onFail === 'warn', + isError: onFail === 'error', + current: currentEngine, + required: dependencyAsAuthored, + }) + + errors.push(err) + } + } + return errors +} + +module.exports = { + checkDevEngines, +} diff --git a/node_modules/npm-install-checks/lib/index.js b/node_modules/npm-install-checks/lib/index.js index 728e8cf3f8682..7170292087308 100644 --- a/node_modules/npm-install-checks/lib/index.js +++ b/node_modules/npm-install-checks/lib/index.js @@ -1,4 +1,6 @@ const semver = require('semver') +const currentEnv = require('./current-env') +const { checkDevEngines } = require('./dev-engines') const checkEngine = (target, npmVer, nodeVer, force = false) => { const nodev = force ? null : nodeVer @@ -20,26 +22,34 @@ const checkEngine = (target, npmVer, nodeVer, force = false) => { } } -const checkPlatform = (target, force = false) => { +const checkPlatform = (target, force = false, environment = {}) => { if (force) { return } - const platform = process.platform - const arch = process.arch - const osOk = target.os ? checkList(platform, target.os) : true - const cpuOk = target.cpu ? checkList(arch, target.cpu) : true + const os = environment.os || currentEnv.os() + const cpu = environment.cpu || currentEnv.cpu() + const libc = environment.libc || currentEnv.libc(os) - if (!osOk || !cpuOk) { + const osOk = target.os ? checkList(os, target.os) : true + const cpuOk = target.cpu ? checkList(cpu, target.cpu) : true + let libcOk = target.libc ? checkList(libc, target.libc) : true + if (target.libc && !libc) { + libcOk = false + } + + if (!osOk || !cpuOk || !libcOk) { throw Object.assign(new Error('Unsupported platform'), { pkgid: target._id, current: { - os: platform, - cpu: arch, + os, + cpu, + libc, }, required: { os: target.os, cpu: target.cpu, + libc: target.libc, }, code: 'EBADPLATFORM', }) @@ -75,4 +85,6 @@ const checkList = (value, list) => { module.exports = { checkEngine, checkPlatform, + checkDevEngines, + currentEnv, } diff --git a/node_modules/npm-install-checks/package.json b/node_modules/npm-install-checks/package.json index ce33718514b4a..aae100c2d4f3c 100644 --- a/node_modules/npm-install-checks/package.json +++ b/node_modules/npm-install-checks/package.json @@ -1,32 +1,29 @@ { "name": "npm-install-checks", - "version": "5.0.0", + "version": "8.0.0", "description": "Check the engines and platform fields in package.json", "main": "lib/index.js", "dependencies": { "semver": "^7.1.1" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "scripts": { "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/npm-install-checks.git" + "url": "git+https://github.com/npm/npm-install-checks.git" }, "keywords": [ "npm,", @@ -38,11 +35,18 @@ "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.27.1", + "publish": "true" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/npm-normalize-package-bin/index.js b/node_modules/npm-normalize-package-bin/index.js deleted file mode 100644 index 5a738ff82e1e3..0000000000000 --- a/node_modules/npm-normalize-package-bin/index.js +++ /dev/null @@ -1,60 +0,0 @@ -// pass in a manifest with a 'bin' field here, and it'll turn it -// into a properly santized bin object -const {join, basename} = require('path') - -const normalize = pkg => - !pkg.bin ? removeBin(pkg) - : typeof pkg.bin === 'string' ? normalizeString(pkg) - : Array.isArray(pkg.bin) ? normalizeArray(pkg) - : typeof pkg.bin === 'object' ? normalizeObject(pkg) - : removeBin(pkg) - -const normalizeString = pkg => { - if (!pkg.name) - return removeBin(pkg) - pkg.bin = { [pkg.name]: pkg.bin } - return normalizeObject(pkg) -} - -const normalizeArray = pkg => { - pkg.bin = pkg.bin.reduce((acc, k) => { - acc[basename(k)] = k - return acc - }, {}) - return normalizeObject(pkg) -} - -const removeBin = pkg => { - delete pkg.bin - return pkg -} - -const normalizeObject = pkg => { - const orig = pkg.bin - const clean = {} - let hasBins = false - Object.keys(orig).forEach(binKey => { - const base = join('/', basename(binKey.replace(/\\|:/g, '/'))).substr(1) - - if (typeof orig[binKey] !== 'string' || !base) - return - - const binTarget = join('/', orig[binKey]) - .replace(/\\/g, '/').substr(1) - - if (!binTarget) - return - - clean[base] = binTarget - hasBins = true - }) - - if (hasBins) - pkg.bin = clean - else - delete pkg.bin - - return pkg -} - -module.exports = normalize diff --git a/node_modules/npm-normalize-package-bin/lib/index.js b/node_modules/npm-normalize-package-bin/lib/index.js new file mode 100644 index 0000000000000..3cb8478cf6e2f --- /dev/null +++ b/node_modules/npm-normalize-package-bin/lib/index.js @@ -0,0 +1,64 @@ +// pass in a manifest with a 'bin' field here, and it'll turn it +// into a properly santized bin object +const { join, basename } = require('path') + +const normalize = pkg => + !pkg.bin ? removeBin(pkg) + : typeof pkg.bin === 'string' ? normalizeString(pkg) + : Array.isArray(pkg.bin) ? normalizeArray(pkg) + : typeof pkg.bin === 'object' ? normalizeObject(pkg) + : removeBin(pkg) + +const normalizeString = pkg => { + if (!pkg.name) { + return removeBin(pkg) + } + pkg.bin = { [pkg.name]: pkg.bin } + return normalizeObject(pkg) +} + +const normalizeArray = pkg => { + pkg.bin = pkg.bin.reduce((acc, k) => { + acc[basename(k)] = k + return acc + }, {}) + return normalizeObject(pkg) +} + +const removeBin = pkg => { + delete pkg.bin + return pkg +} + +const normalizeObject = pkg => { + const orig = pkg.bin + const clean = {} + let hasBins = false + Object.keys(orig).forEach(binKey => { + const base = join('/', basename(binKey.replace(/\\|:/g, '/'))).slice(1) + + if (typeof orig[binKey] !== 'string' || !base) { + return + } + + const binTarget = join('/', orig[binKey].replace(/\\/g, '/')) + .replace(/\\/g, '/').slice(1) + + if (!binTarget) { + return + } + + clean[base] = binTarget + hasBins = true + }) + + if (hasBins) { + pkg.bin = clean + } else { + delete pkg.bin + } + + return pkg +} + +module.exports = normalize diff --git a/node_modules/npm-normalize-package-bin/package-lock.json b/node_modules/npm-normalize-package-bin/package-lock.json deleted file mode 100644 index 0d3390d4eee63..0000000000000 --- a/node_modules/npm-normalize-package-bin/package-lock.json +++ /dev/null @@ -1,3529 +0,0 @@ -{ - "name": "npm-normalize-package-bin", - "version": "1.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", - "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", - "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", - "dev": true - }, - "@babel/runtime": { - "version": "7.7.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.6.tgz", - "integrity": "sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", - "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "async-hook-domain": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-1.1.3.tgz", - "integrity": "sha512-ZovMxSbADV3+biB7oR1GL5lGyptI24alp0LWHlmz1OFc5oL47pz3EiIF6nXOkDW7yLqih4NtsiYduzdDW0i+Wg==", - "dev": true, - "requires": { - "source-map-support": "^0.5.11" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "bind-obj-methods": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" - }, - "dependencies": { - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "coveralls": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.9.tgz", - "integrity": "sha512-nNBg3B1+4iDox5A5zqHKzUTiwl2ey4k2o0NEcVZYvl+GOSJdKBj4AJGKLv6h3SvWch7tABHePAQOSZWM9E2hMg==", - "dev": true, - "requires": { - "js-yaml": "^3.13.1", - "lcov-parse": "^1.0.0", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.88.0" - } - }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - }, - "diff-frag": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/diff-frag/-/diff-frag-1.0.1.tgz", - "integrity": "sha512-6/v2PC/6UTGcWPPetb9acL8foberUg/CtPdALeJUdD1B/weHNvzftoo00gYznqHGRhHEbykUGzqfG9RWOSr5yw==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events-to-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "findit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", - "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", - "dev": true - }, - "flow-parser": { - "version": "0.113.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.113.0.tgz", - "integrity": "sha512-+hRyEB1sVLNMTMniDdM1JIS8BJ3HUL7IFIJaxX+t/JUy0GNYdI0Tg1QLx8DJmOF8HeoCrUDcREpnDAc/pPta3w==", - "dev": true - }, - "flow-remove-types": { - "version": "2.113.0", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.113.0.tgz", - "integrity": "sha512-Rp4hN/JlGmUjNxXuBXr6Or+MgDH9xKc+ZiUSRzl/fbpiH9RaCPAQKsgVEYNPcIE26q6RpAuMQfvzR0jQfuwUZQ==", - "dev": true, - "requires": { - "flow-parser": "^0.113.0", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - } - }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-exists-cached": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", - "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, - "optional": true - }, - "function-loop": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz", - "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-processinfo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-1.0.0.tgz", - "integrity": "sha512-FY0cPmWa4WoQNlvB8VOcafiRoB5nB+l2Pz2xGuXHRSy1KM8QFOYfz/rN+bGMCAeejrY3mrpF5oJHcN0s/garCg==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^6.0.5", - "istanbul-lib-coverage": "^2.0.3", - "rimraf": "^2.6.3", - "uuid": "^3.3.2" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", - "dev": true, - "requires": { - "handlebars": "^4.1.2" - } - }, - "jackspeak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", - "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", - "dev": true, - "requires": { - "cliui": "^4.1.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "dev": true, - "requires": { - "mime-db": "1.42.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "own-or": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", - "dev": true - }, - "own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", - "dev": true, - "requires": { - "own-or": "^1.0.0" - } - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "react": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", - "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - } - } - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - } - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tap": { - "version": "14.10.2", - "resolved": "https://registry.npmjs.org/tap/-/tap-14.10.2.tgz", - "integrity": "sha512-JeUDsVrMFmR6b3p9hO9yIT/jibrK6LI7nFza5cqDGsxJyCp7yU3enRgS5nekuoAOzewbrU7P+9QDRDT01urROA==", - "dev": true, - "requires": { - "async-hook-domain": "^1.1.3", - "bind-obj-methods": "^2.0.0", - "browser-process-hrtime": "^1.0.0", - "chokidar": "^3.3.0", - "color-support": "^1.1.0", - "coveralls": "^3.0.8", - "diff": "^4.0.1", - "esm": "^3.2.25", - "findit": "^2.0.0", - "flow-remove-types": "^2.112.0", - "foreground-child": "^1.3.3", - "fs-exists-cached": "^1.0.0", - "function-loop": "^1.0.2", - "glob": "^7.1.6", - "import-jsx": "^3.0.0", - "ink": "^2.5.0", - "isexe": "^2.0.0", - "istanbul-lib-processinfo": "^1.0.0", - "jackspeak": "^1.4.0", - "minipass": "^3.1.1", - "mkdirp": "^0.5.1", - "nyc": "^14.1.1", - "opener": "^1.5.1", - "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "react": "^16.12.0", - "rimraf": "^2.7.1", - "signal-exit": "^3.0.0", - "source-map-support": "^0.5.16", - "stack-utils": "^1.0.2", - "tap-mocha-reporter": "^5.0.0", - "tap-parser": "^10.0.1", - "tap-yaml": "^1.0.0", - "tcompare": "^3.0.0", - "treport": "^1.0.0", - "trivial-deferred": "^1.0.1", - "ts-node": "^8.5.2", - "typescript": "^3.7.2", - "which": "^2.0.2", - "write-file-atomic": "^3.0.1", - "yaml": "^1.7.2", - "yapool": "^1.0.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "bundled": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/parser": { - "version": "7.7.4", - "bundled": true, - "dev": true - }, - "@babel/template": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.7.2", - "bundled": true, - "requires": { - "@babel/types": "^7.7.2", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "bundled": true - } - } - }, - "@babel/helper-builder-react-jsx": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "esutils": "^2.0.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "bundled": true, - "dev": true - }, - "@babel/helpers": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - }, - "dependencies": { - "@babel/generator": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/parser": { - "version": "7.7.4", - "bundled": true, - "dev": true - }, - "@babel/template": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - } - } - }, - "@babel/highlight": { - "version": "7.5.0", - "bundled": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "js-tokens": { - "version": "4.0.0", - "bundled": true - } - } - }, - "@babel/parser": { - "version": "7.7.3", - "bundled": true - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.7.4" - } - }, - "@babel/runtime": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.7.0", - "bundled": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" - } - }, - "@babel/types": { - "version": "7.7.2", - "bundled": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "@types/prop-types": { - "version": "15.7.3", - "bundled": true, - "dev": true - }, - "@types/react": { - "version": "16.9.13", - "bundled": true, - "dev": true, - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" - } - }, - "ansi-escapes": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "auto-bind": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "@types/react": "^16.8.12" - } - }, - "caller-callsite": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cardinal": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, - "chalk": { - "version": "2.4.2", - "bundled": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "ci-info": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "slice-ansi": "^1.0.0", - "string-width": "^2.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "bundled": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true - }, - "csstype": { - "version": "2.6.7", - "bundled": true, - "dev": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "bundled": true, - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "esprima": { - "version": "4.0.1", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.3", - "bundled": true - }, - "events-to-array": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "globals": { - "version": "11.12.0", - "bundled": true, - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "bundled": true - }, - "import-jsx": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "@babel/core": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/plugin-transform-destructuring": "^7.5.0", - "@babel/plugin-transform-react-jsx": "^7.3.0", - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "ink": { - "version": "2.5.0", - "bundled": true, - "dev": true, - "requires": { - "@types/react": "^16.8.6", - "ansi-escapes": "^4.2.1", - "arrify": "^1.0.1", - "auto-bind": "^2.0.0", - "chalk": "^2.4.1", - "cli-cursor": "^2.1.0", - "cli-truncate": "^1.1.0", - "is-ci": "^2.0.0", - "lodash.throttle": "^4.1.1", - "log-update": "^3.0.0", - "prop-types": "^15.6.2", - "react-reconciler": "^0.21.0", - "scheduler": "^0.15.0", - "signal-exit": "^3.0.2", - "slice-ansi": "^1.0.0", - "string-length": "^2.0.0", - "widest-line": "^2.0.0", - "wrap-ansi": "^5.0.0", - "yoga-layout-prebuilt": "^1.9.3" - } - }, - "is-ci": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "bundled": true - }, - "json5": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "lodash": { - "version": "4.17.15", - "bundled": true - }, - "lodash.throttle": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "log-update": { - "version": "3.3.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "bundled": true, - "dev": true - } - } - }, - "loose-envify": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "onetime": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "path-parse": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "punycode": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "react-is": { - "version": "16.10.2", - "bundled": true, - "dev": true - }, - "react-reconciler": { - "version": "0.21.0", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.15.0" - } - }, - "redeyed": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "esprima": "~4.0.0" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "bundled": true, - "dev": true - }, - "resolve": { - "version": "1.12.0", - "bundled": true, - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "scheduler": { - "version": "0.15.0", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "bundled": true - }, - "string-length": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "bundled": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tap-parser": { - "version": "10.0.1", - "bundled": true, - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "minipass": "^3.0.0", - "tap-yaml": "^1.0.0" - } - }, - "tap-yaml": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "yaml": "^1.5.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "bundled": true - }, - "treport": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "cardinal": "^2.1.1", - "chalk": "^3.0.0", - "import-jsx": "^3.0.0", - "ink": "^2.5.0", - "ms": "^2.1.2", - "string-length": "^3.1.0", - "tap-parser": "^10.0.1", - "unicode-length": "^2.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "4.2.0", - "bundled": true, - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "string-length": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "unicode-length": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "punycode": "^2.0.0", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - } - } - }, - "type-fest": { - "version": "0.8.1", - "bundled": true, - "dev": true - }, - "widest-line": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yaml": { - "version": "1.7.2", - "bundled": true, - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } - }, - "yoga-layout-prebuilt": { - "version": "1.9.3", - "bundled": true, - "dev": true - } - } - }, - "tap-mocha-reporter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.0.tgz", - "integrity": "sha512-8HlAtdmYGlDZuW83QbF/dc46L7cN+AGhLZcanX3I9ILvxUAl+G2/mtucNPSXecTlG/4iP1hv6oMo0tMhkn3Tsw==", - "dev": true, - "requires": { - "color-support": "^1.1.0", - "debug": "^2.1.3", - "diff": "^1.3.2", - "escape-string-regexp": "^1.0.3", - "glob": "^7.0.5", - "readable-stream": "^2.1.5", - "tap-parser": "^10.0.0", - "tap-yaml": "^1.0.0", - "unicode-length": "^1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "tap-parser": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", - "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "minipass": "^3.0.0", - "tap-yaml": "^1.0.0" - } - }, - "tap-yaml": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", - "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", - "dev": true, - "requires": { - "yaml": "^1.5.0" - } - }, - "tcompare": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-3.0.4.tgz", - "integrity": "sha512-Q3TitMVK59NyKgQyFh+857wTAUE329IzLDehuPgU4nF5e8g+EUQ+yUbjUy1/6ugiNnXztphT+NnqlCXolv9P3A==", - "dev": true, - "requires": { - "diff-frag": "^1.0.1" - } - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "trivial-deferred": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", - "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", - "dev": true - }, - "ts-node": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz", - "integrity": "sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", - "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==", - "dev": true - }, - "uglify-js": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", - "integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - } - }, - "unicode-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", - "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", - "dev": true, - "requires": { - "punycode": "^1.3.2", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } - }, - "yapool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", - "dev": true - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/node_modules/npm-normalize-package-bin/package.json b/node_modules/npm-normalize-package-bin/package.json index a331a682e74e0..55dc65ad5ee92 100644 --- a/node_modules/npm-normalize-package-bin/package.json +++ b/node_modules/npm-normalize-package-bin/package.json @@ -1,21 +1,45 @@ { "name": "npm-normalize-package-bin", - "version": "1.0.1", + "version": "5.0.0", "description": "Turn any flavor of allowable package.json bin into a normalized object", - "repository": "git+https://github.com/npm/npm-normalize-package-bin", - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", + "main": "lib/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/npm-normalize-package-bin.git" + }, + "author": "GitHub Inc.", "license": "ISC", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { - "tap": "^14.10.2" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" + }, + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": "true" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/npm-normalize-package-bin/test/array.js b/node_modules/npm-normalize-package-bin/test/array.js deleted file mode 100644 index 63dafa8913741..0000000000000 --- a/node_modules/npm-normalize-package-bin/test/array.js +++ /dev/null @@ -1,37 +0,0 @@ -const normalize = require('../') -const t = require('tap') - -t.test('benign array', async t => { - const pkg = { name: 'hello', version: 'world', bin: ['./x/y', 'y/z', './a'] } - const expect = { name: 'hello', version: 'world', bin: { - y: 'x/y', - z: 'y/z', - a: 'a', - } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('conflicting array', async t => { - const pkg = { name: 'hello', version: 'world', bin: ['./x/y', 'z/y', './a'] } - const expect = { name: 'hello', version: 'world', bin: { - y: 'z/y', - a: 'a', - } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('slashy array', async t => { - const pkg = { name: 'hello', version: 'world', bin: [ '/etc/passwd' ] } - const expect = { name: 'hello', version: 'world', bin: { passwd: 'etc/passwd' } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('dotty array', async t => { - const pkg = { name: 'hello', version: 'world', bin: ['../../../../etc/passwd'] } - const expect = { name: 'hello', version: 'world', bin: { passwd: 'etc/passwd' } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) diff --git a/node_modules/npm-normalize-package-bin/test/nobin.js b/node_modules/npm-normalize-package-bin/test/nobin.js deleted file mode 100644 index 536d7eb22f68a..0000000000000 --- a/node_modules/npm-normalize-package-bin/test/nobin.js +++ /dev/null @@ -1,35 +0,0 @@ -const normalize = require('../') -const t = require('tap') - -// all of these just delete the bins, so expect the same value -const expect = { name: 'hello', version: 'world' } - -t.test('no bin in object', async t => { - const pkg = { name: 'hello', version: 'world' } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('empty string bin in object', async t => { - const pkg = { name: 'hello', version: 'world', bin: '' } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('false bin in object', async t => { - const pkg = { name: 'hello', version: 'world', bin: false } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('null bin in object', async t => { - const pkg = { name: 'hello', version: 'world', bin: null } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('number bin', async t => { - const pkg = { name: 'hello', version: 'world', bin: 42069 } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) diff --git a/node_modules/npm-normalize-package-bin/test/object.js b/node_modules/npm-normalize-package-bin/test/object.js deleted file mode 100644 index 00d23684fb75b..0000000000000 --- a/node_modules/npm-normalize-package-bin/test/object.js +++ /dev/null @@ -1,141 +0,0 @@ -const normalize = require('../') -const t = require('tap') - -t.test('benign object', async t => { - // just clean up the ./ in the targets and remove anything weird - const pkg = { name: 'hello', version: 'world', bin: { - y: './x/y', - z: './y/z', - a: './a', - } } - const expect = { name: 'hello', version: 'world', bin: { - y: 'x/y', - z: 'y/z', - a: 'a', - } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('empty and non-string targets', async t => { - // just clean up the ./ in the targets and remove anything weird - const pkg = { name: 'hello', version: 'world', bin: { - z: './././', - y: '', - './x': 'x.js', - re: /asdf/, - foo: { bar: 'baz' }, - false: false, - null: null, - array: [1,2,3], - func: function () {}, - } } - const expect = { name: 'hello', version: 'world', bin: { - x: 'x.js', - } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('slashy object', async t => { - const pkg = { name: 'hello', version: 'world', bin: { - '/path/foo': '/etc/passwd', - 'bar': '/etc/passwd', - '/etc/glorb/baz': '/etc/passwd', - '/etc/passwd:/bin/usr/exec': '/etc/passwd', - } } - const expect = { - name: 'hello', - version: 'world', - bin: { - foo: 'etc/passwd', - bar: 'etc/passwd', - baz: 'etc/passwd', - exec: 'etc/passwd', - } - } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('dotty object', async t => { - const pkg = { - name: 'hello', - version: 'world', - bin: { - 'nodots': '../../../../etc/passwd', - '../../../../../../dots': '../../../../etc/passwd', - '.././../\\./..//C:\\./': 'this is removed', - '.././../\\./..//C:\\/': 'super safe programming language', - '.././../\\./..//C:\\x\\y\\z/': 'xyz', - } } - const expect = { name: 'hello', version: 'world', bin: { - nodots: 'etc/passwd', - dots: 'etc/passwd', - C: 'super safe programming language', - z: 'xyz', - } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('weird object', async t => { - const pkg = { name: 'hello', version: 'world', bin: /asdf/ } - const expect = { name: 'hello', version: 'world' } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('oddball keys', async t => { - const pkg = { - bin: { - '~': 'target', - '£': 'target', - 'ζ': 'target', - 'ぎ': 'target', - '操': 'target', - '🎱': 'target', - '💎': 'target', - '💸': 'target', - '🦉': 'target', - 'сheck-dom': 'target', - 'Ωpm': 'target', - 'ζλ': 'target', - 'мга': 'target', - 'пше': 'target', - 'тзч': 'target', - 'тзь': 'target', - 'нфкт': 'target', - 'ссср': 'target', - '君の名は': 'target', - '君の名は': 'target', - } - } - - const expect = { - bin: { - '~': 'target', - '£': 'target', - 'ζ': 'target', - 'ぎ': 'target', - '操': 'target', - '🎱': 'target', - '💎': 'target', - '💸': 'target', - '🦉': 'target', - 'сheck-dom': 'target', - 'Ωpm': 'target', - 'ζλ': 'target', - 'мга': 'target', - 'пше': 'target', - 'тзч': 'target', - 'тзь': 'target', - 'нфкт': 'target', - 'ссср': 'target', - '君の名は': 'target', - }, - } - - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) diff --git a/node_modules/npm-normalize-package-bin/test/string.js b/node_modules/npm-normalize-package-bin/test/string.js deleted file mode 100644 index b6de8f8f589b5..0000000000000 --- a/node_modules/npm-normalize-package-bin/test/string.js +++ /dev/null @@ -1,37 +0,0 @@ -const normalize = require('../') -const t = require('tap') - -t.test('benign string', async t => { - const pkg = { name: 'hello', version: 'world', bin: 'hello.js' } - const expect = { name: 'hello', version: 'world', bin: { hello: 'hello.js' } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('slashy string', async t => { - const pkg = { name: 'hello', version: 'world', bin: '/etc/passwd' } - const expect = { name: 'hello', version: 'world', bin: { hello: 'etc/passwd' } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('dotty string', async t => { - const pkg = { name: 'hello', version: 'world', bin: '../../../../etc/passwd' } - const expect = { name: 'hello', version: 'world', bin: { hello: 'etc/passwd' } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('double path', async t => { - const pkg = { name: 'hello', version: 'world', bin: '/etc/passwd:/bin/usr/exec' } - const expect = { name: 'hello', version: 'world', bin: { hello: 'etc/passwd:/bin/usr/exec' } } - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) - -t.test('string with no name', async t => { - const pkg = { bin: 'foobar.js' } - const expect = {} - t.strictSame(normalize(pkg), expect) - t.strictSame(normalize(normalize(pkg)), expect, 'double sanitize ok') -}) diff --git a/node_modules/npm-package-arg/lib/npa.js b/node_modules/npm-package-arg/lib/npa.js index 61fee0783ecc7..a25c0a5368941 100644 --- a/node_modules/npm-package-arg/lib/npa.js +++ b/node_modules/npm-package-arg/lib/npa.js @@ -1,21 +1,24 @@ 'use strict' -module.exports = npa -module.exports.resolve = resolve -module.exports.Result = Result -const url = require('url') +const isWindows = process.platform === 'win32' + +const { URL } = require('node:url') +// We need to use path/win32 so that we get consistent results in tests, but this also means we need to manually convert backslashes to forward slashes when generating file: urls with paths. +const path = isWindows ? require('node:path/win32') : require('node:path') +const { homedir } = require('node:os') const HostedGit = require('hosted-git-info') 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 ? /\\|[/]/ : /[/]/ const isURL = /^(?:git[+])?[a-z]+:/i const isGit = /^[^@]+@[^:.]+\.[^:]+:.+$/i -const isFilename = /[.](?:tgz|tar.gz|tar)$/i +const isFileType = /[.](?:tgz|tar\.gz|tar)$/i +const isPortNumber = /:[0-9]+(\/|$)/i +const isWindowsFile = /^(?:[.]|~[/]|[/\\]|[a-zA-Z]:)/ +const isPosixFile = /^(?:[.]|~[/]|[/]|[a-zA-Z]:)/ +const defaultRegistry = 'https://registry.npmjs.org' function npa (arg, where) { let name @@ -29,21 +32,23 @@ function npa (arg, where) { return npa(arg.raw, where || arg.where) } } - const nameEndsAt = arg[0] === '@' ? arg.slice(1).indexOf('@') + 1 : arg.indexOf('@') + const nameEndsAt = arg.indexOf('@', 1) // Skip possible leading @ const namePart = nameEndsAt > 0 ? arg.slice(0, nameEndsAt) : arg if (isURL.test(arg)) { spec = arg } else if (isGit.test(arg)) { spec = `git+ssh://${arg}` - } else if (namePart[0] !== '@' && (hasSlashes.test(namePart) || isFilename.test(namePart))) { + // eslint-disable-next-line max-len + } else if (!namePart.startsWith('@') && (hasSlashes.test(namePart) || isFileType.test(namePart))) { spec = arg } else if (nameEndsAt > 0) { name = namePart - spec = arg.slice(nameEndsAt + 1) + spec = arg.slice(nameEndsAt + 1) || '*' } else { const valid = validatePackageName(arg) if (valid.validForOldPackages) { name = arg + spec = '*' } else { spec = arg } @@ -51,7 +56,25 @@ function npa (arg, where) { return resolve(name, spec, where, arg) } -const isFilespec = isWindows ? /^(?:[.]|~[/]|[/\\]|[a-zA-Z]:)/ : /^(?:[.]|~[/]|[/]|[a-zA-Z]:)/ +function isFileSpec (spec) { + if (!spec) { + return false + } + if (spec.toLowerCase().startsWith('file:')) { + return true + } + if (isWindows) { + return isWindowsFile.test(spec) + } + return isPosixFile.test(spec) +} + +function isAliasSpec (spec) { + if (!spec) { + return false + } + return spec.toLowerCase().startsWith('npm:') +} function resolve (name, spec, where, arg) { const res = new Result({ @@ -62,12 +85,16 @@ function resolve (name, spec, where, arg) { }) if (name) { - res.setName(name) + res.name = name + } + + if (!where) { + where = process.cwd() } - if (spec && (isFilespec.test(spec) || /^file:/i.test(spec))) { + if (isFileSpec(spec)) { return fromFile(res, where) - } else if (spec && /^npm:/i.test(spec)) { + } else if (isAliasSpec(spec)) { return fromAlias(res, where) } @@ -79,13 +106,29 @@ function resolve (name, spec, where, arg) { return fromHostedGit(res, hosted) } else if (spec && isURL.test(spec)) { return fromURL(res) - } else if (spec && (hasSlashes.test(spec) || isFilename.test(spec))) { + } else if (spec && (hasSlashes.test(spec) || isFileType.test(spec))) { return fromFile(res, where) } else { return fromRegistry(res) } } +function toPurl (arg, reg = defaultRegistry) { + const res = npa(arg) + + if (res.type !== 'version') { + throw invalidPurlType(res.type, res.raw) + } + + // URI-encode leading @ of scoped packages + let purl = 'pkg:npm/' + res.name.replace(/^@/, '%40') + '@' + res.rawSpec + if (reg !== defaultRegistry) { + purl += '?repository_url=' + reg + } + + return purl +} + function invalidPackageName (name, valid, raw) { // eslint-disable-next-line max-len const err = new Error(`Invalid package name "${name}" of package "${raw}": ${valid.errors.join('; ')}.`) @@ -100,66 +143,76 @@ function invalidTagName (name, raw) { return err } -function Result (opts) { - this.type = opts.type - this.registry = opts.registry - this.where = opts.where - if (opts.raw == null) { - this.raw = opts.name ? opts.name + '@' + opts.rawSpec : opts.rawSpec - } else { - this.raw = opts.raw - } - - this.name = undefined - this.escapedName = undefined - this.scope = undefined - this.rawSpec = opts.rawSpec == null ? '' : opts.rawSpec - this.saveSpec = opts.saveSpec - this.fetchSpec = opts.fetchSpec - if (opts.name) { - this.setName(opts.name) - } - this.gitRange = opts.gitRange - this.gitCommittish = opts.gitCommittish - this.gitSubdir = opts.gitSubdir - this.hosted = opts.hosted +function invalidPurlType (type, raw) { + // eslint-disable-next-line max-len + const err = new Error(`Invalid type "${type}" of package "${raw}": Purl can only be generated for "version" types.`) + err.code = 'EINVALIDPURLTYPE' + return err } -Result.prototype.setName = function (name) { - const valid = validatePackageName(name) - if (!valid.validForOldPackages) { - throw invalidPackageName(name, valid, this.raw) +class Result { + constructor (opts) { + this.type = opts.type + this.registry = opts.registry + this.where = opts.where + if (opts.raw == null) { + this.raw = opts.name ? `${opts.name}@${opts.rawSpec}` : opts.rawSpec + } else { + this.raw = opts.raw + } + this.name = undefined + this.escapedName = undefined + this.scope = undefined + this.rawSpec = opts.rawSpec || '' + this.saveSpec = opts.saveSpec + this.fetchSpec = opts.fetchSpec + if (opts.name) { + this.setName(opts.name) + } + this.gitRange = opts.gitRange + this.gitCommittish = opts.gitCommittish + this.gitSubdir = opts.gitSubdir + this.hosted = opts.hosted } - this.name = name - this.scope = name[0] === '@' ? name.slice(0, name.indexOf('/')) : undefined - // scoped packages in couch must have slash url-encoded, e.g. @foo%2Fbar - this.escapedName = name.replace('/', '%2f') - return this -} + // TODO move this to a getter/setter in a semver major + setName (name) { + const valid = validatePackageName(name) + if (!valid.validForOldPackages) { + throw invalidPackageName(name, valid, this.raw) + } -Result.prototype.toString = function () { - const full = [] - if (this.name != null && this.name !== '') { - full.push(this.name) + this.name = name + this.scope = name[0] === '@' ? name.slice(0, name.indexOf('/')) : undefined + // scoped packages in couch must have slash url-encoded, e.g. @foo%2Fbar + this.escapedName = name.replace('/', '%2f') + return this } - const spec = this.saveSpec || this.fetchSpec || this.rawSpec - if (spec != null && spec !== '') { - full.push(spec) + + toString () { + const full = [] + if (this.name != null && this.name !== '') { + full.push(this.name) + } + const spec = this.saveSpec || this.fetchSpec || this.rawSpec + if (spec != null && spec !== '') { + full.push(spec) + } + return full.length ? full.join('@') : this.raw } - return full.length ? full.join('@') : this.raw -} -Result.prototype.toJSON = function () { - const result = Object.assign({}, this) - delete result.hosted - return result + toJSON () { + const result = Object.assign({}, this) + delete result.hosted + return result + } } -function setGitCommittish (res, committish) { +// sets res.gitCommittish, res.gitRange, and res.gitSubdir +function setGitAttrs (res, committish) { if (!committish) { res.gitCommittish = null - return res + return } // for each :: separated item: @@ -197,31 +250,71 @@ function setGitCommittish (res, committish) { } log.warn('npm-package-arg', `ignoring unknown key "${name}"`) } +} - return res +// Taken from: EncodePathChars and lookup_table in src/node_url.cc +// url.pathToFileURL only returns absolute references. We can't use it to encode paths. +// encodeURI mangles windows paths. We can't use it to encode paths. +// Under the hood, url.pathToFileURL does a limited set of encoding, with an extra windows step, and then calls path.resolve. +// The encoding node does without path.resolve is not available outside of the source, so we are recreating it here. +const encodedPathChars = new Map([ + ['\0', '%00'], + ['\t', '%09'], + ['\n', '%0A'], + ['\r', '%0D'], + [' ', '%20'], + ['"', '%22'], + ['#', '%23'], + ['%', '%25'], + ['?', '%3F'], + ['[', '%5B'], + ['\\', isWindows ? '/' : '%5C'], + [']', '%5D'], + ['^', '%5E'], + ['|', '%7C'], + ['~', '%7E'], +]) + +function pathToFileURL (str) { + let result = '' + for (let i = 0; i < str.length; i++) { + result = `${result}${encodedPathChars.get(str[i]) ?? str[i]}` + } + if (result.startsWith('file:')) { + return result + } + return `file:${result}` } function fromFile (res, where) { - if (!where) { - where = process.cwd() - } - res.type = isFilename.test(res.rawSpec) ? 'file' : 'directory' + res.type = isFileType.test(res.rawSpec) ? 'file' : 'directory' res.where = where - // always put the '/' on where when resolving urls, or else - // file:foo from /path/to/bar goes to /path/to/foo, when we want - // it to be /path/to/bar/foo + let rawSpec = pathToFileURL(res.rawSpec) + + if (rawSpec.startsWith('file:/')) { + // XXX backwards compatibility lack of compliance with RFC 8089 + + // turn file://path into file:/path + if (/^file:\/\/[^/]/.test(rawSpec)) { + rawSpec = `file:/${rawSpec.slice(5)}` + } + + // turn file:/../path into file:../path + // for 1 or 3 leading slashes (2 is already ruled out from handling file:// explicitly above) + if (/^\/{1,3}\.\.?(\/|$)/.test(rawSpec.slice(5))) { + rawSpec = rawSpec.replace(/^file:\/{1,3}/, 'file:') + } + } - let specUrl let resolvedUrl - const prefix = (!/^file:/.test(res.rawSpec) ? 'file:' : '') - const rawWithPrefix = prefix + res.rawSpec - let rawNoPrefix = rawWithPrefix.replace(/^file:/, '') + let specUrl try { - resolvedUrl = new url.URL(rawWithPrefix, `file://${path.resolve(where)}/`) - specUrl = new url.URL(rawWithPrefix) + // always put the '/' on "where", or else file:foo from /path/to/bar goes to /path/to/foo, when we want it to be /path/to/bar/foo + resolvedUrl = new URL(rawSpec, `${pathToFileURL(path.resolve(where))}/`) + specUrl = new URL(rawSpec) } catch (originalError) { - const er = new Error('Invalid file: URL, must comply with RFC 8909') + const er = new Error('Invalid file: URL, must comply with RFC 8089') throw Object.assign(er, { raw: res.rawSpec, spec: res, @@ -230,39 +323,6 @@ function fromFile (res, where) { }) } - // environment switch for testing - if (process.env.NPM_PACKAGE_ARG_8909_STRICT !== '1') { - // XXX backwards compatibility lack of compliance with 8909 - // Remove when we want a breaking change to come into RFC compliance. - if (resolvedUrl.host && resolvedUrl.host !== 'localhost') { - const rawSpec = res.rawSpec.replace(/^file:\/\//, 'file:///') - resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`) - specUrl = new url.URL(rawSpec) - rawNoPrefix = rawSpec.replace(/^file:/, '') - } - // turn file:/../foo into file:../foo - if (/^\/\.\.?(\/|$)/.test(rawNoPrefix)) { - const rawSpec = res.rawSpec.replace(/^file:\//, 'file:') - resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`) - specUrl = new url.URL(rawSpec) - rawNoPrefix = rawSpec.replace(/^file:/, '') - } - // XXX end 8909 violation backwards compatibility section - } - - // file:foo - relative url to ./foo - // file:/foo - absolute path /foo - // file:///foo - absolute path to /foo, no authority host - // file://localhost/foo - absolute path to /foo, on localhost - // file://foo - absolute path to / on foo host (error!) - if (resolvedUrl.host && resolvedUrl.host !== 'localhost') { - const msg = `Invalid file: URL, must be absolute if // present` - throw Object.assign(new Error(msg), { - raw: res.rawSpec, - parsed: resolvedUrl, - }) - } - // turn /C:/blah into just C:/blah on windows let specPath = decodeURIComponent(specUrl.pathname) let resolvedPath = decodeURIComponent(resolvedUrl.pathname) @@ -276,13 +336,21 @@ function fromFile (res, where) { if (/^\/~(\/|$)/.test(specPath)) { res.saveSpec = `file:${specPath.substr(1)}` resolvedPath = path.resolve(homedir(), specPath.substr(3)) - } else if (!path.isAbsolute(rawNoPrefix)) { + } else if (!path.isAbsolute(rawSpec.slice(5))) { res.saveSpec = `file:${path.relative(where, resolvedPath)}` } else { res.saveSpec = `file:${path.resolve(resolvedPath)}` } res.fetchSpec = path.resolve(where, resolvedPath) + // re-normalize the slashes in saveSpec due to node:path/win32 behavior in windows + res.saveSpec = res.saveSpec.split('\\').join('/') + // Ignoring because this only happens in windows + /* istanbul ignore next */ + if (res.saveSpec.startsWith('file://')) { + // normalization of \\win32\root paths can cause a double / which we don't want + res.saveSpec = `file:/${res.saveSpec.slice(7)}` + } return res } @@ -291,7 +359,8 @@ function fromHostedGit (res, hosted) { res.hosted = hosted res.saveSpec = hosted.toString({ noGitPlus: false, noCommittish: false }) res.fetchSpec = hosted.getDefaultRepresentation() === 'shortcut' ? null : hosted.toString() - return setGitCommittish(res, hosted.committish) + setGitAttrs(res, hosted.committish) + return res } function unsupportedURLType (protocol, spec) { @@ -300,54 +369,53 @@ function unsupportedURLType (protocol, spec) { return err } -function matchGitScp (spec) { - // git ssh specifiers are overloaded to also use scp-style git - // specifiers, so we have to parse those out and treat them special. - // They are NOT true URIs, so we can't hand them to `url.parse`. - // - // This regex looks for things that look like: - // git+ssh://git@my.custom.git.com:username/project.git#deadbeef - // - // ...and various combinations. The username in the beginning is *required*. - const matched = spec.match(/^git\+ssh:\/\/([^:#]+:[^#]+(?:\.git)?)(?:#(.*))?$/i) - return matched && !matched[1].match(/:[0-9]+\/?.*$/i) && { - fetchSpec: matched[1], - gitCommittish: matched[2] == null ? null : matched[2], - } -} - function fromURL (res) { - // eslint-disable-next-line node/no-deprecated-api - const urlparse = url.parse(res.rawSpec) - res.saveSpec = res.rawSpec + let rawSpec = res.rawSpec + res.saveSpec = rawSpec + if (rawSpec.startsWith('git+ssh:')) { + // git ssh specifiers are overloaded to also use scp-style git + // specifiers, so we have to parse those out and treat them special. + // They are NOT true URIs, so we can't hand them to URL. + + // This regex looks for things that look like: + // git+ssh://git@my.custom.git.com:username/project.git#deadbeef + // ...and various combinations. The username in the beginning is *required*. + const matched = rawSpec.match(/^git\+ssh:\/\/([^:#]+:[^#]+(?:\.git)?)(?:#(.*))?$/i) + // Filter out all-number "usernames" which are really port numbers + // They can either be :1234 :1234/ or :1234/path but not :12abc + if (matched && !matched[1].match(isPortNumber)) { + res.type = 'git' + setGitAttrs(res, matched[2]) + res.fetchSpec = matched[1] + return res + } + } else if (rawSpec.startsWith('git+file://')) { + // URL can't handle windows paths + rawSpec = rawSpec.replace(/\\/g, '/') + } + const parsedUrl = new URL(rawSpec) // check the protocol, and then see if it's git or not - switch (urlparse.protocol) { + switch (parsedUrl.protocol) { case 'git:': case 'git+http:': case 'git+https:': case 'git+rsync:': case 'git+ftp:': case 'git+file:': - case 'git+ssh:': { + case 'git+ssh:': res.type = 'git' - const match = urlparse.protocol === 'git+ssh:' ? matchGitScp(res.rawSpec) - : null - if (match) { - setGitCommittish(res, match.gitCommittish) - res.fetchSpec = match.fetchSpec + setGitAttrs(res, parsedUrl.hash.slice(1)) + if (parsedUrl.protocol === 'git+file:' && /^git\+file:\/\/[a-z]:/i.test(rawSpec)) { + // URL can't handle drive letters on windows file paths, the host can't contain a : + res.fetchSpec = `git+file://${parsedUrl.host.toLowerCase()}:${parsedUrl.pathname}` } else { - setGitCommittish(res, urlparse.hash != null ? urlparse.hash.slice(1) : '') - urlparse.protocol = urlparse.protocol.replace(/^git[+]/, '') - if (urlparse.protocol === 'file:' && /^git\+file:\/\/[a-z]:/i.test(res.rawSpec)) { - // keep the drive letter : on windows file paths - urlparse.host += ':' - urlparse.hostname += ':' - } - delete urlparse.hash - res.fetchSpec = url.format(urlparse) + parsedUrl.hash = '' + res.fetchSpec = parsedUrl.toString() + } + if (res.fetchSpec.startsWith('git+')) { + res.fetchSpec = res.fetchSpec.slice(4) } break - } case 'http:': case 'https:': res.type = 'remote' @@ -355,7 +423,7 @@ function fromURL (res) { break default: - throw unsupportedURLType(urlparse.protocol, res.rawSpec) + throw unsupportedURLType(parsedUrl.protocol, rawSpec) } return res @@ -371,6 +439,10 @@ function fromAlias (res, where) { throw new Error('aliases only work for registry deps') } + if (!subSpec.name) { + throw new Error('aliases must have a name') + } + res.subSpec = subSpec res.registry = true res.type = 'alias' @@ -381,7 +453,7 @@ function fromAlias (res, where) { function fromRegistry (res) { res.registry = true - const spec = res.rawSpec === '' ? 'latest' : res.rawSpec.trim() + const spec = res.rawSpec.trim() // no save spec for registry components as we save based on the fetched // version, not on the argument so this can't compute that. res.saveSpec = null @@ -400,3 +472,8 @@ function fromRegistry (res) { } return res } + +module.exports = npa +module.exports.resolve = resolve +module.exports.toPurl = toPurl +module.exports.Result = Result diff --git a/node_modules/npm-package-arg/package.json b/node_modules/npm-package-arg/package.json index b9729db5d4f14..2e2d027f05582 100644 --- a/node_modules/npm-package-arg/package.json +++ b/node_modules/npm-package-arg/package.json @@ -1,6 +1,6 @@ { "name": "npm-package-arg", - "version": "9.1.0", + "version": "13.0.2", "description": "Parse the things that can be arguments to `npm install`", "main": "./lib/npa.js", "directories": { @@ -11,33 +11,31 @@ "lib/" ], "dependencies": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" + "validate-npm-package-name": "^7.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", "tap": "^16.0.1" }, "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "test": "tap", "snap": "tap", "npmclilint": "npmcli-lint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", "postsnap": "npm run lintfix --", "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/npm-package-arg.git" + "url": "git+https://github.com/npm/npm-package-arg.git" }, "author": "GitHub Inc.", "license": "ISC", @@ -46,13 +44,17 @@ }, "homepage": "https://github.com/npm/npm-package-arg", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "tap": { - "branches": 97 + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.28.0", + "publish": true } } diff --git a/node_modules/npm-packlist/bin/index.js b/node_modules/npm-packlist/bin/index.js deleted file mode 100755 index 48a6b879aa823..0000000000000 --- a/node_modules/npm-packlist/bin/index.js +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env node -'use strict' - -const packlist = require('../') - -const dirs = [] -let doSort = false -process.argv.slice(2).forEach(arg => { - if (arg === '-h' || arg === '--help') { - console.log('usage: npm-packlist [-s --sort] [directory, directory, ...]') - process.exit(0) - } else if (arg === '-s' || arg === '--sort') { - doSort = true - } else { - dirs.push(arg) - } -}) - -const sort = list => doSort ? list.sort((a, b) => a.localeCompare(b, 'en')) : list - -const main = async () => { - if (!dirs.length) { - const results = await packlist({ path: process.cwd() }) - console.log(sort(results).join('\n')) - } else { - for (const dir of dirs) { - console.group(`> ${dir}`) - const results = await packlist({ path: dir }) - console.log(sort(results).join('\n')) - console.groupEnd() - } - } -} - -// coverage disabled for catch handler because we don't need to test that -main().catch(/* istanbul ignore next */(err) => { - process.exitCode = 1 - console.error(err.stack) -}) diff --git a/node_modules/npm-packlist/lib/index.js b/node_modules/npm-packlist/lib/index.js index bd72329f027e6..ada704de4575d 100644 --- a/node_modules/npm-packlist/lib/index.js +++ b/node_modules/npm-packlist/lib/index.js @@ -1,87 +1,19 @@ 'use strict' -// Do a two-pass walk, first to get the list of packages that need to be -// bundled, then again to get the actual files and folders. -// Keep a cache of node_modules content and package.json data, so that the -// second walk doesn't have to re-do all the same work. +const { Walker: IgnoreWalker } = require('ignore-walk') +const { lstatSync: lstat, readFileSync: readFile } = require('fs') +const { basename, dirname, extname, join, relative, resolve, sep } = require('path') +const { log } = require('proc-log') -const bundleWalk = require('npm-bundled') -const BundleWalker = bundleWalk.BundleWalker +// symbols used to represent synthetic rule sets +const defaultRules = Symbol('npm-packlist.rules.default') +const strictRules = Symbol('npm-packlist.rules.strict') -const ignoreWalk = require('ignore-walk') -const IgnoreWalker = ignoreWalk.Walker - -const rootBuiltinRules = Symbol('root-builtin-rules') -const packageNecessaryRules = Symbol('package-necessary-rules') -const path = require('path') - -const normalizePackageBin = require('npm-normalize-package-bin') - -// Weird side-effect of this: a readme (etc) file will be included -// if it exists anywhere within a folder with a package.json file. -// The original intent was only to include these files in the root, -// but now users in the wild are dependent on that behavior for -// localized documentation and other use cases. Adding a `/` to -// these rules, while tempting and arguably more "correct", is a -// significant change that will break existing use cases. -const packageMustHaveFileNames = 'readme|copying|license|licence' - -const packageMustHaves = `@(${packageMustHaveFileNames}){,.*[^~$]}` -const packageMustHavesRE = new RegExp(`^(${packageMustHaveFileNames})(\\..*[^~$])?$`, 'i') - -const fs = require('fs') -const glob = require('glob') -const globify = pattern => pattern.split('\\').join('/') - -const readOutOfTreeIgnoreFiles = (root, rel, result = '') => { - for (const file of ['.npmignore', '.gitignore']) { - try { - const ignoreContent = fs.readFileSync(path.join(root, file), { encoding: 'utf8' }) - result += ignoreContent + '\n' - // break the loop immediately after concatting, this allows us to prioritize the - // .npmignore and discard the .gitignore if one exists - break - } catch (err) { - // we ignore ENOENT errors completely because we don't care if the file doesn't exist - // but we throw everything else because failing to read a file that does exist is - // something that the user likely wants to know about. we don't need to test this. - /* istanbul ignore next */ - if (err.code !== 'ENOENT') { - throw err - } - } - } - - if (!rel) { - return result - } - - const firstRel = rel.split(path.sep)[0] - const newRoot = path.join(root, firstRel) - const newRel = path.relative(newRoot, path.join(root, rel)) - - return readOutOfTreeIgnoreFiles(newRoot, newRel, result) -} - -const pathHasPkg = (input) => { - if (!input.startsWith('node_modules/')) { - return false - } - - const segments = input.slice('node_modules/'.length).split('/', 2) - return segments[0].startsWith('@') - ? segments.length === 2 - : true -} - -const pkgFromPath = (input) => { - const segments = input.slice('node_modules/'.length).split('/', 2) - return segments[0].startsWith('@') - ? segments.join('/') - : segments[0] -} +// There may be others, but :?|<> are handled by node-tar +const nameIsBadForWindows = file => /\*/.test(file) -const defaultRules = [ +// these are the default rules that are applied to everything except for non-link bundled deps +const defaults = [ '.npmignore', '.gitignore', '**/.git', @@ -103,410 +35,430 @@ const defaultRules = [ '._*', '**/._*/**', '*.orig', - '/package-lock.json', - '/yarn.lock', - '/pnpm-lock.yaml', '/archived-packages/**', ] -// There may be others, but :?|<> are handled by node-tar -const nameIsBadForWindows = file => /\*/.test(file) +const strictDefaults = [ + // these are forcibly excluded + '/.git', +] -class Walker extends IgnoreWalker { - constructor (opt) { - opt = opt || {} - - // the order in which rules are applied. - opt.ignoreFiles = [ - rootBuiltinRules, - 'package.json', - '.npmignore', - '.gitignore', - packageNecessaryRules, - ] +const normalizePath = (path) => path.split('\\').join('/') - opt.includeEmpty = false - opt.path = opt.path || process.cwd() - - // only follow links in the root node_modules folder, because if those - // folders are included, it's because they're bundled, and bundles - // should include the contents, not the symlinks themselves. - // This regexp tests to see that we're either a node_modules folder, - // or a @scope within a node_modules folder, in the root's node_modules - // hierarchy (ie, not in test/foo/node_modules/ or something). - const followRe = /^(?:\/node_modules\/(?:@[^/]+\/[^/]+|[^/]+)\/)*\/node_modules(?:\/@[^/]+)?$/ - const rootPath = opt.parent ? opt.parent.root : opt.path - const followTestPath = opt.path.replace(/\\/g, '/').slice(rootPath.length) - opt.follow = followRe.test(followTestPath) - - super(opt) - - // ignore a bunch of things by default at the root level. - // also ignore anything in the main project node_modules hierarchy, - // except bundled dependencies - if (this.isProject) { - this.bundled = opt.bundled || [] - this.bundledScopes = Array.from(new Set( - this.bundled.filter(f => /^@/.test(f)) - .map(f => f.split('/')[0]))) - this.packageJsonCache = this.parent ? this.parent.packageJsonCache - : (opt.packageJsonCache || new Map()) - let rules = defaultRules.join('\n') + '\n' - - if (opt.prefix && opt.workspaces) { - const gPath = globify(opt.path) - const gPrefix = globify(opt.prefix) - const gWorkspaces = opt.workspaces.map((ws) => globify(ws)) - // if opt.path and opt.prefix are not the same directory, and opt.workspaces has opt.path - // in it, then we know that opt.path is a workspace directory. in order to not drop ignore - // rules from directories between the workspace root (opt.prefix) and the workspace itself - // (opt.path), we need to find and read those now - /* istanbul ignore else */ - if (gPath !== gPrefix && gWorkspaces.includes(gPath)) { - // relpath is the relative path between the prefix and the parent of opt.path - // we use the parent because ignore-walk will read the files in opt.path already - const relpath = path.relative(opt.prefix, path.dirname(opt.path)) - rules += readOutOfTreeIgnoreFiles(opt.prefix, relpath) - } else if (gPath === gPrefix) { - // on the other hand, if the path and the prefix are the same, then we ignore workspaces - // so that we don't pack workspaces inside of a root project - rules += opt.workspaces.map((ws) => globify(path.relative(opt.path, ws))).join('\n') - } +const readOutOfTreeIgnoreFiles = (root, rel, result = []) => { + for (const file of ['.npmignore', '.gitignore']) { + try { + const ignoreContent = readFile(join(root, file), { encoding: 'utf8' }) + result.push(ignoreContent) + // break the loop immediately after reading, this allows us to prioritize + // the .npmignore and discard the .gitignore if one is present + break + } catch (err) { + // we ignore ENOENT errors completely because we don't care if the file doesn't exist + // but we throw everything else because failing to read a file that does exist is + // something that the user likely wants to know about + // istanbul ignore next -- we do not need to test a thrown error + if (err.code !== 'ENOENT') { + throw err } - - super.onReadIgnoreFile(rootBuiltinRules, rules, _ => _) - } else { - this.bundled = [] - this.bundledScopes = [] - this.packageJsonCache = this.parent.packageJsonCache } } - get isProject () { - return !this.parent || this.parent.follow && this.isSymbolicLink + if (!rel) { + return result } - onReaddir (entries) { - if (this.isProject) { - entries = entries.filter(e => - e !== '.git' && - !(e === 'node_modules' && this.bundled.length === 0) - ) - } - - // if we have a package.json, then look in it for 'files' - // we _only_ do this in the root project, not bundled deps - // or other random folders. Bundled deps are always assumed - // to be in the state the user wants to include them, and - // a package.json somewhere else might be a template or - // test or something else entirely. - if (!this.isProject || !entries.includes('package.json')) { - return super.onReaddir(entries) - } + const firstRel = rel.split(sep, 1)[0] + const newRoot = join(root, firstRel) + const newRel = relative(newRoot, join(root, rel)) - // when the cache has been seeded with the root manifest, - // we must respect that (it may differ from the filesystem) - const ig = path.resolve(this.path, 'package.json') + return readOutOfTreeIgnoreFiles(newRoot, newRel, result) +} - if (this.packageJsonCache.has(ig)) { - const pkg = this.packageJsonCache.get(ig) +class PackWalker extends IgnoreWalker { + constructor (tree, opts) { + const options = { + ...opts, + includeEmpty: false, + follow: false, + // we path.resolve() here because ignore-walk doesn't do it and we want full paths + path: resolve(opts?.path || tree.path).replace(/\\/g, '/'), + ignoreFiles: opts?.ignoreFiles || [ + defaultRules, + 'package.json', + '.npmignore', + '.gitignore', + strictRules, + ], + } - // fall back to filesystem when seeded manifest is invalid - if (!pkg || typeof pkg !== 'object') { - return this.readPackageJson(entries) + super(options) + + this.isPackage = options.isPackage + this.seen = options.seen || new Set() + this.tree = tree + this.requiredFiles = options.requiredFiles || [] + + const additionalDefaults = [] + if (options.prefix && options.workspaces) { + const path = normalizePath(options.path) + const prefix = normalizePath(options.prefix) + const workspaces = options.workspaces.map((ws) => normalizePath(ws)) + + // istanbul ignore else - this does nothing unless we need it to + if (path !== prefix && workspaces.includes(path)) { + // if path and prefix are not the same directory, and workspaces has path in it + // then we know path is a workspace directory. in order to not drop ignore rules + // from directories between the workspaces root (prefix) and the workspace itself + // (path) we need to find and read those now + const relpath = relative(options.prefix, dirname(options.path)) + additionalDefaults.push(...readOutOfTreeIgnoreFiles(options.prefix, relpath)) + } else if (path === prefix) { + // on the other hand, if the path and prefix are the same, then we ignore workspaces + // so that we don't pack a workspace as part of the root project. append them as + // normalized relative paths from the root + additionalDefaults.push(...workspaces.map((w) => normalizePath(relative(options.path, w)))) } - - // feels wonky, but this ensures package bin is _always_ - // normalized, as well as guarding against invalid JSON - return this.getPackageFiles(entries, JSON.stringify(pkg)) } - this.readPackageJson(entries) - } + // go ahead and inject the default rules now + this.injectRules(defaultRules, [...defaults, ...additionalDefaults]) - onReadPackageJson (entries, er, pkg) { - if (er) { - this.emit('error', er) - } else { - this.getPackageFiles(entries, pkg) + if (!this.isPackage) { + // if this instance is not a package, then place some strict default rules, and append + // known required files for this directory + this.injectRules(strictRules, [ + ...strictDefaults, + ...this.requiredFiles.map((file) => `!${file}`), + ]) } } - mustHaveFilesFromPackage (pkg) { - const files = [] - if (pkg.browser) { - files.push('/' + pkg.browser) + // overridden method: we intercept the reading of the package.json file here so that we can + // process it into both the package.json file rules as well as the strictRules synthetic rule set + addIgnoreFile (file, callback) { + // if we're adding anything other than package.json, then let ignore-walk handle it + if (file !== 'package.json' || !this.isPackage) { + return super.addIgnoreFile(file, callback) } - if (pkg.main) { - files.push('/' + pkg.main) - } - if (pkg.bin) { - // always an object because normalized already - for (const key in pkg.bin) { - files.push('/' + pkg.bin[key]) - } + + return this.processPackage(callback) + } + + // overridden method: if we're done, but we're a package, then we also need to evaluate bundles + // before we actually emit our done event + emit (ev, data) { + if (ev !== 'done' || !this.isPackage) { + return super.emit(ev, data) } - files.push( - '/package.json', - '/npm-shrinkwrap.json', - '!/package-lock.json', - packageMustHaves - ) - return files + + // we intentionally delay the done event while keeping the function sync here + // eslint-disable-next-line promise/catch-or-return, promise/always-return + this.gatherBundles().then(() => { + super.emit('done', this.result) + }) + return true } - getPackageFiles (entries, pkg) { - try { - // XXX this could be changed to use read-package-json-fast - // which handles the normalizing of bins for us, and simplifies - // the test for bundleDependencies and bundledDependencies later. - // HOWEVER if we do this, we need to be sure that we're careful - // about what we write back out since rpj-fast removes some fields - // that the user likely wants to keep. it also would add a second - // file read that we would want to optimize away. - pkg = normalizePackageBin(JSON.parse(pkg.toString())) - } catch (er) { - // not actually a valid package.json - return super.onReaddir(entries) + // overridden method: before actually filtering, we make sure that we've removed the rules for + // files that should no longer take effect due to our order of precedence + filterEntries () { + if (this.ignoreRules['package.json']) { + // package.json means no .npmignore or .gitignore + this.ignoreRules['.npmignore'] = null + this.ignoreRules['.gitignore'] = null + } else if (this.ignoreRules['.npmignore']) { + // .npmignore means no .gitignore + this.ignoreRules['.gitignore'] = null + } else if (this.ignoreRules['.gitignore'] && !this.ignoreRules['.npmignore']) { + log.warn( + 'gitignore-fallback', + 'No .npmignore file found, using .gitignore for file exclusion. Consider creating a .npmignore file to explicitly control published files.' + ) } - const ig = path.resolve(this.path, 'package.json') - this.packageJsonCache.set(ig, pkg) + return super.filterEntries() + } - // no files list, just return the normal readdir() result - if (!Array.isArray(pkg.files)) { - return super.onReaddir(entries) + // overridden method: we never want to include anything that isn't a file or directory + onstat (opts, callback) { + if (!opts.st.isFile() && !opts.st.isDirectory()) { + return callback() } - pkg.files.push(...this.mustHaveFilesFromPackage(pkg)) + return super.onstat(opts, callback) + } - // If the package has a files list, then it's unlikely to include - // node_modules, because why would you do that? but since we use - // the files list as the effective readdir result, that means it - // looks like we don't have a node_modules folder at all unless we - // include it here. - if ((pkg.bundleDependencies || pkg.bundledDependencies) && entries.includes('node_modules')) { - pkg.files.push('node_modules') + // overridden method: we want to refuse to pack files that are invalid, node-tar protects us from + // a lot of them but not all + stat (opts, callback) { + if (nameIsBadForWindows(opts.entry)) { + return callback() } - const patterns = Array.from(new Set(pkg.files)).reduce((set, pattern) => { - const excl = pattern.match(/^!+/) - if (excl) { - pattern = pattern.slice(excl[0].length) - } - // strip off any / or ./ from the start of the pattern. /foo => foo, ./foo => foo - pattern = pattern.replace(/^\.?\/+/, '') - // an odd number of ! means a negated pattern. !!foo ==> foo - const negate = excl && excl[0].length % 2 === 1 - set.push({ pattern, negate }) - return set - }, []) - - let n = patterns.length - const set = new Set() - const negates = new Set() - const results = [] - const then = (pattern, negate, er, fileList, i) => { - if (er) { - return this.emit('error', er) - } + return super.stat(opts, callback) + } - results[i] = { negate, fileList } - if (--n === 0) { - processResults(results) + // overridden method: this is called to create options for a child walker when we step + // in to a normal child directory (this will never be a bundle). the default method here + // copies the root's `ignoreFiles` value, but we don't want to respect package.json for + // subdirectories, so we override it with a list that intentionally omits package.json + walkerOpt (entry, opts) { + let ignoreFiles = null + + // however, if we have a tree, and we have workspaces, and the directory we're about + // to step into is a workspace, then we _do_ want to respect its package.json + if (this.tree.workspaces) { + const workspaceDirs = [...this.tree.workspaces.values()] + .map((dir) => dir.replace(/\\/g, '/')) + + const entryPath = join(this.path, entry).replace(/\\/g, '/') + if (workspaceDirs.includes(entryPath)) { + ignoreFiles = [ + defaultRules, + 'package.json', + '.npmignore', + '.gitignore', + strictRules, + ] } + } else { + ignoreFiles = [ + defaultRules, + '.npmignore', + '.gitignore', + strictRules, + ] } - const processResults = processed => { - for (const { negate, fileList } of processed) { - if (negate) { - fileList.forEach(f => { - f = f.replace(/\/+$/, '') - set.delete(f) - negates.add(f) - }) - } else { - fileList.forEach(f => { - f = f.replace(/\/+$/, '') - set.add(f) - negates.delete(f) - }) - } - } - const list = Array.from(set) - // replace the files array with our computed explicit set - pkg.files = list.concat(Array.from(negates).map(f => '!' + f)) - const rdResult = Array.from(new Set( - list.map(f => f.replace(/^\/+/, '')) - )) - super.onReaddir(rdResult) + return { + ...super.walkerOpt(entry, opts), + ignoreFiles, + // we map over our own requiredFiles and pass ones that are within this entry + requiredFiles: this.requiredFiles + .map((file) => { + if (relative(file, entry) === '..') { + return relative(entry, file).replace(/\\/g, '/') + } + return false + }) + .filter(Boolean), } + } - // maintain the index so that we process them in-order only once all - // are completed, otherwise the parallelism messes things up, since a - // glob like **/*.js will always be slower than a subsequent !foo.js - patterns.forEach(({ pattern, negate }, i) => - this.globFiles(pattern, (er, res) => then(pattern, negate, er, res, i))) + // overridden method: we want child walkers to be instances of this class, not ignore-walk + walker (entry, opts, callback) { + new PackWalker(this.tree, this.walkerOpt(entry, opts)).on('done', callback).start() } - filterEntry (entry, partial) { - // get the partial path from the root of the walk - const p = this.path.slice(this.root.length + 1) - const { isProject } = this - const pkg = isProject && pathHasPkg(entry) - ? pkgFromPath(entry) - : null - const rootNM = isProject && entry === 'node_modules' - const rootPJ = isProject && entry === 'package.json' - - return ( - // if we're in a bundled package, check with the parent. - /^node_modules($|\/)/i.test(p) && !this.isProject ? this.parent.filterEntry( - this.basename + '/' + entry, partial) - - // if package is bundled, all files included - // also include @scope dirs for bundled scoped deps - // they'll be ignored if no files end up in them. - // However, this only matters if we're in the root. - // node_modules folders elsewhere, like lib/node_modules, - // should be included normally unless ignored. - : pkg ? this.bundled.indexOf(pkg) !== -1 || - this.bundledScopes.indexOf(pkg) !== -1 - - // only walk top node_modules if we want to bundle something - : rootNM ? !!this.bundled.length - - // always include package.json at the root. - : rootPJ ? true - - // always include readmes etc in any included dir - : packageMustHavesRE.test(entry) ? true - - // npm-shrinkwrap and package.json always included in the root pkg - : isProject && (entry === 'npm-shrinkwrap.json' || entry === 'package.json') - ? true - - // package-lock never included - : isProject && entry === 'package-lock.json' ? false - - // otherwise, follow ignore-walk's logic - : super.filterEntry(entry, partial) - ) + // overridden method: we use a custom sort method to help compressibility + sort (a, b) { + // optimize for compressibility + // extname, then basename, then locale alphabetically + // https://twitter.com/isntitvacant/status/1131094910923231232 + const exta = extname(a).toLowerCase() + const extb = extname(b).toLowerCase() + const basea = basename(a).toLowerCase() + const baseb = basename(b).toLowerCase() + + return exta.localeCompare(extb, 'en') || + basea.localeCompare(baseb, 'en') || + a.localeCompare(b, 'en') } - filterEntries () { - if (this.ignoreRules['.npmignore']) { - this.ignoreRules['.gitignore'] = null - } - this.filterEntries = super.filterEntries - super.filterEntries() + // convenience method: this joins the given rules with newlines, appends a trailing newline, + // and calls the internal onReadIgnoreFile method + injectRules (filename, rules, callback = () => {}) { + this.onReadIgnoreFile(filename, `${rules.join('\n')}\n`, callback) } - addIgnoreFile (file, then) { - const ig = path.resolve(this.path, file) - if (file === 'package.json' && !this.isProject) { - then() - } else if (this.packageJsonCache.has(ig)) { - this.onPackageJson(ig, this.packageJsonCache.get(ig), then) - } else { - super.addIgnoreFile(file, then) + // custom method: this is called by addIgnoreFile when we find a package.json, it uses the + // arborist tree to pull both default rules and strict rules for the package + processPackage (callback) { + const { + bin, + browser, + files, + main, + } = this.tree.package + + // rules in these arrays are inverted since they are patterns we want to _not_ ignore + const ignores = [] + const strict = [ + ...strictDefaults, + '!/package.json', + '!/readme{,.*[^~$]}', + '!/copying{,.*[^~$]}', + '!/license{,.*[^~$]}', + '!/licence{,.*[^~$]}', + '/.git', + '/node_modules', + '.npmrc', + '/package-lock.json', + '/yarn.lock', + '/pnpm-lock.yaml', + '/bun.lockb', + ] + + // if we have a files array in our package, we need to pull rules from it + if (files) { + for (let file of files) { + // invert the rule because these are things we want to include + if (file.startsWith('./')) { + file = file.slice(1) + } + if (file.endsWith('/*')) { + file += '*' + } + const inverse = `!${file}` + try { + // if an entry in the files array is a specific file, then we need to include it as a + // strict requirement for this package. if it's a directory or a pattern, it's a default + // pattern instead. this is ugly, but we have to stat to find out if it's a file + const stat = lstat(join(this.path, file.replace(/^!+/, '')).replace(/\\/g, '/')) + // if we have a file and we know that, it's strictly required + if (stat.isFile()) { + strict.unshift(inverse) + this.requiredFiles.push(file.startsWith('/') ? file.slice(1) : file) + } else if (stat.isDirectory()) { + // otherwise, it's a default ignore, and since we got here we know it's not a pattern + // so we include the directory contents + ignores.push(inverse) + ignores.push(`${inverse}/**`) + } + // if the thing exists, but is neither a file or a directory, we don't want it at all + } catch (err) { + // if lstat throws, then we assume we're looking at a pattern and treat it as a default + ignores.push(inverse) + } + } + + // we prepend a '*' to exclude everything, followed by our inverted file rules + // which now mean to include those + this.injectRules('package.json', ['*', ...ignores]) } - } - onPackageJson (ig, pkg, then) { - this.packageJsonCache.set(ig, pkg) + // browser is required + if (browser) { + strict.push(`!/${browser}`) + } - if (Array.isArray(pkg.files)) { - // in this case we already included all the must-haves - super.onReadIgnoreFile('package.json', pkg.files.map( - f => '!' + f - ).join('\n') + '\n', then) - } else { - // if there's a bin, browser or main, make sure we don't ignore it - // also, don't ignore the package.json itself, or any files that - // must be included in the package. - const rules = this.mustHaveFilesFromPackage(pkg).map(f => `!${f}`) - const data = rules.join('\n') + '\n' - super.onReadIgnoreFile(packageNecessaryRules, data, then) + // main is required + if (main) { + strict.push(`!/${main}`) } - } - // override parent stat function to completely skip any filenames - // that will break windows entirely. - // XXX(isaacs) Next major version should make this an error instead. - stat ({ entry, file, dir }, then) { - if (nameIsBadForWindows(entry)) { - then() - } else { - super.stat({ entry, file, dir }, then) + // each bin is required + if (bin) { + for (const key in bin) { + strict.push(`!/${bin[key]}`) + } } + + // and now we add all of the strict rules to our synthetic file + this.injectRules(strictRules, strict, callback) } - // override parent onstat function to nix all symlinks, other than - // those coming out of the followed bundled symlink deps - onstat ({ st, entry, file, dir, isSymbolicLink }, then) { - if (st.isSymbolicLink()) { - then() - } else { - super.onstat({ st, entry, file, dir, isSymbolicLink }, then) + // custom method: after we've finished gathering the files for the root package, we call this + // before emitting the 'done' event in order to gather all of the files for bundled deps + async gatherBundles () { + if (this.seen.has(this.tree)) { + return } - } - onReadIgnoreFile (file, data, then) { - if (file === 'package.json') { - try { - const ig = path.resolve(this.path, file) - this.onPackageJson(ig, JSON.parse(data), then) - } catch (er) { - // ignore package.json files that are not json - then() - } + // add this node to our seen tracker + this.seen.add(this.tree) + + // if we're the project root, then we look at our bundleDependencies, otherwise we got here + // because we're a bundled dependency of the root, which means we need to include all prod + // and optional dependencies in the bundle + let toBundle + if (this.tree.isProjectRoot) { + const { bundleDependencies } = this.tree.package + toBundle = bundleDependencies || [] } else { - super.onReadIgnoreFile(file, data, then) + const { dependencies, optionalDependencies } = this.tree.package + toBundle = Object.keys(dependencies || {}).concat(Object.keys(optionalDependencies || {})) } - } - sort (a, b) { - // optimize for compressibility - // extname, then basename, then locale alphabetically - // https://twitter.com/isntitvacant/status/1131094910923231232 - const exta = path.extname(a).toLowerCase() - const extb = path.extname(b).toLowerCase() - const basea = path.basename(a).toLowerCase() - const baseb = path.basename(b).toLowerCase() + for (const dep of toBundle) { + const edge = this.tree.edgesOut.get(dep) + // no edgeOut = missing node, so skip it. we can't pack it if it's not here + // we also refuse to pack peer dependencies and dev dependencies + if (!edge || edge.peer || edge.dev) { + continue + } - return exta.localeCompare(extb, 'en') || - basea.localeCompare(baseb, 'en') || - a.localeCompare(b, 'en') - } + // get a reference to the node we're bundling + const node = this.tree.edgesOut.get(dep).to + // if there's no node, this is most likely an optional dependency that hasn't been + // installed. just skip it. + if (!node) { + continue + } + // we use node.path for the path because we want the location the node was linked to, + // not where it actually lives on disk + const path = node.path + // but link nodes don't have edgesOut, so we need to pass in the target of the node + // in order to make sure we correctly traverse its dependencies + const tree = node.target + + // and start building options to be passed to the walker for this package + const walkerOpts = { + path, + isPackage: true, + ignoreFiles: [], + seen: this.seen, // pass through seen so we can prevent infinite circular loops + } - globFiles (pattern, cb) { - glob(globify(pattern), { dot: true, cwd: this.path, nocase: true }, cb) - } + // if our node is a link, we apply defaultRules. we don't do this for regular bundled + // deps because their .npmignore and .gitignore files are excluded by default and may + // override defaults + if (node.isLink) { + walkerOpts.ignoreFiles.push(defaultRules) + } - readPackageJson (entries) { - fs.readFile(this.path + '/package.json', (er, pkg) => - this.onReadPackageJson(entries, er, pkg)) - } + // _all_ nodes will follow package.json rules from their package root + walkerOpts.ignoreFiles.push('package.json') + + // only link nodes will obey .npmignore or .gitignore + if (node.isLink) { + walkerOpts.ignoreFiles.push('.npmignore') + walkerOpts.ignoreFiles.push('.gitignore') + } - walker (entry, opt, then) { - new Walker(this.walkerOpt(entry, opt)).on('done', then).start() + // _all_ nodes follow strict rules + walkerOpts.ignoreFiles.push(strictRules) + + // create a walker for this dependency and gather its results + const walker = new PackWalker(tree, walkerOpts) + const bundled = await new Promise((pResolve, pReject) => { + walker.on('error', pReject) + walker.on('done', pResolve) + walker.start() + }) + + // now we make sure we have our paths correct from the root, and accumulate everything into + // our own result set to deduplicate + const relativeFrom = relative(this.root, walker.path) + for (const file of bundled) { + this.result.add(join(relativeFrom, file).replace(/\\/g, '/')) + } + } } } -const walk = (options, callback) => { - options = options || {} - const p = new Promise((resolve, reject) => { - const bw = new BundleWalker(options) - bw.on('done', bundled => { - options.bundled = bundled - options.packageJsonCache = bw.packageJsonCache - new Walker(options).on('done', resolve).on('error', reject).start() - }) - bw.start() +const walk = (tree, options, callback) => { + if (typeof options === 'function') { + callback = options + options = {} + } + const p = new Promise((pResolve, pReject) => { + new PackWalker(tree, { ...options, isPackage: true }) + .on('done', pResolve).on('error', pReject).start() }) return callback ? p.then(res => callback(null, res), callback) : p } module.exports = walk -walk.Walker = Walker +walk.Walker = PackWalker diff --git a/node_modules/npm-packlist/package.json b/node_modules/npm-packlist/package.json index 4c63caf21e810..30cddb4df2e37 100644 --- a/node_modules/npm-packlist/package.json +++ b/node_modules/npm-packlist/package.json @@ -1,16 +1,14 @@ { "name": "npm-packlist", - "version": "5.1.1", + "version": "10.0.3", "description": "Get a list of the files to add from a folder into an npm package", "directories": { "test": "test" }, - "main": "lib", + "main": "lib/index.js", "dependencies": { - "glob": "^8.0.1", - "ignore-walk": "^5.0.1", - "npm-bundled": "^1.1.2", - "npm-normalize-package-bin": "^1.0.1" + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" }, "author": "GitHub Inc.", "license": "ISC", @@ -19,8 +17,9 @@ "lib/" ], "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/arborist": "^9.0.0", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.27.1", "mutate-fs": "^2.1.1", "tap": "^16.0.1" }, @@ -29,33 +28,35 @@ "posttest": "npm run lint", "snap": "tap", "postsnap": "npm run lintfix --", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "eslint": "eslint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "npmclilint": "npmcli-lint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force" }, "repository": { "type": "git", - "url": "https://github.com/npm/npm-packlist.git" + "url": "git+https://github.com/npm/npm-packlist.git" }, "tap": { "test-env": [ "LC_ALL=sk" + ], + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ], + "files": [ + "test/*.js" ] }, - "bin": { - "npm-packlist": "bin/index.js" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/npm-pick-manifest/lib/index.js b/node_modules/npm-pick-manifest/lib/index.js index f2934e9ca1822..985c78df7a9bf 100644 --- a/node_modules/npm-pick-manifest/lib/index.js +++ b/node_modules/npm-pick-manifest/lib/index.js @@ -93,13 +93,10 @@ const pickManifest = (packument, wanted, opts) => { throw new Error('Only tag, version, and range are supported') } - // if the type is 'tag', and not just the implicit default, then it must - // be that exactly, or nothing else will do. + // if the type is 'tag', and not just the implicit default, then it must be that exactly, or nothing else will do. if (wanted && type === 'tag') { const ver = distTags[wanted] - // if the version in the dist-tags is before the before date, then - // we use that. Otherwise, we get the highest precedence version - // prior to the dist-tag. + // if the version in the dist-tags is before the before date, then we use that. Otherwise, we get the highest precedence version prior to the dist-tag. if (isBefore(verTimes, ver, time)) { return decorateAvoid(versions[ver] || staged[ver] || restricted[ver], avoid) } else { @@ -117,15 +114,19 @@ const pickManifest = (packument, wanted, opts) => { // ok, sort based on our heuristics, and pick the best fit const range = type === 'range' ? wanted : '*' - // if the range is *, then we prefer the 'latest' if available - // but skip this if it should be avoided, in that case we have - // to try a little harder. + // if the range is *, then we prefer the 'latest' if available but skip this if it should be avoided, in that case we have to try a little harder. const defaultVer = distTags[defaultTag] if (defaultVer && (range === '*' || semver.satisfies(defaultVer, range, { loose: true })) && + !restricted[defaultVer] && !shouldAvoid(defaultVer, avoid)) { const mani = versions[defaultVer] - if (mani && isBefore(verTimes, defaultVer, time)) { + const ok = mani && + isBefore(verTimes, defaultVer, time) && + engineOk(mani, npmVersion, nodeVersion) && + !mani.deprecated && + !staged[defaultVer] + if (ok) { return mani } } @@ -134,7 +135,7 @@ const pickManifest = (packument, wanted, opts) => { const allEntries = Object.entries(versions) .concat(Object.entries(staged)) .concat(Object.entries(restricted)) - .filter(([ver, mani]) => isBefore(verTimes, ver, time)) + .filter(([ver]) => isBefore(verTimes, ver, time)) if (!allEntries.length) { throw Object.assign(new Error(`No versions available for ${name}`), { @@ -148,17 +149,17 @@ const pickManifest = (packument, wanted, opts) => { } const sortSemverOpt = { loose: true } - const entries = allEntries.filter(([ver, mani]) => + const entries = allEntries.filter(([ver]) => semver.satisfies(ver, range, { loose: true })) .sort((a, b) => { const [vera, mania] = a const [verb, manib] = b const notavoida = !shouldAvoid(vera, avoid) const notavoidb = !shouldAvoid(verb, avoid) - const notrestra = !restricted[a] - const notrestrb = !restricted[b] - const notstagea = !staged[a] - const notstageb = !staged[b] + const notrestra = !restricted[vera] + const notrestrb = !restricted[verb] + const notstagea = !staged[vera] + const notstageb = !staged[verb] const notdepra = !mania.deprecated const notdeprb = !manib.deprecated const enginea = engineOk(mania, npmVersion, nodeVersion) @@ -210,7 +211,7 @@ module.exports = (packument, wanted, opts = {}) => { code, type: npa.resolve(packument.name, wanted).type, wanted, - versions: Object.keys(packument.versions), + versions: Object.keys(packument.versions ?? {}), name, distTags: packument['dist-tags'], defaultTag, diff --git a/node_modules/npm-pick-manifest/package.json b/node_modules/npm-pick-manifest/package.json index 79867d9cebaf2..5cfafcfb70885 100644 --- a/node_modules/npm-pick-manifest/package.json +++ b/node_modules/npm-pick-manifest/package.json @@ -1,6 +1,6 @@ { "name": "npm-pick-manifest", - "version": "7.0.1", + "version": "11.0.3", "description": "Resolves a matching manifest from a package metadata document according to standard npm semver resolution rules.", "main": "./lib", "files": [ @@ -9,20 +9,18 @@ ], "scripts": { "coverage": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "test": "tap", "posttest": "npm run lint", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/npm-pick-manifest.git" + "url": "git+https://github.com/npm/npm-pick-manifest.git" }, "keywords": [ "npm", @@ -32,24 +30,29 @@ "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "npm-install-checks": "^5.0.0", - "npm-normalize-package-bin": "^1.0.1", - "npm-package-arg": "^9.0.0", + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", "semver": "^7.3.5" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/npm-profile/lib/index.js b/node_modules/npm-profile/lib/index.js index ce78882a55438..83ab5e1b46b68 100644 --- a/node_modules/npm-profile/lib/index.js +++ b/node_modules/npm-profile/lib/index.js @@ -1,37 +1,34 @@ -'use strict' - +const { URL } = require('node:url') +const timers = require('node:timers/promises') const fetch = require('npm-registry-fetch') 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 = {}) => { - const { creds } = opts - return loginWeb(opener, opts).catch(er => { +const login = async (opener, prompter, opts = {}) => { + try { + return await loginWeb(opener, opts) + } catch (er) { if (er instanceof WebLoginNotSupported) { - log.verbose('web login not supported, trying couch') - return prompter(creds) - .then(data => loginCouch(data.username, data.password, opts)) - } else { - throw er + log.verbose('web login', 'not supported, trying couch') + const { username, password } = await prompter(opts.creds) + return loginCouch(username, password, opts) } - }) + throw er + } } -const adduser = (opener, prompter, opts = {}) => { - const { creds } = opts - return adduserWeb(opener, opts).catch(er => { +const adduser = async (opener, prompter, opts = {}) => { + try { + return await adduserWeb(opener, opts) + } catch (er) { if (er instanceof WebLoginNotSupported) { - log.verbose('web adduser not supported, trying couch') - return prompter(creds) - .then(data => adduserCouch(data.username, data.email, data.password, opts)) - } else { - throw er + log.verbose('web adduser', 'not supported, trying couch') + const { username, email, password } = await prompter(opts.creds) + return adduserCouch(username, email, password, opts) } - }) + throw er + } } const adduserWeb = (opener, opts = {}) => { @@ -47,88 +44,104 @@ const loginWeb = (opener, opts = {}) => { const isValidUrl = u => { try { return /^https?:$/.test(new URL(u).protocol) - } catch (er) { + } catch { return false } } -const webAuth = (opener, opts, body) => { - const { hostname } = opts - body.hostname = hostname || os.hostname() - const target = '/-/v1/login' - const doneEmitter = new EventEmitter() - return fetch(target, { - ...opts, - method: 'POST', - body, - }).then(res => { - return Promise.all([res, res.json()]) - }).then(([res, content]) => { - const { doneUrl, loginUrl } = content +const webAuth = async (opener, opts, body) => { + try { + const res = await fetch('/-/v1/login', { + ...opts, + method: 'POST', + body, + }) + + const content = await res.json() log.verbose('web auth', 'got response', content) + + const { doneUrl, loginUrl } = content if (!isValidUrl(doneUrl) || !isValidUrl(loginUrl)) { throw new WebLoginInvalidResponse('POST', res, content) } - return content - }).then(({ doneUrl, loginUrl }) => { - log.verbose('web auth', 'opening url pair') - - const openPromise = opener(loginUrl, doneEmitter) - const webAuthCheckPromise = webAuthCheckLogin(doneUrl, { ...opts, cache: false }) - .then(authResult => { - log.verbose('web auth', 'done-check finished') - - // cancel open prompt if it's present - doneEmitter.emit('abort') - - return authResult - }) - - return Promise.all([openPromise, webAuthCheckPromise]).then( - // pick the auth result and pass it along - ([, authResult]) => authResult - ) - }).catch(er => { - // cancel open prompt if it's present - doneEmitter.emit('abort') + return await webAuthOpener(opener, loginUrl, doneUrl, opts) + } catch (er) { if ((er.statusCode >= 400 && er.statusCode <= 499) || er.statusCode === 500) { throw new WebLoginNotSupported('POST', { status: er.statusCode, - headers: { raw: () => er.headers }, + headers: er.headers, }, er.body) - } else { - throw er } - }) + throw er + } } -const webAuthCheckLogin = (doneUrl, opts) => { - return fetch(doneUrl, opts).then(res => { - return Promise.all([res, res.json()]) - }).then(([res, content]) => { - if (res.status === 200) { - if (!content.token) { - throw new WebLoginInvalidResponse('GET', res, content) - } else { - return content - } - } else if (res.status === 202) { - const retry = +res.headers.get('retry-after') * 1000 - if (retry > 0) { - return sleep(retry).then(() => webAuthCheckLogin(doneUrl, opts)) - } else { - return webAuthCheckLogin(doneUrl, opts) - } - } else { +const webAuthOpener = async (opener, loginUrl, doneUrl, opts) => { + const abortController = new AbortController() + const { signal } = abortController + try { + log.verbose('web auth', 'opening url pair') + const [, authResult] = await Promise.all([ + opener(loginUrl, { signal }).catch((err) => { + if (err.name === 'AbortError') { + abortController.abort() + return + } + throw err + }), + webAuthCheckLogin(doneUrl, { ...opts, cache: false }, { signal }).then((r) => { + log.verbose('web auth', 'done-check finished') + abortController.abort() + return r + }), + ]) + return authResult + } catch (er) { + abortController.abort() + throw er + } +} + +const webAuthCheckLogin = async (doneUrl, opts, { signal } = {}) => { + signal?.throwIfAborted() + + const res = await fetch(doneUrl, opts) + const content = await res.json() + + if (res.status === 200) { + if (!content.token) { throw new WebLoginInvalidResponse('GET', res, content) } + return content + } + + if (res.status === 202) { + const retry = +res.headers.get('retry-after') * 1000 + if (retry > 0) { + await timers.setTimeout(retry, null, { signal }) + } + return webAuthCheckLogin(doneUrl, opts, { signal }) + } + + throw new WebLoginInvalidResponse('GET', res, content) +} + +const couchEndpoint = (username) => `/-/user/org.couchdb.user:${encodeURIComponent(username)}` + +const putCouch = async (path, username, body, opts) => { + const result = await fetch.json(`${couchEndpoint(username)}${path}`, { + ...opts, + method: 'PUT', + body, }) + result.username = username + return result } -const adduserCouch = (username, email, password, opts = {}) => { +const adduserCouch = async (username, email, password, opts = {}) => { const body = { - _id: 'org.couchdb.user:' + username, + _id: `org.couchdb.user:${username}`, name: username, password: password, email: email, @@ -136,134 +149,107 @@ const adduserCouch = (username, email, password, opts = {}) => { roles: [], date: new Date().toISOString(), } - const logObj = { + + log.verbose('adduser', 'before first PUT', { ...body, password: 'XXXXX', - } - log.verbose('adduser', 'before first PUT', logObj) - - const target = '/-/user/org.couchdb.user:' + encodeURIComponent(username) - return fetch.json(target, { - ...opts, - method: 'PUT', - body, - }).then(result => { - result.username = username - return result }) + + return putCouch('', username, body, opts) } -const loginCouch = (username, password, opts = {}) => { +const loginCouch = async (username, password, opts = {}) => { const body = { - _id: 'org.couchdb.user:' + username, + _id: `org.couchdb.user:${username}`, name: username, password: password, type: 'user', roles: [], date: new Date().toISOString(), } - const logObj = { + + log.verbose('login', 'before first PUT', { ...body, password: 'XXXXX', - } - log.verbose('login', 'before first PUT', logObj) + }) - const target = '/-/user/org.couchdb.user:' + encodeURIComponent(username) - return fetch.json(target, { - ...opts, - method: 'PUT', - body, - }).catch(err => { + try { + return await putCouch('', username, body, opts) + } catch (err) { if (err.code === 'E400') { err.message = `There is no user with the username "${username}".` throw err } + if (err.code !== 'E409') { throw err } - return fetch.json(target, { - ...opts, - query: { write: true }, - }).then(result => { - Object.keys(result).forEach(k => { - if (!body[k] || k === 'roles') { - body[k] = result[k] - } - }) - const { otp } = opts - return fetch.json(`${target}/-rev/${body._rev}`, { - ...opts, - method: 'PUT', - body, - forceAuth: { - username, - password: Buffer.from(password, 'utf8').toString('base64'), - otp, - }, - }) - }) - }).then(result => { - result.username = username - return result - }) -} + } -const get = (opts = {}) => fetch.json('/-/npm/v1/user', opts) + const result = await fetch.json(couchEndpoint(username), { + ...opts, + query: { write: true }, + }) -const set = (profile, opts = {}) => { - Object.keys(profile).forEach(key => { - // profile keys can't be empty strings, but they CAN be null - if (profile[key] === '') { - profile[key] = null + for (const k of Object.keys(result)) { + if (!body[k] || k === 'roles') { + body[k] = result[k] } - }) - return fetch.json('/-/npm/v1/user', { + } + + return putCouch(`/-rev/${body._rev}`, username, body, { ...opts, - method: 'POST', - body: profile, + forceAuth: { + username, + password: Buffer.from(password, 'utf8').toString('base64'), + otp: opts.otp, + }, }) } -const listTokens = (opts = {}) => { - const untilLastPage = (href, objects) => { - return fetch.json(href, opts).then(result => { - objects = objects ? objects.concat(result.objects) : result.objects - if (result.urls.next) { - return untilLastPage(result.urls.next, objects) - } else { - return objects - } - }) +const get = (opts = {}) => fetch.json('/-/npm/v1/user', opts) + +const set = (profile, opts = {}) => fetch.json('/-/npm/v1/user', { + ...opts, + method: 'POST', + // profile keys can't be empty strings, but they CAN be null + body: Object.fromEntries(Object.entries(profile).map(([k, v]) => [k, v === '' ? null : v])), +}) + +const paginate = async (href, opts, items = []) => { + const result = await fetch.json(href, opts) + items = items.concat(result.objects) + if (result.urls.next) { + return paginate(result.urls.next, opts, items) } - return untilLastPage('/-/npm/v1/tokens') + return items } -const removeToken = (tokenKey, opts = {}) => { - const target = `/-/npm/v1/tokens/token/${tokenKey}` - return fetch(target, { +const listTokens = (opts = {}) => paginate('/-/npm/v1/tokens', opts) + +const removeToken = async (tokenKey, opts = {}) => { + await fetch(`/-/npm/v1/tokens/token/${tokenKey}`, { ...opts, method: 'DELETE', ignoreBody: true, - }).then(() => null) -} - -const createToken = (password, readonly, cidrs, opts = {}) => { - return fetch.json('/-/npm/v1/tokens', { - ...opts, - method: 'POST', - body: { - password: password, - readonly: readonly, - cidr_whitelist: cidrs, - }, }) + return null } +const createToken = (password, readonly, cidrs, opts = {}) => fetch.json('/-/npm/v1/tokens', { + ...opts, + method: 'POST', + body: { + password: password, + readonly: readonly, + cidr_whitelist: cidrs, + }, +}) + class WebLoginInvalidResponse extends HttpErrorBase { constructor (method, res, body) { super(method, res, body) this.message = 'Invalid response from web login endpoint' - Error.captureStackTrace(this, WebLoginInvalidResponse) } } @@ -272,13 +258,9 @@ class WebLoginNotSupported extends HttpErrorBase { super(method, res, body) this.message = 'Web login not supported' this.code = 'ENYI' - Error.captureStackTrace(this, WebLoginNotSupported) } } -const sleep = (ms) => - new Promise((resolve, reject) => setTimeout(resolve, ms)) - module.exports = { adduserCouch, loginCouch, @@ -292,4 +274,5 @@ module.exports = { removeToken, createToken, webAuthCheckLogin, + webAuthOpener, } diff --git a/node_modules/npm-profile/package.json b/node_modules/npm-profile/package.json index 457a1fb0988fb..0f97cc1efa193 100644 --- a/node_modules/npm-profile/package.json +++ b/node_modules/npm-profile/package.json @@ -1,49 +1,52 @@ { "name": "npm-profile", - "version": "6.2.1", + "version": "12.0.1", "description": "Library for updating an npmjs.com profile", "keywords": [], "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0" + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0" }, "main": "./lib/index.js", "repository": { "type": "git", - "url": "https://github.com/npm/npm-profile.git" + "url": "git+https://github.com/npm/npm-profile.git" }, "files": [ "bin/", "lib/" ], "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "nock": "^13.2.4", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "nock": "^13.5.6", "tap": "^16.0.1" }, "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "posttest": "npm run lint", "test": "tap", "snap": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "template-oss-apply": "template-oss-apply --force" + "lintfix": "npm run eslint -- --fix", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/npm-registry-fetch/lib/auth.js b/node_modules/npm-registry-fetch/lib/auth.js index 870ce0d923cd0..9270025fa8d90 100644 --- a/node_modules/npm-registry-fetch/lib/auth.js +++ b/node_modules/npm-registry-fetch/lib/auth.js @@ -4,8 +4,8 @@ const npa = require('npm-package-arg') const { URL } = require('url') // Find the longest registry key that is used for some kind of auth -// in the options. -const regKeyFromURI = (uri, opts) => { +// in the options. Returns the registry key and the auth config. +const regFromURI = (uri, opts) => { const parsed = new URL(uri) // try to find a config key indicating we have auth for this registry // can be one of :_authToken, :_auth, :_password and :username, or @@ -14,23 +14,40 @@ const regKeyFromURI = (uri, opts) => { // stopping when we reach '//'. let regKey = `//${parsed.host}${parsed.pathname}` while (regKey.length > '//'.length) { + const authKey = hasAuth(regKey, opts) // got some auth for this URI - if (hasAuth(regKey, opts)) { - return regKey + if (authKey) { + return { regKey, authKey } } // can be either //host/some/path/:_auth or //host/some/path:_auth // walk up by removing EITHER what's after the slash OR the slash itself regKey = regKey.replace(/([^/]+|\/)$/, '') } + return { regKey: false, authKey: null } } -const hasAuth = (regKey, opts) => ( - opts[`${regKey}:_authToken`] || - opts[`${regKey}:_auth`] || - opts[`${regKey}:username`] && opts[`${regKey}:_password`] || - opts[`${regKey}:certfile`] && opts[`${regKey}:keyfile`] -) +// Not only do we want to know if there is auth, but if we are calling `npm +// logout` we want to know what config value specifically provided it. This is +// so we can look up where the config came from to delete it (i.e. user vs +// project) +const hasAuth = (regKey, opts) => { + if (opts[`${regKey}:_authToken`]) { + return '_authToken' + } + if (opts[`${regKey}:_auth`]) { + return '_auth' + } + if (opts[`${regKey}:username`] && opts[`${regKey}:_password`]) { + // 'password' can be inferred to also be present + return 'username' + } + if (opts[`${regKey}:certfile`] && opts[`${regKey}:keyfile`]) { + // 'keyfile' can be inferred to also be present + return 'certfile' + } + return false +} const sameHost = (a, b) => { const parsedA = new URL(a) @@ -63,11 +80,14 @@ const getAuth = (uri, opts = {}) => { if (!uri) { throw new Error('URI is required') } - const regKey = regKeyFromURI(uri, forceAuth || opts) + const { regKey, authKey } = regFromURI(uri, forceAuth || opts) // we are only allowed to use what's in forceAuth if specified if (forceAuth && !regKey) { return new Auth({ + // if we force auth we don't want to refer back to anything in config + regKey: false, + authKey: null, scopeAuthKey: null, token: forceAuth._authToken || forceAuth.token, username: forceAuth.username, @@ -88,8 +108,8 @@ const getAuth = (uri, opts = {}) => { // registry where we logged in, but the same auth SHOULD be sent // to that artifact host, then we track where it was coming in from, // and warn the user if we get a 4xx error on it. - const scopeAuthKey = regKeyFromURI(registry, opts) - return new Auth({ scopeAuthKey }) + const { regKey: scopeAuthKey, authKey: _authKey } = regFromURI(registry, opts) + return new Auth({ scopeAuthKey, regKey: scopeAuthKey, authKey: _authKey }) } } @@ -104,6 +124,8 @@ const getAuth = (uri, opts = {}) => { return new Auth({ scopeAuthKey: null, + regKey, + authKey, token, auth, username, @@ -114,8 +136,22 @@ const getAuth = (uri, opts = {}) => { } class Auth { - constructor ({ token, auth, username, password, scopeAuthKey, certfile, keyfile }) { + constructor ({ + token, + auth, + username, + password, + scopeAuthKey, + certfile, + keyfile, + regKey, + authKey, + }) { + // same as regKey but only present for scoped auth. Should have been named scopeRegKey this.scopeAuthKey = scopeAuthKey + // `${regKey}:${authKey}` will get you back to the auth config that gave us auth + this.regKey = regKey + this.authKey = authKey this.token = null this.auth = null this.isBasicAuth = false diff --git a/node_modules/npm-registry-fetch/lib/check-response.js b/node_modules/npm-registry-fetch/lib/check-response.js index 714513908df40..2f183082ab2ce 100644 --- a/node_modules/npm-registry-fetch/lib/check-response.js +++ b/node_modules/npm-registry-fetch/lib/check-response.js @@ -3,8 +3,8 @@ const errors = require('./errors.js') const { Response } = require('minipass-fetch') const defaultOpts = require('./default-opts.js') -const log = require('proc-log') -const cleanUrl = require('./clean-url.js') +const { log } = require('proc-log') +const { redact: cleanUrl } = require('@npmcli/redact') /* eslint-disable-next-line max-len */ const moreInfoUrl = 'https://github.com/npm/cli/wiki/No-auth-for-URI,-but-auth-present-for-scoped-registry' @@ -48,10 +48,18 @@ function logRequest (method, res, startTime) { const cacheStr = cacheStatus ? ` (cache ${cacheStatus})` : '' const urlStr = cleanUrl(res.url) - log.http( - 'fetch', - `${method.toUpperCase()} ${res.status} ${urlStr} ${elapsedTime}ms${attemptStr}${cacheStr}` - ) + // If make-fetch-happen reports a cache hit, then there was no fetch + if (cacheStatus === 'hit') { + log.http( + 'cache', + `${urlStr} ${elapsedTime}ms${attemptStr}${cacheStr}` + ) + } else { + log.http( + 'fetch', + `${method.toUpperCase()} ${res.status} ${urlStr} ${elapsedTime}ms${attemptStr}${cacheStr}` + ) + } } function checkErrors (method, res, startTime, opts) { @@ -61,7 +69,9 @@ function checkErrors (method, res, startTime, opts) { let parsed = body try { parsed = JSON.parse(body.toString('utf8')) - } catch (e) {} + } catch { + // ignore errors + } if (res.status === 401 && res.headers.get('www-authenticate')) { const auth = res.headers.get('www-authenticate') .split(/,\s*/) diff --git a/node_modules/npm-registry-fetch/lib/clean-url.js b/node_modules/npm-registry-fetch/lib/clean-url.js deleted file mode 100644 index ba31dc462f3c5..0000000000000 --- a/node_modules/npm-registry-fetch/lib/clean-url.js +++ /dev/null @@ -1,24 +0,0 @@ -const { URL } = require('url') - -const replace = '***' -const tokenRegex = /\bnpm_[a-zA-Z0-9]{36}\b/g -const guidRegex = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/g - -const cleanUrl = (str) => { - if (typeof str !== 'string' || !str) { - return str - } - - try { - const url = new URL(str) - if (url.password) { - str = str.replace(url.password, replace) - } - } catch {} - - return str - .replace(tokenRegex, `npm_${replace}`) - .replace(guidRegex, `npm_${replace}`) -} - -module.exports = cleanUrl diff --git a/node_modules/npm-registry-fetch/lib/errors.js b/node_modules/npm-registry-fetch/lib/errors.js index cf5ddba6f300c..5bf6b012a24ef 100644 --- a/node_modules/npm-registry-fetch/lib/errors.js +++ b/node_modules/npm-registry-fetch/lib/errors.js @@ -1,10 +1,10 @@ 'use strict' -const url = require('url') +const { URL } = require('node:url') function packageName (href) { try { - let basePath = new url.URL(href).pathname.slice(1) + let basePath = new URL(href).pathname.slice(1) if (!basePath.match(/^-/)) { basePath = basePath.split('/') var index = basePath.indexOf('_rewrite') @@ -15,7 +15,7 @@ function packageName (href) { } return decodeURIComponent(basePath[index]) } - } catch (_) { + } catch { // this is ok } } @@ -24,16 +24,16 @@ class HttpErrorBase extends Error { constructor (method, res, body, spec) { super() this.name = this.constructor.name - this.headers = res.headers.raw() + this.headers = typeof res.headers?.raw === 'function' ? res.headers.raw() : res.headers this.statusCode = res.status this.code = `E${res.status}` this.method = method this.uri = res.url this.body = body this.pkgid = spec ? spec.toString() : packageName(res.url) + Error.captureStackTrace(this, this.constructor) } } -module.exports.HttpErrorBase = HttpErrorBase class HttpErrorGeneral extends HttpErrorBase { constructor (method, res, body, spec) { @@ -45,36 +45,36 @@ class HttpErrorGeneral extends HttpErrorBase { }${ (body && body.error) ? ' - ' + body.error : '' }` - Error.captureStackTrace(this, HttpErrorGeneral) } } -module.exports.HttpErrorGeneral = HttpErrorGeneral class HttpErrorAuthOTP extends HttpErrorBase { constructor (method, res, body, spec) { super(method, res, body, spec) this.message = 'OTP required for authentication' this.code = 'EOTP' - Error.captureStackTrace(this, HttpErrorAuthOTP) } } -module.exports.HttpErrorAuthOTP = HttpErrorAuthOTP class HttpErrorAuthIPAddress extends HttpErrorBase { constructor (method, res, body, spec) { super(method, res, body, spec) this.message = 'Login is not allowed from your IP address' this.code = 'EAUTHIP' - Error.captureStackTrace(this, HttpErrorAuthIPAddress) } } -module.exports.HttpErrorAuthIPAddress = HttpErrorAuthIPAddress class HttpErrorAuthUnknown extends HttpErrorBase { constructor (method, res, body, spec) { super(method, res, body, spec) this.message = 'Unable to authenticate, need: ' + res.headers.get('www-authenticate') - Error.captureStackTrace(this, HttpErrorAuthUnknown) } } -module.exports.HttpErrorAuthUnknown = HttpErrorAuthUnknown + +module.exports = { + HttpErrorBase, + HttpErrorGeneral, + HttpErrorAuthOTP, + HttpErrorAuthIPAddress, + HttpErrorAuthUnknown, +} diff --git a/node_modules/npm-registry-fetch/lib/index.js b/node_modules/npm-registry-fetch/lib/index.js index cc331a50c0963..91d450f245f05 100644 --- a/node_modules/npm-registry-fetch/lib/index.js +++ b/node_modules/npm-registry-fetch/lib/index.js @@ -4,12 +4,12 @@ const { HttpErrorAuthOTP } = require('./errors.js') const checkResponse = require('./check-response.js') const getAuth = require('./auth.js') const fetch = require('make-fetch-happen') -const JSONStream = require('minipass-json-stream') +const JSONStream = require('./json-stream') const npa = require('npm-package-arg') const qs = require('querystring') const url = require('url') const zlib = require('minizlib') -const Minipass = require('minipass') +const { Minipass } = require('minipass') const defaultOpts = require('./default-opts.js') @@ -130,6 +130,7 @@ function regFetch (uri, /* istanbul ignore next */ opts_ = {}) { }, strictSSL: opts.strictSSL, timeout: opts.timeout || 30 * 1000, + signal: opts.signal, }).then(res => checkResponse({ method, uri, @@ -166,6 +167,8 @@ function regFetch (uri, /* istanbul ignore next */ opts_ = {}) { return Promise.resolve(body).then(doFetch) } +module.exports.getAuth = getAuth + module.exports.json = fetchJSON function fetchJSON (uri, opts) { return regFetch(uri, opts).then(res => res.json()) @@ -243,5 +246,3 @@ function getHeaders (uri, auth, opts) { return headers } - -module.exports.cleanUrl = require('./clean-url.js') diff --git a/node_modules/npm-registry-fetch/lib/json-stream.js b/node_modules/npm-registry-fetch/lib/json-stream.js new file mode 100644 index 0000000000000..36b05ad4a20b9 --- /dev/null +++ b/node_modules/npm-registry-fetch/lib/json-stream.js @@ -0,0 +1,223 @@ +const Parser = require('jsonparse') +const { Minipass } = require('minipass') + +class JSONStreamError extends Error { + constructor (err, caller) { + super(err.message) + Error.captureStackTrace(this, caller || this.constructor) + } + + get name () { + return 'JSONStreamError' + } +} + +const check = (x, y) => + typeof x === 'string' ? String(y) === x + : x && typeof x.test === 'function' ? x.test(y) + : typeof x === 'boolean' || typeof x === 'object' ? x + : typeof x === 'function' ? x(y) + : false + +class JSONStream extends Minipass { + #count = 0 + #ending = false + #footer = null + #header = null + #map = null + #onTokenOriginal + #parser + #path = null + #root = null + + constructor (opts) { + super({ + ...opts, + objectMode: true, + }) + + const parser = this.#parser = new Parser() + parser.onValue = value => this.#onValue(value) + this.#onTokenOriginal = parser.onToken + parser.onToken = (token, value) => this.#onToken(token, value) + parser.onError = er => this.#onError(er) + + this.#path = typeof opts.path === 'string' + ? opts.path.split('.').map(e => + e === '$*' ? { emitKey: true } + : e === '*' ? true + : e === '' ? { recurse: true } + : e) + : Array.isArray(opts.path) && opts.path.length ? opts.path + : null + + if (typeof opts.map === 'function') { + this.#map = opts.map + } + } + + #setHeaderFooter (key, value) { + // header has not been emitted yet + if (this.#header !== false) { + this.#header = this.#header || {} + this.#header[key] = value + } + + // footer has not been emitted yet but header has + if (this.#footer !== false && this.#header === false) { + this.#footer = this.#footer || {} + this.#footer[key] = value + } + } + + #onError (er) { + // error will always happen during a write() call. + const caller = this.#ending ? this.end : this.write + this.#ending = false + return this.emit('error', new JSONStreamError(er, caller)) + } + + #onToken (token, value) { + const parser = this.#parser + this.#onTokenOriginal.call(this.#parser, token, value) + if (parser.stack.length === 0) { + if (this.#root) { + const root = this.#root + if (!this.#path) { + super.write(root) + } + this.#root = null + this.#count = 0 + } + } + } + + #onValue (value) { + const parser = this.#parser + // the LAST onValue encountered is the root object. + // just overwrite it each time. + this.#root = value + + if (!this.#path) { + return + } + + let i = 0 // iterates on path + let j = 0 // iterates on stack + let emitKey = false + while (i < this.#path.length) { + const key = this.#path[i] + j++ + + if (key && !key.recurse) { + const c = (j === parser.stack.length) ? parser : parser.stack[j] + if (!c) { + return + } + if (!check(key, c.key)) { + this.#setHeaderFooter(c.key, value) + return + } + emitKey = !!key.emitKey + i++ + } else { + i++ + if (i >= this.#path.length) { + return + } + const nextKey = this.#path[i] + if (!nextKey) { + return + } + while (true) { + const c = (j === parser.stack.length) ? parser : parser.stack[j] + if (!c) { + return + } + if (check(nextKey, c.key)) { + i++ + if (!Object.isFrozen(parser.stack[j])) { + parser.stack[j].value = null + } + break + } else { + this.#setHeaderFooter(c.key, value) + } + j++ + } + } + } + + // emit header + if (this.#header) { + const header = this.#header + this.#header = false + this.emit('header', header) + } + if (j !== parser.stack.length) { + return + } + + this.#count++ + const actualPath = parser.stack.slice(1) + .map(e => e.key).concat([parser.key]) + if (value !== null && value !== undefined) { + const data = this.#map ? this.#map(value, actualPath) : value + if (data !== null && data !== undefined) { + const emit = emitKey ? { value: data } : data + if (emitKey) { + emit.key = parser.key + } + super.write(emit) + } + } + + if (parser.value) { + delete parser.value[parser.key] + } + + for (const k of parser.stack) { + k.value = null + } + } + + write (chunk, encoding) { + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding) + } else if (!Buffer.isBuffer(chunk)) { + return this.emit('error', new TypeError( + 'Can only parse JSON from string or buffer input')) + } + this.#parser.write(chunk) + return this.flowing + } + + end (chunk, encoding) { + this.#ending = true + if (chunk) { + this.write(chunk, encoding) + } + + const h = this.#header + this.#header = null + const f = this.#footer + this.#footer = null + if (h) { + this.emit('header', h) + } + if (f) { + this.emit('footer', f) + } + return super.end() + } + + static get JSONStreamError () { + return JSONStreamError + } + + static parse (path, map) { + return new JSONStream({ path, map }) + } +} + +module.exports = JSONStream diff --git a/node_modules/npm-registry-fetch/package.json b/node_modules/npm-registry-fetch/package.json index 8a0189a9ef74d..6f43ed7036796 100644 --- a/node_modules/npm-registry-fetch/package.json +++ b/node_modules/npm-registry-fetch/package.json @@ -1,6 +1,6 @@ { "name": "npm-registry-fetch", - "version": "13.3.0", + "version": "19.1.1", "description": "Fetch-based http client for use with npm registry APIs", "main": "lib", "files": [ @@ -8,12 +8,9 @@ "lib/" ], "scripts": { - "eslint": "eslint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", - "preversion": "npm test", - "postversion": "npm publish", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "lint": "npm run eslint", + "lintfix": "npm run eslint -- --fix", "test": "tap", "posttest": "npm run lint", "npmclilint": "npmcli-lint", @@ -24,7 +21,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/npm/npm-registry-fetch.git" + "url": "git+https://github.com/npm/npm-registry-fetch.git" }, "keywords": [ "npm", @@ -34,32 +31,38 @@ "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "make-fetch-happen": "^10.0.6", - "minipass": "^3.1.6", - "minipass-fetch": "^2.0.3", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0" + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "cacache": "^16.0.2", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", + "cacache": "^20.0.0", "nock": "^13.2.4", "require-inject": "^1.4.4", - "ssri": "^9.0.0", + "ssri": "^13.0.0", "tap": "^16.0.1" }, "tap": { "check-coverage": true, - "test-ignore": "test[\\\\/](util|cache)[\\\\/]" + "test-ignore": "test[\\\\/](util|cache)[\\\\/]", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.28.0", + "publish": "true" } } diff --git a/node_modules/npm-user-validate/lib/index.js b/node_modules/npm-user-validate/lib/index.js new file mode 100644 index 0000000000000..379a31d2720e3 --- /dev/null +++ b/node_modules/npm-user-validate/lib/index.js @@ -0,0 +1,61 @@ +exports.email = email +exports.pw = pw +exports.username = username +var requirements = exports.requirements = { + username: { + length: 'Name length must be less than or equal to 214 characters long', + lowerCase: 'Name must be lowercase', + urlSafe: 'Name may not contain non-url-safe chars', + dot: 'Name may not start with "."', + illegal: 'Name may not contain illegal character', + }, + password: {}, + email: { + length: 'Email length must be less then or equal to 254 characters long', + valid: 'Email must be an email address', + }, +} + +var illegalCharacterRe = new RegExp('([' + [ + "'", +].join() + '])') + +function username (un) { + if (un !== un.toLowerCase()) { + return new Error(requirements.username.lowerCase) + } + + if (un !== encodeURIComponent(un)) { + return new Error(requirements.username.urlSafe) + } + + if (un.charAt(0) === '.') { + return new Error(requirements.username.dot) + } + + if (un.length > 214) { + return new Error(requirements.username.length) + } + + var illegal = un.match(illegalCharacterRe) + if (illegal) { + return new Error(requirements.username.illegal + ' "' + illegal[0] + '"') + } + + return null +} + +function email (em) { + if (em.length > 254) { + return new Error(requirements.email.length) + } + if (!em.match(/^[^@]+@.+\..+$/)) { + return new Error(requirements.email.valid) + } + + return null +} + +function pw () { + return null +} diff --git a/node_modules/npm-user-validate/npm-user-validate.js b/node_modules/npm-user-validate/npm-user-validate.js deleted file mode 100644 index ffd8791c7eb95..0000000000000 --- a/node_modules/npm-user-validate/npm-user-validate.js +++ /dev/null @@ -1,61 +0,0 @@ -exports.email = email -exports.pw = pw -exports.username = username -var requirements = exports.requirements = { - username: { - length: 'Name length must be less than or equal to 214 characters long', - lowerCase: 'Name must be lowercase', - urlSafe: 'Name may not contain non-url-safe chars', - dot: 'Name may not start with "."', - illegal: 'Name may not contain illegal character' - }, - password: {}, - email: { - length: 'Email length must be less then or equal to 254 characters long', - valid: 'Email must be an email address' - } -} - -var illegalCharacterRe = new RegExp('([' + [ - "'" -].join() + '])') - -function username (un) { - if (un !== un.toLowerCase()) { - return new Error(requirements.username.lowerCase) - } - - if (un !== encodeURIComponent(un)) { - return new Error(requirements.username.urlSafe) - } - - if (un.charAt(0) === '.') { - return new Error(requirements.username.dot) - } - - if (un.length > 214) { - return new Error(requirements.username.length) - } - - var illegal = un.match(illegalCharacterRe) - if (illegal) { - return new Error(requirements.username.illegal + ' "' + illegal[0] + '"') - } - - return null -} - -function email (em) { - if (em.length > 254) { - return new Error(requirements.email.length) - } - if (!em.match(/^[^@]+@.+\..+$/)) { - return new Error(requirements.email.valid) - } - - return null -} - -function pw (pw) { - return null -} diff --git a/node_modules/npm-user-validate/package.json b/node_modules/npm-user-validate/package.json index ffcf1be7f5c62..b7a30835afb7b 100644 --- a/node_modules/npm-user-validate/package.json +++ b/node_modules/npm-user-validate/package.json @@ -1,29 +1,50 @@ { "name": "npm-user-validate", - "version": "1.0.1", + "version": "4.0.0", "description": "User validations for npm", - "main": "npm-user-validate.js", + "main": "lib/index.js", "devDependencies": { - "standard": "^8.4.0", - "standard-version": "^3.0.0", - "tap": "^7.1.2" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.2" }, "scripts": { - "pretest": "standard", - "test": "tap --100 test/*.js" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "git://github.com/npm/npm-user-validate.git" + "url": "git+https://github.com/npm/npm-user-validate.git" }, "keywords": [ "npm", "validation", "registry" ], - "author": "Robert Kowalski <rok@kowalski.gd>", + "author": "GitHub Inc.", "license": "BSD-2-Clause", "files": [ - "npm-user-validate.js" - ] + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + } } diff --git a/node_modules/npmlog/LICENSE.md b/node_modules/npmlog/LICENSE.md deleted file mode 100644 index 5fc208ff122e0..0000000000000 --- a/node_modules/npmlog/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -<!-- This file is automatically added by @npmcli/template-oss. Do not edit. --> - -ISC License - -Copyright npm, Inc. - -Permission to use, copy, modify, and/or distribute this -software for any purpose with or without fee is hereby -granted, provided that the above copyright notice and this -permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL -WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO -EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE -USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/npmlog/lib/log.js b/node_modules/npmlog/lib/log.js deleted file mode 100644 index be650c6a42608..0000000000000 --- a/node_modules/npmlog/lib/log.js +++ /dev/null @@ -1,404 +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) { - return - } - - this.progressEnabled = true - this.tracker.on('change', this.showProgress) - if (this._paused) { - return - } - - 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/node_modules/npmlog/package.json b/node_modules/npmlog/package.json deleted file mode 100644 index bdb5a384781ce..0000000000000 --- a/node_modules/npmlog/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "author": "GitHub Inc.", - "name": "npmlog", - "description": "logger for npm", - "version": "6.0.2", - "repository": { - "type": "git", - "url": "https://github.com/npm/npmlog.git" - }, - "main": "lib/log.js", - "files": [ - "bin/", - "lib/" - ], - "scripts": { - "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", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "snap": "tap", - "template-oss-apply": "template-oss-apply --force" - }, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.4.1", - "tap": "^16.0.1" - }, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "tap": { - "branches": 95 - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.4.1" - } -} diff --git a/node_modules/once/LICENSE b/node_modules/once/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/once/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/once/once.js b/node_modules/once/once.js deleted file mode 100644 index 235406736d9d9..0000000000000 --- a/node_modules/once/once.js +++ /dev/null @@ -1,42 +0,0 @@ -var wrappy = require('wrappy') -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) - -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) - -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f -} diff --git a/node_modules/once/package.json b/node_modules/once/package.json deleted file mode 100644 index 16815b2fa1119..0000000000000 --- a/node_modules/once/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "once", - "version": "1.4.0", - "description": "Run a function exactly one time", - "main": "once.js", - "directories": { - "test": "test" - }, - "dependencies": { - "wrappy": "1" - }, - "devDependencies": { - "tap": "^7.0.1" - }, - "scripts": { - "test": "tap test/*.js" - }, - "files": [ - "once.js" - ], - "repository": { - "type": "git", - "url": "git://github.com/isaacs/once" - }, - "keywords": [ - "once", - "function", - "one", - "single" - ], - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "license": "ISC" -} diff --git a/node_modules/opener/LICENSE.txt b/node_modules/opener/LICENSE.txt deleted file mode 100644 index f74bd1310f4e0..0000000000000 --- a/node_modules/opener/LICENSE.txt +++ /dev/null @@ -1,47 +0,0 @@ -Dual licensed under WTFPL and MIT: - ---- - -Copyright © 2012–2020 Domenic Denicola <d@domenic.me> - -This work is free. You can redistribute it and/or modify it under the -terms of the Do What The Fuck You Want To Public License, Version 2, -as published by Sam Hocevar. See below for more details. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. - ---- - -The MIT License (MIT) - -Copyright © 2012–2020 Domenic Denicola <d@domenic.me> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/opener/bin/opener-bin.js b/node_modules/opener/bin/opener-bin.js deleted file mode 100755 index a051ea8f03f19..0000000000000 --- a/node_modules/opener/bin/opener-bin.js +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env node -"use strict"; - -var opener = require(".."); - -opener(process.argv.slice(2), function (error) { - if (error) { - throw error; - } -}); diff --git a/node_modules/opener/lib/opener.js b/node_modules/opener/lib/opener.js deleted file mode 100644 index 08888c6bb8a2a..0000000000000 --- a/node_modules/opener/lib/opener.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict"; -var childProcess = require("child_process"); -var os = require("os"); - -module.exports = function opener(args, options, callback) { - var platform = process.platform; - - // Attempt to detect Windows Subystem for Linux (WSL). WSL itself as Linux (which works in most cases), but in - // this specific case we need to treat it as actually being Windows. The "Windows-way" of opening things through - // cmd.exe works just fine here, whereas using xdg-open does not, since there is no X Windows in WSL. - if (platform === "linux" && os.release().indexOf("Microsoft") !== -1) { - platform = "win32"; - } - - // http://stackoverflow.com/q/1480971/3191, but see below for Windows. - var command; - switch (platform) { - case "win32": { - command = "cmd.exe"; - break; - } - case "darwin": { - command = "open"; - break; - } - default: { - command = "xdg-open"; - break; - } - } - - if (typeof args === "string") { - args = [args]; - } - - if (typeof options === "function") { - callback = options; - options = {}; - } - - if (options && typeof options === "object" && options.command) { - if (platform === "win32") { - // *always* use cmd on windows - args = [options.command].concat(args); - } else { - command = options.command; - } - } - - if (platform === "win32") { - // On Windows, we really want to use the "start" command. But, the rules regarding arguments with spaces, and - // escaping them with quotes, can get really arcane. So the easiest way to deal with this is to pass off the - // responsibility to "cmd /c", which has that logic built in. - // - // Furthermore, if "cmd /c" double-quoted the first parameter, then "start" will interpret it as a window title, - // so we need to add a dummy empty-string window title: http://stackoverflow.com/a/154090/3191 - // - // Additionally, on Windows ampersand and caret need to be escaped when passed to "start" - args = args.map(function (value) { - return value.replace(/[&^]/g, "^$&"); - }); - args = ["/c", "start", "\"\""].concat(args); - } - - return childProcess.execFile(command, args, options, callback); -}; diff --git a/node_modules/opener/package.json b/node_modules/opener/package.json deleted file mode 100644 index 0af377d15f72a..0000000000000 --- a/node_modules/opener/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "opener", - "description": "Opens stuff, like webpages and files and executables, cross-platform", - "version": "1.5.2", - "author": "Domenic Denicola <d@domenic.me> (https://domenic.me/)", - "license": "(WTFPL OR MIT)", - "repository": "domenic/opener", - "main": "lib/opener.js", - "bin": "bin/opener-bin.js", - "files": [ - "lib/", - "bin/" - ], - "scripts": { - "lint": "eslint ." - }, - "devDependencies": { - "eslint": "^7.7.0" - } -} diff --git a/node_modules/p-map/index.d.ts b/node_modules/p-map/index.d.ts deleted file mode 100644 index bcbe0afcee88d..0000000000000 --- a/node_modules/p-map/index.d.ts +++ /dev/null @@ -1,67 +0,0 @@ -declare namespace pMap { - interface Options { - /** - Number of concurrently pending promises returned by `mapper`. - - Must be an integer from 1 and up or `Infinity`. - - @default Infinity - */ - readonly concurrency?: number; - - /** - When set to `false`, instead of stopping when a promise rejects, it will wait for all the promises to settle and then reject with an [aggregated error](https://github.com/sindresorhus/aggregate-error) containing all the errors from the rejected promises. - - @default true - */ - readonly stopOnError?: boolean; - } - - /** - Function which is called for every item in `input`. Expected to return a `Promise` or value. - - @param element - Iterated element. - @param index - Index of the element in the source array. - */ - type Mapper<Element = any, NewElement = unknown> = ( - element: Element, - index: number - ) => NewElement | Promise<NewElement>; -} - -/** -@param input - Iterated over concurrently in the `mapper` function. -@param mapper - Function which is called for every item in `input`. Expected to return a `Promise` or value. -@returns A `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned from `mapper` in `input` order. - -@example -``` -import pMap = require('p-map'); -import got = require('got'); - -const sites = [ - getWebsiteFromUsername('https://sindresorhus'), //=> Promise - 'https://ava.li', - 'https://github.com' -]; - -(async () => { - const mapper = async site => { - const {requestUrl} = await got.head(site); - return requestUrl; - }; - - const result = await pMap(sites, mapper, {concurrency: 2}); - - console.log(result); - //=> ['https://sindresorhus.com/', 'https://ava.li/', 'https://github.com/'] -})(); -``` -*/ -declare function pMap<Element, NewElement>( - input: Iterable<Element>, - mapper: pMap.Mapper<Element, NewElement>, - options?: pMap.Options -): Promise<NewElement[]>; - -export = pMap; diff --git a/node_modules/p-map/index.js b/node_modules/p-map/index.js index c11a28512a473..f713b9bf363b0 100644 --- a/node_modules/p-map/index.js +++ b/node_modules/p-map/index.js @@ -1,49 +1,107 @@ -'use strict'; -const AggregateError = require('aggregate-error'); - -module.exports = async ( +export default async function pMap( iterable, mapper, { - concurrency = Infinity, - stopOnError = true - } = {} -) => { - return new Promise((resolve, reject) => { + concurrency = Number.POSITIVE_INFINITY, + stopOnError = true, + signal, + } = {}, +) { + return new Promise((resolve_, reject_) => { + if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) { + throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`); + } + if (typeof mapper !== 'function') { throw new TypeError('Mapper function is required'); } - if (!((Number.isSafeInteger(concurrency) || concurrency === Infinity) && concurrency >= 1)) { + if (!((Number.isSafeInteger(concurrency) && concurrency >= 1) || concurrency === Number.POSITIVE_INFINITY)) { throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`); } const result = []; const errors = []; - const iterator = iterable[Symbol.iterator](); + const skippedIndexesMap = new Map(); let isRejected = false; + let isResolved = false; let isIterableDone = false; let resolvingCount = 0; let currentIndex = 0; + const iterator = iterable[Symbol.iterator] === undefined ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator](); + + const signalListener = () => { + reject(signal.reason); + }; - const next = () => { - if (isRejected) { + const cleanup = () => { + signal?.removeEventListener('abort', signalListener); + }; + + const resolve = value => { + resolve_(value); + cleanup(); + }; + + const reject = reason => { + isRejected = true; + isResolved = true; + reject_(reason); + cleanup(); + }; + + if (signal) { + if (signal.aborted) { + reject(signal.reason); + } + + signal.addEventListener('abort', signalListener, {once: true}); + } + + const next = async () => { + if (isResolved) { return; } - const nextItem = iterator.next(); + const nextItem = await iterator.next(); + const index = currentIndex; currentIndex++; + // Note: `iterator.next()` can be called many times in parallel. + // This can cause multiple calls to this `next()` function to + // receive a `nextItem` with `done === true`. + // The shutdown logic that rejects/resolves must be protected + // so it runs only one time as the `skippedIndex` logic is + // non-idempotent. if (nextItem.done) { isIterableDone = true; - if (resolvingCount === 0) { - if (!stopOnError && errors.length !== 0) { - reject(new AggregateError(errors)); - } else { + if (resolvingCount === 0 && !isResolved) { + if (!stopOnError && errors.length > 0) { + reject(new AggregateError(errors)); // eslint-disable-line unicorn/error-message + return; + } + + isResolved = true; + + if (skippedIndexesMap.size === 0) { resolve(result); + return; + } + + const pureResult = []; + + // Support multiple `pMapSkip`'s. + for (const [index, value] of result.entries()) { + if (skippedIndexesMap.get(index) === pMapSkip) { + continue; + } + + pureResult.push(value); } + + resolve(pureResult); } return; @@ -51,31 +109,175 @@ module.exports = async ( resolvingCount++; + // Intentionally detached (async () => { try { const element = await nextItem.value; - result[index] = await mapper(element, index); + + if (isResolved) { + return; + } + + const value = await mapper(element, index); + + // Use Map to stage the index of the element. + if (value === pMapSkip) { + skippedIndexesMap.set(index, value); + } + + result[index] = value; + resolvingCount--; - next(); + await next(); } catch (error) { if (stopOnError) { - isRejected = true; reject(error); } else { errors.push(error); resolvingCount--; - next(); + + // In that case we can't really continue regardless of `stopOnError` state + // since an iterable is likely to continue throwing after it throws once. + // If we continue calling `next()` indefinitely we will likely end up + // in an infinite loop of failed iteration. + try { + await next(); + } catch (error) { + reject(error); + } } } })(); }; - for (let i = 0; i < concurrency; i++) { - next(); + // Create the concurrent runners in a detached (non-awaited) + // promise. We need this so we can await the `next()` calls + // to stop creating runners before hitting the concurrency limit + // if the iterable has already been marked as done. + // NOTE: We *must* do this for async iterators otherwise we'll spin up + // infinite `next()` calls by default and never start the event loop. + (async () => { + for (let index = 0; index < concurrency; index++) { + try { + // eslint-disable-next-line no-await-in-loop + await next(); + } catch (error) { + reject(error); + break; + } - if (isIterableDone) { - break; + if (isIterableDone || isRejected) { + break; + } } - } + })(); }); -}; +} + +export function pMapIterable( + iterable, + mapper, + { + concurrency = Number.POSITIVE_INFINITY, + backpressure = concurrency, + } = {}, +) { + if (iterable[Symbol.iterator] === undefined && iterable[Symbol.asyncIterator] === undefined) { + throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`); + } + + if (typeof mapper !== 'function') { + throw new TypeError('Mapper function is required'); + } + + if (!((Number.isSafeInteger(concurrency) && concurrency >= 1) || concurrency === Number.POSITIVE_INFINITY)) { + throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`); + } + + if (!((Number.isSafeInteger(backpressure) && backpressure >= concurrency) || backpressure === Number.POSITIVE_INFINITY)) { + throw new TypeError(`Expected \`backpressure\` to be an integer from \`concurrency\` (${concurrency}) and up or \`Infinity\`, got \`${backpressure}\` (${typeof backpressure})`); + } + + return { + async * [Symbol.asyncIterator]() { + const iterator = iterable[Symbol.asyncIterator] === undefined ? iterable[Symbol.iterator]() : iterable[Symbol.asyncIterator](); + + const promises = []; + let pendingPromisesCount = 0; + let isDone = false; + let index = 0; + + function trySpawn() { + if (isDone || !(pendingPromisesCount < concurrency && promises.length < backpressure)) { + return; + } + + pendingPromisesCount++; + + const promise = (async () => { + const {done, value} = await iterator.next(); + + if (done) { + pendingPromisesCount--; + return {done: true}; + } + + // Spawn if still below concurrency and backpressure limit + trySpawn(); + + try { + const returnValue = await mapper(await value, index++); + + pendingPromisesCount--; + + if (returnValue === pMapSkip) { + const index = promises.indexOf(promise); + + if (index > 0) { + promises.splice(index, 1); + } + } + + // Spawn if still below backpressure limit and just dropped below concurrency limit + trySpawn(); + + return {done: false, value: returnValue}; + } catch (error) { + pendingPromisesCount--; + isDone = true; + return {error}; + } + })(); + + promises.push(promise); + } + + trySpawn(); + + while (promises.length > 0) { + const {error, done, value} = await promises[0]; // eslint-disable-line no-await-in-loop + + promises.shift(); + + if (error) { + throw error; + } + + if (done) { + return; + } + + // Spawn if just dropped below backpressure limit and below the concurrency limit + trySpawn(); + + if (value === pMapSkip) { + continue; + } + + yield value; + } + }, + }; +} + +export const pMapSkip = Symbol('skip'); diff --git a/node_modules/p-map/package.json b/node_modules/p-map/package.json index 042b1af553f2d..6401a2a6a51a9 100644 --- a/node_modules/p-map/package.json +++ b/node_modules/p-map/package.json @@ -1,6 +1,6 @@ { "name": "p-map", - "version": "4.0.0", + "version": "7.0.4", "description": "Map over promises concurrently", "license": "MIT", "repository": "sindresorhus/p-map", @@ -10,8 +10,14 @@ "email": "sindresorhus@gmail.com", "url": "https://sindresorhus.com" }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "default": "./index.js" + }, + "sideEffects": false, "engines": { - "node": ">=10" + "node": ">=18" }, "scripts": { "test": "xo && ava && tsd" @@ -38,16 +44,14 @@ "parallel", "bluebird" ], - "dependencies": { - "aggregate-error": "^3.0.0" - }, "devDependencies": { - "ava": "^2.2.0", - "delay": "^4.1.0", - "in-range": "^2.0.0", - "random-int": "^2.0.0", - "time-span": "^3.1.0", - "tsd": "^0.7.4", - "xo": "^0.27.2" + "ava": "^5.2.0", + "chalk": "^5.3.0", + "delay": "^6.0.0", + "in-range": "^3.0.0", + "random-int": "^3.0.0", + "time-span": "^5.1.0", + "tsd": "^0.29.0", + "xo": "^0.56.0" } } diff --git a/node_modules/p-map/readme.md b/node_modules/p-map/readme.md deleted file mode 100644 index 53a3715747c2c..0000000000000 --- a/node_modules/p-map/readme.md +++ /dev/null @@ -1,89 +0,0 @@ -# p-map [![Build Status](https://travis-ci.org/sindresorhus/p-map.svg?branch=master)](https://travis-ci.org/sindresorhus/p-map) - -> Map over promises concurrently - -Useful when you need to run promise-returning & async functions multiple times with different inputs concurrently. - -## Install - -``` -$ npm install p-map -``` - -## Usage - -```js -const pMap = require('p-map'); -const got = require('got'); - -const sites = [ - getWebsiteFromUsername('https://sindresorhus'), //=> Promise - 'https://ava.li', - 'https://github.com' -]; - -(async () => { - const mapper = async site => { - const {requestUrl} = await got.head(site); - return requestUrl; - }; - - const result = await pMap(sites, mapper, {concurrency: 2}); - - console.log(result); - //=> ['https://sindresorhus.com/', 'https://ava.li/', 'https://github.com/'] -})(); -``` - -## API - -### pMap(input, mapper, options?) - -Returns a `Promise` that is fulfilled when all promises in `input` and ones returned from `mapper` are fulfilled, or rejects if any of the promises reject. The fulfilled value is an `Array` of the fulfilled values returned from `mapper` in `input` order. - -#### input - -Type: `Iterable<Promise | unknown>` - -Iterated over concurrently in the `mapper` function. - -#### mapper(element, index) - -Type: `Function` - -Expected to return a `Promise` or value. - -#### options - -Type: `object` - -##### concurrency - -Type: `number` (Integer)\ -Default: `Infinity`\ -Minimum: `1` - -Number of concurrently pending promises returned by `mapper`. - -##### stopOnError - -Type: `boolean`\ -Default: `true` - -When set to `false`, instead of stopping when a promise rejects, it will wait for all the promises to settle and then reject with an [aggregated error](https://github.com/sindresorhus/aggregate-error) containing all the errors from the rejected promises. - -## p-map for enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of p-map and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-p-map?utm_source=npm-p-map&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - -## Related - -- [p-all](https://github.com/sindresorhus/p-all) - Run promise-returning & async functions concurrently with optional limited concurrency -- [p-filter](https://github.com/sindresorhus/p-filter) - Filter promises concurrently -- [p-times](https://github.com/sindresorhus/p-times) - Run promise-returning & async functions a specific number of times concurrently -- [p-props](https://github.com/sindresorhus/p-props) - Like `Promise.all()` but for `Map` and `Object` -- [p-map-series](https://github.com/sindresorhus/p-map-series) - Map over promises serially -- [p-queue](https://github.com/sindresorhus/p-queue) - Promise queue with concurrency control -- [More…](https://github.com/sindresorhus/promise-fun) diff --git a/node_modules/pacote/bin/index.js b/node_modules/pacote/bin/index.js new file mode 100755 index 0000000000000..f35b62ca71a53 --- /dev/null +++ b/node_modules/pacote/bin/index.js @@ -0,0 +1,158 @@ +#!/usr/bin/env node + +const run = conf => { + const pacote = require('../') + switch (conf._[0]) { + case 'resolve': + case 'manifest': + case 'packument': + if (conf._[0] === 'resolve' && conf.long) { + return pacote.manifest(conf._[1], conf).then(mani => ({ + resolved: mani._resolved, + integrity: mani._integrity, + from: mani._from, + })) + } + return pacote[conf._[0]](conf._[1], conf) + + case 'tarball': + if (!conf._[2] || conf._[2] === '-') { + return pacote.tarball.stream(conf._[1], stream => { + stream.pipe( + conf.testStdout || + /* istanbul ignore next */ + process.stdout + ) + // make sure it resolves something falsey + return stream.promise().then(() => { + return false + }) + }, conf) + } else { + return pacote.tarball.file(conf._[1], conf._[2], conf) + } + + case 'extract': + return pacote.extract(conf._[1], conf._[2], conf) + + default: /* istanbul ignore next */ { + throw new Error(`bad command: ${conf._[0]}`) + } + } +} + +const version = require('../package.json').version +const usage = () => +`Pacote - The JavaScript Package Handler, v${version} + +Usage: + + pacote resolve <spec> + Resolve a specifier and output the fully resolved target + Returns integrity and from if '--long' flag is set. + + pacote manifest <spec> + Fetch a manifest and print to stdout + + pacote packument <spec> + Fetch a full packument and print to stdout + + pacote tarball <spec> [<filename>] + Fetch a package tarball and save to <filename> + If <filename> is missing or '-', the tarball will be streamed to stdout. + + pacote extract <spec> <folder> + Extract a package to the destination folder. + +Configuration values all match the names of configs passed to npm, or +options passed to Pacote. Additional flags for this executable: + + --long Print an object from 'resolve', including integrity and spec. + --json Print result objects as JSON rather than node's default. + (This is the default if stdout is not a TTY.) + --help -h Print this helpful text. + +For example '--cache=/path/to/folder' will use that folder as the cache. +` + +const shouldJSON = (conf, result) => + conf.json || + !process.stdout.isTTY && + conf.json === undefined && + result && + typeof result === 'object' + +const pretty = (conf, result) => + shouldJSON(conf, result) ? JSON.stringify(result, 0, 2) : result + +let addedLogListener = false +const main = args => { + const conf = parse(args) + if (conf.help || conf.h) { + return console.log(usage()) + } + + if (!addedLogListener) { + process.on('log', console.error) + addedLogListener = true + } + + try { + return run(conf) + .then(result => result && console.log(pretty(conf, result))) + .catch(er => { + console.error(er) + process.exit(1) + }) + } catch (er) { + console.error(er.message) + console.error(usage()) + } +} + +const parseArg = arg => { + const split = arg.slice(2).split('=') + const k = split.shift() + const v = split.join('=') + const no = /^no-/.test(k) && !v + const key = (no ? k.slice(3) : k) + .replace(/^tag$/, 'defaultTag') + .replace(/-([a-z])/g, (_, c) => c.toUpperCase()) + const value = v ? v.replace(/^~/, process.env.HOME) : !no + return { key, value } +} + +const parse = args => { + const conf = { + _: [], + cache: process.env.HOME + '/.npm/_cacache', + } + let dashdash = false + args.forEach(arg => { + if (dashdash) { + conf._.push(arg) + } else if (arg === '--') { + dashdash = true + } else if (arg === '-h') { + conf.help = true + } else if (/^--/.test(arg)) { + const { key, value } = parseArg(arg) + conf[key] = value + } else { + conf._.push(arg) + } + }) + return conf +} + +if (module === require.main) { + main(process.argv.slice(2)) +} else { + module.exports = { + main, + run, + usage, + parseArg, + parse, + } +} diff --git a/node_modules/pacote/lib/bin.js b/node_modules/pacote/lib/bin.js deleted file mode 100755 index 4a1f911e42bc5..0000000000000 --- a/node_modules/pacote/lib/bin.js +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env node - -const run = conf => { - const pacote = require('../') - switch (conf._[0]) { - case 'resolve': - case 'manifest': - case 'packument': - if (conf._[0] === 'resolve' && conf.long) { - return pacote.manifest(conf._[1], conf).then(mani => ({ - resolved: mani._resolved, - integrity: mani._integrity, - from: mani._from, - })) - } - return pacote[conf._[0]](conf._[1], conf) - - case 'tarball': - if (!conf._[2] || conf._[2] === '-') { - return pacote.tarball.stream(conf._[1], stream => { - stream.pipe(conf.testStdout || - /* istanbul ignore next */ process.stdout) - // make sure it resolves something falsey - return stream.promise().then(() => {}) - }, conf) - } else { - return pacote.tarball.file(conf._[1], conf._[2], conf) - } - - case 'extract': - return pacote.extract(conf._[1], conf._[2], conf) - - default: /* istanbul ignore next */ { - throw new Error(`bad command: ${conf._[0]}`) - } - } -} - -const version = require('../package.json').version -const usage = () => -`Pacote - The JavaScript Package Handler, v${version} - -Usage: - - pacote resolve <spec> - Resolve a specifier and output the fully resolved target - Returns integrity and from if '--long' flag is set. - - pacote manifest <spec> - Fetch a manifest and print to stdout - - pacote packument <spec> - Fetch a full packument and print to stdout - - pacote tarball <spec> [<filename>] - Fetch a package tarball and save to <filename> - If <filename> is missing or '-', the tarball will be streamed to stdout. - - pacote extract <spec> <folder> - Extract a package to the destination folder. - -Configuration values all match the names of configs passed to npm, or -options passed to Pacote. Additional flags for this executable: - - --long Print an object from 'resolve', including integrity and spec. - --json Print result objects as JSON rather than node's default. - (This is the default if stdout is not a TTY.) - --help -h Print this helpful text. - -For example '--cache=/path/to/folder' will use that folder as the cache. -` - -const shouldJSON = (conf, result) => - conf.json || - !process.stdout.isTTY && - conf.json === undefined && - result && - typeof result === 'object' - -const pretty = (conf, result) => - shouldJSON(conf, result) ? JSON.stringify(result, 0, 2) : result - -let addedLogListener = false -const main = args => { - const conf = parse(args) - if (conf.help || conf.h) { - return console.log(usage()) - } - - if (!addedLogListener) { - process.on('log', console.error) - addedLogListener = true - } - - try { - return run(conf) - .then(result => result && console.log(pretty(conf, result))) - .catch(er => { - console.error(er) - process.exit(1) - }) - } catch (er) { - console.error(er.message) - console.error(usage()) - } -} - -const parseArg = arg => { - const split = arg.slice(2).split('=') - const k = split.shift() - const v = split.join('=') - const no = /^no-/.test(k) && !v - const key = (no ? k.slice(3) : k) - .replace(/^tag$/, 'defaultTag') - .replace(/-([a-z])/g, (_, c) => c.toUpperCase()) - const value = v ? v.replace(/^~/, process.env.HOME) : !no - return { key, value } -} - -const parse = args => { - const conf = { - _: [], - cache: process.env.HOME + '/.npm/_cacache', - } - let dashdash = false - args.forEach(arg => { - if (dashdash) { - conf._.push(arg) - } else if (arg === '--') { - dashdash = true - } else if (arg === '-h') { - conf.help = true - } else if (/^--/.test(arg)) { - const { key, value } = parseArg(arg) - conf[key] = value - } else { - conf._.push(arg) - } - }) - return conf -} - -if (module === require.main) { - main(process.argv.slice(2)) -} else { - module.exports = { - main, - run, - usage, - parseArg, - parse, - } -} diff --git a/node_modules/pacote/lib/dir.js b/node_modules/pacote/lib/dir.js index 502379810a006..04846eb8a6e22 100644 --- a/node_modules/pacote/lib/dir.js +++ b/node_modules/pacote/lib/dir.js @@ -1,21 +1,21 @@ +const { resolve } = require('node:path') +const packlist = require('npm-packlist') +const runScript = require('@npmcli/run-script') +const tar = require('tar') +const { Minipass } = require('minipass') const Fetcher = require('./fetcher.js') const FileFetcher = require('./file.js') -const Minipass = require('minipass') +const _ = require('./util/protected.js') const tarCreateOptions = require('./util/tar-create-options.js') -const packlist = require('npm-packlist') -const tar = require('tar') -const _prepareDir = Symbol('_prepareDir') -const { resolve } = require('path') -const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') - -const runScript = require('@npmcli/run-script') -const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') class DirFetcher extends Fetcher { constructor (spec, opts) { super(spec, opts) // just the fully resolved filename this.resolved = this.spec.fetchSpec + + this.tree = opts.tree || null + this.Arborist = opts.Arborist || null } // exposes tarCreateOptions as public API @@ -27,28 +27,27 @@ class DirFetcher extends Fetcher { return ['directory'] } - [_prepareDir] () { + #prepareDir () { return this.manifest().then(mani => { if (!mani.scripts || !mani.scripts.prepare) { return } + if (this.opts.ignoreScripts) { + return + } // we *only* run prepare. // pre/post-pack is run by the npm CLI for publish and pack, // 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({ + // this || undefined is because runScript will be unhappy with the default null value + scriptShell: this.opts.scriptShell || undefined, pkg: mani, event: 'prepare', path: this.resolved, - stdioString: true, stdio, - banner, env: { npm_package_resolved: this.resolved, npm_package_integrity: this.integrity, @@ -58,7 +57,11 @@ class DirFetcher extends Fetcher { }) } - [_tarballFromResolved] () { + [_.tarballFromResolved] () { + if (!this.tree && !this.Arborist) { + throw new Error('DirFetcher requires either a tree or an Arborist constructor to pack') + } + const stream = new Minipass() stream.resolved = this.resolved stream.integrity = this.integrity @@ -67,8 +70,14 @@ class DirFetcher extends Fetcher { // run the prepare script, get the list of files, and tar it up // pipe to the stream, and proxy errors the chain. - this[_prepareDir]() - .then(() => packlist({ path: this.resolved, prefix, workspaces })) + this.#prepareDir() + .then(async () => { + if (!this.tree) { + const arb = new this.Arborist({ path: this.resolved }) + this.tree = await arb.loadActual() + } + return packlist(this.tree, { path: this.resolved, prefix, workspaces }) + }) .then(files => tar.c(tarCreateOptions(this.package), files) .on('error', er => stream.emit('error', er)).pipe(stream)) .catch(er => stream.emit('error', er)) @@ -80,7 +89,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/node_modules/pacote/lib/fetcher.js b/node_modules/pacote/lib/fetcher.js index 5f93e703bca4b..8d52d28eefd4d 100644 --- a/node_modules/pacote/lib/fetcher.js +++ b/node_modules/pacote/lib/fetcher.js @@ -3,49 +3,26 @@ // It handles the unpacking and retry logic that is shared among // all of the other Fetcher types. +const { basename, dirname } = require('node:path') +const { rm, mkdir } = require('node:fs/promises') +const PackageJson = require('@npmcli/package-json') +const cacache = require('cacache') +const fsm = require('fs-minipass') +const getContents = require('@npmcli/installed-package-contents') const npa = require('npm-package-arg') +const retry = require('promise-retry') const ssri = require('ssri') -const { promisify } = require('util') -const { basename, dirname } = require('path') -const rimraf = promisify(require('rimraf')) const tar = require('tar') -const log = require('proc-log') -const retry = require('promise-retry') -const fsm = require('fs-minipass') -const cacache = require('cacache') +const { Minipass } = require('minipass') +const { log } = require('proc-log') +const _ = require('./util/protected.js') +const cacheDir = require('./util/cache-dir.js') 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 Minipass = require('minipass') - -// we only change ownership on unix platforms, and only if uid is 0 -const selfOwner = process.getuid && process.getuid() === 0 ? { - uid: 0, - gid: process.getgid(), -} : null -const chownr = selfOwner ? promisify(require('chownr')) : null -const inferOwner = selfOwner ? require('infer-owner') : null -const mkdirp = require('mkdirp') -const cacheDir = require('./util/cache-dir.js') -// Private methods. -// Child classes should not have to override these. -// Users should never call them. -const _chown = Symbol('_chown') -const _extract = Symbol('_extract') -const _mkdir = Symbol('_mkdir') -const _empty = Symbol('_empty') -const _toFile = Symbol('_toFile') -const _tarxOptions = Symbol('_tarxOptions') -const _entryMode = Symbol('_entryMode') -const _istream = Symbol('_istream') -const _assertType = Symbol('_assertType') -const _tarballFromCache = Symbol('_tarballFromCache') -const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') -const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches') -const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') +// 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) class FetcherBase { constructor (spec, opts) { @@ -65,12 +42,13 @@ class FetcherBase { this.from = this.spec.registry ? `${this.spec.name}@${this.spec.rawSpec}` : this.spec.saveSpec - this[_assertType]() + this.#assertType() // clone the opts object so that others aren't upset when we mutate it // by adding/modifying the integrity value. this.opts = { ...opts } - this.cache = opts.cache || cacheDir() + this.cache = opts.cache || cacheDir().cacache + this.tufCache = opts.tufCache || cacheDir().tufcache this.resolved = opts.resolved || null // default to caching/verifying with sha512, that's what we usually have @@ -100,11 +78,9 @@ class FetcherBase { this.before = opts.before this.fullMetadata = this.before ? true : !!opts.fullMetadata this.fullReadJson = !!opts.fullReadJson - if (this.fullReadJson) { - this[_readPackageJson] = readPackageJson - } else { - this[_readPackageJson] = readPackageJsonFast - } + this[_.readPackageJson] = this.fullReadJson + ? packageJsonPrepare + : packageJsonNormalize // rrh is a registry hostname or 'never' or 'always' // defaults to registry.npmjs.org @@ -195,7 +171,7 @@ class FetcherBase { // private, should be overridden. // Note that they should *not* calculate or check integrity or cache, // but *just* return the raw tarball data stream. - [_tarballFromResolved] () { + [_.tarballFromResolved] () { throw this.notImplementedError } @@ -211,17 +187,25 @@ class FetcherBase { // private // Note: cacache will raise a EINTEGRITY error if the integrity doesn't match - [_tarballFromCache] () { - return cacache.get.stream.byDigest(this.cache, this.integrity, this.opts) + #tarballFromCache () { + const startTime = Date.now() + const stream = cacache.get.stream.byDigest(this.cache, this.integrity, this.opts) + const elapsedTime = Date.now() - startTime + // cache is good, so log it as a hit in particular since there was no fetch logged + log.http( + 'cache', + `${this.spec} ${elapsedTime}ms (cache hit)` + ) + return stream } - get [_cacheFetches] () { + get [_.cacheFetches] () { return true } - [_istream] (stream) { + #istream (stream) { // if not caching this, just return it - if (!this.opts.cache || !this[_cacheFetches]) { + if (!this.opts.cache || !this[_.cacheFetches]) { // instead of creating a new integrity stream, we only piggyback on the // provided stream's events if (stream.hasIntegrityEmitter) { @@ -254,6 +238,7 @@ class FetcherBase { cstream.on('error', err => stream.emit('error', err)) stream.pipe(cstream) + // eslint-disable-next-line promise/catch-or-return cstream.promise().catch(() => {}).then(() => middleStream.end()) return middleStream } @@ -269,8 +254,11 @@ class FetcherBase { } // override the types getter - get types () {} - [_assertType] () { + get types () { + return false + } + + #assertType () { if (this.types && !this.types.includes(this.spec.type)) { throw new TypeError(`Wrong spec type (${ this.spec.type @@ -309,7 +297,7 @@ class FetcherBase { !this.preferOnline && this.integrity && this.resolved - ) ? streamHandler(this[_tarballFromCache]()).catch(er => { + ) ? streamHandler(this.#tarballFromCache()).catch(er => { if (this.isDataCorruptionError(er)) { log.warn('tarball', `cached data for ${ this.spec @@ -332,7 +320,7 @@ class FetcherBase { }. Extracting by manifest.`) } return this.resolve().then(() => retry(tryAgain => - streamHandler(this[_istream](this[_tarballFromResolved]())) + streamHandler(this.#istream(this[_.tarballFromResolved]())) .catch(streamErr => { // Most likely data integrity. A cache ENOENT error is unlikely // here, since we're definitely not reading from the cache, but it @@ -355,47 +343,24 @@ class FetcherBase { return cacache.rm.content(this.cache, this.integrity, this.opts) } - async [_chown] (path, uid, gid) { - return selfOwner && (selfOwner.gid !== gid || selfOwner.uid !== uid) - ? chownr(path, uid, gid) - : /* istanbul ignore next - we don't test in root-owned folders */ null - } - - [_empty] (path) { + #empty (path) { return getContents({ path, depth: 1 }).then(contents => Promise.all( - contents.map(entry => rimraf(entry)))) + contents.map(entry => rm(entry, { recursive: true, force: true })))) } - [_mkdir] (dest) { - // if we're bothering to do owner inference, then do it. - // otherwise just make the dir, and return an empty object. - // always empty the dir dir to start with, but do so - // _after_ inferring the owner, in case there's an existing folder - // there that we would want to preserve which differs from the - // parent folder (rare, but probably happens sometimes). - return !inferOwner - ? this[_empty](dest).then(() => mkdirp(dest)).then(() => ({})) - : inferOwner(dest).then(({ uid, gid }) => - this[_empty](dest) - .then(() => mkdirp(dest)) - .then(made => { - // ignore the || dest part in coverage. It's there to handle - // race conditions where the dir may be made by someone else - // after being removed by us. - const dir = made || /* istanbul ignore next */ dest - return this[_chown](dir, uid, gid) - }) - .then(() => ({ uid, gid }))) + async #mkdir (dest) { + await this.#empty(dest) + return await mkdir(dest, { recursive: true }) } // extraction is always the same. the only difference is where // the tarball comes from. - extract (dest) { - return this[_mkdir](dest).then(({ uid, gid }) => - this.tarballStream(tarball => this[_extract](dest, tarball, uid, gid))) + async extract (dest) { + await this.#mkdir(dest) + return this.tarballStream((tarball) => this.#extract(dest, tarball)) } - [_toFile] (dest) { + #toFile (dest) { return this.tarballStream(str => new Promise((res, rej) => { const writer = new fsm.WriteStream(dest) str.on('error', er => writer.emit('error', er)) @@ -409,19 +374,15 @@ class FetcherBase { })) } - // don't use this[_mkdir] because we don't want to rimraf anything - tarballFile (dest) { + // don't use this.#mkdir because we don't want to rimraf anything + async tarballFile (dest) { const dir = dirname(dest) - return !inferOwner - ? mkdirp(dir).then(() => this[_toFile](dest)) - : inferOwner(dest).then(({ uid, gid }) => - mkdirp(dir).then(made => this[_toFile](dest) - .then(res => this[_chown](made || dir, uid, gid) - .then(() => res)))) + await mkdir(dir, { recursive: true }) + return this.#toFile(dest) } - [_extract] (dest, tarball, uid, gid) { - const extractor = tar.x(this[_tarxOptions]({ cwd: dest, uid, gid })) + #extract (dest, tarball) { + const extractor = tar.x(this.#tarxOptions({ cwd: dest })) const p = new Promise((resolve, reject) => { extractor.on('end', () => { resolve({ @@ -446,7 +407,7 @@ class FetcherBase { // always ensure that entries are at least as permissive as our configured // dmode/fmode, but never more permissive than the umask allows. - [_entryMode] (path, mode, type) { + #entryMode (path, mode, type) { const m = /Directory|GNUDumpDir/.test(type) ? this.dmode : /File$/.test(type) ? this.fmode : /* istanbul ignore next - should never happen in a pkg */ 0 @@ -457,7 +418,7 @@ class FetcherBase { return ((mode | m) & ~this.umask) | exe | 0o600 } - [_tarxOptions] ({ cwd, uid, gid }) { + #tarxOptions ({ cwd }) { const sawIgnores = new Set() return { cwd, @@ -467,7 +428,7 @@ class FetcherBase { if (/Link$/.test(entry.type)) { return false } - entry.mode = this[_entryMode](entry.path, entry.mode, entry.type) + entry.mode = this.#entryMode(entry.path, entry.mode, entry.type) // this replicates the npm pack behavior where .gitignore files // are treated like .npmignore files, but only if a .npmignore // file is not present. @@ -492,9 +453,9 @@ class FetcherBase { log.warn('tar', code, msg) log.silly('tar', code, msg, data) }, - uid, - gid, umask: this.umask, + // always ignore ownership info from tarball metadata + preserveOwner: false, } } } @@ -508,11 +469,31 @@ const FileFetcher = require('./file.js') const DirFetcher = require('./dir.js') const RemoteFetcher = require('./remote.js') +// possible values for allow: 'all', 'root', 'none' +const canUseGit = (allow = 'all', isRoot = false) => { + if (allow === 'all') { + return true + } + if (allow !== 'none' && isRoot) { + return true + } + return false +} + // Get an appropriate fetcher object from a spec and options FetcherBase.get = (rawSpec, opts = {}) => { const spec = npa(rawSpec, opts.where) switch (spec.type) { case 'git': + if (!canUseGit(opts.allowGit, opts._isRoot)) { + throw Object.assign( + new Error(`Fetching${opts.allowGit === 'root' ? ' non-root' : ''} packages from git has been disabled`), + { + code: 'EALLOWGIT', + package: spec.toString(), + } + ) + } return new GitFetcher(spec, opts) case 'remote': diff --git a/node_modules/pacote/lib/file.js b/node_modules/pacote/lib/file.js index bf99bb86e359e..2021325085e4f 100644 --- a/node_modules/pacote/lib/file.js +++ b/node_modules/pacote/lib/file.js @@ -1,11 +1,9 @@ -const Fetcher = require('./fetcher.js') -const fsm = require('fs-minipass') +const { resolve } = require('node:path') +const { stat, chmod } = require('node:fs/promises') const cacache = require('cacache') -const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') -const _exeBins = Symbol('_exeBins') -const { resolve } = require('path') -const fs = require('fs') -const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') +const fsm = require('fs-minipass') +const Fetcher = require('./fetcher.js') +const _ = require('./util/protected.js') class FileFetcher extends Fetcher { constructor (spec, opts) { @@ -26,7 +24,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), @@ -35,28 +33,28 @@ class FileFetcher extends Fetcher { })) } - [_exeBins] (pkg, dest) { + #exeBins (pkg, dest) { if (!pkg.bin) { 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,11 +62,11 @@ 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[_exeBins](pkg, dest)).then(() => result)) + : this[_.readPackageJson](dest).then(pkg => + this.#exeBins(pkg, dest)).then(() => result)) } - [_tarballFromResolved] () { + [_.tarballFromResolved] () { // create a read stream and return it return new fsm.ReadStream(this.resolved) } diff --git a/node_modules/pacote/lib/git.js b/node_modules/pacote/lib/git.js index 9d84d95fa62ab..077193a86f026 100644 --- a/node_modules/pacote/lib/git.js +++ b/node_modules/pacote/lib/git.js @@ -1,28 +1,18 @@ +const cacache = require('cacache') +const git = require('@npmcli/git') +const npa = require('npm-package-arg') +const pickManifest = require('npm-pick-manifest') +const { Minipass } = require('minipass') +const { log } = require('proc-log') +const DirFetcher = require('./dir.js') const Fetcher = require('./fetcher.js') const FileFetcher = require('./file.js') const RemoteFetcher = require('./remote.js') -const DirFetcher = require('./dir.js') -const hashre = /^[a-f0-9]{40}$/ -const git = require('@npmcli/git') -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 _ = require('./util/protected.js') +const addGitSha = require('./util/add-git-sha.js') const npm = require('./util/npm.js') -const _resolvedFromRepo = Symbol('_resolvedFromRepo') -const _resolvedFromHosted = Symbol('_resolvedFromHosted') -const _resolvedFromClone = Symbol('_resolvedFromClone') -const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') -const _addGitSha = Symbol('_addGitSha') -const addGitSha = require('./util/add-git-sha.js') -const _clone = Symbol('_clone') -const _cloneHosted = Symbol('_cloneHosted') -const _cloneRepo = Symbol('_cloneRepo') -const _setResolvedWithSha = Symbol('_setResolvedWithSha') -const _prepareDir = Symbol('_prepareDir') -const _readPackageJson = Symbol.for('package.Fetcher._readPackageJson') +const hashre = /^[a-f0-9]{40}$/ // get the repository url. // prefer https if there's auth, since ssh will drop that. @@ -61,6 +51,8 @@ class GitFetcher extends Fetcher { } else { this.resolvedSha = '' } + + this.Arborist = opts.Arborist || null } // just exposed to make it easier to test all the combinations @@ -82,8 +74,9 @@ class GitFetcher extends Fetcher { // fetch the git repo and then look at the current hash const h = this.spec.hosted // try to use ssh, fall back to git. - return h ? this[_resolvedFromHosted](h) - : this[_resolvedFromRepo](this.spec.fetchSpec) + return h + ? this.#resolvedFromHosted(h) + : this.#resolvedFromRepo(this.spec.fetchSpec) } // first try https, since that's faster and passphrase-less for @@ -91,23 +84,22 @@ class GitFetcher extends Fetcher { // Fall back to SSH to support private repos // NB: we always store the https url in resolved field if auth // is present, otherwise ssh if the hosted type provides it - [_resolvedFromHosted] (hosted) { - return this[_resolvedFromRepo](hosted.https && hosted.https()) - .catch(er => { - // Throw early since we know pathspec errors will fail again if retried - if (er instanceof git.errors.GitPathspecError) { - throw er - } - const ssh = hosted.sshurl && hosted.sshurl() - // no fallthrough if we can't fall through or have https auth - if (!ssh || hosted.auth) { - throw er - } - return this[_resolvedFromRepo](ssh) - }) + #resolvedFromHosted (hosted) { + return this.#resolvedFromRepo(hosted.https && hosted.https()).catch(er => { + // Throw early since we know pathspec errors will fail again if retried + if (er instanceof git.errors.GitPathspecError) { + throw er + } + const ssh = hosted.sshurl && hosted.sshurl() + // no fallthrough if we can't fall through or have https auth + if (!ssh || hosted.auth) { + throw er + } + return this.#resolvedFromRepo(ssh) + }) } - [_resolvedFromRepo] (gitRemote) { + #resolvedFromRepo (gitRemote) { // XXX make this a custom error class if (!gitRemote) { return Promise.reject(new Error(`No git url for ${this.spec}`)) @@ -128,17 +120,17 @@ class GitFetcher extends Fetcher { // the committish provided isn't in the rev list // things like HEAD~3 or @yesterday can land here. if (!revDoc || !revDoc.sha) { - return this[_resolvedFromClone]() + return this.#resolvedFromClone() } this.resolvedRef = revDoc this.resolvedSha = revDoc.sha - this[_addGitSha](revDoc.sha) + this.#addGitSha(revDoc.sha) return this.resolved }) } - [_setResolvedWithSha] (withSha) { + #setResolvedWithSha (withSha) { // we haven't cloned, so a tgz download is still faster // of course, if it's not a known host, we can't do that. this.resolved = !this.spec.hosted ? withSha @@ -147,18 +139,18 @@ class GitFetcher extends Fetcher { // when we get the git sha, we affix it to our spec to build up // either a git url with a hash, or a tarball download URL - [_addGitSha] (sha) { - this[_setResolvedWithSha](addGitSha(this.spec, sha)) + #addGitSha (sha) { + this.#setResolvedWithSha(addGitSha(this.spec, sha)) } - [_resolvedFromClone] () { + #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 => { + #prepareDir (dir) { + 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 || !( @@ -198,20 +190,24 @@ class GitFetcher extends Fetcher { }) } - [_tarballFromResolved] () { + [_.tarballFromResolved] () { const stream = new Minipass() stream.resolved = this.resolved stream.from = this.from // check it out and then shell out to the DirFetcher tarball packer - this[_clone](dir => this[_prepareDir](dir) + this.#clone(dir => this.#prepareDir(dir) .then(() => new Promise((res, rej) => { + if (!this.Arborist) { + throw new Error('GitFetcher requires an Arborist constructor to pack a tarball') + } const df = new DirFetcher(`file:${dir}`, { ...this.opts, + Arborist: this.Arborist, resolved: null, integrity: null, }) - const dirStream = df[_tarballFromResolved]() + const dirStream = df[_.tarballFromResolved]() dirStream.on('error', rej) dirStream.on('end', res) dirStream.pipe(stream) @@ -229,7 +225,7 @@ class GitFetcher extends Fetcher { // TODO: after cloning, create a tarball of the folder, and add to the cache // with cacache.put.stream(), using a key that's deterministic based on the // spec and repo, so that we don't ever clone the same thing multiple times. - [_clone] (handler, tarballOk = true) { + #clone (handler, tarballOk = true) { const o = { tmpPrefix: 'git-clone' } const ref = this.resolvedSha || this.spec.gitCommittish const h = this.spec.hosted @@ -239,7 +235,7 @@ class GitFetcher extends Fetcher { tarballOk = tarballOk && h && resolved === repoUrl(h, { noCommittish: false }) && h.tarball - return cacache.tmp.withTmp(this.cache, o, tmp => { + return cacache.tmp.withTmp(this.cache, o, async tmp => { // if we're resolved, and have a tarball url, shell out to RemoteFetcher if (tarballOk) { const nameat = this.spec.name ? `${this.spec.name}@` : '' @@ -252,23 +248,22 @@ class GitFetcher extends Fetcher { }).extract(tmp).then(() => handler(tmp), er => { // fall back to ssh download if tarball fails if (er.constructor.name.match(/^Http/)) { - return this[_clone](handler, false) + return this.#clone(handler, false) } else { throw er } }) } - return ( - h ? this[_cloneHosted](ref, tmp) - : this[_cloneRepo](this.spec.fetchSpec, ref, tmp) - ).then(sha => { - this.resolvedSha = sha - if (!this.resolved) { - this[_addGitSha](sha) - } - }) - .then(() => handler(tmp)) + const sha = await ( + h ? this.#cloneHosted(ref, tmp) + : this.#cloneRepo(this.spec.fetchSpec, ref, tmp) + ) + this.resolvedSha = sha + if (!this.resolved) { + await this.#addGitSha(sha) + } + return handler(tmp) }) } @@ -277,9 +272,9 @@ class GitFetcher extends Fetcher { // Fall back to SSH to support private repos // NB: we always store the https url in resolved field if auth // is present, otherwise ssh if the hosted type provides it - [_cloneHosted] (ref, tmp) { + #cloneHosted (ref, tmp) { const hosted = this.spec.hosted - return this[_cloneRepo](hosted.https({ noCommittish: true }), ref, tmp) + return this.#cloneRepo(hosted.https({ noCommittish: true }), ref, tmp) .catch(er => { // Throw early since we know pathspec errors will fail again if retried if (er instanceof git.errors.GitPathspecError) { @@ -290,11 +285,11 @@ class GitFetcher extends Fetcher { if (!ssh || hosted.auth) { throw er } - return this[_cloneRepo](ssh, ref, tmp) + return this.#cloneRepo(ssh, ref, tmp) }) } - [_cloneRepo] (repo, ref, tmp) { + #cloneRepo (repo, ref, tmp) { const { opts, spec } = this return git.clone(repo, ref, tmp, { ...opts, spec }) } @@ -306,8 +301,8 @@ class GitFetcher extends Fetcher { return this.spec.hosted && this.resolved ? FileFetcher.prototype.manifest.apply(this) - : this[_clone](dir => - this[_readPackageJson](dir + '/package.json') + : this.#clone(dir => + this[_.readPackageJson](dir) .then(mani => this.package = { ...mani, _resolved: this.resolved, diff --git a/node_modules/pacote/lib/index.js b/node_modules/pacote/lib/index.js index cbcbd7c92d15f..f35314d275d5f 100644 --- a/node_modules/pacote/lib/index.js +++ b/node_modules/pacote/lib/index.js @@ -5,6 +5,10 @@ const FileFetcher = require('./file.js') const DirFetcher = require('./dir.js') const RemoteFetcher = require('./remote.js') +const tarball = (spec, opts) => get(spec, opts).tarball() +tarball.stream = (spec, handler, opts) => get(spec, opts).tarballStream(handler) +tarball.file = (spec, dest, opts) => get(spec, opts).tarballFile(dest) + module.exports = { GitFetcher, RegistryFetcher, @@ -14,10 +18,6 @@ module.exports = { resolve: (spec, opts) => get(spec, opts).resolve(), extract: (spec, dest, opts) => get(spec, opts).extract(dest), manifest: (spec, opts) => get(spec, opts).manifest(), - tarball: (spec, opts) => get(spec, opts).tarball(), packument: (spec, opts) => get(spec, opts).packument(), + tarball, } -module.exports.tarball.stream = (spec, handler, opts) => - get(spec, opts).tarballStream(handler) -module.exports.tarball.file = (spec, dest, opts) => - get(spec, opts).tarballFile(dest) diff --git a/node_modules/pacote/lib/registry.js b/node_modules/pacote/lib/registry.js index c8eb6b0290702..1ecf4ee177349 100644 --- a/node_modules/pacote/lib/registry.js +++ b/node_modules/pacote/lib/registry.js @@ -1,22 +1,26 @@ +const crypto = require('node:crypto') +const PackageJson = require('@npmcli/package-json') +const pickManifest = require('npm-pick-manifest') +const ssri = require('ssri') +const npa = require('npm-package-arg') +const sigstore = require('sigstore') +const fetch = require('npm-registry-fetch') const Fetcher = require('./fetcher.js') 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 npa = require('npm-package-arg') -const rpj = require('read-package-json-fast') -const pickManifest = require('npm-pick-manifest') -const ssri = require('ssri') -const crypto = require('crypto') +const _ = require('./util/protected.js') // Corgis are cute. 🐕🐶 const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' const fullDoc = 'application/json' -const fetch = require('npm-registry-fetch') +// Some really old packages have no time field in their packument so we need a +// cutoff date. +const MISSING_TIME_CUTOFF = '2015-01-01T00:00:00.000Z' -const _headers = Symbol('_headers') class RegistryFetcher extends Fetcher { + #cacheKey constructor (spec, opts) { super(spec, opts) @@ -28,15 +32,9 @@ class RegistryFetcher extends Fetcher { // already. this.packumentCache = this.opts.packumentCache || null - // handle case when npm-package-arg guesses wrong. - if (this.spec.type === 'tag' && - this.spec.rawSpec === '' && - this.defaultTag !== 'latest') { - this.spec = npa(`${this.spec.name}@${this.defaultTag}`) - } this.registry = fetch.pickRegistry(spec, opts) - this.packumentUrl = removeTrailingSlashes(this.registry) + '/' + - this.spec.escapedName + this.packumentUrl = `${removeTrailingSlashes(this.registry)}/${this.spec.escapedName}` + this.#cacheKey = `${this.fullMetadata ? 'full' : 'corgi'}:${this.packumentUrl}` const parsed = new URL(this.registry) const regKey = `//${parsed.host}${parsed.pathname}` @@ -64,7 +62,7 @@ class RegistryFetcher extends Fetcher { return this.resolved } - [_headers] () { + #headers () { return { // npm will override UA, but ensure that we always send *something* 'user-agent': this.opts.userAgent || @@ -81,8 +79,8 @@ class RegistryFetcher extends Fetcher { // note this might be either an in-flight promise for a request, // or the actual packument, but we never want to make more than // one request at a time for the same thing regardless. - if (this.packumentCache && this.packumentCache.has(this.packumentUrl)) { - return this.packumentCache.get(this.packumentUrl) + if (this.packumentCache?.has(this.#cacheKey)) { + return this.packumentCache.get(this.#cacheKey) } // npm-registry-fetch the packument @@ -91,22 +89,21 @@ class RegistryFetcher extends Fetcher { try { const res = await fetch(this.packumentUrl, { ...this.opts, - headers: this[_headers](), + headers: this.#headers(), spec: this.spec, + // never check integrity for packuments themselves integrity: null, }) const packument = await res.json() - packument._cached = res.headers.has('x-local-cache') - packument._contentLength = +res.headers.get('content-length') - if (this.packumentCache) { - this.packumentCache.set(this.packumentUrl, packument) + const contentLength = res.headers.get('content-length') + if (contentLength) { + packument._contentLength = Number(contentLength) } + this.packumentCache?.set(this.#cacheKey, packument) return packument } catch (err) { - if (this.packumentCache) { - this.packumentCache.delete(this.packumentUrl) - } + this.packumentCache?.delete(this.#cacheKey) if (err.code !== 'E404' || this.fullMetadata) { throw err } @@ -121,15 +118,29 @@ class RegistryFetcher extends Fetcher { return this.package } + // When verifying signatures, we need to fetch the full/uncompressed + // packument to get publish time as this is not included in the + // corgi/compressed packument. + if (this.opts.verifySignatures) { + this.fullMetadata = true + } + 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 + const time = packument.time?.[mani.version] + if (time) { + mani._time = time + } + // add _resolved and _integrity from dist object const { dist } = mani if (dist) { @@ -177,8 +188,10 @@ class RegistryFetcher extends Fetcher { 'but no corresponding public key can be found' ), { code: 'EMISSINGSIGNATUREKEY' }) } - const validPublicKey = - !publicKey.expires || (Date.parse(publicKey.expires) > Date.now()) + + const publishedTime = Date.parse(mani._time || MISSING_TIME_CUTOFF) + const validPublicKey = !publicKey.expires || + publishedTime < Date.parse(publicKey.expires) if (!validPublicKey) { throw Object.assign(new Error( `${mani._id} has a registry signature with keyid: ${signature.keyid} ` + @@ -211,18 +224,138 @@ class RegistryFetcher extends Fetcher { mani._signatures = dist.signatures } } + + if (dist.attestations) { + if (this.opts.verifyAttestations) { + // Always fetch attestations from the current registry host + const attestationsPath = new URL(dist.attestations.url).pathname + const attestationsUrl = removeTrailingSlashes(this.registry) + attestationsPath + const res = await fetch(attestationsUrl, { + ...this.opts, + // disable integrity check for attestations json payload, we check the + // integrity in the verification steps below + integrity: null, + }) + const { attestations } = await res.json() + const bundles = attestations.map(({ predicateType, bundle }) => { + const statement = JSON.parse( + Buffer.from(bundle.dsseEnvelope.payload, 'base64').toString('utf8') + ) + const keyid = bundle.dsseEnvelope.signatures[0].keyid + const signature = bundle.dsseEnvelope.signatures[0].sig + + return { + predicateType, + bundle, + statement, + keyid, + signature, + } + }) + + const attestationKeyIds = bundles.map((b) => b.keyid).filter((k) => !!k) + const attestationRegistryKeys = (this.registryKeys || []) + .filter(key => attestationKeyIds.includes(key.keyid)) + if (!attestationRegistryKeys.length) { + throw Object.assign(new Error( + `${mani._id} has attestations but no corresponding public key(s) can be found` + ), { code: 'EMISSINGSIGNATUREKEY' }) + } + + for (const { predicateType, bundle, keyid, signature, statement } of bundles) { + const publicKey = attestationRegistryKeys.find(key => key.keyid === keyid) + // Publish attestations have a keyid set and a valid public key must be found + if (keyid) { + if (!publicKey) { + throw Object.assign(new Error( + `${mani._id} has attestations with keyid: ${keyid} ` + + 'but no corresponding public key can be found' + ), { code: 'EMISSINGSIGNATUREKEY' }) + } + + const integratedTime = new Date( + Number( + bundle.verificationMaterial.tlogEntries[0].integratedTime + ) * 1000 + ) + const validPublicKey = !publicKey.expires || + (integratedTime < Date.parse(publicKey.expires)) + if (!validPublicKey) { + throw Object.assign(new Error( + `${mani._id} has attestations with keyid: ${keyid} ` + + `but the corresponding public key has expired ${publicKey.expires}` + ), { code: 'EEXPIREDSIGNATUREKEY' }) + } + } + + const subject = { + name: statement.subject[0].name, + sha512: statement.subject[0].digest.sha512, + } + + // Only type 'version' can be turned into a PURL + const purl = this.spec.type === 'version' ? npa.toPurl(this.spec) : this.spec + // Verify the statement subject matches the package, version + if (subject.name !== purl) { + throw Object.assign(new Error( + `${mani._id} package name and version (PURL): ${purl} ` + + `doesn't match what was signed: ${subject.name}` + ), { code: 'EATTESTATIONSUBJECT' }) + } + + // Verify the statement subject matches the tarball integrity + const integrityHexDigest = ssri.parse(this.integrity).hexDigest() + if (subject.sha512 !== integrityHexDigest) { + throw Object.assign(new Error( + `${mani._id} package integrity (hex digest): ` + + `${integrityHexDigest} ` + + `doesn't match what was signed: ${subject.sha512}` + ), { code: 'EATTESTATIONSUBJECT' }) + } + + try { + // Provenance attestations are signed with a signing certificate + // (including the key) so we don't need to return a public key. + // + // Publish attestations are signed with a keyid so we need to + // specify a public key from the keys endpoint: `registry-host.tld/-/npm/v1/keys` + const options = { + tufCachePath: this.tufCache, + tufForceCache: true, + keySelector: publicKey ? () => publicKey.pemkey : undefined, + } + await sigstore.verify(bundle, options) + } catch (e) { + throw Object.assign(new Error( + `${mani._id} failed to verify attestation: ${e.message}` + ), { + code: 'EATTESTATIONVERIFY', + predicateType, + keyid, + signature, + resolved: mani._resolved, + integrity: mani._integrity, + }) + } + } + mani._attestations = dist.attestations + } else { + mani._attestations = dist.attestations + } + } } + this.package = mani return this.package } - [_tarballFromResolved] () { + [_.tarballFromResolved] () { // we use a RemoteFetcher to get the actual tarball stream return new RemoteFetcher(this.resolved, { ...this.opts, resolved: this.resolved, pkgid: `registry:${this.spec.name}@${this.resolved}`, - })[_tarballFromResolved]() + })[_.tarballFromResolved]() } get types () { diff --git a/node_modules/pacote/lib/remote.js b/node_modules/pacote/lib/remote.js index 6759dbba3ed2f..bd321e65a1f18 100644 --- a/node_modules/pacote/lib/remote.js +++ b/node_modules/pacote/lib/remote.js @@ -1,12 +1,10 @@ +const fetch = require('npm-registry-fetch') +const { Minipass } = require('minipass') const Fetcher = require('./fetcher.js') const FileFetcher = require('./file.js') -const _tarballFromResolved = Symbol.for('pacote.Fetcher._tarballFromResolved') +const _ = require('./util/protected.js') const pacoteVersion = require('../package.json').version -const fetch = require('npm-registry-fetch') -const Minipass = require('minipass') -const _cacheFetches = Symbol.for('pacote.Fetcher._cacheFetches') -const _headers = Symbol('_headers') class RemoteFetcher extends Fetcher { constructor (spec, opts) { super(spec, opts) @@ -25,22 +23,23 @@ class RemoteFetcher extends Fetcher { // Don't need to cache tarball fetches in pacote, because make-fetch-happen // will write into cacache anyway. - get [_cacheFetches] () { + get [_.cacheFetches] () { return false } - [_tarballFromResolved] () { + [_.tarballFromResolved] () { const stream = new Minipass() stream.hasIntegrityEmitter = true const fetchOpts = { ...this.opts, - headers: this[_headers](), + headers: this.#headers(), spec: this.spec, integrity: this.integrity, algorithms: [this.pickIntegrityAlgorithm()], } + // eslint-disable-next-line promise/always-return fetch(this.resolved, fetchOpts).then(res => { res.body.on('error', /* istanbul ignore next - exceedingly rare and hard to simulate */ @@ -58,7 +57,7 @@ class RemoteFetcher extends Fetcher { return stream } - [_headers] () { + #headers () { return { // npm will override this, but ensure that we always send *something* 'user-agent': this.opts.userAgent || diff --git a/node_modules/pacote/lib/util/cache-dir.js b/node_modules/pacote/lib/util/cache-dir.js index 4236213edd409..ba5683a7bb5bf 100644 --- a/node_modules/pacote/lib/util/cache-dir.js +++ b/node_modules/pacote/lib/util/cache-dir.js @@ -1,12 +1,15 @@ -const os = require('os') -const { resolve } = require('path') +const { resolve } = require('node:path') +const { tmpdir, homedir } = require('node:os') module.exports = (fakePlatform = false) => { - const temp = os.tmpdir() + const temp = tmpdir() const uidOrPid = process.getuid ? process.getuid() : process.pid - const home = os.homedir() || resolve(temp, 'npm-' + uidOrPid) + const home = homedir() || resolve(temp, 'npm-' + uidOrPid) const platform = fakePlatform || process.platform const cacheExtra = platform === 'win32' ? 'npm-cache' : '.npm' const cacheRoot = (platform === 'win32' && process.env.LOCALAPPDATA) || home - return resolve(cacheRoot, cacheExtra, '_cacache') + return { + cacache: resolve(cacheRoot, cacheExtra, '_cacache'), + tufcache: resolve(cacheRoot, cacheExtra, '_tuf'), + } } diff --git a/node_modules/pacote/lib/util/npm.js b/node_modules/pacote/lib/util/npm.js index c444d788ad192..a3005c255565f 100644 --- a/node_modules/pacote/lib/util/npm.js +++ b/node_modules/pacote/lib/util/npm.js @@ -10,5 +10,5 @@ module.exports = (npmBin, npmCommand, cwd, env, extra) => { // in temp directories. this lets us link previously-seen repos that // are also being prepared. - return spawn(cmd, args, { cwd, stdioString: true, env }, extra) + return spawn(cmd, args, { cwd, env }, extra) } diff --git a/node_modules/pacote/lib/util/protected.js b/node_modules/pacote/lib/util/protected.js new file mode 100644 index 0000000000000..e05203b481e6a --- /dev/null +++ b/node_modules/pacote/lib/util/protected.js @@ -0,0 +1,5 @@ +module.exports = { + cacheFetches: Symbol.for('pacote.Fetcher._cacheFetches'), + readPackageJson: Symbol.for('package.Fetcher._readPackageJson'), + tarballFromResolved: Symbol.for('pacote.Fetcher._tarballFromResolved'), +} diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index 696c925d35320..b0cef67100abb 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,35 +1,39 @@ { "name": "pacote", - "version": "13.6.1", + "version": "21.1.0", "description": "JavaScript package downloader", "author": "GitHub Inc.", "bin": { - "pacote": "lib/bin.js" + "pacote": "bin/index.js" }, "license": "ISC", "main": "lib/index.js", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "timeout": 300 + "timeout": 300, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "hosted-git-info": "^5.0.0", + "@npmcli/arborist": "^9.0.2", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.0", + "hosted-git-info": "^9.0.0", "mutate-fs": "^2.1.1", "nock": "^13.2.4", "npm-registry-mock": "^1.3.2", + "rimraf": "^6.0.1", "tap": "^16.0.1" }, "files": [ @@ -42,38 +46,35 @@ "git" ], "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/run-script": "^4.1.0", - "cacache": "^16.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.6", - "mkdirp": "^1.0.4", - "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.1.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", "promise-retry": "^2.0.1", - "read-package-json": "^5.0.0", - "read-package-json-fast": "^2.0.3", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11" + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "repository": { "type": "git", - "url": "https://github.com/npm/pacote.git" + "url": "git+https://github.com/npm/pacote.git" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0", - "windowsCI": false + "version": "4.28.0", + "windowsCI": false, + "publish": "true" } } diff --git a/node_modules/parse-conflict-json/package.json b/node_modules/parse-conflict-json/package.json index 5dab68d52f7ca..1d4bc1021695a 100644 --- a/node_modules/parse-conflict-json/package.json +++ b/node_modules/parse-conflict-json/package.json @@ -1,6 +1,6 @@ { "name": "parse-conflict-json", - "version": "2.0.2", + "version": "5.0.1", "description": "Parse a JSON string that has git merge conflicts, resolving if possible", "author": "GitHub Inc.", "license": "ISC", @@ -8,42 +8,44 @@ "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.0", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "dependencies": { - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", + "json-parse-even-better-errors": "^5.0.0", + "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "repository": { "type": "git", - "url": "https://github.com/npm/parse-conflict-json.git" + "url": "git+https://github.com/npm/parse-conflict-json.git" }, "files": [ "bin/", "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.0" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/path-is-absolute/index.js b/node_modules/path-is-absolute/index.js deleted file mode 100644 index 22aa6c3560799..0000000000000 --- a/node_modules/path-is-absolute/index.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; diff --git a/node_modules/path-is-absolute/license b/node_modules/path-is-absolute/license deleted file mode 100644 index 654d0bfe94343..0000000000000 --- a/node_modules/path-is-absolute/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (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/node_modules/path-is-absolute/package.json b/node_modules/path-is-absolute/package.json deleted file mode 100644 index 91196d5e9c133..0000000000000 --- a/node_modules/path-is-absolute/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "path-is-absolute", - "version": "1.0.1", - "description": "Node.js 0.12 path.isAbsolute() ponyfill", - "license": "MIT", - "repository": "sindresorhus/path-is-absolute", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=0.10.0" - }, - "scripts": { - "test": "xo && node test.js" - }, - "files": [ - "index.js" - ], - "keywords": [ - "path", - "paths", - "file", - "dir", - "absolute", - "isabsolute", - "is-absolute", - "built-in", - "util", - "utils", - "core", - "ponyfill", - "polyfill", - "shim", - "is", - "detect", - "check" - ], - "devDependencies": { - "xo": "^0.16.0" - } -} diff --git a/node_modules/path-is-absolute/readme.md b/node_modules/path-is-absolute/readme.md deleted file mode 100644 index 8dbdf5fcb775e..0000000000000 --- a/node_modules/path-is-absolute/readme.md +++ /dev/null @@ -1,59 +0,0 @@ -# path-is-absolute [![Build Status](https://travis-ci.org/sindresorhus/path-is-absolute.svg?branch=master)](https://travis-ci.org/sindresorhus/path-is-absolute) - -> Node.js 0.12 [`path.isAbsolute()`](http://nodejs.org/api/path.html#path_path_isabsolute_path) [ponyfill](https://ponyfill.com) - - -## Install - -``` -$ npm install --save path-is-absolute -``` - - -## Usage - -```js -const pathIsAbsolute = require('path-is-absolute'); - -// Running on Linux -pathIsAbsolute('/home/foo'); -//=> true -pathIsAbsolute('C:/Users/foo'); -//=> false - -// Running on Windows -pathIsAbsolute('C:/Users/foo'); -//=> true -pathIsAbsolute('/home/foo'); -//=> false - -// Running on any OS -pathIsAbsolute.posix('/home/foo'); -//=> true -pathIsAbsolute.posix('C:/Users/foo'); -//=> false -pathIsAbsolute.win32('C:/Users/foo'); -//=> true -pathIsAbsolute.win32('/home/foo'); -//=> false -``` - - -## API - -See the [`path.isAbsolute()` docs](http://nodejs.org/api/path.html#path_path_isabsolute_path). - -### pathIsAbsolute(path) - -### pathIsAbsolute.posix(path) - -POSIX specific version. - -### pathIsAbsolute.win32(path) - -Windows specific version. - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/path-scurry/LICENSE.md b/node_modules/path-scurry/LICENSE.md new file mode 100644 index 0000000000000..c5402b9577a8c --- /dev/null +++ b/node_modules/path-scurry/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/path-scurry/dist/commonjs/index.js b/node_modules/path-scurry/dist/commonjs/index.js new file mode 100644 index 0000000000000..112f732d69a3f --- /dev/null +++ b/node_modules/path-scurry/dist/commonjs/index.js @@ -0,0 +1,2018 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PathScurry = exports.Path = exports.PathScurryDarwin = exports.PathScurryPosix = exports.PathScurryWin32 = exports.PathScurryBase = exports.PathPosix = exports.PathWin32 = exports.PathBase = exports.ChildrenCache = exports.ResolveCache = void 0; +const lru_cache_1 = require("lru-cache"); +const node_path_1 = require("node:path"); +const node_url_1 = require("node:url"); +const fs_1 = require("fs"); +const actualFS = __importStar(require("node:fs")); +const realpathSync = fs_1.realpathSync.native; +// TODO: test perf of fs/promises realpath vs realpathCB, +// since the promises one uses realpath.native +const promises_1 = require("node:fs/promises"); +const minipass_1 = require("minipass"); +const defaultFS = { + lstatSync: fs_1.lstatSync, + readdir: fs_1.readdir, + readdirSync: fs_1.readdirSync, + readlinkSync: fs_1.readlinkSync, + realpathSync, + promises: { + lstat: promises_1.lstat, + readdir: promises_1.readdir, + readlink: promises_1.readlink, + realpath: promises_1.realpath, + }, +}; +// if they just gave us require('fs') then use our default +const fsFromOption = (fsOption) => !fsOption || fsOption === defaultFS || fsOption === actualFS ? + defaultFS + : { + ...defaultFS, + ...fsOption, + promises: { + ...defaultFS.promises, + ...(fsOption.promises || {}), + }, + }; +// turn something like //?/c:/ into c:\ +const uncDriveRegexp = /^\\\\\?\\([a-z]:)\\?$/i; +const uncToDrive = (rootPath) => rootPath.replace(/\//g, '\\').replace(uncDriveRegexp, '$1\\'); +// windows paths are separated by either / or \ +const eitherSep = /[\\\/]/; +const UNKNOWN = 0; // may not even exist, for all we know +const IFIFO = 0b0001; +const IFCHR = 0b0010; +const IFDIR = 0b0100; +const IFBLK = 0b0110; +const IFREG = 0b1000; +const IFLNK = 0b1010; +const IFSOCK = 0b1100; +const IFMT = 0b1111; +// mask to unset low 4 bits +const IFMT_UNKNOWN = ~IFMT; +// set after successfully calling readdir() and getting entries. +const READDIR_CALLED = 0b0000_0001_0000; +// set after a successful lstat() +const LSTAT_CALLED = 0b0000_0010_0000; +// set if an entry (or one of its parents) is definitely not a dir +const ENOTDIR = 0b0000_0100_0000; +// set if an entry (or one of its parents) does not exist +// (can also be set on lstat errors like EACCES or ENAMETOOLONG) +const ENOENT = 0b0000_1000_0000; +// cannot have child entries -- also verify &IFMT is either IFDIR or IFLNK +// set if we fail to readlink +const ENOREADLINK = 0b0001_0000_0000; +// set if we know realpath() will fail +const ENOREALPATH = 0b0010_0000_0000; +const ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH; +const TYPEMASK = 0b0011_1111_1111; +const entToType = (s) => s.isFile() ? IFREG + : s.isDirectory() ? IFDIR + : s.isSymbolicLink() ? IFLNK + : s.isCharacterDevice() ? IFCHR + : s.isBlockDevice() ? IFBLK + : s.isSocket() ? IFSOCK + : s.isFIFO() ? IFIFO + : UNKNOWN; +// normalize unicode path names +const normalizeCache = new lru_cache_1.LRUCache({ max: 2 ** 12 }); +const normalize = (s) => { + const c = normalizeCache.get(s); + if (c) + return c; + const n = s.normalize('NFKD'); + normalizeCache.set(s, n); + return n; +}; +const normalizeNocaseCache = new lru_cache_1.LRUCache({ max: 2 ** 12 }); +const normalizeNocase = (s) => { + const c = normalizeNocaseCache.get(s); + if (c) + return c; + const n = normalize(s.toLowerCase()); + normalizeNocaseCache.set(s, n); + return n; +}; +/** + * An LRUCache for storing resolved path strings or Path objects. + * @internal + */ +class ResolveCache extends lru_cache_1.LRUCache { + constructor() { + super({ max: 256 }); + } +} +exports.ResolveCache = ResolveCache; +// In order to prevent blowing out the js heap by allocating hundreds of +// thousands of Path entries when walking extremely large trees, the "children" +// in this tree are represented by storing an array of Path entries in an +// LRUCache, indexed by the parent. At any time, Path.children() may return an +// empty array, indicating that it doesn't know about any of its children, and +// thus has to rebuild that cache. This is fine, it just means that we don't +// benefit as much from having the cached entries, but huge directory walks +// don't blow out the stack, and smaller ones are still as fast as possible. +// +//It does impose some complexity when building up the readdir data, because we +//need to pass a reference to the children array that we started with. +/** + * an LRUCache for storing child entries. + * @internal + */ +class ChildrenCache extends lru_cache_1.LRUCache { + constructor(maxSize = 16 * 1024) { + super({ + maxSize, + // parent + children + sizeCalculation: a => a.length + 1, + }); + } +} +exports.ChildrenCache = ChildrenCache; +const setAsCwd = Symbol('PathScurry setAsCwd'); +/** + * Path objects are sort of like a super-powered + * {@link https://nodejs.org/docs/latest/api/fs.html#class-fsdirent fs.Dirent} + * + * Each one represents a single filesystem entry on disk, which may or may not + * exist. It includes methods for reading various types of information via + * lstat, readlink, and readdir, and caches all information to the greatest + * degree possible. + * + * Note that fs operations that would normally throw will instead return an + * "empty" value. This is in order to prevent excessive overhead from error + * stack traces. + */ +class PathBase { + /** + * the basename of this path + * + * **Important**: *always* test the path name against any test string + * usingthe {@link isNamed} method, and not by directly comparing this + * string. Otherwise, unicode path strings that the system sees as identical + * will not be properly treated as the same path, leading to incorrect + * behavior and possible security issues. + */ + name; + /** + * the Path entry corresponding to the path root. + * + * @internal + */ + root; + /** + * All roots found within the current PathScurry family + * + * @internal + */ + roots; + /** + * a reference to the parent path, or undefined in the case of root entries + * + * @internal + */ + parent; + /** + * boolean indicating whether paths are compared case-insensitively + * @internal + */ + nocase; + /** + * boolean indicating that this path is the current working directory + * of the PathScurry collection that contains it. + */ + isCWD = false; + // potential default fs override + #fs; + // Stats fields + #dev; + get dev() { + return this.#dev; + } + #mode; + get mode() { + return this.#mode; + } + #nlink; + get nlink() { + return this.#nlink; + } + #uid; + get uid() { + return this.#uid; + } + #gid; + get gid() { + return this.#gid; + } + #rdev; + get rdev() { + return this.#rdev; + } + #blksize; + get blksize() { + return this.#blksize; + } + #ino; + get ino() { + return this.#ino; + } + #size; + get size() { + return this.#size; + } + #blocks; + get blocks() { + return this.#blocks; + } + #atimeMs; + get atimeMs() { + return this.#atimeMs; + } + #mtimeMs; + get mtimeMs() { + return this.#mtimeMs; + } + #ctimeMs; + get ctimeMs() { + return this.#ctimeMs; + } + #birthtimeMs; + get birthtimeMs() { + return this.#birthtimeMs; + } + #atime; + get atime() { + return this.#atime; + } + #mtime; + get mtime() { + return this.#mtime; + } + #ctime; + get ctime() { + return this.#ctime; + } + #birthtime; + get birthtime() { + return this.#birthtime; + } + #matchName; + #depth; + #fullpath; + #fullpathPosix; + #relative; + #relativePosix; + #type; + #children; + #linkTarget; + #realpath; + /** + * This property is for compatibility with the Dirent class as of + * Node v20, where Dirent['parentPath'] refers to the path of the + * directory that was passed to readdir. For root entries, it's the path + * to the entry itself. + */ + get parentPath() { + return (this.parent || this).fullpath(); + } + /* c8 ignore start */ + /** + * Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively, + * this property refers to the *parent* path, not the path object itself. + * + * @deprecated + */ + get path() { + return this.parentPath; + } + /* c8 ignore stop */ + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + this.name = name; + this.#matchName = nocase ? normalizeNocase(name) : normalize(name); + this.#type = type & TYPEMASK; + this.nocase = nocase; + this.roots = roots; + this.root = root || this; + this.#children = children; + this.#fullpath = opts.fullpath; + this.#relative = opts.relative; + this.#relativePosix = opts.relativePosix; + this.parent = opts.parent; + if (this.parent) { + this.#fs = this.parent.#fs; + } + else { + this.#fs = fsFromOption(opts.fs); + } + } + /** + * Returns the depth of the Path object from its root. + * + * For example, a path at `/foo/bar` would have a depth of 2. + */ + depth() { + if (this.#depth !== undefined) + return this.#depth; + if (!this.parent) + return (this.#depth = 0); + return (this.#depth = this.parent.depth() + 1); + } + /** + * @internal + */ + childrenCache() { + return this.#children; + } + /** + * Get the Path object referenced by the string path, resolved from this Path + */ + resolve(path) { + if (!path) { + return this; + } + const rootPath = this.getRootString(path); + const dir = path.substring(rootPath.length); + const dirParts = dir.split(this.splitSep); + const result = rootPath ? + this.getRoot(rootPath).#resolveParts(dirParts) + : this.#resolveParts(dirParts); + return result; + } + #resolveParts(dirParts) { + let p = this; + for (const part of dirParts) { + p = p.child(part); + } + return p; + } + /** + * Returns the cached children Path objects, if still available. If they + * have fallen out of the cache, then returns an empty array, and resets the + * READDIR_CALLED bit, so that future calls to readdir() will require an fs + * lookup. + * + * @internal + */ + children() { + const cached = this.#children.get(this); + if (cached) { + return cached; + } + const children = Object.assign([], { provisional: 0 }); + this.#children.set(this, children); + this.#type &= ~READDIR_CALLED; + return children; + } + /** + * Resolves a path portion and returns or creates the child Path. + * + * Returns `this` if pathPart is `''` or `'.'`, or `parent` if pathPart is + * `'..'`. + * + * This should not be called directly. If `pathPart` contains any path + * separators, it will lead to unsafe undefined behavior. + * + * Use `Path.resolve()` instead. + * + * @internal + */ + child(pathPart, opts) { + if (pathPart === '' || pathPart === '.') { + return this; + } + if (pathPart === '..') { + return this.parent || this; + } + // find the child + const children = this.children(); + const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart); + for (const p of children) { + if (p.#matchName === name) { + return p; + } + } + // didn't find it, create provisional child, since it might not + // actually exist. If we know the parent isn't a dir, then + // in fact it CAN'T exist. + const s = this.parent ? this.sep : ''; + const fullpath = this.#fullpath ? this.#fullpath + s + pathPart : undefined; + const pchild = this.newChild(pathPart, UNKNOWN, { + ...opts, + parent: this, + fullpath, + }); + if (!this.canReaddir()) { + pchild.#type |= ENOENT; + } + // don't have to update provisional, because if we have real children, + // then provisional is set to children.length, otherwise a lower number + children.push(pchild); + return pchild; + } + /** + * The relative path from the cwd. If it does not share an ancestor with + * the cwd, then this ends up being equivalent to the fullpath() + */ + relative() { + if (this.isCWD) + return ''; + if (this.#relative !== undefined) { + return this.#relative; + } + const name = this.name; + const p = this.parent; + if (!p) { + return (this.#relative = this.name); + } + const pv = p.relative(); + return pv + (!pv || !p.parent ? '' : this.sep) + name; + } + /** + * The relative path from the cwd, using / as the path separator. + * If it does not share an ancestor with + * the cwd, then this ends up being equivalent to the fullpathPosix() + * On posix systems, this is identical to relative(). + */ + relativePosix() { + if (this.sep === '/') + return this.relative(); + if (this.isCWD) + return ''; + if (this.#relativePosix !== undefined) + return this.#relativePosix; + const name = this.name; + const p = this.parent; + if (!p) { + return (this.#relativePosix = this.fullpathPosix()); + } + const pv = p.relativePosix(); + return pv + (!pv || !p.parent ? '' : '/') + name; + } + /** + * The fully resolved path string for this Path entry + */ + fullpath() { + if (this.#fullpath !== undefined) { + return this.#fullpath; + } + const name = this.name; + const p = this.parent; + if (!p) { + return (this.#fullpath = this.name); + } + const pv = p.fullpath(); + const fp = pv + (!p.parent ? '' : this.sep) + name; + return (this.#fullpath = fp); + } + /** + * On platforms other than windows, this is identical to fullpath. + * + * On windows, this is overridden to return the forward-slash form of the + * full UNC path. + */ + fullpathPosix() { + if (this.#fullpathPosix !== undefined) + return this.#fullpathPosix; + if (this.sep === '/') + return (this.#fullpathPosix = this.fullpath()); + if (!this.parent) { + const p = this.fullpath().replace(/\\/g, '/'); + if (/^[a-z]:\//i.test(p)) { + return (this.#fullpathPosix = `//?/${p}`); + } + else { + return (this.#fullpathPosix = p); + } + } + const p = this.parent; + const pfpp = p.fullpathPosix(); + const fpp = pfpp + (!pfpp || !p.parent ? '' : '/') + this.name; + return (this.#fullpathPosix = fpp); + } + /** + * Is the Path of an unknown type? + * + * Note that we might know *something* about it if there has been a previous + * filesystem operation, for example that it does not exist, or is not a + * link, or whether it has child entries. + */ + isUnknown() { + return (this.#type & IFMT) === UNKNOWN; + } + isType(type) { + return this[`is${type}`](); + } + getType() { + return (this.isUnknown() ? 'Unknown' + : this.isDirectory() ? 'Directory' + : this.isFile() ? 'File' + : this.isSymbolicLink() ? 'SymbolicLink' + : this.isFIFO() ? 'FIFO' + : this.isCharacterDevice() ? 'CharacterDevice' + : this.isBlockDevice() ? 'BlockDevice' + : /* c8 ignore start */ this.isSocket() ? 'Socket' + : 'Unknown'); + /* c8 ignore stop */ + } + /** + * Is the Path a regular file? + */ + isFile() { + return (this.#type & IFMT) === IFREG; + } + /** + * Is the Path a directory? + */ + isDirectory() { + return (this.#type & IFMT) === IFDIR; + } + /** + * Is the path a character device? + */ + isCharacterDevice() { + return (this.#type & IFMT) === IFCHR; + } + /** + * Is the path a block device? + */ + isBlockDevice() { + return (this.#type & IFMT) === IFBLK; + } + /** + * Is the path a FIFO pipe? + */ + isFIFO() { + return (this.#type & IFMT) === IFIFO; + } + /** + * Is the path a socket? + */ + isSocket() { + return (this.#type & IFMT) === IFSOCK; + } + /** + * Is the path a symbolic link? + */ + isSymbolicLink() { + return (this.#type & IFLNK) === IFLNK; + } + /** + * Return the entry if it has been subject of a successful lstat, or + * undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* simply + * mean that we haven't called lstat on it. + */ + lstatCached() { + return this.#type & LSTAT_CALLED ? this : undefined; + } + /** + * Return the cached link target if the entry has been the subject of a + * successful readlink, or undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * readlink() has been called at some point. + */ + readlinkCached() { + return this.#linkTarget; + } + /** + * Returns the cached realpath target if the entry has been the subject + * of a successful realpath, or undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * realpath() has been called at some point. + */ + realpathCached() { + return this.#realpath; + } + /** + * Returns the cached child Path entries array if the entry has been the + * subject of a successful readdir(), or [] otherwise. + * + * Does not read the filesystem, so an empty array *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * readdir() has been called recently enough to still be valid. + */ + readdirCached() { + const children = this.children(); + return children.slice(0, children.provisional); + } + /** + * Return true if it's worth trying to readlink. Ie, we don't (yet) have + * any indication that readlink will definitely fail. + * + * Returns false if the path is known to not be a symlink, if a previous + * readlink failed, or if the entry does not exist. + */ + canReadlink() { + if (this.#linkTarget) + return true; + if (!this.parent) + return false; + // cases where it cannot possibly succeed + const ifmt = this.#type & IFMT; + return !((ifmt !== UNKNOWN && ifmt !== IFLNK) || + this.#type & ENOREADLINK || + this.#type & ENOENT); + } + /** + * Return true if readdir has previously been successfully called on this + * path, indicating that cachedReaddir() is likely valid. + */ + calledReaddir() { + return !!(this.#type & READDIR_CALLED); + } + /** + * Returns true if the path is known to not exist. That is, a previous lstat + * or readdir failed to verify its existence when that would have been + * expected, or a parent entry was marked either enoent or enotdir. + */ + isENOENT() { + return !!(this.#type & ENOENT); + } + /** + * Return true if the path is a match for the given path name. This handles + * case sensitivity and unicode normalization. + * + * Note: even on case-sensitive systems, it is **not** safe to test the + * equality of the `.name` property to determine whether a given pathname + * matches, due to unicode normalization mismatches. + * + * Always use this method instead of testing the `path.name` property + * directly. + */ + isNamed(n) { + return !this.nocase ? + this.#matchName === normalize(n) + : this.#matchName === normalizeNocase(n); + } + /** + * Return the Path object corresponding to the target of a symbolic link. + * + * If the Path is not a symbolic link, or if the readlink call fails for any + * reason, `undefined` is returned. + * + * Result is cached, and thus may be outdated if the filesystem is mutated. + */ + async readlink() { + const target = this.#linkTarget; + if (target) { + return target; + } + if (!this.canReadlink()) { + return undefined; + } + /* c8 ignore start */ + // already covered by the canReadlink test, here for ts grumples + if (!this.parent) { + return undefined; + } + /* c8 ignore stop */ + try { + const read = await this.#fs.promises.readlink(this.fullpath()); + const linkTarget = (await this.parent.realpath())?.resolve(read); + if (linkTarget) { + return (this.#linkTarget = linkTarget); + } + } + catch (er) { + this.#readlinkFail(er.code); + return undefined; + } + } + /** + * Synchronous {@link PathBase.readlink} + */ + readlinkSync() { + const target = this.#linkTarget; + if (target) { + return target; + } + if (!this.canReadlink()) { + return undefined; + } + /* c8 ignore start */ + // already covered by the canReadlink test, here for ts grumples + if (!this.parent) { + return undefined; + } + /* c8 ignore stop */ + try { + const read = this.#fs.readlinkSync(this.fullpath()); + const linkTarget = this.parent.realpathSync()?.resolve(read); + if (linkTarget) { + return (this.#linkTarget = linkTarget); + } + } + catch (er) { + this.#readlinkFail(er.code); + return undefined; + } + } + #readdirSuccess(children) { + // succeeded, mark readdir called bit + this.#type |= READDIR_CALLED; + // mark all remaining provisional children as ENOENT + for (let p = children.provisional; p < children.length; p++) { + const c = children[p]; + if (c) + c.#markENOENT(); + } + } + #markENOENT() { + // mark as UNKNOWN and ENOENT + if (this.#type & ENOENT) + return; + this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN; + this.#markChildrenENOENT(); + } + #markChildrenENOENT() { + // all children are provisional and do not exist + const children = this.children(); + children.provisional = 0; + for (const p of children) { + p.#markENOENT(); + } + } + #markENOREALPATH() { + this.#type |= ENOREALPATH; + this.#markENOTDIR(); + } + // save the information when we know the entry is not a dir + #markENOTDIR() { + // entry is not a directory, so any children can't exist. + // this *should* be impossible, since any children created + // after it's been marked ENOTDIR should be marked ENOENT, + // so it won't even get to this point. + /* c8 ignore start */ + if (this.#type & ENOTDIR) + return; + /* c8 ignore stop */ + let t = this.#type; + // this could happen if we stat a dir, then delete it, + // then try to read it or one of its children. + if ((t & IFMT) === IFDIR) + t &= IFMT_UNKNOWN; + this.#type = t | ENOTDIR; + this.#markChildrenENOENT(); + } + #readdirFail(code = '') { + // markENOTDIR and markENOENT also set provisional=0 + if (code === 'ENOTDIR' || code === 'EPERM') { + this.#markENOTDIR(); + } + else if (code === 'ENOENT') { + this.#markENOENT(); + } + else { + this.children().provisional = 0; + } + } + #lstatFail(code = '') { + // Windows just raises ENOENT in this case, disable for win CI + /* c8 ignore start */ + if (code === 'ENOTDIR') { + // already know it has a parent by this point + const p = this.parent; + p.#markENOTDIR(); + } + else if (code === 'ENOENT') { + /* c8 ignore stop */ + this.#markENOENT(); + } + } + #readlinkFail(code = '') { + let ter = this.#type; + ter |= ENOREADLINK; + if (code === 'ENOENT') + ter |= ENOENT; + // windows gets a weird error when you try to readlink a file + if (code === 'EINVAL' || code === 'UNKNOWN') { + // exists, but not a symlink, we don't know WHAT it is, so remove + // all IFMT bits. + ter &= IFMT_UNKNOWN; + } + this.#type = ter; + // windows just gets ENOENT in this case. We do cover the case, + // just disabled because it's impossible on Windows CI + /* c8 ignore start */ + if (code === 'ENOTDIR' && this.parent) { + this.parent.#markENOTDIR(); + } + /* c8 ignore stop */ + } + #readdirAddChild(e, c) { + return (this.#readdirMaybePromoteChild(e, c) || + this.#readdirAddNewChild(e, c)); + } + #readdirAddNewChild(e, c) { + // alloc new entry at head, so it's never provisional + const type = entToType(e); + const child = this.newChild(e.name, type, { parent: this }); + const ifmt = child.#type & IFMT; + if (ifmt !== IFDIR && ifmt !== IFLNK && ifmt !== UNKNOWN) { + child.#type |= ENOTDIR; + } + c.unshift(child); + c.provisional++; + return child; + } + #readdirMaybePromoteChild(e, c) { + for (let p = c.provisional; p < c.length; p++) { + const pchild = c[p]; + const name = this.nocase ? normalizeNocase(e.name) : normalize(e.name); + if (name !== pchild.#matchName) { + continue; + } + return this.#readdirPromoteChild(e, pchild, p, c); + } + } + #readdirPromoteChild(e, p, index, c) { + const v = p.name; + // retain any other flags, but set ifmt from dirent + p.#type = (p.#type & IFMT_UNKNOWN) | entToType(e); + // case sensitivity fixing when we learn the true name. + if (v !== e.name) + p.name = e.name; + // just advance provisional index (potentially off the list), + // otherwise we have to splice/pop it out and re-insert at head + if (index !== c.provisional) { + if (index === c.length - 1) + c.pop(); + else + c.splice(index, 1); + c.unshift(p); + } + c.provisional++; + return p; + } + /** + * Call lstat() on this Path, and update all known information that can be + * determined. + * + * Note that unlike `fs.lstat()`, the returned value does not contain some + * information, such as `mode`, `dev`, `nlink`, and `ino`. If that + * information is required, you will need to call `fs.lstat` yourself. + * + * If the Path refers to a nonexistent file, or if the lstat call fails for + * any reason, `undefined` is returned. Otherwise the updated Path object is + * returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async lstat() { + if ((this.#type & ENOENT) === 0) { + try { + this.#applyStat(await this.#fs.promises.lstat(this.fullpath())); + return this; + } + catch (er) { + this.#lstatFail(er.code); + } + } + } + /** + * synchronous {@link PathBase.lstat} + */ + lstatSync() { + if ((this.#type & ENOENT) === 0) { + try { + this.#applyStat(this.#fs.lstatSync(this.fullpath())); + return this; + } + catch (er) { + this.#lstatFail(er.code); + } + } + } + #applyStat(st) { + const { atime, atimeMs, birthtime, birthtimeMs, blksize, blocks, ctime, ctimeMs, dev, gid, ino, mode, mtime, mtimeMs, nlink, rdev, size, uid, } = st; + this.#atime = atime; + this.#atimeMs = atimeMs; + this.#birthtime = birthtime; + this.#birthtimeMs = birthtimeMs; + this.#blksize = blksize; + this.#blocks = blocks; + this.#ctime = ctime; + this.#ctimeMs = ctimeMs; + this.#dev = dev; + this.#gid = gid; + this.#ino = ino; + this.#mode = mode; + this.#mtime = mtime; + this.#mtimeMs = mtimeMs; + this.#nlink = nlink; + this.#rdev = rdev; + this.#size = size; + this.#uid = uid; + const ifmt = entToType(st); + // retain any other flags, but set the ifmt + this.#type = (this.#type & IFMT_UNKNOWN) | ifmt | LSTAT_CALLED; + if (ifmt !== UNKNOWN && ifmt !== IFDIR && ifmt !== IFLNK) { + this.#type |= ENOTDIR; + } + } + #onReaddirCB = []; + #readdirCBInFlight = false; + #callOnReaddirCB(children) { + this.#readdirCBInFlight = false; + const cbs = this.#onReaddirCB.slice(); + this.#onReaddirCB.length = 0; + cbs.forEach(cb => cb(null, children)); + } + /** + * Standard node-style callback interface to get list of directory entries. + * + * If the Path cannot or does not contain any children, then an empty array + * is returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + * + * @param cb The callback called with (er, entries). Note that the `er` + * param is somewhat extraneous, as all readdir() errors are handled and + * simply result in an empty set of entries being returned. + * @param allowZalgo Boolean indicating that immediately known results should + * *not* be deferred with `queueMicrotask`. Defaults to `false`. Release + * zalgo at your peril, the dark pony lord is devious and unforgiving. + */ + readdirCB(cb, allowZalgo = false) { + if (!this.canReaddir()) { + if (allowZalgo) + cb(null, []); + else + queueMicrotask(() => cb(null, [])); + return; + } + const children = this.children(); + if (this.calledReaddir()) { + const c = children.slice(0, children.provisional); + if (allowZalgo) + cb(null, c); + else + queueMicrotask(() => cb(null, c)); + return; + } + // don't have to worry about zalgo at this point. + this.#onReaddirCB.push(cb); + if (this.#readdirCBInFlight) { + return; + } + this.#readdirCBInFlight = true; + // else read the directory, fill up children + // de-provisionalize any provisional children. + const fullpath = this.fullpath(); + this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => { + if (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + else { + // if we didn't get an error, we always get entries. + //@ts-ignore + for (const e of entries) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + this.#callOnReaddirCB(children.slice(0, children.provisional)); + return; + }); + } + #asyncReaddirInFlight; + /** + * Return an array of known child entries. + * + * If the Path cannot or does not contain any children, then an empty array + * is returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async readdir() { + if (!this.canReaddir()) { + return []; + } + const children = this.children(); + if (this.calledReaddir()) { + return children.slice(0, children.provisional); + } + // else read the directory, fill up children + // de-provisionalize any provisional children. + const fullpath = this.fullpath(); + if (this.#asyncReaddirInFlight) { + await this.#asyncReaddirInFlight; + } + else { + /* c8 ignore start */ + let resolve = () => { }; + /* c8 ignore stop */ + this.#asyncReaddirInFlight = new Promise(res => (resolve = res)); + try { + for (const e of await this.#fs.promises.readdir(fullpath, { + withFileTypes: true, + })) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + catch (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + this.#asyncReaddirInFlight = undefined; + resolve(); + } + return children.slice(0, children.provisional); + } + /** + * synchronous {@link PathBase.readdir} + */ + readdirSync() { + if (!this.canReaddir()) { + return []; + } + const children = this.children(); + if (this.calledReaddir()) { + return children.slice(0, children.provisional); + } + // else read the directory, fill up children + // de-provisionalize any provisional children. + const fullpath = this.fullpath(); + try { + for (const e of this.#fs.readdirSync(fullpath, { + withFileTypes: true, + })) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + catch (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + return children.slice(0, children.provisional); + } + canReaddir() { + if (this.#type & ENOCHILD) + return false; + const ifmt = IFMT & this.#type; + // we always set ENOTDIR when setting IFMT, so should be impossible + /* c8 ignore start */ + if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) { + return false; + } + /* c8 ignore stop */ + return true; + } + shouldWalk(dirs, walkFilter) { + return ((this.#type & IFDIR) === IFDIR && + !(this.#type & ENOCHILD) && + !dirs.has(this) && + (!walkFilter || walkFilter(this))); + } + /** + * Return the Path object corresponding to path as resolved + * by realpath(3). + * + * If the realpath call fails for any reason, `undefined` is returned. + * + * Result is cached, and thus may be outdated if the filesystem is mutated. + * On success, returns a Path object. + */ + async realpath() { + if (this.#realpath) + return this.#realpath; + if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) + return undefined; + try { + const rp = await this.#fs.promises.realpath(this.fullpath()); + return (this.#realpath = this.resolve(rp)); + } + catch (_) { + this.#markENOREALPATH(); + } + } + /** + * Synchronous {@link realpath} + */ + realpathSync() { + if (this.#realpath) + return this.#realpath; + if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) + return undefined; + try { + const rp = this.#fs.realpathSync(this.fullpath()); + return (this.#realpath = this.resolve(rp)); + } + catch (_) { + this.#markENOREALPATH(); + } + } + /** + * Internal method to mark this Path object as the scurry cwd, + * called by {@link PathScurry#chdir} + * + * @internal + */ + [setAsCwd](oldCwd) { + if (oldCwd === this) + return; + oldCwd.isCWD = false; + this.isCWD = true; + const changed = new Set([]); + let rp = []; + let p = this; + while (p && p.parent) { + changed.add(p); + p.#relative = rp.join(this.sep); + p.#relativePosix = rp.join('/'); + p = p.parent; + rp.push('..'); + } + // now un-memoize parents of old cwd + p = oldCwd; + while (p && p.parent && !changed.has(p)) { + p.#relative = undefined; + p.#relativePosix = undefined; + p = p.parent; + } + } +} +exports.PathBase = PathBase; +/** + * Path class used on win32 systems + * + * Uses `'\\'` as the path separator for returned paths, either `'\\'` or `'/'` + * as the path separator for parsing paths. + */ +class PathWin32 extends PathBase { + /** + * Separator for generating path strings. + */ + sep = '\\'; + /** + * Separator for parsing path strings. + */ + splitSep = eitherSep; + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + super(name, type, root, roots, nocase, children, opts); + } + /** + * @internal + */ + newChild(name, type = UNKNOWN, opts = {}) { + return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts); + } + /** + * @internal + */ + getRootString(path) { + return node_path_1.win32.parse(path).root; + } + /** + * @internal + */ + getRoot(rootPath) { + rootPath = uncToDrive(rootPath.toUpperCase()); + if (rootPath === this.root.name) { + return this.root; + } + // ok, not that one, check if it matches another we know about + for (const [compare, root] of Object.entries(this.roots)) { + if (this.sameRoot(rootPath, compare)) { + return (this.roots[rootPath] = root); + } + } + // otherwise, have to create a new one. + return (this.roots[rootPath] = new PathScurryWin32(rootPath, this).root); + } + /** + * @internal + */ + sameRoot(rootPath, compare = this.root.name) { + // windows can (rarely) have case-sensitive filesystem, but + // UNC and drive letters are always case-insensitive, and canonically + // represented uppercase. + rootPath = rootPath + .toUpperCase() + .replace(/\//g, '\\') + .replace(uncDriveRegexp, '$1\\'); + return rootPath === compare; + } +} +exports.PathWin32 = PathWin32; +/** + * Path class used on all posix systems. + * + * Uses `'/'` as the path separator. + */ +class PathPosix extends PathBase { + /** + * separator for parsing path strings + */ + splitSep = '/'; + /** + * separator for generating path strings + */ + sep = '/'; + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + super(name, type, root, roots, nocase, children, opts); + } + /** + * @internal + */ + getRootString(path) { + return path.startsWith('/') ? '/' : ''; + } + /** + * @internal + */ + getRoot(_rootPath) { + return this.root; + } + /** + * @internal + */ + newChild(name, type = UNKNOWN, opts = {}) { + return new PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts); + } +} +exports.PathPosix = PathPosix; +/** + * The base class for all PathScurry classes, providing the interface for path + * resolution and filesystem operations. + * + * Typically, you should *not* instantiate this class directly, but rather one + * of the platform-specific classes, or the exported {@link PathScurry} which + * defaults to the current platform. + */ +class PathScurryBase { + /** + * The root Path entry for the current working directory of this Scurry + */ + root; + /** + * The string path for the root of this Scurry's current working directory + */ + rootPath; + /** + * A collection of all roots encountered, referenced by rootPath + */ + roots; + /** + * The Path entry corresponding to this PathScurry's current working directory. + */ + cwd; + #resolveCache; + #resolvePosixCache; + #children; + /** + * Perform path comparisons case-insensitively. + * + * Defaults true on Darwin and Windows systems, false elsewhere. + */ + nocase; + #fs; + /** + * This class should not be instantiated directly. + * + * Use PathScurryWin32, PathScurryDarwin, PathScurryPosix, or PathScurry + * + * @internal + */ + constructor(cwd = process.cwd(), pathImpl, sep, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS, } = {}) { + this.#fs = fsFromOption(fs); + if (cwd instanceof URL || cwd.startsWith('file://')) { + cwd = (0, node_url_1.fileURLToPath)(cwd); + } + // resolve and split root, and then add to the store. + // this is the only time we call path.resolve() + const cwdPath = pathImpl.resolve(cwd); + this.roots = Object.create(null); + this.rootPath = this.parseRootPath(cwdPath); + this.#resolveCache = new ResolveCache(); + this.#resolvePosixCache = new ResolveCache(); + this.#children = new ChildrenCache(childrenCacheSize); + const split = cwdPath.substring(this.rootPath.length).split(sep); + // resolve('/') leaves '', splits to [''], we don't want that. + if (split.length === 1 && !split[0]) { + split.pop(); + } + /* c8 ignore start */ + if (nocase === undefined) { + throw new TypeError('must provide nocase setting to PathScurryBase ctor'); + } + /* c8 ignore stop */ + this.nocase = nocase; + this.root = this.newRoot(this.#fs); + this.roots[this.rootPath] = this.root; + let prev = this.root; + let len = split.length - 1; + const joinSep = pathImpl.sep; + let abs = this.rootPath; + let sawFirst = false; + for (const part of split) { + const l = len--; + prev = prev.child(part, { + relative: new Array(l).fill('..').join(joinSep), + relativePosix: new Array(l).fill('..').join('/'), + fullpath: (abs += (sawFirst ? '' : joinSep) + part), + }); + sawFirst = true; + } + this.cwd = prev; + } + /** + * Get the depth of a provided path, string, or the cwd + */ + depth(path = this.cwd) { + if (typeof path === 'string') { + path = this.cwd.resolve(path); + } + return path.depth(); + } + /** + * Return the cache of child entries. Exposed so subclasses can create + * child Path objects in a platform-specific way. + * + * @internal + */ + childrenCache() { + return this.#children; + } + /** + * Resolve one or more path strings to a resolved string + * + * Same interface as require('path').resolve. + * + * Much faster than path.resolve() when called multiple times for the same + * path, because the resolved Path objects are cached. Much slower + * otherwise. + */ + resolve(...paths) { + // first figure out the minimum number of paths we have to test + // we always start at cwd, but any absolutes will bump the start + let r = ''; + for (let i = paths.length - 1; i >= 0; i--) { + const p = paths[i]; + if (!p || p === '.') + continue; + r = r ? `${p}/${r}` : p; + if (this.isAbsolute(p)) { + break; + } + } + const cached = this.#resolveCache.get(r); + if (cached !== undefined) { + return cached; + } + const result = this.cwd.resolve(r).fullpath(); + this.#resolveCache.set(r, result); + return result; + } + /** + * Resolve one or more path strings to a resolved string, returning + * the posix path. Identical to .resolve() on posix systems, but on + * windows will return a forward-slash separated UNC path. + * + * Same interface as require('path').resolve. + * + * Much faster than path.resolve() when called multiple times for the same + * path, because the resolved Path objects are cached. Much slower + * otherwise. + */ + resolvePosix(...paths) { + // first figure out the minimum number of paths we have to test + // we always start at cwd, but any absolutes will bump the start + let r = ''; + for (let i = paths.length - 1; i >= 0; i--) { + const p = paths[i]; + if (!p || p === '.') + continue; + r = r ? `${p}/${r}` : p; + if (this.isAbsolute(p)) { + break; + } + } + const cached = this.#resolvePosixCache.get(r); + if (cached !== undefined) { + return cached; + } + const result = this.cwd.resolve(r).fullpathPosix(); + this.#resolvePosixCache.set(r, result); + return result; + } + /** + * find the relative path from the cwd to the supplied path string or entry + */ + relative(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.relative(); + } + /** + * find the relative path from the cwd to the supplied path string or + * entry, using / as the path delimiter, even on Windows. + */ + relativePosix(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.relativePosix(); + } + /** + * Return the basename for the provided string or Path object + */ + basename(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.name; + } + /** + * Return the dirname for the provided string or Path object + */ + dirname(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return (entry.parent || entry).fullpath(); + } + async readdir(entry = this.cwd, opts = { + withFileTypes: true, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes } = opts; + if (!entry.canReaddir()) { + return []; + } + else { + const p = await entry.readdir(); + return withFileTypes ? p : p.map(e => e.name); + } + } + readdirSync(entry = this.cwd, opts = { + withFileTypes: true, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true } = opts; + if (!entry.canReaddir()) { + return []; + } + else if (withFileTypes) { + return entry.readdirSync(); + } + else { + return entry.readdirSync().map(e => e.name); + } + } + /** + * Call lstat() on the string or Path object, and update all known + * information that can be determined. + * + * Note that unlike `fs.lstat()`, the returned value does not contain some + * information, such as `mode`, `dev`, `nlink`, and `ino`. If that + * information is required, you will need to call `fs.lstat` yourself. + * + * If the Path refers to a nonexistent file, or if the lstat call fails for + * any reason, `undefined` is returned. Otherwise the updated Path object is + * returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async lstat(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.lstat(); + } + /** + * synchronous {@link PathScurryBase.lstat} + */ + lstatSync(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.lstatSync(); + } + async readlink(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = await entry.readlink(); + return withFileTypes ? e : e?.fullpath(); + } + readlinkSync(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = entry.readlinkSync(); + return withFileTypes ? e : e?.fullpath(); + } + async realpath(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = await entry.realpath(); + return withFileTypes ? e : e?.fullpath(); + } + realpathSync(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = entry.realpathSync(); + return withFileTypes ? e : e?.fullpath(); + } + async walk(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = []; + if (!filter || filter(entry)) { + results.push(withFileTypes ? entry : entry.fullpath()); + } + const dirs = new Set(); + const walk = (dir, cb) => { + dirs.add(dir); + dir.readdirCB((er, entries) => { + /* c8 ignore start */ + if (er) { + return cb(er); + } + /* c8 ignore stop */ + let len = entries.length; + if (!len) + return cb(); + const next = () => { + if (--len === 0) { + cb(); + } + }; + for (const e of entries) { + if (!filter || filter(e)) { + results.push(withFileTypes ? e : e.fullpath()); + } + if (follow && e.isSymbolicLink()) { + e.realpath() + .then(r => (r?.isUnknown() ? r.lstat() : r)) + .then(r => r?.shouldWalk(dirs, walkFilter) ? walk(r, next) : next()); + } + else { + if (e.shouldWalk(dirs, walkFilter)) { + walk(e, next); + } + else { + next(); + } + } + } + }, true); // zalgooooooo + }; + const start = entry; + return new Promise((res, rej) => { + walk(start, er => { + /* c8 ignore start */ + if (er) + return rej(er); + /* c8 ignore stop */ + res(results); + }); + }); + } + walkSync(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = []; + if (!filter || filter(entry)) { + results.push(withFileTypes ? entry : entry.fullpath()); + } + const dirs = new Set([entry]); + for (const dir of dirs) { + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter || filter(e)) { + results.push(withFileTypes ? e : e.fullpath()); + } + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + dirs.add(r); + } + } + } + return results; + } + /** + * Support for `for await` + * + * Alias for {@link PathScurryBase.iterate} + * + * Note: As of Node 19, this is very slow, compared to other methods of + * walking. Consider using {@link PathScurryBase.stream} if memory overhead + * and backpressure are concerns, or {@link PathScurryBase.walk} if not. + */ + [Symbol.asyncIterator]() { + return this.iterate(); + } + iterate(entry = this.cwd, options = {}) { + // iterating async over the stream is significantly more performant, + // especially in the warm-cache scenario, because it buffers up directory + // entries in the background instead of waiting for a yield for each one. + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + options = entry; + entry = this.cwd; + } + return this.stream(entry, options)[Symbol.asyncIterator](); + } + /** + * Iterating over a PathScurry performs a synchronous walk. + * + * Alias for {@link PathScurryBase.iterateSync} + */ + [Symbol.iterator]() { + return this.iterateSync(); + } + *iterateSync(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + if (!filter || filter(entry)) { + yield withFileTypes ? entry : entry.fullpath(); + } + const dirs = new Set([entry]); + for (const dir of dirs) { + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter || filter(e)) { + yield withFileTypes ? e : e.fullpath(); + } + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + dirs.add(r); + } + } + } + } + stream(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = new minipass_1.Minipass({ objectMode: true }); + if (!filter || filter(entry)) { + results.write(withFileTypes ? entry : entry.fullpath()); + } + const dirs = new Set(); + const queue = [entry]; + let processing = 0; + const process = () => { + let paused = false; + while (!paused) { + const dir = queue.shift(); + if (!dir) { + if (processing === 0) + results.end(); + return; + } + processing++; + dirs.add(dir); + const onReaddir = (er, entries, didRealpaths = false) => { + /* c8 ignore start */ + if (er) + return results.emit('error', er); + /* c8 ignore stop */ + if (follow && !didRealpaths) { + const promises = []; + for (const e of entries) { + if (e.isSymbolicLink()) { + promises.push(e + .realpath() + .then((r) => r?.isUnknown() ? r.lstat() : r)); + } + } + if (promises.length) { + Promise.all(promises).then(() => onReaddir(null, entries, true)); + return; + } + } + for (const e of entries) { + if (e && (!filter || filter(e))) { + if (!results.write(withFileTypes ? e : e.fullpath())) { + paused = true; + } + } + } + processing--; + for (const e of entries) { + const r = e.realpathCached() || e; + if (r.shouldWalk(dirs, walkFilter)) { + queue.push(r); + } + } + if (paused && !results.flowing) { + results.once('drain', process); + } + else if (!sync) { + process(); + } + }; + // zalgo containment + let sync = true; + dir.readdirCB(onReaddir, true); + sync = false; + } + }; + process(); + return results; + } + streamSync(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = new minipass_1.Minipass({ objectMode: true }); + const dirs = new Set(); + if (!filter || filter(entry)) { + results.write(withFileTypes ? entry : entry.fullpath()); + } + const queue = [entry]; + let processing = 0; + const process = () => { + let paused = false; + while (!paused) { + const dir = queue.shift(); + if (!dir) { + if (processing === 0) + results.end(); + return; + } + processing++; + dirs.add(dir); + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter || filter(e)) { + if (!results.write(withFileTypes ? e : e.fullpath())) { + paused = true; + } + } + } + processing--; + for (const e of entries) { + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + queue.push(r); + } + } + } + if (paused && !results.flowing) + results.once('drain', process); + }; + process(); + return results; + } + chdir(path = this.cwd) { + const oldCwd = this.cwd; + this.cwd = typeof path === 'string' ? this.cwd.resolve(path) : path; + this.cwd[setAsCwd](oldCwd); + } +} +exports.PathScurryBase = PathScurryBase; +/** + * Windows implementation of {@link PathScurryBase} + * + * Defaults to case insensitve, uses `'\\'` to generate path strings. Uses + * {@link PathWin32} for Path objects. + */ +class PathScurryWin32 extends PathScurryBase { + /** + * separator for generating path strings + */ + sep = '\\'; + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = true } = opts; + super(cwd, node_path_1.win32, '\\', { ...opts, nocase }); + this.nocase = nocase; + for (let p = this.cwd; p; p = p.parent) { + p.nocase = this.nocase; + } + } + /** + * @internal + */ + parseRootPath(dir) { + // if the path starts with a single separator, it's not a UNC, and we'll + // just get separator as the root, and driveFromUNC will return \ + // In that case, mount \ on the root from the cwd. + return node_path_1.win32.parse(dir).root.toUpperCase(); + } + /** + * @internal + */ + newRoot(fs) { + return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs }); + } + /** + * Return true if the provided path string is an absolute path + */ + isAbsolute(p) { + return (p.startsWith('/') || p.startsWith('\\') || /^[a-z]:(\/|\\)/i.test(p)); + } +} +exports.PathScurryWin32 = PathScurryWin32; +/** + * {@link PathScurryBase} implementation for all posix systems other than Darwin. + * + * Defaults to case-sensitive matching, uses `'/'` to generate path strings. + * + * Uses {@link PathPosix} for Path objects. + */ +class PathScurryPosix extends PathScurryBase { + /** + * separator for generating path strings + */ + sep = '/'; + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = false } = opts; + super(cwd, node_path_1.posix, '/', { ...opts, nocase }); + this.nocase = nocase; + } + /** + * @internal + */ + parseRootPath(_dir) { + return '/'; + } + /** + * @internal + */ + newRoot(fs) { + return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs }); + } + /** + * Return true if the provided path string is an absolute path + */ + isAbsolute(p) { + return p.startsWith('/'); + } +} +exports.PathScurryPosix = PathScurryPosix; +/** + * {@link PathScurryBase} implementation for Darwin (macOS) systems. + * + * Defaults to case-insensitive matching, uses `'/'` for generating path + * strings. + * + * Uses {@link PathPosix} for Path objects. + */ +class PathScurryDarwin extends PathScurryPosix { + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = true } = opts; + super(cwd, { ...opts, nocase }); + } +} +exports.PathScurryDarwin = PathScurryDarwin; +/** + * Default {@link PathBase} implementation for the current platform. + * + * {@link PathWin32} on Windows systems, {@link PathPosix} on all others. + */ +exports.Path = process.platform === 'win32' ? PathWin32 : PathPosix; +/** + * Default {@link PathScurryBase} implementation for the current platform. + * + * {@link PathScurryWin32} on Windows systems, {@link PathScurryDarwin} on + * Darwin (macOS) systems, {@link PathScurryPosix} on all others. + */ +exports.PathScurry = process.platform === 'win32' ? PathScurryWin32 + : process.platform === 'darwin' ? PathScurryDarwin + : PathScurryPosix; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/path-scurry/dist/commonjs/package.json b/node_modules/path-scurry/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/path-scurry/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/path-scurry/dist/esm/index.js b/node_modules/path-scurry/dist/esm/index.js new file mode 100644 index 0000000000000..dc7cae493aa50 --- /dev/null +++ b/node_modules/path-scurry/dist/esm/index.js @@ -0,0 +1,1983 @@ +import { LRUCache } from 'lru-cache'; +import { posix, win32 } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { lstatSync, readdir as readdirCB, readdirSync, readlinkSync, realpathSync as rps, } from 'fs'; +import * as actualFS from 'node:fs'; +const realpathSync = rps.native; +// TODO: test perf of fs/promises realpath vs realpathCB, +// since the promises one uses realpath.native +import { lstat, readdir, readlink, realpath } from 'node:fs/promises'; +import { Minipass } from 'minipass'; +const defaultFS = { + lstatSync, + readdir: readdirCB, + readdirSync, + readlinkSync, + realpathSync, + promises: { + lstat, + readdir, + readlink, + realpath, + }, +}; +// if they just gave us require('fs') then use our default +const fsFromOption = (fsOption) => !fsOption || fsOption === defaultFS || fsOption === actualFS ? + defaultFS + : { + ...defaultFS, + ...fsOption, + promises: { + ...defaultFS.promises, + ...(fsOption.promises || {}), + }, + }; +// turn something like //?/c:/ into c:\ +const uncDriveRegexp = /^\\\\\?\\([a-z]:)\\?$/i; +const uncToDrive = (rootPath) => rootPath.replace(/\//g, '\\').replace(uncDriveRegexp, '$1\\'); +// windows paths are separated by either / or \ +const eitherSep = /[\\\/]/; +const UNKNOWN = 0; // may not even exist, for all we know +const IFIFO = 0b0001; +const IFCHR = 0b0010; +const IFDIR = 0b0100; +const IFBLK = 0b0110; +const IFREG = 0b1000; +const IFLNK = 0b1010; +const IFSOCK = 0b1100; +const IFMT = 0b1111; +// mask to unset low 4 bits +const IFMT_UNKNOWN = ~IFMT; +// set after successfully calling readdir() and getting entries. +const READDIR_CALLED = 0b0000_0001_0000; +// set after a successful lstat() +const LSTAT_CALLED = 0b0000_0010_0000; +// set if an entry (or one of its parents) is definitely not a dir +const ENOTDIR = 0b0000_0100_0000; +// set if an entry (or one of its parents) does not exist +// (can also be set on lstat errors like EACCES or ENAMETOOLONG) +const ENOENT = 0b0000_1000_0000; +// cannot have child entries -- also verify &IFMT is either IFDIR or IFLNK +// set if we fail to readlink +const ENOREADLINK = 0b0001_0000_0000; +// set if we know realpath() will fail +const ENOREALPATH = 0b0010_0000_0000; +const ENOCHILD = ENOTDIR | ENOENT | ENOREALPATH; +const TYPEMASK = 0b0011_1111_1111; +const entToType = (s) => s.isFile() ? IFREG + : s.isDirectory() ? IFDIR + : s.isSymbolicLink() ? IFLNK + : s.isCharacterDevice() ? IFCHR + : s.isBlockDevice() ? IFBLK + : s.isSocket() ? IFSOCK + : s.isFIFO() ? IFIFO + : UNKNOWN; +// normalize unicode path names +const normalizeCache = new LRUCache({ max: 2 ** 12 }); +const normalize = (s) => { + const c = normalizeCache.get(s); + if (c) + return c; + const n = s.normalize('NFKD'); + normalizeCache.set(s, n); + return n; +}; +const normalizeNocaseCache = new LRUCache({ max: 2 ** 12 }); +const normalizeNocase = (s) => { + const c = normalizeNocaseCache.get(s); + if (c) + return c; + const n = normalize(s.toLowerCase()); + normalizeNocaseCache.set(s, n); + return n; +}; +/** + * An LRUCache for storing resolved path strings or Path objects. + * @internal + */ +export class ResolveCache extends LRUCache { + constructor() { + super({ max: 256 }); + } +} +// In order to prevent blowing out the js heap by allocating hundreds of +// thousands of Path entries when walking extremely large trees, the "children" +// in this tree are represented by storing an array of Path entries in an +// LRUCache, indexed by the parent. At any time, Path.children() may return an +// empty array, indicating that it doesn't know about any of its children, and +// thus has to rebuild that cache. This is fine, it just means that we don't +// benefit as much from having the cached entries, but huge directory walks +// don't blow out the stack, and smaller ones are still as fast as possible. +// +//It does impose some complexity when building up the readdir data, because we +//need to pass a reference to the children array that we started with. +/** + * an LRUCache for storing child entries. + * @internal + */ +export class ChildrenCache extends LRUCache { + constructor(maxSize = 16 * 1024) { + super({ + maxSize, + // parent + children + sizeCalculation: a => a.length + 1, + }); + } +} +const setAsCwd = Symbol('PathScurry setAsCwd'); +/** + * Path objects are sort of like a super-powered + * {@link https://nodejs.org/docs/latest/api/fs.html#class-fsdirent fs.Dirent} + * + * Each one represents a single filesystem entry on disk, which may or may not + * exist. It includes methods for reading various types of information via + * lstat, readlink, and readdir, and caches all information to the greatest + * degree possible. + * + * Note that fs operations that would normally throw will instead return an + * "empty" value. This is in order to prevent excessive overhead from error + * stack traces. + */ +export class PathBase { + /** + * the basename of this path + * + * **Important**: *always* test the path name against any test string + * usingthe {@link isNamed} method, and not by directly comparing this + * string. Otherwise, unicode path strings that the system sees as identical + * will not be properly treated as the same path, leading to incorrect + * behavior and possible security issues. + */ + name; + /** + * the Path entry corresponding to the path root. + * + * @internal + */ + root; + /** + * All roots found within the current PathScurry family + * + * @internal + */ + roots; + /** + * a reference to the parent path, or undefined in the case of root entries + * + * @internal + */ + parent; + /** + * boolean indicating whether paths are compared case-insensitively + * @internal + */ + nocase; + /** + * boolean indicating that this path is the current working directory + * of the PathScurry collection that contains it. + */ + isCWD = false; + // potential default fs override + #fs; + // Stats fields + #dev; + get dev() { + return this.#dev; + } + #mode; + get mode() { + return this.#mode; + } + #nlink; + get nlink() { + return this.#nlink; + } + #uid; + get uid() { + return this.#uid; + } + #gid; + get gid() { + return this.#gid; + } + #rdev; + get rdev() { + return this.#rdev; + } + #blksize; + get blksize() { + return this.#blksize; + } + #ino; + get ino() { + return this.#ino; + } + #size; + get size() { + return this.#size; + } + #blocks; + get blocks() { + return this.#blocks; + } + #atimeMs; + get atimeMs() { + return this.#atimeMs; + } + #mtimeMs; + get mtimeMs() { + return this.#mtimeMs; + } + #ctimeMs; + get ctimeMs() { + return this.#ctimeMs; + } + #birthtimeMs; + get birthtimeMs() { + return this.#birthtimeMs; + } + #atime; + get atime() { + return this.#atime; + } + #mtime; + get mtime() { + return this.#mtime; + } + #ctime; + get ctime() { + return this.#ctime; + } + #birthtime; + get birthtime() { + return this.#birthtime; + } + #matchName; + #depth; + #fullpath; + #fullpathPosix; + #relative; + #relativePosix; + #type; + #children; + #linkTarget; + #realpath; + /** + * This property is for compatibility with the Dirent class as of + * Node v20, where Dirent['parentPath'] refers to the path of the + * directory that was passed to readdir. For root entries, it's the path + * to the entry itself. + */ + get parentPath() { + return (this.parent || this).fullpath(); + } + /* c8 ignore start */ + /** + * Deprecated alias for Dirent['parentPath'] Somewhat counterintuitively, + * this property refers to the *parent* path, not the path object itself. + * + * @deprecated + */ + get path() { + return this.parentPath; + } + /* c8 ignore stop */ + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + this.name = name; + this.#matchName = nocase ? normalizeNocase(name) : normalize(name); + this.#type = type & TYPEMASK; + this.nocase = nocase; + this.roots = roots; + this.root = root || this; + this.#children = children; + this.#fullpath = opts.fullpath; + this.#relative = opts.relative; + this.#relativePosix = opts.relativePosix; + this.parent = opts.parent; + if (this.parent) { + this.#fs = this.parent.#fs; + } + else { + this.#fs = fsFromOption(opts.fs); + } + } + /** + * Returns the depth of the Path object from its root. + * + * For example, a path at `/foo/bar` would have a depth of 2. + */ + depth() { + if (this.#depth !== undefined) + return this.#depth; + if (!this.parent) + return (this.#depth = 0); + return (this.#depth = this.parent.depth() + 1); + } + /** + * @internal + */ + childrenCache() { + return this.#children; + } + /** + * Get the Path object referenced by the string path, resolved from this Path + */ + resolve(path) { + if (!path) { + return this; + } + const rootPath = this.getRootString(path); + const dir = path.substring(rootPath.length); + const dirParts = dir.split(this.splitSep); + const result = rootPath ? + this.getRoot(rootPath).#resolveParts(dirParts) + : this.#resolveParts(dirParts); + return result; + } + #resolveParts(dirParts) { + let p = this; + for (const part of dirParts) { + p = p.child(part); + } + return p; + } + /** + * Returns the cached children Path objects, if still available. If they + * have fallen out of the cache, then returns an empty array, and resets the + * READDIR_CALLED bit, so that future calls to readdir() will require an fs + * lookup. + * + * @internal + */ + children() { + const cached = this.#children.get(this); + if (cached) { + return cached; + } + const children = Object.assign([], { provisional: 0 }); + this.#children.set(this, children); + this.#type &= ~READDIR_CALLED; + return children; + } + /** + * Resolves a path portion and returns or creates the child Path. + * + * Returns `this` if pathPart is `''` or `'.'`, or `parent` if pathPart is + * `'..'`. + * + * This should not be called directly. If `pathPart` contains any path + * separators, it will lead to unsafe undefined behavior. + * + * Use `Path.resolve()` instead. + * + * @internal + */ + child(pathPart, opts) { + if (pathPart === '' || pathPart === '.') { + return this; + } + if (pathPart === '..') { + return this.parent || this; + } + // find the child + const children = this.children(); + const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart); + for (const p of children) { + if (p.#matchName === name) { + return p; + } + } + // didn't find it, create provisional child, since it might not + // actually exist. If we know the parent isn't a dir, then + // in fact it CAN'T exist. + const s = this.parent ? this.sep : ''; + const fullpath = this.#fullpath ? this.#fullpath + s + pathPart : undefined; + const pchild = this.newChild(pathPart, UNKNOWN, { + ...opts, + parent: this, + fullpath, + }); + if (!this.canReaddir()) { + pchild.#type |= ENOENT; + } + // don't have to update provisional, because if we have real children, + // then provisional is set to children.length, otherwise a lower number + children.push(pchild); + return pchild; + } + /** + * The relative path from the cwd. If it does not share an ancestor with + * the cwd, then this ends up being equivalent to the fullpath() + */ + relative() { + if (this.isCWD) + return ''; + if (this.#relative !== undefined) { + return this.#relative; + } + const name = this.name; + const p = this.parent; + if (!p) { + return (this.#relative = this.name); + } + const pv = p.relative(); + return pv + (!pv || !p.parent ? '' : this.sep) + name; + } + /** + * The relative path from the cwd, using / as the path separator. + * If it does not share an ancestor with + * the cwd, then this ends up being equivalent to the fullpathPosix() + * On posix systems, this is identical to relative(). + */ + relativePosix() { + if (this.sep === '/') + return this.relative(); + if (this.isCWD) + return ''; + if (this.#relativePosix !== undefined) + return this.#relativePosix; + const name = this.name; + const p = this.parent; + if (!p) { + return (this.#relativePosix = this.fullpathPosix()); + } + const pv = p.relativePosix(); + return pv + (!pv || !p.parent ? '' : '/') + name; + } + /** + * The fully resolved path string for this Path entry + */ + fullpath() { + if (this.#fullpath !== undefined) { + return this.#fullpath; + } + const name = this.name; + const p = this.parent; + if (!p) { + return (this.#fullpath = this.name); + } + const pv = p.fullpath(); + const fp = pv + (!p.parent ? '' : this.sep) + name; + return (this.#fullpath = fp); + } + /** + * On platforms other than windows, this is identical to fullpath. + * + * On windows, this is overridden to return the forward-slash form of the + * full UNC path. + */ + fullpathPosix() { + if (this.#fullpathPosix !== undefined) + return this.#fullpathPosix; + if (this.sep === '/') + return (this.#fullpathPosix = this.fullpath()); + if (!this.parent) { + const p = this.fullpath().replace(/\\/g, '/'); + if (/^[a-z]:\//i.test(p)) { + return (this.#fullpathPosix = `//?/${p}`); + } + else { + return (this.#fullpathPosix = p); + } + } + const p = this.parent; + const pfpp = p.fullpathPosix(); + const fpp = pfpp + (!pfpp || !p.parent ? '' : '/') + this.name; + return (this.#fullpathPosix = fpp); + } + /** + * Is the Path of an unknown type? + * + * Note that we might know *something* about it if there has been a previous + * filesystem operation, for example that it does not exist, or is not a + * link, or whether it has child entries. + */ + isUnknown() { + return (this.#type & IFMT) === UNKNOWN; + } + isType(type) { + return this[`is${type}`](); + } + getType() { + return (this.isUnknown() ? 'Unknown' + : this.isDirectory() ? 'Directory' + : this.isFile() ? 'File' + : this.isSymbolicLink() ? 'SymbolicLink' + : this.isFIFO() ? 'FIFO' + : this.isCharacterDevice() ? 'CharacterDevice' + : this.isBlockDevice() ? 'BlockDevice' + : /* c8 ignore start */ this.isSocket() ? 'Socket' + : 'Unknown'); + /* c8 ignore stop */ + } + /** + * Is the Path a regular file? + */ + isFile() { + return (this.#type & IFMT) === IFREG; + } + /** + * Is the Path a directory? + */ + isDirectory() { + return (this.#type & IFMT) === IFDIR; + } + /** + * Is the path a character device? + */ + isCharacterDevice() { + return (this.#type & IFMT) === IFCHR; + } + /** + * Is the path a block device? + */ + isBlockDevice() { + return (this.#type & IFMT) === IFBLK; + } + /** + * Is the path a FIFO pipe? + */ + isFIFO() { + return (this.#type & IFMT) === IFIFO; + } + /** + * Is the path a socket? + */ + isSocket() { + return (this.#type & IFMT) === IFSOCK; + } + /** + * Is the path a symbolic link? + */ + isSymbolicLink() { + return (this.#type & IFLNK) === IFLNK; + } + /** + * Return the entry if it has been subject of a successful lstat, or + * undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* simply + * mean that we haven't called lstat on it. + */ + lstatCached() { + return this.#type & LSTAT_CALLED ? this : undefined; + } + /** + * Return the cached link target if the entry has been the subject of a + * successful readlink, or undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * readlink() has been called at some point. + */ + readlinkCached() { + return this.#linkTarget; + } + /** + * Returns the cached realpath target if the entry has been the subject + * of a successful realpath, or undefined otherwise. + * + * Does not read the filesystem, so an undefined result *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * realpath() has been called at some point. + */ + realpathCached() { + return this.#realpath; + } + /** + * Returns the cached child Path entries array if the entry has been the + * subject of a successful readdir(), or [] otherwise. + * + * Does not read the filesystem, so an empty array *could* just mean we + * don't have any cached data. Only use it if you are very sure that a + * readdir() has been called recently enough to still be valid. + */ + readdirCached() { + const children = this.children(); + return children.slice(0, children.provisional); + } + /** + * Return true if it's worth trying to readlink. Ie, we don't (yet) have + * any indication that readlink will definitely fail. + * + * Returns false if the path is known to not be a symlink, if a previous + * readlink failed, or if the entry does not exist. + */ + canReadlink() { + if (this.#linkTarget) + return true; + if (!this.parent) + return false; + // cases where it cannot possibly succeed + const ifmt = this.#type & IFMT; + return !((ifmt !== UNKNOWN && ifmt !== IFLNK) || + this.#type & ENOREADLINK || + this.#type & ENOENT); + } + /** + * Return true if readdir has previously been successfully called on this + * path, indicating that cachedReaddir() is likely valid. + */ + calledReaddir() { + return !!(this.#type & READDIR_CALLED); + } + /** + * Returns true if the path is known to not exist. That is, a previous lstat + * or readdir failed to verify its existence when that would have been + * expected, or a parent entry was marked either enoent or enotdir. + */ + isENOENT() { + return !!(this.#type & ENOENT); + } + /** + * Return true if the path is a match for the given path name. This handles + * case sensitivity and unicode normalization. + * + * Note: even on case-sensitive systems, it is **not** safe to test the + * equality of the `.name` property to determine whether a given pathname + * matches, due to unicode normalization mismatches. + * + * Always use this method instead of testing the `path.name` property + * directly. + */ + isNamed(n) { + return !this.nocase ? + this.#matchName === normalize(n) + : this.#matchName === normalizeNocase(n); + } + /** + * Return the Path object corresponding to the target of a symbolic link. + * + * If the Path is not a symbolic link, or if the readlink call fails for any + * reason, `undefined` is returned. + * + * Result is cached, and thus may be outdated if the filesystem is mutated. + */ + async readlink() { + const target = this.#linkTarget; + if (target) { + return target; + } + if (!this.canReadlink()) { + return undefined; + } + /* c8 ignore start */ + // already covered by the canReadlink test, here for ts grumples + if (!this.parent) { + return undefined; + } + /* c8 ignore stop */ + try { + const read = await this.#fs.promises.readlink(this.fullpath()); + const linkTarget = (await this.parent.realpath())?.resolve(read); + if (linkTarget) { + return (this.#linkTarget = linkTarget); + } + } + catch (er) { + this.#readlinkFail(er.code); + return undefined; + } + } + /** + * Synchronous {@link PathBase.readlink} + */ + readlinkSync() { + const target = this.#linkTarget; + if (target) { + return target; + } + if (!this.canReadlink()) { + return undefined; + } + /* c8 ignore start */ + // already covered by the canReadlink test, here for ts grumples + if (!this.parent) { + return undefined; + } + /* c8 ignore stop */ + try { + const read = this.#fs.readlinkSync(this.fullpath()); + const linkTarget = this.parent.realpathSync()?.resolve(read); + if (linkTarget) { + return (this.#linkTarget = linkTarget); + } + } + catch (er) { + this.#readlinkFail(er.code); + return undefined; + } + } + #readdirSuccess(children) { + // succeeded, mark readdir called bit + this.#type |= READDIR_CALLED; + // mark all remaining provisional children as ENOENT + for (let p = children.provisional; p < children.length; p++) { + const c = children[p]; + if (c) + c.#markENOENT(); + } + } + #markENOENT() { + // mark as UNKNOWN and ENOENT + if (this.#type & ENOENT) + return; + this.#type = (this.#type | ENOENT) & IFMT_UNKNOWN; + this.#markChildrenENOENT(); + } + #markChildrenENOENT() { + // all children are provisional and do not exist + const children = this.children(); + children.provisional = 0; + for (const p of children) { + p.#markENOENT(); + } + } + #markENOREALPATH() { + this.#type |= ENOREALPATH; + this.#markENOTDIR(); + } + // save the information when we know the entry is not a dir + #markENOTDIR() { + // entry is not a directory, so any children can't exist. + // this *should* be impossible, since any children created + // after it's been marked ENOTDIR should be marked ENOENT, + // so it won't even get to this point. + /* c8 ignore start */ + if (this.#type & ENOTDIR) + return; + /* c8 ignore stop */ + let t = this.#type; + // this could happen if we stat a dir, then delete it, + // then try to read it or one of its children. + if ((t & IFMT) === IFDIR) + t &= IFMT_UNKNOWN; + this.#type = t | ENOTDIR; + this.#markChildrenENOENT(); + } + #readdirFail(code = '') { + // markENOTDIR and markENOENT also set provisional=0 + if (code === 'ENOTDIR' || code === 'EPERM') { + this.#markENOTDIR(); + } + else if (code === 'ENOENT') { + this.#markENOENT(); + } + else { + this.children().provisional = 0; + } + } + #lstatFail(code = '') { + // Windows just raises ENOENT in this case, disable for win CI + /* c8 ignore start */ + if (code === 'ENOTDIR') { + // already know it has a parent by this point + const p = this.parent; + p.#markENOTDIR(); + } + else if (code === 'ENOENT') { + /* c8 ignore stop */ + this.#markENOENT(); + } + } + #readlinkFail(code = '') { + let ter = this.#type; + ter |= ENOREADLINK; + if (code === 'ENOENT') + ter |= ENOENT; + // windows gets a weird error when you try to readlink a file + if (code === 'EINVAL' || code === 'UNKNOWN') { + // exists, but not a symlink, we don't know WHAT it is, so remove + // all IFMT bits. + ter &= IFMT_UNKNOWN; + } + this.#type = ter; + // windows just gets ENOENT in this case. We do cover the case, + // just disabled because it's impossible on Windows CI + /* c8 ignore start */ + if (code === 'ENOTDIR' && this.parent) { + this.parent.#markENOTDIR(); + } + /* c8 ignore stop */ + } + #readdirAddChild(e, c) { + return (this.#readdirMaybePromoteChild(e, c) || + this.#readdirAddNewChild(e, c)); + } + #readdirAddNewChild(e, c) { + // alloc new entry at head, so it's never provisional + const type = entToType(e); + const child = this.newChild(e.name, type, { parent: this }); + const ifmt = child.#type & IFMT; + if (ifmt !== IFDIR && ifmt !== IFLNK && ifmt !== UNKNOWN) { + child.#type |= ENOTDIR; + } + c.unshift(child); + c.provisional++; + return child; + } + #readdirMaybePromoteChild(e, c) { + for (let p = c.provisional; p < c.length; p++) { + const pchild = c[p]; + const name = this.nocase ? normalizeNocase(e.name) : normalize(e.name); + if (name !== pchild.#matchName) { + continue; + } + return this.#readdirPromoteChild(e, pchild, p, c); + } + } + #readdirPromoteChild(e, p, index, c) { + const v = p.name; + // retain any other flags, but set ifmt from dirent + p.#type = (p.#type & IFMT_UNKNOWN) | entToType(e); + // case sensitivity fixing when we learn the true name. + if (v !== e.name) + p.name = e.name; + // just advance provisional index (potentially off the list), + // otherwise we have to splice/pop it out and re-insert at head + if (index !== c.provisional) { + if (index === c.length - 1) + c.pop(); + else + c.splice(index, 1); + c.unshift(p); + } + c.provisional++; + return p; + } + /** + * Call lstat() on this Path, and update all known information that can be + * determined. + * + * Note that unlike `fs.lstat()`, the returned value does not contain some + * information, such as `mode`, `dev`, `nlink`, and `ino`. If that + * information is required, you will need to call `fs.lstat` yourself. + * + * If the Path refers to a nonexistent file, or if the lstat call fails for + * any reason, `undefined` is returned. Otherwise the updated Path object is + * returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async lstat() { + if ((this.#type & ENOENT) === 0) { + try { + this.#applyStat(await this.#fs.promises.lstat(this.fullpath())); + return this; + } + catch (er) { + this.#lstatFail(er.code); + } + } + } + /** + * synchronous {@link PathBase.lstat} + */ + lstatSync() { + if ((this.#type & ENOENT) === 0) { + try { + this.#applyStat(this.#fs.lstatSync(this.fullpath())); + return this; + } + catch (er) { + this.#lstatFail(er.code); + } + } + } + #applyStat(st) { + const { atime, atimeMs, birthtime, birthtimeMs, blksize, blocks, ctime, ctimeMs, dev, gid, ino, mode, mtime, mtimeMs, nlink, rdev, size, uid, } = st; + this.#atime = atime; + this.#atimeMs = atimeMs; + this.#birthtime = birthtime; + this.#birthtimeMs = birthtimeMs; + this.#blksize = blksize; + this.#blocks = blocks; + this.#ctime = ctime; + this.#ctimeMs = ctimeMs; + this.#dev = dev; + this.#gid = gid; + this.#ino = ino; + this.#mode = mode; + this.#mtime = mtime; + this.#mtimeMs = mtimeMs; + this.#nlink = nlink; + this.#rdev = rdev; + this.#size = size; + this.#uid = uid; + const ifmt = entToType(st); + // retain any other flags, but set the ifmt + this.#type = (this.#type & IFMT_UNKNOWN) | ifmt | LSTAT_CALLED; + if (ifmt !== UNKNOWN && ifmt !== IFDIR && ifmt !== IFLNK) { + this.#type |= ENOTDIR; + } + } + #onReaddirCB = []; + #readdirCBInFlight = false; + #callOnReaddirCB(children) { + this.#readdirCBInFlight = false; + const cbs = this.#onReaddirCB.slice(); + this.#onReaddirCB.length = 0; + cbs.forEach(cb => cb(null, children)); + } + /** + * Standard node-style callback interface to get list of directory entries. + * + * If the Path cannot or does not contain any children, then an empty array + * is returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + * + * @param cb The callback called with (er, entries). Note that the `er` + * param is somewhat extraneous, as all readdir() errors are handled and + * simply result in an empty set of entries being returned. + * @param allowZalgo Boolean indicating that immediately known results should + * *not* be deferred with `queueMicrotask`. Defaults to `false`. Release + * zalgo at your peril, the dark pony lord is devious and unforgiving. + */ + readdirCB(cb, allowZalgo = false) { + if (!this.canReaddir()) { + if (allowZalgo) + cb(null, []); + else + queueMicrotask(() => cb(null, [])); + return; + } + const children = this.children(); + if (this.calledReaddir()) { + const c = children.slice(0, children.provisional); + if (allowZalgo) + cb(null, c); + else + queueMicrotask(() => cb(null, c)); + return; + } + // don't have to worry about zalgo at this point. + this.#onReaddirCB.push(cb); + if (this.#readdirCBInFlight) { + return; + } + this.#readdirCBInFlight = true; + // else read the directory, fill up children + // de-provisionalize any provisional children. + const fullpath = this.fullpath(); + this.#fs.readdir(fullpath, { withFileTypes: true }, (er, entries) => { + if (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + else { + // if we didn't get an error, we always get entries. + //@ts-ignore + for (const e of entries) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + this.#callOnReaddirCB(children.slice(0, children.provisional)); + return; + }); + } + #asyncReaddirInFlight; + /** + * Return an array of known child entries. + * + * If the Path cannot or does not contain any children, then an empty array + * is returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async readdir() { + if (!this.canReaddir()) { + return []; + } + const children = this.children(); + if (this.calledReaddir()) { + return children.slice(0, children.provisional); + } + // else read the directory, fill up children + // de-provisionalize any provisional children. + const fullpath = this.fullpath(); + if (this.#asyncReaddirInFlight) { + await this.#asyncReaddirInFlight; + } + else { + /* c8 ignore start */ + let resolve = () => { }; + /* c8 ignore stop */ + this.#asyncReaddirInFlight = new Promise(res => (resolve = res)); + try { + for (const e of await this.#fs.promises.readdir(fullpath, { + withFileTypes: true, + })) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + catch (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + this.#asyncReaddirInFlight = undefined; + resolve(); + } + return children.slice(0, children.provisional); + } + /** + * synchronous {@link PathBase.readdir} + */ + readdirSync() { + if (!this.canReaddir()) { + return []; + } + const children = this.children(); + if (this.calledReaddir()) { + return children.slice(0, children.provisional); + } + // else read the directory, fill up children + // de-provisionalize any provisional children. + const fullpath = this.fullpath(); + try { + for (const e of this.#fs.readdirSync(fullpath, { + withFileTypes: true, + })) { + this.#readdirAddChild(e, children); + } + this.#readdirSuccess(children); + } + catch (er) { + this.#readdirFail(er.code); + children.provisional = 0; + } + return children.slice(0, children.provisional); + } + canReaddir() { + if (this.#type & ENOCHILD) + return false; + const ifmt = IFMT & this.#type; + // we always set ENOTDIR when setting IFMT, so should be impossible + /* c8 ignore start */ + if (!(ifmt === UNKNOWN || ifmt === IFDIR || ifmt === IFLNK)) { + return false; + } + /* c8 ignore stop */ + return true; + } + shouldWalk(dirs, walkFilter) { + return ((this.#type & IFDIR) === IFDIR && + !(this.#type & ENOCHILD) && + !dirs.has(this) && + (!walkFilter || walkFilter(this))); + } + /** + * Return the Path object corresponding to path as resolved + * by realpath(3). + * + * If the realpath call fails for any reason, `undefined` is returned. + * + * Result is cached, and thus may be outdated if the filesystem is mutated. + * On success, returns a Path object. + */ + async realpath() { + if (this.#realpath) + return this.#realpath; + if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) + return undefined; + try { + const rp = await this.#fs.promises.realpath(this.fullpath()); + return (this.#realpath = this.resolve(rp)); + } + catch (_) { + this.#markENOREALPATH(); + } + } + /** + * Synchronous {@link realpath} + */ + realpathSync() { + if (this.#realpath) + return this.#realpath; + if ((ENOREALPATH | ENOREADLINK | ENOENT) & this.#type) + return undefined; + try { + const rp = this.#fs.realpathSync(this.fullpath()); + return (this.#realpath = this.resolve(rp)); + } + catch (_) { + this.#markENOREALPATH(); + } + } + /** + * Internal method to mark this Path object as the scurry cwd, + * called by {@link PathScurry#chdir} + * + * @internal + */ + [setAsCwd](oldCwd) { + if (oldCwd === this) + return; + oldCwd.isCWD = false; + this.isCWD = true; + const changed = new Set([]); + let rp = []; + let p = this; + while (p && p.parent) { + changed.add(p); + p.#relative = rp.join(this.sep); + p.#relativePosix = rp.join('/'); + p = p.parent; + rp.push('..'); + } + // now un-memoize parents of old cwd + p = oldCwd; + while (p && p.parent && !changed.has(p)) { + p.#relative = undefined; + p.#relativePosix = undefined; + p = p.parent; + } + } +} +/** + * Path class used on win32 systems + * + * Uses `'\\'` as the path separator for returned paths, either `'\\'` or `'/'` + * as the path separator for parsing paths. + */ +export class PathWin32 extends PathBase { + /** + * Separator for generating path strings. + */ + sep = '\\'; + /** + * Separator for parsing path strings. + */ + splitSep = eitherSep; + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + super(name, type, root, roots, nocase, children, opts); + } + /** + * @internal + */ + newChild(name, type = UNKNOWN, opts = {}) { + return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts); + } + /** + * @internal + */ + getRootString(path) { + return win32.parse(path).root; + } + /** + * @internal + */ + getRoot(rootPath) { + rootPath = uncToDrive(rootPath.toUpperCase()); + if (rootPath === this.root.name) { + return this.root; + } + // ok, not that one, check if it matches another we know about + for (const [compare, root] of Object.entries(this.roots)) { + if (this.sameRoot(rootPath, compare)) { + return (this.roots[rootPath] = root); + } + } + // otherwise, have to create a new one. + return (this.roots[rootPath] = new PathScurryWin32(rootPath, this).root); + } + /** + * @internal + */ + sameRoot(rootPath, compare = this.root.name) { + // windows can (rarely) have case-sensitive filesystem, but + // UNC and drive letters are always case-insensitive, and canonically + // represented uppercase. + rootPath = rootPath + .toUpperCase() + .replace(/\//g, '\\') + .replace(uncDriveRegexp, '$1\\'); + return rootPath === compare; + } +} +/** + * Path class used on all posix systems. + * + * Uses `'/'` as the path separator. + */ +export class PathPosix extends PathBase { + /** + * separator for parsing path strings + */ + splitSep = '/'; + /** + * separator for generating path strings + */ + sep = '/'; + /** + * Do not create new Path objects directly. They should always be accessed + * via the PathScurry class or other methods on the Path class. + * + * @internal + */ + constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) { + super(name, type, root, roots, nocase, children, opts); + } + /** + * @internal + */ + getRootString(path) { + return path.startsWith('/') ? '/' : ''; + } + /** + * @internal + */ + getRoot(_rootPath) { + return this.root; + } + /** + * @internal + */ + newChild(name, type = UNKNOWN, opts = {}) { + return new PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts); + } +} +/** + * The base class for all PathScurry classes, providing the interface for path + * resolution and filesystem operations. + * + * Typically, you should *not* instantiate this class directly, but rather one + * of the platform-specific classes, or the exported {@link PathScurry} which + * defaults to the current platform. + */ +export class PathScurryBase { + /** + * The root Path entry for the current working directory of this Scurry + */ + root; + /** + * The string path for the root of this Scurry's current working directory + */ + rootPath; + /** + * A collection of all roots encountered, referenced by rootPath + */ + roots; + /** + * The Path entry corresponding to this PathScurry's current working directory. + */ + cwd; + #resolveCache; + #resolvePosixCache; + #children; + /** + * Perform path comparisons case-insensitively. + * + * Defaults true on Darwin and Windows systems, false elsewhere. + */ + nocase; + #fs; + /** + * This class should not be instantiated directly. + * + * Use PathScurryWin32, PathScurryDarwin, PathScurryPosix, or PathScurry + * + * @internal + */ + constructor(cwd = process.cwd(), pathImpl, sep, { nocase, childrenCacheSize = 16 * 1024, fs = defaultFS, } = {}) { + this.#fs = fsFromOption(fs); + if (cwd instanceof URL || cwd.startsWith('file://')) { + cwd = fileURLToPath(cwd); + } + // resolve and split root, and then add to the store. + // this is the only time we call path.resolve() + const cwdPath = pathImpl.resolve(cwd); + this.roots = Object.create(null); + this.rootPath = this.parseRootPath(cwdPath); + this.#resolveCache = new ResolveCache(); + this.#resolvePosixCache = new ResolveCache(); + this.#children = new ChildrenCache(childrenCacheSize); + const split = cwdPath.substring(this.rootPath.length).split(sep); + // resolve('/') leaves '', splits to [''], we don't want that. + if (split.length === 1 && !split[0]) { + split.pop(); + } + /* c8 ignore start */ + if (nocase === undefined) { + throw new TypeError('must provide nocase setting to PathScurryBase ctor'); + } + /* c8 ignore stop */ + this.nocase = nocase; + this.root = this.newRoot(this.#fs); + this.roots[this.rootPath] = this.root; + let prev = this.root; + let len = split.length - 1; + const joinSep = pathImpl.sep; + let abs = this.rootPath; + let sawFirst = false; + for (const part of split) { + const l = len--; + prev = prev.child(part, { + relative: new Array(l).fill('..').join(joinSep), + relativePosix: new Array(l).fill('..').join('/'), + fullpath: (abs += (sawFirst ? '' : joinSep) + part), + }); + sawFirst = true; + } + this.cwd = prev; + } + /** + * Get the depth of a provided path, string, or the cwd + */ + depth(path = this.cwd) { + if (typeof path === 'string') { + path = this.cwd.resolve(path); + } + return path.depth(); + } + /** + * Return the cache of child entries. Exposed so subclasses can create + * child Path objects in a platform-specific way. + * + * @internal + */ + childrenCache() { + return this.#children; + } + /** + * Resolve one or more path strings to a resolved string + * + * Same interface as require('path').resolve. + * + * Much faster than path.resolve() when called multiple times for the same + * path, because the resolved Path objects are cached. Much slower + * otherwise. + */ + resolve(...paths) { + // first figure out the minimum number of paths we have to test + // we always start at cwd, but any absolutes will bump the start + let r = ''; + for (let i = paths.length - 1; i >= 0; i--) { + const p = paths[i]; + if (!p || p === '.') + continue; + r = r ? `${p}/${r}` : p; + if (this.isAbsolute(p)) { + break; + } + } + const cached = this.#resolveCache.get(r); + if (cached !== undefined) { + return cached; + } + const result = this.cwd.resolve(r).fullpath(); + this.#resolveCache.set(r, result); + return result; + } + /** + * Resolve one or more path strings to a resolved string, returning + * the posix path. Identical to .resolve() on posix systems, but on + * windows will return a forward-slash separated UNC path. + * + * Same interface as require('path').resolve. + * + * Much faster than path.resolve() when called multiple times for the same + * path, because the resolved Path objects are cached. Much slower + * otherwise. + */ + resolvePosix(...paths) { + // first figure out the minimum number of paths we have to test + // we always start at cwd, but any absolutes will bump the start + let r = ''; + for (let i = paths.length - 1; i >= 0; i--) { + const p = paths[i]; + if (!p || p === '.') + continue; + r = r ? `${p}/${r}` : p; + if (this.isAbsolute(p)) { + break; + } + } + const cached = this.#resolvePosixCache.get(r); + if (cached !== undefined) { + return cached; + } + const result = this.cwd.resolve(r).fullpathPosix(); + this.#resolvePosixCache.set(r, result); + return result; + } + /** + * find the relative path from the cwd to the supplied path string or entry + */ + relative(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.relative(); + } + /** + * find the relative path from the cwd to the supplied path string or + * entry, using / as the path delimiter, even on Windows. + */ + relativePosix(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.relativePosix(); + } + /** + * Return the basename for the provided string or Path object + */ + basename(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.name; + } + /** + * Return the dirname for the provided string or Path object + */ + dirname(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return (entry.parent || entry).fullpath(); + } + async readdir(entry = this.cwd, opts = { + withFileTypes: true, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes } = opts; + if (!entry.canReaddir()) { + return []; + } + else { + const p = await entry.readdir(); + return withFileTypes ? p : p.map(e => e.name); + } + } + readdirSync(entry = this.cwd, opts = { + withFileTypes: true, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true } = opts; + if (!entry.canReaddir()) { + return []; + } + else if (withFileTypes) { + return entry.readdirSync(); + } + else { + return entry.readdirSync().map(e => e.name); + } + } + /** + * Call lstat() on the string or Path object, and update all known + * information that can be determined. + * + * Note that unlike `fs.lstat()`, the returned value does not contain some + * information, such as `mode`, `dev`, `nlink`, and `ino`. If that + * information is required, you will need to call `fs.lstat` yourself. + * + * If the Path refers to a nonexistent file, or if the lstat call fails for + * any reason, `undefined` is returned. Otherwise the updated Path object is + * returned. + * + * Results are cached, and thus may be out of date if the filesystem is + * mutated. + */ + async lstat(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.lstat(); + } + /** + * synchronous {@link PathScurryBase.lstat} + */ + lstatSync(entry = this.cwd) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + return entry.lstatSync(); + } + async readlink(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = await entry.readlink(); + return withFileTypes ? e : e?.fullpath(); + } + readlinkSync(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = entry.readlinkSync(); + return withFileTypes ? e : e?.fullpath(); + } + async realpath(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = await entry.realpath(); + return withFileTypes ? e : e?.fullpath(); + } + realpathSync(entry = this.cwd, { withFileTypes } = { + withFileTypes: false, + }) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + withFileTypes = entry.withFileTypes; + entry = this.cwd; + } + const e = entry.realpathSync(); + return withFileTypes ? e : e?.fullpath(); + } + async walk(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = []; + if (!filter || filter(entry)) { + results.push(withFileTypes ? entry : entry.fullpath()); + } + const dirs = new Set(); + const walk = (dir, cb) => { + dirs.add(dir); + dir.readdirCB((er, entries) => { + /* c8 ignore start */ + if (er) { + return cb(er); + } + /* c8 ignore stop */ + let len = entries.length; + if (!len) + return cb(); + const next = () => { + if (--len === 0) { + cb(); + } + }; + for (const e of entries) { + if (!filter || filter(e)) { + results.push(withFileTypes ? e : e.fullpath()); + } + if (follow && e.isSymbolicLink()) { + e.realpath() + .then(r => (r?.isUnknown() ? r.lstat() : r)) + .then(r => r?.shouldWalk(dirs, walkFilter) ? walk(r, next) : next()); + } + else { + if (e.shouldWalk(dirs, walkFilter)) { + walk(e, next); + } + else { + next(); + } + } + } + }, true); // zalgooooooo + }; + const start = entry; + return new Promise((res, rej) => { + walk(start, er => { + /* c8 ignore start */ + if (er) + return rej(er); + /* c8 ignore stop */ + res(results); + }); + }); + } + walkSync(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = []; + if (!filter || filter(entry)) { + results.push(withFileTypes ? entry : entry.fullpath()); + } + const dirs = new Set([entry]); + for (const dir of dirs) { + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter || filter(e)) { + results.push(withFileTypes ? e : e.fullpath()); + } + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + dirs.add(r); + } + } + } + return results; + } + /** + * Support for `for await` + * + * Alias for {@link PathScurryBase.iterate} + * + * Note: As of Node 19, this is very slow, compared to other methods of + * walking. Consider using {@link PathScurryBase.stream} if memory overhead + * and backpressure are concerns, or {@link PathScurryBase.walk} if not. + */ + [Symbol.asyncIterator]() { + return this.iterate(); + } + iterate(entry = this.cwd, options = {}) { + // iterating async over the stream is significantly more performant, + // especially in the warm-cache scenario, because it buffers up directory + // entries in the background instead of waiting for a yield for each one. + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + options = entry; + entry = this.cwd; + } + return this.stream(entry, options)[Symbol.asyncIterator](); + } + /** + * Iterating over a PathScurry performs a synchronous walk. + * + * Alias for {@link PathScurryBase.iterateSync} + */ + [Symbol.iterator]() { + return this.iterateSync(); + } + *iterateSync(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + if (!filter || filter(entry)) { + yield withFileTypes ? entry : entry.fullpath(); + } + const dirs = new Set([entry]); + for (const dir of dirs) { + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter || filter(e)) { + yield withFileTypes ? e : e.fullpath(); + } + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + dirs.add(r); + } + } + } + } + stream(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = new Minipass({ objectMode: true }); + if (!filter || filter(entry)) { + results.write(withFileTypes ? entry : entry.fullpath()); + } + const dirs = new Set(); + const queue = [entry]; + let processing = 0; + const process = () => { + let paused = false; + while (!paused) { + const dir = queue.shift(); + if (!dir) { + if (processing === 0) + results.end(); + return; + } + processing++; + dirs.add(dir); + const onReaddir = (er, entries, didRealpaths = false) => { + /* c8 ignore start */ + if (er) + return results.emit('error', er); + /* c8 ignore stop */ + if (follow && !didRealpaths) { + const promises = []; + for (const e of entries) { + if (e.isSymbolicLink()) { + promises.push(e + .realpath() + .then((r) => r?.isUnknown() ? r.lstat() : r)); + } + } + if (promises.length) { + Promise.all(promises).then(() => onReaddir(null, entries, true)); + return; + } + } + for (const e of entries) { + if (e && (!filter || filter(e))) { + if (!results.write(withFileTypes ? e : e.fullpath())) { + paused = true; + } + } + } + processing--; + for (const e of entries) { + const r = e.realpathCached() || e; + if (r.shouldWalk(dirs, walkFilter)) { + queue.push(r); + } + } + if (paused && !results.flowing) { + results.once('drain', process); + } + else if (!sync) { + process(); + } + }; + // zalgo containment + let sync = true; + dir.readdirCB(onReaddir, true); + sync = false; + } + }; + process(); + return results; + } + streamSync(entry = this.cwd, opts = {}) { + if (typeof entry === 'string') { + entry = this.cwd.resolve(entry); + } + else if (!(entry instanceof PathBase)) { + opts = entry; + entry = this.cwd; + } + const { withFileTypes = true, follow = false, filter, walkFilter, } = opts; + const results = new Minipass({ objectMode: true }); + const dirs = new Set(); + if (!filter || filter(entry)) { + results.write(withFileTypes ? entry : entry.fullpath()); + } + const queue = [entry]; + let processing = 0; + const process = () => { + let paused = false; + while (!paused) { + const dir = queue.shift(); + if (!dir) { + if (processing === 0) + results.end(); + return; + } + processing++; + dirs.add(dir); + const entries = dir.readdirSync(); + for (const e of entries) { + if (!filter || filter(e)) { + if (!results.write(withFileTypes ? e : e.fullpath())) { + paused = true; + } + } + } + processing--; + for (const e of entries) { + let r = e; + if (e.isSymbolicLink()) { + if (!(follow && (r = e.realpathSync()))) + continue; + if (r.isUnknown()) + r.lstatSync(); + } + if (r.shouldWalk(dirs, walkFilter)) { + queue.push(r); + } + } + } + if (paused && !results.flowing) + results.once('drain', process); + }; + process(); + return results; + } + chdir(path = this.cwd) { + const oldCwd = this.cwd; + this.cwd = typeof path === 'string' ? this.cwd.resolve(path) : path; + this.cwd[setAsCwd](oldCwd); + } +} +/** + * Windows implementation of {@link PathScurryBase} + * + * Defaults to case insensitve, uses `'\\'` to generate path strings. Uses + * {@link PathWin32} for Path objects. + */ +export class PathScurryWin32 extends PathScurryBase { + /** + * separator for generating path strings + */ + sep = '\\'; + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = true } = opts; + super(cwd, win32, '\\', { ...opts, nocase }); + this.nocase = nocase; + for (let p = this.cwd; p; p = p.parent) { + p.nocase = this.nocase; + } + } + /** + * @internal + */ + parseRootPath(dir) { + // if the path starts with a single separator, it's not a UNC, and we'll + // just get separator as the root, and driveFromUNC will return \ + // In that case, mount \ on the root from the cwd. + return win32.parse(dir).root.toUpperCase(); + } + /** + * @internal + */ + newRoot(fs) { + return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs }); + } + /** + * Return true if the provided path string is an absolute path + */ + isAbsolute(p) { + return (p.startsWith('/') || p.startsWith('\\') || /^[a-z]:(\/|\\)/i.test(p)); + } +} +/** + * {@link PathScurryBase} implementation for all posix systems other than Darwin. + * + * Defaults to case-sensitive matching, uses `'/'` to generate path strings. + * + * Uses {@link PathPosix} for Path objects. + */ +export class PathScurryPosix extends PathScurryBase { + /** + * separator for generating path strings + */ + sep = '/'; + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = false } = opts; + super(cwd, posix, '/', { ...opts, nocase }); + this.nocase = nocase; + } + /** + * @internal + */ + parseRootPath(_dir) { + return '/'; + } + /** + * @internal + */ + newRoot(fs) { + return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs }); + } + /** + * Return true if the provided path string is an absolute path + */ + isAbsolute(p) { + return p.startsWith('/'); + } +} +/** + * {@link PathScurryBase} implementation for Darwin (macOS) systems. + * + * Defaults to case-insensitive matching, uses `'/'` for generating path + * strings. + * + * Uses {@link PathPosix} for Path objects. + */ +export class PathScurryDarwin extends PathScurryPosix { + constructor(cwd = process.cwd(), opts = {}) { + const { nocase = true } = opts; + super(cwd, { ...opts, nocase }); + } +} +/** + * Default {@link PathBase} implementation for the current platform. + * + * {@link PathWin32} on Windows systems, {@link PathPosix} on all others. + */ +export const Path = process.platform === 'win32' ? PathWin32 : PathPosix; +/** + * Default {@link PathScurryBase} implementation for the current platform. + * + * {@link PathScurryWin32} on Windows systems, {@link PathScurryDarwin} on + * Darwin (macOS) systems, {@link PathScurryPosix} on all others. + */ +export const PathScurry = process.platform === 'win32' ? PathScurryWin32 + : process.platform === 'darwin' ? PathScurryDarwin + : PathScurryPosix; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/path-scurry/dist/esm/package.json b/node_modules/path-scurry/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/path-scurry/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/path-scurry/package.json b/node_modules/path-scurry/package.json new file mode 100644 index 0000000000000..831f23469b786 --- /dev/null +++ b/node_modules/path-scurry/package.json @@ -0,0 +1,88 @@ +{ + "name": "path-scurry", + "version": "2.0.1", + "description": "walk paths fast and efficiently", + "author": "Isaac Z. Schlueter <i@izs.me> (https://blog.izs.me)", + "main": "./dist/commonjs/index.js", + "type": "module", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "files": [ + "dist" + ], + "license": "BlueOak-1.0.0", + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --log-level warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts", + "bench": "bash ./scripts/bench.sh" + }, + "prettier": { + "experimentalTernaries": true, + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "devDependencies": { + "@nodelib/fs.walk": "^2.0.0", + "@types/node": "^20.14.10", + "mkdirp": "^3.0.0", + "prettier": "^3.3.2", + "rimraf": "^5.0.8", + "tap": "^20.0.3", + "ts-node": "^10.9.2", + "tshy": "^2.0.1", + "typedoc": "^0.26.3", + "typescript": "^5.5.3" + }, + "tap": { + "typecheck": true + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/path-scurry" + }, + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "tshy": { + "selfLink": false, + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" +} diff --git a/node_modules/postcss-selector-parser/API.md b/node_modules/postcss-selector-parser/API.md index 6aa1f1438f1be..e564830b66b04 100644 --- a/node_modules/postcss-selector-parser/API.md +++ b/node_modules/postcss-selector-parser/API.md @@ -254,7 +254,7 @@ if (next && next.type !== 'combinator') { } ``` -### `node.replaceWith(node)` +### `node.replaceWith(node[,...nodeN])` Replace a node with another. @@ -267,6 +267,8 @@ attr.replaceWith(className); Arguments: * `node`: The node to substitute the original with. +... +* `nodeN`: The node to substitute the original with. ### `node.remove()` @@ -278,16 +280,13 @@ if (node.type === 'id') { } ``` -### `node.clone()` +### `node.clone([opts])` Returns a copy of a node, detached from any parent containers that the original might have had. ```js -const cloned = parser.id({value: 'search'}); -String(cloned); - -// => #search +const cloned = node.clone(); ``` ### `node.isAtPosition(line, column)` @@ -395,16 +394,18 @@ Arguments: ### `container.atPosition(line, column)` -Returns the node at the source position `index`. +Returns the node at the source position `line` and `column`. ```js -selector.at(0) === selector.first; -selector.at(0) === selector.nodes[0]; +// Input: :not(.foo),\n#foo > :matches(ol, ul) +selector.atPosition(1, 1); // => :not(.foo) +selector.atPosition(2, 1); // => \n#foo ``` Arguments: -* `index`: The index of the node to return. +* `line`: The line number of the node to return. +* `column`: The column number of the node to return. ### `container.index(node)` @@ -532,7 +533,7 @@ Arguments: * `node`: The node to add. -### `container.insertBefore(old, new)` & `container.insertAfter(old, new)` +### `container.insertBefore(old, new[, ...newNodes])` & `container.insertAfter(old, new[, ...newNodes])` Add a node before or after an existing node in a container: @@ -787,7 +788,7 @@ has a method `error(message, options)` that returns an error object. This method should always be used to raise errors relating to the syntax of selectors. The options to this method are passed to postcss's error constructor -([documentation](http://api.postcss.org/Container.html#error)). +([documentation](http://postcss.org/api/#container-error)). #### Async Error Example diff --git a/node_modules/postcss-selector-parser/dist/index.js b/node_modules/postcss-selector-parser/dist/index.js index 6e76a32bdd442..995741a7ff3be 100644 --- a/node_modules/postcss-selector-parser/dist/index.js +++ b/node_modules/postcss-selector-parser/dist/index.js @@ -2,21 +2,14 @@ exports.__esModule = true; exports["default"] = void 0; - var _processor = _interopRequireDefault(require("./processor")); - var selectors = _interopRequireWildcard(require("./selectors")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - var parser = function parser(processor) { return new _processor["default"](processor); }; - Object.assign(parser, selectors); delete parser.__esModule; var _default = parser; diff --git a/node_modules/postcss-selector-parser/dist/parser.js b/node_modules/postcss-selector-parser/dist/parser.js index e0451de00f43e..e36af64dbd338 100644 --- a/node_modules/postcss-selector-parser/dist/parser.js +++ b/node_modules/postcss-selector-parser/dist/parser.js @@ -2,70 +2,43 @@ exports.__esModule = true; exports["default"] = void 0; - var _root = _interopRequireDefault(require("./selectors/root")); - var _selector = _interopRequireDefault(require("./selectors/selector")); - var _className = _interopRequireDefault(require("./selectors/className")); - var _comment = _interopRequireDefault(require("./selectors/comment")); - var _id = _interopRequireDefault(require("./selectors/id")); - var _tag = _interopRequireDefault(require("./selectors/tag")); - var _string = _interopRequireDefault(require("./selectors/string")); - var _pseudo = _interopRequireDefault(require("./selectors/pseudo")); - var _attribute = _interopRequireWildcard(require("./selectors/attribute")); - var _universal = _interopRequireDefault(require("./selectors/universal")); - var _combinator = _interopRequireDefault(require("./selectors/combinator")); - var _nesting = _interopRequireDefault(require("./selectors/nesting")); - var _sortAscending = _interopRequireDefault(require("./sortAscending")); - var _tokenize = _interopRequireWildcard(require("./tokenize")); - var tokens = _interopRequireWildcard(require("./tokenTypes")); - var types = _interopRequireWildcard(require("./selectors/types")); - var _util = require("./util"); - var _WHITESPACE_TOKENS, _Object$assign; - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } var WHITESPACE_TOKENS = (_WHITESPACE_TOKENS = {}, _WHITESPACE_TOKENS[tokens.space] = true, _WHITESPACE_TOKENS[tokens.cr] = true, _WHITESPACE_TOKENS[tokens.feed] = true, _WHITESPACE_TOKENS[tokens.newline] = true, _WHITESPACE_TOKENS[tokens.tab] = true, _WHITESPACE_TOKENS); var WHITESPACE_EQUIV_TOKENS = Object.assign({}, WHITESPACE_TOKENS, (_Object$assign = {}, _Object$assign[tokens.comment] = true, _Object$assign)); - function tokenStart(token) { return { line: token[_tokenize.FIELDS.START_LINE], column: token[_tokenize.FIELDS.START_COL] }; } - function tokenEnd(token) { return { line: token[_tokenize.FIELDS.END_LINE], column: token[_tokenize.FIELDS.END_COL] }; } - function getSource(startLine, startColumn, endLine, endColumn) { return { start: { @@ -78,62 +51,48 @@ function getSource(startLine, startColumn, endLine, endColumn) { } }; } - function getTokenSource(token) { return getSource(token[_tokenize.FIELDS.START_LINE], token[_tokenize.FIELDS.START_COL], token[_tokenize.FIELDS.END_LINE], token[_tokenize.FIELDS.END_COL]); } - function getTokenSourceSpan(startToken, endToken) { if (!startToken) { return undefined; } - return getSource(startToken[_tokenize.FIELDS.START_LINE], startToken[_tokenize.FIELDS.START_COL], endToken[_tokenize.FIELDS.END_LINE], endToken[_tokenize.FIELDS.END_COL]); } - function unescapeProp(node, prop) { var value = node[prop]; - if (typeof value !== "string") { return; } - if (value.indexOf("\\") !== -1) { (0, _util.ensureObject)(node, 'raws'); node[prop] = (0, _util.unesc)(value); - if (node.raws[prop] === undefined) { node.raws[prop] = value; } } - return node; } - function indexesOf(array, item) { var i = -1; var indexes = []; - while ((i = array.indexOf(item, i + 1)) !== -1) { indexes.push(i); } - return indexes; } - function uniqs() { var list = Array.prototype.concat.apply([], arguments); return list.filter(function (item, i) { return i === list.indexOf(item); }); } - var Parser = /*#__PURE__*/function () { function Parser(rule, options) { if (options === void 0) { options = {}; } - this.rule = rule; this.options = Object.assign({ lossy: false, @@ -157,62 +116,51 @@ var Parser = /*#__PURE__*/function () { line: 1, column: 1 } - } + }, + sourceIndex: 0 }); this.root.append(selector); this.current = selector; this.loop(); } - var _proto = Parser.prototype; - _proto._errorGenerator = function _errorGenerator() { var _this = this; - return function (message, errorOptions) { if (typeof _this.rule === 'string') { return new Error(message); } - return _this.rule.error(message, errorOptions); }; }; - _proto.attribute = function attribute() { var attr = []; var startingToken = this.currToken; this.position++; - while (this.position < this.tokens.length && this.currToken[_tokenize.FIELDS.TYPE] !== tokens.closeSquare) { attr.push(this.currToken); this.position++; } - if (this.currToken[_tokenize.FIELDS.TYPE] !== tokens.closeSquare) { return this.expected('closing square bracket', this.currToken[_tokenize.FIELDS.START_POS]); } - var len = attr.length; var node = { source: getSource(startingToken[1], startingToken[2], this.currToken[3], this.currToken[4]), sourceIndex: startingToken[_tokenize.FIELDS.START_POS] }; - if (len === 1 && !~[tokens.word].indexOf(attr[0][_tokenize.FIELDS.TYPE])) { return this.expected('attribute', attr[0][_tokenize.FIELDS.START_POS]); } - var pos = 0; var spaceBefore = ''; var commentBefore = ''; var lastAdded = null; var spaceAfterMeaningfulToken = false; - while (pos < len) { var token = attr[pos]; var content = this.content(token); var next = attr[pos + 1]; - switch (token[_tokenize.FIELDS.TYPE]) { case tokens.space: // if ( @@ -222,17 +170,14 @@ var Parser = /*#__PURE__*/function () { // return this.expected('attribute', token[TOKEN.START_POS], content); // } spaceAfterMeaningfulToken = true; - if (this.options.lossy) { break; } - if (lastAdded) { (0, _util.ensureObject)(node, 'spaces', lastAdded); var prevContent = node.spaces[lastAdded].after || ''; node.spaces[lastAdded].after = prevContent + content; var existingComment = (0, _util.getProp)(node, 'raws', 'spaces', lastAdded, 'after') || null; - if (existingComment) { node.raws.spaces[lastAdded].after = existingComment + content; } @@ -240,9 +185,7 @@ var Parser = /*#__PURE__*/function () { spaceBefore = spaceBefore + content; commentBefore = commentBefore + content; } - break; - case tokens.asterisk: if (next[_tokenize.FIELDS.TYPE] === tokens.equals) { node.operator = content; @@ -253,72 +196,57 @@ var Parser = /*#__PURE__*/function () { node.spaces.attribute.before = spaceBefore; spaceBefore = ''; } - if (commentBefore) { (0, _util.ensureObject)(node, 'raws', 'spaces', 'attribute'); node.raws.spaces.attribute.before = spaceBefore; commentBefore = ''; } - node.namespace = (node.namespace || "") + content; var rawValue = (0, _util.getProp)(node, 'raws', 'namespace') || null; - if (rawValue) { node.raws.namespace += content; } - lastAdded = 'namespace'; } - spaceAfterMeaningfulToken = false; break; - case tokens.dollar: if (lastAdded === "value") { var oldRawValue = (0, _util.getProp)(node, 'raws', 'value'); node.value += "$"; - if (oldRawValue) { node.raws.value = oldRawValue + "$"; } - break; } - // Falls through - case tokens.caret: if (next[_tokenize.FIELDS.TYPE] === tokens.equals) { node.operator = content; lastAdded = 'operator'; } - spaceAfterMeaningfulToken = false; break; - case tokens.combinator: if (content === '~' && next[_tokenize.FIELDS.TYPE] === tokens.equals) { node.operator = content; lastAdded = 'operator'; } - if (content !== '|') { spaceAfterMeaningfulToken = false; break; } - if (next[_tokenize.FIELDS.TYPE] === tokens.equals) { node.operator = content; lastAdded = 'operator'; } else if (!node.namespace && !node.attribute) { node.namespace = true; } - spaceAfterMeaningfulToken = false; break; - case tokens.word: - if (next && this.content(next) === '|' && attr[pos + 2] && attr[pos + 2][_tokenize.FIELDS.TYPE] !== tokens.equals && // this look-ahead probably fails with comment nodes involved. + if (next && this.content(next) === '|' && attr[pos + 2] && attr[pos + 2][_tokenize.FIELDS.TYPE] !== tokens.equals && + // this look-ahead probably fails with comment nodes involved. !node.operator && !node.namespace) { node.namespace = content; lastAdded = 'namespace'; @@ -328,56 +256,42 @@ var Parser = /*#__PURE__*/function () { node.spaces.attribute.before = spaceBefore; spaceBefore = ''; } - if (commentBefore) { (0, _util.ensureObject)(node, 'raws', 'spaces', 'attribute'); node.raws.spaces.attribute.before = commentBefore; commentBefore = ''; } - node.attribute = (node.attribute || "") + content; - var _rawValue = (0, _util.getProp)(node, 'raws', 'attribute') || null; - if (_rawValue) { node.raws.attribute += content; } - lastAdded = 'attribute'; - } else if (!node.value && node.value !== "" || lastAdded === "value" && !spaceAfterMeaningfulToken) { + } else if (!node.value && node.value !== "" || lastAdded === "value" && !(spaceAfterMeaningfulToken || node.quoteMark)) { var _unescaped = (0, _util.unesc)(content); - var _oldRawValue = (0, _util.getProp)(node, 'raws', 'value') || ''; - var oldValue = node.value || ''; node.value = oldValue + _unescaped; node.quoteMark = null; - if (_unescaped !== content || _oldRawValue) { (0, _util.ensureObject)(node, 'raws'); node.raws.value = (_oldRawValue || oldValue) + content; } - lastAdded = 'value'; } else { var insensitive = content === 'i' || content === "I"; - if ((node.value || node.value === '') && (node.quoteMark || spaceAfterMeaningfulToken)) { node.insensitive = insensitive; - if (!insensitive || content === "I") { (0, _util.ensureObject)(node, 'raws'); node.raws.insensitiveFlag = content; } - lastAdded = 'insensitive'; - if (spaceBefore) { (0, _util.ensureObject)(node, 'spaces', 'insensitive'); node.spaces.insensitive.before = spaceBefore; spaceBefore = ''; } - if (commentBefore) { (0, _util.ensureObject)(node, 'raws', 'spaces', 'insensitive'); node.raws.spaces.insensitive.before = commentBefore; @@ -386,27 +300,22 @@ var Parser = /*#__PURE__*/function () { } else if (node.value || node.value === '') { lastAdded = 'value'; node.value += content; - if (node.raws.value) { node.raws.value += content; } } } - spaceAfterMeaningfulToken = false; break; - case tokens.str: if (!node.attribute || !node.operator) { return this.error("Expected an attribute followed by an operator preceding the string.", { index: token[_tokenize.FIELDS.START_POS] }); } - var _unescapeValue = (0, _attribute.unescapeValue)(content), - unescaped = _unescapeValue.unescaped, - quoteMark = _unescapeValue.quoteMark; - + unescaped = _unescapeValue.unescaped, + quoteMark = _unescapeValue.quoteMark; node.value = unescaped; node.quoteMark = quoteMark; lastAdded = 'value'; @@ -414,23 +323,19 @@ var Parser = /*#__PURE__*/function () { node.raws.value = content; spaceAfterMeaningfulToken = false; break; - case tokens.equals: if (!node.attribute) { return this.expected('attribute', token[_tokenize.FIELDS.START_POS], content); } - if (node.value) { return this.error('Unexpected "=" found; an operator was already defined.', { index: token[_tokenize.FIELDS.START_POS] }); } - node.operator = node.operator ? node.operator + content : content; lastAdded = 'operator'; spaceAfterMeaningfulToken = false; break; - case tokens.comment: if (lastAdded) { if (spaceAfterMeaningfulToken || next && next[_tokenize.FIELDS.TYPE] === tokens.space || lastAdded === 'insensitive') { @@ -447,23 +352,20 @@ var Parser = /*#__PURE__*/function () { } else { commentBefore = commentBefore + content; } - break; - default: return this.error("Unexpected \"" + content + "\" found.", { index: token[_tokenize.FIELDS.START_POS] }); } - pos++; } - unescapeProp(node, "attribute"); unescapeProp(node, "namespace"); this.newNode(new _attribute["default"](node)); this.position++; } + /** * return a node containing meaningless garbage up to (but not including) the specified token position. * if the token position is negative, all remaining tokens are consumed. @@ -475,19 +377,15 @@ var Parser = /*#__PURE__*/function () { * a previous node's space metadata. * * In lossy mode, this returns only comments. - */ - ; - + */; _proto.parseWhitespaceEquivalentTokens = function parseWhitespaceEquivalentTokens(stopPosition) { if (stopPosition < 0) { stopPosition = this.tokens.length; } - var startPosition = this.position; var nodes = []; var space = ""; var lastComment = undefined; - do { if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) { if (!this.options.lossy) { @@ -495,12 +393,10 @@ var Parser = /*#__PURE__*/function () { } } else if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.comment) { var spaces = {}; - if (space) { spaces.before = space; space = ""; } - lastComment = new _comment["default"]({ value: this.content(), source: getTokenSource(this.currToken), @@ -510,7 +406,6 @@ var Parser = /*#__PURE__*/function () { nodes.push(lastComment); } } while (++this.position < stopPosition); - if (space) { if (lastComment) { lastComment.spaces.after = space; @@ -528,62 +423,49 @@ var Parser = /*#__PURE__*/function () { })); } } - return nodes; } - /** - * - * @param {*} nodes - */ - ; + /** + * + * @param {*} nodes + */; _proto.convertWhitespaceNodesToSpace = function convertWhitespaceNodesToSpace(nodes, requiredSpace) { var _this2 = this; - if (requiredSpace === void 0) { requiredSpace = false; } - var space = ""; var rawSpace = ""; nodes.forEach(function (n) { var spaceBefore = _this2.lossySpace(n.spaces.before, requiredSpace); - var rawSpaceBefore = _this2.lossySpace(n.rawSpaceBefore, requiredSpace); - space += spaceBefore + _this2.lossySpace(n.spaces.after, requiredSpace && spaceBefore.length === 0); rawSpace += spaceBefore + n.value + _this2.lossySpace(n.rawSpaceAfter, requiredSpace && rawSpaceBefore.length === 0); }); - if (rawSpace === space) { rawSpace = undefined; } - var result = { space: space, rawSpace: rawSpace }; return result; }; - _proto.isNamedCombinator = function isNamedCombinator(position) { if (position === void 0) { position = this.position; } - return this.tokens[position + 0] && this.tokens[position + 0][_tokenize.FIELDS.TYPE] === tokens.slash && this.tokens[position + 1] && this.tokens[position + 1][_tokenize.FIELDS.TYPE] === tokens.word && this.tokens[position + 2] && this.tokens[position + 2][_tokenize.FIELDS.TYPE] === tokens.slash; }; - _proto.namedCombinator = function namedCombinator() { if (this.isNamedCombinator()) { var nameRaw = this.content(this.tokens[this.position + 1]); var name = (0, _util.unesc)(nameRaw).toLowerCase(); var raws = {}; - if (name !== nameRaw) { raws.value = "/" + nameRaw + "/"; } - var node = new _combinator["default"]({ value: "/" + name + "/", source: getSource(this.currToken[_tokenize.FIELDS.START_LINE], this.currToken[_tokenize.FIELDS.START_COL], this.tokens[this.position + 2][_tokenize.FIELDS.END_LINE], this.tokens[this.position + 2][_tokenize.FIELDS.END_COL]), @@ -596,32 +478,24 @@ var Parser = /*#__PURE__*/function () { this.unexpected(); } }; - _proto.combinator = function combinator() { var _this3 = this; - if (this.content() === '|') { return this.namespace(); - } // We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector. - - + } + // We need to decide between a space that's a descendant combinator and meaningless whitespace at the end of a selector. var nextSigTokenPos = this.locateNextMeaningfulToken(this.position); - - if (nextSigTokenPos < 0 || this.tokens[nextSigTokenPos][_tokenize.FIELDS.TYPE] === tokens.comma) { + if (nextSigTokenPos < 0 || this.tokens[nextSigTokenPos][_tokenize.FIELDS.TYPE] === tokens.comma || this.tokens[nextSigTokenPos][_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { var nodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); - if (nodes.length > 0) { var last = this.current.last; - if (last) { var _this$convertWhitespa = this.convertWhitespaceNodesToSpace(nodes), - space = _this$convertWhitespa.space, - rawSpace = _this$convertWhitespa.rawSpace; - + space = _this$convertWhitespa.space, + rawSpace = _this$convertWhitespa.rawSpace; if (rawSpace !== undefined) { last.rawSpaceAfter += rawSpace; } - last.spaces.after += space; } else { nodes.forEach(function (n) { @@ -629,19 +503,14 @@ var Parser = /*#__PURE__*/function () { }); } } - return; } - var firstToken = this.currToken; var spaceOrDescendantSelectorNodes = undefined; - if (nextSigTokenPos > this.position) { spaceOrDescendantSelectorNodes = this.parseWhitespaceEquivalentTokens(nextSigTokenPos); } - var node; - if (this.isNamedCombinator()) { node = this.namedCombinator(); } else if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.combinator) { @@ -651,45 +520,40 @@ var Parser = /*#__PURE__*/function () { sourceIndex: this.currToken[_tokenize.FIELDS.START_POS] }); this.position++; - } else if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) {// pass + } else if (WHITESPACE_TOKENS[this.currToken[_tokenize.FIELDS.TYPE]]) { + // pass } else if (!spaceOrDescendantSelectorNodes) { this.unexpected(); } - if (node) { if (spaceOrDescendantSelectorNodes) { var _this$convertWhitespa2 = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes), - _space = _this$convertWhitespa2.space, - _rawSpace = _this$convertWhitespa2.rawSpace; - + _space = _this$convertWhitespa2.space, + _rawSpace = _this$convertWhitespa2.rawSpace; node.spaces.before = _space; node.rawSpaceBefore = _rawSpace; } } else { // descendant combinator var _this$convertWhitespa3 = this.convertWhitespaceNodesToSpace(spaceOrDescendantSelectorNodes, true), - _space2 = _this$convertWhitespa3.space, - _rawSpace2 = _this$convertWhitespa3.rawSpace; - + _space2 = _this$convertWhitespa3.space, + _rawSpace2 = _this$convertWhitespa3.rawSpace; if (!_rawSpace2) { _rawSpace2 = _space2; } - var spaces = {}; var raws = { spaces: {} }; - if (_space2.endsWith(' ') && _rawSpace2.endsWith(' ')) { spaces.before = _space2.slice(0, _space2.length - 1); raws.spaces.before = _rawSpace2.slice(0, _rawSpace2.length - 1); - } else if (_space2.startsWith(' ') && _rawSpace2.startsWith(' ')) { + } else if (_space2[0] === ' ' && _rawSpace2[0] === ' ') { spaces.after = _space2.slice(1); raws.spaces.after = _rawSpace2.slice(1); } else { raws.value = _rawSpace2; } - node = new _combinator["default"]({ value: ' ', source: getTokenSourceSpan(firstToken, this.tokens[this.position - 1]), @@ -698,34 +562,29 @@ var Parser = /*#__PURE__*/function () { raws: raws }); } - if (this.currToken && this.currToken[_tokenize.FIELDS.TYPE] === tokens.space) { node.spaces.after = this.optionalSpace(this.content()); this.position++; } - return this.newNode(node); }; - _proto.comma = function comma() { if (this.position === this.tokens.length - 1) { this.root.trailingComma = true; this.position++; return; } - this.current._inferEndPosition(); - var selector = new _selector["default"]({ source: { start: tokenStart(this.tokens[this.position + 1]) - } + }, + sourceIndex: this.tokens[this.position + 1][_tokenize.FIELDS.START_POS] }); this.current.parent.append(selector); this.current = selector; this.position++; }; - _proto.comment = function comment() { var current = this.currToken; this.newNode(new _comment["default"]({ @@ -735,32 +594,28 @@ var Parser = /*#__PURE__*/function () { })); this.position++; }; - _proto.error = function error(message, opts) { throw this.root.error(message, opts); }; - _proto.missingBackslash = function missingBackslash() { return this.error('Expected a backslash preceding the semicolon.', { index: this.currToken[_tokenize.FIELDS.START_POS] }); }; - _proto.missingParenthesis = function missingParenthesis() { return this.expected('opening parenthesis', this.currToken[_tokenize.FIELDS.START_POS]); }; - _proto.missingSquareBracket = function missingSquareBracket() { return this.expected('opening square bracket', this.currToken[_tokenize.FIELDS.START_POS]); }; - _proto.unexpected = function unexpected() { return this.error("Unexpected '" + this.content() + "'. Escaping special characters with \\ may help.", this.currToken[_tokenize.FIELDS.START_POS]); }; - + _proto.unexpectedPipe = function unexpectedPipe() { + return this.error("Unexpected '|'.", this.currToken[_tokenize.FIELDS.START_POS]); + }; _proto.namespace = function namespace() { var before = this.prevToken && this.content(this.prevToken) || true; - if (this.nextToken[_tokenize.FIELDS.TYPE] === tokens.word) { this.position++; return this.word(before); @@ -768,18 +623,16 @@ var Parser = /*#__PURE__*/function () { this.position++; return this.universal(before); } + this.unexpectedPipe(); }; - _proto.nesting = function nesting() { if (this.nextToken) { var nextContent = this.content(this.nextToken); - if (nextContent === "|") { this.position++; return; } } - var current = this.currToken; this.newNode(new _nesting["default"]({ value: this.content(), @@ -788,31 +641,27 @@ var Parser = /*#__PURE__*/function () { })); this.position++; }; - _proto.parentheses = function parentheses() { var last = this.current.last; var unbalanced = 1; this.position++; - if (last && last.type === types.PSEUDO) { var selector = new _selector["default"]({ source: { - start: tokenStart(this.tokens[this.position - 1]) - } + start: tokenStart(this.tokens[this.position]) + }, + sourceIndex: this.tokens[this.position][_tokenize.FIELDS.START_POS] }); var cache = this.current; last.append(selector); this.current = selector; - while (this.position < this.tokens.length && unbalanced) { if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) { unbalanced++; } - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { unbalanced--; } - if (unbalanced) { this.parse(); } else { @@ -821,7 +670,6 @@ var Parser = /*#__PURE__*/function () { this.position++; } } - this.current = cache; } else { // I think this case should be an error. It's used to implement a basic parse of media queries @@ -829,21 +677,17 @@ var Parser = /*#__PURE__*/function () { var parenStart = this.currToken; var parenValue = "("; var parenEnd; - while (this.position < this.tokens.length && unbalanced) { if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) { unbalanced++; } - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.closeParenthesis) { unbalanced--; } - parenEnd = this.currToken; parenValue += this.parseParenthesisToken(this.currToken); this.position++; } - if (last) { last.appendToPropertyAndEscape("value", parenValue, parenValue); } else { @@ -854,37 +698,29 @@ var Parser = /*#__PURE__*/function () { })); } } - if (unbalanced) { return this.expected('closing parenthesis', this.currToken[_tokenize.FIELDS.START_POS]); } }; - _proto.pseudo = function pseudo() { var _this4 = this; - var pseudoStr = ''; var startingToken = this.currToken; - while (this.currToken && this.currToken[_tokenize.FIELDS.TYPE] === tokens.colon) { pseudoStr += this.content(); this.position++; } - if (!this.currToken) { return this.expected(['pseudo-class', 'pseudo-element'], this.position - 1); } - if (this.currToken[_tokenize.FIELDS.TYPE] === tokens.word) { this.splitWord(false, function (first, length) { pseudoStr += first; - _this4.newNode(new _pseudo["default"]({ value: pseudoStr, source: getTokenSourceSpan(startingToken, _this4.currToken), sourceIndex: startingToken[_tokenize.FIELDS.START_POS] })); - if (length > 1 && _this4.nextToken && _this4.nextToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis) { _this4.error('Misplaced parenthesis.', { index: _this4.nextToken[_tokenize.FIELDS.START_POS] @@ -895,10 +731,9 @@ var Parser = /*#__PURE__*/function () { return this.expected(['pseudo-class', 'pseudo-element'], this.currToken[_tokenize.FIELDS.START_POS]); } }; - _proto.space = function space() { - var content = this.content(); // Handle space before and after the selector - + var content = this.content(); + // Handle space before and after the selector if (this.position === 0 || this.prevToken[_tokenize.FIELDS.TYPE] === tokens.comma || this.prevToken[_tokenize.FIELDS.TYPE] === tokens.openParenthesis || this.current.nodes.every(function (node) { return node.type === 'comment'; })) { @@ -911,7 +746,6 @@ var Parser = /*#__PURE__*/function () { this.combinator(); } }; - _proto.string = function string() { var current = this.currToken; this.newNode(new _string["default"]({ @@ -921,15 +755,12 @@ var Parser = /*#__PURE__*/function () { })); this.position++; }; - _proto.universal = function universal(namespace) { var nextToken = this.nextToken; - if (nextToken && this.content(nextToken) === '|') { this.position++; return this.namespace(); } - var current = this.currToken; this.newNode(new _universal["default"]({ value: this.content(), @@ -938,63 +769,51 @@ var Parser = /*#__PURE__*/function () { }), namespace); this.position++; }; - _proto.splitWord = function splitWord(namespace, firstCallback) { var _this5 = this; - var nextToken = this.nextToken; var word = this.content(); - while (nextToken && ~[tokens.dollar, tokens.caret, tokens.equals, tokens.word].indexOf(nextToken[_tokenize.FIELDS.TYPE])) { this.position++; var current = this.content(); word += current; - if (current.lastIndexOf('\\') === current.length - 1) { var next = this.nextToken; - if (next && next[_tokenize.FIELDS.TYPE] === tokens.space) { word += this.requiredSpace(this.content(next)); this.position++; } } - nextToken = this.nextToken; } - var hasClass = indexesOf(word, '.').filter(function (i) { // Allow escaped dot within class name - var escapedDot = word[i - 1] === '\\'; // Allow decimal numbers percent in @keyframes - + var escapedDot = word[i - 1] === '\\'; + // Allow decimal numbers percent in @keyframes var isKeyframesPercent = /^\d+\.\d+%$/.test(word); return !escapedDot && !isKeyframesPercent; }); var hasId = indexesOf(word, '#').filter(function (i) { return word[i - 1] !== '\\'; - }); // Eliminate Sass interpolations from the list of id indexes - + }); + // Eliminate Sass interpolations from the list of id indexes var interpolations = indexesOf(word, '#{'); - if (interpolations.length) { hasId = hasId.filter(function (hashIndex) { return !~interpolations.indexOf(hashIndex); }); } - var indices = (0, _sortAscending["default"])(uniqs([0].concat(hasClass, hasId))); indices.forEach(function (ind, i) { var index = indices[i + 1] || word.length; var value = word.slice(ind, index); - if (i === 0 && firstCallback) { return firstCallback.call(_this5, value, indices.length); } - var node; var current = _this5.currToken; var sourceIndex = current[_tokenize.FIELDS.START_POS] + indices[i]; var source = getSource(current[1], current[2] + ind, current[3], current[2] + (index - 1)); - if (~hasClass.indexOf(ind)) { var classNameOpts = { value: value.slice(1), @@ -1018,136 +837,105 @@ var Parser = /*#__PURE__*/function () { unescapeProp(tagOpts, "value"); node = new _tag["default"](tagOpts); } - - _this5.newNode(node, namespace); // Ensure that the namespace is used only once - - + _this5.newNode(node, namespace); + // Ensure that the namespace is used only once namespace = null; }); this.position++; }; - _proto.word = function word(namespace) { var nextToken = this.nextToken; - if (nextToken && this.content(nextToken) === '|') { this.position++; return this.namespace(); } - return this.splitWord(namespace); }; - _proto.loop = function loop() { while (this.position < this.tokens.length) { this.parse(true); } - this.current._inferEndPosition(); - return this.root; }; - _proto.parse = function parse(throwOnParenthesis) { switch (this.currToken[_tokenize.FIELDS.TYPE]) { case tokens.space: this.space(); break; - case tokens.comment: this.comment(); break; - case tokens.openParenthesis: this.parentheses(); break; - case tokens.closeParenthesis: if (throwOnParenthesis) { this.missingParenthesis(); } - break; - case tokens.openSquare: this.attribute(); break; - case tokens.dollar: case tokens.caret: case tokens.equals: case tokens.word: this.word(); break; - case tokens.colon: this.pseudo(); break; - case tokens.comma: this.comma(); break; - case tokens.asterisk: this.universal(); break; - case tokens.ampersand: this.nesting(); break; - case tokens.slash: case tokens.combinator: this.combinator(); break; - case tokens.str: this.string(); break; // These cases throw; no break needed. - case tokens.closeSquare: this.missingSquareBracket(); - case tokens.semicolon: this.missingBackslash(); - default: this.unexpected(); } } + /** * Helpers - */ - ; - + */; _proto.expected = function expected(description, index, found) { if (Array.isArray(description)) { var last = description.pop(); description = description.join(', ') + " or " + last; } - var an = /^[aeiou]/.test(description[0]) ? 'an' : 'a'; - if (!found) { return this.error("Expected " + an + " " + description + ".", { index: index }); } - return this.error("Expected " + an + " " + description + ", found \"" + found + "\" instead.", { index: index }); }; - _proto.requiredSpace = function requiredSpace(space) { return this.options.lossy ? ' ' : space; }; - _proto.optionalSpace = function optionalSpace(space) { return this.options.lossy ? '' : space; }; - _proto.lossySpace = function lossySpace(space, required) { if (this.options.lossy) { return required ? ' ' : ''; @@ -1155,47 +943,37 @@ var Parser = /*#__PURE__*/function () { return space; } }; - _proto.parseParenthesisToken = function parseParenthesisToken(token) { var content = this.content(token); - if (token[_tokenize.FIELDS.TYPE] === tokens.space) { return this.requiredSpace(content); } else { return content; } }; - _proto.newNode = function newNode(node, namespace) { if (namespace) { if (/^ +$/.test(namespace)) { if (!this.options.lossy) { this.spaces = (this.spaces || '') + namespace; } - namespace = true; } - node.namespace = namespace; unescapeProp(node, "namespace"); } - if (this.spaces) { node.spaces.before = this.spaces; this.spaces = ''; } - return this.current.append(node); }; - _proto.content = function content(token) { if (token === void 0) { token = this.currToken; } - return this.css.slice(token[_tokenize.FIELDS.START_POS], token[_tokenize.FIELDS.END_POS]); }; - /** * returns the index of the next non-whitespace, non-comment token. * returns -1 if no meaningful token is found. @@ -1204,9 +982,7 @@ var Parser = /*#__PURE__*/function () { if (startPosition === void 0) { startPosition = this.position + 1; } - var searchPosition = startPosition; - while (searchPosition < this.tokens.length) { if (WHITESPACE_EQUIV_TOKENS[this.tokens[searchPosition][_tokenize.FIELDS.TYPE]]) { searchPosition++; @@ -1215,10 +991,8 @@ var Parser = /*#__PURE__*/function () { return searchPosition; } } - return -1; }; - _createClass(Parser, [{ key: "currToken", get: function get() { @@ -1235,9 +1009,7 @@ var Parser = /*#__PURE__*/function () { return this.tokens[this.position - 1]; } }]); - return Parser; }(); - exports["default"] = Parser; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/processor.js b/node_modules/postcss-selector-parser/dist/processor.js index a00170c281f96..dbfa09188e63d 100644 --- a/node_modules/postcss-selector-parser/dist/processor.js +++ b/node_modules/postcss-selector-parser/dist/processor.js @@ -2,83 +2,63 @@ exports.__esModule = true; exports["default"] = void 0; - var _parser = _interopRequireDefault(require("./parser")); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - var Processor = /*#__PURE__*/function () { function Processor(func, options) { this.func = func || function noop() {}; - this.funcRes = null; this.options = options; } - var _proto = Processor.prototype; - _proto._shouldUpdateSelector = function _shouldUpdateSelector(rule, options) { if (options === void 0) { options = {}; } - var merged = Object.assign({}, this.options, options); - if (merged.updateSelector === false) { return false; } else { return typeof rule !== "string"; } }; - _proto._isLossy = function _isLossy(options) { if (options === void 0) { options = {}; } - var merged = Object.assign({}, this.options, options); - if (merged.lossless === false) { return true; } else { return false; } }; - _proto._root = function _root(rule, options) { if (options === void 0) { options = {}; } - var parser = new _parser["default"](rule, this._parseOptions(options)); return parser.root; }; - _proto._parseOptions = function _parseOptions(options) { return { lossy: this._isLossy(options) }; }; - _proto._run = function _run(rule, options) { var _this = this; - if (options === void 0) { options = {}; } - return new Promise(function (resolve, reject) { try { var root = _this._root(rule, options); - Promise.resolve(_this.func(root)).then(function (transform) { var string = undefined; - if (_this._shouldUpdateSelector(rule, options)) { string = root.toString(); rule.selector = string; } - return { transform: transform, root: root, @@ -91,116 +71,100 @@ var Processor = /*#__PURE__*/function () { } }); }; - _proto._runSync = function _runSync(rule, options) { if (options === void 0) { options = {}; } - var root = this._root(rule, options); - var transform = this.func(root); - if (transform && typeof transform.then === "function") { throw new Error("Selector processor returned a promise to a synchronous call."); } - var string = undefined; - if (options.updateSelector && typeof rule !== "string") { string = root.toString(); rule.selector = string; } - return { transform: transform, root: root, string: string }; } + /** * Process rule into a selector AST. * * @param rule {postcss.Rule | string} The css selector to be processed * @param options The options for processing * @returns {Promise<parser.Root>} The AST of the selector after processing it. - */ - ; - + */; _proto.ast = function ast(rule, options) { return this._run(rule, options).then(function (result) { return result.root; }); } + /** * Process rule into a selector AST synchronously. * * @param rule {postcss.Rule | string} The css selector to be processed * @param options The options for processing * @returns {parser.Root} The AST of the selector after processing it. - */ - ; - + */; _proto.astSync = function astSync(rule, options) { return this._runSync(rule, options).root; } + /** * Process a selector into a transformed value asynchronously * * @param rule {postcss.Rule | string} The css selector to be processed * @param options The options for processing * @returns {Promise<any>} The value returned by the processor. - */ - ; - + */; _proto.transform = function transform(rule, options) { return this._run(rule, options).then(function (result) { return result.transform; }); } + /** * Process a selector into a transformed value synchronously. * * @param rule {postcss.Rule | string} The css selector to be processed * @param options The options for processing * @returns {any} The value returned by the processor. - */ - ; - + */; _proto.transformSync = function transformSync(rule, options) { return this._runSync(rule, options).transform; } + /** * Process a selector into a new selector string asynchronously. * * @param rule {postcss.Rule | string} The css selector to be processed * @param options The options for processing * @returns {string} the selector after processing. - */ - ; - + */; _proto.process = function process(rule, options) { return this._run(rule, options).then(function (result) { return result.string || result.root.toString(); }); } + /** * Process a selector into a new selector string synchronously. * * @param rule {postcss.Rule | string} The css selector to be processed * @param options The options for processing * @returns {string} the selector after processing. - */ - ; - + */; _proto.processSync = function processSync(rule, options) { var result = this._runSync(rule, options); - return result.string || result.root.toString(); }; - return Processor; }(); - exports["default"] = Processor; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/attribute.js b/node_modules/postcss-selector-parser/dist/selectors/attribute.js index 8f535e5d73129..0351a22bfa597 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/attribute.js +++ b/node_modules/postcss-selector-parser/dist/selectors/attribute.js @@ -1,98 +1,70 @@ "use strict"; exports.__esModule = true; -exports.unescapeValue = unescapeValue; exports["default"] = void 0; - +exports.unescapeValue = unescapeValue; var _cssesc = _interopRequireDefault(require("cssesc")); - var _unesc = _interopRequireDefault(require("../util/unesc")); - var _namespace = _interopRequireDefault(require("./namespace")); - var _types = require("./types"); - var _CSSESC_QUOTE_OPTIONS; - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var deprecate = require("util-deprecate"); - var WRAPPED_IN_QUOTES = /^('|")([^]*)\1$/; var warnOfDeprecatedValueAssignment = deprecate(function () {}, "Assigning an attribute a value containing characters that might need to be escaped is deprecated. " + "Call attribute.setValue() instead."); var warnOfDeprecatedQuotedAssignment = deprecate(function () {}, "Assigning attr.quoted is deprecated and has no effect. Assign to attr.quoteMark instead."); var warnOfDeprecatedConstructor = deprecate(function () {}, "Constructing an Attribute selector with a value without specifying quoteMark is deprecated. Note: The value should be unescaped now."); - function unescapeValue(value) { var deprecatedUsage = false; var quoteMark = null; var unescaped = value; var m = unescaped.match(WRAPPED_IN_QUOTES); - if (m) { quoteMark = m[1]; unescaped = m[2]; } - unescaped = (0, _unesc["default"])(unescaped); - if (unescaped !== value) { deprecatedUsage = true; } - return { deprecatedUsage: deprecatedUsage, unescaped: unescaped, quoteMark: quoteMark }; } - function handleDeprecatedContructorOpts(opts) { if (opts.quoteMark !== undefined) { return opts; } - if (opts.value === undefined) { return opts; } - warnOfDeprecatedConstructor(); - var _unescapeValue = unescapeValue(opts.value), - quoteMark = _unescapeValue.quoteMark, - unescaped = _unescapeValue.unescaped; - + quoteMark = _unescapeValue.quoteMark, + unescaped = _unescapeValue.unescaped; if (!opts.raws) { opts.raws = {}; } - if (opts.raws.value === undefined) { opts.raws.value = opts.value; } - opts.value = unescaped; opts.quoteMark = quoteMark; return opts; } - var Attribute = /*#__PURE__*/function (_Namespace) { _inheritsLoose(Attribute, _Namespace); - function Attribute(opts) { var _this; - if (opts === void 0) { opts = {}; } - _this = _Namespace.call(this, handleDeprecatedContructorOpts(opts)) || this; _this.type = _types.ATTRIBUTE; _this.raws = _this.raws || {}; @@ -107,6 +79,7 @@ var Attribute = /*#__PURE__*/function (_Namespace) { _this._constructed = true; return _this; } + /** * Returns the Attribute's value quoted such that it would be legal to use * in the value of a css file. The original value's quotation setting @@ -128,42 +101,34 @@ var Attribute = /*#__PURE__*/function (_Namespace) { * and the other options specified here. See the `smartQuoteMark()` * method. **/ - - var _proto = Attribute.prototype; - _proto.getQuotedValue = function getQuotedValue(options) { if (options === void 0) { options = {}; } - var quoteMark = this._determineQuoteMark(options); - var cssescopts = CSSESC_QUOTE_OPTIONS[quoteMark]; var escaped = (0, _cssesc["default"])(this._value, cssescopts); return escaped; }; - _proto._determineQuoteMark = function _determineQuoteMark(options) { return options.smart ? this.smartQuoteMark(options) : this.preferredQuoteMark(options); } + /** * Set the unescaped value with the specified quotation options. The value * provided must not include any wrapping quote marks -- those quotes will * be interpreted as part of the value and escaped accordingly. - */ - ; - + */; _proto.setValue = function setValue(value, options) { if (options === void 0) { options = {}; } - this._value = value; this._quoteMark = this._determineQuoteMark(options); - this._syncRawValue(); } + /** * Intelligently select a quoteMark value based on the value's contents. If * the value is a legal CSS ident, it will not be quoted. Otherwise a quote @@ -175,35 +140,28 @@ var Attribute = /*#__PURE__*/function (_Namespace) { * * @param options This takes the quoteMark and preferCurrentQuoteMark options * from the quoteValue method. - */ - ; - + */; _proto.smartQuoteMark = function smartQuoteMark(options) { var v = this.value; var numSingleQuotes = v.replace(/[^']/g, '').length; var numDoubleQuotes = v.replace(/[^"]/g, '').length; - if (numSingleQuotes + numDoubleQuotes === 0) { var escaped = (0, _cssesc["default"])(v, { isIdentifier: true }); - if (escaped === v) { return Attribute.NO_QUOTE; } else { var pref = this.preferredQuoteMark(options); - if (pref === Attribute.NO_QUOTE) { // pick a quote mark that isn't none and see if it's smaller var quote = this.quoteMark || options.quoteMark || Attribute.DOUBLE_QUOTE; var opts = CSSESC_QUOTE_OPTIONS[quote]; var quoteValue = (0, _cssesc["default"])(v, opts); - if (quoteValue.length < escaped.length) { return quote; } } - return pref; } } else if (numDoubleQuotes === numSingleQuotes) { @@ -214,30 +172,24 @@ var Attribute = /*#__PURE__*/function (_Namespace) { return Attribute.SINGLE_QUOTE; } } + /** * Selects the preferred quote mark based on the options and the current quote mark value. * If you want the quote mark to depend on the attribute value, call `smartQuoteMark(opts)` * instead. - */ - ; - + */; _proto.preferredQuoteMark = function preferredQuoteMark(options) { var quoteMark = options.preferCurrentQuoteMark ? this.quoteMark : options.quoteMark; - if (quoteMark === undefined) { quoteMark = options.preferCurrentQuoteMark ? options.quoteMark : this.quoteMark; } - if (quoteMark === undefined) { quoteMark = Attribute.DOUBLE_QUOTE; } - return quoteMark; }; - _proto._syncRawValue = function _syncRawValue() { var rawValue = (0, _cssesc["default"])(this._value, CSSESC_QUOTE_OPTIONS[this.quoteMark]); - if (rawValue === this._value) { if (this.raws) { delete this.raws.value; @@ -246,13 +198,11 @@ var Attribute = /*#__PURE__*/function (_Namespace) { this.raws.value = rawValue; } }; - _proto._handleEscapes = function _handleEscapes(prop, value) { if (this._constructed) { var escaped = (0, _cssesc["default"])(value, { isIdentifier: true }); - if (escaped !== value) { this.raws[prop] = escaped; } else { @@ -260,7 +210,6 @@ var Attribute = /*#__PURE__*/function (_Namespace) { } } }; - _proto._spacesFor = function _spacesFor(name) { var attrSpaces = { before: '', @@ -270,20 +219,17 @@ var Attribute = /*#__PURE__*/function (_Namespace) { var rawSpaces = this.raws.spaces && this.raws.spaces[name] || {}; return Object.assign(attrSpaces, spaces, rawSpaces); }; - _proto._stringFor = function _stringFor(name, spaceName, concat) { if (spaceName === void 0) { spaceName = name; } - if (concat === void 0) { concat = defaultAttrConcat; } - var attrSpaces = this._spacesFor(spaceName); - return concat(this.stringifyProperty(name), attrSpaces); } + /** * returns the offset of the attribute part specified relative to the * start of the node of the output string. @@ -297,78 +243,53 @@ var Attribute = /*#__PURE__*/function (_Namespace) { * * "insensitive" - the case insensitivity flag; * @param part One of the possible values inside an attribute. * @returns -1 if the name is invalid or the value doesn't exist in this attribute. - */ - ; - + */; _proto.offsetOf = function offsetOf(name) { var count = 1; - var attributeSpaces = this._spacesFor("attribute"); - count += attributeSpaces.before.length; - if (name === "namespace" || name === "ns") { return this.namespace ? count : -1; } - if (name === "attributeNS") { return count; } - count += this.namespaceString.length; - if (this.namespace) { count += 1; } - if (name === "attribute") { return count; } - count += this.stringifyProperty("attribute").length; count += attributeSpaces.after.length; - var operatorSpaces = this._spacesFor("operator"); - count += operatorSpaces.before.length; var operator = this.stringifyProperty("operator"); - if (name === "operator") { return operator ? count : -1; } - count += operator.length; count += operatorSpaces.after.length; - var valueSpaces = this._spacesFor("value"); - count += valueSpaces.before.length; var value = this.stringifyProperty("value"); - if (name === "value") { return value ? count : -1; } - count += value.length; count += valueSpaces.after.length; - var insensitiveSpaces = this._spacesFor("insensitive"); - count += insensitiveSpaces.before.length; - if (name === "insensitive") { return this.insensitive ? count : -1; } - return -1; }; - _proto.toString = function toString() { var _this2 = this; - var selector = [this.rawSpaceBefore, '[']; selector.push(this._stringFor('qualifiedAttribute', 'attribute')); - if (this.operator && (this.value || this.value === '')) { selector.push(this._stringFor('operator')); selector.push(this._stringFor('value')); @@ -376,16 +297,13 @@ var Attribute = /*#__PURE__*/function (_Namespace) { if (attrValue.length > 0 && !_this2.quoted && attrSpaces.before.length === 0 && !(_this2.spaces.value && _this2.spaces.value.after)) { attrSpaces.before = " "; } - return defaultAttrConcat(attrValue, attrSpaces); })); } - selector.push(']'); selector.push(this.rawSpaceAfter); return selector.join(''); }; - _createClass(Attribute, [{ key: "quoted", get: function get() { @@ -395,35 +313,33 @@ var Attribute = /*#__PURE__*/function (_Namespace) { set: function set(value) { warnOfDeprecatedQuotedAssignment(); } + /** * returns a single (`'`) or double (`"`) quote character if the value is quoted. * returns `null` if the value is not quoted. * returns `undefined` if the quotation state is unknown (this can happen when * the attribute is constructed without specifying a quote mark.) */ - }, { key: "quoteMark", get: function get() { return this._quoteMark; } + /** * Set the quote mark to be used by this attribute's value. * If the quote mark changes, the raw (escaped) value at `attr.raws.value` of the attribute * value is updated accordingly. * * @param {"'" | '"' | null} quoteMark The quote mark or `null` if the value should be unquoted. - */ - , + */, set: function set(quoteMark) { if (!this._constructed) { this._quoteMark = quoteMark; return; } - if (this._quoteMark !== quoteMark) { this._quoteMark = quoteMark; - this._syncRawValue(); } } @@ -441,7 +357,8 @@ var Attribute = /*#__PURE__*/function (_Namespace) { key: "value", get: function get() { return this._value; - } + }, + set: /** * Before 3.0, the value had to be set to an escaped value including any wrapped * quote marks. In 3.0, the semantics of `Attribute.value` changed so that the value @@ -454,30 +371,50 @@ var Attribute = /*#__PURE__*/function (_Namespace) { * Instead, you should call `attr.setValue(newValue, opts)` and pass options that describe * how the new value is quoted. */ - , - set: function set(v) { + function set(v) { if (this._constructed) { var _unescapeValue2 = unescapeValue(v), - deprecatedUsage = _unescapeValue2.deprecatedUsage, - unescaped = _unescapeValue2.unescaped, - quoteMark = _unescapeValue2.quoteMark; - + deprecatedUsage = _unescapeValue2.deprecatedUsage, + unescaped = _unescapeValue2.unescaped, + quoteMark = _unescapeValue2.quoteMark; if (deprecatedUsage) { warnOfDeprecatedValueAssignment(); } - if (unescaped === this._value && quoteMark === this._quoteMark) { return; } - this._value = unescaped; this._quoteMark = quoteMark; - this._syncRawValue(); } else { this._value = v; } } + }, { + key: "insensitive", + get: function get() { + return this._insensitive; + } + + /** + * Set the case insensitive flag. + * If the case insensitive flag changes, the raw (escaped) value at `attr.raws.insensitiveFlag` + * of the attribute is updated accordingly. + * + * @param {true | false} insensitive true if the attribute should match case-insensitively. + */, + set: function set(insensitive) { + if (!insensitive) { + this._insensitive = false; + + // "i" and "I" can be used in "this.raws.insensitiveFlag" to store the original notation. + // When setting `attr.insensitive = false` both should be erased to ensure correct serialization. + if (this.raws && (this.raws.insensitiveFlag === 'I' || this.raws.insensitiveFlag === 'i')) { + this.raws.insensitiveFlag = undefined; + } + } + this._insensitive = insensitive; + } }, { key: "attribute", get: function get() { @@ -485,14 +422,11 @@ var Attribute = /*#__PURE__*/function (_Namespace) { }, set: function set(name) { this._handleEscapes("attribute", name); - this._attribute = name; } }]); - return Attribute; }(_namespace["default"]); - exports["default"] = Attribute; Attribute.NO_QUOTE = null; Attribute.SINGLE_QUOTE = "'"; @@ -509,7 +443,6 @@ var CSSESC_QUOTE_OPTIONS = (_CSSESC_QUOTE_OPTIONS = { }, _CSSESC_QUOTE_OPTIONS[null] = { isIdentifier: true }, _CSSESC_QUOTE_OPTIONS); - function defaultAttrConcat(attrValue, attrSpaces) { return "" + attrSpaces.before + attrValue + attrSpaces.after; } \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/className.js b/node_modules/postcss-selector-parser/dist/selectors/className.js index 22409914cf728..af325977c1146 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/className.js +++ b/node_modules/postcss-selector-parser/dist/selectors/className.js @@ -2,43 +2,28 @@ exports.__esModule = true; exports["default"] = void 0; - var _cssesc = _interopRequireDefault(require("cssesc")); - var _util = require("../util"); - var _node = _interopRequireDefault(require("./node")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var ClassName = /*#__PURE__*/function (_Node) { _inheritsLoose(ClassName, _Node); - function ClassName(opts) { var _this; - _this = _Node.call(this, opts) || this; _this.type = _types.CLASS; _this._constructed = true; return _this; } - var _proto = ClassName.prototype; - _proto.valueToString = function valueToString() { return '.' + _Node.prototype.valueToString.call(this); }; - _createClass(ClassName, [{ key: "value", get: function get() { @@ -49,7 +34,6 @@ var ClassName = /*#__PURE__*/function (_Node) { var escaped = (0, _cssesc["default"])(v, { isIdentifier: true }); - if (escaped !== v) { (0, _util.ensureObject)(this, "raws"); this.raws.value = escaped; @@ -57,13 +41,10 @@ var ClassName = /*#__PURE__*/function (_Node) { delete this.raws.value; } } - this._value = v; } }]); - return ClassName; }(_node["default"]); - exports["default"] = ClassName; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/combinator.js b/node_modules/postcss-selector-parser/dist/selectors/combinator.js index 271ab4d3b1f44..c6449f43cfddb 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/combinator.js +++ b/node_modules/postcss-selector-parser/dist/selectors/combinator.js @@ -2,30 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _node = _interopRequireDefault(require("./node")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Combinator = /*#__PURE__*/function (_Node) { _inheritsLoose(Combinator, _Node); - function Combinator(opts) { var _this; - _this = _Node.call(this, opts) || this; _this.type = _types.COMBINATOR; return _this; } - return Combinator; }(_node["default"]); - exports["default"] = Combinator; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/comment.js b/node_modules/postcss-selector-parser/dist/selectors/comment.js index e778094e110c2..1709d5be925d6 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/comment.js +++ b/node_modules/postcss-selector-parser/dist/selectors/comment.js @@ -2,30 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _node = _interopRequireDefault(require("./node")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Comment = /*#__PURE__*/function (_Node) { _inheritsLoose(Comment, _Node); - function Comment(opts) { var _this; - _this = _Node.call(this, opts) || this; _this.type = _types.COMMENT; return _this; } - return Comment; }(_node["default"]); - exports["default"] = Comment; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/constructors.js b/node_modules/postcss-selector-parser/dist/selectors/constructors.js index 078023eb28f2d..688259324cdd2 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/constructors.js +++ b/node_modules/postcss-selector-parser/dist/selectors/constructors.js @@ -2,101 +2,64 @@ exports.__esModule = true; exports.universal = exports.tag = exports.string = exports.selector = exports.root = exports.pseudo = exports.nesting = exports.id = exports.comment = exports.combinator = exports.className = exports.attribute = void 0; - var _attribute = _interopRequireDefault(require("./attribute")); - var _className = _interopRequireDefault(require("./className")); - var _combinator = _interopRequireDefault(require("./combinator")); - var _comment = _interopRequireDefault(require("./comment")); - var _id = _interopRequireDefault(require("./id")); - var _nesting = _interopRequireDefault(require("./nesting")); - var _pseudo = _interopRequireDefault(require("./pseudo")); - var _root = _interopRequireDefault(require("./root")); - var _selector = _interopRequireDefault(require("./selector")); - var _string = _interopRequireDefault(require("./string")); - var _tag = _interopRequireDefault(require("./tag")); - var _universal = _interopRequireDefault(require("./universal")); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - var attribute = function attribute(opts) { return new _attribute["default"](opts); }; - exports.attribute = attribute; - var className = function className(opts) { return new _className["default"](opts); }; - exports.className = className; - var combinator = function combinator(opts) { return new _combinator["default"](opts); }; - exports.combinator = combinator; - var comment = function comment(opts) { return new _comment["default"](opts); }; - exports.comment = comment; - var id = function id(opts) { return new _id["default"](opts); }; - exports.id = id; - var nesting = function nesting(opts) { return new _nesting["default"](opts); }; - exports.nesting = nesting; - var pseudo = function pseudo(opts) { return new _pseudo["default"](opts); }; - exports.pseudo = pseudo; - var root = function root(opts) { return new _root["default"](opts); }; - exports.root = root; - var selector = function selector(opts) { return new _selector["default"](opts); }; - exports.selector = selector; - var string = function string(opts) { return new _string["default"](opts); }; - exports.string = string; - var tag = function tag(opts) { return new _tag["default"](opts); }; - exports.tag = tag; - var universal = function universal(opts) { return new _universal["default"](opts); }; - exports.universal = universal; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/container.js b/node_modules/postcss-selector-parser/dist/selectors/container.js index 2626fb85bba85..84755cbd541a2 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/container.js +++ b/node_modules/postcss-selector-parser/dist/selectors/container.js @@ -2,145 +2,118 @@ exports.__esModule = true; exports["default"] = void 0; - var _node = _interopRequireDefault(require("./node")); - var types = _interopRequireWildcard(require("./types")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); } - +function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Container = /*#__PURE__*/function (_Node) { _inheritsLoose(Container, _Node); - function Container(opts) { var _this; - _this = _Node.call(this, opts) || this; - if (!_this.nodes) { _this.nodes = []; } - return _this; } - var _proto = Container.prototype; - _proto.append = function append(selector) { selector.parent = this; this.nodes.push(selector); return this; }; - _proto.prepend = function prepend(selector) { selector.parent = this; this.nodes.unshift(selector); + for (var id in this.indexes) { + this.indexes[id]++; + } return this; }; - _proto.at = function at(index) { return this.nodes[index]; }; - _proto.index = function index(child) { if (typeof child === 'number') { return child; } - return this.nodes.indexOf(child); }; - _proto.removeChild = function removeChild(child) { child = this.index(child); this.at(child).parent = undefined; this.nodes.splice(child, 1); var index; - for (var id in this.indexes) { index = this.indexes[id]; - if (index >= child) { this.indexes[id] = index - 1; } } - return this; }; - _proto.removeAll = function removeAll() { for (var _iterator = _createForOfIteratorHelperLoose(this.nodes), _step; !(_step = _iterator()).done;) { var node = _step.value; node.parent = undefined; } - this.nodes = []; return this; }; - _proto.empty = function empty() { return this.removeAll(); }; - _proto.insertAfter = function insertAfter(oldNode, newNode) { + var _this$nodes; newNode.parent = this; var oldIndex = this.index(oldNode); - this.nodes.splice(oldIndex + 1, 0, newNode); + var resetNode = []; + for (var i = 2; i < arguments.length; i++) { + resetNode.push(arguments[i]); + } + (_this$nodes = this.nodes).splice.apply(_this$nodes, [oldIndex + 1, 0, newNode].concat(resetNode)); newNode.parent = this; var index; - for (var id in this.indexes) { index = this.indexes[id]; - - if (oldIndex <= index) { - this.indexes[id] = index + 1; + if (oldIndex < index) { + this.indexes[id] = index + arguments.length - 1; } } - return this; }; - _proto.insertBefore = function insertBefore(oldNode, newNode) { + var _this$nodes2; newNode.parent = this; var oldIndex = this.index(oldNode); - this.nodes.splice(oldIndex, 0, newNode); + var resetNode = []; + for (var i = 2; i < arguments.length; i++) { + resetNode.push(arguments[i]); + } + (_this$nodes2 = this.nodes).splice.apply(_this$nodes2, [oldIndex, 0, newNode].concat(resetNode)); newNode.parent = this; var index; - for (var id in this.indexes) { index = this.indexes[id]; - - if (index <= oldIndex) { - this.indexes[id] = index + 1; + if (index >= oldIndex) { + this.indexes[id] = index + arguments.length - 1; } } - return this; }; - _proto._findChildAtPosition = function _findChildAtPosition(line, col) { var found = undefined; this.each(function (node) { if (node.atPosition) { var foundChild = node.atPosition(line, col); - if (foundChild) { found = foundChild; return false; @@ -152,11 +125,12 @@ var Container = /*#__PURE__*/function (_Node) { }); return found; } + /** * Return the most specific node at the line and column number given. * The source location is based on the original parsed location, locations aren't * updated as selector nodes are mutated. - * + * * Note that this location is relative to the location of the first character * of the selector, and not the location of the selector in the overall document * when used in conjunction with postcss. @@ -164,9 +138,7 @@ var Container = /*#__PURE__*/function (_Node) { * If not found, returns undefined. * @param {number} line The line number of the node to find. (1-based index) * @param {number} col The column number of the node to find. (1-based index) - */ - ; - + */; _proto.atPosition = function atPosition(line, col) { if (this.isAtPosition(line, col)) { return this._findChildAtPosition(line, col) || this; @@ -174,7 +146,6 @@ var Container = /*#__PURE__*/function (_Node) { return undefined; } }; - _proto._inferEndPosition = function _inferEndPosition() { if (this.last && this.last.source && this.last.source.end) { this.source = this.source || {}; @@ -182,195 +153,152 @@ var Container = /*#__PURE__*/function (_Node) { Object.assign(this.source.end, this.last.source.end); } }; - _proto.each = function each(callback) { if (!this.lastEach) { this.lastEach = 0; } - if (!this.indexes) { this.indexes = {}; } - this.lastEach++; var id = this.lastEach; this.indexes[id] = 0; - if (!this.length) { return undefined; } - var index, result; - while (this.indexes[id] < this.length) { index = this.indexes[id]; result = callback(this.at(index), index); - if (result === false) { break; } - this.indexes[id] += 1; } - delete this.indexes[id]; - if (result === false) { return false; } }; - _proto.walk = function walk(callback) { return this.each(function (node, i) { var result = callback(node, i); - if (result !== false && node.length) { result = node.walk(callback); } - if (result === false) { return false; } }); }; - _proto.walkAttributes = function walkAttributes(callback) { var _this2 = this; - return this.walk(function (selector) { if (selector.type === types.ATTRIBUTE) { return callback.call(_this2, selector); } }); }; - _proto.walkClasses = function walkClasses(callback) { var _this3 = this; - return this.walk(function (selector) { if (selector.type === types.CLASS) { return callback.call(_this3, selector); } }); }; - _proto.walkCombinators = function walkCombinators(callback) { var _this4 = this; - return this.walk(function (selector) { if (selector.type === types.COMBINATOR) { return callback.call(_this4, selector); } }); }; - _proto.walkComments = function walkComments(callback) { var _this5 = this; - return this.walk(function (selector) { if (selector.type === types.COMMENT) { return callback.call(_this5, selector); } }); }; - _proto.walkIds = function walkIds(callback) { var _this6 = this; - return this.walk(function (selector) { if (selector.type === types.ID) { return callback.call(_this6, selector); } }); }; - _proto.walkNesting = function walkNesting(callback) { var _this7 = this; - return this.walk(function (selector) { if (selector.type === types.NESTING) { return callback.call(_this7, selector); } }); }; - _proto.walkPseudos = function walkPseudos(callback) { var _this8 = this; - return this.walk(function (selector) { if (selector.type === types.PSEUDO) { return callback.call(_this8, selector); } }); }; - _proto.walkTags = function walkTags(callback) { var _this9 = this; - return this.walk(function (selector) { if (selector.type === types.TAG) { return callback.call(_this9, selector); } }); }; - _proto.walkUniversals = function walkUniversals(callback) { var _this10 = this; - return this.walk(function (selector) { if (selector.type === types.UNIVERSAL) { return callback.call(_this10, selector); } }); }; - _proto.split = function split(callback) { var _this11 = this; - var current = []; return this.reduce(function (memo, node, index) { var split = callback.call(_this11, node); current.push(node); - if (split) { memo.push(current); current = []; } else if (index === _this11.length - 1) { memo.push(current); } - return memo; }, []); }; - _proto.map = function map(callback) { return this.nodes.map(callback); }; - _proto.reduce = function reduce(callback, memo) { return this.nodes.reduce(callback, memo); }; - _proto.every = function every(callback) { return this.nodes.every(callback); }; - _proto.some = function some(callback) { return this.nodes.some(callback); }; - _proto.filter = function filter(callback) { return this.nodes.filter(callback); }; - _proto.sort = function sort(callback) { return this.nodes.sort(callback); }; - _proto.toString = function toString() { return this.map(String).join(''); }; - _createClass(Container, [{ key: "first", get: function get() { @@ -387,9 +315,7 @@ var Container = /*#__PURE__*/function (_Node) { return this.nodes.length; } }]); - return Container; }(_node["default"]); - exports["default"] = Container; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/guards.js b/node_modules/postcss-selector-parser/dist/selectors/guards.js index c949af57eb1fd..f06161e97cb26 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/guards.js +++ b/node_modules/postcss-selector-parser/dist/selectors/guards.js @@ -1,27 +1,25 @@ "use strict"; exports.__esModule = true; -exports.isNode = isNode; -exports.isPseudoElement = isPseudoElement; -exports.isPseudoClass = isPseudoClass; +exports.isComment = exports.isCombinator = exports.isClassName = exports.isAttribute = void 0; exports.isContainer = isContainer; +exports.isIdentifier = void 0; exports.isNamespace = isNamespace; -exports.isUniversal = exports.isTag = exports.isString = exports.isSelector = exports.isRoot = exports.isPseudo = exports.isNesting = exports.isIdentifier = exports.isComment = exports.isCombinator = exports.isClassName = exports.isAttribute = void 0; - +exports.isNesting = void 0; +exports.isNode = isNode; +exports.isPseudo = void 0; +exports.isPseudoClass = isPseudoClass; +exports.isPseudoElement = isPseudoElement; +exports.isUniversal = exports.isTag = exports.isString = exports.isSelector = exports.isRoot = void 0; var _types = require("./types"); - var _IS_TYPE; - var IS_TYPE = (_IS_TYPE = {}, _IS_TYPE[_types.ATTRIBUTE] = true, _IS_TYPE[_types.CLASS] = true, _IS_TYPE[_types.COMBINATOR] = true, _IS_TYPE[_types.COMMENT] = true, _IS_TYPE[_types.ID] = true, _IS_TYPE[_types.NESTING] = true, _IS_TYPE[_types.PSEUDO] = true, _IS_TYPE[_types.ROOT] = true, _IS_TYPE[_types.SELECTOR] = true, _IS_TYPE[_types.STRING] = true, _IS_TYPE[_types.TAG] = true, _IS_TYPE[_types.UNIVERSAL] = true, _IS_TYPE); - function isNode(node) { return typeof node === "object" && IS_TYPE[node.type]; } - function isNodeType(type, node) { return isNode(node) && node.type === type; } - var isAttribute = isNodeType.bind(null, _types.ATTRIBUTE); exports.isAttribute = isAttribute; var isClassName = isNodeType.bind(null, _types.CLASS); @@ -46,19 +44,15 @@ var isTag = isNodeType.bind(null, _types.TAG); exports.isTag = isTag; var isUniversal = isNodeType.bind(null, _types.UNIVERSAL); exports.isUniversal = isUniversal; - function isPseudoElement(node) { return isPseudo(node) && node.value && (node.value.startsWith("::") || node.value.toLowerCase() === ":before" || node.value.toLowerCase() === ":after" || node.value.toLowerCase() === ":first-letter" || node.value.toLowerCase() === ":first-line"); } - function isPseudoClass(node) { return isPseudo(node) && !isPseudoElement(node); } - function isContainer(node) { return !!(isNode(node) && node.walk); } - function isNamespace(node) { return isAttribute(node) || isTag(node); } \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/id.js b/node_modules/postcss-selector-parser/dist/selectors/id.js index 4e83147e3c4ef..8baef72860c9b 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/id.js +++ b/node_modules/postcss-selector-parser/dist/selectors/id.js @@ -2,36 +2,24 @@ exports.__esModule = true; exports["default"] = void 0; - var _node = _interopRequireDefault(require("./node")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var ID = /*#__PURE__*/function (_Node) { _inheritsLoose(ID, _Node); - function ID(opts) { var _this; - _this = _Node.call(this, opts) || this; _this.type = _types.ID; return _this; } - var _proto = ID.prototype; - _proto.valueToString = function valueToString() { return '#' + _Node.prototype.valueToString.call(this); }; - return ID; }(_node["default"]); - exports["default"] = ID; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/index.js b/node_modules/postcss-selector-parser/dist/selectors/index.js index 1fe9b138a5a26..f1f6b7f5e63ca 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/index.js +++ b/node_modules/postcss-selector-parser/dist/selectors/index.js @@ -1,25 +1,19 @@ "use strict"; exports.__esModule = true; - var _types = require("./types"); - Object.keys(_types).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (key in exports && exports[key] === _types[key]) return; exports[key] = _types[key]; }); - var _constructors = require("./constructors"); - Object.keys(_constructors).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (key in exports && exports[key] === _constructors[key]) return; exports[key] = _constructors[key]; }); - var _guards = require("./guards"); - Object.keys(_guards).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (key in exports && exports[key] === _guards[key]) return; diff --git a/node_modules/postcss-selector-parser/dist/selectors/namespace.js b/node_modules/postcss-selector-parser/dist/selectors/namespace.js index fd6c729e16661..cc97647bd174b 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/namespace.js +++ b/node_modules/postcss-selector-parser/dist/selectors/namespace.js @@ -2,32 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _cssesc = _interopRequireDefault(require("cssesc")); - var _util = require("../util"); - var _node = _interopRequireDefault(require("./node")); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Namespace = /*#__PURE__*/function (_Node) { _inheritsLoose(Namespace, _Node); - function Namespace() { return _Node.apply(this, arguments) || this; } - var _proto = Namespace.prototype; - _proto.qualifiedName = function qualifiedName(value) { if (this.namespace) { return this.namespaceString + "|" + value; @@ -35,11 +23,9 @@ var Namespace = /*#__PURE__*/function (_Node) { return value; } }; - _proto.valueToString = function valueToString() { return this.qualifiedName(_Node.prototype.valueToString.call(this)); }; - _createClass(Namespace, [{ key: "namespace", get: function get() { @@ -48,19 +34,15 @@ var Namespace = /*#__PURE__*/function (_Node) { set: function set(namespace) { if (namespace === true || namespace === "*" || namespace === "&") { this._namespace = namespace; - if (this.raws) { delete this.raws.namespace; } - return; } - var escaped = (0, _cssesc["default"])(namespace, { isIdentifier: true }); this._namespace = namespace; - if (escaped !== namespace) { (0, _util.ensureObject)(this, "raws"); this.raws.namespace = escaped; @@ -81,7 +63,6 @@ var Namespace = /*#__PURE__*/function (_Node) { get: function get() { if (this.namespace) { var ns = this.stringifyProperty("namespace"); - if (ns === true) { return ''; } else { @@ -92,10 +73,8 @@ var Namespace = /*#__PURE__*/function (_Node) { } } }]); - return Namespace; }(_node["default"]); - exports["default"] = Namespace; ; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/nesting.js b/node_modules/postcss-selector-parser/dist/selectors/nesting.js index 3288c78f2dddb..218992875a60c 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/nesting.js +++ b/node_modules/postcss-selector-parser/dist/selectors/nesting.js @@ -2,31 +2,21 @@ exports.__esModule = true; exports["default"] = void 0; - var _node = _interopRequireDefault(require("./node")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Nesting = /*#__PURE__*/function (_Node) { _inheritsLoose(Nesting, _Node); - function Nesting(opts) { var _this; - _this = _Node.call(this, opts) || this; _this.type = _types.NESTING; _this.value = '&'; return _this; } - return Nesting; }(_node["default"]); - exports["default"] = Nesting; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/node.js b/node_modules/postcss-selector-parser/dist/selectors/node.js index e8eca11c70ecf..9a8295101066a 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/node.js +++ b/node_modules/postcss-selector-parser/dist/selectors/node.js @@ -2,28 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _util = require("../util"); - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } var cloneNode = function cloneNode(obj, parent) { if (typeof obj !== 'object' || obj === null) { return obj; } - var cloned = new obj.constructor(); - for (var i in obj) { if (!obj.hasOwnProperty(i)) { continue; } - var value = obj[i]; var type = typeof value; - if (i === 'parent' && type === 'object') { if (parent) { cloned[i] = parent; @@ -36,66 +28,52 @@ var cloneNode = function cloneNode(obj, parent) { cloned[i] = cloneNode(value, cloned); } } - return cloned; }; - var Node = /*#__PURE__*/function () { function Node(opts) { if (opts === void 0) { opts = {}; } - Object.assign(this, opts); this.spaces = this.spaces || {}; this.spaces.before = this.spaces.before || ''; this.spaces.after = this.spaces.after || ''; } - var _proto = Node.prototype; - _proto.remove = function remove() { if (this.parent) { this.parent.removeChild(this); } - this.parent = undefined; return this; }; - _proto.replaceWith = function replaceWith() { if (this.parent) { for (var index in arguments) { this.parent.insertBefore(this, arguments[index]); } - this.remove(); } - return this; }; - _proto.next = function next() { return this.parent.at(this.parent.index(this) + 1); }; - _proto.prev = function prev() { return this.parent.at(this.parent.index(this) - 1); }; - _proto.clone = function clone(overrides) { if (overrides === void 0) { overrides = {}; } - var cloned = cloneNode(this); - for (var name in overrides) { cloned[name] = overrides[name]; } - return cloned; } + /** * Some non-standard syntax doesn't follow normal escaping rules for css. * This allows non standard syntax to be appended to an existing property @@ -104,24 +82,21 @@ var Node = /*#__PURE__*/function () { * @param {string} name the property to set * @param {any} value the unescaped value of the property * @param {string} valueEscaped optional. the escaped value of the property. - */ - ; - + */; _proto.appendToPropertyAndEscape = function appendToPropertyAndEscape(name, value, valueEscaped) { if (!this.raws) { this.raws = {}; } - var originalValue = this[name]; var originalEscaped = this.raws[name]; this[name] = originalValue + value; // this may trigger a setter that updates raws, so it has to be set first. - if (originalEscaped || valueEscaped !== value) { this.raws[name] = (originalEscaped || originalValue) + valueEscaped; } else { delete this.raws[name]; // delete any escaped value that was created by the setter. } } + /** * Some non-standard syntax doesn't follow normal escaping rules for css. * This allows the escaped value to be specified directly, allowing illegal @@ -129,86 +104,68 @@ var Node = /*#__PURE__*/function () { * @param {string} name the property to set * @param {any} value the unescaped value of the property * @param {string} valueEscaped the escaped value of the property. - */ - ; - + */; _proto.setPropertyAndEscape = function setPropertyAndEscape(name, value, valueEscaped) { if (!this.raws) { this.raws = {}; } - this[name] = value; // this may trigger a setter that updates raws, so it has to be set first. - this.raws[name] = valueEscaped; } + /** * When you want a value to passed through to CSS directly. This method * deletes the corresponding raw value causing the stringifier to fallback * to the unescaped value. * @param {string} name the property to set. * @param {any} value The value that is both escaped and unescaped. - */ - ; - + */; _proto.setPropertyWithoutEscape = function setPropertyWithoutEscape(name, value) { this[name] = value; // this may trigger a setter that updates raws, so it has to be set first. - if (this.raws) { delete this.raws[name]; } } + /** * * @param {number} line The number (starting with 1) * @param {number} column The column number (starting with 1) - */ - ; - + */; _proto.isAtPosition = function isAtPosition(line, column) { if (this.source && this.source.start && this.source.end) { if (this.source.start.line > line) { return false; } - if (this.source.end.line < line) { return false; } - if (this.source.start.line === line && this.source.start.column > column) { return false; } - if (this.source.end.line === line && this.source.end.column < column) { return false; } - return true; } - return undefined; }; - _proto.stringifyProperty = function stringifyProperty(name) { return this.raws && this.raws[name] || this[name]; }; - _proto.valueToString = function valueToString() { return String(this.stringifyProperty("value")); }; - _proto.toString = function toString() { return [this.rawSpaceBefore, this.valueToString(), this.rawSpaceAfter].join(''); }; - _createClass(Node, [{ key: "rawSpaceBefore", get: function get() { var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.before; - if (rawSpace === undefined) { rawSpace = this.spaces && this.spaces.before; } - return rawSpace || ""; }, set: function set(raw) { @@ -219,11 +176,9 @@ var Node = /*#__PURE__*/function () { key: "rawSpaceAfter", get: function get() { var rawSpace = this.raws && this.raws.spaces && this.raws.spaces.after; - if (rawSpace === undefined) { rawSpace = this.spaces.after; } - return rawSpace || ""; }, set: function set(raw) { @@ -231,9 +186,7 @@ var Node = /*#__PURE__*/function () { this.raws.spaces.after = raw; } }]); - return Node; }(); - exports["default"] = Node; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/pseudo.js b/node_modules/postcss-selector-parser/dist/selectors/pseudo.js index a0e7bca170a76..4371e5900f5c7 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/pseudo.js +++ b/node_modules/postcss-selector-parser/dist/selectors/pseudo.js @@ -2,37 +2,25 @@ exports.__esModule = true; exports["default"] = void 0; - var _container = _interopRequireDefault(require("./container")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Pseudo = /*#__PURE__*/function (_Container) { _inheritsLoose(Pseudo, _Container); - function Pseudo(opts) { var _this; - _this = _Container.call(this, opts) || this; _this.type = _types.PSEUDO; return _this; } - var _proto = Pseudo.prototype; - _proto.toString = function toString() { var params = this.length ? '(' + this.map(String).join(',') + ')' : ''; return [this.rawSpaceBefore, this.stringifyProperty("value"), params, this.rawSpaceAfter].join(''); }; - return Pseudo; }(_container["default"]); - exports["default"] = Pseudo; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/root.js b/node_modules/postcss-selector-parser/dist/selectors/root.js index be5c2ccb2dac8..8c599d15809f5 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/root.js +++ b/node_modules/postcss-selector-parser/dist/selectors/root.js @@ -2,34 +2,22 @@ exports.__esModule = true; exports["default"] = void 0; - var _container = _interopRequireDefault(require("./container")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Root = /*#__PURE__*/function (_Container) { _inheritsLoose(Root, _Container); - function Root(opts) { var _this; - _this = _Container.call(this, opts) || this; _this.type = _types.ROOT; return _this; } - var _proto = Root.prototype; - _proto.toString = function toString() { var str = this.reduce(function (memo, selector) { memo.push(String(selector)); @@ -37,7 +25,6 @@ var Root = /*#__PURE__*/function (_Container) { }, []).join(','); return this.trailingComma ? str + ',' : str; }; - _proto.error = function error(message, options) { if (this._error) { return this._error(message, options); @@ -45,16 +32,13 @@ var Root = /*#__PURE__*/function (_Container) { return new Error(message); } }; - _createClass(Root, [{ key: "errorGenerator", set: function set(handler) { this._error = handler; } }]); - return Root; }(_container["default"]); - exports["default"] = Root; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/selector.js b/node_modules/postcss-selector-parser/dist/selectors/selector.js index 699eeb6e546f9..8cc4bc1cddd75 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/selector.js +++ b/node_modules/postcss-selector-parser/dist/selectors/selector.js @@ -2,30 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _container = _interopRequireDefault(require("./container")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Selector = /*#__PURE__*/function (_Container) { _inheritsLoose(Selector, _Container); - function Selector(opts) { var _this; - _this = _Container.call(this, opts) || this; _this.type = _types.SELECTOR; return _this; } - return Selector; }(_container["default"]); - exports["default"] = Selector; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/string.js b/node_modules/postcss-selector-parser/dist/selectors/string.js index e61df30c74a0a..4749791416b57 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/string.js +++ b/node_modules/postcss-selector-parser/dist/selectors/string.js @@ -2,30 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _node = _interopRequireDefault(require("./node")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var String = /*#__PURE__*/function (_Node) { _inheritsLoose(String, _Node); - function String(opts) { var _this; - _this = _Node.call(this, opts) || this; _this.type = _types.STRING; return _this; } - return String; }(_node["default"]); - exports["default"] = String; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/tag.js b/node_modules/postcss-selector-parser/dist/selectors/tag.js index e298db15fafd1..224e74de4a2f7 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/tag.js +++ b/node_modules/postcss-selector-parser/dist/selectors/tag.js @@ -2,30 +2,20 @@ exports.__esModule = true; exports["default"] = void 0; - var _namespace = _interopRequireDefault(require("./namespace")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Tag = /*#__PURE__*/function (_Namespace) { _inheritsLoose(Tag, _Namespace); - function Tag(opts) { var _this; - _this = _Namespace.call(this, opts) || this; _this.type = _types.TAG; return _this; } - return Tag; }(_namespace["default"]); - exports["default"] = Tag; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/selectors/types.js b/node_modules/postcss-selector-parser/dist/selectors/types.js index ab897b8ce5c12..824cc0c738945 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/types.js +++ b/node_modules/postcss-selector-parser/dist/selectors/types.js @@ -1,7 +1,7 @@ "use strict"; exports.__esModule = true; -exports.UNIVERSAL = exports.ATTRIBUTE = exports.CLASS = exports.COMBINATOR = exports.COMMENT = exports.ID = exports.NESTING = exports.PSEUDO = exports.ROOT = exports.SELECTOR = exports.STRING = exports.TAG = void 0; +exports.UNIVERSAL = exports.TAG = exports.STRING = exports.SELECTOR = exports.ROOT = exports.PSEUDO = exports.NESTING = exports.ID = exports.COMMENT = exports.COMBINATOR = exports.CLASS = exports.ATTRIBUTE = void 0; var TAG = 'tag'; exports.TAG = TAG; var STRING = 'string'; diff --git a/node_modules/postcss-selector-parser/dist/selectors/universal.js b/node_modules/postcss-selector-parser/dist/selectors/universal.js index cf25473d1c3d4..5b5874380b8e9 100644 --- a/node_modules/postcss-selector-parser/dist/selectors/universal.js +++ b/node_modules/postcss-selector-parser/dist/selectors/universal.js @@ -2,31 +2,21 @@ exports.__esModule = true; exports["default"] = void 0; - var _namespace = _interopRequireDefault(require("./namespace")); - var _types = require("./types"); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var Universal = /*#__PURE__*/function (_Namespace) { _inheritsLoose(Universal, _Namespace); - function Universal(opts) { var _this; - _this = _Namespace.call(this, opts) || this; _this.type = _types.UNIVERSAL; _this.value = '*'; return _this; } - return Universal; }(_namespace["default"]); - exports["default"] = Universal; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/sortAscending.js b/node_modules/postcss-selector-parser/dist/sortAscending.js index 3ef56acc570c8..5666d5dc99f89 100644 --- a/node_modules/postcss-selector-parser/dist/sortAscending.js +++ b/node_modules/postcss-selector-parser/dist/sortAscending.js @@ -2,12 +2,10 @@ exports.__esModule = true; exports["default"] = sortAscending; - function sortAscending(list) { return list.sort(function (a, b) { return a - b; }); } - ; module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/tokenTypes.js b/node_modules/postcss-selector-parser/dist/tokenTypes.js index 48314b93e0058..59d8e6c6bf4cf 100644 --- a/node_modules/postcss-selector-parser/dist/tokenTypes.js +++ b/node_modules/postcss-selector-parser/dist/tokenTypes.js @@ -1,91 +1,66 @@ "use strict"; exports.__esModule = true; -exports.combinator = exports.word = exports.comment = exports.str = exports.tab = exports.newline = exports.feed = exports.cr = exports.backslash = exports.bang = exports.slash = exports.doubleQuote = exports.singleQuote = exports.space = exports.greaterThan = exports.pipe = exports.equals = exports.plus = exports.caret = exports.tilde = exports.dollar = exports.closeSquare = exports.openSquare = exports.closeParenthesis = exports.openParenthesis = exports.semicolon = exports.colon = exports.comma = exports.at = exports.asterisk = exports.ampersand = void 0; +exports.word = exports.tilde = exports.tab = exports.str = exports.space = exports.slash = exports.singleQuote = exports.semicolon = exports.plus = exports.pipe = exports.openSquare = exports.openParenthesis = exports.newline = exports.greaterThan = exports.feed = exports.equals = exports.doubleQuote = exports.dollar = exports.cr = exports.comment = exports.comma = exports.combinator = exports.colon = exports.closeSquare = exports.closeParenthesis = exports.caret = exports.bang = exports.backslash = exports.at = exports.asterisk = exports.ampersand = void 0; var ampersand = 38; // `&`.charCodeAt(0); - exports.ampersand = ampersand; var asterisk = 42; // `*`.charCodeAt(0); - exports.asterisk = asterisk; var at = 64; // `@`.charCodeAt(0); - exports.at = at; var comma = 44; // `,`.charCodeAt(0); - exports.comma = comma; var colon = 58; // `:`.charCodeAt(0); - exports.colon = colon; var semicolon = 59; // `;`.charCodeAt(0); - exports.semicolon = semicolon; var openParenthesis = 40; // `(`.charCodeAt(0); - exports.openParenthesis = openParenthesis; var closeParenthesis = 41; // `)`.charCodeAt(0); - exports.closeParenthesis = closeParenthesis; var openSquare = 91; // `[`.charCodeAt(0); - exports.openSquare = openSquare; var closeSquare = 93; // `]`.charCodeAt(0); - exports.closeSquare = closeSquare; var dollar = 36; // `$`.charCodeAt(0); - exports.dollar = dollar; var tilde = 126; // `~`.charCodeAt(0); - exports.tilde = tilde; var caret = 94; // `^`.charCodeAt(0); - exports.caret = caret; var plus = 43; // `+`.charCodeAt(0); - exports.plus = plus; var equals = 61; // `=`.charCodeAt(0); - exports.equals = equals; var pipe = 124; // `|`.charCodeAt(0); - exports.pipe = pipe; var greaterThan = 62; // `>`.charCodeAt(0); - exports.greaterThan = greaterThan; var space = 32; // ` `.charCodeAt(0); - exports.space = space; var singleQuote = 39; // `'`.charCodeAt(0); - exports.singleQuote = singleQuote; var doubleQuote = 34; // `"`.charCodeAt(0); - exports.doubleQuote = doubleQuote; var slash = 47; // `/`.charCodeAt(0); - exports.slash = slash; var bang = 33; // `!`.charCodeAt(0); - exports.bang = bang; var backslash = 92; // '\\'.charCodeAt(0); - exports.backslash = backslash; var cr = 13; // '\r'.charCodeAt(0); - exports.cr = cr; var feed = 12; // '\f'.charCodeAt(0); - exports.feed = feed; var newline = 10; // '\n'.charCodeAt(0); - exports.newline = newline; var tab = 9; // '\t'.charCodeAt(0); -// Expose aliases primarily for readability. +// Expose aliases primarily for readability. exports.tab = tab; -var str = singleQuote; // No good single character representation! +var str = singleQuote; +// No good single character representation! exports.str = str; var comment = -1; exports.comment = comment; diff --git a/node_modules/postcss-selector-parser/dist/tokenize.js b/node_modules/postcss-selector-parser/dist/tokenize.js index bee9fee632e84..bf61d261b5cd7 100644 --- a/node_modules/postcss-selector-parser/dist/tokenize.js +++ b/node_modules/postcss-selector-parser/dist/tokenize.js @@ -1,39 +1,30 @@ "use strict"; exports.__esModule = true; -exports["default"] = tokenize; exports.FIELDS = void 0; - +exports["default"] = tokenize; var t = _interopRequireWildcard(require("./tokenTypes")); - var _unescapable, _wordDelimiters; - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } var unescapable = (_unescapable = {}, _unescapable[t.tab] = true, _unescapable[t.newline] = true, _unescapable[t.cr] = true, _unescapable[t.feed] = true, _unescapable); var wordDelimiters = (_wordDelimiters = {}, _wordDelimiters[t.space] = true, _wordDelimiters[t.tab] = true, _wordDelimiters[t.newline] = true, _wordDelimiters[t.cr] = true, _wordDelimiters[t.feed] = true, _wordDelimiters[t.ampersand] = true, _wordDelimiters[t.asterisk] = true, _wordDelimiters[t.bang] = true, _wordDelimiters[t.comma] = true, _wordDelimiters[t.colon] = true, _wordDelimiters[t.semicolon] = true, _wordDelimiters[t.openParenthesis] = true, _wordDelimiters[t.closeParenthesis] = true, _wordDelimiters[t.openSquare] = true, _wordDelimiters[t.closeSquare] = true, _wordDelimiters[t.singleQuote] = true, _wordDelimiters[t.doubleQuote] = true, _wordDelimiters[t.plus] = true, _wordDelimiters[t.pipe] = true, _wordDelimiters[t.tilde] = true, _wordDelimiters[t.greaterThan] = true, _wordDelimiters[t.equals] = true, _wordDelimiters[t.dollar] = true, _wordDelimiters[t.caret] = true, _wordDelimiters[t.slash] = true, _wordDelimiters); var hex = {}; var hexChars = "0123456789abcdefABCDEF"; - for (var i = 0; i < hexChars.length; i++) { hex[hexChars.charCodeAt(i)] = true; } + /** * Returns the last index of the bar css word * @param {string} css The string in which the word begins * @param {number} start The index into the string where word's first letter occurs */ - - function consumeWord(css, start) { var next = start; var code; - do { code = css.charCodeAt(next); - if (wordDelimiters[code]) { return next - 1; } else if (code === t.backslash) { @@ -43,31 +34,28 @@ function consumeWord(css, start) { next++; } } while (next < css.length); - return next - 1; } + /** * Returns the last index of the escape sequence * @param {string} css The string in which the sequence begins * @param {number} start The index into the string where escape character (`\`) occurs. */ - - function consumeEscape(css, start) { var next = start; var code = css.charCodeAt(next + 1); - - if (unescapable[code]) {// just consume the escape char + if (unescapable[code]) { + // just consume the escape char } else if (hex[code]) { - var hexDigits = 0; // consume up to 6 hex chars - + var hexDigits = 0; + // consume up to 6 hex chars do { next++; hexDigits++; code = css.charCodeAt(next + 1); - } while (hex[code] && hexDigits < 6); // if fewer than 6 hex chars, a trailing space ends the escape - - + } while (hex[code] && hexDigits < 6); + // if fewer than 6 hex chars, a trailing space ends the escape if (hexDigits < 6 && code === t.space) { next++; } @@ -75,10 +63,8 @@ function consumeEscape(css, start) { // the next char is part of the current word next++; } - return next; } - var FIELDS = { TYPE: 0, START_LINE: 1, @@ -89,18 +75,16 @@ var FIELDS = { END_POS: 6 }; exports.FIELDS = FIELDS; - function tokenize(input) { var tokens = []; var css = input.css.valueOf(); var _css = css, - length = _css.length; + length = _css.length; var offset = -1; var line = 1; var start = 0; var end = 0; var code, content, endColumn, endLine, escaped, escapePos, last, lines, next, nextLine, nextOffset, quote, tokenType; - function unclosed(what, fix) { if (input.safe) { // fyi: this is never set to true. @@ -110,15 +94,12 @@ function tokenize(input) { throw input.error('Unclosed ' + what, line, start - offset, start); } } - while (start < length) { code = css.charCodeAt(start); - if (code === t.newline) { offset = start; line += 1; } - switch (code) { case t.space: case t.tab: @@ -126,41 +107,35 @@ function tokenize(input) { case t.cr: case t.feed: next = start; - do { next += 1; code = css.charCodeAt(next); - if (code === t.newline) { offset = next; line += 1; } } while (code === t.space || code === t.newline || code === t.tab || code === t.cr || code === t.feed); - tokenType = t.space; endLine = line; endColumn = next - offset - 1; end = next; break; - case t.plus: case t.greaterThan: case t.tilde: case t.pipe: next = start; - do { next += 1; code = css.charCodeAt(next); } while (code === t.plus || code === t.greaterThan || code === t.tilde || code === t.pipe); - tokenType = t.combinator; endLine = line; endColumn = start - offset; end = next; break; - // Consume these characters as single tokens. + // Consume these characters as single tokens. case t.asterisk: case t.ampersand: case t.bang: @@ -180,46 +155,36 @@ function tokenize(input) { endColumn = start - offset; end = next + 1; break; - case t.singleQuote: case t.doubleQuote: quote = code === t.singleQuote ? "'" : '"'; next = start; - do { escaped = false; next = css.indexOf(quote, next + 1); - if (next === -1) { unclosed('quote', quote); } - escapePos = next; - while (css.charCodeAt(escapePos - 1) === t.backslash) { escapePos -= 1; escaped = !escaped; } } while (escaped); - tokenType = t.str; endLine = line; endColumn = start - offset; end = next + 1; break; - default: if (code === t.slash && css.charCodeAt(start + 1) === t.asterisk) { next = css.indexOf('*/', start + 2) + 1; - if (next === 0) { unclosed('comment', '*/'); } - content = css.slice(start, next + 1); lines = content.split('\n'); last = lines.length - 1; - if (last > 0) { nextLine = line + last; nextOffset = next - lines[last].length; @@ -227,7 +192,6 @@ function tokenize(input) { nextLine = line; nextOffset = offset; } - tokenType = t.comment; line = nextLine; endLine = nextLine; @@ -244,28 +208,32 @@ function tokenize(input) { endLine = line; endColumn = next - offset; } - end = next + 1; break; - } // Ensure that the token structure remains consistent - + } - tokens.push([tokenType, // [0] Token type - line, // [1] Starting line - start - offset, // [2] Starting column - endLine, // [3] Ending line - endColumn, // [4] Ending column - start, // [5] Start position / Source index + // Ensure that the token structure remains consistent + tokens.push([tokenType, + // [0] Token type + line, + // [1] Starting line + start - offset, + // [2] Starting column + endLine, + // [3] Ending line + endColumn, + // [4] Ending column + start, + // [5] Start position / Source index end // [6] End position - ]); // Reset offset for the next token + ]); + // Reset offset for the next token if (nextOffset) { offset = nextOffset; nextOffset = null; } - start = end; } - return tokens; } \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/util/ensureObject.js b/node_modules/postcss-selector-parser/dist/util/ensureObject.js index 3472e07522840..494941adaf212 100644 --- a/node_modules/postcss-selector-parser/dist/util/ensureObject.js +++ b/node_modules/postcss-selector-parser/dist/util/ensureObject.js @@ -2,21 +2,16 @@ exports.__esModule = true; exports["default"] = ensureObject; - function ensureObject(obj) { for (var _len = arguments.length, props = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { props[_key - 1] = arguments[_key]; } - while (props.length > 0) { var prop = props.shift(); - if (!obj[prop]) { obj[prop] = {}; } - obj = obj[prop]; } } - module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/util/getProp.js b/node_modules/postcss-selector-parser/dist/util/getProp.js index 53e07c90253eb..a2b7a07307b0e 100644 --- a/node_modules/postcss-selector-parser/dist/util/getProp.js +++ b/node_modules/postcss-selector-parser/dist/util/getProp.js @@ -2,23 +2,17 @@ exports.__esModule = true; exports["default"] = getProp; - function getProp(obj) { for (var _len = arguments.length, props = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { props[_key - 1] = arguments[_key]; } - while (props.length > 0) { var prop = props.shift(); - if (!obj[prop]) { return undefined; } - obj = obj[prop]; } - return obj; } - module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/util/index.js b/node_modules/postcss-selector-parser/dist/util/index.js index 043fda8c64b9a..f96ec11b6d476 100644 --- a/node_modules/postcss-selector-parser/dist/util/index.js +++ b/node_modules/postcss-selector-parser/dist/util/index.js @@ -1,22 +1,13 @@ "use strict"; exports.__esModule = true; -exports.stripComments = exports.ensureObject = exports.getProp = exports.unesc = void 0; - +exports.unesc = exports.stripComments = exports.getProp = exports.ensureObject = void 0; var _unesc = _interopRequireDefault(require("./unesc")); - exports.unesc = _unesc["default"]; - var _getProp = _interopRequireDefault(require("./getProp")); - exports.getProp = _getProp["default"]; - var _ensureObject = _interopRequireDefault(require("./ensureObject")); - exports.ensureObject = _ensureObject["default"]; - var _stripComments = _interopRequireDefault(require("./stripComments")); - exports.stripComments = _stripComments["default"]; - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/util/stripComments.js b/node_modules/postcss-selector-parser/dist/util/stripComments.js index c74f1fecdcc64..0baa0e07eb0b9 100644 --- a/node_modules/postcss-selector-parser/dist/util/stripComments.js +++ b/node_modules/postcss-selector-parser/dist/util/stripComments.js @@ -2,26 +2,20 @@ exports.__esModule = true; exports["default"] = stripComments; - function stripComments(str) { var s = ""; var commentStart = str.indexOf("/*"); var lastEnd = 0; - while (commentStart >= 0) { s = s + str.slice(lastEnd, commentStart); var commentEnd = str.indexOf("*/", commentStart + 2); - if (commentEnd < 0) { return s; } - lastEnd = commentEnd + 2; commentStart = str.indexOf("/*", lastEnd); } - s = s + str.slice(lastEnd); return s; } - module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/dist/util/unesc.js b/node_modules/postcss-selector-parser/dist/util/unesc.js index 3136e7e008420..87396bee181e2 100644 --- a/node_modules/postcss-selector-parser/dist/util/unesc.js +++ b/node_modules/postcss-selector-parser/dist/util/unesc.js @@ -2,7 +2,6 @@ exports.__esModule = true; exports["default"] = unesc; - // Many thanks for this post which made this migration much easier. // https://mathiasbynens.be/notes/css-escapes @@ -15,79 +14,63 @@ function gobbleHex(str) { var lower = str.toLowerCase(); var hex = ''; var spaceTerminated = false; - for (var i = 0; i < 6 && lower[i] !== undefined; i++) { - var code = lower.charCodeAt(i); // check to see if we are dealing with a valid hex char [a-f|0-9] - - var valid = code >= 97 && code <= 102 || code >= 48 && code <= 57; // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point - + var code = lower.charCodeAt(i); + // check to see if we are dealing with a valid hex char [a-f|0-9] + var valid = code >= 97 && code <= 102 || code >= 48 && code <= 57; + // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point spaceTerminated = code === 32; - if (!valid) { break; } - hex += lower[i]; } - if (hex.length === 0) { return undefined; } - var codePoint = parseInt(hex, 16); - var isSurrogate = codePoint >= 0xD800 && codePoint <= 0xDFFF; // Add special case for + var isSurrogate = codePoint >= 0xD800 && codePoint <= 0xDFFF; + // Add special case for // "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point" // https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point - if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10FFFF) { return ["\uFFFD", hex.length + (spaceTerminated ? 1 : 0)]; } - return [String.fromCodePoint(codePoint), hex.length + (spaceTerminated ? 1 : 0)]; } - var CONTAINS_ESCAPE = /\\/; - function unesc(str) { var needToProcess = CONTAINS_ESCAPE.test(str); - if (!needToProcess) { return str; } - var ret = ""; - for (var i = 0; i < str.length; i++) { if (str[i] === "\\") { var gobbled = gobbleHex(str.slice(i + 1, i + 7)); - if (gobbled !== undefined) { ret += gobbled[0]; i += gobbled[1]; continue; - } // Retain a pair of \\ if double escaped `\\\\` - // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e - + } + // Retain a pair of \\ if double escaped `\\\\` + // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e if (str[i + 1] === "\\") { ret += "\\"; i++; continue; - } // if \\ is at the end of the string retain it - // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb - + } + // if \\ is at the end of the string retain it + // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb if (str.length === i + 1) { ret += str[i]; } - continue; } - ret += str[i]; } - return ret; } - module.exports = exports.default; \ No newline at end of file diff --git a/node_modules/postcss-selector-parser/package.json b/node_modules/postcss-selector-parser/package.json index a6f33589ba051..c4f057c915bfd 100644 --- a/node_modules/postcss-selector-parser/package.json +++ b/node_modules/postcss-selector-parser/package.json @@ -1,6 +1,6 @@ { "name": "postcss-selector-parser", - "version": "6.0.10", + "version": "7.1.1", "devDependencies": { "@babel/cli": "^7.11.6", "@babel/core": "^7.11.6", @@ -9,16 +9,16 @@ "@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/preset-env": "^7.11.5", "@babel/register": "^7.11.5", - "ava": "^3.12.1", + "ava": "^5.1.0", "babel-plugin-add-module-exports": "^1.0.4", - "coveralls": "^3.1.0", - "del-cli": "^3.0.1", - "eslint": "^7.9.0", - "eslint-plugin-import": "^2.22.0", - "glob": "^7.1.6", + "coveralls-next": "^4.2.1", + "del-cli": "^5.0.0", + "eslint": "^8.28.0", + "eslint-plugin-import": "^2.26.0", + "glob": "^8.0.3", "minimist": "^1.2.5", "nyc": "^15.1.0", - "postcss": "^8.0.0", + "postcss": "^8.4.31", "semver": "^7.3.2", "typescript": "^4.0.3" }, @@ -33,11 +33,13 @@ "!**/__tests__" ], "scripts": { - "pretest": "eslint src && tsc --noEmit postcss-selector-parser.d.ts", + "typecheck": "tsc --noEmit --strict postcss-selector-parser.d.ts postcss-selector-parser.test.ts", + "pretest": "eslint src && npm run typecheck", "prepare": "del-cli dist && BABEL_ENV=publish babel src --out-dir dist --ignore /__tests__/", "lintfix": "eslint --fix src", "report": "nyc report --reporter=html", - "test": "nyc ava src/__tests__/*.js ", + "test": "nyc ava src/__tests__/*.mjs", + "test:node22": "nyc ava src/__tests__/*.mjs --node-arguments=--no-experimental-detect-module", "testone": "ava" }, "dependencies": { @@ -67,7 +69,8 @@ "@babel/register" ], "concurrency": 5, - "timeout": "25s" + "timeout": "25s", + "nodeArguments": [] }, "nyc": { "exclude": [ diff --git a/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts b/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts deleted file mode 100644 index 89a2c5239edb1..0000000000000 --- a/node_modules/postcss-selector-parser/postcss-selector-parser.d.ts +++ /dev/null @@ -1,555 +0,0 @@ -// Type definitions for postcss-selector-parser 2.2.3 -// Definitions by: Chris Eppstein <chris@eppsteins.net> - -/*~ Note that ES6 modules cannot directly export callable functions. - *~ This file should be imported using the CommonJS-style: - *~ import x = require('someLibrary'); - *~ - *~ Refer to the documentation to understand common - *~ workarounds for this limitation of ES6 modules. - */ - -/*~ This declaration specifies that the function - *~ is the exported object from the file - */ -export = parser; - -// A type that's T but not U. -type Diff<T, U> = T extends U ? never : T; - -// TODO: Conditional types in TS 1.8 will really clean this up. -declare function parser(): parser.Processor<never>; -declare function parser<Transform>(processor: parser.AsyncProcessor<Transform>): parser.Processor<Transform, never>; -declare function parser(processor: parser.AsyncProcessor<void>): parser.Processor<never, never>; -declare function parser<Transform>(processor: parser.SyncProcessor<Transform>): parser.Processor<Transform>; -declare function parser(processor: parser.SyncProcessor<void>): parser.Processor<never>; -declare function parser<Transform>(processor?: parser.SyncProcessor<Transform> | parser.AsyncProcessor<Transform>): parser.Processor<Transform>; - -/*~ If you want to expose types from your module as well, you can - *~ place them in this block. Often you will want to describe the - *~ shape of the return type of the function; that type should - *~ be declared in here, as this example shows. - */ -declare namespace parser { - /* copied from postcss -- so we don't need to add a dependency */ - type ErrorOptions = { - plugin?: string; - word?: string; - index?: number - }; - /* the bits we use of postcss.Rule, copied from postcss -- so we don't need to add a dependency */ - type PostCSSRuleNode = { - selector: string - /** - * @returns postcss.CssSyntaxError but it's a complex object, caller - * should cast to it if they have a dependency on postcss. - */ - error(message: string, options?: ErrorOptions): Error; - }; - /** Accepts a string */ - type Selectors = string | PostCSSRuleNode - type ProcessorFn<ReturnType = void> = (root: parser.Root) => ReturnType; - type SyncProcessor<Transform = void> = ProcessorFn<Transform>; - type AsyncProcessor<Transform = void> = ProcessorFn<PromiseLike<Transform>>; - - const TAG: "tag"; - const STRING: "string"; - const SELECTOR: "selector"; - const ROOT: "root"; - const PSEUDO: "pseudo"; - const NESTING: "nesting"; - const ID: "id"; - const COMMENT: "comment"; - const COMBINATOR: "combinator"; - const CLASS: "class"; - const ATTRIBUTE: "attribute"; - const UNIVERSAL: "universal"; - - interface NodeTypes { - tag: Tag, - string: String, - selector: Selector, - root: Root, - pseudo: Pseudo, - nesting: Nesting, - id: Identifier, - comment: Comment, - combinator: Combinator, - class: ClassName, - attribute: Attribute, - universal: Universal - } - - type Node = NodeTypes[keyof NodeTypes]; - - function isNode(node: any): node is Node; - - interface Options { - /** - * Preserve whitespace when true. Default: false; - */ - lossless: boolean; - /** - * When true and a postcss.Rule is passed, set the result of - * processing back onto the rule when done. Default: false. - */ - updateSelector: boolean; - } - class Processor< - TransformType = never, - SyncSelectorsType extends Selectors | never = Selectors - > { - res: Root; - readonly result: String; - ast(selectors: Selectors, options?: Partial<Options>): Promise<Root>; - astSync(selectors: SyncSelectorsType, options?: Partial<Options>): Root; - transform(selectors: Selectors, options?: Partial<Options>): Promise<TransformType>; - transformSync(selectors: SyncSelectorsType, options?: Partial<Options>): TransformType; - process(selectors: Selectors, options?: Partial<Options>): Promise<string>; - processSync(selectors: SyncSelectorsType, options?: Partial<Options>): string; - } - interface ParserOptions { - css: string; - error: (message: string, options: ErrorOptions) => Error; - options: Options; - } - class Parser { - input: ParserOptions; - lossy: boolean; - position: number; - root: Root; - selectors: string; - current: Selector; - constructor(input: ParserOptions); - /** - * Raises an error, if the processor is invoked on - * a postcss Rule node, a better error message is raised. - */ - error(message: string, options?: ErrorOptions): void; - } - interface NodeSource { - start?: { - line: number, - column: number - }, - end?: { - line: number, - column: number - } - } - interface SpaceAround { - before: string; - after: string; - } - interface Spaces extends SpaceAround { - [spaceType: string]: string | Partial<SpaceAround> | undefined; - } - interface NodeOptions<Value = string> { - value: Value; - spaces?: Partial<Spaces>; - source?: NodeSource; - sourceIndex?: number; - } - interface Base< - Value extends string | undefined = string, - ParentType extends Container | undefined = Container | undefined - > { - type: keyof NodeTypes; - parent: ParentType; - value: Value; - spaces: Spaces; - source?: NodeSource; - sourceIndex: number; - rawSpaceBefore: string; - rawSpaceAfter: string; - remove(): Node; - replaceWith(...nodes: Node[]): Node; - next(): Node; - prev(): Node; - clone(opts: {[override: string]:any}): Node; - /** - * Return whether this node includes the character at the position of the given line and column. - * Returns undefined if the nodes lack sufficient source metadata to determine the position. - * @param line 1-index based line number relative to the start of the selector. - * @param column 1-index based column number relative to the start of the selector. - */ - isAtPosition(line: number, column: number): boolean | undefined; - /** - * Some non-standard syntax doesn't follow normal escaping rules for css, - * this allows the escaped value to be specified directly, allowing illegal characters to be - * directly inserted into css output. - * @param name the property to set - * @param value the unescaped value of the property - * @param valueEscaped optional. the escaped value of the property. - */ - setPropertyAndEscape(name: string, value: any, valueEscaped: string): void; - /** - * When you want a value to passed through to CSS directly. This method - * deletes the corresponding raw value causing the stringifier to fallback - * to the unescaped value. - * @param name the property to set. - * @param value The value that is both escaped and unescaped. - */ - setPropertyWithoutEscape(name: string, value: any): void; - /** - * Some non-standard syntax doesn't follow normal escaping rules for css. - * This allows non standard syntax to be appended to an existing property - * by specifying the escaped value. By specifying the escaped value, - * illegal characters are allowed to be directly inserted into css output. - * @param {string} name the property to set - * @param {any} value the unescaped value of the property - * @param {string} valueEscaped optional. the escaped value of the property. - */ - appendToPropertyAndEscape(name: string, value: any, valueEscaped: string): void; - toString(): string; - } - interface ContainerOptions extends NodeOptions { - nodes?: Array<Node>; - } - interface Container< - Value extends string | undefined = string, - Child extends Node = Node - > extends Base<Value> { - nodes: Array<Child>; - append(selector: Selector): this; - prepend(selector: Selector): this; - at(index: number): Child; - /** - * Return the most specific node at the line and column number given. - * The source location is based on the original parsed location, locations aren't - * updated as selector nodes are mutated. - * - * Note that this location is relative to the location of the first character - * of the selector, and not the location of the selector in the overall document - * when used in conjunction with postcss. - * - * If not found, returns undefined. - * @param line The line number of the node to find. (1-based index) - * @param col The column number of the node to find. (1-based index) - */ - atPosition(line: number, column: number): Child; - index(child: Child): number; - readonly first: Child; - readonly last: Child; - readonly length: number; - removeChild(child: Child): this; - removeAll(): Container; - empty(): Container; - insertAfter(oldNode: Child, newNode: Child): this; - insertBefore(oldNode: Child, newNode: Child): this; - each(callback: (node: Child) => boolean | void): boolean | undefined; - walk( - callback: (node: Node) => boolean | void - ): boolean | undefined; - walkAttributes( - callback: (node: Attribute) => boolean | void - ): boolean | undefined; - walkClasses( - callback: (node: ClassName) => boolean | void - ): boolean | undefined; - walkCombinators( - callback: (node: Combinator) => boolean | void - ): boolean | undefined; - walkComments( - callback: (node: Comment) => boolean | void - ): boolean | undefined; - walkIds( - callback: (node: Identifier) => boolean | void - ): boolean | undefined; - walkNesting( - callback: (node: Nesting) => boolean | void - ): boolean | undefined; - walkPseudos( - callback: (node: Pseudo) => boolean | void - ): boolean | undefined; - walkTags(callback: (node: Tag) => boolean | void): boolean | undefined; - split(callback: (node: Child) => boolean): [Child[], Child[]]; - map<T>(callback: (node: Child) => T): T[]; - reduce( - callback: ( - previousValue: Child, - currentValue: Child, - currentIndex: number, - array: readonly Child[] - ) => Child - ): Child; - reduce( - callback: ( - previousValue: Child, - currentValue: Child, - currentIndex: number, - array: readonly Child[] - ) => Child, - initialValue: Child - ): Child; - reduce<T>( - callback: ( - previousValue: T, - currentValue: Child, - currentIndex: number, - array: readonly Child[] - ) => T, - initialValue: T - ): T; - every(callback: (node: Child) => boolean): boolean; - some(callback: (node: Child) => boolean): boolean; - filter(callback: (node: Child) => boolean): Child[]; - sort(callback: (nodeA: Child, nodeB: Child) => number): Child[]; - toString(): string; - } - function isContainer(node: any): node is Root | Selector | Pseudo; - - interface NamespaceOptions<Value extends string | undefined = string> extends NodeOptions<Value> { - namespace?: string | true; - } - interface Namespace<Value extends string | undefined = string> extends Base<Value> { - /** alias for namespace */ - ns: string | true; - /** - * namespace prefix. - */ - namespace: string | true; - /** - * If a namespace exists, prefix the value provided with it, separated by |. - */ - qualifiedName(value: string): string; - /** - * A string representing the namespace suitable for output. - */ - readonly namespaceString: string; - } - function isNamespace(node: any): node is Attribute | Tag; - - interface Root extends Container<undefined, Selector> { - type: "root"; - /** - * Raises an error, if the processor is invoked on - * a postcss Rule node, a better error message is raised. - */ - error(message: string, options?: ErrorOptions): Error; - nodeAt(line: number, column: number): Node - } - function root(opts: ContainerOptions): Root; - function isRoot(node: any): node is Root; - - interface _Selector<S> extends Container<string, Diff<Node, S>> { - type: "selector"; - } - type Selector = _Selector<Selector>; - function selector(opts: ContainerOptions): Selector; - function isSelector(node: any): node is Selector; - - interface CombinatorRaws { - value?: string; - spaces?: { - before?: string; - after?: string; - }; - } - interface Combinator extends Base { - type: "combinator"; - raws?: CombinatorRaws; - } - function combinator(opts: NodeOptions): Combinator; - function isCombinator(node: any): node is Combinator; - - interface ClassName extends Base { - type: "class"; - } - function className(opts: NamespaceOptions): ClassName; - function isClassName(node: any): node is ClassName; - - type AttributeOperator = "=" | "~=" | "|=" | "^=" | "$=" | "*="; - type QuoteMark = '"' | "'" | null; - interface PreferredQuoteMarkOptions { - quoteMark?: QuoteMark; - preferCurrentQuoteMark?: boolean; - } - interface SmartQuoteMarkOptions extends PreferredQuoteMarkOptions { - smart?: boolean; - } - interface AttributeOptions extends NamespaceOptions<string | undefined> { - attribute: string; - operator?: AttributeOperator; - insensitive?: boolean; - quoteMark?: QuoteMark; - /** @deprecated Use quoteMark instead. */ - quoted?: boolean; - spaces?: { - before?: string; - after?: string; - attribute?: Partial<SpaceAround>; - operator?: Partial<SpaceAround>; - value?: Partial<SpaceAround>; - insensitive?: Partial<SpaceAround>; - } - raws: { - unquoted?: string; - attribute?: string; - operator?: string; - value?: string; - insensitive?: string; - spaces?: { - attribute?: Partial<Spaces>; - operator?: Partial<Spaces>; - value?: Partial<Spaces>; - insensitive?: Partial<Spaces>; - } - }; - } - interface Attribute extends Namespace<string | undefined> { - type: "attribute"; - attribute: string; - operator?: AttributeOperator; - insensitive?: boolean; - quoteMark: QuoteMark; - quoted?: boolean; - spaces: { - before: string; - after: string; - attribute?: Partial<Spaces>; - operator?: Partial<Spaces>; - value?: Partial<Spaces>; - insensitive?: Partial<Spaces>; - } - raws: { - /** @deprecated The attribute value is unquoted, use that instead.. */ - unquoted?: string; - attribute?: string; - operator?: string; - /** The value of the attribute with quotes and escapes. */ - value?: string; - insensitive?: string; - spaces?: { - attribute?: Partial<Spaces>; - operator?: Partial<Spaces>; - value?: Partial<Spaces>; - insensitive?: Partial<Spaces>; - } - }; - /** - * The attribute name after having been qualified with a namespace. - */ - readonly qualifiedAttribute: string; - - /** - * The case insensitivity flag or an empty string depending on whether this - * attribute is case insensitive. - */ - readonly insensitiveFlag : 'i' | ''; - - /** - * Returns the attribute's value quoted such that it would be legal to use - * in the value of a css file. The original value's quotation setting - * used for stringification is left unchanged. See `setValue(value, options)` - * if you want to control the quote settings of a new value for the attribute or - * `set quoteMark(mark)` if you want to change the quote settings of the current - * value. - * - * You can also change the quotation used for the current value by setting quoteMark. - **/ - getQuotedValue(options?: SmartQuoteMarkOptions): string; - - /** - * Set the unescaped value with the specified quotation options. The value - * provided must not include any wrapping quote marks -- those quotes will - * be interpreted as part of the value and escaped accordingly. - * @param value - */ - setValue(value: string, options?: SmartQuoteMarkOptions): void; - - /** - * Intelligently select a quoteMark value based on the value's contents. If - * the value is a legal CSS ident, it will not be quoted. Otherwise a quote - * mark will be picked that minimizes the number of escapes. - * - * If there's no clear winner, the quote mark from these options is used, - * then the source quote mark (this is inverted if `preferCurrentQuoteMark` is - * true). If the quoteMark is unspecified, a double quote is used. - **/ - smartQuoteMark(options: PreferredQuoteMarkOptions): QuoteMark; - - /** - * Selects the preferred quote mark based on the options and the current quote mark value. - * If you want the quote mark to depend on the attribute value, call `smartQuoteMark(opts)` - * instead. - */ - preferredQuoteMark(options: PreferredQuoteMarkOptions): QuoteMark - - /** - * returns the offset of the attribute part specified relative to the - * start of the node of the output string. - * - * * "ns" - alias for "namespace" - * * "namespace" - the namespace if it exists. - * * "attribute" - the attribute name - * * "attributeNS" - the start of the attribute or its namespace - * * "operator" - the match operator of the attribute - * * "value" - The value (string or identifier) - * * "insensitive" - the case insensitivity flag; - * @param part One of the possible values inside an attribute. - * @returns -1 if the name is invalid or the value doesn't exist in this attribute. - */ - offsetOf(part: "ns" | "namespace" | "attribute" | "attributeNS" | "operator" | "value" | "insensitive"): number; - } - function attribute(opts: AttributeOptions): Attribute; - function isAttribute(node: any): node is Attribute; - - interface Pseudo extends Container<string, Selector> { - type: "pseudo"; - } - function pseudo(opts: ContainerOptions): Pseudo; - /** - * Checks wether the node is the Psuedo subtype of node. - */ - function isPseudo(node: any): node is Pseudo; - - /** - * Checks wether the node is, specifically, a pseudo element instead of - * pseudo class. - */ - function isPseudoElement(node: any): node is Pseudo; - - /** - * Checks wether the node is, specifically, a pseudo class instead of - * pseudo element. - */ - function isPseudoClass(node: any): node is Pseudo; - - - interface Tag extends Namespace { - type: "tag"; - } - function tag(opts: NamespaceOptions): Tag; - function isTag(node: any): node is Tag; - - interface Comment extends Base { - type: "comment"; - } - function comment(opts: NodeOptions): Comment; - function isComment(node: any): node is Comment; - - interface Identifier extends Base { - type: "id"; - } - function id(opts: any): any; - function isIdentifier(node: any): node is Identifier; - - interface Nesting extends Base { - type: "nesting"; - } - function nesting(opts: any): any; - function isNesting(node: any): node is Nesting; - - interface String extends Base { - type: "string"; - } - function string(opts: NodeOptions): String; - function isString(node: any): node is String; - - interface Universal extends Base { - type: "universal"; - } - function universal(opts?: NamespaceOptions): any; - function isUniversal(node: any): node is Universal; -} diff --git a/node_modules/proc-log/lib/index.js b/node_modules/proc-log/lib/index.js index 7c5dfad3b7ba3..94515ad9139c6 100644 --- a/node_modules/proc-log/lib/index.js +++ b/node_modules/proc-log/lib/index.js @@ -1,23 +1,158 @@ -// 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 (...args) { + // Support callback for backwards compatibility and pass additional args to event + let fn + if (typeof args[0] === 'function') { + fn = args.shift() + } + process.emit('input', 'start', ...args) + function end () { + return process.emit('input', 'end', ...args) + } + if (typeof fn === 'function') { + const res = fn() + if (res && res.finally) { + return res.finally(end) + } + end() + return res + } + return end + }, + end: function (...args) { + return process.emit('input', 'end', ...args) + }, + 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/node_modules/proc-log/package.json b/node_modules/proc-log/package.json index ca2f1c771d8e9..556697d71ed7e 100644 --- a/node_modules/proc-log/package.json +++ b/node_modules/proc-log/package.json @@ -1,6 +1,6 @@ { "name": "proc-log", - "version": "2.0.1", + "version": "6.1.0", "files": [ "bin/", "lib/" @@ -9,7 +9,7 @@ "description": "just emit 'log' events on the process object", "repository": { "type": "git", - "url": "https://github.com/npm/proc-log.git" + "url": "git+https://github.com/npm/proc-log.git" }, "author": "GitHub Inc.", "license": "ISC", @@ -18,24 +18,29 @@ "snap": "tap", "posttest": "npm run lint", "postsnap": "eslint index.js test/*.js --fix", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "template-oss-apply": "template-oss-apply --force" + "lintfix": "npm run eslint -- --fix", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.0", + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.1", "tap": "^16.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.0" + "version": "4.28.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/proggy/LICENSE b/node_modules/proggy/LICENSE new file mode 100644 index 0000000000000..83837797202b7 --- /dev/null +++ b/node_modules/proggy/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +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 +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/proggy/lib/client.js b/node_modules/proggy/lib/client.js new file mode 100644 index 0000000000000..2eafb9c75addc --- /dev/null +++ b/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/node_modules/proggy/lib/index.js b/node_modules/proggy/lib/index.js new file mode 100644 index 0000000000000..834948b4ff860 --- /dev/null +++ b/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/node_modules/proggy/lib/tracker.js b/node_modules/proggy/lib/tracker.js new file mode 100644 index 0000000000000..56c78d9434dc7 --- /dev/null +++ b/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/node_modules/proggy/package.json b/node_modules/proggy/package.json new file mode 100644 index 0000000000000..351e53c4fc1c5 --- /dev/null +++ b/node_modules/proggy/package.json @@ -0,0 +1,50 @@ +{ + "name": "proggy", + "version": "4.0.0", + "files": [ + "bin/", + "lib/" + ], + "main": "lib/index.js", + "description": "Progress bar updates at a distance", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/proggy.git" + }, + "author": "GitHub Inc.", + "license": "ISC", + "scripts": { + "test": "tap", + "posttest": "npm run lint", + "snap": "tap", + "postsnap": "eslint lib test --fix", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "lintfix": "npm run eslint -- --fix", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "devDependencies": { + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "chalk": "^4.1.2", + "cli-progress": "^3.10.0", + "npmlog": "^7.0.0", + "tap": "^16.0.1" + }, + "tap": { + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + } +} diff --git a/node_modules/promise-all-reject-late/package-lock.json b/node_modules/promise-all-reject-late/package-lock.json deleted file mode 100644 index 4d485cd40bc4c..0000000000000 --- a/node_modules/promise-all-reject-late/package-lock.json +++ /dev/null @@ -1,3447 +0,0 @@ -{ - "name": "promise-all-reject-late", - "version": "1.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/generator": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz", - "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz", - "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==", - "dev": true - }, - "@babel/runtime": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz", - "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "arg": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", - "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "async-hook-domain": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-1.1.3.tgz", - "integrity": "sha512-ZovMxSbADV3+biB7oR1GL5lGyptI24alp0LWHlmz1OFc5oL47pz3EiIF6nXOkDW7yLqih4NtsiYduzdDW0i+Wg==", - "dev": true, - "requires": { - "source-map-support": "^0.5.11" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", - "dev": true - }, - "bind-obj-methods": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" - }, - "dependencies": { - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" - } - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "coveralls": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.9.tgz", - "integrity": "sha512-nNBg3B1+4iDox5A5zqHKzUTiwl2ey4k2o0NEcVZYvl+GOSJdKBj4AJGKLv6h3SvWch7tABHePAQOSZWM9E2hMg==", - "dev": true, - "requires": { - "js-yaml": "^3.13.1", - "lcov-parse": "^1.0.0", - "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.88.0" - } - }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - }, - "diff-frag": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/diff-frag/-/diff-frag-1.0.1.tgz", - "integrity": "sha512-6/v2PC/6UTGcWPPetb9acL8foberUg/CtPdALeJUdD1B/weHNvzftoo00gYznqHGRhHEbykUGzqfG9RWOSr5yw==", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events-to-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "findit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", - "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", - "dev": true - }, - "flow-parser": { - "version": "0.114.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.114.0.tgz", - "integrity": "sha512-Qt9HT3v507bCerJfp4FX4N5E7ysinBzxjpK1rL7bJ/Bw12puF6lva2MAIXYS1d83bV7BT/F7EDk+faJQY5MpRA==", - "dev": true - }, - "flow-remove-types": { - "version": "2.114.0", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.114.0.tgz", - "integrity": "sha512-ckon8RO7tFcVGW3Ll0jAWgULVrNa/cEN0JXp2I7XmzWT/GCQghSb+0312NjtAb+y3W9iXpPxkVMI86+SDU0E0Q==", - "dev": true, - "requires": { - "flow-parser": "^0.114.0", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - } - }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-exists-cached": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", - "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, - "optional": true - }, - "function-loop": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz", - "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, - "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-processinfo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-1.0.0.tgz", - "integrity": "sha512-FY0cPmWa4WoQNlvB8VOcafiRoB5nB+l2Pz2xGuXHRSy1KM8QFOYfz/rN+bGMCAeejrY3mrpF5oJHcN0s/garCg==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^6.0.5", - "istanbul-lib-coverage": "^2.0.3", - "rimraf": "^2.6.3", - "uuid": "^3.3.2" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", - "dev": true, - "requires": { - "handlebars": "^4.1.2" - } - }, - "jackspeak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", - "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", - "dev": true, - "requires": { - "cliui": "^4.1.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", - "dev": true - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "dev": true, - "requires": { - "mime-db": "1.42.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", - "dev": true - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "own-or": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", - "dev": true - }, - "own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", - "dev": true, - "requires": { - "own-or": "^1.0.0" - } - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "dev": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "react": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", - "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - } - } - }, - "readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.7" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", - "integrity": "sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - } - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tap": { - "version": "14.10.5", - "resolved": "https://registry.npmjs.org/tap/-/tap-14.10.5.tgz", - "integrity": "sha512-8I8zMFEVu7e7RVcjK1GUNf1vW+6B9TRCZWGgif5siMBfvwTE9/EPN/7aH6W2r+WR2H2YHXcrCJ3XhRitYEVKfQ==", - "dev": true, - "requires": { - "@types/react": "^16.9.16", - "async-hook-domain": "^1.1.3", - "bind-obj-methods": "^2.0.0", - "browser-process-hrtime": "^1.0.0", - "chokidar": "^3.3.0", - "color-support": "^1.1.0", - "coveralls": "^3.0.8", - "diff": "^4.0.1", - "esm": "^3.2.25", - "findit": "^2.0.0", - "flow-remove-types": "^2.112.0", - "foreground-child": "^1.3.3", - "fs-exists-cached": "^1.0.0", - "function-loop": "^1.0.2", - "glob": "^7.1.6", - "import-jsx": "^3.0.0", - "ink": "^2.5.0", - "isexe": "^2.0.0", - "istanbul-lib-processinfo": "^1.0.0", - "jackspeak": "^1.4.0", - "minipass": "^3.1.1", - "mkdirp": "^0.5.1", - "nyc": "^14.1.1", - "opener": "^1.5.1", - "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "react": "^16.12.0", - "rimraf": "^2.7.1", - "signal-exit": "^3.0.0", - "source-map-support": "^0.5.16", - "stack-utils": "^1.0.2", - "tap-mocha-reporter": "^5.0.0", - "tap-parser": "^10.0.1", - "tap-yaml": "^1.0.0", - "tcompare": "^3.0.0", - "treport": "^1.0.1", - "trivial-deferred": "^1.0.1", - "ts-node": "^8.5.2", - "typescript": "^3.7.2", - "which": "^2.0.2", - "write-file-atomic": "^3.0.1", - "yaml": "^1.7.2", - "yapool": "^1.0.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "bundled": true, - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/core": { - "version": "7.7.5", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "bundled": true, - "dev": true - } - } - }, - "@babel/helper-builder-react-jsx": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4", - "esutils": "^2.0.0" - } - }, - "@babel/helper-function-name": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.0.0", - "bundled": true, - "dev": true - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.7.4" - } - }, - "@babel/helpers": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.7.5", - "bundled": true, - "dev": true - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.7.4" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.7.4", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.7.4" - } - }, - "@babel/runtime": { - "version": "7.7.6", - "bundled": true, - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, - "@babel/template": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" - } - }, - "@babel/traverse": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.7.4", - "bundled": true, - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "@types/prop-types": { - "version": "15.7.3", - "bundled": true, - "dev": true - }, - "@types/react": { - "version": "16.9.16", - "bundled": true, - "dev": true, - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" - } - }, - "ansi-escapes": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "ansi-regex": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "auto-bind": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "caller-callsite": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cardinal": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, - "chalk": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.0", - "bundled": true, - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - } - } - }, - "ci-info": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-truncate": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "color-convert": { - "version": "1.9.3", - "bundled": true, - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.7.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - } - } - }, - "csstype": { - "version": "2.6.8", - "bundled": true, - "dev": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "bundled": true, - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "esprima": { - "version": "4.0.1", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "events-to-array": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "globals": { - "version": "11.12.0", - "bundled": true, - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "import-jsx": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "@babel/core": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/plugin-transform-destructuring": "^7.5.0", - "@babel/plugin-transform-react-jsx": "^7.3.0", - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "ink": { - "version": "2.6.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "arrify": "^2.0.1", - "auto-bind": "^3.0.0", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-truncate": "^2.0.0", - "is-ci": "^2.0.0", - "lodash.throttle": "^4.1.1", - "log-update": "^3.0.0", - "prop-types": "^15.6.2", - "react-reconciler": "^0.24.0", - "scheduler": "^0.18.0", - "signal-exit": "^3.0.2", - "slice-ansi": "^3.0.0", - "string-length": "^3.1.0", - "widest-line": "^3.1.0", - "wrap-ansi": "^6.2.0", - "yoga-layout-prebuilt": "^1.9.3" - } - }, - "is-ci": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "bundled": true, - "dev": true - }, - "json5": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "lodash": { - "version": "4.17.15", - "bundled": true, - "dev": true - }, - "lodash.throttle": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "log-update": { - "version": "3.3.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "onetime": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "loose-envify": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "onetime": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "path-parse": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "punycode": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "react-is": { - "version": "16.12.0", - "bundled": true, - "dev": true - }, - "react-reconciler": { - "version": "0.24.0", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.18.0" - } - }, - "redeyed": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "esprima": "~4.0.0" - } - }, - "regenerator-runtime": { - "version": "0.13.3", - "bundled": true, - "dev": true - }, - "resolve": { - "version": "1.13.1", - "bundled": true, - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "scheduler": { - "version": "0.18.0", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slice-ansi": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.0", - "bundled": true, - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - } - } - }, - "string-length": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string-width": { - "version": "4.2.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^4.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "tap-parser": { - "version": "10.0.1", - "bundled": true, - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "minipass": "^3.0.0", - "tap-yaml": "^1.0.0" - } - }, - "tap-yaml": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "yaml": "^1.5.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "treport": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "cardinal": "^2.1.1", - "chalk": "^3.0.0", - "import-jsx": "^3.0.0", - "ink": "^2.5.0", - "ms": "^2.1.2", - "string-length": "^3.1.0", - "tap-parser": "^10.0.1", - "unicode-length": "^2.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "unicode-length": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "punycode": "^2.0.0", - "strip-ansi": "^3.0.1" - } - } - } - }, - "type-fest": { - "version": "0.8.1", - "bundled": true, - "dev": true - }, - "widest-line": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.0", - "bundled": true, - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - } - } - }, - "yaml": { - "version": "1.7.2", - "bundled": true, - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } - }, - "yoga-layout-prebuilt": { - "version": "1.9.3", - "bundled": true, - "dev": true - } - } - }, - "tap-mocha-reporter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.0.tgz", - "integrity": "sha512-8HlAtdmYGlDZuW83QbF/dc46L7cN+AGhLZcanX3I9ILvxUAl+G2/mtucNPSXecTlG/4iP1hv6oMo0tMhkn3Tsw==", - "dev": true, - "requires": { - "color-support": "^1.1.0", - "debug": "^2.1.3", - "diff": "^1.3.2", - "escape-string-regexp": "^1.0.3", - "glob": "^7.0.5", - "readable-stream": "^2.1.5", - "tap-parser": "^10.0.0", - "tap-yaml": "^1.0.0", - "unicode-length": "^1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "tap-parser": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", - "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "minipass": "^3.0.0", - "tap-yaml": "^1.0.0" - } - }, - "tap-yaml": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", - "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", - "dev": true, - "requires": { - "yaml": "^1.5.0" - } - }, - "tcompare": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-3.0.4.tgz", - "integrity": "sha512-Q3TitMVK59NyKgQyFh+857wTAUE329IzLDehuPgU4nF5e8g+EUQ+yUbjUy1/6ugiNnXztphT+NnqlCXolv9P3A==", - "dev": true, - "requires": { - "diff-frag": "^1.0.1" - } - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "trivial-deferred": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", - "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", - "dev": true - }, - "ts-node": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz", - "integrity": "sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz", - "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==", - "dev": true - }, - "uglify-js": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.3.tgz", - "integrity": "sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - } - }, - "unicode-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", - "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", - "dev": true, - "requires": { - "punycode": "^1.3.2", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } - }, - "yapool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", - "dev": true - }, - "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/node_modules/promise-call-limit/dist/commonjs/index.js b/node_modules/promise-call-limit/dist/commonjs/index.js new file mode 100644 index 0000000000000..b32a85bb11aa3 --- /dev/null +++ b/node_modules/promise-call-limit/dist/commonjs/index.js @@ -0,0 +1,87 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.callLimit = void 0; +const os = __importStar(require("node:os")); +// availableParallelism available only since node v19, for older versions use +// cpus() cpus() can return an empty list if /proc is not mounted, use 1 in +// this case +/* c8 ignore start */ +const defLimit = 'availableParallelism' in os ? + Math.max(1, os.availableParallelism() - 1) + : Math.max(1, os.cpus().length - 1); +const callLimit = (queue, { limit = defLimit, rejectLate } = {}) => new Promise((res, rej) => { + let active = 0; + let current = 0; + const results = []; + // Whether or not we rejected, distinct from the rejection just in case the rejection itself is falsey + let rejected = false; + let rejection; + const reject = (er) => { + if (rejected) + return; + rejected = true; + rejection ??= er; + if (!rejectLate) + rej(rejection); + }; + let resolved = false; + const resolve = () => { + if (resolved || active > 0) + return; + resolved = true; + res(results); + }; + const run = () => { + const c = current++; + if (c >= queue.length) + return rejected ? reject() : resolve(); + active++; + const step = queue[c]; + /* c8 ignore start */ + if (!step) + throw new Error('walked off queue'); + /* c8 ignore stop */ + results[c] = step() + .then(result => { + active--; + results[c] = result; + return result; + }, er => { + active--; + reject(er); + }) + .then(result => { + if (rejected && active === 0) + return rej(rejection); + run(); + return result; + }); + }; + for (let i = 0; i < limit; i++) + run(); +}); +exports.callLimit = callLimit; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/promise-call-limit/dist/commonjs/package.json b/node_modules/promise-call-limit/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/promise-call-limit/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/promise-call-limit/dist/esm/index.js b/node_modules/promise-call-limit/dist/esm/index.js new file mode 100644 index 0000000000000..fe709db7fc04c --- /dev/null +++ b/node_modules/promise-call-limit/dist/esm/index.js @@ -0,0 +1,60 @@ +import * as os from 'node:os'; +// availableParallelism available only since node v19, for older versions use +// cpus() cpus() can return an empty list if /proc is not mounted, use 1 in +// this case +/* c8 ignore start */ +const defLimit = 'availableParallelism' in os ? + Math.max(1, os.availableParallelism() - 1) + : Math.max(1, os.cpus().length - 1); +export const callLimit = (queue, { limit = defLimit, rejectLate } = {}) => new Promise((res, rej) => { + let active = 0; + let current = 0; + const results = []; + // Whether or not we rejected, distinct from the rejection just in case the rejection itself is falsey + let rejected = false; + let rejection; + const reject = (er) => { + if (rejected) + return; + rejected = true; + rejection ??= er; + if (!rejectLate) + rej(rejection); + }; + let resolved = false; + const resolve = () => { + if (resolved || active > 0) + return; + resolved = true; + res(results); + }; + const run = () => { + const c = current++; + if (c >= queue.length) + return rejected ? reject() : resolve(); + active++; + const step = queue[c]; + /* c8 ignore start */ + if (!step) + throw new Error('walked off queue'); + /* c8 ignore stop */ + results[c] = step() + .then(result => { + active--; + results[c] = result; + return result; + }, er => { + active--; + reject(er); + }) + .then(result => { + if (rejected && active === 0) + return rej(rejection); + run(); + return result; + }); + }; + for (let i = 0; i < limit; i++) + run(); +}); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/promise-call-limit/dist/esm/package.json b/node_modules/promise-call-limit/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/promise-call-limit/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/promise-call-limit/index.js b/node_modules/promise-call-limit/index.js deleted file mode 100644 index a093c2481c451..0000000000000 --- a/node_modules/promise-call-limit/index.js +++ /dev/null @@ -1,43 +0,0 @@ -const defLimit = require('os').cpus().length -const callLimit = (queue, limit = defLimit) => new Promise((res, rej) => { - let active = 0 - let current = 0 - const results = [] - - let rejected = false - const reject = er => { - if (rejected) - return - rejected = true - rej(er) - } - - let resolved = false - const resolve = () => { - if (resolved || active > 0) - return - resolved = true - res(results) - } - - const run = () => { - const c = current++ - if (c >= queue.length) { - return resolve() - } - - active ++ - results[c] = queue[c]().then(result => { - active -- - results[c] = result - run() - return result - }, reject) - } - - for (let i = 0; i < limit; i++) { - run() - } -}) - -module.exports = callLimit diff --git a/node_modules/promise-call-limit/package.json b/node_modules/promise-call-limit/package.json index ae5e4617fbbd9..ab14595366e22 100644 --- a/node_modules/promise-call-limit/package.json +++ b/node_modules/promise-call-limit/package.json @@ -1,8 +1,8 @@ { "name": "promise-call-limit", - "version": "1.0.1", + "version": "3.0.2", "files": [ - "index.js" + "dist" ], "description": "Call an array of promise-returning functions, restricting concurrency to a specified limit.", "repository": { @@ -12,18 +12,57 @@ "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", "license": "ISC", "scripts": { + "prepare": "tshy", + "pretest": "npm run prepare", + "snap": "tap", "test": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true + "prepublishOnly": "git push origin --follow-tags", + "format": "prettier --write . --log-level warn --cache" }, "devDependencies": { - "tap": "^14.10.6" + "prettier": "^3.3.3", + "tap": "^21.0.1", + "tshy": "^3.0.2", + "typedoc": "^0.26.6" + }, + "prettier": { + "experimentalTernaries": true, + "semi": false, + "printWidth": 70, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" }, "funding": { "url": "https://github.com/sponsors/isaacs" - } + }, + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "type": "module", + "module": "./dist/esm/index.js" } diff --git a/node_modules/promise-inflight/LICENSE b/node_modules/promise-inflight/LICENSE deleted file mode 100644 index 83e7c4c62903d..0000000000000 --- a/node_modules/promise-inflight/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2017, Rebecca Turner <me@re-becca.org> - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/node_modules/promise-inflight/inflight.js b/node_modules/promise-inflight/inflight.js deleted file mode 100644 index ce054d34be859..0000000000000 --- a/node_modules/promise-inflight/inflight.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict' -module.exports = inflight - -let Bluebird -try { - Bluebird = require('bluebird') -} catch (_) { - Bluebird = Promise -} - -const active = {} -inflight.active = active -function inflight (unique, doFly) { - return Bluebird.all([unique, doFly]).then(function (args) { - const unique = args[0] - const doFly = args[1] - if (Array.isArray(unique)) { - return Bluebird.all(unique).then(function (uniqueArr) { - return _inflight(uniqueArr.join(''), doFly) - }) - } else { - return _inflight(unique, doFly) - } - }) - - function _inflight (unique, doFly) { - if (!active[unique]) { - active[unique] = (new Bluebird(function (resolve) { - return resolve(doFly()) - })) - active[unique].then(cleanup, cleanup) - function cleanup() { delete active[unique] } - } - return active[unique] - } -} diff --git a/node_modules/promise-inflight/package.json b/node_modules/promise-inflight/package.json deleted file mode 100644 index 0d8930c5b6d49..0000000000000 --- a/node_modules/promise-inflight/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "promise-inflight", - "version": "1.0.1", - "description": "One promise for multiple requests in flight to avoid async duplication", - "main": "inflight.js", - "files": [ - "inflight.js" - ], - "license": "ISC", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "Rebecca Turner <me@re-becca.org> (http://re-becca.org/)", - "devDependencies": {}, - "repository": { - "type": "git", - "url": "git+https://github.com/iarna/promise-inflight.git" - }, - "bugs": { - "url": "https://github.com/iarna/promise-inflight/issues" - }, - "homepage": "https://github.com/iarna/promise-inflight#readme" -} diff --git a/node_modules/promzard/example/buffer.js b/node_modules/promzard/example/buffer.js deleted file mode 100644 index 828f9d1df9da2..0000000000000 --- a/node_modules/promzard/example/buffer.js +++ /dev/null @@ -1,12 +0,0 @@ -var pz = require('../promzard') - -var path = require('path') -var file = path.resolve(__dirname, 'substack-input.js') -var buf = require('fs').readFileSync(file) -var ctx = { basename: path.basename(path.dirname(file)) } - -pz.fromBuffer(buf, ctx, function (er, res) { - if (er) - throw er - console.error(JSON.stringify(res, null, 2)) -}) diff --git a/node_modules/promzard/example/index.js b/node_modules/promzard/example/index.js deleted file mode 100644 index 435131f3a6d1e..0000000000000 --- a/node_modules/promzard/example/index.js +++ /dev/null @@ -1,11 +0,0 @@ -var pz = require('../promzard') - -var path = require('path') -var file = path.resolve(__dirname, 'substack-input.js') -var ctx = { basename: path.basename(path.dirname(file)) } - -pz(file, ctx, function (er, res) { - if (er) - throw er - console.error(JSON.stringify(res, null, 2)) -}) diff --git a/node_modules/promzard/example/npm-init/init-input.js b/node_modules/promzard/example/npm-init/init-input.js deleted file mode 100644 index ba7781b3539e4..0000000000000 --- a/node_modules/promzard/example/npm-init/init-input.js +++ /dev/null @@ -1,191 +0,0 @@ -var fs = require('fs') -var path = require('path'); - -module.exports = { - "name" : prompt('name', - typeof name === 'undefined' - ? basename.replace(/^node-|[.-]js$/g, ''): name), - "version" : prompt('version', typeof version !== "undefined" - ? version : '0.0.0'), - "description" : (function () { - if (typeof description !== 'undefined' && description) { - return description - } - var value; - try { - var src = fs.readFileSync('README.md', 'utf8'); - value = src.split('\n').filter(function (line) { - return /\s+/.test(line) - && line.trim() !== basename.replace(/^node-/, '') - && !line.trim().match(/^#/) - ; - })[0] - .trim() - .replace(/^./, function (c) { return c.toLowerCase() }) - .replace(/\.$/, '') - ; - } - catch (e) { - try { - // Wouldn't it be nice if that file mattered? - var d = fs.readFileSync('.git/description', 'utf8') - } catch (e) {} - if (d.trim() && !value) value = d - } - return prompt('description', value); - })(), - "main" : (function () { - var f - try { - f = fs.readdirSync(dirname).filter(function (f) { - return f.match(/\.js$/) - }) - if (f.indexOf('index.js') !== -1) - f = 'index.js' - else if (f.indexOf('main.js') !== -1) - f = 'main.js' - else if (f.indexOf(basename + '.js') !== -1) - f = basename + '.js' - else - f = f[0] - } catch (e) {} - - return prompt('entry point', f || 'index.js') - })(), - "bin" : function (cb) { - fs.readdir(dirname + '/bin', function (er, d) { - // no bins - if (er) return cb() - // just take the first js file we find there, or nada - return cb(null, d.filter(function (f) { - return f.match(/\.js$/) - })[0]) - }) - }, - "directories" : function (cb) { - fs.readdir('.', function (er, dirs) { - if (er) return cb(er) - var res = {} - dirs.forEach(function (d) { - switch (d) { - case 'example': case 'examples': return res.example = d - case 'test': case 'tests': return res.test = d - case 'doc': case 'docs': return res.doc = d - case 'man': return res.man = d - } - }) - if (Object.keys(res).length === 0) res = undefined - return cb(null, res) - }) - }, - "dependencies" : typeof dependencies !== 'undefined' ? dependencies - : function (cb) { - fs.readdir('node_modules', function (er, dir) { - if (er) return cb() - var deps = {} - var n = dir.length - dir.forEach(function (d) { - if (d.match(/^\./)) return next() - if (d.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/)) - return next() - fs.readFile('node_modules/' + d + '/package.json', function (er, p) { - if (er) return next() - try { p = JSON.parse(p) } catch (e) { return next() } - if (!p.version) return next() - deps[d] = '~' + p.version - return next() - }) - }) - function next () { - if (--n === 0) return cb(null, deps) - } - }) - }, - "devDependencies" : typeof devDependencies !== 'undefined' ? devDependencies - : function (cb) { - // same as dependencies but for dev deps - fs.readdir('node_modules', function (er, dir) { - if (er) return cb() - var deps = {} - var n = dir.length - dir.forEach(function (d) { - if (d.match(/^\./)) return next() - if (!d.match(/^(expresso|mocha|tap|coffee-script|coco|streamline)$/)) - return next() - fs.readFile('node_modules/' + d + '/package.json', function (er, p) { - if (er) return next() - try { p = JSON.parse(p) } catch (e) { return next() } - if (!p.version) return next() - deps[d] = '~' + p.version - return next() - }) - }) - function next () { - if (--n === 0) return cb(null, deps) - } - }) - }, - "scripts" : (function () { - // check to see what framework is in use, if any - try { var d = fs.readdirSync('node_modules') } - catch (e) { d = [] } - var s = typeof scripts === 'undefined' ? {} : scripts - - if (d.indexOf('coffee-script') !== -1) - s.prepublish = prompt('build command', - s.prepublish || 'coffee src/*.coffee -o lib') - - var notest = 'echo "Error: no test specified" && exit 1' - function tx (test) { - return test || notest - } - - if (!s.test || s.test === notest) { - if (d.indexOf('tap') !== -1) - s.test = prompt('test command', 'tap test/*.js', tx) - else if (d.indexOf('expresso') !== -1) - s.test = prompt('test command', 'expresso test', tx) - else if (d.indexOf('mocha') !== -1) - s.test = prompt('test command', 'mocha', tx) - else - s.test = prompt('test command', tx) - } - - return s - - })(), - - "repository" : (function () { - try { var gconf = fs.readFileSync('.git/config') } - catch (e) { gconf = null } - if (gconf) { - gconf = gconf.split(/\r?\n/) - var i = gconf.indexOf('[remote "origin"]') - if (i !== -1) { - var u = gconf[i + 1] - if (!u.match(/^\s*url =/)) u = gconf[i + 2] - if (!u.match(/^\s*url =/)) u = null - else u = u.replace(/^\s*url = /, '') - } - if (u && u.match(/^git@github.com:/)) - u = u.replace(/^git@github.com:/, 'git://github.com/') - } - - return prompt('git repository', u) - })(), - - "keywords" : prompt(function (s) { - if (!s) return undefined - if (Array.isArray(s)) s = s.join(' ') - if (typeof s !== 'string') return s - return s.split(/[\s,]+/) - }), - "author" : config['init.author.name'] - ? { - "name" : config['init.author.name'], - "email" : config['init.author.email'], - "url" : config['init.author.url'] - } - : undefined, - "license" : prompt('license', 'BSD') -} diff --git a/node_modules/promzard/example/npm-init/init.js b/node_modules/promzard/example/npm-init/init.js deleted file mode 100644 index 09484cd1c1991..0000000000000 --- a/node_modules/promzard/example/npm-init/init.js +++ /dev/null @@ -1,37 +0,0 @@ -var PZ = require('../../promzard').PromZard -var path = require('path') -var input = path.resolve(__dirname, 'init-input.js') - -var fs = require('fs') -var package = path.resolve(__dirname, 'package.json') -var pkg - -fs.readFile(package, 'utf8', function (er, d) { - if (er) ctx = {} - try { ctx = JSON.parse(d); pkg = JSON.parse(d) } - catch (e) { ctx = {} } - - ctx.dirname = path.dirname(package) - ctx.basename = path.basename(ctx.dirname) - if (!ctx.version) ctx.version = undefined - - // this should be replaced with the npm conf object - ctx.config = {} - - console.error('ctx=', ctx) - - var pz = new PZ(input, ctx) - - pz.on('data', function (data) { - console.error('pz data', data) - if (!pkg) pkg = {} - Object.keys(data).forEach(function (k) { - if (data[k] !== undefined && data[k] !== null) pkg[k] = data[k] - }) - console.error('package data %s', JSON.stringify(data, null, 2)) - fs.writeFile(package, JSON.stringify(pkg, null, 2), function (er) { - if (er) throw er - console.log('ok') - }) - }) -}) diff --git a/node_modules/promzard/example/npm-init/package.json b/node_modules/promzard/example/npm-init/package.json deleted file mode 100644 index 89c6d1fb6e2ac..0000000000000 --- a/node_modules/promzard/example/npm-init/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "npm-init", - "version": "0.0.0", - "description": "an initter you init wit, innit?", - "main": "index.js", - "scripts": { - "test": "asdf" - }, - "license": "BSD" -} \ No newline at end of file diff --git a/node_modules/promzard/example/substack-input.js b/node_modules/promzard/example/substack-input.js deleted file mode 100644 index bf7aedb82d41f..0000000000000 --- a/node_modules/promzard/example/substack-input.js +++ /dev/null @@ -1,61 +0,0 @@ -module.exports = { - "name" : basename.replace(/^node-/, ''), - "version" : "0.0.0", - "description" : (function (cb) { - var fs = require('fs'); - var value; - try { - var src = fs.readFileSync('README.markdown', 'utf8'); - value = src.split('\n').filter(function (line) { - return /\s+/.test(line) - && line.trim() !== basename.replace(/^node-/, '') - ; - })[0] - .trim() - .replace(/^./, function (c) { return c.toLowerCase() }) - .replace(/\.$/, '') - ; - } - catch (e) {} - - return prompt('description', value); - })(), - "main" : prompt('entry point', 'index.js'), - "bin" : function (cb) { - var path = require('path'); - var fs = require('fs'); - var exists = fs.exists || path.exists; - exists('bin/cmd.js', function (ex) { - var bin - if (ex) { - var bin = {} - bin[basename.replace(/^node-/, '')] = 'bin/cmd.js' - } - cb(null, bin); - }); - }, - "directories" : { - "example" : "example", - "test" : "test" - }, - "dependencies" : {}, - "devDependencies" : { - "tap" : "~0.2.5" - }, - "scripts" : { - "test" : "tap test/*.js" - }, - "repository" : { - "type" : "git", - "url" : "git://github.com/substack/" + basename + ".git" - }, - "homepage" : "https://github.com/substack/" + basename, - "keywords" : prompt(function (s) { return s.split(/\s+/) }), - "author" : { - "name" : "James Halliday", - "email" : "mail@substack.net", - "url" : "http://substack.net" - }, - "license" : "MIT", - "engine" : { "node" : ">=0.6" } -} diff --git a/node_modules/promzard/lib/index.js b/node_modules/promzard/lib/index.js new file mode 100644 index 0000000000000..130bb4e3aa9e5 --- /dev/null +++ b/node_modules/promzard/lib/index.js @@ -0,0 +1,176 @@ +const fs = require('fs/promises') +const { runInThisContext } = require('vm') +const { promisify } = require('util') +const { randomBytes } = require('crypto') +const { Module } = require('module') +const { dirname, basename } = require('path') +const { read } = require('read') + +const files = {} + +class PromZard { + #file = null + #backupFile = null + #ctx = null + #unique = randomBytes(8).toString('hex') + #prompts = [] + + constructor (file, ctx = {}, options = {}) { + this.#file = file + this.#ctx = ctx + this.#backupFile = options.backupFile + } + + static async promzard (file, ctx, options) { + const pz = new PromZard(file, ctx, options) + return pz.load() + } + + static async fromBuffer (buf, ctx, options) { + let filename = 0 + do { + filename = '\0' + Math.random() + } while (files[filename]) + files[filename] = buf + const ret = await PromZard.promzard(filename, ctx, options) + delete files[filename] + return ret + } + + async load () { + if (files[this.#file]) { + return this.#loaded() + } + + try { + files[this.#file] = await fs.readFile(this.#file, 'utf8') + } catch (er) { + if (er && this.#backupFile) { + this.#file = this.#backupFile + this.#backupFile = null + return this.load() + } + throw er + } + + return this.#loaded() + } + + async #loaded () { + const mod = new Module(this.#file, module) + mod.loaded = true + mod.filename = this.#file + mod.id = this.#file + mod.paths = Module._nodeModulePaths(dirname(this.#file)) + + this.#ctx.prompt = this.#makePrompt() + this.#ctx.__filename = this.#file + this.#ctx.__dirname = dirname(this.#file) + this.#ctx.__basename = basename(this.#file) + this.#ctx.module = mod + this.#ctx.require = (p) => mod.require(p) + this.#ctx.require.resolve = (p) => Module._resolveFilename(p, mod) + this.#ctx.exports = mod.exports + + const body = `(function(${Object.keys(this.#ctx).join(', ')}) { ${files[this.#file]}\n })` + runInThisContext(body, this.#file).apply(this.#ctx, Object.values(this.#ctx)) + this.#ctx.res = mod.exports + + return this.#walk() + } + + #makePrompt () { + return (...args) => { + let p, d, t + for (let i = 0; i < args.length; i++) { + const a = args[i] + if (typeof a === 'string') { + if (p) { + d = a + } else { + p = a + } + } else if (typeof a === 'function') { + t = a + } else if (a && typeof a === 'object') { + p = a.prompt || p + d = a.default || d + t = a.transform || t + } + } + try { + return `${this.#unique}-${this.#prompts.length}` + } finally { + this.#prompts.push([p, d, t]) + } + } + } + + async #walk (o = this.#ctx.res) { + const keys = Object.keys(o) + + const len = keys.length + let i = 0 + + while (i < len) { + const k = keys[i] + const v = o[k] + i++ + + if (v && typeof v === 'object') { + o[k] = await this.#walk(v) + continue + } + + if (v && typeof v === 'string' && v.startsWith(this.#unique)) { + const n = +v.slice(this.#unique.length + 1) + + // default to the key + // default to the ctx value, if there is one + const [prompt = k, def = this.#ctx[k], tx] = this.#prompts[n] + + try { + o[k] = await this.#prompt(prompt, def, tx) + } catch (er) { + if (er.notValid) { + // eslint-disable-next-line no-console + console.log(er.message) + i-- + } else { + throw er + } + } + continue + } + + if (typeof v === 'function') { + // XXX: remove v.length check to remove cb from functions + // would be a breaking change for `npm init` + // XXX: if cb is no longer an argument then this.#ctx should + // be passed in to allow arrow fns to be used and still access ctx + const fn = v.length ? promisify(v) : v + o[k] = await fn.call(this.#ctx) + // back up so that we process this one again. + // this is because it might return a prompt() call in the cb. + i-- + continue + } + } + + return o + } + + async #prompt (prompt, def, tx) { + const res = await read({ prompt: prompt + ':', default: def }).then((r) => tx ? tx(r) : r) + // XXX: remove this to require throwing an error instead of + // returning it. would be a breaking change for `npm init` + if (res instanceof Error && res.notValid) { + throw res + } + return res + } +} + +module.exports = PromZard.promzard +module.exports.fromBuffer = PromZard.fromBuffer +module.exports.PromZard = PromZard diff --git a/node_modules/promzard/package.json b/node_modules/promzard/package.json index 77e3bd65513c9..38fec6423f721 100644 --- a/node_modules/promzard/package.json +++ b/node_modules/promzard/package.json @@ -1,20 +1,50 @@ { - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "name": "promzard", "description": "prompting wizardly", - "version": "0.3.0", + "version": "3.0.1", "repository": { - "url": "git://github.com/isaacs/promzard" + "url": "git+https://github.com/npm/promzard.git", + "type": "git" }, "dependencies": { - "read": "1" + "read": "^5.0.0" }, "devDependencies": { - "tap": "~0.2.5" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, - "main": "promzard.js", + "main": "lib/index.js", "scripts": { - "test": "tap test/*.js" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, - "license": "ISC" + "license": "ISC", + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "jobs": 1, + "test-ignore": "fixtures/", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + } } diff --git a/node_modules/promzard/promzard.js b/node_modules/promzard/promzard.js deleted file mode 100644 index da1abca9535e4..0000000000000 --- a/node_modules/promzard/promzard.js +++ /dev/null @@ -1,238 +0,0 @@ -module.exports = promzard -promzard.PromZard = PromZard - -var fs = require('fs') -var vm = require('vm') -var util = require('util') -var files = {} -var crypto = require('crypto') -var EventEmitter = require('events').EventEmitter -var read = require('read') - -var Module = require('module').Module -var path = require('path') - -function promzard (file, ctx, cb) { - if (typeof ctx === 'function') cb = ctx, ctx = null; - if (!ctx) ctx = {}; - var pz = new PromZard(file, ctx) - pz.on('error', cb) - pz.on('data', function (data) { - cb(null, data) - }) -} -promzard.fromBuffer = function (buf, ctx, cb) { - var filename = 0 - do { - filename = '\0' + Math.random(); - } while (files[filename]) - files[filename] = buf - var ret = promzard(filename, ctx, cb) - delete files[filename] - return ret -} - -function PromZard (file, ctx) { - if (!(this instanceof PromZard)) - return new PromZard(file, ctx) - EventEmitter.call(this) - this.file = file - this.ctx = ctx - this.unique = crypto.randomBytes(8).toString('hex') - this.load() -} - -PromZard.prototype = Object.create( - EventEmitter.prototype, - { constructor: { - value: PromZard, - readable: true, - configurable: true, - writable: true, - enumerable: false } } ) - -PromZard.prototype.load = function () { - if (files[this.file]) - return this.loaded() - - fs.readFile(this.file, 'utf8', function (er, d) { - if (er && this.backupFile) { - this.file = this.backupFile - delete this.backupFile - return this.load() - } - if (er) - return this.emit('error', this.error = er) - files[this.file] = d - this.loaded() - }.bind(this)) -} - -PromZard.prototype.loaded = function () { - this.ctx.prompt = this.makePrompt() - this.ctx.__filename = this.file - this.ctx.__dirname = path.dirname(this.file) - this.ctx.__basename = path.basename(this.file) - var mod = this.ctx.module = this.makeModule() - this.ctx.require = function (path) { - return mod.require(path) - } - this.ctx.require.resolve = function(path) { - return Module._resolveFilename(path, mod); - } - this.ctx.exports = mod.exports - - this.script = this.wrap(files[this.file]) - var fn = vm.runInThisContext(this.script, this.file) - var args = Object.keys(this.ctx).map(function (k) { - return this.ctx[k] - }.bind(this)) - try { var res = fn.apply(this.ctx, args) } - catch (er) { this.emit('error', er) } - if (res && - typeof res === 'object' && - exports === mod.exports && - Object.keys(exports).length === 1) { - this.result = res - } else { - this.result = mod.exports - } - this.walk() -} - -PromZard.prototype.makeModule = function () { - var mod = new Module(this.file, module) - mod.loaded = true - mod.filename = this.file - mod.id = this.file - mod.paths = Module._nodeModulePaths(path.dirname(this.file)) - return mod -} - -PromZard.prototype.wrap = function (body) { - var s = '(function( %s ) { %s\n })' - var args = Object.keys(this.ctx).join(', ') - return util.format(s, args, body) -} - -PromZard.prototype.makePrompt = function () { - this.prompts = [] - return prompt.bind(this) - function prompt () { - var p, d, t - for (var i = 0; i < arguments.length; i++) { - var a = arguments[i] - if (typeof a === 'string' && p) - d = a - else if (typeof a === 'string') - p = a - else if (typeof a === 'function') - t = a - else if (a && typeof a === 'object') { - p = a.prompt || p - d = a.default || d - t = a.transform || t - } - } - - try { return this.unique + '-' + this.prompts.length } - finally { this.prompts.push([p, d, t]) } - } -} - -PromZard.prototype.walk = function (o, cb) { - o = o || this.result - cb = cb || function (er, res) { - if (er) - return this.emit('error', this.error = er) - this.result = res - return this.emit('data', res) - } - cb = cb.bind(this) - var keys = Object.keys(o) - var i = 0 - var len = keys.length - - L.call(this) - function L () { - if (this.error) - return - while (i < len) { - var k = keys[i] - var v = o[k] - i++ - - if (v && typeof v === 'object') { - return this.walk(v, function (er, res) { - if (er) return cb(er) - o[k] = res - L.call(this) - }.bind(this)) - } else if (v && - typeof v === 'string' && - v.indexOf(this.unique) === 0) { - var n = +v.substr(this.unique.length + 1) - var prompt = this.prompts[n] - if (isNaN(n) || !prompt) - continue - - // default to the key - if (undefined === prompt[0]) - prompt[0] = k - - // default to the ctx value, if there is one - if (undefined === prompt[1]) - prompt[1] = this.ctx[k] - - return this.prompt(prompt, function (er, res) { - if (er) { - if (!er.notValid) { - return this.emit('error', this.error = er); - } - console.log(er.message) - i -- - return L.call(this) - } - o[k] = res - L.call(this) - }.bind(this)) - } else if (typeof v === 'function') { - try { return v.call(this.ctx, function (er, res) { - if (er) - return this.emit('error', this.error = er) - o[k] = res - // back up so that we process this one again. - // this is because it might return a prompt() call in the cb. - i -- - L.call(this) - }.bind(this)) } - catch (er) { this.emit('error', er) } - } - } - // made it to the end of the loop, maybe - if (i >= len) - return cb(null, o) - } -} - -PromZard.prototype.prompt = function (pdt, cb) { - var prompt = pdt[0] - var def = pdt[1] - var tx = pdt[2] - - if (tx) { - cb = function (cb) { return function (er, data) { - try { - var res = tx(data) - if (!er && res instanceof Error && !!res.notValid) { - return cb(res, null) - } - return cb(er, res) - } - catch (er) { this.emit('error', er) } - }}(cb).bind(this) - } - - read({ prompt: prompt + ':' , default: def }, cb) -} - diff --git a/node_modules/promzard/test/basic.js b/node_modules/promzard/test/basic.js deleted file mode 100644 index ad1c92df9c4c0..0000000000000 --- a/node_modules/promzard/test/basic.js +++ /dev/null @@ -1,91 +0,0 @@ -var tap = require('tap') -var pz = require('../promzard.js') -var spawn = require('child_process').spawn - -tap.test('run the example', function (t) { - - var example = require.resolve('../example/index.js') - var node = process.execPath - - var expect = { - "name": "example", - "version": "0.0.0", - "description": "testing description", - "main": "test-entry.js", - "directories": { - "example": "example", - "test": "test" - }, - "dependencies": {}, - "devDependencies": { - "tap": "~0.2.5" - }, - "scripts": { - "test": "tap test/*.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/substack/example.git" - }, - "homepage": "https://github.com/substack/example", - "keywords": [ - "fugazi", - "function", - "waiting", - "room" - ], - "author": { - "name": "James Halliday", - "email": "mail@substack.net", - "url": "http://substack.net" - }, - "license": "MIT", - "engine": { - "node": ">=0.6" - } - } - - console.error('%s %s', node, example) - var c = spawn(node, [example], { customFds: [-1,-1,-1] }) - var output = '' - c.stdout.on('data', function (d) { - output += d - respond() - }) - - var actual = '' - c.stderr.on('data', function (d) { - actual += d - }) - - function respond () { - console.error('respond', output) - if (output.match(/description: $/)) { - c.stdin.write('testing description\n') - return - } - if (output.match(/entry point: \(index\.js\) $/)) { - c.stdin.write('test-entry.js\n') - return - } - if (output.match(/keywords: $/)) { - c.stdin.write('fugazi function waiting room\n') - // "read" module is weird on node >= 0.10 when not a TTY - // requires explicit ending for reasons. - // could dig in, but really just wanna make tests pass, whatever. - c.stdin.end() - return - } - } - - c.on('exit', function () { - console.error('exit event') - }) - - c.on('close', function () { - console.error('actual', actual) - actual = JSON.parse(actual) - t.deepEqual(actual, expect) - t.end() - }) -}) diff --git a/node_modules/promzard/test/buffer.js b/node_modules/promzard/test/buffer.js deleted file mode 100644 index e1d240e2e4f48..0000000000000 --- a/node_modules/promzard/test/buffer.js +++ /dev/null @@ -1,84 +0,0 @@ -var tap = require('tap') -var pz = require('../promzard.js') -var spawn = require('child_process').spawn - -tap.test('run the example using a buffer', function (t) { - - var example = require.resolve('../example/buffer.js') - var node = process.execPath - - var expect = { - "name": "example", - "version": "0.0.0", - "description": "testing description", - "main": "test-entry.js", - "directories": { - "example": "example", - "test": "test" - }, - "dependencies": {}, - "devDependencies": { - "tap": "~0.2.5" - }, - "scripts": { - "test": "tap test/*.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/substack/example.git" - }, - "homepage": "https://github.com/substack/example", - "keywords": [ - "fugazi", - "function", - "waiting", - "room" - ], - "author": { - "name": "James Halliday", - "email": "mail@substack.net", - "url": "http://substack.net" - }, - "license": "MIT", - "engine": { - "node": ">=0.6" - } - } - - var c = spawn(node, [example], { customFds: [-1,-1,-1] }) - var output = '' - c.stdout.on('data', function (d) { - output += d - respond() - }) - - var actual = '' - c.stderr.on('data', function (d) { - actual += d - }) - - function respond () { - if (output.match(/description: $/)) { - c.stdin.write('testing description\n') - return - } - if (output.match(/entry point: \(index\.js\) $/)) { - c.stdin.write('test-entry.js\n') - return - } - if (output.match(/keywords: $/)) { - c.stdin.write('fugazi function waiting room\n') - // "read" module is weird on node >= 0.10 when not a TTY - // requires explicit ending for reasons. - // could dig in, but really just wanna make tests pass, whatever. - c.stdin.end() - return - } - } - - c.on('close', function () { - actual = JSON.parse(actual) - t.deepEqual(actual, expect) - t.end() - }) -}) diff --git a/node_modules/promzard/test/exports.input b/node_modules/promzard/test/exports.input deleted file mode 100644 index 061cbfe1055aa..0000000000000 --- a/node_modules/promzard/test/exports.input +++ /dev/null @@ -1,5 +0,0 @@ -exports.a = 1 + 2 -exports.b = prompt('To be or not to be?', '!2b') -exports.c = {} -exports.c.x = prompt() -exports.c.y = tmpdir + "/y/file.txt" diff --git a/node_modules/promzard/test/exports.js b/node_modules/promzard/test/exports.js deleted file mode 100644 index c17993a4e9e75..0000000000000 --- a/node_modules/promzard/test/exports.js +++ /dev/null @@ -1,48 +0,0 @@ -var test = require('tap').test; -var promzard = require('../'); - -if (process.argv[2] === 'child') { - return child() -} - -test('exports', function (t) { - t.plan(1); - - var spawn = require('child_process').spawn - var child = spawn(process.execPath, [__filename, 'child']) - - var output = '' - child.stderr.on('data', function (c) { - output += c - }) - - setTimeout(function () { - child.stdin.write('\n'); - }, 100) - setTimeout(function () { - child.stdin.end('55\n'); - }, 200) - - child.on('close', function () { - console.error('output=%j', output) - output = JSON.parse(output) - t.same({ - a : 3, - b : '!2b', - c : { - x : 55, - y : '/tmp/y/file.txt', - } - }, output); - t.end() - }) -}); - -function child () { - var ctx = { tmpdir : '/tmp' } - var file = __dirname + '/exports.input'; - - promzard(file, ctx, function (err, output) { - console.error(JSON.stringify(output)) - }); -} diff --git a/node_modules/promzard/test/fn.input b/node_modules/promzard/test/fn.input deleted file mode 100644 index ed6c3f1c80c5b..0000000000000 --- a/node_modules/promzard/test/fn.input +++ /dev/null @@ -1,18 +0,0 @@ -var fs = require('fs') - -module.exports = { - "a": 1 + 2, - "b": prompt('To be or not to be?', '!2b', function (s) { - return s.toUpperCase() + '...' - }), - "c": { - "x": prompt(function (x) { return x * 100 }), - "y": tmpdir + "/y/file.txt" - }, - a_function: function (cb) { - fs.readFile(__filename, 'utf8', cb) - }, - asyncPrompt: function (cb) { - return cb(null, prompt('a prompt at any other time would smell as sweet')) - } -} diff --git a/node_modules/promzard/test/fn.js b/node_modules/promzard/test/fn.js deleted file mode 100644 index 899ebedbdd010..0000000000000 --- a/node_modules/promzard/test/fn.js +++ /dev/null @@ -1,56 +0,0 @@ -var test = require('tap').test; -var promzard = require('../'); -var fs = require('fs') -var file = __dirname + '/fn.input'; - -var expect = { - a : 3, - b : '!2B...', - c : { - x : 5500, - y : '/tmp/y/file.txt', - } -} -expect.a_function = fs.readFileSync(file, 'utf8') -expect.asyncPrompt = 'async prompt' - -if (process.argv[2] === 'child') { - return child() -} - -test('prompt callback param', function (t) { - t.plan(1); - - var spawn = require('child_process').spawn - var child = spawn(process.execPath, [__filename, 'child']) - - var output = '' - child.stderr.on('data', function (c) { - output += c - }) - - child.on('close', function () { - console.error('output=%j', output) - output = JSON.parse(output) - t.same(output, expect); - t.end() - }) - - setTimeout(function () { - child.stdin.write('\n') - }, 100) - setTimeout(function () { - child.stdin.write('55\n') - }, 150) - setTimeout(function () { - child.stdin.end('async prompt\n') - }, 200) -}) - -function child () { - var ctx = { tmpdir : '/tmp' } - var file = __dirname + '/fn.input'; - promzard(file, ctx, function (err, output) { - console.error(JSON.stringify(output)) - }) -} diff --git a/node_modules/promzard/test/simple.input b/node_modules/promzard/test/simple.input deleted file mode 100644 index e49def6470d59..0000000000000 --- a/node_modules/promzard/test/simple.input +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - "a": 1 + 2, - "b": prompt('To be or not to be?', '!2b'), - "c": { - "x": prompt(), - "y": tmpdir + "/y/file.txt" - } -} diff --git a/node_modules/promzard/test/simple.js b/node_modules/promzard/test/simple.js deleted file mode 100644 index 034a86475afbd..0000000000000 --- a/node_modules/promzard/test/simple.js +++ /dev/null @@ -1,30 +0,0 @@ -var test = require('tap').test; -var promzard = require('../'); - -test('simple', function (t) { - t.plan(1); - - var ctx = { tmpdir : '/tmp' } - var file = __dirname + '/simple.input'; - promzard(file, ctx, function (err, output) { - t.same( - { - a : 3, - b : '!2b', - c : { - x : 55, - y : '/tmp/y/file.txt', - } - }, - output - ); - }); - - setTimeout(function () { - process.stdin.emit('data', '\n'); - }, 100); - - setTimeout(function () { - process.stdin.emit('data', '55\n'); - }, 200); -}); diff --git a/node_modules/promzard/test/validate.input b/node_modules/promzard/test/validate.input deleted file mode 100644 index 839c0652294ac..0000000000000 --- a/node_modules/promzard/test/validate.input +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - "name": prompt("name", function (data) { - if (data === 'cool') return data - var er = new Error('not cool') - er.notValid = true - return er - }) -} diff --git a/node_modules/promzard/test/validate.js b/node_modules/promzard/test/validate.js deleted file mode 100644 index a120681494e60..0000000000000 --- a/node_modules/promzard/test/validate.js +++ /dev/null @@ -1,20 +0,0 @@ - -var promzard = require('../') -var test = require('tap').test - -test('validate', function (t) { - t.plan(2) - var ctx = { tmpdir : '/tmp' } - var file = __dirname + '/validate.input' - promzard(file, ctx, function (er, found) { - t.ok(!er) - var wanted = { name: 'cool' } - t.same(found, wanted) - }) - setTimeout(function () { - process.stdin.emit('data', 'not cool\n') - }, 100) - setTimeout(function () { - process.stdin.emit('data', 'cool\n') - }, 200) -}) diff --git a/node_modules/qrcode-terminal/example/basic.png b/node_modules/qrcode-terminal/example/basic.png deleted file mode 100644 index 2ab5c226f4311..0000000000000 Binary files a/node_modules/qrcode-terminal/example/basic.png and /dev/null differ diff --git a/node_modules/read-cmd-shim/lib/index.js b/node_modules/read-cmd-shim/lib/index.js index 782d4c36dced5..dafc874463f63 100644 --- a/node_modules/read-cmd-shim/lib/index.js +++ b/node_modules/read-cmd-shim/lib/index.js @@ -56,8 +56,10 @@ const readCmdShim = path => { if (destination) { return destination } - return Promise.reject(notaShim(path, er)) - }, readFileEr => Promise.reject(wrapError(readFileEr, er))) + throw notaShim(path, er) + }, readFileEr => { + throw wrapError(readFileEr, er) + }) } const readCmdShimSync = path => { diff --git a/node_modules/read-cmd-shim/package.json b/node_modules/read-cmd-shim/package.json index fee454f017c2f..d3ebc40e311bb 100644 --- a/node_modules/read-cmd-shim/package.json +++ b/node_modules/read-cmd-shim/package.json @@ -1,33 +1,34 @@ { "name": "read-cmd-shim", - "version": "3.0.0", + "version": "6.0.0", "description": "Figure out what a cmd-shim is pointing at. This acts as the equivalent of fs.readlink.", "main": "lib/index.js", "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", - "cmd-shim": "^4.0.0", - "rimraf": "^3.0.0", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "cmd-shim": "^7.0.0", "tap": "^16.0.1" }, "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "test": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "repository": { "type": "git", - "url": "https://github.com/npm/read-cmd-shim.git" + "url": "git+https://github.com/npm/read-cmd-shim.git" }, "license": "ISC", "homepage": "https://github.com/npm/read-cmd-shim#readme", @@ -37,10 +38,11 @@ ], "author": "GitHub Inc.", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.2" + "version": "4.27.1", + "publish": true } } diff --git a/node_modules/read-package-json-fast/LICENSE b/node_modules/read-package-json-fast/LICENSE deleted file mode 100644 index 20a4762540923..0000000000000 --- a/node_modules/read-package-json-fast/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) npm, Inc. and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/read-package-json-fast/index.js b/node_modules/read-package-json-fast/index.js deleted file mode 100644 index 646ff7dfbbd76..0000000000000 --- a/node_modules/read-package-json-fast/index.js +++ /dev/null @@ -1,136 +0,0 @@ -const {promisify} = require('util') -const fs = require('fs') -const readFile = promisify(fs.readFile) -const lstat = promisify(fs.lstat) -const readdir = promisify(fs.readdir) -const parse = require('json-parse-even-better-errors') - -const { resolve, dirname, join, relative } = require('path') - -const rpj = path => readFile(path, 'utf8') - .then(data => readBinDir(path, normalize(stripUnderscores(parse(data))))) - .catch(er => { - er.path = path - throw er - }) - -const normalizePackageBin = require('npm-normalize-package-bin') - -// load the directories.bin folder as a 'bin' object -const readBinDir = async (path, data) => { - if (data.bin) - return data - - const m = data.directories && data.directories.bin - if (!m || typeof m !== 'string') - return data - - // cut off any monkey business, like setting directories.bin - // to ../../../etc/passwd or /etc/passwd or something like that. - const root = dirname(path) - const dir = join('.', join('/', m)) - data.bin = await walkBinDir(root, dir, {}) - return data -} - -const walkBinDir = async (root, dir, obj) => { - const entries = await readdir(resolve(root, dir)).catch(() => []) - for (const entry of entries) { - if (entry.charAt(0) === '.') - continue - const f = resolve(root, dir, entry) - // ignore stat errors, weird file types, symlinks, etc. - const st = await lstat(f).catch(() => null) - if (!st) - continue - else if (st.isFile()) - obj[entry] = relative(root, f) - else if (st.isDirectory()) - await walkBinDir(root, join(dir, entry), obj) - } - return obj -} - -// do not preserve _fields set in files, they are sus -const stripUnderscores = data => { - for (const key of Object.keys(data).filter(k => /^_/.test(k))) - delete data[key] - return data -} - -const normalize = data => { - add_id(data) - fixBundled(data) - pruneRepeatedOptionals(data) - fixScripts(data) - fixFunding(data) - normalizePackageBin(data) - return data -} - -rpj.normalize = normalize - -const add_id = data => { - if (data.name && data.version) - data._id = `${data.name}@${data.version}` - return data -} - -// it was once common practice to list deps both in optionalDependencies -// and in dependencies, to support npm versions that did not know abbout -// optionalDependencies. This is no longer a relevant need, so duplicating -// the deps in two places is unnecessary and excessive. -const pruneRepeatedOptionals = data => { - const od = data.optionalDependencies - const dd = data.dependencies || {} - if (od && typeof od === 'object') { - for (const name of Object.keys(od)) { - delete dd[name] - } - } - if (Object.keys(dd).length === 0) - delete data.dependencies - return data -} - -const fixBundled = data => { - const bdd = data.bundledDependencies - const bd = data.bundleDependencies === undefined ? bdd - : data.bundleDependencies - - if (bd === false) - data.bundleDependencies = [] - else if (bd === true) - data.bundleDependencies = Object.keys(data.dependencies || {}) - else if (bd && typeof bd === 'object') { - if (!Array.isArray(bd)) - data.bundleDependencies = Object.keys(bd) - else - data.bundleDependencies = bd - } else - delete data.bundleDependencies - - delete data.bundledDependencies - return data -} - -const fixScripts = data => { - if (!data.scripts || typeof data.scripts !== 'object') { - delete data.scripts - return data - } - - for (const [name, script] of Object.entries(data.scripts)) { - if (typeof script !== 'string') - delete data.scripts[name] - } - return data -} - -const fixFunding = data => { - if (data.funding && typeof data.funding === 'string') - data.funding = { url: data.funding } - return data -} - -module.exports = rpj diff --git a/node_modules/read-package-json-fast/package.json b/node_modules/read-package-json-fast/package.json deleted file mode 100644 index c3a9f7dc5c37b..0000000000000 --- a/node_modules/read-package-json-fast/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "read-package-json-fast", - "version": "2.0.3", - "description": "Like read-package-json, but faster", - "author": "Isaac Z. Schlueter <i@izs.me> (https://izs.me)", - "license": "ISC", - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags" - }, - "engines": { - "node": ">=10" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "tap": "^15.0.9" - }, - "dependencies": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/npm/read-package-json-fast.git" - }, - "files": [ - "index.js" - ] -} diff --git a/node_modules/read-package-json/LICENSE b/node_modules/read-package-json/LICENSE deleted file mode 100644 index 052085c436514..0000000000000 --- a/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/node_modules/read-package-json/lib/read-json.js b/node_modules/read-package-json/lib/read-json.js deleted file mode 100644 index c55eca32259ed..0000000000000 --- a/node_modules/read-package-json/lib/read-json.js +++ /dev/null @@ -1,605 +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] = obj[ii] - } - } else if (typeof obj === 'object') { - var newobj = {} - for (var kk in obj) { - newobj[kk] = jsonClone[kk] - } - } 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) - } - - glob('*.gyp', { cwd: dir }, function (er, files) { - if (er) { - return cb(er) - } - if (data.gypfile === false) { - return cb(null, data) - } - gypfile_(file, data, files, cb) - }) -} - -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) - } - glob('server.js', { cwd: dir }, function (er, files) { - if (er) { - return cb(er) - } - serverjs_(file, data, files, cb) - }) -} - -function serverjs_ (file, data, files, cb) { - if (!files.length) { - return cb(null, data) - } - var s = data.scripts || {} - 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, function (er, files) { - if (er) { - return cb(er) - } - // 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) - readme_(file, data, rm, cb) - }) -} - -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 }, function (er, mansGlob) { - if (er) { - return cb(er) - } - data.man = mansGlob.map(man => - path.relative(dirname, path.join(cwd, man)).split(path.sep).join('/') - ) - return cb(null, data) - }) -} - -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), m) - glob('**', { cwd: m }, function (er, binsGlob) { - if (er) { - return cb(er) - } - bins_(file, data, binsGlob, cb) - }) -} - -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 ? 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/node_modules/read-package-json/package.json b/node_modules/read-package-json/package.json deleted file mode 100644 index 8bb77ca01f653..0000000000000 --- a/node_modules/read-package-json/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "read-package-json", - "version": "5.0.1", - "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", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "snap": "tap", - "template-oss-apply": "template-oss-apply --force" - }, - "dependencies": { - "glob": "^8.0.1", - "json-parse-even-better-errors": "^2.3.1", - "normalize-package-data": "^4.0.0", - "npm-normalize-package-bin": "^1.0.1" - }, - "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.4.1", - "tap": "^16.0.1" - }, - "license": "ISC", - "files": [ - "bin/", - "lib/" - ], - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "tap": { - "branches": 68, - "functions": 83, - "lines": 76, - "statements": 77 - }, - "templateOSS": { - "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.4.1" - } -} diff --git a/node_modules/read/dist/commonjs/package.json b/node_modules/read/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/read/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/read/dist/commonjs/read.js b/node_modules/read/dist/commonjs/read.js new file mode 100644 index 0000000000000..744a5f3bf4baf --- /dev/null +++ b/node_modules/read/dist/commonjs/read.js @@ -0,0 +1,94 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.read = read; +const mute_stream_1 = __importDefault(require("mute-stream")); +const readline_1 = require("readline"); +async function read({ default: def, input = process.stdin, output = process.stdout, completer, prompt = '', silent, timeout, edit, terminal, replace, history, }) { + if (typeof def !== 'undefined' && + typeof def !== 'string' && + typeof def !== 'number') { + throw new Error('default value must be string or number'); + } + let editDef = false; + const defString = def?.toString(); + prompt = prompt.trim() + ' '; + terminal = !!(terminal || output.isTTY); + if (defString) { + if (silent) { + prompt += '(<default hidden>) '; + // TODO: add tests for edit + /* c8 ignore start */ + } + else if (edit) { + editDef = true; + /* c8 ignore stop */ + } + else { + prompt += '(' + defString + ') '; + } + } + const m = new mute_stream_1.default({ replace, prompt }); + m.pipe(output, { end: false }); + output = m; + return new Promise((resolve, reject) => { + const rl = (0, readline_1.createInterface)({ input, output, terminal, completer, history }); + // TODO: add tests for timeout + /* c8 ignore start */ + const timer = timeout && setTimeout(() => onError(new Error('timed out')), timeout); + /* c8 ignore stop */ + m.unmute(); + rl.setPrompt(prompt); + rl.prompt(); + if (silent) { + m.mute(); + // TODO: add tests for edit + default + /* c8 ignore start */ + } + else if (editDef && defString) { + const rlEdit = rl; + rlEdit.line = defString; + rlEdit.cursor = defString.length; + rlEdit._refreshLine(); + } + /* c8 ignore stop */ + const done = () => { + rl.close(); + clearTimeout(timer); + m.mute(); + m.end(); + }; + // TODO: add tests for rejecting + /* c8 ignore start */ + const onError = (er) => { + done(); + reject(er); + }; + /* c8 ignore stop */ + rl.on('error', onError); + rl.on('line', line => { + // TODO: add tests for silent + /* c8 ignore start */ + if (silent && terminal) { + m.unmute(); + } + /* c8 ignore stop */ + done(); + // TODO: add tests for default + /* c8 ignore start */ + // truncate the \n at the end. + return resolve(line.replace(/\r?\n?$/, '') || defString || ''); + /* c8 ignore stop */ + }); + // TODO: add tests for sigint + /* c8 ignore start */ + rl.on('SIGINT', () => { + rl.close(); + onError(new Error('canceled')); + }); + /* c8 ignore stop */ + }); +} +//# sourceMappingURL=read.js.map \ No newline at end of file diff --git a/node_modules/read/dist/esm/package.json b/node_modules/read/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/read/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/read/dist/esm/read.js b/node_modules/read/dist/esm/read.js new file mode 100644 index 0000000000000..672be49ae88a7 --- /dev/null +++ b/node_modules/read/dist/esm/read.js @@ -0,0 +1,88 @@ +import Mute from 'mute-stream'; +import { createInterface } from 'readline'; +export async function read({ default: def, input = process.stdin, output = process.stdout, completer, prompt = '', silent, timeout, edit, terminal, replace, history, }) { + if (typeof def !== 'undefined' && + typeof def !== 'string' && + typeof def !== 'number') { + throw new Error('default value must be string or number'); + } + let editDef = false; + const defString = def?.toString(); + prompt = prompt.trim() + ' '; + terminal = !!(terminal || output.isTTY); + if (defString) { + if (silent) { + prompt += '(<default hidden>) '; + // TODO: add tests for edit + /* c8 ignore start */ + } + else if (edit) { + editDef = true; + /* c8 ignore stop */ + } + else { + prompt += '(' + defString + ') '; + } + } + const m = new Mute({ replace, prompt }); + m.pipe(output, { end: false }); + output = m; + return new Promise((resolve, reject) => { + const rl = createInterface({ input, output, terminal, completer, history }); + // TODO: add tests for timeout + /* c8 ignore start */ + const timer = timeout && setTimeout(() => onError(new Error('timed out')), timeout); + /* c8 ignore stop */ + m.unmute(); + rl.setPrompt(prompt); + rl.prompt(); + if (silent) { + m.mute(); + // TODO: add tests for edit + default + /* c8 ignore start */ + } + else if (editDef && defString) { + const rlEdit = rl; + rlEdit.line = defString; + rlEdit.cursor = defString.length; + rlEdit._refreshLine(); + } + /* c8 ignore stop */ + const done = () => { + rl.close(); + clearTimeout(timer); + m.mute(); + m.end(); + }; + // TODO: add tests for rejecting + /* c8 ignore start */ + const onError = (er) => { + done(); + reject(er); + }; + /* c8 ignore stop */ + rl.on('error', onError); + rl.on('line', line => { + // TODO: add tests for silent + /* c8 ignore start */ + if (silent && terminal) { + m.unmute(); + } + /* c8 ignore stop */ + done(); + // TODO: add tests for default + /* c8 ignore start */ + // truncate the \n at the end. + return resolve(line.replace(/\r?\n?$/, '') || defString || ''); + /* c8 ignore stop */ + }); + // TODO: add tests for sigint + /* c8 ignore start */ + rl.on('SIGINT', () => { + rl.close(); + onError(new Error('canceled')); + }); + /* c8 ignore stop */ + }); +} +//# sourceMappingURL=read.js.map \ No newline at end of file diff --git a/node_modules/read/lib/read.js b/node_modules/read/lib/read.js deleted file mode 100644 index a93d1b3b532c0..0000000000000 --- a/node_modules/read/lib/read.js +++ /dev/null @@ -1,113 +0,0 @@ - -module.exports = read - -var readline = require('readline') -var Mute = require('mute-stream') - -function read (opts, cb) { - if (opts.num) { - throw new Error('read() no longer accepts a char number limit') - } - - if (typeof opts.default !== 'undefined' && - typeof opts.default !== 'string' && - typeof opts.default !== 'number') { - throw new Error('default value must be string or number') - } - - var input = opts.input || process.stdin - var output = opts.output || process.stdout - var prompt = (opts.prompt || '').trim() + ' ' - var silent = opts.silent - var editDef = false - var timeout = opts.timeout - - var def = opts.default || '' - if (def) { - if (silent) { - prompt += '(<default hidden>) ' - } else if (opts.edit) { - editDef = true - } else { - prompt += '(' + def + ') ' - } - } - var terminal = !!(opts.terminal || output.isTTY) - - var m = new Mute({ replace: opts.replace, prompt: prompt }) - m.pipe(output, {end: false}) - output = m - var rlOpts = { input: input, output: output, terminal: terminal } - - if (process.version.match(/^v0\.6/)) { - var rl = readline.createInterface(rlOpts.input, rlOpts.output) - } else { - var rl = readline.createInterface(rlOpts) - } - - - output.unmute() - rl.setPrompt(prompt) - rl.prompt() - if (silent) { - output.mute() - } else if (editDef) { - rl.line = def - rl.cursor = def.length - rl._refreshLine() - } - - var called = false - rl.on('line', onLine) - rl.on('error', onError) - - rl.on('SIGINT', function () { - rl.close() - onError(new Error('canceled')) - }) - - var timer - if (timeout) { - timer = setTimeout(function () { - onError(new Error('timed out')) - }, timeout) - } - - function done () { - called = true - rl.close() - - if (process.version.match(/^v0\.6/)) { - rl.input.removeAllListeners('data') - rl.input.removeAllListeners('keypress') - rl.input.pause() - } - - clearTimeout(timer) - output.mute() - output.end() - } - - function onError (er) { - if (called) return - done() - return cb(er) - } - - function onLine (line) { - if (called) return - if (silent && terminal) { - output.unmute() - output.write('\r\n') - } - done() - // truncate the \n at the end. - line = line.replace(/\r?\n$/, '') - var isDefault = !!(editDef && line === def) - if (def && !line) { - isDefault = true - line = def - } - cb(null, line, isDefault) - } -} diff --git a/node_modules/read/package.json b/node_modules/read/package.json index 3b480aa769117..723bcfb9656a1 100644 --- a/node_modules/read/package.json +++ b/node_modules/read/package.json @@ -1,27 +1,88 @@ { "name": "read", - "version": "1.0.7", - "main": "lib/read.js", + "version": "5.0.1", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/read.d.ts", + "default": "./dist/esm/read.js" + }, + "require": { + "types": "./dist/commonjs/read.d.ts", + "default": "./dist/commonjs/read.js" + } + } + }, + "type": "module", + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/read.ts" + } + }, "dependencies": { - "mute-stream": "~0.0.4" + "mute-stream": "^3.0.0" }, "devDependencies": { - "tap": "^1.2.0" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "@types/mute-stream": "^0.0.4", + "@types/tap": "^15.0.11", + "@typescript-eslint/parser": "^8.0.1", + "c8": "^10.1.2", + "eslint-import-resolver-typescript": "^4.3.2", + "tap": "^16.3.9", + "ts-node": "^10.9.1", + "tshy": "^3.0.2", + "typescript": "^5.2.2" }, "engines": { - "node": ">=0.8" + "node": "^20.17.0 || >=22.9.0" }, - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "GitHub Inc.", "description": "read(1) for node programs", "repository": { "type": "git", - "url": "git://github.com/isaacs/read.git" + "url": "git+https://github.com/npm/read.git" }, "license": "ISC", "scripts": { - "test": "tap test/*.js" + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "c8 tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true, + "typescript": true + }, + "main": "./dist/commonjs/read.js", + "types": "./dist/commonjs/read.d.ts", + "tap": { + "coverage": false, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "files": [ - "lib/read.js" - ] + "dist/" + ], + "module": "./dist/esm/read.js" } diff --git a/node_modules/readable-stream/CONTRIBUTING.md b/node_modules/readable-stream/CONTRIBUTING.md deleted file mode 100644 index f478d58dca85b..0000000000000 --- a/node_modules/readable-stream/CONTRIBUTING.md +++ /dev/null @@ -1,38 +0,0 @@ -# Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -* (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -* (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -* (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -* (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. - -## Moderation Policy - -The [Node.js Moderation Policy] applies to this WG. - -## Code of Conduct - -The [Node.js Code of Conduct][] applies to this WG. - -[Node.js Code of Conduct]: -https://github.com/nodejs/node/blob/master/CODE_OF_CONDUCT.md -[Node.js Moderation Policy]: -https://github.com/nodejs/TSC/blob/master/Moderation-Policy.md diff --git a/node_modules/readable-stream/GOVERNANCE.md b/node_modules/readable-stream/GOVERNANCE.md deleted file mode 100644 index 16ffb93f24bec..0000000000000 --- a/node_modules/readable-stream/GOVERNANCE.md +++ /dev/null @@ -1,136 +0,0 @@ -### Streams Working Group - -The Node.js Streams is jointly governed by a Working Group -(WG) -that is responsible for high-level guidance of the project. - -The WG has final authority over this project including: - -* Technical direction -* Project governance and process (including this policy) -* Contribution policy -* GitHub repository hosting -* Conduct guidelines -* Maintaining the list of additional Collaborators - -For the current list of WG members, see the project -[README.md](./README.md#current-project-team-members). - -### Collaborators - -The readable-stream GitHub repository is -maintained by the WG and additional Collaborators who are added by the -WG on an ongoing basis. - -Individuals making significant and valuable contributions are made -Collaborators and given commit-access to the project. These -individuals are identified by the WG and their addition as -Collaborators is discussed during the WG meeting. - -_Note:_ If you make a significant contribution and are not considered -for commit-access log an issue or contact a WG member directly and it -will be brought up in the next WG meeting. - -Modifications of the contents of the readable-stream repository are -made on -a collaborative basis. Anybody with a GitHub account may propose a -modification via pull request and it will be considered by the project -Collaborators. All pull requests must be reviewed and accepted by a -Collaborator with sufficient expertise who is able to take full -responsibility for the change. In the case of pull requests proposed -by an existing Collaborator, an additional Collaborator is required -for sign-off. Consensus should be sought if additional Collaborators -participate and there is disagreement around a particular -modification. See _Consensus Seeking Process_ below for further detail -on the consensus model used for governance. - -Collaborators may opt to elevate significant or controversial -modifications, or modifications that have not found consensus to the -WG for discussion by assigning the ***WG-agenda*** tag to a pull -request or issue. The WG should serve as the final arbiter where -required. - -For the current list of Collaborators, see the project -[README.md](./README.md#members). - -### WG Membership - -WG seats are not time-limited. There is no fixed size of the WG. -However, the expected target is between 6 and 12, to ensure adequate -coverage of important areas of expertise, balanced with the ability to -make decisions efficiently. - -There is no specific set of requirements or qualifications for WG -membership beyond these rules. - -The WG may add additional members to the WG by unanimous consensus. - -A WG member may be removed from the WG by voluntary resignation, or by -unanimous consensus of all other WG members. - -Changes to WG membership should be posted in the agenda, and may be -suggested as any other agenda item (see "WG Meetings" below). - -If an addition or removal is proposed during a meeting, and the full -WG is not in attendance to participate, then the addition or removal -is added to the agenda for the subsequent meeting. This is to ensure -that all members are given the opportunity to participate in all -membership decisions. If a WG member is unable to attend a meeting -where a planned membership decision is being made, then their consent -is assumed. - -No more than 1/3 of the WG members may be affiliated with the same -employer. If removal or resignation of a WG member, or a change of -employment by a WG member, creates a situation where more than 1/3 of -the WG membership shares an employer, then the situation must be -immediately remedied by the resignation or removal of one or more WG -members affiliated with the over-represented employer(s). - -### WG Meetings - -The WG meets occasionally on a Google Hangout On Air. A designated moderator -approved by the WG runs the meeting. Each meeting should be -published to YouTube. - -Items are added to the WG agenda that are considered contentious or -are modifications of governance, contribution policy, WG membership, -or release process. - -The intention of the agenda is not to approve or review all patches; -that should happen continuously on GitHub and be handled by the larger -group of Collaborators. - -Any community member or contributor can ask that something be added to -the next meeting's agenda by logging a GitHub Issue. Any Collaborator, -WG member or the moderator can add the item to the agenda by adding -the ***WG-agenda*** tag to the issue. - -Prior to each WG meeting the moderator will share the Agenda with -members of the WG. WG members can add any items they like to the -agenda at the beginning of each meeting. The moderator and the WG -cannot veto or remove items. - -The WG may invite persons or representatives from certain projects to -participate in a non-voting capacity. - -The moderator is responsible for summarizing the discussion of each -agenda item and sends it as a pull request after the meeting. - -### Consensus Seeking Process - -The WG follows a -[Consensus -Seeking](http://en.wikipedia.org/wiki/Consensus-seeking_decision-making) -decision-making model. - -When an agenda item has appeared to reach a consensus the moderator -will ask "Does anyone object?" as a final call for dissent from the -consensus. - -If an agenda item cannot reach a consensus a WG member can call for -either a closing vote or a vote to table the issue to the next -meeting. The call for a vote must be seconded by a majority of the WG -or else the discussion will continue. Simple majority wins. - -Note that changes to WG membership require a majority consensus. See -"WG Membership" above. diff --git a/node_modules/readable-stream/LICENSE b/node_modules/readable-stream/LICENSE deleted file mode 100644 index 2873b3b2e5950..0000000000000 --- a/node_modules/readable-stream/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Node.js is licensed for use as follows: - -""" -Copyright Node.js contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -""" - -This license applies to parts of Node.js originating from the -https://github.com/joyent/node repository: - -""" -Copyright Joyent, Inc. and other Node contributors. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -""" diff --git a/node_modules/readable-stream/errors-browser.js b/node_modules/readable-stream/errors-browser.js deleted file mode 100644 index fb8e73e1893b1..0000000000000 --- a/node_modules/readable-stream/errors-browser.js +++ /dev/null @@ -1,127 +0,0 @@ -'use strict'; - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } - -var codes = {}; - -function createErrorType(code, message, Base) { - if (!Base) { - Base = Error; - } - - function getMessage(arg1, arg2, arg3) { - if (typeof message === 'string') { - return message; - } else { - return message(arg1, arg2, arg3); - } - } - - var NodeError = - /*#__PURE__*/ - function (_Base) { - _inheritsLoose(NodeError, _Base); - - function NodeError(arg1, arg2, arg3) { - return _Base.call(this, getMessage(arg1, arg2, arg3)) || this; - } - - return NodeError; - }(Base); - - NodeError.prototype.name = Base.name; - NodeError.prototype.code = code; - codes[code] = NodeError; -} // https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js - - -function oneOf(expected, thing) { - if (Array.isArray(expected)) { - var len = expected.length; - expected = expected.map(function (i) { - return String(i); - }); - - if (len > 2) { - return "one of ".concat(thing, " ").concat(expected.slice(0, len - 1).join(', '), ", or ") + expected[len - 1]; - } else if (len === 2) { - return "one of ".concat(thing, " ").concat(expected[0], " or ").concat(expected[1]); - } else { - return "of ".concat(thing, " ").concat(expected[0]); - } - } else { - return "of ".concat(thing, " ").concat(String(expected)); - } -} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith - - -function startsWith(str, search, pos) { - return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; -} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith - - -function endsWith(str, search, this_len) { - if (this_len === undefined || this_len > str.length) { - this_len = str.length; - } - - return str.substring(this_len - search.length, this_len) === search; -} // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes - - -function includes(str, search, start) { - if (typeof start !== 'number') { - start = 0; - } - - if (start + search.length > str.length) { - return false; - } else { - return str.indexOf(search, start) !== -1; - } -} - -createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { - return 'The value "' + value + '" is invalid for option "' + name + '"'; -}, TypeError); -createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { - // determiner: 'must be' or 'must not be' - var determiner; - - if (typeof expected === 'string' && startsWith(expected, 'not ')) { - determiner = 'must not be'; - expected = expected.replace(/^not /, ''); - } else { - determiner = 'must be'; - } - - var msg; - - if (endsWith(name, ' argument')) { - // For cases like 'first argument' - msg = "The ".concat(name, " ").concat(determiner, " ").concat(oneOf(expected, 'type')); - } else { - var type = includes(name, '.') ? 'property' : 'argument'; - msg = "The \"".concat(name, "\" ").concat(type, " ").concat(determiner, " ").concat(oneOf(expected, 'type')); - } - - msg += ". Received type ".concat(typeof actual); - return msg; -}, TypeError); -createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); -createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { - return 'The ' + name + ' method is not implemented'; -}); -createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); -createErrorType('ERR_STREAM_DESTROYED', function (name) { - return 'Cannot call ' + name + ' after a stream was destroyed'; -}); -createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); -createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); -createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); -createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); -createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { - return 'Unknown encoding: ' + arg; -}, TypeError); -createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); -module.exports.codes = codes; diff --git a/node_modules/readable-stream/errors.js b/node_modules/readable-stream/errors.js deleted file mode 100644 index 8471526d6e7f7..0000000000000 --- a/node_modules/readable-stream/errors.js +++ /dev/null @@ -1,116 +0,0 @@ -'use strict'; - -const codes = {}; - -function createErrorType(code, message, Base) { - if (!Base) { - Base = Error - } - - function getMessage (arg1, arg2, arg3) { - if (typeof message === 'string') { - return message - } else { - return message(arg1, arg2, arg3) - } - } - - class NodeError extends Base { - constructor (arg1, arg2, arg3) { - super(getMessage(arg1, arg2, arg3)); - } - } - - NodeError.prototype.name = Base.name; - NodeError.prototype.code = code; - - codes[code] = NodeError; -} - -// https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js -function oneOf(expected, thing) { - if (Array.isArray(expected)) { - const len = expected.length; - expected = expected.map((i) => String(i)); - if (len > 2) { - return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` + - expected[len - 1]; - } else if (len === 2) { - return `one of ${thing} ${expected[0]} or ${expected[1]}`; - } else { - return `of ${thing} ${expected[0]}`; - } - } else { - return `of ${thing} ${String(expected)}`; - } -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith -function startsWith(str, search, pos) { - return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith -function endsWith(str, search, this_len) { - if (this_len === undefined || this_len > str.length) { - this_len = str.length; - } - return str.substring(this_len - search.length, this_len) === search; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes -function includes(str, search, start) { - if (typeof start !== 'number') { - start = 0; - } - - if (start + search.length > str.length) { - return false; - } else { - return str.indexOf(search, start) !== -1; - } -} - -createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { - return 'The value "' + value + '" is invalid for option "' + name + '"' -}, TypeError); -createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { - // determiner: 'must be' or 'must not be' - let determiner; - if (typeof expected === 'string' && startsWith(expected, 'not ')) { - determiner = 'must not be'; - expected = expected.replace(/^not /, ''); - } else { - determiner = 'must be'; - } - - let msg; - if (endsWith(name, ' argument')) { - // For cases like 'first argument' - msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`; - } else { - const type = includes(name, '.') ? 'property' : 'argument'; - msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`; - } - - msg += `. Received type ${typeof actual}`; - return msg; -}, TypeError); -createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); -createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { - return 'The ' + name + ' method is not implemented' -}); -createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); -createErrorType('ERR_STREAM_DESTROYED', function (name) { - return 'Cannot call ' + name + ' after a stream was destroyed'; -}); -createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); -createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); -createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); -createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); -createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { - return 'Unknown encoding: ' + arg -}, TypeError); -createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); - -module.exports.codes = codes; diff --git a/node_modules/readable-stream/experimentalWarning.js b/node_modules/readable-stream/experimentalWarning.js deleted file mode 100644 index 78e841495bf24..0000000000000 --- a/node_modules/readable-stream/experimentalWarning.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -var experimentalWarnings = new Set(); - -function emitExperimentalWarning(feature) { - if (experimentalWarnings.has(feature)) return; - var msg = feature + ' is an experimental feature. This feature could ' + - 'change at any time'; - experimentalWarnings.add(feature); - process.emitWarning(msg, 'ExperimentalWarning'); -} - -function noop() {} - -module.exports.emitExperimentalWarning = process.emitWarning - ? emitExperimentalWarning - : noop; diff --git a/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/readable-stream/lib/_stream_duplex.js deleted file mode 100644 index 67525192250f6..0000000000000 --- a/node_modules/readable-stream/lib/_stream_duplex.js +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. -'use strict'; -/*<replacement>*/ - -var objectKeys = Object.keys || function (obj) { - var keys = []; - - for (var key in obj) { - keys.push(key); - } - - return keys; -}; -/*</replacement>*/ - - -module.exports = Duplex; - -var Readable = require('./_stream_readable'); - -var Writable = require('./_stream_writable'); - -require('inherits')(Duplex, Readable); - -{ - // Allow the keys array to be GC'ed. - var keys = objectKeys(Writable.prototype); - - for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; - } -} - -function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - Readable.call(this, options); - Writable.call(this, options); - this.allowHalfOpen = true; - - if (options) { - if (options.readable === false) this.readable = false; - if (options.writable === false) this.writable = false; - - if (options.allowHalfOpen === false) { - this.allowHalfOpen = false; - this.once('end', onend); - } - } -} - -Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._writableState.highWaterMark; - } -}); -Object.defineProperty(Duplex.prototype, 'writableBuffer', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._writableState && this._writableState.getBuffer(); - } -}); -Object.defineProperty(Duplex.prototype, 'writableLength', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._writableState.length; - } -}); // the no-half-open enforcer - -function onend() { - // If the writable side ended, then we're ok. - if (this._writableState.ended) return; // no more data can be written. - // But allow more writes to happen in this tick. - - process.nextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} - -Object.defineProperty(Duplex.prototype, 'destroyed', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - if (this._readableState === undefined || this._writableState === undefined) { - return false; - } - - return this._readableState.destroyed && this._writableState.destroyed; - }, - set: function set(value) { - // we ignore the value if the stream - // has not been initialized yet - if (this._readableState === undefined || this._writableState === undefined) { - return; - } // backward compatibility, the user is explicitly - // managing destroyed - - - this._readableState.destroyed = value; - this._writableState.destroyed = value; - } -}); \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/readable-stream/lib/_stream_passthrough.js deleted file mode 100644 index 32e7414c5a827..0000000000000 --- a/node_modules/readable-stream/lib/_stream_passthrough.js +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. -'use strict'; - -module.exports = PassThrough; - -var Transform = require('./_stream_transform'); - -require('inherits')(PassThrough, Transform); - -function PassThrough(options) { - if (!(this instanceof PassThrough)) return new PassThrough(options); - Transform.call(this, options); -} - -PassThrough.prototype._transform = function (chunk, encoding, cb) { - cb(null, chunk); -}; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/readable-stream/lib/_stream_readable.js deleted file mode 100644 index 192d451488f20..0000000000000 --- a/node_modules/readable-stream/lib/_stream_readable.js +++ /dev/null @@ -1,1124 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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 = Readable; -/*<replacement>*/ - -var Duplex; -/*</replacement>*/ - -Readable.ReadableState = ReadableState; -/*<replacement>*/ - -var EE = require('events').EventEmitter; - -var EElistenerCount = function EElistenerCount(emitter, type) { - return emitter.listeners(type).length; -}; -/*</replacement>*/ - -/*<replacement>*/ - - -var Stream = require('./internal/streams/stream'); -/*</replacement>*/ - - -var Buffer = require('buffer').Buffer; - -var OurUint8Array = global.Uint8Array || function () {}; - -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} - -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} -/*<replacement>*/ - - -var debugUtil = require('util'); - -var debug; - -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function debug() {}; -} -/*</replacement>*/ - - -var BufferList = require('./internal/streams/buffer_list'); - -var destroyImpl = require('./internal/streams/destroy'); - -var _require = require('./internal/streams/state'), - getHighWaterMark = _require.getHighWaterMark; - -var _require$codes = require('../errors').codes, - ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, - ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, - ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, - ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance. - - -var StringDecoder; -var createReadableStreamAsyncIterator; -var from; - -require('inherits')(Readable, Stream); - -var errorOrDestroy = destroyImpl.errorOrDestroy; -var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; - -function prependListener(emitter, event, fn) { - // Sadly this is not cacheable as some libraries bundle their own - // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; -} - -function ReadableState(options, stream, isDuplex) { - Duplex = Duplex || require('./_stream_duplex'); - options = options || {}; // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - - if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - - this.objectMode = !!options.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - - this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; // a flag to be able to tell if the event 'readable'/'data' is emitted - // immediately, or on a later tick. We set this to true at first, because - // any actions that shouldn't happen until "later" should generally also - // not happen before the first read call. - - this.sync = true; // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - this.paused = true; // Should close be emitted on destroy. Defaults to true. - - this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish') - - this.autoDestroy = !!options.autoDestroy; // has it been destroyed - - this.destroyed = false; // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - - this.defaultEncoding = options.defaultEncoding || 'utf8'; // the number of writers that are awaiting a drain event in .pipe()s - - this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled - - this.readingMore = false; - this.decoder = null; - this.encoding = null; - - if (options.encoding) { - if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -function Readable(options) { - Duplex = Duplex || require('./_stream_duplex'); - if (!(this instanceof Readable)) return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside - // the ReadableState constructor, at least with V8 6.5 - - var isDuplex = this instanceof Duplex; - this._readableState = new ReadableState(options, this, isDuplex); // legacy - - this.readable = true; - - if (options) { - if (typeof options.read === 'function') this._read = options.read; - if (typeof options.destroy === 'function') this._destroy = options.destroy; - } - - Stream.call(this); -} - -Object.defineProperty(Readable.prototype, 'destroyed', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - if (this._readableState === undefined) { - return false; - } - - return this._readableState.destroyed; - }, - set: function set(value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._readableState) { - return; - } // backward compatibility, the user is explicitly - // managing destroyed - - - this._readableState.destroyed = value; - } -}); -Readable.prototype.destroy = destroyImpl.destroy; -Readable.prototype._undestroy = destroyImpl.undestroy; - -Readable.prototype._destroy = function (err, cb) { - cb(err); -}; // Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. - - -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - var skipChunkCheck; - - if (!state.objectMode) { - if (typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - - if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; - } - - skipChunkCheck = true; - } - } else { - skipChunkCheck = true; - } - - return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); -}; // Unshift should *always* be something directly out of read() - - -Readable.prototype.unshift = function (chunk) { - return readableAddChunk(this, chunk, null, true, false); -}; - -function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { - debug('readableAddChunk', chunk); - var state = stream._readableState; - - if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else { - var er; - if (!skipChunkCheck) er = chunkInvalid(state, chunk); - - if (er) { - errorOrDestroy(stream, er); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (addToFront) { - if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true); - } else if (state.ended) { - errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); - } else if (state.destroyed) { - return false; - } else { - state.reading = false; - - if (state.decoder && !encoding) { - chunk = state.decoder.write(chunk); - if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); - } else { - addChunk(stream, state, chunk, false); - } - } - } else if (!addToFront) { - state.reading = false; - maybeReadMore(stream, state); - } - } // We can push more data if we are below the highWaterMark. - // Also, if we have no data yet, we can stand some more bytes. - // This is to work around cases where hwm=0, such as the repl. - - - return !state.ended && (state.length < state.highWaterMark || state.length === 0); -} - -function addChunk(stream, state, chunk, addToFront) { - if (state.flowing && state.length === 0 && !state.sync) { - state.awaitDrain = 0; - stream.emit('data', chunk); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - if (state.needReadable) emitReadable(stream); - } - - maybeReadMore(stream, state); -} - -function chunkInvalid(state, chunk) { - var er; - - if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); - } - - return er; -} - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; // backwards compatibility. - - -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - var decoder = new StringDecoder(enc); - this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8 - - this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers: - - var p = this._readableState.buffer.head; - var content = ''; - - while (p !== null) { - content += decoder.write(p.data); - p = p.next; - } - - this._readableState.buffer.clear(); - - if (content !== '') this._readableState.buffer.push(content); - this._readableState.length = content.length; - return this; -}; // Don't raise the hwm > 1GB - - -var MAX_HWM = 0x40000000; - -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - - return n; -} // This function is designed to be inlinable, so please take care when making -// changes to the function body. - - -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } // If we're asking for more than the current hwm, then raise the hwm. - - - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; // Don't have enough - - if (!state.ended) { - state.needReadable = true; - return 0; - } - - return state.length; -} // you can override either this method, or the async _read(n) below. - - -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - - if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. - - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - // if we need a readable event, then we need to do some reading. - - - var doRead = state.needReadable; - debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some - - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - - - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; // if the length is currently zero, then we *need* a readable event. - - if (state.length === 0) state.needReadable = true; // call internal read method - - this._read(state.highWaterMark); - - state.sync = false; // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = state.length <= state.highWaterMark; - n = 0; - } else { - state.length -= n; - state.awaitDrain = 0; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. - - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - return ret; -}; - -function onEofChunk(stream, state) { - debug('onEofChunk'); - if (state.ended) return; - - if (state.decoder) { - var chunk = state.decoder.end(); - - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - - state.ended = true; - - if (state.sync) { - // if we are sync, wait until next tick to emit the data. - // Otherwise we risk emitting data in the flow() - // the readable code triggers during a read() call - emitReadable(stream); - } else { - // emit 'readable' now to make sure it gets picked up. - state.needReadable = false; - - if (!state.emittedReadable) { - state.emittedReadable = true; - emitReadable_(stream); - } - } -} // Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. - - -function emitReadable(stream) { - var state = stream._readableState; - debug('emitReadable', state.needReadable, state.emittedReadable); - state.needReadable = false; - - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - process.nextTick(emitReadable_, stream); - } -} - -function emitReadable_(stream) { - var state = stream._readableState; - debug('emitReadable_', state.destroyed, state.length, state.ended); - - if (!state.destroyed && (state.length || state.ended)) { - stream.emit('readable'); - state.emittedReadable = false; - } // The stream needs another readable event if - // 1. It is not flowing, as the flow mechanism will take - // care of it. - // 2. It is not ended. - // 3. It is below the highWaterMark, so we can schedule - // another readable later. - - - state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; - flow(stream); -} // at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. - - -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - process.nextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - // Attempt to read more data if we should. - // - // The conditions for reading more data are (one of): - // - Not enough data buffered (state.length < state.highWaterMark). The loop - // is responsible for filling the buffer with enough data if such data - // is available. If highWaterMark is 0 and we are not in the flowing mode - // we should _not_ attempt to buffer any extra data. We'll get more data - // when the stream consumer calls read() instead. - // - No data in the buffer, and the stream is in flowing mode. In this mode - // the loop below is responsible for ensuring read() is called. Failing to - // call read here would abort the flow and there's no other mechanism for - // continuing the flow if the stream consumer has just subscribed to the - // 'data' event. - // - // In addition to the above conditions to keep reading data, the following - // conditions prevent the data from being read: - // - The stream has ended (state.ended). - // - There is already a pending 'read' operation (state.reading). This is a - // case where the the stream has called the implementation defined _read() - // method, but they are processing the call asynchronously and have _not_ - // called push() with new data. In this case we skip performing more - // read()s. The execution ends in this method again after the _read() ends - // up calling push() with more data. - while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) { - var len = state.length; - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) // didn't get any data, stop spinning. - break; - } - - state.readingMore = false; -} // abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. - - -Readable.prototype._read = function (n) { - errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - - case 1: - state.pipes = [state.pipes, dest]; - break; - - default: - state.pipes.push(dest); - break; - } - - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn); - dest.on('unpipe', onunpipe); - - function onunpipe(readable, unpipeInfo) { - debug('onunpipe'); - - if (readable === src) { - if (unpipeInfo && unpipeInfo.hasUnpiped === false) { - unpipeInfo.hasUnpiped = true; - cleanup(); - } - } - } - - function onend() { - debug('onend'); - dest.end(); - } // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - - - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - var cleanedUp = false; - - function cleanup() { - debug('cleanup'); // cleanup event handlers once the pipe is broken - - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', unpipe); - src.removeListener('data', ondata); - cleanedUp = true; // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - src.on('data', ondata); - - function ondata(chunk) { - debug('ondata'); - var ret = dest.write(chunk); - debug('dest.write', ret); - - if (ret === false) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', state.awaitDrain); - state.awaitDrain++; - } - - src.pause(); - } - } // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - - - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er); - } // Make sure our error handler is attached before userland ones. - - - prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once. - - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - - dest.once('close', onclose); - - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } // tell the dest that it's being piped to - - - dest.emit('pipe', src); // start the flow if it hasn't been started already. - - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function pipeOnDrainFunctionResult() { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - var unpipeInfo = { - hasUnpiped: false - }; // if we're not piping anywhere, then do nothing. - - if (state.pipesCount === 0) return this; // just one destination. most common case. - - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - if (!dest) dest = state.pipes; // got a match. - - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this, unpipeInfo); - return this; - } // slow case. multiple pipe destinations. - - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this, { - hasUnpiped: false - }); - } - - return this; - } // try to find the right one. - - - var index = indexOf(state.pipes, dest); - if (index === -1) return this; - state.pipes.splice(index, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - dest.emit('unpipe', this, unpipeInfo); - return this; -}; // set up data events if they are asked for -// Ensure readable listeners eventually get something - - -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - var state = this._readableState; - - if (ev === 'data') { - // update readableListening so that resume() may be a no-op - // a few lines down. This is needed to support once('readable'). - state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused - - if (state.flowing !== false) this.resume(); - } else if (ev === 'readable') { - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.flowing = false; - state.emittedReadable = false; - debug('on readable', state.length, state.reading); - - if (state.length) { - emitReadable(this); - } else if (!state.reading) { - process.nextTick(nReadingNextTick, this); - } - } - } - - return res; -}; - -Readable.prototype.addListener = Readable.prototype.on; - -Readable.prototype.removeListener = function (ev, fn) { - var res = Stream.prototype.removeListener.call(this, ev, fn); - - if (ev === 'readable') { - // We need to check if there is someone still listening to - // readable and reset the state. However this needs to happen - // after readable has been emitted but before I/O (nextTick) to - // support once('readable', fn) cycles. This means that calling - // resume within the same tick will have no - // effect. - process.nextTick(updateReadableListening, this); - } - - return res; -}; - -Readable.prototype.removeAllListeners = function (ev) { - var res = Stream.prototype.removeAllListeners.apply(this, arguments); - - if (ev === 'readable' || ev === undefined) { - // We need to check if there is someone still listening to - // readable and reset the state. However this needs to happen - // after readable has been emitted but before I/O (nextTick) to - // support once('readable', fn) cycles. This means that calling - // resume within the same tick will have no - // effect. - process.nextTick(updateReadableListening, this); - } - - return res; -}; - -function updateReadableListening(self) { - var state = self._readableState; - state.readableListening = self.listenerCount('readable') > 0; - - if (state.resumeScheduled && !state.paused) { - // flowing needs to be set to true now, otherwise - // the upcoming resume will not flow. - state.flowing = true; // crude way to check if we should resume - } else if (self.listenerCount('data') > 0) { - self.resume(); - } -} - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} // pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. - - -Readable.prototype.resume = function () { - var state = this._readableState; - - if (!state.flowing) { - debug('resume'); // we flow only if there is no one listening - // for readable, but we still have to call - // resume() - - state.flowing = !state.readableListening; - resume(this, state); - } - - state.paused = false; - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - process.nextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - debug('resume', state.reading); - - if (!state.reading) { - stream.read(0); - } - - state.resumeScheduled = false; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - - if (this._readableState.flowing !== false) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - - this._readableState.paused = true; - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - - while (state.flowing && stream.read() !== null) { - ; - } -} // wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. - - -Readable.prototype.wrap = function (stream) { - var _this = this; - - var state = this._readableState; - var paused = false; - stream.on('end', function () { - debug('wrapped end'); - - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) _this.push(chunk); - } - - _this.push(null); - }); - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode - - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = _this.push(chunk); - - if (!ret) { - paused = true; - stream.pause(); - } - }); // proxy all the other methods. - // important when wrapping filters and duplexes. - - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function methodWrap(method) { - return function methodWrapReturnFunction() { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } // proxy certain important events. - - - for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); - } // when we try to consume some more bytes, simply unpause the - // underlying stream. - - - this._read = function (n) { - debug('wrapped _read', n); - - if (paused) { - paused = false; - stream.resume(); - } - }; - - return this; -}; - -if (typeof Symbol === 'function') { - Readable.prototype[Symbol.asyncIterator] = function () { - if (createReadableStreamAsyncIterator === undefined) { - createReadableStreamAsyncIterator = require('./internal/streams/async_iterator'); - } - - return createReadableStreamAsyncIterator(this); - }; -} - -Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState.highWaterMark; - } -}); -Object.defineProperty(Readable.prototype, 'readableBuffer', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState && this._readableState.buffer; - } -}); -Object.defineProperty(Readable.prototype, 'readableFlowing', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState.flowing; - }, - set: function set(state) { - if (this._readableState) { - this._readableState.flowing = state; - } - } -}); // exposed for testing purposes only. - -Readable._fromList = fromList; -Object.defineProperty(Readable.prototype, 'readableLength', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._readableState.length; - } -}); // Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. - -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = state.buffer.consume(n, state.decoder); - } - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - debug('endReadable', state.endEmitted); - - if (!state.endEmitted) { - state.ended = true; - process.nextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift. - - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - - if (state.autoDestroy) { - // In case of duplex streams we need a way to detect - // if the writable side is ready for autoDestroy as well - var wState = stream._writableState; - - if (!wState || wState.autoDestroy && wState.finished) { - stream.destroy(); - } - } - } -} - -if (typeof Symbol === 'function') { - Readable.from = function (iterable, opts) { - if (from === undefined) { - from = require('./internal/streams/from'); - } - - return from(Readable, iterable, opts); - }; -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - - return -1; -} \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/readable-stream/lib/_stream_transform.js deleted file mode 100644 index 41a738c4e9359..0000000000000 --- a/node_modules/readable-stream/lib/_stream_transform.js +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. -'use strict'; - -module.exports = Transform; - -var _require$codes = require('../errors').codes, - ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, - ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, - ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING, - ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0; - -var Duplex = require('./_stream_duplex'); - -require('inherits')(Transform, Duplex); - -function afterTransform(er, data) { - var ts = this._transformState; - ts.transforming = false; - var cb = ts.writecb; - - if (cb === null) { - return this.emit('error', new ERR_MULTIPLE_CALLBACK()); - } - - ts.writechunk = null; - ts.writecb = null; - if (data != null) // single equals check for both `null` and `undefined` - this.push(data); - cb(er); - var rs = this._readableState; - rs.reading = false; - - if (rs.needReadable || rs.length < rs.highWaterMark) { - this._read(rs.highWaterMark); - } -} - -function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - Duplex.call(this, options); - this._transformState = { - afterTransform: afterTransform.bind(this), - needTransform: false, - transforming: false, - writecb: null, - writechunk: null, - writeencoding: null - }; // start out asking for a readable event once data is transformed. - - this._readableState.needReadable = true; // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - - this._readableState.sync = false; - - if (options) { - if (typeof options.transform === 'function') this._transform = options.transform; - if (typeof options.flush === 'function') this._flush = options.flush; - } // When the writable side finishes, then flush out anything remaining. - - - this.on('prefinish', prefinish); -} - -function prefinish() { - var _this = this; - - if (typeof this._flush === 'function' && !this._readableState.destroyed) { - this._flush(function (er, data) { - done(_this, er, data); - }); - } else { - done(this, null, null); - } -} - -Transform.prototype.push = function (chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; // This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. - - -Transform.prototype._transform = function (chunk, encoding, cb) { - cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()')); -}; - -Transform.prototype._write = function (chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); - } -}; // Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. - - -Transform.prototype._read = function (n) { - var ts = this._transformState; - - if (ts.writechunk !== null && !ts.transforming) { - ts.transforming = true; - - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } -}; - -Transform.prototype._destroy = function (err, cb) { - Duplex.prototype._destroy.call(this, err, function (err2) { - cb(err2); - }); -}; - -function done(stream, er, data) { - if (er) return stream.emit('error', er); - if (data != null) // single equals check for both `null` and `undefined` - stream.push(data); // TODO(BridgeAR): Write a test for these two error cases - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - - if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0(); - if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING(); - return stream.push(null); -} \ No newline at end of file diff --git a/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/readable-stream/lib/_stream_writable.js deleted file mode 100644 index a2634d7c24fd5..0000000000000 --- a/node_modules/readable-stream/lib/_stream_writable.js +++ /dev/null @@ -1,697 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. -'use strict'; - -module.exports = Writable; -/* <replacement> */ - -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} // It seems a linked list but it is not -// there will be only 2 of these for each stream - - -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - - this.finish = function () { - onCorkedFinish(_this, state); - }; -} -/* </replacement> */ - -/*<replacement>*/ - - -var Duplex; -/*</replacement>*/ - -Writable.WritableState = WritableState; -/*<replacement>*/ - -var internalUtil = { - deprecate: require('util-deprecate') -}; -/*</replacement>*/ - -/*<replacement>*/ - -var Stream = require('./internal/streams/stream'); -/*</replacement>*/ - - -var Buffer = require('buffer').Buffer; - -var OurUint8Array = global.Uint8Array || function () {}; - -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} - -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} - -var destroyImpl = require('./internal/streams/destroy'); - -var _require = require('./internal/streams/state'), - getHighWaterMark = _require.getHighWaterMark; - -var _require$codes = require('../errors').codes, - ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, - ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, - ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, - ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE, - ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED, - ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES, - ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END, - ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING; - -var errorOrDestroy = destroyImpl.errorOrDestroy; - -require('inherits')(Writable, Stream); - -function nop() {} - -function WritableState(options, stream, isDuplex) { - Duplex = Duplex || require('./_stream_duplex'); - options = options || {}; // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream, - // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. - - if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag to indicate whether or not this stream - // contains buffers or objects. - - this.objectMode = !!options.objectMode; - if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - - this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); // if _final has been called - - this.finalCalled = false; // drain event flag. - - this.needDrain = false; // at the start of calling end() - - this.ending = false; // when end() has been called, and returned - - this.ended = false; // when 'finish' is emitted - - this.finished = false; // has it been destroyed - - this.destroyed = false; // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - - this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - - this.length = 0; // a flag to see when we're in the middle of a write. - - this.writing = false; // when true all writes will be buffered until .uncork() call - - this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - - this.sync = true; // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - - this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) - - this.onwrite = function (er) { - onwrite(stream, er); - }; // the callback that the user supplies to write(chunk,encoding,cb) - - - this.writecb = null; // the amount that is being written when _write is called. - - this.writelen = 0; - this.bufferedRequest = null; - this.lastBufferedRequest = null; // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - - this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - - this.prefinished = false; // True if the error was already emitted and should not be thrown again - - this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true. - - this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'finish' (and potentially 'end') - - this.autoDestroy = !!options.autoDestroy; // count buffered requests - - this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - - this.corkedRequestsFree = new CorkedRequest(this); -} - -WritableState.prototype.getBuffer = function getBuffer() { - var current = this.bufferedRequest; - var out = []; - - while (current) { - out.push(current); - current = current.next; - } - - return out; -}; - -(function () { - try { - Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function writableStateBufferGetter() { - return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') - }); - } catch (_) {} -})(); // Test _writableState for inheritance to account for Duplex streams, -// whose prototype chain only points to Readable. - - -var realHasInstance; - -if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { - realHasInstance = Function.prototype[Symbol.hasInstance]; - Object.defineProperty(Writable, Symbol.hasInstance, { - value: function value(object) { - if (realHasInstance.call(this, object)) return true; - if (this !== Writable) return false; - return object && object._writableState instanceof WritableState; - } - }); -} else { - realHasInstance = function realHasInstance(object) { - return object instanceof this; - }; -} - -function Writable(options) { - Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too. - // `realHasInstance` is necessary because using plain `instanceof` - // would return false, as no `_writableState` property is attached. - // Trying to use the custom `instanceof` for Writable here will also break the - // Node.js LazyTransform implementation, which has a non-trivial getter for - // `_writableState` that would lead to infinite recursion. - // Checking for a Stream.Duplex instance is faster here instead of inside - // the WritableState constructor, at least with V8 6.5 - - var isDuplex = this instanceof Duplex; - if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options); - this._writableState = new WritableState(options, this, isDuplex); // legacy. - - this.writable = true; - - if (options) { - if (typeof options.write === 'function') this._write = options.write; - if (typeof options.writev === 'function') this._writev = options.writev; - if (typeof options.destroy === 'function') this._destroy = options.destroy; - if (typeof options.final === 'function') this._final = options.final; - } - - Stream.call(this); -} // Otherwise people can pipe Writable streams, which is just wrong. - - -Writable.prototype.pipe = function () { - errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); -}; - -function writeAfterEnd(stream, cb) { - var er = new ERR_STREAM_WRITE_AFTER_END(); // TODO: defer error events consistently everywhere, not just the cb - - errorOrDestroy(stream, er); - process.nextTick(cb, er); -} // Checks that a user-supplied chunk is valid, especially for the particular -// mode the stream is in. Currently this means that `null` is never accepted -// and undefined/non-string values are only allowed in object mode. - - -function validChunk(stream, state, chunk, cb) { - var er; - - if (chunk === null) { - er = new ERR_STREAM_NULL_VALUES(); - } else if (typeof chunk !== 'string' && !state.objectMode) { - er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk); - } - - if (er) { - errorOrDestroy(stream, er); - process.nextTick(cb, er); - return false; - } - - return true; -} - -Writable.prototype.write = function (chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - - var isBuf = !state.objectMode && _isUint8Array(chunk); - - if (isBuf && !Buffer.isBuffer(chunk)) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; - if (typeof cb !== 'function') cb = nop; - if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { - state.pendingcb++; - ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); - } - return ret; -}; - -Writable.prototype.cork = function () { - this._writableState.corked++; -}; - -Writable.prototype.uncork = function () { - var state = this._writableState; - - if (state.corked) { - state.corked--; - if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); - } -}; - -Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { - // node::ParseEncoding() requires lower case. - if (typeof encoding === 'string') encoding = encoding.toLowerCase(); - if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding); - this._writableState.defaultEncoding = encoding; - return this; -}; - -Object.defineProperty(Writable.prototype, 'writableBuffer', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._writableState && this._writableState.getBuffer(); - } -}); - -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = Buffer.from(chunk, encoding); - } - - return chunk; -} - -Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._writableState.highWaterMark; - } -}); // if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. - -function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { - if (!isBuf) { - var newChunk = decodeChunk(state, chunk, encoding); - - if (chunk !== newChunk) { - isBuf = true; - encoding = 'buffer'; - chunk = newChunk; - } - } - - var len = state.objectMode ? 1 : chunk.length; - state.length += len; - var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. - - if (!ret) state.needDrain = true; - - if (state.writing || state.corked) { - var last = state.lastBufferedRequest; - state.lastBufferedRequest = { - chunk: chunk, - encoding: encoding, - isBuf: isBuf, - callback: cb, - next: null - }; - - if (last) { - last.next = state.lastBufferedRequest; - } else { - state.bufferedRequest = state.lastBufferedRequest; - } - - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - - if (sync) { - // defer the callback if we are being called synchronously - // to avoid piling up things on the stack - process.nextTick(cb, er); // this can emit finish, and it will always happen - // after error - - process.nextTick(finishMaybe, stream, state); - stream._writableState.errorEmitted = true; - errorOrDestroy(stream, er); - } else { - // the caller expect this to happen before if - // it is async - cb(er); - stream._writableState.errorEmitted = true; - errorOrDestroy(stream, er); // this can emit finish, but finish must - // always follow error - - finishMaybe(stream, state); - } -} - -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} - -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; - if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK(); - onwriteStateUpdate(state); - if (er) onwriteError(stream, state, sync, er, cb);else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(state) || stream.destroyed; - - if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { - clearBuffer(stream, state); - } - - if (sync) { - process.nextTick(afterWrite, stream, state, finished, cb); - } else { - afterWrite(stream, state, finished, cb); - } - } -} - -function afterWrite(stream, state, finished, cb) { - if (!finished) onwriteDrain(stream, state); - state.pendingcb--; - cb(); - finishMaybe(stream, state); -} // Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. - - -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } -} // if there's something in the buffer waiting, then process it - - -function clearBuffer(stream, state) { - state.bufferProcessing = true; - var entry = state.bufferedRequest; - - if (stream._writev && entry && entry.next) { - // Fast case, write everything using _writev() - var l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - var count = 0; - var allBuffers = true; - - while (entry) { - buffer[count] = entry; - if (!entry.isBuf) allBuffers = false; - entry = entry.next; - count += 1; - } - - buffer.allBuffers = allBuffers; - doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - - state.pendingcb++; - state.lastBufferedRequest = null; - - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - state.corkedRequestsFree = new CorkedRequest(state); - } - - state.bufferedRequestCount = 0; - } else { - // Slow case, write chunks one-by-one - while (entry) { - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - doWrite(stream, state, false, len, chunk, encoding, cb); - entry = entry.next; - state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - - if (state.writing) { - break; - } - } - - if (entry === null) state.lastBufferedRequest = null; - } - - state.bufferedRequest = entry; - state.bufferProcessing = false; -} - -Writable.prototype._write = function (chunk, encoding, cb) { - cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()')); -}; - -Writable.prototype._writev = null; - -Writable.prototype.end = function (chunk, encoding, cb) { - var state = this._writableState; - - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks - - if (state.corked) { - state.corked = 1; - this.uncork(); - } // ignore unnecessary end() calls. - - - if (!state.ending) endWritable(this, state, cb); - return this; -}; - -Object.defineProperty(Writable.prototype, 'writableLength', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - return this._writableState.length; - } -}); - -function needFinish(state) { - return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; -} - -function callFinal(stream, state) { - stream._final(function (err) { - state.pendingcb--; - - if (err) { - errorOrDestroy(stream, err); - } - - state.prefinished = true; - stream.emit('prefinish'); - finishMaybe(stream, state); - }); -} - -function prefinish(stream, state) { - if (!state.prefinished && !state.finalCalled) { - if (typeof stream._final === 'function' && !state.destroyed) { - state.pendingcb++; - state.finalCalled = true; - process.nextTick(callFinal, stream, state); - } else { - state.prefinished = true; - stream.emit('prefinish'); - } - } -} - -function finishMaybe(stream, state) { - var need = needFinish(state); - - if (need) { - prefinish(stream, state); - - if (state.pendingcb === 0) { - state.finished = true; - stream.emit('finish'); - - if (state.autoDestroy) { - // In case of duplex streams we need a way to detect - // if the readable side is ready for autoDestroy as well - var rState = stream._readableState; - - if (!rState || rState.autoDestroy && rState.endEmitted) { - stream.destroy(); - } - } - } - } - - return need; -} - -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - - if (cb) { - if (state.finished) process.nextTick(cb);else stream.once('finish', cb); - } - - state.ended = true; - stream.writable = false; -} - -function onCorkedFinish(corkReq, state, err) { - var entry = corkReq.entry; - corkReq.entry = null; - - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } // reuse the free corkReq. - - - state.corkedRequestsFree.next = corkReq; -} - -Object.defineProperty(Writable.prototype, 'destroyed', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function get() { - if (this._writableState === undefined) { - return false; - } - - return this._writableState.destroyed; - }, - set: function set(value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._writableState) { - return; - } // backward compatibility, the user is explicitly - // managing destroyed - - - this._writableState.destroyed = value; - } -}); -Writable.prototype.destroy = destroyImpl.destroy; -Writable.prototype._undestroy = destroyImpl.undestroy; - -Writable.prototype._destroy = function (err, cb) { - cb(err); -}; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/async_iterator.js b/node_modules/readable-stream/lib/internal/streams/async_iterator.js deleted file mode 100644 index 9fb615a2f3bc4..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/async_iterator.js +++ /dev/null @@ -1,207 +0,0 @@ -'use strict'; - -var _Object$setPrototypeO; - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var finished = require('./end-of-stream'); - -var kLastResolve = Symbol('lastResolve'); -var kLastReject = Symbol('lastReject'); -var kError = Symbol('error'); -var kEnded = Symbol('ended'); -var kLastPromise = Symbol('lastPromise'); -var kHandlePromise = Symbol('handlePromise'); -var kStream = Symbol('stream'); - -function createIterResult(value, done) { - return { - value: value, - done: done - }; -} - -function readAndResolve(iter) { - var resolve = iter[kLastResolve]; - - if (resolve !== null) { - var data = iter[kStream].read(); // we defer if data is null - // we can be expecting either 'end' or - // 'error' - - if (data !== null) { - iter[kLastPromise] = null; - iter[kLastResolve] = null; - iter[kLastReject] = null; - resolve(createIterResult(data, false)); - } - } -} - -function onReadable(iter) { - // we wait for the next tick, because it might - // emit an error with process.nextTick - process.nextTick(readAndResolve, iter); -} - -function wrapForNext(lastPromise, iter) { - return function (resolve, reject) { - lastPromise.then(function () { - if (iter[kEnded]) { - resolve(createIterResult(undefined, true)); - return; - } - - iter[kHandlePromise](resolve, reject); - }, reject); - }; -} - -var AsyncIteratorPrototype = Object.getPrototypeOf(function () {}); -var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = { - get stream() { - return this[kStream]; - }, - - next: function next() { - var _this = this; - - // if we have detected an error in the meanwhile - // reject straight away - var error = this[kError]; - - if (error !== null) { - return Promise.reject(error); - } - - if (this[kEnded]) { - return Promise.resolve(createIterResult(undefined, true)); - } - - if (this[kStream].destroyed) { - // We need to defer via nextTick because if .destroy(err) is - // called, the error will be emitted via nextTick, and - // we cannot guarantee that there is no error lingering around - // waiting to be emitted. - return new Promise(function (resolve, reject) { - process.nextTick(function () { - if (_this[kError]) { - reject(_this[kError]); - } else { - resolve(createIterResult(undefined, true)); - } - }); - }); - } // if we have multiple next() calls - // we will wait for the previous Promise to finish - // this logic is optimized to support for await loops, - // where next() is only called once at a time - - - var lastPromise = this[kLastPromise]; - var promise; - - if (lastPromise) { - promise = new Promise(wrapForNext(lastPromise, this)); - } else { - // fast path needed to support multiple this.push() - // without triggering the next() queue - var data = this[kStream].read(); - - if (data !== null) { - return Promise.resolve(createIterResult(data, false)); - } - - promise = new Promise(this[kHandlePromise]); - } - - this[kLastPromise] = promise; - return promise; - } -}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () { - return this; -}), _defineProperty(_Object$setPrototypeO, "return", function _return() { - var _this2 = this; - - // destroy(err, cb) is a private API - // we can guarantee we have that here, because we control the - // Readable class this is attached to - return new Promise(function (resolve, reject) { - _this2[kStream].destroy(null, function (err) { - if (err) { - reject(err); - return; - } - - resolve(createIterResult(undefined, true)); - }); - }); -}), _Object$setPrototypeO), AsyncIteratorPrototype); - -var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) { - var _Object$create; - - var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, { - value: stream, - writable: true - }), _defineProperty(_Object$create, kLastResolve, { - value: null, - writable: true - }), _defineProperty(_Object$create, kLastReject, { - value: null, - writable: true - }), _defineProperty(_Object$create, kError, { - value: null, - writable: true - }), _defineProperty(_Object$create, kEnded, { - value: stream._readableState.endEmitted, - writable: true - }), _defineProperty(_Object$create, kHandlePromise, { - value: function value(resolve, reject) { - var data = iterator[kStream].read(); - - if (data) { - iterator[kLastPromise] = null; - iterator[kLastResolve] = null; - iterator[kLastReject] = null; - resolve(createIterResult(data, false)); - } else { - iterator[kLastResolve] = resolve; - iterator[kLastReject] = reject; - } - }, - writable: true - }), _Object$create)); - iterator[kLastPromise] = null; - finished(stream, function (err) { - if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') { - var reject = iterator[kLastReject]; // reject if we are waiting for data in the Promise - // returned by next() and store the error - - if (reject !== null) { - iterator[kLastPromise] = null; - iterator[kLastResolve] = null; - iterator[kLastReject] = null; - reject(err); - } - - iterator[kError] = err; - return; - } - - var resolve = iterator[kLastResolve]; - - if (resolve !== null) { - iterator[kLastPromise] = null; - iterator[kLastResolve] = null; - iterator[kLastReject] = null; - resolve(createIterResult(undefined, true)); - } - - iterator[kEnded] = true; - }); - stream.on('readable', onReadable.bind(null, iterator)); - return iterator; -}; - -module.exports = createReadableStreamAsyncIterator; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/buffer_list.js b/node_modules/readable-stream/lib/internal/streams/buffer_list.js deleted file mode 100644 index cdea425f19dd9..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/buffer_list.js +++ /dev/null @@ -1,210 +0,0 @@ -'use strict'; - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -var _require = require('buffer'), - Buffer = _require.Buffer; - -var _require2 = require('util'), - inspect = _require2.inspect; - -var custom = inspect && inspect.custom || 'inspect'; - -function copyBuffer(src, target, offset) { - Buffer.prototype.copy.call(src, target, offset); -} - -module.exports = -/*#__PURE__*/ -function () { - function BufferList() { - _classCallCheck(this, BufferList); - - this.head = null; - this.tail = null; - this.length = 0; - } - - _createClass(BufferList, [{ - key: "push", - value: function push(v) { - var entry = { - data: v, - next: null - }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; - } - }, { - key: "unshift", - value: function unshift(v) { - var entry = { - data: v, - next: this.head - }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; - } - }, { - key: "shift", - value: function shift() { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; - } - }, { - key: "clear", - value: function clear() { - this.head = this.tail = null; - this.length = 0; - } - }, { - key: "join", - value: function join(s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - - while (p = p.next) { - ret += s + p.data; - } - - return ret; - } - }, { - key: "concat", - value: function concat(n) { - if (this.length === 0) return Buffer.alloc(0); - var ret = Buffer.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - - while (p) { - copyBuffer(p.data, ret, i); - i += p.data.length; - p = p.next; - } - - return ret; - } // Consumes a specified amount of bytes or characters from the buffered data. - - }, { - key: "consume", - value: function consume(n, hasStrings) { - var ret; - - if (n < this.head.data.length) { - // `slice` is the same for buffers and strings. - ret = this.head.data.slice(0, n); - this.head.data = this.head.data.slice(n); - } else if (n === this.head.data.length) { - // First chunk is a perfect match. - ret = this.shift(); - } else { - // Result spans more than one buffer. - ret = hasStrings ? this._getString(n) : this._getBuffer(n); - } - - return ret; - } - }, { - key: "first", - value: function first() { - return this.head.data; - } // Consumes a specified amount of characters from the buffered data. - - }, { - key: "_getString", - value: function _getString(n) { - var p = this.head; - var c = 1; - var ret = p.data; - n -= ret.length; - - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) this.head = p.next;else this.head = this.tail = null; - } else { - this.head = p; - p.data = str.slice(nb); - } - - break; - } - - ++c; - } - - this.length -= c; - return ret; - } // Consumes a specified amount of bytes from the buffered data. - - }, { - key: "_getBuffer", - value: function _getBuffer(n) { - var ret = Buffer.allocUnsafe(n); - var p = this.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) this.head = p.next;else this.head = this.tail = null; - } else { - this.head = p; - p.data = buf.slice(nb); - } - - break; - } - - ++c; - } - - this.length -= c; - return ret; - } // Make sure the linked list only shows the minimal necessary information. - - }, { - key: custom, - value: function value(_, options) { - return inspect(this, _objectSpread({}, options, { - // Only inspect one level. - depth: 0, - // It should not recurse. - customInspect: false - })); - } - }]); - - return BufferList; -}(); \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/destroy.js b/node_modules/readable-stream/lib/internal/streams/destroy.js deleted file mode 100644 index 3268a16f3b6f2..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/destroy.js +++ /dev/null @@ -1,105 +0,0 @@ -'use strict'; // undocumented cb() API, needed for core, not for public API - -function destroy(err, cb) { - var _this = this; - - var readableDestroyed = this._readableState && this._readableState.destroyed; - var writableDestroyed = this._writableState && this._writableState.destroyed; - - if (readableDestroyed || writableDestroyed) { - if (cb) { - cb(err); - } else if (err) { - if (!this._writableState) { - process.nextTick(emitErrorNT, this, err); - } else if (!this._writableState.errorEmitted) { - this._writableState.errorEmitted = true; - process.nextTick(emitErrorNT, this, err); - } - } - - return this; - } // we set destroyed to true before firing error callbacks in order - // to make it re-entrance safe in case destroy() is called within callbacks - - - if (this._readableState) { - this._readableState.destroyed = true; - } // if this is a duplex stream mark the writable part as destroyed as well - - - if (this._writableState) { - this._writableState.destroyed = true; - } - - this._destroy(err || null, function (err) { - if (!cb && err) { - if (!_this._writableState) { - process.nextTick(emitErrorAndCloseNT, _this, err); - } else if (!_this._writableState.errorEmitted) { - _this._writableState.errorEmitted = true; - process.nextTick(emitErrorAndCloseNT, _this, err); - } else { - process.nextTick(emitCloseNT, _this); - } - } else if (cb) { - process.nextTick(emitCloseNT, _this); - cb(err); - } else { - process.nextTick(emitCloseNT, _this); - } - }); - - return this; -} - -function emitErrorAndCloseNT(self, err) { - emitErrorNT(self, err); - emitCloseNT(self); -} - -function emitCloseNT(self) { - if (self._writableState && !self._writableState.emitClose) return; - if (self._readableState && !self._readableState.emitClose) return; - self.emit('close'); -} - -function undestroy() { - if (this._readableState) { - this._readableState.destroyed = false; - this._readableState.reading = false; - this._readableState.ended = false; - this._readableState.endEmitted = false; - } - - if (this._writableState) { - this._writableState.destroyed = false; - this._writableState.ended = false; - this._writableState.ending = false; - this._writableState.finalCalled = false; - this._writableState.prefinished = false; - this._writableState.finished = false; - this._writableState.errorEmitted = false; - } -} - -function emitErrorNT(self, err) { - self.emit('error', err); -} - -function errorOrDestroy(stream, err) { - // We have tests that rely on errors being emitted - // in the same tick, so changing this is semver major. - // For now when you opt-in to autoDestroy we allow - // the error to be emitted nextTick. In a future - // semver major update we should change the default to this. - var rState = stream._readableState; - var wState = stream._writableState; - if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err); -} - -module.exports = { - destroy: destroy, - undestroy: undestroy, - errorOrDestroy: errorOrDestroy -}; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/end-of-stream.js b/node_modules/readable-stream/lib/internal/streams/end-of-stream.js deleted file mode 100644 index 831f286d98fa9..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +++ /dev/null @@ -1,104 +0,0 @@ -// Ported from https://github.com/mafintosh/end-of-stream with -// permission from the author, Mathias Buus (@mafintosh). -'use strict'; - -var ERR_STREAM_PREMATURE_CLOSE = require('../../../errors').codes.ERR_STREAM_PREMATURE_CLOSE; - -function once(callback) { - var called = false; - return function () { - if (called) return; - called = true; - - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - callback.apply(this, args); - }; -} - -function noop() {} - -function isRequest(stream) { - return stream.setHeader && typeof stream.abort === 'function'; -} - -function eos(stream, opts, callback) { - if (typeof opts === 'function') return eos(stream, null, opts); - if (!opts) opts = {}; - callback = once(callback || noop); - var readable = opts.readable || opts.readable !== false && stream.readable; - var writable = opts.writable || opts.writable !== false && stream.writable; - - var onlegacyfinish = function onlegacyfinish() { - if (!stream.writable) onfinish(); - }; - - var writableEnded = stream._writableState && stream._writableState.finished; - - var onfinish = function onfinish() { - writable = false; - writableEnded = true; - if (!readable) callback.call(stream); - }; - - var readableEnded = stream._readableState && stream._readableState.endEmitted; - - var onend = function onend() { - readable = false; - readableEnded = true; - if (!writable) callback.call(stream); - }; - - var onerror = function onerror(err) { - callback.call(stream, err); - }; - - var onclose = function onclose() { - var err; - - if (readable && !readableEnded) { - if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); - return callback.call(stream, err); - } - - if (writable && !writableEnded) { - if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); - return callback.call(stream, err); - } - }; - - var onrequest = function onrequest() { - stream.req.on('finish', onfinish); - }; - - if (isRequest(stream)) { - stream.on('complete', onfinish); - stream.on('abort', onclose); - if (stream.req) onrequest();else stream.on('request', onrequest); - } else if (writable && !stream._writableState) { - // legacy streams - stream.on('end', onlegacyfinish); - stream.on('close', onlegacyfinish); - } - - stream.on('end', onend); - stream.on('finish', onfinish); - if (opts.error !== false) stream.on('error', onerror); - stream.on('close', onclose); - return function () { - stream.removeListener('complete', onfinish); - stream.removeListener('abort', onclose); - stream.removeListener('request', onrequest); - if (stream.req) stream.req.removeListener('finish', onfinish); - stream.removeListener('end', onlegacyfinish); - stream.removeListener('close', onlegacyfinish); - stream.removeListener('finish', onfinish); - stream.removeListener('end', onend); - stream.removeListener('error', onerror); - stream.removeListener('close', onclose); - }; -} - -module.exports = eos; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/from-browser.js b/node_modules/readable-stream/lib/internal/streams/from-browser.js deleted file mode 100644 index a4ce56f3c90f6..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/from-browser.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function () { - throw new Error('Readable.from is not available in the browser') -}; diff --git a/node_modules/readable-stream/lib/internal/streams/from.js b/node_modules/readable-stream/lib/internal/streams/from.js deleted file mode 100644 index 6c41284416799..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/from.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } - -function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var ERR_INVALID_ARG_TYPE = require('../../../errors').codes.ERR_INVALID_ARG_TYPE; - -function from(Readable, iterable, opts) { - var iterator; - - if (iterable && typeof iterable.next === 'function') { - iterator = iterable; - } else if (iterable && iterable[Symbol.asyncIterator]) iterator = iterable[Symbol.asyncIterator]();else if (iterable && iterable[Symbol.iterator]) iterator = iterable[Symbol.iterator]();else throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable); - - var readable = new Readable(_objectSpread({ - objectMode: true - }, opts)); // Reading boolean to protect against _read - // being called before last iteration completion. - - var reading = false; - - readable._read = function () { - if (!reading) { - reading = true; - next(); - } - }; - - function next() { - return _next2.apply(this, arguments); - } - - function _next2() { - _next2 = _asyncToGenerator(function* () { - try { - var _ref = yield iterator.next(), - value = _ref.value, - done = _ref.done; - - if (done) { - readable.push(null); - } else if (readable.push((yield value))) { - next(); - } else { - reading = false; - } - } catch (err) { - readable.destroy(err); - } - }); - return _next2.apply(this, arguments); - } - - return readable; -} - -module.exports = from; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/pipeline.js b/node_modules/readable-stream/lib/internal/streams/pipeline.js deleted file mode 100644 index 6589909889c58..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/pipeline.js +++ /dev/null @@ -1,97 +0,0 @@ -// Ported from https://github.com/mafintosh/pump with -// permission from the author, Mathias Buus (@mafintosh). -'use strict'; - -var eos; - -function once(callback) { - var called = false; - return function () { - if (called) return; - called = true; - callback.apply(void 0, arguments); - }; -} - -var _require$codes = require('../../../errors').codes, - ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, - ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED; - -function noop(err) { - // Rethrow the error if it exists to avoid swallowing it - if (err) throw err; -} - -function isRequest(stream) { - return stream.setHeader && typeof stream.abort === 'function'; -} - -function destroyer(stream, reading, writing, callback) { - callback = once(callback); - var closed = false; - stream.on('close', function () { - closed = true; - }); - if (eos === undefined) eos = require('./end-of-stream'); - eos(stream, { - readable: reading, - writable: writing - }, function (err) { - if (err) return callback(err); - closed = true; - callback(); - }); - var destroyed = false; - return function (err) { - if (closed) return; - if (destroyed) return; - destroyed = true; // request.destroy just do .end - .abort is what we want - - if (isRequest(stream)) return stream.abort(); - if (typeof stream.destroy === 'function') return stream.destroy(); - callback(err || new ERR_STREAM_DESTROYED('pipe')); - }; -} - -function call(fn) { - fn(); -} - -function pipe(from, to) { - return from.pipe(to); -} - -function popCallback(streams) { - if (!streams.length) return noop; - if (typeof streams[streams.length - 1] !== 'function') return noop; - return streams.pop(); -} - -function pipeline() { - for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { - streams[_key] = arguments[_key]; - } - - var callback = popCallback(streams); - if (Array.isArray(streams[0])) streams = streams[0]; - - if (streams.length < 2) { - throw new ERR_MISSING_ARGS('streams'); - } - - var error; - var destroys = streams.map(function (stream, i) { - var reading = i < streams.length - 1; - var writing = i > 0; - return destroyer(stream, reading, writing, function (err) { - if (!error) error = err; - if (err) destroys.forEach(call); - if (reading) return; - destroys.forEach(call); - callback(error); - }); - }); - return streams.reduce(pipe); -} - -module.exports = pipeline; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/state.js b/node_modules/readable-stream/lib/internal/streams/state.js deleted file mode 100644 index 19887eb8a9070..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/state.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -var ERR_INVALID_OPT_VALUE = require('../../../errors').codes.ERR_INVALID_OPT_VALUE; - -function highWaterMarkFrom(options, isDuplex, duplexKey) { - return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null; -} - -function getHighWaterMark(state, options, duplexKey, isDuplex) { - var hwm = highWaterMarkFrom(options, isDuplex, duplexKey); - - if (hwm != null) { - if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) { - var name = isDuplex ? duplexKey : 'highWaterMark'; - throw new ERR_INVALID_OPT_VALUE(name, hwm); - } - - return Math.floor(hwm); - } // Default value - - - return state.objectMode ? 16 : 16 * 1024; -} - -module.exports = { - getHighWaterMark: getHighWaterMark -}; \ No newline at end of file diff --git a/node_modules/readable-stream/lib/internal/streams/stream-browser.js b/node_modules/readable-stream/lib/internal/streams/stream-browser.js deleted file mode 100644 index 9332a3fdae706..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/stream-browser.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('events').EventEmitter; diff --git a/node_modules/readable-stream/lib/internal/streams/stream.js b/node_modules/readable-stream/lib/internal/streams/stream.js deleted file mode 100644 index ce2ad5b6ee57f..0000000000000 --- a/node_modules/readable-stream/lib/internal/streams/stream.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('stream'); diff --git a/node_modules/readable-stream/package.json b/node_modules/readable-stream/package.json deleted file mode 100644 index 0b0c4bd207ace..0000000000000 --- a/node_modules/readable-stream/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "readable-stream", - "version": "3.6.0", - "description": "Streams3, a user-land copy of the stream library from Node.js", - "main": "readable.js", - "engines": { - "node": ">= 6" - }, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "devDependencies": { - "@babel/cli": "^7.2.0", - "@babel/core": "^7.2.0", - "@babel/polyfill": "^7.0.0", - "@babel/preset-env": "^7.2.0", - "airtap": "0.0.9", - "assert": "^1.4.0", - "bl": "^2.0.0", - "deep-strict-equal": "^0.2.0", - "events.once": "^2.0.2", - "glob": "^7.1.2", - "gunzip-maybe": "^1.4.1", - "hyperquest": "^2.1.3", - "lolex": "^2.6.0", - "nyc": "^11.0.0", - "pump": "^3.0.0", - "rimraf": "^2.6.2", - "tap": "^12.0.0", - "tape": "^4.9.0", - "tar-fs": "^1.16.2", - "util-promisify": "^2.1.0" - }, - "scripts": { - "test": "tap -J --no-esm test/parallel/*.js test/ours/*.js", - "ci": "TAP=1 tap --no-esm test/parallel/*.js test/ours/*.js | tee test.tap", - "test-browsers": "airtap --sauce-connect --loopback airtap.local -- test/browser.js", - "test-browser-local": "airtap --open --local -- test/browser.js", - "cover": "nyc npm test", - "report": "nyc report --reporter=lcov", - "update-browser-errors": "babel -o errors-browser.js errors.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/nodejs/readable-stream" - }, - "keywords": [ - "readable", - "stream", - "pipe" - ], - "browser": { - "util": false, - "worker_threads": false, - "./errors": "./errors-browser.js", - "./readable.js": "./readable-browser.js", - "./lib/internal/streams/from.js": "./lib/internal/streams/from-browser.js", - "./lib/internal/streams/stream.js": "./lib/internal/streams/stream-browser.js" - }, - "nyc": { - "include": [ - "lib/**.js" - ] - }, - "license": "MIT" -} diff --git a/node_modules/readable-stream/readable-browser.js b/node_modules/readable-stream/readable-browser.js deleted file mode 100644 index adbf60de832f9..0000000000000 --- a/node_modules/readable-stream/readable-browser.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = module.exports = require('./lib/_stream_readable.js'); -exports.Stream = exports; -exports.Readable = exports; -exports.Writable = require('./lib/_stream_writable.js'); -exports.Duplex = require('./lib/_stream_duplex.js'); -exports.Transform = require('./lib/_stream_transform.js'); -exports.PassThrough = require('./lib/_stream_passthrough.js'); -exports.finished = require('./lib/internal/streams/end-of-stream.js'); -exports.pipeline = require('./lib/internal/streams/pipeline.js'); diff --git a/node_modules/readable-stream/readable.js b/node_modules/readable-stream/readable.js deleted file mode 100644 index 9e0ca120ded82..0000000000000 --- a/node_modules/readable-stream/readable.js +++ /dev/null @@ -1,16 +0,0 @@ -var Stream = require('stream'); -if (process.env.READABLE_STREAM === 'disable' && Stream) { - module.exports = Stream.Readable; - Object.assign(module.exports, Stream); - module.exports.Stream = Stream; -} else { - exports = module.exports = require('./lib/_stream_readable.js'); - exports.Stream = Stream || exports; - exports.Readable = exports; - exports.Writable = require('./lib/_stream_writable.js'); - exports.Duplex = require('./lib/_stream_duplex.js'); - exports.Transform = require('./lib/_stream_transform.js'); - exports.PassThrough = require('./lib/_stream_passthrough.js'); - exports.finished = require('./lib/internal/streams/end-of-stream.js'); - exports.pipeline = require('./lib/internal/streams/pipeline.js'); -} diff --git a/node_modules/readdir-scoped-modules/LICENSE b/node_modules/readdir-scoped-modules/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/readdir-scoped-modules/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/readdir-scoped-modules/package.json b/node_modules/readdir-scoped-modules/package.json deleted file mode 100644 index d41b99c2643a2..0000000000000 --- a/node_modules/readdir-scoped-modules/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "readdir-scoped-modules", - "version": "1.1.0", - "description": "Like `fs.readdir` but handling `@org/module` dirs as if they were a single entry.", - "main": "readdir.js", - "directories": { - "test": "test" - }, - "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - }, - "devDependencies": { - "tap": "^1.2.0" - }, - "scripts": { - "test": "tap test/*.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/npm/readdir-scoped-modules" - }, - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "license": "ISC", - "bugs": { - "url": "https://github.com/npm/readdir-scoped-modules/issues" - }, - "homepage": "https://github.com/npm/readdir-scoped-modules", - "files": [ - "readdir.js" - ] -} diff --git a/node_modules/readdir-scoped-modules/readdir.js b/node_modules/readdir-scoped-modules/readdir.js deleted file mode 100644 index 806d787051852..0000000000000 --- a/node_modules/readdir-scoped-modules/readdir.js +++ /dev/null @@ -1,121 +0,0 @@ -var fs = require ('graceful-fs') -var dz = require ('dezalgo') -var once = require ('once') -var path = require ('path') -var debug = require ('debuglog') ('rds') - -module . exports = readdir -readdir.sync = readdirSync - -function readdir (dir, cb) { - fs . readdir (dir, function (er, kids) { - if (er) - return cb (er) - - debug ('dir=%j, kids=%j', dir, kids) - readScopes (dir, kids, function (er, data) { - if (er) - return cb (er) - - // Sort for bonus consistency points - data = data . sort (function (a, b) { - return a > b ? 1 : -1 - }) - - return cb (null, data) - }) - }) -} - -function readdirSync (dir) { - var kids = fs . readdirSync (dir) - debug ('dir=%j, kids=%j', dir, kids) - var data = readScopesSync (dir, kids) - // Sort for bonus consistency points - data = data . sort (function (a, b) { - return a > b ? 1 : -1 - }) - - return data -} - -// Turn [ 'a', '@scope' ] into -// ['a', '@scope/foo', '@scope/bar'] -function readScopes (root, kids, cb) { - var scopes = kids . filter (function (kid) { - return kid . charAt (0) === '@' - }) - - kids = kids . filter (function (kid) { - return kid . charAt (0) !== '@' - }) - - debug ('scopes=%j', scopes) - - if (scopes . length === 0) - dz (cb) (null, kids) // prevent maybe-sync zalgo release - - cb = once (cb) - var l = scopes . length - scopes . forEach (function (scope) { - var scopedir = path . resolve (root, scope) - debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir) - fs . readdir (scopedir, then . bind (null, scope)) - }) - - function then (scope, er, scopekids) { - if (er) - return cb (er) - - // XXX: Not sure how old this node bug is. Maybe superstition? - scopekids = scopekids . filter (function (scopekid) { - return !(scopekid === '.' || scopekid === '..' || !scopekid) - }) - - kids . push . apply (kids, scopekids . map (function (scopekid) { - return scope + '/' + scopekid - })) - - debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids) - - if (--l === 0) - cb (null, kids) - } -} - -function readScopesSync (root, kids) { - var scopes = kids . filter (function (kid) { - return kid . charAt (0) === '@' - }) - - kids = kids . filter (function (kid) { - return kid . charAt (0) !== '@' - }) - - debug ('scopes=%j', scopes) - - if (scopes . length === 0) - return kids - - var l = scopes . length - scopes . forEach (function (scope) { - var scopedir = path . resolve (root, scope) - debug ('root=%j scope=%j scopedir=%j', root, scope, scopedir) - then (scope, fs . readdirSync (scopedir)) - }) - - function then (scope, scopekids) { - // XXX: Not sure how old this node bug is. Maybe superstition? - scopekids = scopekids . filter (function (scopekid) { - return !(scopekid === '.' || scopekid === '..' || !scopekid) - }) - - kids . push . apply (kids, scopekids . map (function (scopekid) { - return scope + '/' + scopekid - })) - - debug ('scope=%j scopekids=%j kids=%j', scope, scopekids, kids) - } - - return kids -} diff --git a/node_modules/rimraf/LICENSE b/node_modules/rimraf/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/rimraf/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/rimraf/bin.js b/node_modules/rimraf/bin.js deleted file mode 100755 index 023814cc93e84..0000000000000 --- a/node_modules/rimraf/bin.js +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env node - -const rimraf = require('./') - -const path = require('path') - -const isRoot = arg => /^(\/|[a-zA-Z]:\\)$/.test(path.resolve(arg)) -const filterOutRoot = arg => { - const ok = preserveRoot === false || !isRoot(arg) - if (!ok) { - console.error(`refusing to remove ${arg}`) - console.error('Set --no-preserve-root to allow this') - } - return ok -} - -let help = false -let dashdash = false -let noglob = false -let preserveRoot = true -const args = process.argv.slice(2).filter(arg => { - if (dashdash) - return !!arg - else if (arg === '--') - dashdash = true - else if (arg === '--no-glob' || arg === '-G') - noglob = true - else if (arg === '--glob' || arg === '-g') - noglob = false - else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/)) - help = true - else if (arg === '--preserve-root') - preserveRoot = true - else if (arg === '--no-preserve-root') - preserveRoot = false - else - return !!arg -}).filter(arg => !preserveRoot || filterOutRoot(arg)) - -const go = n => { - if (n >= args.length) - return - const options = noglob ? { glob: false } : {} - rimraf(args[n], options, er => { - if (er) - throw er - go(n+1) - }) -} - -if (help || args.length === 0) { - // If they didn't ask for help, then this is not a "success" - const log = help ? console.log : console.error - log('Usage: rimraf <path> [<path> ...]') - log('') - log(' Deletes all files and folders at "path" recursively.') - log('') - log('Options:') - log('') - log(' -h, --help Display this usage info') - log(' -G, --no-glob Do not expand glob patterns in arguments') - log(' -g, --glob Expand glob patterns in arguments (default)') - log(' --preserve-root Do not remove \'/\' (default)') - log(' --no-preserve-root Do not treat \'/\' specially') - log(' -- Stop parsing flags') - process.exit(help ? 0 : 1) -} else - go(0) diff --git a/node_modules/rimraf/node_modules/brace-expansion/LICENSE b/node_modules/rimraf/node_modules/brace-expansion/LICENSE deleted file mode 100644 index de3226673c387..0000000000000 --- a/node_modules/rimraf/node_modules/brace-expansion/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/node_modules/rimraf/node_modules/brace-expansion/index.js b/node_modules/rimraf/node_modules/brace-expansion/index.js deleted file mode 100644 index 0478be81eabc2..0000000000000 --- a/node_modules/rimraf/node_modules/brace-expansion/index.js +++ /dev/null @@ -1,201 +0,0 @@ -var concatMap = require('concat-map'); -var balanced = require('balanced-match'); - -module.exports = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - diff --git a/node_modules/rimraf/node_modules/brace-expansion/package.json b/node_modules/rimraf/node_modules/brace-expansion/package.json deleted file mode 100644 index a18faa8fd67b8..0000000000000 --- a/node_modules/rimraf/node_modules/brace-expansion/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "brace-expansion", - "description": "Brace expansion as known from sh/bash", - "version": "1.1.11", - "repository": { - "type": "git", - "url": "git://github.com/juliangruber/brace-expansion.git" - }, - "homepage": "https://github.com/juliangruber/brace-expansion", - "main": "index.js", - "scripts": { - "test": "tape test/*.js", - "gentest": "bash test/generate.sh", - "bench": "matcha test/perf/bench.js" - }, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - }, - "devDependencies": { - "matcha": "^0.7.0", - "tape": "^4.6.0" - }, - "keywords": [], - "author": { - "name": "Julian Gruber", - "email": "mail@juliangruber.com", - "url": "http://juliangruber.com" - }, - "license": "MIT", - "testling": { - "files": "test/*.js", - "browsers": [ - "ie/8..latest", - "firefox/20..latest", - "firefox/nightly", - "chrome/25..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/node_modules/rimraf/node_modules/glob/LICENSE b/node_modules/rimraf/node_modules/glob/LICENSE deleted file mode 100644 index 42ca266df1d52..0000000000000 --- a/node_modules/rimraf/node_modules/glob/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -## Glob Logo - -Glob's logo created by Tanya Brassie <http://tanyabrassie.com/>, licensed -under a Creative Commons Attribution-ShareAlike 4.0 International License -https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/node_modules/rimraf/node_modules/glob/common.js b/node_modules/rimraf/node_modules/glob/common.js deleted file mode 100644 index 424c46e1dab1b..0000000000000 --- a/node_modules/rimraf/node_modules/glob/common.js +++ /dev/null @@ -1,238 +0,0 @@ -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var fs = require("fs") -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") -var Minimatch = minimatch.Minimatch - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - self.fs = options.fs || fs - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = false - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} diff --git a/node_modules/rimraf/node_modules/glob/glob.js b/node_modules/rimraf/node_modules/glob/glob.js deleted file mode 100644 index 37a4d7e60775a..0000000000000 --- a/node_modules/rimraf/node_modules/glob/glob.js +++ /dev/null @@ -1,790 +0,0 @@ -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var inherits = require('inherits') -var EE = require('events').EventEmitter -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var globSync = require('./sync.js') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = require('inflight') -var util = require('util') -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -var once = require('once') - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync - -// old api surface -glob.glob = glob - -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true - - var g = new Glob(pattern, options) - var set = g.minimatch.set - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {<filename>: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) - e = abs - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - self.fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - self.fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - self.fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return self.fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -} diff --git a/node_modules/rimraf/node_modules/glob/package.json b/node_modules/rimraf/node_modules/glob/package.json deleted file mode 100644 index 5940b649b7e65..0000000000000 --- a/node_modules/rimraf/node_modules/glob/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "name": "glob", - "description": "a little globber", - "version": "7.2.3", - "publishConfig": { - "tag": "v7-legacy" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-glob.git" - }, - "main": "glob.js", - "files": [ - "glob.js", - "sync.js", - "common.js" - ], - "engines": { - "node": "*" - }, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "devDependencies": { - "memfs": "^3.2.0", - "mkdirp": "0", - "rimraf": "^2.2.8", - "tap": "^15.0.6", - "tick": "0.0.6" - }, - "tap": { - "before": "test/00-setup.js", - "after": "test/zz-cleanup.js", - "jobs": 1 - }, - "scripts": { - "prepublish": "npm run benchclean", - "profclean": "rm -f v8.log profile.txt", - "test": "tap", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", - "bench": "bash benchmark.sh", - "prof": "bash prof.sh && cat profile.txt", - "benchclean": "node benchclean.js" - }, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } -} diff --git a/node_modules/rimraf/node_modules/glob/sync.js b/node_modules/rimraf/node_modules/glob/sync.js deleted file mode 100644 index 2c4f480192d28..0000000000000 --- a/node_modules/rimraf/node_modules/glob/sync.js +++ /dev/null @@ -1,486 +0,0 @@ -module.exports = globSync -globSync.GlobSync = GlobSync - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path-is-absolute') -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert.ok(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert.ok(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) { - e = abs - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, this.fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = this.fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} diff --git a/node_modules/rimraf/node_modules/minimatch/LICENSE b/node_modules/rimraf/node_modules/minimatch/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/rimraf/node_modules/minimatch/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/rimraf/node_modules/minimatch/minimatch.js b/node_modules/rimraf/node_modules/minimatch/minimatch.js deleted file mode 100644 index fda45ade7cfc3..0000000000000 --- a/node_modules/rimraf/node_modules/minimatch/minimatch.js +++ /dev/null @@ -1,947 +0,0 @@ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = (function () { try { return require('path') } catch (e) {}}()) || { - sep: '/' -} -minimatch.sep = path.sep - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - b = b || {} - var t = {} - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || typeof def !== 'object' || !Object.keys(def).length) { - return minimatch - } - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - m.Minimatch.defaults = function defaults (options) { - return orig.defaults(ext(def, options)).Minimatch - } - - m.filter = function filter (pattern, options) { - return orig.filter(pattern, ext(def, options)) - } - - m.defaults = function defaults (options) { - return orig.defaults(ext(def, options)) - } - - m.makeRe = function makeRe (pattern, options) { - return orig.makeRe(pattern, ext(def, options)) - } - - m.braceExpand = function braceExpand (pattern, options) { - return orig.braceExpand(pattern, ext(def, options)) - } - - m.match = function (list, pattern, options) { - return orig.match(list, pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - assertValidPattern(pattern) - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - assertValidPattern(pattern) - - if (!options) options = {} - - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (!options.allowWindowsEscape && path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - this.partial = !!options.partial - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) } - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - assertValidPattern(pattern) - - // Thanks to Yeting Li <https://github.com/yetingli> for - // improving this regexp to avoid a ReDOS vulnerability. - if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -var MAX_PATTERN_LENGTH = 1024 * 64 -var assertValidPattern = function (pattern) { - if (typeof pattern !== 'string') { - throw new TypeError('invalid pattern') - } - - if (pattern.length > MAX_PATTERN_LENGTH) { - throw new TypeError('pattern is too long') - } -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - assertValidPattern(pattern) - - var options = this.options - - // shortcuts - if (pattern === '**') { - if (!options.noglobstar) - return GLOBSTAR - else - pattern = '*' - } - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - /* istanbul ignore next */ - case '/': { - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - } - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:<pattern>)<type> - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '[': case '.': case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) /* istanbul ignore next - should be impossible */ { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) /* istanbul ignore next - should be impossible */ { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = function match (f, partial) { - if (typeof partial === 'undefined') partial = this.partial - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - /* istanbul ignore if */ - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - /* istanbul ignore if */ - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - hit = f === p - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else /* istanbul ignore else */ if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - return (fi === fl - 1) && (file[fi] === '') - } - - // should be unreachable. - /* istanbul ignore next */ - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} diff --git a/node_modules/rimraf/node_modules/minimatch/package.json b/node_modules/rimraf/node_modules/minimatch/package.json deleted file mode 100644 index 566efdfe45cb8..0000000000000 --- a/node_modules/rimraf/node_modules/minimatch/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)", - "name": "minimatch", - "description": "a glob matcher in javascript", - "version": "3.1.2", - "publishConfig": { - "tag": "v3-legacy" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/minimatch.git" - }, - "main": "minimatch.js", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "engines": { - "node": "*" - }, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "devDependencies": { - "tap": "^15.1.6" - }, - "license": "ISC", - "files": [ - "minimatch.js" - ] -} diff --git a/node_modules/rimraf/package.json b/node_modules/rimraf/package.json deleted file mode 100644 index 1bf8d5e38775d..0000000000000 --- a/node_modules/rimraf/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "rimraf", - "version": "3.0.2", - "main": "rimraf.js", - "description": "A deep deletion module for node (like `rm -rf`)", - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", - "license": "ISC", - "repository": "git://github.com/isaacs/rimraf.git", - "scripts": { - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "test": "tap test/*.js" - }, - "bin": "./bin.js", - "dependencies": { - "glob": "^7.1.3" - }, - "files": [ - "LICENSE", - "README.md", - "bin.js", - "rimraf.js" - ], - "devDependencies": { - "mkdirp": "^0.5.1", - "tap": "^12.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } -} diff --git a/node_modules/rimraf/rimraf.js b/node_modules/rimraf/rimraf.js deleted file mode 100644 index 34da4171d7559..0000000000000 --- a/node_modules/rimraf/rimraf.js +++ /dev/null @@ -1,360 +0,0 @@ -const assert = require("assert") -const path = require("path") -const fs = require("fs") -let glob = undefined -try { - glob = require("glob") -} catch (_err) { - // treat glob as optional. -} - -const defaultGlobOpts = { - nosort: true, - silent: true -} - -// for EMFILE handling -let timeout = 0 - -const isWindows = (process.platform === "win32") - -const defaults = options => { - const methods = [ - 'unlink', - 'chmod', - 'stat', - 'lstat', - 'rmdir', - 'readdir' - ] - methods.forEach(m => { - options[m] = options[m] || fs[m] - m = m + 'Sync' - options[m] = options[m] || fs[m] - }) - - options.maxBusyTries = options.maxBusyTries || 3 - options.emfileWait = options.emfileWait || 1000 - if (options.glob === false) { - options.disableGlob = true - } - if (options.disableGlob !== true && glob === undefined) { - throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') - } - options.disableGlob = options.disableGlob || false - options.glob = options.glob || defaultGlobOpts -} - -const rimraf = (p, options, cb) => { - if (typeof options === 'function') { - cb = options - options = {} - } - - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert.equal(typeof cb, 'function', 'rimraf: callback function required') - assert(options, 'rimraf: invalid options argument provided') - assert.equal(typeof options, 'object', 'rimraf: options should be object') - - defaults(options) - - let busyTries = 0 - let errState = null - let n = 0 - - const next = (er) => { - errState = errState || er - if (--n === 0) - cb(errState) - } - - const afterGlob = (er, results) => { - if (er) - return cb(er) - - n = results.length - if (n === 0) - return cb() - - results.forEach(p => { - const CB = (er) => { - if (er) { - if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && - busyTries < options.maxBusyTries) { - busyTries ++ - // try again, with the same exact callback as this one. - return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) - } - - // this one won't happen if graceful-fs is used. - if (er.code === "EMFILE" && timeout < options.emfileWait) { - return setTimeout(() => rimraf_(p, options, CB), timeout ++) - } - - // already gone - if (er.code === "ENOENT") er = null - } - - timeout = 0 - next(er) - } - rimraf_(p, options, CB) - }) - } - - if (options.disableGlob || !glob.hasMagic(p)) - return afterGlob(null, [p]) - - options.lstat(p, (er, stat) => { - if (!er) - return afterGlob(null, [p]) - - glob(p, options.glob, afterGlob) - }) - -} - -// Two possible strategies. -// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR -// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR -// -// Both result in an extra syscall when you guess wrong. However, there -// are likely far more normal files in the world than directories. This -// is based on the assumption that a the average number of files per -// directory is >= 1. -// -// If anyone ever complains about this, then I guess the strategy could -// be made configurable somehow. But until then, YAGNI. -const rimraf_ = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') - - // sunos lets the root user unlink directories, which is... weird. - // so we have to lstat here and make sure it's not a dir. - options.lstat(p, (er, st) => { - if (er && er.code === "ENOENT") - return cb(null) - - // Windows can EPERM on stat. Life is suffering. - if (er && er.code === "EPERM" && isWindows) - fixWinEPERM(p, options, er, cb) - - if (st && st.isDirectory()) - return rmdir(p, options, er, cb) - - options.unlink(p, er => { - if (er) { - if (er.code === "ENOENT") - return cb(null) - if (er.code === "EPERM") - return (isWindows) - ? fixWinEPERM(p, options, er, cb) - : rmdir(p, options, er, cb) - if (er.code === "EISDIR") - return rmdir(p, options, er, cb) - } - return cb(er) - }) - }) -} - -const fixWinEPERM = (p, options, er, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') - - options.chmod(p, 0o666, er2 => { - if (er2) - cb(er2.code === "ENOENT" ? null : er) - else - options.stat(p, (er3, stats) => { - if (er3) - cb(er3.code === "ENOENT" ? null : er) - else if (stats.isDirectory()) - rmdir(p, options, er, cb) - else - options.unlink(p, cb) - }) - }) -} - -const fixWinEPERMSync = (p, options, er) => { - assert(p) - assert(options) - - try { - options.chmodSync(p, 0o666) - } catch (er2) { - if (er2.code === "ENOENT") - return - else - throw er - } - - let stats - try { - stats = options.statSync(p) - } catch (er3) { - if (er3.code === "ENOENT") - return - else - throw er - } - - if (stats.isDirectory()) - rmdirSync(p, options, er) - else - options.unlinkSync(p) -} - -const rmdir = (p, options, originalEr, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') - - // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) - // if we guessed wrong, and it's not a directory, then - // raise the original error. - options.rmdir(p, er => { - if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) - rmkids(p, options, cb) - else if (er && er.code === "ENOTDIR") - cb(originalEr) - else - cb(er) - }) -} - -const rmkids = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') - - options.readdir(p, (er, files) => { - if (er) - return cb(er) - let n = files.length - if (n === 0) - return options.rmdir(p, cb) - let errState - files.forEach(f => { - rimraf(path.join(p, f), options, er => { - if (errState) - return - if (er) - return cb(errState = er) - if (--n === 0) - options.rmdir(p, cb) - }) - }) - }) -} - -// this looks simpler, and is strictly *faster*, but will -// tie up the JavaScript thread and fail on excessively -// deep directory trees. -const rimrafSync = (p, options) => { - options = options || {} - defaults(options) - - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert(options, 'rimraf: missing options') - assert.equal(typeof options, 'object', 'rimraf: options should be object') - - let results - - if (options.disableGlob || !glob.hasMagic(p)) { - results = [p] - } else { - try { - options.lstatSync(p) - results = [p] - } catch (er) { - results = glob.sync(p, options.glob) - } - } - - if (!results.length) - return - - for (let i = 0; i < results.length; i++) { - const p = results[i] - - let st - try { - st = options.lstatSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - - // Windows can EPERM on stat. Life is suffering. - if (er.code === "EPERM" && isWindows) - fixWinEPERMSync(p, options, er) - } - - try { - // sunos lets the root user unlink directories, which is... weird. - if (st && st.isDirectory()) - rmdirSync(p, options, null) - else - options.unlinkSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "EPERM") - return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) - if (er.code !== "EISDIR") - throw er - - rmdirSync(p, options, er) - } - } -} - -const rmdirSync = (p, options, originalEr) => { - assert(p) - assert(options) - - try { - options.rmdirSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "ENOTDIR") - throw originalEr - if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") - rmkidsSync(p, options) - } -} - -const rmkidsSync = (p, options) => { - assert(p) - assert(options) - options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) - - // We only end up here once we got ENOTEMPTY at least once, and - // at this point, we are guaranteed to have removed all the kids. - // So, we know that it won't be ENOENT or ENOTDIR or anything else. - // try really hard to delete stuff on windows, because it has a - // PROFOUNDLY annoying habit of not closing handles promptly when - // files are deleted, resulting in spurious ENOTEMPTY errors. - const retries = isWindows ? 100 : 1 - let i = 0 - do { - let threw = true - try { - const ret = options.rmdirSync(p, options) - threw = false - return ret - } finally { - if (++i < retries && threw) - continue - } - } while (true) -} - -module.exports = rimraf -rimraf.sync = rimrafSync diff --git a/node_modules/safe-buffer/LICENSE b/node_modules/safe-buffer/LICENSE deleted file mode 100644 index 0c068ceecbd48..0000000000000 --- a/node_modules/safe-buffer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Feross Aboukhadijeh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/node_modules/safe-buffer/index.d.ts b/node_modules/safe-buffer/index.d.ts deleted file mode 100644 index e9fed809a5ab5..0000000000000 --- a/node_modules/safe-buffer/index.d.ts +++ /dev/null @@ -1,187 +0,0 @@ -declare module "safe-buffer" { - export class Buffer { - length: number - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): { type: 'Buffer', data: any[] }; - equals(otherBuffer: Buffer): boolean; - compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; - readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; - readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; - readUInt8(offset: number, noAssert?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - swap16(): Buffer; - swap32(): Buffer; - swap64(): Buffer; - writeUInt8(value: number, offset: number, noAssert?: boolean): number; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeInt8(value: number, offset: number, noAssert?: boolean): number; - writeInt16LE(value: number, offset: number, noAssert?: boolean): number; - writeInt16BE(value: number, offset: number, noAssert?: boolean): number; - writeInt32LE(value: number, offset: number, noAssert?: boolean): number; - writeInt32BE(value: number, offset: number, noAssert?: boolean): number; - writeFloatLE(value: number, offset: number, noAssert?: boolean): number; - writeFloatBE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; - fill(value: any, offset?: number, end?: number): this; - indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; - lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; - includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; - - /** - * Allocates a new buffer containing the given {str}. - * - * @param str String to store in buffer. - * @param encoding encoding to use, optional. Default is 'utf8' - */ - constructor (str: string, encoding?: string); - /** - * Allocates a new buffer of {size} octets. - * - * @param size count of octets to allocate. - */ - constructor (size: number); - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - constructor (array: Uint8Array); - /** - * Produces a Buffer backed by the same allocated memory as - * the given {ArrayBuffer}. - * - * - * @param arrayBuffer The ArrayBuffer with which to share memory. - */ - constructor (arrayBuffer: ArrayBuffer); - /** - * Allocates a new buffer containing the given {array} of octets. - * - * @param array The octets to store. - */ - constructor (array: any[]); - /** - * Copies the passed {buffer} data onto a new {Buffer} instance. - * - * @param buffer The buffer to copy. - */ - constructor (buffer: Buffer); - prototype: Buffer; - /** - * Allocates a new Buffer using an {array} of octets. - * - * @param array - */ - static from(array: any[]): Buffer; - /** - * When passed a reference to the .buffer property of a TypedArray instance, - * the newly created Buffer will share the same allocated memory as the TypedArray. - * The optional {byteOffset} and {length} arguments specify a memory range - * within the {arrayBuffer} that will be shared by the Buffer. - * - * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() - * @param byteOffset - * @param length - */ - static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; - /** - * Copies the passed {buffer} data onto a new Buffer instance. - * - * @param buffer - */ - static from(buffer: Buffer): Buffer; - /** - * Creates a new Buffer containing the given JavaScript string {str}. - * If provided, the {encoding} parameter identifies the character encoding. - * If not provided, {encoding} defaults to 'utf8'. - * - * @param str - */ - static from(str: string, encoding?: string): Buffer; - /** - * Returns true if {obj} is a Buffer - * - * @param obj object to test. - */ - static isBuffer(obj: any): obj is Buffer; - /** - * Returns true if {encoding} is a valid encoding argument. - * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' - * - * @param encoding string to test. - */ - static isEncoding(encoding: string): boolean; - /** - * Gives the actual byte length of a string. encoding defaults to 'utf8'. - * This is not the same as String.prototype.length since that returns the number of characters in a string. - * - * @param string string to test. - * @param encoding encoding used to evaluate (defaults to 'utf8') - */ - static byteLength(string: string, encoding?: string): number; - /** - * Returns a buffer which is the result of concatenating all the buffers in the list together. - * - * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. - * If the list has exactly one item, then the first item of the list is returned. - * If the list has more than one item, then a new Buffer is created. - * - * @param list An array of Buffer objects to concatenate - * @param totalLength Total length of the buffers when concatenated. - * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. - */ - static concat(list: Buffer[], totalLength?: number): Buffer; - /** - * The same as buf1.compare(buf2). - */ - static compare(buf1: Buffer, buf2: Buffer): number; - /** - * Allocates a new buffer of {size} octets. - * - * @param size count of octets to allocate. - * @param fill if specified, buffer will be initialized by calling buf.fill(fill). - * If parameter is omitted, buffer will be filled with zeros. - * @param encoding encoding used for call to buf.fill while initalizing - */ - static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; - /** - * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents - * of the newly created Buffer are unknown and may contain sensitive data. - * - * @param size count of octets to allocate - */ - static allocUnsafe(size: number): Buffer; - /** - * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents - * of the newly created Buffer are unknown and may contain sensitive data. - * - * @param size count of octets to allocate - */ - static allocUnsafeSlow(size: number): Buffer; - } -} \ No newline at end of file diff --git a/node_modules/safe-buffer/index.js b/node_modules/safe-buffer/index.js deleted file mode 100644 index f8d3ec98852f4..0000000000000 --- a/node_modules/safe-buffer/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */ -/* eslint-disable node/no-deprecated-api */ -var buffer = require('buffer') -var Buffer = buffer.Buffer - -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] - } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer -} - -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) -} - -SafeBuffer.prototype = Object.create(Buffer.prototype) - -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) - -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) -} - -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - } else { - buf.fill(0) - } - return buf -} - -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) -} - -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return buffer.SlowBuffer(size) -} diff --git a/node_modules/safe-buffer/package.json b/node_modules/safe-buffer/package.json deleted file mode 100644 index f2869e256477a..0000000000000 --- a/node_modules/safe-buffer/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "safe-buffer", - "description": "Safer Node.js Buffer API", - "version": "5.2.1", - "author": { - "name": "Feross Aboukhadijeh", - "email": "feross@feross.org", - "url": "https://feross.org" - }, - "bugs": { - "url": "https://github.com/feross/safe-buffer/issues" - }, - "devDependencies": { - "standard": "*", - "tape": "^5.0.0" - }, - "homepage": "https://github.com/feross/safe-buffer", - "keywords": [ - "buffer", - "buffer allocate", - "node security", - "safe", - "safe-buffer", - "security", - "uninitialized" - ], - "license": "MIT", - "main": "index.js", - "types": "index.d.ts", - "repository": { - "type": "git", - "url": "git://github.com/feross/safe-buffer.git" - }, - "scripts": { - "test": "standard && tape test/*.js" - }, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] -} diff --git a/node_modules/safer-buffer/Readme.md b/node_modules/safer-buffer/Readme.md deleted file mode 100644 index 14b0822909320..0000000000000 --- a/node_modules/safer-buffer/Readme.md +++ /dev/null @@ -1,156 +0,0 @@ -# safer-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![javascript style guide][standard-image]][standard-url] [![Security Responsible Disclosure][secuirty-image]][secuirty-url] - -[travis-image]: https://travis-ci.org/ChALkeR/safer-buffer.svg?branch=master -[travis-url]: https://travis-ci.org/ChALkeR/safer-buffer -[npm-image]: https://img.shields.io/npm/v/safer-buffer.svg -[npm-url]: https://npmjs.org/package/safer-buffer -[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg -[standard-url]: https://standardjs.com -[secuirty-image]: https://img.shields.io/badge/Security-Responsible%20Disclosure-green.svg -[secuirty-url]: https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md - -Modern Buffer API polyfill without footguns, working on Node.js from 0.8 to current. - -## How to use? - -First, port all `Buffer()` and `new Buffer()` calls to `Buffer.alloc()` and `Buffer.from()` API. - -Then, to achieve compatibility with outdated Node.js versions (`<4.5.0` and 5.x `<5.9.0`), use -`const Buffer = require('safer-buffer').Buffer` in all files where you make calls to the new -Buffer API. _Use `var` instead of `const` if you need that for your Node.js version range support._ - -Also, see the -[porting Buffer](https://github.com/ChALkeR/safer-buffer/blob/master/Porting-Buffer.md) guide. - -## Do I need it? - -Hopefully, not — dropping support for outdated Node.js versions should be fine nowdays, and that -is the recommended path forward. You _do_ need to port to the `Buffer.alloc()` and `Buffer.from()` -though. - -See the [porting guide](https://github.com/ChALkeR/safer-buffer/blob/master/Porting-Buffer.md) -for a better description. - -## Why not [safe-buffer](https://npmjs.com/safe-buffer)? - -_In short: while `safe-buffer` serves as a polyfill for the new API, it allows old API usage and -itself contains footguns._ - -`safe-buffer` could be used safely to get the new API while still keeping support for older -Node.js versions (like this module), but while analyzing ecosystem usage of the old Buffer API -I found out that `safe-buffer` is itself causing problems in some cases. - -For example, consider the following snippet: - -```console -$ cat example.unsafe.js -console.log(Buffer(20)) -$ ./node-v6.13.0-linux-x64/bin/node example.unsafe.js -<Buffer 0a 00 00 00 00 00 00 00 28 13 de 02 00 00 00 00 05 00 00 00> -$ standard example.unsafe.js -standard: Use JavaScript Standard Style (https://standardjs.com) - /home/chalker/repo/safer-buffer/example.unsafe.js:2:13: 'Buffer()' was deprecated since v6. Use 'Buffer.alloc()' or 'Buffer.from()' (use 'https://www.npmjs.com/package/safe-buffer' for '<4.5.0') instead. -``` - -This is allocates and writes to console an uninitialized chunk of memory. -[standard](https://www.npmjs.com/package/standard) linter (among others) catch that and warn people -to avoid using unsafe API. - -Let's now throw in `safe-buffer`! - -```console -$ cat example.safe-buffer.js -const Buffer = require('safe-buffer').Buffer -console.log(Buffer(20)) -$ standard example.safe-buffer.js -$ ./node-v6.13.0-linux-x64/bin/node example.safe-buffer.js -<Buffer 08 00 00 00 00 00 00 00 28 58 01 82 fe 7f 00 00 00 00 00 00> -``` - -See the problem? Adding in `safe-buffer` _magically removes the lint warning_, but the behavior -remains identiсal to what we had before, and when launched on Node.js 6.x LTS — this dumps out -chunks of uninitialized memory. -_And this code will still emit runtime warnings on Node.js 10.x and above._ - -That was done by design. I first considered changing `safe-buffer`, prohibiting old API usage or -emitting warnings on it, but that significantly diverges from `safe-buffer` design. After some -discussion, it was decided to move my approach into a separate package, and _this is that separate -package_. - -This footgun is not imaginary — I observed top-downloaded packages doing that kind of thing, -«fixing» the lint warning by blindly including `safe-buffer` without any actual changes. - -Also in some cases, even if the API _was_ migrated to use of safe Buffer API — a random pull request -can bring unsafe Buffer API usage back to the codebase by adding new calls — and that could go -unnoticed even if you have a linter prohibiting that (becase of the reason stated above), and even -pass CI. _I also observed that being done in popular packages._ - -Some examples: - * [webdriverio](https://github.com/webdriverio/webdriverio/commit/05cbd3167c12e4930f09ef7cf93b127ba4effae4#diff-124380949022817b90b622871837d56cR31) - (a module with 548 759 downloads/month), - * [websocket-stream](https://github.com/maxogden/websocket-stream/commit/c9312bd24d08271687d76da0fe3c83493871cf61) - (218 288 d/m, fix in [maxogden/websocket-stream#142](https://github.com/maxogden/websocket-stream/pull/142)), - * [node-serialport](https://github.com/node-serialport/node-serialport/commit/e8d9d2b16c664224920ce1c895199b1ce2def48c) - (113 138 d/m, fix in [node-serialport/node-serialport#1510](https://github.com/node-serialport/node-serialport/pull/1510)), - * [karma](https://github.com/karma-runner/karma/commit/3d94b8cf18c695104ca195334dc75ff054c74eec) - (3 973 193 d/m, fix in [karma-runner/karma#2947](https://github.com/karma-runner/karma/pull/2947)), - * [spdy-transport](https://github.com/spdy-http2/spdy-transport/commit/5375ac33f4a62a4f65bcfc2827447d42a5dbe8b1) - (5 970 727 d/m, fix in [spdy-http2/spdy-transport#53](https://github.com/spdy-http2/spdy-transport/pull/53)). - * And there are a lot more over the ecosystem. - -I filed a PR at -[mysticatea/eslint-plugin-node#110](https://github.com/mysticatea/eslint-plugin-node/pull/110) to -partially fix that (for cases when that lint rule is used), but it is a semver-major change for -linter rules and presets, so it would take significant time for that to reach actual setups. -_It also hasn't been released yet (2018-03-20)._ - -Also, `safer-buffer` discourages the usage of `.allocUnsafe()`, which is often done by a mistake. -It still supports it with an explicit concern barier, by placing it under -`require('safer-buffer/dangereous')`. - -## But isn't throwing bad? - -Not really. It's an error that could be noticed and fixed early, instead of causing havoc later like -unguarded `new Buffer()` calls that end up receiving user input can do. - -This package affects only the files where `var Buffer = require('safer-buffer').Buffer` was done, so -it is really simple to keep track of things and make sure that you don't mix old API usage with that. -Also, CI should hint anything that you might have missed. - -New commits, if tested, won't land new usage of unsafe Buffer API this way. -_Node.js 10.x also deals with that by printing a runtime depecation warning._ - -### Would it affect third-party modules? - -No, unless you explicitly do an awful thing like monkey-patching or overriding the built-in `Buffer`. -Don't do that. - -### But I don't want throwing… - -That is also fine! - -Also, it could be better in some cases when you don't comprehensive enough test coverage. - -In that case — just don't override `Buffer` and use -`var SaferBuffer = require('safer-buffer').Buffer` instead. - -That way, everything using `Buffer` natively would still work, but there would be two drawbacks: - -* `Buffer.from`/`Buffer.alloc` won't be polyfilled — use `SaferBuffer.from` and - `SaferBuffer.alloc` instead. -* You are still open to accidentally using the insecure deprecated API — use a linter to catch that. - -Note that using a linter to catch accidential `Buffer` constructor usage in this case is strongly -recommended. `Buffer` is not overriden in this usecase, so linters won't get confused. - -## «Without footguns»? - -Well, it is still possible to do _some_ things with `Buffer` API, e.g. accessing `.buffer` property -on older versions and duping things from there. You shouldn't do that in your code, probabably. - -The intention is to remove the most significant footguns that affect lots of packages in the -ecosystem, and to do it in the proper way. - -Also, this package doesn't protect against security issues affecting some Node.js versions, so for -usage in your own production code, it is still recommended to update to a Node.js version -[supported by upstream](https://github.com/nodejs/release#release-schedule). diff --git a/node_modules/semver/bin/semver.js b/node_modules/semver/bin/semver.js index 8d1b55720e0ab..dbb1bf534ec72 100755 --- a/node_modules/semver/bin/semver.js +++ b/node_modules/semver/bin/semver.js @@ -3,6 +3,8 @@ // Exits successfully and prints matching version(s) if // any supplied version is valid and passes all tests. +'use strict' + const argv = process.argv.slice(2) let versions = [] @@ -23,7 +25,10 @@ let rtl = false let identifier +let identifierBase + const semver = require('../') +const parseOptions = require('../internal/parse-options') let reverse = false @@ -58,6 +63,7 @@ const main = () => { switch (argv[0]) { case 'major': case 'minor': case 'patch': case 'prerelease': case 'premajor': case 'preminor': case 'prepatch': + case 'release': inc = argv.shift() break default: @@ -71,6 +77,12 @@ const main = () => { case '-r': case '--range': range.push(argv.shift()) break + case '-n': + identifierBase = argv.shift() + if (identifierBase === 'false') { + identifierBase = false + } + break case '-c': case '--coerce': coerce = true break @@ -88,7 +100,7 @@ const main = () => { } } - options = { loose: loose, includePrerelease: includePrerelease, rtl: rtl } + options = parseOptions({ loose, includePrerelease, rtl }) versions = versions.map((v) => { return coerce ? (semver.coerce(v, options) || { version: v }).version : v @@ -110,7 +122,11 @@ const main = () => { return fail() } } - return success(versions) + versions + .sort((a, b) => semver[reverse ? 'rcompare' : 'compare'](a, b, options)) + .map(v => semver.clean(v, options)) + .map(v => inc ? semver.inc(v, inc, options, identifier, identifierBase) : v) + .forEach(v => console.log(v)) } const failInc = () => { @@ -120,19 +136,6 @@ const failInc = () => { const fail = () => process.exit(1) -const success = () => { - const compare = reverse ? 'rcompare' : 'compare' - versions.sort((a, b) => { - return semver[compare](a, b, options) - }).map((v) => { - return semver.clean(v, options) - }).map((v) => { - return inc ? semver.inc(v, inc, options, identifier) : v - }).forEach((v, i, _) => { - console.log(v) - }) -} - const help = () => console.log( `SemVer ${version} @@ -149,7 +152,7 @@ Options: -i --increment [<level>] Increment a version by the specified level. Level can be one of: major, minor, patch, premajor, preminor, - prepatch, or prerelease. Default level is 'patch'. + prepatch, prerelease, or release. Default level is 'patch'. Only one version may be specified. --preid <identifier> @@ -172,6 +175,11 @@ Options: --ltr Coerce version strings left to right (default) +-n <base> + Base number to be used for the prerelease identifier. + Can be either 0 or 1, or false to omit the number altogether. + Defaults to 0. + Program exits successfully if any valid version satisfies all supplied ranges, and prints all satisfying versions. diff --git a/node_modules/semver/classes/comparator.js b/node_modules/semver/classes/comparator.js index 62cd204d9b796..647c1f0976fd7 100644 --- a/node_modules/semver/classes/comparator.js +++ b/node_modules/semver/classes/comparator.js @@ -1,3 +1,5 @@ +'use strict' + const ANY = Symbol('SemVer ANY') // hoisted class for cyclic dependency class Comparator { @@ -16,6 +18,7 @@ class Comparator { } } + comp = comp.trim().split(/\s+/).join(' ') debug('comparator', comp, options) this.options = options this.loose = !!options.loose @@ -78,13 +81,6 @@ class Comparator { throw new TypeError('a Comparator is required') } - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false, - } - } - if (this.operator === '') { if (this.value === '') { return true @@ -97,39 +93,50 @@ class Comparator { return new Range(this.value, options).test(comp.semver) } - const sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - const sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - const sameSemVer = this.semver.version === comp.semver.version - const differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - const oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<') - const oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>') - - return ( - sameDirectionIncreasing || - sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || - oppositeDirectionsGreaterThan - ) + options = parseOptions(options) + + // Special cases where nothing can possibly be lower + if (options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { + return false + } + if (!options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { + return false + } + + // Same direction increasing (> or >=) + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + // Same direction decreasing (< or <=) + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + // same SemVer and both sides are inclusive (<= or >=) + if ( + (this.semver.version === comp.semver.version) && + this.operator.includes('=') && comp.operator.includes('=')) { + return true + } + // opposite directions less than + if (cmp(this.semver, '<', comp.semver, options) && + this.operator.startsWith('>') && comp.operator.startsWith('<')) { + return true + } + // opposite directions greater than + if (cmp(this.semver, '>', comp.semver, options) && + this.operator.startsWith('<') && comp.operator.startsWith('>')) { + return true + } + return false } } module.exports = Comparator const parseOptions = require('../internal/parse-options') -const { re, t } = require('../internal/re') +const { safeRe: re, t } = require('../internal/re') const cmp = require('../functions/cmp') const debug = require('../internal/debug') const SemVer = require('./semver') diff --git a/node_modules/semver/classes/index.js b/node_modules/semver/classes/index.js index 5e3f5c9b19cef..91c24ec4a7264 100644 --- a/node_modules/semver/classes/index.js +++ b/node_modules/semver/classes/index.js @@ -1,3 +1,5 @@ +'use strict' + module.exports = { SemVer: require('./semver.js'), Range: require('./range.js'), diff --git a/node_modules/semver/classes/range.js b/node_modules/semver/classes/range.js index 7dc24bc714b02..94629ce6f5df6 100644 --- a/node_modules/semver/classes/range.js +++ b/node_modules/semver/classes/range.js @@ -1,3 +1,7 @@ +'use strict' + +const SPACE_CHARACTERS = /\s+/g + // hoisted class for cyclic dependency class Range { constructor (range, options) { @@ -18,7 +22,7 @@ class Range { // just put it in the set and return this.raw = range.value this.set = [[range]] - this.format() + this.formatted = undefined return this } @@ -26,9 +30,13 @@ class Range { this.loose = !!options.loose this.includePrerelease = !!options.includePrerelease - // First, split based on boolean or || - this.raw = range - this.set = range + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range.trim().replace(SPACE_CHARACTERS, ' ') + + // First, split on || + this.set = this.raw .split('||') // map the range to a 2d array of comparators .map(r => this.parseRange(r.trim())) @@ -38,7 +46,7 @@ class Range { .filter(c => c.length) if (!this.set.length) { - throw new TypeError(`Invalid SemVer Range: ${range}`) + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) } // if we have any that are not the null set, throw out null sets. @@ -59,16 +67,29 @@ class Range { } } - this.format() + this.formatted = undefined + } + + get range () { + if (this.formatted === undefined) { + this.formatted = '' + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += '||' + } + const comps = this.set[i] + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += ' ' + } + this.formatted += comps[k].toString().trim() + } + } + } + return this.formatted } format () { - this.range = this.set - .map((comps) => { - return comps.join(' ').trim() - }) - .join('||') - .trim() return this.range } @@ -77,12 +98,12 @@ class Range { } parseRange (range) { - range = range.trim() - // memoize range parsing for performance. // this is a very hot path, and fully deterministic. - const memoOpts = Object.keys(this.options).join(',') - const memoKey = `parseRange:${memoOpts}:${range}` + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE) + const memoKey = memoOpts + ':' + range const cached = cache.get(memoKey) if (cached) { return cached @@ -93,18 +114,18 @@ class Range { const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) debug('comparator trim', range) // `~ 1.2.3` => `~1.2.3` range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + debug('tilde trim', range) // `^ 1.2.3` => `^1.2.3` range = range.replace(re[t.CARETTRIM], caretTrimReplace) - - // normalize spaces - range = range.split(/\s+/).join(' ') + debug('caret trim', range) // At this point, the range is completely trimmed and // ready to be split into comparators. @@ -190,22 +211,24 @@ class Range { return false } } + module.exports = Range -const LRU = require('lru-cache') -const cache = new LRU({ max: 1000 }) +const LRU = require('../internal/lrucache') +const cache = new LRU() const parseOptions = require('../internal/parse-options') const Comparator = require('./comparator') const debug = require('../internal/debug') const SemVer = require('./semver') const { - re, + safeRe: re, t, comparatorTrimReplace, tildeTrimReplace, caretTrimReplace, } = require('../internal/re') +const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') const isNullSet = c => c.value === '<0.0.0-0' const isAny = c => c.value === '' @@ -232,6 +255,7 @@ const isSatisfiable = (comparators, options) => { // already replaced the hyphen ranges // turn into a set of JUST comparators. const parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], '') debug('comp', comp, options) comp = replaceCarets(comp, options) debug('caret', comp) @@ -252,10 +276,14 @@ const isX = id => !id || id.toLowerCase() === 'x' || id === '*' // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 -const replaceTildes = (comp, options) => - comp.trim().split(/\s+/).map((c) => { - return replaceTilde(c, options) - }).join(' ') +// ~0.0.1 --> >=0.0.1 <0.1.0-0 +const replaceTildes = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceTilde(c, options)) + .join(' ') +} const replaceTilde = (comp, options) => { const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] @@ -291,10 +319,15 @@ const replaceTilde = (comp, options) => { // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 // ^1.2.3 --> >=1.2.3 <2.0.0-0 // ^1.2.0 --> >=1.2.0 <2.0.0-0 -const replaceCarets = (comp, options) => - comp.trim().split(/\s+/).map((c) => { - return replaceCaret(c, options) - }).join(' ') +// ^0.0.1 --> >=0.0.1 <0.0.2-0 +// ^0.1.0 --> >=0.1.0 <0.2.0-0 +const replaceCarets = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceCaret(c, options)) + .join(' ') +} const replaceCaret = (comp, options) => { debug('caret', comp, options) @@ -351,9 +384,10 @@ const replaceCaret = (comp, options) => { const replaceXRanges = (comp, options) => { debug('replaceXRanges', comp, options) - return comp.split(/\s+/).map((c) => { - return replaceXRange(c, options) - }).join(' ') + return comp + .split(/\s+/) + .map((c) => replaceXRange(c, options)) + .join(' ') } const replaceXRange = (comp, options) => { @@ -436,12 +470,15 @@ const replaceXRange = (comp, options) => { const replaceStars = (comp, options) => { debug('replaceStars', comp, options) // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[t.STAR], '') + return comp + .trim() + .replace(re[t.STAR], '') } const replaceGTE0 = (comp, options) => { debug('replaceGTE0', comp, options) - return comp.trim() + return comp + .trim() .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') } @@ -450,9 +487,10 @@ const replaceGTE0 = (comp, options) => { // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do // 1.2 - 3.4 => >=1.2.0 <3.5.0-0 +// TODO build? const hyphenReplace = incPr => ($0, from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) => { + to, tM, tm, tp, tpr) => { if (isX(fM)) { from = '' } else if (isX(fm)) { @@ -479,7 +517,7 @@ const hyphenReplace = incPr => ($0, to = `<=${to}` } - return (`${from} ${to}`).trim() + return `${from} ${to}`.trim() } const testSet = (set, version, options) => { diff --git a/node_modules/semver/classes/semver.js b/node_modules/semver/classes/semver.js index af62955194793..92254be1bf075 100644 --- a/node_modules/semver/classes/semver.js +++ b/node_modules/semver/classes/semver.js @@ -1,6 +1,8 @@ +'use strict' + const debug = require('../internal/debug') const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') -const { re, t } = require('../internal/re') +const { safeRe: re, t } = require('../internal/re') const parseOptions = require('../internal/parse-options') const { compareIdentifiers } = require('../internal/identifiers') @@ -10,13 +12,13 @@ class SemVer { if (version instanceof SemVer) { if (version.loose === !!options.loose && - version.includePrerelease === !!options.includePrerelease) { + version.includePrerelease === !!options.includePrerelease) { return version } else { version = version.version } } else if (typeof version !== 'string') { - throw new TypeError(`Invalid Version: ${version}`) + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) } if (version.length > MAX_LENGTH) { @@ -109,11 +111,25 @@ class SemVer { other = new SemVer(other, this.options) } - return ( - compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) - ) + if (this.major < other.major) { + return -1 + } + if (this.major > other.major) { + return 1 + } + if (this.minor < other.minor) { + return -1 + } + if (this.minor > other.minor) { + return 1 + } + if (this.patch < other.patch) { + return -1 + } + if (this.patch > other.patch) { + return 1 + } + return 0 } comparePre (other) { @@ -158,7 +174,7 @@ class SemVer { do { const a = this.build[i] const b = other.build[i] - debug('prerelease compare', i, a, b) + debug('build compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { @@ -175,36 +191,55 @@ class SemVer { // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. - inc (release, identifier) { + inc (release, identifier, identifierBase) { + if (release.startsWith('pre')) { + if (!identifier && identifierBase === false) { + throw new Error('invalid increment argument: identifier is empty') + } + // Avoid an invalid semver results + if (identifier) { + const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]) + if (!match || match[1] !== identifier) { + throw new Error(`invalid identifier: ${identifier}`) + } + } + } + switch (release) { case 'premajor': this.prerelease.length = 0 this.patch = 0 this.minor = 0 this.major++ - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'preminor': this.prerelease.length = 0 this.patch = 0 this.minor++ - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) + this.inc('patch', identifier, identifierBase) + this.inc('pre', identifier, identifierBase) break // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) { - this.inc('patch', identifier) + this.inc('patch', identifier, identifierBase) } - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) + break + case 'release': + if (this.prerelease.length === 0) { + throw new Error(`version ${this.raw} is not a prerelease`) + } + this.prerelease.length = 0 break case 'major': @@ -246,9 +281,11 @@ class SemVer { break // This probably shouldn't be used publicly. // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. - case 'pre': + case 'pre': { + const base = Number(identifierBase) ? 1 : 0 + if (this.prerelease.length === 0) { - this.prerelease = [0] + this.prerelease = [base] } else { let i = this.prerelease.length while (--i >= 0) { @@ -259,27 +296,36 @@ class SemVer { } if (i === -1) { // didn't increment anything - this.prerelease.push(0) + if (identifier === this.prerelease.join('.') && identifierBase === false) { + throw new Error('invalid increment argument: identifier already exists') + } + this.prerelease.push(base) } } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + let prerelease = [identifier, base] + if (identifierBase === false) { + prerelease = [identifier] + } if (compareIdentifiers(this.prerelease[0], identifier) === 0) { if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] + this.prerelease = prerelease } } else { - this.prerelease = [identifier, 0] + this.prerelease = prerelease } } break - + } default: throw new Error(`invalid increment argument: ${release}`) } - this.format() - this.raw = this.version + this.raw = this.format() + if (this.build.length) { + this.raw += `+${this.build.join('.')}` + } return this } } diff --git a/node_modules/semver/functions/clean.js b/node_modules/semver/functions/clean.js index 811fe6b82cb73..79703d6316617 100644 --- a/node_modules/semver/functions/clean.js +++ b/node_modules/semver/functions/clean.js @@ -1,3 +1,5 @@ +'use strict' + const parse = require('./parse') const clean = (version, options) => { const s = parse(version.trim().replace(/^[=v]+/, ''), options) diff --git a/node_modules/semver/functions/cmp.js b/node_modules/semver/functions/cmp.js index 40119094747dd..77487dcaac5f5 100644 --- a/node_modules/semver/functions/cmp.js +++ b/node_modules/semver/functions/cmp.js @@ -1,3 +1,5 @@ +'use strict' + const eq = require('./eq') const neq = require('./neq') const gt = require('./gt') diff --git a/node_modules/semver/functions/coerce.js b/node_modules/semver/functions/coerce.js index 2e01452fddad6..cfe027599516f 100644 --- a/node_modules/semver/functions/coerce.js +++ b/node_modules/semver/functions/coerce.js @@ -1,6 +1,8 @@ +'use strict' + const SemVer = require('../classes/semver') const parse = require('./parse') -const { re, t } = require('../internal/re') +const { safeRe: re, t } = require('../internal/re') const coerce = (version, options) => { if (version instanceof SemVer) { @@ -19,34 +21,42 @@ const coerce = (version, options) => { let match = null if (!options.rtl) { - match = version.match(re[t.COERCE]) + match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]) } else { // Find the right-most coercible string that does not share // a terminus with a more left-ward coercible string. // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4' // // Walk through the string checking with a /g regexp // Manually set the index so as to pick up overlapping matches. // Stop when we get a match that ends at the string end, since no // coercible string can be more right-ward without the same terminus. + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL] let next - while ((next = re[t.COERCERTL].exec(version)) && + while ((next = coerceRtlRegex.exec(version)) && (!match || match.index + match[0].length !== version.length) ) { if (!match || next.index + next[0].length !== match.index + match[0].length) { match = next } - re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length } // leave it in a clean state - re[t.COERCERTL].lastIndex = -1 + coerceRtlRegex.lastIndex = -1 } if (match === null) { return null } - return parse(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options) + const major = match[2] + const minor = match[3] || '0' + const patch = match[4] || '0' + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : '' + const build = options.includePrerelease && match[6] ? `+${match[6]}` : '' + + return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options) } module.exports = coerce diff --git a/node_modules/semver/functions/compare-build.js b/node_modules/semver/functions/compare-build.js index 9eb881bef0fdd..99157cf3d105e 100644 --- a/node_modules/semver/functions/compare-build.js +++ b/node_modules/semver/functions/compare-build.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const compareBuild = (a, b, loose) => { const versionA = new SemVer(a, loose) diff --git a/node_modules/semver/functions/compare-loose.js b/node_modules/semver/functions/compare-loose.js index 4881fbe00250c..75316346a81cb 100644 --- a/node_modules/semver/functions/compare-loose.js +++ b/node_modules/semver/functions/compare-loose.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const compareLoose = (a, b) => compare(a, b, true) module.exports = compareLoose diff --git a/node_modules/semver/functions/compare.js b/node_modules/semver/functions/compare.js index 748b7afa514a9..63d8090c626ce 100644 --- a/node_modules/semver/functions/compare.js +++ b/node_modules/semver/functions/compare.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const compare = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose)) diff --git a/node_modules/semver/functions/diff.js b/node_modules/semver/functions/diff.js index 87200ef3b88e8..04e064e9196b5 100644 --- a/node_modules/semver/functions/diff.js +++ b/node_modules/semver/functions/diff.js @@ -1,23 +1,60 @@ -const parse = require('./parse') -const eq = require('./eq') +'use strict' + +const parse = require('./parse.js') const diff = (version1, version2) => { - if (eq(version1, version2)) { + const v1 = parse(version1, null, true) + const v2 = parse(version2, null, true) + const comparison = v1.compare(v2) + + if (comparison === 0) { return null - } else { - const v1 = parse(version1) - const v2 = parse(version2) - const hasPre = v1.prerelease.length || v2.prerelease.length - const prefix = hasPre ? 'pre' : '' - const defaultResult = hasPre ? 'prerelease' : '' - for (const key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } + } + + const v1Higher = comparison > 0 + const highVersion = v1Higher ? v1 : v2 + const lowVersion = v1Higher ? v2 : v1 + const highHasPre = !!highVersion.prerelease.length + const lowHasPre = !!lowVersion.prerelease.length + + if (lowHasPre && !highHasPre) { + // Going from prerelease -> no prerelease requires some special casing + + // If the low version has only a major, then it will always be a major + // Some examples: + // 1.0.0-1 -> 1.0.0 + // 1.0.0-1 -> 1.1.1 + // 1.0.0-1 -> 2.0.0 + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' + } + + // If the main part has no difference + if (lowVersion.compareMain(highVersion) === 0) { + if (lowVersion.minor && !lowVersion.patch) { + return 'minor' } + return 'patch' } - return defaultResult // may be undefined } + + // add the `pre` prefix if we are going to a prerelease version + const prefix = highHasPre ? 'pre' : '' + + if (v1.major !== v2.major) { + return prefix + 'major' + } + + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + + if (v1.patch !== v2.patch) { + return prefix + 'patch' + } + + // high and low are preleases + return 'prerelease' } + module.exports = diff diff --git a/node_modules/semver/functions/eq.js b/node_modules/semver/functions/eq.js index 271fed976f34a..5f0eead1169fe 100644 --- a/node_modules/semver/functions/eq.js +++ b/node_modules/semver/functions/eq.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const eq = (a, b, loose) => compare(a, b, loose) === 0 module.exports = eq diff --git a/node_modules/semver/functions/gt.js b/node_modules/semver/functions/gt.js index d9b2156d8b56c..84a57ddff50a0 100644 --- a/node_modules/semver/functions/gt.js +++ b/node_modules/semver/functions/gt.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const gt = (a, b, loose) => compare(a, b, loose) > 0 module.exports = gt diff --git a/node_modules/semver/functions/gte.js b/node_modules/semver/functions/gte.js index 5aeaa634707a0..7c52bdf2529ad 100644 --- a/node_modules/semver/functions/gte.js +++ b/node_modules/semver/functions/gte.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const gte = (a, b, loose) => compare(a, b, loose) >= 0 module.exports = gte diff --git a/node_modules/semver/functions/inc.js b/node_modules/semver/functions/inc.js index 62d1da2c4093b..ff999e9d04d7f 100644 --- a/node_modules/semver/functions/inc.js +++ b/node_modules/semver/functions/inc.js @@ -1,7 +1,10 @@ +'use strict' + const SemVer = require('../classes/semver') -const inc = (version, release, options, identifier) => { +const inc = (version, release, options, identifier, identifierBase) => { if (typeof (options) === 'string') { + identifierBase = identifier identifier = options options = undefined } @@ -10,7 +13,7 @@ const inc = (version, release, options, identifier) => { return new SemVer( version instanceof SemVer ? version.version : version, options - ).inc(release, identifier).version + ).inc(release, identifier, identifierBase).version } catch (er) { return null } diff --git a/node_modules/semver/functions/lt.js b/node_modules/semver/functions/lt.js index b440ab7d4212d..2fb32a0e63c9a 100644 --- a/node_modules/semver/functions/lt.js +++ b/node_modules/semver/functions/lt.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const lt = (a, b, loose) => compare(a, b, loose) < 0 module.exports = lt diff --git a/node_modules/semver/functions/lte.js b/node_modules/semver/functions/lte.js index 6dcc956505584..da9ee8f4e4404 100644 --- a/node_modules/semver/functions/lte.js +++ b/node_modules/semver/functions/lte.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const lte = (a, b, loose) => compare(a, b, loose) <= 0 module.exports = lte diff --git a/node_modules/semver/functions/major.js b/node_modules/semver/functions/major.js index 4283165e9d271..e6d08dc20cf20 100644 --- a/node_modules/semver/functions/major.js +++ b/node_modules/semver/functions/major.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const major = (a, loose) => new SemVer(a, loose).major module.exports = major diff --git a/node_modules/semver/functions/minor.js b/node_modules/semver/functions/minor.js index 57b3455f827ba..9e70ffda19223 100644 --- a/node_modules/semver/functions/minor.js +++ b/node_modules/semver/functions/minor.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const minor = (a, loose) => new SemVer(a, loose).minor module.exports = minor diff --git a/node_modules/semver/functions/neq.js b/node_modules/semver/functions/neq.js index f944c01576973..84326b7733610 100644 --- a/node_modules/semver/functions/neq.js +++ b/node_modules/semver/functions/neq.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const neq = (a, b, loose) => compare(a, b, loose) !== 0 module.exports = neq diff --git a/node_modules/semver/functions/parse.js b/node_modules/semver/functions/parse.js index a66663aa5918f..d544d33a7e93c 100644 --- a/node_modules/semver/functions/parse.js +++ b/node_modules/semver/functions/parse.js @@ -1,32 +1,17 @@ -const { MAX_LENGTH } = require('../internal/constants') -const { re, t } = require('../internal/re') -const SemVer = require('../classes/semver') - -const parseOptions = require('../internal/parse-options') -const parse = (version, options) => { - options = parseOptions(options) +'use strict' +const SemVer = require('../classes/semver') +const parse = (version, options, throwErrors = false) => { if (version instanceof SemVer) { return version } - - if (typeof version !== 'string') { - return null - } - - if (version.length > MAX_LENGTH) { - return null - } - - const r = options.loose ? re[t.LOOSE] : re[t.FULL] - if (!r.test(version)) { - return null - } - try { return new SemVer(version, options) } catch (er) { - return null + if (!throwErrors) { + return null + } + throw er } } diff --git a/node_modules/semver/functions/patch.js b/node_modules/semver/functions/patch.js index 63afca2524fca..7675162f1742a 100644 --- a/node_modules/semver/functions/patch.js +++ b/node_modules/semver/functions/patch.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const patch = (a, loose) => new SemVer(a, loose).patch module.exports = patch diff --git a/node_modules/semver/functions/prerelease.js b/node_modules/semver/functions/prerelease.js index 06aa13248ae65..b8fe1db5049a2 100644 --- a/node_modules/semver/functions/prerelease.js +++ b/node_modules/semver/functions/prerelease.js @@ -1,3 +1,5 @@ +'use strict' + const parse = require('./parse') const prerelease = (version, options) => { const parsed = parse(version, options) diff --git a/node_modules/semver/functions/rcompare.js b/node_modules/semver/functions/rcompare.js index 0ac509e79dc8c..8e1c222b2ffc2 100644 --- a/node_modules/semver/functions/rcompare.js +++ b/node_modules/semver/functions/rcompare.js @@ -1,3 +1,5 @@ +'use strict' + const compare = require('./compare') const rcompare = (a, b, loose) => compare(b, a, loose) module.exports = rcompare diff --git a/node_modules/semver/functions/rsort.js b/node_modules/semver/functions/rsort.js index 82404c5cfe026..5d3d20096844b 100644 --- a/node_modules/semver/functions/rsort.js +++ b/node_modules/semver/functions/rsort.js @@ -1,3 +1,5 @@ +'use strict' + const compareBuild = require('./compare-build') const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)) module.exports = rsort diff --git a/node_modules/semver/functions/satisfies.js b/node_modules/semver/functions/satisfies.js index 50af1c199b6ca..a0264a222ac82 100644 --- a/node_modules/semver/functions/satisfies.js +++ b/node_modules/semver/functions/satisfies.js @@ -1,3 +1,5 @@ +'use strict' + const Range = require('../classes/range') const satisfies = (version, range, options) => { try { diff --git a/node_modules/semver/functions/sort.js b/node_modules/semver/functions/sort.js index 4d10917aba8e5..edb24b1dc3324 100644 --- a/node_modules/semver/functions/sort.js +++ b/node_modules/semver/functions/sort.js @@ -1,3 +1,5 @@ +'use strict' + const compareBuild = require('./compare-build') const sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose)) module.exports = sort diff --git a/node_modules/semver/functions/valid.js b/node_modules/semver/functions/valid.js index f27bae10731c0..0db67edcb5952 100644 --- a/node_modules/semver/functions/valid.js +++ b/node_modules/semver/functions/valid.js @@ -1,3 +1,5 @@ +'use strict' + const parse = require('./parse') const valid = (version, options) => { const v = parse(version, options) diff --git a/node_modules/semver/index.js b/node_modules/semver/index.js index 57e2ae649479b..285662acb3289 100644 --- a/node_modules/semver/index.js +++ b/node_modules/semver/index.js @@ -1,48 +1,91 @@ +'use strict' + // just pre-load all the stuff that index.js lazily exports const internalRe = require('./internal/re') +const constants = require('./internal/constants') +const SemVer = require('./classes/semver') +const identifiers = require('./internal/identifiers') +const parse = require('./functions/parse') +const valid = require('./functions/valid') +const clean = require('./functions/clean') +const inc = require('./functions/inc') +const diff = require('./functions/diff') +const major = require('./functions/major') +const minor = require('./functions/minor') +const patch = require('./functions/patch') +const prerelease = require('./functions/prerelease') +const compare = require('./functions/compare') +const rcompare = require('./functions/rcompare') +const compareLoose = require('./functions/compare-loose') +const compareBuild = require('./functions/compare-build') +const sort = require('./functions/sort') +const rsort = require('./functions/rsort') +const gt = require('./functions/gt') +const lt = require('./functions/lt') +const eq = require('./functions/eq') +const neq = require('./functions/neq') +const gte = require('./functions/gte') +const lte = require('./functions/lte') +const cmp = require('./functions/cmp') +const coerce = require('./functions/coerce') +const Comparator = require('./classes/comparator') +const Range = require('./classes/range') +const satisfies = require('./functions/satisfies') +const toComparators = require('./ranges/to-comparators') +const maxSatisfying = require('./ranges/max-satisfying') +const minSatisfying = require('./ranges/min-satisfying') +const minVersion = require('./ranges/min-version') +const validRange = require('./ranges/valid') +const outside = require('./ranges/outside') +const gtr = require('./ranges/gtr') +const ltr = require('./ranges/ltr') +const intersects = require('./ranges/intersects') +const simplifyRange = require('./ranges/simplify') +const subset = require('./ranges/subset') module.exports = { + parse, + valid, + clean, + inc, + diff, + major, + minor, + patch, + prerelease, + compare, + rcompare, + compareLoose, + compareBuild, + sort, + rsort, + gt, + lt, + eq, + neq, + gte, + lte, + cmp, + coerce, + Comparator, + Range, + satisfies, + toComparators, + maxSatisfying, + minSatisfying, + minVersion, + validRange, + outside, + gtr, + ltr, + intersects, + simplifyRange, + subset, + SemVer, re: internalRe.re, src: internalRe.src, tokens: internalRe.t, - SEMVER_SPEC_VERSION: require('./internal/constants').SEMVER_SPEC_VERSION, - SemVer: require('./classes/semver'), - compareIdentifiers: require('./internal/identifiers').compareIdentifiers, - rcompareIdentifiers: require('./internal/identifiers').rcompareIdentifiers, - parse: require('./functions/parse'), - valid: require('./functions/valid'), - clean: require('./functions/clean'), - inc: require('./functions/inc'), - diff: require('./functions/diff'), - major: require('./functions/major'), - minor: require('./functions/minor'), - patch: require('./functions/patch'), - prerelease: require('./functions/prerelease'), - compare: require('./functions/compare'), - rcompare: require('./functions/rcompare'), - compareLoose: require('./functions/compare-loose'), - compareBuild: require('./functions/compare-build'), - sort: require('./functions/sort'), - rsort: require('./functions/rsort'), - gt: require('./functions/gt'), - lt: require('./functions/lt'), - eq: require('./functions/eq'), - neq: require('./functions/neq'), - gte: require('./functions/gte'), - lte: require('./functions/lte'), - cmp: require('./functions/cmp'), - coerce: require('./functions/coerce'), - Comparator: require('./classes/comparator'), - Range: require('./classes/range'), - satisfies: require('./functions/satisfies'), - toComparators: require('./ranges/to-comparators'), - maxSatisfying: require('./ranges/max-satisfying'), - minSatisfying: require('./ranges/min-satisfying'), - minVersion: require('./ranges/min-version'), - validRange: require('./ranges/valid'), - outside: require('./ranges/outside'), - gtr: require('./ranges/gtr'), - ltr: require('./ranges/ltr'), - intersects: require('./ranges/intersects'), - simplifyRange: require('./ranges/simplify'), - subset: require('./ranges/subset'), + SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, + compareIdentifiers: identifiers.compareIdentifiers, + rcompareIdentifiers: identifiers.rcompareIdentifiers, } diff --git a/node_modules/semver/internal/constants.js b/node_modules/semver/internal/constants.js index 4f0de59b56949..6d1db9154331d 100644 --- a/node_modules/semver/internal/constants.js +++ b/node_modules/semver/internal/constants.js @@ -1,3 +1,5 @@ +'use strict' + // Note: this is the semver.org version of the spec that it implements // Not necessarily the package version of this code. const SEMVER_SPEC_VERSION = '2.0.0' @@ -9,9 +11,27 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16 +// Max safe length for a build identifier. The max length minus 6 characters for +// the shortest version with a build 0.0.0+BUILD. +const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + +const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', +] + module.exports = { - SEMVER_SPEC_VERSION, MAX_LENGTH, - MAX_SAFE_INTEGER, MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, } diff --git a/node_modules/semver/internal/debug.js b/node_modules/semver/internal/debug.js index 1c00e1369aa2a..20d1e9dceea90 100644 --- a/node_modules/semver/internal/debug.js +++ b/node_modules/semver/internal/debug.js @@ -1,3 +1,5 @@ +'use strict' + const debug = ( typeof process === 'object' && process.env && diff --git a/node_modules/semver/internal/identifiers.js b/node_modules/semver/internal/identifiers.js index e612d0a3d8361..d053472dd58b3 100644 --- a/node_modules/semver/internal/identifiers.js +++ b/node_modules/semver/internal/identifiers.js @@ -1,5 +1,11 @@ +'use strict' + const numeric = /^[0-9]+$/ const compareIdentifiers = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') { + return a === b ? 0 : a < b ? -1 : 1 + } + const anum = numeric.test(a) const bnum = numeric.test(b) diff --git a/node_modules/semver/internal/lrucache.js b/node_modules/semver/internal/lrucache.js new file mode 100644 index 0000000000000..b8bf5262a0505 --- /dev/null +++ b/node_modules/semver/internal/lrucache.js @@ -0,0 +1,42 @@ +'use strict' + +class LRUCache { + constructor () { + this.max = 1000 + this.map = new Map() + } + + get (key) { + const value = this.map.get(key) + if (value === undefined) { + return undefined + } else { + // Remove the key from the map and add it to the end + this.map.delete(key) + this.map.set(key, value) + return value + } + } + + delete (key) { + return this.map.delete(key) + } + + set (key, value) { + const deleted = this.delete(key) + + if (!deleted && value !== undefined) { + // If cache is full, delete the least recently used item + if (this.map.size >= this.max) { + const firstKey = this.map.keys().next().value + this.delete(firstKey) + } + + this.map.set(key, value) + } + + return this + } +} + +module.exports = LRUCache diff --git a/node_modules/semver/internal/parse-options.js b/node_modules/semver/internal/parse-options.js index bbd9ec77a3ff4..5295454130d42 100644 --- a/node_modules/semver/internal/parse-options.js +++ b/node_modules/semver/internal/parse-options.js @@ -1,11 +1,17 @@ -// parse out just the options we care about so we always get a consistent -// obj with keys in a consistent order. -const opts = ['includePrerelease', 'loose', 'rtl'] -const parseOptions = options => - !options ? {} - : typeof options !== 'object' ? { loose: true } - : opts.filter(k => options[k]).reduce((o, k) => { - o[k] = true - return o - }, {}) +'use strict' + +// parse out just the options we care about +const looseOption = Object.freeze({ loose: true }) +const emptyOpts = Object.freeze({ }) +const parseOptions = options => { + if (!options) { + return emptyOpts + } + + if (typeof options !== 'object') { + return looseOption + } + + return options +} module.exports = parseOptions diff --git a/node_modules/semver/internal/re.js b/node_modules/semver/internal/re.js index ed88398a9dbf5..4758c58d424a9 100644 --- a/node_modules/semver/internal/re.js +++ b/node_modules/semver/internal/re.js @@ -1,19 +1,53 @@ -const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants') +'use strict' + +const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, +} = require('./constants') const debug = require('./debug') exports = module.exports = {} // The actual regexps go on exports.re const re = exports.re = [] +const safeRe = exports.safeRe = [] const src = exports.src = [] +const safeSrc = exports.safeSrc = [] const t = exports.t = {} let R = 0 +const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`) + } + return value +} + const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value) const index = R++ debug(name, index, value) t[name] = index src[index] = value + safeSrc[index] = safe re[index] = new RegExp(value, isGlobal ? 'g' : undefined) + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) } // The following Regular Expressions can be used for tokenizing, @@ -23,13 +57,13 @@ const createToken = (name, value, isGlobal) => { // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') -createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') +createToken('NUMERICIDENTIFIERLOOSE', '\\d+') // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. -createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') +createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) // ## Main Version // Three dot-separated numeric identifiers. @@ -44,12 +78,14 @@ createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + // ## Pre-release Version Identifier // A numeric identifier, or a non-numeric identifier. +// Non-numberic identifiers include numberic identifiers but can be longer. +// Therefore non-numberic identifiers must go first. -createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER] -}|${src[t.NONNUMERICIDENTIFIER]})`) +createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIER]})`) -createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE] -}|${src[t.NONNUMERICIDENTIFIER]})`) +createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIERLOOSE]})`) // ## Pre-release Version // Hyphen, followed by one or more dot-separated pre-release version @@ -64,7 +100,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. -createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') +createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -124,12 +160,17 @@ createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) // Coercion. // Extract anything that could conceivably be a part of a valid semver -createToken('COERCE', `${'(^|[^\\d])' + +createToken('COERCEPLAIN', `${'(^|[^\\d])' + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) +createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) +createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + `(?:$|[^\\d])`) createToken('COERCERTL', src[t.COERCE], true) +createToken('COERCERTLFULL', src[t.COERCEFULL], true) // Tilde ranges. // Meaning is "reasonably at or greater than" diff --git a/node_modules/semver/node_modules/lru-cache/LICENSE b/node_modules/semver/node_modules/lru-cache/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/semver/node_modules/lru-cache/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/semver/node_modules/lru-cache/index.js b/node_modules/semver/node_modules/lru-cache/index.js deleted file mode 100644 index 573b6b85b9779..0000000000000 --- a/node_modules/semver/node_modules/lru-cache/index.js +++ /dev/null @@ -1,334 +0,0 @@ -'use strict' - -// A linked list to keep track of recently-used-ness -const Yallist = require('yallist') - -const MAX = Symbol('max') -const LENGTH = Symbol('length') -const LENGTH_CALCULATOR = Symbol('lengthCalculator') -const ALLOW_STALE = Symbol('allowStale') -const MAX_AGE = Symbol('maxAge') -const DISPOSE = Symbol('dispose') -const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet') -const LRU_LIST = Symbol('lruList') -const CACHE = Symbol('cache') -const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet') - -const naiveLength = () => 1 - -// lruList is a yallist where the head is the youngest -// item, and the tail is the oldest. the list contains the Hit -// objects as the entries. -// Each Hit object has a reference to its Yallist.Node. This -// never changes. -// -// cache is a Map (or PseudoMap) that matches the keys to -// the Yallist.Node object. -class LRUCache { - constructor (options) { - if (typeof options === 'number') - options = { max: options } - - if (!options) - options = {} - - if (options.max && (typeof options.max !== 'number' || options.max < 0)) - throw new TypeError('max must be a non-negative number') - // Kind of weird to have a default max of Infinity, but oh well. - const max = this[MAX] = options.max || Infinity - - const lc = options.length || naiveLength - this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc - this[ALLOW_STALE] = options.stale || false - if (options.maxAge && typeof options.maxAge !== 'number') - throw new TypeError('maxAge must be a number') - this[MAX_AGE] = options.maxAge || 0 - this[DISPOSE] = options.dispose - this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false - this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false - this.reset() - } - - // resize the cache when the max changes. - set max (mL) { - if (typeof mL !== 'number' || mL < 0) - throw new TypeError('max must be a non-negative number') - - this[MAX] = mL || Infinity - trim(this) - } - get max () { - return this[MAX] - } - - set allowStale (allowStale) { - this[ALLOW_STALE] = !!allowStale - } - get allowStale () { - return this[ALLOW_STALE] - } - - set maxAge (mA) { - if (typeof mA !== 'number') - throw new TypeError('maxAge must be a non-negative number') - - this[MAX_AGE] = mA - trim(this) - } - get maxAge () { - return this[MAX_AGE] - } - - // resize the cache when the lengthCalculator changes. - set lengthCalculator (lC) { - if (typeof lC !== 'function') - lC = naiveLength - - if (lC !== this[LENGTH_CALCULATOR]) { - this[LENGTH_CALCULATOR] = lC - this[LENGTH] = 0 - this[LRU_LIST].forEach(hit => { - hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key) - this[LENGTH] += hit.length - }) - } - trim(this) - } - get lengthCalculator () { return this[LENGTH_CALCULATOR] } - - get length () { return this[LENGTH] } - get itemCount () { return this[LRU_LIST].length } - - rforEach (fn, thisp) { - thisp = thisp || this - for (let walker = this[LRU_LIST].tail; walker !== null;) { - const prev = walker.prev - forEachStep(this, fn, walker, thisp) - walker = prev - } - } - - forEach (fn, thisp) { - thisp = thisp || this - for (let walker = this[LRU_LIST].head; walker !== null;) { - const next = walker.next - forEachStep(this, fn, walker, thisp) - walker = next - } - } - - keys () { - return this[LRU_LIST].toArray().map(k => k.key) - } - - values () { - return this[LRU_LIST].toArray().map(k => k.value) - } - - reset () { - if (this[DISPOSE] && - this[LRU_LIST] && - this[LRU_LIST].length) { - this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)) - } - - this[CACHE] = new Map() // hash of items by key - this[LRU_LIST] = new Yallist() // list of items in order of use recency - this[LENGTH] = 0 // length of items in the list - } - - dump () { - return this[LRU_LIST].map(hit => - isStale(this, hit) ? false : { - k: hit.key, - v: hit.value, - e: hit.now + (hit.maxAge || 0) - }).toArray().filter(h => h) - } - - dumpLru () { - return this[LRU_LIST] - } - - set (key, value, maxAge) { - maxAge = maxAge || this[MAX_AGE] - - if (maxAge && typeof maxAge !== 'number') - throw new TypeError('maxAge must be a number') - - const now = maxAge ? Date.now() : 0 - const len = this[LENGTH_CALCULATOR](value, key) - - if (this[CACHE].has(key)) { - if (len > this[MAX]) { - del(this, this[CACHE].get(key)) - return false - } - - const node = this[CACHE].get(key) - const item = node.value - - // dispose of the old one before overwriting - // split out into 2 ifs for better coverage tracking - if (this[DISPOSE]) { - if (!this[NO_DISPOSE_ON_SET]) - this[DISPOSE](key, item.value) - } - - item.now = now - item.maxAge = maxAge - item.value = value - this[LENGTH] += len - item.length - item.length = len - this.get(key) - trim(this) - return true - } - - const hit = new Entry(key, value, len, now, maxAge) - - // oversized objects fall out of cache automatically. - if (hit.length > this[MAX]) { - if (this[DISPOSE]) - this[DISPOSE](key, value) - - return false - } - - this[LENGTH] += hit.length - this[LRU_LIST].unshift(hit) - this[CACHE].set(key, this[LRU_LIST].head) - trim(this) - return true - } - - has (key) { - if (!this[CACHE].has(key)) return false - const hit = this[CACHE].get(key).value - return !isStale(this, hit) - } - - get (key) { - return get(this, key, true) - } - - peek (key) { - return get(this, key, false) - } - - pop () { - const node = this[LRU_LIST].tail - if (!node) - return null - - del(this, node) - return node.value - } - - del (key) { - del(this, this[CACHE].get(key)) - } - - load (arr) { - // reset the cache - this.reset() - - const now = Date.now() - // A previous serialized cache has the most recent items first - for (let l = arr.length - 1; l >= 0; l--) { - const hit = arr[l] - const expiresAt = hit.e || 0 - if (expiresAt === 0) - // the item was created without expiration in a non aged cache - this.set(hit.k, hit.v) - else { - const maxAge = expiresAt - now - // dont add already expired items - if (maxAge > 0) { - this.set(hit.k, hit.v, maxAge) - } - } - } - } - - prune () { - this[CACHE].forEach((value, key) => get(this, key, false)) - } -} - -const get = (self, key, doUse) => { - const node = self[CACHE].get(key) - if (node) { - const hit = node.value - if (isStale(self, hit)) { - del(self, node) - if (!self[ALLOW_STALE]) - return undefined - } else { - if (doUse) { - if (self[UPDATE_AGE_ON_GET]) - node.value.now = Date.now() - self[LRU_LIST].unshiftNode(node) - } - } - return hit.value - } -} - -const isStale = (self, hit) => { - if (!hit || (!hit.maxAge && !self[MAX_AGE])) - return false - - const diff = Date.now() - hit.now - return hit.maxAge ? diff > hit.maxAge - : self[MAX_AGE] && (diff > self[MAX_AGE]) -} - -const trim = self => { - if (self[LENGTH] > self[MAX]) { - for (let walker = self[LRU_LIST].tail; - self[LENGTH] > self[MAX] && walker !== null;) { - // We know that we're about to delete this one, and also - // what the next least recently used key will be, so just - // go ahead and set it now. - const prev = walker.prev - del(self, walker) - walker = prev - } - } -} - -const del = (self, node) => { - if (node) { - const hit = node.value - if (self[DISPOSE]) - self[DISPOSE](hit.key, hit.value) - - self[LENGTH] -= hit.length - self[CACHE].delete(hit.key) - self[LRU_LIST].removeNode(node) - } -} - -class Entry { - constructor (key, value, length, now, maxAge) { - this.key = key - this.value = value - this.length = length - this.now = now - this.maxAge = maxAge || 0 - } -} - -const forEachStep = (self, fn, node, thisp) => { - let hit = node.value - if (isStale(self, hit)) { - del(self, node) - if (!self[ALLOW_STALE]) - hit = undefined - } - if (hit) - fn.call(thisp, hit.value, hit.key, self) -} - -module.exports = LRUCache diff --git a/node_modules/semver/node_modules/lru-cache/package.json b/node_modules/semver/node_modules/lru-cache/package.json deleted file mode 100644 index 43b7502c3e7c7..0000000000000 --- a/node_modules/semver/node_modules/lru-cache/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "lru-cache", - "description": "A cache object that deletes the least-recently-used items.", - "version": "6.0.0", - "author": "Isaac Z. Schlueter <i@izs.me>", - "keywords": [ - "mru", - "lru", - "cache" - ], - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "main": "index.js", - "repository": "git://github.com/isaacs/node-lru-cache.git", - "devDependencies": { - "benchmark": "^2.1.4", - "tap": "^14.10.7" - }, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "files": [ - "index.js" - ], - "engines": { - "node": ">=10" - } -} diff --git a/node_modules/semver/package.json b/node_modules/semver/package.json index 7898f5902cb73..2b8cadaa2387e 100644 --- a/node_modules/semver/package.json +++ b/node_modules/semver/package.json @@ -1,36 +1,35 @@ { "name": "semver", - "version": "7.3.7", + "version": "7.7.3", "description": "The semantic version parser used by npm.", "main": "index.js", "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", - "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "posttest": "npm run lint", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.3.2", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.25.1", + "benchmark": "^2.1.4", "tap": "^16.0.0" }, "license": "ISC", "repository": { "type": "git", - "url": "https://github.com/npm/node-semver.git" + "url": "git+https://github.com/npm/node-semver.git" }, "bin": { "semver": "bin/semver.js" }, "files": [ "bin/", + "lib/", "classes/", "functions/", "internal/", @@ -40,29 +39,22 @@ "range.bnf" ], "tap": { - "check-coverage": true, - "coverage-map": "map.js" + "timeout": 30, + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { "node": ">=10" }, - "dependencies": { - "lru-cache": "^6.0.0" - }, "author": "GitHub Inc.", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.3.2", + "version": "4.25.1", "engines": ">=10", - "ciVersions": [ - "10.0.0", - "10.x", - "12.x", - "14.x", - "16.x" - ], "distPaths": [ - "bin/", "classes/", "functions/", "internal/", @@ -70,6 +62,17 @@ "index.js", "preload.js", "range.bnf" - ] + ], + "allowPaths": [ + "/classes/", + "/functions/", + "/internal/", + "/ranges/", + "/index.js", + "/preload.js", + "/range.bnf", + "/benchmarks" + ], + "publish": "true" } } diff --git a/node_modules/semver/preload.js b/node_modules/semver/preload.js index 947cd4f7917ff..e6c47b9b051d9 100644 --- a/node_modules/semver/preload.js +++ b/node_modules/semver/preload.js @@ -1,2 +1,4 @@ +'use strict' + // XXX remove in v8 or beyond module.exports = require('./index.js') diff --git a/node_modules/semver/ranges/gtr.js b/node_modules/semver/ranges/gtr.js index db7e35599dd56..0e7601f693554 100644 --- a/node_modules/semver/ranges/gtr.js +++ b/node_modules/semver/ranges/gtr.js @@ -1,3 +1,5 @@ +'use strict' + // Determine if version is greater than all the versions possible in the range. const outside = require('./outside') const gtr = (version, range, options) => outside(version, range, '>', options) diff --git a/node_modules/semver/ranges/intersects.js b/node_modules/semver/ranges/intersects.js index 3d1a6f31dfbe0..917be7e4293d2 100644 --- a/node_modules/semver/ranges/intersects.js +++ b/node_modules/semver/ranges/intersects.js @@ -1,7 +1,9 @@ +'use strict' + const Range = require('../classes/range') const intersects = (r1, r2, options) => { r1 = new Range(r1, options) r2 = new Range(r2, options) - return r1.intersects(r2) + return r1.intersects(r2, options) } module.exports = intersects diff --git a/node_modules/semver/ranges/ltr.js b/node_modules/semver/ranges/ltr.js index 528a885ebdfcd..aa5e568ec279d 100644 --- a/node_modules/semver/ranges/ltr.js +++ b/node_modules/semver/ranges/ltr.js @@ -1,3 +1,5 @@ +'use strict' + const outside = require('./outside') // Determine if version is less than all the versions possible in the range const ltr = (version, range, options) => outside(version, range, '<', options) diff --git a/node_modules/semver/ranges/max-satisfying.js b/node_modules/semver/ranges/max-satisfying.js index 6e3d993c67860..01fe5ae383715 100644 --- a/node_modules/semver/ranges/max-satisfying.js +++ b/node_modules/semver/ranges/max-satisfying.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const Range = require('../classes/range') diff --git a/node_modules/semver/ranges/min-satisfying.js b/node_modules/semver/ranges/min-satisfying.js index 9b60974e2253a..af89c8ef43269 100644 --- a/node_modules/semver/ranges/min-satisfying.js +++ b/node_modules/semver/ranges/min-satisfying.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const Range = require('../classes/range') const minSatisfying = (versions, range, options) => { diff --git a/node_modules/semver/ranges/min-version.js b/node_modules/semver/ranges/min-version.js index 350e1f78368ea..09a65aa36fd51 100644 --- a/node_modules/semver/ranges/min-version.js +++ b/node_modules/semver/ranges/min-version.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const Range = require('../classes/range') const gt = require('../functions/gt') diff --git a/node_modules/semver/ranges/outside.js b/node_modules/semver/ranges/outside.js index ae99b10a5b9e6..ca7442120798e 100644 --- a/node_modules/semver/ranges/outside.js +++ b/node_modules/semver/ranges/outside.js @@ -1,3 +1,5 @@ +'use strict' + const SemVer = require('../classes/semver') const Comparator = require('../classes/comparator') const { ANY } = Comparator diff --git a/node_modules/semver/ranges/simplify.js b/node_modules/semver/ranges/simplify.js index 618d5b6273551..262732e670d7d 100644 --- a/node_modules/semver/ranges/simplify.js +++ b/node_modules/semver/ranges/simplify.js @@ -1,3 +1,5 @@ +'use strict' + // given a set of versions and a range, create a "simplified" range // that includes the same versions that the original range does // If the original range is shorter than the simplified one, return that. diff --git a/node_modules/semver/ranges/subset.js b/node_modules/semver/ranges/subset.js index e0dea43c2b6a8..2c49aef1be5e8 100644 --- a/node_modules/semver/ranges/subset.js +++ b/node_modules/semver/ranges/subset.js @@ -1,3 +1,5 @@ +'use strict' + const Range = require('../classes/range.js') const Comparator = require('../classes/comparator.js') const { ANY } = Comparator @@ -68,6 +70,9 @@ const subset = (sub, dom, options = {}) => { return true } +const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] +const minimumVersion = [new Comparator('>=0.0.0')] + const simpleSubset = (sub, dom, options) => { if (sub === dom) { return true @@ -77,9 +82,9 @@ const simpleSubset = (sub, dom, options) => { if (dom.length === 1 && dom[0].semver === ANY) { return true } else if (options.includePrerelease) { - sub = [new Comparator('>=0.0.0-0')] + sub = minimumVersionWithPreRelease } else { - sub = [new Comparator('>=0.0.0')] + sub = minimumVersion } } @@ -87,7 +92,7 @@ const simpleSubset = (sub, dom, options) => { if (options.includePrerelease) { return true } else { - dom = [new Comparator('>=0.0.0')] + dom = minimumVersion } } diff --git a/node_modules/semver/ranges/to-comparators.js b/node_modules/semver/ranges/to-comparators.js index 6c8bc7e6f15a4..5be251961acbd 100644 --- a/node_modules/semver/ranges/to-comparators.js +++ b/node_modules/semver/ranges/to-comparators.js @@ -1,3 +1,5 @@ +'use strict' + const Range = require('../classes/range') // Mostly just for testing and legacy API reasons diff --git a/node_modules/semver/ranges/valid.js b/node_modules/semver/ranges/valid.js index 365f35689d358..cc6b0e9f68f95 100644 --- a/node_modules/semver/ranges/valid.js +++ b/node_modules/semver/ranges/valid.js @@ -1,3 +1,5 @@ +'use strict' + const Range = require('../classes/range') const validRange = (range, options) => { try { diff --git a/node_modules/set-blocking/LICENSE.txt b/node_modules/set-blocking/LICENSE.txt deleted file mode 100644 index 836440bef7cf1..0000000000000 --- a/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/node_modules/set-blocking/index.js b/node_modules/set-blocking/index.js deleted file mode 100644 index 6f78774bb63ee..0000000000000 --- a/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/node_modules/set-blocking/package.json b/node_modules/set-blocking/package.json deleted file mode 100644 index c082db72c6259..0000000000000 --- a/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 <ben@npmjs.com>", - "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/node_modules/signal-exit/LICENSE.txt b/node_modules/signal-exit/LICENSE.txt index eead04a12162d..954f2fa823500 100644 --- a/node_modules/signal-exit/LICENSE.txt +++ b/node_modules/signal-exit/LICENSE.txt @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2015, Contributors +Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided diff --git a/node_modules/signal-exit/dist/cjs/browser.js b/node_modules/signal-exit/dist/cjs/browser.js new file mode 100644 index 0000000000000..614fbf0100235 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/browser.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unload = exports.load = exports.onExit = void 0; +const onExit = () => () => { }; +exports.onExit = onExit; +const load = () => { }; +exports.load = load; +const unload = () => { }; +exports.unload = unload; +//# sourceMappingURL=browser.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/index.js b/node_modules/signal-exit/dist/cjs/index.js new file mode 100644 index 0000000000000..797e6743fe48e --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/index.js @@ -0,0 +1,279 @@ +"use strict"; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.unload = exports.load = exports.onExit = exports.signals = void 0; +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +// grab a reference to node's real process object right away +const signals_js_1 = require("./signals.js"); +Object.defineProperty(exports, "signals", { enumerable: true, get: function () { return signals_js_1.signals; } }); +const processOk = (process) => !!process && + typeof process === 'object' && + typeof process.removeListener === 'function' && + typeof process.emit === 'function' && + typeof process.reallyExit === 'function' && + typeof process.listeners === 'function' && + typeof process.kill === 'function' && + typeof process.pid === 'number' && + typeof process.on === 'function'; +const kExitEmitter = Symbol.for('signal-exit emitter'); +const global = globalThis; +const ObjectDefineProperty = Object.defineProperty.bind(Object); +// teeny special purpose ee +class Emitter { + emitted = { + afterExit: false, + exit: false, + }; + listeners = { + afterExit: [], + exit: [], + }; + count = 0; + id = Math.random(); + constructor() { + if (global[kExitEmitter]) { + return global[kExitEmitter]; + } + ObjectDefineProperty(global, kExitEmitter, { + value: this, + writable: false, + enumerable: false, + configurable: false, + }); + } + on(ev, fn) { + this.listeners[ev].push(fn); + } + removeListener(ev, fn) { + const list = this.listeners[ev]; + const i = list.indexOf(fn); + /* c8 ignore start */ + if (i === -1) { + return; + } + /* c8 ignore stop */ + if (i === 0 && list.length === 1) { + list.length = 0; + } + else { + list.splice(i, 1); + } + } + emit(ev, code, signal) { + if (this.emitted[ev]) { + return false; + } + this.emitted[ev] = true; + let ret = false; + for (const fn of this.listeners[ev]) { + ret = fn(code, signal) === true || ret; + } + if (ev === 'exit') { + ret = this.emit('afterExit', code, signal) || ret; + } + return ret; + } +} +class SignalExitBase { +} +const signalExitWrap = (handler) => { + return { + onExit(cb, opts) { + return handler.onExit(cb, opts); + }, + load() { + return handler.load(); + }, + unload() { + return handler.unload(); + }, + }; +}; +class SignalExitFallback extends SignalExitBase { + onExit() { + return () => { }; + } + load() { } + unload() { } +} +class SignalExit extends SignalExitBase { + // "SIGHUP" throws an `ENOSYS` error on Windows, + // so use a supported signal instead + /* c8 ignore start */ + #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; + /* c8 ignore stop */ + #emitter = new Emitter(); + #process; + #originalProcessEmit; + #originalProcessReallyExit; + #sigListeners = {}; + #loaded = false; + constructor(process) { + super(); + this.#process = process; + // { <signal>: <listener fn>, ... } + this.#sigListeners = {}; + for (const sig of signals_js_1.signals) { + this.#sigListeners[sig] = () => { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + const listeners = this.#process.listeners(sig); + let { count } = this.#emitter; + // This is a workaround for the fact that signal-exit v3 and signal + // exit v4 are not aware of each other, and each will attempt to let + // the other handle it, so neither of them do. To correct this, we + // detect if we're the only handler *except* for previous versions + // of signal-exit, and increment by the count of listeners it has + // created. + /* c8 ignore start */ + const p = process; + if (typeof p.__signal_exit_emitter__ === 'object' && + typeof p.__signal_exit_emitter__.count === 'number') { + count += p.__signal_exit_emitter__.count; + } + /* c8 ignore stop */ + if (listeners.length === count) { + this.unload(); + const ret = this.#emitter.emit('exit', null, sig); + /* c8 ignore start */ + const s = sig === 'SIGHUP' ? this.#hupSig : sig; + if (!ret) + process.kill(process.pid, s); + /* c8 ignore stop */ + } + }; + } + this.#originalProcessReallyExit = process.reallyExit; + this.#originalProcessEmit = process.emit; + } + onExit(cb, opts) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return () => { }; + } + /* c8 ignore stop */ + if (this.#loaded === false) { + this.load(); + } + const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; + this.#emitter.on(ev, cb); + return () => { + this.#emitter.removeListener(ev, cb); + if (this.#emitter.listeners['exit'].length === 0 && + this.#emitter.listeners['afterExit'].length === 0) { + this.unload(); + } + }; + } + load() { + if (this.#loaded) { + return; + } + this.#loaded = true; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + this.#emitter.count += 1; + for (const sig of signals_js_1.signals) { + try { + const fn = this.#sigListeners[sig]; + if (fn) + this.#process.on(sig, fn); + } + catch (_) { } + } + this.#process.emit = (ev, ...a) => { + return this.#processEmit(ev, ...a); + }; + this.#process.reallyExit = (code) => { + return this.#processReallyExit(code); + }; + } + unload() { + if (!this.#loaded) { + return; + } + this.#loaded = false; + signals_js_1.signals.forEach(sig => { + const listener = this.#sigListeners[sig]; + /* c8 ignore start */ + if (!listener) { + throw new Error('Listener not defined for signal: ' + sig); + } + /* c8 ignore stop */ + try { + this.#process.removeListener(sig, listener); + /* c8 ignore start */ + } + catch (_) { } + /* c8 ignore stop */ + }); + this.#process.emit = this.#originalProcessEmit; + this.#process.reallyExit = this.#originalProcessReallyExit; + this.#emitter.count -= 1; + } + #processReallyExit(code) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return 0; + } + this.#process.exitCode = code || 0; + /* c8 ignore stop */ + this.#emitter.emit('exit', this.#process.exitCode, null); + return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); + } + #processEmit(ev, ...args) { + const og = this.#originalProcessEmit; + if (ev === 'exit' && processOk(this.#process)) { + if (typeof args[0] === 'number') { + this.#process.exitCode = args[0]; + /* c8 ignore start */ + } + /* c8 ignore start */ + const ret = og.call(this.#process, ev, ...args); + /* c8 ignore start */ + this.#emitter.emit('exit', this.#process.exitCode, null); + /* c8 ignore stop */ + return ret; + } + else { + return og.call(this.#process, ev, ...args); + } + } +} +const process = globalThis.process; +// wrap so that we call the method on the actual handler, without +// exporting it directly. +_a = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()), +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +exports.onExit = _a.onExit, +/** + * Load the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +exports.load = _a.load, +/** + * Unload the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +exports.unload = _a.unload; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/cjs/package.json b/node_modules/signal-exit/dist/cjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/signal-exit/dist/cjs/signals.js b/node_modules/signal-exit/dist/cjs/signals.js new file mode 100644 index 0000000000000..28afc5027d51d --- /dev/null +++ b/node_modules/signal-exit/dist/cjs/signals.js @@ -0,0 +1,42 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.signals = void 0; +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +exports.signals = []; +exports.signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); +if (process.platform !== 'win32') { + exports.signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ); +} +if (process.platform === 'linux') { + exports.signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); +} +//# sourceMappingURL=signals.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/browser.js b/node_modules/signal-exit/dist/mjs/browser.js new file mode 100644 index 0000000000000..9c5f9b9e748c5 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/browser.js @@ -0,0 +1,4 @@ +export const onExit = () => () => { }; +export const load = () => { }; +export const unload = () => { }; +//# sourceMappingURL=browser.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/index.js b/node_modules/signal-exit/dist/mjs/index.js new file mode 100644 index 0000000000000..4a78bad847d40 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/index.js @@ -0,0 +1,275 @@ +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +// grab a reference to node's real process object right away +import { signals } from './signals.js'; +export { signals }; +const processOk = (process) => !!process && + typeof process === 'object' && + typeof process.removeListener === 'function' && + typeof process.emit === 'function' && + typeof process.reallyExit === 'function' && + typeof process.listeners === 'function' && + typeof process.kill === 'function' && + typeof process.pid === 'number' && + typeof process.on === 'function'; +const kExitEmitter = Symbol.for('signal-exit emitter'); +const global = globalThis; +const ObjectDefineProperty = Object.defineProperty.bind(Object); +// teeny special purpose ee +class Emitter { + emitted = { + afterExit: false, + exit: false, + }; + listeners = { + afterExit: [], + exit: [], + }; + count = 0; + id = Math.random(); + constructor() { + if (global[kExitEmitter]) { + return global[kExitEmitter]; + } + ObjectDefineProperty(global, kExitEmitter, { + value: this, + writable: false, + enumerable: false, + configurable: false, + }); + } + on(ev, fn) { + this.listeners[ev].push(fn); + } + removeListener(ev, fn) { + const list = this.listeners[ev]; + const i = list.indexOf(fn); + /* c8 ignore start */ + if (i === -1) { + return; + } + /* c8 ignore stop */ + if (i === 0 && list.length === 1) { + list.length = 0; + } + else { + list.splice(i, 1); + } + } + emit(ev, code, signal) { + if (this.emitted[ev]) { + return false; + } + this.emitted[ev] = true; + let ret = false; + for (const fn of this.listeners[ev]) { + ret = fn(code, signal) === true || ret; + } + if (ev === 'exit') { + ret = this.emit('afterExit', code, signal) || ret; + } + return ret; + } +} +class SignalExitBase { +} +const signalExitWrap = (handler) => { + return { + onExit(cb, opts) { + return handler.onExit(cb, opts); + }, + load() { + return handler.load(); + }, + unload() { + return handler.unload(); + }, + }; +}; +class SignalExitFallback extends SignalExitBase { + onExit() { + return () => { }; + } + load() { } + unload() { } +} +class SignalExit extends SignalExitBase { + // "SIGHUP" throws an `ENOSYS` error on Windows, + // so use a supported signal instead + /* c8 ignore start */ + #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP'; + /* c8 ignore stop */ + #emitter = new Emitter(); + #process; + #originalProcessEmit; + #originalProcessReallyExit; + #sigListeners = {}; + #loaded = false; + constructor(process) { + super(); + this.#process = process; + // { <signal>: <listener fn>, ... } + this.#sigListeners = {}; + for (const sig of signals) { + this.#sigListeners[sig] = () => { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + const listeners = this.#process.listeners(sig); + let { count } = this.#emitter; + // This is a workaround for the fact that signal-exit v3 and signal + // exit v4 are not aware of each other, and each will attempt to let + // the other handle it, so neither of them do. To correct this, we + // detect if we're the only handler *except* for previous versions + // of signal-exit, and increment by the count of listeners it has + // created. + /* c8 ignore start */ + const p = process; + if (typeof p.__signal_exit_emitter__ === 'object' && + typeof p.__signal_exit_emitter__.count === 'number') { + count += p.__signal_exit_emitter__.count; + } + /* c8 ignore stop */ + if (listeners.length === count) { + this.unload(); + const ret = this.#emitter.emit('exit', null, sig); + /* c8 ignore start */ + const s = sig === 'SIGHUP' ? this.#hupSig : sig; + if (!ret) + process.kill(process.pid, s); + /* c8 ignore stop */ + } + }; + } + this.#originalProcessReallyExit = process.reallyExit; + this.#originalProcessEmit = process.emit; + } + onExit(cb, opts) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return () => { }; + } + /* c8 ignore stop */ + if (this.#loaded === false) { + this.load(); + } + const ev = opts?.alwaysLast ? 'afterExit' : 'exit'; + this.#emitter.on(ev, cb); + return () => { + this.#emitter.removeListener(ev, cb); + if (this.#emitter.listeners['exit'].length === 0 && + this.#emitter.listeners['afterExit'].length === 0) { + this.unload(); + } + }; + } + load() { + if (this.#loaded) { + return; + } + this.#loaded = true; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + this.#emitter.count += 1; + for (const sig of signals) { + try { + const fn = this.#sigListeners[sig]; + if (fn) + this.#process.on(sig, fn); + } + catch (_) { } + } + this.#process.emit = (ev, ...a) => { + return this.#processEmit(ev, ...a); + }; + this.#process.reallyExit = (code) => { + return this.#processReallyExit(code); + }; + } + unload() { + if (!this.#loaded) { + return; + } + this.#loaded = false; + signals.forEach(sig => { + const listener = this.#sigListeners[sig]; + /* c8 ignore start */ + if (!listener) { + throw new Error('Listener not defined for signal: ' + sig); + } + /* c8 ignore stop */ + try { + this.#process.removeListener(sig, listener); + /* c8 ignore start */ + } + catch (_) { } + /* c8 ignore stop */ + }); + this.#process.emit = this.#originalProcessEmit; + this.#process.reallyExit = this.#originalProcessReallyExit; + this.#emitter.count -= 1; + } + #processReallyExit(code) { + /* c8 ignore start */ + if (!processOk(this.#process)) { + return 0; + } + this.#process.exitCode = code || 0; + /* c8 ignore stop */ + this.#emitter.emit('exit', this.#process.exitCode, null); + return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode); + } + #processEmit(ev, ...args) { + const og = this.#originalProcessEmit; + if (ev === 'exit' && processOk(this.#process)) { + if (typeof args[0] === 'number') { + this.#process.exitCode = args[0]; + /* c8 ignore start */ + } + /* c8 ignore start */ + const ret = og.call(this.#process, ev, ...args); + /* c8 ignore start */ + this.#emitter.emit('exit', this.#process.exitCode, null); + /* c8 ignore stop */ + return ret; + } + else { + return og.call(this.#process, ev, ...args); + } + } +} +const process = globalThis.process; +// wrap so that we call the method on the actual handler, without +// exporting it directly. +export const { +/** + * Called when the process is exiting, whether via signal, explicit + * exit, or running out of stuff to do. + * + * If the global process object is not suitable for instrumentation, + * then this will be a no-op. + * + * Returns a function that may be used to unload signal-exit. + */ +onExit, +/** + * Load the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +load, +/** + * Unload the listeners. Likely you never need to call this, unless + * doing a rather deep integration with signal-exit functionality. + * Mostly exposed for the benefit of testing. + * + * @internal + */ +unload, } = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/dist/mjs/package.json b/node_modules/signal-exit/dist/mjs/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/signal-exit/dist/mjs/signals.js b/node_modules/signal-exit/dist/mjs/signals.js new file mode 100644 index 0000000000000..7dbf15a5a6321 --- /dev/null +++ b/node_modules/signal-exit/dist/mjs/signals.js @@ -0,0 +1,39 @@ +/** + * This is not the set of all possible signals. + * + * It IS, however, the set of all signals that trigger + * an exit on either Linux or BSD systems. Linux is a + * superset of the signal names supported on BSD, and + * the unknown signals just fail to register, so we can + * catch that easily enough. + * + * Windows signals are a different set, since there are + * signals that terminate Windows processes, but don't + * terminate (or don't even exist) on Posix systems. + * + * Don't bother with SIGKILL. It's uncatchable, which + * means that we can't fire any callbacks anyway. + * + * If a user does happen to register a handler on a non- + * fatal signal like SIGWINCH or something, and then + * exit, it'll end up firing `process.emit('exit')`, so + * the handler will be fired anyway. + * + * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised + * artificially, inherently leave the process in a + * state from which it is not safe to try and enter JS + * listeners. + */ +export const signals = []; +signals.push('SIGHUP', 'SIGINT', 'SIGTERM'); +if (process.platform !== 'win32') { + signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ); +} +if (process.platform === 'linux') { + signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT'); +} +//# sourceMappingURL=signals.js.map \ No newline at end of file diff --git a/node_modules/signal-exit/index.js b/node_modules/signal-exit/index.js deleted file mode 100644 index 93703f369265c..0000000000000 --- a/node_modules/signal-exit/index.js +++ /dev/null @@ -1,202 +0,0 @@ -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -// grab a reference to node's real process object right away -var process = global.process - -const processOk = function (process) { - return process && - typeof process === 'object' && - typeof process.removeListener === 'function' && - typeof process.emit === 'function' && - typeof process.reallyExit === 'function' && - typeof process.listeners === 'function' && - typeof process.kill === 'function' && - typeof process.pid === 'number' && - typeof process.on === 'function' -} - -// some kind of non-node environment, just no-op -/* istanbul ignore if */ -if (!processOk(process)) { - module.exports = function () { - return function () {} - } -} else { - var assert = require('assert') - var signals = require('./signals.js') - var isWin = /^win/i.test(process.platform) - - var EE = require('events') - /* istanbul ignore if */ - if (typeof EE !== 'function') { - EE = EE.EventEmitter - } - - var emitter - if (process.__signal_exit_emitter__) { - emitter = process.__signal_exit_emitter__ - } else { - emitter = process.__signal_exit_emitter__ = new EE() - emitter.count = 0 - emitter.emitted = {} - } - - // Because this emitter is a global, we have to check to see if a - // previous version of this library failed to enable infinite listeners. - // I know what you're about to say. But literally everything about - // signal-exit is a compromise with evil. Get used to it. - if (!emitter.infinite) { - emitter.setMaxListeners(Infinity) - emitter.infinite = true - } - - module.exports = function (cb, opts) { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return function () {} - } - assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') - - if (loaded === false) { - load() - } - - var ev = 'exit' - if (opts && opts.alwaysLast) { - ev = 'afterexit' - } - - var remove = function () { - emitter.removeListener(ev, cb) - if (emitter.listeners('exit').length === 0 && - emitter.listeners('afterexit').length === 0) { - unload() - } - } - emitter.on(ev, cb) - - return remove - } - - var unload = function unload () { - if (!loaded || !processOk(global.process)) { - return - } - loaded = false - - signals.forEach(function (sig) { - try { - process.removeListener(sig, sigListeners[sig]) - } catch (er) {} - }) - process.emit = originalProcessEmit - process.reallyExit = originalProcessReallyExit - emitter.count -= 1 - } - module.exports.unload = unload - - var emit = function emit (event, code, signal) { - /* istanbul ignore if */ - if (emitter.emitted[event]) { - return - } - emitter.emitted[event] = true - emitter.emit(event, code, signal) - } - - // { <signal>: <listener fn>, ... } - var sigListeners = {} - signals.forEach(function (sig) { - sigListeners[sig] = function listener () { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return - } - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - var listeners = process.listeners(sig) - if (listeners.length === emitter.count) { - unload() - emit('exit', null, sig) - /* istanbul ignore next */ - emit('afterexit', null, sig) - /* istanbul ignore next */ - if (isWin && sig === 'SIGHUP') { - // "SIGHUP" throws an `ENOSYS` error on Windows, - // so use a supported signal instead - sig = 'SIGINT' - } - /* istanbul ignore next */ - process.kill(process.pid, sig) - } - } - }) - - module.exports.signals = function () { - return signals - } - - var loaded = false - - var load = function load () { - if (loaded || !processOk(global.process)) { - return - } - loaded = true - - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - emitter.count += 1 - - signals = signals.filter(function (sig) { - try { - process.on(sig, sigListeners[sig]) - return true - } catch (er) { - return false - } - }) - - process.emit = processEmit - process.reallyExit = processReallyExit - } - module.exports.load = load - - var originalProcessReallyExit = process.reallyExit - var processReallyExit = function processReallyExit (code) { - /* istanbul ignore if */ - if (!processOk(global.process)) { - return - } - process.exitCode = code || /* istanbul ignore next */ 0 - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - originalProcessReallyExit.call(process, process.exitCode) - } - - var originalProcessEmit = process.emit - var processEmit = function processEmit (ev, arg) { - if (ev === 'exit' && processOk(global.process)) { - /* istanbul ignore else */ - if (arg !== undefined) { - process.exitCode = arg - } - var ret = originalProcessEmit.apply(this, arguments) - /* istanbul ignore next */ - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - return ret - } else { - return originalProcessEmit.apply(this, arguments) - } - } -} diff --git a/node_modules/signal-exit/package.json b/node_modules/signal-exit/package.json index e1a00311f9fbe..ac176cec74374 100644 --- a/node_modules/signal-exit/package.json +++ b/node_modules/signal-exit/package.json @@ -1,19 +1,49 @@ { "name": "signal-exit", - "version": "3.0.7", + "version": "4.1.0", "description": "when you want to fire an event no matter how a process exits.", - "main": "index.js", - "scripts": { - "test": "tap", - "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "browser": "./dist/mjs/browser.js", + "types": "./dist/mjs/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "./signals": { + "import": { + "types": "./dist/mjs/signals.d.ts", + "default": "./dist/mjs/signals.js" + }, + "require": { + "types": "./dist/cjs/signals.d.ts", + "default": "./dist/cjs/signals.js" + } + }, + "./browser": { + "import": { + "types": "./dist/mjs/browser.d.ts", + "default": "./dist/mjs/browser.js" + }, + "require": { + "types": "./dist/cjs/browser.d.ts", + "default": "./dist/cjs/browser.js" + } + } }, "files": [ - "index.js", - "signals.js" + "dist" ], + "engines": { + "node": ">=14" + }, "repository": { "type": "git", "url": "https://github.com/tapjs/signal-exit.git" @@ -24,15 +54,53 @@ ], "author": "Ben Coe <ben@npmjs.com>", "license": "ISC", - "bugs": { - "url": "https://github.com/tapjs/signal-exit/issues" - }, - "homepage": "https://github.com/tapjs/signal-exit", "devDependencies": { - "chai": "^3.5.0", - "coveralls": "^3.1.1", - "nyc": "^15.1.0", - "standard-version": "^9.3.1", - "tap": "^15.1.1" + "@types/cross-spawn": "^6.0.2", + "@types/node": "^18.15.11", + "@types/signal-exit": "^3.0.1", + "@types/tap": "^15.0.8", + "c8": "^7.13.0", + "prettier": "^2.8.6", + "tap": "^16.3.4", + "ts-node": "^10.9.1", + "typedoc": "^0.23.28", + "typescript": "^5.0.2" + }, + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" + }, + "prettier": { + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "tap": { + "coverage": false, + "jobs": 1, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } } diff --git a/node_modules/signal-exit/signals.js b/node_modules/signal-exit/signals.js deleted file mode 100644 index 3bd67a8a554e3..0000000000000 --- a/node_modules/signal-exit/signals.js +++ /dev/null @@ -1,53 +0,0 @@ -// This is not the set of all possible signals. -// -// It IS, however, the set of all signals that trigger -// an exit on either Linux or BSD systems. Linux is a -// superset of the signal names supported on BSD, and -// the unknown signals just fail to register, so we can -// catch that easily enough. -// -// Don't bother with SIGKILL. It's uncatchable, which -// means that we can't fire any callbacks anyway. -// -// If a user does happen to register a handler on a non- -// fatal signal like SIGWINCH or something, and then -// exit, it'll end up firing `process.emit('exit')`, so -// the handler will be fired anyway. -// -// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised -// artificially, inherently leave the process in a -// state from which it is not safe to try and enter JS -// listeners. -module.exports = [ - 'SIGABRT', - 'SIGALRM', - 'SIGHUP', - 'SIGINT', - 'SIGTERM' -] - -if (process.platform !== 'win32') { - module.exports.push( - 'SIGVTALRM', - 'SIGXCPU', - 'SIGXFSZ', - 'SIGUSR2', - 'SIGTRAP', - 'SIGSYS', - 'SIGQUIT', - 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ) -} - -if (process.platform === 'linux') { - module.exports.push( - 'SIGIO', - 'SIGPOLL', - 'SIGPWR', - 'SIGSTKFLT', - 'SIGUNUSED' - ) -} diff --git a/node_modules/sigstore/LICENSE b/node_modules/sigstore/LICENSE new file mode 100644 index 0000000000000..e9e7c1679a09d --- /dev/null +++ b/node_modules/sigstore/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 The Sigstore Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/sigstore/dist/config.js b/node_modules/sigstore/dist/config.js new file mode 100644 index 0000000000000..e8b2392f97f23 --- /dev/null +++ b/node_modules/sigstore/dist/config.js @@ -0,0 +1,120 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DEFAULT_TIMEOUT = exports.DEFAULT_RETRY = void 0; +exports.createBundleBuilder = createBundleBuilder; +exports.createKeyFinder = createKeyFinder; +exports.createVerificationPolicy = createVerificationPolicy; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const core_1 = require("@sigstore/core"); +const sign_1 = require("@sigstore/sign"); +const verify_1 = require("@sigstore/verify"); +exports.DEFAULT_RETRY = { retries: 2 }; +exports.DEFAULT_TIMEOUT = 5000; +function createBundleBuilder(bundleType, options) { + const bundlerOptions = { + signer: initSigner(options), + witnesses: initWitnesses(options), + }; + switch (bundleType) { + case 'messageSignature': + return new sign_1.MessageSignatureBundleBuilder(bundlerOptions); + case 'dsseEnvelope': + return new sign_1.DSSEBundleBuilder({ + ...bundlerOptions, + certificateChain: options.legacyCompatibility, + }); + } +} +// Translates the public KeySelector type into the KeyFinderFunc type needed by +// the verifier. +function createKeyFinder(keySelector) { + return (hint) => { + const key = keySelector(hint); + if (!key) { + throw new verify_1.VerificationError({ + code: 'PUBLIC_KEY_ERROR', + message: `key not found: ${hint}`, + }); + } + return { + publicKey: core_1.crypto.createPublicKey(key), + validFor: () => true, + }; + }; +} +function createVerificationPolicy(options) { + const policy = {}; + const san = options.certificateIdentityEmail || options.certificateIdentityURI; + if (san) { + policy.subjectAlternativeName = san; + } + if (options.certificateIssuer) { + policy.extensions = { issuer: options.certificateIssuer }; + } + return policy; +} +// Instantiate the FulcioSigner based on the supplied options. +function initSigner(options) { + return new sign_1.FulcioSigner({ + fulcioBaseURL: options.fulcioURL, + identityProvider: options.identityProvider || initIdentityProvider(options), + retry: options.retry ?? exports.DEFAULT_RETRY, + timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, + }); +} +// Instantiate an identity provider based on the supplied options. If an +// explicit identity token is provided, use that. Otherwise, use the CI +// context provider. +function initIdentityProvider(options) { + const token = options.identityToken; + if (token) { + /* istanbul ignore next */ + return { getToken: () => Promise.resolve(token) }; + } + else { + return new sign_1.CIContextProvider('sigstore'); + } +} +// Instantiate a collection of witnesses based on the supplied options. +function initWitnesses(options) { + const witnesses = []; + if (isRekorEnabled(options)) { + witnesses.push(new sign_1.RekorWitness({ + rekorBaseURL: options.rekorURL, + entryType: options.legacyCompatibility ? 'intoto' : 'dsse', + fetchOnConflict: false, + retry: options.retry ?? exports.DEFAULT_RETRY, + timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, + })); + } + if (isTSAEnabled(options)) { + witnesses.push(new sign_1.TSAWitness({ + tsaBaseURL: options.tsaServerURL, + retry: options.retry ?? exports.DEFAULT_RETRY, + timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, + })); + } + return witnesses; +} +// Type assertion to ensure that Rekor is enabled +function isRekorEnabled(options) { + return options.tlogUpload !== false; +} +// Type assertion to ensure that TSA is enabled +function isTSAEnabled(options) { + return options.tsaServerURL !== undefined; +} diff --git a/node_modules/sigstore/dist/index.js b/node_modules/sigstore/dist/index.js new file mode 100644 index 0000000000000..7f6a5cf86bbfc --- /dev/null +++ b/node_modules/sigstore/dist/index.js @@ -0,0 +1,34 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verify = exports.sign = exports.createVerifier = exports.attest = exports.VerificationError = exports.PolicyError = exports.TUFError = exports.InternalError = exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = exports.ValidationError = void 0; +/* +Copyright 2022 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +var bundle_1 = require("@sigstore/bundle"); +Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return bundle_1.ValidationError; } }); +var sign_1 = require("@sigstore/sign"); +Object.defineProperty(exports, "DEFAULT_FULCIO_URL", { enumerable: true, get: function () { return sign_1.DEFAULT_FULCIO_URL; } }); +Object.defineProperty(exports, "DEFAULT_REKOR_URL", { enumerable: true, get: function () { return sign_1.DEFAULT_REKOR_URL; } }); +Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return sign_1.InternalError; } }); +var tuf_1 = require("@sigstore/tuf"); +Object.defineProperty(exports, "TUFError", { enumerable: true, get: function () { return tuf_1.TUFError; } }); +var verify_1 = require("@sigstore/verify"); +Object.defineProperty(exports, "PolicyError", { enumerable: true, get: function () { return verify_1.PolicyError; } }); +Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return verify_1.VerificationError; } }); +var sigstore_1 = require("./sigstore"); +Object.defineProperty(exports, "attest", { enumerable: true, get: function () { return sigstore_1.attest; } }); +Object.defineProperty(exports, "createVerifier", { enumerable: true, get: function () { return sigstore_1.createVerifier; } }); +Object.defineProperty(exports, "sign", { enumerable: true, get: function () { return sigstore_1.sign; } }); +Object.defineProperty(exports, "verify", { enumerable: true, get: function () { return sigstore_1.verify; } }); diff --git a/node_modules/sigstore/dist/sigstore.js b/node_modules/sigstore/dist/sigstore.js new file mode 100644 index 0000000000000..f7d79ed880588 --- /dev/null +++ b/node_modules/sigstore/dist/sigstore.js @@ -0,0 +1,112 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sign = sign; +exports.attest = attest; +exports.verify = verify; +exports.createVerifier = createVerifier; +/* +Copyright 2023 The Sigstore Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +const bundle_1 = require("@sigstore/bundle"); +const tuf = __importStar(require("@sigstore/tuf")); +const verify_1 = require("@sigstore/verify"); +const config = __importStar(require("./config")); +async function sign(payload, +/* istanbul ignore next */ +options = {}) { + const bundler = config.createBundleBuilder('messageSignature', options); + const bundle = await bundler.create({ data: payload }); + return (0, bundle_1.bundleToJSON)(bundle); +} +async function attest(payload, payloadType, +/* istanbul ignore next */ +options = {}) { + const bundler = config.createBundleBuilder('dsseEnvelope', options); + const bundle = await bundler.create({ data: payload, type: payloadType }); + return (0, bundle_1.bundleToJSON)(bundle); +} +async function verify(bundle, dataOrOptions, options) { + let data; + if (Buffer.isBuffer(dataOrOptions)) { + data = dataOrOptions; + } + else { + options = dataOrOptions; + } + const verifier = await createVerifier(options); + return verifier.verify(bundle, data); +} +async function createVerifier( +/* istanbul ignore next */ +options = {}) { + const trustedRoot = await tuf.getTrustedRoot({ + mirrorURL: options.tufMirrorURL, + rootPath: options.tufRootPath, + cachePath: options.tufCachePath, + forceCache: options.tufForceCache, + retry: options.retry ?? config.DEFAULT_RETRY, + timeout: options.timeout ?? config.DEFAULT_TIMEOUT, + }); + const keyFinder = options.keySelector + ? config.createKeyFinder(options.keySelector) + : undefined; + const trustMaterial = (0, verify_1.toTrustMaterial)(trustedRoot, keyFinder); + const verifierOptions = { + ctlogThreshold: options.ctLogThreshold, + tlogThreshold: options.tlogThreshold, + }; + const verifier = new verify_1.Verifier(trustMaterial, verifierOptions); + const policy = config.createVerificationPolicy(options); + return { + verify: (bundle, payload) => { + const deserializedBundle = (0, bundle_1.bundleFromJSON)(bundle); + const signedEntity = (0, verify_1.toSignedEntity)(deserializedBundle, payload); + return verifier.verify(signedEntity, policy); + }, + }; +} diff --git a/node_modules/sigstore/package.json b/node_modules/sigstore/package.json new file mode 100644 index 0000000000000..5965f0889ca7d --- /dev/null +++ b/node_modules/sigstore/package.json @@ -0,0 +1,47 @@ +{ + "name": "sigstore", + "version": "4.1.0", + "description": "code-signing for npm packages", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "shx rm -rf dist *.tsbuildinfo", + "build": "tsc --build", + "test": "jest" + }, + "files": [ + "dist", + "store" + ], + "author": "bdehamer@github.com", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/sigstore/sigstore-js.git" + }, + "bugs": { + "url": "https://github.com/sigstore/sigstore-js/issues" + }, + "homepage": "https://github.com/sigstore/sigstore-js/tree/main/packages/client#readme", + "publishConfig": { + "provenance": true + }, + "devDependencies": { + "@sigstore/rekor-types": "^4.0.0", + "@sigstore/jest": "^0.0.0", + "@sigstore/mock": "^0.11.0", + "@tufjs/repo-mock": "^4.0.0", + "@types/make-fetch-happen": "^10.0.4" + }, + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/smart-buffer/build/smartbuffer.js.map b/node_modules/smart-buffer/build/smartbuffer.js.map deleted file mode 100644 index 37f0d6e16fc68..0000000000000 --- a/node_modules/smart-buffer/build/smartbuffer.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"smartbuffer.js","sourceRoot":"","sources":["../src/smartbuffer.ts"],"names":[],"mappings":";;AAAA,mCAGiB;AAcjB,kDAAkD;AAClD,MAAM,wBAAwB,GAAW,IAAI,CAAC;AAE9C,kEAAkE;AAClE,MAAM,4BAA4B,GAAmB,MAAM,CAAC;AAE5D,MAAM,WAAW;IAQf;;;;OAIG;IACH,YAAY,OAA4B;QAZjC,WAAM,GAAW,CAAC,CAAC;QAElB,cAAS,GAAmB,4BAA4B,CAAC;QAEzD,iBAAY,GAAW,CAAC,CAAC;QACzB,gBAAW,GAAW,CAAC,CAAC;QAQ9B,IAAI,WAAW,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE;YAC7C,sBAAsB;YACtB,IAAI,OAAO,CAAC,QAAQ,EAAE;gBACpB,qBAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;aACnC;YAED,iCAAiC;YACjC,IAAI,OAAO,CAAC,IAAI,EAAE;gBAChB,IAAI,uBAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE;oBACrD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iBAC/C;qBAAM;oBACL,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,wBAAwB,CAAC,CAAC;iBAClD;gBACD,2BAA2B;aAC5B;iBAAM,IAAI,OAAO,CAAC,IAAI,EAAE;gBACvB,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;oBACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;oBAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;iBACnC;qBAAM;oBACL,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;iBACpD;aACF;iBAAM;gBACL,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;aAC3D;SACF;aAAM;YACL,mEAAmE;YACnE,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;aACpD;YAED,oCAAoC;YACpC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;SAC3D;IACH,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,QAAyB;QAC5D,OAAO,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,UAAU,CAAC,IAAY,EAAE,QAAyB;QAC9D,OAAO,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,WAAW,CAAC,OAA2B;QACnD,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAA2B;QACrD,MAAM,WAAW,GAAuB,OAAO,CAAC;QAEhD,OAAO,CACL,WAAW;YACX,CAAC,WAAW,CAAC,QAAQ,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,CAAC,CACzG,CAAC;IACJ,CAAC;IAED,kBAAkB;IAElB;;;;;OAKG;IACH,QAAQ,CAAC,MAAe;QACtB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,MAAe;QAC5B,iCAAyB,CAAC,gBAAgB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,MAAe;QAC5B,iCAAyB,CAAC,gBAAgB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,KAAa,EAAE,MAAe;QACtC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,KAAa,EAAE,MAAe;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAc;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,KAAa,EAAE,MAAe;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAc;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED,oBAAoB;IAEpB;;;;;OAKG;IACH,SAAS,CAAC,MAAe;QACvB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAe;QAC7B,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAe;QAC7B,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,MAAe;QACvC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,KAAa,EAAE,MAAc;QACvC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAe;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,KAAa,EAAE,MAAc;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAe;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,KAAa,EAAE,MAAc;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtF,CAAC;IAED,iBAAiB;IAEjB;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED,wBAAwB;IAExB;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED,UAAU;IAEV;;;;;;;;OAQG;IACH,UAAU,CAAC,IAA8B,EAAE,QAAyB;QAClE,IAAI,SAAS,CAAC;QAEd,kBAAkB;QAClB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,wBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;SAC5D;aAAM;YACL,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;SAC5C;QAED,iBAAiB;QACjB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;SACzB;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAEpH,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,KAAa,EAAE,MAAc,EAAE,QAAyB;QACnE,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,KAAa,EAAE,IAA8B,EAAE,QAAyB;QAClF,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,QAAyB;QACpC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;SACzB;QAED,+DAA+D;QAC/D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,6EAA6E;QAC7E,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACnD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBAC1B,OAAO,GAAG,CAAC,CAAC;gBACZ,MAAM;aACP;SACF;QAED,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC;QAE/B,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc,EAAE,QAAyB;QACrE,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,eAAe;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,KAAa,EAAE,IAA8B,EAAE,QAAyB;QACpF,eAAe;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU;IAEV;;;;;;OAMG;IACH,UAAU,CAAC,MAAe;QACxB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,wBAAgB,CAAC,MAAM,CAAC,CAAC;SAC1B;QAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAErE,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE3D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAc;QACxC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,KAAa,EAAE,MAAe;QACxC,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,+DAA+D;QAC/D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,6EAA6E;QAC7E,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACnD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBAC1B,OAAO,GAAG,CAAC,CAAC;gBACZ,MAAM;aACP;SACF;QAED,aAAa;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,eAAe;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,mCAAmC;QACnC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,wBAAgB,CAAC,MAAM,CAAC,CAAC;SAC1B;QAED,eAAe;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE9F,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU,CAAC,MAAc;QAC3B,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,oBAAoB;QACpB,yBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW,CAAC,MAAc;QAC5B,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,oBAAoB;QACpB,yBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ,CAAC,QAAwB;QACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;QAExB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAAyB;QAChC,MAAM,WAAW,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAE7E,8BAA8B;QAC9B,qBAAa,CAAC,WAAW,CAAC,CAAC;QAE3B,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACK,aAAa,CACnB,KAAa,EACb,QAAiB,EACjB,IAA8B,EAC9B,QAAyB;QAEzB,IAAI,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC;QAClC,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,mBAAmB;QACnB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,SAAS,GAAG,IAAI,CAAC;YACjB,qBAAqB;SACtB;aAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YACnC,qBAAa,CAAC,IAAI,CAAC,CAAC;YACpB,WAAW,GAAG,IAAI,CAAC;SACpB;QAED,mCAAmC;QACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;YAChC,qBAAa,CAAC,QAAQ,CAAC,CAAC;YACxB,WAAW,GAAG,QAAQ,CAAC;SACxB;QAED,kCAAkC;QAClC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAEzD,mDAAmD;QACnD,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;SAC9C;aAAM;YACL,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;SAC9C;QAED,cAAc;QACd,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAE5D,0CAA0C;QAC1C,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC;SACjC;aAAM;YACL,mFAAmF;YACnF,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;gBAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;aACzE;iBAAM;gBACL,2FAA2F;gBAC3F,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC;aACjC;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAC,KAAa,EAAE,QAAiB,EAAE,MAAe;QACrE,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,mDAAmD;QACnD,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;SAChD;aAAM;YACL,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;SAChD;QAED,qBAAqB;QACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAElC,0CAA0C;QAC1C,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;SACnC;aAAM;YACL,mFAAmF;YACnF,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;gBAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aAC3E;iBAAM;gBACL,2FAA2F;gBAC3F,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;aACnC;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,cAAc,CAAC,MAAc,EAAE,MAAe;QACpD,gDAAgD;QAChD,IAAI,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;QAEjC,qCAAqC;QACrC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,mCAAmC;YACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;YAEzB,8BAA8B;YAC9B,SAAS,GAAG,MAAM,CAAC;SACpB;QAED,8GAA8G;QAC9G,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACrD,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;SACpD;IACH,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,UAAkB,EAAE,MAAc;QACzD,mCAAmC;QACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,mDAAmD;QACnD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;QAE/C,kIAAkI;QAClI,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SAC7E;QAED,qCAAqC;QACrC,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE;YACrC,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;SACnC;aAAM;YACL,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;SAC3B;IACH,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,UAAkB,EAAE,MAAe;QAC1D,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,wCAAwC;QACxC,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;QAE7C,8FAA8F;QAC9F,IAAI,SAAS,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE;YACxC,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;SACtC;IACH,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,SAAiB;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAEpC,IAAI,SAAS,GAAG,SAAS,EAAE;YACzB,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;YACtB,IAAI,SAAS,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,SAAS,GAAG,SAAS,EAAE;gBACzB,SAAS,GAAG,SAAS,CAAC;aACvB;YACD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAE3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;SACxC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACK,gBAAgB,CAAI,IAA2B,EAAE,QAAgB,EAAE,MAAe;QACxF,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEtC,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE5F,2EAA2E;QAC3E,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC;SAC9B;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;;OAWG;IACK,kBAAkB,CACxB,IAA2C,EAC3C,QAAgB,EAChB,KAAQ,EACR,MAAc;QAEd,mCAAmC;QACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,0EAA0E;QAC1E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAExC,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAErC,2CAA2C;QAC3C,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;OAWG;IACK,iBAAiB,CACvB,IAA2C,EAC3C,QAAgB,EAChB,KAAQ,EACR,MAAe;QAEf,0CAA0C;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,gEAAgE;YAChE,IAAI,MAAM,GAAG,CAAC,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,2BAA2B,CAAC,CAAC;aACrD;YAED,wBAAgB,CAAC,MAAM,CAAC,CAAC;SAC1B;QAED,uDAAuD;QACvD,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,0EAA0E;QAC1E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAExC,mFAAmF;QACnF,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;SACvE;aAAM;YACL,mGAAmG;YACnG,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;SAC/B;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAE4B,kCAAW"} \ No newline at end of file diff --git a/node_modules/smart-buffer/build/utils.js.map b/node_modules/smart-buffer/build/utils.js.map deleted file mode 100644 index fc7388d3b7010..0000000000000 --- a/node_modules/smart-buffer/build/utils.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AACA,mCAAgC;AAEhC;;GAEG;AACH,MAAM,MAAM,GAAG;IACb,gBAAgB,EAAE,kGAAkG;IACpH,wBAAwB,EAAE,wEAAwE;IAClG,0BAA0B,EAAE,gDAAgD;IAC5E,0BAA0B,EAAE,2FAA2F;IACvH,cAAc,EAAE,uCAAuC;IACvD,yBAAyB,EAAE,oEAAoE;IAC/F,cAAc,EAAE,uCAAuC;IACvD,yBAAyB,EAAE,oEAAoE;IAC/F,qBAAqB,EAAE,sEAAsE;IAC7F,qBAAqB,EAAE,yFAAyF;IAChH,0BAA0B,EAAE,0DAA0D;IACtF,2BAA2B,EAAE,2DAA2D;CACzF,CAAC;AAuGA,wBAAM;AArGR;;;;GAIG;AACH,SAAS,aAAa,CAAC,QAAwB;IAC7C,IAAI,CAAC,eAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;KAC1C;AACH,CAAC;AA4F0B,sCAAa;AA1FxC;;;;GAIG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAmFS,0CAAe;AAjFzB;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,KAAU,EAAE,MAAe;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,oCAAoC;QACpC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SACzE;KACF;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;KAC/F;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,MAAW;IACnC,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AA0DC,4CAAgB;AAxDlB;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,MAAW;IACnC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAgDyC,4CAAgB;AA9C1D;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,IAAiB;IAC1D,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;KAC/C;AACH,CAAC;AAqCmB,8CAAiB;AAnCrC;;;GAGG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AACrF,CAAC;AAcD;;GAEG;AACH,SAAS,yBAAyB,CAAC,YAA0B;IAC3D,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IAED,IAAI,OAAO,eAAM,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,WAAW,EAAE;QACzD,MAAM,IAAI,KAAK,CAAC,8CAA8C,YAAY,GAAG,CAAC,CAAC;KAChF;AACH,CAAC;AAIsC,8DAAyB"} \ No newline at end of file diff --git a/node_modules/smart-buffer/typings/smartbuffer.d.ts b/node_modules/smart-buffer/typings/smartbuffer.d.ts deleted file mode 100644 index d07379b2983a4..0000000000000 --- a/node_modules/smart-buffer/typings/smartbuffer.d.ts +++ /dev/null @@ -1,755 +0,0 @@ -/// <reference types="node" /> -/** - * Object interface for constructing new SmartBuffer instances. - */ -interface SmartBufferOptions { - encoding?: BufferEncoding; - size?: number; - buff?: Buffer; -} -declare class SmartBuffer { - length: number; - private _encoding; - private _buff; - private _writeOffset; - private _readOffset; - /** - * Creates a new SmartBuffer instance. - * - * @param options { SmartBufferOptions } The SmartBufferOptions to apply to this instance. - */ - constructor(options?: SmartBufferOptions); - /** - * Creates a new SmartBuffer instance with the provided internal Buffer size and optional encoding. - * - * @param size { Number } The size of the internal Buffer. - * @param encoding { String } The BufferEncoding to use for strings. - * - * @return { SmartBuffer } - */ - static fromSize(size: number, encoding?: BufferEncoding): SmartBuffer; - /** - * Creates a new SmartBuffer instance with the provided Buffer and optional encoding. - * - * @param buffer { Buffer } The Buffer to use as the internal Buffer value. - * @param encoding { String } The BufferEncoding to use for strings. - * - * @return { SmartBuffer } - */ - static fromBuffer(buff: Buffer, encoding?: BufferEncoding): SmartBuffer; - /** - * Creates a new SmartBuffer instance with the provided SmartBufferOptions options. - * - * @param options { SmartBufferOptions } The options to use when creating the SmartBuffer instance. - */ - static fromOptions(options: SmartBufferOptions): SmartBuffer; - /** - * Type checking function that determines if an object is a SmartBufferOptions object. - */ - static isSmartBufferOptions(options: SmartBufferOptions): options is SmartBufferOptions; - /** - * Reads an Int8 value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readInt8(offset?: number): number; - /** - * Reads an Int16BE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readInt16BE(offset?: number): number; - /** - * Reads an Int16LE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readInt16LE(offset?: number): number; - /** - * Reads an Int32BE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readInt32BE(offset?: number): number; - /** - * Reads an Int32LE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readInt32LE(offset?: number): number; - /** - * Reads a BigInt64BE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { BigInt } - */ - readBigInt64BE(offset?: number): bigint; - /** - * Reads a BigInt64LE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { BigInt } - */ - readBigInt64LE(offset?: number): bigint; - /** - * Writes an Int8 value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeInt8(value: number, offset?: number): SmartBuffer; - /** - * Inserts an Int8 value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertInt8(value: number, offset: number): SmartBuffer; - /** - * Writes an Int16BE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeInt16BE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an Int16BE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertInt16BE(value: number, offset: number): SmartBuffer; - /** - * Writes an Int16LE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeInt16LE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an Int16LE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertInt16LE(value: number, offset: number): SmartBuffer; - /** - * Writes an Int32BE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeInt32BE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an Int32BE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertInt32BE(value: number, offset: number): SmartBuffer; - /** - * Writes an Int32LE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeInt32LE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an Int32LE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertInt32LE(value: number, offset: number): SmartBuffer; - /** - * Writes a BigInt64BE value to the current write position (or at optional offset). - * - * @param value { BigInt } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeBigInt64BE(value: bigint, offset?: number): SmartBuffer; - /** - * Inserts a BigInt64BE value at the given offset value. - * - * @param value { BigInt } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertBigInt64BE(value: bigint, offset: number): SmartBuffer; - /** - * Writes a BigInt64LE value to the current write position (or at optional offset). - * - * @param value { BigInt } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeBigInt64LE(value: bigint, offset?: number): SmartBuffer; - /** - * Inserts a Int64LE value at the given offset value. - * - * @param value { BigInt } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertBigInt64LE(value: bigint, offset: number): SmartBuffer; - /** - * Reads an UInt8 value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readUInt8(offset?: number): number; - /** - * Reads an UInt16BE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readUInt16BE(offset?: number): number; - /** - * Reads an UInt16LE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readUInt16LE(offset?: number): number; - /** - * Reads an UInt32BE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readUInt32BE(offset?: number): number; - /** - * Reads an UInt32LE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readUInt32LE(offset?: number): number; - /** - * Reads a BigUInt64BE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { BigInt } - */ - readBigUInt64BE(offset?: number): bigint; - /** - * Reads a BigUInt64LE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { BigInt } - */ - readBigUInt64LE(offset?: number): bigint; - /** - * Writes an UInt8 value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeUInt8(value: number, offset?: number): SmartBuffer; - /** - * Inserts an UInt8 value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertUInt8(value: number, offset: number): SmartBuffer; - /** - * Writes an UInt16BE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeUInt16BE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an UInt16BE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertUInt16BE(value: number, offset: number): SmartBuffer; - /** - * Writes an UInt16LE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeUInt16LE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an UInt16LE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertUInt16LE(value: number, offset: number): SmartBuffer; - /** - * Writes an UInt32BE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeUInt32BE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an UInt32BE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertUInt32BE(value: number, offset: number): SmartBuffer; - /** - * Writes an UInt32LE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeUInt32LE(value: number, offset?: number): SmartBuffer; - /** - * Inserts an UInt32LE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertUInt32LE(value: number, offset: number): SmartBuffer; - /** - * Writes a BigUInt64BE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeBigUInt64BE(value: bigint, offset?: number): SmartBuffer; - /** - * Inserts a BigUInt64BE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertBigUInt64BE(value: bigint, offset: number): SmartBuffer; - /** - * Writes a BigUInt64LE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeBigUInt64LE(value: bigint, offset?: number): SmartBuffer; - /** - * Inserts a BigUInt64LE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertBigUInt64LE(value: bigint, offset: number): SmartBuffer; - /** - * Reads an FloatBE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readFloatBE(offset?: number): number; - /** - * Reads an FloatLE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readFloatLE(offset?: number): number; - /** - * Writes a FloatBE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeFloatBE(value: number, offset?: number): SmartBuffer; - /** - * Inserts a FloatBE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertFloatBE(value: number, offset: number): SmartBuffer; - /** - * Writes a FloatLE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeFloatLE(value: number, offset?: number): SmartBuffer; - /** - * Inserts a FloatLE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertFloatLE(value: number, offset: number): SmartBuffer; - /** - * Reads an DoublEBE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readDoubleBE(offset?: number): number; - /** - * Reads an DoubleLE value from the current read position or an optionally provided offset. - * - * @param offset { Number } The offset to read data from (optional) - * @return { Number } - */ - readDoubleLE(offset?: number): number; - /** - * Writes a DoubleBE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeDoubleBE(value: number, offset?: number): SmartBuffer; - /** - * Inserts a DoubleBE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertDoubleBE(value: number, offset: number): SmartBuffer; - /** - * Writes a DoubleLE value to the current write position (or at optional offset). - * - * @param value { Number } The value to write. - * @param offset { Number } The offset to write the value at. - * - * @return this - */ - writeDoubleLE(value: number, offset?: number): SmartBuffer; - /** - * Inserts a DoubleLE value at the given offset value. - * - * @param value { Number } The value to insert. - * @param offset { Number } The offset to insert the value at. - * - * @return this - */ - insertDoubleLE(value: number, offset: number): SmartBuffer; - /** - * Reads a String from the current read position. - * - * @param arg1 { Number | String } The number of bytes to read as a String, or the BufferEncoding to use for - * the string (Defaults to instance level encoding). - * @param encoding { String } The BufferEncoding to use for the string (Defaults to instance level encoding). - * - * @return { String } - */ - readString(arg1?: number | BufferEncoding, encoding?: BufferEncoding): string; - /** - * Inserts a String - * - * @param value { String } The String value to insert. - * @param offset { Number } The offset to insert the string at. - * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). - * - * @return this - */ - insertString(value: string, offset: number, encoding?: BufferEncoding): SmartBuffer; - /** - * Writes a String - * - * @param value { String } The String value to write. - * @param arg2 { Number | String } The offset to write the string at, or the BufferEncoding to use. - * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). - * - * @return this - */ - writeString(value: string, arg2?: number | BufferEncoding, encoding?: BufferEncoding): SmartBuffer; - /** - * Reads a null-terminated String from the current read position. - * - * @param encoding { String } The BufferEncoding to use for the string (Defaults to instance level encoding). - * - * @return { String } - */ - readStringNT(encoding?: BufferEncoding): string; - /** - * Inserts a null-terminated String. - * - * @param value { String } The String value to write. - * @param arg2 { Number | String } The offset to write the string to, or the BufferEncoding to use. - * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). - * - * @return this - */ - insertStringNT(value: string, offset: number, encoding?: BufferEncoding): SmartBuffer; - /** - * Writes a null-terminated String. - * - * @param value { String } The String value to write. - * @param arg2 { Number | String } The offset to write the string to, or the BufferEncoding to use. - * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). - * - * @return this - */ - writeStringNT(value: string, arg2?: number | BufferEncoding, encoding?: BufferEncoding): SmartBuffer; - /** - * Reads a Buffer from the internal read position. - * - * @param length { Number } The length of data to read as a Buffer. - * - * @return { Buffer } - */ - readBuffer(length?: number): Buffer; - /** - * Writes a Buffer to the current write position. - * - * @param value { Buffer } The Buffer to write. - * @param offset { Number } The offset to write the Buffer to. - * - * @return this - */ - insertBuffer(value: Buffer, offset: number): SmartBuffer; - /** - * Writes a Buffer to the current write position. - * - * @param value { Buffer } The Buffer to write. - * @param offset { Number } The offset to write the Buffer to. - * - * @return this - */ - writeBuffer(value: Buffer, offset?: number): SmartBuffer; - /** - * Reads a null-terminated Buffer from the current read poisiton. - * - * @return { Buffer } - */ - readBufferNT(): Buffer; - /** - * Inserts a null-terminated Buffer. - * - * @param value { Buffer } The Buffer to write. - * @param offset { Number } The offset to write the Buffer to. - * - * @return this - */ - insertBufferNT(value: Buffer, offset: number): SmartBuffer; - /** - * Writes a null-terminated Buffer. - * - * @param value { Buffer } The Buffer to write. - * @param offset { Number } The offset to write the Buffer to. - * - * @return this - */ - writeBufferNT(value: Buffer, offset?: number): SmartBuffer; - /** - * Clears the SmartBuffer instance to its original empty state. - */ - clear(): SmartBuffer; - /** - * Gets the remaining data left to be read from the SmartBuffer instance. - * - * @return { Number } - */ - remaining(): number; - /** - * Gets the current read offset value of the SmartBuffer instance. - * - * @return { Number } - */ - /** - * Sets the read offset value of the SmartBuffer instance. - * - * @param offset { Number } - The offset value to set. - */ - readOffset: number; - /** - * Gets the current write offset value of the SmartBuffer instance. - * - * @return { Number } - */ - /** - * Sets the write offset value of the SmartBuffer instance. - * - * @param offset { Number } - The offset value to set. - */ - writeOffset: number; - /** - * Gets the currently set string encoding of the SmartBuffer instance. - * - * @return { BufferEncoding } The string Buffer encoding currently set. - */ - /** - * Sets the string encoding of the SmartBuffer instance. - * - * @param encoding { BufferEncoding } The string Buffer encoding to set. - */ - encoding: BufferEncoding; - /** - * Gets the underlying internal Buffer. (This includes unmanaged data in the Buffer) - * - * @return { Buffer } The Buffer value. - */ - readonly internalBuffer: Buffer; - /** - * Gets the value of the internal managed Buffer (Includes managed data only) - * - * @param { Buffer } - */ - toBuffer(): Buffer; - /** - * Gets the String value of the internal managed Buffer - * - * @param encoding { String } The BufferEncoding to display the Buffer as (defaults to instance level encoding). - */ - toString(encoding?: BufferEncoding): string; - /** - * Destroys the SmartBuffer instance. - */ - destroy(): SmartBuffer; - /** - * Handles inserting and writing strings. - * - * @param value { String } The String value to insert. - * @param isInsert { Boolean } True if inserting a string, false if writing. - * @param arg2 { Number | String } The offset to insert the string at, or the BufferEncoding to use. - * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). - */ - private _handleString; - /** - * Handles writing or insert of a Buffer. - * - * @param value { Buffer } The Buffer to write. - * @param offset { Number } The offset to write the Buffer to. - */ - private _handleBuffer; - /** - * Ensures that the internal Buffer is large enough to read data. - * - * @param length { Number } The length of the data that needs to be read. - * @param offset { Number } The offset of the data that needs to be read. - */ - private ensureReadable; - /** - * Ensures that the internal Buffer is large enough to insert data. - * - * @param dataLength { Number } The length of the data that needs to be written. - * @param offset { Number } The offset of the data to be written. - */ - private ensureInsertable; - /** - * Ensures that the internal Buffer is large enough to write data. - * - * @param dataLength { Number } The length of the data that needs to be written. - * @param offset { Number } The offset of the data to be written (defaults to writeOffset). - */ - private _ensureWriteable; - /** - * Ensures that the internal Buffer is large enough to write at least the given amount of data. - * - * @param minLength { Number } The minimum length of the data needs to be written. - */ - private _ensureCapacity; - /** - * Reads a numeric number value using the provided function. - * - * @typeparam T { number | bigint } The type of the value to be read - * - * @param func { Function(offset: number) => number } The function to read data on the internal Buffer with. - * @param byteSize { Number } The number of bytes read. - * @param offset { Number } The offset to read from (optional). When this is not provided, the managed readOffset is used instead. - * - * @returns { T } the number value - */ - private _readNumberValue; - /** - * Inserts a numeric number value based on the given offset and value. - * - * @typeparam T { number | bigint } The type of the value to be written - * - * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. - * @param byteSize { Number } The number of bytes written. - * @param value { T } The number value to write. - * @param offset { Number } the offset to write the number at (REQUIRED). - * - * @returns SmartBuffer this buffer - */ - private _insertNumberValue; - /** - * Writes a numeric number value based on the given offset and value. - * - * @typeparam T { number | bigint } The type of the value to be written - * - * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. - * @param byteSize { Number } The number of bytes written. - * @param value { T } The number value to write. - * @param offset { Number } the offset to write the number at (REQUIRED). - * - * @returns SmartBuffer this buffer - */ - private _writeNumberValue; -} -export { SmartBufferOptions, SmartBuffer }; diff --git a/node_modules/smart-buffer/typings/utils.d.ts b/node_modules/smart-buffer/typings/utils.d.ts deleted file mode 100644 index b32b4d44c04c1..0000000000000 --- a/node_modules/smart-buffer/typings/utils.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -/// <reference types="node" /> -import { SmartBuffer } from './smartbuffer'; -import { Buffer } from 'buffer'; -/** - * Error strings - */ -declare const ERRORS: { - INVALID_ENCODING: string; - INVALID_SMARTBUFFER_SIZE: string; - INVALID_SMARTBUFFER_BUFFER: string; - INVALID_SMARTBUFFER_OBJECT: string; - INVALID_OFFSET: string; - INVALID_OFFSET_NON_NUMBER: string; - INVALID_LENGTH: string; - INVALID_LENGTH_NON_NUMBER: string; - INVALID_TARGET_OFFSET: string; - INVALID_TARGET_LENGTH: string; - INVALID_READ_BEYOND_BOUNDS: string; - INVALID_WRITE_BEYOND_BOUNDS: string; -}; -/** - * Checks if a given encoding is a valid Buffer encoding. (Throws an exception if check fails) - * - * @param { String } encoding The encoding string to check. - */ -declare function checkEncoding(encoding: BufferEncoding): void; -/** - * Checks if a given number is a finite integer. (Throws an exception if check fails) - * - * @param { Number } value The number value to check. - */ -declare function isFiniteInteger(value: number): boolean; -/** - * Checks if a length value is valid. (Throws an exception if check fails) - * - * @param { Number } length The value to check. - */ -declare function checkLengthValue(length: any): void; -/** - * Checks if a offset value is valid. (Throws an exception if check fails) - * - * @param { Number } offset The value to check. - */ -declare function checkOffsetValue(offset: any): void; -/** - * Checks if a target offset value is out of bounds. (Throws an exception if check fails) - * - * @param { Number } offset The offset value to check. - * @param { SmartBuffer } buff The SmartBuffer instance to check against. - */ -declare function checkTargetOffset(offset: number, buff: SmartBuffer): void; -interface Buffer { - readBigInt64BE(offset?: number): bigint; - readBigInt64LE(offset?: number): bigint; - readBigUInt64BE(offset?: number): bigint; - readBigUInt64LE(offset?: number): bigint; - writeBigInt64BE(value: bigint, offset?: number): number; - writeBigInt64LE(value: bigint, offset?: number): number; - writeBigUInt64BE(value: bigint, offset?: number): number; - writeBigUInt64LE(value: bigint, offset?: number): number; -} -/** - * Throws if Node.js version is too low to support bigint - */ -declare function bigIntAndBufferInt64Check(bufferMethod: keyof Buffer): void; -export { ERRORS, isFiniteInteger, checkEncoding, checkOffsetValue, checkLengthValue, checkTargetOffset, bigIntAndBufferInt64Check }; diff --git a/node_modules/socks-proxy-agent/LICENSE b/node_modules/socks-proxy-agent/LICENSE new file mode 100644 index 0000000000000..008728cb51847 --- /dev/null +++ b/node_modules/socks-proxy-agent/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> + +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. \ No newline at end of file diff --git a/node_modules/socks-proxy-agent/dist/index.d.ts b/node_modules/socks-proxy-agent/dist/index.d.ts deleted file mode 100644 index 4de33b1252a18..0000000000000 --- a/node_modules/socks-proxy-agent/dist/index.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -/// <reference types="node" /> -import { SocksProxy } from 'socks'; -import { Agent, ClientRequest, RequestOptions } from 'agent-base'; -import { AgentOptions } from 'agent-base'; -import { Url } from 'url'; -import net from 'net'; -import tls from 'tls'; -interface BaseSocksProxyAgentOptions { - host?: string | null; - port?: string | number | null; - username?: string | null; - tls?: tls.ConnectionOptions | null; -} -interface SocksProxyAgentOptionsExtra { - timeout?: number; -} -export interface SocksProxyAgentOptions extends AgentOptions, BaseSocksProxyAgentOptions, Partial<Omit<Url & SocksProxy, keyof BaseSocksProxyAgentOptions>> { -} -export declare class SocksProxyAgent extends Agent { - private readonly shouldLookup; - private readonly proxy; - private readonly tlsConnectionOptions; - timeout: number | null; - constructor(input: string | SocksProxyAgentOptions, options?: SocksProxyAgentOptionsExtra); - /** - * Initiates a SOCKS connection to the specified SOCKS proxy server, - * which in turn connects to the specified remote host and port. - * - * @api protected - */ - callback(req: ClientRequest, opts: RequestOptions): Promise<net.Socket>; -} -export {}; diff --git a/node_modules/socks-proxy-agent/dist/index.js b/node_modules/socks-proxy-agent/dist/index.js index 55b598b7f5ca7..15e06e8f43176 100644 --- a/node_modules/socks-proxy-agent/dist/index.js +++ b/node_modules/socks-proxy-agent/dist/index.js @@ -1,12 +1,26 @@ "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; @@ -16,173 +30,157 @@ exports.SocksProxyAgent = void 0; const socks_1 = require("socks"); const agent_base_1 = require("agent-base"); const debug_1 = __importDefault(require("debug")); -const dns_1 = __importDefault(require("dns")); -const tls_1 = __importDefault(require("tls")); +const dns = __importStar(require("dns")); +const net = __importStar(require("net")); +const tls = __importStar(require("tls")); +const url_1 = require("url"); const debug = (0, debug_1.default)('socks-proxy-agent'); -function parseSocksProxy(opts) { - var _a; - let port = 0; +const setServernameFromNonIpHost = (options) => { + if (options.servername === undefined && + options.host && + !net.isIP(options.host)) { + return { + ...options, + servername: options.host, + }; + } + return options; +}; +function parseSocksURL(url) { let lookup = false; let type = 5; - const host = opts.hostname; - if (host == null) { - throw new TypeError('No "host"'); - } - if (typeof opts.port === 'number') { - port = opts.port; - } - else if (typeof opts.port === 'string') { - port = parseInt(opts.port, 10); - } + const host = url.hostname; // From RFC 1928, Section 3: https://tools.ietf.org/html/rfc1928#section-3 // "The SOCKS service is conventionally located on TCP port 1080" - if (port == null) { - port = 1080; - } + const port = parseInt(url.port, 10) || 1080; // figure out if we want socks v4 or v5, based on the "protocol" used. // Defaults to 5. - if (opts.protocol != null) { - switch (opts.protocol.replace(':', '')) { - case 'socks4': - lookup = true; - // pass through - case 'socks4a': - type = 4; - break; - case 'socks5': - lookup = true; - // pass through - case 'socks': // no version specified, default to 5h - case 'socks5h': - type = 5; - break; - default: - throw new TypeError(`A "socks" protocol must be specified! Got: ${String(opts.protocol)}`); - } - } - if (typeof opts.type !== 'undefined') { - if (opts.type === 4 || opts.type === 5) { - type = opts.type; - } - else { - throw new TypeError(`"type" must be 4 or 5, got: ${String(opts.type)}`); - } + switch (url.protocol.replace(':', '')) { + case 'socks4': + lookup = true; + type = 4; + break; + // pass through + case 'socks4a': + type = 4; + break; + case 'socks5': + lookup = true; + type = 5; + break; + // pass through + case 'socks': // no version specified, default to 5h + type = 5; + break; + case 'socks5h': + type = 5; + break; + default: + throw new TypeError(`A "socks" protocol must be specified! Got: ${String(url.protocol)}`); } const proxy = { host, port, - type + type, }; - let userId = (_a = opts.userId) !== null && _a !== void 0 ? _a : opts.username; - let password = opts.password; - if (opts.auth != null) { - const auth = opts.auth.split(':'); - userId = auth[0]; - password = auth[1]; - } - if (userId != null) { + if (url.username) { Object.defineProperty(proxy, 'userId', { - value: userId, - enumerable: false + value: decodeURIComponent(url.username), + enumerable: false, }); } - if (password != null) { + if (url.password != null) { Object.defineProperty(proxy, 'password', { - value: password, - enumerable: false + value: decodeURIComponent(url.password), + enumerable: false, }); } return { lookup, proxy }; } -const normalizeProxyOptions = (input) => { - let proxyOptions; - if (typeof input === 'string') { - proxyOptions = new URL(input); - } - else { - proxyOptions = input; - } - if (proxyOptions == null) { - throw new TypeError('a SOCKS proxy server `host` and `port` must be specified!'); - } - return proxyOptions; -}; class SocksProxyAgent extends agent_base_1.Agent { - constructor(input, options) { - var _a; - const proxyOptions = normalizeProxyOptions(input); - super(proxyOptions); - const parsedProxy = parseSocksProxy(proxyOptions); - this.shouldLookup = parsedProxy.lookup; - this.proxy = parsedProxy.proxy; - this.tlsConnectionOptions = proxyOptions.tls != null ? proxyOptions.tls : {}; - this.timeout = (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : null; + constructor(uri, opts) { + super(opts); + const url = typeof uri === 'string' ? new url_1.URL(uri) : uri; + const { proxy, lookup } = parseSocksURL(url); + this.shouldLookup = lookup; + this.proxy = proxy; + this.timeout = opts?.timeout ?? null; + this.socketOptions = opts?.socketOptions ?? null; } /** * Initiates a SOCKS connection to the specified SOCKS proxy server, * which in turn connects to the specified remote host and port. - * - * @api protected */ - callback(req, opts) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const { shouldLookup, proxy, timeout } = this; - let { host, port, lookup: lookupCallback } = opts; - if (host == null) { - throw new Error('No `host` defined!'); - } - if (shouldLookup) { - // Client-side DNS resolution for "4" and "5" socks proxy versions. - host = yield new Promise((resolve, reject) => { - // Use the request's custom lookup, if one was configured: - const lookupFn = lookupCallback !== null && lookupCallback !== void 0 ? lookupCallback : dns_1.default.lookup; - lookupFn(host, {}, (err, res) => { - if (err) { - reject(err); - } - else { - resolve(res); - } - }); - }); - } - const socksOpts = { - proxy, - destination: { host, port }, - command: 'connect', - timeout: timeout !== null && timeout !== void 0 ? timeout : undefined - }; - const cleanup = (tlsSocket) => { - req.destroy(); - socket.destroy(); - if (tlsSocket) - tlsSocket.destroy(); - }; - debug('Creating socks proxy connection: %o', socksOpts); - const { socket } = yield socks_1.SocksClient.createConnection(socksOpts); - debug('Successfully created socks proxy connection'); - if (timeout !== null) { - socket.setTimeout(timeout); - socket.on('timeout', () => cleanup()); - } - if (opts.secureEndpoint) { - // The proxy is connecting to a TLS server, so upgrade - // this socket connection to a TLS connection. - debug('Upgrading socket connection to TLS'); - const servername = (_a = opts.servername) !== null && _a !== void 0 ? _a : opts.host; - const tlsSocket = tls_1.default.connect(Object.assign(Object.assign(Object.assign({}, omit(opts, 'host', 'hostname', 'path', 'port')), { socket, - servername }), this.tlsConnectionOptions)); - tlsSocket.once('error', (error) => { - debug('socket TLS error', error.message); - cleanup(tlsSocket); + async connect(req, opts) { + const { shouldLookup, proxy, timeout } = this; + if (!opts.host) { + throw new Error('No `host` defined!'); + } + let { host } = opts; + const { port, lookup: lookupFn = dns.lookup } = opts; + if (shouldLookup) { + // Client-side DNS resolution for "4" and "5" socks proxy versions. + host = await new Promise((resolve, reject) => { + // Use the request's custom lookup, if one was configured: + lookupFn(host, {}, (err, res) => { + if (err) { + reject(err); + } + else { + resolve(res); + } }); - return tlsSocket; - } - return socket; - }); + }); + } + const socksOpts = { + proxy, + destination: { + host, + port: typeof port === 'number' ? port : parseInt(port, 10), + }, + command: 'connect', + timeout: timeout ?? undefined, + // @ts-expect-error the type supplied by socks for socket_options is wider + // than necessary since socks will always override the host and port + socket_options: this.socketOptions ?? undefined, + }; + const cleanup = (tlsSocket) => { + req.destroy(); + socket.destroy(); + if (tlsSocket) + tlsSocket.destroy(); + }; + debug('Creating socks proxy connection: %o', socksOpts); + const { socket } = await socks_1.SocksClient.createConnection(socksOpts); + debug('Successfully created socks proxy connection'); + if (timeout !== null) { + socket.setTimeout(timeout); + socket.on('timeout', () => cleanup()); + } + if (opts.secureEndpoint) { + // The proxy is connecting to a TLS server, so upgrade + // this socket connection to a TLS connection. + debug('Upgrading socket connection to TLS'); + const tlsSocket = tls.connect({ + ...omit(setServernameFromNonIpHost(opts), 'host', 'path', 'port'), + socket, + }); + tlsSocket.once('error', (error) => { + debug('Socket TLS error', error.message); + cleanup(tlsSocket); + }); + return tlsSocket; + } + return socket; } } +SocksProxyAgent.protocols = [ + 'socks', + 'socks4', + 'socks4a', + 'socks5', + 'socks5h', +]; exports.SocksProxyAgent = SocksProxyAgent; function omit(obj, ...keys) { const ret = {}; diff --git a/node_modules/socks-proxy-agent/dist/index.js.map b/node_modules/socks-proxy-agent/dist/index.js.map deleted file mode 100644 index e183e8e7a13ce..0000000000000 --- a/node_modules/socks-proxy-agent/dist/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,iCAAmE;AACnE,2CAAiE;AAEjE,kDAA+B;AAE/B,8CAAqB;AAErB,8CAAqB;AAarB,MAAM,KAAK,GAAG,IAAA,eAAW,EAAC,mBAAmB,CAAC,CAAA;AAE9C,SAAS,eAAe,CAAE,IAA4B;;IACpD,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,IAAI,GAAuB,CAAC,CAAA;IAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAA;IAE1B,IAAI,IAAI,IAAI,IAAI,EAAE;QAChB,MAAM,IAAI,SAAS,CAAC,WAAW,CAAC,CAAA;KACjC;IAED,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;QACjC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;KACjB;SAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;QACxC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;KAC/B;IAED,0EAA0E;IAC1E,iEAAiE;IACjE,IAAI,IAAI,IAAI,IAAI,EAAE;QAChB,IAAI,GAAG,IAAI,CAAA;KACZ;IAED,sEAAsE;IACtE,iBAAiB;IACjB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE;QACzB,QAAQ,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YACtC,KAAK,QAAQ;gBACX,MAAM,GAAG,IAAI,CAAA;YACf,eAAe;YACf,KAAK,SAAS;gBACZ,IAAI,GAAG,CAAC,CAAA;gBACR,MAAK;YACP,KAAK,QAAQ;gBACX,MAAM,GAAG,IAAI,CAAA;YACf,eAAe;YACf,KAAK,OAAO,CAAC,CAAC,sCAAsC;YACpD,KAAK,SAAS;gBACZ,IAAI,GAAG,CAAC,CAAA;gBACR,MAAK;YACP;gBACE,MAAM,IAAI,SAAS,CAAC,8CAA8C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;SAC7F;KACF;IAED,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE;QACpC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;YACtC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;SACjB;aAAM;YACL,MAAM,IAAI,SAAS,CAAC,+BAA+B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;SACxE;KACF;IAED,MAAM,KAAK,GAAe;QACxB,IAAI;QACJ,IAAI;QACJ,IAAI;KACL,CAAA;IAED,IAAI,MAAM,GAAG,MAAA,IAAI,CAAC,MAAM,mCAAI,IAAI,CAAC,QAAQ,CAAA;IACzC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC5B,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACjC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QAChB,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;KACnB;IACD,IAAI,MAAM,IAAI,IAAI,EAAE;QAClB,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE;YACrC,KAAK,EAAE,MAAM;YACb,UAAU,EAAE,KAAK;SAClB,CAAC,CAAA;KACH;IACD,IAAI,QAAQ,IAAI,IAAI,EAAE;QACpB,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE;YACvC,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,KAAK;SAClB,CAAC,CAAA;KACH;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAC1B,CAAC;AAED,MAAM,qBAAqB,GAAG,CAAC,KAAsC,EAA0B,EAAE;IAC/F,IAAI,YAAoC,CAAA;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,YAAY,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;KAC9B;SAAM;QACL,YAAY,GAAG,KAAK,CAAA;KACrB;IACD,IAAI,YAAY,IAAI,IAAI,EAAE;QACxB,MAAM,IAAI,SAAS,CAAC,2DAA2D,CAAC,CAAA;KACjF;IAED,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAID,MAAa,eAAgB,SAAQ,kBAAK;IAMxC,YAAa,KAAsC,EAAE,OAAqC;;QACxF,MAAM,YAAY,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;QACjD,KAAK,CAAC,YAAY,CAAC,CAAA;QAEnB,MAAM,WAAW,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;QAEjD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,MAAM,CAAA;QACtC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,CAAA;QAC9B,IAAI,CAAC,oBAAoB,GAAG,YAAY,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5E,IAAI,CAAC,OAAO,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,mCAAI,IAAI,CAAA;IACzC,CAAC;IAED;;;;;OAKG;IACG,QAAQ,CAAE,GAAkB,EAAE,IAAoB;;;YACtD,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;YAE7C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;YAEjD,IAAI,IAAI,IAAI,IAAI,EAAE;gBAChB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;aACtC;YAED,IAAI,YAAY,EAAE;gBAChB,mEAAmE;gBACnE,IAAI,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBACnD,0DAA0D;oBAC1D,MAAM,QAAQ,GAAG,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,aAAG,CAAC,MAAM,CAAA;oBAC7C,QAAQ,CAAC,IAAK,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;wBAC/B,IAAI,GAAG,EAAE;4BACP,MAAM,CAAC,GAAG,CAAC,CAAA;yBACZ;6BAAM;4BACL,OAAO,CAAC,GAAG,CAAC,CAAA;yBACb;oBACH,CAAC,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;aACH;YAED,MAAM,SAAS,GAAuB;gBACpC,KAAK;gBACL,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;gBAC3B,OAAO,EAAE,SAAS;gBAClB,OAAO,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,SAAS;aAC9B,CAAA;YAED,MAAM,OAAO,GAAG,CAAC,SAAyB,EAAE,EAAE;gBAC5C,GAAG,CAAC,OAAO,EAAE,CAAA;gBACb,MAAM,CAAC,OAAO,EAAE,CAAA;gBAChB,IAAI,SAAS;oBAAE,SAAS,CAAC,OAAO,EAAE,CAAA;YACpC,CAAC,CAAA;YAED,KAAK,CAAC,qCAAqC,EAAE,SAAS,CAAC,CAAA;YACvD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,mBAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAA;YAChE,KAAK,CAAC,6CAA6C,CAAC,CAAA;YAEpD,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBAC1B,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;aACtC;YAED,IAAI,IAAI,CAAC,cAAc,EAAE;gBACvB,sDAAsD;gBACtD,8CAA8C;gBAC9C,KAAK,CAAC,oCAAoC,CAAC,CAAA;gBAC3C,MAAM,UAAU,GAAG,MAAA,IAAI,CAAC,UAAU,mCAAI,IAAI,CAAC,IAAI,CAAA;gBAE/C,MAAM,SAAS,GAAG,aAAG,CAAC,OAAO,+CACxB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,KACjD,MAAM;oBACN,UAAU,KACP,IAAI,CAAC,oBAAoB,EAC5B,CAAA;gBAEF,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;oBAChC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;oBACxC,OAAO,CAAC,SAAS,CAAC,CAAA;gBACpB,CAAC,CAAC,CAAA;gBAEF,OAAO,SAAS,CAAA;aACjB;YAED,OAAO,MAAM,CAAA;;KACd;CACF;AA7FD,0CA6FC;AAED,SAAS,IAAI,CACX,GAAM,EACN,GAAG,IAAO;IAIV,MAAM,GAAG,GAAG,EAAgD,CAAA;IAC5D,IAAI,GAAqB,CAAA;IACzB,KAAK,GAAG,IAAI,GAAG,EAAE;QACf,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACvB,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;SACpB;KACF;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"} \ No newline at end of file diff --git a/node_modules/socks-proxy-agent/package.json b/node_modules/socks-proxy-agent/package.json index aa2999969c174..0f330a7310677 100644 --- a/node_modules/socks-proxy-agent/package.json +++ b/node_modules/socks-proxy-agent/package.json @@ -1,9 +1,12 @@ { "name": "socks-proxy-agent", + "version": "8.0.5", "description": "A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS", - "homepage": "https://github.com/TooTallNate/node-socks-proxy-agent#readme", - "version": "7.0.0", - "main": "dist/index.js", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], "author": { "email": "nathan@tootallnate.net", "name": "Nathan Rajlich", @@ -89,10 +92,8 @@ ], "repository": { "type": "git", - "url": "git://github.com/TooTallNate/node-socks-proxy-agent.git" - }, - "bugs": { - "url": "https://github.com/TooTallNate/node-socks-proxy-agent/issues" + "url": "https://github.com/TooTallNate/proxy-agents.git", + "directory": "packages/socks-proxy-agent" }, "keywords": [ "agent", @@ -106,76 +107,36 @@ "socks5h" ], "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" }, "devDependencies": { - "@commitlint/cli": "latest", - "@commitlint/config-conventional": "latest", - "@types/debug": "latest", - "@types/node": "latest", - "cacheable-lookup": "latest", - "conventional-github-releaser": "latest", - "dns2": "latest", - "finepack": "latest", - "git-authors-cli": "latest", - "mocha": "9", - "nano-staged": "latest", - "npm-check-updates": "latest", - "prettier-standard": "latest", - "raw-body": "latest", - "rimraf": "latest", - "simple-git-hooks": "latest", + "@types/async-retry": "^1.4.5", + "@types/debug": "^4.1.7", + "@types/dns2": "^2.0.3", + "@types/jest": "^29.5.1", + "@types/node": "^14.18.45", + "async-listen": "^3.0.0", + "async-retry": "^1.3.3", + "cacheable-lookup": "^6.1.0", + "dns2": "^2.1.0", + "jest": "^29.5.0", "socksv5": "github:TooTallNate/socksv5#fix/dstSock-close-event", - "standard": "latest", - "standard-markdown": "latest", - "standard-version": "latest", - "ts-standard": "latest", - "typescript": "latest" + "ts-jest": "^29.1.0", + "typescript": "^5.0.4", + "proxy": "2.2.0", + "tsconfig": "0.0.0" }, "engines": { - "node": ">= 10" + "node": ">= 14" }, - "files": [ - "dist" - ], + "license": "MIT", "scripts": { "build": "tsc", - "clean": "rimraf node_modules", - "contributors": "(git-authors-cli && finepack && git add package.json && git commit -m 'build: contributors' --no-verify) || true", - "lint": "ts-standard", - "postrelease": "npm run release:tags && npm run release:github && (ci-publish || npm publish --access=public)", - "prebuild": "rimraf dist", - "prepublishOnly": "npm run build", - "prerelease": "npm run update:check && npm run contributors", - "release": "standard-version -a", - "release:github": "conventional-github-releaser -p angular", - "release:tags": "git push --follow-tags origin HEAD:master", - "test": "mocha --reporter spec", - "update": "ncu -u", - "update:check": "ncu -- --error-level 2" - }, - "license": "MIT", - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, - "nano-staged": { - "*.js": [ - "prettier-standard" - ], - "*.md": [ - "standard-markdown" - ], - "package.json": [ - "finepack" - ] - }, - "simple-git-hooks": { - "commit-msg": "npx commitlint --edit", - "pre-commit": "npx nano-staged" - }, - "typings": "dist/index.d.ts" -} + "test": "jest --env node --verbose --bail test/test.ts", + "test-e2e": "jest --env node --verbose --bail test/e2e.test.ts", + "lint": "eslint . --ext .ts", + "pack": "node ../../scripts/pack.mjs" + } +} \ No newline at end of file diff --git a/node_modules/socks/build/client/socksclient.js b/node_modules/socks/build/client/socksclient.js index 40a82a53214a4..09b1f55767aa7 100644 --- a/node_modules/socks/build/client/socksclient.js +++ b/node_modules/socks/build/client/socksclient.js @@ -12,13 +12,13 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.SocksClientError = exports.SocksClient = void 0; const events_1 = require("events"); const net = require("net"); -const ip = require("ip"); const smart_buffer_1 = require("smart-buffer"); const constants_1 = require("../common/constants"); const helpers_1 = require("../common/helpers"); const receivebuffer_1 = require("../common/receivebuffer"); const util_1 = require("../common/util"); Object.defineProperty(exports, "SocksClientError", { enumerable: true, get: function () { return util_1.SocksClientError; } }); +const ip_address_1 = require("ip-address"); class SocksClient extends events_1.EventEmitter { constructor(options) { super(); @@ -45,6 +45,7 @@ class SocksClient extends events_1.EventEmitter { catch (err) { if (typeof callback === 'function') { callback(err); + // eslint-disable-next-line @typescript-eslint/no-explicit-any return resolve(err); // Resolves pending promise (prevents memory leaks). } else { @@ -68,6 +69,7 @@ class SocksClient extends events_1.EventEmitter { client.removeAllListeners(); if (typeof callback === 'function') { callback(err); + // eslint-disable-next-line @typescript-eslint/no-explicit-any resolve(err); // Resolves pending promise (prevents memory leaks). } else { @@ -86,6 +88,7 @@ class SocksClient extends events_1.EventEmitter { * @returns { Promise } */ static createConnectionChain(options, callback) { + // eslint-disable-next-line no-async-promise-executor return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { // Validate SocksClientChainOptions try { @@ -94,19 +97,19 @@ class SocksClient extends events_1.EventEmitter { catch (err) { if (typeof callback === 'function') { callback(err); + // eslint-disable-next-line @typescript-eslint/no-explicit-any return resolve(err); // Resolves pending promise (prevents memory leaks). } else { return reject(err); } } - let sock; // Shuffle proxies if (options.randomizeChain) { (0, util_1.shuffleArray)(options.proxies); } try { - // tslint:disable-next-line:no-increment-decrement + let sock; for (let i = 0; i < options.proxies.length; i++) { const nextProxy = options.proxies[i]; // If we've reached the last proxy in the chain, the destination is the actual destination, otherwise it's the next proxy. @@ -122,12 +125,10 @@ class SocksClient extends events_1.EventEmitter { command: 'connect', proxy: nextProxy, destination: nextDestination, - // Initial connection ignores this as sock is undefined. Subsequent connections re-use the first proxy socket to form a chain. + existing_socket: sock, }); // If sock is undefined, assign it here. - if (!sock) { - sock = result.socket; - } + sock = sock || result.socket; } if (typeof callback === 'function') { callback(null, { socket: sock }); @@ -140,6 +141,7 @@ class SocksClient extends events_1.EventEmitter { catch (err) { if (typeof callback === 'function') { callback(err); + // eslint-disable-next-line @typescript-eslint/no-explicit-any resolve(err); // Resolves pending promise (prevents memory leaks). } else { @@ -159,11 +161,11 @@ class SocksClient extends events_1.EventEmitter { // IPv4/IPv6/Hostname if (net.isIPv4(options.remoteHost.host)) { buff.writeUInt8(constants_1.Socks5HostType.IPv4); - buff.writeUInt32BE(ip.toLong(options.remoteHost.host)); + buff.writeUInt32BE((0, helpers_1.ipv4ToInt32)(options.remoteHost.host)); } else if (net.isIPv6(options.remoteHost.host)) { buff.writeUInt8(constants_1.Socks5HostType.IPv6); - buff.writeBuffer(ip.toBuffer(options.remoteHost.host)); + buff.writeBuffer((0, helpers_1.ipToBuffer)(options.remoteHost.host)); } else { buff.writeUInt8(constants_1.Socks5HostType.Hostname); @@ -187,10 +189,10 @@ class SocksClient extends events_1.EventEmitter { const hostType = buff.readUInt8(); let remoteHost; if (hostType === constants_1.Socks5HostType.IPv4) { - remoteHost = ip.fromLong(buff.readUInt32BE()); + remoteHost = (0, helpers_1.int32ToIpv4)(buff.readUInt32BE()); } else if (hostType === constants_1.Socks5HostType.IPv6) { - remoteHost = ip.toString(buff.readBuffer(16)); + remoteHost = ip_address_1.Address6.fromByteArray(Array.from(buff.readBuffer(16))).canonicalForm(); } else { remoteHost = buff.readString(buff.readUInt8()); @@ -399,7 +401,7 @@ class SocksClient extends events_1.EventEmitter { buff.writeUInt16BE(this.options.destination.port); // Socks 4 (IPv4) if (net.isIPv4(this.options.destination.host)) { - buff.writeBuffer(ip.toBuffer(this.options.destination.host)); + buff.writeBuffer((0, helpers_1.ipToBuffer)(this.options.destination.host)); buff.writeStringNT(userId); // Socks 4a (hostname) } @@ -431,7 +433,7 @@ class SocksClient extends events_1.EventEmitter { buff.readOffset = 2; const remoteHost = { port: buff.readUInt16BE(), - host: ip.fromLong(buff.readUInt32BE()), + host: (0, helpers_1.int32ToIpv4)(buff.readUInt32BE()), }; // If host is 0.0.0.0, set to proxy host. if (remoteHost.host === '0.0.0.0') { @@ -462,7 +464,7 @@ class SocksClient extends events_1.EventEmitter { buff.readOffset = 2; const remoteHost = { port: buff.readUInt16BE(), - host: ip.fromLong(buff.readUInt32BE()), + host: (0, helpers_1.int32ToIpv4)(buff.readUInt32BE()), }; this.setState(constants_1.SocksClientState.Established); this.removeInternalSocketHandlers(); @@ -608,11 +610,11 @@ class SocksClient extends events_1.EventEmitter { // ipv4, ipv6, domain? if (net.isIPv4(this.options.destination.host)) { buff.writeUInt8(constants_1.Socks5HostType.IPv4); - buff.writeBuffer(ip.toBuffer(this.options.destination.host)); + buff.writeBuffer((0, helpers_1.ipToBuffer)(this.options.destination.host)); } else if (net.isIPv6(this.options.destination.host)) { buff.writeUInt8(constants_1.Socks5HostType.IPv6); - buff.writeBuffer(ip.toBuffer(this.options.destination.host)); + buff.writeBuffer((0, helpers_1.ipToBuffer)(this.options.destination.host)); } else { buff.writeUInt8(constants_1.Socks5HostType.Hostname); @@ -650,7 +652,7 @@ class SocksClient extends events_1.EventEmitter { } buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4)); remoteHost = { - host: ip.fromLong(buff.readUInt32BE()), + host: (0, helpers_1.int32ToIpv4)(buff.readUInt32BE()), port: buff.readUInt16BE(), }; // If given host is 0.0.0.0, assume remote proxy ip instead. @@ -683,7 +685,7 @@ class SocksClient extends events_1.EventEmitter { } buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4)); remoteHost = { - host: ip.toString(buff.readBuffer(16)), + host: ip_address_1.Address6.fromByteArray(Array.from(buff.readBuffer(16))).canonicalForm(), port: buff.readUInt16BE(), }; } @@ -741,7 +743,7 @@ class SocksClient extends events_1.EventEmitter { } buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4)); remoteHost = { - host: ip.fromLong(buff.readUInt32BE()), + host: (0, helpers_1.int32ToIpv4)(buff.readUInt32BE()), port: buff.readUInt16BE(), }; // If given host is 0.0.0.0, assume remote proxy ip instead. @@ -774,7 +776,7 @@ class SocksClient extends events_1.EventEmitter { } buff = smart_buffer_1.SmartBuffer.fromBuffer(this.receiveBuffer.get(dataNeeded).slice(4)); remoteHost = { - host: ip.toString(buff.readBuffer(16)), + host: ip_address_1.Address6.fromByteArray(Array.from(buff.readBuffer(16))).canonicalForm(), port: buff.readUInt16BE(), }; } diff --git a/node_modules/socks/build/client/socksclient.js.map b/node_modules/socks/build/client/socksclient.js.map deleted file mode 100644 index 15d0b565ac33f..0000000000000 --- a/node_modules/socks/build/client/socksclient.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"socksclient.js","sourceRoot":"","sources":["../../src/client/socksclient.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mCAAoC;AACpC,2BAA2B;AAC3B,yBAAyB;AACzB,+CAAyC;AACzC,mDAkB6B;AAC7B,+CAG2B;AAC3B,2DAAsD;AACtD,yCAA8D;AAg7B5D,iGAh7BM,uBAAgB,OAg7BN;AAt5BlB,MAAM,WAAY,SAAQ,qBAAY;IAgBpC,YAAY,OAA2B;QACrC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,qBACP,OAAO,CACX,CAAC;QAEF,8BAA8B;QAC9B,IAAA,oCAA0B,EAAC,OAAO,CAAC,CAAC;QAEpC,gBAAgB;QAChB,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,gBAAgB,CACrB,OAA2B,EAC3B,QAAmB;QAEnB,OAAO,IAAI,OAAO,CAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClE,8BAA8B;YAC9B,IAAI;gBACF,IAAA,oCAA0B,EAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;aAClD;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,OAAO,CAAC,GAAU,CAAC,CAAC,CAAC,oDAAoD;iBACjF;qBAAM;oBACL,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;iBACpB;aACF;YAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,IAAiC,EAAE,EAAE;gBAC/D,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,oDAAoD;iBACpE;qBAAM;oBACL,OAAO,CAAC,IAAI,CAAC,CAAC;iBACf;YACH,CAAC,CAAC,CAAC;YAEH,kDAAkD;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAClC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,CAAC,GAAU,CAAC,CAAC,CAAC,oDAAoD;iBAC1E;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,qBAAqB,CAC1B,OAAgC,EAChC,QAAmB;QAEnB,OAAO,IAAI,OAAO,CAA8B,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;YACxE,mCAAmC;YACnC,IAAI;gBACF,IAAA,yCAA+B,EAAC,OAAO,CAAC,CAAC;aAC1C;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,OAAO,CAAC,GAAU,CAAC,CAAC,CAAC,oDAAoD;iBACjF;qBAAM;oBACL,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;iBACpB;aACF;YAED,IAAI,IAAgB,CAAC;YAErB,kBAAkB;YAClB,IAAI,OAAO,CAAC,cAAc,EAAE;gBAC1B,IAAA,mBAAY,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAC/B;YAED,IAAI;gBACF,kDAAkD;gBAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBAErC,0HAA0H;oBAC1H,MAAM,eAAe,GACnB,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;wBAC9B,CAAC,CAAC,OAAO,CAAC,WAAW;wBACrB,CAAC,CAAC;4BACE,IAAI,EACF,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;gCAC3B,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;4BAClC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;yBAClC,CAAC;oBAER,4CAA4C;oBAC5C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,gBAAgB,CAAC;wBAChD,OAAO,EAAE,SAAS;wBAClB,KAAK,EAAE,SAAS;wBAChB,WAAW,EAAE,eAAe;wBAC5B,8HAA8H;qBAC/H,CAAC,CAAC;oBAEH,wCAAwC;oBACxC,IAAI,CAAC,IAAI,EAAE;wBACT,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;qBACtB;iBACF;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,IAAI,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAC;oBAC/B,OAAO,CAAC,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC,oDAAoD;iBAC9E;qBAAM;oBACL,OAAO,CAAC,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAC;iBACzB;aACF;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,CAAC,GAAU,CAAC,CAAC,CAAC,oDAAoD;iBAC1E;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;aACF;QACH,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,OAA6B;QACjD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;QAE1C,qBAAqB;QACrB,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YACvC,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACxD;aAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACxD;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;SAC3C;QAED,OAAO;QACP,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE5C,OAAO;QACP,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAY;QAC/B,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QAEpB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAmB,IAAI,CAAC,SAAS,EAAE,CAAC;QAClD,IAAI,UAAU,CAAC;QAEf,IAAI,QAAQ,KAAK,0BAAc,CAAC,IAAI,EAAE;YACpC,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;SAC/C;aAAM,IAAI,QAAQ,KAAK,0BAAc,CAAC,IAAI,EAAE;YAC3C,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;SAC/C;aAAM;YACL,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;SAChD;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEvC,OAAO;YACL,WAAW;YACX,UAAU,EAAE;gBACV,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,UAAU;aACjB;YACD,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,QAA0B;QACzC,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,KAAK,EAAE;YACzC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;SACvB;IACH,CAAC;IAED;;;OAGG;IACI,OAAO,CAAC,cAAuB;QACpC,IAAI,CAAC,cAAc,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE/C,+CAA+C;QAC/C,MAAM,KAAK,GAAG,UAAU,CACtB,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,EACjC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,2BAAe,CACxC,CAAC;QAEF,8EAA8E;QAC9E,IAAI,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE;YACpD,KAAK,CAAC,KAAK,EAAE,CAAC;SACf;QAED,yGAAyG;QACzG,IAAI,cAAc,EAAE;YAClB,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;SAC9B;aAAM;YACL,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;SAChC;QAED,gCAAgC;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;QAEzC,IAAI,cAAc,EAAE;YAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SAC7B;aAAM;YACJ,IAAI,CAAC,MAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAE7D,IACE,IAAI,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;gBAC1C,IAAI,CAAC,OAAO,CAAC,eAAe,KAAK,IAAI,EACrC;gBACC,IAAI,CAAC,MAAqB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;aACxE;SACF;QAED,6FAA6F;QAC7F,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YAC/C,YAAY,CAAC,GAAG,EAAE;gBAChB,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;oBACjC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;oBAErE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBACtC;gBACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,+EAA+E;IACvE,gBAAgB;QACtB,uCACK,IAAI,CAAC,OAAO,CAAC,cAAc,KAC9B,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAC7D,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAC7B;IACJ,CAAC;IAED;;;OAGG;IACK,oBAAoB;QAC1B,IACE,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,WAAW;YAC3C,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,yBAAyB,EACzD;YACA,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,uBAAuB,CAAC,CAAC;SAClD;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB;QACtB,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,SAAS,CAAC,CAAC;QAE1C,0BAA0B;QAC1B,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;YACjC,IAAI,CAAC,0BAA0B,EAAE,CAAC;SACnC;aAAM;YACL,IAAI,CAAC,0BAA0B,EAAE,CAAC;SACnC;QAED,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,oBAAoB,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,IAAY;QACxC;;;UAGE;QACF,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEhC,6BAA6B;QAC7B,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,mFAAmF;QACnF,OACE,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,WAAW;YAC3C,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,KAAK;YACrC,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,IAAI,CAAC,4BAA4B,EAC9D;YACA,gDAAgD;YAChD,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,oBAAoB,EAAE;gBACxD,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;oBACjC,4CAA4C;oBAC5C,IAAI,CAAC,kCAAkC,EAAE,CAAC;iBAC3C;qBAAM;oBACL,wDAAwD;oBACxD,IAAI,CAAC,oCAAoC,EAAE,CAAC;iBAC7C;gBACD,wDAAwD;aACzD;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,kBAAkB,EAAE;gBAC7D,IAAI,CAAC,kDAAkD,EAAE,CAAC;gBAC1D,6DAA6D;aAC9D;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,kBAAkB,EAAE;gBAC7D,IAAI,CAAC,kCAAkC,EAAE,CAAC;gBAC1C,mEAAmE;aACpE;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,yBAAyB,EAAE;gBACpE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;oBACjC,IAAI,CAAC,sCAAsC,EAAE,CAAC;iBAC/C;qBAAM;oBACL,IAAI,CAAC,sCAAsC,EAAE,CAAC;iBAC/C;aACF;iBAAM;gBACL,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,aAAa,CAAC,CAAC;gBACvC,MAAM;aACP;SACF;IACH,CAAC;IAED;;;OAGG;IACK,cAAc;QACpB,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAED;;;OAGG;IACK,cAAc,CAAC,GAAU;QAC/B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACK,4BAA4B;QAClC,6FAA6F;QAC7F,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,GAAW;QAC7B,2FAA2F;QAC3F,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,KAAK,EAAE;YACzC,+BAA+B;YAC/B,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,KAAK,CAAC,CAAC;YAEtC,iBAAiB;YACjB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAEtB,4BAA4B;YAC5B,IAAI,CAAC,4BAA4B,EAAE,CAAC;YAEpC,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,uBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;SAC7D;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAE/C,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,wBAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAElD,iBAAiB;QACjB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC7C,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3B,sBAAsB;SACvB;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SACnD;QAED,IAAI,CAAC,4BAA4B;YAC/B,uCAA2B,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrC,CAAC;IAED;;;OAGG;IACK,kCAAkC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEvC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YACtC,IAAI,CAAC,WAAW,CACd,GAAG,kBAAM,CAAC,6BAA6B,OACrC,0BAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,GAAG,CACJ,CAAC;SACH;aAAM;YACL,gBAAgB;YAChB,IAAI,wBAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,IAAI,EAAE;gBAC5D,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBAEpB,MAAM,UAAU,GAAoB;oBAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;oBACzB,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;iBACvC,CAAC;gBAEF,yCAAyC;gBACzC,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;iBAChD;gBACD,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,yBAAyB,CAAC,CAAC;gBAC1D,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;gBAEtD,mBAAmB;aACpB;iBAAM;gBACL,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,WAAW,CAAC,CAAC;gBAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;aACjD;SACF;IACH,CAAC;IAED;;;OAGG;IACK,sCAAsC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEvC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YACtC,IAAI,CAAC,WAAW,CACd,GAAG,kBAAM,CAAC,0CAA0C,OAClD,0BAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,GAAG,CACJ,CAAC;SACH;aAAM;YACL,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;YAEpB,MAAM,UAAU,GAAoB;gBAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;gBACzB,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aACvC,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,WAAW,CAAC,CAAC;YAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;SAC7D;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAE/B,wCAAwC;QACxC,MAAM,oBAAoB,GAAG,CAAC,sBAAU,CAAC,MAAM,CAAC,CAAC;QAEjD,6FAA6F;QAC7F,sHAAsH;QACtH,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC5D,oBAAoB,CAAC,IAAI,CAAC,sBAAU,CAAC,QAAQ,CAAC,CAAC;SAChD;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE;YACvD,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;SAClE;QAED,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,MAAM,UAAU,IAAI,oBAAoB,EAAE;YAC7C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;SAC7B;QAED,IAAI,CAAC,4BAA4B;YAC/B,uCAA2B,CAAC,8BAA8B,CAAC;QAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,oBAAoB,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACK,oCAAoC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEvC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,yCAAyC,CAAC,CAAC;SACpE;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,qCAAyB,EAAE;YAChD,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,+CAA+C,CAAC,CAAC;SAC1E;aAAM;YACL,6EAA6E;YAC7E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,sBAAU,CAAC,MAAM,EAAE;gBACjC,IAAI,CAAC,oBAAoB,GAAG,sBAAU,CAAC,MAAM,CAAC;gBAC9C,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,0EAA0E;aAC3E;iBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,sBAAU,CAAC,QAAQ,EAAE;gBAC1C,IAAI,CAAC,oBAAoB,GAAG,sBAAU,CAAC,QAAQ,CAAC;gBAChD,IAAI,CAAC,gCAAgC,EAAE,CAAC;gBACxC,qFAAqF;aACtF;iBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE;gBAC5D,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC;gBAClE,IAAI,CAAC,8BAA8B,EAAE,CAAC;aACvC;iBAAM;gBACL,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,4CAA4C,CAAC,CAAC;aACvE;SACF;IACH,CAAC;IAED;;;;OAIG;IACK,gCAAgC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAEnD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE3B,IAAI,CAAC,4BAA4B;YAC/B,uCAA2B,CAAC,oCAAoC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC;IAEa,8BAA8B;;YAC1C,IAAI,CAAC,4BAA4B;gBAC/B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC,CAAC;YAC1E,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,kBAAkB,CAAC,CAAC;QACrD,CAAC;KAAA;IAEa,uCAAuC,CAAC,IAAY;;YAChE,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC;QACrE,CAAC;KAAA;IAEa,iDAAiD,CAC7D,IAAY;;YAEZ,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;QAC1B,CAAC;KAAA;IAEa,mDAAmD,CAC/D,IAAY;;YAEZ,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;QAC1B,CAAC;KAAA;IAED;;;OAGG;IACW,kDAAkD;;YAC9D,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,8BAA8B,CAAC,CAAC;YAE/D,IAAI,UAAU,GAAY,KAAK,CAAC;YAEhC,IAAI,IAAI,CAAC,oBAAoB,KAAK,sBAAU,CAAC,MAAM,EAAE;gBACnD,UAAU,GAAG,MAAM,IAAI,CAAC,iDAAiD,CACvE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAC1B,CAAC;aACH;iBAAM,IAAI,IAAI,CAAC,oBAAoB,KAAK,sBAAU,CAAC,QAAQ,EAAE;gBAC5D,UAAU;oBACR,MAAM,IAAI,CAAC,mDAAmD,CAC5D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAC1B,CAAC;aACL;iBAAM,IACL,IAAI,CAAC,oBAAoB,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EACnE;gBACA,UAAU,GAAG,MAAM,IAAI,CAAC,uCAAuC,CAC7D,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CACrE,CAAC;aACH;YAED,IAAI,CAAC,UAAU,EAAE;gBACf,IAAI,CAAC,WAAW,CAAC,kBAAM,CAAC,0BAA0B,CAAC,CAAC;aACrD;iBAAM;gBACL,IAAI,CAAC,wBAAwB,EAAE,CAAC;aACjC;QACH,CAAC;KAAA;IAED;;OAEG;IACK,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAE/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,wBAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,sBAAsB;QACtB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC7C,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;SAC9D;aAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YACpD,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;SAC9D;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SACjD;QACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAElD,IAAI,CAAC,4BAA4B;YAC/B,uCAA2B,CAAC,oBAAoB,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC;IAED;;;OAGG;IACK,kCAAkC;QACxC,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE1C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YAC9D,IAAI,CAAC,WAAW,CACd,GAAG,kBAAM,CAAC,mCAAmC,MAC3C,0BAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1B,EAAE,CACH,CAAC;SACH;aAAM;YACL,oBAAoB;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,UAA2B,CAAC;YAChC,IAAI,IAAiB,CAAC;YAEtB,OAAO;YACP,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBACvC,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC1C,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC;oBAC/C,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;iBAChD;gBAED,WAAW;aACZ;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,QAAQ,EAAE;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GACd,uCAA2B,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,CAAC,qCAAqC;gBAEvG,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC1C,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC;oBAC/C,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;oBACjC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBACF,OAAO;aACR;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBAC9C,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC1C,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC;oBAC/C,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;aACH;YAED,6BAA6B;YAC7B,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,qBAAqB,CAAC,CAAC;YAEtD,gEAAgE;YAChE,IAAI,wBAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,OAAO,EAAE;gBAC/D,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,WAAW,CAAC,CAAC;gBAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;aAC7D;iBAAM,IAAI,wBAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,IAAI,EAAE;gBACnE;mHACmG;gBACnG,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,yBAAyB,CAAC,CAAC;gBAC1D,IAAI,CAAC,4BAA4B;oBAC/B,uCAA2B,CAAC,oBAAoB,CAAC;gBACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;gBACtD;;;kBAGE;aACH;iBAAM,IACL,wBAAY,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,SAAS,EAC7D;gBACA,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,WAAW,CAAC,CAAC;gBAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;oBACvB,UAAU;oBACV,MAAM,EAAE,IAAI,CAAC,MAAM;iBACpB,CAAC,CAAC;aACJ;SACF;IACH,CAAC;IAED;;OAEG;IACK,sCAAsC;QAC5C,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE1C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YAC9D,IAAI,CAAC,WAAW,CACd,GAAG,kBAAM,CAAC,0CAA0C,MAClD,0BAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1B,EAAE,CACH,CAAC;SACH;aAAM;YACL,oBAAoB;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,UAA2B,CAAC;YAChC,IAAI,IAAiB,CAAC;YAEtB,OAAO;YACP,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBACvC,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC1C,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC;oBAC/C,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;iBAChD;gBAED,WAAW;aACZ;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,QAAQ,EAAE;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GACd,uCAA2B,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,CAAC,8BAA8B;gBAEhG,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC1C,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC;oBAC/C,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;oBACjC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBACF,OAAO;aACR;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBAC9C,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC1C,IAAI,CAAC,4BAA4B,GAAG,UAAU,CAAC;oBAC/C,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC5C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;aACH;YAED,IAAI,CAAC,QAAQ,CAAC,4BAAgB,CAAC,WAAW,CAAC,CAAC;YAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;SAC7D;IACH,CAAC;IAED,IAAI,kBAAkB;QACpB,yBACK,IAAI,CAAC,OAAO,EACf;IACJ,CAAC;CACF;AAGC,kCAAW"} \ No newline at end of file diff --git a/node_modules/socks/build/common/constants.js b/node_modules/socks/build/common/constants.js index 3c9ff90ac9feb..aaf16418fe941 100644 --- a/node_modules/socks/build/common/constants.js +++ b/node_modules/socks/build/common/constants.js @@ -38,10 +38,10 @@ const SOCKS_INCOMING_PACKET_SIZES = { Socks5InitialHandshakeResponse: 2, Socks5UserPassAuthenticationResponse: 2, // Command response + incoming connection (bind) - Socks5ResponseHeader: 5, - Socks5ResponseIPv4: 10, - Socks5ResponseIPv6: 22, - Socks5ResponseHostname: (hostNameLength) => hostNameLength + 7, + Socks5ResponseHeader: 5, // We need at least 5 to read the hostname length, then we wait for the address+port information. + Socks5ResponseIPv4: 10, // 4 header + 4 ip + 2 port + Socks5ResponseIPv6: 22, // 4 header + 16 ip + 2 port + Socks5ResponseHostname: (hostNameLength) => hostNameLength + 7, // 4 header + 1 host length + host + 2 port // Command response + incoming connection (bind) Socks4Response: 8, // 2 header + 2 port + 4 ip }; @@ -51,23 +51,20 @@ var SocksCommand; SocksCommand[SocksCommand["connect"] = 1] = "connect"; SocksCommand[SocksCommand["bind"] = 2] = "bind"; SocksCommand[SocksCommand["associate"] = 3] = "associate"; -})(SocksCommand || (SocksCommand = {})); -exports.SocksCommand = SocksCommand; +})(SocksCommand || (exports.SocksCommand = SocksCommand = {})); var Socks4Response; (function (Socks4Response) { Socks4Response[Socks4Response["Granted"] = 90] = "Granted"; Socks4Response[Socks4Response["Failed"] = 91] = "Failed"; Socks4Response[Socks4Response["Rejected"] = 92] = "Rejected"; Socks4Response[Socks4Response["RejectedIdent"] = 93] = "RejectedIdent"; -})(Socks4Response || (Socks4Response = {})); -exports.Socks4Response = Socks4Response; +})(Socks4Response || (exports.Socks4Response = Socks4Response = {})); var Socks5Auth; (function (Socks5Auth) { Socks5Auth[Socks5Auth["NoAuth"] = 0] = "NoAuth"; Socks5Auth[Socks5Auth["GSSApi"] = 1] = "GSSApi"; Socks5Auth[Socks5Auth["UserPass"] = 2] = "UserPass"; -})(Socks5Auth || (Socks5Auth = {})); -exports.Socks5Auth = Socks5Auth; +})(Socks5Auth || (exports.Socks5Auth = Socks5Auth = {})); const SOCKS5_CUSTOM_AUTH_START = 0x80; exports.SOCKS5_CUSTOM_AUTH_START = SOCKS5_CUSTOM_AUTH_START; const SOCKS5_CUSTOM_AUTH_END = 0xfe; @@ -85,15 +82,13 @@ var Socks5Response; Socks5Response[Socks5Response["TTLExpired"] = 6] = "TTLExpired"; Socks5Response[Socks5Response["CommandNotSupported"] = 7] = "CommandNotSupported"; Socks5Response[Socks5Response["AddressNotSupported"] = 8] = "AddressNotSupported"; -})(Socks5Response || (Socks5Response = {})); -exports.Socks5Response = Socks5Response; +})(Socks5Response || (exports.Socks5Response = Socks5Response = {})); var Socks5HostType; (function (Socks5HostType) { Socks5HostType[Socks5HostType["IPv4"] = 1] = "IPv4"; Socks5HostType[Socks5HostType["Hostname"] = 3] = "Hostname"; Socks5HostType[Socks5HostType["IPv6"] = 4] = "IPv6"; -})(Socks5HostType || (Socks5HostType = {})); -exports.Socks5HostType = Socks5HostType; +})(Socks5HostType || (exports.Socks5HostType = Socks5HostType = {})); var SocksClientState; (function (SocksClientState) { SocksClientState[SocksClientState["Created"] = 0] = "Created"; @@ -109,6 +104,5 @@ var SocksClientState; SocksClientState[SocksClientState["Established"] = 10] = "Established"; SocksClientState[SocksClientState["Disconnected"] = 11] = "Disconnected"; SocksClientState[SocksClientState["Error"] = 99] = "Error"; -})(SocksClientState || (SocksClientState = {})); -exports.SocksClientState = SocksClientState; +})(SocksClientState || (exports.SocksClientState = SocksClientState = {})); //# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/node_modules/socks/build/common/constants.js.map b/node_modules/socks/build/common/constants.js.map deleted file mode 100644 index c1e070dea4ac3..0000000000000 --- a/node_modules/socks/build/common/constants.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":";;;AAIA,MAAM,eAAe,GAAG,KAAK,CAAC;AA4M5B,0CAAe;AAxMjB,kBAAkB;AAClB,MAAM,MAAM,GAAG;IACb,mBAAmB,EAAE,wFAAwF;IAC7G,+BAA+B,EAAE,oGAAoG;IACrI,wBAAwB,EAAE,8FAA8F;IACxH,oCAAoC,EAAE,2CAA2C;IACjF,uCAAuC,EAAE,uFAAuF;IAChI,8BAA8B,EAAE,4CAA4C;IAC5E,gCAAgC,EAAE,8EAA8E;IAChH,sCAAsC,EAAE,2DAA2D;IACnG,wCAAwC,EAAE,oDAAoD;IAC9F,0CAA0C,EAAE,kKAAkK;IAC9M,gBAAgB,EAAE,mBAAmB;IACrC,YAAY,EAAE,eAAe;IAC7B,uBAAuB,EAAE,4BAA4B;IACrD,aAAa,EAAE,qDAAqD;IACpE,8BAA8B,EAAE,4CAA4C;IAC5E,6BAA6B,EAAE,kCAAkC;IACjE,uCAAuC,EAAE,6CAA6C;IACtF,0CAA0C,EAAE,iDAAiD;IAC7F,qCAAqC,EAAE,oDAAoD;IAC3F,yCAAyC,EAAE,mEAAmE;IAC9G,+CAA+C,EAAE,6EAA6E;IAC9H,4CAA4C,EAAE,yEAAyE;IACvH,0BAA0B,EAAE,8BAA8B;IAC1D,2BAA2B,EAAE,kDAAkD;IAC/E,mCAAmC,EAAE,kCAAkC;IACvE,uCAAuC,EAAE,sDAAsD;IAC/F,0CAA0C,EAAE,iDAAiD;CAC9F,CAAC;AA4KA,wBAAM;AA1KR,MAAM,2BAA2B,GAAG;IAClC,8BAA8B,EAAE,CAAC;IACjC,oCAAoC,EAAE,CAAC;IACvC,gDAAgD;IAChD,oBAAoB,EAAE,CAAC;IACvB,kBAAkB,EAAE,EAAE;IACtB,kBAAkB,EAAE,EAAE;IACtB,sBAAsB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,cAAc,GAAG,CAAC;IACtE,gDAAgD;IAChD,cAAc,EAAE,CAAC,EAAE,2BAA2B;CAC/C,CAAC;AAgLA,kEAA2B;AA5K7B,IAAK,YAIJ;AAJD,WAAK,YAAY;IACf,qDAAc,CAAA;IACd,+CAAW,CAAA;IACX,yDAAgB,CAAA;AAClB,CAAC,EAJI,YAAY,KAAZ,YAAY,QAIhB;AA0JC,oCAAY;AAxJd,IAAK,cAKJ;AALD,WAAK,cAAc;IACjB,0DAAc,CAAA;IACd,wDAAa,CAAA;IACb,4DAAe,CAAA;IACf,sEAAoB,CAAA;AACtB,CAAC,EALI,cAAc,KAAd,cAAc,QAKlB;AAoJC,wCAAc;AAlJhB,IAAK,UAIJ;AAJD,WAAK,UAAU;IACb,+CAAa,CAAA;IACb,+CAAa,CAAA;IACb,mDAAe,CAAA;AACjB,CAAC,EAJI,UAAU,KAAV,UAAU,QAId;AA+IC,gCAAU;AA7IZ,MAAM,wBAAwB,GAAG,IAAI,CAAC;AA0JpC,4DAAwB;AAzJ1B,MAAM,sBAAsB,GAAG,IAAI,CAAC;AA0JlC,wDAAsB;AAxJxB,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAyJrC,8DAAyB;AAvJ3B,IAAK,cAUJ;AAVD,WAAK,cAAc;IACjB,yDAAc,CAAA;IACd,yDAAc,CAAA;IACd,+DAAiB,CAAA;IACjB,+EAAyB,CAAA;IACzB,yEAAsB,CAAA;IACtB,6EAAwB,CAAA;IACxB,+DAAiB,CAAA;IACjB,iFAA0B,CAAA;IAC1B,iFAA0B,CAAA;AAC5B,CAAC,EAVI,cAAc,KAAd,cAAc,QAUlB;AAgIC,wCAAc;AA9HhB,IAAK,cAIJ;AAJD,WAAK,cAAc;IACjB,mDAAW,CAAA;IACX,2DAAe,CAAA;IACf,mDAAW,CAAA;AACb,CAAC,EAJI,cAAc,KAAd,cAAc,QAIlB;AAyHC,wCAAc;AAvHhB,IAAK,gBAcJ;AAdD,WAAK,gBAAgB;IACnB,6DAAW,CAAA;IACX,mEAAc,CAAA;IACd,iEAAa,CAAA;IACb,uFAAwB,CAAA;IACxB,+GAAoC,CAAA;IACpC,mFAAsB,CAAA;IACtB,2GAAkC,CAAA;IAClC,mFAAsB,CAAA;IACtB,yFAAyB,CAAA;IACzB,iGAA6B,CAAA;IAC7B,sEAAgB,CAAA;IAChB,wEAAiB,CAAA;IACjB,0DAAU,CAAA;AACZ,CAAC,EAdI,gBAAgB,KAAhB,gBAAgB,QAcpB;AA2GC,4CAAgB"} \ No newline at end of file diff --git a/node_modules/socks/build/common/helpers.js b/node_modules/socks/build/common/helpers.js index f84db8f6729d6..f0fcaf043d604 100644 --- a/node_modules/socks/build/common/helpers.js +++ b/node_modules/socks/build/common/helpers.js @@ -1,9 +1,11 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.validateSocksClientChainOptions = exports.validateSocksClientOptions = void 0; +exports.ipToBuffer = exports.int32ToIpv4 = exports.ipv4ToInt32 = exports.validateSocksClientChainOptions = exports.validateSocksClientOptions = void 0; const util_1 = require("./util"); const constants_1 = require("./constants"); const stream = require("stream"); +const ip_address_1 = require("ip-address"); +const net = require("net"); /** * Validates the provided SocksClientOptions * @param options { SocksClientOptions } @@ -102,6 +104,7 @@ function validateCustomProxyAuth(proxy, options) { function isValidSocksRemoteHost(remoteHost) { return (remoteHost && typeof remoteHost.host === 'string' && + Buffer.byteLength(remoteHost.host) < 256 && typeof remoteHost.port === 'number' && remoteHost.port >= 0 && remoteHost.port <= 65535); @@ -125,4 +128,40 @@ function isValidSocksProxy(proxy) { function isValidTimeoutValue(value) { return typeof value === 'number' && value > 0; } +function ipv4ToInt32(ip) { + const address = new ip_address_1.Address4(ip); + // Convert the IPv4 address parts to an integer + return address.toArray().reduce((acc, part) => (acc << 8) + part, 0) >>> 0; +} +exports.ipv4ToInt32 = ipv4ToInt32; +function int32ToIpv4(int32) { + // Extract each byte (octet) from the 32-bit integer + const octet1 = (int32 >>> 24) & 0xff; + const octet2 = (int32 >>> 16) & 0xff; + const octet3 = (int32 >>> 8) & 0xff; + const octet4 = int32 & 0xff; + // Combine the octets into a string in IPv4 format + return [octet1, octet2, octet3, octet4].join('.'); +} +exports.int32ToIpv4 = int32ToIpv4; +function ipToBuffer(ip) { + if (net.isIPv4(ip)) { + // Handle IPv4 addresses + const address = new ip_address_1.Address4(ip); + return Buffer.from(address.toArray()); + } + else if (net.isIPv6(ip)) { + // Handle IPv6 addresses + const address = new ip_address_1.Address6(ip); + return Buffer.from(address + .canonicalForm() + .split(':') + .map((segment) => segment.padStart(4, '0')) + .join(''), 'hex'); + } + else { + throw new Error('Invalid IP address format'); + } +} +exports.ipToBuffer = ipToBuffer; //# sourceMappingURL=helpers.js.map \ No newline at end of file diff --git a/node_modules/socks/build/common/helpers.js.map b/node_modules/socks/build/common/helpers.js.map deleted file mode 100644 index dae124861aa90..0000000000000 --- a/node_modules/socks/build/common/helpers.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/common/helpers.ts"],"names":[],"mappings":";;;AAKA,iCAAwC;AACxC,2CAMqB;AACrB,iCAAiC;AAEjC;;;;GAIG;AACH,SAAS,0BAA0B,CACjC,OAA2B,EAC3B,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;IAEnD,8BAA8B;IAC9B,IAAI,CAAC,wBAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAClC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;KACjE;IAED,6CAA6C;IAC7C,IAAI,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE;QACpD,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAC;KAC7E;IAED,oBAAoB;IACpB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QAChD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,oCAAoC,EAC3C,OAAO,CACR,CAAC;KACH;IAED,2BAA2B;IAC3B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACrC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAC;KAC5E;IAED,gCAAgC;IAChC,uBAAuB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAEhD,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC5D,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,gCAAgC,EACvC,OAAO,CACR,CAAC;KACH;IAED,sCAAsC;IACtC,IACE,OAAO,CAAC,eAAe;QACvB,CAAC,CAAC,OAAO,CAAC,eAAe,YAAY,MAAM,CAAC,MAAM,CAAC,EACnD;QACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,uCAAuC,EAC9C,OAAO,CACR,CAAC;KACH;AACH,CAAC;AA6IO,gEAA0B;AA3IlC;;;GAGG;AACH,SAAS,+BAA+B,CAAC,OAAgC;IACvE,2CAA2C;IAC3C,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;QACjC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;KACtE;IAED,oBAAoB;IACpB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QAChD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,oCAAoC,EAC3C,OAAO,CACR,CAAC;KACH;IAED,4BAA4B;IAC5B,IACE,CAAC,CACC,OAAO,CAAC,OAAO;QACf,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9B,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAC5B,EACD;QACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,sCAAsC,EAC7C,OAAO,CACR,CAAC;KACH;IAED,mBAAmB;IACnB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAiB,EAAE,EAAE;QAC5C,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,8BAA8B,EACrC,OAAO,CACR,CAAC;SACH;QAED,gCAAgC;QAChC,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC5D,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,gCAAgC,EACvC,OAAO,CACR,CAAC;KACH;AACH,CAAC;AAuFmC,0EAA+B;AArFnE,SAAS,uBAAuB,CAC9B,KAAiB,EACjB,OAAqD;IAErD,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE;QAC1C,4BAA4B;QAC5B,IACE,KAAK,CAAC,kBAAkB,GAAG,oCAAwB;YACnD,KAAK,CAAC,kBAAkB,GAAG,kCAAsB,EACjD;YACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,wCAAwC,EAC/C,OAAO,CACR,CAAC;SACH;QAED,sCAAsC;QACtC,IACE,KAAK,CAAC,2BAA2B,KAAK,SAAS;YAC/C,OAAO,KAAK,CAAC,2BAA2B,KAAK,UAAU,EACvD;YACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,0CAA0C,EACjD,OAAO,CACR,CAAC;SACH;QAED,oCAAoC;QACpC,IAAI,KAAK,CAAC,yBAAyB,KAAK,SAAS,EAAE;YACjD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,0CAA0C,EACjD,OAAO,CACR,CAAC;SACH;QAED,+CAA+C;QAC/C,IACE,KAAK,CAAC,4BAA4B,KAAK,SAAS;YAChD,OAAO,KAAK,CAAC,4BAA4B,KAAK,UAAU,EACxD;YACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,0CAA0C,EACjD,OAAO,CACR,CAAC;SACH;KACF;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,UAA2B;IACzD,OAAO,CACL,UAAU;QACV,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,UAAU,CAAC,IAAI,IAAI,CAAC;QACpB,UAAU,CAAC,IAAI,IAAI,KAAK,CACzB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,KAAiB;IAC1C,OAAO,CACL,KAAK;QACL,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC;QACvE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,KAAK,CAAC,IAAI,IAAI,CAAC;QACf,KAAK,CAAC,IAAI,IAAI,KAAK;QACnB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC;AAChD,CAAC"} \ No newline at end of file diff --git a/node_modules/socks/build/common/receivebuffer.js.map b/node_modules/socks/build/common/receivebuffer.js.map deleted file mode 100644 index 144edb0b9b336..0000000000000 --- a/node_modules/socks/build/common/receivebuffer.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"receivebuffer.js","sourceRoot":"","sources":["../../src/common/receivebuffer.ts"],"names":[],"mappings":";;;AAAA,MAAM,aAAa;IAKjB,YAAY,OAAe,IAAI;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC1B,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;SACH;QAED,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YACnD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;YACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,CAC9B,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EACtC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CACjC,CACF,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SACvB;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,MAAc;QACjB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;SACH;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,GAAG,CAAC,MAAc;QAChB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;SACH;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;QAEtB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAEO,sCAAa"} \ No newline at end of file diff --git a/node_modules/socks/build/common/util.js b/node_modules/socks/build/common/util.js index 283314a0d4456..f66b72e43e386 100644 --- a/node_modules/socks/build/common/util.js +++ b/node_modules/socks/build/common/util.js @@ -16,7 +16,6 @@ exports.SocksClientError = SocksClientError; * @param array The array to shuffle. */ function shuffleArray(array) { - // tslint:disable-next-line:no-increment-decrement for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; diff --git a/node_modules/socks/build/common/util.js.map b/node_modules/socks/build/common/util.js.map deleted file mode 100644 index 8d94a2ace787a..0000000000000 --- a/node_modules/socks/build/common/util.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/common/util.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAM,gBAAiB,SAAQ,KAAK;IAClC,YACE,OAAe,EACR,OAAqD;QAE5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,YAAO,GAAP,OAAO,CAA8C;IAG9D,CAAC;CACF;AAwBuB,4CAAgB;AAtBxC;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAY;IAChC,kDAAkD;IAClD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAC7C;AACH,CAAC;AAYyC,oCAAY"} \ No newline at end of file diff --git a/node_modules/socks/build/index.js b/node_modules/socks/build/index.js index 17b6f42df8e5b..05fbb1d949b48 100644 --- a/node_modules/socks/build/index.js +++ b/node_modules/socks/build/index.js @@ -1,7 +1,11 @@ "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; diff --git a/node_modules/socks/build/index.js.map b/node_modules/socks/build/index.js.map deleted file mode 100644 index ff654a08e01b3..0000000000000 --- a/node_modules/socks/build/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,uDAAqC"} \ No newline at end of file diff --git a/node_modules/socks/package.json b/node_modules/socks/package.json index 61c3f1dcf17fd..a7a2a20190ad3 100644 --- a/node_modules/socks/package.json +++ b/node_modules/socks/package.json @@ -1,7 +1,7 @@ { "name": "socks", "private": false, - "version": "2.6.2", + "version": "2.8.7", "description": "Fully featured SOCKS proxy client supporting SOCKSv4, SOCKSv4a, and SOCKSv5. Includes Bind and Associate functionality.", "main": "build/index.js", "typings": "typings/index.d.ts", @@ -23,7 +23,7 @@ "socks5" ], "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" }, "author": "Josh Glazebrook", @@ -33,51 +33,26 @@ "license": "MIT", "readmeFilename": "README.md", "devDependencies": { - "@types/ip": "1.1.0", - "@types/mocha": "^9.1.0", - "@types/node": "^17.0.15", - "coveralls": "^3.1.1", - "mocha": "^9.2.0", - "nyc": "15.1.0", - "prettier": "^2.5.1", - "socks5-server": "^0.1.1", - "ts-node": "^10.4.0", - "typescript": "^4.5.5" + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.17", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "eslint": "^8.20.0", + "mocha": "^10.0.0", + "prettier": "^3.2.5", + "ts-node": "^10.9.1", + "typescript": "^5.3.3" }, "dependencies": { - "ip": "^1.1.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "scripts": { "prepublish": "npm install -g typescript && npm run build", "test": "NODE_ENV=test mocha --recursive --require ts-node/register test/**/*.ts", "prettier": "prettier --write ./src/**/*.ts --config .prettierrc.yaml", - "coverage": "NODE_ENV=test nyc npm test", - "coveralls": "NODE_ENV=test nyc npm test && nyc report --reporter=text-lcov | coveralls", - "lint": "tslint --project tsconfig.json 'src/**/*.ts'", - "build": "rm -rf build typings && prettier --write ./src/**/*.ts --config .prettierrc.yaml && tsc -p ." - }, - "nyc": { - "extension": [ - ".ts", - ".tsx" - ], - "include": [ - "src/*.ts", - "src/**/*.ts" - ], - "exclude": [ - "**.*.d.ts", - "node_modules", - "typings" - ], - "require": [ - "ts-node/register" - ], - "reporter": [ - "json", - "html" - ], - "all": true + "lint": "eslint 'src/**/*.ts'", + "build": "rm -rf build typings && prettier --write ./src/**/*.ts --config .prettierrc.yaml && tsc -p .", + "build-raw": "rm -rf build typings && tsc -p ." } } diff --git a/node_modules/socks/typings/client/socksclient.d.ts b/node_modules/socks/typings/client/socksclient.d.ts deleted file mode 100644 index d8ce1b965f0e0..0000000000000 --- a/node_modules/socks/typings/client/socksclient.d.ts +++ /dev/null @@ -1,160 +0,0 @@ -/// <reference types="node" /> -import { EventEmitter } from 'events'; -import { SocksClientOptions, SocksClientChainOptions, SocksRemoteHost, SocksProxy, SocksClientBoundEvent, SocksClientEstablishedEvent, SocksUDPFrameDetails } from '../common/constants'; -import { SocksClientError } from '../common/util'; -import { Duplex } from 'stream'; -declare interface SocksClient { - on(event: 'error', listener: (err: SocksClientError) => void): this; - on(event: 'bound', listener: (info: SocksClientBoundEvent) => void): this; - on(event: 'established', listener: (info: SocksClientEstablishedEvent) => void): this; - once(event: string, listener: (...args: any[]) => void): this; - once(event: 'error', listener: (err: SocksClientError) => void): this; - once(event: 'bound', listener: (info: SocksClientBoundEvent) => void): this; - once(event: 'established', listener: (info: SocksClientEstablishedEvent) => void): this; - emit(event: string | symbol, ...args: any[]): boolean; - emit(event: 'error', err: SocksClientError): boolean; - emit(event: 'bound', info: SocksClientBoundEvent): boolean; - emit(event: 'established', info: SocksClientEstablishedEvent): boolean; -} -declare class SocksClient extends EventEmitter implements SocksClient { - private options; - private socket; - private state; - private receiveBuffer; - private nextRequiredPacketBufferSize; - private socks5ChosenAuthType; - private onDataReceived; - private onClose; - private onError; - private onConnect; - constructor(options: SocksClientOptions); - /** - * Creates a new SOCKS connection. - * - * Note: Supports callbacks and promises. Only supports the connect command. - * @param options { SocksClientOptions } Options. - * @param callback { Function } An optional callback function. - * @returns { Promise } - */ - static createConnection(options: SocksClientOptions, callback?: Function): Promise<SocksClientEstablishedEvent>; - /** - * Creates a new SOCKS connection chain to a destination host through 2 or more SOCKS proxies. - * - * Note: Supports callbacks and promises. Only supports the connect method. - * Note: Implemented via createConnection() factory function. - * @param options { SocksClientChainOptions } Options - * @param callback { Function } An optional callback function. - * @returns { Promise } - */ - static createConnectionChain(options: SocksClientChainOptions, callback?: Function): Promise<SocksClientEstablishedEvent>; - /** - * Creates a SOCKS UDP Frame. - * @param options - */ - static createUDPFrame(options: SocksUDPFrameDetails): Buffer; - /** - * Parses a SOCKS UDP frame. - * @param data - */ - static parseUDPFrame(data: Buffer): SocksUDPFrameDetails; - /** - * Internal state setter. If the SocksClient is in an error state, it cannot be changed to a non error state. - */ - private setState; - /** - * Starts the connection establishment to the proxy and destination. - * @param existingSocket Connected socket to use instead of creating a new one (internal use). - */ - connect(existingSocket?: Duplex): void; - private getSocketOptions; - /** - * Handles internal Socks timeout callback. - * Note: If the Socks client is not BoundWaitingForConnection or Established, the connection will be closed. - */ - private onEstablishedTimeout; - /** - * Handles Socket connect event. - */ - private onConnectHandler; - /** - * Handles Socket data event. - * @param data - */ - private onDataReceivedHandler; - /** - * Handles processing of the data we have received. - */ - private processData; - /** - * Handles Socket close event. - * @param had_error - */ - private onCloseHandler; - /** - * Handles Socket error event. - * @param err - */ - private onErrorHandler; - /** - * Removes internal event listeners on the underlying Socket. - */ - private removeInternalSocketHandlers; - /** - * Closes and destroys the underlying Socket. Emits an error event. - * @param err { String } An error string to include in error event. - */ - private closeSocket; - /** - * Sends initial Socks v4 handshake request. - */ - private sendSocks4InitialHandshake; - /** - * Handles Socks v4 handshake response. - * @param data - */ - private handleSocks4FinalHandshakeResponse; - /** - * Handles Socks v4 incoming connection request (BIND) - * @param data - */ - private handleSocks4IncomingConnectionResponse; - /** - * Sends initial Socks v5 handshake request. - */ - private sendSocks5InitialHandshake; - /** - * Handles initial Socks v5 handshake response. - * @param data - */ - private handleInitialSocks5HandshakeResponse; - /** - * Sends Socks v5 user & password auth handshake. - * - * Note: No auth and user/pass are currently supported. - */ - private sendSocks5UserPassAuthentication; - private sendSocks5CustomAuthentication; - private handleSocks5CustomAuthHandshakeResponse; - private handleSocks5AuthenticationNoAuthHandshakeResponse; - private handleSocks5AuthenticationUserPassHandshakeResponse; - /** - * Handles Socks v5 auth handshake response. - * @param data - */ - private handleInitialSocks5AuthenticationHandshakeResponse; - /** - * Sends Socks v5 final handshake request. - */ - private sendSocks5CommandRequest; - /** - * Handles Socks v5 final handshake response. - * @param data - */ - private handleSocks5FinalHandshakeResponse; - /** - * Handles Socks v5 incoming connection request (BIND). - */ - private handleSocks5IncomingConnectionResponse; - get socksClientOptions(): SocksClientOptions; -} -export { SocksClient, SocksClientOptions, SocksClientChainOptions, SocksClientError, SocksRemoteHost, SocksProxy, SocksUDPFrameDetails, }; diff --git a/node_modules/socks/typings/common/constants.d.ts b/node_modules/socks/typings/common/constants.d.ts deleted file mode 100644 index 664795cb180fb..0000000000000 --- a/node_modules/socks/typings/common/constants.d.ts +++ /dev/null @@ -1,150 +0,0 @@ -/// <reference types="node" /> -import { Duplex } from 'stream'; -import { Socket, SocketConnectOpts } from 'net'; -import { RequireOnlyOne } from './util'; -declare const DEFAULT_TIMEOUT = 30000; -declare type SocksProxyType = 4 | 5; -declare const ERRORS: { - InvalidSocksCommand: string; - InvalidSocksCommandForOperation: string; - InvalidSocksCommandChain: string; - InvalidSocksClientOptionsDestination: string; - InvalidSocksClientOptionsExistingSocket: string; - InvalidSocksClientOptionsProxy: string; - InvalidSocksClientOptionsTimeout: string; - InvalidSocksClientOptionsProxiesLength: string; - InvalidSocksClientOptionsCustomAuthRange: string; - InvalidSocksClientOptionsCustomAuthOptions: string; - NegotiationError: string; - SocketClosed: string; - ProxyConnectionTimedOut: string; - InternalError: string; - InvalidSocks4HandshakeResponse: string; - Socks4ProxyRejectedConnection: string; - InvalidSocks4IncomingConnectionResponse: string; - Socks4ProxyRejectedIncomingBoundConnection: string; - InvalidSocks5InitialHandshakeResponse: string; - InvalidSocks5IntiailHandshakeSocksVersion: string; - InvalidSocks5InitialHandshakeNoAcceptedAuthType: string; - InvalidSocks5InitialHandshakeUnknownAuthType: string; - Socks5AuthenticationFailed: string; - InvalidSocks5FinalHandshake: string; - InvalidSocks5FinalHandshakeRejected: string; - InvalidSocks5IncomingConnectionResponse: string; - Socks5ProxyRejectedIncomingBoundConnection: string; -}; -declare const SOCKS_INCOMING_PACKET_SIZES: { - Socks5InitialHandshakeResponse: number; - Socks5UserPassAuthenticationResponse: number; - Socks5ResponseHeader: number; - Socks5ResponseIPv4: number; - Socks5ResponseIPv6: number; - Socks5ResponseHostname: (hostNameLength: number) => number; - Socks4Response: number; -}; -declare type SocksCommandOption = 'connect' | 'bind' | 'associate'; -declare enum SocksCommand { - connect = 1, - bind = 2, - associate = 3 -} -declare enum Socks4Response { - Granted = 90, - Failed = 91, - Rejected = 92, - RejectedIdent = 93 -} -declare enum Socks5Auth { - NoAuth = 0, - GSSApi = 1, - UserPass = 2 -} -declare const SOCKS5_CUSTOM_AUTH_START = 128; -declare const SOCKS5_CUSTOM_AUTH_END = 254; -declare const SOCKS5_NO_ACCEPTABLE_AUTH = 255; -declare enum Socks5Response { - Granted = 0, - Failure = 1, - NotAllowed = 2, - NetworkUnreachable = 3, - HostUnreachable = 4, - ConnectionRefused = 5, - TTLExpired = 6, - CommandNotSupported = 7, - AddressNotSupported = 8 -} -declare enum Socks5HostType { - IPv4 = 1, - Hostname = 3, - IPv6 = 4 -} -declare enum SocksClientState { - Created = 0, - Connecting = 1, - Connected = 2, - SentInitialHandshake = 3, - ReceivedInitialHandshakeResponse = 4, - SentAuthentication = 5, - ReceivedAuthenticationResponse = 6, - SentFinalHandshake = 7, - ReceivedFinalResponse = 8, - BoundWaitingForConnection = 9, - Established = 10, - Disconnected = 11, - Error = 99 -} -/** - * Represents a SocksProxy - */ -declare type SocksProxy = RequireOnlyOne<{ - ipaddress?: string; - host?: string; - port: number; - type: SocksProxyType; - userId?: string; - password?: string; - custom_auth_method?: number; - custom_auth_request_handler?: () => Promise<Buffer>; - custom_auth_response_size?: number; - custom_auth_response_handler?: (data: Buffer) => Promise<boolean>; -}, 'host' | 'ipaddress'>; -/** - * Represents a remote host - */ -interface SocksRemoteHost { - host: string; - port: number; -} -/** - * SocksClient connection options. - */ -interface SocksClientOptions { - command: SocksCommandOption; - destination: SocksRemoteHost; - proxy: SocksProxy; - timeout?: number; - existing_socket?: Duplex; - set_tcp_nodelay?: boolean; - socket_options?: SocketConnectOpts; -} -/** - * SocksClient chain connection options. - */ -interface SocksClientChainOptions { - command: 'connect'; - destination: SocksRemoteHost; - proxies: SocksProxy[]; - timeout?: number; - randomizeChain?: false; -} -interface SocksClientEstablishedEvent { - socket: Socket; - remoteHost?: SocksRemoteHost; -} -declare type SocksClientBoundEvent = SocksClientEstablishedEvent; -interface SocksUDPFrameDetails { - frameNumber?: number; - remoteHost: SocksRemoteHost; - data: Buffer; -} -export { DEFAULT_TIMEOUT, ERRORS, SocksProxyType, SocksCommand, Socks4Response, Socks5Auth, Socks5HostType, Socks5Response, SocksClientState, SocksProxy, SocksRemoteHost, SocksCommandOption, SocksClientOptions, SocksClientChainOptions, SocksClientEstablishedEvent, SocksClientBoundEvent, SocksUDPFrameDetails, SOCKS_INCOMING_PACKET_SIZES, SOCKS5_CUSTOM_AUTH_START, SOCKS5_CUSTOM_AUTH_END, SOCKS5_NO_ACCEPTABLE_AUTH, }; diff --git a/node_modules/socks/typings/common/helpers.d.ts b/node_modules/socks/typings/common/helpers.d.ts deleted file mode 100644 index 8c3a106979df1..0000000000000 --- a/node_modules/socks/typings/common/helpers.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SocksClientOptions, SocksClientChainOptions } from '../client/socksclient'; -/** - * Validates the provided SocksClientOptions - * @param options { SocksClientOptions } - * @param acceptedCommands { string[] } A list of accepted SocksProxy commands. - */ -declare function validateSocksClientOptions(options: SocksClientOptions, acceptedCommands?: string[]): void; -/** - * Validates the SocksClientChainOptions - * @param options { SocksClientChainOptions } - */ -declare function validateSocksClientChainOptions(options: SocksClientChainOptions): void; -export { validateSocksClientOptions, validateSocksClientChainOptions }; diff --git a/node_modules/socks/typings/common/receivebuffer.d.ts b/node_modules/socks/typings/common/receivebuffer.d.ts deleted file mode 100644 index 756e98b5893ed..0000000000000 --- a/node_modules/socks/typings/common/receivebuffer.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// <reference types="node" /> -declare class ReceiveBuffer { - private buffer; - private offset; - private originalSize; - constructor(size?: number); - get length(): number; - append(data: Buffer): number; - peek(length: number): Buffer; - get(length: number): Buffer; -} -export { ReceiveBuffer }; diff --git a/node_modules/socks/typings/common/util.d.ts b/node_modules/socks/typings/common/util.d.ts deleted file mode 100644 index 29c539adaabc4..0000000000000 --- a/node_modules/socks/typings/common/util.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { SocksClientOptions, SocksClientChainOptions } from './constants'; -/** - * Error wrapper for SocksClient - */ -declare class SocksClientError extends Error { - options: SocksClientOptions | SocksClientChainOptions; - constructor(message: string, options: SocksClientOptions | SocksClientChainOptions); -} -/** - * Shuffles a given array. - * @param array The array to shuffle. - */ -declare function shuffleArray(array: any[]): void; -declare type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & { - [K in Keys]?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>; -}[Keys]; -export { RequireOnlyOne, SocksClientError, shuffleArray }; diff --git a/node_modules/socks/typings/index.d.ts b/node_modules/socks/typings/index.d.ts deleted file mode 100644 index fbf9006ef1d3d..0000000000000 --- a/node_modules/socks/typings/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './client/socksclient'; diff --git a/node_modules/spdx-correct/index.js b/node_modules/spdx-correct/index.js index c51a79f5d1c80..4d9037e0cc435 100644 --- a/node_modules/spdx-correct/index.js +++ b/node_modules/spdx-correct/index.js @@ -25,6 +25,18 @@ function valid (string) { } } +// Sorting function that orders the given array of transpositions such +// that a transposition with the longer pattern comes before a transposition +// with a shorter pattern. This is to prevent e.g. the transposition +// ["General Public License", "GPL"] from matching to "Lesser General Public License" +// before a longer and more accurate transposition ["Lesser General Public License", "LGPL"] +// has a chance to be recognized. +function sortTranspositions(a, b) { + var length = b[0].length - a[0].length + if (length !== 0) return length + return a[0].toUpperCase().localeCompare(b[0].toUpperCase()) +} + // Common transpositions of license identifier acronyms var transpositions = [ ['APGL', 'AGPL'], @@ -41,8 +53,17 @@ var transpositions = [ ['GUN', 'GPL'], ['+', ''], ['GNU GPL', 'GPL'], + ['GNU LGPL', 'LGPL'], ['GNU/GPL', 'GPL'], ['GNU GLP', 'GPL'], + ['GNU LESSER GENERAL PUBLIC LICENSE', 'LGPL'], + ['GNU Lesser General Public License', 'LGPL'], + ['GNU LESSER GENERAL PUBLIC LICENSE', 'LGPL-2.1'], + ['GNU Lesser General Public License', 'LGPL-2.1'], + ['LESSER GENERAL PUBLIC LICENSE', 'LGPL'], + ['Lesser General Public License', 'LGPL'], + ['LESSER GENERAL PUBLIC LICENSE', 'LGPL-2.1'], + ['Lesser General Public License', 'LGPL-2.1'], ['GNU General Public License', 'GPL'], ['Gnu public license', 'GPL'], ['GNU Public License', 'GPL'], @@ -51,8 +72,9 @@ var transpositions = [ ['Mozilla Public License', 'MPL'], ['Universal Permissive License', 'UPL'], ['WTH', 'WTF'], + ['WTFGPL', 'WTFPL'], ['-License', ''] -] +].sort(sortTranspositions) var TRANSPOSED = 0 var CORRECT = 1 @@ -254,7 +276,7 @@ var lastResorts = [ ['MPL', 'MPL-2.0'], ['X11', 'X11'], ['ZLIB', 'Zlib'] -].concat(licensesWithOneVersion) +].concat(licensesWithOneVersion).sort(sortTranspositions) var SUBSTRING = 0 var IDENTIFIER = 1 diff --git a/node_modules/spdx-correct/node_modules/spdx-expression-parse/AUTHORS b/node_modules/spdx-correct/node_modules/spdx-expression-parse/AUTHORS new file mode 100644 index 0000000000000..257a76b9484c1 --- /dev/null +++ b/node_modules/spdx-correct/node_modules/spdx-expression-parse/AUTHORS @@ -0,0 +1,4 @@ +C. Scott Ananian <cscott@cscott.net> (http://cscott.net) +Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com) +Shinnosuke Watanabe <snnskwtnb@gmail.com> +Antoine Motet <antoine.motet@gmail.com> diff --git a/node_modules/spdx-correct/node_modules/spdx-expression-parse/LICENSE b/node_modules/spdx-correct/node_modules/spdx-expression-parse/LICENSE new file mode 100644 index 0000000000000..831618eaba6c8 --- /dev/null +++ b/node_modules/spdx-correct/node_modules/spdx-expression-parse/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2015 Kyle E. Mitchell & other authors listed in AUTHORS + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/spdx-correct/node_modules/spdx-expression-parse/index.js b/node_modules/spdx-correct/node_modules/spdx-expression-parse/index.js new file mode 100644 index 0000000000000..52fab560aea70 --- /dev/null +++ b/node_modules/spdx-correct/node_modules/spdx-expression-parse/index.js @@ -0,0 +1,8 @@ +'use strict' + +var scan = require('./scan') +var parse = require('./parse') + +module.exports = function (source) { + return parse(scan(source)) +} diff --git a/node_modules/spdx-correct/node_modules/spdx-expression-parse/package.json b/node_modules/spdx-correct/node_modules/spdx-expression-parse/package.json new file mode 100644 index 0000000000000..c9edc9f939cdf --- /dev/null +++ b/node_modules/spdx-correct/node_modules/spdx-expression-parse/package.json @@ -0,0 +1,39 @@ +{ + "name": "spdx-expression-parse", + "description": "parse SPDX license expressions", + "version": "3.0.1", + "author": "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com)", + "files": [ + "AUTHORS", + "index.js", + "parse.js", + "scan.js" + ], + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + }, + "devDependencies": { + "defence-cli": "^3.0.1", + "replace-require-self": "^1.0.0", + "standard": "^14.1.0" + }, + "keywords": [ + "SPDX", + "law", + "legal", + "license", + "metadata", + "package", + "package.json", + "standards" + ], + "license": "MIT", + "repository": "jslicense/spdx-expression-parse.js", + "scripts": { + "lint": "standard", + "test:readme": "defence -i javascript README.md | replace-require-self | node", + "test:suite": "node test.js", + "test": "npm run test:suite && npm run test:readme" + } +} diff --git a/node_modules/spdx-correct/node_modules/spdx-expression-parse/parse.js b/node_modules/spdx-correct/node_modules/spdx-expression-parse/parse.js new file mode 100644 index 0000000000000..5a00b45c5799c --- /dev/null +++ b/node_modules/spdx-correct/node_modules/spdx-expression-parse/parse.js @@ -0,0 +1,138 @@ +'use strict' + +// The ABNF grammar in the spec is totally ambiguous. +// +// This parser follows the operator precedence defined in the +// `Order of Precedence and Parentheses` section. + +module.exports = function (tokens) { + var index = 0 + + function hasMore () { + return index < tokens.length + } + + function token () { + return hasMore() ? tokens[index] : null + } + + function next () { + if (!hasMore()) { + throw new Error() + } + index++ + } + + function parseOperator (operator) { + var t = token() + if (t && t.type === 'OPERATOR' && operator === t.string) { + next() + return t.string + } + } + + function parseWith () { + if (parseOperator('WITH')) { + var t = token() + if (t && t.type === 'EXCEPTION') { + next() + return t.string + } + throw new Error('Expected exception after `WITH`') + } + } + + function parseLicenseRef () { + // TODO: Actually, everything is concatenated into one string + // for backward-compatibility but it could be better to return + // a nice structure. + var begin = index + var string = '' + var t = token() + if (t.type === 'DOCUMENTREF') { + next() + string += 'DocumentRef-' + t.string + ':' + if (!parseOperator(':')) { + throw new Error('Expected `:` after `DocumentRef-...`') + } + } + t = token() + if (t.type === 'LICENSEREF') { + next() + string += 'LicenseRef-' + t.string + return { license: string } + } + index = begin + } + + function parseLicense () { + var t = token() + if (t && t.type === 'LICENSE') { + next() + var node = { license: t.string } + if (parseOperator('+')) { + node.plus = true + } + var exception = parseWith() + if (exception) { + node.exception = exception + } + return node + } + } + + function parseParenthesizedExpression () { + var left = parseOperator('(') + if (!left) { + return + } + + var expr = parseExpression() + + if (!parseOperator(')')) { + throw new Error('Expected `)`') + } + + return expr + } + + function parseAtom () { + return ( + parseParenthesizedExpression() || + parseLicenseRef() || + parseLicense() + ) + } + + function makeBinaryOpParser (operator, nextParser) { + return function parseBinaryOp () { + var left = nextParser() + if (!left) { + return + } + + if (!parseOperator(operator)) { + return left + } + + var right = parseBinaryOp() + if (!right) { + throw new Error('Expected expression') + } + return { + left: left, + conjunction: operator.toLowerCase(), + right: right + } + } + } + + var parseAnd = makeBinaryOpParser('AND', parseAtom) + var parseExpression = makeBinaryOpParser('OR', parseAnd) + + var node = parseExpression() + if (!node || hasMore()) { + throw new Error('Syntax error') + } + return node +} diff --git a/node_modules/spdx-correct/node_modules/spdx-expression-parse/scan.js b/node_modules/spdx-correct/node_modules/spdx-expression-parse/scan.js new file mode 100644 index 0000000000000..b74fce2e2c663 --- /dev/null +++ b/node_modules/spdx-correct/node_modules/spdx-expression-parse/scan.js @@ -0,0 +1,131 @@ +'use strict' + +var licenses = [] + .concat(require('spdx-license-ids')) + .concat(require('spdx-license-ids/deprecated')) +var exceptions = require('spdx-exceptions') + +module.exports = function (source) { + var index = 0 + + function hasMore () { + return index < source.length + } + + // `value` can be a regexp or a string. + // If it is recognized, the matching source string is returned and + // the index is incremented. Otherwise `undefined` is returned. + function read (value) { + if (value instanceof RegExp) { + var chars = source.slice(index) + var match = chars.match(value) + if (match) { + index += match[0].length + return match[0] + } + } else { + if (source.indexOf(value, index) === index) { + index += value.length + return value + } + } + } + + function skipWhitespace () { + read(/[ ]*/) + } + + function operator () { + var string + var possibilities = ['WITH', 'AND', 'OR', '(', ')', ':', '+'] + for (var i = 0; i < possibilities.length; i++) { + string = read(possibilities[i]) + if (string) { + break + } + } + + if (string === '+' && index > 1 && source[index - 2] === ' ') { + throw new Error('Space before `+`') + } + + return string && { + type: 'OPERATOR', + string: string + } + } + + function idstring () { + return read(/[A-Za-z0-9-.]+/) + } + + function expectIdstring () { + var string = idstring() + if (!string) { + throw new Error('Expected idstring at offset ' + index) + } + return string + } + + function documentRef () { + if (read('DocumentRef-')) { + var string = expectIdstring() + return { type: 'DOCUMENTREF', string: string } + } + } + + function licenseRef () { + if (read('LicenseRef-')) { + var string = expectIdstring() + return { type: 'LICENSEREF', string: string } + } + } + + function identifier () { + var begin = index + var string = idstring() + + if (licenses.indexOf(string) !== -1) { + return { + type: 'LICENSE', + string: string + } + } else if (exceptions.indexOf(string) !== -1) { + return { + type: 'EXCEPTION', + string: string + } + } + + index = begin + } + + // Tries to read the next token. Returns `undefined` if no token is + // recognized. + function parseToken () { + // Ordering matters + return ( + operator() || + documentRef() || + licenseRef() || + identifier() + ) + } + + var tokens = [] + while (hasMore()) { + skipWhitespace() + if (!hasMore()) { + break + } + + var token = parseToken() + if (!token) { + throw new Error('Unexpected `' + source[index] + + '` at offset ' + index) + } + + tokens.push(token) + } + return tokens +} diff --git a/node_modules/spdx-correct/package.json b/node_modules/spdx-correct/package.json index 35c68bdaa6c61..d77615638be66 100644 --- a/node_modules/spdx-correct/package.json +++ b/node_modules/spdx-correct/package.json @@ -1,24 +1,17 @@ { "name": "spdx-correct", "description": "correct invalid SPDX expressions", - "version": "3.1.1", - "author": "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com)", - "contributors": [ - "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com)", - "Christian Zommerfelds <aero_super@yahoo.com>", - "Tal Einat <taleinat@gmail.com>", - "Dan Butvinik <butvinik@outlook.com>" - ], + "version": "3.2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" }, "devDependencies": { - "defence-cli": "^2.0.1", + "defence-cli": "^3.0.1", "replace-require-self": "^1.0.0", - "standard": "^11.0.0", - "standard-markdown": "^4.0.2", - "tape": "^4.9.0" + "standard": "^14.3.4", + "standard-markdown": "^6.0.0", + "tape": "^5.0.1" }, "files": [ "index.js" diff --git a/node_modules/spdx-exceptions/deprecated.json b/node_modules/spdx-exceptions/deprecated.json new file mode 100644 index 0000000000000..cba7e2badb14e --- /dev/null +++ b/node_modules/spdx-exceptions/deprecated.json @@ -0,0 +1,3 @@ +[ + "Nokia-Qt-exception-1.1" +] diff --git a/node_modules/spdx-exceptions/index.json b/node_modules/spdx-exceptions/index.json index f88f088ab2fa1..d9549d3e40e4e 100644 --- a/node_modules/spdx-exceptions/index.json +++ b/node_modules/spdx-exceptions/index.json @@ -1,40 +1,68 @@ [ "389-exception", + "Asterisk-exception", "Autoconf-exception-2.0", "Autoconf-exception-3.0", + "Autoconf-exception-generic", + "Autoconf-exception-generic-3.0", + "Autoconf-exception-macro", + "Bison-exception-1.24", "Bison-exception-2.2", "Bootloader-exception", "Classpath-exception-2.0", "CLISP-exception-2.0", + "cryptsetup-OpenSSL-exception", "DigiRule-FOSS-exception", "eCos-exception-2.0", "Fawkes-Runtime-exception", "FLTK-exception", + "fmt-exception", "Font-exception-2.0", "freertos-exception-2.0", "GCC-exception-2.0", + "GCC-exception-2.0-note", "GCC-exception-3.1", + "Gmsh-exception", + "GNAT-exception", + "GNOME-examples-exception", + "GNU-compiler-exception", "gnu-javamail-exception", + "GPL-3.0-interface-exception", "GPL-3.0-linking-exception", "GPL-3.0-linking-source-exception", "GPL-CC-1.0", + "GStreamer-exception-2005", + "GStreamer-exception-2008", "i2p-gpl-java-exception", + "KiCad-libraries-exception", + "LGPL-3.0-linking-exception", + "libpri-OpenH323-exception", "Libtool-exception", "Linux-syscall-note", + "LLGPL", "LLVM-exception", "LZMA-exception", "mif-exception", - "Nokia-Qt-exception-1.1", "OCaml-LGPL-linking-exception", "OCCT-exception-1.0", "OpenJDK-assembly-exception-1.0", "openvpn-openssl-exception", "PS-or-PDF-font-exception-20170817", + "QPL-1.0-INRIA-2004-exception", "Qt-GPL-exception-1.0", "Qt-LGPL-exception-1.1", "Qwt-exception-1.0", + "SANE-exception", + "SHL-2.0", + "SHL-2.1", + "stunnel-exception", + "SWI-exception", "Swift-exception", + "Texinfo-exception", "u-boot-exception-2.0", + "UBDL-exception", "Universal-FOSS-exception-1.0", - "WxWindows-exception-3.1" + "vsftpd-openssl-exception", + "WxWindows-exception-3.1", + "x11vnc-openssl-exception" ] diff --git a/node_modules/spdx-exceptions/package.json b/node_modules/spdx-exceptions/package.json index 2bafc6a38b243..2f9a9504b2cac 100644 --- a/node_modules/spdx-exceptions/package.json +++ b/node_modules/spdx-exceptions/package.json @@ -1,7 +1,7 @@ { "name": "spdx-exceptions", "description": "list of SPDX standard license exceptions", - "version": "2.3.0", + "version": "2.5.0", "author": "The Linux Foundation", "contributors": [ "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com/)" @@ -9,9 +9,11 @@ "license": "CC-BY-3.0", "repository": "kemitchell/spdx-exceptions.json", "files": [ - "index.json" + "index.json", + "deprecated.json" ], "scripts": { - "build": "node build.js" + "build": "node build.js", + "latest": "node latest.js" } } diff --git a/node_modules/spdx-expression-parse/package.json b/node_modules/spdx-expression-parse/package.json index c9edc9f939cdf..c3a22afcf7dfc 100644 --- a/node_modules/spdx-expression-parse/package.json +++ b/node_modules/spdx-expression-parse/package.json @@ -1,7 +1,7 @@ { "name": "spdx-expression-parse", "description": "parse SPDX license expressions", - "version": "3.0.1", + "version": "4.0.0", "author": "Kyle E. Mitchell <kyle@kemitchell.com> (https://kemitchell.com)", "files": [ "AUTHORS", diff --git a/node_modules/spdx-expression-parse/scan.js b/node_modules/spdx-expression-parse/scan.js index b74fce2e2c663..528522282703c 100644 --- a/node_modules/spdx-expression-parse/scan.js +++ b/node_modules/spdx-expression-parse/scan.js @@ -37,7 +37,7 @@ module.exports = function (source) { function operator () { var string - var possibilities = ['WITH', 'AND', 'OR', '(', ')', ':', '+'] + var possibilities = [/^WITH/i, /^AND/i, /^OR/i, '(', ')', ':', '+'] for (var i = 0; i < possibilities.length; i++) { string = read(possibilities[i]) if (string) { @@ -51,7 +51,7 @@ module.exports = function (source) { return string && { type: 'OPERATOR', - string: string + string: string.toUpperCase() } } diff --git a/node_modules/spdx-license-ids/deprecated.json b/node_modules/spdx-license-ids/deprecated.json index c7de09858ff35..4f70a14c7469d 100644 --- a/node_modules/spdx-license-ids/deprecated.json +++ b/node_modules/spdx-license-ids/deprecated.json @@ -19,8 +19,10 @@ "LGPL-2.0", "LGPL-2.1", "LGPL-3.0", + "Net-SNMP", "Nunit", "StandardML-NJ", + "bzip2-1.0.5", "eCos-2.0", "wxWindows" ] diff --git a/node_modules/spdx-license-ids/index.json b/node_modules/spdx-license-ids/index.json index a2f18e40160aa..b09dc98435c9e 100644 --- a/node_modules/spdx-license-ids/index.json +++ b/node_modules/spdx-license-ids/index.json @@ -1,5 +1,6 @@ [ "0BSD", + "3D-Slicer-1.0", "AAL", "ADSL", "AFL-1.1", @@ -11,8 +12,10 @@ "AGPL-1.0-or-later", "AGPL-3.0-only", "AGPL-3.0-or-later", + "AMD-newlib", "AMDPLPA", "AML", + "AML-glslang", "AMPAS", "ANTLR-PD", "ANTLR-PD-fallback", @@ -22,25 +25,38 @@ "APSL-1.1", "APSL-1.2", "APSL-2.0", + "ASWF-Digital-Assets-1.0", + "ASWF-Digital-Assets-1.1", "Abstyles", + "AdaCore-doc", "Adobe-2006", + "Adobe-Display-PostScript", "Adobe-Glyph", + "Adobe-Utopia", "Afmparse", "Aladdin", "Apache-1.0", "Apache-1.1", "Apache-2.0", + "App-s2p", + "Arphic-1999", "Artistic-1.0", "Artistic-1.0-Perl", "Artistic-1.0-cl8", "Artistic-2.0", + "Artistic-dist", + "Aspell-RU", "BSD-1-Clause", "BSD-2-Clause", + "BSD-2-Clause-Darwin", "BSD-2-Clause-Patent", "BSD-2-Clause-Views", + "BSD-2-Clause-first-lines", + "BSD-2-Clause-pkgconf-disclaimer", "BSD-3-Clause", "BSD-3-Clause-Attribution", "BSD-3-Clause-Clear", + "BSD-3-Clause-HP", "BSD-3-Clause-LBNL", "BSD-3-Clause-Modification", "BSD-3-Clause-No-Military-License", @@ -48,20 +64,38 @@ "BSD-3-Clause-No-Nuclear-License-2014", "BSD-3-Clause-No-Nuclear-Warranty", "BSD-3-Clause-Open-MPI", + "BSD-3-Clause-Sun", + "BSD-3-Clause-acpica", + "BSD-3-Clause-flex", "BSD-4-Clause", "BSD-4-Clause-Shortened", "BSD-4-Clause-UC", + "BSD-4.3RENO", + "BSD-4.3TAHOE", + "BSD-Advertising-Acknowledgement", + "BSD-Attribution-HPND-disclaimer", + "BSD-Inferno-Nettverk", "BSD-Protection", "BSD-Source-Code", + "BSD-Source-beginning-file", + "BSD-Systemics", + "BSD-Systemics-W3Works", "BSL-1.0", "BUSL-1.1", + "Baekmuk", "Bahyph", "Barr", "Beerware", "BitTorrent-1.0", "BitTorrent-1.1", + "Bitstream-Charter", + "Bitstream-Vera", "BlueOak-1.0.0", + "Boehm-GC", + "Boehm-GC-without-fee", "Borceux", + "Brian-Gladman-2-Clause", + "Brian-Gladman-3-Clause", "C-UDA-1.0", "CAL-1.0", "CAL-1.0-Combined-Work-Exception", @@ -72,7 +106,9 @@ "CC-BY-2.5-AU", "CC-BY-3.0", "CC-BY-3.0-AT", + "CC-BY-3.0-AU", "CC-BY-3.0-DE", + "CC-BY-3.0-IGO", "CC-BY-3.0-NL", "CC-BY-3.0-US", "CC-BY-4.0", @@ -91,6 +127,7 @@ "CC-BY-NC-ND-4.0", "CC-BY-NC-SA-1.0", "CC-BY-NC-SA-2.0", + "CC-BY-NC-SA-2.0-DE", "CC-BY-NC-SA-2.0-FR", "CC-BY-NC-SA-2.0-UK", "CC-BY-NC-SA-2.5", @@ -112,8 +149,11 @@ "CC-BY-SA-3.0", "CC-BY-SA-3.0-AT", "CC-BY-SA-3.0-DE", + "CC-BY-SA-3.0-IGO", "CC-BY-SA-4.0", "CC-PDDC", + "CC-PDM-1.0", + "CC-SA-1.0", "CC0-1.0", "CDDL-1.0", "CDDL-1.1", @@ -132,6 +172,9 @@ "CERN-OHL-P-2.0", "CERN-OHL-S-2.0", "CERN-OHL-W-2.0", + "CFITSIO", + "CMU-Mach", + "CMU-Mach-nodoc", "CNRI-Jython", "CNRI-Python", "CNRI-Python-GPL-Compatible", @@ -141,16 +184,30 @@ "CPOL-1.02", "CUA-OPL-1.0", "Caldera", + "Caldera-no-preamble", + "Catharon", "ClArtistic", + "Clips", "Community-Spec-1.0", "Condor-1.1", + "Cornell-Lossless-JPEG", + "Cronyx", "Crossword", + "CryptoSwift", "CrystalStacker", "Cube", "D-FSL-1.0", + "DEC-3-Clause", + "DL-DE-BY-2.0", + "DL-DE-ZERO-2.0", "DOC", "DRL-1.0", + "DRL-1.1", "DSDP", + "DocBook-DTD", + "DocBook-Schema", + "DocBook-Stylesheet", + "DocBook-XML", "Dotseqn", "ECL-1.0", "ECL-2.0", @@ -163,18 +220,28 @@ "EUPL-1.0", "EUPL-1.1", "EUPL-1.2", + "Elastic-2.0", "Entessa", "ErlPL-1.1", "Eurosym", + "FBM", "FDK-AAC", "FSFAP", + "FSFAP-no-warranty-disclaimer", "FSFUL", "FSFULLR", + "FSFULLRSD", + "FSFULLRWD", + "FSL-1.1-ALv2", + "FSL-1.1-MIT", "FTL", "Fair", + "Ferguson-Twofish", "Frameworx-1.0", "FreeBSD-DOC", "FreeImage", + "Furuseth", + "GCR-docs", "GD", "GFDL-1.1-invariants-only", "GFDL-1.1-invariants-or-later", @@ -202,29 +269,68 @@ "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later", + "Game-Programming-Gems", "Giftware", "Glide", "Glulxe", + "Graphics-Gems", + "Gutmann", + "HDF5", + "HIDAPI", + "HP-1986", + "HP-1989", "HPND", + "HPND-DEC", + "HPND-Fenneberg-Livingston", + "HPND-INRIA-IMAG", + "HPND-Intel", + "HPND-Kevlin-Henney", + "HPND-MIT-disclaimer", + "HPND-Markus-Kuhn", + "HPND-Netrek", + "HPND-Pbmplus", + "HPND-UC", + "HPND-UC-export-US", + "HPND-doc", + "HPND-doc-sell", + "HPND-export-US", + "HPND-export-US-acknowledgement", + "HPND-export-US-modify", + "HPND-export2-US", + "HPND-merchantability-variant", + "HPND-sell-MIT-disclaimer-xserver", + "HPND-sell-regexpr", "HPND-sell-variant", + "HPND-sell-variant-MIT-disclaimer", + "HPND-sell-variant-MIT-disclaimer-rev", "HTMLTIDY", "HaskellReport", "Hippocratic-2.1", "IBM-pibs", "ICU", + "IEC-Code-Components-EULA", "IJG", + "IJG-short", "IPA", "IPL-1.0", "ISC", + "ISC-Veillard", "ImageMagick", "Imlib2", "Info-ZIP", + "Inner-Net-2.0", + "InnoSetup", "Intel", "Intel-ACPI", "Interbase-1.0", + "JPL-image", "JPNIC", "JSON", + "Jam", "JasPer-2.0", + "Kastrup", + "Kazlib", + "Knuth-CTAN", "LAL-1.2", "LAL-1.3", "LGPL-2.0-only", @@ -234,6 +340,8 @@ "LGPL-3.0-only", "LGPL-3.0-or-later", "LGPLLR", + "LOOP", + "LPD-document", "LPL-1.0", "LPL-1.02", "LPPL-1.0", @@ -241,31 +349,52 @@ "LPPL-1.2", "LPPL-1.3a", "LPPL-1.3c", + "LZMA-SDK-9.11-to-9.20", + "LZMA-SDK-9.22", "Latex2e", + "Latex2e-translated-notice", "Leptonica", "LiLiQ-P-1.1", "LiLiQ-R-1.1", "LiLiQ-Rplus-1.1", "Libpng", "Linux-OpenIB", + "Linux-man-pages-1-para", "Linux-man-pages-copyleft", + "Linux-man-pages-copyleft-2-para", + "Linux-man-pages-copyleft-var", + "Lucida-Bitmap-Fonts", + "MIPS", "MIT", "MIT-0", "MIT-CMU", + "MIT-Click", + "MIT-Festival", + "MIT-Khronos-old", "MIT-Modern-Variant", + "MIT-Wu", "MIT-advertising", "MIT-enna", "MIT-feh", "MIT-open-group", + "MIT-testregex", "MITNFA", + "MMIXware", + "MPEG-SSG", "MPL-1.0", "MPL-1.1", "MPL-2.0", "MPL-2.0-no-copyleft-exception", + "MS-LPL", "MS-PL", "MS-RL", "MTLL", + "Mackerras-3-Clause", + "Mackerras-3-Clause-acknowledgment", "MakeIndex", + "Martin-Birgmeier", + "McPhee-slideshow", + "Minpack", "MirOS", "Motosoto", "MulanPSL-1.0", @@ -275,11 +404,15 @@ "NAIST-2003", "NASA-1.3", "NBPL-1.0", + "NCBI-PD", "NCGL-UK-2.0", + "NCL", "NCSA", "NGPL", + "NICTA-1.0", "NIST-PD", "NIST-PD-fallback", + "NIST-Software", "NLOD-1.0", "NLOD-2.0", "NLPL", @@ -288,19 +421,21 @@ "NPL-1.1", "NPOSL-3.0", "NRL", + "NTIA-PD", "NTP", "NTP-0", "Naumen", - "Net-SNMP", "NetCDF", "Newsletr", "Nokia", "Noweb", "O-UDA-1.0", + "OAR", "OCCT-PL", "OCLC-2.0", "ODC-By-1.0", "ODbL-1.0", + "OFFIS", "OFL-1.0", "OFL-1.0-RFN", "OFL-1.0-no-RFN", @@ -330,8 +465,10 @@ "OLDAP-2.6", "OLDAP-2.7", "OLDAP-2.8", + "OLFL-1.3", "OML", "OPL-1.0", + "OPL-UK-3.0", "OPUBL-1.0", "OSET-PL-2.1", "OSL-1.0", @@ -339,19 +476,27 @@ "OSL-2.0", "OSL-2.1", "OSL-3.0", + "OpenPBS-2.3", "OpenSSL", + "OpenSSL-standalone", + "OpenVision", + "PADL", "PDDL-1.0", "PHP-3.0", "PHP-3.01", + "PPL", "PSF-2.0", "Parity-6.0.0", "Parity-7.0.0", + "Pixar", "Plexus", "PolyForm-Noncommercial-1.0.0", "PolyForm-Small-Business-1.0.0", "PostgreSQL", "Python-2.0", + "Python-2.0.1", "QPL-1.0", + "QPL-1.0-INRIA-2004", "Qhull", "RHeCos-1.1", "RPL-1.1", @@ -361,46 +506,78 @@ "RSCPL", "Rdisc", "Ruby", + "Ruby-pty", "SAX-PD", + "SAX-PD-2.0", "SCEA", "SGI-B-1.0", "SGI-B-1.1", "SGI-B-2.0", + "SGI-OpenGL", + "SGP4", "SHL-0.5", "SHL-0.51", "SISSL", "SISSL-1.2", + "SL", + "SMAIL-GPL", "SMLNJ", "SMPPL", "SNIA", + "SOFA", "SPL-1.0", "SSH-OpenSSH", "SSH-short", + "SSLeay-standalone", "SSPL-1.0", + "SUL-1.0", "SWL", "Saxpath", + "SchemeReport", "Sendmail", "Sendmail-8.23", + "Sendmail-Open-Source-1.1", "SimPL-2.0", "Sleepycat", + "Soundex", "Spencer-86", "Spencer-94", "Spencer-99", "SugarCRM-1.1.3", + "Sun-PPP", + "Sun-PPP-2000", + "SunPro", + "Symlinks", "TAPR-OHL-1.0", "TCL", "TCP-wrappers", + "TGPPL-1.0", "TMate", "TORQUE-1.1", "TOSL", + "TPDL", + "TPL-1.0", + "TTWL", + "TTYP0", "TU-Berlin-1.0", "TU-Berlin-2.0", + "TermReadKey", + "ThirdEye", + "TrustedQSL", + "UCAR", "UCL-1.0", + "UMich-Merit", "UPL-1.0", + "URT-RLE", + "Ubuntu-font-1.0", + "Unicode-3.0", "Unicode-DFS-2015", "Unicode-DFS-2016", "Unicode-TOU", + "UnixCrypt", "Unlicense", + "Unlicense-libtelnet", + "Unlicense-libwhirlpool", "VOSTROM", "VSL-1.0", "Vim", @@ -409,11 +586,16 @@ "W3C-20150513", "WTFPL", "Watcom-1.0", + "Widget-Workshop", "Wsuipa", "X11", + "X11-distribute-modifications-variant", + "X11-swapped", "XFree86-1.1", "XSkat", + "Xdebug-1.03", "Xerox", + "Xfig", "Xnet", "YPL-1.0", "YPL-1.1", @@ -421,30 +603,67 @@ "ZPL-2.0", "ZPL-2.1", "Zed", + "Zeeff", "Zend-2.0", "Zimbra-1.3", "Zimbra-1.4", "Zlib", + "any-OSI", + "any-OSI-perl-modules", + "bcrypt-Solar-Designer", "blessing", - "bzip2-1.0.5", "bzip2-1.0.6", + "check-cvs", + "checkmk", "copyleft-next-0.3.0", "copyleft-next-0.3.1", "curl", + "cve-tou", "diffmark", + "dtoa", "dvipdfm", "eGenix", "etalab-2.0", + "fwlw", "gSOAP-1.3b", + "generic-xts", "gnuplot", + "gtkbook", + "hdparm", "iMatix", + "jove", + "libpng-1.6.35", "libpng-2.0", "libselinux-1.0", "libtiff", + "libutil-David-Nugent", + "lsof", + "magaz", + "mailprio", + "man2html", + "metamail", + "mpi-permissive", "mpich2", + "mplus", + "ngrep", + "pkgconf", + "pnmstitch", "psfrag", "psutils", + "python-ldap", + "radvd", + "snprintf", + "softSurfer", + "ssh-keyscan", + "swrule", + "threeparttable", + "ulem", + "w3m", + "wwl", "xinetd", + "xkeyboard-config-Zinoviev", + "xlock", "xpp", + "xzoom", "zlib-acknowledgement" ] diff --git a/node_modules/spdx-license-ids/package.json b/node_modules/spdx-license-ids/package.json index 61b10edc24ceb..201e888cecfaa 100644 --- a/node_modules/spdx-license-ids/package.json +++ b/node_modules/spdx-license-ids/package.json @@ -1,14 +1,14 @@ { "name": "spdx-license-ids", - "version": "3.0.11", + "version": "3.0.22", "description": "A list of SPDX license identifiers", "repository": "jslicense/spdx-license-ids", "author": "Shinnosuke Watanabe (https://github.com/shinnn)", "license": "CC0-1.0", "scripts": { "build": "node build.js", - "pretest": "eslint .", "latest": "node latest.js", + "pretest": "npm run build", "test": "node test.js" }, "files": [ @@ -25,15 +25,5 @@ "json", "array", "oss" - ], - "devDependencies": { - "@shinnn/eslint-config": "^7.0.0", - "eslint": "^8.2.0", - "eslint-formatter-codeframe": "^7.32.1", - "rmfr": "^2.0.0", - "tape": "^5.3.1" - }, - "eslintConfig": { - "extends": "@shinnn" - } + ] } diff --git a/node_modules/ssri/lib/index.js b/node_modules/ssri/lib/index.js index 1443137cbc708..9acc432261248 100644 --- a/node_modules/ssri/lib/index.js +++ b/node_modules/ssri/lib/index.js @@ -1,83 +1,76 @@ 'use strict' const crypto = require('crypto') -const MiniPass = require('minipass') +const { Minipass } = require('minipass') -const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512'] +const SPEC_ALGORITHMS = ['sha512', 'sha384', 'sha256'] +const DEFAULT_ALGORITHMS = ['sha512'] // TODO: this should really be a hardcoded list of algorithms we support, // rather than [a-z0-9]. const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i -const SRI_REGEX = /^([a-z0-9]+)-([^?]+)([?\S*]*)$/ +const SRI_REGEX = /^([a-z0-9]+)-([^?]+)(\?[?\S*]*)?$/ const STRICT_SRI_REGEX = /^([a-z0-9]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)?$/ const VCHAR_REGEX = /^[\x21-\x7E]+$/ -const defaultOpts = { - algorithms: ['sha512'], - error: false, - options: [], - pickAlgorithm: getPrioritizedHash, - sep: ' ', - single: false, - strict: false, -} - -const ssriOpts = (opts = {}) => ({ ...defaultOpts, ...opts }) +const getOptString = options => options?.length ? `?${options.join('?')}` : '' -const getOptString = options => !options || !options.length - ? '' - : `?${options.join('?')}` +class IntegrityStream extends Minipass { + #emittedIntegrity + #emittedSize + #emittedVerified -const _onEnd = Symbol('_onEnd') -const _getOptions = Symbol('_getOptions') -const _emittedSize = Symbol('_emittedSize') -const _emittedIntegrity = Symbol('_emittedIntegrity') -const _emittedVerified = Symbol('_emittedVerified') - -class IntegrityStream extends MiniPass { constructor (opts) { super() this.size = 0 this.opts = opts // may be overridden later, but set now for class consistency - this[_getOptions]() + this.#getOptions() // options used for calculating stream. can't be changed. - const { algorithms = defaultOpts.algorithms } = opts - this.algorithms = Array.from( - new Set(algorithms.concat(this.algorithm ? [this.algorithm] : [])) - ) + if (opts?.algorithms) { + this.algorithms = [...opts.algorithms] + } else { + this.algorithms = [...DEFAULT_ALGORITHMS] + } + if (this.algorithm !== null && !this.algorithms.includes(this.algorithm)) { + this.algorithms.push(this.algorithm) + } + this.hashes = this.algorithms.map(crypto.createHash) } - [_getOptions] () { - const { - integrity, - size, - options, - } = { ...defaultOpts, ...this.opts } - + #getOptions () { // For verification - this.sri = integrity ? parse(integrity, this.opts) : null - this.expectedSize = size - this.goodSri = this.sri ? !!Object.keys(this.sri).length : false - this.algorithm = this.goodSri ? this.sri.pickAlgorithm(this.opts) : null + this.sri = this.opts?.integrity ? parse(this.opts?.integrity, this.opts) : null + this.expectedSize = this.opts?.size + + if (!this.sri) { + this.algorithm = null + } else if (this.sri.isHash) { + this.goodSri = true + this.algorithm = this.sri.algorithm + } else { + this.goodSri = !this.sri.isEmpty() + this.algorithm = this.sri.pickAlgorithm(this.opts) + } + this.digests = this.goodSri ? this.sri[this.algorithm] : null - this.optString = getOptString(options) + this.optString = getOptString(this.opts?.options) } on (ev, handler) { - if (ev === 'size' && this[_emittedSize]) { - return handler(this[_emittedSize]) + if (ev === 'size' && this.#emittedSize) { + return handler(this.#emittedSize) } - if (ev === 'integrity' && this[_emittedIntegrity]) { - return handler(this[_emittedIntegrity]) + if (ev === 'integrity' && this.#emittedIntegrity) { + return handler(this.#emittedIntegrity) } - if (ev === 'verified' && this[_emittedVerified]) { - return handler(this[_emittedVerified]) + if (ev === 'verified' && this.#emittedVerified) { + return handler(this.#emittedVerified) } return super.on(ev, handler) @@ -85,7 +78,7 @@ class IntegrityStream extends MiniPass { emit (ev, data) { if (ev === 'end') { - this[_onEnd]() + this.#onEnd() } return super.emit(ev, data) } @@ -96,9 +89,9 @@ class IntegrityStream extends MiniPass { return super.write(data) } - [_onEnd] () { + #onEnd () { if (!this.goodSri) { - this[_getOptions]() + this.#getOptions() } const newSri = parse(this.hashes.map((h, i) => { return `${this.algorithms[i]}-${h.digest('base64')}${this.optString}` @@ -123,12 +116,12 @@ class IntegrityStream extends MiniPass { err.sri = this.sri this.emit('error', err) } else { - this[_emittedSize] = this.size + this.#emittedSize = this.size this.emit('size', this.size) - this[_emittedIntegrity] = newSri + this.#emittedIntegrity = newSri this.emit('integrity', newSri) if (match) { - this[_emittedVerified] = match + this.#emittedVerified = match this.emit('verified', match) } } @@ -141,8 +134,7 @@ class Hash { } constructor (hash, opts) { - opts = ssriOpts(opts) - const strict = !!opts.strict + const strict = opts?.strict this.source = hash.trim() // set default values so that we make V8 happy to @@ -161,7 +153,7 @@ class Hash { if (!match) { return } - if (strict && !SPEC_ALGORITHMS.some(a => a === match[1])) { + if (strict && !SPEC_ALGORITHMS.includes(match[1])) { return } this.algorithm = match[1] @@ -181,15 +173,37 @@ class Hash { return this.toString() } + match (integrity, opts) { + const other = parse(integrity, opts) + if (!other) { + return false + } + if (other.isIntegrity) { + const algo = other.pickAlgorithm(opts, [this.algorithm]) + + if (!algo) { + return false + } + + const foundHash = other[algo].find(hash => hash.digest === this.digest) + + if (foundHash) { + return foundHash + } + + return false + } + return other.digest === this.digest ? other : false + } + toString (opts) { - opts = ssriOpts(opts) - if (opts.strict) { + if (opts?.strict) { // Strict mode enforces the standard as close to the foot of the // letter as it can. if (!( // The spec has very restricted productions for algorithms. // https://www.w3.org/TR/CSP2/#source-list-syntax - SPEC_ALGORITHMS.some(x => x === this.algorithm) && + SPEC_ALGORITHMS.includes(this.algorithm) && // Usually, if someone insists on using a "different" base64, we // leave it as-is, since there's multiple standards, and the // specified is not a URL-safe variant. @@ -203,13 +217,43 @@ class Hash { return '' } } - const options = this.options && this.options.length - ? `?${this.options.join('?')}` - : '' - return `${this.algorithm}-${this.digest}${options}` + return `${this.algorithm}-${this.digest}${getOptString(this.options)}` } } +function integrityHashToString (toString, sep, opts, hashes) { + const toStringIsNotEmpty = toString !== '' + + let shouldAddFirstSep = false + let complement = '' + + const lastIndex = hashes.length - 1 + + for (let i = 0; i < lastIndex; i++) { + const hashString = Hash.prototype.toString.call(hashes[i], opts) + + if (hashString) { + shouldAddFirstSep = true + + complement += hashString + complement += sep + } + } + + const finalHashString = Hash.prototype.toString.call(hashes[lastIndex], opts) + + if (finalHashString) { + shouldAddFirstSep = true + complement += finalHashString + } + + if (toStringIsNotEmpty && shouldAddFirstSep) { + return toString + sep + complement + } + + return toString + complement +} + class Integrity { get isIntegrity () { return true @@ -224,21 +268,28 @@ class Integrity { } toString (opts) { - opts = ssriOpts(opts) - let sep = opts.sep || ' ' - if (opts.strict) { + let sep = opts?.sep || ' ' + let toString = '' + + if (opts?.strict) { // Entries must be separated by whitespace, according to spec. sep = sep.replace(/\S+/g, ' ') + + for (const hash of SPEC_ALGORITHMS) { + if (this[hash]) { + toString = integrityHashToString(toString, sep, opts, this[hash]) + } + } + } else { + for (const hash of Object.keys(this)) { + toString = integrityHashToString(toString, sep, opts, this[hash]) + } } - return Object.keys(this).map(k => { - return this[k].map(hash => { - return Hash.prototype.toString.call(hash, opts) - }).filter(x => x.length).join(sep) - }).filter(x => x.length).join(sep) + + return toString } concat (integrity, opts) { - opts = ssriOpts(opts) const other = typeof integrity === 'string' ? integrity : stringify(integrity, opts) @@ -252,7 +303,6 @@ class Integrity { // add additional hashes to an integrity value, but prevent // *changing* an existing integrity hash. merge (integrity, opts) { - opts = ssriOpts(opts) const other = parse(integrity, opts) for (const algo in other) { if (this[algo]) { @@ -268,10 +318,13 @@ class Integrity { } match (integrity, opts) { - opts = ssriOpts(opts) const other = parse(integrity, opts) - const algo = other.pickAlgorithm(opts) + if (!other) { + return false + } + const algo = other.pickAlgorithm(opts, Object.keys(this)) return ( + !!algo && this[algo] && other[algo] && this[algo].find(hash => @@ -282,13 +335,22 @@ class Integrity { ) || false } - pickAlgorithm (opts) { - opts = ssriOpts(opts) - const pickAlgorithm = opts.pickAlgorithm - const keys = Object.keys(this) - return keys.reduce((acc, algo) => { - return pickAlgorithm(acc, algo) || acc + // Pick the highest priority algorithm present, optionally also limited to a + // set of hashes found in another integrity. When limiting it may return + // nothing. + pickAlgorithm (opts, hashes) { + const pickAlgorithm = opts?.pickAlgorithm || getPrioritizedHash + const keys = Object.keys(this).filter(k => { + if (hashes?.length) { + return hashes.includes(k) + } + return true }) + if (keys.length) { + return keys.reduce((acc, algo) => pickAlgorithm(acc, algo) || acc) + } + // no intersection between this and hashes, + return null } } @@ -297,7 +359,6 @@ function parse (sri, opts) { if (!sri) { return null } - opts = ssriOpts(opts) if (typeof sri === 'string') { return _parse(sri, opts) } else if (sri.algorithm && sri.digest) { @@ -312,7 +373,7 @@ function parse (sri, opts) { function _parse (integrity, opts) { // 3.4.3. Parse metadata // https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata - if (opts.single) { + if (opts?.single) { return new Hash(integrity, opts) } const hashes = integrity.trim().split(/\s+/).reduce((acc, string) => { @@ -331,7 +392,6 @@ function _parse (integrity, opts) { module.exports.stringify = stringify function stringify (obj, opts) { - opts = ssriOpts(opts) if (obj.algorithm && obj.digest) { return Hash.prototype.toString.call(obj, opts) } else if (typeof obj === 'string') { @@ -343,8 +403,7 @@ function stringify (obj, opts) { module.exports.fromHex = fromHex function fromHex (hexDigest, algorithm, opts) { - opts = ssriOpts(opts) - const optString = getOptString(opts.options) + const optString = getOptString(opts?.options) return parse( `${algorithm}-${ Buffer.from(hexDigest, 'hex').toString('base64') @@ -354,9 +413,8 @@ function fromHex (hexDigest, algorithm, opts) { module.exports.fromData = fromData function fromData (data, opts) { - opts = ssriOpts(opts) - const algorithms = opts.algorithms - const optString = getOptString(opts.options) + const algorithms = opts?.algorithms || [...DEFAULT_ALGORITHMS] + const optString = getOptString(opts?.options) return algorithms.reduce((acc, algo) => { const digest = crypto.createHash(algo).update(data).digest('base64') const hash = new Hash( @@ -379,7 +437,6 @@ function fromData (data, opts) { module.exports.fromStream = fromStream function fromStream (stream, opts) { - opts = ssriOpts(opts) const istream = integrityStream(opts) return new Promise((resolve, reject) => { stream.pipe(istream) @@ -390,16 +447,15 @@ function fromStream (stream, opts) { sri = s }) istream.on('end', () => resolve(sri)) - istream.on('data', () => {}) + istream.resume() }) } module.exports.checkData = checkData function checkData (data, sri, opts) { - opts = ssriOpts(opts) sri = parse(sri, opts) if (!sri || !Object.keys(sri).length) { - if (opts.error) { + if (opts?.error) { throw Object.assign( new Error('No valid integrity hashes to check against'), { code: 'EINTEGRITY', @@ -413,7 +469,8 @@ function checkData (data, sri, opts) { const digest = crypto.createHash(algorithm).update(data).digest('base64') const newSri = parse({ algorithm, digest }) const match = newSri.match(sri, opts) - if (match || !opts.error) { + opts = opts || {} + if (match || !(opts.error)) { return match } else if (typeof opts.size === 'number' && (data.length !== opts.size)) { /* eslint-disable-next-line max-len */ @@ -437,7 +494,7 @@ function checkData (data, sri, opts) { module.exports.checkStream = checkStream function checkStream (stream, sri, opts) { - opts = ssriOpts(opts) + opts = opts || Object.create(null) opts.integrity = sri sri = parse(sri, opts) if (!sri || !Object.keys(sri).length) { @@ -457,20 +514,19 @@ function checkStream (stream, sri, opts) { verified = s }) checker.on('end', () => resolve(verified)) - checker.on('data', () => {}) + checker.resume() }) } module.exports.integrityStream = integrityStream -function integrityStream (opts = {}) { +function integrityStream (opts = Object.create(null)) { return new IntegrityStream(opts) } module.exports.create = createIntegrity function createIntegrity (opts) { - opts = ssriOpts(opts) - const algorithms = opts.algorithms - const optString = getOptString(opts.options) + const algorithms = opts?.algorithms || [...DEFAULT_ALGORITHMS] + const optString = getOptString(opts?.options) const hashes = algorithms.map(crypto.createHash) @@ -479,7 +535,7 @@ function createIntegrity (opts) { hashes.forEach(h => h.update(chunk, enc)) return this }, - digest: function (enc) { + digest: function () { const integrity = algorithms.reduce((acc, algo) => { const digest = hashes.shift().digest('base64') const hash = new Hash( @@ -504,7 +560,7 @@ function createIntegrity (opts) { } } -const NODE_HASHES = new Set(crypto.getHashes()) +const NODE_HASHES = crypto.getHashes() // This is a Best Effort™ at a reasonable priority for hash algos const DEFAULT_PRIORITY = [ @@ -514,7 +570,7 @@ const DEFAULT_PRIORITY = [ 'sha3', 'sha3-256', 'sha3-384', 'sha3-512', 'sha3_256', 'sha3_384', 'sha3_512', -].filter(algo => NODE_HASHES.has(algo)) +].filter(algo => NODE_HASHES.includes(algo)) function getPrioritizedHash (algo1, algo2) { /* eslint-disable-next-line max-len */ diff --git a/node_modules/ssri/package.json b/node_modules/ssri/package.json index 91c1f919788cd..8781bdf5f80c0 100644 --- a/node_modules/ssri/package.json +++ b/node_modules/ssri/package.json @@ -1,6 +1,6 @@ { "name": "ssri", - "version": "9.0.1", + "version": "13.0.0", "description": "Standard Subresource Integrity library -- parses, serializes, generates, and verifies integrity metadata according to the SRI spec.", "main": "lib/index.js", "files": [ @@ -10,24 +10,26 @@ "scripts": { "prerelease": "npm t", "postrelease": "npm publish", - "prepublishOnly": "git push origin --follow-tags", "posttest": "npm run lint", "test": "tap", "coverage": "tap", - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "npm publish", - "snap": "tap" + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "repository": { "type": "git", - "url": "https://github.com/npm/ssri.git" + "url": "git+https://github.com/npm/ssri.git" }, "keywords": [ "w3c", @@ -46,18 +48,19 @@ "author": "GitHub Inc.", "license": "ISC", "dependencies": { - "minipass": "^3.1.1" + "minipass": "^7.0.3" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", "tap": "^16.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0" + "version": "4.27.1", + "publish": "true" } } diff --git a/node_modules/string-width/index.d.ts b/node_modules/string-width/index.d.ts deleted file mode 100644 index 12b5309751dd5..0000000000000 --- a/node_modules/string-width/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -declare const stringWidth: { - /** - Get the visual width of a string - the number of columns required to display it. - - Some Unicode characters are [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) and use double the normal width. [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) are stripped and doesn't affect the width. - - @example - ``` - import stringWidth = require('string-width'); - - stringWidth('a'); - //=> 1 - - stringWidth('古'); - //=> 2 - - stringWidth('\u001B[1m古\u001B[22m'); - //=> 2 - ``` - */ - (string: string): number; - - // TODO: remove this in the next major version, refactor the whole definition to: - // declare function stringWidth(string: string): number; - // export = stringWidth; - default: typeof stringWidth; -} - -export = stringWidth; diff --git a/node_modules/string-width/readme.md b/node_modules/string-width/readme.md deleted file mode 100644 index bdd314129ca74..0000000000000 --- a/node_modules/string-width/readme.md +++ /dev/null @@ -1,50 +0,0 @@ -# string-width - -> Get the visual width of a string - the number of columns required to display it - -Some Unicode characters are [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) and use double the normal width. [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) are stripped and doesn't affect the width. - -Useful to be able to measure the actual width of command-line output. - - -## Install - -``` -$ npm install string-width -``` - - -## Usage - -```js -const stringWidth = require('string-width'); - -stringWidth('a'); -//=> 1 - -stringWidth('古'); -//=> 2 - -stringWidth('\u001B[1m古\u001B[22m'); -//=> 2 -``` - - -## Related - -- [string-width-cli](https://github.com/sindresorhus/string-width-cli) - CLI for this module -- [string-length](https://github.com/sindresorhus/string-length) - Get the real length of a string -- [widest-line](https://github.com/sindresorhus/widest-line) - Get the visual width of the widest line in a string - - ---- - -<div align="center"> - <b> - <a href="https://tidelift.com/subscription/pkg/npm-string-width?utm_source=npm-string-width&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> - </b> - <br> - <sub> - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. - </sub> -</div> diff --git a/node_modules/string_decoder/LICENSE b/node_modules/string_decoder/LICENSE deleted file mode 100644 index 778edb20730ef..0000000000000 --- a/node_modules/string_decoder/LICENSE +++ /dev/null @@ -1,48 +0,0 @@ -Node.js is licensed for use as follows: - -""" -Copyright Node.js contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -""" - -This license applies to parts of Node.js originating from the -https://github.com/joyent/node repository: - -""" -Copyright Joyent, Inc. and other Node contributors. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -""" - diff --git a/node_modules/string_decoder/lib/string_decoder.js b/node_modules/string_decoder/lib/string_decoder.js deleted file mode 100644 index 2e89e63f7933e..0000000000000 --- a/node_modules/string_decoder/lib/string_decoder.js +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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'; - -/*<replacement>*/ - -var Buffer = require('safe-buffer').Buffer; -/*</replacement>*/ - -var isEncoding = Buffer.isEncoding || function (encoding) { - encoding = '' + encoding; - switch (encoding && encoding.toLowerCase()) { - case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': - return true; - default: - return false; - } -}; - -function _normalizeEncoding(enc) { - if (!enc) return 'utf8'; - var retried; - while (true) { - switch (enc) { - case 'utf8': - case 'utf-8': - return 'utf8'; - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return 'utf16le'; - case 'latin1': - case 'binary': - return 'latin1'; - case 'base64': - case 'ascii': - case 'hex': - return enc; - default: - if (retried) return; // undefined - enc = ('' + enc).toLowerCase(); - retried = true; - } - } -}; - -// Do not cache `Buffer.isEncoding` when checking encoding names as some -// modules monkey-patch it to support additional encodings -function normalizeEncoding(enc) { - var nenc = _normalizeEncoding(enc); - if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); - return nenc || enc; -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. -exports.StringDecoder = StringDecoder; -function StringDecoder(encoding) { - this.encoding = normalizeEncoding(encoding); - var nb; - switch (this.encoding) { - case 'utf16le': - this.text = utf16Text; - this.end = utf16End; - nb = 4; - break; - case 'utf8': - this.fillLast = utf8FillLast; - nb = 4; - break; - case 'base64': - this.text = base64Text; - this.end = base64End; - nb = 3; - break; - default: - this.write = simpleWrite; - this.end = simpleEnd; - return; - } - this.lastNeed = 0; - this.lastTotal = 0; - this.lastChar = Buffer.allocUnsafe(nb); -} - -StringDecoder.prototype.write = function (buf) { - if (buf.length === 0) return ''; - var r; - var i; - if (this.lastNeed) { - r = this.fillLast(buf); - if (r === undefined) return ''; - i = this.lastNeed; - this.lastNeed = 0; - } else { - i = 0; - } - if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); - return r || ''; -}; - -StringDecoder.prototype.end = utf8End; - -// Returns only complete characters in a Buffer -StringDecoder.prototype.text = utf8Text; - -// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer -StringDecoder.prototype.fillLast = function (buf) { - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); - this.lastNeed -= buf.length; -}; - -// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a -// continuation byte. If an invalid byte is detected, -2 is returned. -function utf8CheckByte(byte) { - if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; - return byte >> 6 === 0x02 ? -1 : -2; -} - -// Checks at most 3 bytes at the end of a Buffer in order to detect an -// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) -// needed to complete the UTF-8 character (if applicable) are returned. -function utf8CheckIncomplete(self, buf, i) { - var j = buf.length - 1; - if (j < i) return 0; - var nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 1; - return nb; - } - if (--j < i || nb === -2) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 2; - return nb; - } - if (--j < i || nb === -2) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) { - if (nb === 2) nb = 0;else self.lastNeed = nb - 3; - } - return nb; - } - return 0; -} - -// Validates as many continuation bytes for a multi-byte UTF-8 character as -// needed or are available. If we see a non-continuation byte where we expect -// one, we "replace" the validated continuation bytes we've seen so far with -// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding -// behavior. The continuation byte check is included three times in the case -// where all of the continuation bytes for a character exist in the same buffer. -// It is also done this way as a slight performance increase instead of using a -// loop. -function utf8CheckExtraBytes(self, buf, p) { - if ((buf[0] & 0xC0) !== 0x80) { - self.lastNeed = 0; - return '\ufffd'; - } - if (self.lastNeed > 1 && buf.length > 1) { - if ((buf[1] & 0xC0) !== 0x80) { - self.lastNeed = 1; - return '\ufffd'; - } - if (self.lastNeed > 2 && buf.length > 2) { - if ((buf[2] & 0xC0) !== 0x80) { - self.lastNeed = 2; - return '\ufffd'; - } - } - } -} - -// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. -function utf8FillLast(buf) { - var p = this.lastTotal - this.lastNeed; - var r = utf8CheckExtraBytes(this, buf, p); - if (r !== undefined) return r; - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, p, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, p, 0, buf.length); - this.lastNeed -= buf.length; -} - -// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a -// partial character, the character's bytes are buffered until the required -// number of bytes are available. -function utf8Text(buf, i) { - var total = utf8CheckIncomplete(this, buf, i); - if (!this.lastNeed) return buf.toString('utf8', i); - this.lastTotal = total; - var end = buf.length - (total - this.lastNeed); - buf.copy(this.lastChar, 0, end); - return buf.toString('utf8', i, end); -} - -// For UTF-8, a replacement character is added when ending on a partial -// character. -function utf8End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + '\ufffd'; - return r; -} - -// UTF-16LE typically needs two bytes per character, but even if we have an even -// number of bytes available, we need to check if we end on a leading/high -// surrogate. In that case, we need to wait for the next two bytes in order to -// decode the last character properly. -function utf16Text(buf, i) { - if ((buf.length - i) % 2 === 0) { - var r = buf.toString('utf16le', i); - if (r) { - var c = r.charCodeAt(r.length - 1); - if (c >= 0xD800 && c <= 0xDBFF) { - this.lastNeed = 2; - this.lastTotal = 4; - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - return r.slice(0, -1); - } - } - return r; - } - this.lastNeed = 1; - this.lastTotal = 2; - this.lastChar[0] = buf[buf.length - 1]; - return buf.toString('utf16le', i, buf.length - 1); -} - -// For UTF-16LE we do not explicitly append special replacement characters if we -// end on a partial character, we simply let v8 handle that. -function utf16End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) { - var end = this.lastTotal - this.lastNeed; - return r + this.lastChar.toString('utf16le', 0, end); - } - return r; -} - -function base64Text(buf, i) { - var n = (buf.length - i) % 3; - if (n === 0) return buf.toString('base64', i); - this.lastNeed = 3 - n; - this.lastTotal = 3; - if (n === 1) { - this.lastChar[0] = buf[buf.length - 1]; - } else { - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - } - return buf.toString('base64', i, buf.length - n); -} - -function base64End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); - return r; -} - -// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) -function simpleWrite(buf) { - return buf.toString(this.encoding); -} - -function simpleEnd(buf) { - return buf && buf.length ? this.write(buf) : ''; -} \ No newline at end of file diff --git a/node_modules/string_decoder/package.json b/node_modules/string_decoder/package.json deleted file mode 100644 index b2bb141160cad..0000000000000 --- a/node_modules/string_decoder/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "string_decoder", - "version": "1.3.0", - "description": "The string_decoder module from Node core", - "main": "lib/string_decoder.js", - "files": [ - "lib" - ], - "dependencies": { - "safe-buffer": "~5.2.0" - }, - "devDependencies": { - "babel-polyfill": "^6.23.0", - "core-util-is": "^1.0.2", - "inherits": "^2.0.3", - "tap": "~0.4.8" - }, - "scripts": { - "test": "tap test/parallel/*.js && node test/verify-dependencies", - "ci": "tap test/parallel/*.js test/ours/*.js --tap | tee test.tap && node test/verify-dependencies.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/nodejs/string_decoder.git" - }, - "homepage": "https://github.com/nodejs/string_decoder", - "keywords": [ - "string", - "decoder", - "browser", - "browserify" - ], - "license": "MIT" -} diff --git a/node_modules/strip-ansi/index.d.ts b/node_modules/strip-ansi/index.d.ts deleted file mode 100644 index 907fccc29269e..0000000000000 --- a/node_modules/strip-ansi/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** -Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string. - -@example -``` -import stripAnsi = require('strip-ansi'); - -stripAnsi('\u001B[4mUnicorn\u001B[0m'); -//=> 'Unicorn' - -stripAnsi('\u001B]8;;https://github.com\u0007Click\u001B]8;;\u0007'); -//=> 'Click' -``` -*/ -declare function stripAnsi(string: string): string; - -export = stripAnsi; diff --git a/node_modules/strip-ansi/readme.md b/node_modules/strip-ansi/readme.md deleted file mode 100644 index 7c4b56d46ddc7..0000000000000 --- a/node_modules/strip-ansi/readme.md +++ /dev/null @@ -1,46 +0,0 @@ -# strip-ansi [![Build Status](https://travis-ci.org/chalk/strip-ansi.svg?branch=master)](https://travis-ci.org/chalk/strip-ansi) - -> Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string - - -## Install - -``` -$ npm install strip-ansi -``` - - -## Usage - -```js -const stripAnsi = require('strip-ansi'); - -stripAnsi('\u001B[4mUnicorn\u001B[0m'); -//=> 'Unicorn' - -stripAnsi('\u001B]8;;https://github.com\u0007Click\u001B]8;;\u0007'); -//=> 'Click' -``` - - -## strip-ansi for enterprise - -Available as part of the Tidelift Subscription. - -The maintainers of strip-ansi and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-strip-ansi?utm_source=npm-strip-ansi&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - - -## Related - -- [strip-ansi-cli](https://github.com/chalk/strip-ansi-cli) - CLI for this module -- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Streaming version of this module -- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes -- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes -- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right - - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) - diff --git a/node_modules/supports-color/browser.js b/node_modules/supports-color/browser.js index 62afa3a7425dc..f9008d8e71357 100644 --- a/node_modules/supports-color/browser.js +++ b/node_modules/supports-color/browser.js @@ -1,5 +1,35 @@ -'use strict'; -module.exports = { - stdout: false, - stderr: false +/* eslint-env browser */ +/* eslint-disable n/no-unsupported-features/node-builtins */ + +const level = (() => { + if (!('navigator' in globalThis)) { + return 0; + } + + if (globalThis.navigator.userAgentData) { + const brand = navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium'); + if (brand?.version > 93) { + return 3; + } + } + + if (/\b(Chrome|Chromium)\//.test(globalThis.navigator.userAgent)) { + return 1; + } + + return 0; +})(); + +const colorSupport = level !== 0 && { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, }; + +const supportsColor = { + stdout: colorSupport, + stderr: colorSupport, +}; + +export default supportsColor; diff --git a/node_modules/supports-color/index.js b/node_modules/supports-color/index.js index 6fada390fb88d..906a6f9b83224 100644 --- a/node_modules/supports-color/index.js +++ b/node_modules/supports-color/index.js @@ -1,31 +1,59 @@ -'use strict'; -const os = require('os'); -const tty = require('tty'); -const hasFlag = require('has-flag'); +import process from 'node:process'; +import os from 'node:os'; +import tty from 'node:tty'; + +// From: https://github.com/sindresorhus/has-flag/blob/main/index.js +/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) { +function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +} const {env} = process; -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false') || - hasFlag('color=never')) { - forceColor = 0; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = 1; +let flagForceColor; +if ( + hasFlag('no-color') + || hasFlag('no-colors') + || hasFlag('color=false') + || hasFlag('color=never') +) { + flagForceColor = 0; +} else if ( + hasFlag('color') + || hasFlag('colors') + || hasFlag('color=true') + || hasFlag('color=always') +) { + flagForceColor = 1; } -if ('FORCE_COLOR' in env) { +function envForceColor() { + if (!('FORCE_COLOR' in env)) { + return; + } + if (env.FORCE_COLOR === 'true') { - forceColor = 1; - } else if (env.FORCE_COLOR === 'false') { - forceColor = 0; - } else { - forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); + return 1; + } + + if (env.FORCE_COLOR === 'false') { + return 0; + } + + if (env.FORCE_COLOR.length === 0) { + return 1; } + + const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + + if (![0, 1, 2, 3].includes(level)) { + return; + } + + return level; } function translateLevel(level) { @@ -37,23 +65,38 @@ function translateLevel(level) { level, hasBasic: true, has256: level >= 2, - has16m: level >= 3 + has16m: level >= 3, }; } -function supportsColor(haveStream, streamIsTTY) { +function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { + const noFlagForceColor = envForceColor(); + if (noFlagForceColor !== undefined) { + flagForceColor = noFlagForceColor; + } + + const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; + if (forceColor === 0) { return 0; } - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; + if (sniffFlags) { + if (hasFlag('color=16m') + || hasFlag('color=full') + || hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } } - if (hasFlag('color=256')) { - return 2; + // Check for Azure DevOps pipelines. + // Has to be above the `!streamIsTTY` check. + if ('TF_BUILD' in env && 'AGENT_NAME' in env) { + return 1; } if (haveStream && !streamIsTTY && forceColor === undefined) { @@ -71,17 +114,21 @@ function supportsColor(haveStream, streamIsTTY) { // Windows 10 build 14931 is the first release that supports 16m/TrueColor. const osRelease = os.release().split('.'); if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 + Number(osRelease[0]) >= 10 + && Number(osRelease[2]) >= 10_586 ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; + return Number(osRelease[2]) >= 14_931 ? 3 : 2; } return 1; } if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) { + return 3; + } + + if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { return 1; } @@ -96,14 +143,29 @@ function supportsColor(haveStream, streamIsTTY) { return 3; } + if (env.TERM === 'xterm-kitty') { + return 3; + } + + if (env.TERM === 'xterm-ghostty') { + return 3; + } + + if (env.TERM === 'wezterm') { + return 3; + } + if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); switch (env.TERM_PROGRAM) { - case 'iTerm.app': + case 'iTerm.app': { return version >= 3 ? 3 : 2; - case 'Apple_Terminal': + } + + case 'Apple_Terminal': { return 2; + } // No default } } @@ -123,13 +185,18 @@ function supportsColor(haveStream, streamIsTTY) { return min; } -function getSupportLevel(stream) { - const level = supportsColor(stream, stream && stream.isTTY); +export function createSupportsColor(stream, options = {}) { + const level = _supportsColor(stream, { + streamIsTTY: stream && stream.isTTY, + ...options, + }); + return translateLevel(level); } -module.exports = { - supportsColor: getSupportLevel, - stdout: translateLevel(supportsColor(true, tty.isatty(1))), - stderr: translateLevel(supportsColor(true, tty.isatty(2))) +const supportsColor = { + stdout: createSupportsColor({isTTY: tty.isatty(1)}), + stderr: createSupportsColor({isTTY: tty.isatty(2)}), }; + +export default supportsColor; diff --git a/node_modules/supports-color/license b/node_modules/supports-color/license index e7af2f77107d7..fa7ceba3eb4a9 100644 --- a/node_modules/supports-color/license +++ b/node_modules/supports-color/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com) +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/node_modules/supports-color/package.json b/node_modules/supports-color/package.json index f7182edcea2ba..8915597ab45a0 100644 --- a/node_modules/supports-color/package.json +++ b/node_modules/supports-color/package.json @@ -1,23 +1,33 @@ { "name": "supports-color", - "version": "7.2.0", + "version": "10.2.2", "description": "Detect whether a terminal supports color", "license": "MIT", "repository": "chalk/supports-color", + "funding": "https://github.com/chalk/supports-color?sponsor=1", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" + "url": "https://sindresorhus.com" }, + "type": "module", + "exports": { + "types": "./index.d.ts", + "node": "./index.js", + "default": "./browser.js" + }, + "sideEffects": false, "engines": { - "node": ">=8" + "node": ">=18" }, "scripts": { - "test": "xo && ava" + "test": "xo && ava && tsd" }, "files": [ "index.js", - "browser.js" + "index.d.ts", + "browser.js", + "browser.d.ts" ], "keywords": [ "color", @@ -41,13 +51,14 @@ "truecolor", "16m" ], - "dependencies": { - "has-flag": "^4.0.0" - }, "devDependencies": { - "ava": "^1.4.1", - "import-fresh": "^3.0.0", - "xo": "^0.24.0" + "@types/node": "^22.10.2", + "ava": "^6.2.0", + "tsd": "^0.31.2", + "xo": "^0.60.0" }, - "browser": "browser.js" + "ava": { + "serial": true, + "workerThreads": false + } } diff --git a/node_modules/supports-color/readme.md b/node_modules/supports-color/readme.md deleted file mode 100644 index 3654228586333..0000000000000 --- a/node_modules/supports-color/readme.md +++ /dev/null @@ -1,76 +0,0 @@ -# supports-color [![Build Status](https://travis-ci.org/chalk/supports-color.svg?branch=master)](https://travis-ci.org/chalk/supports-color) - -> Detect whether a terminal supports color - - -## Install - -``` -$ npm install supports-color -``` - - -## Usage - -```js -const supportsColor = require('supports-color'); - -if (supportsColor.stdout) { - console.log('Terminal stdout supports color'); -} - -if (supportsColor.stdout.has256) { - console.log('Terminal stdout supports 256 colors'); -} - -if (supportsColor.stderr.has16m) { - console.log('Terminal stderr supports 16 million colors (truecolor)'); -} -``` - - -## API - -Returns an `Object` with a `stdout` and `stderr` property for testing either streams. Each property is an `Object`, or `false` if color is not supported. - -The `stdout`/`stderr` objects specifies a level of support for color through a `.level` property and a corresponding flag: - -- `.level = 1` and `.hasBasic = true`: Basic color support (16 colors) -- `.level = 2` and `.has256 = true`: 256 color support -- `.level = 3` and `.has16m = true`: Truecolor support (16 million colors) - - -## Info - -It obeys the `--color` and `--no-color` CLI flags. - -For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. - -Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. - - -## Related - -- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module -- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right - - -## Maintainers - -- [Sindre Sorhus](https://github.com/sindresorhus) -- [Josh Junon](https://github.com/qix-) - - ---- - -<div align="center"> - <b> - <a href="https://tidelift.com/subscription/pkg/npm-supports-color?utm_source=npm-supports-color&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a> - </b> - <br> - <sub> - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies. - </sub> -</div> - ---- diff --git a/node_modules/tar/LICENSE b/node_modules/tar/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/tar/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/tar/LICENSE.md b/node_modules/tar/LICENSE.md new file mode 100644 index 0000000000000..c5402b9577a8c --- /dev/null +++ b/node_modules/tar/LICENSE.md @@ -0,0 +1,55 @@ +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/tar/dist/commonjs/create.js b/node_modules/tar/dist/commonjs/create.js new file mode 100644 index 0000000000000..3190afc48318f --- /dev/null +++ b/node_modules/tar/dist/commonjs/create.js @@ -0,0 +1,83 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.create = void 0; +const fs_minipass_1 = require("@isaacs/fs-minipass"); +const node_path_1 = __importDefault(require("node:path")); +const list_js_1 = require("./list.js"); +const make_command_js_1 = require("./make-command.js"); +const pack_js_1 = require("./pack.js"); +const createFileSync = (opt, files) => { + const p = new pack_js_1.PackSync(opt); + const stream = new fs_minipass_1.WriteStreamSync(opt.file, { + mode: opt.mode || 0o666, + }); + p.pipe(stream); + addFilesSync(p, files); +}; +const createFile = (opt, files) => { + const p = new pack_js_1.Pack(opt); + const stream = new fs_minipass_1.WriteStream(opt.file, { + mode: opt.mode || 0o666, + }); + p.pipe(stream); + const promise = new Promise((res, rej) => { + stream.on('error', rej); + stream.on('close', res); + p.on('error', rej); + }); + addFilesAsync(p, files); + return promise; +}; +const addFilesSync = (p, files) => { + files.forEach(file => { + if (file.charAt(0) === '@') { + (0, list_js_1.list)({ + file: node_path_1.default.resolve(p.cwd, file.slice(1)), + sync: true, + noResume: true, + onReadEntry: entry => p.add(entry), + }); + } + else { + p.add(file); + } + }); + p.end(); +}; +const addFilesAsync = async (p, files) => { + for (let i = 0; i < files.length; i++) { + const file = String(files[i]); + if (file.charAt(0) === '@') { + await (0, list_js_1.list)({ + file: node_path_1.default.resolve(String(p.cwd), file.slice(1)), + noResume: true, + onReadEntry: entry => { + p.add(entry); + }, + }); + } + else { + p.add(file); + } + } + p.end(); +}; +const createSync = (opt, files) => { + const p = new pack_js_1.PackSync(opt); + addFilesSync(p, files); + return p; +}; +const createAsync = (opt, files) => { + const p = new pack_js_1.Pack(opt); + addFilesAsync(p, files); + return p; +}; +exports.create = (0, make_command_js_1.makeCommand)(createFileSync, createFile, createSync, createAsync, (_opt, files) => { + if (!files?.length) { + throw new TypeError('no paths specified to add to archive'); + } +}); +//# sourceMappingURL=create.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/cwd-error.js b/node_modules/tar/dist/commonjs/cwd-error.js new file mode 100644 index 0000000000000..d703a7772be3a --- /dev/null +++ b/node_modules/tar/dist/commonjs/cwd-error.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CwdError = void 0; +class CwdError extends Error { + path; + code; + syscall = 'chdir'; + constructor(path, code) { + super(`${code}: Cannot cd into '${path}'`); + this.path = path; + this.code = code; + } + get name() { + return 'CwdError'; + } +} +exports.CwdError = CwdError; +//# sourceMappingURL=cwd-error.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/extract.js b/node_modules/tar/dist/commonjs/extract.js new file mode 100644 index 0000000000000..86deb304d8b01 --- /dev/null +++ b/node_modules/tar/dist/commonjs/extract.js @@ -0,0 +1,88 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.extract = void 0; +// tar -x +const fsm = __importStar(require("@isaacs/fs-minipass")); +const node_fs_1 = __importDefault(require("node:fs")); +const list_js_1 = require("./list.js"); +const make_command_js_1 = require("./make-command.js"); +const unpack_js_1 = require("./unpack.js"); +const extractFileSync = (opt) => { + const u = new unpack_js_1.UnpackSync(opt); + const file = opt.file; + const stat = node_fs_1.default.statSync(file); + // This trades a zero-byte read() syscall for a stat + // However, it will usually result in less memory allocation + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + const stream = new fsm.ReadStreamSync(file, { + readSize: readSize, + size: stat.size, + }); + stream.pipe(u); +}; +const extractFile = (opt, _) => { + const u = new unpack_js_1.Unpack(opt); + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + const file = opt.file; + const p = new Promise((resolve, reject) => { + u.on('error', reject); + u.on('close', resolve); + // This trades a zero-byte read() syscall for a stat + // However, it will usually result in less memory allocation + node_fs_1.default.stat(file, (er, stat) => { + if (er) { + reject(er); + } + else { + const stream = new fsm.ReadStream(file, { + readSize: readSize, + size: stat.size, + }); + stream.on('error', reject); + stream.pipe(u); + } + }); + }); + return p; +}; +exports.extract = (0, make_command_js_1.makeCommand)(extractFileSync, extractFile, opt => new unpack_js_1.UnpackSync(opt), opt => new unpack_js_1.Unpack(opt), (opt, files) => { + if (files?.length) + (0, list_js_1.filesFilter)(opt, files); +}); +//# sourceMappingURL=extract.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/get-write-flag.js b/node_modules/tar/dist/commonjs/get-write-flag.js new file mode 100644 index 0000000000000..94add8f6b2231 --- /dev/null +++ b/node_modules/tar/dist/commonjs/get-write-flag.js @@ -0,0 +1,29 @@ +"use strict"; +// Get the appropriate flag to use for creating files +// We use fmap on Windows platforms for files less than +// 512kb. This is a fairly low limit, but avoids making +// things slower in some cases. Since most of what this +// library is used for is extracting tarballs of many +// relatively small files in npm packages and the like, +// it can be a big boost on Windows platforms. +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getWriteFlag = void 0; +const fs_1 = __importDefault(require("fs")); +const platform = process.env.__FAKE_PLATFORM__ || process.platform; +const isWindows = platform === 'win32'; +/* c8 ignore start */ +const { O_CREAT, O_TRUNC, O_WRONLY } = fs_1.default.constants; +const UV_FS_O_FILEMAP = Number(process.env.__FAKE_FS_O_FILENAME__) || + fs_1.default.constants.UV_FS_O_FILEMAP || + 0; +/* c8 ignore stop */ +const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP; +const fMapLimit = 512 * 1024; +const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY; +exports.getWriteFlag = !fMapEnabled ? + () => 'w' + : (size) => (size < fMapLimit ? fMapFlag : 'w'); +//# sourceMappingURL=get-write-flag.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/header.js b/node_modules/tar/dist/commonjs/header.js new file mode 100644 index 0000000000000..12558ed925623 --- /dev/null +++ b/node_modules/tar/dist/commonjs/header.js @@ -0,0 +1,325 @@ +"use strict"; +// parse a 512-byte header block to a data object, or vice-versa +// encode returns `true` if a pax extended header is needed, because +// the data could not be faithfully encoded in a simple header. +// (Also, check header.needPax to see if it needs a pax header.) +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Header = void 0; +const node_path_1 = require("node:path"); +const large = __importStar(require("./large-numbers.js")); +const types = __importStar(require("./types.js")); +class Header { + cksumValid = false; + needPax = false; + nullBlock = false; + block; + path; + mode; + uid; + gid; + size; + cksum; + #type = 'Unsupported'; + linkpath; + uname; + gname; + devmaj = 0; + devmin = 0; + atime; + ctime; + mtime; + charset; + comment; + constructor(data, off = 0, ex, gex) { + if (Buffer.isBuffer(data)) { + this.decode(data, off || 0, ex, gex); + } + else if (data) { + this.#slurp(data); + } + } + decode(buf, off, ex, gex) { + if (!off) { + off = 0; + } + if (!buf || !(buf.length >= off + 512)) { + throw new Error('need 512 bytes for header'); + } + this.path = ex?.path ?? decString(buf, off, 100); + this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8); + this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8); + this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8); + this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12); + this.mtime = + ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12); + this.cksum = decNumber(buf, off + 148, 12); + // if we have extended or global extended headers, apply them now + // See https://github.com/npm/node-tar/pull/187 + // Apply global before local, so it overrides + if (gex) + this.#slurp(gex, true); + if (ex) + this.#slurp(ex); + // old tar versions marked dirs as a file with a trailing / + const t = decString(buf, off + 156, 1); + if (types.isCode(t)) { + this.#type = t || '0'; + } + if (this.#type === '0' && this.path.slice(-1) === '/') { + this.#type = '5'; + } + // tar implementations sometimes incorrectly put the stat(dir).size + // as the size in the tarball, even though Directory entries are + // not able to have any body at all. In the very rare chance that + // it actually DOES have a body, we weren't going to do anything with + // it anyway, and it'll just be a warning about an invalid header. + if (this.#type === '5') { + this.size = 0; + } + this.linkpath = decString(buf, off + 157, 100); + if (buf.subarray(off + 257, off + 265).toString() === + 'ustar\u000000') { + /* c8 ignore start */ + this.uname = + ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32); + this.gname = + ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32); + this.devmaj = + ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0; + this.devmin = + ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0; + /* c8 ignore stop */ + if (buf[off + 475] !== 0) { + // definitely a prefix, definitely >130 chars. + const prefix = decString(buf, off + 345, 155); + this.path = prefix + '/' + this.path; + } + else { + const prefix = decString(buf, off + 345, 130); + if (prefix) { + this.path = prefix + '/' + this.path; + } + /* c8 ignore start */ + this.atime = + ex?.atime ?? gex?.atime ?? decDate(buf, off + 476, 12); + this.ctime = + ex?.ctime ?? gex?.ctime ?? decDate(buf, off + 488, 12); + /* c8 ignore stop */ + } + } + let sum = 8 * 0x20; + for (let i = off; i < off + 148; i++) { + sum += buf[i]; + } + for (let i = off + 156; i < off + 512; i++) { + sum += buf[i]; + } + this.cksumValid = sum === this.cksum; + if (this.cksum === undefined && sum === 8 * 0x20) { + this.nullBlock = true; + } + } + #slurp(ex, gex = false) { + Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. Also, any + // null/undefined values are ignored. + return !(v === null || + v === undefined || + (k === 'path' && gex) || + (k === 'linkpath' && gex) || + k === 'global'); + }))); + } + encode(buf, off = 0) { + if (!buf) { + buf = this.block = Buffer.alloc(512); + } + if (this.#type === 'Unsupported') { + this.#type = '0'; + } + if (!(buf.length >= off + 512)) { + throw new Error('need 512 bytes for header'); + } + const prefixSize = this.ctime || this.atime ? 130 : 155; + const split = splitPrefix(this.path || '', prefixSize); + const path = split[0]; + const prefix = split[1]; + this.needPax = !!split[2]; + this.needPax = encString(buf, off, 100, path) || this.needPax; + this.needPax = + encNumber(buf, off + 100, 8, this.mode) || this.needPax; + this.needPax = + encNumber(buf, off + 108, 8, this.uid) || this.needPax; + this.needPax = + encNumber(buf, off + 116, 8, this.gid) || this.needPax; + this.needPax = + encNumber(buf, off + 124, 12, this.size) || this.needPax; + this.needPax = + encDate(buf, off + 136, 12, this.mtime) || this.needPax; + buf[off + 156] = this.#type.charCodeAt(0); + this.needPax = + encString(buf, off + 157, 100, this.linkpath) || this.needPax; + buf.write('ustar\u000000', off + 257, 8); + this.needPax = + encString(buf, off + 265, 32, this.uname) || this.needPax; + this.needPax = + encString(buf, off + 297, 32, this.gname) || this.needPax; + this.needPax = + encNumber(buf, off + 329, 8, this.devmaj) || this.needPax; + this.needPax = + encNumber(buf, off + 337, 8, this.devmin) || this.needPax; + this.needPax = + encString(buf, off + 345, prefixSize, prefix) || this.needPax; + if (buf[off + 475] !== 0) { + this.needPax = + encString(buf, off + 345, 155, prefix) || this.needPax; + } + else { + this.needPax = + encString(buf, off + 345, 130, prefix) || this.needPax; + this.needPax = + encDate(buf, off + 476, 12, this.atime) || this.needPax; + this.needPax = + encDate(buf, off + 488, 12, this.ctime) || this.needPax; + } + let sum = 8 * 0x20; + for (let i = off; i < off + 148; i++) { + sum += buf[i]; + } + for (let i = off + 156; i < off + 512; i++) { + sum += buf[i]; + } + this.cksum = sum; + encNumber(buf, off + 148, 8, this.cksum); + this.cksumValid = true; + return this.needPax; + } + get type() { + return (this.#type === 'Unsupported' ? + this.#type + : types.name.get(this.#type)); + } + get typeKey() { + return this.#type; + } + set type(type) { + const c = String(types.code.get(type)); + if (types.isCode(c) || c === 'Unsupported') { + this.#type = c; + } + else if (types.isCode(type)) { + this.#type = type; + } + else { + throw new TypeError('invalid entry type: ' + type); + } + } +} +exports.Header = Header; +const splitPrefix = (p, prefixSize) => { + const pathSize = 100; + let pp = p; + let prefix = ''; + let ret = undefined; + const root = node_path_1.posix.parse(p).root || '.'; + if (Buffer.byteLength(pp) < pathSize) { + ret = [pp, prefix, false]; + } + else { + // first set prefix to the dir, and path to the base + prefix = node_path_1.posix.dirname(pp); + pp = node_path_1.posix.basename(pp); + do { + if (Buffer.byteLength(pp) <= pathSize && + Buffer.byteLength(prefix) <= prefixSize) { + // both fit! + ret = [pp, prefix, false]; + } + else if (Buffer.byteLength(pp) > pathSize && + Buffer.byteLength(prefix) <= prefixSize) { + // prefix fits in prefix, but path doesn't fit in path + ret = [pp.slice(0, pathSize - 1), prefix, true]; + } + else { + // make path take a bit from prefix + pp = node_path_1.posix.join(node_path_1.posix.basename(prefix), pp); + prefix = node_path_1.posix.dirname(prefix); + } + } while (prefix !== root && ret === undefined); + // at this point, found no resolution, just truncate + if (!ret) { + ret = [p.slice(0, pathSize - 1), '', true]; + } + } + return ret; +}; +const decString = (buf, off, size) => buf + .subarray(off, off + size) + .toString('utf8') + .replace(/\0.*/, ''); +const decDate = (buf, off, size) => numToDate(decNumber(buf, off, size)); +const numToDate = (num) => num === undefined ? undefined : new Date(num * 1000); +const decNumber = (buf, off, size) => Number(buf[off]) & 0x80 ? + large.parse(buf.subarray(off, off + size)) + : decSmallNumber(buf, off, size); +const nanUndef = (value) => (isNaN(value) ? undefined : value); +const decSmallNumber = (buf, off, size) => nanUndef(parseInt(buf + .subarray(off, off + size) + .toString('utf8') + .replace(/\0.*$/, '') + .trim(), 8)); +// the maximum encodable as a null-terminated octal, by field size +const MAXNUM = { + 12: 0o77777777777, + 8: 0o7777777, +}; +const encNumber = (buf, off, size, num) => num === undefined ? false + : num > MAXNUM[size] || num < 0 ? + (large.encode(num, buf.subarray(off, off + size)), true) + : (encSmallNumber(buf, off, size, num), false); +const encSmallNumber = (buf, off, size, num) => buf.write(octalString(num, size), off, size, 'ascii'); +const octalString = (num, size) => padOctal(Math.floor(num).toString(8), size); +const padOctal = (str, size) => (str.length === size - 1 ? + str + : new Array(size - str.length - 1).join('0') + str + ' ') + '\0'; +const encDate = (buf, off, size, date) => date === undefined ? false : (encNumber(buf, off, size, date.getTime() / 1000)); +// enough to fill the longest string we've got +const NULLS = new Array(156).join('\0'); +// pad with nulls, return true if it's longer or non-ascii +const encString = (buf, off, size, str) => str === undefined ? false : ((buf.write(str + NULLS, off, size, 'utf8'), + str.length !== Buffer.byteLength(str) || str.length > size)); +//# sourceMappingURL=header.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/index.js b/node_modules/tar/dist/commonjs/index.js new file mode 100644 index 0000000000000..bd975c77281b7 --- /dev/null +++ b/node_modules/tar/dist/commonjs/index.js @@ -0,0 +1,64 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.u = exports.types = exports.r = exports.t = exports.x = exports.c = void 0; +__exportStar(require("./create.js"), exports); +var create_js_1 = require("./create.js"); +Object.defineProperty(exports, "c", { enumerable: true, get: function () { return create_js_1.create; } }); +__exportStar(require("./extract.js"), exports); +var extract_js_1 = require("./extract.js"); +Object.defineProperty(exports, "x", { enumerable: true, get: function () { return extract_js_1.extract; } }); +__exportStar(require("./header.js"), exports); +__exportStar(require("./list.js"), exports); +var list_js_1 = require("./list.js"); +Object.defineProperty(exports, "t", { enumerable: true, get: function () { return list_js_1.list; } }); +// classes +__exportStar(require("./pack.js"), exports); +__exportStar(require("./parse.js"), exports); +__exportStar(require("./pax.js"), exports); +__exportStar(require("./read-entry.js"), exports); +__exportStar(require("./replace.js"), exports); +var replace_js_1 = require("./replace.js"); +Object.defineProperty(exports, "r", { enumerable: true, get: function () { return replace_js_1.replace; } }); +exports.types = __importStar(require("./types.js")); +__exportStar(require("./unpack.js"), exports); +__exportStar(require("./update.js"), exports); +var update_js_1 = require("./update.js"); +Object.defineProperty(exports, "u", { enumerable: true, get: function () { return update_js_1.update; } }); +__exportStar(require("./write-entry.js"), exports); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/large-numbers.js b/node_modules/tar/dist/commonjs/large-numbers.js new file mode 100644 index 0000000000000..5b07aa7f71b48 --- /dev/null +++ b/node_modules/tar/dist/commonjs/large-numbers.js @@ -0,0 +1,99 @@ +"use strict"; +// Tar can encode large and negative numbers using a leading byte of +// 0xff for negative, and 0x80 for positive. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.parse = exports.encode = void 0; +const encode = (num, buf) => { + if (!Number.isSafeInteger(num)) { + // The number is so large that javascript cannot represent it with integer + // precision. + throw Error('cannot encode number outside of javascript safe integer range'); + } + else if (num < 0) { + encodeNegative(num, buf); + } + else { + encodePositive(num, buf); + } + return buf; +}; +exports.encode = encode; +const encodePositive = (num, buf) => { + buf[0] = 0x80; + for (var i = buf.length; i > 1; i--) { + buf[i - 1] = num & 0xff; + num = Math.floor(num / 0x100); + } +}; +const encodeNegative = (num, buf) => { + buf[0] = 0xff; + var flipped = false; + num = num * -1; + for (var i = buf.length; i > 1; i--) { + var byte = num & 0xff; + num = Math.floor(num / 0x100); + if (flipped) { + buf[i - 1] = onesComp(byte); + } + else if (byte === 0) { + buf[i - 1] = 0; + } + else { + flipped = true; + buf[i - 1] = twosComp(byte); + } + } +}; +const parse = (buf) => { + const pre = buf[0]; + const value = pre === 0x80 ? pos(buf.subarray(1, buf.length)) + : pre === 0xff ? twos(buf) + : null; + if (value === null) { + throw Error('invalid base256 encoding'); + } + if (!Number.isSafeInteger(value)) { + // The number is so large that javascript cannot represent it with integer + // precision. + throw Error('parsed number outside of javascript safe integer range'); + } + return value; +}; +exports.parse = parse; +const twos = (buf) => { + var len = buf.length; + var sum = 0; + var flipped = false; + for (var i = len - 1; i > -1; i--) { + var byte = Number(buf[i]); + var f; + if (flipped) { + f = onesComp(byte); + } + else if (byte === 0) { + f = byte; + } + else { + flipped = true; + f = twosComp(byte); + } + if (f !== 0) { + sum -= f * Math.pow(256, len - i - 1); + } + } + return sum; +}; +const pos = (buf) => { + var len = buf.length; + var sum = 0; + for (var i = len - 1; i > -1; i--) { + var byte = Number(buf[i]); + if (byte !== 0) { + sum += byte * Math.pow(256, len - i - 1); + } + } + return sum; +}; +const onesComp = (byte) => (0xff ^ byte) & 0xff; +const twosComp = (byte) => ((0xff ^ byte) + 1) & 0xff; +//# sourceMappingURL=large-numbers.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/list.js b/node_modules/tar/dist/commonjs/list.js new file mode 100644 index 0000000000000..5157bc8ba8b2f --- /dev/null +++ b/node_modules/tar/dist/commonjs/list.js @@ -0,0 +1,150 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.list = exports.filesFilter = void 0; +// tar -t +const fsm = __importStar(require("@isaacs/fs-minipass")); +const node_fs_1 = __importDefault(require("node:fs")); +const path_1 = require("path"); +const make_command_js_1 = require("./make-command.js"); +const parse_js_1 = require("./parse.js"); +const strip_trailing_slashes_js_1 = require("./strip-trailing-slashes.js"); +const onReadEntryFunction = (opt) => { + const onReadEntry = opt.onReadEntry; + opt.onReadEntry = + onReadEntry ? + e => { + onReadEntry(e); + e.resume(); + } + : e => e.resume(); +}; +// construct a filter that limits the file entries listed +// include child entries if a dir is included +const filesFilter = (opt, files) => { + const map = new Map(files.map(f => [(0, strip_trailing_slashes_js_1.stripTrailingSlashes)(f), true])); + const filter = opt.filter; + const mapHas = (file, r = '') => { + const root = r || (0, path_1.parse)(file).root || '.'; + let ret; + if (file === root) + ret = false; + else { + const m = map.get(file); + if (m !== undefined) { + ret = m; + } + else { + ret = mapHas((0, path_1.dirname)(file), root); + } + } + map.set(file, ret); + return ret; + }; + opt.filter = + filter ? + (file, entry) => filter(file, entry) && mapHas((0, strip_trailing_slashes_js_1.stripTrailingSlashes)(file)) + : file => mapHas((0, strip_trailing_slashes_js_1.stripTrailingSlashes)(file)); +}; +exports.filesFilter = filesFilter; +const listFileSync = (opt) => { + const p = new parse_js_1.Parser(opt); + const file = opt.file; + let fd; + try { + fd = node_fs_1.default.openSync(file, 'r'); + const stat = node_fs_1.default.fstatSync(fd); + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + if (stat.size < readSize) { + const buf = Buffer.allocUnsafe(stat.size); + const read = node_fs_1.default.readSync(fd, buf, 0, stat.size, 0); + p.end(read === buf.byteLength ? buf : buf.subarray(0, read)); + } + else { + let pos = 0; + const buf = Buffer.allocUnsafe(readSize); + while (pos < stat.size) { + const bytesRead = node_fs_1.default.readSync(fd, buf, 0, readSize, pos); + if (bytesRead === 0) + break; + pos += bytesRead; + p.write(buf.subarray(0, bytesRead)); + } + p.end(); + } + } + finally { + if (typeof fd === 'number') { + try { + node_fs_1.default.closeSync(fd); + /* c8 ignore next */ + } + catch (er) { } + } + } +}; +const listFile = (opt, _files) => { + const parse = new parse_js_1.Parser(opt); + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + const file = opt.file; + const p = new Promise((resolve, reject) => { + parse.on('error', reject); + parse.on('end', resolve); + node_fs_1.default.stat(file, (er, stat) => { + if (er) { + reject(er); + } + else { + const stream = new fsm.ReadStream(file, { + readSize: readSize, + size: stat.size, + }); + stream.on('error', reject); + stream.pipe(parse); + } + }); + }); + return p; +}; +exports.list = (0, make_command_js_1.makeCommand)(listFileSync, listFile, opt => new parse_js_1.Parser(opt), opt => new parse_js_1.Parser(opt), (opt, files) => { + if (files?.length) + (0, exports.filesFilter)(opt, files); + if (!opt.noResume) + onReadEntryFunction(opt); +}); +//# sourceMappingURL=list.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/make-command.js b/node_modules/tar/dist/commonjs/make-command.js new file mode 100644 index 0000000000000..1814319e78bc6 --- /dev/null +++ b/node_modules/tar/dist/commonjs/make-command.js @@ -0,0 +1,61 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.makeCommand = void 0; +const options_js_1 = require("./options.js"); +const makeCommand = (syncFile, asyncFile, syncNoFile, asyncNoFile, validate) => { + return Object.assign((opt_ = [], entries, cb) => { + if (Array.isArray(opt_)) { + entries = opt_; + opt_ = {}; + } + if (typeof entries === 'function') { + cb = entries; + entries = undefined; + } + if (!entries) { + entries = []; + } + else { + entries = Array.from(entries); + } + const opt = (0, options_js_1.dealias)(opt_); + validate?.(opt, entries); + if ((0, options_js_1.isSyncFile)(opt)) { + if (typeof cb === 'function') { + throw new TypeError('callback not supported for sync tar functions'); + } + return syncFile(opt, entries); + } + else if ((0, options_js_1.isAsyncFile)(opt)) { + const p = asyncFile(opt, entries); + // weirdness to make TS happy + const c = cb ? cb : undefined; + return c ? p.then(() => c(), c) : p; + } + else if ((0, options_js_1.isSyncNoFile)(opt)) { + if (typeof cb === 'function') { + throw new TypeError('callback not supported for sync tar functions'); + } + return syncNoFile(opt, entries); + } + else if ((0, options_js_1.isAsyncNoFile)(opt)) { + if (typeof cb === 'function') { + throw new TypeError('callback only supported with file option'); + } + return asyncNoFile(opt, entries); + /* c8 ignore start */ + } + else { + throw new Error('impossible options??'); + } + /* c8 ignore stop */ + }, { + syncFile, + asyncFile, + syncNoFile, + asyncNoFile, + validate, + }); +}; +exports.makeCommand = makeCommand; +//# sourceMappingURL=make-command.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/mkdir.js b/node_modules/tar/dist/commonjs/mkdir.js new file mode 100644 index 0000000000000..606619efbcde3 --- /dev/null +++ b/node_modules/tar/dist/commonjs/mkdir.js @@ -0,0 +1,188 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mkdirSync = exports.mkdir = void 0; +const chownr_1 = require("chownr"); +const node_fs_1 = __importDefault(require("node:fs")); +const promises_1 = __importDefault(require("node:fs/promises")); +const node_path_1 = __importDefault(require("node:path")); +const cwd_error_js_1 = require("./cwd-error.js"); +const normalize_windows_path_js_1 = require("./normalize-windows-path.js"); +const symlink_error_js_1 = require("./symlink-error.js"); +const checkCwd = (dir, cb) => { + node_fs_1.default.stat(dir, (er, st) => { + if (er || !st.isDirectory()) { + er = new cwd_error_js_1.CwdError(dir, er?.code || 'ENOTDIR'); + } + cb(er); + }); +}; +/** + * Wrapper around fs/promises.mkdir for tar's needs. + * + * The main purpose is to avoid creating directories if we know that + * they already exist (and track which ones exist for this purpose), + * and prevent entries from being extracted into symlinked folders, + * if `preservePaths` is not set. + */ +const mkdir = (dir, opt, cb) => { + dir = (0, normalize_windows_path_js_1.normalizeWindowsPath)(dir); + // if there's any overlap between mask and mode, + // then we'll need an explicit chmod + /* c8 ignore next */ + const umask = opt.umask ?? 0o22; + const mode = opt.mode | 0o0700; + const needChmod = (mode & umask) !== 0; + const uid = opt.uid; + const gid = opt.gid; + const doChown = typeof uid === 'number' && + typeof gid === 'number' && + (uid !== opt.processUid || gid !== opt.processGid); + const preserve = opt.preserve; + const unlink = opt.unlink; + const cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd); + const done = (er, created) => { + if (er) { + cb(er); + } + else { + if (created && doChown) { + (0, chownr_1.chownr)(created, uid, gid, er => done(er)); + } + else if (needChmod) { + node_fs_1.default.chmod(dir, mode, cb); + } + else { + cb(); + } + } + }; + if (dir === cwd) { + return checkCwd(dir, done); + } + if (preserve) { + return promises_1.default.mkdir(dir, { mode, recursive: true }).then(made => done(null, made ?? undefined), // oh, ts + done); + } + const sub = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.relative(cwd, dir)); + const parts = sub.split('/'); + mkdir_(cwd, parts, mode, unlink, cwd, undefined, done); +}; +exports.mkdir = mkdir; +const mkdir_ = (base, parts, mode, unlink, cwd, created, cb) => { + if (!parts.length) { + return cb(null, created); + } + const p = parts.shift(); + const part = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(base + '/' + p)); + node_fs_1.default.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb)); +}; +const onmkdir = (part, parts, mode, unlink, cwd, created, cb) => (er) => { + if (er) { + node_fs_1.default.lstat(part, (statEr, st) => { + if (statEr) { + statEr.path = + statEr.path && (0, normalize_windows_path_js_1.normalizeWindowsPath)(statEr.path); + cb(statEr); + } + else if (st.isDirectory()) { + mkdir_(part, parts, mode, unlink, cwd, created, cb); + } + else if (unlink) { + node_fs_1.default.unlink(part, er => { + if (er) { + return cb(er); + } + node_fs_1.default.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb)); + }); + } + else if (st.isSymbolicLink()) { + return cb(new symlink_error_js_1.SymlinkError(part, part + '/' + parts.join('/'))); + } + else { + cb(er); + } + }); + } + else { + created = created || part; + mkdir_(part, parts, mode, unlink, cwd, created, cb); + } +}; +const checkCwdSync = (dir) => { + let ok = false; + let code = undefined; + try { + ok = node_fs_1.default.statSync(dir).isDirectory(); + } + catch (er) { + code = er?.code; + } + finally { + if (!ok) { + throw new cwd_error_js_1.CwdError(dir, code ?? 'ENOTDIR'); + } + } +}; +const mkdirSync = (dir, opt) => { + dir = (0, normalize_windows_path_js_1.normalizeWindowsPath)(dir); + // if there's any overlap between mask and mode, + // then we'll need an explicit chmod + /* c8 ignore next */ + const umask = opt.umask ?? 0o22; + const mode = opt.mode | 0o700; + const needChmod = (mode & umask) !== 0; + const uid = opt.uid; + const gid = opt.gid; + const doChown = typeof uid === 'number' && + typeof gid === 'number' && + (uid !== opt.processUid || gid !== opt.processGid); + const preserve = opt.preserve; + const unlink = opt.unlink; + const cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd); + const done = (created) => { + if (created && doChown) { + (0, chownr_1.chownrSync)(created, uid, gid); + } + if (needChmod) { + node_fs_1.default.chmodSync(dir, mode); + } + }; + if (dir === cwd) { + checkCwdSync(cwd); + return done(); + } + if (preserve) { + return done(node_fs_1.default.mkdirSync(dir, { mode, recursive: true }) ?? undefined); + } + const sub = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.relative(cwd, dir)); + const parts = sub.split('/'); + let created = undefined; + for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) { + part = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(part)); + try { + node_fs_1.default.mkdirSync(part, mode); + created = created || part; + } + catch (er) { + const st = node_fs_1.default.lstatSync(part); + if (st.isDirectory()) { + continue; + } + else if (unlink) { + node_fs_1.default.unlinkSync(part); + node_fs_1.default.mkdirSync(part, mode); + created = created || part; + continue; + } + else if (st.isSymbolicLink()) { + return new symlink_error_js_1.SymlinkError(part, part + '/' + parts.join('/')); + } + } + } + return done(created); +}; +exports.mkdirSync = mkdirSync; +//# sourceMappingURL=mkdir.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/mode-fix.js b/node_modules/tar/dist/commonjs/mode-fix.js new file mode 100644 index 0000000000000..49dd727961d29 --- /dev/null +++ b/node_modules/tar/dist/commonjs/mode-fix.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.modeFix = void 0; +const modeFix = (mode, isDir, portable) => { + mode &= 0o7777; + // in portable mode, use the minimum reasonable umask + // if this system creates files with 0o664 by default + // (as some linux distros do), then we'll write the + // archive with 0o644 instead. Also, don't ever create + // a file that is not readable/writable by the owner. + if (portable) { + mode = (mode | 0o600) & ~0o22; + } + // if dirs are readable, then they should be listable + if (isDir) { + if (mode & 0o400) { + mode |= 0o100; + } + if (mode & 0o40) { + mode |= 0o10; + } + if (mode & 0o4) { + mode |= 0o1; + } + } + return mode; +}; +exports.modeFix = modeFix; +//# sourceMappingURL=mode-fix.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/normalize-unicode.js b/node_modules/tar/dist/commonjs/normalize-unicode.js new file mode 100644 index 0000000000000..5b0eaec8ccb49 --- /dev/null +++ b/node_modules/tar/dist/commonjs/normalize-unicode.js @@ -0,0 +1,38 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.normalizeUnicode = void 0; +// warning: extremely hot code path. +// This has been meticulously optimized for use +// within npm install on large package trees. +// Do not edit without careful benchmarking. +const normalizeCache = Object.create(null); +// Limit the size of this. Very low-sophistication LRU cache +const MAX = 10000; +const cache = new Set(); +const normalizeUnicode = (s) => { + if (!cache.has(s)) { + // shake out identical accents and ligatures + normalizeCache[s] = s + .normalize('NFD') + .toLocaleLowerCase('en') + .toLocaleUpperCase('en'); + } + else { + cache.delete(s); + } + cache.add(s); + const ret = normalizeCache[s]; + let i = cache.size - MAX; + // only prune when we're 10% over the max + if (i > MAX / 10) { + for (const s of cache) { + cache.delete(s); + delete normalizeCache[s]; + if (--i <= 0) + break; + } + } + return ret; +}; +exports.normalizeUnicode = normalizeUnicode; +//# sourceMappingURL=normalize-unicode.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/normalize-windows-path.js b/node_modules/tar/dist/commonjs/normalize-windows-path.js new file mode 100644 index 0000000000000..b0c7aaa9f2d17 --- /dev/null +++ b/node_modules/tar/dist/commonjs/normalize-windows-path.js @@ -0,0 +1,12 @@ +"use strict"; +// on windows, either \ or / are valid directory separators. +// on unix, \ is a valid character in filenames. +// so, on windows, and only on windows, we replace all \ chars with /, +// so that we can use / as our one and only directory separator char. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.normalizeWindowsPath = void 0; +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; +exports.normalizeWindowsPath = platform !== 'win32' ? + (p) => p + : (p) => p && p.replace(/\\/g, '/'); +//# sourceMappingURL=normalize-windows-path.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/options.js b/node_modules/tar/dist/commonjs/options.js new file mode 100644 index 0000000000000..4cd06505bc72b --- /dev/null +++ b/node_modules/tar/dist/commonjs/options.js @@ -0,0 +1,66 @@ +"use strict"; +// turn tar(1) style args like `C` into the more verbose things like `cwd` +Object.defineProperty(exports, "__esModule", { value: true }); +exports.dealias = exports.isNoFile = exports.isFile = exports.isAsync = exports.isSync = exports.isAsyncNoFile = exports.isSyncNoFile = exports.isAsyncFile = exports.isSyncFile = void 0; +const argmap = new Map([ + ['C', 'cwd'], + ['f', 'file'], + ['z', 'gzip'], + ['P', 'preservePaths'], + ['U', 'unlink'], + ['strip-components', 'strip'], + ['stripComponents', 'strip'], + ['keep-newer', 'newer'], + ['keepNewer', 'newer'], + ['keep-newer-files', 'newer'], + ['keepNewerFiles', 'newer'], + ['k', 'keep'], + ['keep-existing', 'keep'], + ['keepExisting', 'keep'], + ['m', 'noMtime'], + ['no-mtime', 'noMtime'], + ['p', 'preserveOwner'], + ['L', 'follow'], + ['h', 'follow'], + ['onentry', 'onReadEntry'], +]); +const isSyncFile = (o) => !!o.sync && !!o.file; +exports.isSyncFile = isSyncFile; +const isAsyncFile = (o) => !o.sync && !!o.file; +exports.isAsyncFile = isAsyncFile; +const isSyncNoFile = (o) => !!o.sync && !o.file; +exports.isSyncNoFile = isSyncNoFile; +const isAsyncNoFile = (o) => !o.sync && !o.file; +exports.isAsyncNoFile = isAsyncNoFile; +const isSync = (o) => !!o.sync; +exports.isSync = isSync; +const isAsync = (o) => !o.sync; +exports.isAsync = isAsync; +const isFile = (o) => !!o.file; +exports.isFile = isFile; +const isNoFile = (o) => !o.file; +exports.isNoFile = isNoFile; +const dealiasKey = (k) => { + const d = argmap.get(k); + if (d) + return d; + return k; +}; +const dealias = (opt = {}) => { + if (!opt) + return {}; + const result = {}; + for (const [key, v] of Object.entries(opt)) { + // TS doesn't know that aliases are going to always be the same type + const k = dealiasKey(key); + result[k] = v; + } + // affordance for deprecated noChmod -> chmod + if (result.chmod === undefined && result.noChmod === false) { + result.chmod = true; + } + delete result.noChmod; + return result; +}; +exports.dealias = dealias; +//# sourceMappingURL=options.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/pack.js b/node_modules/tar/dist/commonjs/pack.js new file mode 100644 index 0000000000000..67de8272c71f5 --- /dev/null +++ b/node_modules/tar/dist/commonjs/pack.js @@ -0,0 +1,516 @@ +"use strict"; +// A readable tar stream creator +// Technically, this is a transform stream that you write paths into, +// and tar format comes out of. +// The `add()` method is like `write()` but returns this, +// and end() return `this` as well, so you can +// do `new Pack(opt).add('files').add('dir').end().pipe(output) +// You could also do something like: +// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar')) +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PackSync = exports.Pack = exports.PackJob = void 0; +const fs_1 = __importDefault(require("fs")); +const write_entry_js_1 = require("./write-entry.js"); +class PackJob { + path; + absolute; + entry; + stat; + readdir; + pending = false; + ignore = false; + piped = false; + constructor(path, absolute) { + this.path = path || './'; + this.absolute = absolute; + } +} +exports.PackJob = PackJob; +const minipass_1 = require("minipass"); +const zlib = __importStar(require("minizlib")); +const yallist_1 = require("yallist"); +const read_entry_js_1 = require("./read-entry.js"); +const warn_method_js_1 = require("./warn-method.js"); +const EOF = Buffer.alloc(1024); +const ONSTAT = Symbol('onStat'); +const ENDED = Symbol('ended'); +const QUEUE = Symbol('queue'); +const CURRENT = Symbol('current'); +const PROCESS = Symbol('process'); +const PROCESSING = Symbol('processing'); +const PROCESSJOB = Symbol('processJob'); +const JOBS = Symbol('jobs'); +const JOBDONE = Symbol('jobDone'); +const ADDFSENTRY = Symbol('addFSEntry'); +const ADDTARENTRY = Symbol('addTarEntry'); +const STAT = Symbol('stat'); +const READDIR = Symbol('readdir'); +const ONREADDIR = Symbol('onreaddir'); +const PIPE = Symbol('pipe'); +const ENTRY = Symbol('entry'); +const ENTRYOPT = Symbol('entryOpt'); +const WRITEENTRYCLASS = Symbol('writeEntryClass'); +const WRITE = Symbol('write'); +const ONDRAIN = Symbol('ondrain'); +const path_1 = __importDefault(require("path")); +const normalize_windows_path_js_1 = require("./normalize-windows-path.js"); +class Pack extends minipass_1.Minipass { + sync = false; + opt; + cwd; + maxReadSize; + preservePaths; + strict; + noPax; + prefix; + linkCache; + statCache; + file; + portable; + zip; + readdirCache; + noDirRecurse; + follow; + noMtime; + mtime; + filter; + jobs; + [WRITEENTRYCLASS]; + onWriteEntry; + // Note: we actually DO need a linked list here, because we + // shift() to update the head of the list where we start, but still + // while that happens, need to know what the next item in the queue + // will be. Since we do multiple jobs in parallel, it's not as simple + // as just an Array.shift(), since that would lose the information about + // the next job in the list. We could add a .next field on the PackJob + // class, but then we'd have to be tracking the tail of the queue the + // whole time, and Yallist just does that for us anyway. + [QUEUE]; + [JOBS] = 0; + [PROCESSING] = false; + [ENDED] = false; + constructor(opt = {}) { + //@ts-ignore + super(); + this.opt = opt; + this.file = opt.file || ''; + this.cwd = opt.cwd || process.cwd(); + this.maxReadSize = opt.maxReadSize; + this.preservePaths = !!opt.preservePaths; + this.strict = !!opt.strict; + this.noPax = !!opt.noPax; + this.prefix = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.prefix || ''); + this.linkCache = opt.linkCache || new Map(); + this.statCache = opt.statCache || new Map(); + this.readdirCache = opt.readdirCache || new Map(); + this.onWriteEntry = opt.onWriteEntry; + this[WRITEENTRYCLASS] = write_entry_js_1.WriteEntry; + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + this.portable = !!opt.portable; + if (opt.gzip || opt.brotli || opt.zstd) { + if ((opt.gzip ? 1 : 0) + + (opt.brotli ? 1 : 0) + + (opt.zstd ? 1 : 0) > + 1) { + throw new TypeError('gzip, brotli, zstd are mutually exclusive'); + } + if (opt.gzip) { + if (typeof opt.gzip !== 'object') { + opt.gzip = {}; + } + if (this.portable) { + opt.gzip.portable = true; + } + this.zip = new zlib.Gzip(opt.gzip); + } + if (opt.brotli) { + if (typeof opt.brotli !== 'object') { + opt.brotli = {}; + } + this.zip = new zlib.BrotliCompress(opt.brotli); + } + if (opt.zstd) { + if (typeof opt.zstd !== 'object') { + opt.zstd = {}; + } + this.zip = new zlib.ZstdCompress(opt.zstd); + } + /* c8 ignore next */ + if (!this.zip) + throw new Error('impossible'); + const zip = this.zip; + zip.on('data', chunk => super.write(chunk)); + zip.on('end', () => super.end()); + zip.on('drain', () => this[ONDRAIN]()); + this.on('resume', () => zip.resume()); + } + else { + this.on('drain', this[ONDRAIN]); + } + this.noDirRecurse = !!opt.noDirRecurse; + this.follow = !!opt.follow; + this.noMtime = !!opt.noMtime; + if (opt.mtime) + this.mtime = opt.mtime; + this.filter = + typeof opt.filter === 'function' ? opt.filter : () => true; + this[QUEUE] = new yallist_1.Yallist(); + this[JOBS] = 0; + this.jobs = Number(opt.jobs) || 4; + this[PROCESSING] = false; + this[ENDED] = false; + } + [WRITE](chunk) { + return super.write(chunk); + } + add(path) { + this.write(path); + return this; + } + end(path, encoding, cb) { + /* c8 ignore start */ + if (typeof path === 'function') { + cb = path; + path = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + /* c8 ignore stop */ + if (path) { + this.add(path); + } + this[ENDED] = true; + this[PROCESS](); + /* c8 ignore next */ + if (cb) + cb(); + return this; + } + write(path) { + if (this[ENDED]) { + throw new Error('write after end'); + } + if (path instanceof read_entry_js_1.ReadEntry) { + this[ADDTARENTRY](path); + } + else { + this[ADDFSENTRY](path); + } + return this.flowing; + } + [ADDTARENTRY](p) { + const absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path_1.default.resolve(this.cwd, p.path)); + // in this case, we don't have to wait for the stat + if (!this.filter(p.path, p)) { + p.resume(); + } + else { + const job = new PackJob(p.path, absolute); + job.entry = new write_entry_js_1.WriteEntryTar(p, this[ENTRYOPT](job)); + job.entry.on('end', () => this[JOBDONE](job)); + this[JOBS] += 1; + this[QUEUE].push(job); + } + this[PROCESS](); + } + [ADDFSENTRY](p) { + const absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path_1.default.resolve(this.cwd, p)); + this[QUEUE].push(new PackJob(p, absolute)); + this[PROCESS](); + } + [STAT](job) { + job.pending = true; + this[JOBS] += 1; + const stat = this.follow ? 'stat' : 'lstat'; + fs_1.default[stat](job.absolute, (er, stat) => { + job.pending = false; + this[JOBS] -= 1; + if (er) { + this.emit('error', er); + } + else { + this[ONSTAT](job, stat); + } + }); + } + [ONSTAT](job, stat) { + this.statCache.set(job.absolute, stat); + job.stat = stat; + // now we have the stat, we can filter it. + if (!this.filter(job.path, stat)) { + job.ignore = true; + } + else if (stat.isFile() && + stat.nlink > 1 && + job === this[CURRENT] && + !this.linkCache.get(`${stat.dev}:${stat.ino}`) && + !this.sync) { + // if it's not filtered, and it's a new File entry, + // jump the queue in case any pending Link entries are about + // to try to link to it. This prevents a hardlink from coming ahead + // of its target in the archive. + this[PROCESSJOB](job); + } + this[PROCESS](); + } + [READDIR](job) { + job.pending = true; + this[JOBS] += 1; + fs_1.default.readdir(job.absolute, (er, entries) => { + job.pending = false; + this[JOBS] -= 1; + if (er) { + return this.emit('error', er); + } + this[ONREADDIR](job, entries); + }); + } + [ONREADDIR](job, entries) { + this.readdirCache.set(job.absolute, entries); + job.readdir = entries; + this[PROCESS](); + } + [PROCESS]() { + if (this[PROCESSING]) { + return; + } + this[PROCESSING] = true; + for (let w = this[QUEUE].head; !!w && this[JOBS] < this.jobs; w = w.next) { + this[PROCESSJOB](w.value); + if (w.value.ignore) { + const p = w.next; + this[QUEUE].removeNode(w); + w.next = p; + } + } + this[PROCESSING] = false; + if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) { + if (this.zip) { + this.zip.end(EOF); + } + else { + super.write(EOF); + super.end(); + } + } + } + get [CURRENT]() { + return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value; + } + [JOBDONE](_job) { + this[QUEUE].shift(); + this[JOBS] -= 1; + this[PROCESS](); + } + [PROCESSJOB](job) { + if (job.pending) { + return; + } + if (job.entry) { + if (job === this[CURRENT] && !job.piped) { + this[PIPE](job); + } + return; + } + if (!job.stat) { + const sc = this.statCache.get(job.absolute); + if (sc) { + this[ONSTAT](job, sc); + } + else { + this[STAT](job); + } + } + if (!job.stat) { + return; + } + // filtered out! + if (job.ignore) { + return; + } + if (!this.noDirRecurse && + job.stat.isDirectory() && + !job.readdir) { + const rc = this.readdirCache.get(job.absolute); + if (rc) { + this[ONREADDIR](job, rc); + } + else { + this[READDIR](job); + } + if (!job.readdir) { + return; + } + } + // we know it doesn't have an entry, because that got checked above + job.entry = this[ENTRY](job); + if (!job.entry) { + job.ignore = true; + return; + } + if (job === this[CURRENT] && !job.piped) { + this[PIPE](job); + } + } + [ENTRYOPT](job) { + return { + onwarn: (code, msg, data) => this.warn(code, msg, data), + noPax: this.noPax, + cwd: this.cwd, + absolute: job.absolute, + preservePaths: this.preservePaths, + maxReadSize: this.maxReadSize, + strict: this.strict, + portable: this.portable, + linkCache: this.linkCache, + statCache: this.statCache, + noMtime: this.noMtime, + mtime: this.mtime, + prefix: this.prefix, + onWriteEntry: this.onWriteEntry, + }; + } + [ENTRY](job) { + this[JOBS] += 1; + try { + const e = new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job)); + return e + .on('end', () => this[JOBDONE](job)) + .on('error', er => this.emit('error', er)); + } + catch (er) { + this.emit('error', er); + } + } + [ONDRAIN]() { + if (this[CURRENT] && this[CURRENT].entry) { + this[CURRENT].entry.resume(); + } + } + // like .pipe() but using super, because our write() is special + [PIPE](job) { + job.piped = true; + if (job.readdir) { + job.readdir.forEach(entry => { + const p = job.path; + const base = p === './' ? '' : p.replace(/\/*$/, '/'); + this[ADDFSENTRY](base + entry); + }); + } + const source = job.entry; + const zip = this.zip; + /* c8 ignore start */ + if (!source) + throw new Error('cannot pipe without source'); + /* c8 ignore stop */ + if (zip) { + source.on('data', chunk => { + if (!zip.write(chunk)) { + source.pause(); + } + }); + } + else { + source.on('data', chunk => { + if (!super.write(chunk)) { + source.pause(); + } + }); + } + } + pause() { + if (this.zip) { + this.zip.pause(); + } + return super.pause(); + } + warn(code, message, data = {}) { + (0, warn_method_js_1.warnMethod)(this, code, message, data); + } +} +exports.Pack = Pack; +class PackSync extends Pack { + sync = true; + constructor(opt) { + super(opt); + this[WRITEENTRYCLASS] = write_entry_js_1.WriteEntrySync; + } + // pause/resume are no-ops in sync streams. + pause() { } + resume() { } + [STAT](job) { + const stat = this.follow ? 'statSync' : 'lstatSync'; + this[ONSTAT](job, fs_1.default[stat](job.absolute)); + } + [READDIR](job) { + this[ONREADDIR](job, fs_1.default.readdirSync(job.absolute)); + } + // gotta get it all in this tick + [PIPE](job) { + const source = job.entry; + const zip = this.zip; + if (job.readdir) { + job.readdir.forEach(entry => { + const p = job.path; + const base = p === './' ? '' : p.replace(/\/*$/, '/'); + this[ADDFSENTRY](base + entry); + }); + } + /* c8 ignore start */ + if (!source) + throw new Error('Cannot pipe without source'); + /* c8 ignore stop */ + if (zip) { + source.on('data', chunk => { + zip.write(chunk); + }); + } + else { + source.on('data', chunk => { + super[WRITE](chunk); + }); + } + } +} +exports.PackSync = PackSync; +//# sourceMappingURL=pack.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/package.json b/node_modules/tar/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/tar/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/tar/dist/commonjs/parse.js b/node_modules/tar/dist/commonjs/parse.js new file mode 100644 index 0000000000000..db7b0124a3c05 --- /dev/null +++ b/node_modules/tar/dist/commonjs/parse.js @@ -0,0 +1,620 @@ +"use strict"; +// this[BUFFER] is the remainder of a chunk if we're waiting for +// the full 512 bytes of a header to come in. We will Buffer.concat() +// it to the next write(), which is a mem copy, but a small one. +// +// this[QUEUE] is a list of entries that haven't been emitted +// yet this can only get filled up if the user keeps write()ing after +// a write() returns false, or does a write() with more than one entry +// +// We don't buffer chunks, we always parse them and either create an +// entry, or push it into the active entry. The ReadEntry class knows +// to throw data away if .ignore=true +// +// Shift entry off the buffer when it emits 'end', and emit 'entry' for +// the next one in the list. +// +// At any time, we're pushing body chunks into the entry at WRITEENTRY, +// and waiting for 'end' on the entry at READENTRY +// +// ignored entries get .resume() called on them straight away +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Parser = void 0; +const events_1 = require("events"); +const minizlib_1 = require("minizlib"); +const header_js_1 = require("./header.js"); +const pax_js_1 = require("./pax.js"); +const read_entry_js_1 = require("./read-entry.js"); +const warn_method_js_1 = require("./warn-method.js"); +const maxMetaEntrySize = 1024 * 1024; +const gzipHeader = Buffer.from([0x1f, 0x8b]); +const zstdHeader = Buffer.from([0x28, 0xb5, 0x2f, 0xfd]); +const ZIP_HEADER_LEN = Math.max(gzipHeader.length, zstdHeader.length); +const STATE = Symbol('state'); +const WRITEENTRY = Symbol('writeEntry'); +const READENTRY = Symbol('readEntry'); +const NEXTENTRY = Symbol('nextEntry'); +const PROCESSENTRY = Symbol('processEntry'); +const EX = Symbol('extendedHeader'); +const GEX = Symbol('globalExtendedHeader'); +const META = Symbol('meta'); +const EMITMETA = Symbol('emitMeta'); +const BUFFER = Symbol('buffer'); +const QUEUE = Symbol('queue'); +const ENDED = Symbol('ended'); +const EMITTEDEND = Symbol('emittedEnd'); +const EMIT = Symbol('emit'); +const UNZIP = Symbol('unzip'); +const CONSUMECHUNK = Symbol('consumeChunk'); +const CONSUMECHUNKSUB = Symbol('consumeChunkSub'); +const CONSUMEBODY = Symbol('consumeBody'); +const CONSUMEMETA = Symbol('consumeMeta'); +const CONSUMEHEADER = Symbol('consumeHeader'); +const CONSUMING = Symbol('consuming'); +const BUFFERCONCAT = Symbol('bufferConcat'); +const MAYBEEND = Symbol('maybeEnd'); +const WRITING = Symbol('writing'); +const ABORTED = Symbol('aborted'); +const DONE = Symbol('onDone'); +const SAW_VALID_ENTRY = Symbol('sawValidEntry'); +const SAW_NULL_BLOCK = Symbol('sawNullBlock'); +const SAW_EOF = Symbol('sawEOF'); +const CLOSESTREAM = Symbol('closeStream'); +const noop = () => true; +class Parser extends events_1.EventEmitter { + file; + strict; + maxMetaEntrySize; + filter; + brotli; + zstd; + writable = true; + readable = false; + [QUEUE] = []; + [BUFFER]; + [READENTRY]; + [WRITEENTRY]; + [STATE] = 'begin'; + [META] = ''; + [EX]; + [GEX]; + [ENDED] = false; + [UNZIP]; + [ABORTED] = false; + [SAW_VALID_ENTRY]; + [SAW_NULL_BLOCK] = false; + [SAW_EOF] = false; + [WRITING] = false; + [CONSUMING] = false; + [EMITTEDEND] = false; + constructor(opt = {}) { + super(); + this.file = opt.file || ''; + // these BADARCHIVE errors can't be detected early. listen on DONE. + this.on(DONE, () => { + if (this[STATE] === 'begin' || + this[SAW_VALID_ENTRY] === false) { + // either less than 1 block of data, or all entries were invalid. + // Either way, probably not even a tarball. + this.warn('TAR_BAD_ARCHIVE', 'Unrecognized archive format'); + } + }); + if (opt.ondone) { + this.on(DONE, opt.ondone); + } + else { + this.on(DONE, () => { + this.emit('prefinish'); + this.emit('finish'); + this.emit('end'); + }); + } + this.strict = !!opt.strict; + this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize; + this.filter = typeof opt.filter === 'function' ? opt.filter : noop; + // Unlike gzip, brotli doesn't have any magic bytes to identify it + // Users need to explicitly tell us they're extracting a brotli file + // Or we infer from the file extension + const isTBR = opt.file && + (opt.file.endsWith('.tar.br') || opt.file.endsWith('.tbr')); + // if it's a tbr file it MIGHT be brotli, but we don't know until + // we look at it and verify it's not a valid tar file. + this.brotli = + !(opt.gzip || opt.zstd) && opt.brotli !== undefined ? opt.brotli + : isTBR ? undefined + : false; + // zstd has magic bytes to identify it, but we also support explicit options + // and file extension detection + const isTZST = opt.file && + (opt.file.endsWith('.tar.zst') || opt.file.endsWith('.tzst')); + this.zstd = + !(opt.gzip || opt.brotli) && opt.zstd !== undefined ? opt.zstd + : isTZST ? true + : undefined; + // have to set this so that streams are ok piping into it + this.on('end', () => this[CLOSESTREAM]()); + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + if (typeof opt.onReadEntry === 'function') { + this.on('entry', opt.onReadEntry); + } + } + warn(code, message, data = {}) { + (0, warn_method_js_1.warnMethod)(this, code, message, data); + } + [CONSUMEHEADER](chunk, position) { + if (this[SAW_VALID_ENTRY] === undefined) { + this[SAW_VALID_ENTRY] = false; + } + let header; + try { + header = new header_js_1.Header(chunk, position, this[EX], this[GEX]); + } + catch (er) { + return this.warn('TAR_ENTRY_INVALID', er); + } + if (header.nullBlock) { + if (this[SAW_NULL_BLOCK]) { + this[SAW_EOF] = true; + // ending an archive with no entries. pointless, but legal. + if (this[STATE] === 'begin') { + this[STATE] = 'header'; + } + this[EMIT]('eof'); + } + else { + this[SAW_NULL_BLOCK] = true; + this[EMIT]('nullBlock'); + } + } + else { + this[SAW_NULL_BLOCK] = false; + if (!header.cksumValid) { + this.warn('TAR_ENTRY_INVALID', 'checksum failure', { header }); + } + else if (!header.path) { + this.warn('TAR_ENTRY_INVALID', 'path is required', { header }); + } + else { + const type = header.type; + if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) { + this.warn('TAR_ENTRY_INVALID', 'linkpath required', { + header, + }); + } + else if (!/^(Symbolic)?Link$/.test(type) && + !/^(Global)?ExtendedHeader$/.test(type) && + header.linkpath) { + this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', { + header, + }); + } + else { + const entry = (this[WRITEENTRY] = new read_entry_js_1.ReadEntry(header, this[EX], this[GEX])); + // we do this for meta & ignored entries as well, because they + // are still valid tar, or else we wouldn't know to ignore them + if (!this[SAW_VALID_ENTRY]) { + if (entry.remain) { + // this might be the one! + const onend = () => { + if (!entry.invalid) { + this[SAW_VALID_ENTRY] = true; + } + }; + entry.on('end', onend); + } + else { + this[SAW_VALID_ENTRY] = true; + } + } + if (entry.meta) { + if (entry.size > this.maxMetaEntrySize) { + entry.ignore = true; + this[EMIT]('ignoredEntry', entry); + this[STATE] = 'ignore'; + entry.resume(); + } + else if (entry.size > 0) { + this[META] = ''; + entry.on('data', c => (this[META] += c)); + this[STATE] = 'meta'; + } + } + else { + this[EX] = undefined; + entry.ignore = + entry.ignore || !this.filter(entry.path, entry); + if (entry.ignore) { + // probably valid, just not something we care about + this[EMIT]('ignoredEntry', entry); + this[STATE] = entry.remain ? 'ignore' : 'header'; + entry.resume(); + } + else { + if (entry.remain) { + this[STATE] = 'body'; + } + else { + this[STATE] = 'header'; + entry.end(); + } + if (!this[READENTRY]) { + this[QUEUE].push(entry); + this[NEXTENTRY](); + } + else { + this[QUEUE].push(entry); + } + } + } + } + } + } + } + [CLOSESTREAM]() { + queueMicrotask(() => this.emit('close')); + } + [PROCESSENTRY](entry) { + let go = true; + if (!entry) { + this[READENTRY] = undefined; + go = false; + } + else if (Array.isArray(entry)) { + const [ev, ...args] = entry; + this.emit(ev, ...args); + } + else { + this[READENTRY] = entry; + this.emit('entry', entry); + if (!entry.emittedEnd) { + entry.on('end', () => this[NEXTENTRY]()); + go = false; + } + } + return go; + } + [NEXTENTRY]() { + do { } while (this[PROCESSENTRY](this[QUEUE].shift())); + if (!this[QUEUE].length) { + // At this point, there's nothing in the queue, but we may have an + // entry which is being consumed (readEntry). + // If we don't, then we definitely can handle more data. + // If we do, and either it's flowing, or it has never had any data + // written to it, then it needs more. + // The only other possibility is that it has returned false from a + // write() call, so we wait for the next drain to continue. + const re = this[READENTRY]; + const drainNow = !re || re.flowing || re.size === re.remain; + if (drainNow) { + if (!this[WRITING]) { + this.emit('drain'); + } + } + else { + re.once('drain', () => this.emit('drain')); + } + } + } + [CONSUMEBODY](chunk, position) { + // write up to but no more than writeEntry.blockRemain + const entry = this[WRITEENTRY]; + /* c8 ignore start */ + if (!entry) { + throw new Error('attempt to consume body without entry??'); + } + const br = entry.blockRemain ?? 0; + /* c8 ignore stop */ + const c = br >= chunk.length && position === 0 ? + chunk + : chunk.subarray(position, position + br); + entry.write(c); + if (!entry.blockRemain) { + this[STATE] = 'header'; + this[WRITEENTRY] = undefined; + entry.end(); + } + return c.length; + } + [CONSUMEMETA](chunk, position) { + const entry = this[WRITEENTRY]; + const ret = this[CONSUMEBODY](chunk, position); + // if we finished, then the entry is reset + if (!this[WRITEENTRY] && entry) { + this[EMITMETA](entry); + } + return ret; + } + [EMIT](ev, data, extra) { + if (!this[QUEUE].length && !this[READENTRY]) { + this.emit(ev, data, extra); + } + else { + this[QUEUE].push([ev, data, extra]); + } + } + [EMITMETA](entry) { + this[EMIT]('meta', this[META]); + switch (entry.type) { + case 'ExtendedHeader': + case 'OldExtendedHeader': + this[EX] = pax_js_1.Pax.parse(this[META], this[EX], false); + break; + case 'GlobalExtendedHeader': + this[GEX] = pax_js_1.Pax.parse(this[META], this[GEX], true); + break; + case 'NextFileHasLongPath': + case 'OldGnuLongPath': { + const ex = this[EX] ?? Object.create(null); + this[EX] = ex; + ex.path = this[META].replace(/\0.*/, ''); + break; + } + case 'NextFileHasLongLinkpath': { + const ex = this[EX] || Object.create(null); + this[EX] = ex; + ex.linkpath = this[META].replace(/\0.*/, ''); + break; + } + /* c8 ignore start */ + default: + throw new Error('unknown meta: ' + entry.type); + /* c8 ignore stop */ + } + } + abort(error) { + this[ABORTED] = true; + this.emit('abort', error); + // always throws, even in non-strict mode + this.warn('TAR_ABORT', error, { recoverable: false }); + } + write(chunk, encoding, cb) { + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, + /* c8 ignore next */ + typeof encoding === 'string' ? encoding : 'utf8'); + } + if (this[ABORTED]) { + /* c8 ignore next */ + cb?.(); + return false; + } + // first write, might be gzipped, zstd, or brotli compressed + const needSniff = this[UNZIP] === undefined || + (this.brotli === undefined && this[UNZIP] === false); + if (needSniff && chunk) { + if (this[BUFFER]) { + chunk = Buffer.concat([this[BUFFER], chunk]); + this[BUFFER] = undefined; + } + if (chunk.length < ZIP_HEADER_LEN) { + this[BUFFER] = chunk; + /* c8 ignore next */ + cb?.(); + return true; + } + // look for gzip header + for (let i = 0; this[UNZIP] === undefined && i < gzipHeader.length; i++) { + if (chunk[i] !== gzipHeader[i]) { + this[UNZIP] = false; + } + } + // look for zstd header if gzip header not found + let isZstd = false; + if (this[UNZIP] === false && this.zstd !== false) { + isZstd = true; + for (let i = 0; i < zstdHeader.length; i++) { + if (chunk[i] !== zstdHeader[i]) { + isZstd = false; + break; + } + } + } + const maybeBrotli = this.brotli === undefined && !isZstd; + if (this[UNZIP] === false && maybeBrotli) { + // read the first header to see if it's a valid tar file. If so, + // we can safely assume that it's not actually brotli, despite the + // .tbr or .tar.br file extension. + // if we ended before getting a full chunk, yes, def brotli + if (chunk.length < 512) { + if (this[ENDED]) { + this.brotli = true; + } + else { + this[BUFFER] = chunk; + /* c8 ignore next */ + cb?.(); + return true; + } + } + else { + // if it's tar, it's pretty reliably not brotli, chances of + // that happening are astronomical. + try { + new header_js_1.Header(chunk.subarray(0, 512)); + this.brotli = false; + } + catch (_) { + this.brotli = true; + } + } + } + if (this[UNZIP] === undefined || + (this[UNZIP] === false && (this.brotli || isZstd))) { + const ended = this[ENDED]; + this[ENDED] = false; + this[UNZIP] = + this[UNZIP] === undefined ? new minizlib_1.Unzip({}) + : isZstd ? new minizlib_1.ZstdDecompress({}) + : new minizlib_1.BrotliDecompress({}); + this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)); + this[UNZIP].on('error', er => this.abort(er)); + this[UNZIP].on('end', () => { + this[ENDED] = true; + this[CONSUMECHUNK](); + }); + this[WRITING] = true; + const ret = !!this[UNZIP][ended ? 'end' : 'write'](chunk); + this[WRITING] = false; + cb?.(); + return ret; + } + } + this[WRITING] = true; + if (this[UNZIP]) { + this[UNZIP].write(chunk); + } + else { + this[CONSUMECHUNK](chunk); + } + this[WRITING] = false; + // return false if there's a queue, or if the current entry isn't flowing + const ret = this[QUEUE].length ? false + : this[READENTRY] ? this[READENTRY].flowing + : true; + // if we have no queue, then that means a clogged READENTRY + if (!ret && !this[QUEUE].length) { + this[READENTRY]?.once('drain', () => this.emit('drain')); + } + /* c8 ignore next */ + cb?.(); + return ret; + } + [BUFFERCONCAT](c) { + if (c && !this[ABORTED]) { + this[BUFFER] = + this[BUFFER] ? Buffer.concat([this[BUFFER], c]) : c; + } + } + [MAYBEEND]() { + if (this[ENDED] && + !this[EMITTEDEND] && + !this[ABORTED] && + !this[CONSUMING]) { + this[EMITTEDEND] = true; + const entry = this[WRITEENTRY]; + if (entry && entry.blockRemain) { + // truncated, likely a damaged file + const have = this[BUFFER] ? this[BUFFER].length : 0; + this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${entry.blockRemain} more bytes, only ${have} available)`, { entry }); + if (this[BUFFER]) { + entry.write(this[BUFFER]); + } + entry.end(); + } + this[EMIT](DONE); + } + } + [CONSUMECHUNK](chunk) { + if (this[CONSUMING] && chunk) { + this[BUFFERCONCAT](chunk); + } + else if (!chunk && !this[BUFFER]) { + this[MAYBEEND](); + } + else if (chunk) { + this[CONSUMING] = true; + if (this[BUFFER]) { + this[BUFFERCONCAT](chunk); + const c = this[BUFFER]; + this[BUFFER] = undefined; + this[CONSUMECHUNKSUB](c); + } + else { + this[CONSUMECHUNKSUB](chunk); + } + while (this[BUFFER] && + this[BUFFER]?.length >= 512 && + !this[ABORTED] && + !this[SAW_EOF]) { + const c = this[BUFFER]; + this[BUFFER] = undefined; + this[CONSUMECHUNKSUB](c); + } + this[CONSUMING] = false; + } + if (!this[BUFFER] || this[ENDED]) { + this[MAYBEEND](); + } + } + [CONSUMECHUNKSUB](chunk) { + // we know that we are in CONSUMING mode, so anything written goes into + // the buffer. Advance the position and put any remainder in the buffer. + let position = 0; + const length = chunk.length; + while (position + 512 <= length && + !this[ABORTED] && + !this[SAW_EOF]) { + switch (this[STATE]) { + case 'begin': + case 'header': + this[CONSUMEHEADER](chunk, position); + position += 512; + break; + case 'ignore': + case 'body': + position += this[CONSUMEBODY](chunk, position); + break; + case 'meta': + position += this[CONSUMEMETA](chunk, position); + break; + /* c8 ignore start */ + default: + throw new Error('invalid state: ' + this[STATE]); + /* c8 ignore stop */ + } + } + if (position < length) { + if (this[BUFFER]) { + this[BUFFER] = Buffer.concat([ + chunk.subarray(position), + this[BUFFER], + ]); + } + else { + this[BUFFER] = chunk.subarray(position); + } + } + } + end(chunk, encoding, cb) { + if (typeof chunk === 'function') { + cb = chunk; + encoding = undefined; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + if (cb) + this.once('finish', cb); + if (!this[ABORTED]) { + if (this[UNZIP]) { + /* c8 ignore start */ + if (chunk) + this[UNZIP].write(chunk); + /* c8 ignore stop */ + this[UNZIP].end(); + } + else { + this[ENDED] = true; + if (this.brotli === undefined || this.zstd === undefined) + chunk = chunk || Buffer.alloc(0); + if (chunk) + this.write(chunk); + this[MAYBEEND](); + } + } + return this; + } +} +exports.Parser = Parser; +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/path-reservations.js b/node_modules/tar/dist/commonjs/path-reservations.js new file mode 100644 index 0000000000000..525d233b2a45f --- /dev/null +++ b/node_modules/tar/dist/commonjs/path-reservations.js @@ -0,0 +1,170 @@ +"use strict"; +// A path exclusive reservation system +// reserve([list, of, paths], fn) +// When the fn is first in line for all its paths, it +// is called with a cb that clears the reservation. +// +// Used by async unpack to avoid clobbering paths in use, +// while still allowing maximal safe parallelization. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PathReservations = void 0; +const node_path_1 = require("node:path"); +const normalize_unicode_js_1 = require("./normalize-unicode.js"); +const strip_trailing_slashes_js_1 = require("./strip-trailing-slashes.js"); +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; +const isWindows = platform === 'win32'; +// return a set of parent dirs for a given path +// '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d'] +const getDirs = (path) => { + const dirs = path + .split('/') + .slice(0, -1) + .reduce((set, path) => { + const s = set[set.length - 1]; + if (s !== undefined) { + path = (0, node_path_1.join)(s, path); + } + set.push(path || '/'); + return set; + }, []); + return dirs; +}; +class PathReservations { + // path => [function or Set] + // A Set object means a directory reservation + // A fn is a direct reservation on that path + #queues = new Map(); + // fn => {paths:[path,...], dirs:[path, ...]} + #reservations = new Map(); + // functions currently running + #running = new Set(); + reserve(paths, fn) { + paths = + isWindows ? + ['win32 parallelization disabled'] + : paths.map(p => { + // don't need normPath, because we skip this entirely for windows + return (0, strip_trailing_slashes_js_1.stripTrailingSlashes)((0, node_path_1.join)((0, normalize_unicode_js_1.normalizeUnicode)(p))); + }); + const dirs = new Set(paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b))); + this.#reservations.set(fn, { dirs, paths }); + for (const p of paths) { + const q = this.#queues.get(p); + if (!q) { + this.#queues.set(p, [fn]); + } + else { + q.push(fn); + } + } + for (const dir of dirs) { + const q = this.#queues.get(dir); + if (!q) { + this.#queues.set(dir, [new Set([fn])]); + } + else { + const l = q[q.length - 1]; + if (l instanceof Set) { + l.add(fn); + } + else { + q.push(new Set([fn])); + } + } + } + return this.#run(fn); + } + // return the queues for each path the function cares about + // fn => {paths, dirs} + #getQueues(fn) { + const res = this.#reservations.get(fn); + /* c8 ignore start */ + if (!res) { + throw new Error('function does not have any path reservations'); + } + /* c8 ignore stop */ + return { + paths: res.paths.map((path) => this.#queues.get(path)), + dirs: [...res.dirs].map(path => this.#queues.get(path)), + }; + } + // check if fn is first in line for all its paths, and is + // included in the first set for all its dir queues + check(fn) { + const { paths, dirs } = this.#getQueues(fn); + return (paths.every(q => q && q[0] === fn) && + dirs.every(q => q && q[0] instanceof Set && q[0].has(fn))); + } + // run the function if it's first in line and not already running + #run(fn) { + if (this.#running.has(fn) || !this.check(fn)) { + return false; + } + this.#running.add(fn); + fn(() => this.#clear(fn)); + return true; + } + #clear(fn) { + if (!this.#running.has(fn)) { + return false; + } + const res = this.#reservations.get(fn); + /* c8 ignore start */ + if (!res) { + throw new Error('invalid reservation'); + } + /* c8 ignore stop */ + const { paths, dirs } = res; + const next = new Set(); + for (const path of paths) { + const q = this.#queues.get(path); + /* c8 ignore start */ + if (!q || q?.[0] !== fn) { + continue; + } + /* c8 ignore stop */ + const q0 = q[1]; + if (!q0) { + this.#queues.delete(path); + continue; + } + q.shift(); + if (typeof q0 === 'function') { + next.add(q0); + } + else { + for (const f of q0) { + next.add(f); + } + } + } + for (const dir of dirs) { + const q = this.#queues.get(dir); + const q0 = q?.[0]; + /* c8 ignore next - type safety only */ + if (!q || !(q0 instanceof Set)) + continue; + if (q0.size === 1 && q.length === 1) { + this.#queues.delete(dir); + continue; + } + else if (q0.size === 1) { + q.shift(); + // next one must be a function, + // or else the Set would've been reused + const n = q[0]; + if (typeof n === 'function') { + next.add(n); + } + } + else { + q0.delete(fn); + } + } + this.#running.delete(fn); + next.forEach(fn => this.#run(fn)); + return true; + } +} +exports.PathReservations = PathReservations; +//# sourceMappingURL=path-reservations.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/pax.js b/node_modules/tar/dist/commonjs/pax.js new file mode 100644 index 0000000000000..d30c0f3efbe9e --- /dev/null +++ b/node_modules/tar/dist/commonjs/pax.js @@ -0,0 +1,158 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Pax = void 0; +const node_path_1 = require("node:path"); +const header_js_1 = require("./header.js"); +class Pax { + atime; + mtime; + ctime; + charset; + comment; + gid; + uid; + gname; + uname; + linkpath; + dev; + ino; + nlink; + path; + size; + mode; + global; + constructor(obj, global = false) { + this.atime = obj.atime; + this.charset = obj.charset; + this.comment = obj.comment; + this.ctime = obj.ctime; + this.dev = obj.dev; + this.gid = obj.gid; + this.global = global; + this.gname = obj.gname; + this.ino = obj.ino; + this.linkpath = obj.linkpath; + this.mtime = obj.mtime; + this.nlink = obj.nlink; + this.path = obj.path; + this.size = obj.size; + this.uid = obj.uid; + this.uname = obj.uname; + } + encode() { + const body = this.encodeBody(); + if (body === '') { + return Buffer.allocUnsafe(0); + } + const bodyLen = Buffer.byteLength(body); + // round up to 512 bytes + // add 512 for header + const bufLen = 512 * Math.ceil(1 + bodyLen / 512); + const buf = Buffer.allocUnsafe(bufLen); + // 0-fill the header section, it might not hit every field + for (let i = 0; i < 512; i++) { + buf[i] = 0; + } + new header_js_1.Header({ + // XXX split the path + // then the path should be PaxHeader + basename, but less than 99, + // prepend with the dirname + /* c8 ignore start */ + path: ('PaxHeader/' + (0, node_path_1.basename)(this.path ?? '')).slice(0, 99), + /* c8 ignore stop */ + mode: this.mode || 0o644, + uid: this.uid, + gid: this.gid, + size: bodyLen, + mtime: this.mtime, + type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader', + linkpath: '', + uname: this.uname || '', + gname: this.gname || '', + devmaj: 0, + devmin: 0, + atime: this.atime, + ctime: this.ctime, + }).encode(buf); + buf.write(body, 512, bodyLen, 'utf8'); + // null pad after the body + for (let i = bodyLen + 512; i < buf.length; i++) { + buf[i] = 0; + } + return buf; + } + encodeBody() { + return (this.encodeField('path') + + this.encodeField('ctime') + + this.encodeField('atime') + + this.encodeField('dev') + + this.encodeField('ino') + + this.encodeField('nlink') + + this.encodeField('charset') + + this.encodeField('comment') + + this.encodeField('gid') + + this.encodeField('gname') + + this.encodeField('linkpath') + + this.encodeField('mtime') + + this.encodeField('size') + + this.encodeField('uid') + + this.encodeField('uname')); + } + encodeField(field) { + if (this[field] === undefined) { + return ''; + } + const r = this[field]; + const v = r instanceof Date ? r.getTime() / 1000 : r; + const s = ' ' + + (field === 'dev' || field === 'ino' || field === 'nlink' ? + 'SCHILY.' + : '') + + field + + '=' + + v + + '\n'; + const byteLen = Buffer.byteLength(s); + // the digits includes the length of the digits in ascii base-10 + // so if it's 9 characters, then adding 1 for the 9 makes it 10 + // which makes it 11 chars. + let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1; + if (byteLen + digits >= Math.pow(10, digits)) { + digits += 1; + } + const len = digits + byteLen; + return len + s; + } + static parse(str, ex, g = false) { + return new Pax(merge(parseKV(str), ex), g); + } +} +exports.Pax = Pax; +const merge = (a, b) => b ? Object.assign({}, b, a) : a; +const parseKV = (str) => str + .replace(/\n$/, '') + .split('\n') + .reduce(parseKVLine, Object.create(null)); +const parseKVLine = (set, line) => { + const n = parseInt(line, 10); + // XXX Values with \n in them will fail this. + // Refactor to not be a naive line-by-line parse. + if (n !== Buffer.byteLength(line) + 1) { + return set; + } + line = line.slice((n + ' ').length); + const kv = line.split('='); + const r = kv.shift(); + if (!r) { + return set; + } + const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1'); + const v = kv.join('='); + set[k] = + /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ? + new Date(Number(v) * 1000) + : /^[0-9]+$/.test(v) ? +v + : v; + return set; +}; +//# sourceMappingURL=pax.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/read-entry.js b/node_modules/tar/dist/commonjs/read-entry.js new file mode 100644 index 0000000000000..15e2d55c938a4 --- /dev/null +++ b/node_modules/tar/dist/commonjs/read-entry.js @@ -0,0 +1,140 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ReadEntry = void 0; +const minipass_1 = require("minipass"); +const normalize_windows_path_js_1 = require("./normalize-windows-path.js"); +class ReadEntry extends minipass_1.Minipass { + extended; + globalExtended; + header; + startBlockSize; + blockRemain; + remain; + type; + meta = false; + ignore = false; + path; + mode; + uid; + gid; + uname; + gname; + size = 0; + mtime; + atime; + ctime; + linkpath; + dev; + ino; + nlink; + invalid = false; + absolute; + unsupported = false; + constructor(header, ex, gex) { + super({}); + // read entries always start life paused. this is to avoid the + // situation where Minipass's auto-ending empty streams results + // in an entry ending before we're ready for it. + this.pause(); + this.extended = ex; + this.globalExtended = gex; + this.header = header; + /* c8 ignore start */ + this.remain = header.size ?? 0; + /* c8 ignore stop */ + this.startBlockSize = 512 * Math.ceil(this.remain / 512); + this.blockRemain = this.startBlockSize; + this.type = header.type; + switch (this.type) { + case 'File': + case 'OldFile': + case 'Link': + case 'SymbolicLink': + case 'CharacterDevice': + case 'BlockDevice': + case 'Directory': + case 'FIFO': + case 'ContiguousFile': + case 'GNUDumpDir': + break; + case 'NextFileHasLongLinkpath': + case 'NextFileHasLongPath': + case 'OldGnuLongPath': + case 'GlobalExtendedHeader': + case 'ExtendedHeader': + case 'OldExtendedHeader': + this.meta = true; + break; + // NOTE: gnutar and bsdtar treat unrecognized types as 'File' + // it may be worth doing the same, but with a warning. + default: + this.ignore = true; + } + /* c8 ignore start */ + if (!header.path) { + throw new Error('no path provided for tar.ReadEntry'); + } + /* c8 ignore stop */ + this.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(header.path); + this.mode = header.mode; + if (this.mode) { + this.mode = this.mode & 0o7777; + } + this.uid = header.uid; + this.gid = header.gid; + this.uname = header.uname; + this.gname = header.gname; + this.size = this.remain; + this.mtime = header.mtime; + this.atime = header.atime; + this.ctime = header.ctime; + /* c8 ignore start */ + this.linkpath = + header.linkpath ? + (0, normalize_windows_path_js_1.normalizeWindowsPath)(header.linkpath) + : undefined; + /* c8 ignore stop */ + this.uname = header.uname; + this.gname = header.gname; + if (ex) { + this.#slurp(ex); + } + if (gex) { + this.#slurp(gex, true); + } + } + write(data) { + const writeLen = data.length; + if (writeLen > this.blockRemain) { + throw new Error('writing more to entry than is appropriate'); + } + const r = this.remain; + const br = this.blockRemain; + this.remain = Math.max(0, r - writeLen); + this.blockRemain = Math.max(0, br - writeLen); + if (this.ignore) { + return true; + } + if (r >= writeLen) { + return super.write(data); + } + // r < writeLen + return super.write(data.subarray(0, r)); + } + #slurp(ex, gex = false) { + if (ex.path) + ex.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(ex.path); + if (ex.linkpath) + ex.linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(ex.linkpath); + Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. Also, any + // null/undefined values are ignored. + return !(v === null || + v === undefined || + (k === 'path' && gex)); + }))); + } +} +exports.ReadEntry = ReadEntry; +//# sourceMappingURL=read-entry.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/replace.js b/node_modules/tar/dist/commonjs/replace.js new file mode 100644 index 0000000000000..5442c2a5bde5e --- /dev/null +++ b/node_modules/tar/dist/commonjs/replace.js @@ -0,0 +1,232 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.replace = void 0; +// tar -r +const fs_minipass_1 = require("@isaacs/fs-minipass"); +const node_fs_1 = __importDefault(require("node:fs")); +const node_path_1 = __importDefault(require("node:path")); +const header_js_1 = require("./header.js"); +const list_js_1 = require("./list.js"); +const make_command_js_1 = require("./make-command.js"); +const options_js_1 = require("./options.js"); +const pack_js_1 = require("./pack.js"); +// starting at the head of the file, read a Header +// If the checksum is invalid, that's our position to start writing +// If it is, jump forward by the specified size (round up to 512) +// and try again. +// Write the new Pack stream starting there. +const replaceSync = (opt, files) => { + const p = new pack_js_1.PackSync(opt); + let threw = true; + let fd; + let position; + try { + try { + fd = node_fs_1.default.openSync(opt.file, 'r+'); + } + catch (er) { + if (er?.code === 'ENOENT') { + fd = node_fs_1.default.openSync(opt.file, 'w+'); + } + else { + throw er; + } + } + const st = node_fs_1.default.fstatSync(fd); + const headBuf = Buffer.alloc(512); + POSITION: for (position = 0; position < st.size; position += 512) { + for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) { + bytes = node_fs_1.default.readSync(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos); + if (position === 0 && + headBuf[0] === 0x1f && + headBuf[1] === 0x8b) { + throw new Error('cannot append to compressed archives'); + } + if (!bytes) { + break POSITION; + } + } + const h = new header_js_1.Header(headBuf); + if (!h.cksumValid) { + break; + } + const entryBlockSize = 512 * Math.ceil((h.size || 0) / 512); + if (position + entryBlockSize + 512 > st.size) { + break; + } + // the 512 for the header we just parsed will be added as well + // also jump ahead all the blocks for the body + position += entryBlockSize; + if (opt.mtimeCache && h.mtime) { + opt.mtimeCache.set(String(h.path), h.mtime); + } + } + threw = false; + streamSync(opt, p, position, fd, files); + } + finally { + if (threw) { + try { + node_fs_1.default.closeSync(fd); + } + catch (er) { } + } + } +}; +const streamSync = (opt, p, position, fd, files) => { + const stream = new fs_minipass_1.WriteStreamSync(opt.file, { + fd: fd, + start: position, + }); + p.pipe(stream); + addFilesSync(p, files); +}; +const replaceAsync = (opt, files) => { + files = Array.from(files); + const p = new pack_js_1.Pack(opt); + const getPos = (fd, size, cb_) => { + const cb = (er, pos) => { + if (er) { + node_fs_1.default.close(fd, _ => cb_(er)); + } + else { + cb_(null, pos); + } + }; + let position = 0; + if (size === 0) { + return cb(null, 0); + } + let bufPos = 0; + const headBuf = Buffer.alloc(512); + const onread = (er, bytes) => { + if (er || typeof bytes === 'undefined') { + return cb(er); + } + bufPos += bytes; + if (bufPos < 512 && bytes) { + return node_fs_1.default.read(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos, onread); + } + if (position === 0 && + headBuf[0] === 0x1f && + headBuf[1] === 0x8b) { + return cb(new Error('cannot append to compressed archives')); + } + // truncated header + if (bufPos < 512) { + return cb(null, position); + } + const h = new header_js_1.Header(headBuf); + if (!h.cksumValid) { + return cb(null, position); + } + /* c8 ignore next */ + const entryBlockSize = 512 * Math.ceil((h.size ?? 0) / 512); + if (position + entryBlockSize + 512 > size) { + return cb(null, position); + } + position += entryBlockSize + 512; + if (position >= size) { + return cb(null, position); + } + if (opt.mtimeCache && h.mtime) { + opt.mtimeCache.set(String(h.path), h.mtime); + } + bufPos = 0; + node_fs_1.default.read(fd, headBuf, 0, 512, position, onread); + }; + node_fs_1.default.read(fd, headBuf, 0, 512, position, onread); + }; + const promise = new Promise((resolve, reject) => { + p.on('error', reject); + let flag = 'r+'; + const onopen = (er, fd) => { + if (er && er.code === 'ENOENT' && flag === 'r+') { + flag = 'w+'; + return node_fs_1.default.open(opt.file, flag, onopen); + } + if (er || !fd) { + return reject(er); + } + node_fs_1.default.fstat(fd, (er, st) => { + if (er) { + return node_fs_1.default.close(fd, () => reject(er)); + } + getPos(fd, st.size, (er, position) => { + if (er) { + return reject(er); + } + const stream = new fs_minipass_1.WriteStream(opt.file, { + fd: fd, + start: position, + }); + p.pipe(stream); + stream.on('error', reject); + stream.on('close', resolve); + addFilesAsync(p, files); + }); + }); + }; + node_fs_1.default.open(opt.file, flag, onopen); + }); + return promise; +}; +const addFilesSync = (p, files) => { + files.forEach(file => { + if (file.charAt(0) === '@') { + (0, list_js_1.list)({ + file: node_path_1.default.resolve(p.cwd, file.slice(1)), + sync: true, + noResume: true, + onReadEntry: entry => p.add(entry), + }); + } + else { + p.add(file); + } + }); + p.end(); +}; +const addFilesAsync = async (p, files) => { + for (let i = 0; i < files.length; i++) { + const file = String(files[i]); + if (file.charAt(0) === '@') { + await (0, list_js_1.list)({ + file: node_path_1.default.resolve(String(p.cwd), file.slice(1)), + noResume: true, + onReadEntry: entry => p.add(entry), + }); + } + else { + p.add(file); + } + } + p.end(); +}; +exports.replace = (0, make_command_js_1.makeCommand)(replaceSync, replaceAsync, +/* c8 ignore start */ +() => { + throw new TypeError('file is required'); +}, () => { + throw new TypeError('file is required'); +}, +/* c8 ignore stop */ +(opt, entries) => { + if (!(0, options_js_1.isFile)(opt)) { + throw new TypeError('file is required'); + } + if (opt.gzip || + opt.brotli || + opt.zstd || + opt.file.endsWith('.br') || + opt.file.endsWith('.tbr')) { + throw new TypeError('cannot append to compressed archives'); + } + if (!entries?.length) { + throw new TypeError('no paths specified to add/replace'); + } +}); +//# sourceMappingURL=replace.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/strip-absolute-path.js b/node_modules/tar/dist/commonjs/strip-absolute-path.js new file mode 100644 index 0000000000000..bb7639c35a110 --- /dev/null +++ b/node_modules/tar/dist/commonjs/strip-absolute-path.js @@ -0,0 +1,29 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stripAbsolutePath = void 0; +// unix absolute paths are also absolute on win32, so we use this for both +const node_path_1 = require("node:path"); +const { isAbsolute, parse } = node_path_1.win32; +// returns [root, stripped] +// Note that windows will think that //x/y/z/a has a "root" of //x/y, and in +// those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip / +// explicitly if it's the first character. +// drive-specific relative paths on Windows get their root stripped off even +// though they are not absolute, so `c:../foo` becomes ['c:', '../foo'] +const stripAbsolutePath = (path) => { + let r = ''; + let parsed = parse(path); + while (isAbsolute(path) || parsed.root) { + // windows will think that //x/y/z has a "root" of //x/y/ + // but strip the //?/C:/ off of //?/C:/path + const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? + '/' + : parsed.root; + path = path.slice(root.length); + r += root; + parsed = parse(path); + } + return [r, path]; +}; +exports.stripAbsolutePath = stripAbsolutePath; +//# sourceMappingURL=strip-absolute-path.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/strip-trailing-slashes.js b/node_modules/tar/dist/commonjs/strip-trailing-slashes.js new file mode 100644 index 0000000000000..6fa74ad6a4ac9 --- /dev/null +++ b/node_modules/tar/dist/commonjs/strip-trailing-slashes.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stripTrailingSlashes = void 0; +// warning: extremely hot code path. +// This has been meticulously optimized for use +// within npm install on large package trees. +// Do not edit without careful benchmarking. +const stripTrailingSlashes = (str) => { + let i = str.length - 1; + let slashesStart = -1; + while (i > -1 && str.charAt(i) === '/') { + slashesStart = i; + i--; + } + return slashesStart === -1 ? str : str.slice(0, slashesStart); +}; +exports.stripTrailingSlashes = stripTrailingSlashes; +//# sourceMappingURL=strip-trailing-slashes.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/symlink-error.js b/node_modules/tar/dist/commonjs/symlink-error.js new file mode 100644 index 0000000000000..cc19ac1a2e3c6 --- /dev/null +++ b/node_modules/tar/dist/commonjs/symlink-error.js @@ -0,0 +1,19 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.SymlinkError = void 0; +class SymlinkError extends Error { + path; + symlink; + syscall = 'symlink'; + code = 'TAR_SYMLINK_ERROR'; + constructor(symlink, path) { + super('TAR_SYMLINK_ERROR: Cannot extract through symbolic link'); + this.symlink = symlink; + this.path = path; + } + get name() { + return 'SymlinkError'; + } +} +exports.SymlinkError = SymlinkError; +//# sourceMappingURL=symlink-error.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/types.js b/node_modules/tar/dist/commonjs/types.js new file mode 100644 index 0000000000000..cb9b684e843b7 --- /dev/null +++ b/node_modules/tar/dist/commonjs/types.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.code = exports.name = exports.isName = exports.isCode = void 0; +const isCode = (c) => exports.name.has(c); +exports.isCode = isCode; +const isName = (c) => exports.code.has(c); +exports.isName = isName; +// map types from key to human-friendly name +exports.name = new Map([ + ['0', 'File'], + // same as File + ['', 'OldFile'], + ['1', 'Link'], + ['2', 'SymbolicLink'], + // Devices and FIFOs aren't fully supported + // they are parsed, but skipped when unpacking + ['3', 'CharacterDevice'], + ['4', 'BlockDevice'], + ['5', 'Directory'], + ['6', 'FIFO'], + // same as File + ['7', 'ContiguousFile'], + // pax headers + ['g', 'GlobalExtendedHeader'], + ['x', 'ExtendedHeader'], + // vendor-specific stuff + // skip + ['A', 'SolarisACL'], + // like 5, but with data, which should be skipped + ['D', 'GNUDumpDir'], + // metadata only, skip + ['I', 'Inode'], + // data = link path of next file + ['K', 'NextFileHasLongLinkpath'], + // data = path of next file + ['L', 'NextFileHasLongPath'], + // skip + ['M', 'ContinuationFile'], + // like L + ['N', 'OldGnuLongPath'], + // skip + ['S', 'SparseFile'], + // skip + ['V', 'TapeVolumeHeader'], + // like x + ['X', 'OldExtendedHeader'], +]); +// map the other direction +exports.code = new Map(Array.from(exports.name).map(kv => [kv[1], kv[0]])); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/unpack.js b/node_modules/tar/dist/commonjs/unpack.js new file mode 100644 index 0000000000000..73ad5f9be5540 --- /dev/null +++ b/node_modules/tar/dist/commonjs/unpack.js @@ -0,0 +1,917 @@ +"use strict"; +// the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet. +// but the path reservations are required to avoid race conditions where +// parallelized unpack ops may mess with one another, due to dependencies +// (like a Link depending on its target) or destructive operations (like +// clobbering an fs object to create one of a different type.) +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UnpackSync = exports.Unpack = void 0; +const fsm = __importStar(require("@isaacs/fs-minipass")); +const node_assert_1 = __importDefault(require("node:assert")); +const node_crypto_1 = require("node:crypto"); +const node_fs_1 = __importDefault(require("node:fs")); +const node_path_1 = __importDefault(require("node:path")); +const get_write_flag_js_1 = require("./get-write-flag.js"); +const mkdir_js_1 = require("./mkdir.js"); +const normalize_windows_path_js_1 = require("./normalize-windows-path.js"); +const parse_js_1 = require("./parse.js"); +const strip_absolute_path_js_1 = require("./strip-absolute-path.js"); +const wc = __importStar(require("./winchars.js")); +const path_reservations_js_1 = require("./path-reservations.js"); +const ONENTRY = Symbol('onEntry'); +const CHECKFS = Symbol('checkFs'); +const CHECKFS2 = Symbol('checkFs2'); +const ISREUSABLE = Symbol('isReusable'); +const MAKEFS = Symbol('makeFs'); +const FILE = Symbol('file'); +const DIRECTORY = Symbol('directory'); +const LINK = Symbol('link'); +const SYMLINK = Symbol('symlink'); +const HARDLINK = Symbol('hardlink'); +const UNSUPPORTED = Symbol('unsupported'); +const CHECKPATH = Symbol('checkPath'); +const STRIPABSOLUTEPATH = Symbol('stripAbsolutePath'); +const MKDIR = Symbol('mkdir'); +const ONERROR = Symbol('onError'); +const PENDING = Symbol('pending'); +const PEND = Symbol('pend'); +const UNPEND = Symbol('unpend'); +const ENDED = Symbol('ended'); +const MAYBECLOSE = Symbol('maybeClose'); +const SKIP = Symbol('skip'); +const DOCHOWN = Symbol('doChown'); +const UID = Symbol('uid'); +const GID = Symbol('gid'); +const CHECKED_CWD = Symbol('checkedCwd'); +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; +const isWindows = platform === 'win32'; +const DEFAULT_MAX_DEPTH = 1024; +// Unlinks on Windows are not atomic. +// +// This means that if you have a file entry, followed by another +// file entry with an identical name, and you cannot re-use the file +// (because it's a hardlink, or because unlink:true is set, or it's +// Windows, which does not have useful nlink values), then the unlink +// will be committed to the disk AFTER the new file has been written +// over the old one, deleting the new file. +// +// To work around this, on Windows systems, we rename the file and then +// delete the renamed file. It's a sloppy kludge, but frankly, I do not +// know of a better way to do this, given windows' non-atomic unlink +// semantics. +// +// See: https://github.com/npm/node-tar/issues/183 +/* c8 ignore start */ +const unlinkFile = (path, cb) => { + if (!isWindows) { + return node_fs_1.default.unlink(path, cb); + } + const name = path + '.DELETE.' + (0, node_crypto_1.randomBytes)(16).toString('hex'); + node_fs_1.default.rename(path, name, er => { + if (er) { + return cb(er); + } + node_fs_1.default.unlink(name, cb); + }); +}; +/* c8 ignore stop */ +/* c8 ignore start */ +const unlinkFileSync = (path) => { + if (!isWindows) { + return node_fs_1.default.unlinkSync(path); + } + const name = path + '.DELETE.' + (0, node_crypto_1.randomBytes)(16).toString('hex'); + node_fs_1.default.renameSync(path, name); + node_fs_1.default.unlinkSync(name); +}; +/* c8 ignore stop */ +// this.gid, entry.gid, this.processUid +const uint32 = (a, b, c) => a !== undefined && a === a >>> 0 ? a + : b !== undefined && b === b >>> 0 ? b + : c; +class Unpack extends parse_js_1.Parser { + [ENDED] = false; + [CHECKED_CWD] = false; + [PENDING] = 0; + reservations = new path_reservations_js_1.PathReservations(); + transform; + writable = true; + readable = false; + uid; + gid; + setOwner; + preserveOwner; + processGid; + processUid; + maxDepth; + forceChown; + win32; + newer; + keep; + noMtime; + preservePaths; + unlink; + cwd; + strip; + processUmask; + umask; + dmode; + fmode; + chmod; + constructor(opt = {}) { + opt.ondone = () => { + this[ENDED] = true; + this[MAYBECLOSE](); + }; + super(opt); + this.transform = opt.transform; + this.chmod = !!opt.chmod; + if (typeof opt.uid === 'number' || typeof opt.gid === 'number') { + // need both or neither + if (typeof opt.uid !== 'number' || + typeof opt.gid !== 'number') { + throw new TypeError('cannot set owner without number uid and gid'); + } + if (opt.preserveOwner) { + throw new TypeError('cannot preserve owner in archive and also set owner explicitly'); + } + this.uid = opt.uid; + this.gid = opt.gid; + this.setOwner = true; + } + else { + this.uid = undefined; + this.gid = undefined; + this.setOwner = false; + } + // default true for root + if (opt.preserveOwner === undefined && + typeof opt.uid !== 'number') { + this.preserveOwner = !!(process.getuid && process.getuid() === 0); + } + else { + this.preserveOwner = !!opt.preserveOwner; + } + this.processUid = + (this.preserveOwner || this.setOwner) && process.getuid ? + process.getuid() + : undefined; + this.processGid = + (this.preserveOwner || this.setOwner) && process.getgid ? + process.getgid() + : undefined; + // prevent excessively deep nesting of subfolders + // set to `Infinity` to remove this restriction + this.maxDepth = + typeof opt.maxDepth === 'number' ? + opt.maxDepth + : DEFAULT_MAX_DEPTH; + // mostly just for testing, but useful in some cases. + // Forcibly trigger a chown on every entry, no matter what + this.forceChown = opt.forceChown === true; + // turn ><?| in filenames into 0xf000-higher encoded forms + this.win32 = !!opt.win32 || isWindows; + // do not unpack over files that are newer than what's in the archive + this.newer = !!opt.newer; + // do not unpack over ANY files + this.keep = !!opt.keep; + // do not set mtime/atime of extracted entries + this.noMtime = !!opt.noMtime; + // allow .., absolute path entries, and unpacking through symlinks + // without this, warn and skip .., relativize absolutes, and error + // on symlinks in extraction path + this.preservePaths = !!opt.preservePaths; + // unlink files and links before writing. This breaks existing hard + // links, and removes symlink directories rather than erroring + this.unlink = !!opt.unlink; + this.cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(opt.cwd || process.cwd())); + this.strip = Number(opt.strip) || 0; + // if we're not chmodding, then we don't need the process umask + this.processUmask = + !this.chmod ? 0 + : typeof opt.processUmask === 'number' ? opt.processUmask + : process.umask(); + this.umask = + typeof opt.umask === 'number' ? opt.umask : this.processUmask; + // default mode for dirs created as parents + this.dmode = opt.dmode || 0o0777 & ~this.umask; + this.fmode = opt.fmode || 0o0666 & ~this.umask; + this.on('entry', entry => this[ONENTRY](entry)); + } + // a bad or damaged archive is a warning for Parser, but an error + // when extracting. Mark those errors as unrecoverable, because + // the Unpack contract cannot be met. + warn(code, msg, data = {}) { + if (code === 'TAR_BAD_ARCHIVE' || code === 'TAR_ABORT') { + data.recoverable = false; + } + return super.warn(code, msg, data); + } + [MAYBECLOSE]() { + if (this[ENDED] && this[PENDING] === 0) { + this.emit('prefinish'); + this.emit('finish'); + this.emit('end'); + } + } + // return false if we need to skip this file + // return true if the field was successfully sanitized + [STRIPABSOLUTEPATH](entry, field) { + const p = entry[field]; + const { type } = entry; + if (!p || this.preservePaths) + return true; + const parts = p.split('/'); + if (parts.includes('..') || + /* c8 ignore next */ + (isWindows && /^[a-z]:\.\.$/i.test(parts[0] ?? ''))) { + // For linkpath, check if the resolved path escapes cwd rather than + // just rejecting any path with '..' - relative symlinks like + // '../sibling/file' are valid if they resolve within the cwd. + // For paths, they just simply may not ever use .. at all. + if (field === 'path' || type === 'Link') { + this.warn('TAR_ENTRY_ERROR', `${field} contains '..'`, { + entry, + [field]: p, + }); + // not ok! + return false; + } + else { + // Resolve linkpath relative to the entry's directory. + // `path.posix` is safe to use because we're operating on + // tar paths, not a filesystem. + const entryDir = node_path_1.default.posix.dirname(entry.path); + const resolved = node_path_1.default.posix.normalize(node_path_1.default.posix.join(entryDir, p)); + // If the resolved path escapes (starts with ..), reject it + if (resolved.startsWith('../') || resolved === '..') { + this.warn('TAR_ENTRY_ERROR', `${field} escapes extraction directory`, { + entry, + [field]: p, + }); + return false; + } + } + } + // strip off the root + const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(p); + if (root) { + // ok, but triggers warning about stripping root + entry[field] = String(stripped); + this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute ${field}`, { + entry, + [field]: p, + }); + } + return true; + } + [CHECKPATH](entry) { + const p = (0, normalize_windows_path_js_1.normalizeWindowsPath)(entry.path); + const parts = p.split('/'); + if (this.strip) { + if (parts.length < this.strip) { + return false; + } + if (entry.type === 'Link') { + const linkparts = (0, normalize_windows_path_js_1.normalizeWindowsPath)(String(entry.linkpath)).split('/'); + if (linkparts.length >= this.strip) { + entry.linkpath = linkparts.slice(this.strip).join('/'); + } + else { + return false; + } + } + parts.splice(0, this.strip); + entry.path = parts.join('/'); + } + if (isFinite(this.maxDepth) && parts.length > this.maxDepth) { + this.warn('TAR_ENTRY_ERROR', 'path excessively deep', { + entry, + path: p, + depth: parts.length, + maxDepth: this.maxDepth, + }); + return false; + } + if (!this[STRIPABSOLUTEPATH](entry, 'path') || + !this[STRIPABSOLUTEPATH](entry, 'linkpath')) { + return false; + } + if (node_path_1.default.isAbsolute(entry.path)) { + entry.absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(entry.path)); + } + else { + entry.absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(this.cwd, entry.path)); + } + // if we somehow ended up with a path that escapes the cwd, and we are + // not in preservePaths mode, then something is fishy! This should have + // been prevented above, so ignore this for coverage. + /* c8 ignore start - defense in depth */ + if (!this.preservePaths && + typeof entry.absolute === 'string' && + entry.absolute.indexOf(this.cwd + '/') !== 0 && + entry.absolute !== this.cwd) { + this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', { + entry, + path: (0, normalize_windows_path_js_1.normalizeWindowsPath)(entry.path), + resolvedPath: entry.absolute, + cwd: this.cwd, + }); + return false; + } + /* c8 ignore stop */ + // an archive can set properties on the extraction directory, but it + // may not replace the cwd with a different kind of thing entirely. + if (entry.absolute === this.cwd && + entry.type !== 'Directory' && + entry.type !== 'GNUDumpDir') { + return false; + } + // only encode : chars that aren't drive letter indicators + if (this.win32) { + const { root: aRoot } = node_path_1.default.win32.parse(String(entry.absolute)); + entry.absolute = + aRoot + wc.encode(String(entry.absolute).slice(aRoot.length)); + const { root: pRoot } = node_path_1.default.win32.parse(entry.path); + entry.path = pRoot + wc.encode(entry.path.slice(pRoot.length)); + } + return true; + } + [ONENTRY](entry) { + if (!this[CHECKPATH](entry)) { + return entry.resume(); + } + node_assert_1.default.equal(typeof entry.absolute, 'string'); + switch (entry.type) { + case 'Directory': + case 'GNUDumpDir': + if (entry.mode) { + entry.mode = entry.mode | 0o700; + } + // eslint-disable-next-line no-fallthrough + case 'File': + case 'OldFile': + case 'ContiguousFile': + case 'Link': + case 'SymbolicLink': + return this[CHECKFS](entry); + case 'CharacterDevice': + case 'BlockDevice': + case 'FIFO': + default: + return this[UNSUPPORTED](entry); + } + } + [ONERROR](er, entry) { + // Cwd has to exist, or else nothing works. That's serious. + // Other errors are warnings, which raise the error in strict + // mode, but otherwise continue on. + if (er.name === 'CwdError') { + this.emit('error', er); + } + else { + this.warn('TAR_ENTRY_ERROR', er, { entry }); + this[UNPEND](); + entry.resume(); + } + } + [MKDIR](dir, mode, cb) { + (0, mkdir_js_1.mkdir)((0, normalize_windows_path_js_1.normalizeWindowsPath)(dir), { + uid: this.uid, + gid: this.gid, + processUid: this.processUid, + processGid: this.processGid, + umask: this.processUmask, + preserve: this.preservePaths, + unlink: this.unlink, + cwd: this.cwd, + mode: mode, + }, cb); + } + [DOCHOWN](entry) { + // in preserve owner mode, chown if the entry doesn't match process + // in set owner mode, chown if setting doesn't match process + return (this.forceChown || + (this.preserveOwner && + ((typeof entry.uid === 'number' && + entry.uid !== this.processUid) || + (typeof entry.gid === 'number' && + entry.gid !== this.processGid))) || + (typeof this.uid === 'number' && + this.uid !== this.processUid) || + (typeof this.gid === 'number' && this.gid !== this.processGid)); + } + [UID](entry) { + return uint32(this.uid, entry.uid, this.processUid); + } + [GID](entry) { + return uint32(this.gid, entry.gid, this.processGid); + } + [FILE](entry, fullyDone) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.fmode; + const stream = new fsm.WriteStream(String(entry.absolute), { + // slight lie, but it can be numeric flags + flags: (0, get_write_flag_js_1.getWriteFlag)(entry.size), + mode: mode, + autoClose: false, + }); + stream.on('error', (er) => { + if (stream.fd) { + node_fs_1.default.close(stream.fd, () => { }); + } + // flush all the data out so that we aren't left hanging + // if the error wasn't actually fatal. otherwise the parse + // is blocked, and we never proceed. + stream.write = () => true; + this[ONERROR](er, entry); + fullyDone(); + }); + let actions = 1; + const done = (er) => { + if (er) { + /* c8 ignore start - we should always have a fd by now */ + if (stream.fd) { + node_fs_1.default.close(stream.fd, () => { }); + } + /* c8 ignore stop */ + this[ONERROR](er, entry); + fullyDone(); + return; + } + if (--actions === 0) { + if (stream.fd !== undefined) { + node_fs_1.default.close(stream.fd, er => { + if (er) { + this[ONERROR](er, entry); + } + else { + this[UNPEND](); + } + fullyDone(); + }); + } + } + }; + stream.on('finish', () => { + // if futimes fails, try utimes + // if utimes fails, fail with the original error + // same for fchown/chown + const abs = String(entry.absolute); + const fd = stream.fd; + if (typeof fd === 'number' && entry.mtime && !this.noMtime) { + actions++; + const atime = entry.atime || new Date(); + const mtime = entry.mtime; + node_fs_1.default.futimes(fd, atime, mtime, er => er ? + node_fs_1.default.utimes(abs, atime, mtime, er2 => done(er2 && er)) + : done()); + } + if (typeof fd === 'number' && this[DOCHOWN](entry)) { + actions++; + const uid = this[UID](entry); + const gid = this[GID](entry); + if (typeof uid === 'number' && typeof gid === 'number') { + node_fs_1.default.fchown(fd, uid, gid, er => er ? + node_fs_1.default.chown(abs, uid, gid, er2 => done(er2 && er)) + : done()); + } + } + done(); + }); + const tx = this.transform ? this.transform(entry) || entry : entry; + if (tx !== entry) { + tx.on('error', (er) => { + this[ONERROR](er, entry); + fullyDone(); + }); + entry.pipe(tx); + } + tx.pipe(stream); + } + [DIRECTORY](entry, fullyDone) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.dmode; + this[MKDIR](String(entry.absolute), mode, er => { + if (er) { + this[ONERROR](er, entry); + fullyDone(); + return; + } + let actions = 1; + const done = () => { + if (--actions === 0) { + fullyDone(); + this[UNPEND](); + entry.resume(); + } + }; + if (entry.mtime && !this.noMtime) { + actions++; + node_fs_1.default.utimes(String(entry.absolute), entry.atime || new Date(), entry.mtime, done); + } + if (this[DOCHOWN](entry)) { + actions++; + node_fs_1.default.chown(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry)), done); + } + done(); + }); + } + [UNSUPPORTED](entry) { + entry.unsupported = true; + this.warn('TAR_ENTRY_UNSUPPORTED', `unsupported entry type: ${entry.type}`, { entry }); + entry.resume(); + } + [SYMLINK](entry, done) { + this[LINK](entry, String(entry.linkpath), 'symlink', done); + } + [HARDLINK](entry, done) { + const linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.resolve(this.cwd, String(entry.linkpath))); + this[LINK](entry, linkpath, 'link', done); + } + [PEND]() { + this[PENDING]++; + } + [UNPEND]() { + this[PENDING]--; + this[MAYBECLOSE](); + } + [SKIP](entry) { + this[UNPEND](); + entry.resume(); + } + // Check if we can reuse an existing filesystem entry safely and + // overwrite it, rather than unlinking and recreating + // Windows doesn't report a useful nlink, so we just never reuse entries + [ISREUSABLE](entry, st) { + return (entry.type === 'File' && + !this.unlink && + st.isFile() && + st.nlink <= 1 && + !isWindows); + } + // check if a thing is there, and if so, try to clobber it + [CHECKFS](entry) { + this[PEND](); + const paths = [entry.path]; + if (entry.linkpath) { + paths.push(entry.linkpath); + } + this.reservations.reserve(paths, done => this[CHECKFS2](entry, done)); + } + [CHECKFS2](entry, fullyDone) { + const done = (er) => { + fullyDone(er); + }; + const checkCwd = () => { + this[MKDIR](this.cwd, this.dmode, er => { + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + this[CHECKED_CWD] = true; + start(); + }); + }; + const start = () => { + if (entry.absolute !== this.cwd) { + const parent = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.dirname(String(entry.absolute))); + if (parent !== this.cwd) { + return this[MKDIR](parent, this.dmode, er => { + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + afterMakeParent(); + }); + } + } + afterMakeParent(); + }; + const afterMakeParent = () => { + node_fs_1.default.lstat(String(entry.absolute), (lstatEr, st) => { + if (st && + (this.keep || + /* c8 ignore next */ + (this.newer && st.mtime > (entry.mtime ?? st.mtime)))) { + this[SKIP](entry); + done(); + return; + } + if (lstatEr || this[ISREUSABLE](entry, st)) { + return this[MAKEFS](null, entry, done); + } + if (st.isDirectory()) { + if (entry.type === 'Directory') { + const needChmod = this.chmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode; + const afterChmod = (er) => this[MAKEFS](er ?? null, entry, done); + if (!needChmod) { + return afterChmod(); + } + return node_fs_1.default.chmod(String(entry.absolute), Number(entry.mode), afterChmod); + } + // Not a dir entry, have to remove it. + // NB: the only way to end up with an entry that is the cwd + // itself, in such a way that == does not detect, is a + // tricky windows absolute path with UNC or 8.3 parts (and + // preservePaths:true, or else it will have been stripped). + // In that case, the user has opted out of path protections + // explicitly, so if they blow away the cwd, c'est la vie. + if (entry.absolute !== this.cwd) { + return node_fs_1.default.rmdir(String(entry.absolute), (er) => this[MAKEFS](er ?? null, entry, done)); + } + } + // not a dir, and not reusable + // don't remove if the cwd, we want that error + if (entry.absolute === this.cwd) { + return this[MAKEFS](null, entry, done); + } + unlinkFile(String(entry.absolute), er => this[MAKEFS](er ?? null, entry, done)); + }); + }; + if (this[CHECKED_CWD]) { + start(); + } + else { + checkCwd(); + } + } + [MAKEFS](er, entry, done) { + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + switch (entry.type) { + case 'File': + case 'OldFile': + case 'ContiguousFile': + return this[FILE](entry, done); + case 'Link': + return this[HARDLINK](entry, done); + case 'SymbolicLink': + return this[SYMLINK](entry, done); + case 'Directory': + case 'GNUDumpDir': + return this[DIRECTORY](entry, done); + } + } + [LINK](entry, linkpath, link, done) { + // XXX: get the type ('symlink' or 'junction') for windows + node_fs_1.default[link](linkpath, String(entry.absolute), er => { + if (er) { + this[ONERROR](er, entry); + } + else { + this[UNPEND](); + entry.resume(); + } + done(); + }); + } +} +exports.Unpack = Unpack; +const callSync = (fn) => { + try { + return [null, fn()]; + } + catch (er) { + return [er, null]; + } +}; +class UnpackSync extends Unpack { + sync = true; + [MAKEFS](er, entry) { + return super[MAKEFS](er, entry, () => { }); + } + [CHECKFS](entry) { + if (!this[CHECKED_CWD]) { + const er = this[MKDIR](this.cwd, this.dmode); + if (er) { + return this[ONERROR](er, entry); + } + this[CHECKED_CWD] = true; + } + // don't bother to make the parent if the current entry is the cwd, + // we've already checked it. + if (entry.absolute !== this.cwd) { + const parent = (0, normalize_windows_path_js_1.normalizeWindowsPath)(node_path_1.default.dirname(String(entry.absolute))); + if (parent !== this.cwd) { + const mkParent = this[MKDIR](parent, this.dmode); + if (mkParent) { + return this[ONERROR](mkParent, entry); + } + } + } + const [lstatEr, st] = callSync(() => node_fs_1.default.lstatSync(String(entry.absolute))); + if (st && + (this.keep || + /* c8 ignore next */ + (this.newer && st.mtime > (entry.mtime ?? st.mtime)))) { + return this[SKIP](entry); + } + if (lstatEr || this[ISREUSABLE](entry, st)) { + return this[MAKEFS](null, entry); + } + if (st.isDirectory()) { + if (entry.type === 'Directory') { + const needChmod = this.chmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode; + const [er] = needChmod ? + callSync(() => { + node_fs_1.default.chmodSync(String(entry.absolute), Number(entry.mode)); + }) + : []; + return this[MAKEFS](er, entry); + } + // not a dir entry, have to remove it + const [er] = callSync(() => node_fs_1.default.rmdirSync(String(entry.absolute))); + this[MAKEFS](er, entry); + } + // not a dir, and not reusable. + // don't remove if it's the cwd, since we want that error. + const [er] = entry.absolute === this.cwd ? + [] + : callSync(() => unlinkFileSync(String(entry.absolute))); + this[MAKEFS](er, entry); + } + [FILE](entry, done) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.fmode; + const oner = (er) => { + let closeError; + try { + node_fs_1.default.closeSync(fd); + } + catch (e) { + closeError = e; + } + if (er || closeError) { + this[ONERROR](er || closeError, entry); + } + done(); + }; + let fd; + try { + fd = node_fs_1.default.openSync(String(entry.absolute), (0, get_write_flag_js_1.getWriteFlag)(entry.size), mode); + /* c8 ignore start - This is only a problem if the file was successfully + * statted, BUT failed to open. Testing this is annoying, and we + * already have ample testint for other uses of oner() methods. + */ + } + catch (er) { + return oner(er); + } + /* c8 ignore stop */ + const tx = this.transform ? this.transform(entry) || entry : entry; + if (tx !== entry) { + tx.on('error', (er) => this[ONERROR](er, entry)); + entry.pipe(tx); + } + tx.on('data', (chunk) => { + try { + node_fs_1.default.writeSync(fd, chunk, 0, chunk.length); + } + catch (er) { + oner(er); + } + }); + tx.on('end', () => { + let er = null; + // try both, falling futimes back to utimes + // if either fails, handle the first error + if (entry.mtime && !this.noMtime) { + const atime = entry.atime || new Date(); + const mtime = entry.mtime; + try { + node_fs_1.default.futimesSync(fd, atime, mtime); + } + catch (futimeser) { + try { + node_fs_1.default.utimesSync(String(entry.absolute), atime, mtime); + } + catch (utimeser) { + er = futimeser; + } + } + } + if (this[DOCHOWN](entry)) { + const uid = this[UID](entry); + const gid = this[GID](entry); + try { + node_fs_1.default.fchownSync(fd, Number(uid), Number(gid)); + } + catch (fchowner) { + try { + node_fs_1.default.chownSync(String(entry.absolute), Number(uid), Number(gid)); + } + catch (chowner) { + er = er || fchowner; + } + } + } + oner(er); + }); + } + [DIRECTORY](entry, done) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.dmode; + const er = this[MKDIR](String(entry.absolute), mode); + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + if (entry.mtime && !this.noMtime) { + try { + node_fs_1.default.utimesSync(String(entry.absolute), entry.atime || new Date(), entry.mtime); + /* c8 ignore next */ + } + catch (er) { } + } + if (this[DOCHOWN](entry)) { + try { + node_fs_1.default.chownSync(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry))); + } + catch (er) { } + } + done(); + entry.resume(); + } + [MKDIR](dir, mode) { + try { + return (0, mkdir_js_1.mkdirSync)((0, normalize_windows_path_js_1.normalizeWindowsPath)(dir), { + uid: this.uid, + gid: this.gid, + processUid: this.processUid, + processGid: this.processGid, + umask: this.processUmask, + preserve: this.preservePaths, + unlink: this.unlink, + cwd: this.cwd, + mode: mode, + }); + } + catch (er) { + return er; + } + } + [LINK](entry, linkpath, link, done) { + const ls = `${link}Sync`; + try { + node_fs_1.default[ls](linkpath, String(entry.absolute)); + done(); + entry.resume(); + } + catch (er) { + return this[ONERROR](er, entry); + } + } +} +exports.UnpackSync = UnpackSync; +//# sourceMappingURL=unpack.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/update.js b/node_modules/tar/dist/commonjs/update.js new file mode 100644 index 0000000000000..7687896f4bfee --- /dev/null +++ b/node_modules/tar/dist/commonjs/update.js @@ -0,0 +1,33 @@ +"use strict"; +// tar -u +Object.defineProperty(exports, "__esModule", { value: true }); +exports.update = void 0; +const make_command_js_1 = require("./make-command.js"); +const replace_js_1 = require("./replace.js"); +// just call tar.r with the filter and mtimeCache +exports.update = (0, make_command_js_1.makeCommand)(replace_js_1.replace.syncFile, replace_js_1.replace.asyncFile, replace_js_1.replace.syncNoFile, replace_js_1.replace.asyncNoFile, (opt, entries = []) => { + replace_js_1.replace.validate?.(opt, entries); + mtimeFilter(opt); +}); +const mtimeFilter = (opt) => { + const filter = opt.filter; + if (!opt.mtimeCache) { + opt.mtimeCache = new Map(); + } + opt.filter = + filter ? + (path, stat) => filter(path, stat) && + !( + /* c8 ignore start */ + ((opt.mtimeCache?.get(path) ?? stat.mtime ?? 0) > + (stat.mtime ?? 0)) + /* c8 ignore stop */ + ) + : (path, stat) => !( + /* c8 ignore start */ + ((opt.mtimeCache?.get(path) ?? stat.mtime ?? 0) > + (stat.mtime ?? 0)) + /* c8 ignore stop */ + ); +}; +//# sourceMappingURL=update.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/warn-method.js b/node_modules/tar/dist/commonjs/warn-method.js new file mode 100644 index 0000000000000..f25502776e36a --- /dev/null +++ b/node_modules/tar/dist/commonjs/warn-method.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.warnMethod = void 0; +const warnMethod = (self, code, message, data = {}) => { + if (self.file) { + data.file = self.file; + } + if (self.cwd) { + data.cwd = self.cwd; + } + data.code = + (message instanceof Error && + message.code) || + code; + data.tarCode = code; + if (!self.strict && data.recoverable !== false) { + if (message instanceof Error) { + data = Object.assign(message, data); + message = message.message; + } + self.emit('warn', code, message, data); + } + else if (message instanceof Error) { + self.emit('error', Object.assign(message, data)); + } + else { + self.emit('error', Object.assign(new Error(`${code}: ${message}`), data)); + } +}; +exports.warnMethod = warnMethod; +//# sourceMappingURL=warn-method.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/winchars.js b/node_modules/tar/dist/commonjs/winchars.js new file mode 100644 index 0000000000000..c0a4405812929 --- /dev/null +++ b/node_modules/tar/dist/commonjs/winchars.js @@ -0,0 +1,14 @@ +"use strict"; +// When writing files on Windows, translate the characters to their +// 0xf000 higher-encoded versions. +Object.defineProperty(exports, "__esModule", { value: true }); +exports.decode = exports.encode = void 0; +const raw = ['|', '<', '>', '?', ':']; +const win = raw.map(char => String.fromCharCode(0xf000 + char.charCodeAt(0))); +const toWin = new Map(raw.map((char, i) => [char, win[i]])); +const toRaw = new Map(win.map((char, i) => [char, raw[i]])); +const encode = (s) => raw.reduce((s, c) => s.split(c).join(toWin.get(c)), s); +exports.encode = encode; +const decode = (s) => win.reduce((s, c) => s.split(c).join(toRaw.get(c)), s); +exports.decode = decode; +//# sourceMappingURL=winchars.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/commonjs/write-entry.js b/node_modules/tar/dist/commonjs/write-entry.js new file mode 100644 index 0000000000000..20e14a0d6c0b6 --- /dev/null +++ b/node_modules/tar/dist/commonjs/write-entry.js @@ -0,0 +1,699 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.WriteEntryTar = exports.WriteEntrySync = exports.WriteEntry = void 0; +const fs_1 = __importDefault(require("fs")); +const minipass_1 = require("minipass"); +const path_1 = __importDefault(require("path")); +const header_js_1 = require("./header.js"); +const mode_fix_js_1 = require("./mode-fix.js"); +const normalize_windows_path_js_1 = require("./normalize-windows-path.js"); +const options_js_1 = require("./options.js"); +const pax_js_1 = require("./pax.js"); +const strip_absolute_path_js_1 = require("./strip-absolute-path.js"); +const strip_trailing_slashes_js_1 = require("./strip-trailing-slashes.js"); +const warn_method_js_1 = require("./warn-method.js"); +const winchars = __importStar(require("./winchars.js")); +const prefixPath = (path, prefix) => { + if (!prefix) { + return (0, normalize_windows_path_js_1.normalizeWindowsPath)(path); + } + path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path).replace(/^\.(\/|$)/, ''); + return (0, strip_trailing_slashes_js_1.stripTrailingSlashes)(prefix) + '/' + path; +}; +const maxReadSize = 16 * 1024 * 1024; +const PROCESS = Symbol('process'); +const FILE = Symbol('file'); +const DIRECTORY = Symbol('directory'); +const SYMLINK = Symbol('symlink'); +const HARDLINK = Symbol('hardlink'); +const HEADER = Symbol('header'); +const READ = Symbol('read'); +const LSTAT = Symbol('lstat'); +const ONLSTAT = Symbol('onlstat'); +const ONREAD = Symbol('onread'); +const ONREADLINK = Symbol('onreadlink'); +const OPENFILE = Symbol('openfile'); +const ONOPENFILE = Symbol('onopenfile'); +const CLOSE = Symbol('close'); +const MODE = Symbol('mode'); +const AWAITDRAIN = Symbol('awaitDrain'); +const ONDRAIN = Symbol('ondrain'); +const PREFIX = Symbol('prefix'); +class WriteEntry extends minipass_1.Minipass { + path; + portable; + myuid = (process.getuid && process.getuid()) || 0; + // until node has builtin pwnam functions, this'll have to do + myuser = process.env.USER || ''; + maxReadSize; + linkCache; + statCache; + preservePaths; + cwd; + strict; + mtime; + noPax; + noMtime; + prefix; + fd; + blockLen = 0; + blockRemain = 0; + buf; + pos = 0; + remain = 0; + length = 0; + offset = 0; + win32; + absolute; + header; + type; + linkpath; + stat; + onWriteEntry; + #hadError = false; + constructor(p, opt_ = {}) { + const opt = (0, options_js_1.dealias)(opt_); + super(); + this.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(p); + // suppress atime, ctime, uid, gid, uname, gname + this.portable = !!opt.portable; + this.maxReadSize = opt.maxReadSize || maxReadSize; + this.linkCache = opt.linkCache || new Map(); + this.statCache = opt.statCache || new Map(); + this.preservePaths = !!opt.preservePaths; + this.cwd = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.cwd || process.cwd()); + this.strict = !!opt.strict; + this.noPax = !!opt.noPax; + this.noMtime = !!opt.noMtime; + this.mtime = opt.mtime; + this.prefix = + opt.prefix ? (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.prefix) : undefined; + this.onWriteEntry = opt.onWriteEntry; + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + let pathWarn = false; + if (!this.preservePaths) { + const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(this.path); + if (root && typeof stripped === 'string') { + this.path = stripped; + pathWarn = root; + } + } + this.win32 = !!opt.win32 || process.platform === 'win32'; + if (this.win32) { + // force the \ to / normalization, since we might not *actually* + // be on windows, but want \ to be considered a path separator. + this.path = winchars.decode(this.path.replace(/\\/g, '/')); + p = p.replace(/\\/g, '/'); + } + this.absolute = (0, normalize_windows_path_js_1.normalizeWindowsPath)(opt.absolute || path_1.default.resolve(this.cwd, p)); + if (this.path === '') { + this.path = './'; + } + if (pathWarn) { + this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { + entry: this, + path: pathWarn + this.path, + }); + } + const cs = this.statCache.get(this.absolute); + if (cs) { + this[ONLSTAT](cs); + } + else { + this[LSTAT](); + } + } + warn(code, message, data = {}) { + return (0, warn_method_js_1.warnMethod)(this, code, message, data); + } + emit(ev, ...data) { + if (ev === 'error') { + this.#hadError = true; + } + return super.emit(ev, ...data); + } + [LSTAT]() { + fs_1.default.lstat(this.absolute, (er, stat) => { + if (er) { + return this.emit('error', er); + } + this[ONLSTAT](stat); + }); + } + [ONLSTAT](stat) { + this.statCache.set(this.absolute, stat); + this.stat = stat; + if (!stat.isFile()) { + stat.size = 0; + } + this.type = getType(stat); + this.emit('stat', stat); + this[PROCESS](); + } + [PROCESS]() { + switch (this.type) { + case 'File': + return this[FILE](); + case 'Directory': + return this[DIRECTORY](); + case 'SymbolicLink': + return this[SYMLINK](); + // unsupported types are ignored. + default: + return this.end(); + } + } + [MODE](mode) { + return (0, mode_fix_js_1.modeFix)(mode, this.type === 'Directory', this.portable); + } + [PREFIX](path) { + return prefixPath(path, this.prefix); + } + [HEADER]() { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot write header before stat'); + } + /* c8 ignore stop */ + if (this.type === 'Directory' && this.portable) { + this.noMtime = true; + } + this.onWriteEntry?.(this); + this.header = new header_js_1.Header({ + path: this[PREFIX](this.path), + // only apply the prefix to hard links. + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + // only the permissions and setuid/setgid/sticky bitflags + // not the higher-order bits that specify file type + mode: this[MODE](this.stat.mode), + uid: this.portable ? undefined : this.stat.uid, + gid: this.portable ? undefined : this.stat.gid, + size: this.stat.size, + mtime: this.noMtime ? undefined : this.mtime || this.stat.mtime, + /* c8 ignore next */ + type: this.type === 'Unsupported' ? undefined : this.type, + uname: this.portable ? undefined + : this.stat.uid === this.myuid ? this.myuser + : '', + atime: this.portable ? undefined : this.stat.atime, + ctime: this.portable ? undefined : this.stat.ctime, + }); + if (this.header.encode() && !this.noPax) { + super.write(new pax_js_1.Pax({ + atime: this.portable ? undefined : this.header.atime, + ctime: this.portable ? undefined : this.header.ctime, + gid: this.portable ? undefined : this.header.gid, + mtime: this.noMtime ? undefined : (this.mtime || this.header.mtime), + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + size: this.header.size, + uid: this.portable ? undefined : this.header.uid, + uname: this.portable ? undefined : this.header.uname, + dev: this.portable ? undefined : this.stat.dev, + ino: this.portable ? undefined : this.stat.ino, + nlink: this.portable ? undefined : this.stat.nlink, + }).encode()); + } + const block = this.header?.block; + /* c8 ignore start */ + if (!block) { + throw new Error('failed to encode header'); + } + /* c8 ignore stop */ + super.write(block); + } + [DIRECTORY]() { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot create directory entry without stat'); + } + /* c8 ignore stop */ + if (this.path.slice(-1) !== '/') { + this.path += '/'; + } + this.stat.size = 0; + this[HEADER](); + this.end(); + } + [SYMLINK]() { + fs_1.default.readlink(this.absolute, (er, linkpath) => { + if (er) { + return this.emit('error', er); + } + this[ONREADLINK](linkpath); + }); + } + [ONREADLINK](linkpath) { + this.linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(linkpath); + this[HEADER](); + this.end(); + } + [HARDLINK](linkpath) { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot create link entry without stat'); + } + /* c8 ignore stop */ + this.type = 'Link'; + this.linkpath = (0, normalize_windows_path_js_1.normalizeWindowsPath)(path_1.default.relative(this.cwd, linkpath)); + this.stat.size = 0; + this[HEADER](); + this.end(); + } + [FILE]() { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot create file entry without stat'); + } + /* c8 ignore stop */ + if (this.stat.nlink > 1) { + const linkKey = `${this.stat.dev}:${this.stat.ino}`; + const linkpath = this.linkCache.get(linkKey); + if (linkpath?.indexOf(this.cwd) === 0) { + return this[HARDLINK](linkpath); + } + this.linkCache.set(linkKey, this.absolute); + } + this[HEADER](); + if (this.stat.size === 0) { + return this.end(); + } + this[OPENFILE](); + } + [OPENFILE]() { + fs_1.default.open(this.absolute, 'r', (er, fd) => { + if (er) { + return this.emit('error', er); + } + this[ONOPENFILE](fd); + }); + } + [ONOPENFILE](fd) { + this.fd = fd; + if (this.#hadError) { + return this[CLOSE](); + } + /* c8 ignore start */ + if (!this.stat) { + throw new Error('should stat before calling onopenfile'); + } + /* c8 ignore start */ + this.blockLen = 512 * Math.ceil(this.stat.size / 512); + this.blockRemain = this.blockLen; + const bufLen = Math.min(this.blockLen, this.maxReadSize); + this.buf = Buffer.allocUnsafe(bufLen); + this.offset = 0; + this.pos = 0; + this.remain = this.stat.size; + this.length = this.buf.length; + this[READ](); + } + [READ]() { + const { fd, buf, offset, length, pos } = this; + if (fd === undefined || buf === undefined) { + throw new Error('cannot read file without first opening'); + } + fs_1.default.read(fd, buf, offset, length, pos, (er, bytesRead) => { + if (er) { + // ignoring the error from close(2) is a bad practice, but at + // this point we already have an error, don't need another one + return this[CLOSE](() => this.emit('error', er)); + } + this[ONREAD](bytesRead); + }); + } + /* c8 ignore start */ + [CLOSE](cb = () => { }) { + /* c8 ignore stop */ + if (this.fd !== undefined) + fs_1.default.close(this.fd, cb); + } + [ONREAD](bytesRead) { + if (bytesRead <= 0 && this.remain > 0) { + const er = Object.assign(new Error('encountered unexpected EOF'), { + path: this.absolute, + syscall: 'read', + code: 'EOF', + }); + return this[CLOSE](() => this.emit('error', er)); + } + if (bytesRead > this.remain) { + const er = Object.assign(new Error('did not encounter expected EOF'), { + path: this.absolute, + syscall: 'read', + code: 'EOF', + }); + return this[CLOSE](() => this.emit('error', er)); + } + /* c8 ignore start */ + if (!this.buf) { + throw new Error('should have created buffer prior to reading'); + } + /* c8 ignore stop */ + // null out the rest of the buffer, if we could fit the block padding + // at the end of this loop, we've incremented bytesRead and this.remain + // to be incremented up to the blockRemain level, as if we had expected + // to get a null-padded file, and read it until the end. then we will + // decrement both remain and blockRemain by bytesRead, and know that we + // reached the expected EOF, without any null buffer to append. + if (bytesRead === this.remain) { + for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) { + this.buf[i + this.offset] = 0; + bytesRead++; + this.remain++; + } + } + const chunk = this.offset === 0 && bytesRead === this.buf.length ? + this.buf + : this.buf.subarray(this.offset, this.offset + bytesRead); + const flushed = this.write(chunk); + if (!flushed) { + this[AWAITDRAIN](() => this[ONDRAIN]()); + } + else { + this[ONDRAIN](); + } + } + [AWAITDRAIN](cb) { + this.once('drain', cb); + } + write(chunk, encoding, cb) { + /* c8 ignore start - just junk to comply with NodeJS.WritableStream */ + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8'); + } + /* c8 ignore stop */ + if (this.blockRemain < chunk.length) { + const er = Object.assign(new Error('writing more data than expected'), { + path: this.absolute, + }); + return this.emit('error', er); + } + this.remain -= chunk.length; + this.blockRemain -= chunk.length; + this.pos += chunk.length; + this.offset += chunk.length; + return super.write(chunk, null, cb); + } + [ONDRAIN]() { + if (!this.remain) { + if (this.blockRemain) { + super.write(Buffer.alloc(this.blockRemain)); + } + return this[CLOSE](er => er ? this.emit('error', er) : this.end()); + } + /* c8 ignore start */ + if (!this.buf) { + throw new Error('buffer lost somehow in ONDRAIN'); + } + /* c8 ignore stop */ + if (this.offset >= this.length) { + // if we only have a smaller bit left to read, alloc a smaller buffer + // otherwise, keep it the same length it was before. + this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length)); + this.offset = 0; + } + this.length = this.buf.length - this.offset; + this[READ](); + } +} +exports.WriteEntry = WriteEntry; +class WriteEntrySync extends WriteEntry { + sync = true; + [LSTAT]() { + this[ONLSTAT](fs_1.default.lstatSync(this.absolute)); + } + [SYMLINK]() { + this[ONREADLINK](fs_1.default.readlinkSync(this.absolute)); + } + [OPENFILE]() { + this[ONOPENFILE](fs_1.default.openSync(this.absolute, 'r')); + } + [READ]() { + let threw = true; + try { + const { fd, buf, offset, length, pos } = this; + /* c8 ignore start */ + if (fd === undefined || buf === undefined) { + throw new Error('fd and buf must be set in READ method'); + } + /* c8 ignore stop */ + const bytesRead = fs_1.default.readSync(fd, buf, offset, length, pos); + this[ONREAD](bytesRead); + threw = false; + } + finally { + // ignoring the error from close(2) is a bad practice, but at + // this point we already have an error, don't need another one + if (threw) { + try { + this[CLOSE](() => { }); + } + catch (er) { } + } + } + } + [AWAITDRAIN](cb) { + cb(); + } + /* c8 ignore start */ + [CLOSE](cb = () => { }) { + /* c8 ignore stop */ + if (this.fd !== undefined) + fs_1.default.closeSync(this.fd); + cb(); + } +} +exports.WriteEntrySync = WriteEntrySync; +class WriteEntryTar extends minipass_1.Minipass { + blockLen = 0; + blockRemain = 0; + buf = 0; + pos = 0; + remain = 0; + length = 0; + preservePaths; + portable; + strict; + noPax; + noMtime; + readEntry; + type; + prefix; + path; + mode; + uid; + gid; + uname; + gname; + header; + mtime; + atime; + ctime; + linkpath; + size; + onWriteEntry; + warn(code, message, data = {}) { + return (0, warn_method_js_1.warnMethod)(this, code, message, data); + } + constructor(readEntry, opt_ = {}) { + const opt = (0, options_js_1.dealias)(opt_); + super(); + this.preservePaths = !!opt.preservePaths; + this.portable = !!opt.portable; + this.strict = !!opt.strict; + this.noPax = !!opt.noPax; + this.noMtime = !!opt.noMtime; + this.onWriteEntry = opt.onWriteEntry; + this.readEntry = readEntry; + const { type } = readEntry; + /* c8 ignore start */ + if (type === 'Unsupported') { + throw new Error('writing entry that should be ignored'); + } + /* c8 ignore stop */ + this.type = type; + if (this.type === 'Directory' && this.portable) { + this.noMtime = true; + } + this.prefix = opt.prefix; + this.path = (0, normalize_windows_path_js_1.normalizeWindowsPath)(readEntry.path); + this.mode = + readEntry.mode !== undefined ? + this[MODE](readEntry.mode) + : undefined; + this.uid = this.portable ? undefined : readEntry.uid; + this.gid = this.portable ? undefined : readEntry.gid; + this.uname = this.portable ? undefined : readEntry.uname; + this.gname = this.portable ? undefined : readEntry.gname; + this.size = readEntry.size; + this.mtime = + this.noMtime ? undefined : opt.mtime || readEntry.mtime; + this.atime = this.portable ? undefined : readEntry.atime; + this.ctime = this.portable ? undefined : readEntry.ctime; + this.linkpath = + readEntry.linkpath !== undefined ? + (0, normalize_windows_path_js_1.normalizeWindowsPath)(readEntry.linkpath) + : undefined; + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + let pathWarn = false; + if (!this.preservePaths) { + const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(this.path); + if (root && typeof stripped === 'string') { + this.path = stripped; + pathWarn = root; + } + } + this.remain = readEntry.size; + this.blockRemain = readEntry.startBlockSize; + this.onWriteEntry?.(this); + this.header = new header_js_1.Header({ + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + // only the permissions and setuid/setgid/sticky bitflags + // not the higher-order bits that specify file type + mode: this.mode, + uid: this.portable ? undefined : this.uid, + gid: this.portable ? undefined : this.gid, + size: this.size, + mtime: this.noMtime ? undefined : this.mtime, + type: this.type, + uname: this.portable ? undefined : this.uname, + atime: this.portable ? undefined : this.atime, + ctime: this.portable ? undefined : this.ctime, + }); + if (pathWarn) { + this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { + entry: this, + path: pathWarn + this.path, + }); + } + if (this.header.encode() && !this.noPax) { + super.write(new pax_js_1.Pax({ + atime: this.portable ? undefined : this.atime, + ctime: this.portable ? undefined : this.ctime, + gid: this.portable ? undefined : this.gid, + mtime: this.noMtime ? undefined : this.mtime, + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + size: this.size, + uid: this.portable ? undefined : this.uid, + uname: this.portable ? undefined : this.uname, + dev: this.portable ? undefined : this.readEntry.dev, + ino: this.portable ? undefined : this.readEntry.ino, + nlink: this.portable ? undefined : this.readEntry.nlink, + }).encode()); + } + const b = this.header?.block; + /* c8 ignore start */ + if (!b) + throw new Error('failed to encode header'); + /* c8 ignore stop */ + super.write(b); + readEntry.pipe(this); + } + [PREFIX](path) { + return prefixPath(path, this.prefix); + } + [MODE](mode) { + return (0, mode_fix_js_1.modeFix)(mode, this.type === 'Directory', this.portable); + } + write(chunk, encoding, cb) { + /* c8 ignore start - just junk to comply with NodeJS.WritableStream */ + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8'); + } + /* c8 ignore stop */ + const writeLen = chunk.length; + if (writeLen > this.blockRemain) { + throw new Error('writing more to entry than is appropriate'); + } + this.blockRemain -= writeLen; + return super.write(chunk, cb); + } + end(chunk, encoding, cb) { + if (this.blockRemain) { + super.write(Buffer.alloc(this.blockRemain)); + } + /* c8 ignore start - just junk to comply with NodeJS.WritableStream */ + if (typeof chunk === 'function') { + cb = chunk; + encoding = undefined; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding ?? 'utf8'); + } + if (cb) + this.once('finish', cb); + chunk ? super.end(chunk, cb) : super.end(cb); + /* c8 ignore stop */ + return this; + } +} +exports.WriteEntryTar = WriteEntryTar; +const getType = (stat) => stat.isFile() ? 'File' + : stat.isDirectory() ? 'Directory' + : stat.isSymbolicLink() ? 'SymbolicLink' + : 'Unsupported'; +//# sourceMappingURL=write-entry.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/create.js b/node_modules/tar/dist/esm/create.js new file mode 100644 index 0000000000000..512a9911d70d5 --- /dev/null +++ b/node_modules/tar/dist/esm/create.js @@ -0,0 +1,77 @@ +import { WriteStream, WriteStreamSync } from '@isaacs/fs-minipass'; +import path from 'node:path'; +import { list } from './list.js'; +import { makeCommand } from './make-command.js'; +import { Pack, PackSync } from './pack.js'; +const createFileSync = (opt, files) => { + const p = new PackSync(opt); + const stream = new WriteStreamSync(opt.file, { + mode: opt.mode || 0o666, + }); + p.pipe(stream); + addFilesSync(p, files); +}; +const createFile = (opt, files) => { + const p = new Pack(opt); + const stream = new WriteStream(opt.file, { + mode: opt.mode || 0o666, + }); + p.pipe(stream); + const promise = new Promise((res, rej) => { + stream.on('error', rej); + stream.on('close', res); + p.on('error', rej); + }); + addFilesAsync(p, files); + return promise; +}; +const addFilesSync = (p, files) => { + files.forEach(file => { + if (file.charAt(0) === '@') { + list({ + file: path.resolve(p.cwd, file.slice(1)), + sync: true, + noResume: true, + onReadEntry: entry => p.add(entry), + }); + } + else { + p.add(file); + } + }); + p.end(); +}; +const addFilesAsync = async (p, files) => { + for (let i = 0; i < files.length; i++) { + const file = String(files[i]); + if (file.charAt(0) === '@') { + await list({ + file: path.resolve(String(p.cwd), file.slice(1)), + noResume: true, + onReadEntry: entry => { + p.add(entry); + }, + }); + } + else { + p.add(file); + } + } + p.end(); +}; +const createSync = (opt, files) => { + const p = new PackSync(opt); + addFilesSync(p, files); + return p; +}; +const createAsync = (opt, files) => { + const p = new Pack(opt); + addFilesAsync(p, files); + return p; +}; +export const create = makeCommand(createFileSync, createFile, createSync, createAsync, (_opt, files) => { + if (!files?.length) { + throw new TypeError('no paths specified to add to archive'); + } +}); +//# sourceMappingURL=create.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/cwd-error.js b/node_modules/tar/dist/esm/cwd-error.js new file mode 100644 index 0000000000000..289a066b8e031 --- /dev/null +++ b/node_modules/tar/dist/esm/cwd-error.js @@ -0,0 +1,14 @@ +export class CwdError extends Error { + path; + code; + syscall = 'chdir'; + constructor(path, code) { + super(`${code}: Cannot cd into '${path}'`); + this.path = path; + this.code = code; + } + get name() { + return 'CwdError'; + } +} +//# sourceMappingURL=cwd-error.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/extract.js b/node_modules/tar/dist/esm/extract.js new file mode 100644 index 0000000000000..2274feef26e78 --- /dev/null +++ b/node_modules/tar/dist/esm/extract.js @@ -0,0 +1,49 @@ +// tar -x +import * as fsm from '@isaacs/fs-minipass'; +import fs from 'node:fs'; +import { filesFilter } from './list.js'; +import { makeCommand } from './make-command.js'; +import { Unpack, UnpackSync } from './unpack.js'; +const extractFileSync = (opt) => { + const u = new UnpackSync(opt); + const file = opt.file; + const stat = fs.statSync(file); + // This trades a zero-byte read() syscall for a stat + // However, it will usually result in less memory allocation + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + const stream = new fsm.ReadStreamSync(file, { + readSize: readSize, + size: stat.size, + }); + stream.pipe(u); +}; +const extractFile = (opt, _) => { + const u = new Unpack(opt); + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + const file = opt.file; + const p = new Promise((resolve, reject) => { + u.on('error', reject); + u.on('close', resolve); + // This trades a zero-byte read() syscall for a stat + // However, it will usually result in less memory allocation + fs.stat(file, (er, stat) => { + if (er) { + reject(er); + } + else { + const stream = new fsm.ReadStream(file, { + readSize: readSize, + size: stat.size, + }); + stream.on('error', reject); + stream.pipe(u); + } + }); + }); + return p; +}; +export const extract = makeCommand(extractFileSync, extractFile, opt => new UnpackSync(opt), opt => new Unpack(opt), (opt, files) => { + if (files?.length) + filesFilter(opt, files); +}); +//# sourceMappingURL=extract.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/get-write-flag.js b/node_modules/tar/dist/esm/get-write-flag.js new file mode 100644 index 0000000000000..2c7f3e8b28fda --- /dev/null +++ b/node_modules/tar/dist/esm/get-write-flag.js @@ -0,0 +1,23 @@ +// Get the appropriate flag to use for creating files +// We use fmap on Windows platforms for files less than +// 512kb. This is a fairly low limit, but avoids making +// things slower in some cases. Since most of what this +// library is used for is extracting tarballs of many +// relatively small files in npm packages and the like, +// it can be a big boost on Windows platforms. +import fs from 'fs'; +const platform = process.env.__FAKE_PLATFORM__ || process.platform; +const isWindows = platform === 'win32'; +/* c8 ignore start */ +const { O_CREAT, O_TRUNC, O_WRONLY } = fs.constants; +const UV_FS_O_FILEMAP = Number(process.env.__FAKE_FS_O_FILENAME__) || + fs.constants.UV_FS_O_FILEMAP || + 0; +/* c8 ignore stop */ +const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP; +const fMapLimit = 512 * 1024; +const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY; +export const getWriteFlag = !fMapEnabled ? + () => 'w' + : (size) => (size < fMapLimit ? fMapFlag : 'w'); +//# sourceMappingURL=get-write-flag.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/header.js b/node_modules/tar/dist/esm/header.js new file mode 100644 index 0000000000000..66db54527d838 --- /dev/null +++ b/node_modules/tar/dist/esm/header.js @@ -0,0 +1,288 @@ +// parse a 512-byte header block to a data object, or vice-versa +// encode returns `true` if a pax extended header is needed, because +// the data could not be faithfully encoded in a simple header. +// (Also, check header.needPax to see if it needs a pax header.) +import { posix as pathModule } from 'node:path'; +import * as large from './large-numbers.js'; +import * as types from './types.js'; +export class Header { + cksumValid = false; + needPax = false; + nullBlock = false; + block; + path; + mode; + uid; + gid; + size; + cksum; + #type = 'Unsupported'; + linkpath; + uname; + gname; + devmaj = 0; + devmin = 0; + atime; + ctime; + mtime; + charset; + comment; + constructor(data, off = 0, ex, gex) { + if (Buffer.isBuffer(data)) { + this.decode(data, off || 0, ex, gex); + } + else if (data) { + this.#slurp(data); + } + } + decode(buf, off, ex, gex) { + if (!off) { + off = 0; + } + if (!buf || !(buf.length >= off + 512)) { + throw new Error('need 512 bytes for header'); + } + this.path = ex?.path ?? decString(buf, off, 100); + this.mode = ex?.mode ?? gex?.mode ?? decNumber(buf, off + 100, 8); + this.uid = ex?.uid ?? gex?.uid ?? decNumber(buf, off + 108, 8); + this.gid = ex?.gid ?? gex?.gid ?? decNumber(buf, off + 116, 8); + this.size = ex?.size ?? gex?.size ?? decNumber(buf, off + 124, 12); + this.mtime = + ex?.mtime ?? gex?.mtime ?? decDate(buf, off + 136, 12); + this.cksum = decNumber(buf, off + 148, 12); + // if we have extended or global extended headers, apply them now + // See https://github.com/npm/node-tar/pull/187 + // Apply global before local, so it overrides + if (gex) + this.#slurp(gex, true); + if (ex) + this.#slurp(ex); + // old tar versions marked dirs as a file with a trailing / + const t = decString(buf, off + 156, 1); + if (types.isCode(t)) { + this.#type = t || '0'; + } + if (this.#type === '0' && this.path.slice(-1) === '/') { + this.#type = '5'; + } + // tar implementations sometimes incorrectly put the stat(dir).size + // as the size in the tarball, even though Directory entries are + // not able to have any body at all. In the very rare chance that + // it actually DOES have a body, we weren't going to do anything with + // it anyway, and it'll just be a warning about an invalid header. + if (this.#type === '5') { + this.size = 0; + } + this.linkpath = decString(buf, off + 157, 100); + if (buf.subarray(off + 257, off + 265).toString() === + 'ustar\u000000') { + /* c8 ignore start */ + this.uname = + ex?.uname ?? gex?.uname ?? decString(buf, off + 265, 32); + this.gname = + ex?.gname ?? gex?.gname ?? decString(buf, off + 297, 32); + this.devmaj = + ex?.devmaj ?? gex?.devmaj ?? decNumber(buf, off + 329, 8) ?? 0; + this.devmin = + ex?.devmin ?? gex?.devmin ?? decNumber(buf, off + 337, 8) ?? 0; + /* c8 ignore stop */ + if (buf[off + 475] !== 0) { + // definitely a prefix, definitely >130 chars. + const prefix = decString(buf, off + 345, 155); + this.path = prefix + '/' + this.path; + } + else { + const prefix = decString(buf, off + 345, 130); + if (prefix) { + this.path = prefix + '/' + this.path; + } + /* c8 ignore start */ + this.atime = + ex?.atime ?? gex?.atime ?? decDate(buf, off + 476, 12); + this.ctime = + ex?.ctime ?? gex?.ctime ?? decDate(buf, off + 488, 12); + /* c8 ignore stop */ + } + } + let sum = 8 * 0x20; + for (let i = off; i < off + 148; i++) { + sum += buf[i]; + } + for (let i = off + 156; i < off + 512; i++) { + sum += buf[i]; + } + this.cksumValid = sum === this.cksum; + if (this.cksum === undefined && sum === 8 * 0x20) { + this.nullBlock = true; + } + } + #slurp(ex, gex = false) { + Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. Also, any + // null/undefined values are ignored. + return !(v === null || + v === undefined || + (k === 'path' && gex) || + (k === 'linkpath' && gex) || + k === 'global'); + }))); + } + encode(buf, off = 0) { + if (!buf) { + buf = this.block = Buffer.alloc(512); + } + if (this.#type === 'Unsupported') { + this.#type = '0'; + } + if (!(buf.length >= off + 512)) { + throw new Error('need 512 bytes for header'); + } + const prefixSize = this.ctime || this.atime ? 130 : 155; + const split = splitPrefix(this.path || '', prefixSize); + const path = split[0]; + const prefix = split[1]; + this.needPax = !!split[2]; + this.needPax = encString(buf, off, 100, path) || this.needPax; + this.needPax = + encNumber(buf, off + 100, 8, this.mode) || this.needPax; + this.needPax = + encNumber(buf, off + 108, 8, this.uid) || this.needPax; + this.needPax = + encNumber(buf, off + 116, 8, this.gid) || this.needPax; + this.needPax = + encNumber(buf, off + 124, 12, this.size) || this.needPax; + this.needPax = + encDate(buf, off + 136, 12, this.mtime) || this.needPax; + buf[off + 156] = this.#type.charCodeAt(0); + this.needPax = + encString(buf, off + 157, 100, this.linkpath) || this.needPax; + buf.write('ustar\u000000', off + 257, 8); + this.needPax = + encString(buf, off + 265, 32, this.uname) || this.needPax; + this.needPax = + encString(buf, off + 297, 32, this.gname) || this.needPax; + this.needPax = + encNumber(buf, off + 329, 8, this.devmaj) || this.needPax; + this.needPax = + encNumber(buf, off + 337, 8, this.devmin) || this.needPax; + this.needPax = + encString(buf, off + 345, prefixSize, prefix) || this.needPax; + if (buf[off + 475] !== 0) { + this.needPax = + encString(buf, off + 345, 155, prefix) || this.needPax; + } + else { + this.needPax = + encString(buf, off + 345, 130, prefix) || this.needPax; + this.needPax = + encDate(buf, off + 476, 12, this.atime) || this.needPax; + this.needPax = + encDate(buf, off + 488, 12, this.ctime) || this.needPax; + } + let sum = 8 * 0x20; + for (let i = off; i < off + 148; i++) { + sum += buf[i]; + } + for (let i = off + 156; i < off + 512; i++) { + sum += buf[i]; + } + this.cksum = sum; + encNumber(buf, off + 148, 8, this.cksum); + this.cksumValid = true; + return this.needPax; + } + get type() { + return (this.#type === 'Unsupported' ? + this.#type + : types.name.get(this.#type)); + } + get typeKey() { + return this.#type; + } + set type(type) { + const c = String(types.code.get(type)); + if (types.isCode(c) || c === 'Unsupported') { + this.#type = c; + } + else if (types.isCode(type)) { + this.#type = type; + } + else { + throw new TypeError('invalid entry type: ' + type); + } + } +} +const splitPrefix = (p, prefixSize) => { + const pathSize = 100; + let pp = p; + let prefix = ''; + let ret = undefined; + const root = pathModule.parse(p).root || '.'; + if (Buffer.byteLength(pp) < pathSize) { + ret = [pp, prefix, false]; + } + else { + // first set prefix to the dir, and path to the base + prefix = pathModule.dirname(pp); + pp = pathModule.basename(pp); + do { + if (Buffer.byteLength(pp) <= pathSize && + Buffer.byteLength(prefix) <= prefixSize) { + // both fit! + ret = [pp, prefix, false]; + } + else if (Buffer.byteLength(pp) > pathSize && + Buffer.byteLength(prefix) <= prefixSize) { + // prefix fits in prefix, but path doesn't fit in path + ret = [pp.slice(0, pathSize - 1), prefix, true]; + } + else { + // make path take a bit from prefix + pp = pathModule.join(pathModule.basename(prefix), pp); + prefix = pathModule.dirname(prefix); + } + } while (prefix !== root && ret === undefined); + // at this point, found no resolution, just truncate + if (!ret) { + ret = [p.slice(0, pathSize - 1), '', true]; + } + } + return ret; +}; +const decString = (buf, off, size) => buf + .subarray(off, off + size) + .toString('utf8') + .replace(/\0.*/, ''); +const decDate = (buf, off, size) => numToDate(decNumber(buf, off, size)); +const numToDate = (num) => num === undefined ? undefined : new Date(num * 1000); +const decNumber = (buf, off, size) => Number(buf[off]) & 0x80 ? + large.parse(buf.subarray(off, off + size)) + : decSmallNumber(buf, off, size); +const nanUndef = (value) => (isNaN(value) ? undefined : value); +const decSmallNumber = (buf, off, size) => nanUndef(parseInt(buf + .subarray(off, off + size) + .toString('utf8') + .replace(/\0.*$/, '') + .trim(), 8)); +// the maximum encodable as a null-terminated octal, by field size +const MAXNUM = { + 12: 0o77777777777, + 8: 0o7777777, +}; +const encNumber = (buf, off, size, num) => num === undefined ? false + : num > MAXNUM[size] || num < 0 ? + (large.encode(num, buf.subarray(off, off + size)), true) + : (encSmallNumber(buf, off, size, num), false); +const encSmallNumber = (buf, off, size, num) => buf.write(octalString(num, size), off, size, 'ascii'); +const octalString = (num, size) => padOctal(Math.floor(num).toString(8), size); +const padOctal = (str, size) => (str.length === size - 1 ? + str + : new Array(size - str.length - 1).join('0') + str + ' ') + '\0'; +const encDate = (buf, off, size, date) => date === undefined ? false : (encNumber(buf, off, size, date.getTime() / 1000)); +// enough to fill the longest string we've got +const NULLS = new Array(156).join('\0'); +// pad with nulls, return true if it's longer or non-ascii +const encString = (buf, off, size, str) => str === undefined ? false : ((buf.write(str + NULLS, off, size, 'utf8'), + str.length !== Buffer.byteLength(str) || str.length > size)); +//# sourceMappingURL=header.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/index.js b/node_modules/tar/dist/esm/index.js new file mode 100644 index 0000000000000..1bac6415c8d73 --- /dev/null +++ b/node_modules/tar/dist/esm/index.js @@ -0,0 +1,20 @@ +export * from './create.js'; +export { create as c } from './create.js'; +export * from './extract.js'; +export { extract as x } from './extract.js'; +export * from './header.js'; +export * from './list.js'; +export { list as t } from './list.js'; +// classes +export * from './pack.js'; +export * from './parse.js'; +export * from './pax.js'; +export * from './read-entry.js'; +export * from './replace.js'; +export { replace as r } from './replace.js'; +export * as types from './types.js'; +export * from './unpack.js'; +export * from './update.js'; +export { update as u } from './update.js'; +export * from './write-entry.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/large-numbers.js b/node_modules/tar/dist/esm/large-numbers.js new file mode 100644 index 0000000000000..4f2f7e5f14fc1 --- /dev/null +++ b/node_modules/tar/dist/esm/large-numbers.js @@ -0,0 +1,94 @@ +// Tar can encode large and negative numbers using a leading byte of +// 0xff for negative, and 0x80 for positive. +export const encode = (num, buf) => { + if (!Number.isSafeInteger(num)) { + // The number is so large that javascript cannot represent it with integer + // precision. + throw Error('cannot encode number outside of javascript safe integer range'); + } + else if (num < 0) { + encodeNegative(num, buf); + } + else { + encodePositive(num, buf); + } + return buf; +}; +const encodePositive = (num, buf) => { + buf[0] = 0x80; + for (var i = buf.length; i > 1; i--) { + buf[i - 1] = num & 0xff; + num = Math.floor(num / 0x100); + } +}; +const encodeNegative = (num, buf) => { + buf[0] = 0xff; + var flipped = false; + num = num * -1; + for (var i = buf.length; i > 1; i--) { + var byte = num & 0xff; + num = Math.floor(num / 0x100); + if (flipped) { + buf[i - 1] = onesComp(byte); + } + else if (byte === 0) { + buf[i - 1] = 0; + } + else { + flipped = true; + buf[i - 1] = twosComp(byte); + } + } +}; +export const parse = (buf) => { + const pre = buf[0]; + const value = pre === 0x80 ? pos(buf.subarray(1, buf.length)) + : pre === 0xff ? twos(buf) + : null; + if (value === null) { + throw Error('invalid base256 encoding'); + } + if (!Number.isSafeInteger(value)) { + // The number is so large that javascript cannot represent it with integer + // precision. + throw Error('parsed number outside of javascript safe integer range'); + } + return value; +}; +const twos = (buf) => { + var len = buf.length; + var sum = 0; + var flipped = false; + for (var i = len - 1; i > -1; i--) { + var byte = Number(buf[i]); + var f; + if (flipped) { + f = onesComp(byte); + } + else if (byte === 0) { + f = byte; + } + else { + flipped = true; + f = twosComp(byte); + } + if (f !== 0) { + sum -= f * Math.pow(256, len - i - 1); + } + } + return sum; +}; +const pos = (buf) => { + var len = buf.length; + var sum = 0; + for (var i = len - 1; i > -1; i--) { + var byte = Number(buf[i]); + if (byte !== 0) { + sum += byte * Math.pow(256, len - i - 1); + } + } + return sum; +}; +const onesComp = (byte) => (0xff ^ byte) & 0xff; +const twosComp = (byte) => ((0xff ^ byte) + 1) & 0xff; +//# sourceMappingURL=large-numbers.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/list.js b/node_modules/tar/dist/esm/list.js new file mode 100644 index 0000000000000..a63a8841769a3 --- /dev/null +++ b/node_modules/tar/dist/esm/list.js @@ -0,0 +1,110 @@ +// tar -t +import * as fsm from '@isaacs/fs-minipass'; +import fs from 'node:fs'; +import { dirname, parse } from 'path'; +import { makeCommand } from './make-command.js'; +import { Parser } from './parse.js'; +import { stripTrailingSlashes } from './strip-trailing-slashes.js'; +const onReadEntryFunction = (opt) => { + const onReadEntry = opt.onReadEntry; + opt.onReadEntry = + onReadEntry ? + e => { + onReadEntry(e); + e.resume(); + } + : e => e.resume(); +}; +// construct a filter that limits the file entries listed +// include child entries if a dir is included +export const filesFilter = (opt, files) => { + const map = new Map(files.map(f => [stripTrailingSlashes(f), true])); + const filter = opt.filter; + const mapHas = (file, r = '') => { + const root = r || parse(file).root || '.'; + let ret; + if (file === root) + ret = false; + else { + const m = map.get(file); + if (m !== undefined) { + ret = m; + } + else { + ret = mapHas(dirname(file), root); + } + } + map.set(file, ret); + return ret; + }; + opt.filter = + filter ? + (file, entry) => filter(file, entry) && mapHas(stripTrailingSlashes(file)) + : file => mapHas(stripTrailingSlashes(file)); +}; +const listFileSync = (opt) => { + const p = new Parser(opt); + const file = opt.file; + let fd; + try { + fd = fs.openSync(file, 'r'); + const stat = fs.fstatSync(fd); + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + if (stat.size < readSize) { + const buf = Buffer.allocUnsafe(stat.size); + const read = fs.readSync(fd, buf, 0, stat.size, 0); + p.end(read === buf.byteLength ? buf : buf.subarray(0, read)); + } + else { + let pos = 0; + const buf = Buffer.allocUnsafe(readSize); + while (pos < stat.size) { + const bytesRead = fs.readSync(fd, buf, 0, readSize, pos); + if (bytesRead === 0) + break; + pos += bytesRead; + p.write(buf.subarray(0, bytesRead)); + } + p.end(); + } + } + finally { + if (typeof fd === 'number') { + try { + fs.closeSync(fd); + /* c8 ignore next */ + } + catch (er) { } + } + } +}; +const listFile = (opt, _files) => { + const parse = new Parser(opt); + const readSize = opt.maxReadSize || 16 * 1024 * 1024; + const file = opt.file; + const p = new Promise((resolve, reject) => { + parse.on('error', reject); + parse.on('end', resolve); + fs.stat(file, (er, stat) => { + if (er) { + reject(er); + } + else { + const stream = new fsm.ReadStream(file, { + readSize: readSize, + size: stat.size, + }); + stream.on('error', reject); + stream.pipe(parse); + } + }); + }); + return p; +}; +export const list = makeCommand(listFileSync, listFile, opt => new Parser(opt), opt => new Parser(opt), (opt, files) => { + if (files?.length) + filesFilter(opt, files); + if (!opt.noResume) + onReadEntryFunction(opt); +}); +//# sourceMappingURL=list.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/make-command.js b/node_modules/tar/dist/esm/make-command.js new file mode 100644 index 0000000000000..f2f737bca78fd --- /dev/null +++ b/node_modules/tar/dist/esm/make-command.js @@ -0,0 +1,57 @@ +import { dealias, isAsyncFile, isAsyncNoFile, isSyncFile, isSyncNoFile, } from './options.js'; +export const makeCommand = (syncFile, asyncFile, syncNoFile, asyncNoFile, validate) => { + return Object.assign((opt_ = [], entries, cb) => { + if (Array.isArray(opt_)) { + entries = opt_; + opt_ = {}; + } + if (typeof entries === 'function') { + cb = entries; + entries = undefined; + } + if (!entries) { + entries = []; + } + else { + entries = Array.from(entries); + } + const opt = dealias(opt_); + validate?.(opt, entries); + if (isSyncFile(opt)) { + if (typeof cb === 'function') { + throw new TypeError('callback not supported for sync tar functions'); + } + return syncFile(opt, entries); + } + else if (isAsyncFile(opt)) { + const p = asyncFile(opt, entries); + // weirdness to make TS happy + const c = cb ? cb : undefined; + return c ? p.then(() => c(), c) : p; + } + else if (isSyncNoFile(opt)) { + if (typeof cb === 'function') { + throw new TypeError('callback not supported for sync tar functions'); + } + return syncNoFile(opt, entries); + } + else if (isAsyncNoFile(opt)) { + if (typeof cb === 'function') { + throw new TypeError('callback only supported with file option'); + } + return asyncNoFile(opt, entries); + /* c8 ignore start */ + } + else { + throw new Error('impossible options??'); + } + /* c8 ignore stop */ + }, { + syncFile, + asyncFile, + syncNoFile, + asyncNoFile, + validate, + }); +}; +//# sourceMappingURL=make-command.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/mkdir.js b/node_modules/tar/dist/esm/mkdir.js new file mode 100644 index 0000000000000..9dba701f2973f --- /dev/null +++ b/node_modules/tar/dist/esm/mkdir.js @@ -0,0 +1,180 @@ +import { chownr, chownrSync } from 'chownr'; +import fs from 'node:fs'; +import fsp from 'node:fs/promises'; +import path from 'node:path'; +import { CwdError } from './cwd-error.js'; +import { normalizeWindowsPath } from './normalize-windows-path.js'; +import { SymlinkError } from './symlink-error.js'; +const checkCwd = (dir, cb) => { + fs.stat(dir, (er, st) => { + if (er || !st.isDirectory()) { + er = new CwdError(dir, er?.code || 'ENOTDIR'); + } + cb(er); + }); +}; +/** + * Wrapper around fs/promises.mkdir for tar's needs. + * + * The main purpose is to avoid creating directories if we know that + * they already exist (and track which ones exist for this purpose), + * and prevent entries from being extracted into symlinked folders, + * if `preservePaths` is not set. + */ +export const mkdir = (dir, opt, cb) => { + dir = normalizeWindowsPath(dir); + // if there's any overlap between mask and mode, + // then we'll need an explicit chmod + /* c8 ignore next */ + const umask = opt.umask ?? 0o22; + const mode = opt.mode | 0o0700; + const needChmod = (mode & umask) !== 0; + const uid = opt.uid; + const gid = opt.gid; + const doChown = typeof uid === 'number' && + typeof gid === 'number' && + (uid !== opt.processUid || gid !== opt.processGid); + const preserve = opt.preserve; + const unlink = opt.unlink; + const cwd = normalizeWindowsPath(opt.cwd); + const done = (er, created) => { + if (er) { + cb(er); + } + else { + if (created && doChown) { + chownr(created, uid, gid, er => done(er)); + } + else if (needChmod) { + fs.chmod(dir, mode, cb); + } + else { + cb(); + } + } + }; + if (dir === cwd) { + return checkCwd(dir, done); + } + if (preserve) { + return fsp.mkdir(dir, { mode, recursive: true }).then(made => done(null, made ?? undefined), // oh, ts + done); + } + const sub = normalizeWindowsPath(path.relative(cwd, dir)); + const parts = sub.split('/'); + mkdir_(cwd, parts, mode, unlink, cwd, undefined, done); +}; +const mkdir_ = (base, parts, mode, unlink, cwd, created, cb) => { + if (!parts.length) { + return cb(null, created); + } + const p = parts.shift(); + const part = normalizeWindowsPath(path.resolve(base + '/' + p)); + fs.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb)); +}; +const onmkdir = (part, parts, mode, unlink, cwd, created, cb) => (er) => { + if (er) { + fs.lstat(part, (statEr, st) => { + if (statEr) { + statEr.path = + statEr.path && normalizeWindowsPath(statEr.path); + cb(statEr); + } + else if (st.isDirectory()) { + mkdir_(part, parts, mode, unlink, cwd, created, cb); + } + else if (unlink) { + fs.unlink(part, er => { + if (er) { + return cb(er); + } + fs.mkdir(part, mode, onmkdir(part, parts, mode, unlink, cwd, created, cb)); + }); + } + else if (st.isSymbolicLink()) { + return cb(new SymlinkError(part, part + '/' + parts.join('/'))); + } + else { + cb(er); + } + }); + } + else { + created = created || part; + mkdir_(part, parts, mode, unlink, cwd, created, cb); + } +}; +const checkCwdSync = (dir) => { + let ok = false; + let code = undefined; + try { + ok = fs.statSync(dir).isDirectory(); + } + catch (er) { + code = er?.code; + } + finally { + if (!ok) { + throw new CwdError(dir, code ?? 'ENOTDIR'); + } + } +}; +export const mkdirSync = (dir, opt) => { + dir = normalizeWindowsPath(dir); + // if there's any overlap between mask and mode, + // then we'll need an explicit chmod + /* c8 ignore next */ + const umask = opt.umask ?? 0o22; + const mode = opt.mode | 0o700; + const needChmod = (mode & umask) !== 0; + const uid = opt.uid; + const gid = opt.gid; + const doChown = typeof uid === 'number' && + typeof gid === 'number' && + (uid !== opt.processUid || gid !== opt.processGid); + const preserve = opt.preserve; + const unlink = opt.unlink; + const cwd = normalizeWindowsPath(opt.cwd); + const done = (created) => { + if (created && doChown) { + chownrSync(created, uid, gid); + } + if (needChmod) { + fs.chmodSync(dir, mode); + } + }; + if (dir === cwd) { + checkCwdSync(cwd); + return done(); + } + if (preserve) { + return done(fs.mkdirSync(dir, { mode, recursive: true }) ?? undefined); + } + const sub = normalizeWindowsPath(path.relative(cwd, dir)); + const parts = sub.split('/'); + let created = undefined; + for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) { + part = normalizeWindowsPath(path.resolve(part)); + try { + fs.mkdirSync(part, mode); + created = created || part; + } + catch (er) { + const st = fs.lstatSync(part); + if (st.isDirectory()) { + continue; + } + else if (unlink) { + fs.unlinkSync(part); + fs.mkdirSync(part, mode); + created = created || part; + continue; + } + else if (st.isSymbolicLink()) { + return new SymlinkError(part, part + '/' + parts.join('/')); + } + } + } + return done(created); +}; +//# sourceMappingURL=mkdir.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/mode-fix.js b/node_modules/tar/dist/esm/mode-fix.js new file mode 100644 index 0000000000000..5fd3bb88c1cb2 --- /dev/null +++ b/node_modules/tar/dist/esm/mode-fix.js @@ -0,0 +1,25 @@ +export const modeFix = (mode, isDir, portable) => { + mode &= 0o7777; + // in portable mode, use the minimum reasonable umask + // if this system creates files with 0o664 by default + // (as some linux distros do), then we'll write the + // archive with 0o644 instead. Also, don't ever create + // a file that is not readable/writable by the owner. + if (portable) { + mode = (mode | 0o600) & ~0o22; + } + // if dirs are readable, then they should be listable + if (isDir) { + if (mode & 0o400) { + mode |= 0o100; + } + if (mode & 0o40) { + mode |= 0o10; + } + if (mode & 0o4) { + mode |= 0o1; + } + } + return mode; +}; +//# sourceMappingURL=mode-fix.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/normalize-unicode.js b/node_modules/tar/dist/esm/normalize-unicode.js new file mode 100644 index 0000000000000..8fa17f5b9ce97 --- /dev/null +++ b/node_modules/tar/dist/esm/normalize-unicode.js @@ -0,0 +1,34 @@ +// warning: extremely hot code path. +// This has been meticulously optimized for use +// within npm install on large package trees. +// Do not edit without careful benchmarking. +const normalizeCache = Object.create(null); +// Limit the size of this. Very low-sophistication LRU cache +const MAX = 10000; +const cache = new Set(); +export const normalizeUnicode = (s) => { + if (!cache.has(s)) { + // shake out identical accents and ligatures + normalizeCache[s] = s + .normalize('NFD') + .toLocaleLowerCase('en') + .toLocaleUpperCase('en'); + } + else { + cache.delete(s); + } + cache.add(s); + const ret = normalizeCache[s]; + let i = cache.size - MAX; + // only prune when we're 10% over the max + if (i > MAX / 10) { + for (const s of cache) { + cache.delete(s); + delete normalizeCache[s]; + if (--i <= 0) + break; + } + } + return ret; +}; +//# sourceMappingURL=normalize-unicode.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/normalize-windows-path.js b/node_modules/tar/dist/esm/normalize-windows-path.js new file mode 100644 index 0000000000000..2d97d2b884e62 --- /dev/null +++ b/node_modules/tar/dist/esm/normalize-windows-path.js @@ -0,0 +1,9 @@ +// on windows, either \ or / are valid directory separators. +// on unix, \ is a valid character in filenames. +// so, on windows, and only on windows, we replace all \ chars with /, +// so that we can use / as our one and only directory separator char. +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; +export const normalizeWindowsPath = platform !== 'win32' ? + (p) => p + : (p) => p && p.replace(/\\/g, '/'); +//# sourceMappingURL=normalize-windows-path.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/options.js b/node_modules/tar/dist/esm/options.js new file mode 100644 index 0000000000000..a006d36c23c92 --- /dev/null +++ b/node_modules/tar/dist/esm/options.js @@ -0,0 +1,54 @@ +// turn tar(1) style args like `C` into the more verbose things like `cwd` +const argmap = new Map([ + ['C', 'cwd'], + ['f', 'file'], + ['z', 'gzip'], + ['P', 'preservePaths'], + ['U', 'unlink'], + ['strip-components', 'strip'], + ['stripComponents', 'strip'], + ['keep-newer', 'newer'], + ['keepNewer', 'newer'], + ['keep-newer-files', 'newer'], + ['keepNewerFiles', 'newer'], + ['k', 'keep'], + ['keep-existing', 'keep'], + ['keepExisting', 'keep'], + ['m', 'noMtime'], + ['no-mtime', 'noMtime'], + ['p', 'preserveOwner'], + ['L', 'follow'], + ['h', 'follow'], + ['onentry', 'onReadEntry'], +]); +export const isSyncFile = (o) => !!o.sync && !!o.file; +export const isAsyncFile = (o) => !o.sync && !!o.file; +export const isSyncNoFile = (o) => !!o.sync && !o.file; +export const isAsyncNoFile = (o) => !o.sync && !o.file; +export const isSync = (o) => !!o.sync; +export const isAsync = (o) => !o.sync; +export const isFile = (o) => !!o.file; +export const isNoFile = (o) => !o.file; +const dealiasKey = (k) => { + const d = argmap.get(k); + if (d) + return d; + return k; +}; +export const dealias = (opt = {}) => { + if (!opt) + return {}; + const result = {}; + for (const [key, v] of Object.entries(opt)) { + // TS doesn't know that aliases are going to always be the same type + const k = dealiasKey(key); + result[k] = v; + } + // affordance for deprecated noChmod -> chmod + if (result.chmod === undefined && result.noChmod === false) { + result.chmod = true; + } + delete result.noChmod; + return result; +}; +//# sourceMappingURL=options.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/pack.js b/node_modules/tar/dist/esm/pack.js new file mode 100644 index 0000000000000..95d9342ac34e6 --- /dev/null +++ b/node_modules/tar/dist/esm/pack.js @@ -0,0 +1,474 @@ +// A readable tar stream creator +// Technically, this is a transform stream that you write paths into, +// and tar format comes out of. +// The `add()` method is like `write()` but returns this, +// and end() return `this` as well, so you can +// do `new Pack(opt).add('files').add('dir').end().pipe(output) +// You could also do something like: +// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar')) +import fs from 'fs'; +import { WriteEntry, WriteEntrySync, WriteEntryTar, } from './write-entry.js'; +export class PackJob { + path; + absolute; + entry; + stat; + readdir; + pending = false; + ignore = false; + piped = false; + constructor(path, absolute) { + this.path = path || './'; + this.absolute = absolute; + } +} +import { Minipass } from 'minipass'; +import * as zlib from 'minizlib'; +import { Yallist } from 'yallist'; +import { ReadEntry } from './read-entry.js'; +import { warnMethod, } from './warn-method.js'; +const EOF = Buffer.alloc(1024); +const ONSTAT = Symbol('onStat'); +const ENDED = Symbol('ended'); +const QUEUE = Symbol('queue'); +const CURRENT = Symbol('current'); +const PROCESS = Symbol('process'); +const PROCESSING = Symbol('processing'); +const PROCESSJOB = Symbol('processJob'); +const JOBS = Symbol('jobs'); +const JOBDONE = Symbol('jobDone'); +const ADDFSENTRY = Symbol('addFSEntry'); +const ADDTARENTRY = Symbol('addTarEntry'); +const STAT = Symbol('stat'); +const READDIR = Symbol('readdir'); +const ONREADDIR = Symbol('onreaddir'); +const PIPE = Symbol('pipe'); +const ENTRY = Symbol('entry'); +const ENTRYOPT = Symbol('entryOpt'); +const WRITEENTRYCLASS = Symbol('writeEntryClass'); +const WRITE = Symbol('write'); +const ONDRAIN = Symbol('ondrain'); +import path from 'path'; +import { normalizeWindowsPath } from './normalize-windows-path.js'; +export class Pack extends Minipass { + sync = false; + opt; + cwd; + maxReadSize; + preservePaths; + strict; + noPax; + prefix; + linkCache; + statCache; + file; + portable; + zip; + readdirCache; + noDirRecurse; + follow; + noMtime; + mtime; + filter; + jobs; + [WRITEENTRYCLASS]; + onWriteEntry; + // Note: we actually DO need a linked list here, because we + // shift() to update the head of the list where we start, but still + // while that happens, need to know what the next item in the queue + // will be. Since we do multiple jobs in parallel, it's not as simple + // as just an Array.shift(), since that would lose the information about + // the next job in the list. We could add a .next field on the PackJob + // class, but then we'd have to be tracking the tail of the queue the + // whole time, and Yallist just does that for us anyway. + [QUEUE]; + [JOBS] = 0; + [PROCESSING] = false; + [ENDED] = false; + constructor(opt = {}) { + //@ts-ignore + super(); + this.opt = opt; + this.file = opt.file || ''; + this.cwd = opt.cwd || process.cwd(); + this.maxReadSize = opt.maxReadSize; + this.preservePaths = !!opt.preservePaths; + this.strict = !!opt.strict; + this.noPax = !!opt.noPax; + this.prefix = normalizeWindowsPath(opt.prefix || ''); + this.linkCache = opt.linkCache || new Map(); + this.statCache = opt.statCache || new Map(); + this.readdirCache = opt.readdirCache || new Map(); + this.onWriteEntry = opt.onWriteEntry; + this[WRITEENTRYCLASS] = WriteEntry; + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + this.portable = !!opt.portable; + if (opt.gzip || opt.brotli || opt.zstd) { + if ((opt.gzip ? 1 : 0) + + (opt.brotli ? 1 : 0) + + (opt.zstd ? 1 : 0) > + 1) { + throw new TypeError('gzip, brotli, zstd are mutually exclusive'); + } + if (opt.gzip) { + if (typeof opt.gzip !== 'object') { + opt.gzip = {}; + } + if (this.portable) { + opt.gzip.portable = true; + } + this.zip = new zlib.Gzip(opt.gzip); + } + if (opt.brotli) { + if (typeof opt.brotli !== 'object') { + opt.brotli = {}; + } + this.zip = new zlib.BrotliCompress(opt.brotli); + } + if (opt.zstd) { + if (typeof opt.zstd !== 'object') { + opt.zstd = {}; + } + this.zip = new zlib.ZstdCompress(opt.zstd); + } + /* c8 ignore next */ + if (!this.zip) + throw new Error('impossible'); + const zip = this.zip; + zip.on('data', chunk => super.write(chunk)); + zip.on('end', () => super.end()); + zip.on('drain', () => this[ONDRAIN]()); + this.on('resume', () => zip.resume()); + } + else { + this.on('drain', this[ONDRAIN]); + } + this.noDirRecurse = !!opt.noDirRecurse; + this.follow = !!opt.follow; + this.noMtime = !!opt.noMtime; + if (opt.mtime) + this.mtime = opt.mtime; + this.filter = + typeof opt.filter === 'function' ? opt.filter : () => true; + this[QUEUE] = new Yallist(); + this[JOBS] = 0; + this.jobs = Number(opt.jobs) || 4; + this[PROCESSING] = false; + this[ENDED] = false; + } + [WRITE](chunk) { + return super.write(chunk); + } + add(path) { + this.write(path); + return this; + } + end(path, encoding, cb) { + /* c8 ignore start */ + if (typeof path === 'function') { + cb = path; + path = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + /* c8 ignore stop */ + if (path) { + this.add(path); + } + this[ENDED] = true; + this[PROCESS](); + /* c8 ignore next */ + if (cb) + cb(); + return this; + } + write(path) { + if (this[ENDED]) { + throw new Error('write after end'); + } + if (path instanceof ReadEntry) { + this[ADDTARENTRY](path); + } + else { + this[ADDFSENTRY](path); + } + return this.flowing; + } + [ADDTARENTRY](p) { + const absolute = normalizeWindowsPath(path.resolve(this.cwd, p.path)); + // in this case, we don't have to wait for the stat + if (!this.filter(p.path, p)) { + p.resume(); + } + else { + const job = new PackJob(p.path, absolute); + job.entry = new WriteEntryTar(p, this[ENTRYOPT](job)); + job.entry.on('end', () => this[JOBDONE](job)); + this[JOBS] += 1; + this[QUEUE].push(job); + } + this[PROCESS](); + } + [ADDFSENTRY](p) { + const absolute = normalizeWindowsPath(path.resolve(this.cwd, p)); + this[QUEUE].push(new PackJob(p, absolute)); + this[PROCESS](); + } + [STAT](job) { + job.pending = true; + this[JOBS] += 1; + const stat = this.follow ? 'stat' : 'lstat'; + fs[stat](job.absolute, (er, stat) => { + job.pending = false; + this[JOBS] -= 1; + if (er) { + this.emit('error', er); + } + else { + this[ONSTAT](job, stat); + } + }); + } + [ONSTAT](job, stat) { + this.statCache.set(job.absolute, stat); + job.stat = stat; + // now we have the stat, we can filter it. + if (!this.filter(job.path, stat)) { + job.ignore = true; + } + else if (stat.isFile() && + stat.nlink > 1 && + job === this[CURRENT] && + !this.linkCache.get(`${stat.dev}:${stat.ino}`) && + !this.sync) { + // if it's not filtered, and it's a new File entry, + // jump the queue in case any pending Link entries are about + // to try to link to it. This prevents a hardlink from coming ahead + // of its target in the archive. + this[PROCESSJOB](job); + } + this[PROCESS](); + } + [READDIR](job) { + job.pending = true; + this[JOBS] += 1; + fs.readdir(job.absolute, (er, entries) => { + job.pending = false; + this[JOBS] -= 1; + if (er) { + return this.emit('error', er); + } + this[ONREADDIR](job, entries); + }); + } + [ONREADDIR](job, entries) { + this.readdirCache.set(job.absolute, entries); + job.readdir = entries; + this[PROCESS](); + } + [PROCESS]() { + if (this[PROCESSING]) { + return; + } + this[PROCESSING] = true; + for (let w = this[QUEUE].head; !!w && this[JOBS] < this.jobs; w = w.next) { + this[PROCESSJOB](w.value); + if (w.value.ignore) { + const p = w.next; + this[QUEUE].removeNode(w); + w.next = p; + } + } + this[PROCESSING] = false; + if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) { + if (this.zip) { + this.zip.end(EOF); + } + else { + super.write(EOF); + super.end(); + } + } + } + get [CURRENT]() { + return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value; + } + [JOBDONE](_job) { + this[QUEUE].shift(); + this[JOBS] -= 1; + this[PROCESS](); + } + [PROCESSJOB](job) { + if (job.pending) { + return; + } + if (job.entry) { + if (job === this[CURRENT] && !job.piped) { + this[PIPE](job); + } + return; + } + if (!job.stat) { + const sc = this.statCache.get(job.absolute); + if (sc) { + this[ONSTAT](job, sc); + } + else { + this[STAT](job); + } + } + if (!job.stat) { + return; + } + // filtered out! + if (job.ignore) { + return; + } + if (!this.noDirRecurse && + job.stat.isDirectory() && + !job.readdir) { + const rc = this.readdirCache.get(job.absolute); + if (rc) { + this[ONREADDIR](job, rc); + } + else { + this[READDIR](job); + } + if (!job.readdir) { + return; + } + } + // we know it doesn't have an entry, because that got checked above + job.entry = this[ENTRY](job); + if (!job.entry) { + job.ignore = true; + return; + } + if (job === this[CURRENT] && !job.piped) { + this[PIPE](job); + } + } + [ENTRYOPT](job) { + return { + onwarn: (code, msg, data) => this.warn(code, msg, data), + noPax: this.noPax, + cwd: this.cwd, + absolute: job.absolute, + preservePaths: this.preservePaths, + maxReadSize: this.maxReadSize, + strict: this.strict, + portable: this.portable, + linkCache: this.linkCache, + statCache: this.statCache, + noMtime: this.noMtime, + mtime: this.mtime, + prefix: this.prefix, + onWriteEntry: this.onWriteEntry, + }; + } + [ENTRY](job) { + this[JOBS] += 1; + try { + const e = new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job)); + return e + .on('end', () => this[JOBDONE](job)) + .on('error', er => this.emit('error', er)); + } + catch (er) { + this.emit('error', er); + } + } + [ONDRAIN]() { + if (this[CURRENT] && this[CURRENT].entry) { + this[CURRENT].entry.resume(); + } + } + // like .pipe() but using super, because our write() is special + [PIPE](job) { + job.piped = true; + if (job.readdir) { + job.readdir.forEach(entry => { + const p = job.path; + const base = p === './' ? '' : p.replace(/\/*$/, '/'); + this[ADDFSENTRY](base + entry); + }); + } + const source = job.entry; + const zip = this.zip; + /* c8 ignore start */ + if (!source) + throw new Error('cannot pipe without source'); + /* c8 ignore stop */ + if (zip) { + source.on('data', chunk => { + if (!zip.write(chunk)) { + source.pause(); + } + }); + } + else { + source.on('data', chunk => { + if (!super.write(chunk)) { + source.pause(); + } + }); + } + } + pause() { + if (this.zip) { + this.zip.pause(); + } + return super.pause(); + } + warn(code, message, data = {}) { + warnMethod(this, code, message, data); + } +} +export class PackSync extends Pack { + sync = true; + constructor(opt) { + super(opt); + this[WRITEENTRYCLASS] = WriteEntrySync; + } + // pause/resume are no-ops in sync streams. + pause() { } + resume() { } + [STAT](job) { + const stat = this.follow ? 'statSync' : 'lstatSync'; + this[ONSTAT](job, fs[stat](job.absolute)); + } + [READDIR](job) { + this[ONREADDIR](job, fs.readdirSync(job.absolute)); + } + // gotta get it all in this tick + [PIPE](job) { + const source = job.entry; + const zip = this.zip; + if (job.readdir) { + job.readdir.forEach(entry => { + const p = job.path; + const base = p === './' ? '' : p.replace(/\/*$/, '/'); + this[ADDFSENTRY](base + entry); + }); + } + /* c8 ignore start */ + if (!source) + throw new Error('Cannot pipe without source'); + /* c8 ignore stop */ + if (zip) { + source.on('data', chunk => { + zip.write(chunk); + }); + } + else { + source.on('data', chunk => { + super[WRITE](chunk); + }); + } + } +} +//# sourceMappingURL=pack.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/package.json b/node_modules/tar/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/tar/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/tar/dist/esm/parse.js b/node_modules/tar/dist/esm/parse.js new file mode 100644 index 0000000000000..50592a1dec635 --- /dev/null +++ b/node_modules/tar/dist/esm/parse.js @@ -0,0 +1,616 @@ +// this[BUFFER] is the remainder of a chunk if we're waiting for +// the full 512 bytes of a header to come in. We will Buffer.concat() +// it to the next write(), which is a mem copy, but a small one. +// +// this[QUEUE] is a list of entries that haven't been emitted +// yet this can only get filled up if the user keeps write()ing after +// a write() returns false, or does a write() with more than one entry +// +// We don't buffer chunks, we always parse them and either create an +// entry, or push it into the active entry. The ReadEntry class knows +// to throw data away if .ignore=true +// +// Shift entry off the buffer when it emits 'end', and emit 'entry' for +// the next one in the list. +// +// At any time, we're pushing body chunks into the entry at WRITEENTRY, +// and waiting for 'end' on the entry at READENTRY +// +// ignored entries get .resume() called on them straight away +import { EventEmitter as EE } from 'events'; +import { BrotliDecompress, Unzip, ZstdDecompress } from 'minizlib'; +import { Header } from './header.js'; +import { Pax } from './pax.js'; +import { ReadEntry } from './read-entry.js'; +import { warnMethod, } from './warn-method.js'; +const maxMetaEntrySize = 1024 * 1024; +const gzipHeader = Buffer.from([0x1f, 0x8b]); +const zstdHeader = Buffer.from([0x28, 0xb5, 0x2f, 0xfd]); +const ZIP_HEADER_LEN = Math.max(gzipHeader.length, zstdHeader.length); +const STATE = Symbol('state'); +const WRITEENTRY = Symbol('writeEntry'); +const READENTRY = Symbol('readEntry'); +const NEXTENTRY = Symbol('nextEntry'); +const PROCESSENTRY = Symbol('processEntry'); +const EX = Symbol('extendedHeader'); +const GEX = Symbol('globalExtendedHeader'); +const META = Symbol('meta'); +const EMITMETA = Symbol('emitMeta'); +const BUFFER = Symbol('buffer'); +const QUEUE = Symbol('queue'); +const ENDED = Symbol('ended'); +const EMITTEDEND = Symbol('emittedEnd'); +const EMIT = Symbol('emit'); +const UNZIP = Symbol('unzip'); +const CONSUMECHUNK = Symbol('consumeChunk'); +const CONSUMECHUNKSUB = Symbol('consumeChunkSub'); +const CONSUMEBODY = Symbol('consumeBody'); +const CONSUMEMETA = Symbol('consumeMeta'); +const CONSUMEHEADER = Symbol('consumeHeader'); +const CONSUMING = Symbol('consuming'); +const BUFFERCONCAT = Symbol('bufferConcat'); +const MAYBEEND = Symbol('maybeEnd'); +const WRITING = Symbol('writing'); +const ABORTED = Symbol('aborted'); +const DONE = Symbol('onDone'); +const SAW_VALID_ENTRY = Symbol('sawValidEntry'); +const SAW_NULL_BLOCK = Symbol('sawNullBlock'); +const SAW_EOF = Symbol('sawEOF'); +const CLOSESTREAM = Symbol('closeStream'); +const noop = () => true; +export class Parser extends EE { + file; + strict; + maxMetaEntrySize; + filter; + brotli; + zstd; + writable = true; + readable = false; + [QUEUE] = []; + [BUFFER]; + [READENTRY]; + [WRITEENTRY]; + [STATE] = 'begin'; + [META] = ''; + [EX]; + [GEX]; + [ENDED] = false; + [UNZIP]; + [ABORTED] = false; + [SAW_VALID_ENTRY]; + [SAW_NULL_BLOCK] = false; + [SAW_EOF] = false; + [WRITING] = false; + [CONSUMING] = false; + [EMITTEDEND] = false; + constructor(opt = {}) { + super(); + this.file = opt.file || ''; + // these BADARCHIVE errors can't be detected early. listen on DONE. + this.on(DONE, () => { + if (this[STATE] === 'begin' || + this[SAW_VALID_ENTRY] === false) { + // either less than 1 block of data, or all entries were invalid. + // Either way, probably not even a tarball. + this.warn('TAR_BAD_ARCHIVE', 'Unrecognized archive format'); + } + }); + if (opt.ondone) { + this.on(DONE, opt.ondone); + } + else { + this.on(DONE, () => { + this.emit('prefinish'); + this.emit('finish'); + this.emit('end'); + }); + } + this.strict = !!opt.strict; + this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize; + this.filter = typeof opt.filter === 'function' ? opt.filter : noop; + // Unlike gzip, brotli doesn't have any magic bytes to identify it + // Users need to explicitly tell us they're extracting a brotli file + // Or we infer from the file extension + const isTBR = opt.file && + (opt.file.endsWith('.tar.br') || opt.file.endsWith('.tbr')); + // if it's a tbr file it MIGHT be brotli, but we don't know until + // we look at it and verify it's not a valid tar file. + this.brotli = + !(opt.gzip || opt.zstd) && opt.brotli !== undefined ? opt.brotli + : isTBR ? undefined + : false; + // zstd has magic bytes to identify it, but we also support explicit options + // and file extension detection + const isTZST = opt.file && + (opt.file.endsWith('.tar.zst') || opt.file.endsWith('.tzst')); + this.zstd = + !(opt.gzip || opt.brotli) && opt.zstd !== undefined ? opt.zstd + : isTZST ? true + : undefined; + // have to set this so that streams are ok piping into it + this.on('end', () => this[CLOSESTREAM]()); + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + if (typeof opt.onReadEntry === 'function') { + this.on('entry', opt.onReadEntry); + } + } + warn(code, message, data = {}) { + warnMethod(this, code, message, data); + } + [CONSUMEHEADER](chunk, position) { + if (this[SAW_VALID_ENTRY] === undefined) { + this[SAW_VALID_ENTRY] = false; + } + let header; + try { + header = new Header(chunk, position, this[EX], this[GEX]); + } + catch (er) { + return this.warn('TAR_ENTRY_INVALID', er); + } + if (header.nullBlock) { + if (this[SAW_NULL_BLOCK]) { + this[SAW_EOF] = true; + // ending an archive with no entries. pointless, but legal. + if (this[STATE] === 'begin') { + this[STATE] = 'header'; + } + this[EMIT]('eof'); + } + else { + this[SAW_NULL_BLOCK] = true; + this[EMIT]('nullBlock'); + } + } + else { + this[SAW_NULL_BLOCK] = false; + if (!header.cksumValid) { + this.warn('TAR_ENTRY_INVALID', 'checksum failure', { header }); + } + else if (!header.path) { + this.warn('TAR_ENTRY_INVALID', 'path is required', { header }); + } + else { + const type = header.type; + if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) { + this.warn('TAR_ENTRY_INVALID', 'linkpath required', { + header, + }); + } + else if (!/^(Symbolic)?Link$/.test(type) && + !/^(Global)?ExtendedHeader$/.test(type) && + header.linkpath) { + this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', { + header, + }); + } + else { + const entry = (this[WRITEENTRY] = new ReadEntry(header, this[EX], this[GEX])); + // we do this for meta & ignored entries as well, because they + // are still valid tar, or else we wouldn't know to ignore them + if (!this[SAW_VALID_ENTRY]) { + if (entry.remain) { + // this might be the one! + const onend = () => { + if (!entry.invalid) { + this[SAW_VALID_ENTRY] = true; + } + }; + entry.on('end', onend); + } + else { + this[SAW_VALID_ENTRY] = true; + } + } + if (entry.meta) { + if (entry.size > this.maxMetaEntrySize) { + entry.ignore = true; + this[EMIT]('ignoredEntry', entry); + this[STATE] = 'ignore'; + entry.resume(); + } + else if (entry.size > 0) { + this[META] = ''; + entry.on('data', c => (this[META] += c)); + this[STATE] = 'meta'; + } + } + else { + this[EX] = undefined; + entry.ignore = + entry.ignore || !this.filter(entry.path, entry); + if (entry.ignore) { + // probably valid, just not something we care about + this[EMIT]('ignoredEntry', entry); + this[STATE] = entry.remain ? 'ignore' : 'header'; + entry.resume(); + } + else { + if (entry.remain) { + this[STATE] = 'body'; + } + else { + this[STATE] = 'header'; + entry.end(); + } + if (!this[READENTRY]) { + this[QUEUE].push(entry); + this[NEXTENTRY](); + } + else { + this[QUEUE].push(entry); + } + } + } + } + } + } + } + [CLOSESTREAM]() { + queueMicrotask(() => this.emit('close')); + } + [PROCESSENTRY](entry) { + let go = true; + if (!entry) { + this[READENTRY] = undefined; + go = false; + } + else if (Array.isArray(entry)) { + const [ev, ...args] = entry; + this.emit(ev, ...args); + } + else { + this[READENTRY] = entry; + this.emit('entry', entry); + if (!entry.emittedEnd) { + entry.on('end', () => this[NEXTENTRY]()); + go = false; + } + } + return go; + } + [NEXTENTRY]() { + do { } while (this[PROCESSENTRY](this[QUEUE].shift())); + if (!this[QUEUE].length) { + // At this point, there's nothing in the queue, but we may have an + // entry which is being consumed (readEntry). + // If we don't, then we definitely can handle more data. + // If we do, and either it's flowing, or it has never had any data + // written to it, then it needs more. + // The only other possibility is that it has returned false from a + // write() call, so we wait for the next drain to continue. + const re = this[READENTRY]; + const drainNow = !re || re.flowing || re.size === re.remain; + if (drainNow) { + if (!this[WRITING]) { + this.emit('drain'); + } + } + else { + re.once('drain', () => this.emit('drain')); + } + } + } + [CONSUMEBODY](chunk, position) { + // write up to but no more than writeEntry.blockRemain + const entry = this[WRITEENTRY]; + /* c8 ignore start */ + if (!entry) { + throw new Error('attempt to consume body without entry??'); + } + const br = entry.blockRemain ?? 0; + /* c8 ignore stop */ + const c = br >= chunk.length && position === 0 ? + chunk + : chunk.subarray(position, position + br); + entry.write(c); + if (!entry.blockRemain) { + this[STATE] = 'header'; + this[WRITEENTRY] = undefined; + entry.end(); + } + return c.length; + } + [CONSUMEMETA](chunk, position) { + const entry = this[WRITEENTRY]; + const ret = this[CONSUMEBODY](chunk, position); + // if we finished, then the entry is reset + if (!this[WRITEENTRY] && entry) { + this[EMITMETA](entry); + } + return ret; + } + [EMIT](ev, data, extra) { + if (!this[QUEUE].length && !this[READENTRY]) { + this.emit(ev, data, extra); + } + else { + this[QUEUE].push([ev, data, extra]); + } + } + [EMITMETA](entry) { + this[EMIT]('meta', this[META]); + switch (entry.type) { + case 'ExtendedHeader': + case 'OldExtendedHeader': + this[EX] = Pax.parse(this[META], this[EX], false); + break; + case 'GlobalExtendedHeader': + this[GEX] = Pax.parse(this[META], this[GEX], true); + break; + case 'NextFileHasLongPath': + case 'OldGnuLongPath': { + const ex = this[EX] ?? Object.create(null); + this[EX] = ex; + ex.path = this[META].replace(/\0.*/, ''); + break; + } + case 'NextFileHasLongLinkpath': { + const ex = this[EX] || Object.create(null); + this[EX] = ex; + ex.linkpath = this[META].replace(/\0.*/, ''); + break; + } + /* c8 ignore start */ + default: + throw new Error('unknown meta: ' + entry.type); + /* c8 ignore stop */ + } + } + abort(error) { + this[ABORTED] = true; + this.emit('abort', error); + // always throws, even in non-strict mode + this.warn('TAR_ABORT', error, { recoverable: false }); + } + write(chunk, encoding, cb) { + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, + /* c8 ignore next */ + typeof encoding === 'string' ? encoding : 'utf8'); + } + if (this[ABORTED]) { + /* c8 ignore next */ + cb?.(); + return false; + } + // first write, might be gzipped, zstd, or brotli compressed + const needSniff = this[UNZIP] === undefined || + (this.brotli === undefined && this[UNZIP] === false); + if (needSniff && chunk) { + if (this[BUFFER]) { + chunk = Buffer.concat([this[BUFFER], chunk]); + this[BUFFER] = undefined; + } + if (chunk.length < ZIP_HEADER_LEN) { + this[BUFFER] = chunk; + /* c8 ignore next */ + cb?.(); + return true; + } + // look for gzip header + for (let i = 0; this[UNZIP] === undefined && i < gzipHeader.length; i++) { + if (chunk[i] !== gzipHeader[i]) { + this[UNZIP] = false; + } + } + // look for zstd header if gzip header not found + let isZstd = false; + if (this[UNZIP] === false && this.zstd !== false) { + isZstd = true; + for (let i = 0; i < zstdHeader.length; i++) { + if (chunk[i] !== zstdHeader[i]) { + isZstd = false; + break; + } + } + } + const maybeBrotli = this.brotli === undefined && !isZstd; + if (this[UNZIP] === false && maybeBrotli) { + // read the first header to see if it's a valid tar file. If so, + // we can safely assume that it's not actually brotli, despite the + // .tbr or .tar.br file extension. + // if we ended before getting a full chunk, yes, def brotli + if (chunk.length < 512) { + if (this[ENDED]) { + this.brotli = true; + } + else { + this[BUFFER] = chunk; + /* c8 ignore next */ + cb?.(); + return true; + } + } + else { + // if it's tar, it's pretty reliably not brotli, chances of + // that happening are astronomical. + try { + new Header(chunk.subarray(0, 512)); + this.brotli = false; + } + catch (_) { + this.brotli = true; + } + } + } + if (this[UNZIP] === undefined || + (this[UNZIP] === false && (this.brotli || isZstd))) { + const ended = this[ENDED]; + this[ENDED] = false; + this[UNZIP] = + this[UNZIP] === undefined ? new Unzip({}) + : isZstd ? new ZstdDecompress({}) + : new BrotliDecompress({}); + this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)); + this[UNZIP].on('error', er => this.abort(er)); + this[UNZIP].on('end', () => { + this[ENDED] = true; + this[CONSUMECHUNK](); + }); + this[WRITING] = true; + const ret = !!this[UNZIP][ended ? 'end' : 'write'](chunk); + this[WRITING] = false; + cb?.(); + return ret; + } + } + this[WRITING] = true; + if (this[UNZIP]) { + this[UNZIP].write(chunk); + } + else { + this[CONSUMECHUNK](chunk); + } + this[WRITING] = false; + // return false if there's a queue, or if the current entry isn't flowing + const ret = this[QUEUE].length ? false + : this[READENTRY] ? this[READENTRY].flowing + : true; + // if we have no queue, then that means a clogged READENTRY + if (!ret && !this[QUEUE].length) { + this[READENTRY]?.once('drain', () => this.emit('drain')); + } + /* c8 ignore next */ + cb?.(); + return ret; + } + [BUFFERCONCAT](c) { + if (c && !this[ABORTED]) { + this[BUFFER] = + this[BUFFER] ? Buffer.concat([this[BUFFER], c]) : c; + } + } + [MAYBEEND]() { + if (this[ENDED] && + !this[EMITTEDEND] && + !this[ABORTED] && + !this[CONSUMING]) { + this[EMITTEDEND] = true; + const entry = this[WRITEENTRY]; + if (entry && entry.blockRemain) { + // truncated, likely a damaged file + const have = this[BUFFER] ? this[BUFFER].length : 0; + this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${entry.blockRemain} more bytes, only ${have} available)`, { entry }); + if (this[BUFFER]) { + entry.write(this[BUFFER]); + } + entry.end(); + } + this[EMIT](DONE); + } + } + [CONSUMECHUNK](chunk) { + if (this[CONSUMING] && chunk) { + this[BUFFERCONCAT](chunk); + } + else if (!chunk && !this[BUFFER]) { + this[MAYBEEND](); + } + else if (chunk) { + this[CONSUMING] = true; + if (this[BUFFER]) { + this[BUFFERCONCAT](chunk); + const c = this[BUFFER]; + this[BUFFER] = undefined; + this[CONSUMECHUNKSUB](c); + } + else { + this[CONSUMECHUNKSUB](chunk); + } + while (this[BUFFER] && + this[BUFFER]?.length >= 512 && + !this[ABORTED] && + !this[SAW_EOF]) { + const c = this[BUFFER]; + this[BUFFER] = undefined; + this[CONSUMECHUNKSUB](c); + } + this[CONSUMING] = false; + } + if (!this[BUFFER] || this[ENDED]) { + this[MAYBEEND](); + } + } + [CONSUMECHUNKSUB](chunk) { + // we know that we are in CONSUMING mode, so anything written goes into + // the buffer. Advance the position and put any remainder in the buffer. + let position = 0; + const length = chunk.length; + while (position + 512 <= length && + !this[ABORTED] && + !this[SAW_EOF]) { + switch (this[STATE]) { + case 'begin': + case 'header': + this[CONSUMEHEADER](chunk, position); + position += 512; + break; + case 'ignore': + case 'body': + position += this[CONSUMEBODY](chunk, position); + break; + case 'meta': + position += this[CONSUMEMETA](chunk, position); + break; + /* c8 ignore start */ + default: + throw new Error('invalid state: ' + this[STATE]); + /* c8 ignore stop */ + } + } + if (position < length) { + if (this[BUFFER]) { + this[BUFFER] = Buffer.concat([ + chunk.subarray(position), + this[BUFFER], + ]); + } + else { + this[BUFFER] = chunk.subarray(position); + } + } + } + end(chunk, encoding, cb) { + if (typeof chunk === 'function') { + cb = chunk; + encoding = undefined; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + if (cb) + this.once('finish', cb); + if (!this[ABORTED]) { + if (this[UNZIP]) { + /* c8 ignore start */ + if (chunk) + this[UNZIP].write(chunk); + /* c8 ignore stop */ + this[UNZIP].end(); + } + else { + this[ENDED] = true; + if (this.brotli === undefined || this.zstd === undefined) + chunk = chunk || Buffer.alloc(0); + if (chunk) + this.write(chunk); + this[MAYBEEND](); + } + } + return this; + } +} +//# sourceMappingURL=parse.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/path-reservations.js b/node_modules/tar/dist/esm/path-reservations.js new file mode 100644 index 0000000000000..f7535c15ea532 --- /dev/null +++ b/node_modules/tar/dist/esm/path-reservations.js @@ -0,0 +1,166 @@ +// A path exclusive reservation system +// reserve([list, of, paths], fn) +// When the fn is first in line for all its paths, it +// is called with a cb that clears the reservation. +// +// Used by async unpack to avoid clobbering paths in use, +// while still allowing maximal safe parallelization. +import { join } from 'node:path'; +import { normalizeUnicode } from './normalize-unicode.js'; +import { stripTrailingSlashes } from './strip-trailing-slashes.js'; +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; +const isWindows = platform === 'win32'; +// return a set of parent dirs for a given path +// '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d'] +const getDirs = (path) => { + const dirs = path + .split('/') + .slice(0, -1) + .reduce((set, path) => { + const s = set[set.length - 1]; + if (s !== undefined) { + path = join(s, path); + } + set.push(path || '/'); + return set; + }, []); + return dirs; +}; +export class PathReservations { + // path => [function or Set] + // A Set object means a directory reservation + // A fn is a direct reservation on that path + #queues = new Map(); + // fn => {paths:[path,...], dirs:[path, ...]} + #reservations = new Map(); + // functions currently running + #running = new Set(); + reserve(paths, fn) { + paths = + isWindows ? + ['win32 parallelization disabled'] + : paths.map(p => { + // don't need normPath, because we skip this entirely for windows + return stripTrailingSlashes(join(normalizeUnicode(p))); + }); + const dirs = new Set(paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b))); + this.#reservations.set(fn, { dirs, paths }); + for (const p of paths) { + const q = this.#queues.get(p); + if (!q) { + this.#queues.set(p, [fn]); + } + else { + q.push(fn); + } + } + for (const dir of dirs) { + const q = this.#queues.get(dir); + if (!q) { + this.#queues.set(dir, [new Set([fn])]); + } + else { + const l = q[q.length - 1]; + if (l instanceof Set) { + l.add(fn); + } + else { + q.push(new Set([fn])); + } + } + } + return this.#run(fn); + } + // return the queues for each path the function cares about + // fn => {paths, dirs} + #getQueues(fn) { + const res = this.#reservations.get(fn); + /* c8 ignore start */ + if (!res) { + throw new Error('function does not have any path reservations'); + } + /* c8 ignore stop */ + return { + paths: res.paths.map((path) => this.#queues.get(path)), + dirs: [...res.dirs].map(path => this.#queues.get(path)), + }; + } + // check if fn is first in line for all its paths, and is + // included in the first set for all its dir queues + check(fn) { + const { paths, dirs } = this.#getQueues(fn); + return (paths.every(q => q && q[0] === fn) && + dirs.every(q => q && q[0] instanceof Set && q[0].has(fn))); + } + // run the function if it's first in line and not already running + #run(fn) { + if (this.#running.has(fn) || !this.check(fn)) { + return false; + } + this.#running.add(fn); + fn(() => this.#clear(fn)); + return true; + } + #clear(fn) { + if (!this.#running.has(fn)) { + return false; + } + const res = this.#reservations.get(fn); + /* c8 ignore start */ + if (!res) { + throw new Error('invalid reservation'); + } + /* c8 ignore stop */ + const { paths, dirs } = res; + const next = new Set(); + for (const path of paths) { + const q = this.#queues.get(path); + /* c8 ignore start */ + if (!q || q?.[0] !== fn) { + continue; + } + /* c8 ignore stop */ + const q0 = q[1]; + if (!q0) { + this.#queues.delete(path); + continue; + } + q.shift(); + if (typeof q0 === 'function') { + next.add(q0); + } + else { + for (const f of q0) { + next.add(f); + } + } + } + for (const dir of dirs) { + const q = this.#queues.get(dir); + const q0 = q?.[0]; + /* c8 ignore next - type safety only */ + if (!q || !(q0 instanceof Set)) + continue; + if (q0.size === 1 && q.length === 1) { + this.#queues.delete(dir); + continue; + } + else if (q0.size === 1) { + q.shift(); + // next one must be a function, + // or else the Set would've been reused + const n = q[0]; + if (typeof n === 'function') { + next.add(n); + } + } + else { + q0.delete(fn); + } + } + this.#running.delete(fn); + next.forEach(fn => this.#run(fn)); + return true; + } +} +//# sourceMappingURL=path-reservations.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/pax.js b/node_modules/tar/dist/esm/pax.js new file mode 100644 index 0000000000000..832808f344da5 --- /dev/null +++ b/node_modules/tar/dist/esm/pax.js @@ -0,0 +1,154 @@ +import { basename } from 'node:path'; +import { Header } from './header.js'; +export class Pax { + atime; + mtime; + ctime; + charset; + comment; + gid; + uid; + gname; + uname; + linkpath; + dev; + ino; + nlink; + path; + size; + mode; + global; + constructor(obj, global = false) { + this.atime = obj.atime; + this.charset = obj.charset; + this.comment = obj.comment; + this.ctime = obj.ctime; + this.dev = obj.dev; + this.gid = obj.gid; + this.global = global; + this.gname = obj.gname; + this.ino = obj.ino; + this.linkpath = obj.linkpath; + this.mtime = obj.mtime; + this.nlink = obj.nlink; + this.path = obj.path; + this.size = obj.size; + this.uid = obj.uid; + this.uname = obj.uname; + } + encode() { + const body = this.encodeBody(); + if (body === '') { + return Buffer.allocUnsafe(0); + } + const bodyLen = Buffer.byteLength(body); + // round up to 512 bytes + // add 512 for header + const bufLen = 512 * Math.ceil(1 + bodyLen / 512); + const buf = Buffer.allocUnsafe(bufLen); + // 0-fill the header section, it might not hit every field + for (let i = 0; i < 512; i++) { + buf[i] = 0; + } + new Header({ + // XXX split the path + // then the path should be PaxHeader + basename, but less than 99, + // prepend with the dirname + /* c8 ignore start */ + path: ('PaxHeader/' + basename(this.path ?? '')).slice(0, 99), + /* c8 ignore stop */ + mode: this.mode || 0o644, + uid: this.uid, + gid: this.gid, + size: bodyLen, + mtime: this.mtime, + type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader', + linkpath: '', + uname: this.uname || '', + gname: this.gname || '', + devmaj: 0, + devmin: 0, + atime: this.atime, + ctime: this.ctime, + }).encode(buf); + buf.write(body, 512, bodyLen, 'utf8'); + // null pad after the body + for (let i = bodyLen + 512; i < buf.length; i++) { + buf[i] = 0; + } + return buf; + } + encodeBody() { + return (this.encodeField('path') + + this.encodeField('ctime') + + this.encodeField('atime') + + this.encodeField('dev') + + this.encodeField('ino') + + this.encodeField('nlink') + + this.encodeField('charset') + + this.encodeField('comment') + + this.encodeField('gid') + + this.encodeField('gname') + + this.encodeField('linkpath') + + this.encodeField('mtime') + + this.encodeField('size') + + this.encodeField('uid') + + this.encodeField('uname')); + } + encodeField(field) { + if (this[field] === undefined) { + return ''; + } + const r = this[field]; + const v = r instanceof Date ? r.getTime() / 1000 : r; + const s = ' ' + + (field === 'dev' || field === 'ino' || field === 'nlink' ? + 'SCHILY.' + : '') + + field + + '=' + + v + + '\n'; + const byteLen = Buffer.byteLength(s); + // the digits includes the length of the digits in ascii base-10 + // so if it's 9 characters, then adding 1 for the 9 makes it 10 + // which makes it 11 chars. + let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1; + if (byteLen + digits >= Math.pow(10, digits)) { + digits += 1; + } + const len = digits + byteLen; + return len + s; + } + static parse(str, ex, g = false) { + return new Pax(merge(parseKV(str), ex), g); + } +} +const merge = (a, b) => b ? Object.assign({}, b, a) : a; +const parseKV = (str) => str + .replace(/\n$/, '') + .split('\n') + .reduce(parseKVLine, Object.create(null)); +const parseKVLine = (set, line) => { + const n = parseInt(line, 10); + // XXX Values with \n in them will fail this. + // Refactor to not be a naive line-by-line parse. + if (n !== Buffer.byteLength(line) + 1) { + return set; + } + line = line.slice((n + ' ').length); + const kv = line.split('='); + const r = kv.shift(); + if (!r) { + return set; + } + const k = r.replace(/^SCHILY\.(dev|ino|nlink)/, '$1'); + const v = kv.join('='); + set[k] = + /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) ? + new Date(Number(v) * 1000) + : /^[0-9]+$/.test(v) ? +v + : v; + return set; +}; +//# sourceMappingURL=pax.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/read-entry.js b/node_modules/tar/dist/esm/read-entry.js new file mode 100644 index 0000000000000..23cc673e61087 --- /dev/null +++ b/node_modules/tar/dist/esm/read-entry.js @@ -0,0 +1,136 @@ +import { Minipass } from 'minipass'; +import { normalizeWindowsPath } from './normalize-windows-path.js'; +export class ReadEntry extends Minipass { + extended; + globalExtended; + header; + startBlockSize; + blockRemain; + remain; + type; + meta = false; + ignore = false; + path; + mode; + uid; + gid; + uname; + gname; + size = 0; + mtime; + atime; + ctime; + linkpath; + dev; + ino; + nlink; + invalid = false; + absolute; + unsupported = false; + constructor(header, ex, gex) { + super({}); + // read entries always start life paused. this is to avoid the + // situation where Minipass's auto-ending empty streams results + // in an entry ending before we're ready for it. + this.pause(); + this.extended = ex; + this.globalExtended = gex; + this.header = header; + /* c8 ignore start */ + this.remain = header.size ?? 0; + /* c8 ignore stop */ + this.startBlockSize = 512 * Math.ceil(this.remain / 512); + this.blockRemain = this.startBlockSize; + this.type = header.type; + switch (this.type) { + case 'File': + case 'OldFile': + case 'Link': + case 'SymbolicLink': + case 'CharacterDevice': + case 'BlockDevice': + case 'Directory': + case 'FIFO': + case 'ContiguousFile': + case 'GNUDumpDir': + break; + case 'NextFileHasLongLinkpath': + case 'NextFileHasLongPath': + case 'OldGnuLongPath': + case 'GlobalExtendedHeader': + case 'ExtendedHeader': + case 'OldExtendedHeader': + this.meta = true; + break; + // NOTE: gnutar and bsdtar treat unrecognized types as 'File' + // it may be worth doing the same, but with a warning. + default: + this.ignore = true; + } + /* c8 ignore start */ + if (!header.path) { + throw new Error('no path provided for tar.ReadEntry'); + } + /* c8 ignore stop */ + this.path = normalizeWindowsPath(header.path); + this.mode = header.mode; + if (this.mode) { + this.mode = this.mode & 0o7777; + } + this.uid = header.uid; + this.gid = header.gid; + this.uname = header.uname; + this.gname = header.gname; + this.size = this.remain; + this.mtime = header.mtime; + this.atime = header.atime; + this.ctime = header.ctime; + /* c8 ignore start */ + this.linkpath = + header.linkpath ? + normalizeWindowsPath(header.linkpath) + : undefined; + /* c8 ignore stop */ + this.uname = header.uname; + this.gname = header.gname; + if (ex) { + this.#slurp(ex); + } + if (gex) { + this.#slurp(gex, true); + } + } + write(data) { + const writeLen = data.length; + if (writeLen > this.blockRemain) { + throw new Error('writing more to entry than is appropriate'); + } + const r = this.remain; + const br = this.blockRemain; + this.remain = Math.max(0, r - writeLen); + this.blockRemain = Math.max(0, br - writeLen); + if (this.ignore) { + return true; + } + if (r >= writeLen) { + return super.write(data); + } + // r < writeLen + return super.write(data.subarray(0, r)); + } + #slurp(ex, gex = false) { + if (ex.path) + ex.path = normalizeWindowsPath(ex.path); + if (ex.linkpath) + ex.linkpath = normalizeWindowsPath(ex.linkpath); + Object.assign(this, Object.fromEntries(Object.entries(ex).filter(([k, v]) => { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. Also, any + // null/undefined values are ignored. + return !(v === null || + v === undefined || + (k === 'path' && gex)); + }))); + } +} +//# sourceMappingURL=read-entry.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/replace.js b/node_modules/tar/dist/esm/replace.js new file mode 100644 index 0000000000000..214aa92446cc6 --- /dev/null +++ b/node_modules/tar/dist/esm/replace.js @@ -0,0 +1,226 @@ +// tar -r +import { WriteStream, WriteStreamSync } from '@isaacs/fs-minipass'; +import fs from 'node:fs'; +import path from 'node:path'; +import { Header } from './header.js'; +import { list } from './list.js'; +import { makeCommand } from './make-command.js'; +import { isFile, } from './options.js'; +import { Pack, PackSync } from './pack.js'; +// starting at the head of the file, read a Header +// If the checksum is invalid, that's our position to start writing +// If it is, jump forward by the specified size (round up to 512) +// and try again. +// Write the new Pack stream starting there. +const replaceSync = (opt, files) => { + const p = new PackSync(opt); + let threw = true; + let fd; + let position; + try { + try { + fd = fs.openSync(opt.file, 'r+'); + } + catch (er) { + if (er?.code === 'ENOENT') { + fd = fs.openSync(opt.file, 'w+'); + } + else { + throw er; + } + } + const st = fs.fstatSync(fd); + const headBuf = Buffer.alloc(512); + POSITION: for (position = 0; position < st.size; position += 512) { + for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) { + bytes = fs.readSync(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos); + if (position === 0 && + headBuf[0] === 0x1f && + headBuf[1] === 0x8b) { + throw new Error('cannot append to compressed archives'); + } + if (!bytes) { + break POSITION; + } + } + const h = new Header(headBuf); + if (!h.cksumValid) { + break; + } + const entryBlockSize = 512 * Math.ceil((h.size || 0) / 512); + if (position + entryBlockSize + 512 > st.size) { + break; + } + // the 512 for the header we just parsed will be added as well + // also jump ahead all the blocks for the body + position += entryBlockSize; + if (opt.mtimeCache && h.mtime) { + opt.mtimeCache.set(String(h.path), h.mtime); + } + } + threw = false; + streamSync(opt, p, position, fd, files); + } + finally { + if (threw) { + try { + fs.closeSync(fd); + } + catch (er) { } + } + } +}; +const streamSync = (opt, p, position, fd, files) => { + const stream = new WriteStreamSync(opt.file, { + fd: fd, + start: position, + }); + p.pipe(stream); + addFilesSync(p, files); +}; +const replaceAsync = (opt, files) => { + files = Array.from(files); + const p = new Pack(opt); + const getPos = (fd, size, cb_) => { + const cb = (er, pos) => { + if (er) { + fs.close(fd, _ => cb_(er)); + } + else { + cb_(null, pos); + } + }; + let position = 0; + if (size === 0) { + return cb(null, 0); + } + let bufPos = 0; + const headBuf = Buffer.alloc(512); + const onread = (er, bytes) => { + if (er || typeof bytes === 'undefined') { + return cb(er); + } + bufPos += bytes; + if (bufPos < 512 && bytes) { + return fs.read(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos, onread); + } + if (position === 0 && + headBuf[0] === 0x1f && + headBuf[1] === 0x8b) { + return cb(new Error('cannot append to compressed archives')); + } + // truncated header + if (bufPos < 512) { + return cb(null, position); + } + const h = new Header(headBuf); + if (!h.cksumValid) { + return cb(null, position); + } + /* c8 ignore next */ + const entryBlockSize = 512 * Math.ceil((h.size ?? 0) / 512); + if (position + entryBlockSize + 512 > size) { + return cb(null, position); + } + position += entryBlockSize + 512; + if (position >= size) { + return cb(null, position); + } + if (opt.mtimeCache && h.mtime) { + opt.mtimeCache.set(String(h.path), h.mtime); + } + bufPos = 0; + fs.read(fd, headBuf, 0, 512, position, onread); + }; + fs.read(fd, headBuf, 0, 512, position, onread); + }; + const promise = new Promise((resolve, reject) => { + p.on('error', reject); + let flag = 'r+'; + const onopen = (er, fd) => { + if (er && er.code === 'ENOENT' && flag === 'r+') { + flag = 'w+'; + return fs.open(opt.file, flag, onopen); + } + if (er || !fd) { + return reject(er); + } + fs.fstat(fd, (er, st) => { + if (er) { + return fs.close(fd, () => reject(er)); + } + getPos(fd, st.size, (er, position) => { + if (er) { + return reject(er); + } + const stream = new WriteStream(opt.file, { + fd: fd, + start: position, + }); + p.pipe(stream); + stream.on('error', reject); + stream.on('close', resolve); + addFilesAsync(p, files); + }); + }); + }; + fs.open(opt.file, flag, onopen); + }); + return promise; +}; +const addFilesSync = (p, files) => { + files.forEach(file => { + if (file.charAt(0) === '@') { + list({ + file: path.resolve(p.cwd, file.slice(1)), + sync: true, + noResume: true, + onReadEntry: entry => p.add(entry), + }); + } + else { + p.add(file); + } + }); + p.end(); +}; +const addFilesAsync = async (p, files) => { + for (let i = 0; i < files.length; i++) { + const file = String(files[i]); + if (file.charAt(0) === '@') { + await list({ + file: path.resolve(String(p.cwd), file.slice(1)), + noResume: true, + onReadEntry: entry => p.add(entry), + }); + } + else { + p.add(file); + } + } + p.end(); +}; +export const replace = makeCommand(replaceSync, replaceAsync, +/* c8 ignore start */ +() => { + throw new TypeError('file is required'); +}, () => { + throw new TypeError('file is required'); +}, +/* c8 ignore stop */ +(opt, entries) => { + if (!isFile(opt)) { + throw new TypeError('file is required'); + } + if (opt.gzip || + opt.brotli || + opt.zstd || + opt.file.endsWith('.br') || + opt.file.endsWith('.tbr')) { + throw new TypeError('cannot append to compressed archives'); + } + if (!entries?.length) { + throw new TypeError('no paths specified to add/replace'); + } +}); +//# sourceMappingURL=replace.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/strip-absolute-path.js b/node_modules/tar/dist/esm/strip-absolute-path.js new file mode 100644 index 0000000000000..cce5ff80b00db --- /dev/null +++ b/node_modules/tar/dist/esm/strip-absolute-path.js @@ -0,0 +1,25 @@ +// unix absolute paths are also absolute on win32, so we use this for both +import { win32 } from 'node:path'; +const { isAbsolute, parse } = win32; +// returns [root, stripped] +// Note that windows will think that //x/y/z/a has a "root" of //x/y, and in +// those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip / +// explicitly if it's the first character. +// drive-specific relative paths on Windows get their root stripped off even +// though they are not absolute, so `c:../foo` becomes ['c:', '../foo'] +export const stripAbsolutePath = (path) => { + let r = ''; + let parsed = parse(path); + while (isAbsolute(path) || parsed.root) { + // windows will think that //x/y/z has a "root" of //x/y/ + // but strip the //?/C:/ off of //?/C:/path + const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? + '/' + : parsed.root; + path = path.slice(root.length); + r += root; + parsed = parse(path); + } + return [r, path]; +}; +//# sourceMappingURL=strip-absolute-path.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/strip-trailing-slashes.js b/node_modules/tar/dist/esm/strip-trailing-slashes.js new file mode 100644 index 0000000000000..ace4218a7547b --- /dev/null +++ b/node_modules/tar/dist/esm/strip-trailing-slashes.js @@ -0,0 +1,14 @@ +// warning: extremely hot code path. +// This has been meticulously optimized for use +// within npm install on large package trees. +// Do not edit without careful benchmarking. +export const stripTrailingSlashes = (str) => { + let i = str.length - 1; + let slashesStart = -1; + while (i > -1 && str.charAt(i) === '/') { + slashesStart = i; + i--; + } + return slashesStart === -1 ? str : str.slice(0, slashesStart); +}; +//# sourceMappingURL=strip-trailing-slashes.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/symlink-error.js b/node_modules/tar/dist/esm/symlink-error.js new file mode 100644 index 0000000000000..d31766e2e0afa --- /dev/null +++ b/node_modules/tar/dist/esm/symlink-error.js @@ -0,0 +1,15 @@ +export class SymlinkError extends Error { + path; + symlink; + syscall = 'symlink'; + code = 'TAR_SYMLINK_ERROR'; + constructor(symlink, path) { + super('TAR_SYMLINK_ERROR: Cannot extract through symbolic link'); + this.symlink = symlink; + this.path = path; + } + get name() { + return 'SymlinkError'; + } +} +//# sourceMappingURL=symlink-error.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/types.js b/node_modules/tar/dist/esm/types.js new file mode 100644 index 0000000000000..27b982ae1e092 --- /dev/null +++ b/node_modules/tar/dist/esm/types.js @@ -0,0 +1,45 @@ +export const isCode = (c) => name.has(c); +export const isName = (c) => code.has(c); +// map types from key to human-friendly name +export const name = new Map([ + ['0', 'File'], + // same as File + ['', 'OldFile'], + ['1', 'Link'], + ['2', 'SymbolicLink'], + // Devices and FIFOs aren't fully supported + // they are parsed, but skipped when unpacking + ['3', 'CharacterDevice'], + ['4', 'BlockDevice'], + ['5', 'Directory'], + ['6', 'FIFO'], + // same as File + ['7', 'ContiguousFile'], + // pax headers + ['g', 'GlobalExtendedHeader'], + ['x', 'ExtendedHeader'], + // vendor-specific stuff + // skip + ['A', 'SolarisACL'], + // like 5, but with data, which should be skipped + ['D', 'GNUDumpDir'], + // metadata only, skip + ['I', 'Inode'], + // data = link path of next file + ['K', 'NextFileHasLongLinkpath'], + // data = path of next file + ['L', 'NextFileHasLongPath'], + // skip + ['M', 'ContinuationFile'], + // like L + ['N', 'OldGnuLongPath'], + // skip + ['S', 'SparseFile'], + // skip + ['V', 'TapeVolumeHeader'], + // like x + ['X', 'OldExtendedHeader'], +]); +// map the other direction +export const code = new Map(Array.from(name).map(kv => [kv[1], kv[0]])); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/unpack.js b/node_modules/tar/dist/esm/unpack.js new file mode 100644 index 0000000000000..3a9aa807798a7 --- /dev/null +++ b/node_modules/tar/dist/esm/unpack.js @@ -0,0 +1,876 @@ +// the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet. +// but the path reservations are required to avoid race conditions where +// parallelized unpack ops may mess with one another, due to dependencies +// (like a Link depending on its target) or destructive operations (like +// clobbering an fs object to create one of a different type.) +import * as fsm from '@isaacs/fs-minipass'; +import assert from 'node:assert'; +import { randomBytes } from 'node:crypto'; +import fs from 'node:fs'; +import path from 'node:path'; +import { getWriteFlag } from './get-write-flag.js'; +import { mkdir, mkdirSync } from './mkdir.js'; +import { normalizeWindowsPath } from './normalize-windows-path.js'; +import { Parser } from './parse.js'; +import { stripAbsolutePath } from './strip-absolute-path.js'; +import * as wc from './winchars.js'; +import { PathReservations } from './path-reservations.js'; +const ONENTRY = Symbol('onEntry'); +const CHECKFS = Symbol('checkFs'); +const CHECKFS2 = Symbol('checkFs2'); +const ISREUSABLE = Symbol('isReusable'); +const MAKEFS = Symbol('makeFs'); +const FILE = Symbol('file'); +const DIRECTORY = Symbol('directory'); +const LINK = Symbol('link'); +const SYMLINK = Symbol('symlink'); +const HARDLINK = Symbol('hardlink'); +const UNSUPPORTED = Symbol('unsupported'); +const CHECKPATH = Symbol('checkPath'); +const STRIPABSOLUTEPATH = Symbol('stripAbsolutePath'); +const MKDIR = Symbol('mkdir'); +const ONERROR = Symbol('onError'); +const PENDING = Symbol('pending'); +const PEND = Symbol('pend'); +const UNPEND = Symbol('unpend'); +const ENDED = Symbol('ended'); +const MAYBECLOSE = Symbol('maybeClose'); +const SKIP = Symbol('skip'); +const DOCHOWN = Symbol('doChown'); +const UID = Symbol('uid'); +const GID = Symbol('gid'); +const CHECKED_CWD = Symbol('checkedCwd'); +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform; +const isWindows = platform === 'win32'; +const DEFAULT_MAX_DEPTH = 1024; +// Unlinks on Windows are not atomic. +// +// This means that if you have a file entry, followed by another +// file entry with an identical name, and you cannot re-use the file +// (because it's a hardlink, or because unlink:true is set, or it's +// Windows, which does not have useful nlink values), then the unlink +// will be committed to the disk AFTER the new file has been written +// over the old one, deleting the new file. +// +// To work around this, on Windows systems, we rename the file and then +// delete the renamed file. It's a sloppy kludge, but frankly, I do not +// know of a better way to do this, given windows' non-atomic unlink +// semantics. +// +// See: https://github.com/npm/node-tar/issues/183 +/* c8 ignore start */ +const unlinkFile = (path, cb) => { + if (!isWindows) { + return fs.unlink(path, cb); + } + const name = path + '.DELETE.' + randomBytes(16).toString('hex'); + fs.rename(path, name, er => { + if (er) { + return cb(er); + } + fs.unlink(name, cb); + }); +}; +/* c8 ignore stop */ +/* c8 ignore start */ +const unlinkFileSync = (path) => { + if (!isWindows) { + return fs.unlinkSync(path); + } + const name = path + '.DELETE.' + randomBytes(16).toString('hex'); + fs.renameSync(path, name); + fs.unlinkSync(name); +}; +/* c8 ignore stop */ +// this.gid, entry.gid, this.processUid +const uint32 = (a, b, c) => a !== undefined && a === a >>> 0 ? a + : b !== undefined && b === b >>> 0 ? b + : c; +export class Unpack extends Parser { + [ENDED] = false; + [CHECKED_CWD] = false; + [PENDING] = 0; + reservations = new PathReservations(); + transform; + writable = true; + readable = false; + uid; + gid; + setOwner; + preserveOwner; + processGid; + processUid; + maxDepth; + forceChown; + win32; + newer; + keep; + noMtime; + preservePaths; + unlink; + cwd; + strip; + processUmask; + umask; + dmode; + fmode; + chmod; + constructor(opt = {}) { + opt.ondone = () => { + this[ENDED] = true; + this[MAYBECLOSE](); + }; + super(opt); + this.transform = opt.transform; + this.chmod = !!opt.chmod; + if (typeof opt.uid === 'number' || typeof opt.gid === 'number') { + // need both or neither + if (typeof opt.uid !== 'number' || + typeof opt.gid !== 'number') { + throw new TypeError('cannot set owner without number uid and gid'); + } + if (opt.preserveOwner) { + throw new TypeError('cannot preserve owner in archive and also set owner explicitly'); + } + this.uid = opt.uid; + this.gid = opt.gid; + this.setOwner = true; + } + else { + this.uid = undefined; + this.gid = undefined; + this.setOwner = false; + } + // default true for root + if (opt.preserveOwner === undefined && + typeof opt.uid !== 'number') { + this.preserveOwner = !!(process.getuid && process.getuid() === 0); + } + else { + this.preserveOwner = !!opt.preserveOwner; + } + this.processUid = + (this.preserveOwner || this.setOwner) && process.getuid ? + process.getuid() + : undefined; + this.processGid = + (this.preserveOwner || this.setOwner) && process.getgid ? + process.getgid() + : undefined; + // prevent excessively deep nesting of subfolders + // set to `Infinity` to remove this restriction + this.maxDepth = + typeof opt.maxDepth === 'number' ? + opt.maxDepth + : DEFAULT_MAX_DEPTH; + // mostly just for testing, but useful in some cases. + // Forcibly trigger a chown on every entry, no matter what + this.forceChown = opt.forceChown === true; + // turn ><?| in filenames into 0xf000-higher encoded forms + this.win32 = !!opt.win32 || isWindows; + // do not unpack over files that are newer than what's in the archive + this.newer = !!opt.newer; + // do not unpack over ANY files + this.keep = !!opt.keep; + // do not set mtime/atime of extracted entries + this.noMtime = !!opt.noMtime; + // allow .., absolute path entries, and unpacking through symlinks + // without this, warn and skip .., relativize absolutes, and error + // on symlinks in extraction path + this.preservePaths = !!opt.preservePaths; + // unlink files and links before writing. This breaks existing hard + // links, and removes symlink directories rather than erroring + this.unlink = !!opt.unlink; + this.cwd = normalizeWindowsPath(path.resolve(opt.cwd || process.cwd())); + this.strip = Number(opt.strip) || 0; + // if we're not chmodding, then we don't need the process umask + this.processUmask = + !this.chmod ? 0 + : typeof opt.processUmask === 'number' ? opt.processUmask + : process.umask(); + this.umask = + typeof opt.umask === 'number' ? opt.umask : this.processUmask; + // default mode for dirs created as parents + this.dmode = opt.dmode || 0o0777 & ~this.umask; + this.fmode = opt.fmode || 0o0666 & ~this.umask; + this.on('entry', entry => this[ONENTRY](entry)); + } + // a bad or damaged archive is a warning for Parser, but an error + // when extracting. Mark those errors as unrecoverable, because + // the Unpack contract cannot be met. + warn(code, msg, data = {}) { + if (code === 'TAR_BAD_ARCHIVE' || code === 'TAR_ABORT') { + data.recoverable = false; + } + return super.warn(code, msg, data); + } + [MAYBECLOSE]() { + if (this[ENDED] && this[PENDING] === 0) { + this.emit('prefinish'); + this.emit('finish'); + this.emit('end'); + } + } + // return false if we need to skip this file + // return true if the field was successfully sanitized + [STRIPABSOLUTEPATH](entry, field) { + const p = entry[field]; + const { type } = entry; + if (!p || this.preservePaths) + return true; + const parts = p.split('/'); + if (parts.includes('..') || + /* c8 ignore next */ + (isWindows && /^[a-z]:\.\.$/i.test(parts[0] ?? ''))) { + // For linkpath, check if the resolved path escapes cwd rather than + // just rejecting any path with '..' - relative symlinks like + // '../sibling/file' are valid if they resolve within the cwd. + // For paths, they just simply may not ever use .. at all. + if (field === 'path' || type === 'Link') { + this.warn('TAR_ENTRY_ERROR', `${field} contains '..'`, { + entry, + [field]: p, + }); + // not ok! + return false; + } + else { + // Resolve linkpath relative to the entry's directory. + // `path.posix` is safe to use because we're operating on + // tar paths, not a filesystem. + const entryDir = path.posix.dirname(entry.path); + const resolved = path.posix.normalize(path.posix.join(entryDir, p)); + // If the resolved path escapes (starts with ..), reject it + if (resolved.startsWith('../') || resolved === '..') { + this.warn('TAR_ENTRY_ERROR', `${field} escapes extraction directory`, { + entry, + [field]: p, + }); + return false; + } + } + } + // strip off the root + const [root, stripped] = stripAbsolutePath(p); + if (root) { + // ok, but triggers warning about stripping root + entry[field] = String(stripped); + this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute ${field}`, { + entry, + [field]: p, + }); + } + return true; + } + [CHECKPATH](entry) { + const p = normalizeWindowsPath(entry.path); + const parts = p.split('/'); + if (this.strip) { + if (parts.length < this.strip) { + return false; + } + if (entry.type === 'Link') { + const linkparts = normalizeWindowsPath(String(entry.linkpath)).split('/'); + if (linkparts.length >= this.strip) { + entry.linkpath = linkparts.slice(this.strip).join('/'); + } + else { + return false; + } + } + parts.splice(0, this.strip); + entry.path = parts.join('/'); + } + if (isFinite(this.maxDepth) && parts.length > this.maxDepth) { + this.warn('TAR_ENTRY_ERROR', 'path excessively deep', { + entry, + path: p, + depth: parts.length, + maxDepth: this.maxDepth, + }); + return false; + } + if (!this[STRIPABSOLUTEPATH](entry, 'path') || + !this[STRIPABSOLUTEPATH](entry, 'linkpath')) { + return false; + } + if (path.isAbsolute(entry.path)) { + entry.absolute = normalizeWindowsPath(path.resolve(entry.path)); + } + else { + entry.absolute = normalizeWindowsPath(path.resolve(this.cwd, entry.path)); + } + // if we somehow ended up with a path that escapes the cwd, and we are + // not in preservePaths mode, then something is fishy! This should have + // been prevented above, so ignore this for coverage. + /* c8 ignore start - defense in depth */ + if (!this.preservePaths && + typeof entry.absolute === 'string' && + entry.absolute.indexOf(this.cwd + '/') !== 0 && + entry.absolute !== this.cwd) { + this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', { + entry, + path: normalizeWindowsPath(entry.path), + resolvedPath: entry.absolute, + cwd: this.cwd, + }); + return false; + } + /* c8 ignore stop */ + // an archive can set properties on the extraction directory, but it + // may not replace the cwd with a different kind of thing entirely. + if (entry.absolute === this.cwd && + entry.type !== 'Directory' && + entry.type !== 'GNUDumpDir') { + return false; + } + // only encode : chars that aren't drive letter indicators + if (this.win32) { + const { root: aRoot } = path.win32.parse(String(entry.absolute)); + entry.absolute = + aRoot + wc.encode(String(entry.absolute).slice(aRoot.length)); + const { root: pRoot } = path.win32.parse(entry.path); + entry.path = pRoot + wc.encode(entry.path.slice(pRoot.length)); + } + return true; + } + [ONENTRY](entry) { + if (!this[CHECKPATH](entry)) { + return entry.resume(); + } + assert.equal(typeof entry.absolute, 'string'); + switch (entry.type) { + case 'Directory': + case 'GNUDumpDir': + if (entry.mode) { + entry.mode = entry.mode | 0o700; + } + // eslint-disable-next-line no-fallthrough + case 'File': + case 'OldFile': + case 'ContiguousFile': + case 'Link': + case 'SymbolicLink': + return this[CHECKFS](entry); + case 'CharacterDevice': + case 'BlockDevice': + case 'FIFO': + default: + return this[UNSUPPORTED](entry); + } + } + [ONERROR](er, entry) { + // Cwd has to exist, or else nothing works. That's serious. + // Other errors are warnings, which raise the error in strict + // mode, but otherwise continue on. + if (er.name === 'CwdError') { + this.emit('error', er); + } + else { + this.warn('TAR_ENTRY_ERROR', er, { entry }); + this[UNPEND](); + entry.resume(); + } + } + [MKDIR](dir, mode, cb) { + mkdir(normalizeWindowsPath(dir), { + uid: this.uid, + gid: this.gid, + processUid: this.processUid, + processGid: this.processGid, + umask: this.processUmask, + preserve: this.preservePaths, + unlink: this.unlink, + cwd: this.cwd, + mode: mode, + }, cb); + } + [DOCHOWN](entry) { + // in preserve owner mode, chown if the entry doesn't match process + // in set owner mode, chown if setting doesn't match process + return (this.forceChown || + (this.preserveOwner && + ((typeof entry.uid === 'number' && + entry.uid !== this.processUid) || + (typeof entry.gid === 'number' && + entry.gid !== this.processGid))) || + (typeof this.uid === 'number' && + this.uid !== this.processUid) || + (typeof this.gid === 'number' && this.gid !== this.processGid)); + } + [UID](entry) { + return uint32(this.uid, entry.uid, this.processUid); + } + [GID](entry) { + return uint32(this.gid, entry.gid, this.processGid); + } + [FILE](entry, fullyDone) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.fmode; + const stream = new fsm.WriteStream(String(entry.absolute), { + // slight lie, but it can be numeric flags + flags: getWriteFlag(entry.size), + mode: mode, + autoClose: false, + }); + stream.on('error', (er) => { + if (stream.fd) { + fs.close(stream.fd, () => { }); + } + // flush all the data out so that we aren't left hanging + // if the error wasn't actually fatal. otherwise the parse + // is blocked, and we never proceed. + stream.write = () => true; + this[ONERROR](er, entry); + fullyDone(); + }); + let actions = 1; + const done = (er) => { + if (er) { + /* c8 ignore start - we should always have a fd by now */ + if (stream.fd) { + fs.close(stream.fd, () => { }); + } + /* c8 ignore stop */ + this[ONERROR](er, entry); + fullyDone(); + return; + } + if (--actions === 0) { + if (stream.fd !== undefined) { + fs.close(stream.fd, er => { + if (er) { + this[ONERROR](er, entry); + } + else { + this[UNPEND](); + } + fullyDone(); + }); + } + } + }; + stream.on('finish', () => { + // if futimes fails, try utimes + // if utimes fails, fail with the original error + // same for fchown/chown + const abs = String(entry.absolute); + const fd = stream.fd; + if (typeof fd === 'number' && entry.mtime && !this.noMtime) { + actions++; + const atime = entry.atime || new Date(); + const mtime = entry.mtime; + fs.futimes(fd, atime, mtime, er => er ? + fs.utimes(abs, atime, mtime, er2 => done(er2 && er)) + : done()); + } + if (typeof fd === 'number' && this[DOCHOWN](entry)) { + actions++; + const uid = this[UID](entry); + const gid = this[GID](entry); + if (typeof uid === 'number' && typeof gid === 'number') { + fs.fchown(fd, uid, gid, er => er ? + fs.chown(abs, uid, gid, er2 => done(er2 && er)) + : done()); + } + } + done(); + }); + const tx = this.transform ? this.transform(entry) || entry : entry; + if (tx !== entry) { + tx.on('error', (er) => { + this[ONERROR](er, entry); + fullyDone(); + }); + entry.pipe(tx); + } + tx.pipe(stream); + } + [DIRECTORY](entry, fullyDone) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.dmode; + this[MKDIR](String(entry.absolute), mode, er => { + if (er) { + this[ONERROR](er, entry); + fullyDone(); + return; + } + let actions = 1; + const done = () => { + if (--actions === 0) { + fullyDone(); + this[UNPEND](); + entry.resume(); + } + }; + if (entry.mtime && !this.noMtime) { + actions++; + fs.utimes(String(entry.absolute), entry.atime || new Date(), entry.mtime, done); + } + if (this[DOCHOWN](entry)) { + actions++; + fs.chown(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry)), done); + } + done(); + }); + } + [UNSUPPORTED](entry) { + entry.unsupported = true; + this.warn('TAR_ENTRY_UNSUPPORTED', `unsupported entry type: ${entry.type}`, { entry }); + entry.resume(); + } + [SYMLINK](entry, done) { + this[LINK](entry, String(entry.linkpath), 'symlink', done); + } + [HARDLINK](entry, done) { + const linkpath = normalizeWindowsPath(path.resolve(this.cwd, String(entry.linkpath))); + this[LINK](entry, linkpath, 'link', done); + } + [PEND]() { + this[PENDING]++; + } + [UNPEND]() { + this[PENDING]--; + this[MAYBECLOSE](); + } + [SKIP](entry) { + this[UNPEND](); + entry.resume(); + } + // Check if we can reuse an existing filesystem entry safely and + // overwrite it, rather than unlinking and recreating + // Windows doesn't report a useful nlink, so we just never reuse entries + [ISREUSABLE](entry, st) { + return (entry.type === 'File' && + !this.unlink && + st.isFile() && + st.nlink <= 1 && + !isWindows); + } + // check if a thing is there, and if so, try to clobber it + [CHECKFS](entry) { + this[PEND](); + const paths = [entry.path]; + if (entry.linkpath) { + paths.push(entry.linkpath); + } + this.reservations.reserve(paths, done => this[CHECKFS2](entry, done)); + } + [CHECKFS2](entry, fullyDone) { + const done = (er) => { + fullyDone(er); + }; + const checkCwd = () => { + this[MKDIR](this.cwd, this.dmode, er => { + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + this[CHECKED_CWD] = true; + start(); + }); + }; + const start = () => { + if (entry.absolute !== this.cwd) { + const parent = normalizeWindowsPath(path.dirname(String(entry.absolute))); + if (parent !== this.cwd) { + return this[MKDIR](parent, this.dmode, er => { + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + afterMakeParent(); + }); + } + } + afterMakeParent(); + }; + const afterMakeParent = () => { + fs.lstat(String(entry.absolute), (lstatEr, st) => { + if (st && + (this.keep || + /* c8 ignore next */ + (this.newer && st.mtime > (entry.mtime ?? st.mtime)))) { + this[SKIP](entry); + done(); + return; + } + if (lstatEr || this[ISREUSABLE](entry, st)) { + return this[MAKEFS](null, entry, done); + } + if (st.isDirectory()) { + if (entry.type === 'Directory') { + const needChmod = this.chmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode; + const afterChmod = (er) => this[MAKEFS](er ?? null, entry, done); + if (!needChmod) { + return afterChmod(); + } + return fs.chmod(String(entry.absolute), Number(entry.mode), afterChmod); + } + // Not a dir entry, have to remove it. + // NB: the only way to end up with an entry that is the cwd + // itself, in such a way that == does not detect, is a + // tricky windows absolute path with UNC or 8.3 parts (and + // preservePaths:true, or else it will have been stripped). + // In that case, the user has opted out of path protections + // explicitly, so if they blow away the cwd, c'est la vie. + if (entry.absolute !== this.cwd) { + return fs.rmdir(String(entry.absolute), (er) => this[MAKEFS](er ?? null, entry, done)); + } + } + // not a dir, and not reusable + // don't remove if the cwd, we want that error + if (entry.absolute === this.cwd) { + return this[MAKEFS](null, entry, done); + } + unlinkFile(String(entry.absolute), er => this[MAKEFS](er ?? null, entry, done)); + }); + }; + if (this[CHECKED_CWD]) { + start(); + } + else { + checkCwd(); + } + } + [MAKEFS](er, entry, done) { + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + switch (entry.type) { + case 'File': + case 'OldFile': + case 'ContiguousFile': + return this[FILE](entry, done); + case 'Link': + return this[HARDLINK](entry, done); + case 'SymbolicLink': + return this[SYMLINK](entry, done); + case 'Directory': + case 'GNUDumpDir': + return this[DIRECTORY](entry, done); + } + } + [LINK](entry, linkpath, link, done) { + // XXX: get the type ('symlink' or 'junction') for windows + fs[link](linkpath, String(entry.absolute), er => { + if (er) { + this[ONERROR](er, entry); + } + else { + this[UNPEND](); + entry.resume(); + } + done(); + }); + } +} +const callSync = (fn) => { + try { + return [null, fn()]; + } + catch (er) { + return [er, null]; + } +}; +export class UnpackSync extends Unpack { + sync = true; + [MAKEFS](er, entry) { + return super[MAKEFS](er, entry, () => { }); + } + [CHECKFS](entry) { + if (!this[CHECKED_CWD]) { + const er = this[MKDIR](this.cwd, this.dmode); + if (er) { + return this[ONERROR](er, entry); + } + this[CHECKED_CWD] = true; + } + // don't bother to make the parent if the current entry is the cwd, + // we've already checked it. + if (entry.absolute !== this.cwd) { + const parent = normalizeWindowsPath(path.dirname(String(entry.absolute))); + if (parent !== this.cwd) { + const mkParent = this[MKDIR](parent, this.dmode); + if (mkParent) { + return this[ONERROR](mkParent, entry); + } + } + } + const [lstatEr, st] = callSync(() => fs.lstatSync(String(entry.absolute))); + if (st && + (this.keep || + /* c8 ignore next */ + (this.newer && st.mtime > (entry.mtime ?? st.mtime)))) { + return this[SKIP](entry); + } + if (lstatEr || this[ISREUSABLE](entry, st)) { + return this[MAKEFS](null, entry); + } + if (st.isDirectory()) { + if (entry.type === 'Directory') { + const needChmod = this.chmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode; + const [er] = needChmod ? + callSync(() => { + fs.chmodSync(String(entry.absolute), Number(entry.mode)); + }) + : []; + return this[MAKEFS](er, entry); + } + // not a dir entry, have to remove it + const [er] = callSync(() => fs.rmdirSync(String(entry.absolute))); + this[MAKEFS](er, entry); + } + // not a dir, and not reusable. + // don't remove if it's the cwd, since we want that error. + const [er] = entry.absolute === this.cwd ? + [] + : callSync(() => unlinkFileSync(String(entry.absolute))); + this[MAKEFS](er, entry); + } + [FILE](entry, done) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.fmode; + const oner = (er) => { + let closeError; + try { + fs.closeSync(fd); + } + catch (e) { + closeError = e; + } + if (er || closeError) { + this[ONERROR](er || closeError, entry); + } + done(); + }; + let fd; + try { + fd = fs.openSync(String(entry.absolute), getWriteFlag(entry.size), mode); + /* c8 ignore start - This is only a problem if the file was successfully + * statted, BUT failed to open. Testing this is annoying, and we + * already have ample testint for other uses of oner() methods. + */ + } + catch (er) { + return oner(er); + } + /* c8 ignore stop */ + const tx = this.transform ? this.transform(entry) || entry : entry; + if (tx !== entry) { + tx.on('error', (er) => this[ONERROR](er, entry)); + entry.pipe(tx); + } + tx.on('data', (chunk) => { + try { + fs.writeSync(fd, chunk, 0, chunk.length); + } + catch (er) { + oner(er); + } + }); + tx.on('end', () => { + let er = null; + // try both, falling futimes back to utimes + // if either fails, handle the first error + if (entry.mtime && !this.noMtime) { + const atime = entry.atime || new Date(); + const mtime = entry.mtime; + try { + fs.futimesSync(fd, atime, mtime); + } + catch (futimeser) { + try { + fs.utimesSync(String(entry.absolute), atime, mtime); + } + catch (utimeser) { + er = futimeser; + } + } + } + if (this[DOCHOWN](entry)) { + const uid = this[UID](entry); + const gid = this[GID](entry); + try { + fs.fchownSync(fd, Number(uid), Number(gid)); + } + catch (fchowner) { + try { + fs.chownSync(String(entry.absolute), Number(uid), Number(gid)); + } + catch (chowner) { + er = er || fchowner; + } + } + } + oner(er); + }); + } + [DIRECTORY](entry, done) { + const mode = typeof entry.mode === 'number' ? + entry.mode & 0o7777 + : this.dmode; + const er = this[MKDIR](String(entry.absolute), mode); + if (er) { + this[ONERROR](er, entry); + done(); + return; + } + if (entry.mtime && !this.noMtime) { + try { + fs.utimesSync(String(entry.absolute), entry.atime || new Date(), entry.mtime); + /* c8 ignore next */ + } + catch (er) { } + } + if (this[DOCHOWN](entry)) { + try { + fs.chownSync(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry))); + } + catch (er) { } + } + done(); + entry.resume(); + } + [MKDIR](dir, mode) { + try { + return mkdirSync(normalizeWindowsPath(dir), { + uid: this.uid, + gid: this.gid, + processUid: this.processUid, + processGid: this.processGid, + umask: this.processUmask, + preserve: this.preservePaths, + unlink: this.unlink, + cwd: this.cwd, + mode: mode, + }); + } + catch (er) { + return er; + } + } + [LINK](entry, linkpath, link, done) { + const ls = `${link}Sync`; + try { + fs[ls](linkpath, String(entry.absolute)); + done(); + entry.resume(); + } + catch (er) { + return this[ONERROR](er, entry); + } + } +} +//# sourceMappingURL=unpack.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/update.js b/node_modules/tar/dist/esm/update.js new file mode 100644 index 0000000000000..21398e9766663 --- /dev/null +++ b/node_modules/tar/dist/esm/update.js @@ -0,0 +1,30 @@ +// tar -u +import { makeCommand } from './make-command.js'; +import { replace as r } from './replace.js'; +// just call tar.r with the filter and mtimeCache +export const update = makeCommand(r.syncFile, r.asyncFile, r.syncNoFile, r.asyncNoFile, (opt, entries = []) => { + r.validate?.(opt, entries); + mtimeFilter(opt); +}); +const mtimeFilter = (opt) => { + const filter = opt.filter; + if (!opt.mtimeCache) { + opt.mtimeCache = new Map(); + } + opt.filter = + filter ? + (path, stat) => filter(path, stat) && + !( + /* c8 ignore start */ + ((opt.mtimeCache?.get(path) ?? stat.mtime ?? 0) > + (stat.mtime ?? 0)) + /* c8 ignore stop */ + ) + : (path, stat) => !( + /* c8 ignore start */ + ((opt.mtimeCache?.get(path) ?? stat.mtime ?? 0) > + (stat.mtime ?? 0)) + /* c8 ignore stop */ + ); +}; +//# sourceMappingURL=update.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/warn-method.js b/node_modules/tar/dist/esm/warn-method.js new file mode 100644 index 0000000000000..13e798afefc85 --- /dev/null +++ b/node_modules/tar/dist/esm/warn-method.js @@ -0,0 +1,27 @@ +export const warnMethod = (self, code, message, data = {}) => { + if (self.file) { + data.file = self.file; + } + if (self.cwd) { + data.cwd = self.cwd; + } + data.code = + (message instanceof Error && + message.code) || + code; + data.tarCode = code; + if (!self.strict && data.recoverable !== false) { + if (message instanceof Error) { + data = Object.assign(message, data); + message = message.message; + } + self.emit('warn', code, message, data); + } + else if (message instanceof Error) { + self.emit('error', Object.assign(message, data)); + } + else { + self.emit('error', Object.assign(new Error(`${code}: ${message}`), data)); + } +}; +//# sourceMappingURL=warn-method.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/winchars.js b/node_modules/tar/dist/esm/winchars.js new file mode 100644 index 0000000000000..c41eb86d69a4b --- /dev/null +++ b/node_modules/tar/dist/esm/winchars.js @@ -0,0 +1,9 @@ +// When writing files on Windows, translate the characters to their +// 0xf000 higher-encoded versions. +const raw = ['|', '<', '>', '?', ':']; +const win = raw.map(char => String.fromCharCode(0xf000 + char.charCodeAt(0))); +const toWin = new Map(raw.map((char, i) => [char, win[i]])); +const toRaw = new Map(win.map((char, i) => [char, raw[i]])); +export const encode = (s) => raw.reduce((s, c) => s.split(c).join(toWin.get(c)), s); +export const decode = (s) => win.reduce((s, c) => s.split(c).join(toRaw.get(c)), s); +//# sourceMappingURL=winchars.js.map \ No newline at end of file diff --git a/node_modules/tar/dist/esm/write-entry.js b/node_modules/tar/dist/esm/write-entry.js new file mode 100644 index 0000000000000..9028cd676b4cd --- /dev/null +++ b/node_modules/tar/dist/esm/write-entry.js @@ -0,0 +1,657 @@ +import fs from 'fs'; +import { Minipass } from 'minipass'; +import path from 'path'; +import { Header } from './header.js'; +import { modeFix } from './mode-fix.js'; +import { normalizeWindowsPath } from './normalize-windows-path.js'; +import { dealias, } from './options.js'; +import { Pax } from './pax.js'; +import { stripAbsolutePath } from './strip-absolute-path.js'; +import { stripTrailingSlashes } from './strip-trailing-slashes.js'; +import { warnMethod, } from './warn-method.js'; +import * as winchars from './winchars.js'; +const prefixPath = (path, prefix) => { + if (!prefix) { + return normalizeWindowsPath(path); + } + path = normalizeWindowsPath(path).replace(/^\.(\/|$)/, ''); + return stripTrailingSlashes(prefix) + '/' + path; +}; +const maxReadSize = 16 * 1024 * 1024; +const PROCESS = Symbol('process'); +const FILE = Symbol('file'); +const DIRECTORY = Symbol('directory'); +const SYMLINK = Symbol('symlink'); +const HARDLINK = Symbol('hardlink'); +const HEADER = Symbol('header'); +const READ = Symbol('read'); +const LSTAT = Symbol('lstat'); +const ONLSTAT = Symbol('onlstat'); +const ONREAD = Symbol('onread'); +const ONREADLINK = Symbol('onreadlink'); +const OPENFILE = Symbol('openfile'); +const ONOPENFILE = Symbol('onopenfile'); +const CLOSE = Symbol('close'); +const MODE = Symbol('mode'); +const AWAITDRAIN = Symbol('awaitDrain'); +const ONDRAIN = Symbol('ondrain'); +const PREFIX = Symbol('prefix'); +export class WriteEntry extends Minipass { + path; + portable; + myuid = (process.getuid && process.getuid()) || 0; + // until node has builtin pwnam functions, this'll have to do + myuser = process.env.USER || ''; + maxReadSize; + linkCache; + statCache; + preservePaths; + cwd; + strict; + mtime; + noPax; + noMtime; + prefix; + fd; + blockLen = 0; + blockRemain = 0; + buf; + pos = 0; + remain = 0; + length = 0; + offset = 0; + win32; + absolute; + header; + type; + linkpath; + stat; + onWriteEntry; + #hadError = false; + constructor(p, opt_ = {}) { + const opt = dealias(opt_); + super(); + this.path = normalizeWindowsPath(p); + // suppress atime, ctime, uid, gid, uname, gname + this.portable = !!opt.portable; + this.maxReadSize = opt.maxReadSize || maxReadSize; + this.linkCache = opt.linkCache || new Map(); + this.statCache = opt.statCache || new Map(); + this.preservePaths = !!opt.preservePaths; + this.cwd = normalizeWindowsPath(opt.cwd || process.cwd()); + this.strict = !!opt.strict; + this.noPax = !!opt.noPax; + this.noMtime = !!opt.noMtime; + this.mtime = opt.mtime; + this.prefix = + opt.prefix ? normalizeWindowsPath(opt.prefix) : undefined; + this.onWriteEntry = opt.onWriteEntry; + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + let pathWarn = false; + if (!this.preservePaths) { + const [root, stripped] = stripAbsolutePath(this.path); + if (root && typeof stripped === 'string') { + this.path = stripped; + pathWarn = root; + } + } + this.win32 = !!opt.win32 || process.platform === 'win32'; + if (this.win32) { + // force the \ to / normalization, since we might not *actually* + // be on windows, but want \ to be considered a path separator. + this.path = winchars.decode(this.path.replace(/\\/g, '/')); + p = p.replace(/\\/g, '/'); + } + this.absolute = normalizeWindowsPath(opt.absolute || path.resolve(this.cwd, p)); + if (this.path === '') { + this.path = './'; + } + if (pathWarn) { + this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { + entry: this, + path: pathWarn + this.path, + }); + } + const cs = this.statCache.get(this.absolute); + if (cs) { + this[ONLSTAT](cs); + } + else { + this[LSTAT](); + } + } + warn(code, message, data = {}) { + return warnMethod(this, code, message, data); + } + emit(ev, ...data) { + if (ev === 'error') { + this.#hadError = true; + } + return super.emit(ev, ...data); + } + [LSTAT]() { + fs.lstat(this.absolute, (er, stat) => { + if (er) { + return this.emit('error', er); + } + this[ONLSTAT](stat); + }); + } + [ONLSTAT](stat) { + this.statCache.set(this.absolute, stat); + this.stat = stat; + if (!stat.isFile()) { + stat.size = 0; + } + this.type = getType(stat); + this.emit('stat', stat); + this[PROCESS](); + } + [PROCESS]() { + switch (this.type) { + case 'File': + return this[FILE](); + case 'Directory': + return this[DIRECTORY](); + case 'SymbolicLink': + return this[SYMLINK](); + // unsupported types are ignored. + default: + return this.end(); + } + } + [MODE](mode) { + return modeFix(mode, this.type === 'Directory', this.portable); + } + [PREFIX](path) { + return prefixPath(path, this.prefix); + } + [HEADER]() { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot write header before stat'); + } + /* c8 ignore stop */ + if (this.type === 'Directory' && this.portable) { + this.noMtime = true; + } + this.onWriteEntry?.(this); + this.header = new Header({ + path: this[PREFIX](this.path), + // only apply the prefix to hard links. + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + // only the permissions and setuid/setgid/sticky bitflags + // not the higher-order bits that specify file type + mode: this[MODE](this.stat.mode), + uid: this.portable ? undefined : this.stat.uid, + gid: this.portable ? undefined : this.stat.gid, + size: this.stat.size, + mtime: this.noMtime ? undefined : this.mtime || this.stat.mtime, + /* c8 ignore next */ + type: this.type === 'Unsupported' ? undefined : this.type, + uname: this.portable ? undefined + : this.stat.uid === this.myuid ? this.myuser + : '', + atime: this.portable ? undefined : this.stat.atime, + ctime: this.portable ? undefined : this.stat.ctime, + }); + if (this.header.encode() && !this.noPax) { + super.write(new Pax({ + atime: this.portable ? undefined : this.header.atime, + ctime: this.portable ? undefined : this.header.ctime, + gid: this.portable ? undefined : this.header.gid, + mtime: this.noMtime ? undefined : (this.mtime || this.header.mtime), + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + size: this.header.size, + uid: this.portable ? undefined : this.header.uid, + uname: this.portable ? undefined : this.header.uname, + dev: this.portable ? undefined : this.stat.dev, + ino: this.portable ? undefined : this.stat.ino, + nlink: this.portable ? undefined : this.stat.nlink, + }).encode()); + } + const block = this.header?.block; + /* c8 ignore start */ + if (!block) { + throw new Error('failed to encode header'); + } + /* c8 ignore stop */ + super.write(block); + } + [DIRECTORY]() { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot create directory entry without stat'); + } + /* c8 ignore stop */ + if (this.path.slice(-1) !== '/') { + this.path += '/'; + } + this.stat.size = 0; + this[HEADER](); + this.end(); + } + [SYMLINK]() { + fs.readlink(this.absolute, (er, linkpath) => { + if (er) { + return this.emit('error', er); + } + this[ONREADLINK](linkpath); + }); + } + [ONREADLINK](linkpath) { + this.linkpath = normalizeWindowsPath(linkpath); + this[HEADER](); + this.end(); + } + [HARDLINK](linkpath) { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot create link entry without stat'); + } + /* c8 ignore stop */ + this.type = 'Link'; + this.linkpath = normalizeWindowsPath(path.relative(this.cwd, linkpath)); + this.stat.size = 0; + this[HEADER](); + this.end(); + } + [FILE]() { + /* c8 ignore start */ + if (!this.stat) { + throw new Error('cannot create file entry without stat'); + } + /* c8 ignore stop */ + if (this.stat.nlink > 1) { + const linkKey = `${this.stat.dev}:${this.stat.ino}`; + const linkpath = this.linkCache.get(linkKey); + if (linkpath?.indexOf(this.cwd) === 0) { + return this[HARDLINK](linkpath); + } + this.linkCache.set(linkKey, this.absolute); + } + this[HEADER](); + if (this.stat.size === 0) { + return this.end(); + } + this[OPENFILE](); + } + [OPENFILE]() { + fs.open(this.absolute, 'r', (er, fd) => { + if (er) { + return this.emit('error', er); + } + this[ONOPENFILE](fd); + }); + } + [ONOPENFILE](fd) { + this.fd = fd; + if (this.#hadError) { + return this[CLOSE](); + } + /* c8 ignore start */ + if (!this.stat) { + throw new Error('should stat before calling onopenfile'); + } + /* c8 ignore start */ + this.blockLen = 512 * Math.ceil(this.stat.size / 512); + this.blockRemain = this.blockLen; + const bufLen = Math.min(this.blockLen, this.maxReadSize); + this.buf = Buffer.allocUnsafe(bufLen); + this.offset = 0; + this.pos = 0; + this.remain = this.stat.size; + this.length = this.buf.length; + this[READ](); + } + [READ]() { + const { fd, buf, offset, length, pos } = this; + if (fd === undefined || buf === undefined) { + throw new Error('cannot read file without first opening'); + } + fs.read(fd, buf, offset, length, pos, (er, bytesRead) => { + if (er) { + // ignoring the error from close(2) is a bad practice, but at + // this point we already have an error, don't need another one + return this[CLOSE](() => this.emit('error', er)); + } + this[ONREAD](bytesRead); + }); + } + /* c8 ignore start */ + [CLOSE](cb = () => { }) { + /* c8 ignore stop */ + if (this.fd !== undefined) + fs.close(this.fd, cb); + } + [ONREAD](bytesRead) { + if (bytesRead <= 0 && this.remain > 0) { + const er = Object.assign(new Error('encountered unexpected EOF'), { + path: this.absolute, + syscall: 'read', + code: 'EOF', + }); + return this[CLOSE](() => this.emit('error', er)); + } + if (bytesRead > this.remain) { + const er = Object.assign(new Error('did not encounter expected EOF'), { + path: this.absolute, + syscall: 'read', + code: 'EOF', + }); + return this[CLOSE](() => this.emit('error', er)); + } + /* c8 ignore start */ + if (!this.buf) { + throw new Error('should have created buffer prior to reading'); + } + /* c8 ignore stop */ + // null out the rest of the buffer, if we could fit the block padding + // at the end of this loop, we've incremented bytesRead and this.remain + // to be incremented up to the blockRemain level, as if we had expected + // to get a null-padded file, and read it until the end. then we will + // decrement both remain and blockRemain by bytesRead, and know that we + // reached the expected EOF, without any null buffer to append. + if (bytesRead === this.remain) { + for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) { + this.buf[i + this.offset] = 0; + bytesRead++; + this.remain++; + } + } + const chunk = this.offset === 0 && bytesRead === this.buf.length ? + this.buf + : this.buf.subarray(this.offset, this.offset + bytesRead); + const flushed = this.write(chunk); + if (!flushed) { + this[AWAITDRAIN](() => this[ONDRAIN]()); + } + else { + this[ONDRAIN](); + } + } + [AWAITDRAIN](cb) { + this.once('drain', cb); + } + write(chunk, encoding, cb) { + /* c8 ignore start - just junk to comply with NodeJS.WritableStream */ + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8'); + } + /* c8 ignore stop */ + if (this.blockRemain < chunk.length) { + const er = Object.assign(new Error('writing more data than expected'), { + path: this.absolute, + }); + return this.emit('error', er); + } + this.remain -= chunk.length; + this.blockRemain -= chunk.length; + this.pos += chunk.length; + this.offset += chunk.length; + return super.write(chunk, null, cb); + } + [ONDRAIN]() { + if (!this.remain) { + if (this.blockRemain) { + super.write(Buffer.alloc(this.blockRemain)); + } + return this[CLOSE](er => er ? this.emit('error', er) : this.end()); + } + /* c8 ignore start */ + if (!this.buf) { + throw new Error('buffer lost somehow in ONDRAIN'); + } + /* c8 ignore stop */ + if (this.offset >= this.length) { + // if we only have a smaller bit left to read, alloc a smaller buffer + // otherwise, keep it the same length it was before. + this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length)); + this.offset = 0; + } + this.length = this.buf.length - this.offset; + this[READ](); + } +} +export class WriteEntrySync extends WriteEntry { + sync = true; + [LSTAT]() { + this[ONLSTAT](fs.lstatSync(this.absolute)); + } + [SYMLINK]() { + this[ONREADLINK](fs.readlinkSync(this.absolute)); + } + [OPENFILE]() { + this[ONOPENFILE](fs.openSync(this.absolute, 'r')); + } + [READ]() { + let threw = true; + try { + const { fd, buf, offset, length, pos } = this; + /* c8 ignore start */ + if (fd === undefined || buf === undefined) { + throw new Error('fd and buf must be set in READ method'); + } + /* c8 ignore stop */ + const bytesRead = fs.readSync(fd, buf, offset, length, pos); + this[ONREAD](bytesRead); + threw = false; + } + finally { + // ignoring the error from close(2) is a bad practice, but at + // this point we already have an error, don't need another one + if (threw) { + try { + this[CLOSE](() => { }); + } + catch (er) { } + } + } + } + [AWAITDRAIN](cb) { + cb(); + } + /* c8 ignore start */ + [CLOSE](cb = () => { }) { + /* c8 ignore stop */ + if (this.fd !== undefined) + fs.closeSync(this.fd); + cb(); + } +} +export class WriteEntryTar extends Minipass { + blockLen = 0; + blockRemain = 0; + buf = 0; + pos = 0; + remain = 0; + length = 0; + preservePaths; + portable; + strict; + noPax; + noMtime; + readEntry; + type; + prefix; + path; + mode; + uid; + gid; + uname; + gname; + header; + mtime; + atime; + ctime; + linkpath; + size; + onWriteEntry; + warn(code, message, data = {}) { + return warnMethod(this, code, message, data); + } + constructor(readEntry, opt_ = {}) { + const opt = dealias(opt_); + super(); + this.preservePaths = !!opt.preservePaths; + this.portable = !!opt.portable; + this.strict = !!opt.strict; + this.noPax = !!opt.noPax; + this.noMtime = !!opt.noMtime; + this.onWriteEntry = opt.onWriteEntry; + this.readEntry = readEntry; + const { type } = readEntry; + /* c8 ignore start */ + if (type === 'Unsupported') { + throw new Error('writing entry that should be ignored'); + } + /* c8 ignore stop */ + this.type = type; + if (this.type === 'Directory' && this.portable) { + this.noMtime = true; + } + this.prefix = opt.prefix; + this.path = normalizeWindowsPath(readEntry.path); + this.mode = + readEntry.mode !== undefined ? + this[MODE](readEntry.mode) + : undefined; + this.uid = this.portable ? undefined : readEntry.uid; + this.gid = this.portable ? undefined : readEntry.gid; + this.uname = this.portable ? undefined : readEntry.uname; + this.gname = this.portable ? undefined : readEntry.gname; + this.size = readEntry.size; + this.mtime = + this.noMtime ? undefined : opt.mtime || readEntry.mtime; + this.atime = this.portable ? undefined : readEntry.atime; + this.ctime = this.portable ? undefined : readEntry.ctime; + this.linkpath = + readEntry.linkpath !== undefined ? + normalizeWindowsPath(readEntry.linkpath) + : undefined; + if (typeof opt.onwarn === 'function') { + this.on('warn', opt.onwarn); + } + let pathWarn = false; + if (!this.preservePaths) { + const [root, stripped] = stripAbsolutePath(this.path); + if (root && typeof stripped === 'string') { + this.path = stripped; + pathWarn = root; + } + } + this.remain = readEntry.size; + this.blockRemain = readEntry.startBlockSize; + this.onWriteEntry?.(this); + this.header = new Header({ + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + // only the permissions and setuid/setgid/sticky bitflags + // not the higher-order bits that specify file type + mode: this.mode, + uid: this.portable ? undefined : this.uid, + gid: this.portable ? undefined : this.gid, + size: this.size, + mtime: this.noMtime ? undefined : this.mtime, + type: this.type, + uname: this.portable ? undefined : this.uname, + atime: this.portable ? undefined : this.atime, + ctime: this.portable ? undefined : this.ctime, + }); + if (pathWarn) { + this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { + entry: this, + path: pathWarn + this.path, + }); + } + if (this.header.encode() && !this.noPax) { + super.write(new Pax({ + atime: this.portable ? undefined : this.atime, + ctime: this.portable ? undefined : this.ctime, + gid: this.portable ? undefined : this.gid, + mtime: this.noMtime ? undefined : this.mtime, + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' && this.linkpath !== undefined ? + this[PREFIX](this.linkpath) + : this.linkpath, + size: this.size, + uid: this.portable ? undefined : this.uid, + uname: this.portable ? undefined : this.uname, + dev: this.portable ? undefined : this.readEntry.dev, + ino: this.portable ? undefined : this.readEntry.ino, + nlink: this.portable ? undefined : this.readEntry.nlink, + }).encode()); + } + const b = this.header?.block; + /* c8 ignore start */ + if (!b) + throw new Error('failed to encode header'); + /* c8 ignore stop */ + super.write(b); + readEntry.pipe(this); + } + [PREFIX](path) { + return prefixPath(path, this.prefix); + } + [MODE](mode) { + return modeFix(mode, this.type === 'Directory', this.portable); + } + write(chunk, encoding, cb) { + /* c8 ignore start - just junk to comply with NodeJS.WritableStream */ + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8'); + } + /* c8 ignore stop */ + const writeLen = chunk.length; + if (writeLen > this.blockRemain) { + throw new Error('writing more to entry than is appropriate'); + } + this.blockRemain -= writeLen; + return super.write(chunk, cb); + } + end(chunk, encoding, cb) { + if (this.blockRemain) { + super.write(Buffer.alloc(this.blockRemain)); + } + /* c8 ignore start - just junk to comply with NodeJS.WritableStream */ + if (typeof chunk === 'function') { + cb = chunk; + encoding = undefined; + chunk = undefined; + } + if (typeof encoding === 'function') { + cb = encoding; + encoding = undefined; + } + if (typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding ?? 'utf8'); + } + if (cb) + this.once('finish', cb); + chunk ? super.end(chunk, cb) : super.end(cb); + /* c8 ignore stop */ + return this; + } +} +const getType = (stat) => stat.isFile() ? 'File' + : stat.isDirectory() ? 'Directory' + : stat.isSymbolicLink() ? 'SymbolicLink' + : 'Unsupported'; +//# sourceMappingURL=write-entry.js.map \ No newline at end of file diff --git a/node_modules/tar/index.js b/node_modules/tar/index.js deleted file mode 100644 index c9ae06e7906c4..0000000000000 --- a/node_modules/tar/index.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -// high-level commands -exports.c = exports.create = require('./lib/create.js') -exports.r = exports.replace = require('./lib/replace.js') -exports.t = exports.list = require('./lib/list.js') -exports.u = exports.update = require('./lib/update.js') -exports.x = exports.extract = require('./lib/extract.js') - -// classes -exports.Pack = require('./lib/pack.js') -exports.Unpack = require('./lib/unpack.js') -exports.Parse = require('./lib/parse.js') -exports.ReadEntry = require('./lib/read-entry.js') -exports.WriteEntry = require('./lib/write-entry.js') -exports.Header = require('./lib/header.js') -exports.Pax = require('./lib/pax.js') -exports.types = require('./lib/types.js') diff --git a/node_modules/tar/lib/create.js b/node_modules/tar/lib/create.js deleted file mode 100644 index d033640ac3b6c..0000000000000 --- a/node_modules/tar/lib/create.js +++ /dev/null @@ -1,104 +0,0 @@ -'use strict' - -// tar -c -const hlo = require('./high-level-opt.js') - -const Pack = require('./pack.js') -const fsm = require('fs-minipass') -const t = require('./list.js') -const path = require('path') - -module.exports = (opt_, files, cb) => { - if (typeof files === 'function') - cb = files - - if (Array.isArray(opt_)) - files = opt_, opt_ = {} - - if (!files || !Array.isArray(files) || !files.length) - throw new TypeError('no files or directories specified') - - files = Array.from(files) - - const opt = hlo(opt_) - - if (opt.sync && typeof cb === 'function') - throw new TypeError('callback not supported for sync tar functions') - - if (!opt.file && typeof cb === 'function') - throw new TypeError('callback only supported with file option') - - return opt.file && opt.sync ? createFileSync(opt, files) - : opt.file ? createFile(opt, files, cb) - : opt.sync ? createSync(opt, files) - : create(opt, files) -} - -const createFileSync = (opt, files) => { - const p = new Pack.Sync(opt) - const stream = new fsm.WriteStreamSync(opt.file, { - mode: opt.mode || 0o666, - }) - p.pipe(stream) - addFilesSync(p, files) -} - -const createFile = (opt, files, cb) => { - const p = new Pack(opt) - const stream = new fsm.WriteStream(opt.file, { - mode: opt.mode || 0o666, - }) - p.pipe(stream) - - const promise = new Promise((res, rej) => { - stream.on('error', rej) - stream.on('close', res) - p.on('error', rej) - }) - - addFilesAsync(p, files) - - return cb ? promise.then(cb, cb) : promise -} - -const addFilesSync = (p, files) => { - files.forEach(file => { - if (file.charAt(0) === '@') { - t({ - file: path.resolve(p.cwd, file.substr(1)), - sync: true, - noResume: true, - onentry: entry => p.add(entry), - }) - } else - p.add(file) - }) - p.end() -} - -const addFilesAsync = (p, files) => { - while (files.length) { - const file = files.shift() - if (file.charAt(0) === '@') { - return t({ - file: path.resolve(p.cwd, file.substr(1)), - noResume: true, - onentry: entry => p.add(entry), - }).then(_ => addFilesAsync(p, files)) - } else - p.add(file) - } - p.end() -} - -const createSync = (opt, files) => { - const p = new Pack.Sync(opt) - addFilesSync(p, files) - return p -} - -const create = (opt, files) => { - const p = new Pack(opt) - addFilesAsync(p, files) - return p -} diff --git a/node_modules/tar/lib/extract.js b/node_modules/tar/lib/extract.js deleted file mode 100644 index 98e946ec5bfbb..0000000000000 --- a/node_modules/tar/lib/extract.js +++ /dev/null @@ -1,107 +0,0 @@ -'use strict' - -// tar -x -const hlo = require('./high-level-opt.js') -const Unpack = require('./unpack.js') -const fs = require('fs') -const fsm = require('fs-minipass') -const path = require('path') -const stripSlash = require('./strip-trailing-slashes.js') - -module.exports = (opt_, files, cb) => { - if (typeof opt_ === 'function') - cb = opt_, files = null, opt_ = {} - else if (Array.isArray(opt_)) - files = opt_, opt_ = {} - - if (typeof files === 'function') - cb = files, files = null - - if (!files) - files = [] - else - files = Array.from(files) - - const opt = hlo(opt_) - - if (opt.sync && typeof cb === 'function') - throw new TypeError('callback not supported for sync tar functions') - - if (!opt.file && typeof cb === 'function') - throw new TypeError('callback only supported with file option') - - if (files.length) - filesFilter(opt, files) - - return opt.file && opt.sync ? extractFileSync(opt) - : opt.file ? extractFile(opt, cb) - : opt.sync ? extractSync(opt) - : extract(opt) -} - -// construct a filter that limits the file entries listed -// include child entries if a dir is included -const filesFilter = (opt, files) => { - const map = new Map(files.map(f => [stripSlash(f), true])) - const filter = opt.filter - - const mapHas = (file, r) => { - const root = r || path.parse(file).root || '.' - const ret = file === root ? false - : map.has(file) ? map.get(file) - : mapHas(path.dirname(file), root) - - map.set(file, ret) - return ret - } - - opt.filter = filter - ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file)) - : file => mapHas(stripSlash(file)) -} - -const extractFileSync = opt => { - const u = new Unpack.Sync(opt) - - const file = opt.file - const stat = fs.statSync(file) - // This trades a zero-byte read() syscall for a stat - // However, it will usually result in less memory allocation - const readSize = opt.maxReadSize || 16 * 1024 * 1024 - const stream = new fsm.ReadStreamSync(file, { - readSize: readSize, - size: stat.size, - }) - stream.pipe(u) -} - -const extractFile = (opt, cb) => { - const u = new Unpack(opt) - const readSize = opt.maxReadSize || 16 * 1024 * 1024 - - const file = opt.file - const p = new Promise((resolve, reject) => { - u.on('error', reject) - u.on('close', resolve) - - // This trades a zero-byte read() syscall for a stat - // However, it will usually result in less memory allocation - fs.stat(file, (er, stat) => { - if (er) - reject(er) - else { - const stream = new fsm.ReadStream(file, { - readSize: readSize, - size: stat.size, - }) - stream.on('error', reject) - stream.pipe(u) - } - }) - }) - return cb ? p.then(cb, cb) : p -} - -const extractSync = opt => new Unpack.Sync(opt) - -const extract = opt => new Unpack(opt) diff --git a/node_modules/tar/lib/get-write-flag.js b/node_modules/tar/lib/get-write-flag.js deleted file mode 100644 index e86959996623c..0000000000000 --- a/node_modules/tar/lib/get-write-flag.js +++ /dev/null @@ -1,20 +0,0 @@ -// Get the appropriate flag to use for creating files -// We use fmap on Windows platforms for files less than -// 512kb. This is a fairly low limit, but avoids making -// things slower in some cases. Since most of what this -// library is used for is extracting tarballs of many -// relatively small files in npm packages and the like, -// it can be a big boost on Windows platforms. -// Only supported in Node v12.9.0 and above. -const platform = process.env.__FAKE_PLATFORM__ || process.platform -const isWindows = platform === 'win32' -const fs = global.__FAKE_TESTING_FS__ || require('fs') - -/* istanbul ignore next */ -const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants - -const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP -const fMapLimit = 512 * 1024 -const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY -module.exports = !fMapEnabled ? () => 'w' - : size => size < fMapLimit ? fMapFlag : 'w' diff --git a/node_modules/tar/lib/header.js b/node_modules/tar/lib/header.js deleted file mode 100644 index 129504048dfab..0000000000000 --- a/node_modules/tar/lib/header.js +++ /dev/null @@ -1,288 +0,0 @@ -'use strict' -// parse a 512-byte header block to a data object, or vice-versa -// encode returns `true` if a pax extended header is needed, because -// the data could not be faithfully encoded in a simple header. -// (Also, check header.needPax to see if it needs a pax header.) - -const types = require('./types.js') -const pathModule = require('path').posix -const large = require('./large-numbers.js') - -const SLURP = Symbol('slurp') -const TYPE = Symbol('type') - -class Header { - constructor (data, off, ex, gex) { - this.cksumValid = false - this.needPax = false - this.nullBlock = false - - this.block = null - this.path = null - this.mode = null - this.uid = null - this.gid = null - this.size = null - this.mtime = null - this.cksum = null - this[TYPE] = '0' - this.linkpath = null - this.uname = null - this.gname = null - this.devmaj = 0 - this.devmin = 0 - this.atime = null - this.ctime = null - - if (Buffer.isBuffer(data)) - this.decode(data, off || 0, ex, gex) - else if (data) - this.set(data) - } - - decode (buf, off, ex, gex) { - if (!off) - off = 0 - - if (!buf || !(buf.length >= off + 512)) - throw new Error('need 512 bytes for header') - - this.path = decString(buf, off, 100) - this.mode = decNumber(buf, off + 100, 8) - this.uid = decNumber(buf, off + 108, 8) - this.gid = decNumber(buf, off + 116, 8) - this.size = decNumber(buf, off + 124, 12) - this.mtime = decDate(buf, off + 136, 12) - this.cksum = decNumber(buf, off + 148, 12) - - // if we have extended or global extended headers, apply them now - // See https://github.com/npm/node-tar/pull/187 - this[SLURP](ex) - this[SLURP](gex, true) - - // old tar versions marked dirs as a file with a trailing / - this[TYPE] = decString(buf, off + 156, 1) - if (this[TYPE] === '') - this[TYPE] = '0' - if (this[TYPE] === '0' && this.path.substr(-1) === '/') - this[TYPE] = '5' - - // tar implementations sometimes incorrectly put the stat(dir).size - // as the size in the tarball, even though Directory entries are - // not able to have any body at all. In the very rare chance that - // it actually DOES have a body, we weren't going to do anything with - // it anyway, and it'll just be a warning about an invalid header. - if (this[TYPE] === '5') - this.size = 0 - - this.linkpath = decString(buf, off + 157, 100) - if (buf.slice(off + 257, off + 265).toString() === 'ustar\u000000') { - this.uname = decString(buf, off + 265, 32) - this.gname = decString(buf, off + 297, 32) - this.devmaj = decNumber(buf, off + 329, 8) - this.devmin = decNumber(buf, off + 337, 8) - if (buf[off + 475] !== 0) { - // definitely a prefix, definitely >130 chars. - const prefix = decString(buf, off + 345, 155) - this.path = prefix + '/' + this.path - } else { - const prefix = decString(buf, off + 345, 130) - if (prefix) - this.path = prefix + '/' + this.path - this.atime = decDate(buf, off + 476, 12) - this.ctime = decDate(buf, off + 488, 12) - } - } - - let sum = 8 * 0x20 - for (let i = off; i < off + 148; i++) - sum += buf[i] - - for (let i = off + 156; i < off + 512; i++) - sum += buf[i] - - this.cksumValid = sum === this.cksum - if (this.cksum === null && sum === 8 * 0x20) - this.nullBlock = true - } - - [SLURP] (ex, global) { - for (const k in ex) { - // we slurp in everything except for the path attribute in - // a global extended header, because that's weird. - if (ex[k] !== null && ex[k] !== undefined && - !(global && k === 'path')) - this[k] = ex[k] - } - } - - encode (buf, off) { - if (!buf) { - buf = this.block = Buffer.alloc(512) - off = 0 - } - - if (!off) - off = 0 - - if (!(buf.length >= off + 512)) - throw new Error('need 512 bytes for header') - - const prefixSize = this.ctime || this.atime ? 130 : 155 - const split = splitPrefix(this.path || '', prefixSize) - const path = split[0] - const prefix = split[1] - this.needPax = split[2] - - this.needPax = encString(buf, off, 100, path) || this.needPax - this.needPax = encNumber(buf, off + 100, 8, this.mode) || this.needPax - this.needPax = encNumber(buf, off + 108, 8, this.uid) || this.needPax - this.needPax = encNumber(buf, off + 116, 8, this.gid) || this.needPax - this.needPax = encNumber(buf, off + 124, 12, this.size) || this.needPax - this.needPax = encDate(buf, off + 136, 12, this.mtime) || this.needPax - buf[off + 156] = this[TYPE].charCodeAt(0) - this.needPax = encString(buf, off + 157, 100, this.linkpath) || this.needPax - buf.write('ustar\u000000', off + 257, 8) - this.needPax = encString(buf, off + 265, 32, this.uname) || this.needPax - this.needPax = encString(buf, off + 297, 32, this.gname) || this.needPax - this.needPax = encNumber(buf, off + 329, 8, this.devmaj) || this.needPax - this.needPax = encNumber(buf, off + 337, 8, this.devmin) || this.needPax - this.needPax = encString(buf, off + 345, prefixSize, prefix) || this.needPax - if (buf[off + 475] !== 0) - this.needPax = encString(buf, off + 345, 155, prefix) || this.needPax - else { - this.needPax = encString(buf, off + 345, 130, prefix) || this.needPax - this.needPax = encDate(buf, off + 476, 12, this.atime) || this.needPax - this.needPax = encDate(buf, off + 488, 12, this.ctime) || this.needPax - } - - let sum = 8 * 0x20 - for (let i = off; i < off + 148; i++) - sum += buf[i] - - for (let i = off + 156; i < off + 512; i++) - sum += buf[i] - - this.cksum = sum - encNumber(buf, off + 148, 8, this.cksum) - this.cksumValid = true - - return this.needPax - } - - set (data) { - for (const i in data) { - if (data[i] !== null && data[i] !== undefined) - this[i] = data[i] - } - } - - get type () { - return types.name.get(this[TYPE]) || this[TYPE] - } - - get typeKey () { - return this[TYPE] - } - - set type (type) { - if (types.code.has(type)) - this[TYPE] = types.code.get(type) - else - this[TYPE] = type - } -} - -const splitPrefix = (p, prefixSize) => { - const pathSize = 100 - let pp = p - let prefix = '' - let ret - const root = pathModule.parse(p).root || '.' - - if (Buffer.byteLength(pp) < pathSize) - ret = [pp, prefix, false] - else { - // first set prefix to the dir, and path to the base - prefix = pathModule.dirname(pp) - pp = pathModule.basename(pp) - - do { - // both fit! - if (Buffer.byteLength(pp) <= pathSize && - Buffer.byteLength(prefix) <= prefixSize) - ret = [pp, prefix, false] - - // prefix fits in prefix, but path doesn't fit in path - else if (Buffer.byteLength(pp) > pathSize && - Buffer.byteLength(prefix) <= prefixSize) - ret = [pp.substr(0, pathSize - 1), prefix, true] - - else { - // make path take a bit from prefix - pp = pathModule.join(pathModule.basename(prefix), pp) - prefix = pathModule.dirname(prefix) - } - } while (prefix !== root && !ret) - - // at this point, found no resolution, just truncate - if (!ret) - ret = [p.substr(0, pathSize - 1), '', true] - } - return ret -} - -const decString = (buf, off, size) => - buf.slice(off, off + size).toString('utf8').replace(/\0.*/, '') - -const decDate = (buf, off, size) => - numToDate(decNumber(buf, off, size)) - -const numToDate = num => num === null ? null : new Date(num * 1000) - -const decNumber = (buf, off, size) => - buf[off] & 0x80 ? large.parse(buf.slice(off, off + size)) - : decSmallNumber(buf, off, size) - -const nanNull = value => isNaN(value) ? null : value - -const decSmallNumber = (buf, off, size) => - nanNull(parseInt( - buf.slice(off, off + size) - .toString('utf8').replace(/\0.*$/, '').trim(), 8)) - -// the maximum encodable as a null-terminated octal, by field size -const MAXNUM = { - 12: 0o77777777777, - 8: 0o7777777, -} - -const encNumber = (buf, off, size, number) => - number === null ? false : - number > MAXNUM[size] || number < 0 - ? (large.encode(number, buf.slice(off, off + size)), true) - : (encSmallNumber(buf, off, size, number), false) - -const encSmallNumber = (buf, off, size, number) => - buf.write(octalString(number, size), off, size, 'ascii') - -const octalString = (number, size) => - padOctal(Math.floor(number).toString(8), size) - -const padOctal = (string, size) => - (string.length === size - 1 ? string - : new Array(size - string.length - 1).join('0') + string + ' ') + '\0' - -const encDate = (buf, off, size, date) => - date === null ? false : - encNumber(buf, off, size, date.getTime() / 1000) - -// enough to fill the longest string we've got -const NULLS = new Array(156).join('\0') -// pad with nulls, return true if it's longer or non-ascii -const encString = (buf, off, size, string) => - string === null ? false : - (buf.write(string + NULLS, off, size, 'utf8'), - string.length !== Buffer.byteLength(string) || string.length > size) - -module.exports = Header diff --git a/node_modules/tar/lib/high-level-opt.js b/node_modules/tar/lib/high-level-opt.js deleted file mode 100644 index 40e44180e1669..0000000000000 --- a/node_modules/tar/lib/high-level-opt.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -// turn tar(1) style args like `C` into the more verbose things like `cwd` - -const argmap = new Map([ - ['C', 'cwd'], - ['f', 'file'], - ['z', 'gzip'], - ['P', 'preservePaths'], - ['U', 'unlink'], - ['strip-components', 'strip'], - ['stripComponents', 'strip'], - ['keep-newer', 'newer'], - ['keepNewer', 'newer'], - ['keep-newer-files', 'newer'], - ['keepNewerFiles', 'newer'], - ['k', 'keep'], - ['keep-existing', 'keep'], - ['keepExisting', 'keep'], - ['m', 'noMtime'], - ['no-mtime', 'noMtime'], - ['p', 'preserveOwner'], - ['L', 'follow'], - ['h', 'follow'], -]) - -module.exports = opt => opt ? Object.keys(opt).map(k => [ - argmap.has(k) ? argmap.get(k) : k, opt[k], -]).reduce((set, kv) => (set[kv[0]] = kv[1], set), Object.create(null)) : {} diff --git a/node_modules/tar/lib/large-numbers.js b/node_modules/tar/lib/large-numbers.js deleted file mode 100644 index dd6f690b9a8d9..0000000000000 --- a/node_modules/tar/lib/large-numbers.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict' -// Tar can encode large and negative numbers using a leading byte of -// 0xff for negative, and 0x80 for positive. - -const encode = (num, buf) => { - if (!Number.isSafeInteger(num)) - // The number is so large that javascript cannot represent it with integer - // precision. - throw Error('cannot encode number outside of javascript safe integer range') - else if (num < 0) - encodeNegative(num, buf) - else - encodePositive(num, buf) - return buf -} - -const encodePositive = (num, buf) => { - buf[0] = 0x80 - - for (var i = buf.length; i > 1; i--) { - buf[i - 1] = num & 0xff - num = Math.floor(num / 0x100) - } -} - -const encodeNegative = (num, buf) => { - buf[0] = 0xff - var flipped = false - num = num * -1 - for (var i = buf.length; i > 1; i--) { - var byte = num & 0xff - num = Math.floor(num / 0x100) - if (flipped) - buf[i - 1] = onesComp(byte) - else if (byte === 0) - buf[i - 1] = 0 - else { - flipped = true - buf[i - 1] = twosComp(byte) - } - } -} - -const parse = (buf) => { - const pre = buf[0] - const value = pre === 0x80 ? pos(buf.slice(1, buf.length)) - : pre === 0xff ? twos(buf) - : null - if (value === null) - throw Error('invalid base256 encoding') - - if (!Number.isSafeInteger(value)) - // The number is so large that javascript cannot represent it with integer - // precision. - throw Error('parsed number outside of javascript safe integer range') - - return value -} - -const twos = (buf) => { - var len = buf.length - var sum = 0 - var flipped = false - for (var i = len - 1; i > -1; i--) { - var byte = buf[i] - var f - if (flipped) - f = onesComp(byte) - else if (byte === 0) - f = byte - else { - flipped = true - f = twosComp(byte) - } - if (f !== 0) - sum -= f * Math.pow(256, len - i - 1) - } - return sum -} - -const pos = (buf) => { - var len = buf.length - var sum = 0 - for (var i = len - 1; i > -1; i--) { - var byte = buf[i] - if (byte !== 0) - sum += byte * Math.pow(256, len - i - 1) - } - return sum -} - -const onesComp = byte => (0xff ^ byte) & 0xff - -const twosComp = byte => ((0xff ^ byte) + 1) & 0xff - -module.exports = { - encode, - parse, -} diff --git a/node_modules/tar/lib/list.js b/node_modules/tar/lib/list.js deleted file mode 100644 index a0c1cf2fbc7ea..0000000000000 --- a/node_modules/tar/lib/list.js +++ /dev/null @@ -1,132 +0,0 @@ -'use strict' - -// XXX: This shares a lot in common with extract.js -// maybe some DRY opportunity here? - -// tar -t -const hlo = require('./high-level-opt.js') -const Parser = require('./parse.js') -const fs = require('fs') -const fsm = require('fs-minipass') -const path = require('path') -const stripSlash = require('./strip-trailing-slashes.js') - -module.exports = (opt_, files, cb) => { - if (typeof opt_ === 'function') - cb = opt_, files = null, opt_ = {} - else if (Array.isArray(opt_)) - files = opt_, opt_ = {} - - if (typeof files === 'function') - cb = files, files = null - - if (!files) - files = [] - else - files = Array.from(files) - - const opt = hlo(opt_) - - if (opt.sync && typeof cb === 'function') - throw new TypeError('callback not supported for sync tar functions') - - if (!opt.file && typeof cb === 'function') - throw new TypeError('callback only supported with file option') - - if (files.length) - filesFilter(opt, files) - - if (!opt.noResume) - onentryFunction(opt) - - return opt.file && opt.sync ? listFileSync(opt) - : opt.file ? listFile(opt, cb) - : list(opt) -} - -const onentryFunction = opt => { - const onentry = opt.onentry - opt.onentry = onentry ? e => { - onentry(e) - e.resume() - } : e => e.resume() -} - -// construct a filter that limits the file entries listed -// include child entries if a dir is included -const filesFilter = (opt, files) => { - const map = new Map(files.map(f => [stripSlash(f), true])) - const filter = opt.filter - - const mapHas = (file, r) => { - const root = r || path.parse(file).root || '.' - const ret = file === root ? false - : map.has(file) ? map.get(file) - : mapHas(path.dirname(file), root) - - map.set(file, ret) - return ret - } - - opt.filter = filter - ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file)) - : file => mapHas(stripSlash(file)) -} - -const listFileSync = opt => { - const p = list(opt) - const file = opt.file - let threw = true - let fd - try { - const stat = fs.statSync(file) - const readSize = opt.maxReadSize || 16 * 1024 * 1024 - if (stat.size < readSize) - p.end(fs.readFileSync(file)) - else { - let pos = 0 - const buf = Buffer.allocUnsafe(readSize) - fd = fs.openSync(file, 'r') - while (pos < stat.size) { - const bytesRead = fs.readSync(fd, buf, 0, readSize, pos) - pos += bytesRead - p.write(buf.slice(0, bytesRead)) - } - p.end() - } - threw = false - } finally { - if (threw && fd) { - try { - fs.closeSync(fd) - } catch (er) {} - } - } -} - -const listFile = (opt, cb) => { - const parse = new Parser(opt) - const readSize = opt.maxReadSize || 16 * 1024 * 1024 - - const file = opt.file - const p = new Promise((resolve, reject) => { - parse.on('error', reject) - parse.on('end', resolve) - - fs.stat(file, (er, stat) => { - if (er) - reject(er) - else { - const stream = new fsm.ReadStream(file, { - readSize: readSize, - size: stat.size, - }) - stream.on('error', reject) - stream.pipe(parse) - } - }) - }) - return cb ? p.then(cb, cb) : p -} - -const list = opt => new Parser(opt) diff --git a/node_modules/tar/lib/mkdir.js b/node_modules/tar/lib/mkdir.js deleted file mode 100644 index a0719e6c36ed3..0000000000000 --- a/node_modules/tar/lib/mkdir.js +++ /dev/null @@ -1,213 +0,0 @@ -'use strict' -// wrapper around mkdirp for tar's needs. - -// TODO: This should probably be a class, not functionally -// passing around state in a gazillion args. - -const mkdirp = require('mkdirp') -const fs = require('fs') -const path = require('path') -const chownr = require('chownr') -const normPath = require('./normalize-windows-path.js') - -class SymlinkError extends Error { - constructor (symlink, path) { - super('Cannot extract through symbolic link') - this.path = path - this.symlink = symlink - } - - get name () { - return 'SylinkError' - } -} - -class CwdError extends Error { - constructor (path, code) { - super(code + ': Cannot cd into \'' + path + '\'') - this.path = path - this.code = code - } - - get name () { - return 'CwdError' - } -} - -const cGet = (cache, key) => cache.get(normPath(key)) -const cSet = (cache, key, val) => cache.set(normPath(key), val) - -const checkCwd = (dir, cb) => { - fs.stat(dir, (er, st) => { - if (er || !st.isDirectory()) - er = new CwdError(dir, er && er.code || 'ENOTDIR') - cb(er) - }) -} - -module.exports = (dir, opt, cb) => { - dir = normPath(dir) - - // if there's any overlap between mask and mode, - // then we'll need an explicit chmod - const umask = opt.umask - const mode = opt.mode | 0o0700 - const needChmod = (mode & umask) !== 0 - - const uid = opt.uid - const gid = opt.gid - const doChown = typeof uid === 'number' && - typeof gid === 'number' && - (uid !== opt.processUid || gid !== opt.processGid) - - const preserve = opt.preserve - const unlink = opt.unlink - const cache = opt.cache - const cwd = normPath(opt.cwd) - - const done = (er, created) => { - if (er) - cb(er) - else { - cSet(cache, dir, true) - if (created && doChown) - chownr(created, uid, gid, er => done(er)) - else if (needChmod) - fs.chmod(dir, mode, cb) - else - cb() - } - } - - if (cache && cGet(cache, dir) === true) - return done() - - if (dir === cwd) - return checkCwd(dir, done) - - if (preserve) - return mkdirp(dir, {mode}).then(made => done(null, made), done) - - const sub = normPath(path.relative(cwd, dir)) - const parts = sub.split('/') - mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done) -} - -const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => { - if (!parts.length) - return cb(null, created) - const p = parts.shift() - const part = normPath(path.resolve(base + '/' + p)) - if (cGet(cache, part)) - return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) - fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) -} - -const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { - if (er) { - fs.lstat(part, (statEr, st) => { - if (statEr) { - statEr.path = statEr.path && normPath(statEr.path) - cb(statEr) - } else if (st.isDirectory()) - mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) - else if (unlink) { - fs.unlink(part, er => { - if (er) - return cb(er) - fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) - }) - } else if (st.isSymbolicLink()) - return cb(new SymlinkError(part, part + '/' + parts.join('/'))) - else - cb(er) - }) - } else { - created = created || part - mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) - } -} - -const checkCwdSync = dir => { - let ok = false - let code = 'ENOTDIR' - try { - ok = fs.statSync(dir).isDirectory() - } catch (er) { - code = er.code - } finally { - if (!ok) - throw new CwdError(dir, code) - } -} - -module.exports.sync = (dir, opt) => { - dir = normPath(dir) - // if there's any overlap between mask and mode, - // then we'll need an explicit chmod - const umask = opt.umask - const mode = opt.mode | 0o0700 - const needChmod = (mode & umask) !== 0 - - const uid = opt.uid - const gid = opt.gid - const doChown = typeof uid === 'number' && - typeof gid === 'number' && - (uid !== opt.processUid || gid !== opt.processGid) - - const preserve = opt.preserve - const unlink = opt.unlink - const cache = opt.cache - const cwd = normPath(opt.cwd) - - const done = (created) => { - cSet(cache, dir, true) - if (created && doChown) - chownr.sync(created, uid, gid) - if (needChmod) - fs.chmodSync(dir, mode) - } - - if (cache && cGet(cache, dir) === true) - return done() - - if (dir === cwd) { - checkCwdSync(cwd) - return done() - } - - if (preserve) - return done(mkdirp.sync(dir, mode)) - - const sub = normPath(path.relative(cwd, dir)) - const parts = sub.split('/') - let created = null - for (let p = parts.shift(), part = cwd; - p && (part += '/' + p); - p = parts.shift()) { - part = normPath(path.resolve(part)) - if (cGet(cache, part)) - continue - - try { - fs.mkdirSync(part, mode) - created = created || part - cSet(cache, part, true) - } catch (er) { - const st = fs.lstatSync(part) - if (st.isDirectory()) { - cSet(cache, part, true) - continue - } else if (unlink) { - fs.unlinkSync(part) - fs.mkdirSync(part, mode) - created = created || part - cSet(cache, part, true) - continue - } else if (st.isSymbolicLink()) - return new SymlinkError(part, part + '/' + parts.join('/')) - } - } - - return done(created) -} diff --git a/node_modules/tar/lib/mode-fix.js b/node_modules/tar/lib/mode-fix.js deleted file mode 100644 index 6a045ffcaec5b..0000000000000 --- a/node_modules/tar/lib/mode-fix.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict' -module.exports = (mode, isDir, portable) => { - mode &= 0o7777 - - // in portable mode, use the minimum reasonable umask - // if this system creates files with 0o664 by default - // (as some linux distros do), then we'll write the - // archive with 0o644 instead. Also, don't ever create - // a file that is not readable/writable by the owner. - if (portable) - mode = (mode | 0o600) & ~0o22 - - // if dirs are readable, then they should be listable - if (isDir) { - if (mode & 0o400) - mode |= 0o100 - if (mode & 0o40) - mode |= 0o10 - if (mode & 0o4) - mode |= 0o1 - } - return mode -} diff --git a/node_modules/tar/lib/normalize-unicode.js b/node_modules/tar/lib/normalize-unicode.js deleted file mode 100644 index 4aeb1d50db9e1..0000000000000 --- a/node_modules/tar/lib/normalize-unicode.js +++ /dev/null @@ -1,11 +0,0 @@ -// warning: extremely hot code path. -// This has been meticulously optimized for use -// within npm install on large package trees. -// Do not edit without careful benchmarking. -const normalizeCache = Object.create(null) -const {hasOwnProperty} = Object.prototype -module.exports = s => { - if (!hasOwnProperty.call(normalizeCache, s)) - normalizeCache[s] = s.normalize('NFKD') - return normalizeCache[s] -} diff --git a/node_modules/tar/lib/normalize-windows-path.js b/node_modules/tar/lib/normalize-windows-path.js deleted file mode 100644 index eb13ba01b7b04..0000000000000 --- a/node_modules/tar/lib/normalize-windows-path.js +++ /dev/null @@ -1,8 +0,0 @@ -// on windows, either \ or / are valid directory separators. -// on unix, \ is a valid character in filenames. -// so, on windows, and only on windows, we replace all \ chars with /, -// so that we can use / as our one and only directory separator char. - -const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform -module.exports = platform !== 'win32' ? p => p - : p => p && p.replace(/\\/g, '/') diff --git a/node_modules/tar/lib/pack.js b/node_modules/tar/lib/pack.js deleted file mode 100644 index 9522c10bfe4a4..0000000000000 --- a/node_modules/tar/lib/pack.js +++ /dev/null @@ -1,397 +0,0 @@ -'use strict' - -// A readable tar stream creator -// Technically, this is a transform stream that you write paths into, -// and tar format comes out of. -// The `add()` method is like `write()` but returns this, -// and end() return `this` as well, so you can -// do `new Pack(opt).add('files').add('dir').end().pipe(output) -// You could also do something like: -// streamOfPaths().pipe(new Pack()).pipe(new fs.WriteStream('out.tar')) - -class PackJob { - constructor (path, absolute) { - this.path = path || './' - this.absolute = absolute - this.entry = null - this.stat = null - this.readdir = null - this.pending = false - this.ignore = false - this.piped = false - } -} - -const MiniPass = require('minipass') -const zlib = require('minizlib') -const ReadEntry = require('./read-entry.js') -const WriteEntry = require('./write-entry.js') -const WriteEntrySync = WriteEntry.Sync -const WriteEntryTar = WriteEntry.Tar -const Yallist = require('yallist') -const EOF = Buffer.alloc(1024) -const ONSTAT = Symbol('onStat') -const ENDED = Symbol('ended') -const QUEUE = Symbol('queue') -const CURRENT = Symbol('current') -const PROCESS = Symbol('process') -const PROCESSING = Symbol('processing') -const PROCESSJOB = Symbol('processJob') -const JOBS = Symbol('jobs') -const JOBDONE = Symbol('jobDone') -const ADDFSENTRY = Symbol('addFSEntry') -const ADDTARENTRY = Symbol('addTarEntry') -const STAT = Symbol('stat') -const READDIR = Symbol('readdir') -const ONREADDIR = Symbol('onreaddir') -const PIPE = Symbol('pipe') -const ENTRY = Symbol('entry') -const ENTRYOPT = Symbol('entryOpt') -const WRITEENTRYCLASS = Symbol('writeEntryClass') -const WRITE = Symbol('write') -const ONDRAIN = Symbol('ondrain') - -const fs = require('fs') -const path = require('path') -const warner = require('./warn-mixin.js') -const normPath = require('./normalize-windows-path.js') - -const Pack = warner(class Pack extends MiniPass { - constructor (opt) { - super(opt) - opt = opt || Object.create(null) - this.opt = opt - this.file = opt.file || '' - this.cwd = opt.cwd || process.cwd() - this.maxReadSize = opt.maxReadSize - this.preservePaths = !!opt.preservePaths - this.strict = !!opt.strict - this.noPax = !!opt.noPax - this.prefix = normPath(opt.prefix || '') - this.linkCache = opt.linkCache || new Map() - this.statCache = opt.statCache || new Map() - this.readdirCache = opt.readdirCache || new Map() - - this[WRITEENTRYCLASS] = WriteEntry - if (typeof opt.onwarn === 'function') - this.on('warn', opt.onwarn) - - this.portable = !!opt.portable - this.zip = null - if (opt.gzip) { - if (typeof opt.gzip !== 'object') - opt.gzip = {} - if (this.portable) - opt.gzip.portable = true - this.zip = new zlib.Gzip(opt.gzip) - this.zip.on('data', chunk => super.write(chunk)) - this.zip.on('end', _ => super.end()) - this.zip.on('drain', _ => this[ONDRAIN]()) - this.on('resume', _ => this.zip.resume()) - } else - this.on('drain', this[ONDRAIN]) - - this.noDirRecurse = !!opt.noDirRecurse - this.follow = !!opt.follow - this.noMtime = !!opt.noMtime - this.mtime = opt.mtime || null - - this.filter = typeof opt.filter === 'function' ? opt.filter : _ => true - - this[QUEUE] = new Yallist() - this[JOBS] = 0 - this.jobs = +opt.jobs || 4 - this[PROCESSING] = false - this[ENDED] = false - } - - [WRITE] (chunk) { - return super.write(chunk) - } - - add (path) { - this.write(path) - return this - } - - end (path) { - if (path) - this.write(path) - this[ENDED] = true - this[PROCESS]() - return this - } - - write (path) { - if (this[ENDED]) - throw new Error('write after end') - - if (path instanceof ReadEntry) - this[ADDTARENTRY](path) - else - this[ADDFSENTRY](path) - return this.flowing - } - - [ADDTARENTRY] (p) { - const absolute = normPath(path.resolve(this.cwd, p.path)) - // in this case, we don't have to wait for the stat - if (!this.filter(p.path, p)) - p.resume() - else { - const job = new PackJob(p.path, absolute, false) - job.entry = new WriteEntryTar(p, this[ENTRYOPT](job)) - job.entry.on('end', _ => this[JOBDONE](job)) - this[JOBS] += 1 - this[QUEUE].push(job) - } - - this[PROCESS]() - } - - [ADDFSENTRY] (p) { - const absolute = normPath(path.resolve(this.cwd, p)) - this[QUEUE].push(new PackJob(p, absolute)) - this[PROCESS]() - } - - [STAT] (job) { - job.pending = true - this[JOBS] += 1 - const stat = this.follow ? 'stat' : 'lstat' - fs[stat](job.absolute, (er, stat) => { - job.pending = false - this[JOBS] -= 1 - if (er) - this.emit('error', er) - else - this[ONSTAT](job, stat) - }) - } - - [ONSTAT] (job, stat) { - this.statCache.set(job.absolute, stat) - job.stat = stat - - // now we have the stat, we can filter it. - if (!this.filter(job.path, stat)) - job.ignore = true - - this[PROCESS]() - } - - [READDIR] (job) { - job.pending = true - this[JOBS] += 1 - fs.readdir(job.absolute, (er, entries) => { - job.pending = false - this[JOBS] -= 1 - if (er) - return this.emit('error', er) - this[ONREADDIR](job, entries) - }) - } - - [ONREADDIR] (job, entries) { - this.readdirCache.set(job.absolute, entries) - job.readdir = entries - this[PROCESS]() - } - - [PROCESS] () { - if (this[PROCESSING]) - return - - this[PROCESSING] = true - for (let w = this[QUEUE].head; - w !== null && this[JOBS] < this.jobs; - w = w.next) { - this[PROCESSJOB](w.value) - if (w.value.ignore) { - const p = w.next - this[QUEUE].removeNode(w) - w.next = p - } - } - - this[PROCESSING] = false - - if (this[ENDED] && !this[QUEUE].length && this[JOBS] === 0) { - if (this.zip) - this.zip.end(EOF) - else { - super.write(EOF) - super.end() - } - } - } - - get [CURRENT] () { - return this[QUEUE] && this[QUEUE].head && this[QUEUE].head.value - } - - [JOBDONE] (job) { - this[QUEUE].shift() - this[JOBS] -= 1 - this[PROCESS]() - } - - [PROCESSJOB] (job) { - if (job.pending) - return - - if (job.entry) { - if (job === this[CURRENT] && !job.piped) - this[PIPE](job) - return - } - - if (!job.stat) { - if (this.statCache.has(job.absolute)) - this[ONSTAT](job, this.statCache.get(job.absolute)) - else - this[STAT](job) - } - if (!job.stat) - return - - // filtered out! - if (job.ignore) - return - - if (!this.noDirRecurse && job.stat.isDirectory() && !job.readdir) { - if (this.readdirCache.has(job.absolute)) - this[ONREADDIR](job, this.readdirCache.get(job.absolute)) - else - this[READDIR](job) - if (!job.readdir) - return - } - - // we know it doesn't have an entry, because that got checked above - job.entry = this[ENTRY](job) - if (!job.entry) { - job.ignore = true - return - } - - if (job === this[CURRENT] && !job.piped) - this[PIPE](job) - } - - [ENTRYOPT] (job) { - return { - onwarn: (code, msg, data) => this.warn(code, msg, data), - noPax: this.noPax, - cwd: this.cwd, - absolute: job.absolute, - preservePaths: this.preservePaths, - maxReadSize: this.maxReadSize, - strict: this.strict, - portable: this.portable, - linkCache: this.linkCache, - statCache: this.statCache, - noMtime: this.noMtime, - mtime: this.mtime, - prefix: this.prefix, - } - } - - [ENTRY] (job) { - this[JOBS] += 1 - try { - return new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job)) - .on('end', () => this[JOBDONE](job)) - .on('error', er => this.emit('error', er)) - } catch (er) { - this.emit('error', er) - } - } - - [ONDRAIN] () { - if (this[CURRENT] && this[CURRENT].entry) - this[CURRENT].entry.resume() - } - - // like .pipe() but using super, because our write() is special - [PIPE] (job) { - job.piped = true - - if (job.readdir) { - job.readdir.forEach(entry => { - const p = job.path - const base = p === './' ? '' : p.replace(/\/*$/, '/') - this[ADDFSENTRY](base + entry) - }) - } - - const source = job.entry - const zip = this.zip - - if (zip) { - source.on('data', chunk => { - if (!zip.write(chunk)) - source.pause() - }) - } else { - source.on('data', chunk => { - if (!super.write(chunk)) - source.pause() - }) - } - } - - pause () { - if (this.zip) - this.zip.pause() - return super.pause() - } -}) - -class PackSync extends Pack { - constructor (opt) { - super(opt) - this[WRITEENTRYCLASS] = WriteEntrySync - } - - // pause/resume are no-ops in sync streams. - pause () {} - resume () {} - - [STAT] (job) { - const stat = this.follow ? 'statSync' : 'lstatSync' - this[ONSTAT](job, fs[stat](job.absolute)) - } - - [READDIR] (job, stat) { - this[ONREADDIR](job, fs.readdirSync(job.absolute)) - } - - // gotta get it all in this tick - [PIPE] (job) { - const source = job.entry - const zip = this.zip - - if (job.readdir) { - job.readdir.forEach(entry => { - const p = job.path - const base = p === './' ? '' : p.replace(/\/*$/, '/') - this[ADDFSENTRY](base + entry) - }) - } - - if (zip) { - source.on('data', chunk => { - zip.write(chunk) - }) - } else { - source.on('data', chunk => { - super[WRITE](chunk) - }) - } - } -} - -Pack.Sync = PackSync - -module.exports = Pack diff --git a/node_modules/tar/lib/parse.js b/node_modules/tar/lib/parse.js deleted file mode 100644 index b1b4e7e47577c..0000000000000 --- a/node_modules/tar/lib/parse.js +++ /dev/null @@ -1,481 +0,0 @@ -'use strict' - -// this[BUFFER] is the remainder of a chunk if we're waiting for -// the full 512 bytes of a header to come in. We will Buffer.concat() -// it to the next write(), which is a mem copy, but a small one. -// -// this[QUEUE] is a Yallist of entries that haven't been emitted -// yet this can only get filled up if the user keeps write()ing after -// a write() returns false, or does a write() with more than one entry -// -// We don't buffer chunks, we always parse them and either create an -// entry, or push it into the active entry. The ReadEntry class knows -// to throw data away if .ignore=true -// -// Shift entry off the buffer when it emits 'end', and emit 'entry' for -// the next one in the list. -// -// At any time, we're pushing body chunks into the entry at WRITEENTRY, -// and waiting for 'end' on the entry at READENTRY -// -// ignored entries get .resume() called on them straight away - -const warner = require('./warn-mixin.js') -const Header = require('./header.js') -const EE = require('events') -const Yallist = require('yallist') -const maxMetaEntrySize = 1024 * 1024 -const Entry = require('./read-entry.js') -const Pax = require('./pax.js') -const zlib = require('minizlib') - -const gzipHeader = Buffer.from([0x1f, 0x8b]) -const STATE = Symbol('state') -const WRITEENTRY = Symbol('writeEntry') -const READENTRY = Symbol('readEntry') -const NEXTENTRY = Symbol('nextEntry') -const PROCESSENTRY = Symbol('processEntry') -const EX = Symbol('extendedHeader') -const GEX = Symbol('globalExtendedHeader') -const META = Symbol('meta') -const EMITMETA = Symbol('emitMeta') -const BUFFER = Symbol('buffer') -const QUEUE = Symbol('queue') -const ENDED = Symbol('ended') -const EMITTEDEND = Symbol('emittedEnd') -const EMIT = Symbol('emit') -const UNZIP = Symbol('unzip') -const CONSUMECHUNK = Symbol('consumeChunk') -const CONSUMECHUNKSUB = Symbol('consumeChunkSub') -const CONSUMEBODY = Symbol('consumeBody') -const CONSUMEMETA = Symbol('consumeMeta') -const CONSUMEHEADER = Symbol('consumeHeader') -const CONSUMING = Symbol('consuming') -const BUFFERCONCAT = Symbol('bufferConcat') -const MAYBEEND = Symbol('maybeEnd') -const WRITING = Symbol('writing') -const ABORTED = Symbol('aborted') -const DONE = Symbol('onDone') -const SAW_VALID_ENTRY = Symbol('sawValidEntry') -const SAW_NULL_BLOCK = Symbol('sawNullBlock') -const SAW_EOF = Symbol('sawEOF') - -const noop = _ => true - -module.exports = warner(class Parser extends EE { - constructor (opt) { - opt = opt || {} - super(opt) - - this.file = opt.file || '' - - // set to boolean false when an entry starts. 1024 bytes of \0 - // is technically a valid tarball, albeit a boring one. - this[SAW_VALID_ENTRY] = null - - // these BADARCHIVE errors can't be detected early. listen on DONE. - this.on(DONE, _ => { - if (this[STATE] === 'begin' || this[SAW_VALID_ENTRY] === false) { - // either less than 1 block of data, or all entries were invalid. - // Either way, probably not even a tarball. - this.warn('TAR_BAD_ARCHIVE', 'Unrecognized archive format') - } - }) - - if (opt.ondone) - this.on(DONE, opt.ondone) - else { - this.on(DONE, _ => { - this.emit('prefinish') - this.emit('finish') - this.emit('end') - this.emit('close') - }) - } - - this.strict = !!opt.strict - this.maxMetaEntrySize = opt.maxMetaEntrySize || maxMetaEntrySize - this.filter = typeof opt.filter === 'function' ? opt.filter : noop - - // have to set this so that streams are ok piping into it - this.writable = true - this.readable = false - - this[QUEUE] = new Yallist() - this[BUFFER] = null - this[READENTRY] = null - this[WRITEENTRY] = null - this[STATE] = 'begin' - this[META] = '' - this[EX] = null - this[GEX] = null - this[ENDED] = false - this[UNZIP] = null - this[ABORTED] = false - this[SAW_NULL_BLOCK] = false - this[SAW_EOF] = false - if (typeof opt.onwarn === 'function') - this.on('warn', opt.onwarn) - if (typeof opt.onentry === 'function') - this.on('entry', opt.onentry) - } - - [CONSUMEHEADER] (chunk, position) { - if (this[SAW_VALID_ENTRY] === null) - this[SAW_VALID_ENTRY] = false - let header - try { - header = new Header(chunk, position, this[EX], this[GEX]) - } catch (er) { - return this.warn('TAR_ENTRY_INVALID', er) - } - - if (header.nullBlock) { - if (this[SAW_NULL_BLOCK]) { - this[SAW_EOF] = true - // ending an archive with no entries. pointless, but legal. - if (this[STATE] === 'begin') - this[STATE] = 'header' - this[EMIT]('eof') - } else { - this[SAW_NULL_BLOCK] = true - this[EMIT]('nullBlock') - } - } else { - this[SAW_NULL_BLOCK] = false - if (!header.cksumValid) - this.warn('TAR_ENTRY_INVALID', 'checksum failure', {header}) - else if (!header.path) - this.warn('TAR_ENTRY_INVALID', 'path is required', {header}) - else { - const type = header.type - if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) - this.warn('TAR_ENTRY_INVALID', 'linkpath required', {header}) - else if (!/^(Symbolic)?Link$/.test(type) && header.linkpath) - this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', {header}) - else { - const entry = this[WRITEENTRY] = new Entry(header, this[EX], this[GEX]) - - // we do this for meta & ignored entries as well, because they - // are still valid tar, or else we wouldn't know to ignore them - if (!this[SAW_VALID_ENTRY]) { - if (entry.remain) { - // this might be the one! - const onend = () => { - if (!entry.invalid) - this[SAW_VALID_ENTRY] = true - } - entry.on('end', onend) - } else - this[SAW_VALID_ENTRY] = true - } - - if (entry.meta) { - if (entry.size > this.maxMetaEntrySize) { - entry.ignore = true - this[EMIT]('ignoredEntry', entry) - this[STATE] = 'ignore' - entry.resume() - } else if (entry.size > 0) { - this[META] = '' - entry.on('data', c => this[META] += c) - this[STATE] = 'meta' - } - } else { - this[EX] = null - entry.ignore = entry.ignore || !this.filter(entry.path, entry) - - if (entry.ignore) { - // probably valid, just not something we care about - this[EMIT]('ignoredEntry', entry) - this[STATE] = entry.remain ? 'ignore' : 'header' - entry.resume() - } else { - if (entry.remain) - this[STATE] = 'body' - else { - this[STATE] = 'header' - entry.end() - } - - if (!this[READENTRY]) { - this[QUEUE].push(entry) - this[NEXTENTRY]() - } else - this[QUEUE].push(entry) - } - } - } - } - } - } - - [PROCESSENTRY] (entry) { - let go = true - - if (!entry) { - this[READENTRY] = null - go = false - } else if (Array.isArray(entry)) - this.emit.apply(this, entry) - else { - this[READENTRY] = entry - this.emit('entry', entry) - if (!entry.emittedEnd) { - entry.on('end', _ => this[NEXTENTRY]()) - go = false - } - } - - return go - } - - [NEXTENTRY] () { - do {} while (this[PROCESSENTRY](this[QUEUE].shift())) - - if (!this[QUEUE].length) { - // At this point, there's nothing in the queue, but we may have an - // entry which is being consumed (readEntry). - // If we don't, then we definitely can handle more data. - // If we do, and either it's flowing, or it has never had any data - // written to it, then it needs more. - // The only other possibility is that it has returned false from a - // write() call, so we wait for the next drain to continue. - const re = this[READENTRY] - const drainNow = !re || re.flowing || re.size === re.remain - if (drainNow) { - if (!this[WRITING]) - this.emit('drain') - } else - re.once('drain', _ => this.emit('drain')) - } - } - - [CONSUMEBODY] (chunk, position) { - // write up to but no more than writeEntry.blockRemain - const entry = this[WRITEENTRY] - const br = entry.blockRemain - const c = (br >= chunk.length && position === 0) ? chunk - : chunk.slice(position, position + br) - - entry.write(c) - - if (!entry.blockRemain) { - this[STATE] = 'header' - this[WRITEENTRY] = null - entry.end() - } - - return c.length - } - - [CONSUMEMETA] (chunk, position) { - const entry = this[WRITEENTRY] - const ret = this[CONSUMEBODY](chunk, position) - - // if we finished, then the entry is reset - if (!this[WRITEENTRY]) - this[EMITMETA](entry) - - return ret - } - - [EMIT] (ev, data, extra) { - if (!this[QUEUE].length && !this[READENTRY]) - this.emit(ev, data, extra) - else - this[QUEUE].push([ev, data, extra]) - } - - [EMITMETA] (entry) { - this[EMIT]('meta', this[META]) - switch (entry.type) { - case 'ExtendedHeader': - case 'OldExtendedHeader': - this[EX] = Pax.parse(this[META], this[EX], false) - break - - case 'GlobalExtendedHeader': - this[GEX] = Pax.parse(this[META], this[GEX], true) - break - - case 'NextFileHasLongPath': - case 'OldGnuLongPath': - this[EX] = this[EX] || Object.create(null) - this[EX].path = this[META].replace(/\0.*/, '') - break - - case 'NextFileHasLongLinkpath': - this[EX] = this[EX] || Object.create(null) - this[EX].linkpath = this[META].replace(/\0.*/, '') - break - - /* istanbul ignore next */ - default: throw new Error('unknown meta: ' + entry.type) - } - } - - abort (error) { - this[ABORTED] = true - this.emit('abort', error) - // always throws, even in non-strict mode - this.warn('TAR_ABORT', error, { recoverable: false }) - } - - write (chunk) { - if (this[ABORTED]) - return - - // first write, might be gzipped - if (this[UNZIP] === null && chunk) { - if (this[BUFFER]) { - chunk = Buffer.concat([this[BUFFER], chunk]) - this[BUFFER] = null - } - if (chunk.length < gzipHeader.length) { - this[BUFFER] = chunk - return true - } - for (let i = 0; this[UNZIP] === null && i < gzipHeader.length; i++) { - if (chunk[i] !== gzipHeader[i]) - this[UNZIP] = false - } - if (this[UNZIP] === null) { - const ended = this[ENDED] - this[ENDED] = false - this[UNZIP] = new zlib.Unzip() - this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)) - this[UNZIP].on('error', er => this.abort(er)) - this[UNZIP].on('end', _ => { - this[ENDED] = true - this[CONSUMECHUNK]() - }) - this[WRITING] = true - const ret = this[UNZIP][ended ? 'end' : 'write'](chunk) - this[WRITING] = false - return ret - } - } - - this[WRITING] = true - if (this[UNZIP]) - this[UNZIP].write(chunk) - else - this[CONSUMECHUNK](chunk) - this[WRITING] = false - - // return false if there's a queue, or if the current entry isn't flowing - const ret = - this[QUEUE].length ? false : - this[READENTRY] ? this[READENTRY].flowing : - true - - // if we have no queue, then that means a clogged READENTRY - if (!ret && !this[QUEUE].length) - this[READENTRY].once('drain', _ => this.emit('drain')) - - return ret - } - - [BUFFERCONCAT] (c) { - if (c && !this[ABORTED]) - this[BUFFER] = this[BUFFER] ? Buffer.concat([this[BUFFER], c]) : c - } - - [MAYBEEND] () { - if (this[ENDED] && - !this[EMITTEDEND] && - !this[ABORTED] && - !this[CONSUMING]) { - this[EMITTEDEND] = true - const entry = this[WRITEENTRY] - if (entry && entry.blockRemain) { - // truncated, likely a damaged file - const have = this[BUFFER] ? this[BUFFER].length : 0 - this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${ - entry.blockRemain} more bytes, only ${have} available)`, {entry}) - if (this[BUFFER]) - entry.write(this[BUFFER]) - entry.end() - } - this[EMIT](DONE) - } - } - - [CONSUMECHUNK] (chunk) { - if (this[CONSUMING]) - this[BUFFERCONCAT](chunk) - else if (!chunk && !this[BUFFER]) - this[MAYBEEND]() - else { - this[CONSUMING] = true - if (this[BUFFER]) { - this[BUFFERCONCAT](chunk) - const c = this[BUFFER] - this[BUFFER] = null - this[CONSUMECHUNKSUB](c) - } else - this[CONSUMECHUNKSUB](chunk) - - while (this[BUFFER] && - this[BUFFER].length >= 512 && - !this[ABORTED] && - !this[SAW_EOF]) { - const c = this[BUFFER] - this[BUFFER] = null - this[CONSUMECHUNKSUB](c) - } - this[CONSUMING] = false - } - - if (!this[BUFFER] || this[ENDED]) - this[MAYBEEND]() - } - - [CONSUMECHUNKSUB] (chunk) { - // we know that we are in CONSUMING mode, so anything written goes into - // the buffer. Advance the position and put any remainder in the buffer. - let position = 0 - const length = chunk.length - while (position + 512 <= length && !this[ABORTED] && !this[SAW_EOF]) { - switch (this[STATE]) { - case 'begin': - case 'header': - this[CONSUMEHEADER](chunk, position) - position += 512 - break - - case 'ignore': - case 'body': - position += this[CONSUMEBODY](chunk, position) - break - - case 'meta': - position += this[CONSUMEMETA](chunk, position) - break - - /* istanbul ignore next */ - default: - throw new Error('invalid state: ' + this[STATE]) - } - } - - if (position < length) { - if (this[BUFFER]) - this[BUFFER] = Buffer.concat([chunk.slice(position), this[BUFFER]]) - else - this[BUFFER] = chunk.slice(position) - } - } - - end (chunk) { - if (!this[ABORTED]) { - if (this[UNZIP]) - this[UNZIP].end(chunk) - else { - this[ENDED] = true - this.write(chunk) - } - } - } -}) diff --git a/node_modules/tar/lib/path-reservations.js b/node_modules/tar/lib/path-reservations.js deleted file mode 100644 index 8183c45f8535c..0000000000000 --- a/node_modules/tar/lib/path-reservations.js +++ /dev/null @@ -1,148 +0,0 @@ -// A path exclusive reservation system -// reserve([list, of, paths], fn) -// When the fn is first in line for all its paths, it -// is called with a cb that clears the reservation. -// -// Used by async unpack to avoid clobbering paths in use, -// while still allowing maximal safe parallelization. - -const assert = require('assert') -const normalize = require('./normalize-unicode.js') -const stripSlashes = require('./strip-trailing-slashes.js') -const { join } = require('path') - -const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform -const isWindows = platform === 'win32' - -module.exports = () => { - // path => [function or Set] - // A Set object means a directory reservation - // A fn is a direct reservation on that path - const queues = new Map() - - // fn => {paths:[path,...], dirs:[path, ...]} - const reservations = new Map() - - // return a set of parent dirs for a given path - // '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d'] - const getDirs = path => { - const dirs = path.split('/').slice(0, -1).reduce((set, path) => { - if (set.length) - path = join(set[set.length - 1], path) - set.push(path || '/') - return set - }, []) - return dirs - } - - // functions currently running - const running = new Set() - - // return the queues for each path the function cares about - // fn => {paths, dirs} - const getQueues = fn => { - const res = reservations.get(fn) - /* istanbul ignore if - unpossible */ - if (!res) - throw new Error('function does not have any path reservations') - return { - paths: res.paths.map(path => queues.get(path)), - dirs: [...res.dirs].map(path => queues.get(path)), - } - } - - // check if fn is first in line for all its paths, and is - // included in the first set for all its dir queues - const check = fn => { - const {paths, dirs} = getQueues(fn) - return paths.every(q => q[0] === fn) && - dirs.every(q => q[0] instanceof Set && q[0].has(fn)) - } - - // run the function if it's first in line and not already running - const run = fn => { - if (running.has(fn) || !check(fn)) - return false - running.add(fn) - fn(() => clear(fn)) - return true - } - - const clear = fn => { - if (!running.has(fn)) - return false - - const { paths, dirs } = reservations.get(fn) - const next = new Set() - - paths.forEach(path => { - const q = queues.get(path) - assert.equal(q[0], fn) - if (q.length === 1) - queues.delete(path) - else { - q.shift() - if (typeof q[0] === 'function') - next.add(q[0]) - else - q[0].forEach(fn => next.add(fn)) - } - }) - - dirs.forEach(dir => { - const q = queues.get(dir) - assert(q[0] instanceof Set) - if (q[0].size === 1 && q.length === 1) - queues.delete(dir) - else if (q[0].size === 1) { - q.shift() - - // must be a function or else the Set would've been reused - next.add(q[0]) - } else - q[0].delete(fn) - }) - running.delete(fn) - - next.forEach(fn => run(fn)) - return true - } - - const reserve = (paths, fn) => { - // collide on matches across case and unicode normalization - // On windows, thanks to the magic of 8.3 shortnames, it is fundamentally - // impossible to determine whether two paths refer to the same thing on - // disk, without asking the kernel for a shortname. - // So, we just pretend that every path matches every other path here, - // effectively removing all parallelization on windows. - paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => { - // don't need normPath, because we skip this entirely for windows - return normalize(stripSlashes(join(p))).toLowerCase() - }) - - const dirs = new Set( - paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b)) - ) - reservations.set(fn, {dirs, paths}) - paths.forEach(path => { - const q = queues.get(path) - if (!q) - queues.set(path, [fn]) - else - q.push(fn) - }) - dirs.forEach(dir => { - const q = queues.get(dir) - if (!q) - queues.set(dir, [new Set([fn])]) - else if (q[q.length - 1] instanceof Set) - q[q.length - 1].add(fn) - else - q.push(new Set([fn])) - }) - - return run(fn) - } - - return { check, reserve } -} diff --git a/node_modules/tar/lib/pax.js b/node_modules/tar/lib/pax.js deleted file mode 100644 index 7768c7b454f76..0000000000000 --- a/node_modules/tar/lib/pax.js +++ /dev/null @@ -1,143 +0,0 @@ -'use strict' -const Header = require('./header.js') -const path = require('path') - -class Pax { - constructor (obj, global) { - this.atime = obj.atime || null - this.charset = obj.charset || null - this.comment = obj.comment || null - this.ctime = obj.ctime || null - this.gid = obj.gid || null - this.gname = obj.gname || null - this.linkpath = obj.linkpath || null - this.mtime = obj.mtime || null - this.path = obj.path || null - this.size = obj.size || null - this.uid = obj.uid || null - this.uname = obj.uname || null - this.dev = obj.dev || null - this.ino = obj.ino || null - this.nlink = obj.nlink || null - this.global = global || false - } - - encode () { - const body = this.encodeBody() - if (body === '') - return null - - const bodyLen = Buffer.byteLength(body) - // round up to 512 bytes - // add 512 for header - const bufLen = 512 * Math.ceil(1 + bodyLen / 512) - const buf = Buffer.allocUnsafe(bufLen) - - // 0-fill the header section, it might not hit every field - for (let i = 0; i < 512; i++) - buf[i] = 0 - - new Header({ - // XXX split the path - // then the path should be PaxHeader + basename, but less than 99, - // prepend with the dirname - path: ('PaxHeader/' + path.basename(this.path)).slice(0, 99), - mode: this.mode || 0o644, - uid: this.uid || null, - gid: this.gid || null, - size: bodyLen, - mtime: this.mtime || null, - type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader', - linkpath: '', - uname: this.uname || '', - gname: this.gname || '', - devmaj: 0, - devmin: 0, - atime: this.atime || null, - ctime: this.ctime || null, - }).encode(buf) - - buf.write(body, 512, bodyLen, 'utf8') - - // null pad after the body - for (let i = bodyLen + 512; i < buf.length; i++) - buf[i] = 0 - - return buf - } - - encodeBody () { - return ( - this.encodeField('path') + - this.encodeField('ctime') + - this.encodeField('atime') + - this.encodeField('dev') + - this.encodeField('ino') + - this.encodeField('nlink') + - this.encodeField('charset') + - this.encodeField('comment') + - this.encodeField('gid') + - this.encodeField('gname') + - this.encodeField('linkpath') + - this.encodeField('mtime') + - this.encodeField('size') + - this.encodeField('uid') + - this.encodeField('uname') - ) - } - - encodeField (field) { - if (this[field] === null || this[field] === undefined) - return '' - const v = this[field] instanceof Date ? this[field].getTime() / 1000 - : this[field] - const s = ' ' + - (field === 'dev' || field === 'ino' || field === 'nlink' - ? 'SCHILY.' : '') + - field + '=' + v + '\n' - const byteLen = Buffer.byteLength(s) - // the digits includes the length of the digits in ascii base-10 - // so if it's 9 characters, then adding 1 for the 9 makes it 10 - // which makes it 11 chars. - let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1 - if (byteLen + digits >= Math.pow(10, digits)) - digits += 1 - const len = digits + byteLen - return len + s - } -} - -Pax.parse = (string, ex, g) => new Pax(merge(parseKV(string), ex), g) - -const merge = (a, b) => - b ? Object.keys(a).reduce((s, k) => (s[k] = a[k], s), b) : a - -const parseKV = string => - string - .replace(/\n$/, '') - .split('\n') - .reduce(parseKVLine, Object.create(null)) - -const parseKVLine = (set, line) => { - const n = parseInt(line, 10) - - // XXX Values with \n in them will fail this. - // Refactor to not be a naive line-by-line parse. - if (n !== Buffer.byteLength(line) + 1) - return set - - line = line.substr((n + ' ').length) - const kv = line.split('=') - const k = kv.shift().replace(/^SCHILY\.(dev|ino|nlink)/, '$1') - if (!k) - return set - - const v = kv.join('=') - set[k] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k) - ? new Date(v * 1000) - : /^[0-9]+$/.test(v) ? +v - : v - return set -} - -module.exports = Pax diff --git a/node_modules/tar/lib/read-entry.js b/node_modules/tar/lib/read-entry.js deleted file mode 100644 index 183a6050ba0d2..0000000000000 --- a/node_modules/tar/lib/read-entry.js +++ /dev/null @@ -1,100 +0,0 @@ -'use strict' -const MiniPass = require('minipass') -const normPath = require('./normalize-windows-path.js') - -const SLURP = Symbol('slurp') -module.exports = class ReadEntry extends MiniPass { - constructor (header, ex, gex) { - super() - // read entries always start life paused. this is to avoid the - // situation where Minipass's auto-ending empty streams results - // in an entry ending before we're ready for it. - this.pause() - this.extended = ex - this.globalExtended = gex - this.header = header - this.startBlockSize = 512 * Math.ceil(header.size / 512) - this.blockRemain = this.startBlockSize - this.remain = header.size - this.type = header.type - this.meta = false - this.ignore = false - switch (this.type) { - case 'File': - case 'OldFile': - case 'Link': - case 'SymbolicLink': - case 'CharacterDevice': - case 'BlockDevice': - case 'Directory': - case 'FIFO': - case 'ContiguousFile': - case 'GNUDumpDir': - break - - case 'NextFileHasLongLinkpath': - case 'NextFileHasLongPath': - case 'OldGnuLongPath': - case 'GlobalExtendedHeader': - case 'ExtendedHeader': - case 'OldExtendedHeader': - this.meta = true - break - - // NOTE: gnutar and bsdtar treat unrecognized types as 'File' - // it may be worth doing the same, but with a warning. - default: - this.ignore = true - } - - this.path = normPath(header.path) - this.mode = header.mode - if (this.mode) - this.mode = this.mode & 0o7777 - this.uid = header.uid - this.gid = header.gid - this.uname = header.uname - this.gname = header.gname - this.size = header.size - this.mtime = header.mtime - this.atime = header.atime - this.ctime = header.ctime - this.linkpath = normPath(header.linkpath) - this.uname = header.uname - this.gname = header.gname - - if (ex) - this[SLURP](ex) - if (gex) - this[SLURP](gex, true) - } - - write (data) { - const writeLen = data.length - if (writeLen > this.blockRemain) - throw new Error('writing more to entry than is appropriate') - - const r = this.remain - const br = this.blockRemain - this.remain = Math.max(0, r - writeLen) - this.blockRemain = Math.max(0, br - writeLen) - if (this.ignore) - return true - - if (r >= writeLen) - return super.write(data) - - // r < writeLen - return super.write(data.slice(0, r)) - } - - [SLURP] (ex, global) { - for (const k in ex) { - // we slurp in everything except for the path attribute in - // a global extended header, because that's weird. - if (ex[k] !== null && ex[k] !== undefined && - !(global && k === 'path')) - this[k] = k === 'path' || k === 'linkpath' ? normPath(ex[k]) : ex[k] - } - } -} diff --git a/node_modules/tar/lib/replace.js b/node_modules/tar/lib/replace.js deleted file mode 100644 index 1374f3f29c619..0000000000000 --- a/node_modules/tar/lib/replace.js +++ /dev/null @@ -1,223 +0,0 @@ -'use strict' - -// tar -r -const hlo = require('./high-level-opt.js') -const Pack = require('./pack.js') -const fs = require('fs') -const fsm = require('fs-minipass') -const t = require('./list.js') -const path = require('path') - -// starting at the head of the file, read a Header -// If the checksum is invalid, that's our position to start writing -// If it is, jump forward by the specified size (round up to 512) -// and try again. -// Write the new Pack stream starting there. - -const Header = require('./header.js') - -module.exports = (opt_, files, cb) => { - const opt = hlo(opt_) - - if (!opt.file) - throw new TypeError('file is required') - - if (opt.gzip) - throw new TypeError('cannot append to compressed archives') - - if (!files || !Array.isArray(files) || !files.length) - throw new TypeError('no files or directories specified') - - files = Array.from(files) - - return opt.sync ? replaceSync(opt, files) - : replace(opt, files, cb) -} - -const replaceSync = (opt, files) => { - const p = new Pack.Sync(opt) - - let threw = true - let fd - let position - - try { - try { - fd = fs.openSync(opt.file, 'r+') - } catch (er) { - if (er.code === 'ENOENT') - fd = fs.openSync(opt.file, 'w+') - else - throw er - } - - const st = fs.fstatSync(fd) - const headBuf = Buffer.alloc(512) - - POSITION: for (position = 0; position < st.size; position += 512) { - for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) { - bytes = fs.readSync( - fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos - ) - - if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) - throw new Error('cannot append to compressed archives') - - if (!bytes) - break POSITION - } - - const h = new Header(headBuf) - if (!h.cksumValid) - break - const entryBlockSize = 512 * Math.ceil(h.size / 512) - if (position + entryBlockSize + 512 > st.size) - break - // the 512 for the header we just parsed will be added as well - // also jump ahead all the blocks for the body - position += entryBlockSize - if (opt.mtimeCache) - opt.mtimeCache.set(h.path, h.mtime) - } - threw = false - - streamSync(opt, p, position, fd, files) - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } - } -} - -const streamSync = (opt, p, position, fd, files) => { - const stream = new fsm.WriteStreamSync(opt.file, { - fd: fd, - start: position, - }) - p.pipe(stream) - addFilesSync(p, files) -} - -const replace = (opt, files, cb) => { - files = Array.from(files) - const p = new Pack(opt) - - const getPos = (fd, size, cb_) => { - const cb = (er, pos) => { - if (er) - fs.close(fd, _ => cb_(er)) - else - cb_(null, pos) - } - - let position = 0 - if (size === 0) - return cb(null, 0) - - let bufPos = 0 - const headBuf = Buffer.alloc(512) - const onread = (er, bytes) => { - if (er) - return cb(er) - bufPos += bytes - if (bufPos < 512 && bytes) { - return fs.read( - fd, headBuf, bufPos, headBuf.length - bufPos, - position + bufPos, onread - ) - } - - if (position === 0 && headBuf[0] === 0x1f && headBuf[1] === 0x8b) - return cb(new Error('cannot append to compressed archives')) - - // truncated header - if (bufPos < 512) - return cb(null, position) - - const h = new Header(headBuf) - if (!h.cksumValid) - return cb(null, position) - - const entryBlockSize = 512 * Math.ceil(h.size / 512) - if (position + entryBlockSize + 512 > size) - return cb(null, position) - - position += entryBlockSize + 512 - if (position >= size) - return cb(null, position) - - if (opt.mtimeCache) - opt.mtimeCache.set(h.path, h.mtime) - bufPos = 0 - fs.read(fd, headBuf, 0, 512, position, onread) - } - fs.read(fd, headBuf, 0, 512, position, onread) - } - - const promise = new Promise((resolve, reject) => { - p.on('error', reject) - let flag = 'r+' - const onopen = (er, fd) => { - if (er && er.code === 'ENOENT' && flag === 'r+') { - flag = 'w+' - return fs.open(opt.file, flag, onopen) - } - - if (er) - return reject(er) - - fs.fstat(fd, (er, st) => { - if (er) - return fs.close(fd, () => reject(er)) - - getPos(fd, st.size, (er, position) => { - if (er) - return reject(er) - const stream = new fsm.WriteStream(opt.file, { - fd: fd, - start: position, - }) - p.pipe(stream) - stream.on('error', reject) - stream.on('close', resolve) - addFilesAsync(p, files) - }) - }) - } - fs.open(opt.file, flag, onopen) - }) - - return cb ? promise.then(cb, cb) : promise -} - -const addFilesSync = (p, files) => { - files.forEach(file => { - if (file.charAt(0) === '@') { - t({ - file: path.resolve(p.cwd, file.substr(1)), - sync: true, - noResume: true, - onentry: entry => p.add(entry), - }) - } else - p.add(file) - }) - p.end() -} - -const addFilesAsync = (p, files) => { - while (files.length) { - const file = files.shift() - if (file.charAt(0) === '@') { - return t({ - file: path.resolve(p.cwd, file.substr(1)), - noResume: true, - onentry: entry => p.add(entry), - }).then(_ => addFilesAsync(p, files)) - } else - p.add(file) - } - p.end() -} diff --git a/node_modules/tar/lib/strip-absolute-path.js b/node_modules/tar/lib/strip-absolute-path.js deleted file mode 100644 index 1aa2d2aec5030..0000000000000 --- a/node_modules/tar/lib/strip-absolute-path.js +++ /dev/null @@ -1,24 +0,0 @@ -// unix absolute paths are also absolute on win32, so we use this for both -const { isAbsolute, parse } = require('path').win32 - -// returns [root, stripped] -// Note that windows will think that //x/y/z/a has a "root" of //x/y, and in -// those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip / -// explicitly if it's the first character. -// drive-specific relative paths on Windows get their root stripped off even -// though they are not absolute, so `c:../foo` becomes ['c:', '../foo'] -module.exports = path => { - let r = '' - - let parsed = parse(path) - while (isAbsolute(path) || parsed.root) { - // windows will think that //x/y/z has a "root" of //x/y/ - // but strip the //?/C:/ off of //?/C:/path - const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? '/' - : parsed.root - path = path.substr(root.length) - r += root - parsed = parse(path) - } - return [r, path] -} diff --git a/node_modules/tar/lib/strip-trailing-slashes.js b/node_modules/tar/lib/strip-trailing-slashes.js deleted file mode 100644 index 3e3ecec5a402b..0000000000000 --- a/node_modules/tar/lib/strip-trailing-slashes.js +++ /dev/null @@ -1,13 +0,0 @@ -// warning: extremely hot code path. -// This has been meticulously optimized for use -// within npm install on large package trees. -// Do not edit without careful benchmarking. -module.exports = str => { - let i = str.length - 1 - let slashesStart = -1 - while (i > -1 && str.charAt(i) === '/') { - slashesStart = i - i-- - } - return slashesStart === -1 ? str : str.slice(0, slashesStart) -} diff --git a/node_modules/tar/lib/types.js b/node_modules/tar/lib/types.js deleted file mode 100644 index 7bfc254658f4e..0000000000000 --- a/node_modules/tar/lib/types.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict' -// map types from key to human-friendly name -exports.name = new Map([ - ['0', 'File'], - // same as File - ['', 'OldFile'], - ['1', 'Link'], - ['2', 'SymbolicLink'], - // Devices and FIFOs aren't fully supported - // they are parsed, but skipped when unpacking - ['3', 'CharacterDevice'], - ['4', 'BlockDevice'], - ['5', 'Directory'], - ['6', 'FIFO'], - // same as File - ['7', 'ContiguousFile'], - // pax headers - ['g', 'GlobalExtendedHeader'], - ['x', 'ExtendedHeader'], - // vendor-specific stuff - // skip - ['A', 'SolarisACL'], - // like 5, but with data, which should be skipped - ['D', 'GNUDumpDir'], - // metadata only, skip - ['I', 'Inode'], - // data = link path of next file - ['K', 'NextFileHasLongLinkpath'], - // data = path of next file - ['L', 'NextFileHasLongPath'], - // skip - ['M', 'ContinuationFile'], - // like L - ['N', 'OldGnuLongPath'], - // skip - ['S', 'SparseFile'], - // skip - ['V', 'TapeVolumeHeader'], - // like x - ['X', 'OldExtendedHeader'], -]) - -// map the other direction -exports.code = new Map(Array.from(exports.name).map(kv => [kv[1], kv[0]])) diff --git a/node_modules/tar/lib/unpack.js b/node_modules/tar/lib/unpack.js deleted file mode 100644 index 7d39dc0f7e79f..0000000000000 --- a/node_modules/tar/lib/unpack.js +++ /dev/null @@ -1,877 +0,0 @@ -'use strict' - -// the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet. -// but the path reservations are required to avoid race conditions where -// parallelized unpack ops may mess with one another, due to dependencies -// (like a Link depending on its target) or destructive operations (like -// clobbering an fs object to create one of a different type.) - -const assert = require('assert') -const Parser = require('./parse.js') -const fs = require('fs') -const fsm = require('fs-minipass') -const path = require('path') -const mkdir = require('./mkdir.js') -const wc = require('./winchars.js') -const pathReservations = require('./path-reservations.js') -const stripAbsolutePath = require('./strip-absolute-path.js') -const normPath = require('./normalize-windows-path.js') -const stripSlash = require('./strip-trailing-slashes.js') -const normalize = require('./normalize-unicode.js') - -const ONENTRY = Symbol('onEntry') -const CHECKFS = Symbol('checkFs') -const CHECKFS2 = Symbol('checkFs2') -const PRUNECACHE = Symbol('pruneCache') -const ISREUSABLE = Symbol('isReusable') -const MAKEFS = Symbol('makeFs') -const FILE = Symbol('file') -const DIRECTORY = Symbol('directory') -const LINK = Symbol('link') -const SYMLINK = Symbol('symlink') -const HARDLINK = Symbol('hardlink') -const UNSUPPORTED = Symbol('unsupported') -const CHECKPATH = Symbol('checkPath') -const MKDIR = Symbol('mkdir') -const ONERROR = Symbol('onError') -const PENDING = Symbol('pending') -const PEND = Symbol('pend') -const UNPEND = Symbol('unpend') -const ENDED = Symbol('ended') -const MAYBECLOSE = Symbol('maybeClose') -const SKIP = Symbol('skip') -const DOCHOWN = Symbol('doChown') -const UID = Symbol('uid') -const GID = Symbol('gid') -const CHECKED_CWD = Symbol('checkedCwd') -const crypto = require('crypto') -const getFlag = require('./get-write-flag.js') -const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform -const isWindows = platform === 'win32' - -// Unlinks on Windows are not atomic. -// -// This means that if you have a file entry, followed by another -// file entry with an identical name, and you cannot re-use the file -// (because it's a hardlink, or because unlink:true is set, or it's -// Windows, which does not have useful nlink values), then the unlink -// will be committed to the disk AFTER the new file has been written -// over the old one, deleting the new file. -// -// To work around this, on Windows systems, we rename the file and then -// delete the renamed file. It's a sloppy kludge, but frankly, I do not -// know of a better way to do this, given windows' non-atomic unlink -// semantics. -// -// See: https://github.com/npm/node-tar/issues/183 -/* istanbul ignore next */ -const unlinkFile = (path, cb) => { - if (!isWindows) - return fs.unlink(path, cb) - - const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') - fs.rename(path, name, er => { - if (er) - return cb(er) - fs.unlink(name, cb) - }) -} - -/* istanbul ignore next */ -const unlinkFileSync = path => { - if (!isWindows) - return fs.unlinkSync(path) - - const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') - fs.renameSync(path, name) - fs.unlinkSync(name) -} - -// this.gid, entry.gid, this.processUid -const uint32 = (a, b, c) => - a === a >>> 0 ? a - : b === b >>> 0 ? b - : c - -// clear the cache if it's a case-insensitive unicode-squashing match. -// we can't know if the current file system is case-sensitive or supports -// unicode fully, so we check for similarity on the maximally compatible -// representation. Err on the side of pruning, since all it's doing is -// preventing lstats, and it's not the end of the world if we get a false -// positive. -// Note that on windows, we always drop the entire cache whenever a -// symbolic link is encountered, because 8.3 filenames are impossible -// to reason about, and collisions are hazards rather than just failures. -const cacheKeyNormalize = path => normalize(stripSlash(normPath(path))) - .toLowerCase() - -const pruneCache = (cache, abs) => { - abs = cacheKeyNormalize(abs) - for (const path of cache.keys()) { - const pnorm = cacheKeyNormalize(path) - if (pnorm === abs || pnorm.indexOf(abs + '/') === 0) - cache.delete(path) - } -} - -const dropCache = cache => { - for (const key of cache.keys()) - cache.delete(key) -} - -class Unpack extends Parser { - constructor (opt) { - if (!opt) - opt = {} - - opt.ondone = _ => { - this[ENDED] = true - this[MAYBECLOSE]() - } - - super(opt) - - this[CHECKED_CWD] = false - - this.reservations = pathReservations() - - this.transform = typeof opt.transform === 'function' ? opt.transform : null - - this.writable = true - this.readable = false - - this[PENDING] = 0 - this[ENDED] = false - - this.dirCache = opt.dirCache || new Map() - - if (typeof opt.uid === 'number' || typeof opt.gid === 'number') { - // need both or neither - if (typeof opt.uid !== 'number' || typeof opt.gid !== 'number') - throw new TypeError('cannot set owner without number uid and gid') - if (opt.preserveOwner) { - throw new TypeError( - 'cannot preserve owner in archive and also set owner explicitly') - } - this.uid = opt.uid - this.gid = opt.gid - this.setOwner = true - } else { - this.uid = null - this.gid = null - this.setOwner = false - } - - // default true for root - if (opt.preserveOwner === undefined && typeof opt.uid !== 'number') - this.preserveOwner = process.getuid && process.getuid() === 0 - else - this.preserveOwner = !!opt.preserveOwner - - this.processUid = (this.preserveOwner || this.setOwner) && process.getuid ? - process.getuid() : null - this.processGid = (this.preserveOwner || this.setOwner) && process.getgid ? - process.getgid() : null - - // mostly just for testing, but useful in some cases. - // Forcibly trigger a chown on every entry, no matter what - this.forceChown = opt.forceChown === true - - // turn ><?| in filenames into 0xf000-higher encoded forms - this.win32 = !!opt.win32 || isWindows - - // do not unpack over files that are newer than what's in the archive - this.newer = !!opt.newer - - // do not unpack over ANY files - this.keep = !!opt.keep - - // do not set mtime/atime of extracted entries - this.noMtime = !!opt.noMtime - - // allow .., absolute path entries, and unpacking through symlinks - // without this, warn and skip .., relativize absolutes, and error - // on symlinks in extraction path - this.preservePaths = !!opt.preservePaths - - // unlink files and links before writing. This breaks existing hard - // links, and removes symlink directories rather than erroring - this.unlink = !!opt.unlink - - this.cwd = normPath(path.resolve(opt.cwd || process.cwd())) - this.strip = +opt.strip || 0 - // if we're not chmodding, then we don't need the process umask - this.processUmask = opt.noChmod ? 0 : process.umask() - this.umask = typeof opt.umask === 'number' ? opt.umask : this.processUmask - - // default mode for dirs created as parents - this.dmode = opt.dmode || (0o0777 & (~this.umask)) - this.fmode = opt.fmode || (0o0666 & (~this.umask)) - - this.on('entry', entry => this[ONENTRY](entry)) - } - - // a bad or damaged archive is a warning for Parser, but an error - // when extracting. Mark those errors as unrecoverable, because - // the Unpack contract cannot be met. - warn (code, msg, data = {}) { - if (code === 'TAR_BAD_ARCHIVE' || code === 'TAR_ABORT') - data.recoverable = false - return super.warn(code, msg, data) - } - - [MAYBECLOSE] () { - if (this[ENDED] && this[PENDING] === 0) { - this.emit('prefinish') - this.emit('finish') - this.emit('end') - this.emit('close') - } - } - - [CHECKPATH] (entry) { - if (this.strip) { - const parts = normPath(entry.path).split('/') - if (parts.length < this.strip) - return false - entry.path = parts.slice(this.strip).join('/') - - if (entry.type === 'Link') { - const linkparts = normPath(entry.linkpath).split('/') - if (linkparts.length >= this.strip) - entry.linkpath = linkparts.slice(this.strip).join('/') - else - return false - } - } - - if (!this.preservePaths) { - const p = normPath(entry.path) - const parts = p.split('/') - if (parts.includes('..') || isWindows && /^[a-z]:\.\.$/i.test(parts[0])) { - this.warn('TAR_ENTRY_ERROR', `path contains '..'`, { - entry, - path: p, - }) - return false - } - - // strip off the root - const [root, stripped] = stripAbsolutePath(p) - if (root) { - entry.path = stripped - this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute path`, { - entry, - path: p, - }) - } - } - - if (path.isAbsolute(entry.path)) - entry.absolute = normPath(path.resolve(entry.path)) - else - entry.absolute = normPath(path.resolve(this.cwd, entry.path)) - - // if we somehow ended up with a path that escapes the cwd, and we are - // not in preservePaths mode, then something is fishy! This should have - // been prevented above, so ignore this for coverage. - /* istanbul ignore if - defense in depth */ - if (!this.preservePaths && - entry.absolute.indexOf(this.cwd + '/') !== 0 && - entry.absolute !== this.cwd) { - this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', { - entry, - path: normPath(entry.path), - resolvedPath: entry.absolute, - cwd: this.cwd, - }) - return false - } - - // an archive can set properties on the extraction directory, but it - // may not replace the cwd with a different kind of thing entirely. - if (entry.absolute === this.cwd && - entry.type !== 'Directory' && - entry.type !== 'GNUDumpDir') - return false - - // only encode : chars that aren't drive letter indicators - if (this.win32) { - const { root: aRoot } = path.win32.parse(entry.absolute) - entry.absolute = aRoot + wc.encode(entry.absolute.substr(aRoot.length)) - const { root: pRoot } = path.win32.parse(entry.path) - entry.path = pRoot + wc.encode(entry.path.substr(pRoot.length)) - } - - return true - } - - [ONENTRY] (entry) { - if (!this[CHECKPATH](entry)) - return entry.resume() - - assert.equal(typeof entry.absolute, 'string') - - switch (entry.type) { - case 'Directory': - case 'GNUDumpDir': - if (entry.mode) - entry.mode = entry.mode | 0o700 - - case 'File': - case 'OldFile': - case 'ContiguousFile': - case 'Link': - case 'SymbolicLink': - return this[CHECKFS](entry) - - case 'CharacterDevice': - case 'BlockDevice': - case 'FIFO': - default: - return this[UNSUPPORTED](entry) - } - } - - [ONERROR] (er, entry) { - // Cwd has to exist, or else nothing works. That's serious. - // Other errors are warnings, which raise the error in strict - // mode, but otherwise continue on. - if (er.name === 'CwdError') - this.emit('error', er) - else { - this.warn('TAR_ENTRY_ERROR', er, {entry}) - this[UNPEND]() - entry.resume() - } - } - - [MKDIR] (dir, mode, cb) { - mkdir(normPath(dir), { - uid: this.uid, - gid: this.gid, - processUid: this.processUid, - processGid: this.processGid, - umask: this.processUmask, - preserve: this.preservePaths, - unlink: this.unlink, - cache: this.dirCache, - cwd: this.cwd, - mode: mode, - noChmod: this.noChmod, - }, cb) - } - - [DOCHOWN] (entry) { - // in preserve owner mode, chown if the entry doesn't match process - // in set owner mode, chown if setting doesn't match process - return this.forceChown || - this.preserveOwner && - (typeof entry.uid === 'number' && entry.uid !== this.processUid || - typeof entry.gid === 'number' && entry.gid !== this.processGid) - || - (typeof this.uid === 'number' && this.uid !== this.processUid || - typeof this.gid === 'number' && this.gid !== this.processGid) - } - - [UID] (entry) { - return uint32(this.uid, entry.uid, this.processUid) - } - - [GID] (entry) { - return uint32(this.gid, entry.gid, this.processGid) - } - - [FILE] (entry, fullyDone) { - const mode = entry.mode & 0o7777 || this.fmode - const stream = new fsm.WriteStream(entry.absolute, { - flags: getFlag(entry.size), - mode: mode, - autoClose: false, - }) - stream.on('error', er => { - if (stream.fd) - fs.close(stream.fd, () => {}) - - // flush all the data out so that we aren't left hanging - // if the error wasn't actually fatal. otherwise the parse - // is blocked, and we never proceed. - stream.write = () => true - this[ONERROR](er, entry) - fullyDone() - }) - - let actions = 1 - const done = er => { - if (er) { - /* istanbul ignore else - we should always have a fd by now */ - if (stream.fd) - fs.close(stream.fd, () => {}) - - this[ONERROR](er, entry) - fullyDone() - return - } - - if (--actions === 0) { - fs.close(stream.fd, er => { - if (er) - this[ONERROR](er, entry) - else - this[UNPEND]() - fullyDone() - }) - } - } - - stream.on('finish', _ => { - // if futimes fails, try utimes - // if utimes fails, fail with the original error - // same for fchown/chown - const abs = entry.absolute - const fd = stream.fd - - if (entry.mtime && !this.noMtime) { - actions++ - const atime = entry.atime || new Date() - const mtime = entry.mtime - fs.futimes(fd, atime, mtime, er => - er ? fs.utimes(abs, atime, mtime, er2 => done(er2 && er)) - : done()) - } - - if (this[DOCHOWN](entry)) { - actions++ - const uid = this[UID](entry) - const gid = this[GID](entry) - fs.fchown(fd, uid, gid, er => - er ? fs.chown(abs, uid, gid, er2 => done(er2 && er)) - : done()) - } - - done() - }) - - const tx = this.transform ? this.transform(entry) || entry : entry - if (tx !== entry) { - tx.on('error', er => { - this[ONERROR](er, entry) - fullyDone() - }) - entry.pipe(tx) - } - tx.pipe(stream) - } - - [DIRECTORY] (entry, fullyDone) { - const mode = entry.mode & 0o7777 || this.dmode - this[MKDIR](entry.absolute, mode, er => { - if (er) { - this[ONERROR](er, entry) - fullyDone() - return - } - - let actions = 1 - const done = _ => { - if (--actions === 0) { - fullyDone() - this[UNPEND]() - entry.resume() - } - } - - if (entry.mtime && !this.noMtime) { - actions++ - fs.utimes(entry.absolute, entry.atime || new Date(), entry.mtime, done) - } - - if (this[DOCHOWN](entry)) { - actions++ - fs.chown(entry.absolute, this[UID](entry), this[GID](entry), done) - } - - done() - }) - } - - [UNSUPPORTED] (entry) { - entry.unsupported = true - this.warn('TAR_ENTRY_UNSUPPORTED', - `unsupported entry type: ${entry.type}`, {entry}) - entry.resume() - } - - [SYMLINK] (entry, done) { - this[LINK](entry, entry.linkpath, 'symlink', done) - } - - [HARDLINK] (entry, done) { - const linkpath = normPath(path.resolve(this.cwd, entry.linkpath)) - this[LINK](entry, linkpath, 'link', done) - } - - [PEND] () { - this[PENDING]++ - } - - [UNPEND] () { - this[PENDING]-- - this[MAYBECLOSE]() - } - - [SKIP] (entry) { - this[UNPEND]() - entry.resume() - } - - // Check if we can reuse an existing filesystem entry safely and - // overwrite it, rather than unlinking and recreating - // Windows doesn't report a useful nlink, so we just never reuse entries - [ISREUSABLE] (entry, st) { - return entry.type === 'File' && - !this.unlink && - st.isFile() && - st.nlink <= 1 && - !isWindows - } - - // check if a thing is there, and if so, try to clobber it - [CHECKFS] (entry) { - this[PEND]() - const paths = [entry.path] - if (entry.linkpath) - paths.push(entry.linkpath) - this.reservations.reserve(paths, done => this[CHECKFS2](entry, done)) - } - - [PRUNECACHE] (entry) { - // if we are not creating a directory, and the path is in the dirCache, - // then that means we are about to delete the directory we created - // previously, and it is no longer going to be a directory, and neither - // is any of its children. - // If a symbolic link is encountered, all bets are off. There is no - // reasonable way to sanitize the cache in such a way we will be able to - // avoid having filesystem collisions. If this happens with a non-symlink - // entry, it'll just fail to unpack, but a symlink to a directory, using an - // 8.3 shortname or certain unicode attacks, can evade detection and lead - // to arbitrary writes to anywhere on the system. - if (entry.type === 'SymbolicLink') - dropCache(this.dirCache) - else if (entry.type !== 'Directory') - pruneCache(this.dirCache, entry.absolute) - } - - [CHECKFS2] (entry, fullyDone) { - this[PRUNECACHE](entry) - - const done = er => { - this[PRUNECACHE](entry) - fullyDone(er) - } - - const checkCwd = () => { - this[MKDIR](this.cwd, this.dmode, er => { - if (er) { - this[ONERROR](er, entry) - done() - return - } - this[CHECKED_CWD] = true - start() - }) - } - - const start = () => { - if (entry.absolute !== this.cwd) { - const parent = normPath(path.dirname(entry.absolute)) - if (parent !== this.cwd) { - return this[MKDIR](parent, this.dmode, er => { - if (er) { - this[ONERROR](er, entry) - done() - return - } - afterMakeParent() - }) - } - } - afterMakeParent() - } - - const afterMakeParent = () => { - fs.lstat(entry.absolute, (lstatEr, st) => { - if (st && (this.keep || this.newer && st.mtime > entry.mtime)) { - this[SKIP](entry) - done() - return - } - if (lstatEr || this[ISREUSABLE](entry, st)) - return this[MAKEFS](null, entry, done) - - if (st.isDirectory()) { - if (entry.type === 'Directory') { - const needChmod = !this.noChmod && - entry.mode && - (st.mode & 0o7777) !== entry.mode - const afterChmod = er => this[MAKEFS](er, entry, done) - if (!needChmod) - return afterChmod() - return fs.chmod(entry.absolute, entry.mode, afterChmod) - } - // Not a dir entry, have to remove it. - // NB: the only way to end up with an entry that is the cwd - // itself, in such a way that == does not detect, is a - // tricky windows absolute path with UNC or 8.3 parts (and - // preservePaths:true, or else it will have been stripped). - // In that case, the user has opted out of path protections - // explicitly, so if they blow away the cwd, c'est la vie. - if (entry.absolute !== this.cwd) { - return fs.rmdir(entry.absolute, er => - this[MAKEFS](er, entry, done)) - } - } - - // not a dir, and not reusable - // don't remove if the cwd, we want that error - if (entry.absolute === this.cwd) - return this[MAKEFS](null, entry, done) - - unlinkFile(entry.absolute, er => - this[MAKEFS](er, entry, done)) - }) - } - - if (this[CHECKED_CWD]) - start() - else - checkCwd() - } - - [MAKEFS] (er, entry, done) { - if (er) { - this[ONERROR](er, entry) - done() - return - } - - switch (entry.type) { - case 'File': - case 'OldFile': - case 'ContiguousFile': - return this[FILE](entry, done) - - case 'Link': - return this[HARDLINK](entry, done) - - case 'SymbolicLink': - return this[SYMLINK](entry, done) - - case 'Directory': - case 'GNUDumpDir': - return this[DIRECTORY](entry, done) - } - } - - [LINK] (entry, linkpath, link, done) { - // XXX: get the type ('symlink' or 'junction') for windows - fs[link](linkpath, entry.absolute, er => { - if (er) - this[ONERROR](er, entry) - else { - this[UNPEND]() - entry.resume() - } - done() - }) - } -} - -const callSync = fn => { - try { - return [null, fn()] - } catch (er) { - return [er, null] - } -} -class UnpackSync extends Unpack { - [MAKEFS] (er, entry) { - return super[MAKEFS](er, entry, () => {}) - } - - [CHECKFS] (entry) { - this[PRUNECACHE](entry) - - if (!this[CHECKED_CWD]) { - const er = this[MKDIR](this.cwd, this.dmode) - if (er) - return this[ONERROR](er, entry) - this[CHECKED_CWD] = true - } - - // don't bother to make the parent if the current entry is the cwd, - // we've already checked it. - if (entry.absolute !== this.cwd) { - const parent = normPath(path.dirname(entry.absolute)) - if (parent !== this.cwd) { - const mkParent = this[MKDIR](parent, this.dmode) - if (mkParent) - return this[ONERROR](mkParent, entry) - } - } - - const [lstatEr, st] = callSync(() => fs.lstatSync(entry.absolute)) - if (st && (this.keep || this.newer && st.mtime > entry.mtime)) - return this[SKIP](entry) - - if (lstatEr || this[ISREUSABLE](entry, st)) - return this[MAKEFS](null, entry) - - if (st.isDirectory()) { - if (entry.type === 'Directory') { - const needChmod = !this.noChmod && - entry.mode && - (st.mode & 0o7777) !== entry.mode - const [er] = needChmod ? callSync(() => { - fs.chmodSync(entry.absolute, entry.mode) - }) : [] - return this[MAKEFS](er, entry) - } - // not a dir entry, have to remove it - const [er] = callSync(() => fs.rmdirSync(entry.absolute)) - this[MAKEFS](er, entry) - } - - // not a dir, and not reusable. - // don't remove if it's the cwd, since we want that error. - const [er] = entry.absolute === this.cwd ? [] - : callSync(() => unlinkFileSync(entry.absolute)) - this[MAKEFS](er, entry) - } - - [FILE] (entry, done) { - const mode = entry.mode & 0o7777 || this.fmode - - const oner = er => { - let closeError - try { - fs.closeSync(fd) - } catch (e) { - closeError = e - } - if (er || closeError) - this[ONERROR](er || closeError, entry) - done() - } - - let fd - try { - fd = fs.openSync(entry.absolute, getFlag(entry.size), mode) - } catch (er) { - return oner(er) - } - const tx = this.transform ? this.transform(entry) || entry : entry - if (tx !== entry) { - tx.on('error', er => this[ONERROR](er, entry)) - entry.pipe(tx) - } - - tx.on('data', chunk => { - try { - fs.writeSync(fd, chunk, 0, chunk.length) - } catch (er) { - oner(er) - } - }) - - tx.on('end', _ => { - let er = null - // try both, falling futimes back to utimes - // if either fails, handle the first error - if (entry.mtime && !this.noMtime) { - const atime = entry.atime || new Date() - const mtime = entry.mtime - try { - fs.futimesSync(fd, atime, mtime) - } catch (futimeser) { - try { - fs.utimesSync(entry.absolute, atime, mtime) - } catch (utimeser) { - er = futimeser - } - } - } - - if (this[DOCHOWN](entry)) { - const uid = this[UID](entry) - const gid = this[GID](entry) - - try { - fs.fchownSync(fd, uid, gid) - } catch (fchowner) { - try { - fs.chownSync(entry.absolute, uid, gid) - } catch (chowner) { - er = er || fchowner - } - } - } - - oner(er) - }) - } - - [DIRECTORY] (entry, done) { - const mode = entry.mode & 0o7777 || this.dmode - const er = this[MKDIR](entry.absolute, mode) - if (er) { - this[ONERROR](er, entry) - done() - return - } - if (entry.mtime && !this.noMtime) { - try { - fs.utimesSync(entry.absolute, entry.atime || new Date(), entry.mtime) - } catch (er) {} - } - if (this[DOCHOWN](entry)) { - try { - fs.chownSync(entry.absolute, this[UID](entry), this[GID](entry)) - } catch (er) {} - } - done() - entry.resume() - } - - [MKDIR] (dir, mode) { - try { - return mkdir.sync(normPath(dir), { - uid: this.uid, - gid: this.gid, - processUid: this.processUid, - processGid: this.processGid, - umask: this.processUmask, - preserve: this.preservePaths, - unlink: this.unlink, - cache: this.dirCache, - cwd: this.cwd, - mode: mode, - }) - } catch (er) { - return er - } - } - - [LINK] (entry, linkpath, link, done) { - try { - fs[link + 'Sync'](linkpath, entry.absolute) - done() - entry.resume() - } catch (er) { - return this[ONERROR](er, entry) - } - } -} - -Unpack.Sync = UnpackSync -module.exports = Unpack diff --git a/node_modules/tar/lib/update.js b/node_modules/tar/lib/update.js deleted file mode 100644 index a5784b73f3c75..0000000000000 --- a/node_modules/tar/lib/update.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict' - -// tar -u - -const hlo = require('./high-level-opt.js') -const r = require('./replace.js') -// just call tar.r with the filter and mtimeCache - -module.exports = (opt_, files, cb) => { - const opt = hlo(opt_) - - if (!opt.file) - throw new TypeError('file is required') - - if (opt.gzip) - throw new TypeError('cannot append to compressed archives') - - if (!files || !Array.isArray(files) || !files.length) - throw new TypeError('no files or directories specified') - - files = Array.from(files) - - mtimeFilter(opt) - return r(opt, files, cb) -} - -const mtimeFilter = opt => { - const filter = opt.filter - - if (!opt.mtimeCache) - opt.mtimeCache = new Map() - - opt.filter = filter ? (path, stat) => - filter(path, stat) && !(opt.mtimeCache.get(path) > stat.mtime) - : (path, stat) => !(opt.mtimeCache.get(path) > stat.mtime) -} diff --git a/node_modules/tar/lib/warn-mixin.js b/node_modules/tar/lib/warn-mixin.js deleted file mode 100644 index aeebb531b5701..0000000000000 --- a/node_modules/tar/lib/warn-mixin.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' -module.exports = Base => class extends Base { - warn (code, message, data = {}) { - if (this.file) - data.file = this.file - if (this.cwd) - data.cwd = this.cwd - data.code = message instanceof Error && message.code || code - data.tarCode = code - if (!this.strict && data.recoverable !== false) { - if (message instanceof Error) { - data = Object.assign(message, data) - message = message.message - } - this.emit('warn', data.tarCode, message, data) - } else if (message instanceof Error) - this.emit('error', Object.assign(message, data)) - else - this.emit('error', Object.assign(new Error(`${code}: ${message}`), data)) - } -} diff --git a/node_modules/tar/lib/winchars.js b/node_modules/tar/lib/winchars.js deleted file mode 100644 index ebcab4aed3e52..0000000000000 --- a/node_modules/tar/lib/winchars.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict' - -// When writing files on Windows, translate the characters to their -// 0xf000 higher-encoded versions. - -const raw = [ - '|', - '<', - '>', - '?', - ':', -] - -const win = raw.map(char => - String.fromCharCode(0xf000 + char.charCodeAt(0))) - -const toWin = new Map(raw.map((char, i) => [char, win[i]])) -const toRaw = new Map(win.map((char, i) => [char, raw[i]])) - -module.exports = { - encode: s => raw.reduce((s, c) => s.split(c).join(toWin.get(c)), s), - decode: s => win.reduce((s, c) => s.split(c).join(toRaw.get(c)), s), -} diff --git a/node_modules/tar/lib/write-entry.js b/node_modules/tar/lib/write-entry.js deleted file mode 100644 index 3702f2ae51979..0000000000000 --- a/node_modules/tar/lib/write-entry.js +++ /dev/null @@ -1,525 +0,0 @@ -'use strict' -const MiniPass = require('minipass') -const Pax = require('./pax.js') -const Header = require('./header.js') -const fs = require('fs') -const path = require('path') -const normPath = require('./normalize-windows-path.js') -const stripSlash = require('./strip-trailing-slashes.js') - -const prefixPath = (path, prefix) => { - if (!prefix) - return normPath(path) - path = normPath(path).replace(/^\.(\/|$)/, '') - return stripSlash(prefix) + '/' + path -} - -const maxReadSize = 16 * 1024 * 1024 -const PROCESS = Symbol('process') -const FILE = Symbol('file') -const DIRECTORY = Symbol('directory') -const SYMLINK = Symbol('symlink') -const HARDLINK = Symbol('hardlink') -const HEADER = Symbol('header') -const READ = Symbol('read') -const LSTAT = Symbol('lstat') -const ONLSTAT = Symbol('onlstat') -const ONREAD = Symbol('onread') -const ONREADLINK = Symbol('onreadlink') -const OPENFILE = Symbol('openfile') -const ONOPENFILE = Symbol('onopenfile') -const CLOSE = Symbol('close') -const MODE = Symbol('mode') -const AWAITDRAIN = Symbol('awaitDrain') -const ONDRAIN = Symbol('ondrain') -const PREFIX = Symbol('prefix') -const HAD_ERROR = Symbol('hadError') -const warner = require('./warn-mixin.js') -const winchars = require('./winchars.js') -const stripAbsolutePath = require('./strip-absolute-path.js') - -const modeFix = require('./mode-fix.js') - -const WriteEntry = warner(class WriteEntry extends MiniPass { - constructor (p, opt) { - opt = opt || {} - super(opt) - if (typeof p !== 'string') - throw new TypeError('path is required') - this.path = normPath(p) - // suppress atime, ctime, uid, gid, uname, gname - this.portable = !!opt.portable - // until node has builtin pwnam functions, this'll have to do - this.myuid = process.getuid && process.getuid() || 0 - this.myuser = process.env.USER || '' - this.maxReadSize = opt.maxReadSize || maxReadSize - this.linkCache = opt.linkCache || new Map() - this.statCache = opt.statCache || new Map() - this.preservePaths = !!opt.preservePaths - this.cwd = normPath(opt.cwd || process.cwd()) - this.strict = !!opt.strict - this.noPax = !!opt.noPax - this.noMtime = !!opt.noMtime - this.mtime = opt.mtime || null - this.prefix = opt.prefix ? normPath(opt.prefix) : null - - this.fd = null - this.blockLen = null - this.blockRemain = null - this.buf = null - this.offset = null - this.length = null - this.pos = null - this.remain = null - - if (typeof opt.onwarn === 'function') - this.on('warn', opt.onwarn) - - let pathWarn = false - if (!this.preservePaths) { - const [root, stripped] = stripAbsolutePath(this.path) - if (root) { - this.path = stripped - pathWarn = root - } - } - - this.win32 = !!opt.win32 || process.platform === 'win32' - if (this.win32) { - // force the \ to / normalization, since we might not *actually* - // be on windows, but want \ to be considered a path separator. - this.path = winchars.decode(this.path.replace(/\\/g, '/')) - p = p.replace(/\\/g, '/') - } - - this.absolute = normPath(opt.absolute || path.resolve(this.cwd, p)) - - if (this.path === '') - this.path = './' - - if (pathWarn) { - this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { - entry: this, - path: pathWarn + this.path, - }) - } - - if (this.statCache.has(this.absolute)) - this[ONLSTAT](this.statCache.get(this.absolute)) - else - this[LSTAT]() - } - - emit (ev, ...data) { - if (ev === 'error') - this[HAD_ERROR] = true - return super.emit(ev, ...data) - } - - [LSTAT] () { - fs.lstat(this.absolute, (er, stat) => { - if (er) - return this.emit('error', er) - this[ONLSTAT](stat) - }) - } - - [ONLSTAT] (stat) { - this.statCache.set(this.absolute, stat) - this.stat = stat - if (!stat.isFile()) - stat.size = 0 - this.type = getType(stat) - this.emit('stat', stat) - this[PROCESS]() - } - - [PROCESS] () { - switch (this.type) { - case 'File': return this[FILE]() - case 'Directory': return this[DIRECTORY]() - case 'SymbolicLink': return this[SYMLINK]() - // unsupported types are ignored. - default: return this.end() - } - } - - [MODE] (mode) { - return modeFix(mode, this.type === 'Directory', this.portable) - } - - [PREFIX] (path) { - return prefixPath(path, this.prefix) - } - - [HEADER] () { - if (this.type === 'Directory' && this.portable) - this.noMtime = true - - this.header = new Header({ - path: this[PREFIX](this.path), - // only apply the prefix to hard links. - linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) - : this.linkpath, - // only the permissions and setuid/setgid/sticky bitflags - // not the higher-order bits that specify file type - mode: this[MODE](this.stat.mode), - uid: this.portable ? null : this.stat.uid, - gid: this.portable ? null : this.stat.gid, - size: this.stat.size, - mtime: this.noMtime ? null : this.mtime || this.stat.mtime, - type: this.type, - uname: this.portable ? null : - this.stat.uid === this.myuid ? this.myuser : '', - atime: this.portable ? null : this.stat.atime, - ctime: this.portable ? null : this.stat.ctime, - }) - - if (this.header.encode() && !this.noPax) { - super.write(new Pax({ - atime: this.portable ? null : this.header.atime, - ctime: this.portable ? null : this.header.ctime, - gid: this.portable ? null : this.header.gid, - mtime: this.noMtime ? null : this.mtime || this.header.mtime, - path: this[PREFIX](this.path), - linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) - : this.linkpath, - size: this.header.size, - uid: this.portable ? null : this.header.uid, - uname: this.portable ? null : this.header.uname, - dev: this.portable ? null : this.stat.dev, - ino: this.portable ? null : this.stat.ino, - nlink: this.portable ? null : this.stat.nlink, - }).encode()) - } - super.write(this.header.block) - } - - [DIRECTORY] () { - if (this.path.substr(-1) !== '/') - this.path += '/' - this.stat.size = 0 - this[HEADER]() - this.end() - } - - [SYMLINK] () { - fs.readlink(this.absolute, (er, linkpath) => { - if (er) - return this.emit('error', er) - this[ONREADLINK](linkpath) - }) - } - - [ONREADLINK] (linkpath) { - this.linkpath = normPath(linkpath) - this[HEADER]() - this.end() - } - - [HARDLINK] (linkpath) { - this.type = 'Link' - this.linkpath = normPath(path.relative(this.cwd, linkpath)) - this.stat.size = 0 - this[HEADER]() - this.end() - } - - [FILE] () { - if (this.stat.nlink > 1) { - const linkKey = this.stat.dev + ':' + this.stat.ino - if (this.linkCache.has(linkKey)) { - const linkpath = this.linkCache.get(linkKey) - if (linkpath.indexOf(this.cwd) === 0) - return this[HARDLINK](linkpath) - } - this.linkCache.set(linkKey, this.absolute) - } - - this[HEADER]() - if (this.stat.size === 0) - return this.end() - - this[OPENFILE]() - } - - [OPENFILE] () { - fs.open(this.absolute, 'r', (er, fd) => { - if (er) - return this.emit('error', er) - this[ONOPENFILE](fd) - }) - } - - [ONOPENFILE] (fd) { - this.fd = fd - if (this[HAD_ERROR]) - return this[CLOSE]() - - this.blockLen = 512 * Math.ceil(this.stat.size / 512) - this.blockRemain = this.blockLen - const bufLen = Math.min(this.blockLen, this.maxReadSize) - this.buf = Buffer.allocUnsafe(bufLen) - this.offset = 0 - this.pos = 0 - this.remain = this.stat.size - this.length = this.buf.length - this[READ]() - } - - [READ] () { - const { fd, buf, offset, length, pos } = this - fs.read(fd, buf, offset, length, pos, (er, bytesRead) => { - if (er) { - // ignoring the error from close(2) is a bad practice, but at - // this point we already have an error, don't need another one - return this[CLOSE](() => this.emit('error', er)) - } - this[ONREAD](bytesRead) - }) - } - - [CLOSE] (cb) { - fs.close(this.fd, cb) - } - - [ONREAD] (bytesRead) { - if (bytesRead <= 0 && this.remain > 0) { - const er = new Error('encountered unexpected EOF') - er.path = this.absolute - er.syscall = 'read' - er.code = 'EOF' - return this[CLOSE](() => this.emit('error', er)) - } - - if (bytesRead > this.remain) { - const er = new Error('did not encounter expected EOF') - er.path = this.absolute - er.syscall = 'read' - er.code = 'EOF' - return this[CLOSE](() => this.emit('error', er)) - } - - // null out the rest of the buffer, if we could fit the block padding - // at the end of this loop, we've incremented bytesRead and this.remain - // to be incremented up to the blockRemain level, as if we had expected - // to get a null-padded file, and read it until the end. then we will - // decrement both remain and blockRemain by bytesRead, and know that we - // reached the expected EOF, without any null buffer to append. - if (bytesRead === this.remain) { - for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) { - this.buf[i + this.offset] = 0 - bytesRead++ - this.remain++ - } - } - - const writeBuf = this.offset === 0 && bytesRead === this.buf.length ? - this.buf : this.buf.slice(this.offset, this.offset + bytesRead) - - const flushed = this.write(writeBuf) - if (!flushed) - this[AWAITDRAIN](() => this[ONDRAIN]()) - else - this[ONDRAIN]() - } - - [AWAITDRAIN] (cb) { - this.once('drain', cb) - } - - write (writeBuf) { - if (this.blockRemain < writeBuf.length) { - const er = new Error('writing more data than expected') - er.path = this.absolute - return this.emit('error', er) - } - this.remain -= writeBuf.length - this.blockRemain -= writeBuf.length - this.pos += writeBuf.length - this.offset += writeBuf.length - return super.write(writeBuf) - } - - [ONDRAIN] () { - if (!this.remain) { - if (this.blockRemain) - super.write(Buffer.alloc(this.blockRemain)) - return this[CLOSE](er => er ? this.emit('error', er) : this.end()) - } - - if (this.offset >= this.length) { - // if we only have a smaller bit left to read, alloc a smaller buffer - // otherwise, keep it the same length it was before. - this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length)) - this.offset = 0 - } - this.length = this.buf.length - this.offset - this[READ]() - } -}) - -class WriteEntrySync extends WriteEntry { - [LSTAT] () { - this[ONLSTAT](fs.lstatSync(this.absolute)) - } - - [SYMLINK] () { - this[ONREADLINK](fs.readlinkSync(this.absolute)) - } - - [OPENFILE] () { - this[ONOPENFILE](fs.openSync(this.absolute, 'r')) - } - - [READ] () { - let threw = true - try { - const { fd, buf, offset, length, pos } = this - const bytesRead = fs.readSync(fd, buf, offset, length, pos) - this[ONREAD](bytesRead) - threw = false - } finally { - // ignoring the error from close(2) is a bad practice, but at - // this point we already have an error, don't need another one - if (threw) { - try { - this[CLOSE](() => {}) - } catch (er) {} - } - } - } - - [AWAITDRAIN] (cb) { - cb() - } - - [CLOSE] (cb) { - fs.closeSync(this.fd) - cb() - } -} - -const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { - constructor (readEntry, opt) { - opt = opt || {} - super(opt) - this.preservePaths = !!opt.preservePaths - this.portable = !!opt.portable - this.strict = !!opt.strict - this.noPax = !!opt.noPax - this.noMtime = !!opt.noMtime - - this.readEntry = readEntry - this.type = readEntry.type - if (this.type === 'Directory' && this.portable) - this.noMtime = true - - this.prefix = opt.prefix || null - - this.path = normPath(readEntry.path) - this.mode = this[MODE](readEntry.mode) - this.uid = this.portable ? null : readEntry.uid - this.gid = this.portable ? null : readEntry.gid - this.uname = this.portable ? null : readEntry.uname - this.gname = this.portable ? null : readEntry.gname - this.size = readEntry.size - this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime - this.atime = this.portable ? null : readEntry.atime - this.ctime = this.portable ? null : readEntry.ctime - this.linkpath = normPath(readEntry.linkpath) - - if (typeof opt.onwarn === 'function') - this.on('warn', opt.onwarn) - - let pathWarn = false - if (!this.preservePaths) { - const [root, stripped] = stripAbsolutePath(this.path) - if (root) { - this.path = stripped - pathWarn = root - } - } - - this.remain = readEntry.size - this.blockRemain = readEntry.startBlockSize - - this.header = new Header({ - path: this[PREFIX](this.path), - linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) - : this.linkpath, - // only the permissions and setuid/setgid/sticky bitflags - // not the higher-order bits that specify file type - mode: this.mode, - uid: this.portable ? null : this.uid, - gid: this.portable ? null : this.gid, - size: this.size, - mtime: this.noMtime ? null : this.mtime, - type: this.type, - uname: this.portable ? null : this.uname, - atime: this.portable ? null : this.atime, - ctime: this.portable ? null : this.ctime, - }) - - if (pathWarn) { - this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { - entry: this, - path: pathWarn + this.path, - }) - } - - if (this.header.encode() && !this.noPax) { - super.write(new Pax({ - atime: this.portable ? null : this.atime, - ctime: this.portable ? null : this.ctime, - gid: this.portable ? null : this.gid, - mtime: this.noMtime ? null : this.mtime, - path: this[PREFIX](this.path), - linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) - : this.linkpath, - size: this.size, - uid: this.portable ? null : this.uid, - uname: this.portable ? null : this.uname, - dev: this.portable ? null : this.readEntry.dev, - ino: this.portable ? null : this.readEntry.ino, - nlink: this.portable ? null : this.readEntry.nlink, - }).encode()) - } - - super.write(this.header.block) - readEntry.pipe(this) - } - - [PREFIX] (path) { - return prefixPath(path, this.prefix) - } - - [MODE] (mode) { - return modeFix(mode, this.type === 'Directory', this.portable) - } - - write (data) { - const writeLen = data.length - if (writeLen > this.blockRemain) - throw new Error('writing more to entry than is appropriate') - this.blockRemain -= writeLen - return super.write(data) - } - - end () { - if (this.blockRemain) - super.write(Buffer.alloc(this.blockRemain)) - return super.end() - } -}) - -WriteEntry.Sync = WriteEntrySync -WriteEntry.Tar = WriteEntryTar - -const getType = stat => - stat.isFile() ? 'File' - : stat.isDirectory() ? 'Directory' - : stat.isSymbolicLink() ? 'SymbolicLink' - : 'Unsupported' - -module.exports = WriteEntry diff --git a/node_modules/tar/node_modules/yallist/LICENSE.md b/node_modules/tar/node_modules/yallist/LICENSE.md new file mode 100644 index 0000000000000..881248b6d7f0c --- /dev/null +++ b/node_modules/tar/node_modules/yallist/LICENSE.md @@ -0,0 +1,63 @@ +All packages under `src/` are licensed according to the terms in +their respective `LICENSE` or `LICENSE.md` files. + +The remainder of this project is licensed under the Blue Oak +Model License, as follows: + +----- + +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +<https://blueoakcouncil.org/license/1.0.0>. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** diff --git a/node_modules/tar/node_modules/yallist/dist/commonjs/index.js b/node_modules/tar/node_modules/yallist/dist/commonjs/index.js new file mode 100644 index 0000000000000..c1e1e4741689d --- /dev/null +++ b/node_modules/tar/node_modules/yallist/dist/commonjs/index.js @@ -0,0 +1,384 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Node = exports.Yallist = void 0; +class Yallist { + tail; + head; + length = 0; + static create(list = []) { + return new Yallist(list); + } + constructor(list = []) { + for (const item of list) { + this.push(item); + } + } + *[Symbol.iterator]() { + for (let walker = this.head; walker; walker = walker.next) { + yield walker.value; + } + } + removeNode(node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list'); + } + const next = node.next; + const prev = node.prev; + if (next) { + next.prev = prev; + } + if (prev) { + prev.next = next; + } + if (node === this.head) { + this.head = next; + } + if (node === this.tail) { + this.tail = prev; + } + this.length--; + node.next = undefined; + node.prev = undefined; + node.list = undefined; + return next; + } + unshiftNode(node) { + if (node === this.head) { + return; + } + if (node.list) { + node.list.removeNode(node); + } + const head = this.head; + node.list = this; + node.next = head; + if (head) { + head.prev = node; + } + this.head = node; + if (!this.tail) { + this.tail = node; + } + this.length++; + } + pushNode(node) { + if (node === this.tail) { + return; + } + if (node.list) { + node.list.removeNode(node); + } + const tail = this.tail; + node.list = this; + node.prev = tail; + if (tail) { + tail.next = node; + } + this.tail = node; + if (!this.head) { + this.head = node; + } + this.length++; + } + push(...args) { + for (let i = 0, l = args.length; i < l; i++) { + push(this, args[i]); + } + return this.length; + } + unshift(...args) { + for (var i = 0, l = args.length; i < l; i++) { + unshift(this, args[i]); + } + return this.length; + } + pop() { + if (!this.tail) { + return undefined; + } + const res = this.tail.value; + const t = this.tail; + this.tail = this.tail.prev; + if (this.tail) { + this.tail.next = undefined; + } + else { + this.head = undefined; + } + t.list = undefined; + this.length--; + return res; + } + shift() { + if (!this.head) { + return undefined; + } + const res = this.head.value; + const h = this.head; + this.head = this.head.next; + if (this.head) { + this.head.prev = undefined; + } + else { + this.tail = undefined; + } + h.list = undefined; + this.length--; + return res; + } + forEach(fn, thisp) { + thisp = thisp || this; + for (let walker = this.head, i = 0; !!walker; i++) { + fn.call(thisp, walker.value, i, this); + walker = walker.next; + } + } + forEachReverse(fn, thisp) { + thisp = thisp || this; + for (let walker = this.tail, i = this.length - 1; !!walker; i--) { + fn.call(thisp, walker.value, i, this); + walker = walker.prev; + } + } + get(n) { + let i = 0; + let walker = this.head; + for (; !!walker && i < n; i++) { + walker = walker.next; + } + if (i === n && !!walker) { + return walker.value; + } + } + getReverse(n) { + let i = 0; + let walker = this.tail; + for (; !!walker && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.prev; + } + if (i === n && !!walker) { + return walker.value; + } + } + map(fn, thisp) { + thisp = thisp || this; + const res = new Yallist(); + for (let walker = this.head; !!walker;) { + res.push(fn.call(thisp, walker.value, this)); + walker = walker.next; + } + return res; + } + mapReverse(fn, thisp) { + thisp = thisp || this; + var res = new Yallist(); + for (let walker = this.tail; !!walker;) { + res.push(fn.call(thisp, walker.value, this)); + walker = walker.prev; + } + return res; + } + reduce(fn, initial) { + let acc; + let walker = this.head; + if (arguments.length > 1) { + acc = initial; + } + else if (this.head) { + walker = this.head.next; + acc = this.head.value; + } + else { + throw new TypeError('Reduce of empty list with no initial value'); + } + for (var i = 0; !!walker; i++) { + acc = fn(acc, walker.value, i); + walker = walker.next; + } + return acc; + } + reduceReverse(fn, initial) { + let acc; + let walker = this.tail; + if (arguments.length > 1) { + acc = initial; + } + else if (this.tail) { + walker = this.tail.prev; + acc = this.tail.value; + } + else { + throw new TypeError('Reduce of empty list with no initial value'); + } + for (let i = this.length - 1; !!walker; i--) { + acc = fn(acc, walker.value, i); + walker = walker.prev; + } + return acc; + } + toArray() { + const arr = new Array(this.length); + for (let i = 0, walker = this.head; !!walker; i++) { + arr[i] = walker.value; + walker = walker.next; + } + return arr; + } + toArrayReverse() { + const arr = new Array(this.length); + for (let i = 0, walker = this.tail; !!walker; i++) { + arr[i] = walker.value; + walker = walker.prev; + } + return arr; + } + slice(from = 0, to = this.length) { + if (to < 0) { + to += this.length; + } + if (from < 0) { + from += this.length; + } + const ret = new Yallist(); + if (to < from || to < 0) { + return ret; + } + if (from < 0) { + from = 0; + } + if (to > this.length) { + to = this.length; + } + let walker = this.head; + let i = 0; + for (i = 0; !!walker && i < from; i++) { + walker = walker.next; + } + for (; !!walker && i < to; i++, walker = walker.next) { + ret.push(walker.value); + } + return ret; + } + sliceReverse(from = 0, to = this.length) { + if (to < 0) { + to += this.length; + } + if (from < 0) { + from += this.length; + } + const ret = new Yallist(); + if (to < from || to < 0) { + return ret; + } + if (from < 0) { + from = 0; + } + if (to > this.length) { + to = this.length; + } + let i = this.length; + let walker = this.tail; + for (; !!walker && i > to; i--) { + walker = walker.prev; + } + for (; !!walker && i > from; i--, walker = walker.prev) { + ret.push(walker.value); + } + return ret; + } + splice(start, deleteCount = 0, ...nodes) { + if (start > this.length) { + start = this.length - 1; + } + if (start < 0) { + start = this.length + start; + } + let walker = this.head; + for (let i = 0; !!walker && i < start; i++) { + walker = walker.next; + } + const ret = []; + for (let i = 0; !!walker && i < deleteCount; i++) { + ret.push(walker.value); + walker = this.removeNode(walker); + } + if (!walker) { + walker = this.tail; + } + else if (walker !== this.tail) { + walker = walker.prev; + } + for (const v of nodes) { + walker = insertAfter(this, walker, v); + } + return ret; + } + reverse() { + const head = this.head; + const tail = this.tail; + for (let walker = head; !!walker; walker = walker.prev) { + const p = walker.prev; + walker.prev = walker.next; + walker.next = p; + } + this.head = tail; + this.tail = head; + return this; + } +} +exports.Yallist = Yallist; +// insertAfter undefined means "make the node the new head of list" +function insertAfter(self, node, value) { + const prev = node; + const next = node ? node.next : self.head; + const inserted = new Node(value, prev, next, self); + if (inserted.next === undefined) { + self.tail = inserted; + } + if (inserted.prev === undefined) { + self.head = inserted; + } + self.length++; + return inserted; +} +function push(self, item) { + self.tail = new Node(item, self.tail, undefined, self); + if (!self.head) { + self.head = self.tail; + } + self.length++; +} +function unshift(self, item) { + self.head = new Node(item, undefined, self.head, self); + if (!self.tail) { + self.tail = self.head; + } + self.length++; +} +class Node { + list; + next; + prev; + value; + constructor(value, prev, next, list) { + this.list = list; + this.value = value; + if (prev) { + prev.next = this; + this.prev = prev; + } + else { + this.prev = undefined; + } + if (next) { + next.prev = this; + this.next = next; + } + else { + this.next = undefined; + } + } +} +exports.Node = Node; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/tar/node_modules/yallist/dist/commonjs/package.json b/node_modules/tar/node_modules/yallist/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/tar/node_modules/yallist/dist/esm/index.js b/node_modules/tar/node_modules/yallist/dist/esm/index.js new file mode 100644 index 0000000000000..3d81c5113b93a --- /dev/null +++ b/node_modules/tar/node_modules/yallist/dist/esm/index.js @@ -0,0 +1,379 @@ +export class Yallist { + tail; + head; + length = 0; + static create(list = []) { + return new Yallist(list); + } + constructor(list = []) { + for (const item of list) { + this.push(item); + } + } + *[Symbol.iterator]() { + for (let walker = this.head; walker; walker = walker.next) { + yield walker.value; + } + } + removeNode(node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list'); + } + const next = node.next; + const prev = node.prev; + if (next) { + next.prev = prev; + } + if (prev) { + prev.next = next; + } + if (node === this.head) { + this.head = next; + } + if (node === this.tail) { + this.tail = prev; + } + this.length--; + node.next = undefined; + node.prev = undefined; + node.list = undefined; + return next; + } + unshiftNode(node) { + if (node === this.head) { + return; + } + if (node.list) { + node.list.removeNode(node); + } + const head = this.head; + node.list = this; + node.next = head; + if (head) { + head.prev = node; + } + this.head = node; + if (!this.tail) { + this.tail = node; + } + this.length++; + } + pushNode(node) { + if (node === this.tail) { + return; + } + if (node.list) { + node.list.removeNode(node); + } + const tail = this.tail; + node.list = this; + node.prev = tail; + if (tail) { + tail.next = node; + } + this.tail = node; + if (!this.head) { + this.head = node; + } + this.length++; + } + push(...args) { + for (let i = 0, l = args.length; i < l; i++) { + push(this, args[i]); + } + return this.length; + } + unshift(...args) { + for (var i = 0, l = args.length; i < l; i++) { + unshift(this, args[i]); + } + return this.length; + } + pop() { + if (!this.tail) { + return undefined; + } + const res = this.tail.value; + const t = this.tail; + this.tail = this.tail.prev; + if (this.tail) { + this.tail.next = undefined; + } + else { + this.head = undefined; + } + t.list = undefined; + this.length--; + return res; + } + shift() { + if (!this.head) { + return undefined; + } + const res = this.head.value; + const h = this.head; + this.head = this.head.next; + if (this.head) { + this.head.prev = undefined; + } + else { + this.tail = undefined; + } + h.list = undefined; + this.length--; + return res; + } + forEach(fn, thisp) { + thisp = thisp || this; + for (let walker = this.head, i = 0; !!walker; i++) { + fn.call(thisp, walker.value, i, this); + walker = walker.next; + } + } + forEachReverse(fn, thisp) { + thisp = thisp || this; + for (let walker = this.tail, i = this.length - 1; !!walker; i--) { + fn.call(thisp, walker.value, i, this); + walker = walker.prev; + } + } + get(n) { + let i = 0; + let walker = this.head; + for (; !!walker && i < n; i++) { + walker = walker.next; + } + if (i === n && !!walker) { + return walker.value; + } + } + getReverse(n) { + let i = 0; + let walker = this.tail; + for (; !!walker && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.prev; + } + if (i === n && !!walker) { + return walker.value; + } + } + map(fn, thisp) { + thisp = thisp || this; + const res = new Yallist(); + for (let walker = this.head; !!walker;) { + res.push(fn.call(thisp, walker.value, this)); + walker = walker.next; + } + return res; + } + mapReverse(fn, thisp) { + thisp = thisp || this; + var res = new Yallist(); + for (let walker = this.tail; !!walker;) { + res.push(fn.call(thisp, walker.value, this)); + walker = walker.prev; + } + return res; + } + reduce(fn, initial) { + let acc; + let walker = this.head; + if (arguments.length > 1) { + acc = initial; + } + else if (this.head) { + walker = this.head.next; + acc = this.head.value; + } + else { + throw new TypeError('Reduce of empty list with no initial value'); + } + for (var i = 0; !!walker; i++) { + acc = fn(acc, walker.value, i); + walker = walker.next; + } + return acc; + } + reduceReverse(fn, initial) { + let acc; + let walker = this.tail; + if (arguments.length > 1) { + acc = initial; + } + else if (this.tail) { + walker = this.tail.prev; + acc = this.tail.value; + } + else { + throw new TypeError('Reduce of empty list with no initial value'); + } + for (let i = this.length - 1; !!walker; i--) { + acc = fn(acc, walker.value, i); + walker = walker.prev; + } + return acc; + } + toArray() { + const arr = new Array(this.length); + for (let i = 0, walker = this.head; !!walker; i++) { + arr[i] = walker.value; + walker = walker.next; + } + return arr; + } + toArrayReverse() { + const arr = new Array(this.length); + for (let i = 0, walker = this.tail; !!walker; i++) { + arr[i] = walker.value; + walker = walker.prev; + } + return arr; + } + slice(from = 0, to = this.length) { + if (to < 0) { + to += this.length; + } + if (from < 0) { + from += this.length; + } + const ret = new Yallist(); + if (to < from || to < 0) { + return ret; + } + if (from < 0) { + from = 0; + } + if (to > this.length) { + to = this.length; + } + let walker = this.head; + let i = 0; + for (i = 0; !!walker && i < from; i++) { + walker = walker.next; + } + for (; !!walker && i < to; i++, walker = walker.next) { + ret.push(walker.value); + } + return ret; + } + sliceReverse(from = 0, to = this.length) { + if (to < 0) { + to += this.length; + } + if (from < 0) { + from += this.length; + } + const ret = new Yallist(); + if (to < from || to < 0) { + return ret; + } + if (from < 0) { + from = 0; + } + if (to > this.length) { + to = this.length; + } + let i = this.length; + let walker = this.tail; + for (; !!walker && i > to; i--) { + walker = walker.prev; + } + for (; !!walker && i > from; i--, walker = walker.prev) { + ret.push(walker.value); + } + return ret; + } + splice(start, deleteCount = 0, ...nodes) { + if (start > this.length) { + start = this.length - 1; + } + if (start < 0) { + start = this.length + start; + } + let walker = this.head; + for (let i = 0; !!walker && i < start; i++) { + walker = walker.next; + } + const ret = []; + for (let i = 0; !!walker && i < deleteCount; i++) { + ret.push(walker.value); + walker = this.removeNode(walker); + } + if (!walker) { + walker = this.tail; + } + else if (walker !== this.tail) { + walker = walker.prev; + } + for (const v of nodes) { + walker = insertAfter(this, walker, v); + } + return ret; + } + reverse() { + const head = this.head; + const tail = this.tail; + for (let walker = head; !!walker; walker = walker.prev) { + const p = walker.prev; + walker.prev = walker.next; + walker.next = p; + } + this.head = tail; + this.tail = head; + return this; + } +} +// insertAfter undefined means "make the node the new head of list" +function insertAfter(self, node, value) { + const prev = node; + const next = node ? node.next : self.head; + const inserted = new Node(value, prev, next, self); + if (inserted.next === undefined) { + self.tail = inserted; + } + if (inserted.prev === undefined) { + self.head = inserted; + } + self.length++; + return inserted; +} +function push(self, item) { + self.tail = new Node(item, self.tail, undefined, self); + if (!self.head) { + self.head = self.tail; + } + self.length++; +} +function unshift(self, item) { + self.head = new Node(item, undefined, self.head, self); + if (!self.tail) { + self.tail = self.head; + } + self.length++; +} +export class Node { + list; + next; + prev; + value; + constructor(value, prev, next, list) { + this.list = list; + this.value = value; + if (prev) { + prev.next = this; + this.prev = prev; + } + else { + this.prev = undefined; + } + if (next) { + next.prev = this; + this.next = next; + } + else { + this.next = undefined; + } + } +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/tar/node_modules/yallist/dist/esm/package.json b/node_modules/tar/node_modules/yallist/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/tar/node_modules/yallist/package.json b/node_modules/tar/node_modules/yallist/package.json new file mode 100644 index 0000000000000..2f5247808bbea --- /dev/null +++ b/node_modules/tar/node_modules/yallist/package.json @@ -0,0 +1,68 @@ +{ + "name": "yallist", + "version": "5.0.0", + "description": "Yet Another Linked List", + "files": [ + "dist" + ], + "devDependencies": { + "prettier": "^3.2.5", + "tap": "^18.7.2", + "tshy": "^1.13.1", + "typedoc": "^0.25.13" + }, + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --loglevel warn --ignore-path ../../.prettierignore --cache", + "typedoc": "typedoc" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/yallist.git" + }, + "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "license": "BlueOak-1.0.0", + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "type": "module", + "prettier": { + "semi": false, + "printWidth": 70, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" + }, + "engines": { + "node": ">=18" + } +} diff --git a/node_modules/tar/package.json b/node_modules/tar/package.json index 9f9977a0ca99b..397764155b514 100644 --- a/node_modules/tar/package.json +++ b/node_modules/tar/package.json @@ -1,59 +1,271 @@ { - "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)", + "author": "Isaac Z. Schlueter", "name": "tar", "description": "tar for node", - "version": "6.1.11", + "version": "7.5.7", "repository": { "type": "git", - "url": "https://github.com/npm/node-tar.git" + "url": "https://github.com/isaacs/node-tar.git" }, "scripts": { - "test:posix": "tap", - "test:win32": "tap --lines=98 --branches=98 --statements=98 --functions=98", - "test": "node test/fixtures/test.js", - "posttest": "npm run lint", - "eslint": "eslint", - "lint": "npm run eslint -- test lib", - "lintfix": "npm run lint -- --fix", + "genparse": "node scripts/generate-parse-fixtures.js", + "snap": "tap", + "test": "tap", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "prepare": "tshy", "preversion": "npm test", "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", - "genparse": "node scripts/generate-parse-fixtures.js", - "bench": "for i in benchmarks/*/*.js; do echo $i; for j in {1..5}; do node $i || break; done; done" + "format": "prettier --write . --log-level warn", + "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts" }, "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "devDependencies": { - "chmodr": "^1.2.0", + "@types/node": "^25.0.9", + "chmodr": "^2.0.2", "end-of-stream": "^1.4.3", - "eslint": "^7.17.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-standard": "^5.0.0", - "events-to-array": "^1.1.2", + "events-to-array": "^2.0.3", "mutate-fs": "^2.1.1", - "rimraf": "^2.7.1", - "tap": "^15.0.9", - "tar-fs": "^1.16.3", - "tar-stream": "^1.6.2" + "nock": "^13.5.4", + "prettier": "^3.8.0", + "rimraf": "^6.1.2", + "tap": "^21.5.0", + "tshy": "^3.1.0", + "typedoc": "^0.28.16" }, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 10" + "node": ">=18" }, "files": [ - "index.js", - "lib/*.js" + "dist" ], - "tap": { - "coverage-map": "map.js", - "check-coverage": true - } + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts", + "./c": "./src/create.ts", + "./create": "./src/create.ts", + "./replace": "./src/create.ts", + "./r": "./src/create.ts", + "./list": "./src/list.ts", + "./t": "./src/list.ts", + "./update": "./src/update.ts", + "./u": "./src/update.ts", + "./extract": "./src/extract.ts", + "./x": "./src/extract.ts", + "./pack": "./src/pack.ts", + "./unpack": "./src/unpack.ts", + "./parse": "./src/parse.ts", + "./read-entry": "./src/read-entry.ts", + "./write-entry": "./src/write-entry.ts", + "./header": "./src/header.ts", + "./pax": "./src/pax.ts", + "./types": "./src/types.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + }, + "./c": { + "import": { + "types": "./dist/esm/create.d.ts", + "default": "./dist/esm/create.js" + }, + "require": { + "types": "./dist/commonjs/create.d.ts", + "default": "./dist/commonjs/create.js" + } + }, + "./create": { + "import": { + "types": "./dist/esm/create.d.ts", + "default": "./dist/esm/create.js" + }, + "require": { + "types": "./dist/commonjs/create.d.ts", + "default": "./dist/commonjs/create.js" + } + }, + "./replace": { + "import": { + "types": "./dist/esm/create.d.ts", + "default": "./dist/esm/create.js" + }, + "require": { + "types": "./dist/commonjs/create.d.ts", + "default": "./dist/commonjs/create.js" + } + }, + "./r": { + "import": { + "types": "./dist/esm/create.d.ts", + "default": "./dist/esm/create.js" + }, + "require": { + "types": "./dist/commonjs/create.d.ts", + "default": "./dist/commonjs/create.js" + } + }, + "./list": { + "import": { + "types": "./dist/esm/list.d.ts", + "default": "./dist/esm/list.js" + }, + "require": { + "types": "./dist/commonjs/list.d.ts", + "default": "./dist/commonjs/list.js" + } + }, + "./t": { + "import": { + "types": "./dist/esm/list.d.ts", + "default": "./dist/esm/list.js" + }, + "require": { + "types": "./dist/commonjs/list.d.ts", + "default": "./dist/commonjs/list.js" + } + }, + "./update": { + "import": { + "types": "./dist/esm/update.d.ts", + "default": "./dist/esm/update.js" + }, + "require": { + "types": "./dist/commonjs/update.d.ts", + "default": "./dist/commonjs/update.js" + } + }, + "./u": { + "import": { + "types": "./dist/esm/update.d.ts", + "default": "./dist/esm/update.js" + }, + "require": { + "types": "./dist/commonjs/update.d.ts", + "default": "./dist/commonjs/update.js" + } + }, + "./extract": { + "import": { + "types": "./dist/esm/extract.d.ts", + "default": "./dist/esm/extract.js" + }, + "require": { + "types": "./dist/commonjs/extract.d.ts", + "default": "./dist/commonjs/extract.js" + } + }, + "./x": { + "import": { + "types": "./dist/esm/extract.d.ts", + "default": "./dist/esm/extract.js" + }, + "require": { + "types": "./dist/commonjs/extract.d.ts", + "default": "./dist/commonjs/extract.js" + } + }, + "./pack": { + "import": { + "types": "./dist/esm/pack.d.ts", + "default": "./dist/esm/pack.js" + }, + "require": { + "types": "./dist/commonjs/pack.d.ts", + "default": "./dist/commonjs/pack.js" + } + }, + "./unpack": { + "import": { + "types": "./dist/esm/unpack.d.ts", + "default": "./dist/esm/unpack.js" + }, + "require": { + "types": "./dist/commonjs/unpack.d.ts", + "default": "./dist/commonjs/unpack.js" + } + }, + "./parse": { + "import": { + "types": "./dist/esm/parse.d.ts", + "default": "./dist/esm/parse.js" + }, + "require": { + "types": "./dist/commonjs/parse.d.ts", + "default": "./dist/commonjs/parse.js" + } + }, + "./read-entry": { + "import": { + "types": "./dist/esm/read-entry.d.ts", + "default": "./dist/esm/read-entry.js" + }, + "require": { + "types": "./dist/commonjs/read-entry.d.ts", + "default": "./dist/commonjs/read-entry.js" + } + }, + "./write-entry": { + "import": { + "types": "./dist/esm/write-entry.d.ts", + "default": "./dist/esm/write-entry.js" + }, + "require": { + "types": "./dist/commonjs/write-entry.d.ts", + "default": "./dist/commonjs/write-entry.js" + } + }, + "./header": { + "import": { + "types": "./dist/esm/header.d.ts", + "default": "./dist/esm/header.js" + }, + "require": { + "types": "./dist/commonjs/header.d.ts", + "default": "./dist/commonjs/header.js" + } + }, + "./pax": { + "import": { + "types": "./dist/esm/pax.d.ts", + "default": "./dist/esm/pax.js" + }, + "require": { + "types": "./dist/commonjs/pax.d.ts", + "default": "./dist/commonjs/pax.js" + } + }, + "./types": { + "import": { + "types": "./dist/esm/types.d.ts", + "default": "./dist/esm/types.js" + }, + "require": { + "types": "./dist/commonjs/types.d.ts", + "default": "./dist/commonjs/types.js" + } + } + }, + "type": "module", + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" } diff --git a/node_modules/text-table/readme.markdown b/node_modules/text-table/readme.markdown deleted file mode 100644 index 18806acd9efbe..0000000000000 --- a/node_modules/text-table/readme.markdown +++ /dev/null @@ -1,134 +0,0 @@ -# text-table - -generate borderless text table strings suitable for printing to stdout - -[![build status](https://secure.travis-ci.org/substack/text-table.png)](http://travis-ci.org/substack/text-table) - -[![browser support](https://ci.testling.com/substack/text-table.png)](http://ci.testling.com/substack/text-table) - -# example - -## default align - -``` js -var table = require('text-table'); -var t = table([ - [ 'master', '0123456789abcdef' ], - [ 'staging', 'fedcba9876543210' ] -]); -console.log(t); -``` - -``` -master 0123456789abcdef -staging fedcba9876543210 -``` - -## left-right align - -``` js -var table = require('text-table'); -var t = table([ - [ 'beep', '1024' ], - [ 'boop', '33450' ], - [ 'foo', '1006' ], - [ 'bar', '45' ] -], { align: [ 'l', 'r' ] }); -console.log(t); -``` - -``` -beep 1024 -boop 33450 -foo 1006 -bar 45 -``` - -## dotted align - -``` js -var table = require('text-table'); -var t = table([ - [ 'beep', '1024' ], - [ 'boop', '334.212' ], - [ 'foo', '1006' ], - [ 'bar', '45.6' ], - [ 'baz', '123.' ] -], { align: [ 'l', '.' ] }); -console.log(t); -``` - -``` -beep 1024 -boop 334.212 -foo 1006 -bar 45.6 -baz 123. -``` - -## centered - -``` js -var table = require('text-table'); -var t = table([ - [ 'beep', '1024', 'xyz' ], - [ 'boop', '3388450', 'tuv' ], - [ 'foo', '10106', 'qrstuv' ], - [ 'bar', '45', 'lmno' ] -], { align: [ 'l', 'c', 'l' ] }); -console.log(t); -``` - -``` -beep 1024 xyz -boop 3388450 tuv -foo 10106 qrstuv -bar 45 lmno -``` - -# methods - -``` js -var table = require('text-table') -``` - -## var s = table(rows, opts={}) - -Return a formatted table string `s` from an array of `rows` and some options -`opts`. - -`rows` should be an array of arrays containing strings, numbers, or other -printable values. - -options can be: - -* `opts.hsep` - separator to use between columns, default `' '` -* `opts.align` - array of alignment types for each column, default `['l','l',...]` -* `opts.stringLength` - callback function to use when calculating the string length - -alignment types are: - -* `'l'` - left -* `'r'` - right -* `'c'` - center -* `'.'` - decimal - -# install - -With [npm](https://npmjs.org) do: - -``` -npm install text-table -``` - -# Use with ANSI-colors - -Since the string length of ANSI color schemes does not equal the length -JavaScript sees internally it is necessary to pass the a custom string length -calculator during the main function call. - -See the `test/ansi-colors.js` file for an example. - -# license - -MIT diff --git a/node_modules/tiny-relative-date/lib/factory.js b/node_modules/tiny-relative-date/lib/factory.js index ac901614457c9..bde0b693690f9 100644 --- a/node_modules/tiny-relative-date/lib/factory.js +++ b/node_modules/tiny-relative-date/lib/factory.js @@ -32,7 +32,7 @@ function relativeDateFactory(translations) { delta = calculateDelta(now, date); } - var translate = function translate(translatePhrase, timeValue) { + var translate = function translate(translatePhrase, timeValue, rawValue) { var key = void 0; if (translatePhrase === 'justNow') { @@ -46,7 +46,7 @@ function relativeDateFactory(translations) { var translation = translations[key]; if (typeof translation === 'function') { - return translation(timeValue); + return translation(timeValue, rawValue); } return translation.replace('{{time}}', timeValue); @@ -54,46 +54,46 @@ function relativeDateFactory(translations) { switch (false) { case !(delta < 30): - return translate('justNow'); + return translate('justNow', delta, delta); case !(delta < minute): - return translate('seconds', delta); + return translate('seconds', delta, delta); case !(delta < 2 * minute): - return translate('aMinute'); + return translate('aMinute', 1, delta); case !(delta < hour): - return translate('minutes', Math.floor(delta / minute)); + return translate('minutes', Math.floor(delta / minute), delta); case Math.floor(delta / hour) !== 1: - return translate('anHour'); + return translate('anHour', Math.floor(delta / minute), delta); case !(delta < day): - return translate('hours', Math.floor(delta / hour)); + return translate('hours', Math.floor(delta / hour), delta); case !(delta < day * 2): - return translate('aDay'); + return translate('aDay', 1, delta); case !(delta < week): - return translate('days', Math.floor(delta / day)); + return translate('days', Math.floor(delta / day), delta); case Math.floor(delta / week) !== 1: - return translate('aWeek'); + return translate('aWeek', 1, delta); case !(delta < month): - return translate('weeks', Math.floor(delta / week)); + return translate('weeks', Math.floor(delta / week), delta); case Math.floor(delta / month) !== 1: - return translate('aMonth'); + return translate('aMonth', 1, delta); case !(delta < year): - return translate('months', Math.floor(delta / month)); + return translate('months', Math.floor(delta / month), delta); case Math.floor(delta / year) !== 1: - return translate('aYear'); + return translate('aYear', 1, delta); default: - return translate('overAYear'); + return translate('overAYear', Math.floor(delta / year), delta); } }; } diff --git a/node_modules/tiny-relative-date/package.json b/node_modules/tiny-relative-date/package.json index 26c88147f9e69..deb0cea29a4bd 100644 --- a/node_modules/tiny-relative-date/package.json +++ b/node_modules/tiny-relative-date/package.json @@ -1,14 +1,14 @@ { "name": "tiny-relative-date", - "version": "1.3.0", + "version": "2.0.2", "description": "Tiny function that provides relative, human-readable dates.", "main": "lib/index.js", "module": "src/index.js", "scripts": { - "build": "babel src -d lib", + "build": "babel src -d lib && cp src/*.d.ts lib/", "test": "npm run eslint && npm run jasmine", - "eslint": "eslint --fix src/**/*.js", - "jasmine": "jasmine", + "eslint": "eslint --fix src/**/*.js spec/*.js", + "jasmine": "TZ=UTC jasmine", "prepublish": "npm run build" }, "files": [ @@ -23,17 +23,17 @@ "url": "https://github.com/wildlyinaccurate/relative-date.git" }, "devDependencies": { - "babel-cli": "^6.24.1", + "babel-cli": "^6.26.0", "babel-plugin-add-module-exports": "^0.2.1", "babel-preset-es2015": "^6.24.1", - "babel-register": "^6.24.1", - "eslint": "^4.1.0", - "eslint-config-standard": "^10.2.1", - "eslint-plugin-import": "^2.6.0", - "eslint-plugin-node": "^5.0.0", - "eslint-plugin-promise": "^3.5.0", + "babel-register": "^6.26.0", + "eslint": "^4.19.1", + "eslint-config-standard": "^11.0.0", + "eslint-plugin-import": "^2.11.0", + "eslint-plugin-node": "^6.0.1", + "eslint-plugin-promise": "^3.7.0", "eslint-plugin-standard": "^3.0.1", - "jasmine": "^2.6.0", - "jasmine-spec-reporter": "^4.1.1" + "jasmine": "^3.1.0", + "jasmine-spec-reporter": "^4.2.1" } } diff --git a/node_modules/tiny-relative-date/src/factory.js b/node_modules/tiny-relative-date/src/factory.js index 689359bcf9bc9..65d310c9444a0 100644 --- a/node_modules/tiny-relative-date/src/factory.js +++ b/node_modules/tiny-relative-date/src/factory.js @@ -1,89 +1,112 @@ const calculateDelta = (now, date) => Math.round(Math.abs(now - date) / 1000) +const minute = 60 +const hour = minute * 60 +const day = hour * 24 +const week = day * 7 +const month = day * 30 +const year = day * 365 + export default function relativeDateFactory (translations) { - return function relativeDate (date, now = new Date()) { - if (!(date instanceof Date)) { - date = new Date(date) + const translate = (date, now, translatePhrase, timeValue, rawValue) => { + let key + + if (translatePhrase === 'justNow') { + key = translatePhrase + } else if (now >= date) { + key = `${translatePhrase}Ago` + } else { + key = `${translatePhrase}FromNow` } - let delta = null + const translation = translations[key] - const minute = 60 - const hour = minute * 60 - const day = hour * 24 - const week = day * 7 - const month = day * 30 - const year = day * 365 - - delta = calculateDelta(now, date) - - if (delta > day && delta < week) { - date = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0) - delta = calculateDelta(now, date) + if (typeof translation === 'function') { + return translation(timeValue, rawValue) } - const translate = (translatePhrase, timeValue) => { - let key - - if (translatePhrase === 'justNow') { - key = translatePhrase - } else if (now >= date) { - key = `${translatePhrase}Ago` - } else { - key = `${translatePhrase}FromNow` - } + return translation.replace('{{time}}', timeValue) + } - const translation = translations[key] + return function relativeDate (date, now = new Date()) { + if (!(date instanceof Date)) { + date = new Date(date) + } - if (typeof translation === 'function') { - return translation(timeValue) - } + let delta = calculateDelta(now, date) - return translation.replace('{{time}}', timeValue) + if (delta > day && delta < week) { + date = new Date( + date.getFullYear(), + date.getMonth(), + date.getDate(), + 0, + 0, + 0 + ) + delta = calculateDelta(now, date) } switch (false) { case !(delta < 30): - return translate('justNow') + return translate(date, now, 'justNow', delta, delta) case !(delta < minute): - return translate('seconds', delta) + return translate(date, now, 'seconds', delta, delta) case !(delta < 2 * minute): - return translate('aMinute') + return translate(date, now, 'aMinute', 1, delta) case !(delta < hour): - return translate('minutes', Math.floor(delta / minute)) + return translate( + date, + now, + 'minutes', + Math.floor(delta / minute), + delta + ) case Math.floor(delta / hour) !== 1: - return translate('anHour') + return translate( + date, + now, + 'anHour', + Math.floor(delta / minute), + delta + ) case !(delta < day): - return translate('hours', Math.floor(delta / hour)) + return translate(date, now, 'hours', Math.floor(delta / hour), delta) case !(delta < day * 2): - return translate('aDay') + return translate(date, now, 'aDay', 1, delta) case !(delta < week): - return translate('days', Math.floor(delta / day)) + return translate(date, now, 'days', Math.floor(delta / day), delta) case Math.floor(delta / week) !== 1: - return translate('aWeek') + return translate(date, now, 'aWeek', 1, delta) case !(delta < month): - return translate('weeks', Math.floor(delta / week)) + return translate(date, now, 'weeks', Math.floor(delta / week), delta) case Math.floor(delta / month) !== 1: - return translate('aMonth') + return translate(date, now, 'aMonth', 1, delta) case !(delta < year): - return translate('months', Math.floor(delta / month)) + return translate(date, now, 'months', Math.floor(delta / month), delta) case Math.floor(delta / year) !== 1: - return translate('aYear') + return translate(date, now, 'aYear', 1, delta) default: - return translate('overAYear') + return translate( + date, + now, + 'overAYear', + Math.floor(delta / year), + delta + ) } } } diff --git a/node_modules/tiny-relative-date/translations/fa.js b/node_modules/tiny-relative-date/translations/fa.js new file mode 100644 index 0000000000000..2a92ba19bab95 --- /dev/null +++ b/node_modules/tiny-relative-date/translations/fa.js @@ -0,0 +1,31 @@ +module.exports = { + justNow: "اکنون", + secondsAgo: "{{time}} ثانیه قبل", + aMinuteAgo: "یک دقیقه قبل", + minutesAgo: "{{time}} دقیقه قبل", + anHourAgo: "یک ساعت قبل", + hoursAgo: "{{time}} ساعت قبل", + aDayAgo: "دیروز", + daysAgo: "{{time}} روز قبل", + aWeekAgo: "یک هفته قبل", + weeksAgo: "{{time}} هفته قبل", + aMonthAgo: "یک ماه قبل", + monthsAgo: "{{time}} ماه قبل", + aYearAgo: "یک سال قبل", + yearsAgo: "{{time}} سال قبل", + overAYearAgo: "بیش از یک سال قبل", + secondsFromNow: "{{time}} ثانیه بعد", + aMinuteFromNow: "یک دقیقه بعد", + minutesFromNow: "{{time}} دقیقه بعد", + anHourFromNow: "an hour from now", + hoursFromNow: "{{time}} ساعت بعد", + aDayFromNow: "فردا", + daysFromNow: "{{time}} روز بعد", + aWeekFromNow: "یک هفته بعد", + weeksFromNow: "{{time}} هفته بعد", + aMonthFromNow: "یک ماه بعد", + monthsFromNow: "{{time}} ماه بعد", + aYearFromNow: "یک سال بعد", + yearsFromNow: "{{time}} سال بعد", + overAYearFromNow: "بیش از یک سال بعد" +} diff --git a/node_modules/tiny-relative-date/translations/ne.js b/node_modules/tiny-relative-date/translations/ne.js new file mode 100644 index 0000000000000..331128ced0e9a --- /dev/null +++ b/node_modules/tiny-relative-date/translations/ne.js @@ -0,0 +1,31 @@ +module.exports = { + justNow: 'भर्खर', + secondsAgo: '{{time}} सेकेण्ड अघि', + aMinuteAgo: '१ मिनेट अघि', + minutesAgo: '{{time}} मिनेट अघि', + anHourAgo: '१ घण्टा अघि', + hoursAgo: '{{time}} घण्टा अघि', + aDayAgo: 'हिजो', + daysAgo: '{{time}} दिन अघि', + aWeekAgo: '१ हप्ता अघि', + weeksAgo: '{{time}} हप्ता अघि', + aMonthAgo: '१ महिना अघि', + monthsAgo: '{{time}} महिना अघि', + aYearAgo: '१ वर्ष अघि', + yearsAgo: '{{time}} वर्ष अघि', + overAYearAgo: '१ वर्षभन्दा धेरै', + secondsFromNow: 'अहिलेदेखि {{time}} सेकेण्ड', + aMinuteFromNow: 'अहिलेदेखि १ मिनेट', + minutesFromNow: 'अहिलेदेखि {{time}} मिनेट', + anHourFromNow: 'अहिलेदेखि १ घण्टा', + hoursFromNow: 'अहिलेदेखि {{time}} घण्टा', + aDayFromNow: 'भोलि', + daysFromNow: 'अहिलेदेखि {{time}} दिन', + aWeekFromNow: 'अहिलेदेखि १ हप्ता', + weeksFromNow: 'अहिलेदेखि {{time}} हप्ता', + aMonthFromNow: 'अहिलेदेखि १ महिना', + monthsFromNow: 'अहिलेदेखि {{time}} महिना', + aYearFromNow: 'अहिलेदेखि १ वर्ष', + yearsFromNow: 'अहिलेदेखि {{time}} वर्ष', + overAYearFromNow: 'अहिलेदेखि १ वर्ष भन्दा धेरै' +} diff --git a/node_modules/tinyglobby/LICENSE b/node_modules/tinyglobby/LICENSE new file mode 100644 index 0000000000000..8657364bb085e --- /dev/null +++ b/node_modules/tinyglobby/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Madeline Gurriarán + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/tinyglobby/dist/index.cjs b/node_modules/tinyglobby/dist/index.cjs new file mode 100644 index 0000000000000..e5cb03ccec9ac --- /dev/null +++ b/node_modules/tinyglobby/dist/index.cjs @@ -0,0 +1,350 @@ +//#region rolldown:runtime +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { + key = keys[i]; + if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { + get: ((k) => from[k]).bind(null, key), + enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable + }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { + value: mod, + enumerable: true +}) : target, mod)); + +//#endregion +let fs = require("fs"); +fs = __toESM(fs); +let path = require("path"); +path = __toESM(path); +let url = require("url"); +url = __toESM(url); +let fdir = require("fdir"); +fdir = __toESM(fdir); +let picomatch = require("picomatch"); +picomatch = __toESM(picomatch); + +//#region src/utils.ts +const isReadonlyArray = Array.isArray; +const isWin = process.platform === "win32"; +const ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/; +function getPartialMatcher(patterns, options = {}) { + const patternsCount = patterns.length; + const patternsParts = Array(patternsCount); + const matchers = Array(patternsCount); + const globstarEnabled = !options.noglobstar; + for (let i = 0; i < patternsCount; i++) { + const parts = splitPattern(patterns[i]); + patternsParts[i] = parts; + const partsCount = parts.length; + const partMatchers = Array(partsCount); + for (let j = 0; j < partsCount; j++) partMatchers[j] = (0, picomatch.default)(parts[j], options); + matchers[i] = partMatchers; + } + return (input) => { + const inputParts = input.split("/"); + if (inputParts[0] === ".." && ONLY_PARENT_DIRECTORIES.test(input)) return true; + for (let i = 0; i < patterns.length; i++) { + const patternParts = patternsParts[i]; + const matcher = matchers[i]; + const inputPatternCount = inputParts.length; + const minParts = Math.min(inputPatternCount, patternParts.length); + let j = 0; + while (j < minParts) { + const part = patternParts[j]; + if (part.includes("/")) return true; + const match = matcher[j](inputParts[j]); + if (!match) break; + if (globstarEnabled && part === "**") return true; + j++; + } + if (j === inputPatternCount) return true; + } + return false; + }; +} +/* node:coverage ignore next 2 */ +const WIN32_ROOT_DIR = /^[A-Z]:\/$/i; +const isRoot = isWin ? (p) => WIN32_ROOT_DIR.test(p) : (p) => p === "/"; +function buildFormat(cwd, root, absolute) { + if (cwd === root || root.startsWith(`${cwd}/`)) { + if (absolute) { + const start = isRoot(cwd) ? cwd.length : cwd.length + 1; + return (p, isDir) => p.slice(start, isDir ? -1 : void 0) || "."; + } + const prefix = root.slice(cwd.length + 1); + if (prefix) return (p, isDir) => { + if (p === ".") return prefix; + const result = `${prefix}/${p}`; + return isDir ? result.slice(0, -1) : result; + }; + return (p, isDir) => isDir && p !== "." ? p.slice(0, -1) : p; + } + if (absolute) return (p) => path.posix.relative(cwd, p) || "."; + return (p) => path.posix.relative(cwd, `${root}/${p}`) || "."; +} +function buildRelative(cwd, root) { + if (root.startsWith(`${cwd}/`)) { + const prefix = root.slice(cwd.length + 1); + return (p) => `${prefix}/${p}`; + } + return (p) => { + const result = path.posix.relative(cwd, `${root}/${p}`); + if (p.endsWith("/") && result !== "") return `${result}/`; + return result || "."; + }; +} +const splitPatternOptions = { parts: true }; +function splitPattern(path$2) { + var _result$parts; + const result = picomatch.default.scan(path$2, splitPatternOptions); + return ((_result$parts = result.parts) === null || _result$parts === void 0 ? void 0 : _result$parts.length) ? result.parts : [path$2]; +} +const ESCAPED_WIN32_BACKSLASHES = /\\(?![()[\]{}!+@])/g; +function convertPosixPathToPattern(path$2) { + return escapePosixPath(path$2); +} +function convertWin32PathToPattern(path$2) { + return escapeWin32Path(path$2).replace(ESCAPED_WIN32_BACKSLASHES, "/"); +} +/** +* Converts a path to a pattern depending on the platform. +* Identical to {@link escapePath} on POSIX systems. +* @see {@link https://superchupu.dev/tinyglobby/documentation#convertPathToPattern} +*/ +/* node:coverage ignore next 3 */ +const convertPathToPattern = isWin ? convertWin32PathToPattern : convertPosixPathToPattern; +const POSIX_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}*?|]|^!|[!+@](?=\()|\\(?![()[\]{}!*+?@|]))/g; +const WIN32_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}]|^!|[!+@](?=\())/g; +const escapePosixPath = (path$2) => path$2.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"); +const escapeWin32Path = (path$2) => path$2.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"); +/** +* Escapes a path's special characters depending on the platform. +* @see {@link https://superchupu.dev/tinyglobby/documentation#escapePath} +*/ +/* node:coverage ignore next */ +const escapePath = isWin ? escapeWin32Path : escapePosixPath; +/** +* Checks if a pattern has dynamic parts. +* +* Has a few minor differences with [`fast-glob`](https://github.com/mrmlnc/fast-glob) for better accuracy: +* +* - Doesn't necessarily return `false` on patterns that include `\`. +* - Returns `true` if the pattern includes parentheses, regardless of them representing one single pattern or not. +* - Returns `true` for unfinished glob extensions i.e. `(h`, `+(h`. +* - Returns `true` for unfinished brace expansions as long as they include `,` or `..`. +* +* @see {@link https://superchupu.dev/tinyglobby/documentation#isDynamicPattern} +*/ +function isDynamicPattern(pattern, options) { + if ((options === null || options === void 0 ? void 0 : options.caseSensitiveMatch) === false) return true; + const scan = picomatch.default.scan(pattern); + return scan.isGlob || scan.negated; +} +function log(...tasks) { + console.log(`[tinyglobby ${(/* @__PURE__ */ new Date()).toLocaleTimeString("es")}]`, ...tasks); +} + +//#endregion +//#region src/index.ts +const PARENT_DIRECTORY = /^(\/?\.\.)+/; +const ESCAPING_BACKSLASHES = /\\(?=[()[\]{}!*+?@|])/g; +const BACKSLASHES = /\\/g; +function normalizePattern(pattern, expandDirectories, cwd, props, isIgnore) { + let result = pattern; + if (pattern.endsWith("/")) result = pattern.slice(0, -1); + if (!result.endsWith("*") && expandDirectories) result += "/**"; + const escapedCwd = escapePath(cwd); + if (path.default.isAbsolute(result.replace(ESCAPING_BACKSLASHES, ""))) result = path.posix.relative(escapedCwd, result); + else result = path.posix.normalize(result); + const parentDirectoryMatch = PARENT_DIRECTORY.exec(result); + const parts = splitPattern(result); + if (parentDirectoryMatch === null || parentDirectoryMatch === void 0 ? void 0 : parentDirectoryMatch[0]) { + const n = (parentDirectoryMatch[0].length + 1) / 3; + let i = 0; + const cwdParts = escapedCwd.split("/"); + while (i < n && parts[i + n] === cwdParts[cwdParts.length + i - n]) { + result = result.slice(0, (n - i - 1) * 3) + result.slice((n - i) * 3 + parts[i + n].length + 1) || "."; + i++; + } + const potentialRoot = path.posix.join(cwd, parentDirectoryMatch[0].slice(i * 3)); + if (!potentialRoot.startsWith(".") && props.root.length > potentialRoot.length) { + props.root = potentialRoot; + props.depthOffset = -n + i; + } + } + if (!isIgnore && props.depthOffset >= 0) { + var _props$commonPath; + (_props$commonPath = props.commonPath) !== null && _props$commonPath !== void 0 || (props.commonPath = parts); + const newCommonPath = []; + const length = Math.min(props.commonPath.length, parts.length); + for (let i = 0; i < length; i++) { + const part = parts[i]; + if (part === "**" && !parts[i + 1]) { + newCommonPath.pop(); + break; + } + if (part !== props.commonPath[i] || isDynamicPattern(part) || i === parts.length - 1) break; + newCommonPath.push(part); + } + props.depthOffset = newCommonPath.length; + props.commonPath = newCommonPath; + props.root = newCommonPath.length > 0 ? path.posix.join(cwd, ...newCommonPath) : cwd; + } + return result; +} +function processPatterns({ patterns = ["**/*"], ignore = [], expandDirectories = true }, cwd, props) { + if (typeof patterns === "string") patterns = [patterns]; + if (typeof ignore === "string") ignore = [ignore]; + const matchPatterns = []; + const ignorePatterns = []; + for (const pattern of ignore) { + if (!pattern) continue; + if (pattern[0] !== "!" || pattern[1] === "(") ignorePatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, true)); + } + for (const pattern of patterns) { + if (!pattern) continue; + if (pattern[0] !== "!" || pattern[1] === "(") matchPatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, false)); + else if (pattern[1] !== "!" || pattern[2] === "(") ignorePatterns.push(normalizePattern(pattern.slice(1), expandDirectories, cwd, props, true)); + } + return { + match: matchPatterns, + ignore: ignorePatterns + }; +} +function formatPaths(paths, relative) { + for (let i = paths.length - 1; i >= 0; i--) { + const path$2 = paths[i]; + paths[i] = relative(path$2); + } + return paths; +} +function normalizeCwd(cwd) { + if (!cwd) return process.cwd().replace(BACKSLASHES, "/"); + if (cwd instanceof URL) return (0, url.fileURLToPath)(cwd).replace(BACKSLASHES, "/"); + return path.default.resolve(cwd).replace(BACKSLASHES, "/"); +} +function getCrawler(patterns, inputOptions = {}) { + const options = process.env.TINYGLOBBY_DEBUG ? { + ...inputOptions, + debug: true + } : inputOptions; + const cwd = normalizeCwd(options.cwd); + if (options.debug) log("globbing with:", { + patterns, + options, + cwd + }); + if (Array.isArray(patterns) && patterns.length === 0) return [{ + sync: () => [], + withPromise: async () => [] + }, false]; + const props = { + root: cwd, + commonPath: null, + depthOffset: 0 + }; + const processed = processPatterns({ + ...options, + patterns + }, cwd, props); + if (options.debug) log("internal processing patterns:", processed); + const matchOptions = { + dot: options.dot, + nobrace: options.braceExpansion === false, + nocase: options.caseSensitiveMatch === false, + noextglob: options.extglob === false, + noglobstar: options.globstar === false, + posix: true + }; + const matcher = (0, picomatch.default)(processed.match, { + ...matchOptions, + ignore: processed.ignore + }); + const ignore = (0, picomatch.default)(processed.ignore, matchOptions); + const partialMatcher = getPartialMatcher(processed.match, matchOptions); + const format = buildFormat(cwd, props.root, options.absolute); + const formatExclude = options.absolute ? format : buildFormat(cwd, props.root, true); + const fdirOptions = { + filters: [options.debug ? (p, isDirectory) => { + const path$2 = format(p, isDirectory); + const matches = matcher(path$2); + if (matches) log(`matched ${path$2}`); + return matches; + } : (p, isDirectory) => matcher(format(p, isDirectory))], + exclude: options.debug ? (_, p) => { + const relativePath = formatExclude(p, true); + const skipped = relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath); + if (skipped) log(`skipped ${p}`); + else log(`crawling ${p}`); + return skipped; + } : (_, p) => { + const relativePath = formatExclude(p, true); + return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath); + }, + fs: options.fs ? { + readdir: options.fs.readdir || fs.default.readdir, + readdirSync: options.fs.readdirSync || fs.default.readdirSync, + realpath: options.fs.realpath || fs.default.realpath, + realpathSync: options.fs.realpathSync || fs.default.realpathSync, + stat: options.fs.stat || fs.default.stat, + statSync: options.fs.statSync || fs.default.statSync + } : void 0, + pathSeparator: "/", + relativePaths: true, + resolveSymlinks: true, + signal: options.signal + }; + if (options.deep !== void 0) fdirOptions.maxDepth = Math.round(options.deep - props.depthOffset); + if (options.absolute) { + fdirOptions.relativePaths = false; + fdirOptions.resolvePaths = true; + fdirOptions.includeBasePath = true; + } + if (options.followSymbolicLinks === false) { + fdirOptions.resolveSymlinks = false; + fdirOptions.excludeSymlinks = true; + } + if (options.onlyDirectories) { + fdirOptions.excludeFiles = true; + fdirOptions.includeDirs = true; + } else if (options.onlyFiles === false) fdirOptions.includeDirs = true; + props.root = props.root.replace(BACKSLASHES, ""); + const root = props.root; + if (options.debug) log("internal properties:", props); + const relative = cwd !== root && !options.absolute && buildRelative(cwd, props.root); + return [new fdir.fdir(fdirOptions).crawl(root), relative]; +} +async function glob(patternsOrOptions, options) { + if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option"); + const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string"; + const opts = isModern ? options : patternsOrOptions; + const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns; + const [crawler, relative] = getCrawler(patterns, opts); + if (!relative) return crawler.withPromise(); + return formatPaths(await crawler.withPromise(), relative); +} +function globSync(patternsOrOptions, options) { + if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option"); + const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string"; + const opts = isModern ? options : patternsOrOptions; + const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns; + const [crawler, relative] = getCrawler(patterns, opts); + if (!relative) return crawler.sync(); + return formatPaths(crawler.sync(), relative); +} + +//#endregion +exports.convertPathToPattern = convertPathToPattern; +exports.escapePath = escapePath; +exports.glob = glob; +exports.globSync = globSync; +exports.isDynamicPattern = isDynamicPattern; \ No newline at end of file diff --git a/node_modules/tinyglobby/dist/index.d.cts b/node_modules/tinyglobby/dist/index.d.cts new file mode 100644 index 0000000000000..9d67dae260a76 --- /dev/null +++ b/node_modules/tinyglobby/dist/index.d.cts @@ -0,0 +1,147 @@ +import { FSLike } from "fdir"; + +//#region src/utils.d.ts + +/** +* Converts a path to a pattern depending on the platform. +* Identical to {@link escapePath} on POSIX systems. +* @see {@link https://superchupu.dev/tinyglobby/documentation#convertPathToPattern} +*/ +declare const convertPathToPattern: (path: string) => string; +/** +* Escapes a path's special characters depending on the platform. +* @see {@link https://superchupu.dev/tinyglobby/documentation#escapePath} +*/ +declare const escapePath: (path: string) => string; +/** +* Checks if a pattern has dynamic parts. +* +* Has a few minor differences with [`fast-glob`](https://github.com/mrmlnc/fast-glob) for better accuracy: +* +* - Doesn't necessarily return `false` on patterns that include `\`. +* - Returns `true` if the pattern includes parentheses, regardless of them representing one single pattern or not. +* - Returns `true` for unfinished glob extensions i.e. `(h`, `+(h`. +* - Returns `true` for unfinished brace expansions as long as they include `,` or `..`. +* +* @see {@link https://superchupu.dev/tinyglobby/documentation#isDynamicPattern} +*/ +declare function isDynamicPattern(pattern: string, options?: { + caseSensitiveMatch: boolean; +}): boolean; +//#endregion +//#region src/index.d.ts +interface GlobOptions { + /** + * Whether to return absolute paths. Disable to have relative paths. + * @default false + */ + absolute?: boolean; + /** + * Enables support for brace expansion syntax, like `{a,b}` or `{1..9}`. + * @default true + */ + braceExpansion?: boolean; + /** + * Whether to match in case-sensitive mode. + * @default true + */ + caseSensitiveMatch?: boolean; + /** + * The working directory in which to search. Results will be returned relative to this directory, unless + * {@link absolute} is set. + * + * It is important to avoid globbing outside this directory when possible, even with absolute paths enabled, + * as doing so can harm performance due to having to recalculate relative paths. + * @default process.cwd() + */ + cwd?: string | URL; + /** + * Logs useful debug information. Meant for development purposes. Logs can change at any time. + * @default false + */ + debug?: boolean; + /** + * Maximum directory depth to crawl. + * @default Infinity + */ + deep?: number; + /** + * Whether to return entries that start with a dot, like `.gitignore` or `.prettierrc`. + * @default false + */ + dot?: boolean; + /** + * Whether to automatically expand directory patterns. + * + * Important to disable if migrating from [`fast-glob`](https://github.com/mrmlnc/fast-glob). + * @default true + */ + expandDirectories?: boolean; + /** + * Enables support for extglobs, like `+(pattern)`. + * @default true + */ + extglob?: boolean; + /** + * Whether to traverse and include symbolic links. Can slightly affect performance. + * @default true + */ + followSymbolicLinks?: boolean; + /** + * An object that overrides `node:fs` functions. + * @default import('node:fs') + */ + fs?: FileSystemAdapter; + /** + * Enables support for matching nested directories with globstars (`**`). + * If `false`, `**` behaves exactly like `*`. + * @default true + */ + globstar?: boolean; + /** + * Glob patterns to exclude from the results. + * @default [] + */ + ignore?: string | readonly string[]; + /** + * Enable to only return directories. + * If `true`, disables {@link onlyFiles}. + * @default false + */ + onlyDirectories?: boolean; + /** + * Enable to only return files. + * @default true + */ + onlyFiles?: boolean; + /** + * @deprecated Provide patterns as the first argument instead. + */ + patterns?: string | readonly string[]; + /** + * An `AbortSignal` to abort crawling the file system. + * @default undefined + */ + signal?: AbortSignal; +} +type FileSystemAdapter = Partial<FSLike>; +/** +* Asynchronously match files following a glob pattern. +* @see {@link https://superchupu.dev/tinyglobby/documentation#glob} +*/ +declare function glob(patterns: string | readonly string[], options?: Omit<GlobOptions, "patterns">): Promise<string[]>; +/** +* @deprecated Provide patterns as the first argument instead. +*/ +declare function glob(options: GlobOptions): Promise<string[]>; +/** +* Synchronously match files following a glob pattern. +* @see {@link https://superchupu.dev/tinyglobby/documentation#globSync} +*/ +declare function globSync(patterns: string | readonly string[], options?: Omit<GlobOptions, "patterns">): string[]; +/** +* @deprecated Provide patterns as the first argument instead. +*/ +declare function globSync(options: GlobOptions): string[]; +//#endregion +export { FileSystemAdapter, GlobOptions, convertPathToPattern, escapePath, glob, globSync, isDynamicPattern }; \ No newline at end of file diff --git a/node_modules/tinyglobby/dist/index.d.mts b/node_modules/tinyglobby/dist/index.d.mts new file mode 100644 index 0000000000000..9d67dae260a76 --- /dev/null +++ b/node_modules/tinyglobby/dist/index.d.mts @@ -0,0 +1,147 @@ +import { FSLike } from "fdir"; + +//#region src/utils.d.ts + +/** +* Converts a path to a pattern depending on the platform. +* Identical to {@link escapePath} on POSIX systems. +* @see {@link https://superchupu.dev/tinyglobby/documentation#convertPathToPattern} +*/ +declare const convertPathToPattern: (path: string) => string; +/** +* Escapes a path's special characters depending on the platform. +* @see {@link https://superchupu.dev/tinyglobby/documentation#escapePath} +*/ +declare const escapePath: (path: string) => string; +/** +* Checks if a pattern has dynamic parts. +* +* Has a few minor differences with [`fast-glob`](https://github.com/mrmlnc/fast-glob) for better accuracy: +* +* - Doesn't necessarily return `false` on patterns that include `\`. +* - Returns `true` if the pattern includes parentheses, regardless of them representing one single pattern or not. +* - Returns `true` for unfinished glob extensions i.e. `(h`, `+(h`. +* - Returns `true` for unfinished brace expansions as long as they include `,` or `..`. +* +* @see {@link https://superchupu.dev/tinyglobby/documentation#isDynamicPattern} +*/ +declare function isDynamicPattern(pattern: string, options?: { + caseSensitiveMatch: boolean; +}): boolean; +//#endregion +//#region src/index.d.ts +interface GlobOptions { + /** + * Whether to return absolute paths. Disable to have relative paths. + * @default false + */ + absolute?: boolean; + /** + * Enables support for brace expansion syntax, like `{a,b}` or `{1..9}`. + * @default true + */ + braceExpansion?: boolean; + /** + * Whether to match in case-sensitive mode. + * @default true + */ + caseSensitiveMatch?: boolean; + /** + * The working directory in which to search. Results will be returned relative to this directory, unless + * {@link absolute} is set. + * + * It is important to avoid globbing outside this directory when possible, even with absolute paths enabled, + * as doing so can harm performance due to having to recalculate relative paths. + * @default process.cwd() + */ + cwd?: string | URL; + /** + * Logs useful debug information. Meant for development purposes. Logs can change at any time. + * @default false + */ + debug?: boolean; + /** + * Maximum directory depth to crawl. + * @default Infinity + */ + deep?: number; + /** + * Whether to return entries that start with a dot, like `.gitignore` or `.prettierrc`. + * @default false + */ + dot?: boolean; + /** + * Whether to automatically expand directory patterns. + * + * Important to disable if migrating from [`fast-glob`](https://github.com/mrmlnc/fast-glob). + * @default true + */ + expandDirectories?: boolean; + /** + * Enables support for extglobs, like `+(pattern)`. + * @default true + */ + extglob?: boolean; + /** + * Whether to traverse and include symbolic links. Can slightly affect performance. + * @default true + */ + followSymbolicLinks?: boolean; + /** + * An object that overrides `node:fs` functions. + * @default import('node:fs') + */ + fs?: FileSystemAdapter; + /** + * Enables support for matching nested directories with globstars (`**`). + * If `false`, `**` behaves exactly like `*`. + * @default true + */ + globstar?: boolean; + /** + * Glob patterns to exclude from the results. + * @default [] + */ + ignore?: string | readonly string[]; + /** + * Enable to only return directories. + * If `true`, disables {@link onlyFiles}. + * @default false + */ + onlyDirectories?: boolean; + /** + * Enable to only return files. + * @default true + */ + onlyFiles?: boolean; + /** + * @deprecated Provide patterns as the first argument instead. + */ + patterns?: string | readonly string[]; + /** + * An `AbortSignal` to abort crawling the file system. + * @default undefined + */ + signal?: AbortSignal; +} +type FileSystemAdapter = Partial<FSLike>; +/** +* Asynchronously match files following a glob pattern. +* @see {@link https://superchupu.dev/tinyglobby/documentation#glob} +*/ +declare function glob(patterns: string | readonly string[], options?: Omit<GlobOptions, "patterns">): Promise<string[]>; +/** +* @deprecated Provide patterns as the first argument instead. +*/ +declare function glob(options: GlobOptions): Promise<string[]>; +/** +* Synchronously match files following a glob pattern. +* @see {@link https://superchupu.dev/tinyglobby/documentation#globSync} +*/ +declare function globSync(patterns: string | readonly string[], options?: Omit<GlobOptions, "patterns">): string[]; +/** +* @deprecated Provide patterns as the first argument instead. +*/ +declare function globSync(options: GlobOptions): string[]; +//#endregion +export { FileSystemAdapter, GlobOptions, convertPathToPattern, escapePath, glob, globSync, isDynamicPattern }; \ No newline at end of file diff --git a/node_modules/tinyglobby/dist/index.mjs b/node_modules/tinyglobby/dist/index.mjs new file mode 100644 index 0000000000000..4f41787d8bc4b --- /dev/null +++ b/node_modules/tinyglobby/dist/index.mjs @@ -0,0 +1,318 @@ +import nativeFs from "fs"; +import path, { posix } from "path"; +import { fileURLToPath } from "url"; +import { fdir } from "fdir"; +import picomatch from "picomatch"; + +//#region src/utils.ts +const isReadonlyArray = Array.isArray; +const isWin = process.platform === "win32"; +const ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/; +function getPartialMatcher(patterns, options = {}) { + const patternsCount = patterns.length; + const patternsParts = Array(patternsCount); + const matchers = Array(patternsCount); + const globstarEnabled = !options.noglobstar; + for (let i = 0; i < patternsCount; i++) { + const parts = splitPattern(patterns[i]); + patternsParts[i] = parts; + const partsCount = parts.length; + const partMatchers = Array(partsCount); + for (let j = 0; j < partsCount; j++) partMatchers[j] = picomatch(parts[j], options); + matchers[i] = partMatchers; + } + return (input) => { + const inputParts = input.split("/"); + if (inputParts[0] === ".." && ONLY_PARENT_DIRECTORIES.test(input)) return true; + for (let i = 0; i < patterns.length; i++) { + const patternParts = patternsParts[i]; + const matcher = matchers[i]; + const inputPatternCount = inputParts.length; + const minParts = Math.min(inputPatternCount, patternParts.length); + let j = 0; + while (j < minParts) { + const part = patternParts[j]; + if (part.includes("/")) return true; + const match = matcher[j](inputParts[j]); + if (!match) break; + if (globstarEnabled && part === "**") return true; + j++; + } + if (j === inputPatternCount) return true; + } + return false; + }; +} +/* node:coverage ignore next 2 */ +const WIN32_ROOT_DIR = /^[A-Z]:\/$/i; +const isRoot = isWin ? (p) => WIN32_ROOT_DIR.test(p) : (p) => p === "/"; +function buildFormat(cwd, root, absolute) { + if (cwd === root || root.startsWith(`${cwd}/`)) { + if (absolute) { + const start = isRoot(cwd) ? cwd.length : cwd.length + 1; + return (p, isDir) => p.slice(start, isDir ? -1 : void 0) || "."; + } + const prefix = root.slice(cwd.length + 1); + if (prefix) return (p, isDir) => { + if (p === ".") return prefix; + const result = `${prefix}/${p}`; + return isDir ? result.slice(0, -1) : result; + }; + return (p, isDir) => isDir && p !== "." ? p.slice(0, -1) : p; + } + if (absolute) return (p) => posix.relative(cwd, p) || "."; + return (p) => posix.relative(cwd, `${root}/${p}`) || "."; +} +function buildRelative(cwd, root) { + if (root.startsWith(`${cwd}/`)) { + const prefix = root.slice(cwd.length + 1); + return (p) => `${prefix}/${p}`; + } + return (p) => { + const result = posix.relative(cwd, `${root}/${p}`); + if (p.endsWith("/") && result !== "") return `${result}/`; + return result || "."; + }; +} +const splitPatternOptions = { parts: true }; +function splitPattern(path$1) { + var _result$parts; + const result = picomatch.scan(path$1, splitPatternOptions); + return ((_result$parts = result.parts) === null || _result$parts === void 0 ? void 0 : _result$parts.length) ? result.parts : [path$1]; +} +const ESCAPED_WIN32_BACKSLASHES = /\\(?![()[\]{}!+@])/g; +function convertPosixPathToPattern(path$1) { + return escapePosixPath(path$1); +} +function convertWin32PathToPattern(path$1) { + return escapeWin32Path(path$1).replace(ESCAPED_WIN32_BACKSLASHES, "/"); +} +/** +* Converts a path to a pattern depending on the platform. +* Identical to {@link escapePath} on POSIX systems. +* @see {@link https://superchupu.dev/tinyglobby/documentation#convertPathToPattern} +*/ +/* node:coverage ignore next 3 */ +const convertPathToPattern = isWin ? convertWin32PathToPattern : convertPosixPathToPattern; +const POSIX_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}*?|]|^!|[!+@](?=\()|\\(?![()[\]{}!*+?@|]))/g; +const WIN32_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}]|^!|[!+@](?=\())/g; +const escapePosixPath = (path$1) => path$1.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"); +const escapeWin32Path = (path$1) => path$1.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"); +/** +* Escapes a path's special characters depending on the platform. +* @see {@link https://superchupu.dev/tinyglobby/documentation#escapePath} +*/ +/* node:coverage ignore next */ +const escapePath = isWin ? escapeWin32Path : escapePosixPath; +/** +* Checks if a pattern has dynamic parts. +* +* Has a few minor differences with [`fast-glob`](https://github.com/mrmlnc/fast-glob) for better accuracy: +* +* - Doesn't necessarily return `false` on patterns that include `\`. +* - Returns `true` if the pattern includes parentheses, regardless of them representing one single pattern or not. +* - Returns `true` for unfinished glob extensions i.e. `(h`, `+(h`. +* - Returns `true` for unfinished brace expansions as long as they include `,` or `..`. +* +* @see {@link https://superchupu.dev/tinyglobby/documentation#isDynamicPattern} +*/ +function isDynamicPattern(pattern, options) { + if ((options === null || options === void 0 ? void 0 : options.caseSensitiveMatch) === false) return true; + const scan = picomatch.scan(pattern); + return scan.isGlob || scan.negated; +} +function log(...tasks) { + console.log(`[tinyglobby ${(/* @__PURE__ */ new Date()).toLocaleTimeString("es")}]`, ...tasks); +} + +//#endregion +//#region src/index.ts +const PARENT_DIRECTORY = /^(\/?\.\.)+/; +const ESCAPING_BACKSLASHES = /\\(?=[()[\]{}!*+?@|])/g; +const BACKSLASHES = /\\/g; +function normalizePattern(pattern, expandDirectories, cwd, props, isIgnore) { + let result = pattern; + if (pattern.endsWith("/")) result = pattern.slice(0, -1); + if (!result.endsWith("*") && expandDirectories) result += "/**"; + const escapedCwd = escapePath(cwd); + if (path.isAbsolute(result.replace(ESCAPING_BACKSLASHES, ""))) result = posix.relative(escapedCwd, result); + else result = posix.normalize(result); + const parentDirectoryMatch = PARENT_DIRECTORY.exec(result); + const parts = splitPattern(result); + if (parentDirectoryMatch === null || parentDirectoryMatch === void 0 ? void 0 : parentDirectoryMatch[0]) { + const n = (parentDirectoryMatch[0].length + 1) / 3; + let i = 0; + const cwdParts = escapedCwd.split("/"); + while (i < n && parts[i + n] === cwdParts[cwdParts.length + i - n]) { + result = result.slice(0, (n - i - 1) * 3) + result.slice((n - i) * 3 + parts[i + n].length + 1) || "."; + i++; + } + const potentialRoot = posix.join(cwd, parentDirectoryMatch[0].slice(i * 3)); + if (!potentialRoot.startsWith(".") && props.root.length > potentialRoot.length) { + props.root = potentialRoot; + props.depthOffset = -n + i; + } + } + if (!isIgnore && props.depthOffset >= 0) { + var _props$commonPath; + (_props$commonPath = props.commonPath) !== null && _props$commonPath !== void 0 || (props.commonPath = parts); + const newCommonPath = []; + const length = Math.min(props.commonPath.length, parts.length); + for (let i = 0; i < length; i++) { + const part = parts[i]; + if (part === "**" && !parts[i + 1]) { + newCommonPath.pop(); + break; + } + if (part !== props.commonPath[i] || isDynamicPattern(part) || i === parts.length - 1) break; + newCommonPath.push(part); + } + props.depthOffset = newCommonPath.length; + props.commonPath = newCommonPath; + props.root = newCommonPath.length > 0 ? posix.join(cwd, ...newCommonPath) : cwd; + } + return result; +} +function processPatterns({ patterns = ["**/*"], ignore = [], expandDirectories = true }, cwd, props) { + if (typeof patterns === "string") patterns = [patterns]; + if (typeof ignore === "string") ignore = [ignore]; + const matchPatterns = []; + const ignorePatterns = []; + for (const pattern of ignore) { + if (!pattern) continue; + if (pattern[0] !== "!" || pattern[1] === "(") ignorePatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, true)); + } + for (const pattern of patterns) { + if (!pattern) continue; + if (pattern[0] !== "!" || pattern[1] === "(") matchPatterns.push(normalizePattern(pattern, expandDirectories, cwd, props, false)); + else if (pattern[1] !== "!" || pattern[2] === "(") ignorePatterns.push(normalizePattern(pattern.slice(1), expandDirectories, cwd, props, true)); + } + return { + match: matchPatterns, + ignore: ignorePatterns + }; +} +function formatPaths(paths, relative) { + for (let i = paths.length - 1; i >= 0; i--) { + const path$1 = paths[i]; + paths[i] = relative(path$1); + } + return paths; +} +function normalizeCwd(cwd) { + if (!cwd) return process.cwd().replace(BACKSLASHES, "/"); + if (cwd instanceof URL) return fileURLToPath(cwd).replace(BACKSLASHES, "/"); + return path.resolve(cwd).replace(BACKSLASHES, "/"); +} +function getCrawler(patterns, inputOptions = {}) { + const options = process.env.TINYGLOBBY_DEBUG ? { + ...inputOptions, + debug: true + } : inputOptions; + const cwd = normalizeCwd(options.cwd); + if (options.debug) log("globbing with:", { + patterns, + options, + cwd + }); + if (Array.isArray(patterns) && patterns.length === 0) return [{ + sync: () => [], + withPromise: async () => [] + }, false]; + const props = { + root: cwd, + commonPath: null, + depthOffset: 0 + }; + const processed = processPatterns({ + ...options, + patterns + }, cwd, props); + if (options.debug) log("internal processing patterns:", processed); + const matchOptions = { + dot: options.dot, + nobrace: options.braceExpansion === false, + nocase: options.caseSensitiveMatch === false, + noextglob: options.extglob === false, + noglobstar: options.globstar === false, + posix: true + }; + const matcher = picomatch(processed.match, { + ...matchOptions, + ignore: processed.ignore + }); + const ignore = picomatch(processed.ignore, matchOptions); + const partialMatcher = getPartialMatcher(processed.match, matchOptions); + const format = buildFormat(cwd, props.root, options.absolute); + const formatExclude = options.absolute ? format : buildFormat(cwd, props.root, true); + const fdirOptions = { + filters: [options.debug ? (p, isDirectory) => { + const path$1 = format(p, isDirectory); + const matches = matcher(path$1); + if (matches) log(`matched ${path$1}`); + return matches; + } : (p, isDirectory) => matcher(format(p, isDirectory))], + exclude: options.debug ? (_, p) => { + const relativePath = formatExclude(p, true); + const skipped = relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath); + if (skipped) log(`skipped ${p}`); + else log(`crawling ${p}`); + return skipped; + } : (_, p) => { + const relativePath = formatExclude(p, true); + return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath); + }, + fs: options.fs ? { + readdir: options.fs.readdir || nativeFs.readdir, + readdirSync: options.fs.readdirSync || nativeFs.readdirSync, + realpath: options.fs.realpath || nativeFs.realpath, + realpathSync: options.fs.realpathSync || nativeFs.realpathSync, + stat: options.fs.stat || nativeFs.stat, + statSync: options.fs.statSync || nativeFs.statSync + } : void 0, + pathSeparator: "/", + relativePaths: true, + resolveSymlinks: true, + signal: options.signal + }; + if (options.deep !== void 0) fdirOptions.maxDepth = Math.round(options.deep - props.depthOffset); + if (options.absolute) { + fdirOptions.relativePaths = false; + fdirOptions.resolvePaths = true; + fdirOptions.includeBasePath = true; + } + if (options.followSymbolicLinks === false) { + fdirOptions.resolveSymlinks = false; + fdirOptions.excludeSymlinks = true; + } + if (options.onlyDirectories) { + fdirOptions.excludeFiles = true; + fdirOptions.includeDirs = true; + } else if (options.onlyFiles === false) fdirOptions.includeDirs = true; + props.root = props.root.replace(BACKSLASHES, ""); + const root = props.root; + if (options.debug) log("internal properties:", props); + const relative = cwd !== root && !options.absolute && buildRelative(cwd, props.root); + return [new fdir(fdirOptions).crawl(root), relative]; +} +async function glob(patternsOrOptions, options) { + if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option"); + const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string"; + const opts = isModern ? options : patternsOrOptions; + const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns; + const [crawler, relative] = getCrawler(patterns, opts); + if (!relative) return crawler.withPromise(); + return formatPaths(await crawler.withPromise(), relative); +} +function globSync(patternsOrOptions, options) { + if (patternsOrOptions && (options === null || options === void 0 ? void 0 : options.patterns)) throw new Error("Cannot pass patterns as both an argument and an option"); + const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string"; + const opts = isModern ? options : patternsOrOptions; + const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns; + const [crawler, relative] = getCrawler(patterns, opts); + if (!relative) return crawler.sync(); + return formatPaths(crawler.sync(), relative); +} + +//#endregion +export { convertPathToPattern, escapePath, glob, globSync, isDynamicPattern }; \ No newline at end of file diff --git a/node_modules/tinyglobby/node_modules/fdir/LICENSE b/node_modules/tinyglobby/node_modules/fdir/LICENSE new file mode 100644 index 0000000000000..bb7fdee44cae6 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/fdir/LICENSE @@ -0,0 +1,7 @@ +Copyright 2023 Abdullah Atta + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/tinyglobby/node_modules/fdir/dist/index.cjs b/node_modules/tinyglobby/node_modules/fdir/dist/index.cjs new file mode 100644 index 0000000000000..4868ffba35d99 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/fdir/dist/index.cjs @@ -0,0 +1,588 @@ +//#region rolldown:runtime +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { + key = keys[i]; + if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { + get: ((k) => from[k]).bind(null, key), + enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable + }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { + value: mod, + enumerable: true +}) : target, mod)); + +//#endregion +const path = __toESM(require("path")); +const fs = __toESM(require("fs")); + +//#region src/utils.ts +function cleanPath(path$1) { + let normalized = (0, path.normalize)(path$1); + if (normalized.length > 1 && normalized[normalized.length - 1] === path.sep) normalized = normalized.substring(0, normalized.length - 1); + return normalized; +} +const SLASHES_REGEX = /[\\/]/g; +function convertSlashes(path$1, separator) { + return path$1.replace(SLASHES_REGEX, separator); +} +const WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i; +function isRootDirectory(path$1) { + return path$1 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path$1); +} +function normalizePath(path$1, options) { + const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options; + const pathNeedsCleaning = process.platform === "win32" && path$1.includes("/") || path$1.startsWith("."); + if (resolvePaths) path$1 = (0, path.resolve)(path$1); + if (normalizePath$1 || pathNeedsCleaning) path$1 = cleanPath(path$1); + if (path$1 === ".") return ""; + const needsSeperator = path$1[path$1.length - 1] !== pathSeparator; + return convertSlashes(needsSeperator ? path$1 + pathSeparator : path$1, pathSeparator); +} + +//#endregion +//#region src/api/functions/join-path.ts +function joinPathWithBasePath(filename, directoryPath) { + return directoryPath + filename; +} +function joinPathWithRelativePath(root, options) { + return function(filename, directoryPath) { + const sameRoot = directoryPath.startsWith(root); + if (sameRoot) return directoryPath.slice(root.length) + filename; + else return convertSlashes((0, path.relative)(root, directoryPath), options.pathSeparator) + options.pathSeparator + filename; + }; +} +function joinPath(filename) { + return filename; +} +function joinDirectoryPath(filename, directoryPath, separator) { + return directoryPath + filename + separator; +} +function build$7(root, options) { + const { relativePaths, includeBasePath } = options; + return relativePaths && root ? joinPathWithRelativePath(root, options) : includeBasePath ? joinPathWithBasePath : joinPath; +} + +//#endregion +//#region src/api/functions/push-directory.ts +function pushDirectoryWithRelativePath(root) { + return function(directoryPath, paths) { + paths.push(directoryPath.substring(root.length) || "."); + }; +} +function pushDirectoryFilterWithRelativePath(root) { + return function(directoryPath, paths, filters) { + const relativePath = directoryPath.substring(root.length) || "."; + if (filters.every((filter) => filter(relativePath, true))) paths.push(relativePath); + }; +} +const pushDirectory = (directoryPath, paths) => { + paths.push(directoryPath || "."); +}; +const pushDirectoryFilter = (directoryPath, paths, filters) => { + const path$1 = directoryPath || "."; + if (filters.every((filter) => filter(path$1, true))) paths.push(path$1); +}; +const empty$2 = () => {}; +function build$6(root, options) { + const { includeDirs, filters, relativePaths } = options; + if (!includeDirs) return empty$2; + if (relativePaths) return filters && filters.length ? pushDirectoryFilterWithRelativePath(root) : pushDirectoryWithRelativePath(root); + return filters && filters.length ? pushDirectoryFilter : pushDirectory; +} + +//#endregion +//#region src/api/functions/push-file.ts +const pushFileFilterAndCount = (filename, _paths, counts, filters) => { + if (filters.every((filter) => filter(filename, false))) counts.files++; +}; +const pushFileFilter = (filename, paths, _counts, filters) => { + if (filters.every((filter) => filter(filename, false))) paths.push(filename); +}; +const pushFileCount = (_filename, _paths, counts, _filters) => { + counts.files++; +}; +const pushFile = (filename, paths) => { + paths.push(filename); +}; +const empty$1 = () => {}; +function build$5(options) { + const { excludeFiles, filters, onlyCounts } = options; + if (excludeFiles) return empty$1; + if (filters && filters.length) return onlyCounts ? pushFileFilterAndCount : pushFileFilter; + else if (onlyCounts) return pushFileCount; + else return pushFile; +} + +//#endregion +//#region src/api/functions/get-array.ts +const getArray = (paths) => { + return paths; +}; +const getArrayGroup = () => { + return [""].slice(0, 0); +}; +function build$4(options) { + return options.group ? getArrayGroup : getArray; +} + +//#endregion +//#region src/api/functions/group-files.ts +const groupFiles = (groups, directory, files) => { + groups.push({ + directory, + files, + dir: directory + }); +}; +const empty = () => {}; +function build$3(options) { + return options.group ? groupFiles : empty; +} + +//#endregion +//#region src/api/functions/resolve-symlink.ts +const resolveSymlinksAsync = function(path$1, state, callback$1) { + const { queue, fs: fs$1, options: { suppressErrors } } = state; + queue.enqueue(); + fs$1.realpath(path$1, (error, resolvedPath) => { + if (error) return queue.dequeue(suppressErrors ? null : error, state); + fs$1.stat(resolvedPath, (error$1, stat) => { + if (error$1) return queue.dequeue(suppressErrors ? null : error$1, state); + if (stat.isDirectory() && isRecursive(path$1, resolvedPath, state)) return queue.dequeue(null, state); + callback$1(stat, resolvedPath); + queue.dequeue(null, state); + }); + }); +}; +const resolveSymlinks = function(path$1, state, callback$1) { + const { queue, fs: fs$1, options: { suppressErrors } } = state; + queue.enqueue(); + try { + const resolvedPath = fs$1.realpathSync(path$1); + const stat = fs$1.statSync(resolvedPath); + if (stat.isDirectory() && isRecursive(path$1, resolvedPath, state)) return; + callback$1(stat, resolvedPath); + } catch (e) { + if (!suppressErrors) throw e; + } +}; +function build$2(options, isSynchronous) { + if (!options.resolveSymlinks || options.excludeSymlinks) return null; + return isSynchronous ? resolveSymlinks : resolveSymlinksAsync; +} +function isRecursive(path$1, resolved, state) { + if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state); + let parent = (0, path.dirname)(path$1); + let depth = 1; + while (parent !== state.root && depth < 2) { + const resolvedPath = state.symlinks.get(parent); + const isSameRoot = !!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath)); + if (isSameRoot) depth++; + else parent = (0, path.dirname)(parent); + } + state.symlinks.set(path$1, resolved); + return depth > 1; +} +function isRecursiveUsingRealPaths(resolved, state) { + return state.visited.includes(resolved + state.options.pathSeparator); +} + +//#endregion +//#region src/api/functions/invoke-callback.ts +const onlyCountsSync = (state) => { + return state.counts; +}; +const groupsSync = (state) => { + return state.groups; +}; +const defaultSync = (state) => { + return state.paths; +}; +const limitFilesSync = (state) => { + return state.paths.slice(0, state.options.maxFiles); +}; +const onlyCountsAsync = (state, error, callback$1) => { + report(error, callback$1, state.counts, state.options.suppressErrors); + return null; +}; +const defaultAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths, state.options.suppressErrors); + return null; +}; +const limitFilesAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths.slice(0, state.options.maxFiles), state.options.suppressErrors); + return null; +}; +const groupsAsync = (state, error, callback$1) => { + report(error, callback$1, state.groups, state.options.suppressErrors); + return null; +}; +function report(error, callback$1, output, suppressErrors) { + if (error && !suppressErrors) callback$1(error, output); + else callback$1(null, output); +} +function build$1(options, isSynchronous) { + const { onlyCounts, group, maxFiles } = options; + if (onlyCounts) return isSynchronous ? onlyCountsSync : onlyCountsAsync; + else if (group) return isSynchronous ? groupsSync : groupsAsync; + else if (maxFiles) return isSynchronous ? limitFilesSync : limitFilesAsync; + else return isSynchronous ? defaultSync : defaultAsync; +} + +//#endregion +//#region src/api/functions/walk-directory.ts +const readdirOpts = { withFileTypes: true }; +const walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + state.queue.enqueue(); + if (currentDepth < 0) return state.queue.dequeue(null, state); + const { fs: fs$1 } = state; + state.visited.push(crawlPath); + state.counts.directories++; + fs$1.readdir(crawlPath || ".", readdirOpts, (error, entries = []) => { + callback$1(entries, directoryPath, currentDepth); + state.queue.dequeue(state.options.suppressErrors ? null : error, state); + }); +}; +const walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + const { fs: fs$1 } = state; + if (currentDepth < 0) return; + state.visited.push(crawlPath); + state.counts.directories++; + let entries = []; + try { + entries = fs$1.readdirSync(crawlPath || ".", readdirOpts); + } catch (e) { + if (!state.options.suppressErrors) throw e; + } + callback$1(entries, directoryPath, currentDepth); +}; +function build(isSynchronous) { + return isSynchronous ? walkSync : walkAsync; +} + +//#endregion +//#region src/api/queue.ts +/** +* This is a custom stateless queue to track concurrent async fs calls. +* It increments a counter whenever a call is queued and decrements it +* as soon as it completes. When the counter hits 0, it calls onQueueEmpty. +*/ +var Queue = class { + count = 0; + constructor(onQueueEmpty) { + this.onQueueEmpty = onQueueEmpty; + } + enqueue() { + this.count++; + return this.count; + } + dequeue(error, output) { + if (this.onQueueEmpty && (--this.count <= 0 || error)) { + this.onQueueEmpty(error, output); + if (error) { + output.controller.abort(); + this.onQueueEmpty = void 0; + } + } + } +}; + +//#endregion +//#region src/api/counter.ts +var Counter = class { + _files = 0; + _directories = 0; + set files(num) { + this._files = num; + } + get files() { + return this._files; + } + set directories(num) { + this._directories = num; + } + get directories() { + return this._directories; + } + /** + * @deprecated use `directories` instead + */ + /* c8 ignore next 3 */ + get dirs() { + return this._directories; + } +}; + +//#endregion +//#region src/api/aborter.ts +/** +* AbortController is not supported on Node 14 so we use this until we can drop +* support for Node 14. +*/ +var Aborter = class { + aborted = false; + abort() { + this.aborted = true; + } +}; + +//#endregion +//#region src/api/walker.ts +var Walker = class { + root; + isSynchronous; + state; + joinPath; + pushDirectory; + pushFile; + getArray; + groupFiles; + resolveSymlink; + walkDirectory; + callbackInvoker; + constructor(root, options, callback$1) { + this.isSynchronous = !callback$1; + this.callbackInvoker = build$1(options, this.isSynchronous); + this.root = normalizePath(root, options); + this.state = { + root: isRootDirectory(this.root) ? this.root : this.root.slice(0, -1), + paths: [""].slice(0, 0), + groups: [], + counts: new Counter(), + options, + queue: new Queue((error, state) => this.callbackInvoker(state, error, callback$1)), + symlinks: /* @__PURE__ */ new Map(), + visited: [""].slice(0, 0), + controller: new Aborter(), + fs: options.fs || fs + }; + this.joinPath = build$7(this.root, options); + this.pushDirectory = build$6(this.root, options); + this.pushFile = build$5(options); + this.getArray = build$4(options); + this.groupFiles = build$3(options); + this.resolveSymlink = build$2(options, this.isSynchronous); + this.walkDirectory = build(this.isSynchronous); + } + start() { + this.pushDirectory(this.root, this.state.paths, this.state.options.filters); + this.walkDirectory(this.state, this.root, this.root, this.state.options.maxDepth, this.walk); + return this.isSynchronous ? this.callbackInvoker(this.state, null) : null; + } + walk = (entries, directoryPath, depth) => { + const { paths, options: { filters, resolveSymlinks: resolveSymlinks$1, excludeSymlinks, exclude, maxFiles, signal, useRealPaths, pathSeparator }, controller } = this.state; + if (controller.aborted || signal && signal.aborted || maxFiles && paths.length > maxFiles) return; + const files = this.getArray(this.state.paths); + for (let i = 0; i < entries.length; ++i) { + const entry = entries[i]; + if (entry.isFile() || entry.isSymbolicLink() && !resolveSymlinks$1 && !excludeSymlinks) { + const filename = this.joinPath(entry.name, directoryPath); + this.pushFile(filename, files, this.state.counts, filters); + } else if (entry.isDirectory()) { + let path$1 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator); + if (exclude && exclude(entry.name, path$1)) continue; + this.pushDirectory(path$1, paths, filters); + this.walkDirectory(this.state, path$1, path$1, depth - 1, this.walk); + } else if (this.resolveSymlink && entry.isSymbolicLink()) { + let path$1 = joinPathWithBasePath(entry.name, directoryPath); + this.resolveSymlink(path$1, this.state, (stat, resolvedPath) => { + if (stat.isDirectory()) { + resolvedPath = normalizePath(resolvedPath, this.state.options); + if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path$1 + pathSeparator)) return; + this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path$1 + pathSeparator, depth - 1, this.walk); + } else { + resolvedPath = useRealPaths ? resolvedPath : path$1; + const filename = (0, path.basename)(resolvedPath); + const directoryPath$1 = normalizePath((0, path.dirname)(resolvedPath), this.state.options); + resolvedPath = this.joinPath(filename, directoryPath$1); + this.pushFile(resolvedPath, files, this.state.counts, filters); + } + }); + } + } + this.groupFiles(this.state.groups, directoryPath, files); + }; +}; + +//#endregion +//#region src/api/async.ts +function promise(root, options) { + return new Promise((resolve$1, reject) => { + callback(root, options, (err, output) => { + if (err) return reject(err); + resolve$1(output); + }); + }); +} +function callback(root, options, callback$1) { + let walker = new Walker(root, options, callback$1); + walker.start(); +} + +//#endregion +//#region src/api/sync.ts +function sync(root, options) { + const walker = new Walker(root, options); + return walker.start(); +} + +//#endregion +//#region src/builder/api-builder.ts +var APIBuilder = class { + constructor(root, options) { + this.root = root; + this.options = options; + } + withPromise() { + return promise(this.root, this.options); + } + withCallback(cb) { + callback(this.root, this.options, cb); + } + sync() { + return sync(this.root, this.options); + } +}; + +//#endregion +//#region src/builder/index.ts +let pm = null; +/* c8 ignore next 6 */ +try { + require.resolve("picomatch"); + pm = require("picomatch"); +} catch {} +var Builder = class { + globCache = {}; + options = { + maxDepth: Infinity, + suppressErrors: true, + pathSeparator: path.sep, + filters: [] + }; + globFunction; + constructor(options) { + this.options = { + ...this.options, + ...options + }; + this.globFunction = this.options.globFunction; + } + group() { + this.options.group = true; + return this; + } + withPathSeparator(separator) { + this.options.pathSeparator = separator; + return this; + } + withBasePath() { + this.options.includeBasePath = true; + return this; + } + withRelativePaths() { + this.options.relativePaths = true; + return this; + } + withDirs() { + this.options.includeDirs = true; + return this; + } + withMaxDepth(depth) { + this.options.maxDepth = depth; + return this; + } + withMaxFiles(limit) { + this.options.maxFiles = limit; + return this; + } + withFullPaths() { + this.options.resolvePaths = true; + this.options.includeBasePath = true; + return this; + } + withErrors() { + this.options.suppressErrors = false; + return this; + } + withSymlinks({ resolvePaths = true } = {}) { + this.options.resolveSymlinks = true; + this.options.useRealPaths = resolvePaths; + return this.withFullPaths(); + } + withAbortSignal(signal) { + this.options.signal = signal; + return this; + } + normalize() { + this.options.normalizePath = true; + return this; + } + filter(predicate) { + this.options.filters.push(predicate); + return this; + } + onlyDirs() { + this.options.excludeFiles = true; + this.options.includeDirs = true; + return this; + } + exclude(predicate) { + this.options.exclude = predicate; + return this; + } + onlyCounts() { + this.options.onlyCounts = true; + return this; + } + crawl(root) { + return new APIBuilder(root || ".", this.options); + } + withGlobFunction(fn) { + this.globFunction = fn; + return this; + } + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + /* c8 ignore next 4 */ + crawlWithOptions(root, options) { + this.options = { + ...this.options, + ...options + }; + return new APIBuilder(root || ".", this.options); + } + glob(...patterns) { + if (this.globFunction) return this.globWithOptions(patterns); + return this.globWithOptions(patterns, ...[{ dot: true }]); + } + globWithOptions(patterns, ...options) { + const globFn = this.globFunction || pm; + /* c8 ignore next 5 */ + if (!globFn) throw new Error("Please specify a glob function to use glob matching."); + var isMatch = this.globCache[patterns.join("\0")]; + if (!isMatch) { + isMatch = globFn(patterns, ...options); + this.globCache[patterns.join("\0")] = isMatch; + } + this.options.filters.push((path$1) => isMatch(path$1)); + return this; + } +}; + +//#endregion +exports.fdir = Builder; \ No newline at end of file diff --git a/node_modules/tinyglobby/node_modules/fdir/dist/index.d.cts b/node_modules/tinyglobby/node_modules/fdir/dist/index.d.cts new file mode 100644 index 0000000000000..f448ef5d9b563 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/fdir/dist/index.d.cts @@ -0,0 +1,155 @@ +/// <reference types="node" /> +import * as nativeFs from "fs"; +import picomatch from "picomatch"; + +//#region src/api/aborter.d.ts +/** + * AbortController is not supported on Node 14 so we use this until we can drop + * support for Node 14. + */ +declare class Aborter { + aborted: boolean; + abort(): void; +} +//#endregion +//#region src/api/queue.d.ts +type OnQueueEmptyCallback = (error: Error | null, output: WalkerState) => void; +/** + * This is a custom stateless queue to track concurrent async fs calls. + * It increments a counter whenever a call is queued and decrements it + * as soon as it completes. When the counter hits 0, it calls onQueueEmpty. + */ +declare class Queue { + private onQueueEmpty?; + count: number; + constructor(onQueueEmpty?: OnQueueEmptyCallback | undefined); + enqueue(): number; + dequeue(error: Error | null, output: WalkerState): void; +} +//#endregion +//#region src/types.d.ts +type Counts = { + files: number; + directories: number; + /** + * @deprecated use `directories` instead. Will be removed in v7.0. + */ + dirs: number; +}; +type Group = { + directory: string; + files: string[]; + /** + * @deprecated use `directory` instead. Will be removed in v7.0. + */ + dir: string; +}; +type GroupOutput = Group[]; +type OnlyCountsOutput = Counts; +type PathsOutput = string[]; +type Output = OnlyCountsOutput | PathsOutput | GroupOutput; +type FSLike = { + readdir: typeof nativeFs.readdir; + readdirSync: typeof nativeFs.readdirSync; + realpath: typeof nativeFs.realpath; + realpathSync: typeof nativeFs.realpathSync; + stat: typeof nativeFs.stat; + statSync: typeof nativeFs.statSync; +}; +type WalkerState = { + root: string; + paths: string[]; + groups: Group[]; + counts: Counts; + options: Options; + queue: Queue; + controller: Aborter; + fs: FSLike; + symlinks: Map<string, string>; + visited: string[]; +}; +type ResultCallback<TOutput extends Output> = (error: Error | null, output: TOutput) => void; +type FilterPredicate = (path: string, isDirectory: boolean) => boolean; +type ExcludePredicate = (dirName: string, dirPath: string) => boolean; +type PathSeparator = "/" | "\\"; +type Options<TGlobFunction = unknown> = { + includeBasePath?: boolean; + includeDirs?: boolean; + normalizePath?: boolean; + maxDepth: number; + maxFiles?: number; + resolvePaths?: boolean; + suppressErrors: boolean; + group?: boolean; + onlyCounts?: boolean; + filters: FilterPredicate[]; + resolveSymlinks?: boolean; + useRealPaths?: boolean; + excludeFiles?: boolean; + excludeSymlinks?: boolean; + exclude?: ExcludePredicate; + relativePaths?: boolean; + pathSeparator: PathSeparator; + signal?: AbortSignal; + globFunction?: TGlobFunction; + fs?: FSLike; +}; +type GlobMatcher = (test: string) => boolean; +type GlobFunction = (glob: string | string[], ...params: unknown[]) => GlobMatcher; +type GlobParams<T> = T extends ((globs: string | string[], ...params: infer TParams extends unknown[]) => GlobMatcher) ? TParams : []; +//#endregion +//#region src/builder/api-builder.d.ts +declare class APIBuilder<TReturnType extends Output> { + private readonly root; + private readonly options; + constructor(root: string, options: Options); + withPromise(): Promise<TReturnType>; + withCallback(cb: ResultCallback<TReturnType>): void; + sync(): TReturnType; +} +//#endregion +//#region src/builder/index.d.ts +declare class Builder<TReturnType extends Output = PathsOutput, TGlobFunction = typeof picomatch> { + private readonly globCache; + private options; + private globFunction?; + constructor(options?: Partial<Options<TGlobFunction>>); + group(): Builder<GroupOutput, TGlobFunction>; + withPathSeparator(separator: "/" | "\\"): this; + withBasePath(): this; + withRelativePaths(): this; + withDirs(): this; + withMaxDepth(depth: number): this; + withMaxFiles(limit: number): this; + withFullPaths(): this; + withErrors(): this; + withSymlinks({ + resolvePaths + }?: { + resolvePaths?: boolean | undefined; + }): this; + withAbortSignal(signal: AbortSignal): this; + normalize(): this; + filter(predicate: FilterPredicate): this; + onlyDirs(): this; + exclude(predicate: ExcludePredicate): this; + onlyCounts(): Builder<OnlyCountsOutput, TGlobFunction>; + crawl(root?: string): APIBuilder<TReturnType>; + withGlobFunction<TFunc>(fn: TFunc): Builder<TReturnType, TFunc>; + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + crawlWithOptions(root: string, options: Partial<Options<TGlobFunction>>): APIBuilder<TReturnType>; + glob(...patterns: string[]): Builder<TReturnType, TGlobFunction>; + globWithOptions(patterns: string[]): Builder<TReturnType, TGlobFunction>; + globWithOptions(patterns: string[], ...options: GlobParams<TGlobFunction>): Builder<TReturnType, TGlobFunction>; +} +//#endregion +//#region src/index.d.ts +type Fdir = typeof Builder; +//#endregion +export { Counts, ExcludePredicate, FSLike, Fdir, FilterPredicate, GlobFunction, GlobMatcher, GlobParams, Group, GroupOutput, OnlyCountsOutput, Options, Output, PathSeparator, PathsOutput, ResultCallback, WalkerState, Builder as fdir }; \ No newline at end of file diff --git a/node_modules/tinyglobby/node_modules/fdir/dist/index.d.mts b/node_modules/tinyglobby/node_modules/fdir/dist/index.d.mts new file mode 100644 index 0000000000000..f448ef5d9b563 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/fdir/dist/index.d.mts @@ -0,0 +1,155 @@ +/// <reference types="node" /> +import * as nativeFs from "fs"; +import picomatch from "picomatch"; + +//#region src/api/aborter.d.ts +/** + * AbortController is not supported on Node 14 so we use this until we can drop + * support for Node 14. + */ +declare class Aborter { + aborted: boolean; + abort(): void; +} +//#endregion +//#region src/api/queue.d.ts +type OnQueueEmptyCallback = (error: Error | null, output: WalkerState) => void; +/** + * This is a custom stateless queue to track concurrent async fs calls. + * It increments a counter whenever a call is queued and decrements it + * as soon as it completes. When the counter hits 0, it calls onQueueEmpty. + */ +declare class Queue { + private onQueueEmpty?; + count: number; + constructor(onQueueEmpty?: OnQueueEmptyCallback | undefined); + enqueue(): number; + dequeue(error: Error | null, output: WalkerState): void; +} +//#endregion +//#region src/types.d.ts +type Counts = { + files: number; + directories: number; + /** + * @deprecated use `directories` instead. Will be removed in v7.0. + */ + dirs: number; +}; +type Group = { + directory: string; + files: string[]; + /** + * @deprecated use `directory` instead. Will be removed in v7.0. + */ + dir: string; +}; +type GroupOutput = Group[]; +type OnlyCountsOutput = Counts; +type PathsOutput = string[]; +type Output = OnlyCountsOutput | PathsOutput | GroupOutput; +type FSLike = { + readdir: typeof nativeFs.readdir; + readdirSync: typeof nativeFs.readdirSync; + realpath: typeof nativeFs.realpath; + realpathSync: typeof nativeFs.realpathSync; + stat: typeof nativeFs.stat; + statSync: typeof nativeFs.statSync; +}; +type WalkerState = { + root: string; + paths: string[]; + groups: Group[]; + counts: Counts; + options: Options; + queue: Queue; + controller: Aborter; + fs: FSLike; + symlinks: Map<string, string>; + visited: string[]; +}; +type ResultCallback<TOutput extends Output> = (error: Error | null, output: TOutput) => void; +type FilterPredicate = (path: string, isDirectory: boolean) => boolean; +type ExcludePredicate = (dirName: string, dirPath: string) => boolean; +type PathSeparator = "/" | "\\"; +type Options<TGlobFunction = unknown> = { + includeBasePath?: boolean; + includeDirs?: boolean; + normalizePath?: boolean; + maxDepth: number; + maxFiles?: number; + resolvePaths?: boolean; + suppressErrors: boolean; + group?: boolean; + onlyCounts?: boolean; + filters: FilterPredicate[]; + resolveSymlinks?: boolean; + useRealPaths?: boolean; + excludeFiles?: boolean; + excludeSymlinks?: boolean; + exclude?: ExcludePredicate; + relativePaths?: boolean; + pathSeparator: PathSeparator; + signal?: AbortSignal; + globFunction?: TGlobFunction; + fs?: FSLike; +}; +type GlobMatcher = (test: string) => boolean; +type GlobFunction = (glob: string | string[], ...params: unknown[]) => GlobMatcher; +type GlobParams<T> = T extends ((globs: string | string[], ...params: infer TParams extends unknown[]) => GlobMatcher) ? TParams : []; +//#endregion +//#region src/builder/api-builder.d.ts +declare class APIBuilder<TReturnType extends Output> { + private readonly root; + private readonly options; + constructor(root: string, options: Options); + withPromise(): Promise<TReturnType>; + withCallback(cb: ResultCallback<TReturnType>): void; + sync(): TReturnType; +} +//#endregion +//#region src/builder/index.d.ts +declare class Builder<TReturnType extends Output = PathsOutput, TGlobFunction = typeof picomatch> { + private readonly globCache; + private options; + private globFunction?; + constructor(options?: Partial<Options<TGlobFunction>>); + group(): Builder<GroupOutput, TGlobFunction>; + withPathSeparator(separator: "/" | "\\"): this; + withBasePath(): this; + withRelativePaths(): this; + withDirs(): this; + withMaxDepth(depth: number): this; + withMaxFiles(limit: number): this; + withFullPaths(): this; + withErrors(): this; + withSymlinks({ + resolvePaths + }?: { + resolvePaths?: boolean | undefined; + }): this; + withAbortSignal(signal: AbortSignal): this; + normalize(): this; + filter(predicate: FilterPredicate): this; + onlyDirs(): this; + exclude(predicate: ExcludePredicate): this; + onlyCounts(): Builder<OnlyCountsOutput, TGlobFunction>; + crawl(root?: string): APIBuilder<TReturnType>; + withGlobFunction<TFunc>(fn: TFunc): Builder<TReturnType, TFunc>; + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + crawlWithOptions(root: string, options: Partial<Options<TGlobFunction>>): APIBuilder<TReturnType>; + glob(...patterns: string[]): Builder<TReturnType, TGlobFunction>; + globWithOptions(patterns: string[]): Builder<TReturnType, TGlobFunction>; + globWithOptions(patterns: string[], ...options: GlobParams<TGlobFunction>): Builder<TReturnType, TGlobFunction>; +} +//#endregion +//#region src/index.d.ts +type Fdir = typeof Builder; +//#endregion +export { Counts, ExcludePredicate, FSLike, Fdir, FilterPredicate, GlobFunction, GlobMatcher, GlobParams, Group, GroupOutput, OnlyCountsOutput, Options, Output, PathSeparator, PathsOutput, ResultCallback, WalkerState, Builder as fdir }; \ No newline at end of file diff --git a/node_modules/tinyglobby/node_modules/fdir/dist/index.mjs b/node_modules/tinyglobby/node_modules/fdir/dist/index.mjs new file mode 100644 index 0000000000000..5c37e092b507d --- /dev/null +++ b/node_modules/tinyglobby/node_modules/fdir/dist/index.mjs @@ -0,0 +1,570 @@ +import { createRequire } from "module"; +import { basename, dirname, normalize, relative, resolve, sep } from "path"; +import * as nativeFs from "fs"; + +//#region rolldown:runtime +var __require = /* @__PURE__ */ createRequire(import.meta.url); + +//#endregion +//#region src/utils.ts +function cleanPath(path) { + let normalized = normalize(path); + if (normalized.length > 1 && normalized[normalized.length - 1] === sep) normalized = normalized.substring(0, normalized.length - 1); + return normalized; +} +const SLASHES_REGEX = /[\\/]/g; +function convertSlashes(path, separator) { + return path.replace(SLASHES_REGEX, separator); +} +const WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i; +function isRootDirectory(path) { + return path === "/" || WINDOWS_ROOT_DIR_REGEX.test(path); +} +function normalizePath(path, options) { + const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options; + const pathNeedsCleaning = process.platform === "win32" && path.includes("/") || path.startsWith("."); + if (resolvePaths) path = resolve(path); + if (normalizePath$1 || pathNeedsCleaning) path = cleanPath(path); + if (path === ".") return ""; + const needsSeperator = path[path.length - 1] !== pathSeparator; + return convertSlashes(needsSeperator ? path + pathSeparator : path, pathSeparator); +} + +//#endregion +//#region src/api/functions/join-path.ts +function joinPathWithBasePath(filename, directoryPath) { + return directoryPath + filename; +} +function joinPathWithRelativePath(root, options) { + return function(filename, directoryPath) { + const sameRoot = directoryPath.startsWith(root); + if (sameRoot) return directoryPath.slice(root.length) + filename; + else return convertSlashes(relative(root, directoryPath), options.pathSeparator) + options.pathSeparator + filename; + }; +} +function joinPath(filename) { + return filename; +} +function joinDirectoryPath(filename, directoryPath, separator) { + return directoryPath + filename + separator; +} +function build$7(root, options) { + const { relativePaths, includeBasePath } = options; + return relativePaths && root ? joinPathWithRelativePath(root, options) : includeBasePath ? joinPathWithBasePath : joinPath; +} + +//#endregion +//#region src/api/functions/push-directory.ts +function pushDirectoryWithRelativePath(root) { + return function(directoryPath, paths) { + paths.push(directoryPath.substring(root.length) || "."); + }; +} +function pushDirectoryFilterWithRelativePath(root) { + return function(directoryPath, paths, filters) { + const relativePath = directoryPath.substring(root.length) || "."; + if (filters.every((filter) => filter(relativePath, true))) paths.push(relativePath); + }; +} +const pushDirectory = (directoryPath, paths) => { + paths.push(directoryPath || "."); +}; +const pushDirectoryFilter = (directoryPath, paths, filters) => { + const path = directoryPath || "."; + if (filters.every((filter) => filter(path, true))) paths.push(path); +}; +const empty$2 = () => {}; +function build$6(root, options) { + const { includeDirs, filters, relativePaths } = options; + if (!includeDirs) return empty$2; + if (relativePaths) return filters && filters.length ? pushDirectoryFilterWithRelativePath(root) : pushDirectoryWithRelativePath(root); + return filters && filters.length ? pushDirectoryFilter : pushDirectory; +} + +//#endregion +//#region src/api/functions/push-file.ts +const pushFileFilterAndCount = (filename, _paths, counts, filters) => { + if (filters.every((filter) => filter(filename, false))) counts.files++; +}; +const pushFileFilter = (filename, paths, _counts, filters) => { + if (filters.every((filter) => filter(filename, false))) paths.push(filename); +}; +const pushFileCount = (_filename, _paths, counts, _filters) => { + counts.files++; +}; +const pushFile = (filename, paths) => { + paths.push(filename); +}; +const empty$1 = () => {}; +function build$5(options) { + const { excludeFiles, filters, onlyCounts } = options; + if (excludeFiles) return empty$1; + if (filters && filters.length) return onlyCounts ? pushFileFilterAndCount : pushFileFilter; + else if (onlyCounts) return pushFileCount; + else return pushFile; +} + +//#endregion +//#region src/api/functions/get-array.ts +const getArray = (paths) => { + return paths; +}; +const getArrayGroup = () => { + return [""].slice(0, 0); +}; +function build$4(options) { + return options.group ? getArrayGroup : getArray; +} + +//#endregion +//#region src/api/functions/group-files.ts +const groupFiles = (groups, directory, files) => { + groups.push({ + directory, + files, + dir: directory + }); +}; +const empty = () => {}; +function build$3(options) { + return options.group ? groupFiles : empty; +} + +//#endregion +//#region src/api/functions/resolve-symlink.ts +const resolveSymlinksAsync = function(path, state, callback$1) { + const { queue, fs, options: { suppressErrors } } = state; + queue.enqueue(); + fs.realpath(path, (error, resolvedPath) => { + if (error) return queue.dequeue(suppressErrors ? null : error, state); + fs.stat(resolvedPath, (error$1, stat) => { + if (error$1) return queue.dequeue(suppressErrors ? null : error$1, state); + if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return queue.dequeue(null, state); + callback$1(stat, resolvedPath); + queue.dequeue(null, state); + }); + }); +}; +const resolveSymlinks = function(path, state, callback$1) { + const { queue, fs, options: { suppressErrors } } = state; + queue.enqueue(); + try { + const resolvedPath = fs.realpathSync(path); + const stat = fs.statSync(resolvedPath); + if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return; + callback$1(stat, resolvedPath); + } catch (e) { + if (!suppressErrors) throw e; + } +}; +function build$2(options, isSynchronous) { + if (!options.resolveSymlinks || options.excludeSymlinks) return null; + return isSynchronous ? resolveSymlinks : resolveSymlinksAsync; +} +function isRecursive(path, resolved, state) { + if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state); + let parent = dirname(path); + let depth = 1; + while (parent !== state.root && depth < 2) { + const resolvedPath = state.symlinks.get(parent); + const isSameRoot = !!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath)); + if (isSameRoot) depth++; + else parent = dirname(parent); + } + state.symlinks.set(path, resolved); + return depth > 1; +} +function isRecursiveUsingRealPaths(resolved, state) { + return state.visited.includes(resolved + state.options.pathSeparator); +} + +//#endregion +//#region src/api/functions/invoke-callback.ts +const onlyCountsSync = (state) => { + return state.counts; +}; +const groupsSync = (state) => { + return state.groups; +}; +const defaultSync = (state) => { + return state.paths; +}; +const limitFilesSync = (state) => { + return state.paths.slice(0, state.options.maxFiles); +}; +const onlyCountsAsync = (state, error, callback$1) => { + report(error, callback$1, state.counts, state.options.suppressErrors); + return null; +}; +const defaultAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths, state.options.suppressErrors); + return null; +}; +const limitFilesAsync = (state, error, callback$1) => { + report(error, callback$1, state.paths.slice(0, state.options.maxFiles), state.options.suppressErrors); + return null; +}; +const groupsAsync = (state, error, callback$1) => { + report(error, callback$1, state.groups, state.options.suppressErrors); + return null; +}; +function report(error, callback$1, output, suppressErrors) { + if (error && !suppressErrors) callback$1(error, output); + else callback$1(null, output); +} +function build$1(options, isSynchronous) { + const { onlyCounts, group, maxFiles } = options; + if (onlyCounts) return isSynchronous ? onlyCountsSync : onlyCountsAsync; + else if (group) return isSynchronous ? groupsSync : groupsAsync; + else if (maxFiles) return isSynchronous ? limitFilesSync : limitFilesAsync; + else return isSynchronous ? defaultSync : defaultAsync; +} + +//#endregion +//#region src/api/functions/walk-directory.ts +const readdirOpts = { withFileTypes: true }; +const walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + state.queue.enqueue(); + if (currentDepth < 0) return state.queue.dequeue(null, state); + const { fs } = state; + state.visited.push(crawlPath); + state.counts.directories++; + fs.readdir(crawlPath || ".", readdirOpts, (error, entries = []) => { + callback$1(entries, directoryPath, currentDepth); + state.queue.dequeue(state.options.suppressErrors ? null : error, state); + }); +}; +const walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => { + const { fs } = state; + if (currentDepth < 0) return; + state.visited.push(crawlPath); + state.counts.directories++; + let entries = []; + try { + entries = fs.readdirSync(crawlPath || ".", readdirOpts); + } catch (e) { + if (!state.options.suppressErrors) throw e; + } + callback$1(entries, directoryPath, currentDepth); +}; +function build(isSynchronous) { + return isSynchronous ? walkSync : walkAsync; +} + +//#endregion +//#region src/api/queue.ts +/** +* This is a custom stateless queue to track concurrent async fs calls. +* It increments a counter whenever a call is queued and decrements it +* as soon as it completes. When the counter hits 0, it calls onQueueEmpty. +*/ +var Queue = class { + count = 0; + constructor(onQueueEmpty) { + this.onQueueEmpty = onQueueEmpty; + } + enqueue() { + this.count++; + return this.count; + } + dequeue(error, output) { + if (this.onQueueEmpty && (--this.count <= 0 || error)) { + this.onQueueEmpty(error, output); + if (error) { + output.controller.abort(); + this.onQueueEmpty = void 0; + } + } + } +}; + +//#endregion +//#region src/api/counter.ts +var Counter = class { + _files = 0; + _directories = 0; + set files(num) { + this._files = num; + } + get files() { + return this._files; + } + set directories(num) { + this._directories = num; + } + get directories() { + return this._directories; + } + /** + * @deprecated use `directories` instead + */ + /* c8 ignore next 3 */ + get dirs() { + return this._directories; + } +}; + +//#endregion +//#region src/api/aborter.ts +/** +* AbortController is not supported on Node 14 so we use this until we can drop +* support for Node 14. +*/ +var Aborter = class { + aborted = false; + abort() { + this.aborted = true; + } +}; + +//#endregion +//#region src/api/walker.ts +var Walker = class { + root; + isSynchronous; + state; + joinPath; + pushDirectory; + pushFile; + getArray; + groupFiles; + resolveSymlink; + walkDirectory; + callbackInvoker; + constructor(root, options, callback$1) { + this.isSynchronous = !callback$1; + this.callbackInvoker = build$1(options, this.isSynchronous); + this.root = normalizePath(root, options); + this.state = { + root: isRootDirectory(this.root) ? this.root : this.root.slice(0, -1), + paths: [""].slice(0, 0), + groups: [], + counts: new Counter(), + options, + queue: new Queue((error, state) => this.callbackInvoker(state, error, callback$1)), + symlinks: /* @__PURE__ */ new Map(), + visited: [""].slice(0, 0), + controller: new Aborter(), + fs: options.fs || nativeFs + }; + this.joinPath = build$7(this.root, options); + this.pushDirectory = build$6(this.root, options); + this.pushFile = build$5(options); + this.getArray = build$4(options); + this.groupFiles = build$3(options); + this.resolveSymlink = build$2(options, this.isSynchronous); + this.walkDirectory = build(this.isSynchronous); + } + start() { + this.pushDirectory(this.root, this.state.paths, this.state.options.filters); + this.walkDirectory(this.state, this.root, this.root, this.state.options.maxDepth, this.walk); + return this.isSynchronous ? this.callbackInvoker(this.state, null) : null; + } + walk = (entries, directoryPath, depth) => { + const { paths, options: { filters, resolveSymlinks: resolveSymlinks$1, excludeSymlinks, exclude, maxFiles, signal, useRealPaths, pathSeparator }, controller } = this.state; + if (controller.aborted || signal && signal.aborted || maxFiles && paths.length > maxFiles) return; + const files = this.getArray(this.state.paths); + for (let i = 0; i < entries.length; ++i) { + const entry = entries[i]; + if (entry.isFile() || entry.isSymbolicLink() && !resolveSymlinks$1 && !excludeSymlinks) { + const filename = this.joinPath(entry.name, directoryPath); + this.pushFile(filename, files, this.state.counts, filters); + } else if (entry.isDirectory()) { + let path = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator); + if (exclude && exclude(entry.name, path)) continue; + this.pushDirectory(path, paths, filters); + this.walkDirectory(this.state, path, path, depth - 1, this.walk); + } else if (this.resolveSymlink && entry.isSymbolicLink()) { + let path = joinPathWithBasePath(entry.name, directoryPath); + this.resolveSymlink(path, this.state, (stat, resolvedPath) => { + if (stat.isDirectory()) { + resolvedPath = normalizePath(resolvedPath, this.state.options); + if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path + pathSeparator)) return; + this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path + pathSeparator, depth - 1, this.walk); + } else { + resolvedPath = useRealPaths ? resolvedPath : path; + const filename = basename(resolvedPath); + const directoryPath$1 = normalizePath(dirname(resolvedPath), this.state.options); + resolvedPath = this.joinPath(filename, directoryPath$1); + this.pushFile(resolvedPath, files, this.state.counts, filters); + } + }); + } + } + this.groupFiles(this.state.groups, directoryPath, files); + }; +}; + +//#endregion +//#region src/api/async.ts +function promise(root, options) { + return new Promise((resolve$1, reject) => { + callback(root, options, (err, output) => { + if (err) return reject(err); + resolve$1(output); + }); + }); +} +function callback(root, options, callback$1) { + let walker = new Walker(root, options, callback$1); + walker.start(); +} + +//#endregion +//#region src/api/sync.ts +function sync(root, options) { + const walker = new Walker(root, options); + return walker.start(); +} + +//#endregion +//#region src/builder/api-builder.ts +var APIBuilder = class { + constructor(root, options) { + this.root = root; + this.options = options; + } + withPromise() { + return promise(this.root, this.options); + } + withCallback(cb) { + callback(this.root, this.options, cb); + } + sync() { + return sync(this.root, this.options); + } +}; + +//#endregion +//#region src/builder/index.ts +let pm = null; +/* c8 ignore next 6 */ +try { + __require.resolve("picomatch"); + pm = __require("picomatch"); +} catch {} +var Builder = class { + globCache = {}; + options = { + maxDepth: Infinity, + suppressErrors: true, + pathSeparator: sep, + filters: [] + }; + globFunction; + constructor(options) { + this.options = { + ...this.options, + ...options + }; + this.globFunction = this.options.globFunction; + } + group() { + this.options.group = true; + return this; + } + withPathSeparator(separator) { + this.options.pathSeparator = separator; + return this; + } + withBasePath() { + this.options.includeBasePath = true; + return this; + } + withRelativePaths() { + this.options.relativePaths = true; + return this; + } + withDirs() { + this.options.includeDirs = true; + return this; + } + withMaxDepth(depth) { + this.options.maxDepth = depth; + return this; + } + withMaxFiles(limit) { + this.options.maxFiles = limit; + return this; + } + withFullPaths() { + this.options.resolvePaths = true; + this.options.includeBasePath = true; + return this; + } + withErrors() { + this.options.suppressErrors = false; + return this; + } + withSymlinks({ resolvePaths = true } = {}) { + this.options.resolveSymlinks = true; + this.options.useRealPaths = resolvePaths; + return this.withFullPaths(); + } + withAbortSignal(signal) { + this.options.signal = signal; + return this; + } + normalize() { + this.options.normalizePath = true; + return this; + } + filter(predicate) { + this.options.filters.push(predicate); + return this; + } + onlyDirs() { + this.options.excludeFiles = true; + this.options.includeDirs = true; + return this; + } + exclude(predicate) { + this.options.exclude = predicate; + return this; + } + onlyCounts() { + this.options.onlyCounts = true; + return this; + } + crawl(root) { + return new APIBuilder(root || ".", this.options); + } + withGlobFunction(fn) { + this.globFunction = fn; + return this; + } + /** + * @deprecated Pass options using the constructor instead: + * ```ts + * new fdir(options).crawl("/path/to/root"); + * ``` + * This method will be removed in v7.0 + */ + /* c8 ignore next 4 */ + crawlWithOptions(root, options) { + this.options = { + ...this.options, + ...options + }; + return new APIBuilder(root || ".", this.options); + } + glob(...patterns) { + if (this.globFunction) return this.globWithOptions(patterns); + return this.globWithOptions(patterns, ...[{ dot: true }]); + } + globWithOptions(patterns, ...options) { + const globFn = this.globFunction || pm; + /* c8 ignore next 5 */ + if (!globFn) throw new Error("Please specify a glob function to use glob matching."); + var isMatch = this.globCache[patterns.join("\0")]; + if (!isMatch) { + isMatch = globFn(patterns, ...options); + this.globCache[patterns.join("\0")] = isMatch; + } + this.options.filters.push((path) => isMatch(path)); + return this; + } +}; + +//#endregion +export { Builder as fdir }; \ No newline at end of file diff --git a/node_modules/tinyglobby/node_modules/fdir/package.json b/node_modules/tinyglobby/node_modules/fdir/package.json new file mode 100644 index 0000000000000..e229dff815080 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/fdir/package.json @@ -0,0 +1,103 @@ +{ + "name": "fdir", + "version": "6.5.0", + "description": "The fastest directory crawler & globbing alternative to glob, fast-glob, & tiny-glob. Crawls 1m files in < 1s", + "main": "./dist/index.cjs", + "types": "./dist/index.d.cts", + "type": "module", + "scripts": { + "prepublishOnly": "npm run test && npm run build", + "build": "tsdown", + "format": "prettier --write src __tests__ benchmarks", + "test": "vitest run __tests__/", + "test:coverage": "vitest run --coverage __tests__/", + "test:watch": "vitest __tests__/", + "bench": "ts-node benchmarks/benchmark.js", + "bench:glob": "ts-node benchmarks/glob-benchmark.ts", + "bench:fdir": "ts-node benchmarks/fdir-benchmark.ts", + "release": "./scripts/release.sh" + }, + "engines": { + "node": ">=12.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/thecodrr/fdir.git" + }, + "keywords": [ + "util", + "os", + "sys", + "fs", + "walk", + "crawler", + "directory", + "files", + "io", + "tiny-glob", + "glob", + "fast-glob", + "speed", + "javascript", + "nodejs" + ], + "author": "thecodrr <thecodrr@protonmail.com>", + "license": "MIT", + "bugs": { + "url": "https://github.com/thecodrr/fdir/issues" + }, + "homepage": "https://github.com/thecodrr/fdir#readme", + "devDependencies": { + "@types/glob": "^8.1.0", + "@types/mock-fs": "^4.13.4", + "@types/node": "^20.9.4", + "@types/picomatch": "^4.0.0", + "@types/tap": "^15.0.11", + "@vitest/coverage-v8": "^0.34.6", + "all-files-in-tree": "^1.1.2", + "benny": "^3.7.1", + "csv-to-markdown-table": "^1.3.1", + "expect": "^29.7.0", + "fast-glob": "^3.3.2", + "fdir1": "npm:fdir@1.2.0", + "fdir2": "npm:fdir@2.1.0", + "fdir3": "npm:fdir@3.4.2", + "fdir4": "npm:fdir@4.1.0", + "fdir5": "npm:fdir@5.0.0", + "fs-readdir-recursive": "^1.1.0", + "get-all-files": "^4.1.0", + "glob": "^10.3.10", + "klaw-sync": "^6.0.0", + "mock-fs": "^5.2.0", + "picomatch": "^4.0.2", + "prettier": "^3.5.3", + "recur-readdir": "0.0.1", + "recursive-files": "^1.0.2", + "recursive-fs": "^2.1.0", + "recursive-readdir": "^2.2.3", + "rrdir": "^12.1.0", + "systeminformation": "^5.21.17", + "tiny-glob": "^0.2.9", + "ts-node": "^10.9.1", + "tsdown": "^0.12.5", + "typescript": "^5.3.2", + "vitest": "^0.34.6", + "walk-sync": "^3.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + }, + "module": "./dist/index.mjs", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./package.json": "./package.json" + } +} diff --git a/node_modules/tinyglobby/node_modules/picomatch/LICENSE b/node_modules/tinyglobby/node_modules/picomatch/LICENSE new file mode 100644 index 0000000000000..3608dca25e30b --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/tinyglobby/node_modules/picomatch/index.js b/node_modules/tinyglobby/node_modules/picomatch/index.js new file mode 100644 index 0000000000000..a753b1d9e843c --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/index.js @@ -0,0 +1,17 @@ +'use strict'; + +const pico = require('./lib/picomatch'); +const utils = require('./lib/utils'); + +function picomatch(glob, options, returnState = false) { + // default to os.platform() + if (options && (options.windows === null || options.windows === undefined)) { + // don't mutate the original options object + options = { ...options, windows: utils.isWindows() }; + } + + return pico(glob, options, returnState); +} + +Object.assign(picomatch, pico); +module.exports = picomatch; diff --git a/node_modules/tinyglobby/node_modules/picomatch/lib/constants.js b/node_modules/tinyglobby/node_modules/picomatch/lib/constants.js new file mode 100644 index 0000000000000..3f7ef7e53adaf --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/lib/constants.js @@ -0,0 +1,180 @@ +'use strict'; + +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; + +/** + * Posix glob regex + */ + +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; +const SEP = '/'; + +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR, + SEP +}; + +/** + * Windows glob regex + */ + +const WINDOWS_CHARS = { + ...POSIX_CHARS, + + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)`, + SEP: '\\' +}; + +/** + * POSIX Bracket Regex + */ + +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; + +module.exports = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, + + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + __proto__: null, + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, + + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ + + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ + + CHAR_ASTERISK: 42, /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + + /** + * Create EXTGLOB_CHARS + */ + + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, + + /** + * Create GLOB_CHARS + */ + + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; + } +}; diff --git a/node_modules/tinyglobby/node_modules/picomatch/lib/parse.js b/node_modules/tinyglobby/node_modules/picomatch/lib/parse.js new file mode 100644 index 0000000000000..8fd8ff499d182 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/lib/parse.js @@ -0,0 +1,1085 @@ +'use strict'; + +const constants = require('./constants'); +const utils = require('./utils'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; + +/** + * Helpers + */ + +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); + } + + args.sort(); + const value = `[${args.join('-')}]`; + + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); + } + + return value; +}; + +/** + * Create the message for a syntax error + */ + +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; +}; + +/** + * Parse the given input string. + * @param {String} input + * @param {Object} options + * @return {Object} + */ + +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + input = REPLACEMENTS[input] || input; + + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; + + const capture = opts.capture ? '' : '?:'; + + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(opts.windows); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); + + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; + + const globstar = opts => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } + + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; + + input = utils.removePrefix(input, state); + len = input.length; + + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; + + /** + * Tokenizing helpers + */ + + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index] || ''; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; + + const negate = () => { + let count = 1; + + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } + + if (count % 2 === 0) { + return false; + } + + state.negated = true; + state.start++; + return true; + }; + + const increment = type => { + state[type]++; + stack.push(type); + }; + + const decrement = type => { + state[type]--; + stack.pop(); + }; + + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ + + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); + + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + + if (extglobs.length && tok.type !== 'paren') { + extglobs[extglobs.length - 1].inner += tok.value; + } + + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.output = (prev.output || prev.value) + tok.value; + prev.value += tok.value; + return; + } + + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; + + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; + + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; + + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); + let rest; + + if (token.type === 'negate') { + let extglobStar = star; + + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } + + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } + + if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { + // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. + // In this case, we need to parse the string and use it in the output of the original pattern. + // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. + // + // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. + const expression = parse(rest, { ...options, fastpaths: false }).output; + + output = token.close = `)${expression})${extglobStar})`; + } + + if (token.prev.type === 'bos') { + state.negatedExtglob = true; + } + } + + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; + + /** + * Fast paths + */ + + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; + + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } + + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } + + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } + + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : `\\${m}`; + }); + + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); + } + } + + if (output === input && opts.contains === true) { + state.output = input; + return state; + } + + state.output = utils.wrapOutput(output, state, options); + return state; + } + + /** + * Tokenize input until we reach end-of-string + */ + + while (!eos()) { + value = advance(); + + if (value === '\u0000') { + continue; + } + + /** + * Escaped characters + */ + + if (value === '\\') { + const next = peek(); + + if (next === '/' && opts.bash !== true) { + continue; + } + + if (next === '.' || next === ';') { + continue; + } + + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } + + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; + + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance(); + } else { + value += advance(); + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } + } + + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ + + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; + + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); + + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } + + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; + } + + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } + + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } + + prev.value += value; + append({ value }); + continue; + } + + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ + + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } + + /** + * Double quotes + */ + + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; + } + + /** + * Parentheses + */ + + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; + } + + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } + + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } + + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } + + /** + * Square brackets + */ + + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } + + value = `\\${value}`; + } else { + increment('brackets'); + } + + push({ type: 'bracket', value }); + continue; + } + + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } + + push({ type: 'text', value, output: `\\${value}` }); + continue; + } + + decrement('brackets'); + + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } + + prev.value += value; + append({ value }); + + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } + + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); + + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } + + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } + + /** + * Braces + */ + + if (value === '{' && opts.nobrace !== true) { + increment('braces'); + + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; + + braces.push(open); + push(open); + continue; + } + + if (value === '}') { + const brace = braces[braces.length - 1]; + + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } + + let output = ')'; + + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; + + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } + + output = expandRange(range, opts); + state.backtrack = true; + } + + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } + + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } + + /** + * Pipes + */ + + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } + + /** + * Commas + */ + + if (value === ',') { + let output = value; + + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } + + push({ type: 'comma', value, output }); + continue; + } + + /** + * Slashes + */ + + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; + } + + /** + * Dots + */ + + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; + } + + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; + } + + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } + + /** + * Question marks + */ + + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } + + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; + + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } + + push({ type: 'text', value, output }); + continue; + } + + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; + } + + push({ type: 'qmark', value, output: QMARK }); + continue; + } + + /** + * Exclamation + */ + + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } + + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } + } + + /** + * Plus + */ + + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } + + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } + + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } + + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } + + /** + * Plain text + */ + + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Plain text + */ + + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } + + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Stars + */ + + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); + continue; + } + + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } + + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } + + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); + + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; + } + + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } + + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { + break; + } + rest = rest.slice(3); + consume('/**', 3); + } + + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } + + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; + + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; + + state.output += prior.output + prev.output; + state.globstar = true; + + consume(value + advance()); + + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } + + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); + + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; + + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } + + const token = { type: 'star', value, output: star }; + + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } + push(token); + continue; + } + + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } + + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; + + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; + + } else { + state.output += nodot; + prev.output += nodot; + } + + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } + + push(token); + } + + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } + + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } + + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } + + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } + + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; + + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; + + if (token.suffix) { + state.output += token.suffix; + } + } + } + + return state; +}; + +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ + +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + input = REPLACEMENTS[input] || input; + + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(opts.windows); + + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; + + if (opts.capture) { + star = `(${star})`; + } + + const globstar = opts => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; + + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + + case '**': + return nodot + globstar(opts); + + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; + + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; + + const source = create(match[1]); + if (!source) return; + + return source + DOT_LITERAL + match[2]; + } + } + }; + + const output = utils.removePrefix(input, state); + let source = create(output); + + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; + } + + return source; +}; + +module.exports = parse; diff --git a/node_modules/tinyglobby/node_modules/picomatch/lib/picomatch.js b/node_modules/tinyglobby/node_modules/picomatch/lib/picomatch.js new file mode 100644 index 0000000000000..d0ebd9f163cf2 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/lib/picomatch.js @@ -0,0 +1,341 @@ +'use strict'; + +const scan = require('./scan'); +const parse = require('./parse'); +const utils = require('./utils'); +const constants = require('./constants'); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); + +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ + +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; + } + + const isState = isObject(glob) && glob.tokens && glob.input; + + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } + + const opts = options || {}; + const posix = opts.windows; + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); + + const state = regex.state; + delete regex.state; + + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; + + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } + + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } + + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } + result.isMatch = false; + return returnObject ? result : false; + } + + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; + + if (returnState) { + matcher.state = state; + } + + return matcher; +}; + +/** + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * ``` + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. + * @api public + */ + +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } + + if (input === '') { + return { isMatch: false, output: '' }; + } + + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; + + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } + + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } + + return { isMatch: Boolean(match), match, output }; +}; + +/** + * Match the basename of a filepath. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * ``` + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public + */ + +picomatch.matchBase = (input, glob, options) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(utils.basename(input)); +}; + +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ + +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); +}; + +/** + * Scan a glob pattern to separate the pattern into segments. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); + * + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } + * ``` + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ + +picomatch.scan = (input, options) => scan(input, options); + +/** + * Compile a regular expression from the `state` object returned by the + * [parse()](#parse) method. + * + * @param {Object} `state` + * @param {Object} `options` + * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. + * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. + * @return {RegExp} + * @api public + */ + +picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return state.output; + } + + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + + let source = `${prepend}(?:${state.output})${append}`; + if (state && state.negated === true) { + source = `^(?!${source}).*$`; + } + + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = state; + } + + return regex; +}; + +/** + * Create a regular expression from a parsed glob pattern. + * + * ```js + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); + * + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. + * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ + +picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } + + let parsed = { negated: false, fastpaths: true }; + + if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + parsed.output = parse.fastpaths(input, options); + } + + if (!parsed.output) { + parsed = parse(input, options); + } + + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; + +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; + } +}; + +/** + * Picomatch constants. + * @return {Object} + */ + +picomatch.constants = constants; + +/** + * Expose "picomatch" + */ + +module.exports = picomatch; diff --git a/node_modules/tinyglobby/node_modules/picomatch/lib/scan.js b/node_modules/tinyglobby/node_modules/picomatch/lib/scan.js new file mode 100644 index 0000000000000..e59cd7a1357b1 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/lib/scan.js @@ -0,0 +1,391 @@ +'use strict'; + +const utils = require('./utils'); +const { + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = require('./constants'); + +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; + +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; + } +}; + +/** + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not + * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). + * + * ```js + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an object with tokens and regex source string. + * @api public + */ + +const scan = (input, options) => { + const opts = options || {}; + + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; + + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let negatedExtglob = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; + + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; + + while (index < length) { + code = advance(); + let next; + + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } + continue; + } + + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; + + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; + } + + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; + + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; + + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; + continue; + } + + lastIndex = index + 1; + continue; + } + + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; + + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; + if (code === CHAR_EXCLAMATION_MARK && index === start) { + negatedExtglob = true; + } + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } + continue; + } + break; + } + } + + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; + } + break; + } + + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; + break; + } + } + + if (scanToEnd === true) { + continue; + } + + break; + } + + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; + } + + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } + + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } + continue; + } + break; + } + + if (isGlob === true) { + finished = true; + + if (scanToEnd === true) { + continue; + } + + break; + } + } + + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } + + let base = str; + let prefix = ''; + let glob = ''; + + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } + + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } + + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); + } + } + + if (opts.unescape === true) { + if (glob) glob = utils.removeBackslashes(glob); + + if (base && backslashes === true) { + base = utils.removeBackslashes(base); + } + } + + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated, + negatedExtglob + }; + + if (opts.tokens === true) { + state.maxDepth = 0; + if (!isPathSeparator(code)) { + tokens.push(token); + } + state.tokens = tokens; + } + + if (opts.parts === true || opts.tokens === true) { + let prevIndex; + + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; + } + if (idx !== 0 || value !== '') { + parts.push(value); + } + prevIndex = i; + } + + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); + + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; + } + } + + state.slashes = slashes; + state.parts = parts; + } + + return state; +}; + +module.exports = scan; diff --git a/node_modules/tinyglobby/node_modules/picomatch/lib/utils.js b/node_modules/tinyglobby/node_modules/picomatch/lib/utils.js new file mode 100644 index 0000000000000..9c97cae222ca8 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/lib/utils.js @@ -0,0 +1,72 @@ +/*global navigator*/ +'use strict'; + +const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL +} = require('./constants'); + +exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); +exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); +exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); +exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); +exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); + +exports.isWindows = () => { + if (typeof navigator !== 'undefined' && navigator.platform) { + const platform = navigator.platform.toLowerCase(); + return platform === 'win32' || platform === 'windows'; + } + + if (typeof process !== 'undefined' && process.platform) { + return process.platform === 'win32'; + } + + return false; +}; + +exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); +}; + +exports.escapeLast = (input, char, lastIdx) => { + const idx = input.lastIndexOf(char, lastIdx); + if (idx === -1) return input; + if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); + return `${input.slice(0, idx)}\\${input.slice(idx)}`; +}; + +exports.removePrefix = (input, state = {}) => { + let output = input; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; + } + return output; +}; + +exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; + + let output = `${prepend}(?:${input})${append}`; + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } + return output; +}; + +exports.basename = (path, { windows } = {}) => { + const segs = path.split(windows ? /[\\/]/ : '/'); + const last = segs[segs.length - 1]; + + if (last === '') { + return segs[segs.length - 2]; + } + + return last; +}; diff --git a/node_modules/tinyglobby/node_modules/picomatch/package.json b/node_modules/tinyglobby/node_modules/picomatch/package.json new file mode 100644 index 0000000000000..372e27e05f412 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/package.json @@ -0,0 +1,83 @@ +{ + "name": "picomatch", + "description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.", + "version": "4.0.3", + "homepage": "https://github.com/micromatch/picomatch", + "author": "Jon Schlinkert (https://github.com/jonschlinkert)", + "funding": "https://github.com/sponsors/jonschlinkert", + "repository": "micromatch/picomatch", + "bugs": { + "url": "https://github.com/micromatch/picomatch/issues" + }, + "license": "MIT", + "files": [ + "index.js", + "posix.js", + "lib" + ], + "sideEffects": false, + "main": "index.js", + "engines": { + "node": ">=12" + }, + "scripts": { + "lint": "eslint --cache --cache-location node_modules/.cache/.eslintcache --report-unused-disable-directives --ignore-path .gitignore .", + "mocha": "mocha --reporter dot", + "test": "npm run lint && npm run mocha", + "test:ci": "npm run test:cover", + "test:cover": "nyc npm run mocha" + }, + "devDependencies": { + "eslint": "^8.57.0", + "fill-range": "^7.0.1", + "gulp-format-md": "^2.0.0", + "mocha": "^10.4.0", + "nyc": "^15.1.0", + "time-require": "github:jonschlinkert/time-require" + }, + "keywords": [ + "glob", + "match", + "picomatch" + ], + "nyc": { + "reporter": [ + "html", + "lcov", + "text-summary" + ] + }, + "verb": { + "toc": { + "render": true, + "method": "preWrite", + "maxdepth": 3 + }, + "layout": "empty", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "related": { + "list": [ + "braces", + "micromatch" + ] + }, + "reflinks": [ + "braces", + "expand-brackets", + "extglob", + "fill-range", + "micromatch", + "minimatch", + "nanomatch", + "picomatch" + ] + } +} diff --git a/node_modules/tinyglobby/node_modules/picomatch/posix.js b/node_modules/tinyglobby/node_modules/picomatch/posix.js new file mode 100644 index 0000000000000..d2f2bc59d0ac7 --- /dev/null +++ b/node_modules/tinyglobby/node_modules/picomatch/posix.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./lib/picomatch'); diff --git a/node_modules/tinyglobby/package.json b/node_modules/tinyglobby/package.json new file mode 100644 index 0000000000000..d0247c25ae3a1 --- /dev/null +++ b/node_modules/tinyglobby/package.json @@ -0,0 +1,73 @@ +{ + "name": "tinyglobby", + "version": "0.2.15", + "description": "A fast and minimal alternative to globby and fast-glob", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.cts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./package.json": "./package.json" + }, + "sideEffects": false, + "files": [ + "dist" + ], + "author": "Superchupu", + "license": "MIT", + "keywords": [ + "glob", + "patterns", + "fast", + "implementation" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/SuperchupuDev/tinyglobby.git" + }, + "bugs": { + "url": "https://github.com/SuperchupuDev/tinyglobby/issues" + }, + "homepage": "https://superchupu.dev/tinyglobby", + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + }, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "devDependencies": { + "@biomejs/biome": "^2.2.3", + "@types/node": "^24.3.1", + "@types/picomatch": "^4.0.2", + "fast-glob": "^3.3.3", + "fs-fixture": "^2.8.1", + "glob": "^11.0.3", + "tinybench": "^5.0.1", + "tsdown": "^0.14.2", + "typescript": "^5.9.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "publishConfig": { + "provenance": true + }, + "scripts": { + "bench": "node benchmark/bench.ts", + "bench:setup": "node benchmark/setup.ts", + "build": "tsdown", + "check": "biome check", + "check:fix": "biome check --write --unsafe", + "format": "biome format --write", + "lint": "biome lint", + "test": "node --test \"test/**/*.ts\"", + "test:coverage": "node --test --experimental-test-coverage \"test/**/*.ts\"", + "test:only": "node --test --test-only \"test/**/*.ts\"", + "typecheck": "tsc --noEmit" + } +} \ No newline at end of file diff --git a/node_modules/treeverse/package.json b/node_modules/treeverse/package.json index 97269b335fc4b..b8de0b21ad719 100644 --- a/node_modules/treeverse/package.json +++ b/node_modules/treeverse/package.json @@ -1,6 +1,6 @@ { "name": "treeverse", - "version": "2.0.0", + "version": "3.0.0", "description": "Walk any kind of tree structure depth- or breadth-first. Supports promises and advanced map-reduce operations with a very small API.", "author": "GitHub Inc.", "license": "ISC", @@ -11,23 +11,23 @@ "scripts": { "test": "tap", "snap": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --follow-tags", "lint": "eslint \"**/*.js\"", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", "lintfix": "npm run lint -- --fix", - "prepublishOnly": "git push origin --follow-tags", "posttest": "npm run lint" }, "tap": { "100": true, - "coverage-map": "test/coverage-map.js" + "coverage-map": "test/coverage-map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "devDependencies": { "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.2", + "@npmcli/template-oss": "4.5.1", "tap": "^16.0.1" }, "files": [ @@ -42,10 +42,10 @@ "breadth first search" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "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": "3.2.2" + "version": "4.5.1" } } diff --git a/node_modules/tuf-js/LICENSE b/node_modules/tuf-js/LICENSE new file mode 100644 index 0000000000000..420700f5d3765 --- /dev/null +++ b/node_modules/tuf-js/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 GitHub and the TUF Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/tuf-js/dist/config.js b/node_modules/tuf-js/dist/config.js new file mode 100644 index 0000000000000..a15e161cc61ac --- /dev/null +++ b/node_modules/tuf-js/dist/config.js @@ -0,0 +1,16 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultConfig = void 0; +exports.defaultConfig = { + maxRootRotations: 256, + maxDelegations: 32, + rootMaxLength: 512000, //bytes + timestampMaxLength: 16384, // bytes + snapshotMaxLength: 2000000, // bytes + targetsMaxLength: 5000000, // bytes + prefixTargetsWithHash: true, + fetchTimeout: 100000, // milliseconds + fetchRetries: undefined, + fetchRetry: 2, + userAgent: '', +}; diff --git a/node_modules/tuf-js/dist/error.js b/node_modules/tuf-js/dist/error.js new file mode 100644 index 0000000000000..3a3c26a068a95 --- /dev/null +++ b/node_modules/tuf-js/dist/error.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DownloadHTTPError = exports.DownloadLengthMismatchError = exports.DownloadError = exports.ExpiredMetadataError = exports.EqualVersionError = exports.BadVersionError = exports.RepositoryError = exports.PersistError = exports.RuntimeError = exports.ValueError = void 0; +// An error about insufficient values +class ValueError extends Error { +} +exports.ValueError = ValueError; +class RuntimeError extends Error { +} +exports.RuntimeError = RuntimeError; +class PersistError extends Error { +} +exports.PersistError = PersistError; +// An error with a repository's state, such as a missing file. +// It covers all exceptions that come from the repository side when +// looking from the perspective of users of metadata API or ngclient. +class RepositoryError extends Error { +} +exports.RepositoryError = RepositoryError; +// An error for metadata that contains an invalid version number. +class BadVersionError extends RepositoryError { +} +exports.BadVersionError = BadVersionError; +// An error for metadata containing a previously verified version number. +class EqualVersionError extends BadVersionError { +} +exports.EqualVersionError = EqualVersionError; +// Indicate that a TUF Metadata file has expired. +class ExpiredMetadataError extends RepositoryError { +} +exports.ExpiredMetadataError = ExpiredMetadataError; +//----- Download Errors ------------------------------------------------------- +// An error occurred while attempting to download a file. +class DownloadError extends Error { +} +exports.DownloadError = DownloadError; +// Indicate that a mismatch of lengths was seen while downloading a file +class DownloadLengthMismatchError extends DownloadError { +} +exports.DownloadLengthMismatchError = DownloadLengthMismatchError; +// Returned by FetcherInterface implementations for HTTP errors. +class DownloadHTTPError extends DownloadError { + statusCode; + constructor(message, statusCode) { + super(message); + this.statusCode = statusCode; + } +} +exports.DownloadHTTPError = DownloadHTTPError; diff --git a/node_modules/tuf-js/dist/fetcher.js b/node_modules/tuf-js/dist/fetcher.js new file mode 100644 index 0000000000000..03c7260c8d17b --- /dev/null +++ b/node_modules/tuf-js/dist/fetcher.js @@ -0,0 +1,92 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DefaultFetcher = exports.BaseFetcher = void 0; +const debug_1 = __importDefault(require("debug")); +const fs_1 = __importDefault(require("fs")); +const make_fetch_happen_1 = __importDefault(require("make-fetch-happen")); +const util_1 = __importDefault(require("util")); +const error_1 = require("./error"); +const tmpfile_1 = require("./utils/tmpfile"); +const log = (0, debug_1.default)('tuf:fetch'); +const USER_AGENT_HEADER = 'User-Agent'; +class BaseFetcher { + // Download file from given URL. The file is downloaded to a temporary + // location and then passed to the given handler. The handler is responsible + // for moving the file to its final location. The temporary file is deleted + // after the handler returns. + async downloadFile(url, maxLength, handler) { + return (0, tmpfile_1.withTempFile)(async (tmpFile) => { + const reader = await this.fetch(url); + let numberOfBytesReceived = 0; + const fileStream = fs_1.default.createWriteStream(tmpFile); + // Read the stream a chunk at a time so that we can check + // the length of the file as we go + try { + for await (const chunk of reader) { + numberOfBytesReceived += chunk.length; + if (numberOfBytesReceived > maxLength) { + throw new error_1.DownloadLengthMismatchError('Max length reached'); + } + await writeBufferToStream(fileStream, chunk); + } + } + finally { + // Make sure we always close the stream + // eslint-disable-next-line @typescript-eslint/unbound-method + await util_1.default.promisify(fileStream.close).bind(fileStream)(); + } + return handler(tmpFile); + }); + } + // Download bytes from given URL. + async downloadBytes(url, maxLength) { + return this.downloadFile(url, maxLength, async (file) => { + const stream = fs_1.default.createReadStream(file); + const chunks = []; + for await (const chunk of stream) { + chunks.push(chunk); + } + return Buffer.concat(chunks); + }); + } +} +exports.BaseFetcher = BaseFetcher; +class DefaultFetcher extends BaseFetcher { + userAgent; + timeout; + retry; + constructor(options = {}) { + super(); + this.userAgent = options.userAgent; + this.timeout = options.timeout; + this.retry = options.retry; + } + async fetch(url) { + log('GET %s', url); + const response = await (0, make_fetch_happen_1.default)(url, { + headers: { + [USER_AGENT_HEADER]: this.userAgent || '', + }, + timeout: this.timeout, + retry: this.retry, + }); + if (!response.ok || !response?.body) { + throw new error_1.DownloadHTTPError('Failed to download', response.status); + } + return response.body; + } +} +exports.DefaultFetcher = DefaultFetcher; +const writeBufferToStream = async (stream, buffer) => { + return new Promise((resolve, reject) => { + stream.write(buffer, (err) => { + if (err) { + reject(err); + } + resolve(true); + }); + }); +}; diff --git a/node_modules/tuf-js/dist/index.js b/node_modules/tuf-js/dist/index.js new file mode 100644 index 0000000000000..5a83b91f355d8 --- /dev/null +++ b/node_modules/tuf-js/dist/index.js @@ -0,0 +1,9 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Updater = exports.BaseFetcher = exports.TargetFile = void 0; +var models_1 = require("@tufjs/models"); +Object.defineProperty(exports, "TargetFile", { enumerable: true, get: function () { return models_1.TargetFile; } }); +var fetcher_1 = require("./fetcher"); +Object.defineProperty(exports, "BaseFetcher", { enumerable: true, get: function () { return fetcher_1.BaseFetcher; } }); +var updater_1 = require("./updater"); +Object.defineProperty(exports, "Updater", { enumerable: true, get: function () { return updater_1.Updater; } }); diff --git a/node_modules/tuf-js/dist/store.js b/node_modules/tuf-js/dist/store.js new file mode 100644 index 0000000000000..1b1669029a8db --- /dev/null +++ b/node_modules/tuf-js/dist/store.js @@ -0,0 +1,219 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.TrustedMetadataStore = void 0; +const models_1 = require("@tufjs/models"); +const error_1 = require("./error"); +class TrustedMetadataStore { + trustedSet = {}; + referenceTime; + constructor(rootData) { + // Client workflow 5.1: record fixed update start time + this.referenceTime = new Date(); + // Client workflow 5.2: load trusted root metadata + this.loadTrustedRoot(rootData); + } + get root() { + if (!this.trustedSet.root) { + throw new ReferenceError('No trusted root metadata'); + } + return this.trustedSet.root; + } + get timestamp() { + return this.trustedSet.timestamp; + } + get snapshot() { + return this.trustedSet.snapshot; + } + get targets() { + return this.trustedSet.targets; + } + getRole(name) { + return this.trustedSet[name]; + } + updateRoot(bytesBuffer) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const data = JSON.parse(bytesBuffer.toString('utf8')); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const newRoot = models_1.Metadata.fromJSON(models_1.MetadataKind.Root, data); + if (newRoot.signed.type != models_1.MetadataKind.Root) { + throw new error_1.RepositoryError(`Expected 'root', got ${newRoot.signed.type}`); + } + // Client workflow 5.4: check for arbitrary software attack + this.root.verifyDelegate(models_1.MetadataKind.Root, newRoot); + // Client workflow 5.5: check for rollback attack + if (newRoot.signed.version != this.root.signed.version + 1) { + throw new error_1.BadVersionError(`Expected version ${this.root.signed.version + 1}, got ${newRoot.signed.version}`); + } + // Check that new root is signed by self + newRoot.verifyDelegate(models_1.MetadataKind.Root, newRoot); + // Client workflow 5.7: set new root as trusted root + this.trustedSet.root = newRoot; + return newRoot; + } + updateTimestamp(bytesBuffer) { + if (this.snapshot) { + throw new error_1.RuntimeError('Cannot update timestamp after snapshot'); + } + if (this.root.signed.isExpired(this.referenceTime)) { + throw new error_1.ExpiredMetadataError('Final root.json is expired'); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const data = JSON.parse(bytesBuffer.toString('utf8')); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const newTimestamp = models_1.Metadata.fromJSON(models_1.MetadataKind.Timestamp, data); + if (newTimestamp.signed.type != models_1.MetadataKind.Timestamp) { + throw new error_1.RepositoryError(`Expected 'timestamp', got ${newTimestamp.signed.type}`); + } + // Client workflow 5.4.2: check for arbitrary software attack + this.root.verifyDelegate(models_1.MetadataKind.Timestamp, newTimestamp); + if (this.timestamp) { + // Prevent rolling back timestamp version + // Client workflow 5.4.3.1: check for rollback attack + if (newTimestamp.signed.version < this.timestamp.signed.version) { + throw new error_1.BadVersionError(`New timestamp version ${newTimestamp.signed.version} is less than current version ${this.timestamp.signed.version}`); + } + // Keep using old timestamp if versions are equal. + if (newTimestamp.signed.version === this.timestamp.signed.version) { + throw new error_1.EqualVersionError(`New timestamp version ${newTimestamp.signed.version} is equal to current version ${this.timestamp.signed.version}`); + } + // Prevent rolling back snapshot version + // Client workflow 5.4.3.2: check for rollback attack + const snapshotMeta = this.timestamp.signed.snapshotMeta; + const newSnapshotMeta = newTimestamp.signed.snapshotMeta; + if (newSnapshotMeta.version < snapshotMeta.version) { + throw new error_1.BadVersionError(`New snapshot version ${newSnapshotMeta.version} is less than current version ${snapshotMeta.version}`); + } + } + // expiry not checked to allow old timestamp to be used for rollback + // protection of new timestamp: expiry is checked in update_snapshot + this.trustedSet.timestamp = newTimestamp; + // Client workflow 5.4.4: check for freeze attack + this.checkFinalTimestamp(); + return newTimestamp; + } + updateSnapshot(bytesBuffer, trusted = false) { + if (!this.timestamp) { + throw new error_1.RuntimeError('Cannot update snapshot before timestamp'); + } + if (this.targets) { + throw new error_1.RuntimeError('Cannot update snapshot after targets'); + } + // Snapshot cannot be loaded if final timestamp is expired + this.checkFinalTimestamp(); + const snapshotMeta = this.timestamp.signed.snapshotMeta; + // Verify non-trusted data against the hashes in timestamp, if any. + // Trusted snapshot data has already been verified once. + // Client workflow 5.5.2: check against timestamp role's snaphsot hash + if (!trusted) { + snapshotMeta.verify(bytesBuffer); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const data = JSON.parse(bytesBuffer.toString('utf8')); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const newSnapshot = models_1.Metadata.fromJSON(models_1.MetadataKind.Snapshot, data); + if (newSnapshot.signed.type != models_1.MetadataKind.Snapshot) { + throw new error_1.RepositoryError(`Expected 'snapshot', got ${newSnapshot.signed.type}`); + } + // Client workflow 5.5.3: check for arbitrary software attack + this.root.verifyDelegate(models_1.MetadataKind.Snapshot, newSnapshot); + // version check against meta version (5.5.4) is deferred to allow old + // snapshot to be used in rollback protection + // Client workflow 5.5.5: check for rollback attack + if (this.snapshot) { + Object.entries(this.snapshot.signed.meta).forEach(([fileName, fileInfo]) => { + const newFileInfo = newSnapshot.signed.meta[fileName]; + if (!newFileInfo) { + throw new error_1.RepositoryError(`Missing file ${fileName} in new snapshot`); + } + if (newFileInfo.version < fileInfo.version) { + throw new error_1.BadVersionError(`New version ${newFileInfo.version} of ${fileName} is less than current version ${fileInfo.version}`); + } + }); + } + this.trustedSet.snapshot = newSnapshot; + // snapshot is loaded, but we raise if it's not valid _final_ snapshot + // Client workflow 5.5.4 & 5.5.6 + this.checkFinalSnapsnot(); + return newSnapshot; + } + updateDelegatedTargets(bytesBuffer, roleName, delegatorName) { + if (!this.snapshot) { + throw new error_1.RuntimeError('Cannot update delegated targets before snapshot'); + } + // Targets cannot be loaded if final snapshot is expired or its version + // does not match meta version in timestamp. + this.checkFinalSnapsnot(); + const delegator = this.trustedSet[delegatorName]; + if (!delegator) { + throw new error_1.RuntimeError(`No trusted ${delegatorName} metadata`); + } + // Extract metadata for the delegated role from snapshot + const meta = this.snapshot.signed.meta?.[`${roleName}.json`]; + if (!meta) { + throw new error_1.RepositoryError(`Missing ${roleName}.json in snapshot`); + } + // Client workflow 5.6.2: check against snapshot role's targets hash + meta.verify(bytesBuffer); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const data = JSON.parse(bytesBuffer.toString('utf8')); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const newDelegate = models_1.Metadata.fromJSON(models_1.MetadataKind.Targets, data); + if (newDelegate.signed.type != models_1.MetadataKind.Targets) { + throw new error_1.RepositoryError(`Expected 'targets', got ${newDelegate.signed.type}`); + } + // Client workflow 5.6.3: check for arbitrary software attack + delegator.verifyDelegate(roleName, newDelegate); + // Client workflow 5.6.4: Check against snapshot role’s targets version + const version = newDelegate.signed.version; + if (version != meta.version) { + throw new error_1.BadVersionError(`Version ${version} of ${roleName} does not match snapshot version ${meta.version}`); + } + // Client workflow 5.6.5: check for a freeze attack + if (newDelegate.signed.isExpired(this.referenceTime)) { + throw new error_1.ExpiredMetadataError(`${roleName}.json is expired`); + } + this.trustedSet[roleName] = newDelegate; + } + // Verifies and loads data as trusted root metadata. + // Note that an expired initial root is still considered valid. + loadTrustedRoot(bytesBuffer) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const data = JSON.parse(bytesBuffer.toString('utf8')); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const root = models_1.Metadata.fromJSON(models_1.MetadataKind.Root, data); + if (root.signed.type != models_1.MetadataKind.Root) { + throw new error_1.RepositoryError(`Expected 'root', got ${root.signed.type}`); + } + root.verifyDelegate(models_1.MetadataKind.Root, root); + this.trustedSet['root'] = root; + } + checkFinalTimestamp() { + // Timestamp MUST be loaded + if (!this.timestamp) { + throw new ReferenceError('No trusted timestamp metadata'); + } + // Client workflow 5.4.4: check for freeze attack + if (this.timestamp.signed.isExpired(this.referenceTime)) { + throw new error_1.ExpiredMetadataError('Final timestamp.json is expired'); + } + } + checkFinalSnapsnot() { + // Snapshot and timestamp MUST be loaded + if (!this.snapshot) { + throw new ReferenceError('No trusted snapshot metadata'); + } + if (!this.timestamp) { + throw new ReferenceError('No trusted timestamp metadata'); + } + // Client workflow 5.5.6: check for freeze attack + if (this.snapshot.signed.isExpired(this.referenceTime)) { + throw new error_1.ExpiredMetadataError('snapshot.json is expired'); + } + // Client workflow 5.5.4: check against timestamp role’s snapshot version + const snapshotMeta = this.timestamp.signed.snapshotMeta; + if (this.snapshot.signed.version !== snapshotMeta.version) { + throw new error_1.BadVersionError("Snapshot version doesn't match timestamp"); + } + } +} +exports.TrustedMetadataStore = TrustedMetadataStore; diff --git a/node_modules/tuf-js/dist/updater.js b/node_modules/tuf-js/dist/updater.js new file mode 100644 index 0000000000000..3f8614d7d498a --- /dev/null +++ b/node_modules/tuf-js/dist/updater.js @@ -0,0 +1,373 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Updater = void 0; +const models_1 = require("@tufjs/models"); +const debug_1 = __importDefault(require("debug")); +const fs = __importStar(require("fs")); +const path = __importStar(require("path")); +const package_json_1 = require("../package.json"); +const config_1 = require("./config"); +const error_1 = require("./error"); +const fetcher_1 = require("./fetcher"); +const store_1 = require("./store"); +const url = __importStar(require("./utils/url")); +const log = (0, debug_1.default)('tuf:cache'); +class Updater { + dir; + metadataBaseUrl; + targetDir; + targetBaseUrl; + forceCache; + trustedSet; + config; + fetcher; + constructor(options) { + const { metadataDir, metadataBaseUrl, targetDir, targetBaseUrl, fetcher, config, } = options; + this.dir = metadataDir; + this.metadataBaseUrl = metadataBaseUrl; + this.targetDir = targetDir; + this.targetBaseUrl = targetBaseUrl; + this.forceCache = options.forceCache ?? false; + const data = this.loadLocalMetadata(models_1.MetadataKind.Root); + this.trustedSet = new store_1.TrustedMetadataStore(data); + this.config = { ...config_1.defaultConfig, ...config }; + const userAgent = config?.userAgent + ? `${config.userAgent} tuf-js/${package_json_1.version}` + : `tuf-js/${package_json_1.version}`; + this.fetcher = + fetcher || + new fetcher_1.DefaultFetcher({ + userAgent, + timeout: this.config.fetchTimeout, + retry: this.config.fetchRetries ?? this.config.fetchRetry, + }); + } + // refresh and load the metadata before downloading the target + // refresh should be called once after the client is initialized + async refresh() { + // If forceCache is true, try to load the timestamp from local storage + // without fetching it from the remote. Otherwise, load the root and + // timestamp from the remote per the TUF spec. + if (this.forceCache) { + // If anything fails, load the root and timestamp from the remote. This + // should cover any situation where the local metadata is corrupted or + // expired. + try { + await this.loadTimestamp({ checkRemote: false }); + } + catch (error) { + await this.loadRoot(); + await this.loadTimestamp(); + } + } + else { + await this.loadRoot(); + await this.loadTimestamp(); + } + await this.loadSnapshot(); + await this.loadTargets(models_1.MetadataKind.Targets, models_1.MetadataKind.Root); + } + // Returns the TargetFile instance with information for the given target path. + // + // Implicitly calls refresh if it hasn't already been called. + async getTargetInfo(targetPath) { + if (!this.trustedSet.targets) { + await this.refresh(); + } + return this.preorderDepthFirstWalk(targetPath); + } + async downloadTarget(targetInfo, filePath, targetBaseUrl) { + const targetPath = filePath || this.generateTargetPath(targetInfo); + if (!targetBaseUrl) { + if (!this.targetBaseUrl) { + throw new error_1.ValueError('Target base URL not set'); + } + targetBaseUrl = this.targetBaseUrl; + } + let targetFilePath = targetInfo.path; + const consistentSnapshot = this.trustedSet.root.signed.consistentSnapshot; + if (consistentSnapshot && this.config.prefixTargetsWithHash) { + const hashes = Object.values(targetInfo.hashes); + const { dir, base } = path.parse(targetFilePath); + const filename = `${hashes[0]}.${base}`; + targetFilePath = dir ? `${dir}/${filename}` : filename; + } + const targetUrl = url.join(targetBaseUrl, targetFilePath); + // Client workflow 5.7.3: download target file + await this.fetcher.downloadFile(targetUrl, targetInfo.length, async (fileName) => { + // Verify hashes and length of downloaded file + await targetInfo.verify(fs.createReadStream(fileName)); + // Copy file to target path + log('WRITE %s', targetPath); + fs.copyFileSync(fileName, targetPath); + }); + return targetPath; + } + async findCachedTarget(targetInfo, filePath) { + if (!filePath) { + filePath = this.generateTargetPath(targetInfo); + } + try { + if (fs.existsSync(filePath)) { + await targetInfo.verify(fs.createReadStream(filePath)); + return filePath; + } + } + catch (error) { + return; // File not found + } + return; // File not found + } + loadLocalMetadata(fileName) { + const filePath = path.join(this.dir, `${fileName}.json`); + log('READ %s', filePath); + return fs.readFileSync(filePath); + } + // Sequentially load and persist on local disk every newer root metadata + // version available on the remote. + // Client workflow 5.3: update root role + async loadRoot() { + // Client workflow 5.3.2: version of trusted root metadata file + const rootVersion = this.trustedSet.root.signed.version; + const lowerBound = rootVersion + 1; + const upperBound = lowerBound + this.config.maxRootRotations; + for (let version = lowerBound; version < upperBound; version++) { + const rootUrl = url.join(this.metadataBaseUrl, `${version}.root.json`); + try { + // Client workflow 5.3.3: download new root metadata file + const bytesData = await this.fetcher.downloadBytes(rootUrl, this.config.rootMaxLength); + // Client workflow 5.3.4 - 5.4.7 + this.trustedSet.updateRoot(bytesData); + // Client workflow 5.3.8: persist root metadata file + this.persistMetadata(models_1.MetadataKind.Root, bytesData); + } + catch (error) { + if (error instanceof error_1.DownloadHTTPError) { + // 404/403 means current root is newest available + if ([403, 404].includes(error.statusCode)) { + break; + } + } + throw error; + } + } + } + // Load local and remote timestamp metadata. + // Client workflow 5.4: update timestamp role + async loadTimestamp({ checkRemote } = { checkRemote: true }) { + // Load local and remote timestamp metadata + try { + const data = this.loadLocalMetadata(models_1.MetadataKind.Timestamp); + this.trustedSet.updateTimestamp(data); + // If checkRemote is disabled, return here to avoid fetching the remote + // timestamp metadata. + if (!checkRemote) { + return; + } + } + catch (error) { + // continue + } + //Load from remote (whether local load succeeded or not) + const timestampUrl = url.join(this.metadataBaseUrl, 'timestamp.json'); + // Client workflow 5.4.1: download timestamp metadata file + const bytesData = await this.fetcher.downloadBytes(timestampUrl, this.config.timestampMaxLength); + try { + // Client workflow 5.4.2 - 5.4.4 + this.trustedSet.updateTimestamp(bytesData); + } + catch (error) { + // If new timestamp version is same as current, discardd the new one. + // This is normal and should NOT raise an error. + if (error instanceof error_1.EqualVersionError) { + return; + } + // Re-raise any other error + throw error; + } + // Client workflow 5.4.5: persist timestamp metadata + this.persistMetadata(models_1.MetadataKind.Timestamp, bytesData); + } + // Load local and remote snapshot metadata. + // Client workflow 5.5: update snapshot role + async loadSnapshot() { + //Load local (and if needed remote) snapshot metadata + try { + const data = this.loadLocalMetadata(models_1.MetadataKind.Snapshot); + this.trustedSet.updateSnapshot(data, true); + } + catch (error) { + if (!this.trustedSet.timestamp) { + throw new ReferenceError('No timestamp metadata'); + } + const snapshotMeta = this.trustedSet.timestamp.signed.snapshotMeta; + const maxLength = snapshotMeta.length || this.config.snapshotMaxLength; + const version = this.trustedSet.root.signed.consistentSnapshot + ? snapshotMeta.version + : undefined; + const snapshotUrl = url.join(this.metadataBaseUrl, version ? `${version}.snapshot.json` : 'snapshot.json'); + try { + // Client workflow 5.5.1: download snapshot metadata file + const bytesData = await this.fetcher.downloadBytes(snapshotUrl, maxLength); + // Client workflow 5.5.2 - 5.5.6 + this.trustedSet.updateSnapshot(bytesData); + // Client workflow 5.5.7: persist snapshot metadata file + this.persistMetadata(models_1.MetadataKind.Snapshot, bytesData); + } + catch (error) { + throw new error_1.RuntimeError(`Unable to load snapshot metadata error ${error}`); + } + } + } + // Load local and remote targets metadata. + // Client workflow 5.6: update targets role + async loadTargets(role, parentRole) { + if (this.trustedSet.getRole(role)) { + return this.trustedSet.getRole(role); + } + try { + const buffer = this.loadLocalMetadata(role); + this.trustedSet.updateDelegatedTargets(buffer, role, parentRole); + } + catch (error) { + // Local 'role' does not exist or is invalid: update from remote + if (!this.trustedSet.snapshot) { + throw new ReferenceError('No snapshot metadata'); + } + const metaInfo = this.trustedSet.snapshot.signed.meta[`${role}.json`]; + // TODO: use length for fetching + const maxLength = metaInfo.length || this.config.targetsMaxLength; + const version = this.trustedSet.root.signed.consistentSnapshot + ? metaInfo.version + : undefined; + const encodedRole = encodeURIComponent(role); + const metadataUrl = url.join(this.metadataBaseUrl, version ? `${version}.${encodedRole}.json` : `${encodedRole}.json`); + try { + // Client workflow 5.6.1: download targets metadata file + const bytesData = await this.fetcher.downloadBytes(metadataUrl, maxLength); + // Client workflow 5.6.2 - 5.6.6 + this.trustedSet.updateDelegatedTargets(bytesData, role, parentRole); + // Client workflow 5.6.7: persist targets metadata file + this.persistMetadata(role, bytesData); + } + catch (error) { + throw new error_1.RuntimeError(`Unable to load targets error ${error}`); + } + } + return this.trustedSet.getRole(role); + } + async preorderDepthFirstWalk(targetPath) { + // Interrogates the tree of target delegations in order of appearance + // (which implicitly order trustworthiness), and returns the matching + // target found in the most trusted role. + // List of delegations to be interrogated. A (role, parent role) pair + // is needed to load and verify the delegated targets metadata. + const delegationsToVisit = [ + { + roleName: models_1.MetadataKind.Targets, + parentRoleName: models_1.MetadataKind.Root, + }, + ]; + const visitedRoleNames = new Set(); + // Client workflow 5.6.7: preorder depth-first traversal of the graph of + // target delegations + while (visitedRoleNames.size <= this.config.maxDelegations && + delegationsToVisit.length > 0) { + // Pop the role name from the top of the stack. + const { roleName, parentRoleName } = delegationsToVisit.pop(); + // Skip any visited current role to prevent cycles. + // Client workflow 5.6.7.1: skip already-visited roles + if (visitedRoleNames.has(roleName)) { + continue; + } + // The metadata for 'role_name' must be downloaded/updated before + // its targets, delegations, and child roles can be inspected. + const targets = (await this.loadTargets(roleName, parentRoleName)) + ?.signed; + if (!targets) { + continue; + } + const target = targets.targets?.[targetPath]; + if (target) { + return target; + } + // After preorder check, add current role to set of visited roles. + visitedRoleNames.add(roleName); + if (targets.delegations) { + const childRolesToVisit = []; + // NOTE: This may be a slow operation if there are many delegated roles. + const rolesForTarget = targets.delegations.rolesForTarget(targetPath); + for (const { role: childName, terminating } of rolesForTarget) { + childRolesToVisit.push({ + roleName: childName, + parentRoleName: roleName, + }); + // Client workflow 5.6.7.2.1 + if (terminating) { + delegationsToVisit.splice(0); // empty the array + break; + } + } + childRolesToVisit.reverse(); + delegationsToVisit.push(...childRolesToVisit); + } + } + return; // no matching target found + } + generateTargetPath(targetInfo) { + if (!this.targetDir) { + throw new error_1.ValueError('Target directory not set'); + } + // URL encode target path + const filePath = encodeURIComponent(targetInfo.path); + return path.join(this.targetDir, filePath); + } + persistMetadata(metaDataName, bytesData) { + const encodedName = encodeURIComponent(metaDataName); + try { + const filePath = path.join(this.dir, `${encodedName}.json`); + log('WRITE %s', filePath); + fs.writeFileSync(filePath, bytesData.toString('utf8')); + } + catch (error) { + throw new error_1.PersistError(`Failed to persist metadata ${encodedName} error: ${error}`); + } + } +} +exports.Updater = Updater; diff --git a/node_modules/tuf-js/dist/utils/tmpfile.js b/node_modules/tuf-js/dist/utils/tmpfile.js new file mode 100644 index 0000000000000..923eef6044bcc --- /dev/null +++ b/node_modules/tuf-js/dist/utils/tmpfile.js @@ -0,0 +1,25 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.withTempFile = void 0; +const promises_1 = __importDefault(require("fs/promises")); +const os_1 = __importDefault(require("os")); +const path_1 = __importDefault(require("path")); +// Invokes the given handler with the path to a temporary file. The file +// is deleted after the handler returns. +const withTempFile = async (handler) => withTempDir(async (dir) => handler(path_1.default.join(dir, 'tempfile'))); +exports.withTempFile = withTempFile; +// Invokes the given handler with a temporary directory. The directory is +// deleted after the handler returns. +const withTempDir = async (handler) => { + const tmpDir = await promises_1.default.realpath(os_1.default.tmpdir()); + const dir = await promises_1.default.mkdtemp(tmpDir + path_1.default.sep); + try { + return await handler(dir); + } + finally { + await promises_1.default.rm(dir, { force: true, recursive: true, maxRetries: 3 }); + } +}; diff --git a/node_modules/tuf-js/dist/utils/url.js b/node_modules/tuf-js/dist/utils/url.js new file mode 100644 index 0000000000000..359d1f3ef385b --- /dev/null +++ b/node_modules/tuf-js/dist/utils/url.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.join = join; +const url_1 = require("url"); +function join(base, path) { + return new url_1.URL(ensureTrailingSlash(base) + removeLeadingSlash(path)).toString(); +} +function ensureTrailingSlash(path) { + return path.endsWith('/') ? path : path + '/'; +} +function removeLeadingSlash(path) { + return path.startsWith('/') ? path.slice(1) : path; +} diff --git a/node_modules/tuf-js/package.json b/node_modules/tuf-js/package.json new file mode 100644 index 0000000000000..30d7a95fa5f10 --- /dev/null +++ b/node_modules/tuf-js/package.json @@ -0,0 +1,43 @@ +{ + "name": "tuf-js", + "version": "4.1.0", + "description": "JavaScript implementation of The Update Framework (TUF)", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc --build tsconfig.build.json", + "clean": "rm -rf dist && rm tsconfig.build.tsbuildinfo", + "test": "jest" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/theupdateframework/tuf-js.git" + }, + "files": [ + "dist" + ], + "keywords": [ + "tuf", + "security", + "update" + ], + "author": "bdehamer@github.com", + "license": "MIT", + "bugs": { + "url": "https://github.com/theupdateframework/tuf-js/issues" + }, + "homepage": "https://github.com/theupdateframework/tuf-js/tree/main/packages/client#readme", + "devDependencies": { + "@tufjs/repo-mock": "4.0.1", + "@types/debug": "^4.1.12", + "@types/make-fetch-happen": "^10.0.4" + }, + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } +} diff --git a/node_modules/unique-filename/coverage/__root__/index.html b/node_modules/unique-filename/coverage/__root__/index.html deleted file mode 100644 index cd55391a67a4c..0000000000000 --- a/node_modules/unique-filename/coverage/__root__/index.html +++ /dev/null @@ -1,73 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <title>Code coverage report for __root__/ - - - - - - -
-

Code coverage report for __root__/

-

- Statements: 100% (4 / 4)      - Branches: 100% (2 / 2)      - Functions: 100% (1 / 1)      - Lines: 100% (4 / 4)      - Ignored: none      -

-
All files » __root__/
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.js100%(4 / 4)100%(2 / 2)100%(1 / 1)100%(4 / 4)
-
-
- - - - - - diff --git a/node_modules/unique-filename/coverage/__root__/index.js.html b/node_modules/unique-filename/coverage/__root__/index.js.html deleted file mode 100644 index 02e5768d3fb64..0000000000000 --- a/node_modules/unique-filename/coverage/__root__/index.js.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - Code coverage report for index.js - - - - - - -
-

Code coverage report for index.js

-

- Statements: 100% (4 / 4)      - Branches: 100% (2 / 2)      - Functions: 100% (1 / 1)      - Lines: 100% (4 / 4)      - Ignored: none      -

-
All files » __root__/ » index.js
-
-
-

-
-
1 -2 -3 -4 -5 -6 -7 -8 -9  -1 -  -1 -  -1 -6 -  - 
'use strict'
-var path = require('path')
- 
-var uniqueSlug = require('unique-slug')
- 
-module.exports = function (filepath, prefix, uniq) {
-  return path.join(filepath, (prefix ? prefix + '-' : '') + uniqueSlug(uniq))
-}
- 
- -
- - - - - - diff --git a/node_modules/unique-filename/coverage/base.css b/node_modules/unique-filename/coverage/base.css deleted file mode 100644 index a6a2f3284d022..0000000000000 --- a/node_modules/unique-filename/coverage/base.css +++ /dev/null @@ -1,182 +0,0 @@ -body, html { - margin:0; padding: 0; -} -body { - font-family: Helvetica Neue, Helvetica,Arial; - font-size: 10pt; -} -div.header, div.footer { - background: #eee; - padding: 1em; -} -div.header { - z-index: 100; - position: fixed; - top: 0; - border-bottom: 1px solid #666; - width: 100%; -} -div.footer { - border-top: 1px solid #666; -} -div.body { - margin-top: 10em; -} -div.meta { - font-size: 90%; - text-align: center; -} -h1, h2, h3 { - font-weight: normal; -} -h1 { - font-size: 12pt; -} -h2 { - font-size: 10pt; -} -pre { - font-family: Consolas, Menlo, Monaco, monospace; - margin: 0; - padding: 0; - line-height: 1.3; - font-size: 14px; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} - -div.path { font-size: 110%; } -div.path a:link, div.path a:visited { color: #000; } -table.coverage { border-collapse: collapse; margin:0; padding: 0 } - -table.coverage td { - margin: 0; - padding: 0; - color: #111; - vertical-align: top; -} -table.coverage td.line-count { - width: 50px; - text-align: right; - padding-right: 5px; -} -table.coverage td.line-coverage { - color: #777 !important; - text-align: right; - border-left: 1px solid #666; - border-right: 1px solid #666; -} - -table.coverage td.text { -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 40px; -} -table.coverage td span.cline-neutral { - background: #eee; -} -table.coverage td span.cline-yes { - background: #b5d592; - color: #999; -} -table.coverage td span.cline-no { - background: #fc8c84; -} - -.cstat-yes { color: #111; } -.cstat-no { background: #fc8c84; color: #111; } -.fstat-no { background: #ffc520; color: #111 !important; } -.cbranch-no { background: yellow !important; color: #111; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -.missing-if-branch { - display: inline-block; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: black; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} - -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} - -.entity, .metric { font-weight: bold; } -.metric { display: inline-block; border: 1px solid #333; padding: 0.3em; background: white; } -.metric small { font-size: 80%; font-weight: normal; color: #666; } - -div.coverage-summary table { border-collapse: collapse; margin: 3em; font-size: 110%; } -div.coverage-summary td, div.coverage-summary table th { margin: 0; padding: 0.25em 1em; border-top: 1px solid #666; border-bottom: 1px solid #666; } -div.coverage-summary th { text-align: left; border: 1px solid #666; background: #eee; font-weight: normal; } -div.coverage-summary th.file { border-right: none !important; } -div.coverage-summary th.pic { border-left: none !important; text-align: right; } -div.coverage-summary th.pct { border-right: none !important; } -div.coverage-summary th.abs { border-left: none !important; text-align: right; } -div.coverage-summary td.pct { text-align: right; border-left: 1px solid #666; } -div.coverage-summary td.abs { text-align: right; font-size: 90%; color: #444; border-right: 1px solid #666; } -div.coverage-summary td.file { border-left: 1px solid #666; white-space: nowrap; } -div.coverage-summary td.pic { min-width: 120px !important; } -div.coverage-summary a:link { text-decoration: none; color: #000; } -div.coverage-summary a:visited { text-decoration: none; color: #777; } -div.coverage-summary a:hover { text-decoration: underline; } -div.coverage-summary tfoot td { border-top: 1px solid #666; } - -div.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -div.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -div.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} - -.high { background: #b5d592 !important; } -.medium { background: #ffe87c !important; } -.low { background: #fc8c84 !important; } - -span.cover-fill, span.cover-empty { - display:inline-block; - border:1px solid #444; - background: white; - height: 12px; -} -span.cover-fill { - background: #ccc; - border-right: 1px solid #444; -} -span.cover-empty { - background: white; - border-left: none; -} -span.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } diff --git a/node_modules/unique-filename/coverage/index.html b/node_modules/unique-filename/coverage/index.html deleted file mode 100644 index b10d186cc3978..0000000000000 --- a/node_modules/unique-filename/coverage/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - Code coverage report for All files - - - - - - -
-

Code coverage report for All files

-

- Statements: 100% (4 / 4)      - Branches: 100% (2 / 2)      - Functions: 100% (1 / 1)      - Lines: 100% (4 / 4)      - Ignored: none      -

-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
__root__/100%(4 / 4)100%(2 / 2)100%(1 / 1)100%(4 / 4)
-
-
- - - - - - diff --git a/node_modules/unique-filename/coverage/prettify.css b/node_modules/unique-filename/coverage/prettify.css deleted file mode 100644 index b317a7cda31a4..0000000000000 --- a/node_modules/unique-filename/coverage/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/node_modules/unique-filename/coverage/prettify.js b/node_modules/unique-filename/coverage/prettify.js deleted file mode 100644 index ef51e03866898..0000000000000 --- a/node_modules/unique-filename/coverage/prettify.js +++ /dev/null @@ -1 +0,0 @@ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/node_modules/unique-filename/coverage/sort-arrow-sprite.png b/node_modules/unique-filename/coverage/sort-arrow-sprite.png deleted file mode 100644 index 03f704a609c6f..0000000000000 Binary files a/node_modules/unique-filename/coverage/sort-arrow-sprite.png and /dev/null differ diff --git a/node_modules/unique-filename/coverage/sorter.js b/node_modules/unique-filename/coverage/sorter.js deleted file mode 100644 index 6afb736c39fb1..0000000000000 --- a/node_modules/unique-filename/coverage/sorter.js +++ /dev/null @@ -1,156 +0,0 @@ -var addSorting = (function () { - "use strict"; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { return document.querySelector('.coverage-summary table'); } - // returns the thead element of the summary table - function getTableHeader() { return getTable().querySelector('thead tr'); } - // returns the tbody element of the summary table - function getTableBody() { return getTable().querySelector('tbody'); } - // returns the th element for nth column - function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function (a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function (a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function () { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i =0 ; i < cols.length; i += 1) { - if (cols[i].sortable) { - el = getNthColumn(i).querySelector('.sorter'); - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function () { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(cols); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/node_modules/unique-filename/index.js b/node_modules/unique-filename/index.js deleted file mode 100644 index 02bf1e273143c..0000000000000 --- a/node_modules/unique-filename/index.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' -var path = require('path') - -var uniqueSlug = require('unique-slug') - -module.exports = function (filepath, prefix, uniq) { - return path.join(filepath, (prefix ? prefix + '-' : '') + uniqueSlug(uniq)) -} diff --git a/node_modules/unique-filename/lib/index.js b/node_modules/unique-filename/lib/index.js new file mode 100644 index 0000000000000..d067d2e709809 --- /dev/null +++ b/node_modules/unique-filename/lib/index.js @@ -0,0 +1,7 @@ +var path = require('path') + +var uniqueSlug = require('unique-slug') + +module.exports = function (filepath, prefix, uniq) { + return path.join(filepath, (prefix ? prefix + '-' : '') + uniqueSlug(uniq)) +} diff --git a/node_modules/unique-filename/package.json b/node_modules/unique-filename/package.json index bc429aa44b079..57892db1fc2c6 100644 --- a/node_modules/unique-filename/package.json +++ b/node_modules/unique-filename/package.json @@ -1,27 +1,53 @@ { "name": "unique-filename", - "version": "1.1.1", + "version": "5.0.0", "description": "Generate a unique filename for use in temporary directories or caches.", - "main": "index.js", + "main": "lib/index.js", "scripts": { - "test": "standard && tap test" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/iarna/unique-filename.git" + "url": "git+https://github.com/npm/unique-filename.git" }, "keywords": [], - "author": "Rebecca Turner (http://re-becca.org/)", + "author": "GitHub Inc.", "license": "ISC", "bugs": { "url": "https://github.com/iarna/unique-filename/issues" }, "homepage": "https://github.com/iarna/unique-filename", "devDependencies": { - "standard": "^5.4.1", - "tap": "^2.3.1" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, "dependencies": { - "unique-slug": "^2.0.0" + "unique-slug": "^6.0.0" + }, + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/unique-filename/test/index.js b/node_modules/unique-filename/test/index.js deleted file mode 100644 index 105b4e52e8b40..0000000000000 --- a/node_modules/unique-filename/test/index.js +++ /dev/null @@ -1,23 +0,0 @@ -'sue strict' -var t = require('tap') -var uniqueFilename = require('../index.js') - -t.plan(6) - -var randomTmpfile = uniqueFilename('tmp') -t.like(randomTmpfile, /^tmp.[a-f0-9]{8}$/, 'random tmp file') - -var randomAgain = uniqueFilename('tmp') -t.notEqual(randomAgain, randomTmpfile, 'random tmp files are not the same') - -var randomPrefixedTmpfile = uniqueFilename('tmp', 'my-test') -t.like(randomPrefixedTmpfile, /^tmp.my-test-[a-f0-9]{8}$/, 'random prefixed tmp file') - -var randomPrefixedAgain = uniqueFilename('tmp', 'my-test') -t.notEqual(randomPrefixedAgain, randomPrefixedTmpfile, 'random prefixed tmp files are not the same') - -var uniqueTmpfile = uniqueFilename('tmp', 'testing', '/my/thing/to/uniq/on') -t.like(uniqueTmpfile, /^tmp.testing-7ddd44c0$/, 'unique filename') - -var uniqueAgain = uniqueFilename('tmp', 'testing', '/my/thing/to/uniq/on') -t.is(uniqueTmpfile, uniqueAgain, 'same unique string component produces same filename') diff --git a/node_modules/unique-slug/index.js b/node_modules/unique-slug/index.js deleted file mode 100644 index fa4761ad2e258..0000000000000 --- a/node_modules/unique-slug/index.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' -var MurmurHash3 = require('imurmurhash') - -module.exports = function (uniq) { - if (uniq) { - var hash = new MurmurHash3(uniq) - return ('00000000' + hash.result().toString(16)).substr(-8) - } else { - return (Math.random().toString(16) + '0000000').substr(2, 8) - } -} diff --git a/node_modules/unique-slug/lib/index.js b/node_modules/unique-slug/lib/index.js new file mode 100644 index 0000000000000..1bac84d95d730 --- /dev/null +++ b/node_modules/unique-slug/lib/index.js @@ -0,0 +1,11 @@ +'use strict' +var MurmurHash3 = require('imurmurhash') + +module.exports = function (uniq) { + if (uniq) { + var hash = new MurmurHash3(uniq) + return ('00000000' + hash.result().toString(16)).slice(-8) + } else { + return (Math.random().toString(16) + '0000000').slice(2, 10) + } +} diff --git a/node_modules/unique-slug/package.json b/node_modules/unique-slug/package.json index 2142e68561f5d..88df517c0335e 100644 --- a/node_modules/unique-slug/package.json +++ b/node_modules/unique-slug/package.json @@ -1,23 +1,49 @@ { "name": "unique-slug", - "version": "2.0.2", + "version": "6.0.0", "description": "Generate a unique character string suitible for use in files and URLs.", - "main": "index.js", + "main": "lib/index.js", "scripts": { - "test": "standard && tap --coverage test" + "test": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "keywords": [], - "author": "Rebecca Turner (http://re-becca.org)", + "author": "GitHub Inc.", "license": "ISC", "devDependencies": { - "standard": "^12.0.1", - "tap": "^12.7.0" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, "repository": { "type": "git", - "url": "git://github.com/iarna/unique-slug.git" + "url": "git+https://github.com/npm/unique-slug.git" }, "dependencies": { "imurmurhash": "^0.1.4" + }, + "files": [ + "bin/", + "lib/" + ], + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": true + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/node_modules/unique-slug/test/index.js b/node_modules/unique-slug/test/index.js deleted file mode 100644 index 0f4ccad04af6f..0000000000000 --- a/node_modules/unique-slug/test/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' -var t = require('tap') -var uniqueSlug = require('../index.js') - -t.plan(5) -var slugA = uniqueSlug() -t.is(slugA.length, 8, 'random slugs are 8 chars') -t.notEqual(slugA, uniqueSlug(), "two slugs aren't the same") -var base = '/path/to/thingy' -var slugB = uniqueSlug(base) -t.is(slugB.length, 8, 'string based slugs are 8 chars') -t.is(slugB, uniqueSlug(base), 'two string based slugs, from the same string are the same') -t.notEqual(slugB, uniqueSlug(slugA), 'two string based slongs, from diff strings are different') diff --git a/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/AUTHORS b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/AUTHORS new file mode 100644 index 0000000000000..257a76b9484c1 --- /dev/null +++ b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/AUTHORS @@ -0,0 +1,4 @@ +C. Scott Ananian (http://cscott.net) +Kyle E. Mitchell (https://kemitchell.com) +Shinnosuke Watanabe +Antoine Motet diff --git a/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/LICENSE b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/LICENSE new file mode 100644 index 0000000000000..831618eaba6c8 --- /dev/null +++ b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2015 Kyle E. Mitchell & other authors listed in AUTHORS + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/index.js b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/index.js new file mode 100644 index 0000000000000..52fab560aea70 --- /dev/null +++ b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/index.js @@ -0,0 +1,8 @@ +'use strict' + +var scan = require('./scan') +var parse = require('./parse') + +module.exports = function (source) { + return parse(scan(source)) +} diff --git a/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/package.json b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/package.json new file mode 100644 index 0000000000000..c9edc9f939cdf --- /dev/null +++ b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/package.json @@ -0,0 +1,39 @@ +{ + "name": "spdx-expression-parse", + "description": "parse SPDX license expressions", + "version": "3.0.1", + "author": "Kyle E. Mitchell (https://kemitchell.com)", + "files": [ + "AUTHORS", + "index.js", + "parse.js", + "scan.js" + ], + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + }, + "devDependencies": { + "defence-cli": "^3.0.1", + "replace-require-self": "^1.0.0", + "standard": "^14.1.0" + }, + "keywords": [ + "SPDX", + "law", + "legal", + "license", + "metadata", + "package", + "package.json", + "standards" + ], + "license": "MIT", + "repository": "jslicense/spdx-expression-parse.js", + "scripts": { + "lint": "standard", + "test:readme": "defence -i javascript README.md | replace-require-self | node", + "test:suite": "node test.js", + "test": "npm run test:suite && npm run test:readme" + } +} diff --git a/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/parse.js b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/parse.js new file mode 100644 index 0000000000000..5a00b45c5799c --- /dev/null +++ b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/parse.js @@ -0,0 +1,138 @@ +'use strict' + +// The ABNF grammar in the spec is totally ambiguous. +// +// This parser follows the operator precedence defined in the +// `Order of Precedence and Parentheses` section. + +module.exports = function (tokens) { + var index = 0 + + function hasMore () { + return index < tokens.length + } + + function token () { + return hasMore() ? tokens[index] : null + } + + function next () { + if (!hasMore()) { + throw new Error() + } + index++ + } + + function parseOperator (operator) { + var t = token() + if (t && t.type === 'OPERATOR' && operator === t.string) { + next() + return t.string + } + } + + function parseWith () { + if (parseOperator('WITH')) { + var t = token() + if (t && t.type === 'EXCEPTION') { + next() + return t.string + } + throw new Error('Expected exception after `WITH`') + } + } + + function parseLicenseRef () { + // TODO: Actually, everything is concatenated into one string + // for backward-compatibility but it could be better to return + // a nice structure. + var begin = index + var string = '' + var t = token() + if (t.type === 'DOCUMENTREF') { + next() + string += 'DocumentRef-' + t.string + ':' + if (!parseOperator(':')) { + throw new Error('Expected `:` after `DocumentRef-...`') + } + } + t = token() + if (t.type === 'LICENSEREF') { + next() + string += 'LicenseRef-' + t.string + return { license: string } + } + index = begin + } + + function parseLicense () { + var t = token() + if (t && t.type === 'LICENSE') { + next() + var node = { license: t.string } + if (parseOperator('+')) { + node.plus = true + } + var exception = parseWith() + if (exception) { + node.exception = exception + } + return node + } + } + + function parseParenthesizedExpression () { + var left = parseOperator('(') + if (!left) { + return + } + + var expr = parseExpression() + + if (!parseOperator(')')) { + throw new Error('Expected `)`') + } + + return expr + } + + function parseAtom () { + return ( + parseParenthesizedExpression() || + parseLicenseRef() || + parseLicense() + ) + } + + function makeBinaryOpParser (operator, nextParser) { + return function parseBinaryOp () { + var left = nextParser() + if (!left) { + return + } + + if (!parseOperator(operator)) { + return left + } + + var right = parseBinaryOp() + if (!right) { + throw new Error('Expected expression') + } + return { + left: left, + conjunction: operator.toLowerCase(), + right: right + } + } + } + + var parseAnd = makeBinaryOpParser('AND', parseAtom) + var parseExpression = makeBinaryOpParser('OR', parseAnd) + + var node = parseExpression() + if (!node || hasMore()) { + throw new Error('Syntax error') + } + return node +} diff --git a/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/scan.js b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/scan.js new file mode 100644 index 0000000000000..b74fce2e2c663 --- /dev/null +++ b/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse/scan.js @@ -0,0 +1,131 @@ +'use strict' + +var licenses = [] + .concat(require('spdx-license-ids')) + .concat(require('spdx-license-ids/deprecated')) +var exceptions = require('spdx-exceptions') + +module.exports = function (source) { + var index = 0 + + function hasMore () { + return index < source.length + } + + // `value` can be a regexp or a string. + // If it is recognized, the matching source string is returned and + // the index is incremented. Otherwise `undefined` is returned. + function read (value) { + if (value instanceof RegExp) { + var chars = source.slice(index) + var match = chars.match(value) + if (match) { + index += match[0].length + return match[0] + } + } else { + if (source.indexOf(value, index) === index) { + index += value.length + return value + } + } + } + + function skipWhitespace () { + read(/[ ]*/) + } + + function operator () { + var string + var possibilities = ['WITH', 'AND', 'OR', '(', ')', ':', '+'] + for (var i = 0; i < possibilities.length; i++) { + string = read(possibilities[i]) + if (string) { + break + } + } + + if (string === '+' && index > 1 && source[index - 2] === ' ') { + throw new Error('Space before `+`') + } + + return string && { + type: 'OPERATOR', + string: string + } + } + + function idstring () { + return read(/[A-Za-z0-9-.]+/) + } + + function expectIdstring () { + var string = idstring() + if (!string) { + throw new Error('Expected idstring at offset ' + index) + } + return string + } + + function documentRef () { + if (read('DocumentRef-')) { + var string = expectIdstring() + return { type: 'DOCUMENTREF', string: string } + } + } + + function licenseRef () { + if (read('LicenseRef-')) { + var string = expectIdstring() + return { type: 'LICENSEREF', string: string } + } + } + + function identifier () { + var begin = index + var string = idstring() + + if (licenses.indexOf(string) !== -1) { + return { + type: 'LICENSE', + string: string + } + } else if (exceptions.indexOf(string) !== -1) { + return { + type: 'EXCEPTION', + string: string + } + } + + index = begin + } + + // Tries to read the next token. Returns `undefined` if no token is + // recognized. + function parseToken () { + // Ordering matters + return ( + operator() || + documentRef() || + licenseRef() || + identifier() + ) + } + + var tokens = [] + while (hasMore()) { + skipWhitespace() + if (!hasMore()) { + break + } + + var token = parseToken() + if (!token) { + throw new Error('Unexpected `' + source[index] + + '` at offset ' + index) + } + + tokens.push(token) + } + return tokens +} diff --git a/node_modules/validate-npm-package-name/lib/builtin-modules.json b/node_modules/validate-npm-package-name/lib/builtin-modules.json new file mode 100644 index 0000000000000..252c24f3ec671 --- /dev/null +++ b/node_modules/validate-npm-package-name/lib/builtin-modules.json @@ -0,0 +1 @@ +["_http_agent","_http_client","_http_common","_http_incoming","_http_outgoing","_http_server","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_wrap","_stream_writable","_tls_common","_tls_wrap","assert","assert/strict","async_hooks","buffer","child_process","cluster","console","constants","crypto","dgram","diagnostics_channel","dns","dns/promises","domain","events","fs","fs/promises","http","http2","https","inspector","inspector/promises","module","net","os","path","path/posix","path/win32","perf_hooks","process","punycode","querystring","readline","readline/promises","repl","stream","stream/consumers","stream/promises","stream/web","string_decoder","sys","timers","timers/promises","tls","trace_events","tty","url","util","util/types","v8","vm","wasi","worker_threads","zlib","node:sea","node:sqlite","node:test","node:test/reporters"] diff --git a/node_modules/validate-npm-package-name/lib/index.js b/node_modules/validate-npm-package-name/lib/index.js index e7e612bfbdf4d..93d77b76b3dd2 100644 --- a/node_modules/validate-npm-package-name/lib/index.js +++ b/node_modules/validate-npm-package-name/lib/index.js @@ -1,8 +1,8 @@ 'use strict' +const builtins = require('./builtin-modules.json') var scopedPackagePattern = new RegExp('^(?:@([^/]+?)[/])?([^/]+?)$') -var builtins = require('builtins') -var blacklist = [ +var exclusionList = [ 'node_modules', 'favicon.ico', ] @@ -30,10 +30,14 @@ function validate (name) { errors.push('name length must be greater than zero') } - if (name.match(/^\./)) { + if (name.startsWith('.')) { errors.push('name cannot start with a period') } + if (name.startsWith('-')) { + errors.push('name cannot start with a hyphen') + } + if (name.match(/^_/)) { errors.push('name cannot start with an underscore') } @@ -43,20 +47,18 @@ function validate (name) { } // No funny business - blacklist.forEach(function (blacklistedName) { - if (name.toLowerCase() === blacklistedName) { - errors.push(blacklistedName + ' is a blacklisted name') + exclusionList.forEach(function (excludedName) { + if (name.toLowerCase() === excludedName) { + errors.push(excludedName + ' is not a valid package name') } }) // Generate warnings for stuff that used to be allowed // core module names like http, events, util, etc - builtins({ version: '*' }).forEach(function (builtin) { - if (name.toLowerCase() === builtin) { - warnings.push(builtin + ' is a core module name') - } - }) + if (builtins.includes(name.toLowerCase())) { + warnings.push(name + ' is a core module name') + } if (name.length > 214) { warnings.push('name can no longer contain more than 214 characters') @@ -77,6 +79,11 @@ function validate (name) { if (nameMatch) { var user = nameMatch[1] var pkg = nameMatch[2] + + if (pkg.startsWith('.')) { + errors.push('name cannot start with a period') + } + if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) { return done(warnings, errors) } diff --git a/node_modules/validate-npm-package-name/package.json b/node_modules/validate-npm-package-name/package.json index fa9a6920d411f..754742cbf6f1c 100644 --- a/node_modules/validate-npm-package-name/package.json +++ b/node_modules/validate-npm-package-name/package.json @@ -1,37 +1,34 @@ { "name": "validate-npm-package-name", - "version": "4.0.0", + "version": "7.0.2", "description": "Give me a string and I'll tell you if it's a valid npm package name", "main": "lib/", "directories": { "test": "test" }, - "dependencies": { - "builtins": "^5.0.0" - }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.2.1", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^6.0.0", + "@npmcli/template-oss": "4.28.1" }, "scripts": { + "builtin-fixture": "node -e \"console.log(JSON.stringify(require('node:module').builtinModules))\" > ./lib/builtin-modules.json", "cov:test": "TAP_FLAGS='--cov' npm run test:code", "test:code": "tap ${TAP_FLAGS:-'--'} test/*.js", "test:style": "standard", - "test": "tap", - "lint": "eslint \"**/*.js\"", + "test": "node --test './test/**/*.js'", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "snap": "tap", - "posttest": "npm run lint" + "lintfix": "npm run eslint -- --fix", + "snap": "node --test --test-update-snapshots './test/**/*.js'", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", + "test:node20": "node --test test", + "test:cover": "node --test --experimental-test-coverage --test-timeout=3000 --test-coverage-lines=100 --test-coverage-functions=100 --test-coverage-branches=100 './test/**/*.js'" }, "repository": { "type": "git", - "url": "https://github.com/npm/validate-npm-package-name.git" + "url": "git+https://github.com/npm/validate-npm-package-name.git" }, "keywords": [ "npm", @@ -50,15 +47,13 @@ "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.2.1" - }, - "tap": { - "statements": 88, - "branches": 92, - "lines": 88 + "version": "4.28.1", + "publish": true, + "testRunner": "node:test", + "latestCiVersion": 24 } } diff --git a/node_modules/walk-up-path/LICENSE b/node_modules/walk-up-path/LICENSE index 05eeeb88c2ef4..d710582667b8b 100644 --- a/node_modules/walk-up-path/LICENSE +++ b/node_modules/walk-up-path/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) Isaac Z. Schlueter +Copyright (c) 2020-2023 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 diff --git a/node_modules/walk-up-path/dist/commonjs/index.js b/node_modules/walk-up-path/dist/commonjs/index.js new file mode 100644 index 0000000000000..9295d00ca85b1 --- /dev/null +++ b/node_modules/walk-up-path/dist/commonjs/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.walkUp = void 0; +const path_1 = require("path"); +const walkUp = function* (path) { + for (path = (0, path_1.resolve)(path); path;) { + yield path; + const pp = (0, path_1.dirname)(path); + if (pp === path) { + break; + } + else { + path = pp; + } + } +}; +exports.walkUp = walkUp; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/walk-up-path/dist/commonjs/package.json b/node_modules/walk-up-path/dist/commonjs/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/node_modules/walk-up-path/dist/commonjs/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/node_modules/walk-up-path/dist/esm/index.js b/node_modules/walk-up-path/dist/esm/index.js new file mode 100644 index 0000000000000..93f37e1d81968 --- /dev/null +++ b/node_modules/walk-up-path/dist/esm/index.js @@ -0,0 +1,14 @@ +import { dirname, resolve } from 'path'; +export const walkUp = function* (path) { + for (path = resolve(path); path;) { + yield path; + const pp = dirname(path); + if (pp === path) { + break; + } + else { + path = pp; + } + } +}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/node_modules/walk-up-path/dist/esm/package.json b/node_modules/walk-up-path/dist/esm/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/node_modules/walk-up-path/dist/esm/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/node_modules/walk-up-path/index.js b/node_modules/walk-up-path/index.js deleted file mode 100644 index 05524a6c055eb..0000000000000 --- a/node_modules/walk-up-path/index.js +++ /dev/null @@ -1,11 +0,0 @@ -const {dirname, resolve} = require('path') -module.exports = function* (path) { - for (path = resolve(path); path;) { - yield path - const pp = dirname(path) - if (pp === path) - path = null - else - path = pp - } -} diff --git a/node_modules/walk-up-path/package.json b/node_modules/walk-up-path/package.json index df69d9238514c..4f6d95363297e 100644 --- a/node_modules/walk-up-path/package.json +++ b/node_modules/walk-up-path/package.json @@ -1,8 +1,8 @@ { "name": "walk-up-path", - "version": "1.0.0", + "version": "4.0.0", "files": [ - "index.js" + "dist" ], "description": "Given a path string, return a generator that walks up the path, emitting each dirname.", "repository": { @@ -12,17 +12,60 @@ "author": "Isaac Z. Schlueter (https://izs.me)", "license": "ISC", "scripts": { - "test": "tap", - "snap": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags", + "prepare": "tshy", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "tap", + "snap": "tap", + "format": "prettier --write . --log-level warn", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts" }, - "tap": { - "check-coverage": true + "prettier": { + "experimentalTernaries": true, + "semi": false, + "printWidth": 75, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" }, "devDependencies": { - "tap": "^14.10.7", - "require-inject": "^1.4.4" + "@types/node": "^20.14.10", + "prettier": "^3.3.2", + "tap": "^20.0.3", + "tshy": "^3.0.0", + "typedoc": "^0.26.3" + }, + "type": "module", + "tshy": { + "exports": { + "./package.json": "./package.json", + ".": "./src/index.ts" + } + }, + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js", + "engines": { + "node": "20 || >=22" } } diff --git a/node_modules/wcwidth/LICENSE b/node_modules/wcwidth/LICENSE deleted file mode 100644 index 313ef1e888e41..0000000000000 --- a/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/node_modules/wcwidth/Readme.md b/node_modules/wcwidth/Readme.md deleted file mode 100644 index 0649a319872be..0000000000000 --- a/node_modules/wcwidth/Readme.md +++ /dev/null @@ -1,33 +0,0 @@ -# wcwidth - -Determine columns needed for a fixed-size wide-character string - ----- - -wcwidth is a simple JavaScript port of [wcwidth](http://man7.org/linux/man-pages/man3/wcswidth.3.html) implemented in C by Markus Kuhn. - -JavaScript port [originally](https://github.com/mycoboco/wcwidth.js) written by Woong Jun (http://code.woong.org/) - -## Example - -```js -'한'.length // => 1 -wcwidth('한'); // => 2 - -'한글'.length // => 2 -wcwidth('한글'); // => 4 -``` - -`wcwidth()` and its string version, `wcswidth()` are defined by IEEE Std -1002.1-2001, a.k.a. POSIX.1-2001, and return the number of columns used -to represent the given wide character and string. - -Markus's implementation assumes the wide character given to those -functions to be encoded in ISO 10646, which is almost true for -JavaScript's characters. - -[Further explaination here](docs) - -## License - -MIT diff --git a/node_modules/wcwidth/combining.js b/node_modules/wcwidth/combining.js deleted file mode 100644 index dac9789d35f0f..0000000000000 --- a/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/node_modules/wcwidth/docs/index.md b/node_modules/wcwidth/docs/index.md deleted file mode 100644 index 5c5126d03287b..0000000000000 --- a/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/node_modules/wcwidth/index.js b/node_modules/wcwidth/index.js deleted file mode 100644 index 48cbb6020aebe..0000000000000 --- a/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/node_modules/wcwidth/package.json b/node_modules/wcwidth/package.json deleted file mode 100644 index eb2df9d0076d2..0000000000000 --- a/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/node_modules/wcwidth/test/index.js b/node_modules/wcwidth/test/index.js deleted file mode 100644 index 5180599a2ff28..0000000000000 --- a/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/node_modules/which/bin/node-which b/node_modules/which/bin/node-which deleted file mode 100755 index 7cee3729eebdd..0000000000000 --- a/node_modules/which/bin/node-which +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env node -var which = require("../") -if (process.argv.length < 3) - usage() - -function usage () { - console.error('usage: which [-as] program ...') - process.exit(1) -} - -var all = false -var silent = false -var dashdash = false -var args = process.argv.slice(2).filter(function (arg) { - if (dashdash || !/^-/.test(arg)) - return true - - if (arg === '--') { - dashdash = true - return false - } - - var flags = arg.substr(1).split('') - for (var f = 0; f < flags.length; f++) { - var flag = flags[f] - switch (flag) { - case 's': - silent = true - break - case 'a': - all = true - break - default: - console.error('which: illegal option -- ' + flag) - usage() - } - } - return false -}) - -process.exit(args.reduce(function (pv, current) { - try { - var f = which.sync(current, { all: all }) - if (all) - f = f.join('\n') - if (!silent) - console.log(f) - return pv; - } catch (e) { - return 1; - } -}, 0)) diff --git a/node_modules/which/bin/which.js b/node_modules/which/bin/which.js new file mode 100755 index 0000000000000..6df16f21acf93 --- /dev/null +++ b/node_modules/which/bin/which.js @@ -0,0 +1,52 @@ +#!/usr/bin/env node + +const which = require('../lib') +const argv = process.argv.slice(2) + +const usage = (err) => { + if (err) { + console.error(`which: ${err}`) + } + console.error('usage: which [-as] program ...') + process.exit(1) +} + +if (!argv.length) { + return usage() +} + +let dashdash = false +const [commands, flags] = argv.reduce((acc, arg) => { + if (dashdash || arg === '--') { + dashdash = true + return acc + } + + if (!/^-/.test(arg)) { + acc[0].push(arg) + return acc + } + + for (const flag of arg.slice(1).split('')) { + if (flag === 's') { + acc[1].silent = true + } else if (flag === 'a') { + acc[1].all = true + } else { + usage(`illegal option -- ${flag}`) + } + } + + return acc +}, [[], {}]) + +for (const command of commands) { + try { + const res = which.sync(command, { all: flags.all }) + if (!flags.silent) { + console.log([].concat(res).join('\n')) + } + } catch (err) { + process.exitCode = 1 + } +} diff --git a/node_modules/which/lib/index.js b/node_modules/which/lib/index.js new file mode 100644 index 0000000000000..2fd358baf888f --- /dev/null +++ b/node_modules/which/lib/index.js @@ -0,0 +1,111 @@ +const { isexe, sync: isexeSync } = require('isexe') +const { join, delimiter, sep, posix } = require('path') + +const isWindows = process.platform === 'win32' + +// used to check for slashed in commands passed in. always checks for the posix +// seperator on all platforms, and checks for the current separator when not on +// a posix platform. don't use the isWindows check for this since that is mocked +// in tests but we still need the code to actually work when called. that is also +// why it is ignored from coverage. +/* istanbul ignore next */ +const rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? '' : sep}]`.replace(/(\\)/g, '\\$1')) +const rRel = new RegExp(`^\\.${rSlash.source}`) + +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) + +const getPathInfo = (cmd, { + path: optPath = process.env.PATH, + pathExt: optPathExt = process.env.PATHEXT, + delimiter: optDelimiter = delimiter, +}) => { + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(rSlash) ? [''] : [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(optPath || /* istanbul ignore next: very unusual */ '').split(optDelimiter), + ] + + if (isWindows) { + const pathExtExe = optPathExt || + ['.EXE', '.CMD', '.BAT', '.COM'].join(optDelimiter) + const pathExt = pathExtExe.split(optDelimiter).flatMap((item) => [item, item.toLowerCase()]) + if (cmd.includes('.') && pathExt[0] !== '') { + pathExt.unshift('') + } + return { pathEnv, pathExt, pathExtExe } + } + + return { pathEnv, pathExt: [''] } +} + +const getPathPart = (raw, cmd) => { + const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw + const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : '' + return prefix + join(pathPart, cmd) +} + +const which = async (cmd, opt = {}) => { + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] + + for (const envPart of pathEnv) { + const p = getPathPart(envPart, cmd) + + for (const ext of pathExt) { + const withExt = p + ext + const is = await isexe(withExt, { pathExt: pathExtExe, ignoreErrors: true }) + if (is) { + if (!opt.all) { + return withExt + } + found.push(withExt) + } + } + } + + if (opt.all && found.length) { + return found + } + + if (opt.nothrow) { + return null + } + + throw getNotFoundError(cmd) +} + +const whichSync = (cmd, opt = {}) => { + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] + + for (const pathEnvPart of pathEnv) { + const p = getPathPart(pathEnvPart, cmd) + + for (const ext of pathExt) { + const withExt = p + ext + const is = isexeSync(withExt, { pathExt: pathExtExe, ignoreErrors: true }) + if (is) { + if (!opt.all) { + return withExt + } + found.push(withExt) + } + } + } + + if (opt.all && found.length) { + return found + } + + if (opt.nothrow) { + return null + } + + throw getNotFoundError(cmd) +} + +module.exports = which +which.sync = whichSync diff --git a/node_modules/which/package.json b/node_modules/which/package.json index 97ad7fbabc52b..915dc4bd27c3a 100644 --- a/node_modules/which/package.json +++ b/node_modules/which/package.json @@ -1,43 +1,52 @@ { - "author": "Isaac Z. Schlueter (http://blog.izs.me)", + "author": "GitHub Inc.", "name": "which", "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.", - "version": "2.0.2", + "version": "6.0.0", "repository": { "type": "git", - "url": "git://github.com/isaacs/node-which.git" + "url": "git+https://github.com/npm/node-which.git" }, - "main": "which.js", + "main": "lib/index.js", "bin": { - "node-which": "./bin/node-which" + "node-which": "./bin/which.js" }, "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "devDependencies": { - "mkdirp": "^0.5.0", - "rimraf": "^2.6.2", - "tap": "^14.6.9" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.3.0" }, "scripts": { "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublish": "npm run changelog", - "prechangelog": "bash gen-changelog.sh", - "changelog": "git add CHANGELOG.md", - "postchangelog": "git commit -m 'update changelog - '${npm_package_version}", - "postpublish": "git push origin --follow-tags" + "lint": "npm run eslint", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "lintfix": "npm run eslint -- --fix", + "snap": "tap", + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "files": [ - "which.js", - "bin/node-which" + "bin/", + "lib/" ], "tap": { - "check-coverage": true + "check-coverage": true, + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "engines": { - "node": ">= 8" + "node": "^20.17.0 || >=22.9.0" + }, + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.27.1", + "publish": "true" } } diff --git a/node_modules/which/which.js b/node_modules/which/which.js deleted file mode 100644 index 82afffd214374..0000000000000 --- a/node_modules/which/which.js +++ /dev/null @@ -1,125 +0,0 @@ -const isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' - -const path = require('path') -const COLON = isWindows ? ';' : ':' -const isexe = require('isexe') - -const getNotFoundError = (cmd) => - Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) - -const getPathInfo = (cmd, opt) => { - const colon = opt.colon || COLON - - // If it has a slash, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] - : ( - [ - // windows always checks the cwd first - ...(isWindows ? [process.cwd()] : []), - ...(opt.path || process.env.PATH || - /* istanbul ignore next: very unusual */ '').split(colon), - ] - ) - const pathExtExe = isWindows - ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' - : '' - const pathExt = isWindows ? pathExtExe.split(colon) : [''] - - if (isWindows) { - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } - - return { - pathEnv, - pathExt, - pathExtExe, - } -} - -const which = (cmd, opt, cb) => { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - if (!opt) - opt = {} - - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] - - const step = i => new Promise((resolve, reject) => { - if (i === pathEnv.length) - return opt.all && found.length ? resolve(found) - : reject(getNotFoundError(cmd)) - - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw - - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd - - resolve(subStep(p, i, 0)) - }) - - const subStep = (p, i, ii) => new Promise((resolve, reject) => { - if (ii === pathExt.length) - return resolve(step(i + 1)) - const ext = pathExt[ii] - isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { - if (!er && is) { - if (opt.all) - found.push(p + ext) - else - return resolve(p + ext) - } - return resolve(subStep(p, i, ii + 1)) - }) - }) - - return cb ? step(0).then(res => cb(null, res), cb) : step(0) -} - -const whichSync = (cmd, opt) => { - opt = opt || {} - - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] - - for (let i = 0; i < pathEnv.length; i ++) { - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw - - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd - - for (let j = 0; j < pathExt.length; j ++) { - const cur = p + pathExt[j] - try { - const is = isexe.sync(cur, { pathExt: pathExtExe }) - if (is) { - if (opt.all) - found.push(cur) - else - return cur - } - } catch (ex) {} - } - } - - if (opt.all && found.length) - return found - - if (opt.nothrow) - return null - - throw getNotFoundError(cmd) -} - -module.exports = which -which.sync = whichSync diff --git a/node_modules/wide-align/LICENSE b/node_modules/wide-align/LICENSE deleted file mode 100755 index f4be44d881b2d..0000000000000 --- a/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/node_modules/wide-align/align.js b/node_modules/wide-align/align.js deleted file mode 100755 index 4f94ca4cde19b..0000000000000 --- a/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/node_modules/wide-align/package.json b/node_modules/wide-align/package.json deleted file mode 100755 index 2dd27074c7777..0000000000000 --- a/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/node_modules/wrappy/LICENSE b/node_modules/wrappy/LICENSE deleted file mode 100644 index 19129e315fe59..0000000000000 --- a/node_modules/wrappy/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter and Contributors - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/wrappy/package.json b/node_modules/wrappy/package.json deleted file mode 100644 index 130752046714d..0000000000000 --- a/node_modules/wrappy/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "wrappy", - "version": "1.0.2", - "description": "Callback wrapping utility", - "main": "wrappy.js", - "files": [ - "wrappy.js" - ], - "directories": { - "test": "test" - }, - "dependencies": {}, - "devDependencies": { - "tap": "^2.3.1" - }, - "scripts": { - "test": "tap --coverage test/*.js" - }, - "repository": { - "type": "git", - "url": "https://github.com/npm/wrappy" - }, - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", - "license": "ISC", - "bugs": { - "url": "https://github.com/npm/wrappy/issues" - }, - "homepage": "https://github.com/npm/wrappy" -} diff --git a/node_modules/wrappy/wrappy.js b/node_modules/wrappy/wrappy.js deleted file mode 100644 index bb7e7d6fcf70f..0000000000000 --- a/node_modules/wrappy/wrappy.js +++ /dev/null @@ -1,33 +0,0 @@ -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} diff --git a/node_modules/write-file-atomic/lib/index.js b/node_modules/write-file-atomic/lib/index.js index 118666d2ce6d8..6013894cd1f4f 100644 --- a/node_modules/write-file-atomic/lib/index.js +++ b/node_modules/write-file-atomic/lib/index.js @@ -6,7 +6,7 @@ module.exports._cleanupOnExit = cleanupOnExit const fs = require('fs') const MurmurHash3 = require('imurmurhash') -const onExit = require('signal-exit') +const { onExit } = require('signal-exit') const path = require('path') const { promisify } = require('util') const activeFiles = {} @@ -39,7 +39,9 @@ function cleanupOnExit (tmpfile) { return () => { try { fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) - } catch (_) {} + } catch { + // ignore errors + } } } @@ -156,7 +158,7 @@ async function writeFileAsync (filename, data, options = {}) { } } -function writeFile (filename, data, options, callback) { +async function writeFile (filename, data, options, callback) { if (options instanceof Function) { callback = options options = {} @@ -164,7 +166,12 @@ function writeFile (filename, data, options, callback) { const promise = writeFileAsync(filename, data, options) if (callback) { - promise.then(callback, callback) + try { + const result = await promise + return callback(result) + } catch (err) { + return callback(err) + } } return promise diff --git a/node_modules/write-file-atomic/package.json b/node_modules/write-file-atomic/package.json index 7219f90b97be0..c72d839f0e661 100644 --- a/node_modules/write-file-atomic/package.json +++ b/node_modules/write-file-atomic/package.json @@ -1,23 +1,21 @@ { "name": "write-file-atomic", - "version": "4.0.1", + "version": "7.0.0", "description": "Write files in an atomic fashion w/configurable ownership", "main": "./lib/index.js", "scripts": { "test": "tap", "posttest": "npm run lint", - "lint": "eslint '**/*.js'", - "postlint": "npm-template-check", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags", - "lintfix": "npm run lint -- --fix", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "lintfix": "npm run eslint -- --fix", "snap": "tap", - "template-copy": "npm-template-copy --force" + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "git://github.com/npm/write-file-atomic.git" + "url": "git+https://github.com/npm/write-file-atomic.git" }, "keywords": [ "writeFile", @@ -31,23 +29,30 @@ "homepage": "https://github.com/npm/write-file-atomic", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "signal-exit": "^4.0.1" }, "devDependencies": { - "@npmcli/template-oss": "^2.7.1", - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2", - "tap": "^15.1.6" + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.27.1", + "tap": "^16.0.1" }, "files": [ - "bin", - "lib" + "bin/", + "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", "windowsCI": false, - "version": "2.7.1" + "version": "4.27.1", + "publish": "true" + }, + "tap": { + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] } } diff --git a/package-lock.json b/package-lock.json index 167f06964af58..0cbb0cb8b4739 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,30 +1,32 @@ { "name": "npm", - "version": "8.16.0", + "version": "11.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "npm", - "version": "8.16.0", + "version": "11.9.0", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", - "@npmcli/ci-detect", "@npmcli/config", "@npmcli/fs", "@npmcli/map-workspaces", + "@npmcli/metavuln-calculator", "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", "@npmcli/run-script", + "@sigstore/tuf", "abbrev", "archy", "cacache", "chalk", - "chownr", + "ci-info", "cli-columns", - "cli-table3", - "columnify", "fastest-levenshtein", + "fs-minipass", "glob", "graceful-fs", "hosted-git-info", @@ -36,7 +38,6 @@ "libnpmdiff", "libnpmexec", "libnpmfund", - "libnpmhook", "libnpmorg", "libnpmpack", "libnpmpublish", @@ -44,10 +45,9 @@ "libnpmteam", "libnpmversion", "make-fetch-happen", + "minimatch", "minipass", "minipass-pipeline", - "mkdirp", - "mkdirp-infer-owner", "ms", "node-gyp", "nopt", @@ -58,175 +58,388 @@ "npm-profile", "npm-registry-fetch", "npm-user-validate", - "npmlog", - "opener", "p-map", "pacote", "parse-conflict-json", "proc-log", "qrcode-terminal", "read", - "read-package-json", - "read-package-json-fast", - "readdir-scoped-modules", - "rimraf", "semver", + "spdx-expression-parse", "ssri", + "supports-color", "tar", "text-table", "tiny-relative-date", "treeverse", "validate-npm-package-name", - "which", - "write-file-atomic" + "which" ], "license": "Artistic-2.0", "workspaces": [ "docs", "smoke-tests", + "mock-globals", + "mock-registry", "workspaces/*" ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^5.0.4", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.2.0", - "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.2.0", - "abbrev": "~1.1.1", + "@npmcli/arborist": "^9.2.0", + "@npmcli/config": "^10.6.0", + "@npmcli/fs": "^5.0.0", + "@npmcli/map-workspaces": "^5.0.3", + "@npmcli/metavuln-calculator": "^9.0.3", + "@npmcli/package-json": "^7.0.4", + "@npmcli/promise-spawn": "^9.0.1", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.3", + "@sigstore/tuf": "^4.0.1", + "abbrev": "^4.0.0", "archy": "~1.0.0", - "cacache": "^16.1.1", - "chalk": "^4.1.2", - "chownr": "^2.0.0", + "cacache": "^20.0.3", + "chalk": "^5.6.2", + "ci-info": "^4.4.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.2", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "glob": "^8.0.1", - "graceful-fs": "^4.2.10", - "hosted-git-info": "^5.0.0", - "ini": "^3.0.0", - "init-package-json": "^3.0.2", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^2.3.1", - "libnpmaccess": "^6.0.2", - "libnpmdiff": "^4.0.2", - "libnpmexec": "^4.0.2", - "libnpmfund": "^3.0.1", - "libnpmhook": "^8.0.2", - "libnpmorg": "^4.0.2", - "libnpmpack": "^4.0.2", - "libnpmpublish": "^6.0.2", - "libnpmsearch": "^5.0.2", - "libnpmteam": "^4.0.2", - "libnpmversion": "^3.0.1", - "make-fetch-happen": "^10.2.0", - "minipass": "^3.1.6", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^13.0.0", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^9.0.2", + "ini": "^6.0.0", + "init-package-json": "^8.2.4", + "is-cidr": "^6.0.1", + "json-parse-even-better-errors": "^5.0.0", + "libnpmaccess": "^10.0.3", + "libnpmdiff": "^8.1.0", + "libnpmexec": "^10.2.0", + "libnpmfund": "^7.0.14", + "libnpmorg": "^8.0.1", + "libnpmpack": "^9.1.0", + "libnpmpublish": "^11.1.3", + "libnpmsearch": "^9.0.1", + "libnpmteam": "^8.0.2", + "libnpmversion": "^8.0.3", + "make-fetch-happen": "^15.0.3", + "minimatch": "^10.1.1", + "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", "ms": "^2.1.2", - "node-gyp": "^9.0.0", - "nopt": "^5.0.0", - "npm-audit-report": "^3.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.1.0", - "npm-pick-manifest": "^7.0.1", - "npm-profile": "^6.2.0", - "npm-registry-fetch": "^13.3.0", - "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.2", - "opener": "^1.5.2", - "p-map": "^4.0.0", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.2", - "proc-log": "^2.0.1", + "node-gyp": "^12.2.0", + "nopt": "^9.0.0", + "npm-audit-report": "^7.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.2", + "npm-pick-manifest": "^11.0.3", + "npm-profile": "^12.0.1", + "npm-registry-fetch": "^19.1.1", + "npm-user-validate": "^4.0.0", + "p-map": "^7.0.4", + "pacote": "^21.1.0", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", - "read": "~1.0.7", - "read-package-json": "^5.0.1", - "read-package-json-fast": "^2.0.3", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.1", - "tar": "^6.1.11", + "read": "^5.0.1", + "semver": "^7.7.3", + "spdx-expression-parse": "^4.0.0", + "ssri": "^13.0.0", + "supports-color": "^10.2.2", + "tar": "^7.5.7", "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^2.0.0", - "validate-npm-package-name": "^4.0.0", - "which": "^2.0.2", - "write-file-atomic": "^4.0.1" + "tiny-relative-date": "^2.0.2", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^7.0.2", + "which": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "licensee": "^8.2.0", - "nock": "^13.2.4", + "@npmcli/docs": "^1.0.0", + "@npmcli/eslint-config": "^5.1.0", + "@npmcli/git": "^7.0.1", + "@npmcli/mock-globals": "^1.0.0", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/template-oss": "4.25.1", + "@tufjs/repo-mock": "^4.0.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "ajv-formats-draft2019": "^1.6.1", + "cli-table3": "^0.6.4", + "diff": "^8.0.3", + "nock": "^13.4.0", + "npm-packlist": "^10.0.3", + "remark": "^15.0.1", + "remark-gfm": "^4.0.1", + "remark-github": "^12.0.0", + "rimraf": "^6.0.1", "spawk": "^1.7.1", - "tap": "^16.0.1" + "tap": "^16.3.9" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^20.17.0 || >=22.9.0" } }, "docs": { + "name": "@npmcli/docs", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "front-matter": "^4.0.2", + "ignore-walk": "^8.0.0", + "jsdom": "27.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-man": "^9.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "semver": "^7.3.8", + "tap": "^16.3.8", + "unified": "^11.0.5", + "yaml": "^2.2.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "docs/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "docs/node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "docs/node_modules/jsdom": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.0.0.tgz", + "integrity": "sha512-lIHeR1qlIRrIN5VMccd8tI2Sgw6ieYXSVktcSHaNe3Z5nE/tcPQYQWOq00wxMvYOsz+73eAkNenVvmPC6bba9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/dom-selector": "^6.5.4", + "cssstyle": "^5.3.0", + "data-urls": "^6.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^7.3.0", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.0.0", + "ws": "^8.18.2", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "docs/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "mock-globals": { + "name": "@npmcli/mock-globals", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "mock-registry": { + "name": "@npmcli/mock-registry", "version": "1.0.0", "license": "ISC", "devDependencies": { - "@mdx-js/mdx": "^1.6.22", - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/fs": "^2.1.0", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.5.0", - "cmark-gfm": "^0.9.0", - "jsdom": "^18.1.0", - "marked-man": "^0.7.0", - "tap": "^16.0.1", - "which": "^2.0.2", - "yaml": "^1.10.0" + "@npmcli/arborist": "^9.1.2", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "json-stringify-safe": "^5.0.1", + "nock": "^13.3.3", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "tap": "^16.3.8" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@actions/core": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/exec": "^1.1.1", + "@actions/http-client": "^2.0.1" + } + }, + "node_modules/@actions/exec": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@actions/io": "^1.0.1" + } + }, + "node_modules/@actions/http-client": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^5.25.4" + } + }, + "node_modules/@actions/http-client/node_modules/undici": { + "version": "5.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=14.0" + } + }, + "node_modules/@actions/io": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", + "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.2.4" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.7.tgz", + "integrity": "sha512-8CO/UQ4tzDd7ula+/CVimJIVWez99UJlbMyIgk8xOnhAVPKLnBZmUFYVgugS441v2ZqUq5EnSh6B0Ua0liSFAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.5" } }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { - "version": "7.16.7", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.12.9", + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -236,471 +449,681 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/core/node_modules/semver": { - "version": "5.7.1", + "version": "6.3.1", "dev": true, "license": "ISC", "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.17.7", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz", + "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.16.7", + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.16.7" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.17.7", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.17.7", + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.17.0" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helpers": { - "version": "7.17.8", + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.16.10", + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", + "node_modules/@colors/colors": { + "version": "1.5.0", "dev": true, "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, + "optional": true, "engines": { - "node": ">=4" + "node": ">=0.1.90" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", + "node_modules/@commitlint/cli": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@commitlint/format": "^19.8.1", + "@commitlint/lint": "^19.8.1", + "@commitlint/load": "^19.8.1", + "@commitlint/read": "^19.8.1", + "@commitlint/types": "^19.8.1", + "tinyexec": "^1.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" }, "engines": { - "node": ">=4" + "node": ">=v18" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", + "node_modules/@commitlint/config-conventional": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "@commitlint/types": "^19.8.1", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, + "engines": { + "node": ">=v18" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", + "node_modules/@commitlint/config-validator": { + "version": "19.8.1", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", + "node_modules/@commitlint/ensure": { + "version": "19.8.1", "dev": true, "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, "engines": { - "node": ">=0.8.0" + "node": ">=v18" } }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", + "node_modules/@commitlint/execute-rule": { + "version": "19.8.1", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=v18" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", + "node_modules/@commitlint/format": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@commitlint/types": "^19.8.1", + "chalk": "^5.3.0" }, "engines": { - "node": ">=4" + "node": ">=v18" } }, - "node_modules/@babel/parser": { - "version": "7.17.8", + "node_modules/@commitlint/is-ignored": { + "version": "19.8.1", "dev": true, "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" + "dependencies": { + "@commitlint/types": "^19.8.1", + "semver": "^7.6.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=v18" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", + "node_modules/@commitlint/lint": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "@commitlint/is-ignored": "^19.8.1", + "@commitlint/parse": "^19.8.1", + "@commitlint/rules": "^19.8.1", + "@commitlint/types": "^19.8.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=v18" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.1", + "node_modules/@commitlint/load": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@commitlint/config-validator": "^19.8.1", + "@commitlint/execute-rule": "^19.8.1", + "@commitlint/resolve-extends": "^19.8.1", + "@commitlint/types": "^19.8.1", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=v18" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", + "node_modules/@commitlint/message": { + "version": "19.8.1", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=v18" } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.14.2", + "node_modules/@commitlint/parse": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@commitlint/types": "^19.8.1", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=v18" } }, - "node_modules/@babel/template": { - "version": "7.16.7", + "node_modules/@commitlint/read": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@commitlint/top-level": "^19.8.1", + "@commitlint/types": "^19.8.1", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8", + "tinyexec": "^1.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=v18" } }, - "node_modules/@babel/traverse": { - "version": "7.17.3", + "node_modules/@commitlint/resolve-extends": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", - "globals": "^11.1.0" + "@commitlint/config-validator": "^19.8.1", + "@commitlint/types": "^19.8.1", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=v18" } }, - "node_modules/@babel/types": { - "version": "7.17.0", + "node_modules/@commitlint/rules": { + "version": "19.8.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" + "@commitlint/ensure": "^19.8.1", + "@commitlint/message": "^19.8.1", + "@commitlint/to-lines": "^19.8.1", + "@commitlint/types": "^19.8.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=v18" } }, - "node_modules/@blueoak/list": { - "version": "2.0.0", + "node_modules/@commitlint/to-lines": { + "version": "19.8.1", "dev": true, - "license": "CC0-1.0" - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "inBundle": true, - "optional": true, + "license": "MIT", "engines": { - "node": ">=0.1.90" + "node": ">=v18" } }, - "node_modules/@eslint/eslintrc": { - "version": "1.2.1", + "node_modules/@commitlint/top-level": { + "version": "19.8.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "find-up": "^7.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=v18" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0", - "peer": true - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@commitlint/types": { + "version": "19.8.1", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.13.0", + "node_modules/@conventional-commits/parser": { + "version": "0.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "unist-util-visit": "^2.0.3", + "unist-util-visit-parents": "^3.1.1" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "peer": true, "dependencies": { - "type-fest": "^0.20.2" + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" }, "engines": { - "node": ">=8" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^2.0.1" + "engines": { + "node": ">=18" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz", + "integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "*" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "peer": true, "engines": { - "node": ">=10" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "peer": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=10.10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "peer": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -709,3122 +1132,3484 @@ "node": "*" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", + "node_modules/@eslint/js": { + "version": "8.57.1", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } }, - "node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", + "node_modules/@google-automations/git-file-utils": { + "version": "3.0.0", "dev": true, - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "@octokit/rest": "^20.1.1", + "@octokit/types": "^13.0.0", + "minimatch": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/auth-token": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/core": { + "version": "5.2.2", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/endpoint": { + "version": "9.0.6", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/graphql": { + "version": "7.1.1", "dev": true, "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 18" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "@octokit/types": "^13.7.0" }, "engines": { - "node": ">=8" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { - "version": "2.2.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", "dev": true, "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, "engines": { - "node": ">=8" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/request": { + "version": "8.4.1", "dev": true, "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/request-error": { + "version": "5.1.1", "dev": true, "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/@mdx-js/mdx": { - "version": "1.6.22", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/rest": { + "version": "20.1.2", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "7.12.9", - "@babel/plugin-syntax-jsx": "7.12.1", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "1.6.22", - "babel-plugin-apply-mdx-type-prop": "1.6.22", - "babel-plugin-extract-import-names": "1.6.22", - "camelcase-css": "2.0.1", - "detab": "2.0.4", - "hast-util-raw": "6.0.1", - "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "10.0.1", - "remark-footnotes": "2.0.0", - "remark-mdx": "1.6.22", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "style-to-object": "0.3.0", - "unified": "9.2.0", - "unist-builder": "2.0.3", - "unist-util-visit": "2.0.3" + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 18" } }, - "node_modules/@mdx-js/util": { - "version": "1.6.22", + "node_modules/@google-automations/git-file-utils/node_modules/@octokit/types": { + "version": "13.10.0", "dev": true, "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "dependencies": { + "@octokit/openapi-types": "^24.2.0" } }, - "node_modules/@npmcli/arborist": { - "resolved": "workspaces/arborist", - "link": true + "node_modules/@google-automations/git-file-utils/node_modules/before-after-hook": { + "version": "2.2.3", + "dev": true, + "license": "Apache-2.0" }, - "node_modules/@npmcli/ci-detect": { - "version": "2.0.0", - "inBundle": true, + "node_modules/@google-automations/git-file-utils/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": ">=10" } }, - "node_modules/@npmcli/config": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-4.2.0.tgz", - "integrity": "sha512-imWNz5dNWb2u+y41jyxL2WB389tkhu3a01Rchn16O/ur6GrnKySgOqdNG3N/9Z+mqxdISMEGKXI/POCauzz0dA==", - "inBundle": true, + "node_modules/@google-automations/git-file-utils/node_modules/universal-user-agent": { + "version": "6.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "dev": true, + "license": "Apache-2.0", + "peer": true, "dependencies": { - "@npmcli/map-workspaces": "^2.0.2", - "ini": "^3.0.0", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^5.0.0", - "proc-log": "^2.0.0", - "read-package-json-fast": "^2.0.3", - "semver": "^7.3.5", - "walk-up-path": "^1.0.0" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=10.10.0" } }, - "node_modules/@npmcli/disparity-colors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/disparity-colors/-/disparity-colors-2.0.0.tgz", - "integrity": "sha512-FFXGrIjhvd2qSZ8iS0yDvbI7nbjdyT2VNO7wotosjYZM2p2r8PN3B7Om3M5NO9KqW/OVzfzLB3L0V5Vo5QXC7A==", + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "ansi-styles": "^4.3.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@npmcli/eslint-config": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/eslint-config/-/eslint-config-3.0.1.tgz", - "integrity": "sha512-a5tr7iOeVePL/GOZyFNbG0+dUH0H2QYHmrRGCOE7y+qA7OrMDDOiHe/Wt1PiSDo+Y9IxNKuxhj6TY01Hq56QKg==", + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", "dev": true, + "license": "ISC", + "peer": true, "dependencies": { - "which": "^2.0.2" - }, - "bin": { - "lint": "bin/index.js" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.22" }, - "peerDependencies": { - "eslint": ">= 8", - "eslint-plugin-node": "^11.1.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@npmcli/fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.1.tgz", - "integrity": "sha512-1Q0uzx6c/NVNGszePbr5Gc2riSU1zLpNlo/1YWntH+eaPmMgBssAW0qXofCVkpdj3ce4swZtlDYQu+NKiYcptg==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@iarna/toml": { + "version": "3.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "inBundle": true, - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, + "license": "MIT", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "20 || >=22" } }, - "node_modules/@npmcli/git": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-3.0.1.tgz", - "integrity": "sha512-UU85F/T+F1oVn3IsB/L6k9zXIMpXBuUBE25QDH0SsURwT6IOBqkC7M16uqo2vVZIyji3X1K4XH9luip7YekH1A==", + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", "inBundle": true, + "license": "MIT", "dependencies": { - "@npmcli/promise-spawn": "^3.0.0", - "lru-cache": "^7.4.4", - "mkdirp": "^1.0.4", - "npm-pick-manifest": "^7.0.0", - "proc-log": "^2.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^2.0.2" + "@isaacs/balanced-match": "^4.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "20 || >=22" } }, - "node_modules/@npmcli/installed-package-contents": { - "version": "1.0.7", - "inBundle": true, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, "license": "ISC", "dependencies": { - "npm-bundled": "^1.1.1", - "npm-normalize-package-bin": "^1.0.1" - }, - "bin": { - "installed-package-contents": "index.js" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">= 10" + "node": ">=12" } }, - "node_modules/@npmcli/map-workspaces": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-2.0.3.tgz", - "integrity": "sha512-X6suAun5QyupNM8iHkNPh0AHdRC2rb1W+MTdMvvA/2ixgmqZwlq5cGUBgmKHUHT2LgrkKJMAXbfAoTxOigpK8Q==", - "inBundle": true, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", "dependencies": { - "@npmcli/name-from-folder": "^1.0.1", - "glob": "^8.0.1", - "minimatch": "^5.0.1", - "read-package-json-fast": "^2.0.3" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@npmcli/metavuln-calculator": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.1.tgz", - "integrity": "sha512-n69ygIaqAedecLeVH3KnO39M6ZHiJ2dEv5A7DGvcqCB8q17BGUgW8QaanIkbWUo2aYGZqJaOORTLAlIvKjNDKA==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", "dependencies": { - "cacache": "^16.0.0", - "json-parse-even-better-errors": "^2.3.1", - "pacote": "^13.0.3", - "semver": "^7.3.5" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@npmcli/move-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.0.tgz", - "integrity": "sha512-UR6D5f4KEGWJV6BGPH3Qb2EtgH+t+1XQ1Tt85c7qicN6cezzuHPdZwwAxqZr4JLtnQu0LZsTza/5gmNmSl8XLg==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", "inBundle": true, + "license": "ISC", "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" + "minipass": "^7.0.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=18.0.0" } }, - "node_modules/@npmcli/name-from-folder": { - "version": "1.0.1", + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", "inBundle": true, "license": "ISC" }, - "node_modules/@npmcli/node-gyp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz", - "integrity": "sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A==", - "inBundle": true, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@npmcli/package-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-2.0.0.tgz", - "integrity": "sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA==", - "inBundle": true, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", "dependencies": { - "json-parse-even-better-errors": "^2.3.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@npmcli/promise-spawn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz", - "integrity": "sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g==", - "inBundle": true, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", "dependencies": { - "infer-owner": "^1.0.4" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@npmcli/query": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-1.1.1.tgz", - "integrity": "sha512-UF3I0fD94wzQ84vojMO2jDB8ibjRSTqhi8oz2mzVKiJ9gZHbeGlu9kzPvgHuGDK0Hf2cARhWtTfCDHNEwlL9hg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "npm-package-arg": "^9.1.0", - "postcss-selector-parser": "^6.0.10", - "semver": "^7.3.7" + "p-locate": "^4.1.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@npmcli/run-script": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-4.2.0.tgz", - "integrity": "sha512-e/QgLg7j2wSJp1/7JRl0GC8c7PMX+uYlA/1Tb+IDOLdSM4T7K1VQ9mm9IGU3WRtY5vEIObpqCLb3aCNCug18DA==", - "inBundle": true, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", "dependencies": { - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/promise-spawn": "^3.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^2.0.3", - "which": "^2.0.2" + "p-try": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@npmcli/template-oss": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@npmcli/template-oss/-/template-oss-3.5.0.tgz", - "integrity": "sha512-cminCPl0see5fxCSQabmHhfUisgxIlq1xG9J815OzeJIyLVgB0DEGDwldKuknw1Xd5Od83ke6sxf90O7OxIlfA==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", "dev": true, - "hasInstallScript": true, + "license": "MIT", "dependencies": { - "@npmcli/fs": "^2.0.1", - "@npmcli/git": "^3.0.0", - "@npmcli/map-workspaces": "^2.0.2", - "@npmcli/package-json": "^2.0.0", - "diff": "^5.0.0", - "glob": "^8.0.1", - "handlebars": "^4.7.7", - "hosted-git-info": "^5.0.0", - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", - "lodash": "^4.17.21", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0", - "semver": "^7.3.5", - "yaml": "^2.0.0-11" - }, - "bin": { - "template-oss-apply": "bin/apply.js", - "template-oss-check": "bin/check.js" + "p-limit": "^2.2.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@npmcli/template-oss/node_modules/yaml": { - "version": "2.0.0-11", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-11.tgz", - "integrity": "sha512-5kGSQrzDyjCk0BLuFfjkoUE9vYcoyrwZIZ+GnpOSM9vhkvPjItYiWJ1jpRSo0aU4QmsoNrFwDT4O7XS2UGcBQg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", "dev": true, + "license": "MIT", "engines": { - "node": ">= 12" + "node": ">=8" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "inBundle": true, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/@types/hast": { - "version": "2.3.4", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "*" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@types/mdast": { - "version": "3.0.10", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "*" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@types/parse5": { - "version": "5.0.3", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@types/unist": { - "version": "2.0.6", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", "dev": true, "license": "MIT" }, - "node_modules/abab": { - "version": "2.0.5", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "inBundle": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } }, - "node_modules/acorn": { - "version": "7.4.1", + "node_modules/@jsep-plugin/assignment": { + "version": "1.3.0", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", + "node_modules/@jsep-plugin/regex": { + "version": "1.0.4", "dev": true, "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", "dev": true, "license": "MIT", "peer": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=0.4.0" + "node": ">= 8" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "inBundle": true, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "debug": "4" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 8" } }, - "node_modules/agentkeepalive": { - "version": "4.2.1", + "node_modules/@npmcli/agent": { + "version": "4.0.0", "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": ">= 8.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", + "node_modules/@npmcli/arborist": { + "resolved": "workspaces/arborist", + "link": true + }, + "node_modules/@npmcli/config": { + "resolved": "workspaces/config", + "link": true + }, + "node_modules/@npmcli/docs": { + "resolved": "docs", + "link": true + }, + "node_modules/@npmcli/eslint-config": { + "version": "5.1.0", + "dev": true, + "license": "ISC", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "which": "^5.0.0" + }, + "bin": { + "lint": "bin/index.js" }, "engines": { - "node": ">=8" + "node": "^18.17.0 || >=20.5.0" + }, + "peerDependencies": { + "eslint": "^8.13.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0" } }, - "node_modules/ajv": { - "version": "6.12.6", + "node_modules/@npmcli/eslint-config/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, - "license": "MIT", - "peer": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "isexe": "^3.1.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", + "node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", "inBundle": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/@npmcli/git": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", + "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "color-convert": "^2.0.1" + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^6.0.0" }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/anymatch": { - "version": "3.1.2", - "dev": true, + "node_modules/@npmcli/map-workspaces": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-5.0.3.tgz", + "integrity": "sha512-o2grssXo1e774E5OtEwwrgoszYRh0lqkJH+Pb9r78UcqdGJRDRfhpM8DvZPjzNLLNYeD/rNbjOKM3Ss5UABROw==", + "inBundle": true, "license": "ISC", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" }, "engines": { - "node": ">= 8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "dev": true, - "license": "MIT", + "node_modules/@npmcli/metavuln-calculator": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-9.0.3.tgz", + "integrity": "sha512-94GLSYhLXF2t2LAC7pDwLaM4uCARzxShyAQKsirmlNcpidH89VA4/+K1LbJmRMgz5gy65E/QBBWQdUvGLe2Frg==", + "inBundle": true, + "license": "ISC", "dependencies": { - "default-require-extensions": "^3.0.0" + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/aproba": { - "version": "2.0.0", + "node_modules/@npmcli/mock-globals": { + "resolved": "mock-globals", + "link": true + }, + "node_modules/@npmcli/mock-registry": { + "resolved": "mock-registry", + "link": true + }, + "node_modules/@npmcli/name-from-folder": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-4.0.0.tgz", + "integrity": "sha512-qfrhVlOSqmKM8i6rkNdZzABj8MKEITGFAY+4teqBziksCQAOLutiAxM1wY2BKEd8KjUSpWmWCYxvXr0y4VTlPg==", "inBundle": true, - "license": "ISC" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/archy": { - "version": "1.0.0", + "node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", "inBundle": true, - "license": "MIT" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/are-we-there-yet": { - "version": "3.0.0", + "node_modules/@npmcli/package-json": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", + "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", "inBundle": true, "license": "ISC", "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", + "node_modules/@npmcli/query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-5.0.0.tgz", + "integrity": "sha512-8TZWfTQOsODpLqo9SVhVjHovmKXNpevHU0gO9e+y4V4fRIOneiXy0u0sMP9LmS71XivrEWfZWg50ReH4WRT4aQ==", + "license": "ISC", "dependencies": { - "sprintf-js": "~1.0.2" + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/array-find-index": { - "version": "1.0.2", - "dev": true, - "license": "MIT", + "node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/asap": { - "version": "2.0.6", + "node_modules/@npmcli/run-script": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", + "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "inBundle": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/smoke-tests": { + "resolved": "smoke-tests", + "link": true }, - "node_modules/asn1": { - "version": "0.2.4", + "node_modules/@npmcli/template-oss": { + "version": "4.25.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, + "hasInstallScript": true, + "license": "ISC", + "workspaces": [ + "workspace/test-workspace" + ], "dependencies": { - "safer-buffer": "~2.1.0" + "@actions/core": "^1.9.1", + "@commitlint/cli": "^19.0.3", + "@commitlint/config-conventional": "^19.2.2", + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^9.1.2", + "@npmcli/git": "^7.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@octokit/rest": "^22.0.0", + "dedent": "^1.5.1", + "diff": "^8.0.2", + "glob": "^11.0.3", + "handlebars": "^4.7.7", + "hosted-git-info": "^9.0.0", + "ini": "^5.0.0", + "json-parse-even-better-errors": "^4.0.0", + "just-deep-map-values": "^1.1.1", + "just-diff": "^6.0.0", + "just-omit": "^2.2.0", + "lodash": "^4.17.21", + "minimatch": "^10.0.3", + "npm-package-arg": "^13.0.0", + "proc-log": "^5.0.0", + "release-please": "^17.1.1", + "semver": "^7.3.5", + "yaml": "^2.1.1" + }, + "bin": { + "template-oss-apply": "bin/apply.js", + "template-oss-check": "bin/check.js", + "template-oss-release-manager": "bin/release-manager.js", + "template-oss-release-please": "bin/release-please.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/assert-plus": { - "version": "1.0.0", + "node_modules/@npmcli/template-oss/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, "engines": { - "node": ">=0.8" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/async-hook-domain": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz", - "integrity": "sha512-14LjCmlK1PK8eDtTezR6WX8TMaYNIzBIsd2D1sGoGjgx0BuNMMoSdk7i/drlbtamy0AWv9yv2tkB+ASdmeqFIw==", + "node_modules/@npmcli/template-oss/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/asynckit": { - "version": "0.4.0", + "node_modules/@npmcli/template-oss/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "node_modules/aws-sign2": { - "version": "0.7.0", + "node_modules/@npmcli/template-oss/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true, + "license": "ISC", "engines": { - "node": "*" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/aws4": { - "version": "1.11.0", + "node_modules/@octokit/auth-token": { + "version": "6.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "engines": { + "node": ">= 20" + } }, - "node_modules/babel-plugin-apply-mdx-type-prop": { - "version": "1.6.22", + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "7.10.4", - "@mdx-js/util": "1.6.22" + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@babel/core": "^7.11.6" + "engines": { + "node": ">= 20" } }, - "node_modules/babel-plugin-apply-mdx-type-prop/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", + "node_modules/@octokit/endpoint": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.2.tgz", + "integrity": "sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } }, - "node_modules/babel-plugin-extract-import-names": { - "version": "1.6.22", + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "7.10.4" + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 20" } }, - "node_modules/babel-plugin-extract-import-names/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", "dev": true, "license": "MIT" }, - "node_modules/bail": { - "version": "1.0.5", + "node_modules/@octokit/plugin-paginate-rest": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "inBundle": true - }, - "node_modules/base64-js": { - "version": "1.5.1", + "node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "dependencies": { - "tweetnacl": "^0.14.3" + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" } }, - "node_modules/benchmark": { - "version": "2.1.4", + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", + "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", "dev": true, "license": "MIT", "dependencies": { - "lodash": "^4.17.4", - "platform": "^1.3.3" + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" } }, - "node_modules/bin-links": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-3.0.1.tgz", - "integrity": "sha512-9vx+ypzVhASvHTS6K+YSGf7nwQdANoz7v6MTC0aCtYnOEZ87YvMf81aY737EZnGZdpbRM3sfWjO9oWkKmuIvyQ==", + "node_modules/@octokit/request": { + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.7.tgz", + "integrity": "sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==", + "dev": true, + "license": "MIT", "dependencies": { - "cmd-shim": "^5.0.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-normalize-package-bin": "^1.0.0", - "read-cmd-shim": "^3.0.0", - "rimraf": "^3.0.0", - "write-file-atomic": "^4.0.0" + "@octokit/endpoint": "^11.0.2", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "fast-content-type-parse": "^3.0.0", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">= 20" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", + "node_modules/@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "dev": true, "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 20" } }, - "node_modules/bind-obj-methods": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-3.0.0.tgz", - "integrity": "sha512-nLEaaz3/sEzNSyPWRsN9HNsqwk1AUyECtGj+XwGdIi3xABnEqecvXtIJ0wehQXuuER5uZ/5fTs2usONgYjG+iw==", + "node_modules/@octokit/rest": { + "version": "22.0.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz", + "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==", "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^7.0.6", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-request-log": "^6.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0" + }, "engines": { - "node": ">=10" + "node": ">= 20" } }, - "node_modules/bindings": { - "version": "1.5.0", + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", "dev": true, "license": "MIT", "dependencies": { - "file-uri-to-path": "1.0.0" + "@octokit/openapi-types": "^27.0.0" } }, - "node_modules/bl": { - "version": "4.1.0", + "node_modules/@rtsao/scc": { + "version": "1.1.0", "dev": true, "license": "MIT", + "peer": true + }, + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/@sigstore/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.1.0.tgz", + "integrity": "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==", "inBundle": true, - "dependencies": { - "balanced-match": "^1.0.0" + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.0", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.0.tgz", + "integrity": "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==", + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "fill-range": "^7.0.1" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.3", + "proc-log": "^6.1.0", + "promise-retry": "^2.0.1" }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/buffer": { - "version": "5.7.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", + "node_modules/@sigstore/tuf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.1.tgz", + "integrity": "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==", + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/buffer-from": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "node_modules/@sigstore/verify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", + "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "semver": "^7.0.0" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/cacache": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.1.tgz", - "integrity": "sha512-VDKN+LHyCQXaaYZ7rA/qtkURU+/yYhviUdvqEv2LT6QPZU8jpyzEkEVAcKlKLt5dJ5BRp11ym8lo3NKLluEPLg==", - "inBundle": true, - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^1.1.1" - }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/caching-transform": { - "version": "4.0.0", - "dev": true, + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", + "inBundle": true, "license": "MIT", "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/caching-transform/node_modules/typedarray-to-buffer": { - "version": "3.1.5", + "node_modules/@tufjs/repo-mock": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/repo-mock/-/repo-mock-4.0.1.tgz", + "integrity": "sha512-8kw+QZ7MprcXjtC0WTbsPgfi1X6Hd+xlA96NcGuCs/sdPFSgTGHlOjfrN1opcT07Rch2vnWYAR+l+/M4VSU2Rw==", "dev": true, "license": "MIT", "dependencies": { - "is-typedarray": "^1.0.0" + "@tufjs/models": "4.1.0", + "nock": "^13.5.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/caching-transform/node_modules/write-file-atomic": { - "version": "3.0.3", + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.2.tgz", + "integrity": "sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "@types/node": "*" } }, - "node_modules/call-bind": { - "version": "1.0.2", + "node_modules/@types/debug": { + "version": "4.1.12", "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/ms": "*" } }, - "node_modules/caller": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/callsites": { - "version": "3.1.0", + "node_modules/@types/hast": { + "version": "3.0.4", "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" + "dependencies": { + "@types/unist": "*" } }, - "node_modules/camelcase": { - "version": "5.3.1", + "node_modules/@types/json5": { + "version": "0.0.29", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" - } + "peer": true }, - "node_modules/camelcase-css": { - "version": "2.0.1", + "node_modules/@types/mdast": { + "version": "4.0.4", "dev": true, "license": "MIT", - "engines": { - "node": ">= 6" + "dependencies": { + "@types/unist": "*" } }, - "node_modules/caseless": { - "version": "0.12.0", + "node_modules/@types/minimist": { + "version": "1.2.5", "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true + "license": "MIT" }, - "node_modules/ccount": { - "version": "1.1.0", + "node_modules/@types/ms": { + "version": "2.1.0", "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "license": "MIT" }, - "node_modules/chalk": { - "version": "4.1.2", - "inBundle": true, + "node_modules/@types/node": { + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", + "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "undici-types": "~7.16.0" } }, - "node_modules/character-entities": { - "version": "1.2.4", + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "license": "MIT" }, - "node_modules/character-entities-legacy": { - "version": "1.1.4", + "node_modules/@types/npm-package-arg": { + "version": "6.1.4", "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "license": "MIT" }, - "node_modules/character-reference-invalid": { - "version": "1.1.4", + "node_modules/@types/unist": { + "version": "2.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "16.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", + "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/chokidar": { - "version": "3.5.1", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", "dev": true, "license": "MIT", - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" + "node": ">=10.0.0" } }, - "node_modules/chownr": { - "version": "2.0.0", + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", "inBundle": true, "license": "ISC", "engines": { - "node": ">=10" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/cidr-regex": { - "version": "3.1.1", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^4.1.0" + "node_modules/acorn": { + "version": "8.15.0", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=10" + "node": ">=0.4.0" } }, - "node_modules/clean-stack": { - "version": "2.2.0", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", "inBundle": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 14" } }, - "node_modules/cli-columns": { - "version": "4.0.0", - "inBundle": true, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", - "inBundle": true, + "node_modules/ajv": { + "version": "8.17.1", + "dev": true, + "license": "MIT", "dependencies": { - "string-width": "^4.2.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": "10.* || >= 12.*" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/cliui": { - "version": "7.0.4", + "node_modules/ajv-formats-draft2019": { + "version": "1.6.1", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "punycode": "^2.1.1", + "schemes": "^1.4.0", + "smtp-address-parser": "^1.0.3", + "uri-js": "^4.4.1" + }, + "peerDependencies": { + "ajv": "*" } }, - "node_modules/clone": { - "version": "1.0.4", + "node_modules/ansi-regex": { + "version": "5.0.1", "inBundle": true, "license": "MIT", "engines": { - "node": ">=0.8" + "node": ">=8" } }, - "node_modules/cmark-gfm": { - "version": "0.9.0", + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^3.0.0", - "prebuild-install": "^6.0.0" - }, "engines": { - "node": ">= 12" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cmd-shim": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-5.0.0.tgz", - "integrity": "sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw==", + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", "dependencies": { - "mkdirp-infer-owner": "^2.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">= 8" } }, - "node_modules/code-point-at": { - "version": "1.1.0", + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collapse-white-space": { - "version": "1.0.6", - "dev": true, - "license": "MIT", + "node": ">=8.6" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "inBundle": true, + "node_modules/append-transform": { + "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "default-require-extensions": "^3.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=8" } }, - "node_modules/color-name": { - "version": "1.1.4", + "node_modules/aproba": { + "version": "2.1.0", + "license": "ISC" + }, + "node_modules/archy": { + "version": "1.0.0", "inBundle": true, "license": "MIT" }, - "node_modules/color-support": { - "version": "1.1.3", - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" }, - "node_modules/columnify": { - "version": "1.6.0", - "inBundle": true, + "node_modules/args": { + "version": "5.0.3", + "dev": true, "license": "MIT", "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" + "camelcase": "5.0.0", + "chalk": "2.4.2", + "leven": "2.1.0", + "mri": "1.1.4" }, "engines": { - "node": ">=8.0.0" + "node": ">= 6.0.0" } }, - "node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/args/node_modules/ansi-styles": { + "version": "3.2.1", "dev": true, "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">= 0.8" + "node": ">=4" } }, - "node_modules/comma-separated-tokens": { - "version": "1.0.8", + "node_modules/args/node_modules/camelcase": { + "version": "5.0.0", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">=6" } }, - "node_modules/common-ancestor-path": { - "version": "1.0.1", - "license": "ISC" - }, - "node_modules/commondir": { - "version": "1.0.1", + "node_modules/args/node_modules/chalk": { + "version": "2.4.2", "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "inBundle": true - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/convert-source-map": { - "version": "1.8.0", + "node_modules/args/node_modules/color-convert": { + "version": "1.9.3", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.1" + "color-name": "1.1.3" } }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", + "node_modules/args/node_modules/color-name": { + "version": "1.1.3", "dev": true, "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.2", + "node_modules/args/node_modules/escape-string-regexp": { + "version": "1.0.5", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } }, - "node_modules/correct-license-metadata": { - "version": "1.4.0", + "node_modules/args/node_modules/has-flag": { + "version": "3.0.0", "dev": true, "license": "MIT", - "dependencies": { - "spdx-expression-validate": "^2.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/coveralls": { - "version": "3.1.1", + "node_modules/args/node_modules/mri": { + "version": "1.1.4", "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "peer": true, - "dependencies": { - "js-yaml": "^3.13.1", - "lcov-parse": "^1.0.0", - "log-driver": "^1.2.7", - "minimist": "^1.2.5", - "request": "^2.88.2" - }, - "bin": { - "coveralls": "bin/coveralls.js" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", + "node_modules/args/node_modules/supports-color": { + "version": "5.5.0", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "has-flag": "^3.0.0" }, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cssom": { - "version": "0.5.0", + "node_modules/array-ify": { + "version": "1.0.0", "dev": true, "license": "MIT" }, - "node_modules/cssstyle": { - "version": "2.3.0", + "node_modules/array-includes": { + "version": "3.1.9", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "cssom": "~0.3.6" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "dev": true, - "license": "MIT" - }, - "node_modules/dashdash": { - "version": "1.14.1", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", "dev": true, "license": "MIT", - "optional": true, "peer": true, "dependencies": { - "assert-plus": "^1.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { - "node": ">=0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/data-urls": { - "version": "3.0.1", + "node_modules/array.prototype.flat": { + "version": "1.3.3", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^10.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=12" - } + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/debug": { - "version": "4.3.4", - "inBundle": true, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "ms": "2.1.2" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/debuglog": { - "version": "1.0.1", - "inBundle": true, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/decamelize": { - "version": "1.2.0", + "node_modules/arrify": { + "version": "1.0.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/decimal.js": { - "version": "10.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/decompress-response": { - "version": "4.2.1", + "node_modules/async-function": { + "version": "1.0.0", "dev": true, "license": "MIT", - "dependencies": { - "mimic-response": "^2.0.0" - }, + "peer": true, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/deep-extend": { - "version": "0.6.0", + "node_modules/async-hook-domain": { + "version": "2.0.4", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=4.0.0" + "node": ">=10" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/default-require-extensions": { - "version": "3.0.0", + "node_modules/async-retry": { + "version": "1.3.3", "dev": true, "license": "MIT", "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" + "retry": "0.13.1" } }, - "node_modules/default-require-extensions/node_modules/strip-bom": { - "version": "4.0.0", + "node_modules/async-retry/node_modules/retry": { + "version": "0.13.1", "dev": true, "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/defaults": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" + "node": ">= 4" } }, - "node_modules/define-properties": { - "version": "1.1.3", + "node_modules/available-typed-arrays": { + "version": "1.0.7", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "object-keys": "^1.0.12" + "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/depd": { - "version": "1.1.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } } }, - "node_modules/detab": { - "version": "2.0.4", + "node_modules/bail": { + "version": "2.0.2", "dev": true, "license": "MIT", - "dependencies": { - "repeat-string": "^1.5.4" - }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/detect-libc": { - "version": "1.0.3", + "node_modules/balanced-match": { + "version": "1.0.2", "dev": true, - "license": "Apache-2.0", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "inBundle": true, - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } + "license": "MIT" }, - "node_modules/docopt": { - "version": "0.6.2", + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } } }, - "node_modules/docs": { - "resolved": "docs", - "link": true - }, - "node_modules/doctrine": { - "version": "3.0.0", + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true, "license": "Apache-2.0", - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" + "bin": { + "baseline-browser-mapping": "dist/cli.js" } }, - "node_modules/domexception": { + "node_modules/basic-auth-parser": { + "version": "0.0.2-1", + "dev": true + }, + "node_modules/before-after-hook": { "version": "4.0.0", "dev": true, - "license": "MIT", - "dependencies": { - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } + "license": "Apache-2.0" }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", + "node_modules/benchmark": { + "version": "2.1.4", "dev": true, "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/encoding": { - "version": "0.1.13", - "inBundle": true, - "license": "MIT", - "optional": true, "dependencies": { - "iconv-lite": "^0.6.2" + "lodash": "^4.17.4", + "platform": "^1.3.3" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "dev": true, "license": "MIT", "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" + "require-from-string": "^2.0.2" } }, - "node_modules/err-code": { - "version": "2.0.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/es-abstract": { - "version": "1.19.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "node_modules/bin-links": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-6.0.0.tgz", + "integrity": "sha512-X4CiKlcV2GjnCMwnKAfbVWpHa++65th9TuzAEYtZoATiOE2DQKhSp4CJlyLoTqdhBKlXjpXjCTYPNNFS33Fi6w==", + "license": "ISC", + "dependencies": { + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "dev": true, + "node_modules/binary-extensions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-3.1.0.tgz", + "integrity": "sha512-Jvvd9hy1w+xUad8+ckQsWA/V1AoyubOvqn0aygjMOVM4BfIaRav1NFS3LsTSDaV4n4FtcCtQXvzep1E6MboqwQ==", "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, "engines": { - "node": ">= 0.4" + "node": ">=18.20" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", + "node_modules/bind-obj-methods": { + "version": "3.0.0", "dev": true, - "license": "MIT", - "peer": true, + "license": "ISC", "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "2.0.0", + "node_modules/boolbase": { + "version": "1.0.0", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } + "license": "ISC" }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", + "node_modules/brace-expansion": { + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" + "balanced-match": "^1.0.0" } }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", + "node_modules/braces": { + "version": "3.0.3", "dev": true, "license": "MIT", "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "fill-range": "^7.1.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, "engines": { - "node": ">= 0.8.0" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", + "node_modules/buffer-from": { + "version": "1.1.2", "dev": true, - "license": "BSD-3-Clause", - "optional": true, + "license": "MIT" + }, + "node_modules/cacache": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", + "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0", + "unique-filename": "^5.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", + "node_modules/caching-transform": { + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2" + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/eslint": { - "version": "8.12.0", + "node_modules/caching-transform/node_modules/signal-exit": { + "version": "3.0.7", "dev": true, - "license": "MIT", - "peer": true, + "license": "ISC" + }, + "node_modules/caching-transform/node_modules/write-file-atomic": { + "version": "3.0.3", + "dev": true, + "license": "ISC", "dependencies": { - "@eslint/eslintrc": "^1.2.1", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", + "node_modules/call-bind": { + "version": "1.0.8", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" }, "engines": { - "node": ">=8.10.0" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-node/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/call-bound": { + "version": "1.0.4", "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { - "node": "*" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", + "node_modules/caller": { + "version": "1.1.0", "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT" + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/eslint-scope": { - "version": "7.1.1", + "node_modules/camelcase": { + "version": "5.3.1", "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=6" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", + "node_modules/camelcase-keys": { + "version": "6.2.2", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", + "node_modules/caniuse-lite": { + "version": "1.0.30001767", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz", + "integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==", "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">=4" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", + "node_modules/ccount": { + "version": "2.0.1", "dev": true, - "license": "Apache-2.0", - "peer": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "inBundle": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", + "node_modules/character-entities": { + "version": "2.0.2", "dev": true, - "license": "Python-2.0", - "peer": true + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/character-entities-html4": { + "version": "2.1.0", "dev": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/eslint/node_modules/eslint-utils": { + "node_modules/character-entities-legacy": { "version": "3.0.0", "dev": true, "license": "MIT", - "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://paulmillr.com/funding/" }, - "peerDependencies": { - "eslint": ">=5" + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", "dev": true, - "license": "Apache-2.0", - "peer": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=10" + "node": ">= 6" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "inBundle": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10.13.0" + "node": ">=18" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.13.0", - "dev": true, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, "license": "MIT", - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, + "node_modules/cidr-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/cidr-regex/-/cidr-regex-5.0.1.tgz", + "integrity": "sha512-2Apfc6qH9uwF3QHmlYBA8ExB9VHq+1/Doj9sEMY55TVBcpQ3y/+gmMpcNIBBtfb5k54Vphmta+1IxjMqPlWWAA==", + "inBundle": true, + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^1.1.7" + "ip-regex": "5.0.0" }, "engines": { - "node": "*" + "node": ">=20" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", + "node_modules/clean-stack": { + "version": "2.2.0", "dev": true, - "license": "(MIT OR CC0-1.0)", - "peer": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/espree": { - "version": "9.3.1", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, + "node_modules/cli-columns": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.3.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 10" } }, - "node_modules/espree/node_modules/acorn": { - "version": "8.7.0", + "node_modules/cli-table3": { + "version": "0.6.5", "dev": true, "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "string-width": "^4.2.0" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "node": "10.* || >= 12.*" }, - "engines": { - "node": ">=4" + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/esquery": { - "version": "1.4.0", + "node_modules/cliui": { + "version": "8.0.1", "dev": true, - "license": "BSD-3-Clause", - "peer": true, + "license": "ISC", "dependencies": { - "estraverse": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=0.10" + "node": ">=12" } }, - "node_modules/esrecurse": { + "node_modules/cliui/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, - "license": "BSD-2-Clause", - "peer": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/estraverse": { - "version": "5.3.0", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/cmd-shim": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-8.0.0.tgz", + "integrity": "sha512-Jk/BK6NCapZ58BKUxlSI+ouKRbjH1NLZCgJkYoab+vEHUY3f6OzpNBN9u7HFSv9J6TRDGs4PLOHezoKGaFRSCA==", + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/events-to-array": { - "version": "1.1.2", - "dev": true, - "license": "ISC" - }, - "node_modules/expand-template": { - "version": "2.0.3", + "node_modules/code-suggester": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/code-suggester/-/code-suggester-5.0.1.tgz", + "integrity": "sha512-8qJiiSCfkbPNWvjEFzdG1UW3axL+Bs0ldV1/TdlBKmF9I/a/WooSQZQCi9M44HoXbVTQesn/IQr6+nIWNnVIWA==", "dev": true, - "license": "(MIT OR WTFPL)", + "license": "Apache-2.0", + "dependencies": { + "@octokit/rest": "^20.1.2", + "@types/yargs": "^16.0.0", + "async-retry": "^1.3.1", + "diff": "^8.0.3", + "glob": "^7.1.6", + "parse-diff": "^0.11.0", + "yargs": "^16.0.0" + }, + "bin": { + "code-suggester": "build/src/bin/code-suggester.js" + }, "engines": { - "node": ">=6" + "node": ">=18.0.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/extsprintf": { - "version": "1.3.0", + "node_modules/code-suggester/node_modules/@octokit/auth-token": { + "version": "4.0.0", "dev": true, - "engines": [ - "node >=0.6.0" - ], "license": "MIT", - "optional": true, - "peer": true + "engines": { + "node": ">= 18" + } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", + "node_modules/code-suggester/node_modules/@octokit/core": { + "version": "5.2.2", "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", + "node_modules/code-suggester/node_modules/@octokit/endpoint": { + "version": "9.0.6", "dev": true, "license": "MIT", - "peer": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "inBundle": true, - "license": "MIT" + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", + "node_modules/code-suggester/node_modules/@octokit/graphql": { + "version": "7.1.1", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "flat-cache": "^3.0.4" + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 18" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", + "node_modules/code-suggester/node_modules/@octokit/openapi-types": { + "version": "24.2.0", "dev": true, "license": "MIT" }, - "node_modules/fill-range": { - "version": "7.0.1", + "node_modules/code-suggester/node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", "dev": true, "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "@octokit/types": "^13.7.0" }, "engines": { - "node": ">=8" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/find-cache-dir": { - "version": "3.3.2", + "node_modules/code-suggester/node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", "dev": true, "license": "MIT", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, "engines": { - "node": ">=8" + "node": ">= 18" }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "4.1.0", + "node_modules/code-suggester/node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@octokit/types": "^13.8.0" }, "engines": { - "node": ">=8" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" } }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "5.0.0", + "node_modules/code-suggester/node_modules/@octokit/request": { + "version": "8.4.1", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/find-cache-dir/node_modules/p-limit": { - "version": "2.3.0", + "node_modules/code-suggester/node_modules/@octokit/request-error": { + "version": "5.1.1", "dev": true, "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 18" } }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "4.1.0", + "node_modules/code-suggester/node_modules/@octokit/rest": { + "version": "20.1.2", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir/node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "node": ">= 18" } }, - "node_modules/find-cache-dir/node_modules/path-exists": { - "version": "4.0.0", + "node_modules/code-suggester/node_modules/@octokit/types": { + "version": "13.10.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "@octokit/openapi-types": "^24.2.0" } }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "4.2.0", + "node_modules/code-suggester/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^4.0.0" + "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/findit": { - "version": "2.0.0", + "node_modules/code-suggester/node_modules/before-after-hook": { + "version": "2.2.3", "dev": true, - "license": "MIT" + "license": "Apache-2.0" }, - "node_modules/flat-cache": { - "version": "3.0.4", + "node_modules/code-suggester/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/flatted": { - "version": "3.2.5", + "node_modules/code-suggester/node_modules/cliui": { + "version": "7.0.4", "dev": true, "license": "ISC", - "peer": true - }, - "node_modules/flow-parser": { - "version": "0.174.1", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/flow-remove-types": { - "version": "2.174.1", + "node_modules/code-suggester/node_modules/glob": { + "version": "7.2.3", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, + "license": "ISC", "dependencies": { - "flow-parser": "^0.174.1", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - }, - "bin": { - "flow-node": "flow-node", - "flow-remove-types": "flow-remove-types" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=4" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child": { - "version": "2.0.0", + "node_modules/code-suggester/node_modules/minimatch": { + "version": "3.1.2", "dev": true, "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8.0.0" + "node": "*" } }, - "node_modules/forever-agent": { - "version": "0.6.1", + "node_modules/code-suggester/node_modules/universal-user-agent": { + "version": "6.0.1", "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true, + "license": "ISC" + }, + "node_modules/code-suggester/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/form-data": { - "version": "4.0.0", + "node_modules/code-suggester/node_modules/yargs": { + "version": "16.2.0", "dev": true, "license": "MIT", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/fromentries": { - "version": "1.3.2", + "node_modules/code-suggester/node_modules/yargs-parser": { + "version": "20.2.9", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "node_modules/fs-access": { - "version": "2.0.0", + "node_modules/color-convert": { + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "null-check": "^1.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, - "node_modules/fs-constants": { - "version": "1.0.0", + "node_modules/color-name": { + "version": "1.1.4", "dev": true, "license": "MIT" }, - "node_modules/fs-exists-cached": { - "version": "1.0.0", + "node_modules/color-support": { + "version": "1.1.3", "dev": true, - "license": "ISC" - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "inBundle": true, "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" + "bin": { + "color-support": "bin.js" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.2", + "node_modules/comma-separated-tokens": { + "version": "2.0.3", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "inBundle": true, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, "license": "MIT" }, - "node_modules/function-loop": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-2.0.1.tgz", - "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==", - "dev": true + "node_modules/common-ancestor-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz", + "integrity": "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">= 18" + } }, - "node_modules/functional-red-black-tree": { + "node_modules/commondir": { "version": "1.0.1", "dev": true, + "license": "MIT" + }, + "node_modules/compare-func": { + "version": "2.0.0", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } }, - "node_modules/gauge": { - "version": "4.0.4", - "inBundle": true, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "dev": true, "license": "ISC", "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": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "compare-func": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=16" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", + "node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=16" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", + "node_modules/conventional-changelog-writer": { + "version": "6.0.1", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=14" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", + "node_modules/conventional-changelog-writer/node_modules/hosted-git-info": { + "version": "4.1.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "lru-cache": "^6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/get-package-type": { - "version": "0.1.0", + "node_modules/conventional-changelog-writer/node_modules/lru-cache": { + "version": "6.0.0", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=8.0.0" + "node": ">=10" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", + "node_modules/conventional-changelog-writer/node_modules/meow": { + "version": "8.1.2", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", + "node_modules/conventional-changelog-writer/node_modules/normalize-package-data": { + "version": "3.0.3", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, + "license": "BSD-2-Clause", "dependencies": { - "assert-plus": "^1.0.0" + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" } }, - "node_modules/github-from-package": { - "version": "0.0.0", + "node_modules/conventional-changelog-writer/node_modules/type-fest": { + "version": "0.18.1", "dev": true, - "license": "MIT" - }, - "node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "inBundle": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/glob-parent": { - "version": "5.1.2", + "node_modules/conventional-changelog-writer/node_modules/yargs-parser": { + "version": "20.2.9", "dev": true, "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/globals": { - "version": "11.12.0", + "node_modules/conventional-commits-filter": { + "version": "3.0.0", "dev": true, "license": "MIT", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, "engines": { - "node": ">=4" + "node": ">=14" } }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "inBundle": true - }, - "node_modules/handlebars": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "node_modules/conventional-commits-parser": { + "version": "5.0.0", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" }, "bin": { - "handlebars": "bin/handlebars" + "conventional-commits-parser": "cli.mjs" }, "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "node": ">=16" } }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/convert-source-map": { + "version": "1.9.0", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/har-schema": { - "version": "2.0.0", + "node_modules/cosmiconfig": { + "version": "9.0.0", "dev": true, - "license": "ISC", - "optional": true, - "peer": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, "engines": { - "node": ">=4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/har-validator": { - "version": "5.1.5", + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", + "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" + "jiti": "^2.6.1" }, "engines": { - "node": ">=6" + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" } }, - "node_modules/has": { - "version": "1.0.3", - "inBundle": true, + "node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, "license": "MIT", "dependencies": { - "function-bind": "^1.1.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">= 0.4.0" + "node": ">= 8" } }, - "node_modules/has-bigints": { - "version": "1.0.1", + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "ISC" }, - "node_modules/has-flag": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/has-symbols": { - "version": "1.0.3", + "node_modules/css-select": { + "version": "5.2.2", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">= 0.4" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "inBundle": true, - "license": "ISC" + "node_modules/cssesc": { + "version": "3.0.0", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } }, - "node_modules/hasha": { - "version": "5.2.2", + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", "dev": true, "license": "MIT", "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=20" } }, - "node_modules/hast-to-hyperscript": { - "version": "9.0.1", + "node_modules/dargs": { + "version": "8.1.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.3", - "comma-separated-tokens": "^1.0.0", - "property-information": "^5.3.0", - "space-separated-tokens": "^1.0.0", - "style-to-object": "^0.3.0", - "unist-util-is": "^4.0.0", - "web-namespaces": "^1.0.0" + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hast-util-from-parse5": { + "node_modules/data-urls": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/parse5": "^5.0.0", - "hastscript": "^6.0.0", - "property-information": "^5.0.0", - "vfile": "^4.0.0", - "vfile-location": "^3.2.0", - "web-namespaces": "^1.0.0" + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=20" } }, - "node_modules/hast-util-parse-selector": { - "version": "2.2.5", + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", "dev": true, "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=20" } }, - "node_modules/hast-util-raw": { - "version": "6.0.1", + "node_modules/data-view-buffer": { + "version": "1.0.2", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^6.0.0", - "hast-util-to-parse5": "^6.0.0", - "html-void-elements": "^1.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hast-util-to-parse5": { - "version": "6.0.0", + "node_modules/data-view-byte-length": { + "version": "1.0.2", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "hast-to-hyperscript": "^9.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/hastscript": { - "version": "6.0.0", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hosted-git-info": { - "version": "5.0.0", + "node_modules/dateformat": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.4.3", "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "lru-cache": "^7.5.1" + "ms": "^2.1.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/html-encoding-sniffer": { - "version": "3.0.0", + "node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^2.0.0" + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" }, "engines": { - "node": ">=12" + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/html-escaper": { - "version": "2.0.2", + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", "dev": true, "license": "MIT" }, - "node_modules/html-void-elements": { - "version": "1.0.5", + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", "dev": true, "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "inBundle": true, - "license": "BSD-2-Clause" + "node_modules/dedent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", + "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "inBundle": true, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "dev": true, "license": "MIT", "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "strip-bom": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/http-signature": { - "version": "1.2.0", + "node_modules/define-data-property": { + "version": "1.1.4", "dev": true, "license": "MIT", - "optional": true, "peer": true, "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "inBundle": true, + "node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "inBundle": true, + "node_modules/deprecation": { + "version": "2.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/dequal": { + "version": "2.0.3", + "dev": true, "license": "MIT", - "dependencies": { - "ms": "^2.0.0" + "engines": { + "node": ">=6" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "devOptional": true, - "inBundle": true, + "node_modules/detect-indent": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "dequal": "^2.0.0" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/discontinuous-range": { + "version": "1.0.0", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "license": "MIT" }, - "node_modules/ignore": { - "version": "5.2.0", + "node_modules/doctrine": { + "version": "3.0.0", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, "engines": { - "node": ">= 4" + "node": ">=6.0.0" } }, - "node_modules/ignore-walk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz", - "integrity": "sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==", - "inBundle": true, + "node_modules/dom-serializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "minimatch": "^5.0.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/import-fresh": { - "version": "3.3.0", + "node_modules/domelementtype": { + "version": "2.3.0", "dev": true, - "license": "MIT", - "peer": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=6" + "node": ">= 4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "inBundle": true, + "node_modules/domutils": { + "version": "3.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "dev": true, "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, "engines": { - "node": ">=0.8.19" + "node": ">=8" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "inBundle": true, + "node_modules/dunder-proto": { + "version": "1.0.1", + "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/infer-owner": { - "version": "1.0.4", - "inBundle": true, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.283", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.283.tgz", + "integrity": "sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==", + "dev": true, "license": "ISC" }, - "node_modules/inflight": { - "version": "1.0.6", + "node_modules/emoji-regex": { + "version": "8.0.0", "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } + "license": "MIT" }, - "node_modules/inherits": { - "version": "2.0.4", + "node_modules/encoding": { + "version": "0.1.13", "inBundle": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } }, - "node_modules/ini": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz", - "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==", - "inBundle": true, + "node_modules/entities": { + "version": "4.5.0", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/init-package-json": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-3.0.2.tgz", - "integrity": "sha512-YhlQPEjNFqlGdzrBfDNRLhvoSgX7iQRgSxgsNknRQ9ITXFT7UMfVMWhBTOh2Y+25lRnGrv5Xz8yZwQ3ACR6T3A==", + "node_modules/env-paths": { + "version": "2.2.1", "inBundle": true, - "dependencies": { - "npm-package-arg": "^9.0.1", - "promzard": "^0.3.0", - "read": "^1.0.7", - "read-package-json": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=6" } }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "dev": true, + "node_modules/err-code": { + "version": "2.0.3", + "inBundle": true, "license": "MIT" }, - "node_modules/internal-slot": { - "version": "1.0.3", + "node_modules/error-ex": { + "version": "1.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", - "inBundle": true - }, - "node_modules/ip-regex": { - "version": "4.3.0", - "inBundle": true, + "node_modules/es-define-property": { + "version": "1.0.1", + "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/is-alphabetical": { - "version": "1.0.4", + "node_modules/es-errors": { + "version": "1.3.0", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "peer": true, + "engines": { + "node": ">= 0.4" } }, - "node_modules/is-alphanumerical": { - "version": "1.0.4", + "node_modules/es-object-atoms": { + "version": "1.1.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "es-errors": "^1.3.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">= 0.4" } }, - "node_modules/is-bigint": { - "version": "1.0.4", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "has-bigints": "^1.0.1" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.4" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", + "node_modules/es-shim-unscopables": { + "version": "1.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "binary-extensions": "^2.0.0" + "hasown": "^2.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", + "node_modules/es-to-primitive": { + "version": "1.3.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -3833,1549 +4618,4793 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "2.0.5", + "node_modules/es6-error": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT", "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/is-callable": { - "version": "1.2.4", + "node_modules/escape-string-regexp": { + "version": "4.0.0", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-cidr": { - "version": "4.0.2", - "inBundle": true, - "license": "BSD-2-Clause", + "node_modules/eslint": { + "version": "8.57.1", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "cidr-regex": "^3.1.1" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=10" - } - }, - "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "inBundle": true, - "dependencies": { - "has": "^1.0.3" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/is-date-object": { - "version": "1.0.5", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/is-decimal": { - "version": "1.0.4", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "peer": true, + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/is-extglob": { - "version": "2.1.1", + "node_modules/eslint-module-utils": { + "version": "2.12.1", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^3.2.7" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "inBundle": true, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "peer": true, + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/is-glob": { - "version": "4.0.3", + "node_modules/eslint-plugin-es": { + "version": "3.0.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "is-extglob": "^2.1.1" + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "1.0.4", - "dev": true, - "license": "MIT", + "node": ">=8.10.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" } }, - "node_modules/is-lambda": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", + "node_modules/eslint-plugin-import": { + "version": "2.32.0", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/is-number": { - "version": "7.0.0", + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.12.0" + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/is-number-object": { - "version": "1.0.6", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "peer": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "license": "MIT", + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", "dev": true, - "license": "MIT" + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/is-regex": { - "version": "1.1.4", + "node_modules/eslint-plugin-node": { + "version": "11.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8.10.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "eslint": ">=5.16.0" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", + "node_modules/eslint-plugin-node/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/is-stream": { - "version": "2.0.1", + "node_modules/eslint-plugin-node/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "license": "MIT", + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=8" + "node": "*" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.6.0", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/is-string": { - "version": "1.0.7", + "node_modules/eslint-scope": { + "version": "7.2.2", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", + "peer": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/is-symbol": { - "version": "1.0.4", + "node_modules/eslint-utils": { + "version": "2.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "has-symbols": "^1.0.2" + "eslint-visitor-keys": "^1.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=4" + } }, - "node_modules/is-weakref": { - "version": "1.0.2", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/is-whitespace-character": { - "version": "1.0.4", + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, "funding": { "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/is-windows": { - "version": "1.0.2", + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-word-character": { - "version": "1.0.4", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/isarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/isstream": { - "version": "0.1.2", + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "dev": true, - "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "peer": true, "dependencies": { - "append-transform": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "peer": true + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", "dev": true, "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", "dev": true, - "license": "ISC", + "license": "MIT", + "peer": true, "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-processinfo/node_modules/p-map": { - "version": "3.0.0", + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "aggregate-error": "^3.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, + "license": "MIT", + "peer": true, "engines": { "node": ">=8" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "peer": true, "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", + "node_modules/eslint/node_modules/yocto-queue": { + "version": "0.1.0", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-reports": { - "version": "3.1.4", + "node_modules/espree": { + "version": "9.6.1", "dev": true, - "license": "BSD-3-Clause", + "license": "BSD-2-Clause", + "peer": true, "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/jackspeak": { - "version": "1.4.1", + "node_modules/esprima": { + "version": "4.0.1", "dev": true, - "license": "ISC", - "dependencies": { - "cliui": "^7.0.4" + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.1", + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "peer": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "estraverse": "^5.1.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=0.10" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/jsdom": { - "version": "18.1.1", + "node_modules/esrecurse": { + "version": "4.3.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", + "peer": true, "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.5.0", - "acorn-globals": "^6.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.1", - "decimal.js": "^10.3.1", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^3.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^10.0.0", - "ws": "^8.2.3", - "xml-name-validator": "^4.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=12" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "node": ">=4.0" } }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.7.0", + "node_modules/estraverse": { + "version": "5.3.0", "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, + "license": "BSD-2-Clause", + "peer": true, "engines": { - "node": ">=0.4.0" + "node": ">=4.0" } }, - "node_modules/jsesc": { - "version": "2.5.2", + "node_modules/esutils": { + "version": "2.0.3", "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, + "license": "BSD-2-Clause", + "peer": true, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/json-parse-errback": { - "version": "2.0.1", + "node_modules/events-to-array": { + "version": "1.1.2", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "inBundle": true, - "license": "MIT" + "license": "Apache-2.0" }, - "node_modules/json-schema": { - "version": "0.4.0", + "node_modules/extend": { + "version": "3.0.2", "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)", - "optional": true, - "peer": true + "license": "MIT" }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", "dev": true, "license": "MIT", "peer": true }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", + "node_modules/fast-levenshtein": { + "version": "2.0.6", "dev": true, "license": "MIT", "peer": true }, - "node_modules/json-stringify-nice": { - "version": "1.1.4", - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node_modules/fast-uri": { + "version": "3.1.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" } }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, - "license": "ISC" + "license": "ISC", + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } }, - "node_modules/json5": { - "version": "2.2.1", + "node_modules/figures": { + "version": "3.2.0", "dev": true, "license": "MIT", - "bin": { - "json5": "lib/cli.js" + "dependencies": { + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsonparse": { - "version": "1.3.1", - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } }, - "node_modules/jsprim": { - "version": "1.4.2", + "node_modules/file-entry-cache": { + "version": "6.0.1", "dev": true, "license": "MIT", - "optional": true, "peer": true, "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=0.6.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/just-diff": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-5.0.3.tgz", - "integrity": "sha512-a8p80xcpJ6sdurk5PxDKb4mav9MeKjA3zFKZpCWBIfvg8mznfnmb13MKZvlrwJ+Lhis0wM3uGAzE0ArhFHvIcg==", - "inBundle": true - }, - "node_modules/just-diff-apply": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.3.1.tgz", - "integrity": "sha512-dgFenZnMsc1xGNqgdtgnh7DK+Oy352CE3VZLbzcbQpsBs9iI2K3M0IRrdgREZ72eItTjbl0suRyvKRdVQa9GbA==", - "inBundle": true - }, - "node_modules/lcov-parse": { - "version": "1.0.0", + "node_modules/fill-range": { + "version": "7.1.1", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, - "bin": { - "lcov-parse": "bin/cli.js" + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/levn": { - "version": "0.4.1", + "node_modules/find-cache-dir": { + "version": "3.3.2", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/libnpmaccess": { - "resolved": "workspaces/libnpmaccess", - "link": true - }, - "node_modules/libnpmdiff": { - "resolved": "workspaces/libnpmdiff", - "link": true - }, - "node_modules/libnpmexec": { - "resolved": "workspaces/libnpmexec", - "link": true - }, - "node_modules/libnpmfund": { - "resolved": "workspaces/libnpmfund", - "link": true - }, - "node_modules/libnpmhook": { - "resolved": "workspaces/libnpmhook", - "link": true - }, - "node_modules/libnpmorg": { - "resolved": "workspaces/libnpmorg", - "link": true - }, - "node_modules/libnpmpack": { - "resolved": "workspaces/libnpmpack", - "link": true + "node_modules/find-up": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/libnpmpublish": { - "resolved": "workspaces/libnpmpublish", - "link": true + "node_modules/findit": { + "version": "2.0.0", + "dev": true, + "license": "MIT" }, - "node_modules/libnpmsearch": { - "resolved": "workspaces/libnpmsearch", - "link": true + "node_modules/flat-cache": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } }, - "node_modules/libnpmteam": { - "resolved": "workspaces/libnpmteam", - "link": true + "node_modules/flat-cache/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "node_modules/libnpmversion": { - "resolved": "workspaces/libnpmversion", - "link": true + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/libtap": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz", - "integrity": "sha512-STLFynswQ2A6W14JkabgGetBNk6INL1REgJ9UeNKw5llXroC2cGLgKTqavv0sl8OLVztLLipVKMcQ7yeUcqpmg==", + "node_modules/flat-cache/node_modules/minimatch": { + "version": "3.1.2", "dev": true, + "license": "ISC", + "peer": true, "dependencies": { - "async-hook-domain": "^2.0.4", - "bind-obj-methods": "^3.0.0", - "diff": "^4.0.2", - "function-loop": "^2.0.1", - "minipass": "^3.1.5", - "own-or": "^1.0.0", - "own-or-env": "^1.0.2", - "signal-exit": "^3.0.4", - "stack-utils": "^2.0.4", - "tap-parser": "^11.0.0", - "tap-yaml": "^1.0.0", - "tcompare": "^5.0.6", - "trivial-deferred": "^1.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10" + "node": "*" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/libtap/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/flatted": { + "version": "3.3.3", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/for-each": { + "version": "0.3.5", "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/front-matter": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1" + } + }, + "node_modules/front-matter/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/front-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/fs-exists-cached": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-loop": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/glob": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.1.tgz", + "integrity": "sha512-B7U/vJpE3DkJ5WXTgTpTRN63uV42DseiXXKMwG14LQBXmsdeIoHAPbU/MEo6II0k5ED74uc2ZGTC6MwHFQhF6w==", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.2", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-directory/node_modules/ini": { + "version": "4.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/groff-escape": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "devOptional": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "8.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/init-package-json": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-8.2.4.tgz", + "integrity": "sha512-SqX/+tPl3sZD+IY0EuMiM1kK1B45h+P6JQPo3Q9zlqNINX2XiX3x/WSbYGFqS6YCkODNbGb3L5RawMrYE/cfKw==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "npm-package-arg": "^13.0.0", + "promzard": "^3.0.1", + "read": "^5.0.1", + "semver": "^7.7.2", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", + "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-binary-path/node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-cidr": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/is-cidr/-/is-cidr-6.0.2.tgz", + "integrity": "sha512-a4SY0KixgRXn67zSCooPNO4YRHZd1z6BIxrEBQUVNPteeajzrJLhZKnn81GVQO51uiCljTtGY+J3o6O3/DZpzg==", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^5.0.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-text-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/isexe": { + "version": "3.1.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsep": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/jsonpath-plus": { + "version": "10.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.3.0", + "@jsep-plugin/regex": "^1.0.4", + "jsep": "^1.4.0" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/just-deep-map-values": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/just-diff": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/just-extend": { + "version": "6.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/just-omit": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/just-safe-set": { + "version": "4.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libnpmaccess": { + "resolved": "workspaces/libnpmaccess", + "link": true + }, + "node_modules/libnpmdiff": { + "resolved": "workspaces/libnpmdiff", + "link": true + }, + "node_modules/libnpmexec": { + "resolved": "workspaces/libnpmexec", + "link": true + }, + "node_modules/libnpmfund": { + "resolved": "workspaces/libnpmfund", + "link": true + }, + "node_modules/libnpmorg": { + "resolved": "workspaces/libnpmorg", + "link": true + }, + "node_modules/libnpmpack": { + "resolved": "workspaces/libnpmpack", + "link": true + }, + "node_modules/libnpmpublish": { + "resolved": "workspaces/libnpmpublish", + "link": true + }, + "node_modules/libnpmsearch": { + "resolved": "workspaces/libnpmsearch", + "link": true + }, + "node_modules/libnpmteam": { + "resolved": "workspaces/libnpmteam", + "link": true + }, + "node_modules/libnpmversion": { + "resolved": "workspaces/libnpmversion", + "link": true + }, + "node_modules/libtap": { + "version": "1.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "async-hook-domain": "^2.0.4", + "bind-obj-methods": "^3.0.0", + "diff": "^4.0.2", + "function-loop": "^2.0.1", + "minipass": "^3.1.5", + "own-or": "^1.0.0", + "own-or-env": "^1.0.2", + "signal-exit": "^3.0.4", + "stack-utils": "^2.0.4", + "tap-parser": "^11.0.0", + "tap-yaml": "^1.0.0", + "tcompare": "^5.0.6", + "trivial-deferred": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/libtap/node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/libtap/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/libtap/node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-fetch-happen": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", + "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/meow": { + "version": "12.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/min-indent": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minify-registry-metadata": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/minimatch": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", + "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.1.tgz", + "integrity": "sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, "engines": { - "node": ">=0.3.1" + "node": ">= 18" } }, - "node_modules/licensee": { - "version": "8.2.0", + "node_modules/modify-values": { + "version": "1.0.1", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@blueoak/list": "^2.0.0", - "correct-license-metadata": "^1.0.1", - "docopt": "^0.6.2", - "fs-access": "^2.0.0", - "has": "^1.0.3", - "json-parse-errback": "^2.0.1", - "npm-license-corrections": "^1.0.0", - "read-package-tree": "^5.3.1", - "run-parallel": "^1.1.9", - "semver": "^6.3.0", - "simple-concat": "^1.0.0", - "spdx-expression-parse": "^3.0.0", - "spdx-expression-validate": "^2.0.0", - "spdx-osi": "^3.0.0", - "spdx-whitelisted": "^1.0.0" - }, - "bin": { - "licensee": "licensee" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/licensee/node_modules/semver": { - "version": "6.3.0", + "node_modules/months": { + "version": "2.1.0", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/lodash": { - "version": "4.17.21", + "node_modules/moo": { + "version": "0.5.2", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause" }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "dev": true, + "node_modules/ms": { + "version": "2.1.3", + "inBundle": true, "license": "MIT" }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "dev": true, - "license": "MIT" + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/lodash.merge": { - "version": "4.6.2", + "node_modules/natural-compare": { + "version": "1.4.0", "dev": true, "license": "MIT", "peer": true }, - "node_modules/lodash.uniq": { - "version": "4.5.0", + "node_modules/nearley": { + "version": "2.20.1", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "bin": { + "nearley-railroad": "bin/nearley-railroad.js", + "nearley-test": "bin/nearley-test.js", + "nearley-unparse": "bin/nearley-unparse.js", + "nearleyc": "bin/nearleyc.js" + }, + "funding": { + "type": "individual", + "url": "https://nearley.js.org/#give-to-nearley" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", "dev": true, "license": "MIT" }, - "node_modules/log-driver": { - "version": "1.2.7", + "node_modules/nock": { + "version": "13.5.6", "dev": true, - "license": "ISC", - "optional": true, - "peer": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, "engines": { - "node": ">=0.8.6" + "node": ">= 10.13" } }, - "node_modules/lru-cache": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.12.0.tgz", - "integrity": "sha512-OIP3DwzRZDfLg9B9VP/huWBlpvbkmbfiBy8xmsXp4RPmE4A3MhwNozc5ZJ3fWnSg8fDcdlE/neRTPG2ycEKliw==", + "node_modules/node-gyp": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.2.0.tgz", + "integrity": "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==", "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, "engines": { - "node": ">=12" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/make-dir": { - "version": "3.1.0", + "node_modules/node-html-parser": { + "version": "6.1.13", "dev": true, "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "css-select": "^5.1.0", + "he": "1.2.0" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "process-on-spawn": "^1.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "inBundle": true, "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, "bin": { - "semver": "bin/semver.js" + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/make-error": { - "version": "1.3.6", + "node_modules/normalize-path": { + "version": "3.0.0", "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-audit-report": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/npm-audit-report/-/npm-audit-report-7.0.0.tgz", + "integrity": "sha512-bluLL4xwGr/3PERYz50h2Upco0TJMDcLcymuFnfDWeGO99NqH724MNzhWi5sXXuXf2jbytFF0LyR8W+w1jTI6A==", + "inBundle": true, "license": "ISC", - "optional": true, - "peer": true + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/make-fetch-happen": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.0.tgz", - "integrity": "sha512-OnEfCLofQVJ5zgKwGk55GaqosqKjaR6khQlJY3dBAA+hM25Bc5CmX5rKUfVut+rYA3uidA7zb7AvcglU87rPRg==", + "node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", "inBundle": true, + "license": "ISC", "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" + "npm-normalize-package-bin": "^5.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/markdown-escapes": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/marked": { - "version": "0.7.0", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "marked": "bin/marked" + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-package-arg": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", + "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/marked-man": { - "version": "0.7.0", - "dev": true, - "license": "MIT", - "bin": { - "marked-man": "bin/marked-man" + "node_modules/npm-packlist": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", + "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" }, - "peerDependencies": { - "marked": "^0.7.0" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/mdast-squeeze-paragraphs": { - "version": "4.0.0", - "dev": true, - "license": "MIT", + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", + "inBundle": true, + "license": "ISC", "dependencies": { - "unist-util-remove": "^2.0.0" + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/mdast-util-definitions": { - "version": "4.0.0", - "dev": true, - "license": "MIT", + "node_modules/npm-profile": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-12.0.1.tgz", + "integrity": "sha512-Xs1mejJ1/9IKucCxdFMkiBJUre0xaxfCpbsO7DB7CadITuT4k68eI05HBlw4kj+Em1rsFMgeFNljFPYvPETbVQ==", + "inBundle": true, + "license": "ISC", "dependencies": { - "unist-util-visit": "^2.0.0" + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/mdast-util-to-hast": { - "version": "10.0.1", - "dev": true, - "license": "MIT", + "node_modules/npm-registry-fetch": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", + "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", + "inBundle": true, + "license": "ISC", "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/mdurl": { - "version": "1.0.1", + "node_modules/npm-user-validate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-4.0.0.tgz", + "integrity": "sha512-TP+Ziq/qPi/JRdhaEhnaiMkqfMGjhDLoh/oRfW+t5aCuIfJxIUxvwk6Sg/6ZJ069N/Be6gs00r+aZeJTfS9uHQ==", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", "dev": true, - "license": "MIT" + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } }, - "node_modules/mime-db": { - "version": "1.52.0", + "node_modules/nyc": { + "version": "15.1.0", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, "engines": { - "node": ">= 0.6" + "node": ">=8.9" } }, - "node_modules/mime-types": { - "version": "2.1.35", + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "color-convert": "^2.0.1" }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "2.1.0", - "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/minify-registry-metadata": { - "version": "2.2.0", + "node_modules/nyc/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, - "license": "ISC" - }, - "node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "inBundle": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/minimist": { - "version": "1.2.6", + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", "dev": true, - "license": "MIT" - }, - "node_modules/minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", - "inBundle": true, + "license": "ISC", "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/minipass-fetch": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", + "node_modules/nyc/node_modules/foreground-child": { + "version": "2.0.0", + "dev": true, + "license": "ISC", "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" + "node": ">=8.0.0" } }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "inBundle": true, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.3", + "dev": true, "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 8" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minipass-json-stream": { - "version": "1.0.1", - "inBundle": true, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "inBundle": true, + "node_modules/nyc/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/minizlib": { - "version": "2.1.2", - "inBundle": true, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" + "node": ">=6" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", "dev": true, - "license": "MIT" - }, - "node_modules/mkdirp-infer-owner": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "chownr": "^2.0.0", - "infer-owner": "^1.0.4", - "mkdirp": "^1.0.3" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/ms": { - "version": "2.1.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "inBundle": true, - "license": "ISC" - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", "dev": true, "license": "MIT", - "peer": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nock": { - "version": "13.2.8", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.8.tgz", - "integrity": "sha512-JT42FrXfQRpfyL4cnbBEJdf4nmBpVP0yoCcSBr+xkT8Q1y3pgtaCKHGAAOIFcEJ3O3t0QbVAmid0S0f2bj3Wpg==", - "dev": true, "dependencies": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.21", - "propagate": "^2.0.0" + "aggregate-error": "^3.0.0" }, "engines": { - "node": ">= 10.13" + "node": ">=8" } }, - "node_modules/node-abi": { - "version": "2.30.1", + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "semver": "^5.4.1" + "engines": { + "node": ">=8" } }, - "node_modules/node-abi/node_modules/semver": { - "version": "5.7.1", + "node_modules/nyc/node_modules/rimraf": { + "version": "3.0.2", "dev": true, "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, "bin": { - "semver": "bin/semver" + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/node-addon-api": { - "version": "3.2.1", + "node_modules/nyc/node_modules/signal-exit": { + "version": "3.0.7", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/node-gyp": { - "version": "9.0.0", - "inBundle": true, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "dev": true, "license": "MIT", "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "^12.22 || ^14.13 || >=16" + "node": ">=8" } }, - "node_modules/node-gyp/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "inBundle": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "dev": true, + "license": "ISC" }, - "node_modules/node-gyp/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "inBundle": true, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/node-gyp/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "inBundle": true, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" }, "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", + "node_modules/object-inspect": { + "version": "1.13.4", "dev": true, "license": "MIT", - "optional": true, "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/node-preload": { - "version": "0.2.1", + "node_modules/object-keys": { + "version": "1.1.1", "dev": true, "license": "MIT", - "dependencies": { - "process-on-spawn": "^1.0.0" - }, + "peer": true, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/nopt": { - "version": "5.0.0", - "inBundle": true, - "license": "ISC", + "node_modules/object.assign": { + "version": "4.1.7", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/normalize-package-data": { - "version": "4.0.0", - "inBundle": true, - "license": "BSD-2-Clause", + "node_modules/object.fromentries": { + "version": "2.0.8", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "hosted-git-info": "^5.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/normalize-path": { - "version": "3.0.0", + "node_modules/object.groupby": { + "version": "1.0.3", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/npm-audit-report": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", + "node_modules/object.values": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "chalk": "^4.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/npm-bundled": { - "version": "1.1.2", - "inBundle": true, + "node_modules/once": { + "version": "1.4.0", + "dev": true, "license": "ISC", "dependencies": { - "npm-normalize-package-bin": "^1.0.1" + "wrappy": "1" } }, - "node_modules/npm-install-checks": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-5.0.0.tgz", - "integrity": "sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA==", - "inBundle": true, + "node_modules/opener": { + "version": "1.5.2", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "semver": "^7.1.1" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">= 0.8.0" } }, - "node_modules/npm-license-corrections": { - "version": "1.5.0", + "node_modules/own-keys": { + "version": "1.0.1", "dev": true, - "license": "CC0-1.0" + "license": "MIT", + "peer": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/npm-normalize-package-bin": { - "version": "1.0.1", - "inBundle": true, + "node_modules/own-or": { + "version": "1.0.0", + "dev": true, "license": "ISC" }, - "node_modules/npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", - "inBundle": true, + "node_modules/own-or-env": { + "version": "1.0.2", + "dev": true, + "license": "ISC", "dependencies": { - "hosted-git-info": "^5.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "validate-npm-package-name": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "own-or": "^1.0.0" } }, - "node_modules/npm-packlist": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.1.tgz", - "integrity": "sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw==", - "inBundle": true, + "node_modules/p-limit": { + "version": "4.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "glob": "^8.0.1", - "ignore-walk": "^5.0.1", - "npm-bundled": "^1.1.2", - "npm-normalize-package-bin": "^1.0.1" - }, - "bin": { - "npm-packlist": "bin/index.js" + "yocto-queue": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-pick-manifest": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz", - "integrity": "sha512-IA8+tuv8KujbsbLQvselW2XQgmXWS47t3CB0ZrzsRZ82DbDfkcFunOaPm4X7qNuhMfq+FmV7hQT4iFVpHqV7mg==", - "inBundle": true, + "node_modules/p-locate": { + "version": "6.0.0", + "dev": true, + "license": "MIT", "dependencies": { - "npm-install-checks": "^5.0.0", - "npm-normalize-package-bin": "^1.0.1", - "npm-package-arg": "^9.0.0", - "semver": "^7.3.5" + "p-limit": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-profile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-6.2.1.tgz", - "integrity": "sha512-Tlu13duByHyDd4Xy0PgroxzxnBYWbGGL5aZifNp8cx2DxUrHSoETXtPKg38aRPsBWMRfDtvcvVfJNasj7oImQQ==", + "node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "inBundle": true, - "dependencies": { - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=18" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=6" } }, - "node_modules/npm-registry-fetch": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.3.0.tgz", - "integrity": "sha512-10LJQ/1+VhKrZjIuY9I/+gQTvumqqlgnsCufoXETHAPFTS3+M+Z5CFhZRDHGavmJ6rOye3UvNga88vl8n1r6gg==", - "inBundle": true, + "node_modules/package-hash": { + "version": "4.0.0", + "dev": true, + "license": "ISC", "dependencies": { - "make-fetch-happen": "^10.0.6", - "minipass": "^3.1.6", - "minipass-fetch": "^2.0.3", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^9.0.1", - "proc-log": "^2.0.0" + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/npm-user-validate": { + "node_modules/package-json-from-dist": { "version": "1.0.1", - "inBundle": true, - "license": "BSD-2-Clause" + "dev": true, + "license": "BlueOak-1.0.0" }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "node_modules/pacote": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.1.0.tgz", + "integrity": "sha512-WF/PwrImIIVaLmtuCeO5L7n6DA0ZGCqmDPO/XbNjZgNUX+2O5z4f4Wdmu6erBWNICkl3ftKJvit2eIVcpegRRw==", "inBundle": true, + "license": "ISC", "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/null-check": { - "version": "1.0.0", + "node_modules/parent-module": { + "version": "1.0.1", "dev": true, "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "dev": true, - "license": "MIT", + "node_modules/parse-conflict-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-5.0.1.tgz", + "integrity": "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ==", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^5.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/nwsapi": { - "version": "2.2.0", + "node_modules/parse-diff": { + "version": "0.11.1", "dev": true, "license": "MIT" }, - "node_modules/nyc": { - "version": "15.1.0", + "node_modules/parse-github-repo-url": { + "version": "1.4.1", "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, - "bin": { - "nyc": "bin/nyc.js" + "engines": { + "node": ">=8" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "5.0.0", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8.9" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/nyc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/path-is-absolute": { + "version": "1.0.1", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", + "node_modules/path-key": { + "version": "3.1.1", "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/path-parse": { + "version": "1.0.7", "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "inBundle": true, + "license": "BlueOak-1.0.0", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/pkg-dir": { + "version": "4.2.0", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "find-up": "^4.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/nyc/node_modules/p-limit": { + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", "dev": true, "license": "MIT", @@ -5389,7 +9418,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nyc/node_modules/p-locate": { + "node_modules/pkg-dir/node_modules/p-locate": { "version": "4.1.0", "dev": true, "license": "MIT", @@ -5400,980 +9429,945 @@ "node": ">=8" } }, - "node_modules/nyc/node_modules/p-map": { - "version": "3.0.0", + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/nyc/node_modules/p-try": { - "version": "2.2.0", + "node_modules/platform": { + "version": "1.3.6", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/nyc/node_modules/path-exists": { - "version": "4.0.0", + "node_modules/possible-typed-array-names": { + "version": "1.1.0", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", + "node_modules/prelude-ls": { + "version": "1.2.1", "dev": true, - "license": "Apache-2.0", - "optional": true, + "license": "MIT", "peer": true, "engines": { - "node": "*" + "node": ">= 0.8.0" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/object-inspect": { - "version": "1.12.0", + "node_modules/process-on-spawn": { + "version": "1.1.0", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "dev": true, - "license": "MIT", + "node_modules/proggy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/proggy/-/proggy-4.0.0.tgz", + "integrity": "sha512-MbA4R+WQT76ZBm/5JUpV9yqcJt92175+Y0Bodg3HgiXzrmKu7Ggq+bpn6y6wHH+gN9NcyKn3yg1+d47VaKwNAQ==", + "license": "ISC", "engines": { - "node": ">= 0.4" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/object.assign": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "license": "ISC", "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.3", - "dev": true, + "node_modules/promise-call-limit": { + "version": "3.0.2", + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "inBundle": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "err-code": "^2.0.2", + "retry": "^0.12.0" }, "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "node_modules/once": { - "version": "1.4.0", + "node_modules/promzard": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-3.0.1.tgz", + "integrity": "sha512-M5mHhWh+Adz0BIxgSrqcc6GTCSconR7zWQV9vnOSptNtr6cSFlApLc28GbQhuN6oOWBQeV2C0bNE47JCY/zu3Q==", "inBundle": true, "license": "ISC", "dependencies": { - "wrappy": "1" + "read": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/opener": { - "version": "1.5.2", - "inBundle": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" + "node_modules/propagate": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" } }, - "node_modules/optionator": { - "version": "0.9.1", + "node_modules/property-information": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy": { + "version": "2.2.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "args": "^5.0.3", + "basic-auth-parser": "0.0.2-1", + "debug": "^4.3.4" + }, + "bin": { + "proxy": "dist/bin/proxy.js" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 14" } }, - "node_modules/own-or": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha512-NfZr5+Tdf6MB8UI9GLvKRs4cXY8/yB0w3xtt84xFdWy8hkGjn+JFc60VhzS/hFRfbyxFcGYMTjnF4Me+RbbqrA==", - "dev": true - }, - "node_modules/own-or-env": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz", - "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==", + "node_modules/punycode": { + "version": "2.3.1", "dev": true, - "dependencies": { - "own-or": "^1.0.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "node_modules/qrcode-terminal": { + "version": "0.12.0", "inBundle": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" } }, - "node_modules/package-hash": { - "version": "4.0.0", + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/quick-lru": { + "version": "4.0.1", "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/pacote": { - "version": "13.6.1", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-13.6.1.tgz", - "integrity": "sha512-L+2BI1ougAPsFjXRyBhcKmfT016NscRFLv6Pz5EiNf1CCFJFU0pSKKQwsZTyAQB+sTuUL4TyFyp6J1Ork3dOqw==", - "inBundle": true, - "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/run-script": "^4.1.0", - "cacache": "^16.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "infer-owner": "^1.0.4", - "minipass": "^3.1.6", - "mkdirp": "^1.0.4", - "npm-package-arg": "^9.0.0", - "npm-packlist": "^5.1.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.1", - "proc-log": "^2.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^5.0.0", - "read-package-json-fast": "^2.0.3", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } + "node_modules/railroad-diagrams": { + "version": "1.0.0", + "dev": true, + "license": "CC0-1.0" }, - "node_modules/parent-module": { - "version": "1.0.1", + "node_modules/randexp": { + "version": "0.4.6", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "callsites": "^3.0.0" + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" }, "engines": { - "node": ">=6" + "node": ">=0.12" } }, - "node_modules/parse-conflict-json": { - "version": "2.0.2", + "node_modules/read": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/read/-/read-5.0.1.tgz", + "integrity": "sha512-+nsqpqYkkpet2UVPG8ZiuE8d113DK4vHYEoEhcrXBAlPiq6di7QRTuNiKQAbaRYegobuX2BpZ6QjanKOXnJdTA==", "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^2.3.1", - "just-diff": "^5.0.1", - "just-diff-apply": "^5.2.0" + "mute-stream": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/parse-entities": { - "version": "2.0.0", + "node_modules/read-cmd-shim": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-6.0.0.tgz", + "integrity": "sha512-1zM5HuOfagXCBWMN83fuFI/x+T/UhZ7k+KIzhrHXcQoeX5+7gmaDYjELQHmmzIodumBHeByBJT4QYS7ufAgs7A==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", "dev": true, "license": "MIT", "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">=8" } }, - "node_modules/parse5": { - "version": "6.0.1", + "node_modules/read-pkg-up": { + "version": "7.0.1", "dev": true, - "license": "MIT" - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "inBundle": true, "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-key": { - "version": "3.1.1", + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", "dev": true, "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/picomatch": { - "version": "2.3.1", + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=8.6" + "dependencies": { + "p-locate": "^4.1.0" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "engines": { + "node": ">=8" } }, - "node_modules/pirates": { - "version": "3.0.2", + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "node-modules-regexp": "^1.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/platform": { - "version": "1.3.6", + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", "dev": true, - "license": "MIT" - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "license": "MIT", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/prebuild-install": { - "version": "6.1.4", + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/prebuild-install/node_modules/ansi-regex": { - "version": "2.1.1", + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", "dev": true, - "license": "MIT", + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/prebuild-install/node_modules/aproba": { - "version": "1.2.0", + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", "dev": true, "license": "ISC" }, - "node_modules/prebuild-install/node_modules/are-we-there-yet": { - "version": "1.1.7", + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "node_modules/prebuild-install/node_modules/gauge": { - "version": "2.7.4", + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", "dev": true, "license": "ISC", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "bin": { + "semver": "bin/semver" } }, - "node_modules/prebuild-install/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", "dev": true, - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/prebuild-install/node_modules/npmlog": { - "version": "4.1.2", + "node_modules/readdirp": { + "version": "3.6.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "node_modules/prebuild-install/node_modules/readable-stream": { - "version": "2.3.7", + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", "dev": true, "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/prebuild-install/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/prebuild-install/node_modules/string_decoder": { - "version": "1.1.1", + "node_modules/redent": { + "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "~5.1.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/prebuild-install/node_modules/string-width": { - "version": "1.0.2", + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/prebuild-install/node_modules/strip-ansi": { - "version": "3.0.1", + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "ansi-regex": "^2.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", + "node_modules/regexpp": { + "version": "3.2.0", "dev": true, "license": "MIT", "peer": true, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/proc-log": { - "version": "2.0.1", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", + "node_modules/rehype-stringify": { + "version": "10.0.1", "dev": true, "license": "MIT", "dependencies": { - "fromentries": "^1.2.0" + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/promise-call-limit": { - "version": "1.0.1", - "license": "ISC", "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", + "node_modules/release-please": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/release-please/-/release-please-17.2.0.tgz", + "integrity": "sha512-DIB8gXH+GBwy1MvkJ/xUceVPW+10OOQagNBaOB/V3B8hHbfsVbQjwEL0Hu6zTRsqve9wRvqE48mKtwjaXIxupA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "@conventional-commits/parser": "^0.4.1", + "@google-automations/git-file-utils": "^3.0.0", + "@iarna/toml": "^3.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/rest": "^20.1.1", + "@types/npm-package-arg": "^6.1.0", + "@xmldom/xmldom": "^0.8.4", + "chalk": "^4.0.0", + "code-suggester": "^5.0.0", + "conventional-changelog-conventionalcommits": "^6.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-filter": "^3.0.0", + "detect-indent": "^6.1.0", + "diff": "^8.0.3", + "figures": "^3.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "js-yaml": "^4.0.0", + "jsonpath-plus": "^10.0.0", + "node-html-parser": "^6.0.0", + "parse-github-repo-url": "^1.4.1", + "semver": "^7.5.3", + "type-fest": "^3.0.0", + "typescript": "^4.6.4", + "unist-util-visit": "^2.0.3", + "unist-util-visit-parents": "^3.1.1", + "xpath": "^0.0.34", + "yaml": "^2.2.2", + "yargs": "^17.0.0" + }, + "bin": { + "release-please": "build/src/bin/release-please.js" }, "engines": { - "node": ">=10" - } - }, - "node_modules/promzard": { - "version": "0.3.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "1" + "node": ">=18.0.0" } }, - "node_modules/propagate": { - "version": "2.0.1", + "node_modules/release-please/node_modules/@octokit/auth-token": { + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">= 8" + "node": ">= 18" } }, - "node_modules/property-information": { - "version": "5.6.0", + "node_modules/release-please/node_modules/@octokit/core": { + "version": "5.2.2", "dev": true, "license": "MIT", "dependencies": { - "xtend": "^4.0.0" + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "engines": { + "node": ">= 18" } }, - "node_modules/psl": { - "version": "1.8.0", - "dev": true, - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.0", + "node_modules/release-please/node_modules/@octokit/endpoint": { + "version": "9.0.6", "dev": true, "license": "MIT", "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "dev": true, - "license": "MIT", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, "engines": { - "node": ">=6" - } - }, - "node_modules/qrcode-terminal": { - "version": "0.12.0", - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" + "node": ">= 18" } }, - "node_modules/qs": { - "version": "6.5.3", + "node_modules/release-please/node_modules/@octokit/graphql": { + "version": "7.1.1", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, "engines": { - "node": ">=0.6" + "node": ">= 18" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", + "node_modules/release-please/node_modules/@octokit/openapi-types": { + "version": "24.2.0", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT" }, - "node_modules/rc": { - "version": "1.2.8", + "node_modules/release-please/node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", "dev": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "license": "MIT", "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "@octokit/types": "^13.7.0" }, - "bin": { - "rc": "cli.js" + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "dev": true, - "license": "ISC" - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", + "node_modules/release-please/node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" } }, - "node_modules/read": { - "version": "1.0.7", - "inBundle": true, - "license": "ISC", + "node_modules/release-please/node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "dev": true, + "license": "MIT", "dependencies": { - "mute-stream": "~0.0.4" + "@octokit/types": "^13.8.0" }, "engines": { - "node": ">=0.8" - } - }, - "node_modules/read-cmd-shim": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-3.0.0.tgz", - "integrity": "sha512-KQDVjGqhZk92PPNRj9ZEXEuqg8bUobSKRw+q0YQ3TKI5xkce7bUJobL4Z/OtiEbAAv70yEpYIXp4iQ9L8oPVog==", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" } }, - "node_modules/read-package-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.1.tgz", - "integrity": "sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg==", - "inBundle": true, + "node_modules/release-please/node_modules/@octokit/request": { + "version": "8.4.1", + "dev": true, + "license": "MIT", "dependencies": { - "glob": "^8.0.1", - "json-parse-even-better-errors": "^2.3.1", - "normalize-package-data": "^4.0.0", - "npm-normalize-package-bin": "^1.0.1" + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">= 18" } }, - "node_modules/read-package-json-fast": { - "version": "2.0.3", - "inBundle": true, - "license": "ISC", + "node_modules/release-please/node_modules/@octokit/request-error": { + "version": "5.1.1", + "dev": true, + "license": "MIT", "dependencies": { - "json-parse-even-better-errors": "^2.3.0", - "npm-normalize-package-bin": "^1.0.1" + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" }, "engines": { - "node": ">=10" + "node": ">= 18" } }, - "node_modules/read-package-tree": { - "version": "5.3.1", + "node_modules/release-please/node_modules/@octokit/rest": { + "version": "20.1.2", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "util-promisify": "^2.1.0" + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/read-package-tree/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/release-please/node_modules/@octokit/types": { + "version": "13.10.0", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@octokit/openapi-types": "^24.2.0" } }, - "node_modules/read-package-tree/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/release-please/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/read-package-tree/node_modules/hosted-git-info": { - "version": "2.8.9", + "node_modules/release-please/node_modules/before-after-hook": { + "version": "2.2.3", "dev": true, - "license": "ISC" + "license": "Apache-2.0" }, - "node_modules/read-package-tree/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/release-please/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/read-package-tree/node_modules/normalize-package-data": { - "version": "2.5.0", + "node_modules/release-please/node_modules/conventional-changelog-conventionalcommits": { + "version": "6.1.0", "dev": true, - "license": "BSD-2-Clause", + "license": "ISC", "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/read-package-tree/node_modules/read-package-json": { - "version": "2.1.2", + "node_modules/release-please/node_modules/supports-color": { + "version": "7.2.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "glob": "^7.1.1", - "json-parse-even-better-errors": "^2.3.0", - "normalize-package-data": "^2.0.0", - "npm-normalize-package-bin": "^1.0.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/read-package-tree/node_modules/semver": { - "version": "5.7.1", + "node_modules/release-please/node_modules/type-fest": { + "version": "3.13.1", "dev": true, - "license": "ISC", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/release-please/node_modules/typescript": { + "version": "4.9.5", + "dev": true, + "license": "Apache-2.0", "bin": { - "semver": "bin/semver" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "inBundle": true, - "license": "MIT", + "node_modules/release-please/node_modules/universal-user-agent": { + "version": "6.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "dev": true, + "license": "ISC", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "es6-error": "^4.0.1" }, "engines": { - "node": ">= 6" + "node": ">=4" } }, - "node_modules/readdir-scoped-modules": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC", + "node_modules/remark": { + "version": "15.0.1", + "dev": true, + "license": "MIT", "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/readdirp": { - "version": "3.5.0", + "node_modules/remark-gfm": { + "version": "4.0.1", "dev": true, "license": "MIT", "dependencies": { - "picomatch": "^2.2.1" + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" }, - "engines": { - "node": ">=8.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/regexpp": { - "version": "3.2.0", + "node_modules/remark-github": { + "version": "12.0.0", "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "to-vfile": "^8.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/release-zalgo": { - "version": "1.0.0", + "node_modules/remark-github/node_modules/@types/unist": { + "version": "3.0.3", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "node_modules/remark-github/node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, + "license": "MIT", "dependencies": { - "es6-error": "^4.0.1" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-footnotes": { - "version": "2.0.0", + "node_modules/remark-github/node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", "dev": true, "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx": { - "version": "1.6.22", + "node_modules/remark-man": { + "version": "9.0.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "7.12.9", - "@babel/helper-plugin-utils": "7.10.4", - "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/plugin-syntax-jsx": "7.12.1", - "@mdx-js/util": "1.6.22", - "is-alphabetical": "1.0.4", - "remark-parse": "8.0.3", - "unified": "9.2.0" + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "github-slugger": "^2.0.0", + "groff-escape": "^2.0.0", + "mdast-util-definitions": "^6.0.0", + "mdast-util-to-string": "^4.0.0", + "months": "^2.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", + "node_modules/remark-man/node_modules/@types/unist": { + "version": "3.0.3", "dev": true, "license": "MIT" }, - "node_modules/remark-parse": { - "version": "8.0.3", + "node_modules/remark-man/node_modules/mdast-util-definitions": { + "version": "6.0.0", "dev": true, "license": "MIT", "dependencies": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-squeeze-paragraphs": { - "version": "4.0.0", + "node_modules/remark-man/node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", "dev": true, "license": "MIT", "dependencies": { - "mdast-squeeze-paragraphs": "^4.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/repeat-string": { - "version": "1.6.1", + "node_modules/remark-man/node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10" + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/request": { - "version": "2.88.2", + "node_modules/remark-parse": { + "version": "11.0.0", "dev": true, - "license": "Apache-2.0", - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" }, - "engines": { - "node": ">= 6" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", + "node_modules/remark-rehype": { + "version": "11.1.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" }, - "engines": { - "node": ">= 0.12" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", + "node_modules/remark-stringify": { + "version": "11.0.0", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" }, - "engines": { - "node": ">=0.8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, "node_modules/require-directory": { @@ -6384,6 +10378,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-inject": { "version": "1.4.4", "dev": true, @@ -6398,28 +10400,40 @@ "license": "ISC" }, "node_modules/resolve": { - "version": "1.22.0", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=4" + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12" } }, "node_modules/retry": { @@ -6430,62 +10444,42 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "inBundle": true, + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", + "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "glob": "^7.1.3" + "glob": "^13.0.0", + "package-json-from-dist": "^1.0.1" }, "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "inBundle": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "inBundle": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "inBundle": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" }, "node_modules/run-parallel": { "version": "1.2.0", @@ -6505,28 +10499,62 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" + "node_modules/safe-array-concat": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -6535,24 +10563,30 @@ "license": "MIT" }, "node_modules/saxes": { - "version": "5.0.1", + "version": "6.0.0", "dev": true, "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=v12.22.7" + } + }, + "node_modules/schemes": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend": "^3.0.0" } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "inBundle": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -6560,22 +10594,56 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "inBundle": true, + "node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "yallist": "^4.0.0" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" + "node_modules/set-function-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/shebang-command": { "version": "2.0.0", @@ -6597,96 +10665,163 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", + "version": "1.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "inBundle": true, - "license": "ISC" + "node_modules/side-channel-list": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/simple-concat": { + "node_modules/side-channel-map": { "version": "1.0.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/simple-get": { - "version": "3.1.1", + "node_modules/side-channel-weakmap": { + "version": "1.0.2", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", + "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/smart-buffer": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/smtp-address-parser": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "nearley": "^2.20.1" + }, "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">=0.10" } }, - "node_modules/smoke-tests": { - "resolved": "smoke-tests", - "link": true - }, "node_modules/socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "version": "2.8.7", "inBundle": true, + "license": "MIT", "dependencies": { - "ip": "^1.1.5", + "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "version": "8.0.5", "inBundle": true, + "license": "MIT", "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" }, "engines": { - "node": ">= 10" + "node": ">= 14" } }, "node_modules/source-map": { - "version": "0.5.7", + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -6702,16 +10837,8 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/space-separated-tokens": { - "version": "1.1.5", + "version": "2.0.2", "dev": true, "license": "MIT", "funding": { @@ -6720,7 +10847,7 @@ } }, "node_modules/spawk": { - "version": "1.7.1", + "version": "1.8.2", "dev": true, "license": "MIT", "engines": { @@ -6743,18 +10870,97 @@ "node": ">=8" } }, - "node_modules/spdx-compare": { - "version": "1.0.0", + "node_modules/spawn-wrap/node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, "license": "MIT", "dependencies": { - "array-find-index": "^1.0.2", - "spdx-expression-parse": "^3.0.0", - "spdx-ranges": "^2.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/spawn-wrap/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawn-wrap/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/spawn-wrap/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/spawn-wrap/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawn-wrap/node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/spawn-wrap/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/spdx-correct": { - "version": "3.1.1", + "version": "3.2.0", "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -6762,13 +10968,22 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, "node_modules/spdx-exceptions": { - "version": "2.3.0", + "version": "2.5.0", "inBundle": true, "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { - "version": "3.0.1", + "version": "4.0.0", "inBundle": true, "license": "MIT", "dependencies": { @@ -6776,36 +10991,28 @@ "spdx-license-ids": "^3.0.0" } }, - "node_modules/spdx-expression-validate": { - "version": "2.0.0", - "dev": true, - "license": "(MIT AND CC-BY-3.0)", - "dependencies": { - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/spdx-license-ids": { - "version": "3.0.11", + "version": "3.0.22", "inBundle": true, "license": "CC0-1.0" }, - "node_modules/spdx-osi": { - "version": "3.0.0", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/spdx-ranges": { - "version": "2.1.1", - "dev": true, - "license": "(MIT AND CC-BY-3.0)" - }, - "node_modules/spdx-whitelisted": { - "version": "1.0.0", + "node_modules/split": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "spdx-compare": "^1.0.0", - "spdx-ranges": "^2.0.0" + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" } }, "node_modules/sprintf-js": { @@ -6813,49 +11020,23 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/sshpk": { - "version": "1.17.0", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", + "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", "inBundle": true, + "license": "ISC", "dependencies": { - "minipass": "^3.1.1" + "minipass": "^7.0.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -6865,28 +11046,35 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/state-toggle": { - "version": "1.0.3", + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "inBundle": true, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "~5.2.0" + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" } }, "node_modules/string-width": { @@ -6902,30 +11090,91 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", + "version": "1.0.9", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", + "version": "1.0.8", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "inBundle": true, @@ -6937,6 +11186,39 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "dev": true, @@ -6949,23 +11231,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-to-object": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, "node_modules/supports-color": { - "version": "7.2.0", + "version": "10.2.2", "inBundle": true, "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -6985,9 +11259,7 @@ "license": "MIT" }, "node_modules/tap": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.0.tgz", - "integrity": "sha512-J9GffPUAbX6FnWbQ/jj7ktzd9nnDFP1fH44OzidqOmxUfZ1hPLMOvpS99LnDiP0H2mO8GY3kGN5XoY0xIKbNFA==", + "version": "16.3.10", "bundleDependencies": [ "ink", "treport", @@ -6996,20 +11268,21 @@ "react" ], "dev": true, + "license": "ISC", "dependencies": { "@isaacs/import-jsx": "^4.0.1", - "@types/react": "^17", + "@types/react": "^17.0.52", "chokidar": "^3.3.0", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", - "glob": "^7.1.6", + "glob": "^7.2.3", "ink": "^3.2.0", "isexe": "^2.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "jackspeak": "^1.4.1", + "istanbul-lib-processinfo": "^2.0.3", + "jackspeak": "^1.4.2", "libtap": "^1.4.0", - "minipass": "^3.1.1", + "minipass": "^3.3.4", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", @@ -7018,10 +11291,10 @@ "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", "tap-mocha-reporter": "^5.0.3", - "tap-parser": "^11.0.1", - "tap-yaml": "^1.0.0", + "tap-parser": "^11.0.2", + "tap-yaml": "^1.0.2", "tcompare": "^5.0.7", - "treport": "^3.0.3", + "treport": "^3.0.4", "which": "^2.0.2" }, "bin": { @@ -7055,7 +11328,7 @@ } }, "node_modules/tap-mocha-reporter": { - "version": "5.0.3", + "version": "5.0.4", "dev": true, "license": "ISC", "dependencies": { @@ -7076,17 +11349,18 @@ } }, "node_modules/tap-mocha-reporter/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/tap-mocha-reporter/node_modules/diff": { - "version": "4.0.2", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -7103,9 +11377,8 @@ }, "node_modules/tap-mocha-reporter/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7123,9 +11396,8 @@ }, "node_modules/tap-mocha-reporter/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7134,7 +11406,7 @@ } }, "node_modules/tap-parser": { - "version": "11.0.1", + "version": "11.0.2", "dev": true, "license": "MIT", "dependencies": { @@ -7149,40 +11421,61 @@ "node": ">= 8" } }, + "node_modules/tap-parser/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tap-yaml": { - "version": "1.0.0", + "version": "1.0.2", "dev": true, "license": "ISC", "dependencies": { - "yaml": "^1.5.0" + "yaml": "^1.10.2" + } + }, + "node_modules/tap-yaml/node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" } }, "node_modules/tap/node_modules/@ampproject/remapping": { - "version": "2.1.2", + "version": "2.2.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" } }, "node_modules/tap/node_modules/@babel/code-frame": { - "version": "7.16.7", + "version": "7.23.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/compat-data": { - "version": "7.17.7", + "version": "7.23.5", "dev": true, "inBundle": true, "license": "MIT", @@ -7191,26 +11484,26 @@ } }, "node_modules/tap/node_modules/@babel/core": { - "version": "7.17.8", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.7", - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.8", - "@babel/parser": "^7.17.8", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -7221,132 +11514,115 @@ } }, "node_modules/tap/node_modules/@babel/generator": { - "version": "7.17.7", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.7", + "version": "7.22.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-compilation-targets": { - "version": "7.17.7", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/tap/node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", + "version": "7.22.20", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.16.7" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/tap/node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", + "version": "7.23.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", + "version": "7.22.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-imports": { - "version": "7.16.7", + "version": "7.22.15", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-transforms": { - "version": "7.17.7", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/tap/node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", + "version": "7.22.5", "dev": true, "inBundle": true, "license": "MIT", @@ -7355,31 +11631,40 @@ } }, "node_modules/tap/node_modules/@babel/helper-simple-access": { - "version": "7.17.7", + "version": "7.22.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", + "version": "7.22.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/tap/node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/tap/node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", + "version": "7.22.20", "dev": true, "inBundle": true, "license": "MIT", @@ -7388,7 +11673,7 @@ } }, "node_modules/tap/node_modules/@babel/helper-validator-option": { - "version": "7.16.7", + "version": "7.23.5", "dev": true, "inBundle": true, "license": "MIT", @@ -7397,27 +11682,27 @@ } }, "node_modules/tap/node_modules/@babel/helpers": { - "version": "7.17.8", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/highlight": { - "version": "7.16.10", + "version": "7.23.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -7425,7 +11710,7 @@ } }, "node_modules/tap/node_modules/@babel/parser": { - "version": "7.17.8", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", @@ -7437,16 +11722,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.17.3", + "version": "7.20.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.17.0", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.7" + "@babel/plugin-transform-parameters": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -7456,12 +11741,12 @@ } }, "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.16.7", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -7483,12 +11768,12 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.17.7", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -7498,12 +11783,12 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.7", + "version": "7.23.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -7513,16 +11798,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.17.3", + "version": "7.23.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" }, "engines": { "node": ">=6.9.0" @@ -7532,34 +11817,34 @@ } }, "node_modules/tap/node_modules/@babel/template": { - "version": "7.16.7", + "version": "7.22.15", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/traverse": { - "version": "7.17.3", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -7567,12 +11852,13 @@ } }, "node_modules/tap/node_modules/@babel/types": { - "version": "7.17.0", + "version": "7.23.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -7599,8 +11885,31 @@ "node": ">=10" } }, + "node_modules/tap/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/tap/node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tap/node_modules/@jridgewell/set-array": { + "version": "1.1.2", "dev": true, "inBundle": true, "license": "MIT", @@ -7609,29 +11918,29 @@ } }, "node_modules/tap/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", + "version": "1.4.15", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/tap/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", + "version": "0.3.20", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/tap/node_modules/@types/prop-types": { - "version": "15.7.4", + "version": "15.7.11", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/tap/node_modules/@types/react": { - "version": "17.0.41", + "version": "17.0.73", "dev": true, "inBundle": true, "license": "MIT", @@ -7642,7 +11951,7 @@ } }, "node_modules/tap/node_modules/@types/scheduler": { - "version": "0.16.2", + "version": "0.16.8", "dev": true, "inBundle": true, "license": "MIT" @@ -7745,7 +12054,7 @@ } }, "node_modules/tap/node_modules/browserslist": { - "version": "4.20.2", + "version": "4.22.2", "dev": true, "funding": [ { @@ -7755,16 +12064,19 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "inBundle": true, "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -7807,7 +12119,7 @@ } }, "node_modules/tap/node_modules/caniuse-lite": { - "version": "1.0.30001319", + "version": "1.0.30001570", "dev": true, "funding": [ { @@ -7817,6 +12129,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "inBundle": true, @@ -7895,6 +12211,62 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tap/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/tap/node_modules/cliui/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tap/node_modules/cliui/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tap/node_modules/cliui/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/tap/node_modules/code-excerpt": { "version": "3.0.0", "dev": true, @@ -7935,13 +12307,10 @@ "license": "MIT" }, "node_modules/tap/node_modules/convert-source-map": { - "version": "1.8.0", + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.1" - } + "license": "MIT" }, "node_modules/tap/node_modules/convert-to-spaces": { "version": "1.0.2", @@ -7953,7 +12322,7 @@ } }, "node_modules/tap/node_modules/csstype": { - "version": "3.0.11", + "version": "3.1.3", "dev": true, "inBundle": true, "license": "MIT" @@ -7976,7 +12345,7 @@ } }, "node_modules/tap/node_modules/electron-to-chromium": { - "version": "1.4.89", + "version": "1.4.614", "dev": true, "inBundle": true, "license": "ISC" @@ -8054,6 +12423,18 @@ "node": ">=8" } }, + "node_modules/tap/node_modules/foreground-child": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/tap/node_modules/fs.realpath": { "version": "1.0.0", "dev": true, @@ -8070,7 +12451,7 @@ } }, "node_modules/tap/node_modules/glob": { - "version": "7.2.0", + "version": "7.2.3", "dev": true, "inBundle": true, "license": "ISC", @@ -8078,7 +12459,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -8266,6 +12647,22 @@ "node": ">=8" } }, + "node_modules/tap/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/jackspeak": { + "version": "1.4.2", + "dev": true, + "license": "ISC", + "dependencies": { + "cliui": "^7.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tap/node_modules/js-tokens": { "version": "4.0.0", "dev": true, @@ -8285,7 +12682,7 @@ } }, "node_modules/tap/node_modules/json5": { - "version": "2.2.1", + "version": "2.2.3", "dev": true, "inBundle": true, "license": "MIT", @@ -8326,6 +12723,15 @@ "loose-envify": "cli.js" } }, + "node_modules/tap/node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, "node_modules/tap/node_modules/make-dir": { "version": "3.1.0", "dev": true, @@ -8363,7 +12769,7 @@ } }, "node_modules/tap/node_modules/minipass": { - "version": "3.1.6", + "version": "3.3.6", "dev": true, "inBundle": true, "license": "ISC", @@ -8374,6 +12780,23 @@ "node": ">=8" } }, + "node_modules/tap/node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tap/node_modules/ms": { "version": "2.1.2", "dev": true, @@ -8381,7 +12804,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/node-releases": { - "version": "2.0.2", + "version": "2.0.14", "dev": true, "inBundle": true, "license": "MIT" @@ -8501,7 +12924,7 @@ } }, "node_modules/tap/node_modules/punycode": { - "version": "2.1.1", + "version": "2.3.1", "dev": true, "inBundle": true, "license": "MIT", @@ -8523,7 +12946,7 @@ } }, "node_modules/tap/node_modules/react-devtools-core": { - "version": "4.24.1", + "version": "4.28.5", "dev": true, "inBundle": true, "license": "MIT", @@ -8595,12 +13018,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/tap/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/tap/node_modules/scheduler": { "version": "0.20.2", "dev": true, @@ -8612,7 +13029,7 @@ } }, "node_modules/tap/node_modules/semver": { - "version": "6.3.0", + "version": "6.3.1", "dev": true, "inBundle": true, "license": "ISC", @@ -8621,10 +13038,13 @@ } }, "node_modules/tap/node_modules/shell-quote": { - "version": "1.7.3", + "version": "1.8.1", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/tap/node_modules/signal-exit": { "version": "3.0.7", @@ -8679,17 +13099,8 @@ "inBundle": true, "license": "MIT" }, - "node_modules/tap/node_modules/source-map": { - "version": "0.5.7", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/tap/node_modules/stack-utils": { - "version": "2.0.5", + "version": "2.0.6", "dev": true, "inBundle": true, "license": "MIT", @@ -8748,7 +13159,7 @@ } }, "node_modules/tap/node_modules/tap-parser": { - "version": "11.0.1", + "version": "11.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -8765,12 +13176,12 @@ } }, "node_modules/tap/node_modules/tap-yaml": { - "version": "1.0.0", + "version": "1.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yaml": "^1.5.0" + "yaml": "^1.10.2" } }, "node_modules/tap/node_modules/to-fast-properties": { @@ -8783,7 +13194,7 @@ } }, "node_modules/tap/node_modules/treport": { - "version": "3.0.3", + "version": "3.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -8794,6 +13205,7 @@ "ink": "^3.2.0", "ms": "^2.1.2", "tap-parser": "^11.0.0", + "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, "peerDependencies": { @@ -8880,34 +13292,56 @@ } }, "node_modules/tap/node_modules/unicode-length": { - "version": "2.0.2", + "version": "2.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "punycode": "^2.0.0", - "strip-ansi": "^3.0.1" + "punycode": "^2.0.0" } }, - "node_modules/tap/node_modules/unicode-length/node_modules/ansi-regex": { - "version": "2.1.1", + "node_modules/tap/node_modules/update-browserslist-db": { + "version": "1.0.13", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "inBundle": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/tap/node_modules/unicode-length/node_modules/strip-ansi": { - "version": "3.0.1", + "node_modules/tap/node_modules/which": { + "version": "2.0.2", "dev": true, - "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ansi-regex": "^2.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, "node_modules/tap/node_modules/widest-line": { @@ -8976,7 +13410,7 @@ "license": "ISC" }, "node_modules/tap/node_modules/ws": { - "version": "7.5.7", + "version": "7.5.9", "dev": true, "inBundle": true, "license": "MIT", @@ -8997,7 +13431,7 @@ } }, "node_modules/tap/node_modules/yallist": { - "version": "4.0.0", + "version": "3.1.1", "dev": true, "inBundle": true, "license": "ISC" @@ -9024,50 +13458,40 @@ } }, "node_modules/tar": { - "version": "6.1.11", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz", + "integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==", "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" } }, - "node_modules/tar-fs": { - "version": "2.1.1", + "node_modules/tar-stream": { + "version": "3.1.7", "dev": true, "license": "MIT", "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "inBundle": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=6" + "node": ">=18" } }, "node_modules/tcompare": { @@ -9082,7 +13506,9 @@ } }, "node_modules/tcompare/node_modules/diff": { - "version": "4.0.2", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -9103,10 +13529,9 @@ } }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9114,9 +13539,8 @@ }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -9134,9 +13558,8 @@ }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -9144,24 +13567,112 @@ "node": "*" } }, + "node_modules/text-decoder": { + "version": "1.2.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/text-extensions": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/text-table": { "version": "0.2.0", "inBundle": true, "license": "MIT" }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, "node_modules/tiny-relative-date": { - "version": "1.3.0", + "version": "2.0.2", "inBundle": true, "license": "MIT" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/tldts": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.21.tgz", + "integrity": "sha512-Plu6V8fF/XU6d2k8jPtlQf5F4Xx2hAin4r2C2ca7wR8NK5MbRTo9huLUWRe28f3Uk8bYZfg74tit/dSjc18xnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.21" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.21.tgz", + "integrity": "sha512-oVOMdHvgjqyzUZH1rOESgJP1uNe2bVrfK0jUHHmiM2rpEiRbf3j4BrsIc6JigJRbHGanQwuZv/R+LTcHsw+bLA==", + "dev": true, + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "dev": true, @@ -9173,45 +13684,54 @@ "node": ">=8.0" } }, + "node_modules/to-vfile": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/tough-cookie": { - "version": "4.0.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" + "tldts": "^7.0.5" }, "engines": { - "node": ">=6" + "node": ">=16" } }, "node_modules/tr46": { - "version": "3.0.0", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.1.1" + "punycode": "^2.3.1" }, "engines": { - "node": ">=12" + "node": ">=20" } }, "node_modules/treeverse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-2.0.0.tgz", - "integrity": "sha512-N5gJCkLu1aXccpOTtqV6ddSEi6ZmGkh3hjmbu1IjcavJK4qyOVQmi0myQKM7z5jVGmD68SJoliaVrMmVObhj6A==", + "version": "3.0.0", "inBundle": true, + "license": "ISC", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/trim": { - "version": "0.0.1", - "dev": true - }, - "node_modules/trim-trailing-lines": { - "version": "1.1.4", + "node_modules/trim-lines": { + "version": "3.0.1", "dev": true, "license": "MIT", "funding": { @@ -9219,14 +13739,24 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/trivial-deferred": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", - "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", - "dev": true + "version": "1.1.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 8" + } }, "node_modules/trough": { - "version": "1.0.5", + "version": "2.2.0", "dev": true, "license": "MIT", "funding": { @@ -9234,59 +13764,61 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ts-node": { - "version": "8.10.2", + "node_modules/tsconfig-paths": { + "version": "3.15.0", "dev": true, "license": "MIT", - "optional": true, "peer": true, "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.17", - "yn": "3.1.1" + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minimist": "^1.2.0" }, "bin": { - "ts-node": "dist/bin.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "typescript": ">=2.7" + "json5": "lib/cli.js" } }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", "dev": true, - "license": "BSD-3-Clause", - "optional": true, + "license": "MIT", "peer": true, "engines": { - "node": ">=0.3.1" + "node": ">=4" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "dev": true, - "license": "Apache-2.0", + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "inBundle": true, + "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" }, "engines": { - "node": "*" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/tweetnacl": { - "version": "0.14.5", + "node_modules/tunnel": { + "version": "0.0.6", "dev": true, - "license": "Unlicense", - "optional": true, - "peer": true + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } }, "node_modules/type-check": { "version": "0.4.0", @@ -9301,32 +13833,118 @@ } }, "node_modules/type-fest": { - "version": "0.8.1", + "version": "0.20.2", "dev": true, "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { - "version": "3.9.10", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "optional": true, "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/uglify-js": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.3.tgz", - "integrity": "sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==", + "version": "3.19.3", "dev": true, + "license": "BSD-2-Clause", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -9336,236 +13954,252 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.1", + "version": "1.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unherit": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, "node_modules/unicode-length": { - "version": "2.0.2", + "version": "2.1.0", "dev": true, "license": "MIT", "dependencies": { - "punycode": "^2.0.0", - "strip-ansi": "^3.0.1" + "punycode": "^2.0.0" } }, - "node_modules/unicode-length/node_modules/ansi-regex": { - "version": "2.1.1", + "node_modules/unicorn-magic": { + "version": "0.1.0", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unicode-length/node_modules/strip-ansi": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" + "node": ">=18" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/unified": { - "version": "9.2.0", + "version": "11.0.5", "dev": true, "license": "MIT", "dependencies": { - "bail": "^1.0.0", + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, + "node_modules/unified/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, "node_modules/unique-filename": { - "version": "1.1.1", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", + "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^2.0.0" + "unique-slug": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/unique-slug": { - "version": "2.0.2", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", + "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", "inBundle": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/unist-builder": { - "version": "2.0.3", + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", "dev": true, "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-generated": { - "version": "1.1.6", + "node_modules/unist-util-is/node_modules/@types/unist": { + "version": "3.0.3", "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "license": "MIT" }, - "node_modules/unist-util-is": { - "version": "4.1.0", + "node_modules/unist-util-position": { + "version": "5.0.0", "dev": true, "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-position": { - "version": "3.1.0", + "node_modules/unist-util-position/node_modules/@types/unist": { + "version": "3.0.3", "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "license": "MIT" }, - "node_modules/unist-util-remove": { - "version": "2.1.0", + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove-position": { - "version": "2.0.1", + "node_modules/unist-util-stringify-position/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/unist-util-visit": { + "version": "2.0.3", "dev": true, "license": "MIT", "dependencies": { - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-stringify-position": { - "version": "2.0.3", + "node_modules/unist-util-visit-parents": { + "version": "3.1.1", "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "^2.0.2" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit": { - "version": "2.0.3", + "node_modules/unist-util-visit-parents/node_modules/unist-util-is": { + "version": "4.1.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-parents": { - "version": "3.1.1", + "node_modules/unist-util-visit/node_modules/unist-util-is": { + "version": "4.1.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/universalify": { - "version": "0.1.2", + "node_modules/universal-user-agent": { + "version": "7.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, "node_modules/uri-js": { "version": "4.4.1", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", - "inBundle": true, "license": "MIT" }, - "node_modules/util-promisify": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3" - } - }, "node_modules/uuid": { - "version": "3.4.0", + "version": "8.3.2", "dev": true, "license": "MIT", "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "peer": true - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "inBundle": true, @@ -9575,249 +14209,378 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/validate-npm-package-name": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz", - "integrity": "sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==", + "node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", "inBundle": true, + "license": "MIT", "dependencies": { - "builtins": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/verror": { - "version": "1.10.0", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "node_modules/validate-npm-package-name": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/vfile": { - "version": "4.2.1", + "version": "6.0.3", "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-location": { - "version": "3.2.0", + "node_modules/vfile-message": { + "version": "4.0.3", "dev": true, "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message": { - "version": "2.0.4", + "node_modules/vfile-message/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/vfile/node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "xml-name-validator": "^5.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=18" } }, - "node_modules/vlq": { - "version": "0.2.3", + "node_modules/walk-up-path": { + "version": "4.0.0", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { - "browser-process-hrtime": "^1.0.0" + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" } }, - "node_modules/w3c-xmlserializer": { - "version": "3.0.0", + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", "dev": true, "license": "MIT", "dependencies": { - "xml-name-validator": "^4.0.0" + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" }, "engines": { - "node": ">=12" + "node": ">=20" } }, - "node_modules/walk-up-path": { - "version": "1.0.0", + "node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", "inBundle": true, - "license": "ISC" + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "node_modules/wcwidth": { - "version": "1.0.1", - "inBundle": true, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "defaults": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/web-namespaces": { - "version": "1.1.4", + "node_modules/which-builtin-type": { + "version": "1.2.1", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/webidl-conversions": { - "version": "7.0.0", + "node_modules/which-collection": { + "version": "1.0.2", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "peer": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", + "node_modules/which-module": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "iconv-lite": "0.6.3" + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", + "node_modules/word-wrap": { + "version": "1.2.5", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/whatwg-url": { - "version": "10.0.0", + "node_modules/wordwrap": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "inBundle": true, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/which-module": { - "version": "2.0.0", + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, - "license": "ISC" - }, - "node_modules/wide-align": { - "version": "1.1.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/word-wrap": { - "version": "1.2.3", + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/wrappy": { "version": "1.0.2", - "inBundle": true, + "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { - "version": "4.0.1", - "inBundle": true, + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.0.tgz", + "integrity": "sha512-YnlPC6JqnZl6aO4uRc+dx5PHguiR9S6WeoLtpxNT9wIG+BDya7ZNE1q7KOjVgaA73hKhKLpVPgJ5QA9THQ5BRg==", "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "signal-exit": "^4.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/ws": { - "version": "8.5.0", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "dev": true, "license": "MIT", "engines": { @@ -9825,7 +14588,7 @@ }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -9837,11 +14600,11 @@ } }, "node_modules/xml-name-validator": { - "version": "4.0.0", + "version": "5.0.0", "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/xmlchars": { @@ -9849,18 +14612,21 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", + "node_modules/xpath": { + "version": "0.0.34", "dev": true, "license": "MIT", "engines": { - "node": ">=0.4" + "node": ">=0.6.0" } }, "node_modules/y18n": { - "version": "4.0.3", + "version": "5.0.8", "dev": true, - "license": "ISC" + "license": "ISC", + "engines": { + "node": ">=10" + } }, "node_modules/yallist": { "version": "4.0.0", @@ -9868,145 +14634,61 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "1.10.2", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, "engines": { - "node": ">= 6" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { - "version": "15.4.1", + "version": "17.7.2", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "18.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/cliui": { - "version": "6.0.0", + "version": "21.1.1", "dev": true, "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "dev": true, "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/wrap-ansi": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/zwitch": { - "version": "1.0.5", + "version": "2.0.4", "dev": true, "license": "MIT", "funding": { @@ -10015,291 +14697,302 @@ } }, "smoke-tests": { - "version": "1.0.0", + "name": "@npmcli/smoke-tests", + "version": "1.0.1", "license": "ISC", "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.5.0", - "minify-registry-metadata": "^2.2.0", - "rimraf": "^3.0.2", - "tap": "^16.0.1", - "which": "^2.0.2" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/template-oss": "4.25.1", + "proxy": "^2.1.1", + "rimraf": "^6.0.1", + "tap": "^16.3.8", + "which": "^6.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/arborist": { "name": "@npmcli/arborist", - "version": "5.4.0", + "version": "9.2.0", "license": "ISC", "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/installed-package-contents": "^1.0.7", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/metavuln-calculator": "^3.0.1", - "@npmcli/move-file": "^2.0.0", - "@npmcli/name-from-folder": "^1.0.1", - "@npmcli/node-gyp": "^2.0.0", - "@npmcli/package-json": "^2.0.0", - "@npmcli/query": "^1.1.1", - "@npmcli/run-script": "^4.1.3", - "bin-links": "^3.0.0", - "cacache": "^16.0.6", - "common-ancestor-path": "^1.0.1", - "json-parse-even-better-errors": "^2.3.1", + "@npmcli/fs": "^5.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/metavuln-calculator": "^9.0.2", + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/query": "^5.0.0", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.0", + "bin-links": "^6.0.0", + "cacache": "^20.0.1", + "common-ancestor-path": "^2.0.0", + "hosted-git-info": "^9.0.0", "json-stringify-nice": "^1.1.4", - "minimatch": "^5.1.0", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", - "nopt": "^5.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.0.0", - "npm-pick-manifest": "^7.0.0", - "npm-registry-fetch": "^13.0.0", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.1", - "proc-log": "^2.0.0", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^9.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.0", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "pacote": "^21.0.2", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.0.0", + "proggy": "^4.0.0", "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.1", - "read-package-json-fast": "^2.0.2", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", + "promise-call-limit": "^3.0.1", "semver": "^7.3.7", - "ssri": "^9.0.0", - "treeverse": "^2.0.0", - "walk-up-path": "^1.0.0" + "ssri": "^13.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" }, "bin": { "arborist": "bin/index.js" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/template-oss": "4.25.1", "benchmark": "^2.1.4", - "chalk": "^4.1.0", - "minify-registry-metadata": "^2.1.0", - "nock": "^13.2.0", - "tap": "^16.0.1", + "minify-registry-metadata": "^4.0.0", + "nock": "^13.3.3", + "tap": "^16.3.8", + "tar-stream": "^3.0.0", "tcompare": "^5.0.6" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "workspaces/libnpmaccess": { - "version": "6.0.3", + "workspaces/config": { + "name": "@npmcli/config", + "version": "10.6.0", "license": "ISC", "dependencies": { - "aproba": "^2.0.0", - "minipass": "^3.1.1", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0" + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "ini": "^6.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "walk-up-path": "^4.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "nock": "^13.2.4", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-globals": "^1.0.0", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "workspaces/libnpmdiff": { - "version": "4.0.4", + "workspaces/libnpmaccess": { + "version": "10.0.3", "license": "ISC", "dependencies": { - "@npmcli/disparity-colors": "^2.0.0", - "@npmcli/installed-package-contents": "^1.0.7", - "binary-extensions": "^2.2.0", - "diff": "^5.0.0", - "minimatch": "^5.0.1", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1", - "tar": "^6.1.0" + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "workspaces/libnpmexec": { - "version": "4.0.9", + "workspaces/libnpmdiff": { + "version": "8.1.0", "license": "ISC", "dependencies": { - "@npmcli/arborist": "^5.0.0", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/fs": "^2.1.1", - "@npmcli/run-script": "^4.2.0", - "chalk": "^4.1.0", - "mkdirp-infer-owner": "^2.0.0", - "npm-package-arg": "^9.0.1", - "npmlog": "^6.0.2", - "pacote": "^13.6.1", - "proc-log": "^2.0.0", - "read": "^1.0.7", - "read-package-json-fast": "^2.0.2", - "semver": "^7.3.7", - "walk-up-path": "^1.0.0" + "@npmcli/arborist": "^9.2.0", + "@npmcli/installed-package-contents": "^4.0.0", + "binary-extensions": "^3.0.0", + "diff": "^8.0.2", + "minimatch": "^10.0.3", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "tar": "^7.5.1" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "bin-links": "^3.0.0", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "workspaces/libnpmfund": { - "version": "3.0.2", + "workspaces/libnpmexec": { + "version": "10.2.0", "license": "ISC", "dependencies": { - "@npmcli/arborist": "^5.0.0" + "@npmcli/arborist": "^9.2.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "read": "^5.0.1", + "semver": "^7.3.7", + "signal-exit": "^4.1.0", + "walk-up-path": "^4.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/template-oss": "4.25.1", + "bin-links": "^6.0.0", + "chalk": "^5.2.0", + "just-extend": "^6.2.0", + "just-safe-set": "^4.2.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "workspaces/libnpmhook": { - "version": "8.0.3", + "workspaces/libnpmfund": { + "version": "7.0.14", "license": "ISC", "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" + "@npmcli/arborist": "^9.2.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "nock": "^13.2.4", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/libnpmorg": { - "version": "4.0.3", + "version": "8.0.1", "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" + "npm-registry-fetch": "^19.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "minipass": "^3.1.1", - "nock": "^13.2.4", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "minipass": "^7.1.1", + "nock": "^13.3.3", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/libnpmpack": { - "version": "4.1.2", + "version": "9.1.0", "license": "ISC", "dependencies": { - "@npmcli/run-script": "^4.1.3", - "npm-package-arg": "^9.0.1", - "pacote": "^13.6.1" + "@npmcli/arborist": "^9.2.0", + "@npmcli/run-script": "^10.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "nock": "^13.0.7", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "nock": "^13.3.3", + "spawk": "^1.7.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/libnpmpublish": { - "version": "6.0.4", + "version": "11.1.3", "license": "ISC", "dependencies": { - "normalize-package-data": "^4.0.0", - "npm-package-arg": "^9.0.1", - "npm-registry-fetch": "^13.0.0", + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.7", - "ssri": "^9.0.0" + "sigstore": "^4.0.0", + "ssri": "^13.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "libnpmpack": "^4.0.0", - "lodash.clonedeep": "^4.5.0", - "nock": "^13.2.4", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-globals": "^1.0.0", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/template-oss": "4.25.1", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/libnpmsearch": { - "version": "5.0.3", + "version": "9.0.1", "license": "ISC", "dependencies": { - "npm-registry-fetch": "^13.0.0" + "npm-registry-fetch": "^19.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "nock": "^13.2.4", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "nock": "^13.3.3", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/libnpmteam": { - "version": "4.0.3", + "version": "8.0.2", "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^13.0.0" + "npm-registry-fetch": "^19.0.0" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "nock": "^13.2.4", - "tap": "^16.0.1" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", + "nock": "^13.3.3", + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "workspaces/libnpmversion": { - "version": "3.0.6", + "version": "8.0.3", "license": "ISC", "dependencies": { - "@npmcli/git": "^3.0.0", - "@npmcli/run-script": "^4.1.3", - "json-parse-even-better-errors": "^2.3.1", - "proc-log": "^2.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", "semver": "^7.3.7" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/template-oss": "4.25.1", "require-inject": "^1.4.4", - "tap": "^16.0.1" + "tap": "^16.3.8" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } } } diff --git a/package.json b/package.json index 6efd43f49e96f..60e6baa52637b 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,21 @@ { - "version": "8.16.0", + "version": "11.9.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ "docs", "smoke-tests", + "mock-globals", + "mock-registry", "workspaces/*" ], "files": [ + "bin/", + "lib/", "index.js", - "bin", - "docs/content/**/*.md", - "docs/output/**/*.html", - "lib", - "man" + "docs/content/", + "docs/output/", + "man/" ], "keywords": [ "install", @@ -21,23 +23,17 @@ "package manager", "package.json" ], - "preferGlobal": true, - "config": { - "publishtest": false - }, "homepage": "https://docs.npmjs.com/", - "author": "Isaac Z. Schlueter (http://blog.izs.me)", + "author": "GitHub Inc.", "repository": { "type": "git", - "url": "https://github.com/npm/cli" + "url": "git+https://github.com/npm/cli.git" }, "bugs": { "url": "https://github.com/npm/cli/issues" }, "directories": { - "bin": "./bin", "doc": "./doc", - "lib": "./lib", "man": "./man" }, "main": "./index.js", @@ -56,95 +52,92 @@ }, "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^5.0.4", - "@npmcli/ci-detect": "^2.0.0", - "@npmcli/config": "^4.2.0", - "@npmcli/fs": "^2.1.0", - "@npmcli/map-workspaces": "^2.0.3", - "@npmcli/package-json": "^2.0.0", - "@npmcli/run-script": "^4.2.0", - "abbrev": "~1.1.1", + "@npmcli/arborist": "^9.2.0", + "@npmcli/config": "^10.6.0", + "@npmcli/fs": "^5.0.0", + "@npmcli/map-workspaces": "^5.0.3", + "@npmcli/metavuln-calculator": "^9.0.3", + "@npmcli/package-json": "^7.0.4", + "@npmcli/promise-spawn": "^9.0.1", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.3", + "@sigstore/tuf": "^4.0.1", + "abbrev": "^4.0.0", "archy": "~1.0.0", - "cacache": "^16.1.1", - "chalk": "^4.1.2", - "chownr": "^2.0.0", + "cacache": "^20.0.3", + "chalk": "^5.6.2", + "ci-info": "^4.4.0", "cli-columns": "^4.0.0", - "cli-table3": "^0.6.2", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.12", - "glob": "^8.0.1", - "graceful-fs": "^4.2.10", - "hosted-git-info": "^5.0.0", - "ini": "^3.0.0", - "init-package-json": "^3.0.2", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^2.3.1", - "libnpmaccess": "^6.0.2", - "libnpmdiff": "^4.0.2", - "libnpmexec": "^4.0.2", - "libnpmfund": "^3.0.1", - "libnpmhook": "^8.0.2", - "libnpmorg": "^4.0.2", - "libnpmpack": "^4.0.2", - "libnpmpublish": "^6.0.2", - "libnpmsearch": "^5.0.2", - "libnpmteam": "^4.0.2", - "libnpmversion": "^3.0.1", - "make-fetch-happen": "^10.2.0", - "minipass": "^3.1.6", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^13.0.0", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^9.0.2", + "ini": "^6.0.0", + "init-package-json": "^8.2.4", + "is-cidr": "^6.0.1", + "json-parse-even-better-errors": "^5.0.0", + "libnpmaccess": "^10.0.3", + "libnpmdiff": "^8.1.0", + "libnpmexec": "^10.2.0", + "libnpmfund": "^7.0.14", + "libnpmorg": "^8.0.1", + "libnpmpack": "^9.1.0", + "libnpmpublish": "^11.1.3", + "libnpmsearch": "^9.0.1", + "libnpmteam": "^8.0.2", + "libnpmversion": "^8.0.3", + "make-fetch-happen": "^15.0.3", + "minimatch": "^10.1.1", + "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "mkdirp-infer-owner": "^2.0.0", "ms": "^2.1.2", - "node-gyp": "^9.0.0", - "nopt": "^5.0.0", - "npm-audit-report": "^3.0.0", - "npm-install-checks": "^5.0.0", - "npm-package-arg": "^9.1.0", - "npm-pick-manifest": "^7.0.1", - "npm-profile": "^6.2.0", - "npm-registry-fetch": "^13.3.0", - "npm-user-validate": "^1.0.1", - "npmlog": "^6.0.2", - "opener": "^1.5.2", - "p-map": "^4.0.0", - "pacote": "^13.6.1", - "parse-conflict-json": "^2.0.2", - "proc-log": "^2.0.1", + "node-gyp": "^12.2.0", + "nopt": "^9.0.0", + "npm-audit-report": "^7.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.2", + "npm-pick-manifest": "^11.0.3", + "npm-profile": "^12.0.1", + "npm-registry-fetch": "^19.1.1", + "npm-user-validate": "^4.0.0", + "p-map": "^7.0.4", + "pacote": "^21.1.0", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.1.0", "qrcode-terminal": "^0.12.0", - "read": "~1.0.7", - "read-package-json": "^5.0.1", - "read-package-json-fast": "^2.0.3", - "readdir-scoped-modules": "^1.1.0", - "rimraf": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^9.0.1", - "tar": "^6.1.11", + "read": "^5.0.1", + "semver": "^7.7.3", + "spdx-expression-parse": "^4.0.0", + "ssri": "^13.0.0", + "supports-color": "^10.2.2", + "tar": "^7.5.7", "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^2.0.0", - "validate-npm-package-name": "^4.0.0", - "which": "^2.0.2", - "write-file-atomic": "^4.0.1" + "tiny-relative-date": "^2.0.2", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^7.0.2", + "which": "^6.0.0" }, "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", - "@npmcli/ci-detect", "@npmcli/config", "@npmcli/fs", "@npmcli/map-workspaces", + "@npmcli/metavuln-calculator", "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", "@npmcli/run-script", + "@sigstore/tuf", "abbrev", "archy", "cacache", "chalk", - "chownr", + "ci-info", "cli-columns", - "cli-table3", - "columnify", "fastest-levenshtein", + "fs-minipass", "glob", "graceful-fs", "hosted-git-info", @@ -156,7 +149,6 @@ "libnpmdiff", "libnpmexec", "libnpmfund", - "libnpmhook", "libnpmorg", "libnpmpack", "libnpmpublish", @@ -164,10 +156,9 @@ "libnpmteam", "libnpmversion", "make-fetch-happen", + "minimatch", "minipass", "minipass-pipeline", - "mkdirp", - "mkdirp-infer-owner", "ms", "node-gyp", "nopt", @@ -178,76 +169,92 @@ "npm-profile", "npm-registry-fetch", "npm-user-validate", - "npmlog", - "opener", "p-map", "pacote", "parse-conflict-json", "proc-log", "qrcode-terminal", "read", - "read-package-json", - "read-package-json-fast", - "readdir-scoped-modules", - "rimraf", "semver", + "spdx-expression-parse", "ssri", + "supports-color", "tar", "text-table", "tiny-relative-date", "treeverse", "validate-npm-package-name", - "which", - "write-file-atomic" + "which" ], "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/template-oss": "3.5.0", - "licensee": "^8.2.0", - "nock": "^13.2.4", + "@npmcli/docs": "^1.0.0", + "@npmcli/eslint-config": "^5.1.0", + "@npmcli/git": "^7.0.1", + "@npmcli/mock-globals": "^1.0.0", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/template-oss": "4.25.1", + "@tufjs/repo-mock": "^4.0.0", + "ajv": "^8.12.0", + "ajv-formats": "^3.0.1", + "ajv-formats-draft2019": "^1.6.1", + "cli-table3": "^0.6.4", + "diff": "^8.0.3", + "nock": "^13.4.0", + "npm-packlist": "^10.0.3", + "remark": "^15.0.1", + "remark-gfm": "^4.0.1", + "remark-github": "^12.0.0", + "rimraf": "^6.0.1", "spawk": "^1.7.1", - "tap": "^16.0.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", - "preversion": "bash scripts/update-authors.sh && git add AUTHORS && git commit -m \"chore: update AUTHORS\" || true", - "licenses": "licensee --production --errors-only", + "licenses": "npx licensee --production --errors-only", "test": "tap", - "test-all": "npm run test --if-present --workspaces --include-workspace-root", + "test:nocolor": "CI=true tap -Rclassic", + "test-all": "node . run test --workspaces --include-workspace-root --if-present", "snap": "tap", - "postsnap": "make -s docs", - "test:nocleanup": "NO_TEST_CLEANUP=1 npm run test --", - "sudotest": "sudo npm run test --", - "sudotest:nocleanup": "sudo NO_TEST_CLEANUP=1 npm run test --", - "posttest": "npm run lint", - "lint": "eslint \"**/*.js\"", - "lintfix": "npm run lint -- --fix", - "lint-all": "npm run lint --if-present --workspaces --include-workspace-root", - "prelint": "rimraf test/npm_cache*", - "resetdeps": "bash scripts/resetdeps.sh" + "prepack": "node . run build -w docs", + "posttest": "node . run lint", + "lint": "node . run eslint", + "lintfix": "node . run eslint -- --fix", + "lint-all": "node . run lint --workspaces --include-workspace-root --if-present", + "resetdeps": "node scripts/resetdeps.js", + "rp-pull-request": "node scripts/update-authors.js", + "postlint": "template-oss-check", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "tap": { "test-env": [ "LC_ALL=sk" ], - "color": 1, - "files": "test/{lib,bin,index.js}", "timeout": 600, "nyc-arg": [ + "--exclude", + "docs/**", + "--exclude", + "smoke-tests/**", + "--exclude", + "mock-globals/**", + "--exclude", + "mock-registry/**", "--exclude", "workspaces/**", "--exclude", "tap-snapshots/**" - ] + ], + "test-ignore": "^(docs|smoke-tests|mock-globals|mock-registry|workspaces)/" }, "templateOSS": { - "rootRepo": false, - "rootModule": false, - "version": "3.5.0" + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.25.1", + "content": "./scripts/template-oss/root.js" }, "license": "Artistic-2.0", "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^20.17.0 || >=22.9.0" } } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000000000..32060705f5c38 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,60 @@ +{ + "plugins": [ + "node-workspace", + "node-workspace-format" + ], + "changelog-sections": [ + { + "type": "feat", + "section": "Features", + "hidden": false + }, + { + "type": "fix", + "section": "Bug Fixes", + "hidden": false + }, + { + "type": "docs", + "section": "Documentation", + "hidden": false + }, + { + "type": "deps", + "section": "Dependencies", + "hidden": false + }, + { + "type": "chore", + "section": "Chores", + "hidden": true + } + ], + "packages": { + ".": { + "package-name": "", + "exclude-paths": [ + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces" + ] + }, + "workspaces/arborist": {}, + "workspaces/config": {}, + "workspaces/libnpmaccess": {}, + "workspaces/libnpmdiff": {}, + "workspaces/libnpmexec": {}, + "workspaces/libnpmfund": {}, + "workspaces/libnpmorg": {}, + "workspaces/libnpmpack": {}, + "workspaces/libnpmpublish": {}, + "workspaces/libnpmsearch": {}, + "workspaces/libnpmteam": {}, + "workspaces/libnpmversion": {} + }, + "prerelease": false, + "group-pull-request-title-pattern": "chore: release ${version}", + "pull-request-title-pattern": "chore: release${component} ${version}", + "prerelease-type": "pre.0" +} diff --git a/scripts/bundle-and-gitignore-deps.js b/scripts/bundle-and-gitignore-deps.js index 93d8d89617eb4..55938106158e9 100644 --- a/scripts/bundle-and-gitignore-deps.js +++ b/scripts/bundle-and-gitignore-deps.js @@ -1,60 +1,262 @@ const Arborist = require('@npmcli/arborist') -const { resolve } = require('path') -const ignore = resolve(__dirname, '../node_modules/.gitignore') -const { writeFileSync } = require('fs') -const pj = resolve(__dirname, '../package.json') -const pkg = require(pj) -const bundle = [] -const arb = new Arborist({ path: resolve(__dirname, '..') }) -const shouldIgnore = [] - -arb.loadVirtual().then(tree => { - for (const node of tree.children.values()) { - const has = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) - const nonProdWorkspace = - node.isWorkspace && !(has(tree.package.dependencies, node.name)) - if (node.dev || nonProdWorkspace) { - console.error('ignore', node.name) - shouldIgnore.push(node.name) - } else if (tree.edgesOut.has(node.name)) { - console.error('BUNDLE', node.name) - bundle.push(node.name) +const packlist = require('npm-packlist') +const { join, relative } = require('node:path') +const localeCompare = require('@isaacs/string-locale-compare')('en') +const PackageJson = require('@npmcli/package-json') +const { run, CWD, git, fs, pkg: rootPkg, EOL } = require('./util') +const npmGit = require('@npmcli/git') + +const ALWAYS_IGNORE = [ + '.bin/', + '.cache/', + 'package-lock.json', + 'CHANGELOG*', + 'changelog*', + 'ChangeLog*', + 'Changelog*', + 'README*', + 'readme*', + 'ReadMe*', + 'Readme*', + '__pycache__', + '.editorconfig', + '.idea/', + '.npmignore', + '.eslintrc*', + '.travis*', + '.github', + '.jscsrc', + '.nycrc', + '.istanbul*', + '.eslintignore', + '.jshintrc*', + '.prettierrc*', + '.jscs.json', + '.dir-locals*', + '.coveralls*', + '.babelrc*', + '.nyc_output', + '.gitkeep', + '*.map', + '*.ts', + '*.png', + '*.jpg', +] + +const lsAndRmIgnored = async (dir) => { + const files = await git( + 'ls-files', + '--cached', + '--ignored', + `--exclude-standard`, + dir, + { lines: true } + ) + + for (const file of files) { + await git('rm', file, '--force') + } + + // check if there are still ignored files left + // if so we will error in the next step + const notRemoved = await git( + 'ls-files', + '--cached', + '--ignored', + `--exclude-standard`, + dir, + { lines: true } + ) + + return notRemoved +} + +const getAllowedPaths = (files) => { + class AllowSegments { + #segments + #usedSegments + + constructor (pathSegments, rootSegments = []) { + // Copy strings with spread operator since we mutate these arrays + this.#segments = [...pathSegments] + this.#usedSegments = [...rootSegments] + } + + get next () { + return this.#segments[0] + } + + get remaining () { + return this.#segments + } + + get used () { + return this.#usedSegments + } + + use () { + const segment = this.#segments.shift() + this.#usedSegments.push(segment) + return segment + } + + allowContents ({ use = true, isDirectory = true } = {}) { + if (use) { + this.use() + } + // Allow a previously ignored directory + // Important: this should NOT have a trailing + // slash if we are not sure it is a directory. + // Since a dep can be a directory or a symlink and + // a trailing slash in a .gitignore file + // tells git to treat it only as a directory + return [`!/${this.used.join('/')}${isDirectory ? '/' : ''}`] + } + + allow ({ use = true } = {}) { + if (use) { + this.use() + } + // Allow a previously ignored directory but ignore everything inside + return [ + ...this.allowContents({ use: false, isDirectory: true }), + `/${this.used.join('/')}/*`, + ] + } + } + + const gatherAllows = (pathParts, usedParts) => { + const ignores = [] + const segments = new AllowSegments(pathParts, usedParts) + + if (segments.next) { + // 1) Process scope segment of the path, if it has one + if (segments.next.startsWith('@')) { + // For scoped deps we need to allow the entire scope dir + // due to how gitignore works. Without this the gitignore will + // never look to allow our bundled dep since the scope dir was ignored. + // It ends up looking like this for `@colors/colors`: + // + // # Allow @colors dir + // !/@colors/ + // # Ignore everything inside. This is safe because there is + // # nothing inside a scope except other packages + // !/colors/* + // + // Then later we will allow the specific dep inside that scope. + // This way if a scope includes bundled AND unbundled deps, + // we only allow the bundled ones. + ignores.push(...segments.allow()) + } + + // 2) Now we process the name segment of the path + // and allow the dir and everything inside of it (like source code, etc) + ignores.push(...segments.allowContents({ isDirectory: false })) + + // 3) If we still have remaining segments and the next segment + // is a nested node_modules directory... + if (segments.next && segments.use() === 'node_modules') { + ignores.push( + // Allow node_modules and ignore everything inside of it + // Set false here since we already "used" the node_modules path segment + ...segments.allow({ use: false }), + // Repeat the process with the remaining path segments to include whatever is left + ...gatherAllows(segments.remaining, segments.used) + ) + } + } + + return ignores + } + + const allowPaths = new Set() + for (const file of files) { + for (const allow of gatherAllows(file.split('/'))) { + allowPaths.add(allow) } } - pkg.bundleDependencies = bundle.sort((a, b) => a.localeCompare(b, 'en')) - - const ignores = shouldIgnore.sort((a, b) => a.localeCompare(b, 'en')) - .map(i => `/${i}`) - .join('\n') - const ignoreData = `# Automatically generated to ignore dev deps -/.package-lock.json -package-lock.json -CHANGELOG* -changelog* -README* -readme* -__pycache__ -.editorconfig -.idea/ -.npmignore -.eslintrc* -.travis* -.github -.jscsrc -.nycrc -.istanbul* -.eslintignore -.jshintrc* -.prettierrc* -.jscs.json -.dir-locals* -.coveralls* -.babelrc* -.nyc_output -.gitkeep - -${ignores} -` - writeFileSync(ignore, ignoreData) - writeFileSync(pj, JSON.stringify(pkg, 0, 2) + '\n') -}) + + return [...allowPaths] +} + +const setBundleDeps = async () => { + const pkg = await PackageJson.load(CWD) + + pkg.update({ + bundleDependencies: Object.keys(pkg.content.dependencies).sort(localeCompare), + }) + + await pkg.save() + + return pkg.content.bundleDependencies +} + +/* +This file sets what is checked in to node_modules. The root .gitignore file +includes node_modules and this file writes an ignore file to +node_modules/.gitignore. We ignore everything and then use a query to find all +the bundled deps and allow each one of those explicitly. + +Since node_modules can be nested we have to process each portion of the path and +allow it while also ignoring everything inside of it, with the exception of a +deps source. We have to do this since everything is ignored by default, and git +will not allow a nested path if its parent has not also been allowed. BUT! We +also have to ignore other things in those directories. +*/ +const main = async () => { + await setBundleDeps() + + const arb = new Arborist({ path: CWD }) + const allFiles = await arb.loadActual().then(packlist) + const workspaceNames = (await rootPkg.mapWorkspaces()).map(p => p.name) + const isWorkspace = (p) => workspaceNames.some(w => p.startsWith(w + '/')) + + // Get all files within node_modules and remove the node_modules/ portion of + // the path for processing since this list will go inside a gitignore at the + // root of the node_modules dir. It also removes workspaces since those are + // symlinks and should not be committed into source control. + const files = allFiles + .filter(f => f.startsWith('node_modules/')) + .map(f => f.replace(/^node_modules\//, '')) + .filter(f => !isWorkspace(f)) + .sort(localeCompare) + + const ignoreFile = [ + '# Automatically generated to ignore everything except bundled deps', + '# Ignore everything by default except this file', + '/*', + '!/.gitignore', + '# Allow all bundled deps', + ...getAllowedPaths(files), + '# Always ignore some specific patterns within any allowed package', + ...ALWAYS_IGNORE, + ] + + const NODE_MODULES = join(CWD, 'node_modules') + const res = await fs.writeFile(join(NODE_MODULES, '.gitignore'), ignoreFile.join(EOL)) + + if (!await npmGit.is({ cwd: CWD })) { + // if we are not running in a git repo then write the files but we do not + // need to run any git commands to check if we have unmatched files in source + return res + } + + // After we write the file we have to check if any of the paths already checked in + // inside node_modules are now going to be ignored. If we find any then fail with + // a list of the paths remaining. We already attempted to `git rm` them so just + // explain what happened and leave the repo in a state to debug. + const trackedAndIgnored = await lsAndRmIgnored(NODE_MODULES) + + if (trackedAndIgnored.length) { + const message = [ + 'The following files are checked in to git but will now be ignored.', + `They could not be removed automatically and will need to be removed manually.`, + ...trackedAndIgnored.map(p => relative(NODE_MODULES, p)), + ].join(EOL) + throw new Error(message) + } + + return res +} + +run(main) diff --git a/scripts/changelog.js b/scripts/changelog.js deleted file mode 100644 index c32e094ff612a..0000000000000 --- a/scripts/changelog.js +++ /dev/null @@ -1,434 +0,0 @@ -/* eslint no-shadow:2 */ -'use strict' - -const { execSync } = require('child_process') -const semver = require('semver') -const fs = require('fs') -const config = require('@npmcli/template-oss') -const { resolve, relative } = require('path') - -const exec = (...args) => execSync(...args).toString().trim() -const today = () => { - const d = new Date() - const pad = s => s.toString().padStart(2, '0') - return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` -} - -const usage = () => ` - node ${relative(process.cwd(), __filename)} [--read|-r] [--write|-w] [tag] - - Generates changelog entries in our format starting from the most recent tag. - By default this script will print the release notes to stdout. - - [tag] (defaults to most recent tag) - A tag to generate release notes for. Helpful for testing this script against - old releases. Leave this empty to look for the most recent tag. - - [--write|-w] (default: false) - When set it will update the changelog with the new release. - If a release with the same version already exists it will replace it, otherwise - it will prepend it to the file directly after the top level changelog title. - - [--read|-r] (default: false) - When set it will read the release notes for the [tag] from the CHANGELOG.md, - instead of fetching it. This is useful after release notes have been manually - edited and need to be pasted somewhere else. -` - -// this script assumes that the tags it looks for all start with this prefix -const TAG_PREFIX = 'v' - -// a naive implementation of console.log/group for indenting console -// output but keeping it in a buffer to be output to a file or console -const logger = (init) => { - let indent = 0 - const step = 2 - const buffer = [init] - return { - toString () { - return buffer.join('\n').trim() - }, - group (s) { - this.log(s) - indent += step - }, - groupEnd () { - indent -= step - }, - log (s) { - if (!s) { - buffer.push('') - } else { - buffer.push(s.split('\n').map((l) => ' '.repeat(indent) + l).join('\n')) - } - }, - } -} - -// some helpers for generating common parts -// of our markdown release notes -const RELEASE = { - sep: '\n\n', - heading: '## ', - // versions in titles must be prefixed with a v - versionRe: semver.src[11].replace(TAG_PREFIX + '?', TAG_PREFIX), - get h1 () { - return '# Changelog' + this.sep - }, - version (s) { - return s.startsWith(TAG_PREFIX) ? s : TAG_PREFIX + s - }, - date (d) { - return `(${d})` - }, - title (v, d) { - return `${this.heading}${this.version(v)} ${this.date(d)}` - }, -} - -// a map of all our changelog types that go into the release notes to be -// looked up by commit type and return the section title -const CHANGELOG = new Map( - config.changelogTypes.filter(c => !c.hidden).map((c) => [c.type, c.section])) - -const assertArgs = (args) => { - if (args.help) { - console.log(usage()) - return process.exit(0) - } - - if (args.force) { - // just to make manual testing easier - return args - } - - // we dont need to be up to date to read from our local changelog - if (!args.read) { - exec(`git fetch ${args.remote}`) - const remoteBranch = `${args.remote}/${args.branch}` - const current = exec(`git rev-parse --abbrev-ref HEAD`) - - if (current !== args.branch) { - throw new Error(`Must be on branch "${args.branch}", rerun with --force to override`) - } - - const localLog = exec(`git log ${remoteBranch}..HEAD`).length > 0 - const remoteLog = exec(`git log HEAD..${remoteBranch}`).length > 0 - - if (current !== args.branch || localLog || remoteLog) { - throw new Error(`Must be in sync with "${remoteBranch}"`) - } - } - - return args -} - -const parseArgs = (argv) => { - const result = { - tag: null, - file: resolve(__dirname, '..', 'CHANGELOG.md'), - branch: 'latest', - remote: 'origin', - type: 'md', // or 'gh' - format: 'short', // or 'long' - write: false, - read: false, - help: false, - force: false, - } - - for (const arg of argv) { - if (arg.startsWith('--')) { - // dash to camel case. no value means boolean true - const [key, value = true] = arg.slice(2).split('=') - result[key.replace(/-([a-z])/g, (a) => a[1].toUpperCase())] = value - } else if (arg.startsWith('-')) { - // shorthands for read and write - const short = arg.slice(1) - const key = short === 'w' ? 'write' : short === 'r' ? 'read' : null - result[key] = true - } else { - // anything else without a -- or - is the tag - // force tag to start with a "v" - result.tag = arg.startsWith(TAG_PREFIX) ? arg : TAG_PREFIX + arg - } - } - - // previous tag to requested tag OR most recent tag and everything after - // only matches tags prefixed with "v" since only the cli is prefixed with v - const getTag = (t = '') => exec(['git', 'describe', '--tags', '--abbrev=0', - `--match="${TAG_PREFIX}*" ${t}`].join(' ')) - - return assertArgs({ - ...result, - // if a tag is passed in get the previous tag to make a range between the two - // this is mostly for testing to generate release notes from old releases - startTag: result.tag ? getTag(`${result.tag}~1`) : getTag(), - endTag: result.tag || '', - }) -} - -// find an entire section of a release from the changelog from a version -const findRelease = (args, version) => { - const changelog = fs.readFileSync(args.file, 'utf-8') - const escRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - - const titleSrc = (v) => [ - '^', - RELEASE.heading, - v ? escRegExp(v) : RELEASE.versionRe, - ' ', - escRegExp(RELEASE.date(today())).replace(/\d/g, '\\d'), - '$', - ].join('') - - const releaseSrc = [ - '(', - titleSrc(version && RELEASE.version(version)), - '[\\s\\S]*?', - RELEASE.sep, - ')', - titleSrc(), - ].join('') - - const [, release = ''] = changelog.match(new RegExp(releaseSrc, 'm')) || [] - return { - release: release.trim(), - changelog, - } -} - -const generateRelease = async (args) => { - const range = `${args.startTag}...${args.endTag}` - - const log = exec(`git log --reverse --pretty='format:%h' ${range}`) - .split('\n') - .filter(Boolean) - // prefix with underscore so its always a valid identifier - .map((sha) => `_${sha}: object (expression: "${sha}") { ...commitCredit }`) - - if (!log.length) { - throw new Error(`No commits found for "${range}"`) - } - - const query = ` - fragment commitCredit on GitObject { - ... on Commit { - message - url - abbreviatedOid - authors (first:10) { - nodes { - user { - login - url - } - email - name - } - } - associatedPullRequests (first:10) { - nodes { - number - url - merged - } - } - } - } - - query { - repository (owner:"npm", name:"cli") { - ${log} - } - } - ` - - const res = JSON.parse(exec(`gh api graphql -f query='${query}'`)) - - // collect commits by valid changelog type - const commits = [...CHANGELOG.values()].reduce((acc, c) => { - acc[c] = [] - return acc - }, {}) - - const allCommits = Object.values(res.data.repository) - - for (const commit of allCommits) { - // get changelog type of commit or bail if there is not a valid one - const [, type] = /(^\w+)[\s(:]?/.exec(commit.message) || [] - const changelogType = CHANGELOG.get(type) - if (!changelogType) { - continue - } - - const message = commit.message - .trim() // remove leading/trailing spaces - .replace(/(\r?\n)+/gm, '\n') // replace multiple newlines with one - .replace(/([^\s]+@\d+\.\d+\.\d+.*)/gm, '`$1`') // wrap package@version in backticks - - // the title is the first line of the commit, 'let' because we change it later - let [title, ...body] = message.split('\n') - - const prs = commit.associatedPullRequests.nodes.filter((pull) => pull.merged) - - // external squashed PRs dont get the associated pr node set - // so we try to grab it from the end of the commit title - // since thats where it goes by default - const [, titleNumber] = title.match(/\s+\(#(\d+)\)$/) || [] - if (titleNumber && !prs.find((pr) => pr.number === +titleNumber)) { - try { - // it could also reference an issue so we do one extra check - // to make sure it is really a pr that has been merged - const realPr = JSON.parse(exec(`gh pr view ${titleNumber} --json url,number,state`, { - stdio: 'pipe', - })) - if (realPr.state === 'MERGED') { - prs.push(realPr) - } - } catch { - // maybe an issue or something else went wrong - // not super important so keep going - } - } - - for (const pr of prs) { - title = title.replace(new RegExp(`\\s*\\(#${pr.number}\\)`, 'g'), '') - } - - body = body - .map((line) => line.trim()) // remove artificial line breaks - .filter(Boolean) // remove blank lines - .join('\n') // rejoin on new lines - .split(/^[*-]/gm) // split on lines starting with bullets - .map((line) => line.trim()) // remove spaces around bullets - .filter((line) => !title.includes(line)) // rm lines that exist in the title - // replace new lines for this bullet with spaces and re-bullet it - .map((line) => `* ${line.trim().replace(/\n/gm, ' ')}`) - .join('\n') // re-join with new lines - - commits[changelogType].push({ - hash: commit.abbreviatedOid, - url: commit.url, - title, - type: changelogType, - body, - prs, - credit: commit.authors.nodes.map((author) => { - if (author.user && author.user.login) { - return { - name: `@${author.user.login}`, - url: author.user.url, - } - } - // if the commit used an email that's not associated with a github account - // then the user field will be empty, so we fall back to using the committer's - // name and email as specified by git - return { - name: author.name, - url: `mailto:${author.email}`, - } - }), - }) - } - - if (!Object.values(commits).flat().length) { - const messages = allCommits.map((c) => c.message.trim().split('\n')[0]) - throw new Error(`No changelog commits found for "${range}":\n${messages.join('\n')}`) - } - - // this doesnt work with majors but we dont do those very often - const semverBump = commits.Features.length ? 'minor' : 'patch' - const version = TAG_PREFIX + semver.parse(args.startTag).inc(semverBump).version - const date = args.endTag ? exec(`git log -1 --date=short --format=%ad ${args.endTag}`) : today() - - const output = logger(RELEASE.title(version, date) + '\n') - - for (const key of Object.keys(commits)) { - if (commits[key].length > 0) { - output.group(`### ${key}\n`) - - for (const commit of commits[key]) { - let groupCommit = `* [\`${commit.hash}\`](${commit.url})` - for (const pr of commit.prs) { - groupCommit += ` [#${pr.number}](${pr.url})` - } - groupCommit += ` ${commit.title}` - if (key !== 'Dependencies') { - for (const user of commit.credit) { - if (args.type === 'gh') { - groupCommit += ` (${user.name})` - } else { - groupCommit += ` ([${user.name}](${user.url}))` - } - } - } - - output.group(groupCommit) - // only optionally add full commit bodies to changelog - if (commit.body && commit.body.length && args.format === 'long') { - output.log(commit.body) - } - output.groupEnd() - } - - output.log() - output.groupEnd() - } - } - - return { - date, - version, - release: output.toString(), - } -} - -const main = async (argv) => { - const args = parseArgs(argv) - - if (args.read) { - // this reads the release notes for that version - let { release } = findRelease(args, args.tag) - if (args.type === 'gh') { - // changelog was written in markdown so convert user links to gh release style - // XXX: this needs to be changed if the `generateRelease` format changes - release = release.replace(/\(\[(@[a-z\d-]+)\]\(https:\/\/github.com\/[a-z\d-]+\)\)/gi, '($1)') - } - return console.log(release) - } - - // otherwise fetch the requested release from github - const { release, version, date } = await generateRelease(args) - - if (args.write) { - // only try and run release manager issue update on write since that signals - // the first time we know the version of the release - try { - exec( - `node scripts/release-manager.js --update --version=${version.slice(1)} --date=${date}`, { - stdio: 'pipe', - }) - } catch (e) { - console.error(`Updating release manager issue failed: ${e.stderr}`) - } - - const { release: existing, changelog } = findRelease(args, version) - fs.writeFileSync( - args.file, - existing - // replace existing release with the newly generated one - ? changelog.replace(existing, release) - // otherwise prepend a new release at the start of the changelog - : changelog.replace(RELEASE.h1, RELEASE.h1 + release + RELEASE.sep), - 'utf-8' - ) - return console.log( - `Release notes for ${version} written to "./${relative(process.cwd(), args.file)}".` - ) - } - - console.log(release) -} - -main(process.argv.slice(2)) diff --git a/scripts/create-node-pr.js b/scripts/create-node-pr.js new file mode 100644 index 0000000000000..c75647ffd0669 --- /dev/null +++ b/scripts/create-node-pr.js @@ -0,0 +1,287 @@ +const { join, basename } = require('node:path') +const fsp = require('node:fs/promises') +const hgi = require('hosted-git-info') +const semver = require('semver') +const pacote = require('pacote') +const { log } = require('proc-log') +const tar = require('tar') +const { cp, withTempDir } = require('@npmcli/fs') +const { CWD, run, spawn, git, fs, gh } = require('./util.js') + +const NODE_FORK = 'npm/node' +// this script expects node to already be cloned to a directory at the cli root named "node" +const NODE_DIR = join(CWD, 'node') +const gitNode = spawn.create('git', { cwd: NODE_DIR }) + +const createNodeTarball = async ({ mani, registryOnly, localTest, tag, dir: extractDir }) => { + const tarball = join(extractDir, 'npm-node.tgz') + await pacote.tarball.file(mani._from, tarball, { resolved: mani._resolved }) + + if (registryOnly) { + // a future goal is to only need files from the published tarball for + // inclusion in node. in that case, we'd be able to remove everything after + // this line since we have already fetched the tarball + return tarball + } + + // extract tarball to current dir and delete original tarball + await tar.x({ strip: 1, file: tarball, cwd: extractDir }) + await fs.rimraf(tarball) + + // checkout the tag since we need to get files from source. + if (!localTest) { + try { + await git('checkout', tag) + } catch (err) { + log.error('Use the `--local-test` flag to avoid checking out the tag') + throw err + } + } + // currently there is an empty .npmrc file in the deps/npm dir in the node repo + // i do not know why and it might not be used but in order to minimize any + // unnecessary churn, let's create that file to match the old process + await fsp.writeFile(join(extractDir, '.npmrc'), '', 'utf-8') + + // copy our test dirs so that tests can be run + for (const path of ['tap-snapshots/', 'test/']) { + await cp(join(CWD, path), join(extractDir, path), { recursive: true }) + } + + // recreate the tarball as closely as possible to how we would before publishing + // to the registry. the only difference here is the extra files we put in the dir + await tar.c({ + ...pacote.DirFetcher.tarCreateOptions(mani), + cwd: extractDir, + file: tarball, + }, ['.']) + + return tarball +} + +const getPrBody = async ({ releases, closePrs }) => { + const useSummary = releases.length > 1 + const releasePath = (v) => `/npm/cli/releases/tag/v${v}` + + // XXX: add links to relevant CI and CITGM runs once we no longer include our tests + let prBody = '' + + if (useSummary) { + const summary = releases.map(r => { + return `[\`npm@${r.version}\`](https://github.com${releasePath(r.version)})` + }) + prBody += `This PR contains changes from: ${summary.join(' ')}\n\n` + } + + if (closePrs.length) { + prBody += `This PR replaces: ${closePrs.map(pr => pr.url).join(' ')}\n\n` + } + + if (prBody) { + prBody += '---\n\n' + } + + for (const { version, body } of releases) { + prBody += useSummary + ? `
${version}\n

\n\n${body}\n\n

\n
` + : body + prBody += '\n' + } + + // These comes from the releases so those link to the raw comparison between tags. + // Since we are putting this in a PR we can change those links back to the releases. + prBody = prBody.replace(/\/npm\/cli\/compare\/v[\w.-]+\.\.\.v([\w.-]+)/g, releasePath('$1')) + + const { remark } = await import('remark') + const { default: remarkGfm } = await import('remark-gfm') + const { default: remarkGithub, defaultBuildUrl } = await import('remark-github') + + return remark() + .use(remarkGfm) + .use(remarkGithub, { + repository: 'npm/cli', + // don't link mentions, but anything else make the link an explicit reference to npm/cli + buildUrl: (values) => values.type === 'mention' ? false : defaultBuildUrl(values), + }) + .process(prBody) + .then(v => String(v)) +} + +const tokenRemoteUrl = ({ host, token }) => { + // this is a remote url that uses a github token as the username + // in order to authenticate with github + const headRemoteUrl = new URL(host.https()) + headRemoteUrl.username = token + // we have to manually change the protocol. the whatwg url spec + // does not allow changing a special protocol to another one + // but the protocol has to be `https:` without the `git+` + return headRemoteUrl.toString().replace('git+https:', 'https:') +} + +const main = async (spec, branch = 'main', opts) => withTempDir(CWD, async (tmpDir) => { + const { GITHUB_TOKEN } = process.env + const { dryRun, registryOnly, localTest } = opts + + if (!spec) { + throw new Error('`spec` is required as the first argument') + } + + if (!branch) { + throw new Error('`branch` is required as the second argument') + } + + if (!GITHUB_TOKEN) { + throw new Error(`process.env.GITHUB_TOKEN is required`) + } + + await fsp.access(NODE_DIR, fsp.constants.F_OK).catch(() => { + throw new Error(`node repo must be checked out to \`${NODE_DIR}\` to continue`) + }) + + await gh.json('repo', 'view', NODE_FORK, 'url').catch(() => { + throw new Error(`node repo must be forked to ${NODE_FORK}`) + }) + + await git.dirty().catch((er) => { + if (localTest) { + return log.info('Skipping git dirty check due to `--local-test` flag') + } + throw er + }) + + const mani = await pacote.manifest(`npm@${spec}`, { preferOnline: true }) + const packument = await pacote.packument('npm', { preferOnline: true }) + const npmVersions = Object.keys(packument.versions).sort(semver.rcompare) + + const npmVersion = semver.parse(mani.version) + const npmHost = hgi.fromUrl(NODE_FORK) + const npmTag = `v${npmVersion}` + // use the target branch as part of the name so we can create multiple PRs for + // the same npm version targeting different Node branches at the same time + const npmBranch = `npm-${npmTag}-${branch}` + const npmRemoteUrl = tokenRemoteUrl({ host: npmHost, token: GITHUB_TOKEN }) + const npmMessage = (v = npmVersion) => `deps: upgrade npm to ${v}` + + const tarball = await createNodeTarball({ + mani, + tag: npmTag, + dir: tmpDir, + registryOnly, + localTest, + }) + log.info('tarball path', tarball) + + const nodeRemote = 'origin' + const nodeBranch = /^\d+$/.test(branch) ? `v${branch}.x-staging` : branch + const nodeHost = hgi.fromUrl(await gitNode('remote', 'get-url', nodeRemote, { out: true })) + const nodePrArgs = ['pr', '-R', nodeHost.path()] + + await gitNode('fetch', nodeRemote) + await gitNode('checkout', nodeBranch) + await gitNode('reset', '--hard', `${nodeRemote}/${nodeBranch}`) + + const nodeNpmPath = join('deps', 'npm') + const nodeNpmDir = join(NODE_DIR, nodeNpmPath) + const nodeNpmVersion = require(join(nodeNpmDir, 'package.json')).version + + // this is the range of all versions included in this update based + // on the current version of npm in node currently. we use this + // to build a list of all release notes and to close any existing PRs + const newNpmVersions = npmVersions.slice( + npmVersions.indexOf(npmVersion.toString()), + npmVersions.indexOf(nodeNpmVersion) + ) + .reverse() + .map((v) => semver.parse(v)) + .filter((version) => version.major === npmVersion.major) + + // get a list of all versions changelogs to add to the body of the PR + // do this before we checkout our branch and make any changes + const npmReleases = await Promise.all(newNpmVersions.map(async (v) => { + // don't include prereleases unless we are updating to a prerelease since we + // manually put all prerelease notes into the first stable major version + if (v.prerelease.length && !npmVersion.prerelease.length) { + return null + } + return { + version: v, + body: await gh.json('release', 'view', `v${v}`, 'body', { quiet: true }).then(r => r.trim()), + } + })).then(r => r.filter(Boolean)) + + log.info('npm versions', newNpmVersions.map(v => v.toString())) + log.info('npm releases', npmReleases.map(u => u.version.toString())) + + await gitNode('branch', '-D', npmBranch, { ok: true }) + await gitNode('checkout', '-b', npmBranch) + await fs.clean(nodeNpmDir) + await tar.x({ strip: 1, file: tarball, cwd: nodeNpmDir }) + await fs.rimraf(join(nodeNpmDir, basename(tarball))) + + await gitNode('add', '-A', nodeNpmPath) + await gitNode('commit', '-m', npmMessage()) + await gitNode('rebase', '--whitespace', 'fix', nodeBranch) + + await gitNode('remote', 'rm', npmHost.user, { ok: true }) + await gitNode('remote', 'add', npmHost.user, npmRemoteUrl) + if (!dryRun) { + await gitNode('push', npmHost.user, npmBranch, '--force') + } + + const npmPrs = await gh.json( + ...nodePrArgs, 'list', + '-S', `in:title "${npmMessage('')}"`, + '--base', nodeBranch, + 'number,title,url' + ) + + log.info('Found other npm PRs', npmPrs) + + let existingPr = null + const closePrs = [] + + for (const pr of npmPrs) { + const prVersion = pr.title.replace(npmMessage(''), '').trim() + log.silly('checking existing PR', prVersion, pr) + + if (!existingPr && prVersion === npmVersion.toString()) { + existingPr = pr + } else if (newNpmVersions.some(v => v.toString() === prVersion)) { + closePrs.push(pr) + } + } + + log.info('Found existing PR', existingPr) + log.info('Found PRs to close', closePrs) + + const prBody = await getPrBody({ releases: npmReleases, closePrs }) + + const prArgs = [ + nodePrArgs, + (existingPr ? ['edit', existingPr.number] : ['create', '-H', `${npmHost.user}:${npmBranch}`]), + '-B', nodeBranch, + '-t', npmMessage(), + ].flat() + + if (dryRun) { + log.info(`gh ${prArgs.join(' ')}`) + return prBody + } + + const newOrUpdatedPr = await gh(prArgs, '-F', '-', { input: prBody, out: true }) + const closeMessage = `Closing in favor of ${newOrUpdatedPr}` + + for (const closePr of closePrs) { + log.info('Attempting to close PR', closePr.url) + try { + await gh(nodePrArgs, 'close', closePr.number, '-c', closeMessage) + } catch (err) { + log.error('Could not close PR', err) + } + } + + return newOrUpdatedPr +}) + +run(({ argv, ...opts }) => main(argv.remain[0], argv.remain[1], opts), { + redact: process.env.GITHUB_TOKEN, +}) diff --git a/scripts/dependency-graph.js b/scripts/dependency-graph.js index 318b9f39b4292..da9b04c14ae23 100644 --- a/scripts/dependency-graph.js +++ b/scripts/dependency-graph.js @@ -1,26 +1,52 @@ -'use strict' +const Arborist = require('@npmcli/arborist') +const os = require('node:os') +const { readFileSync } = require('node:fs') +const { join } = require('node:path') +const { log } = require('proc-log') +const { run, CWD, pkg, fs, EOL } = require('./util.js') // Generates our dependency graph documents in DEPENDENCIES.md. -const Arborist = require('@npmcli/arborist') -const fs = require('fs') - // To re-create npm-cli-repos.txt run: -/* eslint-disable-next-line max-len */ -// gh api "/graphql" -F query='query { search (query: "org:npm topic:npm-cli", type: REPOSITORY, first:100) { nodes { ... on Repository { name } } } }' --jq '.data.search.nodes[].name'|sort -const repos = fs.readFileSync('./scripts/npm-cli-repos.txt', 'utf8').trim().split('\n') +// npx -p @npmcli/stafftools gh repos --json | json -a name | sort > scripts/npm-cli-repos.txt +const repos = readFileSync(join(CWD, 'scripts', 'npm-cli-repos.txt'), 'utf-8').trim().split(os.EOL) + +// Packages with known circular dependencies. This is typically something with arborist as a dependency which is also in arborist's dev dependencies. Not a problem if they're workspaces so we ignore repeats +const circular = new Set(['@npmcli/mock-registry']) + +// TODO Set.intersection/difference was added in node 22.11.0, once we're above that line we can use the builtin +// https://node.green/#ES2025-features-Set-methods-Set-prototype-intersection-- +function intersection (set1, set2) { + const result = new Set() + for (const item of set1) { + if (set2.has(item)) { + result.add(item) + } + } + return result +} + +function difference (set1, set2) { + const result = new Set() + for (const item of set1) { + if (!set2.has(item)) { + result.add(item) + } + } + return result +} // these have a different package name than the repo name, and are ours. const aliases = { - semver: 'node-semver', abbrev: 'abbrev-js', + semver: 'node-semver', + which: 'node-which', } // These are entries in npm-cli-repos.txt that correlate to namespaced repos. // If we see a bare package with just this name, it's NOT ours const namespaced = [ 'arborist', - 'ci-detect', 'config', 'disparity-colors', 'eslint-config', @@ -29,6 +55,7 @@ const namespaced = [ 'git', 'installed-package-contents', 'lint', + 'mock-registry', 'map-workspaces', 'metavuln-calculator', 'move-file', @@ -66,6 +93,7 @@ function escapeName (name) { } return name } + function stripName (name) { if (name.startsWith('@')) { const parts = name.slice(1).split('/') @@ -75,23 +103,23 @@ function stripName (name) { } const main = async function () { - const arborist = new Arborist({ - prefix: process.cwd(), - path: process.cwd(), - }) - const tree = await arborist.loadVirtual({ path: process.cwd(), name: 'npm' }) - tree.name = 'npm' + // add all of the cli's public workspaces as package names + for (const { name, pkg: ws } of await pkg.mapWorkspaces()) { + if (!ws.private) { + repos.push(name) + } + } - const { - heirarchy: heirarchyOurs, - annotations: annotationsOurs, - } = walk(tree, true) + const arborist = new Arborist({ prefix: CWD, path: CWD }) + const tree = await arborist.loadVirtual({ path: CWD, name: 'npm' }) + tree.name = 'npm' - const { - annotations: annotationsAll, - } = walk(tree, false) + const [annotationsOurs, hierarchyOurs] = walk(tree, true) + const [annotationsAll] = walk(tree, false) const out = [ + '', + '', '# npm dependencies', '', '## `github.com/npm/` only', @@ -106,55 +134,83 @@ const main = async function () { ...annotationsAll.sort(), '```', '', - '## npm dependency heirarchy', + '## npm dependency hierarchy', '', 'These are the groups of dependencies in npm that depend on each other.', 'Each group depends on packages lower down the chain, nothing depends on', 'packages higher up the chain.', '', - ` - ${heirarchyOurs.reverse().join('\n - ')}`, + ` - ${hierarchyOurs.reverse().join(`${EOL} - `)}`, ] - fs.writeFileSync('DEPENDENCIES.md', out.join('\n')) - console.log('wrote to DEPENDENCIES.md') + + fs.writeFile(join(CWD, 'DEPENDENCIES.json'), + JSON.stringify(hierarchyOurs.map(v => v.split(', ')), null, 2) + ) + + return fs.writeFile(join(CWD, 'DEPENDENCIES.md'), out.join(EOL)) } const walk = function (tree, onlyOurs) { const annotations = [] // mermaid dependency annotations const dependedBy = {} + iterate(tree, dependedBy, annotations, onlyOurs) + const allDeps = new Set(Object.keys(dependedBy)) const foundDeps = new Set() - const heirarchy = [] - while (allDeps.size) { - const level = [] - for (const dep of allDeps) { - if (!dependedBy[dep].size) { - level.push(dep) - foundDeps.add(dep) + const hierarchy = [] + + if (onlyOurs) { + while (allDeps.size) { + log.silly('SIZE', allDeps.size) + const level = [] + + for (const dep of allDeps) { + log.silly(dep, '::', [...dependedBy[dep]].join(', ')) + log.silly('-'.repeat(80)) + + // things that depend on us that are at the same level + const both = intersection(allDeps, dependedBy[dep]) + // ... minus the known circular dependencies + const neither = difference(both, circular) + if (!dependedBy[dep].size || !neither.size) { + level.push(dep) + foundDeps.add(dep) + } } - } - for (const dep of allDeps) { - for (const found of foundDeps) { - allDeps.delete(found) - dependedBy[dep].delete(found) + + log.silly('LEVEL', level.length) + log.silly('FOUND', foundDeps.size) + + for (const dep of allDeps) { + for (const found of foundDeps) { + allDeps.delete(found) + dependedBy[dep].delete(found) + } } + + log.silly('SIZE', allDeps.size) + + if (!level.length) { + const remaining = `Remaining deps: ${[...allDeps.keys()]}` + throw new Error(`Would do an infinite loop here, need to debug. ${remaining}`) + } + + hierarchy.push(level.join(', ')) + log.silly('HIERARCHY', hierarchy.length) + log.silly('='.repeat(80)) } - if (!level.length) { - throw new Error('Would do an infinite loop here, need to debug') - } - heirarchy.push(level.join(', ')) } - return { heirarchy, annotations } + return [annotations, hierarchy] } + const iterate = function (node, dependedBy, annotations, onlyOurs) { if (!dependedBy[node.packageName]) { dependedBy[node.packageName] = new Set() } for (const [name, edge] of node.edgesOut) { - if ( - (!onlyOurs || isOurs(name)) && !node.dev - ) { + if ((!onlyOurs || isOurs(name)) && !node.dev) { if (!dependedBy[node.packageName].has(edge.name)) { dependedBy[node.packageName].add(edge.name) annotations.push(` ${stripName(node.packageName)}-->${escapeName(edge.name)};`) @@ -166,9 +222,4 @@ const iterate = function (node, dependedBy, annotations, onlyOurs) { } } -main().then(() => { - process.exit(0) -}).catch(err => { - console.error(err) - process.exit(1) -}) +run(main) diff --git a/scripts/fish-completion.js b/scripts/fish-completion.js new file mode 100644 index 0000000000000..bd8e92b56937b --- /dev/null +++ b/scripts/fish-completion.js @@ -0,0 +1,54 @@ +/* eslint-disable no-console */ +const fs = require('node:fs/promises') +const { resolve } = require('node:path') + +const { commands, aliases } = require('../lib/utils/cmd-list.js') +const { definitions } = require('@npmcli/config/lib/definitions') + +async function main () { + const file = resolve(__dirname, '..', 'lib', 'utils', 'completion.fish') + console.log(await fs.readFile(file, 'utf-8')) + const cmds = {} + for (const cmd of commands) { + cmds[cmd] = { aliases: [cmd] } + const cmdClass = require(`../lib/commands/${cmd}.js`) + cmds[cmd].description = cmdClass.description + cmds[cmd].params = cmdClass.params + } + for (const alias in aliases) { + cmds[aliases[alias]].aliases.push(alias) + } + for (const cmd in cmds) { + console.log(`# ${cmd}`) + const { aliases: cmdAliases, description, params = [] } = cmds[cmd] + // If npm completion could return all commands in a fish friendly manner + // like we do w/ run-script these wouldn't be needed. + /* eslint-disable-next-line max-len */ + console.log(`complete -x -c npm -n __fish_npm_needs_command -a '${cmdAliases.join(' ')}' -d '${description}'`) + const shorts = params.map(p => { + // Our multi-character short params (e.g. -ws) are not very standard and + // don't work with things that assume short params are only ever single + // characters. + if (definitions[p].short?.length === 1) { + return `-s ${definitions[p].short}` + } + }).filter(p => p).join(' ') + // The config descriptions are not appropriate for -d here. We may want to + // consider having a more terse description for these. + // We can also have a mechanism to auto-generate the long form of options + // that have predefined values. + // params completion + /* eslint-disable-next-line max-len */ + console.log(`complete -x -c npm -n '__fish_seen_subcommand_from ${cmdAliases.join(' ')}' ${params.map(p => `-l ${p}`).join(' ')} ${shorts}`) + // builtin npm completion + /* eslint-disable-next-line max-len */ + console.log(`complete -x -c npm -n '__fish_seen_subcommand_from ${cmdAliases.join(' ')}' -a '(__fish_complete_npm)'`) + } +} + +main().then(() => { + return process.exit() +}).catch(err => { + console.error(err) + process.exit(1) +}) diff --git a/scripts/git-dirty.js b/scripts/git-dirty.js index 5730ed9006681..1c864856914ab 100644 --- a/scripts/git-dirty.js +++ b/scripts/git-dirty.js @@ -1,17 +1,3 @@ -#!/usr/bin/env node -const { spawnSync } = require('child_process') -const changes = spawnSync('git', ['status', '--porcelain', '-uall']) -const stdout = changes.stdout.toString('utf8') -const stderr = changes.stderr.toString('utf8') -const { status, signal } = changes -console.log(stdout) -console.error(stderr) -if (status || signal) { - console.error({ status, signal }) - process.exitCode = status || 1 -} -if (stdout.trim() !== '') { - throw new Error('git dirty') -} else { - console.log('git clean') -} +const { run, git } = require('./util.js') + +run(git.dirty) diff --git a/scripts/install.sh b/scripts/install.sh deleted file mode 100755 index cd6ea391cea5d..0000000000000 --- a/scripts/install.sh +++ /dev/null @@ -1,175 +0,0 @@ -#!/bin/sh - -# A word about this shell script: -# -# It must work everywhere, including on systems that lack -# a /bin/bash, map 'sh' to ksh, ksh97, bash, ash, or zsh, -# and potentially have either a posix shell or bourne -# shell living at /bin/sh. -# -# See this helpful document on writing portable shell scripts: -# http://www.gnu.org/s/hello/manual/autoconf/Portable-Shell.html -# -# The only shell it won't ever work on is cmd.exe. - -if [ "x$0" = "xsh" ]; then - # run as curl | sh - # on some systems, you can just do cat>npm-install.sh - # which is a bit cuter. But on others, &1 is already closed, - # so catting to another script file won't do anything. - # Follow Location: headers, and fail on errors - curl -q -f -L -s https://www.npmjs.org/install.sh > npm-install-$$.sh - ret=$? - if [ $ret -eq 0 ]; then - (exit 0) - else - rm npm-install-$$.sh - echo "failed to download script" >&2 - exit $ret - fi - sh npm-install-$$.sh - ret=$? - rm npm-install-$$.sh - exit $ret -fi - -debug=0 -npm_config_loglevel="error" -if [ "x$npm_debug" = "x" ]; then - (exit 0) -else - echo "running in debug mode." - echo "note that this requires bash or zsh." - set -o xtrace - set -o pipefail - npm_config_loglevel="verbose" - debug=1 -fi -export npm_config_loglevel - -# make sure that node exists -node=`which node 2>&1` -ret=$? -# if not found, try "nodejs" as it is the case on debian -if [ $ret -ne 0 ]; then - node=`which nodejs 2>&1` - ret=$? -fi -if [ $ret -eq 0 ] && [ -x "$node" ]; then - if [ $debug -eq 1 ]; then - echo "found 'node' at: $node" - echo -n "version: " - $node --version - echo "" - fi - (exit 0) -else - echo "npm cannot be installed without node.js." >&2 - echo "install node first, and then try again." >&2 - echo "" >&2 - exit $ret -fi - -ret=0 -tar="${TAR}" -if [ -z "$tar" ]; then - tar="${npm_config_tar}" -fi -if [ -z "$tar" ]; then - tar=`which tar 2>&1` - ret=$? -fi - -if [ $ret -eq 0 ] && [ -x "$tar" ]; then - if [ $debug -eq 1 ]; then - echo "found 'tar' at: $tar" - echo -n "version: " - $tar --version - echo "" - fi - ret=$? -fi - -if [ $ret -eq 0 ]; then - (exit 0) -else - echo "this script requires 'tar', please install it and try again." - exit 1 -fi - -curl=`which curl 2>&1` -ret=$? -if [ $ret -eq 0 ]; then - if [ $debug -eq 1 ]; then - echo "found 'curl' at: $curl" - echo -n "version: " - $curl --version | head -n 1 - echo "" - fi - (exit 0) -else - echo "this script requires 'curl', please install it and try again." - exit 1 -fi - -# set the temp dir -TMP="${TMPDIR}" -if [ "x$TMP" = "x" ]; then - TMP="/tmp" -fi -TMP="${TMP}/npm.$$" -rm -rf "$TMP" || true -mkdir "$TMP" -if [ $? -ne 0 ]; then - echo "failed to mkdir $TMP" >&2 - exit 1 -fi - -BACK="$PWD" - -t="${npm_install}" -if [ -z "$t" ]; then - t="latest" -fi - -# need to echo "" after, because Posix sed doesn't treat EOF -# as an implied end of line. -url=`(curl -qSsL https://registry.npmjs.org/npm/$t; echo "") \ - | sed -e 's/^.*tarball":"//' \ - | sed -e 's/".*$//'` - -ret=$? -if [ "x$url" = "x" ]; then - ret=125 - # try without the -e arg to sed. - url=`(curl -qSsL https://registry.npmjs.org/npm/$t; echo "") \ - | sed 's/^.*tarball":"//' \ - | sed 's/".*$//'` - ret=$? - if [ "x$url" = "x" ]; then - ret=125 - fi -fi -if [ $ret -ne 0 ]; then - echo "failed to get tarball url for npm/$t" >&2 - exit $ret -fi - - -echo "fetching: $url" >&2 - -cd "$TMP" \ - && curl -qSsL -o npm.tgz "$url" \ - && $tar -xzf npm.tgz \ - && cd "$TMP"/package \ - && echo "installing npm@$t" \ - && "$node" bin/npm-cli.js install -gf ../npm.tgz \ - && cd "$BACK" \ - && rm -rf "$TMP" \ - && echo "successfully installed npm@$t" - -ret=$? -if [ $ret -ne 0 ]; then - echo "failed!" >&2 -fi -exit $ret diff --git a/scripts/npm-cli-repos.txt b/scripts/npm-cli-repos.txt index bbbf2e31c4923..1d2b57e1252e4 100644 --- a/scripts/npm-cli-repos.txt +++ b/scripts/npm-cli-repos.txt @@ -1,67 +1,42 @@ abbrev-js -arborist -are-we-there-yet -benchmarks +agent bin-links cacache -ci-detect cli cmd-shim -config -create-oss -dezalgo -disparity-colors -doctornpm documentation eslint-config -exec fs -fs-minipass -gauge git hosted-git-info ignore-walk -infer-owner -inflight ini init-package-json installed-package-contents -libnpmaccess -libnpmfund -libnpmhook -libnpmorg -libnpmpack -libnpmpublish -libnpmsearch -libnpmteam -libnpmversion -lint +json-parse-even-better-errors make-fetch-happen map-workspaces metavuln-calculator +minify-registry-metadata minipass-fetch -move-file mute-stream name-from-folder -nock-registry node-gyp node-semver -node-tar node-which nopt normalize-package-data npm-audit-report -npm-birthday npm-bundled npm-install-checks npm-install-script npm-normalize-package-bin npm-package-arg npm-packlist +npm-pick-manifest npm-profile npm-registry-fetch npm-user-validate -npmlog package-json pacote parse-conflict-json @@ -69,20 +44,19 @@ proc-log proggy promise-spawn promzard +query read read-cmd-shim -read-package-json read-package-json-fast -readdir-scoped-modules +redact rfcs run-script ssri +stafftools statusboard -stringify-package template-oss -treeverse +types unique-filename unique-slug validate-npm-package-name -wrappy write-file-atomic diff --git a/scripts/publish-tag.js b/scripts/publish-tag.js deleted file mode 100644 index fb8a48233b9c0..0000000000000 --- a/scripts/publish-tag.js +++ /dev/null @@ -1,3 +0,0 @@ -var semver = require('semver') -var version = semver.parse(require('../package.json').version) -console.log('next-%s', version.major) diff --git a/scripts/publish.js b/scripts/publish.js new file mode 100644 index 0000000000000..1d6e13e7f8eda --- /dev/null +++ b/scripts/publish.js @@ -0,0 +1,204 @@ +const semver = require('semver') +const { log } = require('proc-log') +const pacote = require('pacote') +const { read } = require('read') +const Table = require('cli-table3') +const { run, git, npm, pkgPath: cliPath, pkg: cli, spawn } = require('./util.js') +const fs = require('fs').promises + +const resetdeps = () => npm('run', 'resetdeps') + +const op = () => spawn('op', 'item', 'get', 'npm', '--otp', { out: true, ok: true }) + +const getWorkspaceTag = async ({ name, version }) => { + const { prerelease, major } = semver.parse(version) + if (prerelease.length) { + return 'prerelease' + } + + const pack = await pacote.packument(name, { preferOnline: true }).catch(() => null) + + if (!pack) { + // This might never happen but if we were to create a new workspace that has never + // been published before it should be set to latest right away. + return 'latest' + } + + if (major >= semver.major(pack['dist-tags'].latest)) { + // if the major version we are publishing is greater than the major version + // of the latest dist-tag, then this should be latest too + return 'latest' + } + + // Anything else is a backport + return 'backport' +} + +const versionNotExists = async ({ name, version }) => { + const spec = `${name}@${version}` + let exists + try { + await pacote.manifest(spec, { preferOnline: true }) + exists = true // if it exists, no publish needed + } catch { + exists = false // otherwise its needs publishing + } + log.info(`${spec} exists=${exists}`) + return !exists +} + +const getPublishes = async ({ force }) => { + const publishPackages = [] + + for (const { pkg, pkgPath } of await cli.mapWorkspaces({ public: true })) { + const updatePkg = async (cb) => { + const data = JSON.parse(await fs.readFile(pkgPath, 'utf8')) + const result = cb(data) + await fs.writeFile(pkgPath, JSON.stringify(result, null, 2)) + return result + } + + if (force || await versionNotExists(pkg)) { + publishPackages.push({ + workspace: `--workspace=${pkg.name}`, + name: pkg.name, + version: pkg.version, + dependencies: pkg.dependencies, + devDependencies: pkg.devDependencies, + tag: await getWorkspaceTag(pkg), + updatePkg, + }) + } + } + + if (force || await versionNotExists(cli)) { + publishPackages.push({ + workspace: '', + name: cli.name, + version: cli.version, + tag: `next-${semver.major(cli.version)}`, + dependencies: cli.dependencies, + devDependencies: cli.devDependencies, + updatePkg: async (cb) => { + const result = cb(cli) + await fs.writeFile(cliPath, JSON.stringify(result, null, 2)) + return result + }, + }) + } + + return publishPackages +} + +const main = async (opts) => { + const { test, otp, dryRun, smokePublish, packDestination } = opts + + const hasPackDest = !!packDestination + const publishes = await getPublishes({ force: smokePublish }) + + if (!publishes.length) { + throw new Error( + 'Nothing to publish, exiting.\n' + + 'All packages to publish should have their version bumped before running this script.' + ) + } + + const table = new Table({ head: ['name', 'version', 'tag'] }) + for (const publish of publishes) { + table.push([publish.name, publish.version, publish.tag]) + } + + const preformOperations = hasPackDest ? ['publish', 'pack'] : ['publish'] + + const confirmMessage = [ + `Ready to ${preformOperations.join(',')} the following packages:`, + table.toString(), + smokePublish ? null : 'Ok to proceed? ', + ].filter(Boolean).join('\n') + + if (smokePublish) { + log.info(confirmMessage) + } else { + const confirm = await read({ prompt: confirmMessage, default: 'y' }) + if (confirm.trim().toLowerCase().charAt(0) !== 'y') { + throw new Error('Aborted') + } + } + + await git('clean', '-fd') + await resetdeps() + await npm('ls', '--omit=dev', { quiet: true }) + await npm('rm', '--global', '--force', 'npm') + await npm('link', '--force', '--ignore-scripts') + + if (test) { + await npm('run', 'lint-all', '--ignore-scripts') + await npm('run', 'postlint', '--ignore-scripts') + await npm('run', 'test-all', '--ignore-scripts') + } + + await npm('prune', '--omit=dev', '--no-save', '--no-audit', '--no-fund') + await npm('install', '-w', 'docs', '--ignore-scripts', '--no-audit', '--no-fund') + + if (smokePublish) { + log.info(`Skipping git dirty check due to local smoke publish test being run`) + } else { + await git.dirty() + } + + let count = -1 + + if (smokePublish) { + // when we have a smoke test run we'd want to bump the version or else npm will throw an error even with dry-run + // this is the equivalent of running `npm version prerelease`, but ensuring all internally used workflows are bumped + for (const publish of publishes) { + const { version } = await publish.updatePkg((pkg) => ({ ...pkg, version: `${pkg.version}-smoke.0` })) + for (const ipublish of publishes) { + if (ipublish.dependencies?.[publish.name]) { + await ipublish.updatePkg((pkg) => ({ + ...pkg, + dependencies: { + ...pkg.dependencies, + [publish.name]: version, + }, + })) + } + if (ipublish.devDependencies?.[publish.name]) { + await ipublish.updatePkg((pkg) => ({ + ...pkg, + devDependencies: { + ...pkg.devDependencies, + [publish.name]: version, + }, + })) + } + } + } + await npm('install') + } + + for (const publish of publishes) { + log.info(`Publishing ${publish.name}@${publish.version} to ${publish.tag} ${count++}/${publishes.length}`) + const workspace = publish.workspace && `--workspace=${publish.name}` + const publishPkg = (...args) => npm('publish', workspace, `--tag=${publish.tag}`, ...args) + + if (hasPackDest) { + await npm( + 'pack', + workspace, + packDestination && `--pack-destination=${packDestination}` + ) + } + + if (smokePublish) { + await publishPkg('--dry-run', '--ignore-scripts') + } else { + await publishPkg( + dryRun && '--dry-run', + otp && `--otp=${otp === 'op' ? await op() : otp}` + ) + } + } +} + +run(main).catch(resetdeps) diff --git a/scripts/release-manager.js b/scripts/release-manager.js deleted file mode 100644 index 8313692adfdc4..0000000000000 --- a/scripts/release-manager.js +++ /dev/null @@ -1,248 +0,0 @@ -#!/usr/bin/env node - -const { basename, relative } = require('path') -const cp = require('child_process') - -const usage = () => ` - node ${relative(process.cwd(), __filename)} [flags] - - Copies the release process checklist to a GitHub issue, optionally updating the - version and date of the instructions. - - Flags: [--create] [--update[=]] [--date=] [--version=X.Y.Z] - - [--create] (default: true) - By default this will create a new issue in the repo. - - [--update[=]] - Update a specific issue number, or if set without a value it will update the most - recent issue created with the default tag. - - [--tag=] (default: "release-manager") - Issues will be created and looked up with this tag. - - [--version=X.Y.Z] - This script can be run before the next version number is known and then rerun - with this flag to update the checklist with the correct version number. - - [--date=] (default: ${date()}) - Set the date of the release in the release process checklist. -` - -const spawnSync = (cmd, args, options) => { - const res = cp.spawnSync(cmd, args, { ...options, encoding: 'utf-8' }) - if (res.status !== 0) { - throw new Error(res.stderr) - } - return res.stdout.trim() -} - -const get = url => - new Promise((resolve, reject) => { - require('https') - .get(url, resp => { - let d = '' - resp.on('data', c => (d += c)) - resp.on('end', () => resolve(d)) - }) - .on('error', reject) - }) - -const date = () => { - const d = new Date() - const pad = s => s.toString().padStart(2, '0') - return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` -} - -const replaceAll = (str, rep) => - Object.entries(rep).reduce( - (a, [k, v]) => a.replace(new RegExp(k, 'g'), v), - str - ) - -const ghIssue = args => { - const label = ['-l', args.label] - const assignee = ['-a', args.assignee] - const title = ['-t', args.title] - const json = ['--json', 'body,title,number'] - const body = ['--body-file', '-'] - - const issue = (cmd, a, options) => - spawnSync('gh', ['issue', cmd, '-R', args.repo, ...a.flat()], options) - - const listIssues = () => { - const issues = JSON.parse(issue('list', [label, json])) - const ids = issues.map(i => '#' + i.number) - const msg = `Found existing label:${args.label} issues: ${ids.join(', ')}.` - return { issues, msg } - } - - switch (args.command) { - case 'list': { - // get the first matching issue - const { issues, msg } = listIssues() - if (issues.length > 1) { - throw new Error(`${msg} Rerun with --update= to target a specific issue.`) - } - return issues[0] - } - case 'view': - // get an issue by id - return JSON.parse(issue('view', [args.number, json])) - case 'create': { - const { issues, msg } = listIssues() - if (issues.length) { - throw new Error(`${msg} Close before creating a new one.`) - } - // create an issue - return issue('create', [assignee, label, title, body], { input: args.body }) - } - case 'edit': - // edit title and body of an issue - return issue('edit', [args.number, title, body], { input: args.body }) - default: - throw new Error(`Unknown command: ${JSON.stringify(args.command)}`) - } -} - -const getSection = (content, args) => { - const [, heading, section] = args.section.match(/^(#+)\s(.*)/) - - // remove the title since we are making a new one - const [title, ...lines] = content - .split(`${heading} `) - .find(s => s.split('\n')[0].match(new RegExp(section, 'i'))) - .trim() - .split('\n') - - // first task is to run this script, so thats done - const body = lines.join('\n').replace('- [ ] **0', '- [x] **0') - const created = `${basename(args.release)}${heading}${title}` - - return { - title: `Release Manager: v${args.version} (${args.date})`, - body: [ - `**Target Version**: v${args.version}`, - `**Target Date**: ${args.date}`, - // github markdown: 2x backticks + space will escape backticks within title - `**Created From:** [\`\` ${created} \`\`](${args.release})`, - body, - ] - .join('\n') - .trim(), - } -} - -const main = async args => { - const replace = s => replaceAll(s, args.replacements) - - const { body, title, number } = args.create - // get a section of the release process wiki doc - ? getSection(await get(args.release), args) - // get the contents of an existing gh issue by id - // or it will default to the most recent one by label - // this is so it will preserve state of checked todo items - : await ghIssue({ - ...args, - command: typeof args.update === 'string' ? 'view' : 'list', - number: args.update, - }) - - return ghIssue({ - ...args, - command: number ? 'edit' : 'create', - number, - body: replace(body), - title: replace(title), - }) -} - -const parseArgs = raw => { - const result = { - create: false, - update: null, - repo: 'npm/cli', - label: 'release: manager', - assignee: '@me', - date: date(), - version: 'X.Y.Z', - // look for that heading level with a match for the portion after - section: '### .*cli.*', - release: - 'https://raw.githubusercontent.com/wiki/npm/cli/Release-Process-(v8).md', - } - - const replacements = {} - - const clean = { - // this script will not work correctly with the tag style - // of the version (prefixed with a v) so strip it out - version: v => v.replace(/^v/g, ''), - } - - const shorts = { - R: 'repo', - l: 'label', - a: 'assignee', - d: 'date', - v: 'version', - c: 'create', - u: 'update', - } - - const camel = k => k.replace(/-([a-z])/g, a => a[1].toUpperCase()) - - // parse argv into array of [k,v] pairs - // works with --x=1 --x 1 --x -x - const argv = raw - .join(' ') // join to a string - .split(/(?:^|\s+)-/g) // split on starting dashses - .map(x => x.trim().replace(/\s+/g, ' ')) // collapse spaces - .filter(Boolean) // remove empties - .map(x => x.split(/[=\s]/)) // split on equal or space - .map(([k, v]) => [ - // we split on the initial dash previously so now - // 1 dash means 2 and 0 means 1 - ...(k.startsWith('-') ? ['--', k.slice(1)] : ['-', k]), - v ?? true, // default to true for no value - ]) - .map(([dash, key, value]) => ({ dash, key: camel(key), value })) - - for (const { dash, key, value } of argv) { - const k = dash.length < 2 ? shorts[key] : key - if (Object.hasOwn(result, k)) { - result[k] = clean[k] ? clean[k](value) : value - } else { - // any unknown arg is a replacement value - replacements[k] = value - } - } - - if (!result.create && !result.update) { - // set default to create if no command is specified - result.create = true - } else if (result.create && result.update) { - throw new Error('Cannot set both create and update') - } - - if (result.help) { - console.error(usage()) - return process.exit(0) - } - - return { - ...result, - replacements: { - '(\\d+\\.\\d+\\.\\d+|X\\.Y\\.Z)': result.version, - '(\\d{4}-\\d{2}-\\d{2}|YYYY-MM-DD)': result.date, - ...replacements, - }, - } -} - -main(parseArgs(process.argv.slice(2))) - .then(d => console.log(d)) - .catch(err => { - console.error(err) - process.exitCode = 1 - }) diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100644 index a3c1356b002f7..0000000000000 --- a/scripts/release.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -# script for creating a zip and tarball for inclusion in node - -unset CDPATH - -set -e - -rm -rf release *.tgz || true -rm node_modules/node-gyp/gyp/pylib/gyp/__pycache__/*.pyc || true -rm node_modules/node-gyp/gyp/pylib/gyp/generator/__pycache__/*.pyc || true -mkdir release -node ./bin/npm-cli.js pack --loglevel error >/dev/null -mv *.tgz release -cd release -tar xzf *.tgz -cp ../.npmrc package/ -cp -r ../tap-snapshots package/ -cp -r ../test package/ - -mkdir node_modules -mv package node_modules/npm - -# make the zip for windows users -cp node_modules/npm/bin/*.cmd . -zipname=npm-$(node ../bin/npm-cli.js -v).zip -zip -q -9 -r -X "$zipname" *.cmd node_modules - -# make the tar for node's deps -cd node_modules -tarname=npm-$(node ../../bin/npm-cli.js -v).tgz -tar czf "$tarname" npm - -cd .. -mv "node_modules/$tarname" . - -rm -rf *.cmd -rm -rf node_modules - -cd .. - -echo "release/$tarname" -echo "release/$zipname" diff --git a/scripts/resetdeps.js b/scripts/resetdeps.js new file mode 100644 index 0000000000000..b24c83e63b019 --- /dev/null +++ b/scripts/resetdeps.js @@ -0,0 +1,27 @@ +const { join } = require('node:path') +const { symlink } = require('node:fs/promises') +const { CWD, run, pkg, fs, git, npm } = require('./util.js') + +const cleanup = async () => { + await git('checkout', 'node_modules/') + for (const { name, path } of await pkg.mapWorkspaces({ public: true })) { + // add symlinks similar to how arborist does for our production + // workspaces, so they are in place before the initial install. + await symlink(path, join(CWD, 'node_modules', name), 'junction') + } +} + +const main = async ({ packageLock }) => { + await git('status') // run ANY @npmcli/git command to instantiate its lazy loading + await fs.rimraf(join(CWD, 'node_modules')) + for (const { path } of await pkg.mapWorkspaces()) { + await fs.rimraf(join(path, 'node_modules')) + } + + await cleanup() + await npm('i', '--ignore-scripts', '--no-audit', '--no-fund', packageLock && '--package-lock') + await npm('rebuild', '--ignore-scripts') + await npm('run', 'dependencies', '--ignore-scripts') +} + +run(main).catch(cleanup) diff --git a/scripts/resetdeps.sh b/scripts/resetdeps.sh deleted file mode 100755 index 2362c2092a635..0000000000000 --- a/scripts/resetdeps.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -set -e -set -x -rm -rf node_modules -rm -rf docs/node_modules -rm -rf smoke-tests/node_modules -rm -rf "workspaces/*/node_modules" -git checkout node_modules -node . i --ignore-scripts --no-audit --no-fund -node . rebuild --ignore-scripts -node scripts/bundle-and-gitignore-deps.js diff --git a/scripts/smoke-tests.js b/scripts/smoke-tests.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/scripts/smoke-tests.sh b/scripts/smoke-tests.sh new file mode 100755 index 0000000000000..0acda09c26b38 --- /dev/null +++ b/scripts/smoke-tests.sh @@ -0,0 +1,92 @@ + #!/usr/bin/env bash + +set -eo pipefail + +IS_LOCAL="false" +IS_CI="true" + +if [ -z "$CI" ]; then + echo "Running locally will overwrite your globally installed npm." + GITHUB_SHA=$(git rev-parse HEAD) + RUNNER_TEMP=$(mktemp -d) + IS_LOCAL="true" + IS_CI="false" +fi + +if [ -z "$GITHUB_SHA" ]; then + echo "Error: GITHUB_SHA is required" + exit 1 +fi + +if [ -z "$RUNNER_TEMP" ]; then + echo "Error: RUNNER_TEMP is required" + exit 1 +fi + +ORIGINAL_GLOBAL_NPM_VERSION=$(npm --version) +if [ ${#ORIGINAL_GLOBAL_NPM_VERSION} -gt 40 ]; then + echo "Error: Global npm version already contains a git SHA ${ORIGINAL_GLOBAL_NPM_VERSION}" + exit 1 +fi + +ORIGINAL_LOCAL_NPM_VERSION=$(node . --version) +if [ ${#ORIGINAL_LOCAL_NPM_VERSION} -gt 40 ]; then + echo "Error: Local npm version already contains a git SHA ${ORIGINAL_LOCAL_NPM_VERSION}" + exit 1 +fi +NPM_VERSION="$ORIGINAL_LOCAL_NPM_VERSION-$GITHUB_SHA.0" + +# Only cleanup locally +if [ "$IS_LOCAL" == "true" ]; then + function cleanup { + npm pkg set version=$ORIGINAL_LOCAL_NPM_VERSION + node scripts/resetdeps.js + if [ "$(git rev-parse HEAD)" != "$GITHUB_SHA" ]; then + echo "===================================" + echo "===================================" + echo "HEAD is on a different commit." + echo "===================================" + echo "===================================" + fi + if [ "$(npm --version)" == "$NPM_VERSION" ]; then + echo "===================================" + echo "===================================" + echo "Global npm version has changed to $NPM_VERSION" + echo "Run the following to change it back" + echo "npm install npm@$ORIGINAL_GLOBAL_NPM_VERSION -g" + echo "===================================" + echo "===================================" + fi + } + trap cleanup EXIT +fi + +# Version the local source of npm with the current git sha and +# and pack and install it globally the same way we would if we +# were publishing it to the registry. The only difference is in the +# publish.js script which will only pack and not publish +node . version $NPM_VERSION --ignore-scripts --git-tag-version="$IS_CI" +node . pack . --pack-destination "$RUNNER_TEMP" +NPM_TARBALL="$RUNNER_TEMP/npm-$NPM_VERSION.tgz" +node . install --global $NPM_TARBALL + +# Only run the tests if we are sure we have the right version +# otherwise the tests being run are pointless +NPM_GLOBAL_VERSION="$(npm --version)" +if [ "$NPM_GLOBAL_VERSION" != "$NPM_VERSION" ]; then + echo "global npm is not the correct version for smoke-publish" + echo "found: $NPM_GLOBAL_VERSION, expected: $NPM_VERSION" + exit 1 +fi + +# Install dev deps only for smoke tests so they can be run +node . install -w smoke-tests --ignore-scripts --no-audit --no-fund +# Run smoke tests with env vars so it uses the globally installed tarball we +# just packed/installed. The tacked on args at the end are only used for +# debugging locally when we want to pass args to the smoke-tests to limit the +# files being run or grep a test, etc. Also now set CI=true so we get more +# debug output in our tap tests +CI="true" SMOKE_PUBLISH_TARBALL="$NPM_TARBALL" npm test \ + -w smoke-tests \ + --ignore-scripts \ + -- "$@" diff --git a/scripts/template-oss/_job-release-integration-yml.hbs b/scripts/template-oss/_job-release-integration-yml.hbs new file mode 100644 index 0000000000000..7d0ef9c1fa089 --- /dev/null +++ b/scripts/template-oss/_job-release-integration-yml.hbs @@ -0,0 +1,11 @@ +strategy: + fail-fast: false + matrix: + nodeVersion: + - 22 + - 23 + - nightly +uses: ./.github/workflows/node-integration.yml +with: + nodeVersion: $\{{ matrix.nodeVersion }} + npmVersion: $\{{ fromJSON(inputs.releases)[0].version }} diff --git a/scripts/template-oss/_step-deps-yml.hbs b/scripts/template-oss/_step-deps-yml.hbs new file mode 100644 index 0000000000000..c36f9a2f2fb8a --- /dev/null +++ b/scripts/template-oss/_step-deps-yml.hbs @@ -0,0 +1,4 @@ +- name: Check Git Status + run: node scripts/git-dirty.js +- name: Reset Deps + run: node scripts/resetdeps.js {{~#if jobDepFlags}} {{ jobDepFlags }}{{/if}} diff --git a/scripts/template-oss/_step-test-yml.hbs b/scripts/template-oss/_step-test-yml.hbs new file mode 100644 index 0000000000000..f25fc951350c9 --- /dev/null +++ b/scripts/template-oss/_step-test-yml.hbs @@ -0,0 +1,3 @@ +{{> defaultStepTestYml }} +- name: Check Git Status + run: node scripts/git-dirty.js diff --git a/scripts/template-oss/branch-specific-config.js b/scripts/template-oss/branch-specific-config.js new file mode 100644 index 0000000000000..3a2d749783525 --- /dev/null +++ b/scripts/template-oss/branch-specific-config.js @@ -0,0 +1,5 @@ +// Leave this empty to use the default ciVersions from template-oss +// This file is kept here to make it easier to apply template-oss +// changes to other branches which might have different ciVersions +// or other config options +module.exports = {} diff --git a/scripts/template-oss/ci-npmcli-docs-yml.hbs b/scripts/template-oss/ci-npmcli-docs-yml.hbs new file mode 100644 index 0000000000000..a5c4733e59581 --- /dev/null +++ b/scripts/template-oss/ci-npmcli-docs-yml.hbs @@ -0,0 +1,26 @@ +{{> ciYml }} + + compare-docs: + {{> jobYml + jobName="Compare Docs" + jobCheckout=(obj fetch-depth=0) + jobIf="github.event_name == 'pull_request'" + }} + - name: Build Docs + run: | + node . run build -w docs + mv man/ man-update/ + mv docs/output/ docs/output-update/ + mv docs/content/ docs/content-update/ + - name: Get Current Docs + run: | + git clean -fd + git checkout $\{{ github.event.pull_request.base.ref }} + node scripts/resetdeps.js + node . run build -w docs + - name: Diff Man + run: diff -r --color=always man/ man-update/ || true + - name: Diff HTML + run: diff -r --color=always docs/output/ docs/output-update/ || true + - name: Diff Markdown + run: diff -r --color=always docs/content/ docs/content-update/ || true diff --git a/scripts/template-oss/ci-release-yml.hbs b/scripts/template-oss/ci-release-yml.hbs new file mode 100644 index 0000000000000..6ec27f1b2e9d2 --- /dev/null +++ b/scripts/template-oss/ci-release-yml.hbs @@ -0,0 +1,45 @@ +{{> ciReleaseYml }} + + smoke-tests: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + {{> jobMatrixYml + jobName="Smoke Tests" + jobCheckout=(obj ref="${{ inputs.ref }}") + jobCreateCheck=(obj sha="${{ inputs.check-sha }}") + windowsCI=false + macCI=false + }} + - name: Smoke Tests + run: ./scripts/smoke-tests.sh + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: $\{{ secrets.GITHUB_TOKEN }} + conclusion: $\{{ job.status }} + check_id: $\{{ steps.create-check.outputs.check-id }} + + publish-dryrun: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + {{> jobMatrixYml + jobName="Publish Dry-Run" + jobCheckout=(obj ref="${{ inputs.ref }}") + jobCreateCheck=(obj sha="${{ inputs.check-sha }}") + windowsCI=false + macCI=false + }} + - name: Publish Dry-Run + run: node ./scripts/publish.js --pack-destination=$RUNNER_TEMP --smoke-publish=true + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: $\{{ secrets.GITHUB_TOKEN }} + conclusion: $\{{ job.status }} + check_id: $\{{ steps.create-check.outputs.check-id }} \ No newline at end of file diff --git a/scripts/template-oss/ci-yml.hbs b/scripts/template-oss/ci-yml.hbs new file mode 100644 index 0000000000000..386a3716deadd --- /dev/null +++ b/scripts/template-oss/ci-yml.hbs @@ -0,0 +1,71 @@ +{{> ciYml }} + + licenses: + {{> jobYml jobName="Check Licenses" }} + - name: Check Licenses + run: {{rootNpmPath}} run licenses + + smoke-tests: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + {{> jobYml + jobName="Smoke Tests" + jobCheckout=(obj ref="${{ inputs.ref }}") + jobCreateCheck=(obj sha="${{ inputs.check-sha }}") + windowsCI=false + macCI=false + }} + - name: Smoke Tests + run: ./scripts/smoke-tests.sh + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: $\{{ secrets.GITHUB_TOKEN }} + conclusion: $\{{ job.status }} + check_id: $\{{ steps.create-check.outputs.check-id }} + + publish-dryrun: + # This cant be tested on Windows because our node_modules directory + # checks in symlinks which are not supported there. This should be + # fixed somehow, because this means some forms of local development + # are likely broken on Windows as well. + {{> jobYml + jobName="Publish Dry-Run" + jobCheckout=(obj ref="${{ inputs.ref }}") + jobCreateCheck=(obj sha="${{ inputs.check-sha }}") + windowsCI=false + macCI=false + }} + - name: Publish Dry-Run + run: node ./scripts/publish.js --pack-destination=$RUNNER_TEMP --smoke-publish=true + - name: Conclude Check + uses: LouisBrunner/checks-action@v1.6.0 + if: steps.create-check.outputs.check-id && always() + with: + token: $\{{ secrets.GITHUB_TOKEN }} + conclusion: $\{{ job.status }} + check_id: $\{{ steps.create-check.outputs.check-id }} + + windows-shims: + name: Windows Shims Tests + runs-on: windows-latest + defaults: + run: + shell: cmd + steps: + {{> stepsSetupYml }} + - name: Setup WSL + uses: Vampire/setup-wsl@v2.0.1 + - name: Setup Cygwin + uses: egor-tensin/setup-cygwin@v4.0.1 + with: + install-dir: C:\cygwin64 + - name: Run Windows Shims Tests + run: {{rootNpmPath}} test --ignore-scripts -- test/bin/windows-shims.js --no-coverage + env: + WINDOWS_SHIMS_TEST: true + - name: Check Git Status + run: node scripts/git-dirty.js diff --git a/scripts/template-oss/create-node-pr-yml.hbs b/scripts/template-oss/create-node-pr-yml.hbs new file mode 100644 index 0000000000000..04d217eb9dc8e --- /dev/null +++ b/scripts/template-oss/create-node-pr-yml.hbs @@ -0,0 +1,35 @@ +name: "Create Node PR" + +on: + workflow_dispatch: + inputs: + spec: + description: "The npm spec to create the PR from" + required: true + default: 'latest' + branch: + description: "The major node version to serve as the base of the PR. Should be `main` or a number like `18`, `19`, etc." + required: true + default: 'main' + dryRun: + description: "Setting this to anything will run all the steps except opening the PR" + +permissions: + contents: write + +jobs: + create-pull-request: + {{> jobYml jobName="Create Node PR" jobCheckout=(obj fetch-depth=0) }} + - name: Checkout Node + uses: actions/checkout@v3 + with: + token: $\{{ secrets.NODE_PULL_REQUEST_TOKEN }} + repository: nodejs/node + fetch-depth: 0 + path: node + - name: Create Node Pull Request + env: + GITHUB_TOKEN: $\{{ secrets.NODE_PULL_REQUEST_TOKEN }} + run: | + DRY_RUN=$([ -z "$\{{ inputs.dryRun }}" ] && echo "" || echo "--dry-run") + node scripts/create-node-pr.js $\{{ inputs.spec }} $\{{ inputs.branch }} "$DRY_RUN" diff --git a/scripts/template-oss/index.js b/scripts/template-oss/index.js new file mode 100644 index 0000000000000..0f214723f558c --- /dev/null +++ b/scripts/template-oss/index.js @@ -0,0 +1,7 @@ +module.exports = { + ...require('./branch-specific-config.js'), + // Make workspaces use the global version of in workflows. + // This is needed while workspaces and npm have different engines. + // TODO: make npm and its workspaces always use the same engines and delete this. + npm: 'npm', +} diff --git a/scripts/template-oss/node-integration-yml.hbs b/scripts/template-oss/node-integration-yml.hbs new file mode 100644 index 0000000000000..9b4391d3991f2 --- /dev/null +++ b/scripts/template-oss/node-integration-yml.hbs @@ -0,0 +1,493 @@ +name: nodejs integration + +on: + workflow_call: + inputs: + nodeVersion: + description: 'nodejs version' + required: true + type: string + default: nightly + npmVersion: + description: 'npm version' + required: true + type: string + default: git + installFlags: + description: 'extra flags to pass to npm install' + required: false + type: string + default: '' + + workflow_dispatch: + inputs: + nodeVersion: + description: 'nodejs version' + required: true + type: string + default: nightly + npmVersion: + description: 'npm version' + required: true + type: string + default: git + installFlags: + description: 'extra flags to pass to npm install' + required: false + type: string + default: '' + +jobs: + build-nodejs: + name: build nodejs@$\{{ inputs.nodeVersion }} npm@$\{{ inputs.npmVersion }} + runs-on: ubuntu-latest + outputs: + nodeVersion: $\{{ steps.build-nodejs.outputs.nodeVersion }} + steps: + - name: setup ccache + uses: Chocobo1/setup-ccache-action@v1 + with: + override_cache_key: nodejs-$\{{ inputs.nodeVersion }} + - name: build nodejs + id: build-nodejs + run: | + echo "::group::setup" + set -eo pipefail + npmDir="${RUNNER_TEMP}/npm" + sourceDir="${RUNNER_TEMP}/src" + targetDir="${RUNNER_TEMP}/build" + npmFile="${RUNNER_TEMP}/npm.tgz" + sourceFile="${RUNNER_TEMP}/source.tgz" + targetFile="${RUNNER_TEMP}/build.tgz" + echo "::endgroup::" + + echo "::group::finding nodejs version matching $\{{ inputs.nodeVersion }}" + if [[ "$\{{ inputs.nodeVersion }}" == "nightly" ]]; then + nodeVersion=$(curl -sSL https://nodejs.org/download/nightly/index.json | jq -r .[0].version) + nodeUrl="https://nodejs.org/download/nightly/${nodeVersion}/node-${nodeVersion}.tar.gz" + else + nodeVersion=$(curl -sSL https://nodejs.org/download/release/index.json | jq -r 'map(select(.version | test("^v$\{{ inputs.nodeVersion }}"))) | .[0].version') + if [[ -z "$nodeVersion" ]]; then + echo "::error ::unable to find released nodejs version matching: $\{{ inputs.nodeVersion }}" + exit 1 + fi + nodeUrl="https://nodejs.org/download/release/${nodeVersion}/node-${nodeVersion}.tar.gz" + fi + echo "nodeVersion=${nodeVersion}" >> $GITHUB_OUTPUT + echo "::endgroup::" + + echo "::group::extracting source from $nodeUrl" + mkdir -p "$sourceDir" + curl -sSL "$nodeUrl" | tar xz -C "$sourceDir" --strip=1 + echo "::endgroup::" + + echo "::group::cloning npm" + mkdir -p "$npmDir" + git clone https://github.com/npm/cli.git "$npmDir" + npmVersion=$(cat "${npmDir}/package.json" | jq -r '"\(.version)-git"') + echo "::endgroup::" + + if [[ "$\{{ inputs.npmVersion }}" != "git" ]]; then + npmVersion="$\{{ inputs.npmVersion }}" + npmVersion="${npmVersion#v}" + echo "::group::checking out npm@${npmVersion}" + pushd "$npmDir" >/dev/null + taggedSha=$(git show-ref --tags "v${npmVersion}" | cut -d' ' -f1) + git reset --hard "$taggedSha" + publishedSha=$(curl -sSL https://registry.npmjs.org/npm | jq -r --arg ver "$npmVersion" '.versions[$ver].gitHead') + if [[ "$taggedSha" != "$publishedSha" ]]; then + echo "::warning ::git tag ($taggedSha) differs from published tag ($publishedSha)" + fi + popd >/dev/null + echo "::endgroup::" + fi + + echo "::group::packing npm release $npmVersion" + pushd "$npmDir" >/dev/null + node scripts/resetdeps.js + npmtarball="$(node . pack --loglevel=silent --json | jq -r .[0].filename)" + tar czf "$npmFile" -C "$npmDir" . + popd >/dev/null + echo "npm=$npmFile" >> $GITHUB_OUTPUT + echo "::endgroup::" + + echo "::group::updating nodejs bundled npm" + rm -rf "${sourceDir}/deps/npm" + mkdir -p "${sourceDir}/deps/npm" + tar xfz "${npmDir}/${npmtarball}" -C "${sourceDir}/deps/npm" --strip=1 + echo "::endgroup::" + + echo "::group::packing nodejs source" + tar cfz "$sourceFile" -C "$sourceDir" . + echo "source=$sourceFile" >> $GITHUB_OUTPUT + echo "::endgroup::" + + echo "::group::building nodejs" + mkdir -p "$targetDir" + pushd "$sourceDir" >/dev/null + ./configure --prefix="$targetDir" + make -j4 install + popd >/dev/null + echo "::endgroup::" + + echo "::group::packing nodejs build" + tar cfz "$targetFile" -C "$targetDir" . + echo "build=$targetFile" >> $GITHUB_OUTPUT + echo "::endgroup::" + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: nodejs-$\{{ steps.build-nodejs.outputs.nodeVersion }} + path: | + $\{{ steps.build-nodejs.outputs.source }} + $\{{ steps.build-nodejs.outputs.build }} + $\{{ steps.build-nodejs.outputs.npm }} + + test-nodejs: + name: test nodejs + runs-on: ubuntu-latest + needs: + - build-nodejs + steps: + - name: setup ccache + uses: Chocobo1/setup-ccache-action@v1 + with: + override_cache_key: nodejs-$\{{ inputs.nodeVersion }} + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: nodejs-$\{{ needs.build-nodejs.outputs.nodeVersion }} + - name: test nodejs + run: | + set -e + tar xf source.tgz + ./configure + make -j4 test-only + + test-npm: + name: test npm + runs-on: ubuntu-latest + needs: + - build-nodejs + steps: + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: nodejs-$\{{ needs.build-nodejs.outputs.nodeVersion }} + path: $\{{ runner.temp }} + - name: install nodejs $\{{ needs.build-nodejs.outputs.nodeVersion }} + id: install + run: | + set -e + mkdir -p "${RUNNER_TEMP}/node" + tar xf "${RUNNER_TEMP}/build.tgz" -C "${RUNNER_TEMP}/node" + + mkdir -p "${RUNNER_TEMP}/npm" + tar xf "${RUNNER_TEMP}/npm.tgz" -C "${RUNNER_TEMP}/npm" + + echo "${RUNNER_TEMP}/node/bin" >> $GITHUB_PATH + echo "cache=$(npm config get cache)" >> $GITHUB_OUTPUT + - name: setup npm cache + uses: actions/cache@v3 + with: + path: $\{{ steps.install.outputs.cache }} + key: npm-tests + - run: node --version + - run: npm --version + - name: test npm + run: | + echo "::group::setup" + set -e + cd "${RUNNER_TEMP}/npm" + echo "::endgroup::" + + echo "::group::npm run resetdeps" + node scripts/resetdeps.js + echo "::endgroup::" + + echo "::group::npm link" + node . link + echo "::endgroup::" + + STEPEXIT=0 + FINALEXIT=0 + + set +e + echo "::group::npm test" + node . test --ignore-scripts + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + echo "::warning ::npm test failed, exit: $STEPEXIT" + FINALEXIT=STEPEXIT + fi + echo "::endgroup::" + + for workspace in $(npm query .workspace | jq -r .[].name); do + echo "::group::npm test -w $workspace" + node . test -w $workspace --if-present --ignore-scripts + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + echo "::warning ::npm test -w $workspace failed, exit: $STEPEXIT" + FINALEXIT=STEPEXIT + fi + echo "::endgroup::" + done + + exit $FINALEXIT + + generate-matrix: + name: generate matrix + runs-on: ubuntu-latest + outputs: + matrix: $\{{ steps.generate-matrix.outputs.matrix }} + steps: + - name: install dependencies + run: | + npm install --no-save --no-audit --no-fund citgm npm-package-arg + - name: generate matrix + id: generate-matrix + uses: actions/github-script@v6 + env: + NODE_VERSION: "$\{{ inputs.nodeVersion }}" + INSTALL_FLAGS: "$\{{ inputs.installFlags }}" + with: + script: | + const { NODE_VERSION, INSTALL_FLAGS } = process.env + + const { execSync } = require('child_process') + const npa = require('npm-package-arg') + + const lookup = require('./node_modules/citgm/lib/lookup.json') + + const matchesKeyword = (value) => { + const keywords = ['ubuntu', 'debian', 'linux', 'x86', '>=11', '>=12', '>=16', '>=17'] + if (value === true || + (typeof value === 'string' && keywords.includes(value)) || + (Array.isArray(value) && keywords.some((keyword) => value.includes(keyword) || value.includes(true)))) { + return true + } + + return false + } + + // this is a manually updated list of packages that we know currently fail + const knownFailures = [ + 'body-parser', // json parsing error difference + 'clinic', // unknown, lots of failures + 'ember-cli', // timeout in nodejs ci, one failing test for us that timed out + 'express', // body-parser is what actually fails, it's used in a test + 'https-proxy-agent', // looks ssl related + 'node-gyp', // one test consistently times out + 'resolve', // compares results to require.resolve and fails, also missing inspector/promises + 'uuid', // tests that crypto.getRandomValues throws but it doesn't + 'weak', // doesn't seem to build in node >12 + 'mkdirp', // failing actions in own repo + 'undici', // test failure in node >=18, unable to root cause + ] + + if (NODE_VERSION === '18') { + knownFailures.push('multer') + } else if (NODE_VERSION === '19') { + // empty block + } else if (NODE_VERSION === 'nightly') { + // fails in node 20, looks like a streams issue + knownFailures.push('fastify') + // esbuild barfs on node 20.0.0-pre + knownFailures.push('serialport') + } + + // this is a manually updated list of packages that are flaky + const supplementalFlaky = [ + 'pino', // flaky test test/transport/core.test.js:401 + 'tough-cookie', // race condition test/node_util_fallback_test.js:87 + ] + + const matrix = [] + for (const package in lookup) { + const meta = lookup[package] + + // we omit npm from the matrix because its tests are run as their own job + if (matchesKeyword(meta.skip) || meta.yarn === true || package === 'npm') { + continue + } + + const install_flags = ['--no-audit', '--no-fund'] + if (meta.install) { + install_flags.push(meta.install.slice(1)) + } + if (INSTALL_FLAGS) { + install_flags.push(INSTALL_FLAGS) + } + const context = JSON.parse(execSync(`npm show ${package} --json`)) + const test = meta.scripts ? meta.scripts.map((script) => `npm run ${script}`) : ['npm test'] + + const repo = npa(meta.repo || context.repository.url).hosted + const details = {} + if (meta.useGitClone) { + details.repo = repo.https() + } else { + if (meta.ignoreGitHead) { + details.url = repo.tarball() + } else { + details.url = repo.tarball({ committish: context.gitHead }) + } + } + + const env = { ...meta.envVar, NODE_VERSION } + matrix.push({ + package, + version: context.version, + env, + install_flags: install_flags.join(' '), + commands: [...test], + flaky: matchesKeyword(meta.flaky) || supplementalFlaky.includes(package), + knownFailure: knownFailures.includes(package), + ...details, + }) + } + core.setOutput('matrix', matrix) + + citgm: + name: citgm - $\{{ matrix.package }}@$\{{ matrix.version }} $\{{ matrix.flaky && '(flaky)' || '' }} $\{{ matrix.knownFailure && '(known failure)' || '' }} + runs-on: ubuntu-latest + needs: + - build-nodejs + - generate-matrix + strategy: + fail-fast: false + matrix: + include: $\{{ fromJson(needs.generate-matrix.outputs.matrix) }} + steps: + - name: download artifacts + uses: actions/download-artifact@v4 + with: + name: nodejs-$\{{ needs.build-nodejs.outputs.nodeVersion }} + path: $\{{ runner.temp }} + - name: install nodejs $\{{ needs.build-nodejs.outputs.nodeVersion }} + id: install + run: | + set -e + mkdir -p "${RUNNER_TEMP}/node" + tar xf "${RUNNER_TEMP}/build.tgz" -C "${RUNNER_TEMP}/node" + echo "nodedir=${RUNNER_TEMP}/node" >> $GITHUB_OUTPUT + + echo "${RUNNER_TEMP}/node/bin" >> $GITHUB_PATH + echo "cache=$(npm config get cache)" >> $GITHUB_OUTPUT + - name: setup npm cache + uses: actions/cache@v3 + with: + path: $\{{ steps.install.outputs.cache }} + key: npm-$\{{ matrix.package }} + - run: node --version + - run: npm --version + - name: download source + id: download + run: | + set -eo pipefail + TARGET_DIR="${RUNNER_TEMP}/$\{{ matrix.package }}" + mkdir -p "$TARGET_DIR" + echo "target=$TARGET_DIR" >> $GITHUB_OUTPUT + + if [[ -n "$\{{ matrix.repo }}" ]]; then + export GIT_TERMINAL_PROMPT=0 + export GIT_SSH_COMMAND="ssh -oBatchMode=yes" + git clone --recurse-submodules "$\{{ matrix.repo }}" "$TARGET_DIR" + elif [[ -n "$\{{ matrix.url }}" ]]; then + curl -sSL "$\{{ matrix.url }}" | tar xz -C "$TARGET_DIR" --strip=1 + fi + + if [[ -f "${TARGET_DIR}/package-lock.json" ]]; then + lockfileVersion=$(cat "${TARGET_DIR}/package-lock.json" | jq .lockfileVersion) + echo "lockfileVersion=$lockfileVersion" >> $GITHUB_OUTPUT + fi + - name: npm install $\{{ matrix.install_flags }} + id: npm-install + working-directory: $\{{ steps.download.outputs.target }} + run: | + set +e + npm install --nodedir="$\{{steps.install.outputs.nodedir }}" $\{{ matrix.install_flags }} + exitcode=$? + if [[ $exitcode -ne 0 && "$\{{ matrix.knownFailure }}" == "true" ]]; then + echo "::warning ::npm install failed, exit $exitcode" + echo "failed=true" >> $GITHUB_OUTPUT + exit 0 + fi + exit $exitcode + - name: verify lockfileVersion unchanged + working-directory: $\{{ steps.download.outputs.target }} + if: $\{{ steps.download.outputs.lockfileVersion && steps.npm-install.outputs.failed != 'true' }} + run: | + if [[ -f "package-lock.json" ]]; then + newLockfileVersion=$(cat "package-lock.json" | jq .lockfileVersion) + if [[ "$newLockfileVersion" -ne "$\{{ steps.download.outputs.lockfileVersion }}" ]]; then + if [[ "$\{{ steps.download.outputs.lockfileVersion }}" -ne 1 ]]; then + echo "::error ::lockfileVersion changed from $\{{ steps.download.outputs.lockfileVersion }} to $newLockfileVersion" + exit 1 + fi + fi + fi + - name: npm ls + working-directory: $\{{ steps.download.outputs.target }} + if: $\{{ steps.npm-install.outputs.failed != 'true' }} + run: | + npm ls + - name: $\{{ join(matrix.commands, ' && ') }} + id: command + continue-on-error: true + timeout-minutes: 10 + env: $\{{ matrix.env }} + working-directory: $\{{ steps.download.outputs.target }} + if: $\{{ steps.npm-install.outputs.failed != 'true' }} + run: | + set +e + FINALEXIT=0 + STEPEXIT=0 + + export npm_config_nodedir="$\{{ steps.install.outputs.nodedir }}" + + # inlining some patches to make tests run + if [[ "$\{{ matrix.package }}" == "undici" ]]; then + sed -i.bak 's/--experimental-wasm-simd //' package.json + rm -f package.json.bak + sed -i.bak 's/--experimental-wasm-simd//' .taprc + rm -f .taprc.bak + fi + + for row in $(echo '$\{{ toJSON(matrix.commands) }}' | jq -r '.[] | @base64'); do + FAILCOUNT=0 + COMMAND=$(echo "$row" | base64 --decode) + echo "::group::$COMMAND" + $COMMAND + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + FAILCOUNT=1 + if [[ "$\{{ matrix.knownFailure }}" == "true" || "$NODE_VERSION" == "nightly" ]]; then + echo "::warning ::$COMMAND failed, exit: $STEPEXIT" + elif [[ "$\{{ matrix.flaky }}" ]]; then + while [[ $STEPEXIT -ne 0 && $FAILCOUNT -lt 3 ]]; do + $COMMAND + STEPEXIT=$? + if [[ $STEPEXIT -ne 0 ]]; then + ((FAILCOUNT=FAILCOUNT+1)) + fi + done + + if [[ $STEPEXIT -ne 0 ]]; then + echo "::warning ::$COMMAND still failing after $FAILCOUNT attempts, exit: $STEPEXIT" + fi + else + FINALEXIT=$STEPEXIT + echo "::error ::$COMMAND failed, exit: $STEPEXIT" + fi + fi + echo "::endgroup::" + done + exit $FINALEXIT + - name: Set conclusion + env: $\{{ matrix.env }} + run: | + EXIT=1 + if [[ "$\{{ steps.command.outcome }}" == "success" || "$\{{ matrix.flaky }}" == "true" || "$\{{ matrix.knownFailure }}" == "true" || $NODE_VERSION == "nightly" ]]; then + EXIT=0 + fi + exit $EXIT diff --git a/scripts/template-oss/package-json.hbs b/scripts/template-oss/package-json.hbs new file mode 100644 index 0000000000000..51e2692df449f --- /dev/null +++ b/scripts/template-oss/package-json.hbs @@ -0,0 +1,14 @@ +{ + "engines": { + "node": + {{! Set the CLI and private workspaces to the same version }} + {{~#if isRoot~}} + "^20.17.0 || >=22.9.0" + {{~else~}}{{~#if isPrivate~}} + "^20.17.0 || >=22.9.0" + {{~else~}} + {{! All public workspaces get this version }} + "^20.17.0 || >=22.9.0" + {{~/if~}}{{~/if~}} + } +} diff --git a/scripts/template-oss/release-please-config-json.hbs b/scripts/template-oss/release-please-config-json.hbs new file mode 100644 index 0000000000000..d3b59ea7227cd --- /dev/null +++ b/scripts/template-oss/release-please-config-json.hbs @@ -0,0 +1,14 @@ +{ + "packages": { + "{{ pkgPath }}": { + {{#if isRoot}} + "exclude-paths": [ + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces" + ] + {{/if}} + } + } +} diff --git a/scripts/template-oss/root.js b/scripts/template-oss/root.js new file mode 100644 index 0000000000000..58a8c66e077e8 --- /dev/null +++ b/scripts/template-oss/root.js @@ -0,0 +1,76 @@ +const releasePleaseConfig = { + 'release-please-config.json': { + file: 'release-please-config-json.hbs', + overwrite: false, + filter: (p) => p.config.isPublic, + parser: (p) => p.JsonMergeNoComment, + }, +} + +module.exports = { + rootModule: { + add: { + 'CONTRIBUTING.md': false, + 'package.json': { file: 'package-json.hbs', overwrite: false }, + }, + }, + rootRepo: { + add: { + '.github/ISSUE_TEMPLATE/bug.yml': false, + '.github/ISSUE_TEMPLATE/config.yml': false, + '.github/dependabot.yml': false, + '.github/settings.yml': false, + '.github/workflows/post-dependabot.yml': false, + '.github/workflows/ci-release.yml': 'ci-release-yml.hbs', + '.github/workflows/ci.yml': 'ci-yml.hbs', + '.github/workflows/create-node-pr.yml': 'create-node-pr-yml.hbs', + '.github/workflows/node-integration.yml': 'node-integration-yml.hbs', + ...releasePleaseConfig, + }, + }, + workspaceRepo: { + add: { + '.github/dependabot.yml': false, + '.github/settings.yml': false, + '.github/workflows/ci-release.yml': false, + '.github/workflows/post-dependabot.yml': false, + '.github/workflows/release.yml': false, + '.github/workflows/pull-request.yml': false, + ...releasePleaseConfig, + }, + }, + workspaceModule: { + add: { + 'package.json': { file: 'package-json.hbs', overwrite: false }, + }, + }, + lockfile: true, + npm: '.', + defaultBranch: 'latest', + distPaths: [ + 'index.js', + 'docs/content/', + 'docs/output/', + 'man/', + ], + allowDistPaths: false, + allowPaths: [ + '/bin/', + '/lib/', + '/node_modules/', + '/index.js', + '/DEPENDENCIES.md', + '/DEPENDENCIES.json', + '/CONTRIBUTING.md', + '/configure', + '/AUTHORS', + '/.mailmap', + '/.licensee.json', + '/.gitattributes', + ], + ignorePaths: [ + '/node_modules/.bin/', + '/node_modules/.cache/', + ], + ...require('./branch-specific-config.js'), +} diff --git a/scripts/update-authors.js b/scripts/update-authors.js new file mode 100644 index 0000000000000..ca139ca8b59b8 --- /dev/null +++ b/scripts/update-authors.js @@ -0,0 +1,27 @@ +const { join } = require('node:path') +const { CWD, run, git, fs, EOL } = require('./util.js') + +const main = async () => { + const allAuthors = await git('log', '--use-mailmap', '--reverse', '--format=%aN <%aE>', { + lines: true, + quiet: true, + }) + + const authors = new Set() + for (const author of allAuthors) { + if ( + !author.includes('[bot]') && + !author.startsWith('npm team') && + !author.startsWith('npm CLI robot') + ) { + authors.add(author) + } + } + + return fs.writeFile(join(CWD, 'AUTHORS'), [ + `# Authors sorted by whether or not they're me`, + ...authors, + ].join(EOL)) +} + +run(main) diff --git a/scripts/update-authors.sh b/scripts/update-authors.sh deleted file mode 100755 index a9c9a665ab5dc..0000000000000 --- a/scripts/update-authors.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -git log --use-mailmap --reverse --format='%aN <%aE>' | grep -v -e "\[bot\]" -e "^npm team" -e "^npm CLI robot" | perl -wnE ' -BEGIN { - say "# Authors sorted by whether or not they\x27re me"; -} - -print $seen{$_} = $_ unless $seen{$_} -' > AUTHORS diff --git a/scripts/update-cli-repos.js b/scripts/update-cli-repos.js new file mode 100644 index 0000000000000..a2bdb0efadf70 --- /dev/null +++ b/scripts/update-cli-repos.js @@ -0,0 +1,28 @@ +const { join } = require('node:path') +const { fs, gh, run } = require('./util.js') + +const query = ` +query { + search (query: "org:npm topic:npm-cli fork:true archived:false", type: REPOSITORY, first: 100) { + nodes { + ... on Repository { + name + } + } + } +} +` + +const main = async () => { + const result = await gh('api', 'graphql', '-f', `query=${query}`, { stdio: 'pipe' }) + if (result.code !== 0) { + throw new Error(result.stderr) + } + + const repoList = JSON.parse(result.stdout) + const sortedRepoList = repoList.data.search.nodes.map((node) => node.name).sort() + + return fs.writeFile(join(__dirname, 'npm-cli-repos.txt'), sortedRepoList.join('\n')) +} + +run(main) diff --git a/scripts/util.js b/scripts/util.js new file mode 100644 index 0000000000000..838bac5a6bd3f --- /dev/null +++ b/scripts/util.js @@ -0,0 +1,218 @@ +const fsp = require('node:fs/promises') +const { resolve, join, relative } = require('node:path') +const { formatWithOptions } = require('node:util') +const { log } = require('proc-log') +const nopt = require('nopt') +const npmGit = require('@npmcli/git') +const promiseSpawn = require('@npmcli/promise-spawn') +const mapWorkspaces = require('@npmcli/map-workspaces') + +// always use LF newlines for generated files. these files +// are also set to use LF line endings in .gitattributes +const EOL = '\n' +const CWD = resolve(__dirname, '..') + +const rootPkgPath = join(CWD, 'package.json') +const pkg = require(join(CWD, 'package.json')) +pkg.mapWorkspaces = async ({ public = false } = {}) => { + const ws = [] + for (const [name, path] of await mapWorkspaces({ pkg })) { + const pkgPath = join(path, 'package.json') + const pkgJson = require(pkgPath) + + if (public && pkgJson.private) { + continue + } + + ws.push({ name, path, pkgPath, pkg: pkgJson }) + } + return ws +} + +const fs = { + rimraf: (p) => fsp.rm(p, { recursive: true, force: true }), + mkdirp: (p) => fsp.mkdir(p, { recursive: true }), + clean: (p) => fs.rimraf(p).then(() => fs.mkdirp(p)), + rmAll: (p) => Promise.all(p.map(fs.rimraf)), + writeFile: async (p, d) => { + await fsp.writeFile(p, d.trim() + EOL, 'utf-8') + return `Wrote to ${relative(CWD, p)}` + }, +} + +// for spawn, allow a flat array of arguments where the +// the last arg can optionally be an options object +const getArgs = (allArgs) => { + let args = allArgs.flat().filter(Boolean) + let opts = {} + + const last = args[args.length - 1] + if (typeof last === 'object') { + args = args.slice(0, -1) + opts = last + } + + return { args, opts } +} + +const spawn = async (cmd, ...allArgs) => { + const { + args, + opts: { ok, input, out, lines, quiet, env, ...opts }, + } = getArgs(allArgs) + + log.info('spawn', `${cmd} ${args.join(' ')}`) + + let res = null + try { + const spawnOpts = { + stdio: quiet || out || lines ? 'pipe' : 'inherit', + cwd: CWD, + env: { ...process.env, ...env }, + ...opts, + } + const proc = cmd === 'git' ? npmGit.spawn(args, spawnOpts) : promiseSpawn(cmd, args, spawnOpts) + if (input && proc.stdin) { + log.silly('input', input) + proc.stdin.write(input) + proc.stdin.end() + } + res = await proc + } catch (err) { + if (!ok) { + throw err + } + log.silly('suppressed error', err) + } + + if (res?.stdout) { + res.stdout = res.stdout.toString().trim() + if (res.stdout && !quiet) { + log.silly('stdout', res.stdout) + } + } + + if (res?.stderr) { + res.stderr = res.stderr.toString().trim() + if (res.stderr) { + log.silly('stderr', res.stderr) + } + } + + if (lines) { + return (res?.stdout || '') + .split('\n') + .map(l => l.trim()) + .filter(Boolean) + } + + if (out) { + return res?.stdout || '' + } + + return res +} + +// allows for creating spawn functions with a prefilled +// command and checking if the last arg is an options obj +spawn.create = (cmd, ...prefillArgs) => (...cmdArgs) => { + const prefill = getArgs(prefillArgs) + const command = getArgs(cmdArgs) + return spawn( + cmd, + [...prefill.args, ...command.args], + { ...prefill.opts, ...command.opts } + ) +} + +const npm = spawn.create('node', '.') +npm.query = (...args) => npm('query', ...args, { out: true }).then(JSON.parse) + +const git = spawn.create('git') +git.dirty = () => npmGit.isClean({ cwd: CWD }).then(async r => { + if (r) { + return 'git clean' + } + await git('status', '--porcelain=v1', '-uno') + await git('--no-pager', 'diff') + throw new Error('git dirty') +}) + +const gh = spawn.create('gh') +gh.json = async (..._args) => { + const { args, opts } = getArgs(_args) + const keys = args.pop() + let data = await gh(...args, '--json', keys, { ...opts, out: true }).then(JSON.parse) + if (keys.split(',').length === 1) { + data = data[keys] + } + return data +} + +const run = async (main, { redact } = {}) => { + const argv = {} + for (const [k, v] of Object.entries(nopt({}, {}, process.argv))) { + argv[k] = v + // create camelcase key too + argv[k.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] = v + } + + const defaultLevels = ['error', 'warn', 'info'] + process.on('log', (l, ...args) => { + if (argv.debug || process.env.CI || defaultLevels.includes(l)) { + for (const line of formatWithOptions({ colors: true }, ...args).split('\n')) { + const redacted = redact ? line.replaceAll(redact, '***') : line + // eslint-disable-next-line no-console + console.error(l.slice(0, 4).toUpperCase(), redacted) + } + } + }) + + log.silly('argv', argv) + + try { + const res = await main(argv) + if (res) { + // eslint-disable-next-line no-console + console.log(res) + } + } catch (err) { + process.exitCode = err.status || 1 + + const messages = [] + if (err.args) { + // its an error from promise-spawn + for (const [name, value] of Object.entries(err)) { + if (value) { + let msg = Array.isArray(value) ? value.join(' ') : value.toString() + let sep = ' ' + if (msg.includes('\n')) { + msg = ' ' + msg.split('\n').map(l => l.trim()).join('\n ').trim() + sep = '\n' + } + messages.push(`${name}:${sep}${msg}`) + } + // delete from error object so we can log them separately + delete err[name] + } + } + + log.error(err) + if (messages.length) { + log.error(messages.join('\n')) + } + } +} + +module.exports = { + CWD, + pkg, + pkgPath: rootPkgPath, + run, + fs, + spawn, + gh, + npm, + git, + EOL, +} diff --git a/smoke-tests/.eslintrc.js b/smoke-tests/.eslintrc.js index 5db9f815536f1..f21d26eccec7d 100644 --- a/smoke-tests/.eslintrc.js +++ b/smoke-tests/.eslintrc.js @@ -10,6 +10,9 @@ const localConfigs = readdir(__dirname) module.exports = { root: true, + ignorePatterns: [ + 'tap-testdir*/', + ], extends: [ '@npmcli', ...localConfigs, diff --git a/smoke-tests/.gitignore b/smoke-tests/.gitignore index 617e50ca05288..08e5141aa731c 100644 --- a/smoke-tests/.gitignore +++ b/smoke-tests/.gitignore @@ -3,19 +3,21 @@ # ignore everything in the root /* -# keep these -!/.eslintrc.local.* !**/.gitignore -!/docs/ -!/tap-snapshots/ -!/test/ -!/map.js -!/scripts/ -!/README* -!/LICENSE* -!/CHANGELOG* +!/.eslint.config.js !/.eslintrc.js +!/.eslintrc.local.* +!/.git-blame-ignore-revs !/.gitignore !/bin/ +!/CHANGELOG* +!/docs/ !/lib/ +!/LICENSE* +!/map.js !/package.json +!/README* +!/scripts/ +!/tap-snapshots/ +!/test/ +tap-testdir*/ diff --git a/smoke-tests/package.json b/smoke-tests/package.json index b06404681e347..02e7f5e1f988e 100644 --- a/smoke-tests/package.json +++ b/smoke-tests/package.json @@ -1,50 +1,55 @@ { - "name": "smoke-tests", + "name": "@npmcli/smoke-tests", "description": "The npm cli smoke tests", - "version": "1.0.0", + "version": "1.0.1", "private": true, "scripts": { - "lint": "eslint \"**/*.js\"", + "lint": "npm run eslint", "postlint": "template-oss-check", "template-oss-apply": "template-oss-apply --force", - "lintfix": "npm run lint -- --fix", - "preversion": "npm test", - "postversion": "git push origin --follow-tags", + "lintfix": "npm run eslint -- --fix", "snap": "tap", "test": "tap", - "posttest": "npm run lint" + "posttest": "npm run lint", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" }, "repository": { "type": "git", - "url": "https://github.com/npm/cli.git", + "url": "git+https://github.com/npm/cli.git", "directory": "smoke-tests" }, "devDependencies": { - "@npmcli/eslint-config": "^3.0.1", - "@npmcli/promise-spawn": "^3.0.0", - "@npmcli/template-oss": "3.5.0", - "minify-registry-metadata": "^2.2.0", - "rimraf": "^3.0.2", - "tap": "^16.0.1", - "which": "^2.0.2" + "@npmcli/eslint-config": "^5.0.1", + "@npmcli/mock-registry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/template-oss": "4.25.1", + "proxy": "^2.1.1", + "rimraf": "^6.0.1", + "tap": "^16.3.8", + "which": "^6.0.0" }, "author": "GitHub Inc.", "license": "ISC", "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "3.5.0", - "workspaceRepo": false + "version": "4.25.1", + "content": "../scripts/template-oss/index.js" }, "tap": { "no-coverage": true, - "timeout": 300, - "files": "test/index.js" + "timeout": 600, + "jobs": 1, + "test-ignore": "fixtures/*", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] }, "files": [ "bin/", "lib/" ], "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^20.17.0 || >=22.9.0" } } diff --git a/smoke-tests/tap-snapshots/test/index.js.test.cjs b/smoke-tests/tap-snapshots/test/index.js.test.cjs index 68145ce52b12e..1e29ff05185d1 100644 --- a/smoke-tests/tap-snapshots/test/index.js.test.cjs +++ b/smoke-tests/tap-snapshots/test/index.js.test.cjs @@ -5,7 +5,7 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/index.js TAP npm (no args) > should have expected no args output 1`] = ` +exports[`test/index.js TAP basic npm (no args) > should have expected no args output 1`] = ` npm Usage: @@ -21,329 +21,91 @@ npm help npm more involved overview All commands: - access, adduser, audit, bin, bugs, cache, ci, completion, + access, adduser, audit, bugs, cache, ci, completion, config, dedupe, deprecate, diff, dist-tag, docs, doctor, edit, exec, explain, explore, find-dupes, fund, get, help, - 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, search, set, set-script, - shrinkwrap, star, stars, start, stop, team, test, token, + help-search, 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, sbom, search, set, shrinkwrap, + star, stars, start, stop, team, test, token, undeprecate, uninstall, unpublish, unstar, update, version, view, whoami Specify configs in the ini-formatted file: - {CWD}/smoke-tests/test/tap-testdir-index/.npmrc + {NPM}/{TESTDIR}/home/.npmrc or on the command line via: npm --key=value More configuration info: npm help config Configuration fields: npm help 7 config -npm {CWD} - +npm {NPM} ` -exports[`test/index.js TAP npm ci > should throw mismatch deps in lock file error 1`] = ` -npm ERR! code EUSAGE -npm ERR! -npm ERR! \`npm ci\` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with \`npm install\` before continuing. -npm ERR! -npm ERR! Invalid: lock file's abbrev@1.0.4 does not satisfy abbrev@1.1.1 -npm ERR! -npm ERR! Clean install a project -npm ERR! -npm ERR! Usage: -npm ERR! npm ci -npm ERR! -npm ERR! Options: -npm ERR! [-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -npm ERR! [-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -npm ERR! [--omit [--omit ...]] -npm ERR! [--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -npm ERR! [--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -npm ERR! [-w|--workspace [-w|--workspace ...]] -npm ERR! [-ws|--workspaces] [--include-workspace-root] [--install-links] -npm ERR! -npm ERR! aliases: clean-install, ic, install-clean, isntall-clean -npm ERR! -npm ERR! Run "npm help ci" for more info - -npm ERR! A complete log of this run can be found in: - - +exports[`test/index.js TAP basic npm ci > should throw mismatch deps in lock file error 1`] = ` +npm error code EUSAGE +npm error +npm error \`npm ci\` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with \`npm install\` before continuing. +npm error +npm error Invalid: lock file's abbrev@1.0.4 does not satisfy abbrev@1.1.1 +npm error +npm error Clean install a project +npm error +npm error Usage: +npm error npm ci +npm error +npm error Options: +npm error [--install-strategy ] [--legacy-bundling] +npm error [--global-style] [--omit [--omit ...]] +npm error [--include [--include ...]] +npm error [--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] +npm error [--allow-git ] [--no-audit] [--no-bin-links] [--no-fund] +npm error [--dry-run] +npm error [-w|--workspace [-w|--workspace ...]] +npm error [--workspaces] [--include-workspace-root] [--install-links] +npm error +npm error aliases: clean-install, ic, install-clean, isntall-clean +npm error +npm error Run "npm help ci" for more info +npm error A complete log of this run can be found in: {NPM}/{TESTDIR}/cache/_logs/{LOG} ` -exports[`test/index.js TAP npm diff > should have expected diff output 1`] = ` +exports[`test/index.js TAP basic npm diff > should have expected diff output 1`] = ` +diff --git a/index.js b/index.js +index v1.0.4..v1.1.1 100644 +--- a/index.js ++++ b/index.js +@@ -1,1 +1,1 @@ +-module.exports = "1.0.4" +/ No newline at end of file ++module.exports = "1.1.1" +/ No newline at end of file diff --git a/package.json b/package.json index v1.0.4..v1.1.1 100644 --- a/package.json +++ b/package.json -@@ -1,15 +1,21 @@ +@@ -1,4 +1,4 @@ { "name": "abbrev", -- "version": "1.0.4", -+ "version": "1.1.1", - "description": "Like ruby's abbrev module, but in js", - "author": "Isaac Z. Schlueter ", -- "main": "./lib/abbrev.js", -+ "main": "abbrev.js", - "scripts": { -- "test": "node lib/abbrev.js" -+ "test": "tap test.js --100", -+ "preversion": "npm test", -+ "postversion": "npm publish", -+ "postpublish": "git push origin --all; git push origin --tags" - }, - "repository": "http://github.com/isaacs/abbrev-js", -- "license": { -- "type": "MIT", -- "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE" -- } -+ "license": "ISC", -+ "devDependencies": { -+ "tap": "^10.1" -+ }, -+ "files": [ -+ "abbrev.js" -+ ] +- "version": "1.0.4" ++ "version": "1.1.1" } -diff --git a/LICENSE b/LICENSE -index v1.0.4..v1.1.1 100644 ---- a/LICENSE -+++ b/LICENSE -@@ -1,4 +1,27 @@ --Copyright 2009, 2010, 2011 Isaac Z. Schlueter. -+This software is dual-licensed under the ISC and MIT licenses. -+You may use this software under EITHER of the following licenses. -+ -+---------- -+ -+The ISC License -+ -+Copyright (c) Isaac Z. Schlueter and Contributors -+ -+Permission to use, copy, modify, and/or distribute this software for any -+purpose with or without fee is hereby granted, provided that the above -+copyright notice and this permission notice appear in all copies. -+ -+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ -+---------- -+ -+Copyright Isaac Z. Schlueter and Contributors - All rights reserved. - - Permission is hereby granted, free of charge, to any person -diff --git a/lib/abbrev.js b/lib/abbrev.js -deleted file mode 100644 -index v1.0.4..v1.1.1 ---- a/lib/abbrev.js -+++ b/lib/abbrev.js -@@ -1,111 +0,0 @@ -- --module.exports = exports = abbrev.abbrev = abbrev -- --abbrev.monkeyPatch = monkeyPatch -- --function monkeyPatch () { -- Object.defineProperty(Array.prototype, 'abbrev', { -- value: function () { return abbrev(this) }, -- enumerable: false, configurable: true, writable: true -- }) -- -- Object.defineProperty(Object.prototype, 'abbrev', { -- value: function () { return abbrev(Object.keys(this)) }, -- enumerable: false, configurable: true, writable: true -- }) --} -- --function abbrev (list) { -- if (arguments.length !== 1 || !Array.isArray(list)) { -- list = Array.prototype.slice.call(arguments, 0) -- } -- for (var i = 0, l = list.length, args = [] ; i < l ; i ++) { -- args[i] = typeof list[i] === "string" ? list[i] : String(list[i]) -- } -- -- // sort them lexicographically, so that they're next to their nearest kin -- args = args.sort(lexSort) -- -- // walk through each, seeing how much it has in common with the next and previous -- var abbrevs = {} -- , prev = "" -- for (var i = 0, l = args.length ; i < l ; i ++) { -- var current = args[i] -- , next = args[i + 1] || "" -- , nextMatches = true -- , prevMatches = true -- if (current === next) continue -- for (var j = 0, cl = current.length ; j < cl ; j ++) { -- var curChar = current.charAt(j) -- nextMatches = nextMatches && curChar === next.charAt(j) -- prevMatches = prevMatches && curChar === prev.charAt(j) -- if (!nextMatches && !prevMatches) { -- j ++ -- break -- } -- } -- prev = current -- if (j === cl) { -- abbrevs[current] = current -- continue -- } -- for (var a = current.substr(0, j) ; j <= cl ; j ++) { -- abbrevs[a] = current -- a += current.charAt(j) -- } -- } -- return abbrevs --} -- --function lexSort (a, b) { -- return a === b ? 0 : a > b ? 1 : -1 --} -- -- --// tests --if (module === require.main) { -- --var assert = require("assert") --var util = require("util") -- --console.log("running tests") --function test (list, expect) { -- var actual = abbrev(list) -- assert.deepEqual(actual, expect, -- "abbrev("+util.inspect(list)+") === " + util.inspect(expect) + "/n"+ -- "actual: "+util.inspect(actual)) -- actual = abbrev.apply(exports, list) -- assert.deepEqual(abbrev.apply(exports, list), expect, -- "abbrev("+list.map(JSON.stringify).join(",")+") === " + util.inspect(expect) + "/n"+ -- "actual: "+util.inspect(actual)) --} -- --test([ "ruby", "ruby", "rules", "rules", "rules" ], --{ rub: 'ruby' --, ruby: 'ruby' --, rul: 'rules' --, rule: 'rules' --, rules: 'rules' --}) --test(["fool", "foom", "pool", "pope"], --{ fool: 'fool' --, foom: 'foom' --, poo: 'pool' --, pool: 'pool' --, pop: 'pope' --, pope: 'pope' --}) --test(["a", "ab", "abc", "abcd", "abcde", "acde"], --{ a: 'a' --, ab: 'ab' --, abc: 'abc' --, abcd: 'abcd' --, abcde: 'abcde' --, ac: 'acde' --, acd: 'acde' --, acde: 'acde' --}) -- --console.log("pass") -- --} / No newline at end of file -diff --git a/abbrev.js b/abbrev.js -new file mode 100644 -index v1.0.4..v1.1.1 ---- a/abbrev.js -+++ b/abbrev.js -@@ -0,0 +1,61 @@ -+module.exports = exports = abbrev.abbrev = abbrev -+ -+abbrev.monkeyPatch = monkeyPatch -+ -+function monkeyPatch () { -+ Object.defineProperty(Array.prototype, 'abbrev', { -+ value: function () { return abbrev(this) }, -+ enumerable: false, configurable: true, writable: true -+ }) -+ -+ Object.defineProperty(Object.prototype, 'abbrev', { -+ value: function () { return abbrev(Object.keys(this)) }, -+ enumerable: false, configurable: true, writable: true -+ }) -+} -+ -+function abbrev (list) { -+ if (arguments.length !== 1 || !Array.isArray(list)) { -+ list = Array.prototype.slice.call(arguments, 0) -+ } -+ for (var i = 0, l = list.length, args = [] ; i < l ; i ++) { -+ args[i] = typeof list[i] === "string" ? list[i] : String(list[i]) -+ } -+ -+ // sort them lexicographically, so that they're next to their nearest kin -+ args = args.sort(lexSort) -+ -+ // walk through each, seeing how much it has in common with the next and previous -+ var abbrevs = {} -+ , prev = "" -+ for (var i = 0, l = args.length ; i < l ; i ++) { -+ var current = args[i] -+ , next = args[i + 1] || "" -+ , nextMatches = true -+ , prevMatches = true -+ if (current === next) continue -+ for (var j = 0, cl = current.length ; j < cl ; j ++) { -+ var curChar = current.charAt(j) -+ nextMatches = nextMatches && curChar === next.charAt(j) -+ prevMatches = prevMatches && curChar === prev.charAt(j) -+ if (!nextMatches && !prevMatches) { -+ j ++ -+ break -+ } -+ } -+ prev = current -+ if (j === cl) { -+ abbrevs[current] = current -+ continue -+ } -+ for (var a = current.substr(0, j) ; j <= cl ; j ++) { -+ abbrevs[a] = current -+ a += current.charAt(j) -+ } -+ } -+ return abbrevs -+} -+ -+function lexSort (a, b) { -+ return a === b ? 0 : a > b ? 1 : -1 -+} - ` -exports[`test/index.js TAP npm explain > should have expected explain output 1`] = ` +exports[`test/index.js TAP basic npm explain > should have expected explain output 1`] = ` abbrev@1.0.4 node_modules/abbrev abbrev@"^1.0.4" from the root project - ` -exports[`test/index.js TAP npm fund > should have expected fund output 1`] = ` +exports[`test/index.js TAP basic npm fund > should have expected fund output 1`] = ` project@1.0.0 -\`-- https://github.com/sponsors/isaacs - \`-- promise-all-reject-late@1.0.1 - - +\`-- https://github.com/sponsors + \`-- promise-all-reject-late@5.0.0 ` -exports[`test/index.js TAP npm init > should have successful npm init result 1`] = ` -Wrote to {CWD}/smoke-tests/test/tap-testdir-index/project/package.json: +exports[`test/index.js TAP basic npm init > should have successful npm init result 1`] = ` +Wrote to {NPM}/{TESTDIR}/project/package.json: { "name": "project", @@ -355,229 +117,194 @@ Wrote to {CWD}/smoke-tests/test/tap-testdir-index/project/package.json: }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "type": "commonjs" } - - - ` -exports[`test/index.js TAP npm install dev dep > should have expected dev dep added lockfile result 1`] = ` -{ +exports[`test/index.js TAP basic npm install dev dep > should have expected dev dep added lockfile result 1`] = ` +Object { + "lockfileVersion": 3, "name": "project", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { + "packages": Object { + "": Object { + "dependencies": Object { + "abbrev": "^1.0.4", + }, + "devDependencies": Object { + "promise-all-reject-late": "^5.0.0", + }, + "license": "ISC", "name": "project", "version": "1.0.0", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - }, - "devDependencies": { - "promise-all-reject-late": "^1.0.1" - } }, - "node_modules/abbrev": { + "node_modules/abbrev": Object { + "resolved": "{REGISTRY}/abbrev/-/abbrev-1.0.4.tgz", "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", - "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" }, - "node_modules/promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "node_modules/promise-all-reject-late": Object { "dev": true, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - } - }, - "dependencies": { - "abbrev": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", - "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" + "funding": Object { + "url": "https://github.com/sponsors", + }, + "resolved": "{REGISTRY}/promise-all-reject-late/-/promise-all-reject-late-5.0.0.tgz", + "version": "5.0.0", }, - "promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "dev": true - } - } + }, + "requires": true, + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm install dev dep > should have expected dev dep added package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm install dev dep > should have expected dev dep added package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", - "main": "index.js", - "scripts": { - "test": "echo /"Error: no test specified/" && exit 1" + "devDependencies": Object { + "promise-all-reject-late": "^5.0.0", }, - "keywords": [], - "author": "", + "keywords": Array [], "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" + "main": "index.js", + "name": "project", + "scripts": Object { + "test": "echo /"Error: no test specified/" && exit 1", }, - "devDependencies": { - "promise-all-reject-late": "^1.0.1" - } + "type": "commonjs", + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm install dev dep > should have expected dev dep added reify output 1`] = ` - -added 1 package +exports[`test/index.js TAP basic npm install dev dep > should have expected dev dep added reify output 1`] = ` +added 1 package in {TIME} 1 package is looking for funding run \`npm fund\` for details - ` -exports[`test/index.js TAP npm install prodDep@version > should have expected install reify output 1`] = ` - -added 1 package - +exports[`test/index.js TAP basic npm install prodDep@version > should have expected install reify output 1`] = ` +added 1 package in {TIME} ` -exports[`test/index.js TAP npm install prodDep@version > should have expected lockfile result 1`] = ` -{ +exports[`test/index.js TAP basic npm install prodDep@version > should have expected lockfile result 1`] = ` +Object { + "lockfileVersion": 3, "name": "project", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { + "packages": Object { + "": Object { + "dependencies": Object { + "abbrev": "^1.0.4", + }, + "license": "ISC", "name": "project", "version": "1.0.0", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - } }, - "node_modules/abbrev": { + "node_modules/abbrev": Object { + "resolved": "{REGISTRY}/abbrev/-/abbrev-1.0.4.tgz", "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", - "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" - } + }, }, - "dependencies": { - "abbrev": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz", - "integrity": "sha1-vVWuXkE7oXIu5Mq6H26hBBSlns0=" - } - } + "requires": true, + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm install prodDep@version > should have expected package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm install prodDep@version > should have expected package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", + "keywords": Array [], + "license": "ISC", "main": "index.js", - "scripts": { - "test": "echo /"Error: no test specified/" && exit 1" + "name": "project", + "scripts": Object { + "test": "echo /"Error: no test specified/" && exit 1", }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - } + "type": "commonjs", + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm ls > should have expected ls output 1`] = ` -project@1.0.0 {CWD}/smoke-tests/test/tap-testdir-index/project +exports[`test/index.js TAP basic npm ls > should have expected ls output 1`] = ` +project@1.0.0 {NPM}/{TESTDIR}/project +-- abbrev@1.0.4 -\`-- promise-all-reject-late@1.0.1 - - +\`-- promise-all-reject-late@5.0.0 ` -exports[`test/index.js TAP npm outdated > should have expected outdated output 1`] = ` +exports[`test/index.js TAP basic npm outdated > should have expected outdated output 1`] = ` Package Current Wanted Latest Location Depended by abbrev 1.0.4 1.1.1 1.1.1 node_modules/abbrev project - ` -exports[`test/index.js TAP npm pkg > should have expected npm pkg delete modified package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm pkg > should have expected npm pkg delete modified package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", + "keywords": Array [], + "license": "ISC", "main": "index.js", - "scripts": { + "name": "project", + "scripts": Object { + "hello": "echo Hello", "test": "echo /"Error: no test specified/" && exit 1", - "hello": "echo Hello" }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - } + "type": "commonjs", + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm pkg > should have expected npm pkg set modified package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm pkg > should have expected npm pkg set modified package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", + "keywords": Array [], + "license": "ISC", "main": "index.js", - "scripts": { + "name": "project", + "scripts": Object { + "hello": "echo Hello", "test": "echo /"Error: no test specified/" && exit 1", - "hello": "echo Hello" }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" + "tap": Object { + "test-env": Array [ + "LC_ALL=sk", + ], }, - "tap": { - "test-env": [ - "LC_ALL=sk" - ] - } + "type": "commonjs", + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm pkg > should have expected pkg delete output 1`] = ` +exports[`test/index.js TAP basic npm pkg > should have expected pkg delete output 1`] = ` ` -exports[`test/index.js TAP npm pkg > should have expected pkg get output 1`] = ` +exports[`test/index.js TAP basic npm pkg > should have expected pkg get output 1`] = ` "ISC" - ` -exports[`test/index.js TAP npm pkg > should have expected pkg set output 1`] = ` +exports[`test/index.js TAP basic npm pkg > should have expected pkg set output 1`] = ` ` -exports[`test/index.js TAP npm pkg > should print package.json contents 1`] = ` +exports[`test/index.js TAP basic npm pkg > should print package.json contents 1`] = ` { "name": "project", "version": "1.0.0", "description": "", - "ma", + "main": "index.js", "scripts": { "test": "echo /"Error: no test specified/" && exit 1", "hello": "echo Hello" @@ -585,6 +312,7 @@ exports[`test/index.js TAP npm pkg > should print package.json contents 1`] = ` "keywords": [], "author": "", "license": "ISC", + "type": "commonjs", "dependencies": { "abbrev": "^1.0.4" }, @@ -594,210 +322,167 @@ exports[`test/index.js TAP npm pkg > should print package.json contents 1`] = ` ] } } - -` - -exports[`test/index.js TAP npm prefix > should have expected prefix output 1`] = ` -{CWD}/smoke-tests/test/tap-testdir-index/project - -` - -exports[`test/index.js TAP npm run-script > should have expected run-script output 1`] = ` - -> project@1.0.0 hello -> echo Hello - -Hello - ` -exports[`test/index.js TAP npm set-script > should have expected script added package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm pkg set scripts > should have expected script added package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", - "main": "index.js", - "scripts": { - "test": "echo /"Error: no test specified/" && exit 1", - "hello": "echo Hello" + "devDependencies": Object { + "promise-all-reject-late": "^5.0.0", }, - "keywords": [], - "author": "", + "keywords": Array [], "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" + "main": "index.js", + "name": "project", + "scripts": Object { + "hello": "echo Hello", + "test": "echo /"Error: no test specified/" && exit 1", }, - "devDependencies": { - "promise-all-reject-late": "^1.0.1" - } + "type": "commonjs", + "version": "1.0.0", } +` + +exports[`test/index.js TAP basic npm pkg set scripts > should have expected set-script output 1`] = ` ` -exports[`test/index.js TAP npm set-script > should have expected set-script output 1`] = ` +exports[`test/index.js TAP basic npm prefix > should have expected prefix output 1`] = ` +{NPM}/{TESTDIR}/project +` + +exports[`test/index.js TAP basic npm run > should have expected run output 1`] = ` +> project@1.0.0 hello +> echo Hello +Hello ` -exports[`test/index.js TAP npm uninstall > should have expected uninstall lockfile result 1`] = ` -{ +exports[`test/index.js TAP basic npm uninstall > should have expected uninstall lockfile result 1`] = ` +Object { + "lockfileVersion": 3, "name": "project", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { + "packages": Object { + "": Object { + "dependencies": Object { + "abbrev": "^1.0.4", + }, + "license": "ISC", "name": "project", "version": "1.0.0", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - } }, - "node_modules/abbrev": { + "node_modules/abbrev": Object { + "resolved": "{REGISTRY}/abbrev/-/abbrev-1.1.1.tgz", "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - } + }, }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - } - } + "requires": true, + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm uninstall > should have expected uninstall package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm uninstall > should have expected uninstall package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", + "keywords": Array [], + "license": "ISC", "main": "index.js", - "scripts": { + "name": "project", + "scripts": Object { + "hello": "echo Hello", "test": "echo /"Error: no test specified/" && exit 1", - "hello": "echo Hello" }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - } + "type": "commonjs", + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm uninstall > should have expected uninstall reify output 1`] = ` - -removed 1 package - +exports[`test/index.js TAP basic npm uninstall > should have expected uninstall reify output 1`] = ` +removed 1 package in {TIME} ` -exports[`test/index.js TAP npm update dep > should have expected update lockfile result 1`] = ` -{ +exports[`test/index.js TAP basic npm update dep > should have expected update lockfile result 1`] = ` +Object { + "lockfileVersion": 3, "name": "project", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { + "packages": Object { + "": Object { + "dependencies": Object { + "abbrev": "^1.0.4", + }, + "devDependencies": Object { + "promise-all-reject-late": "^5.0.0", + }, + "license": "ISC", "name": "project", "version": "1.0.0", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" - }, - "devDependencies": { - "promise-all-reject-late": "^1.0.1" - } }, - "node_modules/abbrev": { + "node_modules/abbrev": Object { + "resolved": "{REGISTRY}/abbrev/-/abbrev-1.1.1.tgz", "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, - "node_modules/promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "node_modules/promise-all-reject-late": Object { "dev": true, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - } - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "funding": Object { + "url": "https://github.com/sponsors", + }, + "resolved": "{REGISTRY}/promise-all-reject-late/-/promise-all-reject-late-5.0.0.tgz", + "version": "5.0.0", }, - "promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "dev": true - } - } + }, + "requires": true, + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm update dep > should have expected update package.json result 1`] = ` -{ - "name": "project", - "version": "1.0.0", +exports[`test/index.js TAP basic npm update dep > should have expected update package.json result 1`] = ` +Object { + "author": "", + "dependencies": Object { + "abbrev": "^1.0.4", + }, "description": "", - "main": "index.js", - "scripts": { - "test": "echo /"Error: no test specified/" && exit 1", - "hello": "echo Hello" + "devDependencies": Object { + "promise-all-reject-late": "^5.0.0", }, - "keywords": [], - "author": "", + "keywords": Array [], "license": "ISC", - "dependencies": { - "abbrev": "^1.0.4" + "main": "index.js", + "name": "project", + "scripts": Object { + "hello": "echo Hello", + "test": "echo /"Error: no test specified/" && exit 1", }, - "devDependencies": { - "promise-all-reject-late": "^1.0.1" - } + "type": "commonjs", + "version": "1.0.0", } - ` -exports[`test/index.js TAP npm update dep > should have expected update reify output 1`] = ` - -changed 1 package +exports[`test/index.js TAP basic npm update dep > should have expected update reify output 1`] = ` +changed 1 package in {TIME} 1 package is looking for funding run \`npm fund\` for details - ` -exports[`test/index.js TAP npm view > should have expected view output 1`] = ` - -abbrev@1.0.4 | MIT | deps: none | versions: 8 -Like ruby's abbrev module, but in js -https://github.com/isaacs/abbrev-js#readme +exports[`test/index.js TAP basic npm view > should have expected view output 1`] = ` +abbrev@1.0.4 | Proprietary | deps: none | versions: 2 +mocked test package dist -.tarball: https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz -.shasum: bd55ae5e413ba1722ee4caba1f6ea10414a59ecd - -maintainers: -- nlf -- ruyadorno -- darcyclarke -- adam_baldwin -- isaacs +.tarball: {REGISTRY}/abbrev/-/abbrev-1.0.4.tgz +.shasum: undefined dist-tags: latest: 1.1.1 -published over a year ago by isaacs - +published just now ` diff --git a/smoke-tests/test/fixtures/abbrev.json b/smoke-tests/test/fixtures/abbrev.json deleted file mode 100644 index ffcf5474a9de8..0000000000000 --- a/smoke-tests/test/fixtures/abbrev.json +++ /dev/null @@ -1,449 +0,0 @@ -{ - "_id": "abbrev", - "_rev": "72-d1d46bef3d311d6da6737e109e771869", - "name": "abbrev", - "dist-tags": { - "latest": "1.1.1" - }, - "versions": { - "1.0.3": { - "name": "abbrev", - "version": "1.0.3", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "./lib/abbrev.js", - "scripts": { - "test": "node lib/abbrev.js" - }, - "repository": { - "type": "git", - "url": "git://github.com/isaacs/abbrev-js.git" - }, - "_id": "abbrev@1.0.3", - "engines": { - "node": "*" - }, - "_engineSupported": true, - "_npmVersion": "1.0.0rc7", - "_nodeVersion": "v0.5.0-pre", - "_defaultsLoaded": true, - "dist": { - "shasum": "aa049c967f999222aa42e14434f0c562ef468241", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.3.tgz" - }, - "directories": {} - }, - "1.0.4": { - "name": "abbrev", - "version": "1.0.4", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "./lib/abbrev.js", - "scripts": { - "test": "node lib/abbrev.js" - }, - "repository": { - "type": "git", - "url": "http://github.com/isaacs/abbrev-js" - }, - "license": { - "type": "MIT", - "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE" - }, - "_id": "abbrev@1.0.4", - "dist": { - "shasum": "bd55ae5e413ba1722ee4caba1f6ea10414a59ecd", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz" - }, - "_npmVersion": "1.1.70", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {} - }, - "1.0.5": { - "name": "abbrev", - "version": "1.0.5", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "abbrev.js", - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "http://github.com/isaacs/abbrev-js" - }, - "license": { - "type": "MIT", - "url": "https://github.com/isaacs/abbrev-js/raw/master/LICENSE" - }, - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "homepage": "https://github.com/isaacs/abbrev-js", - "_id": "abbrev@1.0.5", - "_shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03", - "_from": ".", - "_npmVersion": "1.4.7", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "dist": { - "shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz" - }, - "directories": {} - }, - "1.0.6": { - "name": "abbrev", - "version": "1.0.6", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "abbrev.js", - "scripts": { - "test": "node test.js" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" - }, - "license": "ISC", - "gitHead": "648a6735d9c5a7a04885e3ada49eed4db36181c2", - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "homepage": "https://github.com/isaacs/abbrev-js#readme", - "_id": "abbrev@1.0.6", - "_shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30", - "_from": ".", - "_npmVersion": "2.10.0", - "_nodeVersion": "2.0.1", - "_npmUser": { - "name": "isaacs", - "email": "isaacs@npmjs.com" - }, - "dist": { - "shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.6.tgz" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {} - }, - "1.0.7": { - "name": "abbrev", - "version": "1.0.7", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "abbrev.js", - "scripts": { - "test": "tap test.js --cov" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" - }, - "license": "ISC", - "devDependencies": { - "tap": "^1.2.0" - }, - "gitHead": "821d09ce7da33627f91bbd8ed631497ed6f760c2", - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "homepage": "https://github.com/isaacs/abbrev-js#readme", - "_id": "abbrev@1.0.7", - "_shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843", - "_from": ".", - "_npmVersion": "2.10.1", - "_nodeVersion": "2.0.1", - "_npmUser": { - "name": "isaacs", - "email": "isaacs@npmjs.com" - }, - "dist": { - "shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "directories": {} - }, - "1.0.9": { - "name": "abbrev", - "version": "1.0.9", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "abbrev.js", - "scripts": { - "test": "tap test.js --cov" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" - }, - "license": "ISC", - "devDependencies": { - "tap": "^5.7.2" - }, - "files": [ - "abbrev.js" - ], - "gitHead": "c386cd9dbb1d8d7581718c54d4ba944cc9298d6f", - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "homepage": "https://github.com/isaacs/abbrev-js#readme", - "_id": "abbrev@1.0.9", - "_shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", - "_from": ".", - "_npmVersion": "3.9.1", - "_nodeVersion": "4.4.4", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "dist": { - "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_npmOperationalInternal": { - "host": "packages-16-east.internal.npmjs.com", - "tmp": "tmp/abbrev-1.0.9.tgz_1466016055839_0.7825860097073019" - }, - "directories": {} - }, - "1.1.0": { - "name": "abbrev", - "version": "1.1.0", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "abbrev.js", - "scripts": { - "test": "tap test.js --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" - }, - "license": "ISC", - "devDependencies": { - "tap": "^10.1" - }, - "files": [ - "abbrev.js" - ], - "gitHead": "7136d4d95449dc44115d4f78b80ec907724f64e0", - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "homepage": "https://github.com/isaacs/abbrev-js#readme", - "_id": "abbrev@1.1.0", - "_shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f", - "_from": ".", - "_npmVersion": "4.3.0", - "_nodeVersion": "8.0.0-pre", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "dist": { - "shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_npmOperationalInternal": { - "host": "packages-12-west.internal.npmjs.com", - "tmp": "tmp/abbrev-1.1.0.tgz_1487054000015_0.9229173036292195" - }, - "directories": {} - }, - "1.1.1": { - "name": "abbrev", - "version": "1.1.1", - "description": "Like ruby's abbrev module, but in js", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "main": "abbrev.js", - "scripts": { - "test": "tap test.js --100", - "preversion": "npm test", - "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" - }, - "license": "ISC", - "devDependencies": { - "tap": "^10.1" - }, - "files": [ - "abbrev.js" - ], - "gitHead": "a9ee72ebc8fe3975f1b0c7aeb3a8f2a806a432eb", - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "homepage": "https://github.com/isaacs/abbrev-js#readme", - "_id": "abbrev@1.1.1", - "_npmVersion": "5.4.2", - "_nodeVersion": "8.5.0", - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "dist": { - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - }, - "maintainers": [ - { - "name": "gabra", - "email": "jerry+1@npmjs.com" - }, - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_npmOperationalInternal": { - "host": "s3://npm-registry-packages", - "tmp": "tmp/abbrev-1.1.1.tgz_1506566833068_0.05750026390887797" - }, - "directories": {} - } - }, - "maintainers": [ - { - "email": "quitlahok@gmail.com", - "name": "nlf" - }, - { - "email": "ruyadorno@hotmail.com", - "name": "ruyadorno" - }, - { - "email": "darcy@darcyclarke.me", - "name": "darcyclarke" - }, - { - "email": "evilpacket@gmail.com", - "name": "adam_baldwin" - }, - { - "email": "i@izs.me", - "name": "isaacs" - } - ], - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me" - }, - "description": "Like ruby's abbrev module, but in js", - "time": { - "modified": "2020-10-13T05:04:03.636Z", - "created": "2011-03-21T22:21:11.183Z", - "1.0.1": "2011-03-21T22:21:11.183Z", - "1.0.2": "2011-03-21T22:21:11.183Z", - "1.0.3": "2011-03-21T22:21:11.183Z", - "1.0.3-1": "2011-03-24T23:01:19.581Z", - "1.0.4": "2013-01-09T00:01:24.135Z", - "1.0.5": "2014-04-17T20:09:12.523Z", - "1.0.6": "2015-05-21T00:58:16.778Z", - "1.0.7": "2015-05-30T22:57:54.685Z", - "1.0.9": "2016-06-15T18:41:01.215Z", - "1.1.0": "2017-02-14T06:33:20.235Z", - "1.1.1": "2017-09-28T02:47:13.220Z" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" - }, - "users": { - "leesei": true, - "ceejbot": true, - "isaacs": true, - "npm-www": true, - "tunnckocore": true, - "ruanyu1": true, - "leodutra": true, - "jessaustin": true, - "jian263994241": true, - "floriannagel": true, - "tdmalone": true, - "ryanve": true, - "detj": true, - "monjer": true, - "d-band": true - }, - "readme": "# abbrev-js\n\nJust like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).\n\nUsage:\n\n var abbrev = require(\"abbrev\");\n abbrev(\"foo\", \"fool\", \"folding\", \"flop\");\n \n // returns:\n { fl: 'flop'\n , flo: 'flop'\n , flop: 'flop'\n , fol: 'folding'\n , fold: 'folding'\n , foldi: 'folding'\n , foldin: 'folding'\n , folding: 'folding'\n , foo: 'foo'\n , fool: 'fool'\n }\n\nThis is handy for command-line scripts, or other cases where you want to be able to accept shorthands.\n", - "readmeFilename": "README.md", - "homepage": "https://github.com/isaacs/abbrev-js#readme", - "bugs": { - "url": "https://github.com/isaacs/abbrev-js/issues" - }, - "license": "ISC" -} diff --git a/smoke-tests/test/fixtures/abbrev.min.json b/smoke-tests/test/fixtures/abbrev.min.json deleted file mode 100644 index c03d91c9c8c19..0000000000000 --- a/smoke-tests/test/fixtures/abbrev.min.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "name": "abbrev", - "dist-tags": { - "latest": "1.1.1" - }, - "versions": { - "1.0.3": { - "name": "abbrev", - "version": "1.0.3", - "dist": { - "shasum": "aa049c967f999222aa42e14434f0c562ef468241", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.3.tgz" - }, - "engines": { - "node": "*" - } - }, - "1.0.4": { - "name": "abbrev", - "version": "1.0.4", - "dist": { - "shasum": "bd55ae5e413ba1722ee4caba1f6ea10414a59ecd", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz" - } - }, - "1.0.5": { - "name": "abbrev", - "version": "1.0.5", - "dist": { - "shasum": "5d8257bd9ebe435e698b2fa431afde4fe7b10b03", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz" - } - }, - "1.0.6": { - "name": "abbrev", - "version": "1.0.6", - "dist": { - "shasum": "b6d632b859b3fa2d6f7e4b195472461b9e32dc30", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.6.tgz" - } - }, - "1.0.7": { - "name": "abbrev", - "version": "1.0.7", - "devDependencies": { - "tap": "^1.2.0" - }, - "dist": { - "shasum": "5b6035b2ee9d4fb5cf859f08a9be81b208491843", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" - } - }, - "1.0.9": { - "name": "abbrev", - "version": "1.0.9", - "devDependencies": { - "tap": "^5.7.2" - }, - "dist": { - "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" - } - }, - "1.1.0": { - "name": "abbrev", - "version": "1.1.0", - "devDependencies": { - "tap": "^10.1" - }, - "dist": { - "shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz" - } - }, - "1.1.1": { - "name": "abbrev", - "version": "1.1.1", - "devDependencies": { - "tap": "^10.1" - }, - "dist": { - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "shasum": "f8f2c887ad10bf67f634f005b6987fed3179aac8", - "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - } - } - }, - "modified": "2020-10-13T05:04:03.636Z" -} diff --git a/smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz deleted file mode 100644 index dfd1b55919e2f..0000000000000 Binary files a/smoke-tests/test/fixtures/abbrev/-/abbrev-1.0.4.tgz and /dev/null differ diff --git a/smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz b/smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz deleted file mode 100644 index 4d9504504f5a3..0000000000000 Binary files a/smoke-tests/test/fixtures/abbrev/-/abbrev-1.1.1.tgz and /dev/null differ diff --git a/smoke-tests/test/fixtures/large-install/package-lock.json b/smoke-tests/test/fixtures/large-install/package-lock.json new file mode 100644 index 0000000000000..65c96e14e859a --- /dev/null +++ b/smoke-tests/test/fixtures/large-install/package-lock.json @@ -0,0 +1,16236 @@ +{ + "name": "@npmcli/smoke-tests-max-listeners", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@npmcli/smoke-tests-max-listeners", + "version": "1.0.0", + "dependencies": { + "@emotion/react": "11.10.", + "@emotion/styled": "11.11.0", + "@fullcalendar/core": "6.1.8", + "@fullcalendar/daygrid": "6.1.8", + "@fullcalendar/list": "6.1.8", + "@fullcalendar/timegrid": "6.1.8", + "@hello-pangea/dnd": "16.3.0", + "@mui/icons-material": "5.14.8", + "@mui/material": "5.14.8", + "@mui/x-data-grid-pro": "6.12.1", + "@tanstack/react-query": "4.35.0", + "chart.js": "4.4.0", + "chartjs-adapter-date-fns": "3.0.0", + "date-fns": "2.30.0", + "detect-browser": "5.3.0", + "dropzone": "5.9.3", + "file-saver": "2.0.5", + "filesize": "10.0.12", + "floatthead": "2.2.5", + "html-react-parser": "4.2.2", + "html2canvas": "1.4.1", + "identity-obj-proxy": "3.0.0", + "include-media": "2.0.0", + "jquery": "3.7.1", + "jquery-ui-touch-punch": "0.2.3", + "js-cookie": "3.0.5", + "lodash": "4.17.21", + "mousetrap": "1.6.5", + "pretty-format": "29.6.3", + "react": "18.2.0", + "react-avatar-editor": "13.0.0", + "react-dom": "18.2.0", + "react-dropzone": "14.2.3", + "select2": "3.5.1", + "stacktrace-js": "2.0.2", + "tablesorter": "2.31.3", + "timepicker": "1.14.1", + "tinymce": "6.7.0", + "tinymce-i18n": "23.8.28", + "tslib": "2.6.2", + "usehooks-ts": "2.9.1", + "uuid": "9.0.0", + "zod": "3.22.2", + "zod-to-json-schema": "3.21.4" + }, + "devDependencies": { + "@playwright/test": "1.37.1", + "@total-typescript/ts-reset": "0.5.1", + "@tsconfig/node18-strictest": "1.0.0", + "@types/archiver": "5.3.2", + "@types/argparse": "2.0.10", + "@types/debug": "4.1.8", + "@types/detect-port": "1.3.3", + "@types/dropzone": "5.7.4", + "@types/express": "4.17.17", + "@types/file-saver": "2.0.5", + "@types/fs-extra": "11.0.1", + "@types/jest": "29.5.4", + "@types/jquery": "3.5.18", + "@types/jquery-monthpicker": "3.0.1", + "@types/jqueryui": "1.12.17", + "@types/js-cookie": "3.0.3", + "@types/lodash": "4.14.198", + "@types/mousetrap": "1.6.11", + "@types/react": "18.2.21", + "@types/react-avatar-editor": "13.0.0", + "@types/react-dom": "18.2.7", + "@types/select2": "3.5.6", + "@types/timepicker": "1.13.3", + "@types/uuid": "9.0.3", + "@types/webpack-bundle-analyzer": "4.6.0", + "@typescript-eslint/eslint-plugin": "6.6.0", + "@typescript-eslint/parser": "6.6.0", + "archiver": "6.0.1", + "argparse": "2.0.1", + "autoprefixer": "10.4.15", + "axios": "1.5.0", + "chalk": "4.1.2", + "copy-webpack-plugin": "11.0.0", + "cross-env": "7.0.3", + "css-loader": "6.8.1", + "css-minimizer-webpack-plugin": "5.0.1", + "debug": "4.3.4", + "detect-port": "1.5.1", + "esbuild": "0.19.2", + "esbuild-sass-plugin": "2.15.0", + "eslint": "8.48.0", + "eslint-import-resolver-webpack": "0.13.7", + "eslint-nibble": "8.1.0", + "eslint-plugin-import": "2.28.1", + "eslint-plugin-jest": "27.2.3", + "eslint-plugin-jsdoc": "46.5.1", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-playwright": "0.16.0", + "eslint-plugin-promise": "6.1.1", + "eslint-plugin-react": "7.33.2", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-stats": "1.0.1", + "express": "4.18.2", + "file-loader": "6.2.0", + "fs-extra": "11.1.1", + "glob": "10.3.4", + "jest": "29.6.4", + "jest-environment-jsdom": "29.6.4", + "jszip": "3.10.1", + "mini-css-extract-plugin": "2.7.6", + "postcss": "8.4.29", + "postcss-loader": "7.3.3", + "postcss-scss": "4.0.7", + "prettier": "3.0.3", + "rimraf": "5.0.1", + "sass": "1.66.1", + "sass-loader": "13.3.2", + "style-loader": "3.3.3", + "stylelint": "15.10.3", + "stylelint-config-standard": "34.0.0", + "terser-webpack-plugin": "5.3.9", + "ts-jest": "29.1.1", + "ts-loader": "9.4.4", + "ts-node": "10.9.1", + "type-fest": "4.3.1", + "typed-scss-modules": "7.1.4", + "typedoc": "0.25.1", + "typescript": "5.2.2", + "url-loader": "4.1.1", + "webpack": "5.88.2", + "webpack-bundle-analyzer": "4.9.1", + "webpack-cli": "5.1.4" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dependencies": { + "@babel/highlight": "^7.0.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", + "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", + "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.22.15", + "@babel/helpers": "^7.22.15", + "@babel/parser": "^7.22.15", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/core/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/core/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/core/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/core/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/core/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/core/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/generator": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", + "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "dependencies": { + "@babel/types": "^7.22.15", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", + "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", + "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "dependencies": { + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", + "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", + "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.22.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", + "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.15.tgz", + "integrity": "sha512-tEVLhk8NRZSmwQ0DJtxxhTrCht1HVo8VaMzYT4w6lwyKBuHsgoioAUA7/6eT2fRfc5/23fuGdlwIxXhRVgWr4g==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/runtime": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", + "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/template/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/template/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/template/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/template/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/template/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/template/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", + "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/traverse/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/traverse/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/traverse/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", + "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.15", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", + "integrity": "sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^2.2.0" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.0.tgz", + "integrity": "sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.4.tgz", + "integrity": "sha512-V/OUXYX91tAC1CDsiY+HotIcJR+vPtzrX8pCplCpT++i8ThZZsq5F5dzZh/bDM3WUOjrvC1ljed1oSJxMfjqhw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", + "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.13" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.40.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz", + "integrity": "sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg==", + "dev": true, + "dependencies": { + "comment-parser": "1.4.0", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.2.tgz", + "integrity": "sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.2.tgz", + "integrity": "sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.2.tgz", + "integrity": "sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.2.tgz", + "integrity": "sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.2.tgz", + "integrity": "sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.2.tgz", + "integrity": "sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.2.tgz", + "integrity": "sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.2.tgz", + "integrity": "sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.2.tgz", + "integrity": "sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.2.tgz", + "integrity": "sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.2.tgz", + "integrity": "sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.2.tgz", + "integrity": "sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.2.tgz", + "integrity": "sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.2.tgz", + "integrity": "sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.2.tgz", + "integrity": "sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.2.tgz", + "integrity": "sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.2.tgz", + "integrity": "sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.2.tgz", + "integrity": "sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.2.tgz", + "integrity": "sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.2.tgz", + "integrity": "sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.2.tgz", + "integrity": "sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz", + "integrity": "sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", + "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz", + "integrity": "sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==", + "dependencies": { + "@floating-ui/utils": "^0.1.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz", + "integrity": "sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==", + "dependencies": { + "@floating-ui/core": "^1.4.1", + "@floating-ui/utils": "^0.1.1" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz", + "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", + "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" + }, + "node_modules/@fullcalendar/core": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.8.tgz", + "integrity": "sha512-i8JBIvZCWGO9dsMEDcx9bnsQZ9PtGSJdOXGgWbhLaGq2iq41OBdp9g9gM4b/Otv2oK8bL5Gl6CsMmb/HkDtA6Q==", + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/daygrid": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.8.tgz", + "integrity": "sha512-kCZxQFKb9Vqa3CZRX0v7rMSJ2mlTt4gDpyLfiNJKxUAq7W51uKurPaFZWicaXy1ESHVBxKNlbx5uNjBpyu50JQ==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.8" + } + }, + "node_modules/@fullcalendar/list": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.8.tgz", + "integrity": "sha512-10N0T/vCtId1cE3JGLpnbAivWVnaWCCkVO7wmbsyr5Y+I939kr/zq4BUNwBoP/xSFVVxx59FETh3iyA+MkV8Fw==", + "peerDependencies": { + "@fullcalendar/core": "~6.1.8" + } + }, + "node_modules/@fullcalendar/timegrid": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.8.tgz", + "integrity": "sha512-3+3KHHCoNcaLs/gQt004hAqICbY5+WAffrZ0ePv+80HFB1OVh8BQ5XXLHSOUbTvXdgtUTcfBHuw9fhO31kt5gA==", + "dependencies": { + "@fullcalendar/daygrid": "~6.1.8" + }, + "peerDependencies": { + "@fullcalendar/core": "~6.1.8" + } + }, + "node_modules/@hello-pangea/dnd": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/@hello-pangea/dnd/-/dnd-16.3.0.tgz", + "integrity": "sha512-RYQ/K8shtJoyNPvFWz0gfXIK7HF3P3mL9UZFGMuHB0ljRSXVgMjVFI/FxcZmakMzw6tO7NflWLriwTNBow/4vw==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "css-box-model": "^1.2.1", + "memoize-one": "^6.0.0", + "raf-schd": "^4.0.3", + "react-redux": "^8.1.1", + "redux": "^4.2.1", + "use-memo-one": "^1.1.3" + }, + "peerDependencies": { + "react": "^16.8.5 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@ianvs/eslint-stats": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ianvs/eslint-stats/-/eslint-stats-2.0.0.tgz", + "integrity": "sha512-DnIVVAiXR4tfWERTiQxr1Prrs/uFEbC1C4gTGORMvbF4k7ENyVQeLcoUfNyhlAj2MB/OeorCrN3wSnYuDOUS6Q==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@ianvs/eslint-stats/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@ianvs/eslint-stats/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@ianvs/eslint-stats/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@ianvs/eslint-stats/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@ianvs/eslint-stats/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@ianvs/eslint-stats/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@ianvs/eslint-stats/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz", + "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz", + "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.4", + "@jest/reporters": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.6.3", + "jest-config": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-resolve-dependencies": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "jest-watcher": "^29.6.4", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz", + "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.4.tgz", + "integrity": "sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==", + "dev": true, + "dependencies": { + "expect": "^29.6.4", + "jest-snapshot": "^29.6.4" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz", + "integrity": "sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz", + "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.6.3", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.4.tgz", + "integrity": "sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/types": "^29.6.3", + "jest-mock": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz", + "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "jest-worker": "^29.6.4", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz", + "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz", + "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.4.tgz", + "integrity": "sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.6.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.14", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.14.tgz", + "integrity": "sha512-Je/9JzzYObsuLCIClgE8XvXNFb55IEz8n2NtStUfASfNiVrwiR8t6VVFFuhofehkyTIN34tq1qbBaOjCnOovBw==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@emotion/is-prop-valid": "^1.2.1", + "@floating-ui/react-dom": "^2.0.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.8", + "@popperjs/core": "^2.11.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.8.tgz", + "integrity": "sha512-8V7ZOC/lKkM03TRHqaThQFIq6bWPnj7L/ZWPh0ymldYFFyh8XdF0ywTgafsofDNYT4StlNknbaTjVHBma3SNjQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.8.tgz", + "integrity": "sha512-YXcReLydTuNWb1/PxduAH5LgnHNH6spSQBaA0JOz9HD4J+vwst0IanAQgsXy9KKCJSjCsHywE3DB8X+w/b4eeQ==", + "dependencies": { + "@babel/runtime": "^7.22.10" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.8.tgz", + "integrity": "sha512-fqvDGGF1pXwOOL/f0Gw+KHo/67hasRpf2ApTIJkbuONOk9AUb2jnYMEqCWmL2sUcbbE3ShMbHl8N7HPSsRv1/A==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/base": "5.0.0-beta.14", + "@mui/core-downloads-tracker": "^5.14.8", + "@mui/system": "^5.14.8", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.8", + "@types/react-transition-group": "^4.4.6", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.14.8.tgz", + "integrity": "sha512-iBzpcl3Mh92XaYpYPdgzzRxNGkjpoDz8rf8/q5m+EBPowFEHV+CCS9hC0Q2pOKLW3VFFikA7w/GHt7n++40JGQ==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/utils": "^5.14.8", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.14.8.tgz", + "integrity": "sha512-LGwOav/Y40PZWZ2yDk4beUoRlc57Vg+Vpxi9V9BBtT2ESAucCgFobkt+T8eVLMWF9huUou5pwKgLSU5pF90hBg==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.8.tgz", + "integrity": "sha512-Dxnasv7Pj5hYe4ZZFKJZu4ufKm6cxpitWt3A+qMPps22YhqyeEqgDBq/HsAB3GOjqDP40fTAvQvS/Hguf4SJuw==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@mui/private-theming": "^5.14.8", + "@mui/styled-engine": "^5.14.8", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.14.8", + "clsx": "^2.0.0", + "csstype": "^3.1.2", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.14.8", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.8.tgz", + "integrity": "sha512-1Ls2FfyY2yVSz9NEqedh3J8JAbbZAnUWkOWLE2f4/Hc4T5UWHMfzBLLrCqExfqyfyU+uXYJPGeNIsky6f8Gh5Q==", + "dependencies": { + "@babel/runtime": "^7.22.10", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^18.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/x-data-grid": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.12.1.tgz", + "integrity": "sha512-lSY1dFBv6yh2ffkkWeMM9c0ajpwIWn/da/ec0kY8OfLa79Hboh53mN09nopylZO8MHJGfDlPvduwuWcgWs+zFw==", + "dependencies": { + "@babel/runtime": "^7.22.11", + "@mui/utils": "^5.14.7", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/x-data-grid-pro": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid-pro/-/x-data-grid-pro-6.12.1.tgz", + "integrity": "sha512-41rJbZy9+aE7uZLbdMmoERHIjMQ0W8cEq6WO9fcx3yjOzDPpIUvBbVglUs4oWrab/yYtfpwvJrScJBbD4HSV+g==", + "dependencies": { + "@babel/runtime": "^7.22.11", + "@mui/utils": "^5.14.7", + "@mui/x-data-grid": "6.12.1", + "@mui/x-license-pro": "6.10.2", + "@types/format-util": "^1.0.2", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/x-license-pro": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-6.10.2.tgz", + "integrity": "sha512-Baw3shilU+eHgU+QYKNPFUKvfS5rSyNJ98pQx02E0gKA22hWp/XAt88K1qUfUMPlkPpvg/uci6gviQSSLZkuKw==", + "dependencies": { + "@babel/runtime": "^7.22.6", + "@mui/utils": "^5.13.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz", + "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "playwright-core": "1.37.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.23", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", + "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==", + "dev": true + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.35.0.tgz", + "integrity": "sha512-4GMcKQuLZQi6RFBiBZNsLhl+hQGYScRZ5ZoVq8QAzfqz9M7vcGin/2YdSESwl7WaV+Qzsb5CZOAbMBes4lNTnA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.35.0.tgz", + "integrity": "sha512-LLYDNnM9ewYHgjm2rzhk4KG/puN2rdoqCUD+N9+V7SwlsYwJk5ypX58rpkoZAhFyZ+KmFUJ7Iv2lIEOoUqydIg==", + "dependencies": { + "@tanstack/query-core": "4.35.0", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@total-typescript/ts-reset": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@total-typescript/ts-reset/-/ts-reset-0.5.1.tgz", + "integrity": "sha512-AqlrT8YA1o7Ff5wPfMOL0pvL+1X+sw60NN6CcOCqs658emD6RfiXhF7Gu9QcfKBH7ELY2nInLhKSCWVoNL70MQ==", + "dev": true + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@tsconfig/node18-strictest": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tsconfig/node18-strictest/-/node18-strictest-1.0.0.tgz", + "integrity": "sha512-bOuNKwO4Fzbt+Su5wqI9zNHwx5C25gLnutwVQA1sBZk0cW8UjVPVcwzIUhJIIJDUx7zDEbAwdCD2HfvIsV8dYg==", + "deprecated": "TypeScript 5.0 supports combining TSConfigs using array syntax in extends", + "dev": true + }, + "node_modules/@types/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-IctHreBuWE5dvBDz/0WeKtyVKVRs4h75IblxOACL92wU66v+HGAfEYAOyXkOFphvRJMhuXdI9huDXpX0FC6lCw==", + "dev": true, + "dependencies": { + "@types/readdir-glob": "*" + } + }, + "node_modules/@types/argparse": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-2.0.10.tgz", + "integrity": "sha512-C4wahC3gz3vQtvPazrJ5ONwmK1zSDllQboiWvpMM/iOswCYfBREFnjFbq/iWKIVOCl8+m5Pk6eva6/ZSsDuIGA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", + "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", + "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/detect-port": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.3.tgz", + "integrity": "sha512-bV/jQlAJ/nPY3XqSatkGpu+nGzou+uSwrH1cROhn+jBFg47yaNH+blW4C7p9KhopC7QxCv/6M86s37k8dMk0Yg==", + "dev": true + }, + "node_modules/@types/dropzone": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/@types/dropzone/-/dropzone-5.7.4.tgz", + "integrity": "sha512-9kLJ2YAmVRWYrHvDoa95pQzHF0HUMKcznsS7FM1Mht5Yieec+HMB6Ybfm+ocvLjvFCvgyYGFTp4nzNFxhZmo3g==", + "dev": true, + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", + "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.17", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", + "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.36", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz", + "integrity": "sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==", + "dev": true + }, + "node_modules/@types/format-util": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/format-util/-/format-util-1.0.2.tgz", + "integrity": "sha512-9SrLCpgzWo2yHHhiMOX0WwgDh37nSbDbWUsRc1ss++o8O97E3tB6SJiyUQM21UeUsKvZNuhDCmkRaINZ4uJAfg==" + }, + "node_modules/@types/fs-extra": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz", + "integrity": "sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==", + "dev": true, + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz", + "integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jquery": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.18.tgz", + "integrity": "sha512-sNm7O6LECFhHmF+3KYo6QIl2fIbjlPYa0PDgDQwfOaEJzwpK20Eub9Ke7VKkGsSJ2K0HUR50S266qYzRX4GlSw==", + "dev": true, + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/jquery-monthpicker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/jquery-monthpicker/-/jquery-monthpicker-3.0.1.tgz", + "integrity": "sha512-jvCXOteLEKlHUL5N3ocMykcEk/aC5ifqZi7CG6ig2i1WaX8KnvBpHGBrpWqfc6DnMgDblNTL81+QXoG0IQ4cGg==", + "dev": true, + "dependencies": { + "@types/jquery": "*", + "@types/jqueryui": "*" + } + }, + "node_modules/@types/jqueryui": { + "version": "1.12.17", + "resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.17.tgz", + "integrity": "sha512-rqiCaZO7d1rAcJVXNSV6MYwt42oB4ArTRr0QbU3f4+Siv0d6m9uRkhiKHpc6oL9NFJKDxzIIDvUeMXTtlJFFaA==", + "dev": true, + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/js-cookie": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.3.tgz", + "integrity": "sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww==", + "dev": true + }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/jsonfile": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.1.tgz", + "integrity": "sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.198", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", + "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/mousetrap": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.11.tgz", + "integrity": "sha512-F0oAily9Q9QQpv9JKxKn0zMKfOo36KHCW7myYsmUyf2t0g+sBTbG3UleTPoguHdE1z3GLFr3p7/wiOio52QFjQ==", + "dev": true + }, + "node_modules/@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.5.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.9.tgz", + "integrity": "sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/qs": { + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", + "integrity": "sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-avatar-editor": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/react-avatar-editor/-/react-avatar-editor-13.0.0.tgz", + "integrity": "sha512-5ymOayy6mfT35xTqzni7UjXvCNEg8/pH4pI5RenITp9PBc02KGTYjSV1WboXiQDYSh5KomLT0ngBLEAIhV1QoQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", + "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "devOptional": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-is": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", + "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.1.tgz", + "integrity": "sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "node_modules/@types/select2": { + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/@types/select2/-/select2-3.5.6.tgz", + "integrity": "sha512-wOq3seKwDwGLSAt93TepfDhZBN25uJnvBxXypcOOFBPS1nHmwysgQiflJJFk6eSdskLZ391O8nvka28DthApbA==", + "dev": true, + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", + "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", + "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/timepicker": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/timepicker/-/timepicker-1.13.3.tgz", + "integrity": "sha512-+8862u1yBKoryCtu5V/rhi+NGZ2Q7KUbtbAWApg3ivaQo2J6uVJGKJxpL671SbVJbCurYjKqnhAQJN20XiysEw==", + "dev": true, + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, + "node_modules/@types/uuid": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.3.tgz", + "integrity": "sha512-taHQQH/3ZyI3zP8M/puluDEIEvtQHVYcC6y3N8ijFtAd28+Ey/G4sg1u2gB01S8MwybLOKAp9/yCMu/uR5l3Ug==", + "dev": true + }, + "node_modules/@types/webpack-bundle-analyzer": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.0.tgz", + "integrity": "sha512-XeQmQCCXdZdap+A/60UKmxW5Mz31Vp9uieGlHB3T4z/o2OLVLtTI3bvTuS6A2OWd/rbAAQiGGWIEFQACu16szA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "tapable": "^2.2.0", + "webpack": "^5" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz", + "integrity": "sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/type-utils": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.6.0.tgz", + "integrity": "sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", + "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", + "integrity": "sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/archiver": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz", + "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==", + "dev": true, + "dependencies": { + "archiver-utils": "^4.0.1", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^5.0.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/archiver-utils": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", + "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "dev": true, + "dependencies": { + "glob": "^8.0.0", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/archiver-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.find": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.2.2.tgz", + "integrity": "sha512-DRumkfW97iZGOfn+lIXbkVrXL04sfYKX+EfOodo8XboR5sxPDVvOjZTF/rysusa9lmhmSOeD6Vp6RKQP+eP4Tg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/attr-accept": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.15", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", + "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.21.10", + "caniuse-lite": "^1.0.30001520", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", + "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz", + "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.6.4", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz", + "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.31.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bundle-require": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-3.1.2.tgz", + "integrity": "sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==", + "dev": true, + "dependencies": { + "load-tsconfig": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.13" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001527", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz", + "integrity": "sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/chart.js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz", + "integrity": "sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=7" + } + }, + "node_modules/chartjs-adapter-date-fns": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-3.0.0.tgz", + "integrity": "sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg==", + "peerDependencies": { + "chart.js": ">=2.8.0", + "date-fns": ">=2.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", + "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/comment-parser": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.0.tgz", + "integrity": "sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/compress-commons": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz", + "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^5.0.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dev": true, + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js-compat": { + "version": "3.32.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.1.tgz", + "integrity": "sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==", + "dependencies": { + "browserslist": "^4.21.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz", + "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz", + "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-loader": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", + "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.21", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.3", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-modules-loader-core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", + "integrity": "sha512-XWOBwgy5nwBn76aA+6ybUGL/3JBnCtBX9Ay9/OWIpzKYWlVHMazvJ+WtHumfi+xxdPF440cWK7JCYtt8xDifew==", + "dev": true, + "dependencies": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.1", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/chalk/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", + "integrity": "sha512-VbGX1LQgQbf9l3cZ3qbUuC3hGqIEOGQFHAEHQ/Diaeo0yLgpgK5Rb8J+OcamIfQ9PbAU/fzBjVtQX3AhJHUvZw==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha512-zF9+UIEvtpeqMGxhpeT9XaIevQSrBBCz9fi7SwfkmjVacsSj8DY5eFVgn+wY8I9vvdDDwK5xC8Myq4UkoLFIkA==", + "dev": true, + "dependencies": { + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha512-X4cquUPIaAd86raVrBwO8fwRfkIdbwFu7CTfEOjiZQHVQwlHRSkTgH5NLDmMm5+1hQO8u6dZ+TOOJDbay1hYpA==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha512-LTYwnA4C1He1BKZXIx1CYiHixdSe9LWYVKadq9lK5aCCMkoOkFyZ7aigt+srfjlRplJY3gIol6KUNefdMQJdlw==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha512-i7IFaR9hlQ6/0UgFuqM6YWaCfA1Ej8WMg8A5DggnH1UGKJvTV/ugqq/KaULixzzOi3T/tF6ClBXcHGCzdd5unA==", + "dev": true, + "dependencies": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "node_modules/css-modules-loader-core/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-modules-loader-core/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz", + "integrity": "sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.1.tgz", + "integrity": "sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^6.0.1", + "lilconfig": "^2.1.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz", + "integrity": "sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^4.0.0", + "postcss-calc": "^9.0.0", + "postcss-colormin": "^6.0.0", + "postcss-convert-values": "^6.0.0", + "postcss-discard-comments": "^6.0.0", + "postcss-discard-duplicates": "^6.0.0", + "postcss-discard-empty": "^6.0.0", + "postcss-discard-overridden": "^6.0.0", + "postcss-merge-longhand": "^6.0.0", + "postcss-merge-rules": "^6.0.1", + "postcss-minify-font-values": "^6.0.0", + "postcss-minify-gradients": "^6.0.0", + "postcss-minify-params": "^6.0.0", + "postcss-minify-selectors": "^6.0.0", + "postcss-normalize-charset": "^6.0.0", + "postcss-normalize-display-values": "^6.0.0", + "postcss-normalize-positions": "^6.0.0", + "postcss-normalize-repeat-style": "^6.0.0", + "postcss-normalize-string": "^6.0.0", + "postcss-normalize-timing-functions": "^6.0.0", + "postcss-normalize-unicode": "^6.0.0", + "postcss-normalize-url": "^6.0.0", + "postcss-normalize-whitespace": "^6.0.0", + "postcss-ordered-values": "^6.0.0", + "postcss-reduce-initial": "^6.0.0", + "postcss-reduce-transforms": "^6.0.0", + "postcss-svgo": "^6.0.0", + "postcss-unique-selectors": "^6.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.0.tgz", + "integrity": "sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", + "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "dev": true, + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dropzone": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.9.3.tgz", + "integrity": "sha512-Azk8kD/2/nJIuVPK+zQ9sjKMRIpRvNyqn9XwbBHNq+iNuSccbJS6hwm1Woy0pMST0erSo0u4j+KJaodndDk4vA==" + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.510", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.510.tgz", + "integrity": "sha512-xPfLIPFcN/WLXBpQ/K4UgE98oUBO5Tia6BD4rkSR0wE7ep/PwBVlgvPJQrIBpmJGVAmUzwPKuDbVt9XV6+uC2g==" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha512-kxpoMgrdtkXZ5h0SeraBS1iRntpTpQ3R8ussdb38+UAFnMGX5DDyJXePm+OCHOcoXvHDw7mc2erbJBpDnl7TPw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/enhanced-resolve/node_modules/tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha512-jX8Et4hHg57mug1/079yitEKWGB3LCwoxByLsNim89LABq8NqgiX+6iYVOsq0vX8uJHkU+DZ5fnq95f800bEsQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.0", + "safe-array-concat": "^1.0.0", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.7", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz", + "integrity": "sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw==", + "dev": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.0", + "safe-array-concat": "^1.0.0" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", + "dev": true + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.2.tgz", + "integrity": "sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.19.2", + "@esbuild/android-arm64": "0.19.2", + "@esbuild/android-x64": "0.19.2", + "@esbuild/darwin-arm64": "0.19.2", + "@esbuild/darwin-x64": "0.19.2", + "@esbuild/freebsd-arm64": "0.19.2", + "@esbuild/freebsd-x64": "0.19.2", + "@esbuild/linux-arm": "0.19.2", + "@esbuild/linux-arm64": "0.19.2", + "@esbuild/linux-ia32": "0.19.2", + "@esbuild/linux-loong64": "0.19.2", + "@esbuild/linux-mips64el": "0.19.2", + "@esbuild/linux-ppc64": "0.19.2", + "@esbuild/linux-riscv64": "0.19.2", + "@esbuild/linux-s390x": "0.19.2", + "@esbuild/linux-x64": "0.19.2", + "@esbuild/netbsd-x64": "0.19.2", + "@esbuild/openbsd-x64": "0.19.2", + "@esbuild/sunos-x64": "0.19.2", + "@esbuild/win32-arm64": "0.19.2", + "@esbuild/win32-ia32": "0.19.2", + "@esbuild/win32-x64": "0.19.2" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sass-plugin": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/esbuild-sass-plugin/-/esbuild-sass-plugin-2.15.0.tgz", + "integrity": "sha512-T0GCHVfeuGBBgY5k19RbExd7vVuC3lzrK8IZbXOqZftw6N9lTBnZuqKhnhdAJBcu6wek7K/fXJ2zzY6KrcNtAg==", + "dev": true, + "dependencies": { + "resolve": "^1.22.2", + "sass": "^1.65.1" + }, + "peerDependencies": { + "esbuild": "^0.19.1" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-filtered-fix": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-filtered-fix/-/eslint-filtered-fix-0.3.0.tgz", + "integrity": "sha512-UMHOza9epEn9T+yVT8RiCFf0JdALpVzmoH62Ez/zvxM540IyUNAkr7aH2Frkv6zlm9a/gbmq/sc7C4SvzZQXcA==", + "dev": true, + "dependencies": { + "optionator": "^0.9.1" + }, + "bin": { + "eslint-filtered-fix": "bin/eslint-filtered-fix.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-formatter-friendly": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-friendly/-/eslint-formatter-friendly-7.0.0.tgz", + "integrity": "sha512-WXg2D5kMHcRxIZA3ulxdevi8/BGTXu72pfOO5vXHqcAfClfIWDSlOljROjCSOCcKvilgmHz1jDWbvFCZHjMQ5w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.0.0", + "chalk": "2.4.2", + "extend": "3.0.2", + "strip-ansi": "5.2.0", + "text-table": "0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/eslint-formatter-friendly/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-formatter-friendly/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-webpack": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.7.tgz", + "integrity": "sha512-2a+meyMeABBRO4K53Oj1ygkmt5lhQS79Lmx2f684Qnv6gjvD4RLOM5jfPGTXwQ0A2K03WSoKt3HRQu/uBgxF7w==", + "dev": true, + "dependencies": { + "array.prototype.find": "^2.2.1", + "debug": "^3.2.7", + "enhanced-resolve": "^0.9.1", + "find-root": "^1.1.0", + "has": "^1.0.3", + "interpret": "^1.4.0", + "is-core-module": "^2.13.0", + "is-regex": "^1.1.4", + "lodash": "^4.17.21", + "resolve": "^2.0.0-next.4", + "semver": "^5.7.2" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint-plugin-import": ">=1.4.0", + "webpack": ">=1.11.0" + } + }, + "node_modules/eslint-import-resolver-webpack/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-webpack/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-import-resolver-webpack/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-nibble": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-nibble/-/eslint-nibble-8.1.0.tgz", + "integrity": "sha512-x9H/1oeuKdC0HsaWeBarOryqNLC+7QZfAZIAP0HnGcmiiPktFIQq/D0e+iiCSyqYLSaui3UwvH56sXMrf5oQhw==", + "dev": true, + "dependencies": { + "@ianvs/eslint-stats": "^2.0.0", + "chalk": "^4.1.1", + "eslint-filtered-fix": "^0.3.0", + "eslint-formatter-friendly": "^7.0.0", + "eslint-summary": "^1.0.0", + "inquirer": "^8.2.3", + "optionator": "^0.9.1" + }, + "bin": { + "eslint-nibble": "bin/eslint-nibble.js" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.28.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", + "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "27.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.3.tgz", + "integrity": "sha512-sRLlSCpICzWuje66Gl9zvdF6mwD5X86I4u55hJyFBsxYOsBCmT5+kSUjf+fkFWVMMgpzNEupjW8WzUqi83hJAQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.10.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0", + "eslint": "^7.0.0 || ^8.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "46.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.5.1.tgz", + "integrity": "sha512-CPbvKprmEuJYoxMj5g8gXfPqUGgcqMM6jpH06Kp4pn5Uy5MrPkFKzoD7UFp2E4RBzfXbJz1+TeuEivwFVMkXBg==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.40.1", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.0", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.5.4", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-playwright": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.16.0.tgz", + "integrity": "sha512-DcHpF0SLbNeh9MT4pMzUGuUSnJ7q5MWbP8sSEFIMS6j7Ggnduq8ghNlfhURgty4c1YFny7Ge9xYTO1FSAoV2Vw==", + "dev": true, + "peerDependencies": { + "eslint": ">=7", + "eslint-plugin-jest": ">=25" + }, + "peerDependenciesMeta": { + "eslint-plugin-jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-stats": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/eslint-stats/-/eslint-stats-1.0.1.tgz", + "integrity": "sha512-5/5v8UvciDsXFNb+e+DMjOX8YZY2l1zpZ8ga3s5pV2CJ/dR0MOFFVXGLItn/jiey+FGBEmCKkFfZlJQra4uQMw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "lodash": "^4.17.4" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint-stats/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-stats/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-stats/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eslint-stats/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/eslint-stats/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-stats/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-stats/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-summary": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-summary/-/eslint-summary-1.0.0.tgz", + "integrity": "sha512-cHr5WiNFhu2guLQykhQV8O7BQcnpFLR6GdLjbQfDDL0yGy9U7dXC6zMUtwoxYgJRC/Wk3yZMc+I6Q15Z7r4j9Q==", + "dev": true, + "dependencies": { + "chalk": "^1.0.0", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-summary/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-summary/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-summary/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-summary/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-summary/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-summary/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz", + "integrity": "sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, + "node_modules/file-selector": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", + "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/filesize": { + "version": "10.0.12", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.0.12.tgz", + "integrity": "sha512-6RS9gDchbn+qWmtV2uSjo5vmKizgfCQeb5jKmqx8HyzA3MoLqqyQxN+QcjkGBJt7FjJ9qFce67Auyya5rRRbpw==", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "dependencies": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "node_modules/floatthead": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/floatthead/-/floatthead-2.2.5.tgz", + "integrity": "sha512-kpSxF0FWhrJMIy/Fu28oMXD8HNzHMwOJsgZ3n+IyRSCH39zaQtUDVq90XxJl3ZRzuWeyn+d802UNzsVqBoBa9w==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", + "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", + "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dev": true, + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/html-dom-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-4.0.0.tgz", + "integrity": "sha512-TUa3wIwi80f5NF8CVWzkopBVqVAtlawUzJoLwVLHns0XSJGynss4jiY0mTWpiDOsuyw+afP+ujjMgRh9CoZcXw==", + "dependencies": { + "domhandler": "5.0.3", + "htmlparser2": "9.0.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-react-parser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-4.2.2.tgz", + "integrity": "sha512-lh0wEGISnFZEAmvQqK4xc0duFMUh/m9YYyAhFursWxdtNv+hCZge0kj1y4wep6qPB5Zm33L+2/P6TcGWAJJbjA==", + "dependencies": { + "domhandler": "5.0.3", + "html-dom-parser": "4.0.0", + "react-property": "2.0.0", + "style-to-js": "1.1.4" + }, + "peerDependencies": { + "react": "0.14 || 15 || 16 || 17 || 18" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/htmlparser2": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.0.0.tgz", + "integrity": "sha512-uxbSI98wmFT/G4P2zXx4OVx04qWUmyFPrD2/CNepa2Zo3GPNaCaaxElDgwUrwYWkK1nr9fft0Ya8dws8coDLLQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", + "dev": true + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/include-media": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/include-media/-/include-media-2.0.0.tgz", + "integrity": "sha512-LSJcffPYIZ/Kln0rIi5UhqQbZxElDCMYA4dPC5MI1rkwwjptgEiOicHnzB0MMhMNJver0+4zULb4MKlgDyapZg==" + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz", + "integrity": "sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz", + "integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.3" + } + }, + "node_modules/jackspeak": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.3.tgz", + "integrity": "sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz", + "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.4", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.6.4" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz", + "integrity": "sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.6.3", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz", + "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "p-limit": "^3.1.0", + "pretty-format": "^29.6.3", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz", + "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==", + "dev": true, + "dependencies": { + "@jest/core": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz", + "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.6.4", + "@jest/types": "^29.6.3", + "babel-jest": "^29.6.4", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-diff": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz", + "integrity": "sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz", + "integrity": "sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz", + "integrity": "sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.6.3", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.6.4.tgz", + "integrity": "sha512-K6wfgUJ16DoMs02JYFid9lOsqfpoVtyJxpRlnTxUHzvZWBnnh2VNGRB9EC1Cro96TQdq5TtSjb3qUjNaJP9IyA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-node": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", + "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.6.3", + "jest-util": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.4.tgz", + "integrity": "sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.6.3", + "jest-worker": "^29.6.4", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz", + "integrity": "sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz", + "integrity": "sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.6.4", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz", + "integrity": "sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.6.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-mock": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz", + "integrity": "sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz", + "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.6.3", + "jest-validate": "^29.6.3", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz", + "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.6.4" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz", + "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==", + "dev": true, + "dependencies": { + "@jest/console": "^29.6.4", + "@jest/environment": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.6.3", + "jest-environment-node": "^29.6.4", + "jest-haste-map": "^29.6.4", + "jest-leak-detector": "^29.6.3", + "jest-message-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-util": "^29.6.3", + "jest-watcher": "^29.6.4", + "jest-worker": "^29.6.4", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz", + "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/globals": "^29.6.4", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-mock": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-snapshot": "^29.6.4", + "jest-util": "^29.6.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-snapshot": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.4.tgz", + "integrity": "sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.6.4", + "@jest/transform": "^29.6.4", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.6.4", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.6.4", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.6.4", + "jest-message-util": "^29.6.3", + "jest-util": "^29.6.3", + "natural-compare": "^1.4.0", + "pretty-format": "^29.6.3", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz", + "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz", + "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz", + "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.6.4", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.6.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.4.tgz", + "integrity": "sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.6.3", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.3.tgz", + "integrity": "sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==" + }, + "node_modules/jquery-ui-touch-punch": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/jquery-ui-touch-punch/-/jquery-ui-touch-punch-0.2.3.tgz", + "integrity": "sha512-Q/7aAd+SjbV0SspHO7Kuk96NJIbLwJAS0lD81U1PKcU2T5ZKayXMORH+Y5qvYLuy41xqVQbWimsRKDn1v3oI2Q==" + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/known-css-properties": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", + "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", + "dev": true + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.escape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", + "integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==", + "dev": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true + }, + "node_modules/lodash.invokemap": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz", + "integrity": "sha512-CfkycNtMqgUlfjfdh2BhKO/ZXrP8ePOX5lEU/g0R3ItJcnuxWDwokMGKx1hWcfOikmyOVx6X9IwWnDGlgKl61w==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.pullall": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.pullall/-/lodash.pullall-4.2.0.tgz", + "integrity": "sha512-VhqxBKH0ZxPpLhiu68YD1KnHmbhQJQctcipvmFnqIBDYzcIHzf3Zpu0tpeOKtR4x76p9yohc506eGdOjTmyIBg==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha512-+y4mDxU4rvXXu5UDSGCGNiesFmwCHuefGMoPCO1WYucNYj7DsLqrFaa2fXVI0H+NNiPTwwzKwspn9yTZqUGqng==", + "dev": true + }, + "node_modules/meow": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", + "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.2", + "camelcase-keys": "^7.0.0", + "decamelize": "^5.0.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.2", + "read-pkg-up": "^8.0.0", + "redent": "^4.0.0", + "trim-newlines": "^4.0.2", + "type-fest": "^1.2.2", + "yargs-parser": "^20.2.9" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", + "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mousetrap": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz", + "integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==" + }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/playwright-core": { + "version": "1.37.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz", + "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/postcss": { + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.0.tgz", + "integrity": "sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.0.tgz", + "integrity": "sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.0.tgz", + "integrity": "sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.0.tgz", + "integrity": "sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.0.tgz", + "integrity": "sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.0.tgz", + "integrity": "sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.3.tgz", + "integrity": "sha512-YgO/yhtevGO/vJePCQmTxiaEwER94LABZN0ZMT4A0vsak9TpO+RvKRs7EmJ8peIlB9xfXCsS7M8LjqncsUZ5HA==", + "dev": true, + "dependencies": { + "cosmiconfig": "^8.2.0", + "jiti": "^1.18.2", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-loader/node_modules/cosmiconfig": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.4.tgz", + "integrity": "sha512-SF+2P8+o/PTV05rgsAjDzL4OFdVXAulSfC/L19VaeVT7+tpOOSscCt2QLxDZ+CLxF2WOiq6y1K5asvs8qUJT/Q==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz", + "integrity": "sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.1.tgz", + "integrity": "sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.0.tgz", + "integrity": "sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.0.tgz", + "integrity": "sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA==", + "dev": true, + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^4.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.0.tgz", + "integrity": "sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^4.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.0.tgz", + "integrity": "sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.0.tgz", + "integrity": "sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.0.tgz", + "integrity": "sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.0.tgz", + "integrity": "sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.0.tgz", + "integrity": "sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.0.tgz", + "integrity": "sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.0.tgz", + "integrity": "sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.0.tgz", + "integrity": "sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.0.tgz", + "integrity": "sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.0.tgz", + "integrity": "sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.0.tgz", + "integrity": "sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg==", + "dev": true, + "dependencies": { + "cssnano-utils": "^4.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz", + "integrity": "sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.0.tgz", + "integrity": "sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", + "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.7.tgz", + "integrity": "sha512-xPv2GseoyXPa58Nro7M73ZntttusuCmZdeOojUFR5PZDz2BR62vfYx1w9TyOnp1+nYFowgOMipsCBhxzVkAEPw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-scss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.4.19" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.0.tgz", + "integrity": "sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.0.2" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.0.tgz", + "integrity": "sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", + "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.3.tgz", + "integrity": "sha512-KddyFewCsO0j3+np81IQ+SweXLDnDQTs5s67BOnrYmYe/yNmUhttQyGsYzy8yUnoljGAQ9sl38YB4vH8ur7Y+w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-avatar-editor": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/react-avatar-editor/-/react-avatar-editor-13.0.0.tgz", + "integrity": "sha512-0xw63MbRRQdDy7YI1IXU9+7tTFxYEFLV8CABvryYOGjZmXRTH2/UA0mafe57ns62uaEFX181kA4XlGlxCaeXKA==", + "dependencies": { + "@babel/plugin-transform-runtime": "^7.12.1", + "@babel/runtime": "^7.12.5", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.14.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-dropzone": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", + "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", + "dependencies": { + "attr-accept": "^2.2.2", + "file-selector": "^0.6.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/react-property": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.0.tgz", + "integrity": "sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==" + }, + "node_modules/react-redux": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.2.tgz", + "integrity": "sha512-xJKYI189VwfsFc4CJvHqHlDrzyFTY/3vZACbE+rr/zQ34Xx1wQfB4OTOSeOSNrF6BDVe8OOdxIrAnMGXA3ggfw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/read-pkg": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", + "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^3.0.2", + "parse-json": "^5.2.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", + "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0", + "read-pkg": "^6.0.0", + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/redent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", + "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", + "dev": true, + "dependencies": { + "indent-string": "^5.0.0", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", + "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, + "node_modules/reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", + "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", + "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "dev": true, + "dependencies": { + "glob": "^10.2.5" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sass": { + "version": "1.66.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz", + "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/sass-loader": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz", + "integrity": "sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==", + "dev": true, + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/select2": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/select2/-/select2-3.5.1.tgz", + "integrity": "sha512-IFX3UFPpPyK1I1Kuw1R1x+upMyNAZbMlkFhiTnRCRR7ii0KU1brmJMLa3GZcrMWCHiQlm0eKqb6i4XO4pqOrGQ==" + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz", + "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", + "integrity": "sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", + "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-generator": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", + "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "node_modules/stacktrace-gps": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", + "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "dependencies": { + "source-map": "0.5.6", + "stackframe": "^1.3.4" + } + }, + "node_modules/stacktrace-gps/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stacktrace-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", + "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "dependencies": { + "error-stack-parser": "^2.0.6", + "stack-generator": "^2.0.5", + "stacktrace-gps": "^3.0.4" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.9.tgz", + "integrity": "sha512-6i5hL3MqG/K2G43mWXWgP+qizFW/QH/7kCNN13JrJS5q48FN5IKksLDscexKP3dnmB6cdm9jlNgAsWNLpSykmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", + "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", + "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", + "dev": true + }, + "node_modules/style-to-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.4.tgz", + "integrity": "sha512-zEeU3vy9xL/hdLBFmzqjhm+2vJ1Y35V0ctDeB2sddsvN1856OdMZUCOOfKUn3nOjjEKr6uLhOnY4CrX6gLDRrA==", + "dependencies": { + "style-to-object": "0.4.2" + } + }, + "node_modules/style-to-object": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.2.tgz", + "integrity": "sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/stylehacks": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.0.tgz", + "integrity": "sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/stylelint": { + "version": "15.10.3", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.10.3.tgz", + "integrity": "sha512-aBQMMxYvFzJJwkmg+BUUg3YfPyeuCuKo2f+LOw7yYbU8AZMblibwzp9OV4srHVeQldxvSFdz0/Xu8blq2AesiA==", + "dev": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", + "@csstools/media-query-list-parser": "^2.1.4", + "@csstools/selector-specificity": "^3.0.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^8.2.0", + "css-functions-list": "^3.2.0", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.1", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^6.0.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.2.4", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.28.0", + "mathml-tag-names": "^2.1.3", + "meow": "^10.1.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.27", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^6.0.0", + "postcss-selector-parser": "^6.0.13", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "style-search": "^0.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz", + "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==", + "dev": true, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "34.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz", + "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^13.0.0" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "stylelint": "^15.10.0" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true + }, + "node_modules/stylelint/node_modules/cosmiconfig": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.4.tgz", + "integrity": "sha512-SF+2P8+o/PTV05rgsAjDzL4OFdVXAulSfC/L19VaeVT7+tpOOSscCt2QLxDZ+CLxF2WOiq6y1K5asvs8qUJT/Q==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/svgo": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", + "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.2.1", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tablesorter": { + "version": "2.31.3", + "resolved": "https://registry.npmjs.org/tablesorter/-/tablesorter-2.31.3.tgz", + "integrity": "sha512-ueEzeKiMajDcCWnUoT1dOeNEaS1OmPh9+8J0O2Sjp3TTijMygH74EA9QNJiNkLJqULyNU0RhbKY26UMUq9iurA==", + "dependencies": { + "jquery": ">=1.2.6" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/terser": { + "version": "5.19.4", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz", + "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/timepicker": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/timepicker/-/timepicker-1.14.1.tgz", + "integrity": "sha512-sNy0zVRacCNQ2bo4NLAG3+AX9ARxmH5IMqwZva9rzzFMJcfKfEnGzmDG7gMYeN5gbM76bzfZbld5WiWcshAUrw==", + "dependencies": { + "jquery": "^3.5.1" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, + "node_modules/tinymce": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-6.7.0.tgz", + "integrity": "sha512-Wf2RSobIXQ7XNw3/v4z1lPGiH3Pjsmc/6/7fG28aIS6uVWj/7IhvOPuwfJJDeOx0o0D3nSnoLHgR2KU8JAdE+w==" + }, + "node_modules/tinymce-i18n": { + "version": "23.8.28", + "resolved": "https://registry.npmjs.org/tinymce-i18n/-/tinymce-i18n-23.8.28.tgz", + "integrity": "sha512-qEYtBwEQwtgyn7meWSC6bCvt2o2GrONT5EpvPRU2fPSqCu1p8Ak+CNOVJmBZiRpyKwikerA1LAmkplgYVxpaYQ==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/trim-newlines": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", + "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", + "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ts-loader": { + "version": "9.4.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.4.tgz", + "integrity": "sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", + "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.3.1.tgz", + "integrity": "sha512-pphNW/msgOUSkJbH58x8sqpq8uQj6b0ZKGxEsLKMUnGorRcDjrUaLS+39+/ub41JNTwrrMyJcUB8+YZs3mbwqw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-scss-modules": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/typed-scss-modules/-/typed-scss-modules-7.1.4.tgz", + "integrity": "sha512-7IjCBxxnNPV5iY1b6Vz2HufXku04iYF8EmWIPkqWtVlM6cX+azKbSVhIIGImQtJSgMWUsOwdlcs0HoqFcYKYsw==", + "dev": true, + "dependencies": { + "bundle-require": "^3.0.4", + "chalk": "4.1.2", + "change-case": "^4.1.2", + "chokidar": "^3.5.3", + "css-modules-loader-core": "^1.1.0", + "esbuild": "^0.14.21", + "glob": "^7.2.0", + "joycon": "^3.1.1", + "reserved-words": "^0.1.2", + "slash": "^3.0.0", + "yargs": "^17.3.1" + }, + "bin": { + "typed-scss-modules": "dist/lib/cli.js" + }, + "peerDependencies": { + "node-sass": "^7.0.3 || ^8.0.0", + "sass": "^1.49.7" + }, + "peerDependenciesMeta": { + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/typed-scss-modules/node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/typed-scss-modules/node_modules/esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "node_modules/typed-scss-modules/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typedoc": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.1.tgz", + "integrity": "sha512-c2ye3YUtGIadxN2O6YwPEXgrZcvhlZ6HlhWZ8jQRNzwLPn2ylhdGqdR8HbyDRyALP8J6lmSANILCkkIdNPFxqA==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.3", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", + "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-memo-one": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/usehooks-ts": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/usehooks-ts/-/usehooks-ts-2.9.1.tgz", + "integrity": "sha512-2FAuSIGHlY+apM9FVlj8/oNhd+1y+Uwv5QNkMQz1oSfdHk4PXo1qoCw9I5M7j0vpH8CSWFJwXbVPeYDjLCx9PA==", + "engines": { + "node": ">=16.15.0", + "npm": ">=8" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.1.tgz", + "integrity": "sha512-jnd6EoYrf9yMxCyYDPj8eutJvtjQNp8PHmni/e/ulydHBWhT5J3menXt3HEkScsu9YqMAcG4CfFjs3rj5pVU1w==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "is-plain-object": "^5.0.0", + "lodash.debounce": "^4.0.8", + "lodash.escape": "^4.0.1", + "lodash.flatten": "^4.4.0", + "lodash.invokemap": "^4.6.0", + "lodash.pullall": "^4.2.0", + "lodash.uniqby": "^4.7.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-cli/node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-merge": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", + "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.0.tgz", + "integrity": "sha512-WR0RJE9Ehsio6U4TuM+LmunEsjQ5ncHlw4sn9ihD6RoJKZrVyH9FWV3dmnwu8B2aNib1OvG2X6adUCyFpQyWcg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zip-stream": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz", + "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==", + "dev": true, + "dependencies": { + "archiver-utils": "^4.0.1", + "compress-commons": "^5.0.1", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/zod": { + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", + "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.21.4.tgz", + "integrity": "sha512-fjUZh4nQ1s6HMccgIeE0VP4QG/YRGPmyjO9sAh890aQKPEk3nqbfUXhMFaC+Dr5KvYBm8BCyvfpZf2jY9aGSsw==", + "peerDependencies": { + "zod": "^3.21.4" + } + } + } +} diff --git a/smoke-tests/test/fixtures/large-install/package.json b/smoke-tests/test/fixtures/large-install/package.json new file mode 100644 index 0000000000000..c3a8ebdba35a9 --- /dev/null +++ b/smoke-tests/test/fixtures/large-install/package.json @@ -0,0 +1,134 @@ +{ + "name": "@npmcli/smoke-tests-max-listeners", + "version": "1.0.0", + "dependencies": { + "@emotion/react": "11.10.", + "@emotion/styled": "11.11.0", + "@fullcalendar/core": "6.1.8", + "@fullcalendar/daygrid": "6.1.8", + "@fullcalendar/list": "6.1.8", + "@fullcalendar/timegrid": "6.1.8", + "@hello-pangea/dnd": "16.3.0", + "@mui/icons-material": "5.14.8", + "@mui/material": "5.14.8", + "@mui/x-data-grid-pro": "6.12.1", + "@tanstack/react-query": "4.35.0", + "chart.js": "4.4.0", + "chartjs-adapter-date-fns": "3.0.0", + "date-fns": "2.30.0", + "detect-browser": "5.3.0", + "dropzone": "5.9.3", + "file-saver": "2.0.5", + "filesize": "10.0.12", + "floatthead": "2.2.5", + "html-react-parser": "4.2.2", + "html2canvas": "1.4.1", + "identity-obj-proxy": "3.0.0", + "include-media": "2.0.0", + "jquery": "3.7.1", + "jquery-ui-touch-punch": "0.2.3", + "js-cookie": "3.0.5", + "lodash": "4.17.21", + "mousetrap": "1.6.5", + "pretty-format": "29.6.3", + "react": "18.2.0", + "react-avatar-editor": "13.0.0", + "react-dom": "18.2.0", + "react-dropzone": "14.2.3", + "select2": "3.5.1", + "stacktrace-js": "2.0.2", + "tablesorter": "2.31.3", + "timepicker": "1.14.1", + "tinymce": "6.7.0", + "tinymce-i18n": "23.8.28", + "tslib": "2.6.2", + "usehooks-ts": "2.9.1", + "uuid": "9.0.0", + "zod": "3.22.2", + "zod-to-json-schema": "3.21.4" + }, + "devDependencies": { + "@playwright/test": "1.37.1", + "@total-typescript/ts-reset": "0.5.1", + "@tsconfig/node18-strictest": "1.0.0", + "@types/archiver": "5.3.2", + "@types/argparse": "2.0.10", + "@types/debug": "4.1.8", + "@types/detect-port": "1.3.3", + "@types/dropzone": "5.7.4", + "@types/express": "4.17.17", + "@types/file-saver": "2.0.5", + "@types/fs-extra": "11.0.1", + "@types/jest": "29.5.4", + "@types/jquery": "3.5.18", + "@types/jquery-monthpicker": "3.0.1", + "@types/jqueryui": "1.12.17", + "@types/js-cookie": "3.0.3", + "@types/lodash": "4.14.198", + "@types/mousetrap": "1.6.11", + "@types/react": "18.2.21", + "@types/react-avatar-editor": "13.0.0", + "@types/react-dom": "18.2.7", + "@types/select2": "3.5.6", + "@types/timepicker": "1.13.3", + "@types/uuid": "9.0.3", + "@types/webpack-bundle-analyzer": "4.6.0", + "@typescript-eslint/eslint-plugin": "6.6.0", + "@typescript-eslint/parser": "6.6.0", + "archiver": "6.0.1", + "argparse": "2.0.1", + "autoprefixer": "10.4.15", + "axios": "1.5.0", + "chalk": "4.1.2", + "copy-webpack-plugin": "11.0.0", + "cross-env": "7.0.3", + "css-loader": "6.8.1", + "css-minimizer-webpack-plugin": "5.0.1", + "debug": "4.3.4", + "detect-port": "1.5.1", + "esbuild": "0.19.2", + "esbuild-sass-plugin": "2.15.0", + "eslint": "8.48.0", + "eslint-import-resolver-webpack": "0.13.7", + "eslint-nibble": "8.1.0", + "eslint-plugin-import": "2.28.1", + "eslint-plugin-jest": "27.2.3", + "eslint-plugin-jsdoc": "46.5.1", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-playwright": "0.16.0", + "eslint-plugin-promise": "6.1.1", + "eslint-plugin-react": "7.33.2", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-stats": "1.0.1", + "express": "4.18.2", + "file-loader": "6.2.0", + "fs-extra": "11.1.1", + "glob": "10.3.4", + "jest": "29.6.4", + "jest-environment-jsdom": "29.6.4", + "jszip": "3.10.1", + "mini-css-extract-plugin": "2.7.6", + "postcss": "8.4.29", + "postcss-loader": "7.3.3", + "postcss-scss": "4.0.7", + "prettier": "3.0.3", + "rimraf": "5.0.1", + "sass": "1.66.1", + "sass-loader": "13.3.2", + "style-loader": "3.3.3", + "stylelint": "15.10.3", + "stylelint-config-standard": "34.0.0", + "terser-webpack-plugin": "5.3.9", + "ts-jest": "29.1.1", + "ts-loader": "9.4.4", + "ts-node": "10.9.1", + "type-fest": "4.3.1", + "typed-scss-modules": "7.1.4", + "typedoc": "0.25.1", + "typescript": "5.2.2", + "url-loader": "4.1.1", + "webpack": "5.88.2", + "webpack-bundle-analyzer": "4.9.1", + "webpack-cli": "5.1.4" + } +} diff --git a/smoke-tests/test/fixtures/promise-all-reject-late.json b/smoke-tests/test/fixtures/promise-all-reject-late.json deleted file mode 100644 index e243b92a3b92e..0000000000000 --- a/smoke-tests/test/fixtures/promise-all-reject-late.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "_id": "promise-all-reject-late", - "_rev": "1-bb2ac9479869cc8479d1dd01c568acc0", - "name": "promise-all-reject-late", - "dist-tags": { - "latest": "1.0.1" - }, - "versions": { - "1.0.0": { - "name": "promise-all-reject-late", - "version": "1.0.0", - "description": "Like Promise.all, but save rejections until all promises are resolved", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "https://izs.me" - }, - "license": "ISC", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "tap": "^14.10.5" - }, - "gitHead": "e9614a15b22f421aa97ff281d4e0f23681edbe98", - "_id": "promise-all-reject-late@1.0.0", - "_nodeVersion": "13.3.0", - "_npmVersion": "6.13.4", - "dist": { - "integrity": "sha512-f5XvVl++12pEo7Sv7f7FGfzVuVpeY2msNKjn7nNcXyOSKh5uVu7IAzDO6RE9hDVoHJhxvg+gqEacwkZ891Se5g==", - "shasum": "4fa37515e2d78c3b0462414402a8debce62b8b9f", - "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.0.tgz", - "fileCount": 7, - "unpackedSize": 123039, - "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeBmldCRA9TVsSAnZWagAAaigP/2CarvNCbglNS0dgjOoH\n7ZuFo1cG+N8BkZct00TyEJjuB+5UUmv9TSnZogfEOGutvMqUTSRhvm3fOWsJ\n7TXs8zJ6SotDR9+xlxqi/skpYXfRdNjdaMvo9kYO5jaV84pstdbl17sPeYXd\nCudbAKp1sYodlaJyqpyfUd2PWUNe/VGLODmjLogHB4/bevT3tdjsdauKrUS4\n3VFw8sS1Fwp7P2YneNIK3C1TY/Yb66KysZO23VsQemCQFKXpQJMa9B6yj8zs\n5BQp+W5tM70IfW6OXD0+Vt2jWr9jmKmoWVEiL5usJT3zD7vRbeH3xQvSEgDD\nskI8vH8iJ+3EbEOWTGlIu7mX88Dp2KnHOoRUkOR03WJWuGnsTC8Uyqi0F1Xd\nFeFlaeNzynR/R2LcdRNiFOM+1xtzfAtVGF7TIp9UjgJwSNNkEMlkNzQqSiC7\n/AeqsAYoBBNmYWY2fvXdS9HQ4HfIGjI++jCYWX4I7sUvOjqfcwlEz8MwromA\nqeBAFPdvnB0F/q/AOOLkcdsO81jES7ts0nB7bDt0rDbztWWq34BSMDnNoSDo\nDE9q8u7g68tQcr3WmOQr4ro10sSbJVJZmz8DSJKCbVJ+FN0+GM+49oyyhIFl\nOjokXn5U8ASEdiZnmFnt51dr9A4fyjhehotJA6qSs7t2fBe86VnufijC971U\nv3Jc\r\n=lLwf\r\n-----END PGP SIGNATURE-----\r\n" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "directories": {}, - "_npmOperationalInternal": { - "host": "s3://npm-registry-packages", - "tmp": "tmp/promise-all-reject-late_1.0.0_1577478492470_0.9438095135747766" - }, - "_hasShrinkwrap": false - }, - "1.0.1": { - "name": "promise-all-reject-late", - "version": "1.0.1", - "description": "Like Promise.all, but save rejections until all promises are resolved", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "https://izs.me" - }, - "license": "ISC", - "scripts": { - "test": "tap", - "preversion": "npm test", - "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" - }, - "tap": { - "check-coverage": true - }, - "devDependencies": { - "tap": "^14.10.5" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "gitHead": "c892a9db86650c9229ab4cc70395106684d6818a", - "_id": "promise-all-reject-late@1.0.1", - "_nodeVersion": "12.14.1", - "_npmVersion": "6.13.6", - "dist": { - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "shasum": "f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2", - "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "fileCount": 8, - "unpackedSize": 123171, - "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL65kCRA9TVsSAnZWagAAas4P/2WFFJvncp0LWb3DbE0t\ndx9BhZEwY3W8V6ug8uKvph24LoQp1PakkncscKS7PsCVHyIslD+fi6V99AmI\nOmL2ECAMUd5N69Cs8eTi4tKTNtUoIslfCu0+SMlCAF11D7oBXSabdOxGQofA\nuksoHdCqGM6M1y2BGjK7FR8dSwvgbQCPaUzazZ5w7w4XqVxDlzbvNj2E5mSF\n5HjlT5q239uNQppwPIFpisyi9DKa0ran2N7F2ioZ1PHvhFCqo6rmL8tAQsxQ\n+3OA4eFD0FJCJuqd3MOaY66mkncfNpmPvQYMyigKBUdJJyrgNsB67yfaFduy\ndK198Bnva5kotttQ4EHxM6gkqRm2d9o1/sYmAUtDELgrVDxzeNl+yG+nCkho\n1ta4cY+wy1dTjqAYaprQJ855nIeGGnr3tvz4dEGX/5eyh5K+oYVOYRFvWFX6\nVlEhBmSRqamfW5N1ndMyY18FM+Vc12yu66yZ3z1FqbgEGqdf3EP3lwWqClpP\nbPdXANzHM1FIz1PGHC7IZFWXH5KV1z+JXXahg/d8CLzz0PY6jaBt4c2xDvo7\nLaEAm7kNMbdewKvuTuG7x2Kqyf1KwjpOhXMrq6h0rlFm0pRt0xAArQ9Sglw8\n2Vq9Ic9EEsSIpzA5iQ86O1xkTREGHTB3uTRXUJixXIGkhLkhBB+Uj9y+GoOh\nX+Dm\r\n=yF+m\r\n-----END PGP SIGNATURE-----\r\n" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "_npmUser": { - "name": "isaacs", - "email": "i@izs.me" - }, - "directories": {}, - "_npmOperationalInternal": { - "host": "s3://npm-registry-packages", - "tmp": "tmp/promise-all-reject-late_1.0.1_1580183139628_0.5159334029276426" - }, - "_hasShrinkwrap": false - } - }, - "time": { - "created": "2019-12-27T20:28:12.428Z", - "1.0.0": "2019-12-27T20:28:12.645Z", - "modified": "2020-01-28T03:45:42.154Z", - "1.0.1": "2020-01-28T03:45:39.762Z" - }, - "maintainers": [ - { - "name": "isaacs", - "email": "i@izs.me" - } - ], - "description": "Like Promise.all, but save rejections until all promises are resolved", - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "https://izs.me" - }, - "license": "ISC", - "readme": "# promise-all-reject-late\n\nLike Promise.all, but save rejections until all promises are resolved.\n\nThis is handy when you want to do a bunch of things in parallel, and\nrollback on failure, without clobbering or conflicting with those parallel\nactions that may be in flight. For example, creating a bunch of files,\nand deleting any if they don't all succeed.\n\nExample:\n\n```js\nconst lateReject = require('promise-all-reject-late')\n\nconst { promisify } = require('util')\nconst fs = require('fs')\nconst writeFile = promisify(fs.writeFile)\n\nconst createFilesOrRollback = (files) => {\n return lateReject(files.map(file => writeFile(file, 'some data')))\n .catch(er => {\n // try to clean up, then fail with the initial error\n // we know that all write attempts are finished at this point\n return lateReject(files.map(file => rimraf(file)))\n .catch(er => {\n console.error('failed to clean up, youre on your own i guess', er)\n })\n .then(() => {\n // fail with the original error\n throw er\n })\n })\n}\n```\n\n## API\n\n* `lateReject([array, of, promises])` - Resolve all the promises,\n returning a promise that rejects with the first error, or resolves with\n the array of results, but only after all promises are settled.\n", - "readmeFilename": "README.md", - "_cached": false, - "_contentLength": 0 -} \ No newline at end of file diff --git a/smoke-tests/test/fixtures/promise-all-reject-late.min.json b/smoke-tests/test/fixtures/promise-all-reject-late.min.json deleted file mode 100644 index 699be7aaf2e82..0000000000000 --- a/smoke-tests/test/fixtures/promise-all-reject-late.min.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "promise-all-reject-late", - "dist-tags": { - "latest": "1.0.1" - }, - "versions": { - "1.0.0": { - "name": "promise-all-reject-late", - "version": "1.0.0", - "devDependencies": { - "tap": "^14.10.5" - }, - "dist": { - "integrity": "sha512-f5XvVl++12pEo7Sv7f7FGfzVuVpeY2msNKjn7nNcXyOSKh5uVu7IAzDO6RE9hDVoHJhxvg+gqEacwkZ891Se5g==", - "shasum": "4fa37515e2d78c3b0462414402a8debce62b8b9f", - "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.0.tgz", - "fileCount": 7, - "unpackedSize": 123039, - "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeBmldCRA9TVsSAnZWagAAaigP/2CarvNCbglNS0dgjOoH\n7ZuFo1cG+N8BkZct00TyEJjuB+5UUmv9TSnZogfEOGutvMqUTSRhvm3fOWsJ\n7TXs8zJ6SotDR9+xlxqi/skpYXfRdNjdaMvo9kYO5jaV84pstdbl17sPeYXd\nCudbAKp1sYodlaJyqpyfUd2PWUNe/VGLODmjLogHB4/bevT3tdjsdauKrUS4\n3VFw8sS1Fwp7P2YneNIK3C1TY/Yb66KysZO23VsQemCQFKXpQJMa9B6yj8zs\n5BQp+W5tM70IfW6OXD0+Vt2jWr9jmKmoWVEiL5usJT3zD7vRbeH3xQvSEgDD\nskI8vH8iJ+3EbEOWTGlIu7mX88Dp2KnHOoRUkOR03WJWuGnsTC8Uyqi0F1Xd\nFeFlaeNzynR/R2LcdRNiFOM+1xtzfAtVGF7TIp9UjgJwSNNkEMlkNzQqSiC7\n/AeqsAYoBBNmYWY2fvXdS9HQ4HfIGjI++jCYWX4I7sUvOjqfcwlEz8MwromA\nqeBAFPdvnB0F/q/AOOLkcdsO81jES7ts0nB7bDt0rDbztWWq34BSMDnNoSDo\nDE9q8u7g68tQcr3WmOQr4ro10sSbJVJZmz8DSJKCbVJ+FN0+GM+49oyyhIFl\nOjokXn5U8ASEdiZnmFnt51dr9A4fyjhehotJA6qSs7t2fBe86VnufijC971U\nv3Jc\r\n=lLwf\r\n-----END PGP SIGNATURE-----\r\n" - } - }, - "1.0.1": { - "name": "promise-all-reject-late", - "version": "1.0.1", - "devDependencies": { - "tap": "^14.10.5" - }, - "dist": { - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "shasum": "f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2", - "tarball": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "fileCount": 8, - "unpackedSize": 123171, - "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeL65kCRA9TVsSAnZWagAAas4P/2WFFJvncp0LWb3DbE0t\ndx9BhZEwY3W8V6ug8uKvph24LoQp1PakkncscKS7PsCVHyIslD+fi6V99AmI\nOmL2ECAMUd5N69Cs8eTi4tKTNtUoIslfCu0+SMlCAF11D7oBXSabdOxGQofA\nuksoHdCqGM6M1y2BGjK7FR8dSwvgbQCPaUzazZ5w7w4XqVxDlzbvNj2E5mSF\n5HjlT5q239uNQppwPIFpisyi9DKa0ran2N7F2ioZ1PHvhFCqo6rmL8tAQsxQ\n+3OA4eFD0FJCJuqd3MOaY66mkncfNpmPvQYMyigKBUdJJyrgNsB67yfaFduy\ndK198Bnva5kotttQ4EHxM6gkqRm2d9o1/sYmAUtDELgrVDxzeNl+yG+nCkho\n1ta4cY+wy1dTjqAYaprQJ855nIeGGnr3tvz4dEGX/5eyh5K+oYVOYRFvWFX6\nVlEhBmSRqamfW5N1ndMyY18FM+Vc12yu66yZ3z1FqbgEGqdf3EP3lwWqClpP\nbPdXANzHM1FIz1PGHC7IZFWXH5KV1z+JXXahg/d8CLzz0PY6jaBt4c2xDvo7\nLaEAm7kNMbdewKvuTuG7x2Kqyf1KwjpOhXMrq6h0rlFm0pRt0xAArQ9Sglw8\n2Vq9Ic9EEsSIpzA5iQ86O1xkTREGHTB3uTRXUJixXIGkhLkhBB+Uj9y+GoOh\nX+Dm\r\n=yF+m\r\n-----END PGP SIGNATURE-----\r\n" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - } - }, - "modified": "2020-01-28T03:45:42.154Z", - "_cached": false, - "_contentLength": 2803 -} \ No newline at end of file diff --git a/smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz b/smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz deleted file mode 100644 index 7da4044238766..0000000000000 Binary files a/smoke-tests/test/fixtures/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz and /dev/null differ diff --git a/smoke-tests/test/fixtures/server.js b/smoke-tests/test/fixtures/server.js deleted file mode 100644 index b1056a2219066..0000000000000 --- a/smoke-tests/test/fixtures/server.js +++ /dev/null @@ -1,49 +0,0 @@ -const { join, basename } = require('path') -const { existsSync, readFileSync } = require('fs') -const http = require('http') -const PORT = 12345 + (+process.env.TAP_CHILD_ID || 0) - -let server = null -const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' - -const start = () => new Promise((resolve) => { - server = http.createServer((req, res) => { - res.setHeader('connection', 'close') - - const f = join(__dirname, join('/', req.url.replace(/@/, '').replace(/%2f/i, '/'))) - - // a magic package that causes us to return an error that will be logged - if (basename(f) === 'fail_reflect_user_agent') { - res.statusCode = 404 - res.setHeader('npm-notice', req.headers['user-agent']) - return res.end() - } - - const isCorgi = req.headers.accept.includes('application/vnd.npm.install-v1+json') - const file = f + ( - isCorgi && existsSync(`${f}.min.json`) ? '.min.json' - : existsSync(`${f}.json`) ? '.json' - : existsSync(`${f}/index.json`) ? 'index.json' - : '' - ) - - try { - const body = readFileSync(file) - res.setHeader('content-length', body.length) - res.setHeader('content-type', /\.min\.json$/.test(file) ? corgiDoc - : /\.json$/.test(file) ? 'application/json' - : 'application/octet-stream') - res.end(body) - } catch { - res.statusCode = 500 - res.setHeader('content-type', 'text/plain') - res.end('bad') - } - }).listen(PORT, resolve) -}) - -module.exports = { - start, - stop: () => server.close(), - registry: `http://localhost:${PORT}/`, -} diff --git a/smoke-tests/test/fixtures/setup.js b/smoke-tests/test/fixtures/setup.js new file mode 100644 index 0000000000000..2d0c54c984243 --- /dev/null +++ b/smoke-tests/test/fixtures/setup.js @@ -0,0 +1,276 @@ +const fs = require('node:fs/promises') +const { existsSync } = require('node:fs') +const { join, resolve, sep, extname, relative, delimiter } = require('node:path') +const which = require('which') +const spawn = require('@npmcli/promise-spawn') +const MockRegistry = require('@npmcli/mock-registry') +const http = require('node:http') +const { createProxy } = require('proxy') + +const { SMOKE_PUBLISH_TARBALL, CI, PATH, Path } = process.env + +const DEFAULT_REGISTRY = new URL('https://registry.npmjs.org/') +const MOCK_REGISTRY = new URL('http://smoke-test-registry.club/') + +const NODE_PATH = process.execPath +const CLI_ROOT = resolve(process.cwd(), '..') +const CLI_JS_BIN = join('bin', 'npm-cli.js') +const NPM_PATH = join(CLI_ROOT, CLI_JS_BIN) + +const WINDOWS = process.platform === 'win32' +const GLOBAL_BIN = WINDOWS ? '' : 'bin' +const GLOBAL_NODE_MODULES = join(WINDOWS ? '' : 'lib', 'node_modules') + +const getOpts = (...a) => { + const [opts, args] = a.reduce((acc, arg) => { + acc[typeof arg === 'object' ? 0 : 1].push(arg) + return acc + }, [[], []]) + return [Object.assign({}, ...opts), args] +} + +const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') + +const testdirHelper = (obj) => { + for (const [key, value] of Object.entries(obj)) { + if (extname(key) === '.json') { + obj[key] = JSON.stringify(value, null, 2) + } else if (typeof value === 'object') { + obj[key] = testdirHelper(value) + } else { + obj[key] = value + } + } + return obj +} + +const getNpmRoot = (r) => { + return r.stdout + .split('\n') + .slice(-1)[0] + .match(/^npm@.*?\s(.*)$/) + ?.[1] +} + +const getCleanPaths = async () => { + const cliBin = join('bin', 'npm') + const npmLinks = await which('npm', { all: true }) + const npmPaths = await Promise.all(npmLinks.map(npm => fs.realpath(npm))) + + const cleanNpmPaths = [...new Set([ + CLI_ROOT, + join(CLI_ROOT, cliBin), + join(CLI_ROOT, CLI_JS_BIN), + ...npmLinks, + ...npmPaths, + ...npmPaths.map(n => n.replace(sep + cliBin, '')), + ...npmPaths.map(n => n.replace(sep + CLI_JS_BIN, '')), + ])] + + return Object.entries({ + NODE: NODE_PATH, + NPM: cleanNpmPaths, + }) +} + +module.exports = async (t, { + testdir = {}, debug, mockRegistry = true, strictRegistryNock = true, useProxy = false, +} = {}) => { + const debugLog = debug || CI ? (...a) => t.comment(...a) : () => {} + debugLog({ SMOKE_PUBLISH_TARBALL, CI }) + + const cleanPaths = await getCleanPaths() + + // setup fixtures + const root = t.testdir({ + cache: {}, + project: { '.npmrc': '' }, + global: { '.npmrc': '' }, + home: { '.npmrc': '' }, + ...testdirHelper(testdir), + }) + const paths = { + root, + project: join(root, 'project'), + global: join(root, 'global'), + home: join(root, 'home'), + userConfig: join(root, 'home', '.npmrc'), + globalConfig: join(root, 'global', '.npmrc'), + cache: join(root, 'cache'), + globalBin: join(root, 'global', GLOBAL_BIN), + globalNodeModules: join(root, 'global', GLOBAL_NODE_MODULES), + } + + const registry = !mockRegistry ? DEFAULT_REGISTRY : new MockRegistry({ + tap: t, + registry: MOCK_REGISTRY, + debug, + strict: strictRegistryNock, + }) + + const proxyEnv = {} + if (useProxy || mockRegistry) { + useProxy = true + const proxyServer = createProxy(http.createServer()) + await new Promise(res => proxyServer.listen(0, res)) + t.teardown(() => proxyServer.close()) + proxyEnv.HTTP_PROXY = new URL(`http://localhost:${proxyServer.address().port}`) + } + + // update notifier should never be written + t.afterEach((t) => { + t.equal(existsSync(join(paths.cache, '_update-notifier-last-checked')), false) + }) + + const cleanOutput = s => { + // sometimes we print normalized paths in snapshots regardless of + // platform so replace those first then replace platform style paths + for (const [key, value] of cleanPaths) { + const values = [].concat(value) + for (const v of values) { + s = s.split(normalizePath(v)).join(`{${key}}`) + } + } + for (const [key, value] of cleanPaths) { + const values = [].concat(value) + for (const v of values) { + s = s.split(v).join(`{${key}}`) + } + } + return s + .split(relative(CLI_ROOT, t.testdirName)).join('{TESTDIR}') + .split(registry.origin).join('{REGISTRY}') + .replace(/\\+/g, '/') + .replace(/\r\n/g, '\n') + .replace(/ \(in a browser\)/g, '') + .replace(/^npm@.* /gm, 'npm ') + .replace(/[0-9TZ_-]*debug-[0-9]+.log$/gm, '{LOG}') + .replace(/in \d+[ms]+$/gm, 'in {TIME}') + } + const log = (...a) => debugLog(cleanOutput(a.join(' '))) + t.cleanSnapshot = cleanOutput + + const getPath = () => `${paths.globalBin}${delimiter}${Path || PATH}` + const getEnvPath = () => ({ [Path ? 'Path' : 'PATH']: getPath() }) + + const baseSpawn = async (spawnCmd, spawnArgs, { + cwd = paths.project, + env, + ...opts } = {} + ) => { + log(`CWD: ${cwd}`) + log(`${spawnCmd} ${spawnArgs.join(' ')}`) + log('-'.repeat(40)) + + const p = spawn(spawnCmd, spawnArgs, { + cwd, + env: { + ...getEnvPath(), + HOME: paths.root, + ComSpec: process.env.ComSpec, + ...env, + }, + ...opts, + }) + + // In debug mode, stream stdout and stderr to console so we can debug hanging processes + p.process.stdout.on('data', (c) => log(c.toString().trim())) + p.process.stderr.on('data', (c) => log(c.toString().trim())) + + const { stdout, stderr } = await p + log('='.repeat(40)) + + return { stderr, stdout } + } + + const baseNpm = async (...a) => { + const [{ cwd, cmd, argv = [], proxy = useProxy, ...opts }, args] = getOpts(...a) + + const isGlobal = args.some(arg => ['-g', '--global', '--global=true'].includes(arg)) + + const defaultFlags = [ + `--registry=${registry.origin}`, + `--cache=${paths.cache}`, + `--prefix=${isGlobal ? paths.global : cwd}`, + `--userconfig=${paths.userConfig}`, + `--globalconfig=${paths.globalConfig}`, + '--no-audit', + '--no-update-notifier', + '--loglevel=silly', + '--fetch-retries=0', + ].filter(Boolean) + + const cliArgv = args.reduce((acc, arg) => { + if (arg.startsWith('-')) { + acc[1].push(arg) + } else { + acc[0].push(arg) + } + return acc + }, [[], defaultFlags]).reduce((acc, i) => acc.concat(i), []) + + return baseSpawn(cmd, [...argv, ...cliArgv], { + cwd, + env: { + ...opts.env, + ...proxy ? proxyEnv : {}, + }, + ...opts, + }) + } + + const npmLocal = async (...args) => { + const [{ force = false }] = getOpts(...args) + if (SMOKE_PUBLISH_TARBALL && !force) { + throw new Error('npmLocal cannot be called during smoke-publish') + } + return baseNpm({ + cwd: CLI_ROOT, + cmd: process.execPath, + argv: ['.'], + proxy: false, + }, ...args) + } + + const npmPath = async (...args) => baseNpm({ + cwd: paths.project, + cmd: 'npm', + shell: true, + }, ...args) + + const npm = async (...args) => baseNpm({ + cwd: paths.project, + cmd: process.execPath, + argv: [NPM_PATH], + }, ...args) + + // helpers for reading/writing files and their source + const readFile = async (f) => { + const file = await fs.readFile(join(paths.project, f), 'utf-8') + return extname(f) === '.json' ? JSON.parse(file) : file + } + + return { + npmPath, + npmLocal, + npm: SMOKE_PUBLISH_TARBALL ? npmPath : npm, + spawn: baseSpawn, + readFile, + getPath, + paths, + registry, + npmLocalTarball: async () => SMOKE_PUBLISH_TARBALL ?? + npmLocal('pack', `--pack-destination=${root}`).then(r => { + const output = r.stdout.trim().split('\n') + return join(root, output[output.length - 1]) + }), + } +} + +module.exports.testdir = testdirHelper +module.exports.getNpmRoot = getNpmRoot +module.exports.CLI_ROOT = CLI_ROOT +module.exports.WINDOWS = WINDOWS +module.exports.SMOKE_PUBLISH = !!SMOKE_PUBLISH_TARBALL +module.exports.SMOKE_PUBLISH_TARBALL = SMOKE_PUBLISH_TARBALL +module.exports.MOCK_REGISTRY = MOCK_REGISTRY diff --git a/smoke-tests/test/index.js b/smoke-tests/test/index.js index bbb833a5728c8..0daf28ae9bf6c 100644 --- a/smoke-tests/test/index.js +++ b/smoke-tests/test/index.js @@ -1,360 +1,407 @@ -const { readFileSync, realpathSync, mkdirSync, existsSync, writeFileSync } = require('fs') -const spawn = require('@npmcli/promise-spawn') -const { join, resolve, sep } = require('path') +const { join } = require('node:path') const t = require('tap') -const rimraf = require('rimraf') -const which = require('which').sync -const { start, stop, registry } = require('./fixtures/server.js') - -const { SMOKE_PUBLISH_NPM, CI, PATH } = process.env -const log = CI ? console.error : () => {} - -const cwd = resolve(__dirname, '..', '..') -const npmCli = join('bin', 'npm-cli.js') -const execArgv = SMOKE_PUBLISH_NPM ? ['npm'] : [process.execPath, join(cwd, npmCli)] -const npmDir = SMOKE_PUBLISH_NPM ? realpathSync(which('npm')).replace(sep + npmCli, '') : cwd - -// setup server -t.before(start) -t.teardown(stop) -// update notifier should never be written -t.afterEach((t) => { - const updateExists = existsSync(join(cacheLocation, '_update-notifier-last-checked')) - t.equal(updateExists, false) -}) - -const readFile = filename => readFileSync(resolve(localPrefix, filename), 'utf-8') -const normalizePath = path => path.replace(/[A-Z]:/, '').replace(/\\/g, '/') - -t.cleanSnapshot = s => - s - // sometimes we print normalized paths in snapshots regardless of - // platform so replace those first - .split(normalizePath(npmDir)) - .join('{CWD}') - .split(normalizePath(cwd)) - .join('{CWD}') - .split(registry) - .join('https://registry.npmjs.org/') - .split(normalizePath(process.execPath)) - .join('node') - // then replace platform style paths - .split(npmDir) - .join('{CWD}') - .split(cwd) - .join('{CWD}') - .replace(/\\+/g, '/') - .replace(/\r\n/g, '\n') - .replace(/ \(in a browser\)/g, '') - .replace(/^npm@.* /gm, 'npm ') - .replace(/^.*debug-[0-9]+.log$/gm, '') - -// setup fixtures -const path = t.testdir({ - '.npmrc': '', - cache: {}, - project: {}, - bin: {}, -}) -const localPrefix = resolve(path, 'project') -const userconfigLocation = resolve(path, '.npmrc') -const cacheLocation = resolve(path, 'cache') -const binLocation = resolve(path, 'bin') - -const exec = async (...args) => { - const cmd = [] - const opts = [ - `--registry=${registry}`, - `--cache=${cacheLocation}`, - `--userconfig=${userconfigLocation}`, - '--no-audit', - '--no-update-notifier', - '--loglevel=silly', - ] - for (const arg of args) { - if (arg.startsWith('--')) { - opts.push(arg) - } else { - cmd.push(arg) - } - } - - // XXX: not sure why outdated fails with no-workspaces but works without it - if (!opts.includes('--workspaces') && cmd[0] !== 'outdated') { - // This is required so we dont detect any workspace roots above the testdir - opts.push('--no-workspaces') - } - - const spawnArgs = [execArgv[0], [...execArgv.slice(1), ...cmd, ...opts]] - log([spawnArgs[0], ...spawnArgs[1]].join(' ')) - - const res = await spawn(...spawnArgs, { - cwd: localPrefix, - env: { - HOME: path, - PATH: `${PATH}:${binLocation}`, +const setup = require('./fixtures/setup.js') + +t.test('basic', async t => { + const { registry, npm, npmPath, npmLocal, readFile, paths } = await setup(t, { + testdir: { + packages: { + 'abbrev-1.0.4': { + 'package.json': { name: 'abbrev', version: '1.0.4' }, + 'index.js': 'module.exports = "1.0.4"', + }, + 'abbrev-1.1.1': { + 'package.json': { name: 'abbrev', version: '1.1.1' }, + 'index.js': 'module.exports = "1.1.1"', + }, + 'promise-all-reject-late': { + 'package.json': { name: 'promise-all-reject-late', version: '5.0.0' }, + 'index.js': 'module.exports = null', + }, + 'exec-test-1.0.0': { + 'package.json': { name: 'exec-test', version: '1.0.0', bin: { 'exec-test': 'run.sh' } }, + 'index.js': 'module.exports = "1.0.0"', + 'run.sh': 'echo 1.0.0', + }, + 'exec-test-1.0.1': { + 'package.json': { name: 'exec-test', version: '1.0.1', bin: { 'exec-test': 'run.sh' } }, + 'index.js': 'module.exports = "1.0.1"', + 'run.sh': 'echo 1.0.1', + }, + }, }, - stdioString: true, - encoding: 'utf-8', }) - log(res.stderr) - return res.stdout -} - -// this test must come first, its package.json will be destroyed and the one -// created in the next test (npm init) will create a new one that must be -// present for later tests -t.test('npm install sends correct user-agent', async t => { - const pkgPath = join(localPrefix, 'package.json') - const pkgContent = JSON.stringify({ - name: 'smoke-test-workspaces', - workspaces: ['packages/*'], - }) - writeFileSync(pkgPath, pkgContent, { encoding: 'utf8' }) + const abbrevManifest = () => registry.manifest({ name: 'abbrev', versions: ['1.0.4', '1.1.1'] }) - const wsRoot = join(localPrefix, 'packages') - mkdirSync(wsRoot) + await t.test('npm init', async t => { + const cmdRes = await npm('init', '-y') - const wsPath = join(wsRoot, 'foo') - mkdirSync(wsPath) + t.matchSnapshot(cmdRes.stdout, 'should have successful npm init result') + const pkg = await readFile('package.json') + t.equal(pkg.name, 'project', 'should have expected generated name') + t.equal(pkg.version, '1.0.0', 'should have expected generated version') + }) - const wsPkgPath = join(wsPath, 'package.json') - const wsContent = JSON.stringify({ - name: 'foo', + await t.test('npm root', async t => { + const npmRoot = await npm('help').then(setup.getNpmRoot) + + if (setup.SMOKE_PUBLISH) { + const globalNpmRoot = await npmPath('help').then(setup.getNpmRoot) + t.rejects(npmLocal('help'), 'npm local rejects during smoke publish') + t.not(npmRoot, setup.CLI_ROOT, 'npm root is not the local source dir') + t.equal( + npmRoot, + globalNpmRoot, + 'during smoke publish, npm root and global root are equal' + ) + } else { + t.equal( + await npmLocal('help').then(setup.getNpmRoot), + setup.CLI_ROOT, + 'npm local root is the local source dir' + ) + t.equal(npmRoot, setup.CLI_ROOT, 'npm root is the local source dir') + } }) - writeFileSync(wsPkgPath, wsContent, { encoding: 'utf8' }) - t.teardown(() => rimraf.sync(`${localPrefix}/*`)) - await t.rejects( - exec('install', 'fail_reflect_user_agent'), - { - stderr: /workspaces\/false/, - }, - 'workspaces/false is present in output' - ) + await t.test('npm --version', async t => { + const v = await npm('--version').then(r => r.stdout.trim()) - await t.rejects( - exec('install', 'fail_reflect_user_agent', '--workspaces'), - { - stderr: /workspaces\/true/, - }, - 'workspaces/true is present in output' - ) -}) + if (setup.SMOKE_PUBLISH) { + t.match(v, /-[0-9a-f]{40}\.\d$/, 'must have a git version') + } else { + t.match(v, /^\d+\.\d+\.\d+/, 'has a version') + } + }) -t.test('npm init', async t => { - const cmdRes = await exec('init', '-y') + await t.test('npm (no args)', async t => { + const err = await npm('--loglevel=notice').catch(e => e) - t.matchSnapshot(cmdRes, 'should have successful npm init result') - const pkg = JSON.parse(readFileSync(resolve(localPrefix, 'package.json'))) - t.equal(pkg.name, 'project', 'should have expected generated name') - t.equal(pkg.version, '1.0.0', 'should have expected generated version') -}) + t.equal(err.code, 1, 'should exit with error code') + t.equal(err.stderr, '', 'should have no stderr output') + t.matchSnapshot(err.stdout, 'should have expected no args output') + }) -t.test('npm --version', async t => { - const v = await exec('--version') + await t.test('npm install prodDep@version', async t => { + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + tarballs: { '1.0.4': join(paths.root, 'packages', 'abbrev-1.0.4') }, + }) - if (SMOKE_PUBLISH_NPM) { - t.match(v.trim(), /-[0-9a-f]{40}\.\d$/, 'must have a git version') - } else { - t.skip('not checking version') - } -}) + const cmdRes = await npm('install', 'abbrev@1.0.4') -t.test('npm (no args)', async t => { - const err = await exec('--loglevel=notice').catch(e => e) + t.matchSnapshot(cmdRes.stdout, 'should have expected install reify output') + t.resolveMatchSnapshot(readFile('package.json'), 'should have expected package.json result') + t.resolveMatchSnapshot(readFile('package-lock.json'), 'should have expected lockfile result') + }) - t.equal(err.code, 1, 'should exit with error code') - t.equal(err.stderr, '', 'should have no stderr output') - t.matchSnapshot(err.stdout, 'should have expected no args output') -}) + await t.test('npm install dev dep', async t => { + const manifest = registry.manifest({ + name: 'promise-all-reject-late', + packuments: [{ version: '5.0.0', funding: 'https://github.com/sponsors' }], + }) + await registry.package({ + manifest: manifest, + tarballs: { '5.0.0': join(paths.root, 'packages', 'promise-all-reject-late') }, + }) + + const cmdRes = await npm('install', 'promise-all-reject-late', '-D') + + t.matchSnapshot(cmdRes.stdout, 'should have expected dev dep added reify output') + t.resolveMatchSnapshot( + readFile('package.json'), + 'should have expected dev dep added package.json result' + ) + t.resolveMatchSnapshot( + readFile('package-lock.json'), + 'should have expected dev dep added lockfile result' + ) + }) -t.test('npm install prodDep@version', async t => { - const cmdRes = await exec('install', 'abbrev@1.0.4') + await t.test('npm ls', async t => { + const cmdRes = await npm('ls') - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected install reify output') - t.matchSnapshot(readFile('package.json'), 'should have expected package.json result') - t.matchSnapshot(readFile('package-lock.json'), 'should have expected lockfile result') -}) + t.matchSnapshot(cmdRes.stdout, 'should have expected ls output') + }) -t.test('npm install dev dep', async t => { - const cmdRes = await exec('install', 'promise-all-reject-late', '-D') - - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected dev dep added reify output') - t.matchSnapshot( - readFile('package.json'), - 'should have expected dev dep added package.json result' - ) - t.matchSnapshot( - readFile('package-lock.json'), - 'should have expected dev dep added lockfile result' - ) -}) + await t.test('npm fund', async t => { + const cmdRes = await npm('fund') -t.test('npm ls', async t => { - const cmdRes = await exec('ls') + t.matchSnapshot(cmdRes.stdout, 'should have expected fund output') + }) - t.matchSnapshot(cmdRes, 'should have expected ls output') -}) + await t.test('npm explain', async t => { + const cmdRes = await npm('explain', 'abbrev') -t.test('npm fund', async t => { - const cmdRes = await exec('fund') + t.matchSnapshot(cmdRes.stdout, 'should have expected explain output') + }) - t.matchSnapshot(cmdRes, 'should have expected fund output') -}) + await t.test('npm diff', async t => { + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + tarballs: { '1.0.4': join(paths.root, 'packages', 'abbrev-1.0.4') }, + }) + await registry.package({ + manifest: manifest, + tarballs: { '1.1.1': join(paths.root, 'packages', 'abbrev-1.1.1') }, + }) -t.test('npm explain', async t => { - const cmdRes = await exec('explain', 'abbrev') + const cmdRes = await npm('diff', '--diff=abbrev@1.0.4', '--diff=abbrev@1.1.1') - t.matchSnapshot(cmdRes, 'should have expected explain output') -}) + t.matchSnapshot(cmdRes.stdout, 'should have expected diff output') + }) -t.test('npm diff', async t => { - const cmdRes = await exec('diff', '--diff=abbrev@1.0.4', '--diff=abbrev@1.1.1') + await t.test('npm outdated', async t => { + await registry.package({ + manifest: registry.manifest({ + name: 'promise-all-reject-late', + versions: ['5.0.0'], + }), + }) + await registry.package({ + manifest: abbrevManifest(), + }) + + const outdated = await npm('outdated').catch(e => e) + + t.equal(outdated.code, 1, 'should exit with error code') + t.not(outdated.stderr, '', 'should have stderr output') + t.matchSnapshot(outdated.stdout, 'should have expected outdated output') + }) - t.matchSnapshot(cmdRes, 'should have expected diff output') -}) + await t.test('npm pkg set scripts', async t => { + const cmdRes = await npm('pkg', 'set', 'scripts.hello=echo Hello') -t.test('npm outdated', async t => { - const err = await exec('outdated').catch(e => e) + t.matchSnapshot(cmdRes.stdout, 'should have expected set-script output') + t.resolveMatchSnapshot( + readFile('package.json'), + 'should have expected script added package.json result' + ) + }) - t.equal(err.code, 1, 'should exit with error code') - t.not(err.stderr, '', 'should have stderr output') - t.matchSnapshot(err.stdout, 'should have expected outdated output') -}) + await t.test('npm run', async t => { + const cmdRes = await npm('run-script', 'hello') -t.test('npm set-script', async t => { - const cmdRes = await exec('set-script', 'hello', 'echo Hello') + t.matchSnapshot(cmdRes.stdout, 'should have expected run output') + }) - t.matchSnapshot(cmdRes, 'should have expected set-script output') - t.matchSnapshot( - readFile('package.json'), - 'should have expected script added package.json result' - ) -}) + await t.test('npm prefix', async t => { + const cmdRes = await npm('prefix') -t.test('npm run-script', async t => { - const cmdRes = await exec('run', 'hello') + t.matchSnapshot(cmdRes.stdout, 'should have expected prefix output') + }) - t.matchSnapshot(cmdRes, 'should have expected run-script output') -}) + await t.test('npm view', async t => { + await registry.package({ + manifest: abbrevManifest(), + }) + const cmdRes = await npm('view', 'abbrev@1.0.4') -t.test('npm prefix', async t => { - const cmdRes = await exec('prefix') + t.matchSnapshot(cmdRes.stdout, 'should have expected view output') + }) - t.matchSnapshot(cmdRes, 'should have expected prefix output') -}) + await t.test('npm update dep', async t => { + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + tarballs: { + '1.1.1': join(paths.root, 'packages', 'abbrev-1.1.1'), + }, + }) + + const cmdRes = await npm('update', 'abbrev') + + t.matchSnapshot(cmdRes.stdout, 'should have expected update reify output') + t.resolveMatchSnapshot(readFile('package.json'), + 'should have expected update package.json result') + t.resolveMatchSnapshot(readFile('package-lock.json'), + 'should have expected update lockfile result') + }) -t.test('npm view', async t => { - const cmdRes = await exec('view', 'abbrev@1.0.4') + await t.test('npm uninstall', async t => { + const cmdRes = await npm('uninstall', 'promise-all-reject-late') - t.matchSnapshot(cmdRes, 'should have expected view output') -}) + t.matchSnapshot(cmdRes.stdout, 'should have expected uninstall reify output') + t.resolveMatchSnapshot(readFile('package.json'), + 'should have expected uninstall package.json result') + t.resolveMatchSnapshot(readFile('package-lock.json'), + 'should have expected uninstall lockfile result') + }) -t.test('npm update dep', async t => { - const cmdRes = await exec('update', 'abbrev') + await t.test('npm pkg', async t => { + let cmdRes = await npm('pkg', 'get', 'license') + t.matchSnapshot(cmdRes.stdout, 'should have expected pkg get output') - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected update reify output') - t.matchSnapshot(readFile('package.json'), 'should have expected update package.json result') - t.matchSnapshot(readFile('package-lock.json'), 'should have expected update lockfile result') -}) + cmdRes = await npm('pkg', 'set', 'tap[test-env][0]=LC_ALL=sk') + t.matchSnapshot(cmdRes.stdout, 'should have expected pkg set output') -t.test('npm uninstall', async t => { - const cmdRes = await exec('uninstall', 'promise-all-reject-late') + t.resolveMatchSnapshot( + readFile('package.json'), + 'should have expected npm pkg set modified package.json result' + ) - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected uninstall reify output') - t.matchSnapshot(readFile('package.json'), 'should have expected uninstall package.json result') - t.matchSnapshot(readFile('package-lock.json'), 'should have expected uninstall lockfile result') -}) + cmdRes = await npm('pkg', 'get') + t.matchSnapshot(cmdRes.stdout, 'should print package.json contents') -t.test('npm pkg', async t => { - let cmdRes = await exec('pkg', 'get', 'license') - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg get output') + cmdRes = await npm('pkg', 'delete', 'tap') + t.matchSnapshot(cmdRes.stdout, 'should have expected pkg delete output') - cmdRes = await exec('pkg', 'set', 'tap[test-env][0]=LC_ALL=sk') - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg set output') + t.resolveMatchSnapshot( + readFile('package.json'), + 'should have expected npm pkg delete modified package.json result' + ) + }) - t.matchSnapshot( - readFile('package.json'), - 'should have expected npm pkg set modified package.json result' - ) + await t.test('npm update --no-save --no-package-lock', async t => { + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + tarballs: { + '1.0.4': join(paths.root, 'packages', 'abbrev-1.0.4'), + }, + }) + + // setup, manually reset dep value + await npm('pkg', 'set', 'dependencies.abbrev==1.0.4') + await npm('install') + + await registry.package({ + manifest: manifest, + tarballs: { + '1.1.1': join(paths.root, 'packages', 'abbrev-1.1.1'), + }, + }) + + await npm('pkg', 'set', 'dependencies.abbrev=^1.0.4') + await npm('update', '--no-save', '--no-package-lock') + + t.equal( + (await readFile('package.json')).dependencies.abbrev, + '^1.0.4', + 'should have expected update --no-save --no-package-lock package.json result' + ) + t.equal( + (await readFile('package-lock.json')).packages['node_modules/abbrev'].version, + '1.0.4', + 'should have expected update --no-save --no-package-lock lockfile result' + ) + t.equal( + (await readFile('node_modules/abbrev/package.json')).version, + '1.1.1', + 'actual installed version is 1.1.1' + ) + }) - cmdRes = await exec('pkg', 'get') - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should print package.json contents') + await t.test('npm update --no-save', async t => { + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + }) + + await npm('update', '--no-save') + + t.equal( + (await readFile('package.json')).dependencies.abbrev, + '^1.0.4', + 'should have expected update --no-save package.json result' + ) + t.equal( + (await readFile('package-lock.json')).packages['node_modules/abbrev'].version, + '1.1.1', + 'should have expected update --no-save lockfile result' + ) + }) - cmdRes = await exec('pkg', 'delete', 'tap') - t.matchSnapshot(cmdRes.replace(/in.*s/, ''), 'should have expected pkg delete output') + await t.test('npm update --save', async t => { + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + }) + + await npm('update', '--save') + + t.equal( + (await readFile('package.json')).dependencies.abbrev, + '^1.1.1', + 'should have expected update --save package.json result' + ) + t.equal( + (await readFile('package-lock.json')).packages['node_modules/abbrev'].version, + '1.1.1', + 'should have expected update --save lockfile result' + ) + }) - t.matchSnapshot( - readFile('package.json'), - 'should have expected npm pkg delete modified package.json result' - ) -}) + await t.test('npm ci', async t => { + await npm('uninstall', 'abbrev') -t.test('npm update --no-save --no-package-lock', async t => { - // setup, manually reset dep value - await exec('pkg', 'set', 'dependencies.abbrev==1.0.4') - await exec(`install`) - await exec('pkg', 'set', 'dependencies.abbrev=^1.0.4') - - await exec('update', '--no-save', '--no-package-lock') - - t.equal( - JSON.parse(readFile('package.json')).dependencies.abbrev, - '^1.0.4', - 'should have expected update --no-save --no-package-lock package.json result' - ) - t.equal( - JSON.parse(readFile('package-lock.json')).packages['node_modules/abbrev'].version, - '1.0.4', - 'should have expected update --no-save --no-package-lock lockfile result' - ) -}) + const manifest = abbrevManifest() + await registry.package({ + manifest: manifest, + tarballs: { + '1.0.4': join(paths.root, 'packages', 'abbrev-1.0.4'), + }, + }) -t.test('npm update --no-save', async t => { - await exec('update', '--no-save') - - t.equal( - JSON.parse(readFile('package.json')).dependencies.abbrev, - '^1.0.4', - 'should have expected update --no-save package.json result' - ) - t.equal( - JSON.parse(readFile('package-lock.json')).packages['node_modules/abbrev'].version, - '1.1.1', - 'should have expected update --no-save lockfile result' - ) -}) + await npm('install', 'abbrev@1.0.4', '--save-exact') -t.test('npm update --save', async t => { - await exec('update', '--save') - - t.equal( - JSON.parse(readFile('package.json')).dependencies.abbrev, - '^1.1.1', - 'should have expected update --save package.json result' - ) - t.equal( - JSON.parse(readFile('package-lock.json')).packages['node_modules/abbrev'].version, - '1.1.1', - 'should have expected update --save lockfile result' - ) -}) + t.equal( + (await readFile('package-lock.json')).packages['node_modules/abbrev'].version, + '1.0.4', + 'should have stored exact installed version' + ) -t.test('npm ci', async t => { - await exec('uninstall', 'abbrev') - await exec('install', 'abbrev@1.0.4', '--save-exact') + await npm('pkg', 'set', 'dependencies.abbrev=^1.1.1') - t.equal( - JSON.parse(readFile('package-lock.json')).packages['node_modules/abbrev'].version, - '1.0.4', - 'should have stored exact installed version' - ) + await registry.package({ + manifest, + }) - await exec('pkg', 'set', 'dependencies.abbrev=^1.1.1') + const err = await npm('ci', '--loglevel=error').catch(e => e) + t.equal(err.code, 1) + t.matchSnapshot(err.stderr, 'should throw mismatch deps in lock file error') + }) - const err = await exec('ci', '--loglevel=error').catch(e => e) - t.equal(err.code, 1) - t.matchSnapshot(err.stderr, 'should throw mismatch deps in lock file error') + await t.test('npm exec', async t => { + if (process.platform === 'win32') { + t.skip() + return + } + // First run finds package + { + const packument = registry.packument({ + name: 'exec-test', version: '1.0.0', bin: { 'exec-test': 'run.sh' }, + }) + const manifest = registry.manifest({ name: 'exec-test', packuments: [packument] }) + await registry.package({ + times: 2, + manifest, + tarballs: { + '1.0.0': join(paths.root, 'packages', 'exec-test-1.0.0'), + }, + }) + + const o = await npm('exec', 'exec-test') + t.match(o.stdout.trim(), '1.0.0') + } + // Second run finds newer version + { + const packument = registry.packument({ + name: 'exec-test', version: '1.0.1', bin: { 'exec-test': 'run.sh' }, + }) + const manifest = registry.manifest({ name: 'exec-test', packuments: [packument] }) + await registry.package({ + times: 2, + manifest, + tarballs: { + '1.0.1': join(paths.root, 'packages', 'exec-test-1.0.1'), + }, + }) + const o = await npm('exec', 'exec-test') + t.match(o.stdout.trim(), '1.0.1') + } + }) }) diff --git a/smoke-tests/test/install-links-package-lock-only.js b/smoke-tests/test/install-links-package-lock-only.js new file mode 100644 index 0000000000000..3658a8e35dc47 --- /dev/null +++ b/smoke-tests/test/install-links-package-lock-only.js @@ -0,0 +1,82 @@ + +const t = require('tap') +const setup = require('./fixtures/setup.js') + +t.test('install links with package lock only', async t => { + const setupTest = async (t) => { + const mock = await setup(t, { + testdir: { + project: { + 'package.json': { + name: 'root', + version: '1.0.0', + workspaces: ['workspaces/*'], + }, + workspaces: { + pkg1: { + 'package.json': { + name: '@npmcli/pkg1', + version: '1.0.0', + dependencies: { '@npmcli/pkg3': '^1.0.0' }, + }, + }, + pkg2: { + 'package.json': { + name: '@npmcli/pkg2', + version: '1.0.0', + dependencies: { '@npmcli/pkg3': '^1.0.0' }, + }, + }, + pkg3: { + 'package.json': { + name: '@npmcli/pkg3', + version: '1.0.0', + }, + }, + }, + }, + }, + }) + const { npm } = mock + + // generate an initially valid lockfile + await npm('install', '--package-lock-only', '--install-links=false') + + // manually set version and semver ranges for pkg3 + await npm('pkg', 'set', '--workspace=@npmcli/pkg1', 'dependencies.@npmcli/pkg3=^1.0.1') + await npm('pkg', 'set', '--workspace=@npmcli/pkg2', 'dependencies.@npmcli/pkg3=^1.0.1') + await npm('pkg', 'set', '--workspace=@npmcli/pkg3', 'version=1.0.1') + + return mock + } + + await t.test('updates package lock with install-links=false', async t => { + const { npm, readFile } = await setupTest(t) + + await npm('install', '--package-lock-only', '--install-links=false') + + const lock = await readFile('package-lock.json') + t.equal(lock.packages['workspaces/pkg3'].version, '1.0.1') + }) + + // See https://github.com/npm/cli/issues/5967 for full bug + // change to t.test when this gets fixed + await t.todo('updates package lock with install-links=true', async t => { + const { npm, readFile, registry } = await setupTest(t) + + // TODO: this test should pass the same as the previous one. For debugging + // purposes the @npmcli/pkg3 package is mocked with only version 1.0.0 so + // the `npm install` command will fail, instead of nock failing for the + // missing request. But a proper fix for this will not need any registry + // requests mocked. + await registry.package({ + manifest: registry.manifest({ name: '@npmcli/pkg3', versions: ['1.0.0'] }), + times: 1, + }) + + await npm('install', '--package-lock-only', '--install-links=true') + + const lock = await readFile('package-lock.json') + t.equal(lock.packages['workspaces/pkg3'].version, '1.0.1') + }) +}) diff --git a/smoke-tests/test/large-install.js b/smoke-tests/test/large-install.js new file mode 100644 index 0000000000000..7b2cfae93de0a --- /dev/null +++ b/smoke-tests/test/large-install.js @@ -0,0 +1,39 @@ +const t = require('tap') +const path = require('node:path') +const setup = require('./fixtures/setup.js') + +const getFixture = (p) => require( + path.resolve(__dirname, './fixtures/large-install', p)) + +const runTest = async (t, { lowMemory } = {}) => { + const { npm } = await setup(t, { + // This test relies on the actual production registry + mockRegistry: false, + testdir: { + project: { + 'package.json': getFixture('package.json'), + ...lowMemory ? {} : { 'package-lock.json': getFixture('package-lock.json') }, + }, + }, + }) + return npm('install', '--no-audit', '--no-fund', { + env: lowMemory ? { NODE_OPTIONS: '--max-old-space-size=500' } : {}, + }) +} + +// This test was originally created for https://github.com/npm/cli/issues/6763 +// but was later removed after the corresponding Node bug was fixed and the test +// started flaking. These flakes were most likely a sign that there was actually +// a bug where maxSockets were not being respected https://github.com/npm/cli/issues/7072. +// So now this test has been brought back and if it does start flaking again it +// should be investigated. +t.test('large install', async t => { + const { stdout } = await runTest(t) + t.match(stdout, /added \d+ packages/) +}) + +t.test('large install, no lock and low memory', async t => { + // Run the same install but with no lockfile and constrained max-old-space-size + const { stdout } = await runTest(t, { lowMemory: true }) + t.match(stdout, /added \d+ packages/) +}) diff --git a/smoke-tests/test/npm-replace-global.js b/smoke-tests/test/npm-replace-global.js new file mode 100644 index 0000000000000..c53beb10875af --- /dev/null +++ b/smoke-tests/test/npm-replace-global.js @@ -0,0 +1,209 @@ + +const t = require('tap') +const { join, dirname, basename, extname } = require('node:path') +const fs = require('node:fs/promises') +const _which = require('which') +const setup = require('./fixtures/setup.js') + +const which = async (cmd, opts) => { + const path = await _which(cmd, { nothrow: true, ...opts }) + return path ? join(dirname(path), basename(path, extname(path))) : null +} + +const setupNpmGlobal = async (t, opts) => { + const mock = await setup(t, opts) + + return { + ...mock, + getPaths: async () => { + const binContents = await fs.readdir(mock.paths.globalBin) + .then(r => r.filter(p => p !== '.npmrc' && p !== 'node_modules')) + .catch(() => null) + + const nodeModulesContents = await fs.readdir(join(mock.paths.globalNodeModules, 'npm')) + .catch(() => null) + + return { + npmRoot: await mock.npmPath('help').then(setup.getNpmRoot), + pathNpm: await which('npm', { path: mock.getPath() }), + globalNpm: await which('npm'), + pathNpx: await which('npx', { path: mock.getPath() }), + globalNpx: await which('npx'), + binContents, + nodeModulesContents, + } + }, + } +} + +t.test('pack and replace global self', async t => { + const { + npm, + npmLocalTarball, + npmPath, + getPaths, + paths: { globalBin, globalNodeModules }, + } = await setupNpmGlobal(t, { + testdir: { + project: { + 'package.json': { name: 'npm', version: '999.999.999' }, + }, + }, + }) + + const tarball = await npmLocalTarball() + await npm('install', tarball, '--global') + + t.equal( + await fs.realpath(join(globalBin, 'npm')), + setup.WINDOWS ? join(globalBin, 'npm') : join(globalNodeModules, 'npm/bin/npm-cli.js'), + 'npm realpath is in the testdir' + ) + t.equal( + await fs.realpath(join(globalBin, 'npx')), + setup.WINDOWS ? join(globalBin, 'npx') : join(globalNodeModules, 'npm/bin/npx-cli.js'), + 'npx realpath is in the testdir' + ) + + const prePaths = await getPaths() + t.equal(prePaths.npmRoot, join(globalNodeModules, 'npm'), 'npm root is in the testdir') + t.equal(prePaths.pathNpm, join(globalBin, 'npm'), 'npm bin is in the testdir') + t.equal(prePaths.pathNpx, join(globalBin, 'npx'), 'npx bin is in the testdir') + t.not(prePaths.pathNpm, prePaths.globalNpm, 'npm bin is not the same as the global one') + t.not(prePaths.pathNpx, prePaths.globalNpx, 'npm bin is not the same as the global one') + t.ok(prePaths.nodeModulesContents.length > 1, 'node modules has npm contents') + t.ok(prePaths.nodeModulesContents.includes('node_modules'), 'npm has its node_modules') + + t.strictSame( + prePaths.binContents, + ['npm', 'npx'].flatMap(p => setup.WINDOWS ? [p, `${p}.cmd`, `${p}.ps1`] : p), + 'bin has npm and npx' + ) + + await npmPath('pack') + await npmPath('install', 'npm-999.999.999.tgz', '--global') + + const postPaths = await getPaths() + t.not(prePaths.npmRoot, postPaths.npmRoot, 'npm roots are different') + t.equal(postPaths.pathNpm, postPaths.globalNpm, 'npm bin is the same as the global one') + t.equal(postPaths.pathNpx, postPaths.globalNpx, 'npx bin is the same as the global one') + t.equal(postPaths.pathNpm, prePaths.globalNpm, 'after install npm bin is same as previous global') + t.equal(postPaths.pathNpx, prePaths.globalNpx, 'after install npx bin is same as previous global') + t.strictSame(postPaths.binContents, [], 'bin is empty') + t.strictSame(postPaths.nodeModulesContents, ['package.json'], 'contents is only package.json') +}) + +t.test('publish and replace global self', async t => { + const { + npm, + npmPath, + registry, + npmLocal, + npmLocalTarball, + getPaths, + paths: { globalBin, globalNodeModules, cache }, + } = await setupNpmGlobal(t, { + strictRegistryNock: false, + testdir: { + home: { + '.npmrc': `//${setup.MOCK_REGISTRY.host}/:_authToken = test-token`, + }, + }, + }) + + let publishedPackument = null + const { name, version } = require('../../package.json') + + const npmPackage = async ({ manifest, ...opts } = {}) => { + await registry.package({ + manifest: registry.manifest({ name, ...manifest }), + ...opts, + }) + } + + const npmInstall = async (useNpm) => { + await npmPackage({ + manifest: { packuments: [publishedPackument] }, + tarballs: { [version]: tarball }, + times: 3, + }) + await fs.rm(cache, { recursive: true, force: true }) + await useNpm('install', 'npm@latest', '--global') + return getPaths() + } + + const tarball = await npmLocalTarball() + + if (setup.SMOKE_PUBLISH) { + await npmPackage() + } + registry.nock.put('/npm', body => { + if (body._id === 'npm' && body.versions[version]) { + publishedPackument = body.versions[version] + return true + } + return false + }).reply(201, {}) + await npmLocal('publish', '--tag=smoke-test', { proxy: true, force: true }) + + t.comment(JSON.stringify(publishedPackument, null, 2)) + + const paths = await npmInstall(npm) + t.equal(paths.npmRoot, join(globalNodeModules, 'npm'), 'npm root is in the testdir') + t.equal(paths.pathNpm, join(globalBin, 'npm'), 'npm bin is in the testdir') + t.equal(paths.pathNpx, join(globalBin, 'npx'), 'npx bin is in the testdir') + t.ok(paths.nodeModulesContents.length > 1, 'node modules has npm contents') + t.ok(paths.nodeModulesContents.includes('node_modules'), 'npm has its node_modules') + + t.strictSame( + paths.binContents, + ['npm', 'npx'].flatMap(p => setup.WINDOWS ? [p, `${p}.cmd`, `${p}.ps1`] : p), + 'bin has npm and npx' + ) + + t.strictSame(await npmInstall(npmPath), paths) +}) + +t.test('fail when updating with lazy require', async t => { + const { + npm, + npmLocalTarball, + npmPath, + paths, + } = await setupNpmGlobal(t, { + testdir: { + project: { + 'package.json': { + name: 'npm', + version: '999.999.999', + bin: { + npm: './my-new-npm-bin.js', + }, + }, + 'my-new-npm-bin.js': `#!/usr/bin/env node\nconsole.log('This worked!')`, + }, + }, + }) + + const tarball = await npmLocalTarball() + await npm('install', tarball, '--global') + await npmPath('pack') + + // exit-handler is the last thing called in the code + // so an uncached lazy require within the exit handler will always throw + await fs.writeFile( + join(paths.globalNodeModules, 'npm/lib/cli/exit-handler.js'), + `module.exports = class { + setNpm(){} + registerUncaughtHandlers(){} + exit() { require('./LAZY_REQUIRE_CANARY') } + }`, + 'utf-8' + ) + + await t.rejects(npmPath('install', 'npm-999.999.999.tgz', '--global'), { + stderr: `Error: Cannot find module './LAZY_REQUIRE_CANARY'`, + }, 'install command fails with lazy require error') + + await t.resolveMatch(npmPath(), { stdout: 'This worked!' }, 'bin placement still works') +}) diff --git a/smoke-tests/test/pack-json-output.js b/smoke-tests/test/pack-json-output.js new file mode 100644 index 0000000000000..59a8e2cded66f --- /dev/null +++ b/smoke-tests/test/pack-json-output.js @@ -0,0 +1,12 @@ + +const t = require('tap') +const setup = require('./fixtures/setup.js') + +t.test('pack --json returns only json on stdout', async t => { + const { npmLocal } = await setup(t) + + const { stderr, stdout } = await npmLocal('pack', '--json', { force: true }) + + t.match(stderr, /> npm@.* prepack\n/, 'stderr has banner') + t.ok(JSON.parse(stdout), 'stdout can be parsed as json') +}) diff --git a/smoke-tests/test/proxy.js b/smoke-tests/test/proxy.js new file mode 100644 index 0000000000000..8746c546de55f --- /dev/null +++ b/smoke-tests/test/proxy.js @@ -0,0 +1,15 @@ +const t = require('tap') +const setup = require('./fixtures/setup.js') + +t.test('proxy', async t => { + const { npm, readFile } = await setup(t, { + mockRegistry: false, + useProxy: true, + }) + + await npm('install', 'abbrev@1.0.4') + + t.strictSame(await readFile('package.json'), { + dependencies: { abbrev: '^1.0.4' }, + }) +}) diff --git a/smoke-tests/test/workspace-ua.js b/smoke-tests/test/workspace-ua.js new file mode 100644 index 0000000000000..ac9e68999107f --- /dev/null +++ b/smoke-tests/test/workspace-ua.js @@ -0,0 +1,34 @@ + +const t = require('tap') +const setup = require('./fixtures/setup.js') + +t.test('basic', async t => { + const { registry, npm } = await setup(t) + + const mock = () => registry.nock + .get(`/fail_reflect_user_agent`) + .reply(404, {}, { 'npm-notice': (req) => req.headers['user-agent'] }) + + await t.test('npm install sends correct user-agent', async t => { + await npm('init', '-y') + await npm('init', '-y', `--workspace=foo`) + + mock() + await t.rejects( + npm('install', 'fail_reflect_user_agent'), + { + stderr: /workspaces\/false/, + }, + 'workspaces/false is present in output' + ) + + mock() + await t.rejects( + npm('install', 'fail_reflect_user_agent', '--workspaces'), + { + stderr: /workspaces\/true/, + }, + 'workspaces/true is present in output' + ) + }) +}) diff --git a/tap-snapshots/test/lib/cli/exit-handler.js.test.cjs b/tap-snapshots/test/lib/cli/exit-handler.js.test.cjs new file mode 100644 index 0000000000000..fd68eea57795b --- /dev/null +++ b/tap-snapshots/test/lib/cli/exit-handler.js.test.cjs @@ -0,0 +1,66 @@ +/* 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/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 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" "silly" "--color" "false" "--timing" "true" +XX timing npm:load:setTitle 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 Completed in {TIME}ms +XX timing command:root Completed in {TIME}ms +XX verbose stack Error: Unknown error +XX error code ECODE +XX error Unknown error +XX timing npm Completed in {TIME}ms +XX info timing Timing info written to: {CWD}/cache/_logs/{DATE}-timing.json +XX verbose cwd {CWD}/prefix +XX verbose os {OS} +XX verbose {NODE-VERSION} +XX verbose npm {NPM-VERSION} +XX verbose exit 1 +XX verbose code 1 +XX error A complete log of this run can be found in: {CWD}/cache/_logs/{DATE}-debug-0.log +` + +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 +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" "silly" "--color" "false" "--timing" "true" +timing npm:load:setTitle 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 Completed in {TIME}ms +timing command:root Completed in {TIME}ms +verbose stack Error: Unknown error +error code ECODE +error Unknown error +timing npm Completed in {TIME}ms +info timing Timing info written to: {CWD}/cache/_logs/{DATE}-timing.json +verbose cwd {CWD}/prefix +verbose os {OS} +verbose {NODE-VERSION} +verbose npm {NPM-VERSION} +verbose exit 1 +verbose code 1 +error A complete log of this run can be found in: {CWD}/cache/_logs/{DATE}-debug-0.log +` diff --git a/tap-snapshots/test/lib/cli/update-notifier.js.test.cjs b/tap-snapshots/test/lib/cli/update-notifier.js.test.cjs new file mode 100644 index 0000000000000..8736ee4623cd4 --- /dev/null +++ b/tap-snapshots/test/lib/cli/update-notifier.js.test.cjs @@ -0,0 +1,110 @@ +/* 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 situation with engine compatibility > must match snapshot 1`] = ` + +New minor version of npm available! 123.420.70 -> 123.421.60 +Changelog: https://github.com/npm/cli/releases/tag/v123.421.60 +To update run: npm install -g npm@123.421.60 + +` + +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/tap-snapshots/test/lib/commands/adduser.js.test.cjs b/tap-snapshots/test/lib/commands/adduser.js.test.cjs deleted file mode 100644 index ba27a6a781ab0..0000000000000 --- a/tap-snapshots/test/lib/commands/adduser.js.test.cjs +++ /dev/null @@ -1,17 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/lib/commands/adduser.js TAP auth-type sso warning > warning 1`] = ` -Object { - "warn": Array [ - Array [ - "config", - "--auth-type=sso is will be removed in a future version.", - ], - ], -} -` diff --git a/tap-snapshots/test/lib/commands/audit.js.test.cjs b/tap-snapshots/test/lib/commands/audit.js.test.cjs index 3e7658c14bb19..843cf7c8dd370 100644 --- a/tap-snapshots/test/lib/commands/audit.js.test.cjs +++ b/tap-snapshots/test/lib/commands/audit.js.test.cjs @@ -45,44 +45,74 @@ 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`] = ` { "invalid": [ { - "name": "kms-demo", - "version": "1.0.0", + "code": "EINTEGRITYSIGNATURE", + "message": "kms-demo@1.0.0 has an invalid registry signature with keyid: SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA and signature: bogus", + "integrity": "sha512-QqZ7VJ/8xPkS9s2IWB7Shj3qTJdcRyeXKbPQnsZjsPEwvutGv0EGeVchPcauoiDFJlGbZMFq5GDCurAGNSghJQ==", + "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", "location": "node_modules/kms-demo", + "name": "kms-demo", + "registry": "https://registry.npmjs.org/", "resolved": "https://registry.npmjs.org/kms-demo/-/kms-demo-1.0.0.tgz", - "integrity": "sha512-QqZ7VJ/8xPkS9s2IWB7Shj3qTJdcRyeXKbPQnsZjsPEwvutGv0EGeVchPcauoiDFJlGbZMFq5GDCurAGNSghJQ==", "signature": "bogus", - "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA" + "type": "dependencies", + "version": "1.0.0" } ], "missing": [ { - "name": "async", - "version": "1.1.1", "location": "node_modules/async", - "resolved": "https://registry.npmjs.org/async/-/async-1.1.1.tgz" + "name": "async", + "registry": "https://registry.npmjs.org/", + "resolved": "https://registry.npmjs.org/async/-/async-1.1.1.tgz", + "version": "1.1.1" } ] } ` +exports[`test/lib/commands/audit.js TAP audit signatures json output with invalid attestations > must match snapshot 1`] = ` +{ + "invalid": [ + { + "code": "EATTESTATIONVERIFY", + "message": "sigstore@1.0.0 failed to verify attestation: artifact signature verification failed", + "integrity": "sha512-e+qfbn/zf1+rCza/BhIA//Awmf0v1pa5HQS8Xk8iXrn9bgytytVLqYD0P7NSqZ6IELTgq+tcDvLPkQjNHyWLNg==", + "keyid": "", + "location": "node_modules/sigstore", + "name": "sigstore", + "registry": "https://registry.npmjs.org/", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.0.0.tgz", + "signature": "MEYCIQD10kAn3lC/1rJvXBtSDckbqkKEmz369gPDKb4lG4zMKQIhAP1+RhbMcASsfXhxpXKNCAjJb+3Av3Br95eKD7VL/BEB", + "predicateType": "https://slsa.dev/provenance/v0.2", + "type": "dependencies", + "version": "1.0.0" + } + ], + "missing": [] +} +` + exports[`test/lib/commands/audit.js TAP audit signatures json output with invalid signatures > must match snapshot 1`] = ` { "invalid": [ { - "name": "kms-demo", - "version": "1.0.0", + "code": "EINTEGRITYSIGNATURE", + "message": "kms-demo@1.0.0 has an invalid registry signature with keyid: SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA and signature: bogus", + "integrity": "sha512-QqZ7VJ/8xPkS9s2IWB7Shj3qTJdcRyeXKbPQnsZjsPEwvutGv0EGeVchPcauoiDFJlGbZMFq5GDCurAGNSghJQ==", + "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", "location": "node_modules/kms-demo", + "name": "kms-demo", + "registry": "https://registry.npmjs.org/", "resolved": "https://registry.npmjs.org/kms-demo/-/kms-demo-1.0.0.tgz", - "integrity": "sha512-QqZ7VJ/8xPkS9s2IWB7Shj3qTJdcRyeXKbPQnsZjsPEwvutGv0EGeVchPcauoiDFJlGbZMFq5GDCurAGNSghJQ==", "signature": "bogus", - "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA" + "type": "dependencies", + "version": "1.0.0" } ], "missing": [] @@ -100,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`] = ` @@ -123,10 +151,9 @@ audited 1 package in xxx 1 package has an invalid registry signature: -@npmcli/arborist@1.0.14 (https://verdaccio-clone.org) +@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`] = ` @@ -134,14 +161,25 @@ audited 1 package in xxx 1 package has a missing registry signature but the registry is providing signing keys: -@npmcli/arborist@1.0.14 (https://verdaccio-clone.org) +@npmcli/arborist@1.0.14 (https://verdaccio-clone.org/) ` exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with keys and 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 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`] = ` @@ -156,14 +194,22 @@ 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`] = ` +audited 1 package in xxx + +1 package has an invalid attestation: +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`] = ` @@ -174,18 +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`] = ` @@ -196,6 +246,17 @@ audited 1 package in xxx kms-demo@1.0.0 (https://registry.npmjs.org/) ` +exports[`test/lib/commands/audit.js TAP audit signatures with multiple invalid attestations > must match snapshot 1`] = ` +audited 2 packages in xxx + +2 packages have invalid attestations: + +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`] = ` audited 2 packages in xxx @@ -204,8 +265,7 @@ audited 2 packages in xxx 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 where published on the registry! - +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`] = ` @@ -227,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`] = ` @@ -240,47 +299,36 @@ audited 2 packages in xxx async@1.1.1 (https://registry.npmjs.org/) ` -exports[`test/lib/commands/audit.js TAP audit signatures with valid signatures > must match snapshot 1`] = ` +exports[`test/lib/commands/audit.js TAP audit signatures with valid attestations > must match snapshot 1`] = ` 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 using alias > must match snapshot 1`] = ` +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`] = ` -# npm audit report - -test-dep-a 1.0.0 -Severity: high -Test advisory 100 - https://github.com/advisories/GHSA-100 -fix available via \`npm audit fix\` -node_modules/test-dep-a - -1 high severity vulnerability - -To address all issues, run: - npm audit fix ` exports[`test/lib/commands/audit.js TAP json audit > must match snapshot 1`] = ` diff --git a/tap-snapshots/test/lib/commands/cache.js.test.cjs b/tap-snapshots/test/lib/commands/cache.js.test.cjs index 1cd699453478e..d5ce43922f024 100644 --- a/tap-snapshots/test/lib/commands/cache.js.test.cjs +++ b/tap-snapshots/test/lib/commands/cache.js.test.cjs @@ -41,6 +41,82 @@ make-fetch-happen:request-cache:https://registry.npmjs.org/foo make-fetch-happen:request-cache:https://registry.npmjs.org/foo/-/foo-1.2.3-beta.tgz ` +exports[`test/lib/commands/cache.js TAP cache npx info: valid and invalid entry > shows invalid package info 1`] = ` +invalid npx cache entry with key deadbeef +location: {CWD}/cache/_npx/deadbeef + +invalid npx cache entry with key badc0de +location: {CWD}/cache/_npx/badc0de +` + +exports[`test/lib/commands/cache.js TAP cache npx info: valid and invalid entry > shows valid package info 1`] = ` +invalid npx cache entry with key deadbeef +location: {CWD}/cache/_npx/deadbeef +` + +exports[`test/lib/commands/cache.js TAP cache npx info: valid entry with _npx directory package > shows valid package info with _npx directory package 1`] = ` +valid npx cache entry with key valid123 +location: {CWD}/cache/_npx/valid123 +packages: +- /path/to/valid-package +` + +exports[`test/lib/commands/cache.js TAP cache npx info: valid entry with _npx packages > shows valid package info with _npx packages 1`] = ` +valid npx cache entry with key valid123 +location: {CWD}/cache/_npx/valid123 +packages: +- valid-package@1.0.0 (valid-package@1.0.0) +` + +exports[`test/lib/commands/cache.js TAP cache npx info: valid entry with a link dependency > shows link dependency realpath (child.isLink branch) 1`] = ` +valid npx cache entry with key link123 +location: {CWD}/cache/_npx/link123 +packages: (unknown) +dependencies: +- {CWD}/cache/_npx/some-other-loc +` + +exports[`test/lib/commands/cache.js TAP cache npx info: valid entry with dependencies > shows valid package info with dependencies 1`] = ` +valid npx cache entry with key valid456 +location: {CWD}/cache/_npx/valid456 +packages: (unknown) +dependencies: +- dep-package@1.0.0 +` + +exports[`test/lib/commands/cache.js TAP cache npx ls: empty cache > logs message for empty npx cache 1`] = ` +npx cache does not exist +` + +exports[`test/lib/commands/cache.js TAP cache npx ls: entry with unknown package > lists entry with unknown package 1`] = ` +unknown123: (unknown) +` + +exports[`test/lib/commands/cache.js TAP cache npx ls: some entries > lists one valid and one invalid entry 1`] = ` +abc123: fake-npx-package@1.0.0 +z9y8x7: (empty/invalid) +` + +exports[`test/lib/commands/cache.js TAP cache npx rm: remove single entry > logs removing single npx cache entry 1`] = ` +Removing npx key at {CWD}/cache/_npx/123removeme +Removing npx key at {CWD}/cache/_npx/123removeme +` + +exports[`test/lib/commands/cache.js TAP cache npx rm: removing all with --force works > logs removing everything 1`] = ` +Removing npx key at {CWD}/cache/_npx/remove-all-yes-force +` + +exports[`test/lib/commands/cache.js TAP cache npx rm: removing all without --force fails > logs usage error when removing all without --force 1`] = ` + +` + +exports[`test/lib/commands/cache.js TAP cache npx rm: removing more than 1, less than all entries > logs removing 2 of 3 entries 1`] = ` +Removing npx key at {CWD}/cache/_npx/123removeme +Removing npx key at {CWD}/cache/_npx/456removeme +Removing npx key at {CWD}/cache/_npx/123removeme +Removing npx key at {CWD}/cache/_npx/456removeme +` + exports[`test/lib/commands/cache.js TAP cache rm > logs deleting single entry 1`] = ` Deleted: make-fetch-happen:request-cache:https://registry.npmjs.org/test-package/-/test-package-1.0.0.tgz ` diff --git a/tap-snapshots/test/lib/commands/completion.js.test.cjs b/tap-snapshots/test/lib/commands/completion.js.test.cjs index f08ef0f37c360..64759ec6ef9cf 100644 --- a/tap-snapshots/test/lib/commands/completion.js.test.cjs +++ b/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,197 +40,178 @@ 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 - bin - bugs - cache - ci - completion - config - dedupe - deprecate - diff - dist-tag - docs - doctor - edit - exec - explain - explore - find-dupes - fund - get - help - 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 - search - set - set-script - shrinkwrap - star - stars - start - stop - team - test - token - uninstall - unpublish - unstar - update - version - view - whoami - login - 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 + 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 + sbom + search + set + shrinkwrap + star + stars + start + stop + team + test + token + undeprecate + 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-script + 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 + ), ] ` exports[`test/lib/commands/completion.js TAP completion filtered subcommands > filtered subcommands 1`] = ` -Array [ - Array [ - "public", - ], -] +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( - public - restricted - grant - revoke - ls-packages - ls-collaborators - edit - 2fa-required - 2fa-not-required - ), - ], + String( + get + grant + list + revoke + set + ), ] ` diff --git a/tap-snapshots/test/lib/commands/config.js.test.cjs b/tap-snapshots/test/lib/commands/config.js.test.cjs index 5c3f86415dfff..d96ebf3412e04 100644 --- a/tap-snapshots/test/lib/commands/config.js.test.cjs +++ b/tap-snapshots/test/lib/commands/config.js.test.cjs @@ -7,9 +7,8 @@ '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}", + "color": {COLOR}, "json": true, "projectloaded": "yes", "userloaded": "yes", @@ -17,23 +16,24 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "access": null, "all": false, "allow-same-version": false, + "allow-git": "all", "also": null, "audit": true, "audit-level": null, - "auth-type": "legacy", + "auth-type": "web", "before": null, "bin-links": true, "browser": null, + "bypass-2fa": false, "ca": null, "cache-max": null, "cache-min": 0, "cafile": null, "call": "", "cert": null, - "ci-name": null, "cidr": null, - "color": true, "commit-hooks": true, + "cpu": null, "depth": null, "description": true, "dev": false, @@ -48,6 +48,9 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "dry-run": false, "editor": "{EDITOR}", "engine-strict": false, + "expect-result-count": null, + "expect-results": null, + "expires": null, "fetch-retries": 2, "fetch-retry-factor": 10, "fetch-retry-maxtimeout": 60000, @@ -60,8 +63,8 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "git": "git", "git-tag-version": true, "global": false, + "globalconfig": "{CWD}/global/etc/npmrc", "global-style": false, - "globalconfig": "{GLOBALPREFIX}/npmrc", "heading": "npm", "https-proxy": null, "if-present": false, @@ -73,18 +76,22 @@ 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-type": "commonjs", "init-version": "1.0.0", + "init-private": false, "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", "key": null, "legacy-bundling": false, "legacy-peer-deps": false, + "libc": null, "link": false, "local-address": null, "location": "user", @@ -93,30 +100,37 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "logs-dir": null, "logs-max": 10, "long": false, + "name": null, "maxsockets": 15, "message": "%s", + "node-gyp": "{CWD}/node_modules/node-gyp/bin/node-gyp.js", "node-options": null, - "node-version": "{NODE-VERSION}", "noproxy": [ "" ], - "npm-version": "{NPM-VERSION}", "offline": false, "omit": [], "omit-lockfile-registry-resolved": false, "only": null, + "orgs": null, "optional": null, + "os": null, "otp": null, "package": [], "package-lock": true, "package-lock-only": false, "pack-destination": ".", + "packages": [], "parseable": false, + "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, "read-only": false, "rebuild-bundle": true, @@ -130,7 +144,14 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "save-peer": false, "save-prefix": "^", "save-prod": false, + "sbom-format": null, + "sbom-type": "library", "scope": "", + "scopes": null, + "packages-all": false, + "packages-and-scopes-permission": null, + "orgs-permission": null, + "token-description": null, "script-shell": null, "searchexclude": "", "searchlimit": 20, @@ -140,19 +161,17 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "shrinkwrap": true, "sign-git-commit": false, "sign-git-tag": false, - "sso-poll-frequency": 500, - "sso-type": "oauth", "strict-peer-deps": false, "strict-ssl": true, "tag": "latest", "tag-version-prefix": "v", "timing": false, - "tmp": "{TMP}", "umask": 0, "unicode": false, "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}", @@ -161,244 +180,275 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna "workspaces": null, "workspaces-update": true, "yes": null, - "metrics-registry": "https://registry.npmjs.org/" + "npm-version": "{NPM-VERSION}" } ` exports[`test/lib/commands/config.js TAP config list --long > output matches snapshot 1`] = ` ; "default" config from default values -_auth = (protected) -access = null -all = false -allow-same-version = false -also = null -audit = true -audit-level = null -auth-type = "legacy" -before = null -bin-links = true -browser = null -ca = null +_auth = (protected) +access = null +all = false +allow-git = "all" +allow-same-version = false +also = null +audit = true +audit-level = null +auth-type = "web" +before = null +bin-links = true +browser = null +bypass-2fa = false +ca = null ; cache = "{CACHE}" ; overridden by cli -cache-max = null -cache-min = 0 -cafile = null -call = "" -cert = null -ci-name = null -cidr = null -color = true -commit-hooks = true -depth = null -description = true -dev = false -diff = [] -diff-dst-prefix = "b/" -diff-ignore-all-space = false -diff-name-only = false -diff-no-prefix = false -diff-src-prefix = "a/" -diff-text = false -diff-unified = 3 -dry-run = false -editor = "{EDITOR}" -engine-strict = false -fetch-retries = 2 -fetch-retry-factor = 10 -fetch-retry-maxtimeout = 60000 -fetch-retry-mintimeout = 10000 -fetch-timeout = 300000 -force = false -foreground-scripts = false -format-package-lock = true -fund = true -git = "git" -git-tag-version = true -global = false -global-style = false -globalconfig = "{GLOBALPREFIX}/npmrc" -heading = "npm" -https-proxy = null -if-present = false -ignore-scripts = false -include = [] -include-staged = false -include-workspace-root = false -init-author-email = "" -init-author-name = "" -init-author-url = "" -init-license = "ISC" -init-module = "{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.version = "1.0.0" -install-links = false -json = false -key = null -legacy-bundling = false -legacy-peer-deps = false -link = false -local-address = null -location = "user" -lockfile-version = null -loglevel = "notice" -logs-dir = null -logs-max = 10 +cache-max = null +cache-min = 0 +cafile = null +call = "" +cert = null +cidr = null +; color = {COLOR} +commit-hooks = true +cpu = null +depth = null +description = true +dev = false +diff = [] +diff-dst-prefix = "b/" +diff-ignore-all-space = false +diff-name-only = false +diff-no-prefix = false +diff-src-prefix = "a/" +diff-text = false +diff-unified = 3 +dry-run = false +editor = "{EDITOR}" +engine-strict = false +expect-result-count = null +expect-results = null +expires = null +fetch-retries = 2 +fetch-retry-factor = 10 +fetch-retry-maxtimeout = 60000 +fetch-retry-mintimeout = 10000 +fetch-timeout = 300000 +force = false +foreground-scripts = false +format-package-lock = true +fund = true +git = "git" +git-tag-version = true +global = false +global-style = false +globalconfig = "{CWD}/global/etc/npmrc" +heading = "npm" +https-proxy = null +if-present = false +ignore-scripts = false +include = [] +include-staged = false +include-workspace-root = false +init-author-email = "" +init-author-name = "" +init-author-url = "" +init-license = "ISC" +init-module = "{CWD}/home/.npm-init.js" +init-private = false +init-type = "commonjs" +init-version = "1.0.0" +init.author.email = "" +init.author.name = "" +init.author.url = "" +init.license = "ISC" +init.module = "{CWD}/home/.npm-init.js" +init.version = "1.0.0" +install-links = false +install-strategy = "hoisted" +json = false +key = null +legacy-bundling = false +legacy-peer-deps = false +libc = null +link = false +local-address = null +location = "user" +lockfile-version = null +loglevel = "notice" +logs-dir = null +logs-max = 10 ; long = false ; overridden by cli -maxsockets = 15 -message = "%s" -metrics-registry = "https://registry.npmjs.org/" -node-options = null -node-version = "{NODE-VERSION}" -noproxy = [""] -npm-version = "{NPM-VERSION}" -offline = false -omit = [] -omit-lockfile-registry-resolved = false -only = null -optional = null -otp = null -pack-destination = "." -package = [] -package-lock = true -package-lock-only = false -parseable = false -prefer-offline = false -prefer-online = false -; prefix = "{REALGLOBALREFIX}" ; overridden by cli -preid = "" -production = null -progress = true -proxy = null -read-only = false -rebuild-bundle = true -registry = "https://registry.npmjs.org/" -replace-registry-host = "npmjs" -save = true -save-bundle = false -save-dev = false -save-exact = false -save-optional = false -save-peer = false -save-prefix = "^" -save-prod = false -scope = "" -script-shell = null -searchexclude = "" -searchlimit = 20 -searchopts = "" -searchstaleness = 900 -shell = "{SHELL}" -shrinkwrap = true -sign-git-commit = false -sign-git-tag = false -sso-poll-frequency = 500 -sso-type = "oauth" -strict-peer-deps = false -strict-ssl = true -tag = "latest" -tag-version-prefix = "v" -timing = false -tmp = "{TMP}" -umask = 0 -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 -version = false -versions = false -viewer = "{VIEWER}" -which = null -workspace = [] -workspaces = null -workspaces-update = true -yes = null +maxsockets = 15 +message = "%s" +name = null +node-gyp = "{CWD}/node_modules/node-gyp/bin/node-gyp.js" +node-options = null +noproxy = [""] +npm-version = "{NPM-VERSION}" +offline = false +omit = [] +omit-lockfile-registry-resolved = false +only = null +optional = null +orgs = null +orgs-permission = null +os = null +otp = null +pack-destination = "." +package = [] +package-lock = true +package-lock-only = false +packages = [] +packages-all = false +packages-and-scopes-permission = null +parseable = false +password = (protected) +prefer-dedupe = false +prefer-offline = false +prefer-online = false +prefix = "{CWD}/global" +preid = "" +production = null +progress = {PROGRESS} +provenance = false +provenance-file = null +proxy = null +read-only = false +rebuild-bundle = true +registry = "https://registry.npmjs.org/" +replace-registry-host = "npmjs" +save = true +save-bundle = false +save-dev = false +save-exact = false +save-optional = false +save-peer = false +save-prefix = "^" +save-prod = false +sbom-format = null +sbom-type = "library" +scope = "" +scopes = null +script-shell = null +searchexclude = "" +searchlimit = 20 +searchopts = "" +searchstaleness = 900 +shell = "{SHELL}" +shrinkwrap = true +sign-git-commit = false +sign-git-tag = false +strict-peer-deps = false +strict-ssl = true +tag = "latest" +tag-version-prefix = "v" +timing = false +token-description = null +umask = 0 +unicode = false +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}" +which = null +workspace = [] +workspaces = null +workspaces-update = true +yes = null -; "global" config from {GLOBALPREFIX}/npmrc +; "global" config from {CWD}/global/etc/npmrc -globalloaded = "yes" +globalloaded = "yes" -; "user" config from {HOME}/.npmrc +; "user" config from {CWD}/home/.npmrc -userloaded = "yes" +userloaded = "yes" -; "project" config from {LOCALPREFIX}/.npmrc +; "project" config from {CWD}/prefix/.npmrc -projectloaded = "yes" +projectloaded = "yes" ; "cli" config from command line options -cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list---long-sandbox/cache" -long = true -prefix = "{LOCALPREFIX}" -userconfig = "{HOME}/.npmrc" +cache = "{CACHE}" +color = {COLOR} +long = true ` exports[`test/lib/commands/config.js TAP config list > output matches snapshot 1`] = ` +; "global" config from {CWD}/global/etc/npmrc + +globalloaded = "yes" + +; "user" config from {CWD}/home/.npmrc + +_auth = (protected) +//nerfdart:_auth = (protected) +//nerfdart:auth = (protected) +auth = (protected) +userloaded = "yes" + +; "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}" +color = {COLOR} -; 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}" +color = {COLOR} +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}" -; 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}" +color = {COLOR} -; 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. + +//some.registry:_authToken = (protected) +other = "not defined" +registry = "https://some.registry" +` + +exports[`test/lib/commands/config.js TAP config list with publishConfig local > warns about unknown config 1`] = ` +Array [ + "Unknown publishConfig config /"other/". This will stop working in the next major version of npm.", +] ` diff --git a/tap-snapshots/test/lib/commands/diff.js.test.cjs b/tap-snapshots/test/lib/commands/diff.js.test.cjs new file mode 100644 index 0000000000000..e87086d7d9b8f --- /dev/null +++ b/tap-snapshots/test/lib/commands/diff.js.test.cjs @@ -0,0 +1,88 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/diff.js TAP no args in a project dir > must match snapshot 1`] = ` +diff --git a/a.js b/a.js +index v0.1.0..v1.0.0 100644 +--- a/a.js ++++ b/a.js +@@ -1,1 +1,1 @@ +-const a = "a@0.1.0" ++const a = "a@1.0.0" +diff --git a/b.js b/b.js +index v0.1.0..v1.0.0 100644 +--- a/b.js ++++ b/b.js +@@ -1,1 +1,1 @@ +-const b = "b@0.1.0" ++const b = "b@1.0.0" +diff --git a/index.js b/index.js +index v0.1.0..v1.0.0 100644 +--- a/index.js ++++ b/index.js +@@ -1,1 +1,1 @@ +-const version = "0.1.0" ++const version = "1.0.0" +diff --git a/package.json b/package.json +index v0.1.0..v1.0.0 100644 +--- a/package.json ++++ b/package.json +@@ -1,4 +1,4 @@ + { + "name": "@npmcli/foo", +- "version": "0.1.0" ++ "version": "1.0.0" + } +` + +exports[`test/lib/commands/diff.js TAP single arg version, filtering by files > must match snapshot 1`] = ` +diff --git a/a.js b/a.js +index v0.1.0..v1.0.0 100644 +--- a/a.js ++++ b/a.js +@@ -1,1 +1,1 @@ +-const a = "a@0.1.0" ++const a = "a@1.0.0" +diff --git a/b.js b/b.js +index v0.1.0..v1.0.0 100644 +--- a/b.js ++++ b/b.js +@@ -1,1 +1,1 @@ +-const b = "b@0.1.0" ++const b = "b@1.0.0" +` + +exports[`test/lib/commands/diff.js TAP various options using --name-only option > must match snapshot 1`] = ` +index.js +package.json +` + +exports[`test/lib/commands/diff.js TAP various options using diff option > must match snapshot 1`] = ` +diff --git a/index.js b/index.js +index v2.0.0..v3.0.0 100644 +--- a/index.js ++++ b/index.js +@@ -18,7 +18,7 @@ + 17 + 18 + 19 +-202.0.0 ++203.0.0 + 21 + 22 + 23 +diff --git a/package.json b/package.json +index v2.0.0..v3.0.0 100644 +--- a/package.json ++++ b/package.json +@@ -1,4 +1,4 @@ + { + "name": "bar", +- "version": "2.0.0" ++ "version": "3.0.0" + } +` diff --git a/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs b/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs index 73cc223a9a0b9..854f93ff1e5f2 100644 --- a/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs +++ b/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs @@ -10,8 +10,7 @@ exports[`test/lib/commands/dist-tag.js TAP add new tag > should return success m ` exports[`test/lib/commands/dist-tag.js TAP add using valid semver range as name > should return success msg 1`] = ` -dist-tag add 1.0.0 to @scoped/another@7.7.7 - +dist-tag add 1.0.0 to @scoped/another@7.7.7 ` exports[`test/lib/commands/dist-tag.js TAP ls in current package > should list available tags for current package 1`] = ` @@ -21,8 +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@latest - +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`] = ` @@ -44,8 +57,7 @@ latest: 2.0.0 ` exports[`test/lib/commands/dist-tag.js TAP remove existing tag > should log remove info 1`] = ` -dist-tag del c from @scoped/another - +dist-tag del c from @scoped/another ` exports[`test/lib/commands/dist-tag.js TAP remove existing tag > should return success msg 1`] = ` @@ -53,15 +65,13 @@ exports[`test/lib/commands/dist-tag.js TAP remove existing tag > should return s ` exports[`test/lib/commands/dist-tag.js TAP remove non-existing tag > should log error msg 1`] = ` -dist-tag del nonexistent from @scoped/another -dist-tag del nonexistent is not a dist-tag on @scoped/another - +dist-tag del nonexistent from @scoped/another +dist-tag del nonexistent is not a dist-tag on @scoped/another ` exports[`test/lib/commands/dist-tag.js TAP set existing version > should log warn msg 1`] = ` -dist-tag add b to @scoped/another@0.6.0 -dist-tag add b is already set to version 0.6.0 - +dist-tag add b to @scoped/another@0.6.0 +dist-tag add b is already set to version 0.6.0 ` exports[`test/lib/commands/dist-tag.js TAP workspaces no args > printed the expected output 1`] = ` @@ -95,7 +105,7 @@ latest-a: 1.0.0 latest: 1.0.0 ` -exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- . > printed the expected output 1`] = ` +exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- .@1, ignores version spec > printed the expected output 1`] = ` workspace-a: latest-a: 1.0.0 latest: 1.0.0 @@ -107,7 +117,7 @@ latest-c: 3.0.0 latest: 3.0.0 ` -exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- .@1, ignores version spec > printed the expected output 1`] = ` +exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- cwd > printed the expected output 1`] = ` workspace-a: latest-a: 1.0.0 latest: 1.0.0 @@ -131,7 +141,7 @@ latest-c: 3.0.0 latest: 3.0.0 ` -exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, . > printed the expected output 1`] = ` +exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, .@1, ignores version spec > printed the expected output 1`] = ` workspace-a: latest-a: 1.0.0 latest: 1.0.0 @@ -143,7 +153,13 @@ latest-c: 3.0.0 latest: 3.0.0 ` -exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, .@1, ignores version spec > printed the expected output 1`] = ` +exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, @scoped/pkg, logs a warning and ignores workspaces > printed the expected output 1`] = ` +a: 0.0.1 +b: 0.5.0 +latest: 1.0.0 +` + +exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, cwd > printed the expected output 1`] = ` workspace-a: latest-a: 1.0.0 latest: 1.0.0 @@ -154,9 +170,3 @@ workspace-c: latest-c: 3.0.0 latest: 3.0.0 ` - -exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, @scoped/pkg, logs a warning and ignores workspaces > printed the expected output 1`] = ` -a: 0.0.1 -b: 0.5.0 -latest: 1.0.0 -` diff --git a/tap-snapshots/test/lib/commands/doctor.js.test.cjs b/tap-snapshots/test/lib/commands/doctor.js.test.cjs index d84d7d368580c..134e2290b5e99 100644 --- a/tap-snapshots/test/lib/commands/doctor.js.test.cjs +++ b/tap-snapshots/test/lib/commands/doctor.js.test.cjs @@ -9,113 +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 [ - "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/) -which git ok /path/to/git -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/) -which git ok /path/to/git -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 [ - "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 [], } @@ -123,125 +121,120 @@ Object { exports[`test/lib/commands/doctor.js TAP bad proxy > logs 1`] = ` Object { - "error": Array [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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 unsupported proxy protocol: 'ssh:' -npm -v not ok Error: unsupported proxy protocol: 'ssh:' -node -v not ok Error: unsupported proxy protocol: 'ssh:' -npm config get registry ok using default registry (https://registry.npmjs.org/) -which git ok /path/to/git -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/) -which git ok /path/to/git -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 [ - "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", ], } ` @@ -250,352 +243,475 @@ 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 [ - "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/) -which git ok /path/to/git -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/) -which git ok /path/to/git -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 [ - "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", ], } ` -exports[`test/lib/commands/doctor.js TAP error reading directory > logs 1`] = ` +exports[`test/lib/commands/doctor.js TAP discrete checks cache > logs 1`] = ` +Object { + "error": Array [], + "info": Array [ + "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`] = ` +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 [ + "doctor Running checkup", + ], + "warn": Array [], +} +` + +exports[`test/lib/commands/doctor.js TAP discrete checks git > output 1`] = ` + +` + +exports[`test/lib/commands/doctor.js TAP discrete checks invalid environment > logs 1`] = ` +Object { + "error": Array [ + "Some problems found. See above for recommendations.", + ], + "info": Array [ + "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`] = ` +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 [ + "doctor Running checkup", + ], + "warn": Array [], +} +` + +exports[`test/lib/commands/doctor.js TAP discrete checks permissions - not windows > output 1`] = ` +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 [ + "doctor Running checkup", + ], + "warn": Array [], +} +` + +exports[`test/lib/commands/doctor.js TAP discrete checks permissions - windows > output 1`] = ` + +` + +exports[`test/lib/commands/doctor.js TAP discrete checks ping > logs 1`] = ` +Object { + "error": Array [], + "info": Array [ + "doctor Running checkup", + "doctor Pinging registry", + ], + "warn": Array [], +} +` + +exports[`test/lib/commands/doctor.js TAP discrete checks ping > output 1`] = ` +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", - ], - Array [ - "getLatestNpmVersion", - "Getting npm package information", - ], - Array [ - "getLatestNodejsVersion", - "Getting Node.js release information", - ], - Array [ - "getGitPath", - "Finding git 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", + ], + "warn": Array [], +} +` + +exports[`test/lib/commands/doctor.js TAP discrete checks registry > output 1`] = ` +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 [ + "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`] = ` +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 [ + "Some problems found. See above for recommendations.", + ], + "info": Array [ + "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}/test/lib/commands/tap-testdir-doctor-error-reading-directory/cache", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/lib/node_modules", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules/.bin", - ], - Array [ - "checkFilesPermission", - "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/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/) -which git ok /path/to/git -Perms check on cached files not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/cache (should be owned by current user) -Perms check on local node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules (should be owned by current user) -Perms check on global node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/lib/node_modules -Perms check on local bin folder not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules/.bin -Perms check on global bin folder not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/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/) -which git ok /path/to/git -Perms check on cached files not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache (should be owned by current user) -Perms check on local node_modules 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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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}/test/lib/commands/tap-testdir-doctor-incorrect-owner/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/) -which git ok /path/to/git -Perms check on cached files not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/cache (should be owned by current user) -Perms check on local node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules (should be owned by current user) -Perms check on global node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/lib/node_modules -Perms check on local bin folder not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules/.bin -Perms check on global bin folder not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/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}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/cache (expect: readable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules (expect: readable, writable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/lib/node_modules (expect: readable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules/.bin (expect: readable, writable, executable)", - ], - Array [ - "checkFilesPermission", - "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/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)", + "Some problems found. See above for recommendations.", ], "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 [ - "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 [], } @@ -603,699 +719,685 @@ Object { exports[`test/lib/commands/doctor.js TAP missing git > logs 1`] = ` Object { - "error": Array [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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 + ), ], } ` 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/) -which git not ok Install git and ensure it's in your PATH. -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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/lib/node_modules", - ], - Array [ - "checkFilesPermission", - "error getting info for {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/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/) -which git ok /path/to/git -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}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/lib/node_modules -Perms check on local bin folder ok -Perms check on global bin folder not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/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 [ - "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/) -which git ok /path/to/git -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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/\` -which git ok /path/to/git -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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 +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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 +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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 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 [], + "error": Array [ + "Some problems found. See above for recommendations.", + ], "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 [ - "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/) -which git ok /path/to/git -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 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 > logs 1`] = ` +exports[`test/lib/commands/doctor.js TAP silent errors > 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 [ - "verifyCachedFiles", - "Verifying the npm cache", - ], - Array [ - "verifyCachedFiles", - String( - Verification complete. Stats: { - "badContentCount": 0, - "reclaimedCount": 0, - "missingContent": 0, - "verifiedContent": 0 - } - ), - ], - ], + "info": Array [], + "warn": Array [], +} +` + +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 [], "warn": Array [], } ` -exports[`test/lib/commands/doctor.js TAP silent > output 1`] = ` +exports[`test/lib/commands/doctor.js TAP silent success > output 1`] = ` ` @@ -1303,51 +1405,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 [ - "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", ], "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/) -which git ok /path/to/git -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 ` diff --git a/tap-snapshots/test/lib/commands/fund.js.test.cjs b/tap-snapshots/test/lib/commands/fund.js.test.cjs index f0df1e1c58ad4..28ffd76d5c736 100644 --- a/tap-snapshots/test/lib/commands/fund.js.test.cjs +++ b/tap-snapshots/test/lib/commands/fund.js.test.cjs @@ -8,22 +8,19 @@ exports[`test/lib/commands/fund.js TAP fund a package with type and multiple sources > should print prompt select message 1`] = ` 1: Foo funding available at the following URL: http://example.com/foo 2: Lorem funding available at the following URL: http://example.com/foo-lorem -Run \`npm fund [<@scope>/] --which=1\`, for example, to open the first funding URL listed in that package - +Run \`npm fund [] --which=1\`, for example, to open the first funding URL listed in that package ` 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`] = ` @@ -32,55 +29,34 @@ 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`] = ` +--which=100 is not a valid index +1: Funding available at the following URL: http://example.com +2: Funding available at the following URL: http://sponsors.example.com/me +3: Funding available at the following URL: http://collective.example.com +Run \`npm fund [] --which=1\`, for example, to open the first funding URL listed in that package ` exports[`test/lib/commands/fund.js TAP fund using nested packages with multiple sources > should prompt with all available URLs 1`] = ` 1: Funding available at the following URL: https://one.example.com 2: Funding available at the following URL: https://two.example.com -Run \`npm fund [<@scope>/] --which=1\`, for example, to open the first funding URL listed in that package - -` - -exports[`test/lib/commands/fund.js TAP fund using nested packages with multiple sources, with a source number > should open the numbered URL 1`] = ` -Funding available at the following URL: - https://one.example.com -` - -exports[`test/lib/commands/fund.js TAP fund using package argument > should open funding url 1`] = ` -individual funding available at the following URL: - http://example.com/donate -` - -exports[`test/lib/commands/fund.js TAP fund using pkg name while having conflicting versions > should open greatest version 1`] = ` -Funding available at the following URL: - http://example.com/2 -` - -exports[`test/lib/commands/fund.js TAP fund using string shorthand > should open string-only url 1`] = ` -Funding available at the following URL: - https://example.com/sponsor +Run \`npm fund [] --which=1\`, for example, to open the first funding URL listed in that package ` 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`] = ` @@ -89,26 +65,20 @@ 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 > should display only filtered workspace name and its deps 1`] = ` +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`] = ` workspaces-support@1.0.0 \`-- https://example.com/a | \`-- 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 > should display only filtered workspace path and its deps 1`] = ` +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`] = ` workspaces-support@1.0.0 \`-- https://example.com/a | \`-- a@1.0.0 \`-- http://example.com/c \`-- c@1.0.0 - - ` diff --git a/tap-snapshots/test/lib/commands/init.js.test.cjs b/tap-snapshots/test/lib/commands/init.js.test.cjs index 97a6722f3ece4..821193a55e1a9 100644 --- a/tap-snapshots/test/lib/commands/init.js.test.cjs +++ b/tap-snapshots/test/lib/commands/init.js.test.cjs @@ -5,60 +5,20 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' -exports[`test/lib/commands/init.js TAP npm init workspces with root > does not print helper info 1`] = ` -Array [] -` +exports[`test/lib/commands/init.js TAP displays output > displays helper info 1`] = ` +This utility will walk you through creating a package.json file. +It only covers the most common items, and tries to guess sensible defaults. -exports[`test/lib/commands/init.js TAP workspaces no args > should print helper info 1`] = ` -Array [] -` +See \`npm help init\` for definitive documentation on these fields +and exactly what they do. -exports[`test/lib/commands/init.js TAP workspaces no args, existing folder > should print helper info 1`] = ` -Array [] -` +Use \`npm install \` afterwards to install a package and +save it as a dependency in the package.json file. -exports[`test/lib/commands/init.js TAP workspaces post workspace-init reify > should print helper info 1`] = ` -Array [ - Array [ - String( - - added 1 package in 100ms - ), - ], -] +Press ^C at any time to quit. ` -exports[`test/lib/commands/init.js TAP workspaces post workspace-init reify > should reify tree on init ws complete 1`] = ` -{ - "name": "top-level", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "top-level", - "workspaces": [ - "a" - ] - }, - "a": { - "version": "1.0.0", - "license": "ISC", - "devDependencies": {} - }, - "node_modules/a": { - "resolved": "a", - "link": true - } - }, - "dependencies": { - "a": { - "version": "file:a" - } - } -} - -` +exports[`test/lib/commands/init.js TAP workspaces no args -- yes > should print helper info 1`] = ` -exports[`test/lib/commands/init.js TAP workspaces with arg but missing workspace folder > should print helper info 1`] = ` -Array [] +added 1 package in {TIME} ` diff --git a/tap-snapshots/test/lib/commands/install.js.test.cjs b/tap-snapshots/test/lib/commands/install.js.test.cjs new file mode 100644 index 0000000000000..3c9fa9bbec447 --- /dev/null +++ b/tap-snapshots/test/lib/commands/install.js.test.cjs @@ -0,0 +1,309 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/install.js TAP devEngines should not utilize engines in root if devEngines is provided > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +warn EBADDEVENGINES The developer of this package has specified the following through devEngines +warn EBADDEVENGINES Invalid devEngines.runtime +warn EBADDEVENGINES Invalid semver version "0.0.1" does not match "v1337.0.0" for "runtime" +warn EBADDEVENGINES { +warn EBADDEVENGINES current: { name: 'node', version: 'v1337.0.0' }, +warn EBADDEVENGINES required: { name: 'node', version: '0.0.1', onFail: 'warn' } +warn EBADDEVENGINES } +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly reify moves {} +silly audit report null + +up to date, audited 1 package in {TIME} +found 0 vulnerabilities +` + +exports[`test/lib/commands/install.js TAP devEngines should show devEngines doesnt break engines > must match snapshot 1`] = ` +silly config load:file:{CWD}/npmrc +silly config load:file:{CWD}/home/.npmrc +silly config load:file:{CWD}/global/etc/npmrc +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" "--global" "true" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly placeDep ROOT alpha@ OK for: want: file:../../prefix/alpha +warn EBADENGINE Unsupported engine { +warn EBADENGINE package: undefined, +warn EBADENGINE required: { node: '1.0.0' }, +warn EBADENGINE current: { node: 'v1337.0.0', npm: '42.0.0' } +warn EBADENGINE } +warn EBADENGINE Unsupported engine { +warn EBADENGINE package: undefined, +warn EBADENGINE required: { node: '1.0.0' }, +warn EBADENGINE current: { node: 'v1337.0.0', npm: '42.0.0' } +warn EBADENGINE } +silly reify moves {} +silly ADD node_modules/alpha + +added 1 package in {TIME} +` + +exports[`test/lib/commands/install.js TAP devEngines should show devEngines has no effect on dev package install > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" "--save-dev" "true" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly placeDep ROOT alpha@ OK for: want: file:alpha +silly reify moves {} +silly audit bulk request {} +silly audit report null +silly ADD node_modules/alpha + +added 1 package, and audited 3 packages in {TIME} +found 0 vulnerabilities +` + +exports[`test/lib/commands/install.js TAP devEngines should show devEngines has no effect on global package install > must match snapshot 1`] = ` +silly config load:file:{CWD}/npmrc +silly config load:file:{CWD}/home/.npmrc +silly config load:file:{CWD}/global/etc/npmrc +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" "--global" "true" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly placeDep ROOT alpha@ OK for: want: file:../../prefix +silly reify moves {} +silly ADD node_modules/alpha + +added 1 package in {TIME} +` + +exports[`test/lib/commands/install.js TAP devEngines should show devEngines has no effect on package install > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly placeDep ROOT alpha@ OK for: want: file:alpha +silly reify moves {} +silly audit bulk request {} +silly audit report null +silly ADD node_modules/alpha + +added 1 package, and audited 3 packages in {TIME} +found 0 vulnerabilities +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize devEngines 2x error case > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +verbose stack Error: The developer of this package has specified the following through devEngines +verbose stack Invalid devEngines.runtime +verbose stack Invalid name "nondescript" does not match "node" for "runtime" +verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:181:27) +verbose stack at MockNpm.#exec ({CWD}/lib/npm.js:252:7) +verbose stack at MockNpm.exec ({CWD}/lib/npm.js:208:9) +error code EBADDEVENGINES +error EBADDEVENGINES The developer of this package has specified the following through devEngines +error EBADDEVENGINES Invalid devEngines.runtime +error EBADDEVENGINES Invalid name "nondescript" does not match "node" for "runtime" +error EBADDEVENGINES { +error EBADDEVENGINES current: { name: 'node', version: 'v1337.0.0' }, +error EBADDEVENGINES required: { name: 'nondescript', onFail: 'error' } +error EBADDEVENGINES } +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize devEngines 2x warning case > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +warn EBADDEVENGINES The developer of this package has specified the following through devEngines +warn EBADDEVENGINES Invalid devEngines.runtime +warn EBADDEVENGINES Invalid name "nondescript" does not match "node" for "runtime" +warn EBADDEVENGINES { +warn EBADDEVENGINES current: { name: 'node', version: 'v1337.0.0' }, +warn EBADDEVENGINES required: { name: 'nondescript', onFail: 'warn' } +warn EBADDEVENGINES } +warn EBADDEVENGINES Invalid devEngines.cpu +warn EBADDEVENGINES Invalid name "risv" does not match "x86" for "cpu" +warn EBADDEVENGINES { +warn EBADDEVENGINES current: { name: 'x86' }, +warn EBADDEVENGINES required: { name: 'risv', onFail: 'warn' } +warn EBADDEVENGINES } +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly reify moves {} +silly audit report null + +up to date, audited 1 package in {TIME} +found 0 vulnerabilities +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize devEngines failure and warning case > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +warn EBADDEVENGINES The developer of this package has specified the following through devEngines +warn EBADDEVENGINES Invalid devEngines.cpu +warn EBADDEVENGINES Invalid name "risv" does not match "x86" for "cpu" +warn EBADDEVENGINES { +warn EBADDEVENGINES current: { name: 'x86' }, +warn EBADDEVENGINES required: { name: 'risv', onFail: 'warn' } +warn EBADDEVENGINES } +verbose stack Error: The developer of this package has specified the following through devEngines +verbose stack Invalid devEngines.runtime +verbose stack Invalid name "nondescript" does not match "node" for "runtime" +verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:181:27) +verbose stack at MockNpm.#exec ({CWD}/lib/npm.js:252:7) +verbose stack at MockNpm.exec ({CWD}/lib/npm.js:208:9) +error code EBADDEVENGINES +error EBADDEVENGINES The developer of this package has specified the following through devEngines +error EBADDEVENGINES Invalid devEngines.runtime +error EBADDEVENGINES Invalid name "nondescript" does not match "node" for "runtime" +error EBADDEVENGINES { +error EBADDEVENGINES current: { name: 'node', version: 'v1337.0.0' }, +error EBADDEVENGINES required: { name: 'nondescript' } +error EBADDEVENGINES } +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize devEngines failure case > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +verbose stack Error: The developer of this package has specified the following through devEngines +verbose stack Invalid devEngines.runtime +verbose stack Invalid name "nondescript" does not match "node" for "runtime" +verbose stack at Install.checkDevEngines ({CWD}/lib/base-cmd.js:181:27) +verbose stack at MockNpm.#exec ({CWD}/lib/npm.js:252:7) +verbose stack at MockNpm.exec ({CWD}/lib/npm.js:208:9) +error code EBADDEVENGINES +error EBADDEVENGINES The developer of this package has specified the following through devEngines +error EBADDEVENGINES Invalid devEngines.runtime +error EBADDEVENGINES Invalid name "nondescript" does not match "node" for "runtime" +error EBADDEVENGINES { +error EBADDEVENGINES current: { name: 'node', version: 'v1337.0.0' }, +error EBADDEVENGINES required: { name: 'nondescript' } +error EBADDEVENGINES } +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize devEngines failure force case > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" "--force" "true" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +warn using --force Recommended protections disabled. +silly logfile done cleaning log files +warn EBADDEVENGINES The developer of this package has specified the following through devEngines +warn EBADDEVENGINES Invalid devEngines.runtime +warn EBADDEVENGINES Invalid name "nondescript" does not match "node" for "runtime" +warn EBADDEVENGINES { +warn EBADDEVENGINES current: { name: 'node', version: 'v1337.0.0' }, +warn EBADDEVENGINES required: { name: 'nondescript' } +warn EBADDEVENGINES } +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly reify moves {} +silly audit report null + +up to date, audited 1 package in {TIME} +found 0 vulnerabilities +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize devEngines success case > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +silly reify moves {} +silly audit report null + +up to date, audited 1 package in {TIME} +found 0 vulnerabilities +` + +exports[`test/lib/commands/install.js TAP devEngines should utilize engines in root if devEngines is not provided > must match snapshot 1`] = ` +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 +verbose title npm +verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "silly" "--color" "false" +verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}- +verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log +silly logfile done cleaning log files +silly packumentCache heap:{heap} maxSize:{maxSize} maxEntrySize:{maxEntrySize} +silly idealTree buildDeps +warn EBADENGINE Unsupported engine { +warn EBADENGINE package: undefined, +warn EBADENGINE required: { node: '0.0.1' }, +warn EBADENGINE current: { node: 'v1337.0.0', npm: '42.0.0' } +warn EBADENGINE } +silly reify moves {} +silly audit report null + +up to date, audited 1 package in {TIME} +found 0 vulnerabilities +` diff --git a/tap-snapshots/test/lib/commands/link.js.test.cjs b/tap-snapshots/test/lib/commands/link.js.test.cjs index e01409e4ce196..c26e30da1ef62 100644 --- a/tap-snapshots/test/lib/commands/link.js.test.cjs +++ b/tap-snapshots/test/lib/commands/link.js.test.cjs @@ -6,45 +6,50 @@ */ 'use strict' exports[`test/lib/commands/link.js TAP hash character in working directory path > should create a global link to current pkg, even within path with hash 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-hash-character-in-working-directory-path/global-prefix/lib/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-hash-character-in-working-directory-path/i_like_#_in_my_paths/test-pkg-link +{CWD}/global/node_modules/test-pkg-link -> {CWD}/other/i_like_#_in_my_paths/test-pkg-link ` exports[`test/lib/commands/link.js TAP link global linked pkg to local nm when using args > should create a local symlink to global pkg 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/@myscope/bar -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/scoped-linked -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/a -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/link-me-too -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/link-me-too -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/test-pkg-link +{CWD}/prefix/node_modules/@myscope/bar -> {CWD}/global/node_modules/@myscope/bar +{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked +{CWD}/prefix/node_modules/a -> {CWD}/global/node_modules/a +{CWD}/prefix/node_modules/link-me-too -> {CWD}/other/link-me-too +{CWD}/prefix/node_modules/test-pkg-link -> {CWD}/other/test-pkg-link ` exports[`test/lib/commands/link.js TAP link global linked pkg to local workspace using args > should create a local symlink to global pkg 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/global-prefix/lib/node_modules/@myscope/bar -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/scoped-linked -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/global-prefix/lib/node_modules/a -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/link-me-too -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/link-me-too -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/test-pkg-link -{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/x -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/packages/x +{CWD}/prefix/node_modules/@myscope/bar -> {CWD}/global/node_modules/@myscope/bar +{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked +{CWD}/prefix/node_modules/a -> {CWD}/global/node_modules/a +{CWD}/prefix/node_modules/link-me-too -> {CWD}/other/link-me-too +{CWD}/prefix/node_modules/test-pkg-link -> {CWD}/other/test-pkg-link +{CWD}/prefix/node_modules/x -> {CWD}/prefix/packages/x ` exports[`test/lib/commands/link.js TAP link pkg already in global space > should create a local symlink to global pkg 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space/scoped-linked +{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked ` exports[`test/lib/commands/link.js TAP link pkg already in global space when prefix is a symlink > should create a local symlink to global pkg 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space-when-prefix-is-a-symlink/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space-when-prefix-is-a-symlink/scoped-linked +{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked ` exports[`test/lib/commands/link.js TAP link to globalDir when in current working dir of pkg and no args > should create a global link to current pkg 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/global-prefix/lib/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/test-pkg-link +{CWD}/global/node_modules/test-pkg-link -> {CWD}/prefix ` exports[`test/lib/commands/link.js TAP link ws to globalDir when workspace specified and no args > should create a global link to current pkg 1`] = ` -{CWD}/test/lib/commands/tap-testdir-link-link-ws-to-globalDir-when-workspace-specified-and-no-args/global-prefix/lib/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-ws-to-globalDir-when-workspace-specified-and-no-args/test-pkg-link/packages/a +{CWD}/global/node_modules/a -> {CWD}/prefix/packages/a + +` + +exports[`test/lib/commands/link.js TAP test linked installed as symlinks > linked package should not be installed 1`] = ` +{CWD}/prefix/node_modules/mylink -> {CWD}/other/mylink ` diff --git a/tap-snapshots/test/lib/commands/ls.js.test.cjs b/tap-snapshots/test/lib/commands/ls.js.test.cjs index 9b6749acfe3bb..fc7fbdf8a906f 100644 --- a/tap-snapshots/test/lib/commands/ls.js.test.cjs +++ b/tap-snapshots/test/lib/commands/ls.js.test.cjs @@ -7,76 +7,73 @@ 'use strict' exports[`test/lib/commands/ls.js TAP ignore missing optional deps --json > ls --json problems 1`] = ` Array [ - "invalid: optional-wrong@3.2.1 {project}/node_modules/optional-wrong", + "invalid: optional-wrong@3.2.1 {CWD}/prefix/node_modules/optional-wrong", "missing: peer-missing@1, required by test-npm-ls-ignore-missing-optional@1.2.3", - "invalid: peer-optional-wrong@3.2.1 {project}/node_modules/peer-optional-wrong", - "invalid: peer-wrong@3.2.1 {project}/node_modules/peer-wrong", + "extraneous: peer-optional-ok@1.2.3 {CWD}/prefix/node_modules/peer-optional-ok", + "invalid: peer-optional-wrong@3.2.1 {CWD}/prefix/node_modules/peer-optional-wrong", + "extraneous: peer-optional-wrong@3.2.1 {CWD}/prefix/node_modules/peer-optional-wrong", + "invalid: peer-wrong@3.2.1 {CWD}/prefix/node_modules/peer-wrong", "missing: prod-missing@1, required by test-npm-ls-ignore-missing-optional@1.2.3", - "invalid: prod-wrong@3.2.1 {project}/node_modules/prod-wrong", + "invalid: prod-wrong@3.2.1 {CWD}/prefix/node_modules/prod-wrong", ] ` exports[`test/lib/commands/ls.js TAP ignore missing optional deps --parseable > ls --parseable result 1`] = ` -{project} -{project}/node_modules/optional-ok -{project}/node_modules/optional-wrong -{project}/node_modules/peer-ok -{project}/node_modules/peer-optional-ok -{project}/node_modules/peer-optional-wrong -{project}/node_modules/peer-wrong -{project}/node_modules/prod-ok -{project}/node_modules/prod-wrong +{CWD}/prefix +{CWD}/prefix/node_modules/optional-ok +{CWD}/prefix/node_modules/optional-wrong +{CWD}/prefix/node_modules/peer-ok +{CWD}/prefix/node_modules/peer-optional-ok +{CWD}/prefix/node_modules/peer-optional-wrong +{CWD}/prefix/node_modules/peer-wrong +{CWD}/prefix/node_modules/prod-ok +{CWD}/prefix/node_modules/prod-wrong ` exports[`test/lib/commands/ls.js TAP ignore missing optional deps human output > ls result 1`] = ` -test-npm-ls-ignore-missing-optional@1.2.3 {project} -+-- unmet optional dependency optional-missing@1 +test-npm-ls-ignore-missing-optional@1.2.3 {CWD}/prefix ++-- UNMET OPTIONAL DEPENDENCY optional-missing@1 +-- optional-ok@1.2.3 +-- optional-wrong@3.2.1 invalid: "1" from the root project -+-- unmet dependency peer-missing@1 ++-- UNMET DEPENDENCY peer-missing@1 +-- peer-ok@1.2.3 -+-- unmet optional dependency peer-optional-missing@1 -+-- peer-optional-ok@1.2.3 -+-- peer-optional-wrong@3.2.1 invalid: "1" from the root project ++-- UNMET OPTIONAL DEPENDENCY peer-optional-missing@1 ++-- peer-optional-ok@1.2.3 extraneous ++-- peer-optional-wrong@3.2.1 invalid: "1" from the root project extraneous +-- peer-wrong@3.2.1 invalid: "1" from the root project -+-- unmet dependency prod-missing@1 ++-- 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}/tap-testdir-ls-ls---depth-0 +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`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---depth-1 +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`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---dev +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}/tap-testdir-ls-ls---link +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`] = ` test-npm-ls@1.0.0 -| {CWD}/tap-testdir-ls-ls---long---depth-0 +| {CWD}/prefix | +-- chai@1.0.0 | @@ -88,12 +85,11 @@ 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`] = ` test-npm-ls@1.0.0 -| {CWD}/tap-testdir-ls-ls---long +| {CWD}/prefix | +-- chai@1.0.0 | @@ -111,324 +107,316 @@ 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`] = ` -{CWD}/tap-testdir-ls-ls---parseable---depth-0 -{CWD}/tap-testdir-ls-ls---parseable---depth-0/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable---depth-0/node_modules/foo +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/foo ` exports[`test/lib/commands/ls.js TAP ls --parseable --depth=1 > should output parseable containing top-level deps and their deps only 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---depth-1 -{CWD}/tap-testdir-ls-ls---parseable---depth-1/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable---depth-1/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable---depth-1/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable --dev > should output tree containing dev deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---dev -{CWD}/tap-testdir-ls-ls---parseable---dev/node_modules/dev-dep -{CWD}/tap-testdir-ls-ls---parseable---dev/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable---dev/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/dev-dep +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable --link > should output tree containing linked deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---link -{CWD}/tap-testdir-ls-ls---parseable---link/node_modules/linked-dep +{CWD}/prefix +{CWD}/prefix/node_modules/linked-dep ` exports[`test/lib/commands/ls.js TAP ls --parseable --long --depth=0 > should output tree containing top-level deps with descriptions 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---long---depth-0:test-npm-ls@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/chai:chai@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/dev-dep:dev-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/optional-dep:optional-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/peer-dep:peer-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/prod-dep:prod-dep@1.0.0 +{CWD}/prefix:test-npm-ls@1.0.0 +{CWD}/prefix/node_modules/chai:chai@1.0.0 +{CWD}/prefix/node_modules/dev-dep:dev-dep@1.0.0 +{CWD}/prefix/node_modules/optional-dep:optional-dep@1.0.0 +{CWD}/prefix/node_modules/peer-dep:peer-dep@1.0.0 +{CWD}/prefix/node_modules/prod-dep:prod-dep@1.0.0 ` exports[`test/lib/commands/ls.js TAP ls --parseable --long > should output tree info with descriptions 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---long:test-npm-ls@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/chai:chai@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/dev-dep:dev-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/optional-dep:optional-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/peer-dep:peer-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/prod-dep:prod-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/foo:foo@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/prod-dep/node_modules/dog:dog@2.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/dog:dog@1.0.0 +{CWD}/prefix:test-npm-ls@1.0.0 +{CWD}/prefix/node_modules/chai:chai@1.0.0 +{CWD}/prefix/node_modules/dev-dep:dev-dep@1.0.0 +{CWD}/prefix/node_modules/optional-dep:optional-dep@1.0.0 +{CWD}/prefix/node_modules/peer-dep:peer-dep@1.0.0 +{CWD}/prefix/node_modules/prod-dep:prod-dep@1.0.0 +{CWD}/prefix/node_modules/foo:foo@1.0.0 +{CWD}/prefix/node_modules/prod-dep/node_modules/dog:dog@2.0.0 +{CWD}/prefix/node_modules/dog:dog@1.0.0 ` exports[`test/lib/commands/ls.js TAP ls --parseable --long missing/invalid/extraneous > should output parseable result containing EXTRANEOUS/INVALID labels 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous:test-npm-ls@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous/node_modules/chai:chai@1.0.0:EXTRANEOUS -{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous/node_modules/foo:foo@1.0.0:INVALID -{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous/node_modules/dog:dog@1.0.0 +{CWD}/prefix:test-npm-ls@1.0.0 +{CWD}/prefix/node_modules/chai:chai@1.0.0:EXTRANEOUS +{CWD}/prefix/node_modules/foo:foo@1.0.0:INVALID +{CWD}/prefix/node_modules/dog:dog@1.0.0 ` exports[`test/lib/commands/ls.js TAP ls --parseable --long print symlink target location > should output parseable results with symlink targets 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location:test-npm-ls@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/chai:chai@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/dev-dep:dev-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/linked-dep:linked-dep@1.0.0:{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/linked-dep -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/optional-dep:optional-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/peer-dep:peer-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/prod-dep:prod-dep@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/foo:foo@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/prod-dep/node_modules/dog:dog@2.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/dog:dog@1.0.0 +{CWD}/prefix:test-npm-ls@1.0.0 +{CWD}/prefix/node_modules/chai:chai@1.0.0 +{CWD}/prefix/node_modules/dev-dep:dev-dep@1.0.0 +{CWD}/prefix/node_modules/linked-dep:linked-dep@1.0.0:{CWD}/prefix/linked-dep +{CWD}/prefix/node_modules/optional-dep:optional-dep@1.0.0 +{CWD}/prefix/node_modules/peer-dep:peer-dep@1.0.0 +{CWD}/prefix/node_modules/prod-dep:prod-dep@1.0.0 +{CWD}/prefix/node_modules/foo:foo@1.0.0 +{CWD}/prefix/node_modules/prod-dep/node_modules/dog:dog@2.0.0 +{CWD}/prefix/node_modules/dog:dog@1.0.0 ` exports[`test/lib/commands/ls.js TAP ls --parseable --long with extraneous deps > should output long parseable output with extraneous info 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps:test-npm-ls@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/chai:chai@1.0.0:EXTRANEOUS -{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/foo:foo@1.0.0 -{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/dog:dog@1.0.0 +{CWD}/prefix:test-npm-ls@1.0.0 +{CWD}/prefix/node_modules/chai:chai@1.0.0:EXTRANEOUS +{CWD}/prefix/node_modules/foo:foo@1.0.0 +{CWD}/prefix/node_modules/dog:dog@1.0.0 ` exports[`test/lib/commands/ls.js TAP ls --parseable --production > should output tree containing production deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable---production -{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/optional-dep -{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/prod-dep -{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/prod-dep/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/optional-dep +{CWD}/prefix/node_modules/prod-dep +{CWD}/prefix/node_modules/prod-dep/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable cycle deps > should print tree output omitting deduped ref 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-cycle-deps -{CWD}/tap-testdir-ls-ls---parseable-cycle-deps/node_modules/a -{CWD}/tap-testdir-ls-ls---parseable-cycle-deps/node_modules/b +{CWD}/prefix +{CWD}/prefix/node_modules/a +{CWD}/prefix/node_modules/b ` exports[`test/lib/commands/ls.js TAP ls --parseable default --depth value should be 0 > should output parseable output containing only top-level dependencies 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-default---depth-value-should-be-0 -{CWD}/tap-testdir-ls-ls---parseable-default---depth-value-should-be-0/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-default---depth-value-should-be-0/node_modules/foo +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/foo ` exports[`test/lib/commands/ls.js TAP ls --parseable empty location > should print empty result 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-empty-location +{CWD}/prefix ` exports[`test/lib/commands/ls.js TAP ls --parseable extraneous deps > should output containing problems info 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps -{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable from and resolved properties > should not be printed in tree output 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-from-and-resolved-properties -{CWD}/tap-testdir-ls-ls---parseable-from-and-resolved-properties/node_modules/simple-output +{CWD}/prefix +{CWD}/prefix/node_modules/simple-output ` exports[`test/lib/commands/ls.js TAP ls --parseable global > should print parseable output for global deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-global -{CWD}/tap-testdir-ls-ls---parseable-global/node_modules/a -{CWD}/tap-testdir-ls-ls---parseable-global/node_modules/b -{CWD}/tap-testdir-ls-ls---parseable-global/node_modules/b/node_modules/c +{CWD}/global +{CWD}/global/node_modules/a +{CWD}/global/node_modules/b +{CWD}/global/node_modules/b/node_modules/c ` exports[`test/lib/commands/ls.js TAP ls --parseable json read problems > should print empty result 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-json-read-problems +{CWD}/prefix ` exports[`test/lib/commands/ls.js TAP ls --parseable missing package.json > should output parseable missing name/version of top-level package 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-missing-package.json -{CWD}/tap-testdir-ls-ls---parseable-missing-package.json/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-missing-package.json/node_modules/dog -{CWD}/tap-testdir-ls-ls---parseable-missing-package.json/node_modules/foo +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/dog +{CWD}/prefix/node_modules/foo ` exports[`test/lib/commands/ls.js TAP ls --parseable missing/invalid/extraneous > should output parseable containing top-level deps and their deps only 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous -{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable no args > should output parseable representation of dependencies structure 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-no-args -{CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/dog +` + +exports[`test/lib/commands/ls.js TAP ls --parseable overridden dep > should contain overridden output 1`] = ` +{CWD}/prefix:test-overridden@1.0.0 +{CWD}/prefix/node_modules/foo:foo@1.0.0 +{CWD}/prefix/node_modules/bar:bar@1.0.0:OVERRIDDEN ` exports[`test/lib/commands/ls.js TAP ls --parseable resolved points to git ref > should output tree containing git refs 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-resolved-points-to-git-ref -{CWD}/tap-testdir-ls-ls---parseable-resolved-points-to-git-ref/node_modules/abbrev +{CWD}/prefix +{CWD}/prefix/node_modules/abbrev ` exports[`test/lib/commands/ls.js TAP ls --parseable unmet optional dep > should output parseable with empty entry for missing optional deps 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/dev-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/optional-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/peer-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/prod-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/prod-dep/node_modules/dog -{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/dev-dep +{CWD}/prefix/node_modules/optional-dep +{CWD}/prefix/node_modules/peer-dep +{CWD}/prefix/node_modules/prod-dep +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/prod-dep/node_modules/dog +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable unmet peer dep > should output parseable signaling missing peer dep in problems 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/dev-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/optional-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/peer-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/prod-dep -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/foo -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/prod-dep/node_modules/dog -{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/dog +{CWD}/prefix +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/dev-dep +{CWD}/prefix/node_modules/optional-dep +{CWD}/prefix/node_modules/peer-dep +{CWD}/prefix/node_modules/prod-dep +{CWD}/prefix/node_modules/foo +{CWD}/prefix/node_modules/prod-dep/node_modules/dog +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable using aliases > should output tree containing aliases 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-using-aliases -{CWD}/tap-testdir-ls-ls---parseable-using-aliases/node_modules/a +{CWD}/prefix +{CWD}/prefix/node_modules/a ` -exports[`test/lib/commands/ls.js TAP ls --parseable with filter arg > should output parseable contaning only occurrences of filtered by package 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-with-filter-arg/node_modules/chai +exports[`test/lib/commands/ls.js TAP ls --parseable with filter arg > should output parseable containing only occurrences of filtered by package 1`] = ` +{CWD}/prefix/node_modules/chai ` -exports[`test/lib/commands/ls.js TAP ls --parseable with filter arg nested dep > should output parseable contaning only occurrences of filtered package 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-with-filter-arg-nested-dep/node_modules/dog +exports[`test/lib/commands/ls.js TAP ls --parseable with filter arg nested dep > should output parseable containing only occurrences of filtered package 1`] = ` +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --parseable with missing filter arg > should output parseable output containing no dependencies info 1`] = ` ` -exports[`test/lib/commands/ls.js TAP ls --parseable with multiple filter args > should output parseable contaning only occurrences of multiple filtered packages and their ancestors 1`] = ` -{CWD}/tap-testdir-ls-ls---parseable-with-multiple-filter-args/node_modules/chai -{CWD}/tap-testdir-ls-ls---parseable-with-multiple-filter-args/node_modules/dog +exports[`test/lib/commands/ls.js TAP ls --parseable with multiple filter args > should output parseable containing only occurrences of multiple filtered packages and their ancestors 1`] = ` +{CWD}/prefix/node_modules/chai +{CWD}/prefix/node_modules/dog ` exports[`test/lib/commands/ls.js TAP ls --production > should output tree containing production deps 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---production +test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 +-- optional-dep@1.0.0 \`-- prod-dep@1.0.0 \`-- dog@2.0.0 - ` exports[`test/lib/commands/ls.js TAP ls broken resolved field > should NOT print git refs in output tree 1`] = ` -npm-broken-resolved-field-test@1.0.0 {CWD}/tap-testdir-ls-ls-broken-resolved-field +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}/tap-testdir-ls-ls-colored-output -+-- chai@1.0.0 extraneous -+-- foo@1.0.0 invalid: "^2.0.0" from the root project +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 | \`-- dog@1.0.0 -\`-- UNMET DEPENDENCY ipsum@^1.0.0 +\`-- UNMET DEPENDENCY ipsum@^1.0.0  ` exports[`test/lib/commands/ls.js TAP ls cycle deps > should print tree output containing deduped ref 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-cycle-deps +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}/tap-testdir-ls-ls-cycle-deps-with-filter-args -\`-- a@1.0.0 +test-npm-ls@1.0.0 {CWD}/prefix +\`-- a@1.0.0  \`-- b@1.0.0 - \`-- a@1.0.0 deduped + \`-- a@1.0.0 deduped  ` exports[`test/lib/commands/ls.js TAP ls deduped missing dep > should output parseable signaling missing peer dep in problems 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-deduped-missing-dep +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}/tap-testdir-ls-ls-default---depth-value-should-be-0 +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}/tap-testdir-ls-ls-empty-location +{CWD}/prefix \`-- (empty) - ` exports[`test/lib/commands/ls.js TAP ls extraneous deps > should output containing problems info 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-extraneous-deps +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 1`] = ` -test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-using-depth-option +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 1`] = ` -test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-using-depth-option +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 1`] = ` -test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-using-depth-option +exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should print expected result > output 1`] = ` +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`] = ` -filter-by-child-of-missing-dep@1.0.0 {CWD}/tap-testdir-ls-ls-filtering-by-child-of-missing-dep +filter-by-child-of-missing-dep@1.0.0 {CWD}/prefix +-- b@1.0.0 extraneous | \`-- c@1.0.0 deduped +-- 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}/tap-testdir-ls-ls-from-and-resolved-properties +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`] = ` -{CWD}/tap-testdir-ls-ls-global +{CWD}/global +-- 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}/tap-testdir-ls-ls-invalid-deduped-dep +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  ` exports[`test/lib/commands/ls.js TAP ls invalid peer dep > should output tree signaling mismatching peer dep in problems 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-invalid-peer-dep +test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 +-- dev-dep@1.0.0 | \`-- foo@1.0.0 @@ -437,52 +425,46 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-invalid-peer-dep +-- 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}/tap-testdir-ls-ls-json-read-problems +{CWD}/prefix \`-- (empty) - ` -exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should filter by parent folder workspace config 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +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 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter single workspace > output 1`] = ` +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 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter using workspace config > output 1`] = ` +workspaces-tree@1.0.0 {CWD}/prefix \`-- a@1.0.0 -> ./a +-- baz@1.0.0 +-- c@1.0.0 \`-- 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 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should include root and specified workspace > output 1`] = ` +workspaces-tree@1.0.0 {CWD}/prefix +-- d@1.0.0 -> ./d | \`-- 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 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list --all workspaces properly > output 1`] = ` +workspaces-tree@1.0.0 {CWD}/prefix +-- a@1.0.0 -> ./a | +-- baz@1.0.0 | +-- c@1.0.0 @@ -494,11 +476,10 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac +-- 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 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list only prod deps of workspaces > output 1`] = ` +workspaces-tree@1.0.0 {CWD}/prefix +-- a@1.0.0 -> ./a | +-- c@1.0.0 | \`-- d@1.0.0 deduped -> ./d @@ -509,86 +490,92 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac +-- 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 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces -+-- a@1.0.0 -> ./a +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 | +-- 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  ` -exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should not list workspaces with --no-workspaces 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should not list workspaces with --no-workspaces > output 1`] = ` +workspaces-tree@1.0.0 {CWD}/prefix \`-- pacote@1.0.0  ` -exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should print all tree and filter by dep within only the ws subtree 1`] = ` -workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces +exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should print all tree and filter by dep within only the ws subtree > output 1`] = ` +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`] = ` -{CWD}/tap-testdir-ls-ls-missing-package.json +{CWD}/prefix +-- chai@1.0.0 extraneous +-- 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`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-missing-invalid-extraneous +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 | \`-- 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`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-no-args +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 output 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 output 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 print deduped symlinks > should output tree containing linked deps 1`] = ` -print-deduped-symlinks@1.0.0 {CWD}/tap-testdir-ls-ls-print-deduped-symlinks +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}/tap-testdir-ls-ls-resolved-points-to-git-ref +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`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-unmet-optional-dep +test-npm-ls@1.0.0 {CWD}/prefix +-- chai@1.0.0 +-- 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 @@ -596,102 +583,91 @@ 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}/tap-testdir-ls-ls-unmet-peer-dep +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}/tap-testdir-ls-ls-using-aliases +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}/tap-testdir-ls-ls-with-args-and-dedupe-entries +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  ` exports[`test/lib/commands/ls.js TAP ls with args and different order of items > should print tree output containing deduped ref 1`] = ` -dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-args-and-different-order-of-items +dedupe-entries@1.0.0 {CWD}/prefix +-- @npmcli/a@1.0.0 | \`-- @npmcli/c@1.0.0 deduped +-- @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}/tap-testdir-ls-ls-with-dot-filter-arg +exports[`test/lib/commands/ls.js TAP ls with dot filter arg > should output tree containing 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}/tap-testdir-ls-ls-with-filter-arg -\`-- chai@1.0.0 +exports[`test/lib/commands/ls.js TAP ls with filter arg > should output tree containing only occurrences of filtered by package and colored output 1`] = ` +test-npm-ls@1.0.0 {CWD}/prefix +\`-- chai@1.0.0  ` -exports[`test/lib/commands/ls.js TAP ls with filter arg nested dep > should output tree contaning only occurrences of filtered package and its ancestors 1`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-filter-arg-nested-dep +exports[`test/lib/commands/ls.js TAP ls with filter arg nested dep > should output tree containing only occurrences of filtered package and its ancestors 1`] = ` +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}/tap-testdir-ls-ls-with-missing-filter-arg +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`] = ` -test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-multiple-filter-args +exports[`test/lib/commands/ls.js TAP ls with multiple filter args > should output tree containing only occurrences of multiple filtered packages and their ancestors 1`] = ` +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`] = ` -dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries +dedupe-entries@1.0.0 {CWD}/prefix +-- @npmcli/a@1.0.0 | \`-- @npmcli/b@1.1.2 deduped +-- @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`] = ` -dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries-and-not-displaying-all +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}/tap-testdir-ls-ls-workspace-and-missing-optional-dep +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`] = ` -test-npm-ls@1.0.0 {cwd}/tap-testdir-ls-show-multiple-invalid-reasons +test-npm-ls@1.0.0 {CWD}/prefix +-- cat@1.0.0 invalid: "^2.0.0" from the root project | \`-- dog@1.0.0 deduped invalid: "^1.2.3" from the root project, "^2.0.0" from node_modules/cat +-- chai@1.0.0 extraneous | \`-- 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/tap-snapshots/test/lib/commands/outdated.js.test.cjs b/tap-snapshots/test/lib/commands/outdated.js.test.cjs index ef6baa9666195..8eac2cc92dd4f 100644 --- a/tap-snapshots/test/lib/commands/outdated.js.test.cjs +++ b/tap-snapshots/test/lib/commands/outdated.js.test.cjs @@ -6,257 +6,294 @@ */ 'use strict' exports[`test/lib/commands/outdated.js TAP aliases > should display aliased outdated dep output 1`] = ` +Package Current Wanted Latest Location Depended by +cat:dog@latest 1.0.0 2.0.0 2.0.0 node_modules/cat prefix +` +exports[`test/lib/commands/outdated.js TAP aliases with version range > should display aliased outdated dep output with correct wanted values 1`] = ` Package Current Wanted Latest Location Depended by -cat:dog@latest 1.0.0 2.0.0 2.0.0 node_modules/cat tap-testdir-outdated-aliases +cat:dog@^1.0.0 1.0.0 1.0.1 2.0.0 node_modules/cat prefix ` -exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --all > must match snapshot 1`] = ` +exports[`test/lib/commands/outdated.js TAP dependent location --long --json > should display dependent location when using --long and --json 1`] = ` +{ + "dog": [ + { + "current": "1.0.0", + "wanted": "1.0.1", + "latest": "2.0.0", + "dependent": "a", + "location": "{CWD}/prefix/node_modules/dog", + "type": "dependencies", + "dependedByLocation": "a" + }, + { + "current": "1.0.0", + "wanted": "1.0.1", + "latest": "2.0.0", + "dependent": "a", + "location": "{CWD}/prefix/node_modules/dog", + "type": "dependencies", + "dependedByLocation": "nest/a" + } + ] +} +` + +exports[`test/lib/commands/outdated.js TAP dependent location --long > should display dependent location when using --long 1`] = ` +Package Current Wanted Latest Location Depended by Package Type Homepage Depended By Location +dog 1.0.0 1.0.1 2.0.0 node_modules/dog a@1.0.0 dependencies a +dog 1.0.0 1.0.1 2.0.0 node_modules/dog a@npm:nest-a@1.0.0 dependencies nest/a +` +exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --all > must match snapshot 1`] = ` Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps -chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps -theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps +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 --json --long > must match snapshot 1`] = ` - { "cat": { "current": "1.0.0", "wanted": "1.0.1", "latest": "1.0.1", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat", - "type": "dependencies" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/cat", + "type": "dependencies", + "dependedByLocation": "" }, "chai": { "current": "1.0.0", "wanted": "1.0.1", "latest": "1.0.1", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai", - "type": "peerDependencies" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/chai", + "type": "peerDependencies", + "dependedByLocation": "" }, "dog": { "current": "1.0.1", "wanted": "1.0.1", "latest": "2.0.0", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog", - "type": "dependencies" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/dog", + "type": "dependencies", + "dependedByLocation": "" }, "theta": { "wanted": "1.0.1", "latest": "1.0.1", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "type": "dependencies" + "dependent": "prefix", + "type": "dependencies", + "dependedByLocation": "" } } ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --json > must match snapshot 1`] = ` - { "cat": { "current": "1.0.0", "wanted": "1.0.1", "latest": "1.0.1", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/cat" }, "chai": { "current": "1.0.0", "wanted": "1.0.1", "latest": "1.0.1", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/chai" }, "dog": { "current": "1.0.1", "wanted": "1.0.1", "latest": "2.0.0", - "dependent": "tap-testdir-outdated-should-display-outdated-deps", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/dog" }, "theta": { "wanted": "1.0.1", "latest": "1.0.1", - "dependent": "tap-testdir-outdated-should-display-outdated-deps" + "dependent": "prefix" } } ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --long > must match snapshot 1`] = ` - -Package Current Wanted Latest Location Depended by Package Type Homepage -cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps dependencies -chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps peerDependencies -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps dependencies -theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps dependencies +Package Current Wanted Latest Location Depended by Package Type Homepage Depended By Location +cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix dependencies +chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix peerDependencies +dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix dependencies +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 tap-testdir-outdated-should-display-outdated-deps -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps -theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps +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 tap-testdir-outdated-should-display-outdated-deps -chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps -theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps +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 tap-testdir-outdated-should-display-outdated-deps -chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps +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`] = ` - -{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:tap-testdir-outdated-should-display-outdated-deps:dependencies: -{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:tap-testdir-outdated-should-display-outdated-deps:peerDependencies: -{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:tap-testdir-outdated-should-display-outdated-deps:dependencies: -:theta@1.0.1:MISSING:theta@1.0.1:tap-testdir-outdated-should-display-outdated-deps:dependencies: +{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:prefix:dependencies:: +{CWD}/prefix/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:prefix:peerDependencies:: +{CWD}/prefix/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:prefix:dependencies:: +:theta@1.0.1:MISSING:theta@1.0.1:prefix:dependencies:: ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --parseable > must match snapshot 1`] = ` - -{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:tap-testdir-outdated-should-display-outdated-deps -{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:tap-testdir-outdated-should-display-outdated-deps -{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:tap-testdir-outdated-should-display-outdated-deps -:theta@1.0.1:MISSING:theta@1.0.1:tap-testdir-outdated-should-display-outdated-deps +{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:prefix +{CWD}/prefix/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:prefix +{CWD}/prefix/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:prefix +:theta@1.0.1:MISSING:theta@1.0.1:prefix ` 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 tap-testdir-outdated-should-display-outdated-deps -chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps -theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps +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`] = ` - Package Current Wanted Latest Location Depended by cat 1.0.0 1.0.1 1.0.1 node_modules/cat global ` exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated specific dep > must match snapshot 1`] = ` - Package Current Wanted Latest Location Depended by -cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps +cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display all dependencies 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display all dependencies > 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 chai 1.0.0 1.0.1 1.0.1 node_modules/chai foo -dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-workspaces +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 +theta MISSING 1.0.1 1.0.1 - d@1.0.0 +theta MISSING 1.0.1 1.0.1 - e@1.0.0 ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display json results filtered by ws 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display json results filtered by ws > output 1`] = ` { "cat": { "current": "1.0.0", "wanted": "1.0.1", "latest": "1.0.1", "dependent": "a", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat" + "location": "{CWD}/prefix/node_modules/cat" } } ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display missing deps when filtering by ws 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display missing deps when filtering by ws > output 1`] = ` Package Current Wanted Latest Location Depended by theta MISSING 1.0.1 1.0.1 - c@1.0.0 ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display nested deps when filtering by ws and using --all 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display nested deps when filtering by ws and using --all > 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 chai 1.0.0 1.0.1 1.0.1 node_modules/chai foo ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display no results if ws has no deps to display 1`] = ` +exports[`test/lib/commands/outdated.js TAP workspaces should display no results if ws has no deps to display > output 1`] = ` ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display only root outdated when ws disabled 1`] = ` +exports[`test/lib/commands/outdated.js TAP workspaces should display only root outdated when ws disabled > output 1`] = ` ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display parseable results filtered by ws 1`] = ` - -{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a +exports[`test/lib/commands/outdated.js TAP workspaces should display parseable results filtered by ws > output 1`] = ` +{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display results filtered by ws 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display results filtered by ws > 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 ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdated deps human output 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated deps human output > 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 tap-testdir-outdated-workspaces +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 +theta MISSING 1.0.1 1.0.1 - d@1.0.0 +theta MISSING 1.0.1 1.0.1 - e@1.0.0 ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdated deps json output 1`] = ` - +exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated deps json output > output 1`] = ` { "cat": { "current": "1.0.0", "wanted": "1.0.1", "latest": "1.0.1", "dependent": "a", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat" + "location": "{CWD}/prefix/node_modules/cat" }, "dog": { "current": "1.0.1", "wanted": "1.0.1", "latest": "2.0.0", - "dependent": "tap-testdir-outdated-workspaces", - "location": "{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/dog" + "dependent": "prefix", + "location": "{CWD}/prefix/node_modules/dog" }, - "theta": { - "wanted": "1.0.1", - "latest": "1.0.1", - "dependent": "c" - } + "theta": [ + { + "wanted": "1.0.1", + "latest": "1.0.1", + "dependent": "c" + }, + { + "wanted": "1.0.1", + "latest": "1.0.1", + "dependent": "d" + }, + { + "wanted": "1.0.1", + "latest": "1.0.1", + "dependent": "e" + } + ] } ` -exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdated deps parseable output 1`] = ` - -{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a -{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:tap-testdir-outdated-workspaces +exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated deps parseable output > output 1`] = ` +{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a +{CWD}/prefix/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:prefix :theta@1.0.1:MISSING:theta@1.0.1:c +:theta@1.0.1:MISSING:theta@1.0.1:d +:theta@1.0.1:MISSING:theta@1.0.1:e ` -exports[`test/lib/commands/outdated.js TAP workspaces > should highlight ws in dependend by section 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 tap-testdir-outdated-workspaces -theta MISSING 1.0.1 1.0.1 - c@1.0.0 +exports[`test/lib/commands/outdated.js TAP workspaces should highlight ws in depended 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 +theta MISSING 1.0.1 1.0.1 - d@1.0.0 +theta MISSING 1.0.1 1.0.1 - e@1.0.0 ` diff --git a/tap-snapshots/test/lib/commands/pack.js.test.cjs b/tap-snapshots/test/lib/commands/pack.js.test.cjs index e3219b45ed54f..9ec24b3816261 100644 --- a/tap-snapshots/test/lib/commands/pack.js.test.cjs +++ b/tap-snapshots/test/lib/commands/pack.js.test.cjs @@ -7,22 +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: 136 B - unpacked size: 41 B - shasum: a92a0679a70a450f14f98a468756948a679e4107 - integrity: sha512-Gka9ZV/Bryxky[...]LgMJ+0F+FhXMA== - 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 [ + "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", +] +` + +exports[`test/lib/commands/pack.js TAP foreground-scripts defaults to true > logs pack contents 1`] = ` +Array [ + "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", ] ` @@ -41,14 +71,14 @@ Array [ Object { "mode": 420, "path": "package.json", - "size": 41, + "size": "{size}", }, ], "id": "test-package@1.0.0", - "integrity": "sha512-Gka9ZV/BryxkypfvMpTvLfaJE1AUi7PK1EAbYqnVzqtucf6QvUK4CFsLVzagY1GwZVx2T1jwWLgMJ+0F+FhXMA==", + "integrity": "{integrity}", "name": "test-package", - "shasum": "a92a0679a70a450f14f98a468756948a679e4107", - "size": 136, + "shasum": "{sha}", + "size": "{size}", "unpackedSize": 41, "version": "1.0.0", }, @@ -56,23 +86,60 @@ Array [ ] ` +exports[`test/lib/commands/pack.js TAP should log scoped package output as valid json > logs pack contents 1`] = ` +Array [] +` + +exports[`test/lib/commands/pack.js TAP should log scoped package output as valid json > outputs as json 1`] = ` +Array [ + Array [ + Object { + "bundled": Array [], + "entryCount": 1, + "filename": "myscope-test-package-1.0.0.tgz", + "files": Array [ + Object { + "mode": 420, + "path": "package.json", + "size": "{size}", + }, + ], + "id": "@myscope/test-package@1.0.0", + "integrity": "{integrity}", + "name": "@myscope/test-package", + "shasum": "{sha}", + "size": "{size}", + "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: 136 B - unpacked size: 41 B - shasum: a92a0679a70a450f14f98a468756948a679e4107 - integrity: sha512-Gka9ZV/Bryxky[...]LgMJ+0F+FhXMA== - 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/tap-snapshots/test/lib/commands/profile.js.test.cjs b/tap-snapshots/test/lib/commands/profile.js.test.cjs index 2103ccdd32e33..1fbb09de29f3c 100644 --- a/tap-snapshots/test/lib/commands/profile.js.test.cjs +++ b/tap-snapshots/test/lib/commands/profile.js.test.cjs @@ -8,8 +8,7 @@ exports[`test/lib/commands/profile.js TAP enable-2fa from token and set otp, retries on pending and verifies with qrcode > should output 2fa enablement success msgs 1`] = ` Scan into your authenticator app: qrcode - Or enter code: -1234 + Or enter code: 1234 2FA successfully enabled. Below are your recovery codes, please print these out. You will need these to recover access to your account if you lose your authentication device. 123456 @@ -47,56 +46,56 @@ github https://github.com/npm ` exports[`test/lib/commands/profile.js TAP profile get no args default output > should output table with contents 1`] = ` -name: foo -email: foo@github.com (verified) -two-factor auth: auth-and-writes -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z +name: foo +email: foo@github.com (verified) +two-factor auth: auth-and-writes +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z ` exports[`test/lib/commands/profile.js TAP profile get no args no tfa enabled > should output expected profile values 1`] = ` -name: foo -email: foo@github.com (verified) -two-factor auth: disabled -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z +name: foo +email: foo@github.com (verified) +two-factor auth: disabled +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z ` exports[`test/lib/commands/profile.js TAP profile get no args profile has cidr_whitelist item > should output table with contents 1`] = ` -name: foo -email: foo@github.com (verified) -two-factor auth: auth-and-writes -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z -cidr_whitelist: 192.168.1.1 +name: foo +email: foo@github.com (verified) +two-factor auth: auth-and-writes +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z +cidr_whitelist: 192.168.1.1 ` exports[`test/lib/commands/profile.js TAP profile get no args unverified email > should output table with contents 1`] = ` -name: foo -email: foo@github.com(unverified) -two-factor auth: auth-and-writes -fullname: Foo Bar -homepage: https://github.com -freenode: foobar -twitter: https://twitter.com/npmjs -github: https://github.com/npm -created: 2015-02-26T01:26:37.384Z -updated: 2020-08-12T16:19:35.326Z +name: foo +email: foo@github.com(unverified) +two-factor auth: auth-and-writes +fullname: Foo Bar +homepage: https://github.com +freenode: foobar +twitter: https://twitter.com/npmjs +github: https://github.com/npm +created: 2015-02-26T01:26:37.384Z +updated: 2020-08-12T16:19:35.326Z ` exports[`test/lib/commands/profile.js TAP profile set writable key --parseable > should output parseable set key success msg 1`] = ` diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index d85a1164e22bf..96a9d064d0e4e 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -6,7 +6,7 @@ */ 'use strict' exports[`test/lib/commands/publish.js TAP _auth config default registry > new package version 1`] = ` -+ test-package@1.0.0 ++ @npmcli/test-package@1.0.0 ` exports[`test/lib/commands/publish.js TAP bare _auth and registry config > new package version 1`] = ` @@ -15,44 +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: 160 B - unpacked size: 87 B - shasum:{sha} - integrity:{sha} - total files: 1 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/ (dry-run)", - ], + "package: @npmcli/test-package@1.0.0", + "Tarball Contents", + "95B package.json", + "Tarball Details", + "name: @npmcli/test-package", + "version: 1.0.0", + "filename: npmcli-test-package-1.0.0.tgz", + "package size: {size}", + "unpacked size: 95 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 [ + "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 [ + "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)", ] ` @@ -65,32 +76,29 @@ exports[`test/lib/commands/publish.js TAP has token auth for scope configured re ` exports[`test/lib/commands/publish.js TAP ignore-scripts > new package version 1`] = ` -+ test-package@1.0.0 ++ @npmcli/test-package@1.0.0 ` exports[`test/lib/commands/publish.js TAP json > must match snapshot 1`] = ` Array [ - Array [ - "", - "Publishing to https://registry.npmjs.org/", - ], + "Publishing to https://registry.npmjs.org/ with tag latest and default access", ] ` exports[`test/lib/commands/publish.js TAP json > new package json 1`] = ` { - "id": "test-package@1.0.0", - "name": "test-package", + "id": "@npmcli/test-package@1.0.0", + "name": "@npmcli/test-package", "version": "1.0.0", - "size": 160, - "unpackedSize": 87, + "size": "{size}", + "unpackedSize": 95, "shasum": "{sha}", - "integrity": "{sha}", - "filename": "test-package-1.0.0.tgz", + "integrity": "{integrity}", + "filename": "npmcli-test-package-1.0.0.tgz", "files": [ { "path": "package.json", - "size": 87, + "size": "{size}", "mode": 420 } ], @@ -99,25 +107,220 @@ exports[`test/lib/commands/publish.js TAP json > new package json 1`] = ` } ` +exports[`test/lib/commands/publish.js TAP manifest > manifest 1`] = ` +Object { + "_id": "npm@{VERSION}", + "author": Object { + "name": "GitHub Inc.", + }, + "bin": Object { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js", + }, + "bugs": Object { + "url": "https://github.com/npm/cli/issues", + }, + "description": "a package manager for JavaScript", + "directories": Object { + "doc": "./doc", + "man": "./man", + }, + "exports": Object { + ".": Array [ + Object { + "default": "./index.js", + }, + "./index.js", + ], + "./package.json": "./package.json", + }, + "files": Array [ + "bin/", + "lib/", + "index.js", + "docs/content/", + "docs/output/", + "man/", + ], + "homepage": "https://docs.npmjs.com/", + "keywords": Array [ + "install", + "modules", + "package manager", + "package.json", + ], + "license": "Artistic-2.0", + "main": "./index.js", + "man": Array [ + "man/man1/npm-access.1", + "man/man1/npm-adduser.1", + "man/man1/npm-audit.1", + "man/man1/npm-bugs.1", + "man/man1/npm-cache.1", + "man/man1/npm-ci.1", + "man/man1/npm-completion.1", + "man/man1/npm-config.1", + "man/man1/npm-dedupe.1", + "man/man1/npm-deprecate.1", + "man/man1/npm-diff.1", + "man/man1/npm-dist-tag.1", + "man/man1/npm-docs.1", + "man/man1/npm-doctor.1", + "man/man1/npm-edit.1", + "man/man1/npm-exec.1", + "man/man1/npm-explain.1", + "man/man1/npm-explore.1", + "man/man1/npm-find-dupes.1", + "man/man1/npm-fund.1", + "man/man1/npm-help-search.1", + "man/man1/npm-help.1", + "man/man1/npm-init.1", + "man/man1/npm-install-ci-test.1", + "man/man1/npm-install-test.1", + "man/man1/npm-install.1", + "man/man1/npm-link.1", + "man/man1/npm-login.1", + "man/man1/npm-logout.1", + "man/man1/npm-ls.1", + "man/man1/npm-org.1", + "man/man1/npm-outdated.1", + "man/man1/npm-owner.1", + "man/man1/npm-pack.1", + "man/man1/npm-ping.1", + "man/man1/npm-pkg.1", + "man/man1/npm-prefix.1", + "man/man1/npm-profile.1", + "man/man1/npm-prune.1", + "man/man1/npm-publish.1", + "man/man1/npm-query.1", + "man/man1/npm-rebuild.1", + "man/man1/npm-repo.1", + "man/man1/npm-restart.1", + "man/man1/npm-root.1", + "man/man1/npm-run.1", + "man/man1/npm-sbom.1", + "man/man1/npm-search.1", + "man/man1/npm-shrinkwrap.1", + "man/man1/npm-star.1", + "man/man1/npm-stars.1", + "man/man1/npm-start.1", + "man/man1/npm-stop.1", + "man/man1/npm-team.1", + "man/man1/npm-test.1", + "man/man1/npm-token.1", + "man/man1/npm-undeprecate.1", + "man/man1/npm-uninstall.1", + "man/man1/npm-unpublish.1", + "man/man1/npm-unstar.1", + "man/man1/npm-update.1", + "man/man1/npm-version.1", + "man/man1/npm-view.1", + "man/man1/npm-whoami.1", + "man/man1/npm.1", + "man/man1/npx.1", + "man/man5/folders.5", + "man/man5/install.5", + "man/man5/npm-global.5", + "man/man5/npm-json.5", + "man/man5/npm-shrinkwrap-json.5", + "man/man5/npmrc.5", + "man/man5/package-json.5", + "man/man5/package-lock-json.5", + "man/man7/config.7", + "man/man7/dependency-selectors.7", + "man/man7/developers.7", + "man/man7/logging.7", + "man/man7/orgs.7", + "man/man7/package-spec.7", + "man/man7/registry.7", + "man/man7/removal.7", + "man/man7/scope.7", + "man/man7/scripts.7", + "man/man7/workspaces.7", + ], + "name": "npm", + "readmeFilename": "README.md", + "repository": Object { + "type": "git", + "url": "git+https://github.com/npm/cli.git", + }, + "version": "{VERSION}", +} +` + exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot 1`] = ` -+ test-package@1.0.0 ++ @npmcli/test-package@1.0.0 ` exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = ` Array [ - Array [ - "", - "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", - ], + "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)", +] +` + +exports[`test/lib/commands/publish.js TAP prioritize CLI flags over publishConfig > new package version 1`] = ` ++ @npmcli/test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP public access > must match snapshot 1`] = ` +Array [ + "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", ] ` +exports[`test/lib/commands/publish.js TAP public access > new package version 1`] = ` ++ @npm/test-package@1.0.0 +` + exports[`test/lib/commands/publish.js TAP re-loads publishConfig.registry if added during script process > new package version 1`] = ` -+ test-package@1.0.0 ++ @npmcli/test-package@1.0.0 ` exports[`test/lib/commands/publish.js TAP respects publishConfig.registry, runs appropriate scripts > new package version 1`] = ` +> @npmcli/test-package@1.0.0 prepublishOnly +> touch scripts-prepublishonly + +> @npmcli/test-package@1.0.0 publish +> touch scripts-publish + +> @npmcli/test-package@1.0.0 postpublish +> touch scripts-postpublish ++ @npmcli/test-package@1.0.0 +` + +exports[`test/lib/commands/publish.js TAP restricted access > must match snapshot 1`] = ` +Array [ + "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", +] +` + +exports[`test/lib/commands/publish.js TAP restricted access > new package version 1`] = ` ++ @npm/test-package@1.0.0 ` exports[`test/lib/commands/publish.js TAP scoped _auth config scoped registry > new package version 1`] = ` @@ -126,47 +329,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: 218 B - unpacked size: 124 B - shasum:{sha} - integrity:{sha} - total files: 2 - ), - ], - Array [ - "", - "", - ], - Array [ - "", - "Publishing to https://registry.npmjs.org/", - ], + "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", ] ` @@ -182,10 +360,18 @@ 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", - "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 "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 "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 Skipping workspace \\u001b[36mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m", ] ` @@ -197,28 +383,44 @@ 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", - "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 "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 "repository" was changed from a string to an object + publish "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git" + ), + "publish Skipping workspace workspace-p, marked as private", ] ` +exports[`test/lib/commands/publish.js TAP workspaces all workspaces - some marked private > one marked private 1`] = ` ++ workspace-a@1.2.3-a +` + +exports[`test/lib/commands/publish.js TAP workspaces different package spec > publish different package spec 1`] = ` ++ pkg@1.2.3 +` + exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in json 1`] = ` { "workspace-a": { "id": "workspace-a@1.2.3-a", "name": "workspace-a", "version": "1.2.3-a", - "size": 162, + "size": "{size}", "unpackedSize": 82, "shasum": "{sha}", - "integrity": "{sha}", + "integrity": "{integrity}", "filename": "workspace-a-1.2.3-a.tgz", "files": [ { "path": "package.json", - "size": 82, + "size": "{size}", "mode": 420 } ], @@ -229,15 +431,15 @@ exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in js "id": "workspace-b@1.2.3-n", "name": "workspace-b", "version": "1.2.3-n", - "size": 171, + "size": "{size}", "unpackedSize": 92, "shasum": "{sha}", - "integrity": "{sha}", + "integrity": "{integrity}", "filename": "workspace-b-1.2.3-n.tgz", "files": [ { "path": "package.json", - "size": 92, + "size": "{size}", "mode": 420 } ], @@ -248,15 +450,15 @@ exports[`test/lib/commands/publish.js TAP workspaces json > all workspaces in js "id": "workspace-n@1.2.3-n", "name": "workspace-n", "version": "1.2.3-n", - "size": 140, + "size": "{size}", "unpackedSize": 42, "shasum": "{sha}", - "integrity": "{sha}", + "integrity": "{integrity}", "filename": "workspace-n-1.2.3-n.tgz", "files": [ { "path": "package.json", - "size": 42, + "size": "{size}", "mode": 420 } ], diff --git a/tap-snapshots/test/lib/commands/query.js.test.cjs b/tap-snapshots/test/lib/commands/query.js.test.cjs index 0a2aa769ee638..65d625b18b029 100644 --- a/tap-snapshots/test/lib/commands/query.js.test.cjs +++ b/tap-snapshots/test/lib/commands/query.js.test.cjs @@ -13,8 +13,8 @@ exports[`test/lib/commands/query.js TAP global > should return global package 1` "_id": "lorem@2.0.0", "pkgid": "lorem@2.0.0", "location": "node_modules/lorem", - "path": "{CWD}/test/lib/commands/tap-testdir-query-global/global/node_modules/lorem", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-global/global/node_modules/lorem", + "path": "{CWD}/global/node_modules/lorem", + "realpath": "{CWD}/global/node_modules/lorem", "resolved": null, "from": [ "" @@ -22,7 +22,9 @@ exports[`test/lib/commands/query.js TAP global > should return global package 1` "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} } ] ` @@ -40,8 +42,8 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w }, "pkgid": "project@", "location": "", - "path": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix", + "path": "{CWD}/prefix", + "realpath": "{CWD}/prefix", "resolved": null, "from": [], "to": [ @@ -51,7 +53,9 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w ], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} }, { "name": "c", @@ -59,14 +63,16 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w "_id": "c@1.0.0", "pkgid": "c@1.0.0", "location": "c", - "path": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix/c", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix/c", + "path": "{CWD}/prefix/c", + "realpath": "{CWD}/prefix/c", "resolved": null, "from": [], "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} } ] ` @@ -79,14 +85,135 @@ exports[`test/lib/commands/query.js TAP linked node > should return linked node "_id": "a@1.0.0", "pkgid": "a@1.0.0", "location": "a", - "path": "{CWD}/test/lib/commands/tap-testdir-query-linked-node/prefix/a", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-linked-node/prefix/a", + "path": "{CWD}/prefix/a", + "realpath": "{CWD}/prefix/a", "resolved": null, "from": [], "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} + } +] +` + +exports[`test/lib/commands/query.js TAP missing > should return missing node 1`] = ` +[ + { + "name": "b", + "version": "^1.0.0", + "_id": "b@^1.0.0", + "pkgid": "b@^1.0.0", + "path": null, + "realpath": null, + "resolved": null, + "from": [ + "" + ], + "to": [], + "dev": true, + "inBundle": false, + "deduped": false, + "overridden": false, + "queryContext": { + "missing": true + } + } +] +` + +exports[`test/lib/commands/query.js TAP package-lock-only missing workspace in tree > should return empty array for missing workspace 1`] = ` +[] +` + +exports[`test/lib/commands/query.js TAP package-lock-only with package lock > should return valid response with only lock info 1`] = ` +[ + { + "name": "project", + "dependencies": { + "a": "^1.0.0" + }, + "pkgid": "project@", + "location": "", + "path": "{CWD}/prefix", + "realpath": "{CWD}/prefix", + "resolved": null, + "from": [], + "to": [ + "node_modules/a" + ], + "dev": false, + "inBundle": false, + "deduped": false, + "overridden": false, + "queryContext": {} + }, + { + "version": "1.2.3", + "resolved": "https://dummy.npmjs.org/a/-/a-1.2.3.tgz", + "integrity": "sha512-dummy", + "engines": { + "node": ">=14.17" + }, + "name": "a", + "_id": "a@1.2.3", + "pkgid": "a@1.2.3", + "location": "node_modules/a", + "path": "{CWD}/prefix/node_modules/a", + "realpath": "{CWD}/prefix/node_modules/a", + "from": [ + "" + ], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false, + "overridden": false, + "queryContext": {} + } +] +` + +exports[`test/lib/commands/query.js TAP package-lock-only with package lock and workspace > should return workspace object with package-lock-only 1`] = ` +[ + { + "name": "root", + "workspaces": [ + "packages/*" + ], + "pkgid": "root@", + "location": "", + "path": "{CWD}/prefix", + "realpath": "{CWD}/prefix", + "resolved": null, + "from": [], + "to": [ + "node_modules/a" + ], + "dev": false, + "inBundle": false, + "deduped": false, + "overridden": false, + "queryContext": {} + }, + { + "name": "a", + "version": "1.0.0", + "_id": "a@1.0.0", + "pkgid": "a@1.0.0", + "location": "packages/a", + "path": "{CWD}/prefix/packages/a", + "realpath": "{CWD}/prefix/packages/a", + "resolved": null, + "from": [], + "to": [], + "dev": false, + "inBundle": false, + "deduped": false, + "overridden": false, + "queryContext": {} } ] ` @@ -101,8 +228,8 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin }, "pkgid": "project@", "location": "", - "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix", + "path": "{CWD}/prefix", + "realpath": "{CWD}/prefix", "resolved": null, "from": [], "to": [ @@ -111,13 +238,15 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin ], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} }, { "pkgid": "a@", "location": "node_modules/a", - "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a", + "path": "{CWD}/prefix/node_modules/a", + "realpath": "{CWD}/prefix/node_modules/a", "resolved": null, "from": [ "" @@ -125,13 +254,15 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} }, { "pkgid": "b@", "location": "node_modules/b", - "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b", + "path": "{CWD}/prefix/node_modules/b", + "realpath": "{CWD}/prefix/node_modules/b", "resolved": null, "from": [ "" @@ -139,7 +270,9 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} } ] ` @@ -157,8 +290,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object }, "pkgid": "project@", "location": "", - "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix", + "path": "{CWD}/prefix", + "realpath": "{CWD}/prefix", "resolved": null, "from": [], "to": [ @@ -167,13 +300,15 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object ], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} }, { "pkgid": "a@", "location": "node_modules/a", - "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/a", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/a", + "path": "{CWD}/prefix/node_modules/a", + "realpath": "{CWD}/prefix/node_modules/a", "resolved": null, "from": [ "" @@ -181,13 +316,15 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} }, { "pkgid": "b@", "location": "node_modules/b", - "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/b", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/b", + "path": "{CWD}/prefix/node_modules/b", + "realpath": "{CWD}/prefix/node_modules/b", "resolved": null, "from": [ "" @@ -195,7 +332,9 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} } ] ` @@ -208,14 +347,16 @@ exports[`test/lib/commands/query.js TAP workspace query > should return workspac "_id": "c@1.0.0", "pkgid": "c@1.0.0", "location": "c", - "path": "{CWD}/test/lib/commands/tap-testdir-query-workspace-query/prefix/c", - "realpath": "{CWD}/test/lib/commands/tap-testdir-query-workspace-query/prefix/c", + "path": "{CWD}/prefix/c", + "realpath": "{CWD}/prefix/c", "resolved": null, "from": [], "to": [], "dev": false, "inBundle": false, - "deduped": false + "deduped": false, + "overridden": false, + "queryContext": {} } ] ` diff --git a/tap-snapshots/test/lib/commands/run-script.js.test.cjs b/tap-snapshots/test/lib/commands/run-script.js.test.cjs new file mode 100644 index 0000000000000..189e2f84d2901 --- /dev/null +++ b/tap-snapshots/test/lib/commands/run-script.js.test.cjs @@ -0,0 +1,274 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/run-script.js TAP list scripts no args > basic report 1`] = ` +Lifecycle scripts included in x@1.2.3: + test + exit 2 + start + node server.js + stop + node kill-server.js +available via \`npm run-script\`: + preenv + echo before the env + postenv + echo after the env +` + +exports[`test/lib/commands/run-script.js TAP list scripts parseable > must match snapshot 1`] = ` +test:exit 2 +start:node server.js +stop:node kill-server.js +preenv:echo before the env +postenv:echo after the env +` + +exports[`test/lib/commands/run-script.js TAP list scripts warn json > json report 1`] = ` +{ + "test": "exit 2", + "start": "node server.js", + "stop": "node kill-server.js", + "preenv": "echo before the env", + "postenv": "echo after the env" +} +` + +exports[`test/lib/commands/run-script.js TAP list scripts, only commands > must match snapshot 1`] = ` +Lifecycle scripts included in x@1.2.3: + preversion + echo doing the version dance +` + +exports[`test/lib/commands/run-script.js TAP list scripts, only non-commands > must match snapshot 1`] = ` +Scripts available in x@1.2.3 via \`npm run-script\`: + glorp + echo doing the glerp glop +` + +exports[`test/lib/commands/run-script.js TAP workspaces failed workspace run with succeeded runs > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`glorp\` failed with error: +code ERR +workspace a@1.0.0 +location {CWD}/prefix/packages/a +ERR +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts --json > must match snapshot 1`] = ` +{ + "a": { + "glorp": "echo a doing the glerp glop" + }, + "b": { + "glorp": "echo b doing the glerp glop" + }, + "c": { + "test": "exit 0", + "posttest": "echo posttest", + "lorem": "echo c lorem" + }, + "d": { + "test": "exit 0", + "posttest": "echo posttest" + }, + "e": { + "test": "exit 0", + "start": "echo start something" + }, + "noscripts": {} +} +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts --parseable > must match snapshot 1`] = ` +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 +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest +available via \`npm run-script\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list all scripts with colors > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest +available via \`npm run-script\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by name > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop +` + +exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by parent folder > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run-script\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest +available via \`npm run-script\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run-script.js TAP workspaces list regular scripts, filtered by path > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run-script\`: + glorp + echo a doing the glerp glop +` + +exports[`test/lib/commands/run-script.js TAP workspaces missing scripts in all workspaces > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`missing-script\` failed with error: +workspace a@1.0.0 +location {CWD}/prefix/packages/a +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=a@1.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace b@2.0.0 +location {CWD}/prefix/packages/b +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=b@2.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace c@1.0.0 +location {CWD}/prefix/packages/c +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=c@1.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace d@1.0.0 +location {CWD}/prefix/packages/d +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=d@1.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace e +location {CWD}/prefix/packages/e +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=e +Lifecycle script \`missing-script\` failed with error: +workspace noscripts@1.0.0 +location {CWD}/prefix/packages/noscripts +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=noscripts@1.0.0 +` + +exports[`test/lib/commands/run-script.js TAP workspaces missing scripts in some workspaces > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`test\` failed with error: +workspace a@1.0.0 +location {CWD}/prefix/packages/a +Missing script: "test" +npm error +To see a list of scripts, run: + npm run --workspace=a@1.0.0 +Lifecycle script \`test\` failed with error: +workspace b@2.0.0 +location {CWD}/prefix/packages/b +Missing script: "test" +npm error +To see a list of scripts, run: + npm run --workspace=b@2.0.0 +` + +exports[`test/lib/commands/run-script.js TAP workspaces single failed workspace run > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`test\` failed with error: +workspace c@1.0.0 +location {CWD}/prefix/packages/c +err +` diff --git a/tap-snapshots/test/lib/commands/run.js.test.cjs b/tap-snapshots/test/lib/commands/run.js.test.cjs new file mode 100644 index 0000000000000..367415db8fe07 --- /dev/null +++ b/tap-snapshots/test/lib/commands/run.js.test.cjs @@ -0,0 +1,274 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/run.js TAP list scripts no args > basic report 1`] = ` +Lifecycle scripts included in x@1.2.3: + test + exit 2 + start + node server.js + stop + node kill-server.js +available via \`npm run\`: + preenv + echo before the env + postenv + echo after the env +` + +exports[`test/lib/commands/run.js TAP list scripts parseable > must match snapshot 1`] = ` +test:exit 2 +start:node server.js +stop:node kill-server.js +preenv:echo before the env +postenv:echo after the env +` + +exports[`test/lib/commands/run.js TAP list scripts warn json > json report 1`] = ` +{ + "test": "exit 2", + "start": "node server.js", + "stop": "node kill-server.js", + "preenv": "echo before the env", + "postenv": "echo after the env" +} +` + +exports[`test/lib/commands/run.js TAP list scripts, only commands > must match snapshot 1`] = ` +Lifecycle scripts included in x@1.2.3: + preversion + echo doing the version dance +` + +exports[`test/lib/commands/run.js TAP list scripts, only non-commands > must match snapshot 1`] = ` +Scripts available in x@1.2.3 via \`npm run\`: + glorp + echo doing the glerp glop +` + +exports[`test/lib/commands/run.js TAP workspaces failed workspace run with succeeded runs > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`glorp\` failed with error: +code ERR +workspace a@1.0.0 +location {CWD}/prefix/packages/a +ERR +` + +exports[`test/lib/commands/run.js TAP workspaces list all scripts --json > must match snapshot 1`] = ` +{ + "a": { + "glorp": "echo a doing the glerp glop" + }, + "b": { + "glorp": "echo b doing the glerp glop" + }, + "c": { + "test": "exit 0", + "posttest": "echo posttest", + "lorem": "echo c lorem" + }, + "d": { + "test": "exit 0", + "posttest": "echo posttest" + }, + "e": { + "test": "exit 0", + "start": "echo start something" + }, + "noscripts": {} +} +` + +exports[`test/lib/commands/run.js TAP workspaces list all scripts --parseable > must match snapshot 1`] = ` +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 +` + +exports[`test/lib/commands/run.js TAP workspaces list all scripts > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest +available via \`npm run\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run.js TAP workspaces list all scripts with colors > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest +available via \`npm run\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run.js TAP workspaces list regular scripts, filtered by name > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run\`: + glorp + echo b doing the glerp glop +` + +exports[`test/lib/commands/run.js TAP workspaces list regular scripts, filtered by parent folder > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run\`: + glorp + echo a doing the glerp glop + +Scripts available in b@2.0.0 via \`npm run\`: + glorp + echo b doing the glerp glop + +Lifecycle scripts included in c@1.0.0: + test + exit 0 + posttest + echo posttest +available via \`npm run\`: + lorem + echo c lorem + +Lifecycle scripts included in d@1.0.0: + test + exit 0 + posttest + echo posttest + +Lifecycle scripts included in e: + test + exit 0 + start + echo start something +` + +exports[`test/lib/commands/run.js TAP workspaces list regular scripts, filtered by path > must match snapshot 1`] = ` +Scripts available in a@1.0.0 via \`npm run\`: + glorp + echo a doing the glerp glop +` + +exports[`test/lib/commands/run.js TAP workspaces missing scripts in all workspaces > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`missing-script\` failed with error: +workspace a@1.0.0 +location {CWD}/prefix/packages/a +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=a@1.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace b@2.0.0 +location {CWD}/prefix/packages/b +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=b@2.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace c@1.0.0 +location {CWD}/prefix/packages/c +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=c@1.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace d@1.0.0 +location {CWD}/prefix/packages/d +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=d@1.0.0 +Lifecycle script \`missing-script\` failed with error: +workspace e +location {CWD}/prefix/packages/e +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=e +Lifecycle script \`missing-script\` failed with error: +workspace noscripts@1.0.0 +location {CWD}/prefix/packages/noscripts +Missing script: "missing-script" +npm error +To see a list of scripts, run: + npm run --workspace=noscripts@1.0.0 +` + +exports[`test/lib/commands/run.js TAP workspaces missing scripts in some workspaces > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`test\` failed with error: +workspace a@1.0.0 +location {CWD}/prefix/packages/a +Missing script: "test" +npm error +To see a list of scripts, run: + npm run --workspace=a@1.0.0 +Lifecycle script \`test\` failed with error: +workspace b@2.0.0 +location {CWD}/prefix/packages/b +Missing script: "test" +npm error +To see a list of scripts, run: + npm run --workspace=b@2.0.0 +` + +exports[`test/lib/commands/run.js TAP workspaces single failed workspace run > should log error msgs for each workspace script 1`] = ` +Lifecycle script \`test\` failed with error: +workspace c@1.0.0 +location {CWD}/prefix/packages/c +err +` diff --git a/tap-snapshots/test/lib/commands/sbom.js.test.cjs b/tap-snapshots/test/lib/commands/sbom.js.test.cjs new file mode 100644 index 0000000000000..3f1600d9beb3c --- /dev/null +++ b/tap-snapshots/test/lib/commands/sbom.js.test.cjs @@ -0,0 +1,1636 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/commands/sbom.js TAP sbom --omit dev > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-sbom@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-sbom-1.0.0" + ], + "packages": [ + { + "name": "test-npm-sbom", + "SPDXID": "SPDXRef-Package-test-npm-sbom-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-sbom@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.0.0" + } + ] + }, + { + "name": "dog", + "SPDXID": "SPDXRef-Package-dog-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo/node_modules/dog", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/dog@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-dog-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom --omit optional > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-sbom@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-sbom-1.0.0" + ], + "packages": [ + { + "name": "test-npm-sbom", + "SPDXID": "SPDXRef-Package-test-npm-sbom-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-sbom@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom --omit peer > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-sbom@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-sbom-1.0.0" + ], + "packages": [ + { + "name": "test-npm-sbom", + "SPDXID": "SPDXRef-Package-test-npm-sbom-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-sbom@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom basic sbom - cyclonedx > must match snapshot 1`] = ` +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:12345678-90ab-cdef-1234-567890abcdef", + "version": 1, + "metadata": { + "timestamp": "2020-01-01T00:00:00.000Z", + "lifecycles": [ + { + "phase": "build" + } + ], + "tools": [ + { + "vendor": "npm", + "name": "cli", + "version": "10.0.0" + } + ], + "component": { + "bom-ref": "test-npm-sbom@1.0.0", + "type": "application", + "name": "prefix", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/test-npm-sbom@1.0.0", + "properties": [], + "externalReferences": [] + } + }, + "components": [ + { + "bom-ref": "chai@1.0.0", + "type": "library", + "name": "chai", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/chai@1.0.0", + "properties": [], + "externalReferences": [] + }, + { + "bom-ref": "foo@1.0.0", + "type": "library", + "name": "foo", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/foo@1.0.0", + "properties": [], + "externalReferences": [] + }, + { + "bom-ref": "dog@1.0.0", + "type": "library", + "name": "dog", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/dog@1.0.0", + "properties": [], + "externalReferences": [] + } + ], + "dependencies": [ + { + "ref": "test-npm-sbom@1.0.0", + "dependsOn": [ + "foo@1.0.0", + "chai@1.0.0" + ] + }, + { + "ref": "chai@1.0.0", + "dependsOn": [] + }, + { + "ref": "foo@1.0.0", + "dependsOn": [ + "dog@1.0.0" + ] + }, + { + "ref": "dog@1.0.0", + "dependsOn": [] + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom basic sbom - spdx > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-sbom@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-sbom-1.0.0" + ], + "packages": [ + { + "name": "test-npm-sbom", + "SPDXID": "SPDXRef-Package-test-npm-sbom-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-sbom@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.0.0" + } + ] + }, + { + "name": "dog", + "SPDXID": "SPDXRef-Package-dog-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo/node_modules/dog", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/dog@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-dog-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom duplicate deps - cyclonedx > must match snapshot 1`] = ` +{ + "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:12345678-90ab-cdef-1234-567890abcdef", + "version": 1, + "metadata": { + "timestamp": "2020-01-01T00:00:00.000Z", + "lifecycles": [ + { + "phase": "build" + } + ], + "tools": [ + { + "vendor": "npm", + "name": "cli", + "version": "10.0.0" + } + ], + "component": { + "bom-ref": "test-npm-sbom@1.0.0", + "type": "library", + "name": "prefix", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/test-npm-sbom@1.0.0", + "properties": [], + "externalReferences": [] + } + }, + "components": [ + { + "bom-ref": "bar@1.0.0", + "type": "library", + "name": "bar", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/bar@1.0.0", + "properties": [], + "externalReferences": [] + }, + { + "bom-ref": "chai@1.0.0", + "type": "library", + "name": "chai", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/chai@1.0.0", + "properties": [], + "externalReferences": [] + }, + { + "bom-ref": "chai@2.0.0", + "type": "library", + "name": "chai", + "version": "2.0.0", + "scope": "required", + "purl": "pkg:npm/chai@2.0.0", + "properties": [], + "externalReferences": [] + }, + { + "bom-ref": "foo@1.0.0", + "type": "library", + "name": "foo", + "version": "1.0.0", + "scope": "required", + "purl": "pkg:npm/foo@1.0.0", + "properties": [], + "externalReferences": [] + } + ], + "dependencies": [ + { + "ref": "test-npm-sbom@1.0.0", + "dependsOn": [ + "foo@1.0.0", + "bar@1.0.0", + "chai@2.0.0" + ] + }, + { + "ref": "bar@1.0.0", + "dependsOn": [ + "chai@1.0.0" + ] + }, + { + "ref": "chai@1.0.0", + "dependsOn": [] + }, + { + "ref": "chai@2.0.0", + "dependsOn": [] + }, + { + "ref": "foo@1.0.0", + "dependsOn": [ + "chai@1.0.0" + ] + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom duplicate deps - spdx > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-sbom@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-sbom-1.0.0" + ], + "packages": [ + { + "name": "test-npm-sbom", + "SPDXID": "SPDXRef-Package-test-npm-sbom-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-sbom@1.0.0" + } + ] + }, + { + "name": "bar", + "SPDXID": "SPDXRef-Package-bar-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/bar", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/bar@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/bar/node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-2.0.0", + "versionInfo": "2.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@2.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-bar-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-2.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-sbom-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-bar-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom extraneous dep > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-ls@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-ls-1.0.0" + ], + "packages": [ + { + "name": "test-npm-ls", + "SPDXID": "SPDXRef-Package-test-npm-ls-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-ls@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.0.0" + } + ] + }, + { + "name": "dog", + "SPDXID": "SPDXRef-Package-dog-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo/node_modules/dog", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/dog@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-dog-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "OPTIONAL_DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom loading a tree containing workspaces should filter workspaces with --workspace > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "workspaces-tree@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-workspaces-tree-1.0.0" + ], + "packages": [ + { + "name": "workspaces-tree", + "SPDXID": "SPDXRef-Package-workspaces-tree-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/workspaces-tree@1.0.0" + } + ] + }, + { + "name": "a", + "SPDXID": "SPDXRef-Package-a-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/a", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/a@1.0.0" + } + ] + }, + { + "name": "d", + "SPDXID": "SPDXRef-Package-d-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/d", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/d@1.0.0" + } + ] + }, + { + "name": "bar", + "SPDXID": "SPDXRef-Package-bar-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/bar", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/bar@1.0.0" + } + ] + }, + { + "name": "baz", + "SPDXID": "SPDXRef-Package-baz-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/baz", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/baz@1.0.0" + } + ] + }, + { + "name": "c", + "SPDXID": "SPDXRef-Package-c-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/c", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/c@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.1.1", + "versionInfo": "1.1.1", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.1.1" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-a-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-d-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-c-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-a-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-d-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-a-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-baz-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-a-1.0.0", + "relationshipType": "DEV_DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.1.1", + "relatedSpdxElement": "SPDXRef-Package-d-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-bar-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.1.1", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom loading a tree containing workspaces should filter workspaces with multiple --workspace flags > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "workspaces-tree@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-workspaces-tree-1.0.0" + ], + "packages": [ + { + "name": "workspaces-tree", + "SPDXID": "SPDXRef-Package-workspaces-tree-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/workspaces-tree@1.0.0" + } + ] + }, + { + "name": "e", + "SPDXID": "SPDXRef-Package-e-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/e", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/e@1.0.0" + } + ] + }, + { + "name": "f", + "SPDXID": "SPDXRef-Package-f-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/f", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/f@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-e-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-f-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom loading a tree containing workspaces should list workspaces properly with default configs > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "workspaces-tree@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-workspaces-tree-1.0.0" + ], + "packages": [ + { + "name": "workspaces-tree", + "SPDXID": "SPDXRef-Package-workspaces-tree-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/workspaces-tree@1.0.0" + } + ] + }, + { + "name": "a", + "SPDXID": "SPDXRef-Package-a-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/a", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/a@1.0.0" + } + ] + }, + { + "name": "b", + "SPDXID": "SPDXRef-Package-b-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/b", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/b@1.0.0" + } + ] + }, + { + "name": "d", + "SPDXID": "SPDXRef-Package-d-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/d", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/d@1.0.0" + } + ] + }, + { + "name": "e", + "SPDXID": "SPDXRef-Package-e-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/e", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/e@1.0.0" + } + ] + }, + { + "name": "f", + "SPDXID": "SPDXRef-Package-f-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/f", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/f@1.0.0" + } + ] + }, + { + "name": "bar", + "SPDXID": "SPDXRef-Package-bar-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/bar", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/bar@1.0.0" + } + ] + }, + { + "name": "baz", + "SPDXID": "SPDXRef-Package-baz-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/baz", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/baz@1.0.0" + } + ] + }, + { + "name": "c", + "SPDXID": "SPDXRef-Package-c-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/c", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/c@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.1.1", + "versionInfo": "1.1.1", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.1.1" + } + ] + }, + { + "name": "pacote", + "SPDXID": "SPDXRef-Package-pacote-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/pacote", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/pacote@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-a-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-b-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-d-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-e-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-f-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-pacote-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-c-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-a-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-d-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-a-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-baz-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-a-1.0.0", + "relationshipType": "DEV_DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.1.1", + "relatedSpdxElement": "SPDXRef-Package-d-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-bar-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.1.1", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom loading a tree containing workspaces should not list workspaces with --no-workspaces > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "workspaces-tree@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-workspaces-tree-1.0.0" + ], + "packages": [ + { + "name": "workspaces-tree", + "SPDXID": "SPDXRef-Package-workspaces-tree-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/workspaces-tree@1.0.0" + } + ] + }, + { + "name": "pacote", + "SPDXID": "SPDXRef-Package-pacote-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/pacote", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/pacote@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-pacote-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-workspaces-tree-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom lock file only - missing lock file > must match snapshot 1`] = ` + +` + +exports[`test/lib/commands/sbom.js TAP sbom lock file only > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-ls@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-ls-1.0.0" + ], + "packages": [ + { + "name": "test-npm-ls", + "SPDXID": "SPDXRef-Package-test-npm-ls-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-ls@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + }, + { + "name": "dog", + "SPDXID": "SPDXRef-Package-dog-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/dog", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/dog@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-dog-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom missing (optional) dep > must match snapshot 1`] = ` +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "test-npm-ls@1.0.0", + "documentNamespace": "http://spdx.org/spdxdocs/test-npm-sbom-1.0.0-12345678-90ab-cdef-1234-567890abcdef", + "creationInfo": { + "created": "2020-01-01T00:00:00.000Z", + "creators": [ + "Tool: npm/cli-10.0.0" + ] + }, + "documentDescribes": [ + "SPDXRef-Package-test-npm-ls-1.0.0" + ], + "packages": [ + { + "name": "test-npm-ls", + "SPDXID": "SPDXRef-Package-test-npm-ls-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "", + "primaryPackagePurpose": "LIBRARY", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/test-npm-ls@1.0.0" + } + ] + }, + { + "name": "chai", + "SPDXID": "SPDXRef-Package-chai-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/chai", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/chai@1.0.0" + } + ] + }, + { + "name": "foo", + "SPDXID": "SPDXRef-Package-foo-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/foo@1.0.0" + } + ] + }, + { + "name": "dog", + "SPDXID": "SPDXRef-Package-dog-1.0.0", + "versionInfo": "1.0.0", + "packageFileName": "node_modules/foo/node_modules/dog", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false, + "homepage": "NOASSERTION", + "licenseDeclared": "NOASSERTION", + "externalRefs": [ + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:npm/dog@1.0.0" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-foo-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-chai-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-test-npm-ls-1.0.0", + "relationshipType": "DEPENDENCY_OF" + }, + { + "spdxElementId": "SPDXRef-Package-dog-1.0.0", + "relatedSpdxElement": "SPDXRef-Package-foo-1.0.0", + "relationshipType": "DEPENDENCY_OF" + } + ] +} +` + +exports[`test/lib/commands/sbom.js TAP sbom missing format > must match snapshot 1`] = ` + +` diff --git a/tap-snapshots/test/lib/commands/search.js.test.cjs b/tap-snapshots/test/lib/commands/search.js.test.cjs index 152e6605676e7..f8dc5d94f4b21 100644 --- a/tap-snapshots/test/lib/commands/search.js.test.cjs +++ b/tap-snapshots/test/lib/commands/search.js.test.cjs @@ -5,134 +5,1086 @@ * 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 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 | +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 +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 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 |  +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 +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 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 +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 +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 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 | +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 +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 npmcli libnpm cli workspaces map-workspaces -@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +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 +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 npmcli libnpm cli workspaces map-workspaces -@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +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 +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 npmcli libnpm cli workspaces map-workspaces -@types/libnpmsearch | TypeScript… | =types | 2019-09-26 | 2.0.1 | +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 +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": "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 | +@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 multiple terms --color > should have expected search results with color 1`] = ` +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 +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 multiple terms text > should have expected search results 1`] = ` +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 +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 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/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs b/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs index dee5f8af83b0f..96b41b117d19b 100644 --- a/tap-snapshots/test/lib/commands/shrinkwrap.js.test.cjs +++ b/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": [ + "shrinkwrap 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": [ + "shrinkwrap 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": [ + "shrinkwrap Converting lock file (npm-shrinkwrap.json) from v2 -> v3" ] } ` @@ -125,13 +136,14 @@ exports[`test/lib/commands/shrinkwrap.js TAP with nothing ancient > must match s "config": {}, "shrinkwrap": { "name": "prefix", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": {} }, "logs": [ - "created a lockfile as npm-shrinkwrap.json with version 2" - ] + "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": [] } ` @@ -163,7 +176,7 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json ancient > "config": {}, "shrinkwrap": { "name": "prefix", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -172,7 +185,10 @@ exports[`test/lib/commands/shrinkwrap.js TAP with npm-shrinkwrap.json ancient > } }, "logs": [ - "npm-shrinkwrap.json updated to version 2" + "npm-shrinkwrap.json updated to version 3" + ], + "warn": [ + "shrinkwrap 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": [ + "shrinkwrap 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": [ + "shrinkwrap 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": [ + "shrinkwrap Converting lock file (npm-shrinkwrap.json) from v2 -> v3" ] } ` @@ -284,7 +310,7 @@ exports[`test/lib/commands/shrinkwrap.js TAP with package-lock.json ancient > mu "config": {}, "shrinkwrap": { "name": "prefix", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -293,7 +319,10 @@ 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 2" + "package-lock.json has been renamed to npm-shrinkwrap.json and updated to version 3" + ], + "warn": [ + "shrinkwrap 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": [ + "shrinkwrap 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": [ + "shrinkwrap 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": [ + "shrinkwrap Converting lock file (npm-shrinkwrap.json) from v2 -> v3" ] } ` diff --git a/tap-snapshots/test/lib/commands/stars.js.test.cjs b/tap-snapshots/test/lib/commands/stars.js.test.cjs index fbf074f718d1d..d55d7b414d7fd 100644 --- a/tap-snapshots/test/lib/commands/stars.js.test.cjs +++ b/tap-snapshots/test/lib/commands/stars.js.test.cjs @@ -6,7 +6,6 @@ */ 'use strict' exports[`test/lib/commands/stars.js TAP no args > should output a list of starred packages 1`] = ` - @npmcli/arborist @npmcli/map-workspaces libnpmfund diff --git a/tap-snapshots/test/lib/commands/team.js.test.cjs b/tap-snapshots/test/lib/commands/team.js.test.cjs index 6a93234f54fc8..f72fcb2f1fa94 100644 --- a/tap-snapshots/test/lib/commands/team.js.test.cjs +++ b/tap-snapshots/test/lib/commands/team.js.test.cjs @@ -37,18 +37,18 @@ ruyadorno ` exports[`test/lib/commands/team.js TAP team ls default output > should list users for a given scope:team 1`] = ` - @npmcli:developers has 4 users: -darcyclarke isaacs nlf ruyadorno +darcyclarke +isaacs +nlf +ruyadorno ` exports[`test/lib/commands/team.js TAP team ls no users > should list no users for a given scope 1`] = ` - @npmcli:developers has 0 users ` exports[`test/lib/commands/team.js TAP team ls single user > should list single user for a given scope 1`] = ` - @npmcli:developers has 1 user: foo ` @@ -60,18 +60,17 @@ npmcli:product ` exports[`test/lib/commands/team.js TAP team ls default output > should list teams for a given scope 1`] = ` - @npmcli has 3 teams: -@npmcli:designers @npmcli:developers @npmcli:product +@npmcli:designers +@npmcli:developers +@npmcli:product ` exports[`test/lib/commands/team.js TAP team ls no teams > should list no teams for a given scope 1`] = ` - @npmcli has 0 teams ` exports[`test/lib/commands/team.js TAP team ls single team > should list single team for a given scope 1`] = ` - @npmcli has 1 team: @npmcli:developers ` diff --git a/tap-snapshots/test/lib/commands/version.js.test.cjs b/tap-snapshots/test/lib/commands/version.js.test.cjs index e19f9b8eef14e..0fed009652597 100644 --- a/tap-snapshots/test/lib/commands/version.js.test.cjs +++ b/tap-snapshots/test/lib/commands/version.js.test.cjs @@ -9,7 +9,7 @@ exports[`test/lib/commands/version.js TAP empty versions workspaces with one arg { "name": "workspaces-test", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -34,14 +34,6 @@ exports[`test/lib/commands/version.js TAP empty versions workspaces with one arg "workspace-b": { "version": "2.0.0" } - }, - "dependencies": { - "workspace-a": { - "version": "file:workspace-a" - }, - "workspace-b": { - "version": "file:workspace-b" - } } } @@ -51,7 +43,7 @@ exports[`test/lib/commands/version.js TAP empty versions workspaces with one arg { "name": "workspaces-test", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -80,14 +72,6 @@ exports[`test/lib/commands/version.js TAP empty versions workspaces with one arg "workspace-b": { "version": "2.0.0" } - }, - "dependencies": { - "workspace-a": { - "version": "file:workspace-a" - }, - "workspace-b": { - "version": "file:workspace-b" - } } } diff --git a/tap-snapshots/test/lib/commands/view.js.test.cjs b/tap-snapshots/test/lib/commands/view.js.test.cjs index d5b7a3b4a7906..d5e7f6bfd4963 100644 --- a/tap-snapshots/test/lib/commands/view.js.test.cjs +++ b/tap-snapshots/test/lib/commands/view.js.test.cjs @@ -5,137 +5,183 @@ * Make sure to inspect the output below. Do not ignore changes! */ 'use strict' +exports[`test/lib/commands/view.js TAP allow-git=root, package with multiple dist‑tags and no time > must match snapshot 1`] = ` + +gray@1.1.0 | Proprietary | deps: none | versions: 1 + +dist +.tarball: http://gray/1.1.0.tgz +.shasum: b + +dist-tags: +latest: 1.1.0 +stable: 1.1.0 +old: 1.0.0 +beta: 1.2.0-beta +alpha: 1.2.0-alpha +` + 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 +z: 1.0.0 +y: 1.0.0 +v1: 1.0.0 +prev: 1.0.0 +d: 1.0.0 +c: 1.0.0 +b: 1.0.0 +a: 1.0.0 +x: 1.0.1 +next: 1.0.1 +h: 1.0.1 +(...and 3 more.) 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 +z: 1.0.0 +y: 1.0.0 +v1: 1.0.0 +prev: 1.0.0 +d: 1.0.0 +c: 1.0.0 +b: 1.0.0 +a: 1.0.0 +x: 1.0.1 +next: 1.0.1 +h: 1.0.1 +(...and 3 more.) 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 +z: 1.0.0 +y: 1.0.0 +v1: 1.0.0 +prev: 1.0.0 +d: 1.0.0 +c: 1.0.0 +b: 1.0.0 +a: 1.0.0 +x: 1.0.1 +next: 1.0.1 +h: 1.0.1 +(...and 3 more.) published {TIME} ago ` @@ -177,133 +223,188 @@ 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`] = ` +[ '1.0.0', '1.0.1' ] ` exports[`test/lib/commands/view.js TAP package with maintainers info as object > must match snapshot 1`] = ` -pink@1.0.0 | Proprietary | deps: none | versions: 2 +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 +z: 1.0.0 +y: 1.0.0 +v1: 1.0.0 +prev: 1.0.0 +d: 1.0.0 +c: 1.0.0 +b: 1.0.0 +a: 1.0.0 +x: 1.0.1 +next: 1.0.1 +h: 1.0.1 +(...and 3 more.) 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 +z: 1.0.0 +y: 1.0.0 +v1: 1.0.0 +prev: 1.0.0 +d: 1.0.0 +c: 1.0.0 +b: 1.0.0 +a: 1.0.0 +x: 1.0.1 +next: 1.0.1 +h: 1.0.1 +(...and 3 more.) 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 +z: 1.0.0 +y: 1.0.0 +v1: 1.0.0 +prev: 1.0.0 +d: 1.0.0 +c: 1.0.0 +b: 1.0.0 +a: 1.0.0 +x: 1.0.1 +next: 1.0.1 +h: 1.0.1 +(...and 3 more.) + +published {TIME} ago +` -published over a year from now +exports[`test/lib/commands/view.js TAP package with single version full json > must match snapshot 1`] = ` +{ + "_id": "single-version", + "name": "single-version", + "dist-tags": { + "latest": "1.0.0" + }, + "versions": [ + "1.0.0" + ], + "version": "1.0.0", + "dist": { + "shasum": "123", + "tarball": "http://hm.single-version.com/1.0.0.tgz", + "fileCount": 1 + } +} ` exports[`test/lib/commands/view.js TAP specific field names array field - 1 element > must match snapshot 1`] = ` @@ -315,6 +416,10 @@ maintainers[0].name = 'claudia' maintainers[1].name = 'isaacs' ` +exports[`test/lib/commands/view.js TAP specific field names fields with empty values > must match snapshot 1`] = ` + +` + exports[`test/lib/commands/view.js TAP specific field names maintainers with email > must match snapshot 1`] = ` maintainers = [ { name: 'claudia', email: 'c@yellow.com', twitter: 'cyellow' }, @@ -346,6 +451,153 @@ yellow@1.0.1 'claudia' yellow@1.0.2 'claudia' ` +exports[`test/lib/commands/view.js TAP workspaces 404 workspaces basic > must match snapshot 1`] = ` + +green@1.0.0 | ACME | deps: 2 | versions: 2 +green is a very important color + +DEPRECATED!! - true + +keywords: colors, green, crayola + +bin: green + +dist +.tarball: http://hm.green.com/1.0.0.tgz +.shasum: 123 +.integrity: --- +.unpackedSize: 1.0 GB + +dependencies: +red: 1.0.0 +yellow: 1.0.0 + +maintainers: +- claudia <c@yellow.com> +- isaacs <i@yellow.com> + +dist-tags: +latest: 1.0.0 +error code E404 +error 404 404 +` + +exports[`test/lib/commands/view.js TAP workspaces 404 workspaces json > must match snapshot 1`] = ` +{ + "green": { + "_id": "green", + "name": "green", + "dist-tags": { + "latest": "1.0.0" + }, + "maintainers": [ + { + "name": "claudia", + "email": "c@yellow.com", + "twitter": "cyellow" + }, + { + "name": "isaacs", + "email": "i@yellow.com", + "twitter": "iyellow" + } + ], + "keywords": [ + "colors", + "green", + "crayola" + ], + "versions": [ + "1.0.0", + "1.0.1" + ], + "version": "1.0.0", + "description": "green is a very important color", + "bugs": { + "url": "http://bugs.green.com" + }, + "deprecated": true, + "repository": { + "url": "http://repository.green.com" + }, + "license": { + "type": "ACME" + }, + "bin": { + "green": "bin/green.js" + }, + "dependencies": { + "red": "1.0.0", + "yellow": "1.0.0" + }, + "dist": { + "shasum": "123", + "tarball": "http://hm.green.com/1.0.0.tgz", + "integrity": "---", + "fileCount": 1, + "unpackedSize": 1000000000 + } + }, + "error": { + "missing-package": { + "code": "E404", + "summary": "404", + "detail": "" + } + } +} +` + +exports[`test/lib/commands/view.js TAP workspaces 404 workspaces json with package named error > must match snapshot 1`] = ` +warn overwriting existing error on json output +{ + "error": { + "missing-package": { + "code": "E404", + "summary": "404", + "detail": "" + } + } +} +` + +exports[`test/lib/commands/view.js TAP workspaces 404 workspaces non-404 error rejects > must match snapshot 1`] = ` + +green@1.0.0 | ACME | deps: 2 | versions: 2 +green is a very important color + +DEPRECATED!! - true + +keywords: colors, green, crayola + +bin: green + +dist +.tarball: http://hm.green.com/1.0.0.tgz +.shasum: 123 +.integrity: --- +.unpackedSize: 1.0 GB + +dependencies: +red: 1.0.0 +yellow: 1.0.0 + +maintainers: +- claudia <c@yellow.com> +- isaacs <i@yellow.com> + +dist-tags: +latest: 1.0.0 +error Unknown error +` + +exports[`test/lib/commands/view.js TAP workspaces 404 workspaces non-404 error rejects with single arg > must match snapshot 1`] = ` +green: +1.0.0 +unknown-error: +error Unknown error +` + exports[`test/lib/commands/view.js TAP workspaces all workspaces --json > must match snapshot 1`] = ` { "green": { @@ -427,43 +679,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`] = ` @@ -491,52 +743,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/tap-snapshots/test/lib/docs.js.test.cjs b/tap-snapshots/test/lib/docs.js.test.cjs new file mode 100644 index 0000000000000..b9b2e32355e94 --- /dev/null +++ b/tap-snapshots/test/lib/docs.js.test.cjs @@ -0,0 +1,4756 @@ +/* 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/docs.js TAP basic usage > must match snapshot 1`] = ` +npm + +Usage: + +npm install install all the dependencies in your project +npm install add the dependency to your project +npm test run this project's tests +npm run run the script named +npm -h quick help on +npm -l display usage info for all commands +npm help search for help on +npm help npm more involved overview + +All commands: + + + +Specify configs in the ini-formatted file: + {USERCONFIG} +or on the command line via: npm --key=value + +More configuration info: npm help config +Configuration fields: npm help 7 config + +npm@{VERSION} {BASEDIR} +` + +exports[`test/lib/docs.js TAP command list > aliases 1`] = ` +Object { + "add": "install", + "add-user": "adduser", + "author": "owner", + "c": "config", + "cit": "install-ci-test", + "clean-install": "ci", + "clean-install-test": "install-ci-test", + "create": "init", + "ddp": "dedupe", + "dist-tags": "dist-tag", + "find": "search", + "hlep": "help", + "home": "docs", + "i": "install", + "ic": "ci", + "in": "install", + "info": "view", + "innit": "init", + "ins": "install", + "inst": "install", + "insta": "install", + "instal": "install", + "install-clean": "ci", + "isnt": "install", + "isnta": "install", + "isntal": "install", + "isntall": "install", + "isntall-clean": "ci", + "issues": "bugs", + "it": "install-test", + "la": "ll", + "list": "ls", + "ln": "link", + "ogr": "org", + "r": "uninstall", + "rb": "rebuild", + "remove": "uninstall", + "rm": "uninstall", + "rum": "run", + "run-script": "run", + "s": "search", + "se": "search", + "show": "view", + "sit": "install-ci-test", + "t": "test", + "tst": "test", + "udpate": "update", + "un": "uninstall", + "unlink": "uninstall", + "up": "update", + "upgrade": "update", + "urn": "run", + "v": "view", + "verison": "version", + "why": "explain", + "x": "exec", +} +` + +exports[`test/lib/docs.js TAP command list > commands 1`] = ` +Array [ + "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", + "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", + "sbom", + "search", + "set", + "shrinkwrap", + "star", + "stars", + "start", + "stop", + "team", + "test", + "token", + "undeprecate", + "uninstall", + "unpublish", + "unstar", + "update", + "version", + "view", + "whoami", +] +` + +exports[`test/lib/docs.js TAP command list > deref 1`] = ` +Function deref(c) +` + +exports[`test/lib/docs.js TAP config > all definitions 1`] = ` +#### \`_auth\` + +* Default: null +* Type: null or String + +A basic-auth string to use when authenticating against the npm registry. +This will ONLY be used to authenticate against the npm registry. For other +registries you will need to scope it like "//other-registry.tld/:_auth" + +Warning: This should generally not be set via a command-line option. It is +safer to use a registry-provided authentication bearer token stored in the +~/.npmrc file by running \`npm login\`. + + + +#### \`access\` + +* Default: 'public' for new packages, existing packages it will not change the + current level +* Type: null, "restricted", or "public" + +If you do not want your scoped package to be publicly viewable (and +installable) set \`--access=restricted\`. + +Unscoped packages cannot be set to \`restricted\`. + +Note: This defaults to not changing the current access level for existing +packages. Specifying a value of \`restricted\` or \`public\` during publish will +change the access for an existing package the same way that \`npm access set +status\` would. + + + +#### \`all\` + +* Default: false +* Type: Boolean + +When running \`npm outdated\` and \`npm ls\`, setting \`--all\` will show all +outdated or installed packages, rather than only those directly depended +upon by the current project. + + + +#### \`allow-git\` + +* Default: "all" +* Type: "all", "none", or "root" + +Limits the ability for npm to fetch dependencies from git references. That +is, dependencies that point to a git repo instead of a version or semver +range. Please note that this could leave your tree incomplete and some +packages may not function as intended or designed. + +\`all\` allows any git dependencies to be fetched and installed. \`none\` +prevents any git dependencies from being fetched and installed. \`root\` only +allows git dependencies defined in your project's package.json to be fetched +installed. Also allows git dependencies to be fetched for other commands +like \`npm view\` + + + +#### \`allow-same-version\` + +* Default: false +* Type: Boolean + +Prevents throwing an error when \`npm version\` is used to set the new version +to the same value as the current version. + + + +#### \`audit\` + +* Default: true +* Type: Boolean + +When "true" submit audit reports alongside the current npm command to the +default registry and all registries configured for scopes. See the +documentation for [\`npm audit\`](/commands/npm-audit) for details on what is +submitted. + + + +#### \`audit-level\` + +* Default: null +* Type: null, "info", "low", "moderate", "high", "critical", or "none" + +The minimum level of vulnerability for \`npm audit\` to exit with a non-zero +exit code. + + + +#### \`auth-type\` + +* Default: "web" +* Type: "legacy" or "web" + +What authentication strategy to use with \`login\`. Note that if an \`otp\` +config is given, this value will always be set to \`legacy\`. + + + +#### \`before\` + +* Default: null +* Type: null or Date + +If passed to \`npm install\`, will rebuild the npm tree such that only +versions that were available **on or before** the given date are installed. +If there are no versions available for the current set of dependencies, the +command will error. + +If the requested version is a \`dist-tag\` and the given tag does not pass the +\`--before\` filter, the most recent version less than or equal to that tag +will be used. For example, \`foo@latest\` might install \`foo@1.2\` even though +\`latest\` is \`2.0\`. + + + +#### \`bin-links\` + +* Default: true +* Type: Boolean + +Tells npm to create symlinks (or \`.cmd\` shims on Windows) for package +executables. + +Set to false to have it not do this. This can be used to work around the +fact that some file systems don't support symlinks, even on ostensibly Unix +systems. + + + +#### \`browser\` + +* Default: macOS: \`"open"\`, Windows: \`"start"\`, Others: \`"xdg-open"\` +* Type: null, Boolean, or String + +The browser that is called by npm commands to open websites. + +Set to \`false\` to suppress browser behavior and instead print urls to +terminal. + +Set to \`true\` to use default system URL opener. + + + +#### \`bypass-2fa\` + +* Default: false +* Type: Boolean + +When creating a Granular Access Token with \`npm token create\`, setting this +to true will allow the token to bypass two-factor authentication. This is +useful for automation and CI/CD workflows. + + + +#### \`ca\` + +* Default: null +* Type: null or String (can be set multiple times) + +The Certificate Authority signing certificate that is trusted for SSL +connections to the registry. Values should be in PEM format (Windows calls +it "Base-64 encoded X.509 (.CER)") with newlines replaced by the string +"\\n". For example: + +\`\`\`ini +ca="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----" +\`\`\` + +Set to \`null\` to only allow "known" registrars, or to a specific CA cert to +trust only that specific signing authority. + +Multiple CAs can be trusted by specifying an array of certificates: + +\`\`\`ini +ca[]="..." +ca[]="..." +\`\`\` + +See also the \`strict-ssl\` config. + + + +#### \`cache\` + +* Default: Windows: \`%LocalAppData%\\npm-cache\`, Posix: \`~/.npm\` +* Type: Path + +The location of npm's cache directory. + + + +#### \`cafile\` + +* Default: null +* Type: Path + +A path to a file containing one or multiple Certificate Authority signing +certificates. Similar to the \`ca\` setting, but allows for multiple CA's, as +well as for the CA information to be stored in a file on disk. + + + +#### \`call\` + +* Default: "" +* Type: String + +Optional companion option for \`npm exec\`, \`npx\` that allows for specifying a +custom command to be run along with the installed packages. + +\`\`\`bash +npm exec --package yo --package generator-node --call "yo node" +\`\`\` + + + +#### \`cidr\` + +* Default: null +* Type: null or String (can be set multiple times) + +This is a list of CIDR address to be used when configuring limited access +tokens with the \`npm token create\` command. + + + +#### \`color\` + +* Default: true unless the NO_COLOR environ is set to something other than '0' +* Type: "always" or Boolean + +If false, never shows colors. If \`"always"\` then always shows colors. If +true, then only prints color codes for tty file descriptors. + + + +#### \`commit-hooks\` + +* Default: true +* Type: Boolean + +Run git commit hooks when using the \`npm version\` command. + + + +#### \`cpu\` + +* Default: null +* Type: null or String + +Override CPU architecture of native modules to install. Acceptable values +are same as \`cpu\` field of package.json, which comes from \`process.arch\`. + + + +#### \`depth\` + +* Default: \`Infinity\` if \`--all\` is set; otherwise, \`0\` +* Type: null or Number + +The depth to go when recursing packages for \`npm ls\`. + +If not set, \`npm ls\` will show only the immediate dependencies of the root +project. If \`--all\` is set, then npm will show all dependencies by default. + + + +#### \`description\` + +* Default: true +* Type: Boolean + +Show the description in \`npm search\` + + + +#### \`diff\` + +* Default: +* Type: String (can be set multiple times) + +Define arguments to compare in \`npm diff\`. + + + +#### \`diff-dst-prefix\` + +* Default: "b/" +* Type: String + +Destination prefix to be used in \`npm diff\` output. + + + +#### \`diff-ignore-all-space\` + +* Default: false +* Type: Boolean + +Ignore whitespace when comparing lines in \`npm diff\`. + + + +#### \`diff-name-only\` + +* Default: false +* Type: Boolean + +Prints only filenames when using \`npm diff\`. + + + +#### \`diff-no-prefix\` + +* Default: false +* Type: Boolean + +Do not show any source or destination prefix in \`npm diff\` output. + +Note: this causes \`npm diff\` to ignore the \`--diff-src-prefix\` and +\`--diff-dst-prefix\` configs. + + + +#### \`diff-src-prefix\` + +* Default: "a/" +* Type: String + +Source prefix to be used in \`npm diff\` output. + + + +#### \`diff-text\` + +* Default: false +* Type: Boolean + +Treat all files as text in \`npm diff\`. + + + +#### \`diff-unified\` + +* Default: 3 +* Type: Number + +The number of lines of context to print in \`npm diff\`. + + + +#### \`dry-run\` + +* Default: false +* Type: Boolean + +Indicates that you don't want npm to make any changes and that it should +only report what it would have done. This can be passed into any of the +commands that modify your local installation, eg, \`install\`, \`update\`, +\`dedupe\`, \`uninstall\`, as well as \`pack\` and \`publish\`. + +Note: This is NOT honored by other network related commands, eg \`dist-tags\`, +\`owner\`, etc. + + + +#### \`editor\` + +* Default: The EDITOR or VISUAL environment variables, or + '%SYSTEMROOT%\\notepad.exe' on Windows, or 'vi' on Unix systems +* Type: String + +The command to run for \`npm edit\` and \`npm config edit\`. + + + +#### \`engine-strict\` + +* Default: false +* Type: Boolean + +If set to true, then npm will stubbornly refuse to install (or even consider +installing) any package that claims to not be compatible with the current +Node.js version. + +This can be overridden by setting the \`--force\` flag. + + + +#### \`expect-result-count\` + +* Default: null +* Type: null or Number + +Tells to expect a specific number of results from the command. + +This config cannot be used with: \`expect-results\` + +#### \`expect-results\` + +* Default: null +* Type: null or Boolean + +Tells npm whether or not to expect results from the command. Can be either +true (expect some results) or false (expect no results). + +This config cannot be used with: \`expect-result-count\` + +#### \`expires\` + +* Default: null +* Type: null or Number + +When creating a Granular Access Token with \`npm token create\`, this sets the +expiration in days. If not specified, the server will determine the default +expiration. + + + +#### \`fetch-retries\` + +* Default: 2 +* Type: Number + +The "retries" config for the \`retry\` module to use when fetching packages +from the registry. + +npm will retry idempotent read requests to the registry in the case of +network failures or 5xx HTTP errors. + + + +#### \`fetch-retry-factor\` + +* Default: 10 +* Type: Number + +The "factor" config for the \`retry\` module to use when fetching packages. + + + +#### \`fetch-retry-maxtimeout\` + +* Default: 60000 (1 minute) +* Type: Number + +The "maxTimeout" config for the \`retry\` module to use when fetching +packages. + + + +#### \`fetch-retry-mintimeout\` + +* Default: 10000 (10 seconds) +* Type: Number + +The "minTimeout" config for the \`retry\` module to use when fetching +packages. + + + +#### \`fetch-timeout\` + +* Default: 300000 (5 minutes) +* Type: Number + +The maximum amount of time to wait for HTTP requests to complete. + + + +#### \`force\` + +* Default: false +* Type: Boolean + +Removes various protections against unfortunate side effects, common +mistakes, unnecessary performance degradation, and malicious input. + +* Allow clobbering non-npm files in global installs. +* Allow the \`npm version\` command to work on an unclean git repository. +* Allow deleting the cache folder with \`npm cache clean\`. +* Allow installing packages that have an \`engines\` declaration requiring a + different version of npm. +* Allow installing packages that have an \`engines\` declaration requiring a + different version of \`node\`, even if \`--engine-strict\` is enabled. +* Allow \`npm audit fix\` to install modules outside your stated dependency + range (including SemVer-major changes). +* Allow unpublishing all versions of a published package. +* Allow conflicting peerDependencies to be installed in the root project. +* Implicitly set \`--yes\` during \`npm init\`. +* Allow clobbering existing values in \`npm pkg\` +* Allow unpublishing of entire packages (not just a single version). + +If you don't have a clear idea of what you want to do, it is strongly +recommended that you do not use this option! + + + +#### \`foreground-scripts\` + +* Default: \`false\` unless when using \`npm pack\` or \`npm publish\` where it + defaults to \`true\` +* Type: Boolean + +Run all build scripts (ie, \`preinstall\`, \`install\`, and \`postinstall\`) +scripts for installed packages in the foreground process, sharing standard +input, output, and error with the main npm process. + +Note that this will generally make installs run slower, and be much noisier, +but can be useful for debugging. + + + +#### \`format-package-lock\` + +* Default: true +* Type: Boolean + +Format \`package-lock.json\` or \`npm-shrinkwrap.json\` as a human readable +file. + + + +#### \`fund\` + +* Default: true +* Type: Boolean + +When "true" displays the message at the end of each \`npm install\` +acknowledging the number of dependencies looking for funding. See [\`npm +fund\`](/commands/npm-fund) for details. + + + +#### \`git\` + +* Default: "git" +* Type: String + +The command to use for git commands. If git is installed on the computer, +but is not in the \`PATH\`, then set this to the full path to the git binary. + + + +#### \`git-tag-version\` + +* Default: true +* Type: Boolean + +Tag the commit when using the \`npm version\` command. Setting this to false +results in no commit being made at all. + + + +#### \`global\` + +* Default: false +* Type: Boolean + +Operates in "global" mode, so that packages are installed into the \`prefix\` +folder instead of the current working directory. See +[folders](/configuring-npm/folders) for more on the differences in behavior. + +* packages are installed into the \`{prefix}/lib/node_modules\` folder, instead + of the current working directory. +* bin files are linked to \`{prefix}/bin\` +* man pages are linked to \`{prefix}/share/man\` + + + +#### \`globalconfig\` + +* Default: The global --prefix setting plus 'etc/npmrc'. For example, + '/usr/local/etc/npmrc' +* Type: Path + +The config file to read for global config options. + + + +#### \`heading\` + +* Default: "npm" +* Type: String + +The string that starts all the debugging log output. + + + +#### \`https-proxy\` + +* Default: null +* Type: null or URL + +A proxy to use for outgoing https requests. If the \`HTTPS_PROXY\` or +\`https_proxy\` or \`HTTP_PROXY\` or \`http_proxy\` environment variables are set, +proxy settings will be honored by the underlying \`make-fetch-happen\` +library. + + + +#### \`if-present\` + +* Default: false +* Type: Boolean + +If true, npm will not exit with an error code when \`run\` is invoked for a +script that isn't defined in the \`scripts\` section of \`package.json\`. This +option can be used when it's desirable to optionally run a script when it's +present and fail if the script fails. This is useful, for example, when +running scripts that may only apply for some builds in an otherwise generic +CI setup. + +This value is not exported to the environment for child processes. + +#### \`ignore-scripts\` + +* Default: false +* Type: Boolean + +If true, npm does not run scripts specified in package.json files. + +Note that commands explicitly intended to run a particular script, such as +\`npm start\`, \`npm stop\`, \`npm restart\`, \`npm test\`, and \`npm run\` will still +run their intended script if \`ignore-scripts\` is set, but they will *not* +run any pre- or post-scripts. + + + +#### \`include\` + +* Default: +* Type: "prod", "dev", "optional", or "peer" (can be set multiple times) + +Option that allows for defining which types of dependencies to install. + +This is the inverse of \`--omit=\`. + +Dependency types specified in \`--include\` will not be omitted, regardless of +the order in which omit/include are specified on the command-line. + + + +#### \`include-staged\` + +* Default: false +* Type: Boolean + +Allow installing "staged" published packages, as defined by [npm RFC PR +#92](https://github.com/npm/rfcs/pull/92). + +This is experimental, and not implemented by the npm public registry. + + + +#### \`include-workspace-root\` + +* Default: false +* Type: Boolean + +Include the workspace root when workspaces are enabled for a command. + +When false, specifying individual workspaces via the \`workspace\` config, or +all workspaces via the \`workspaces\` flag, will cause npm to operate only on +the specified workspaces, and not on the root project. + +This value is not exported to the environment for child processes. + +#### \`init-author-email\` + +* Default: "" +* Type: String + +The value \`npm init\` should use by default for the package author's email. + + + +#### \`init-author-name\` + +* Default: "" +* Type: String + +The value \`npm init\` should use by default for the package author's name. + + + +#### \`init-author-url\` + +* Default: "" +* Type: "" or URL + +The value \`npm init\` should use by default for the package author's +homepage. + + + +#### \`init-license\` + +* Default: "ISC" +* Type: String + +The value \`npm init\` should use by default for the package license. + + + +#### \`init-module\` + +* Default: "~/.npm-init.js" +* Type: Path + +A module that will be loaded by the \`npm init\` command. See the +documentation for the +[init-package-json](https://github.com/npm/init-package-json) module for +more information, or [npm init](/commands/npm-init). + + + +#### \`init-private\` + +* Default: false +* Type: Boolean + +The value \`npm init\` should use by default for the package's private flag. + + + +#### \`init-type\` + +* Default: "commonjs" +* Type: String + +The value that \`npm init\` should use by default for the package.json type +field. + + + +#### \`init-version\` + +* Default: "1.0.0" +* Type: SemVer string + +The value that \`npm init\` should use by default for the package version +number, if not already set in package.json. + + + +#### \`install-links\` + +* Default: false +* Type: Boolean + +When set file: protocol dependencies will be packed and installed as regular +dependencies instead of creating a symlink. This option has no effect on +workspaces. + + + +#### \`install-strategy\` + +* Default: "hoisted" +* Type: "hoisted", "nested", "shallow", or "linked" + +Sets the strategy for installing packages in node_modules. hoisted +(default): Install non-duplicated in top-level, and duplicated as necessary +within directory structure. nested: (formerly --legacy-bundling) install in +place, no hoisting. shallow (formerly --global-style) only install direct +deps at top-level. linked: (experimental) install in node_modules/.store, +link in place, unhoisted. + + + +#### \`json\` + +* Default: false +* Type: Boolean + +Whether or not to output JSON data, rather than the normal output. + +* In \`npm pkg set\` it enables parsing set values with JSON.parse() before + saving them to your \`package.json\`. + +Not supported by all npm commands. + + + +#### \`legacy-peer-deps\` + +* Default: false +* Type: Boolean + +Causes npm to completely ignore \`peerDependencies\` when building a package +tree, as in npm versions 3 through 6. + +If a package cannot be installed because of overly strict \`peerDependencies\` +that collide, it provides a way to move forward resolving the situation. + +This differs from \`--omit=peer\`, in that \`--omit=peer\` will avoid unpacking +\`peerDependencies\` on disk, but will still design a tree such that +\`peerDependencies\` _could_ be unpacked in a correct place. + +Use of \`legacy-peer-deps\` is not recommended, as it will not enforce the +\`peerDependencies\` contract that meta-dependencies may rely on. + + + +#### \`libc\` + +* Default: null +* Type: null or String + +Override libc of native modules to install. Acceptable values are same as +\`libc\` field of package.json + + + +#### \`link\` + +* Default: false +* Type: Boolean + +Used with \`npm ls\`, limiting output to only those packages that are linked. + + + +#### \`local-address\` + +* Default: null +* Type: IP Address + +The IP address of the local interface to use when making connections to the +npm registry. Must be IPv4 in versions of Node prior to 0.12. + + + +#### \`location\` + +* Default: "user" unless \`--global\` is passed, which will also set this value + to "global" +* Type: "global", "user", or "project" + +When passed to \`npm config\` this refers to which config file to use. + +When set to "global" mode, packages are installed into the \`prefix\` folder +instead of the current working directory. See +[folders](/configuring-npm/folders) for more on the differences in behavior. + +* packages are installed into the \`{prefix}/lib/node_modules\` folder, instead + of the current working directory. +* bin files are linked to \`{prefix}/bin\` +* man pages are linked to \`{prefix}/share/man\` + + + +#### \`lockfile-version\` + +* Default: Version 3 if no lockfile, auto-converting v1 lockfiles to v3; + otherwise, maintain current lockfile version. +* Type: null, 1, 2, 3, "1", "2", or "3" + +Set the lockfile format version to be used in package-lock.json and +npm-shrinkwrap-json files. Possible options are: + +1: The lockfile version used by npm versions 5 and 6. Lacks some data that +is used during the install, resulting in slower and possibly less +deterministic installs. Prevents lockfile churn when interoperating with +older npm versions. + +2: The default lockfile version used by npm version 7 and 8. Includes both +the version 1 lockfile data and version 3 lockfile data, for maximum +determinism and interoperability, at the expense of more bytes on disk. + +3: Only the new lockfile information introduced in npm version 7. Smaller on +disk than lockfile version 2, but not interoperable with older npm versions. +Ideal if all users are on npm version 7 and higher. + + + +#### \`loglevel\` + +* Default: "notice" +* Type: "silent", "error", "warn", "notice", "http", "info", "verbose", or + "silly" + +What level of logs to report. All logs are written to a debug log, with the +path to that file printed if the execution of a command fails. + +Any logs of a higher level than the setting are shown. The default is +"notice". + +See also the \`foreground-scripts\` config. + + + +#### \`logs-dir\` + +* Default: A directory named \`_logs\` inside the cache +* Type: null or Path + +The location of npm's log directory. See [\`npm logging\`](/using-npm/logging) +for more information. + + + +#### \`logs-max\` + +* Default: 10 +* Type: Number + +The maximum number of log files to store. + +If set to 0, no log files will be written for the current run. + + + +#### \`long\` + +* Default: false +* Type: Boolean + +Show extended information in \`ls\`, \`search\`, and \`help-search\`. + + + +#### \`maxsockets\` + +* Default: 15 +* Type: Number + +The maximum number of connections to use per origin (protocol/host/port +combination). + + + +#### \`message\` + +* Default: "%s" +* Type: String + +Commit message which is used by \`npm version\` when creating version commit. + +Any "%s" in the message will be replaced with the version number. + + + +#### \`name\` + +* Default: null +* Type: null or String + +When creating a Granular Access Token with \`npm token create\`, this sets the +name/description for the token. + + + +#### \`node-gyp\` + +* Default: The path to the node-gyp bin that ships with npm +* Type: Path + +This is the location of the "node-gyp" bin. By default it uses one that +ships with npm itself. + +You can use this config to specify your own "node-gyp" to run when it is +required to build a package. + + + +#### \`node-options\` + +* Default: null +* Type: null or String + +Options to pass through to Node.js via the \`NODE_OPTIONS\` environment +variable. This does not impact how npm itself is executed but it does impact +how lifecycle scripts are called. + + + +#### \`noproxy\` + +* Default: The value of the NO_PROXY environment variable +* Type: String (can be set multiple times) + +Domain extensions that should bypass any proxies. + +Also accepts a comma-delimited string. + + + +#### \`offline\` + +* Default: false +* Type: Boolean + +Force offline mode: no network requests will be done during install. To +allow the CLI to fill in missing cache data, see \`--prefer-offline\`. + + + +#### \`omit\` + +* Default: 'dev' if the \`NODE_ENV\` environment variable is set to + 'production'; otherwise, empty. +* Type: "dev", "optional", or "peer" (can be set multiple times) + +Dependency types to omit from the installation tree on disk. + +Note that these dependencies _are_ still resolved and added to the +\`package-lock.json\` or \`npm-shrinkwrap.json\` file. They are just not +physically installed on disk. + +If a package type appears in both the \`--include\` and \`--omit\` lists, then +it will be included. + +If the resulting omit list includes \`'dev'\`, then the \`NODE_ENV\` environment +variable will be set to \`'production'\` for all lifecycle scripts. + + + +#### \`omit-lockfile-registry-resolved\` + +* Default: false +* Type: Boolean + +This option causes npm to create lock files without a \`resolved\` key for +registry dependencies. Subsequent installs will need to resolve tarball +endpoints with the configured registry, likely resulting in a longer install +time. + + + +#### \`orgs\` + +* Default: null +* Type: null or String (can be set multiple times) + +When creating a Granular Access Token with \`npm token create\`, this limits +the token access to specific organizations. + + + +#### \`orgs-permission\` + +* Default: null +* Type: null, "read-only", "read-write", or "no-access" + +When creating a Granular Access Token with \`npm token create\`, sets the +permission level for organizations. Options are "read-only", "read-write", +or "no-access". + + + +#### \`os\` + +* Default: null +* Type: null or String + +Override OS of native modules to install. Acceptable values are same as \`os\` +field of package.json, which comes from \`process.platform\`. + + + +#### \`otp\` + +* Default: null +* Type: null or String + +This is a one-time password from a two-factor authenticator. It's needed +when publishing or changing package permissions with \`npm access\`. + +If not set, and a registry response fails with a challenge for a one-time +password, npm will prompt on the command line for one. + + + +#### \`pack-destination\` + +* Default: "." +* Type: String + +Directory in which \`npm pack\` will save tarballs. + + + +#### \`package\` + +* Default: +* Type: String (can be set multiple times) + +The package or packages to install for [\`npm exec\`](/commands/npm-exec) + + + +#### \`package-lock\` + +* Default: true +* Type: Boolean + +If set to false, then ignore \`package-lock.json\` files when installing. This +will also prevent _writing_ \`package-lock.json\` if \`save\` is true. + + + +#### \`package-lock-only\` + +* Default: false +* Type: Boolean + +If set to true, the current operation will only use the \`package-lock.json\`, +ignoring \`node_modules\`. + +For \`update\` this means only the \`package-lock.json\` will be updated, +instead of checking \`node_modules\` and downloading dependencies. + +For \`list\` this means the output will be based on the tree described by the +\`package-lock.json\`, rather than the contents of \`node_modules\`. + + + +#### \`packages\` + +* Default: +* Type: null or String (can be set multiple times) + +When creating a Granular Access Token with \`npm token create\`, this limits +the token access to specific packages. + + + +#### \`packages-all\` + +* Default: false +* Type: Boolean + +When creating a Granular Access Token with \`npm token create\`, grants the +token access to all packages instead of limiting to specific packages. + + + +#### \`packages-and-scopes-permission\` + +* Default: null +* Type: null, "read-only", "read-write", or "no-access" + +When creating a Granular Access Token with \`npm token create\`, sets the +permission level for packages and scopes. Options are "read-only", +"read-write", or "no-access". + + + +#### \`parseable\` + +* Default: false +* Type: Boolean + +Output parseable results from commands that write to standard output. For +\`npm search\`, this will be tab-separated table format. + + + +#### \`password\` + +* Default: null +* Type: null or String + +Password for authentication. Can be provided via command line when creating +tokens, though it's generally safer to be prompted for it. + + + +#### \`prefer-dedupe\` + +* Default: false +* Type: Boolean + +Prefer to deduplicate packages if possible, rather than choosing a newer +version of a dependency. + + + +#### \`prefer-offline\` + +* Default: false +* Type: Boolean + +If true, staleness checks for cached data will be bypassed, but missing data +will be requested from the server. To force full offline mode, use +\`--offline\`. + + + +#### \`prefer-online\` + +* Default: false +* Type: Boolean + +If true, staleness checks for cached data will be forced, making the CLI +look for updates immediately even for fresh package data. + + + +#### \`prefix\` + +* Default: In global mode, the folder where the node executable is installed. + Otherwise, the nearest parent folder containing either a package.json file + or a node_modules folder. +* Type: Path + +The location to install global items. If set on the command line, then it +forces non-global commands to run in the specified folder. + + + +#### \`preid\` + +* Default: "" +* Type: String + +The "prerelease identifier" to use as a prefix for the "prerelease" part of +a semver. Like the \`rc\` in \`1.2.0-rc.8\`. + + + +#### \`progress\` + +* Default: \`true\` when not in CI and both stderr and stdout are TTYs and not + in a dumb terminal +* Type: Boolean + +When set to \`true\`, npm will display a progress bar during time intensive +operations, if \`process.stderr\` and \`process.stdout\` are a TTY. + +Set to \`false\` to suppress the progress bar. + + + +#### \`provenance\` + +* Default: false +* Type: Boolean + +When publishing from a supported cloud CI/CD system, the package will be +publicly linked to where it was built and published from. + +This config cannot be used with: \`provenance-file\` + +#### \`provenance-file\` + +* Default: null +* Type: Path + +When publishing, the provenance bundle at the given path will be used. + +This config cannot be used with: \`provenance\` + +#### \`proxy\` + +* Default: null +* Type: null, false, or URL + +A proxy to use for outgoing http requests. If the \`HTTP_PROXY\` or +\`http_proxy\` environment variables are set, proxy settings will be honored +by the underlying \`request\` library. + + + +#### \`read-only\` + +* Default: false +* Type: Boolean + +This is used to mark a token as unable to publish when configuring limited +access tokens with the \`npm token create\` command. + + + +#### \`rebuild-bundle\` + +* Default: true +* Type: Boolean + +Rebuild bundled dependencies after installation. + + + +#### \`registry\` + +* Default: "https://registry.npmjs.org/" +* Type: URL + +The base URL of the npm registry. + + + +#### \`replace-registry-host\` + +* Default: "npmjs" +* Type: "npmjs", "never", "always", or String + +Defines behavior for replacing the registry host in a lockfile with the +configured registry. + +The default behavior is to replace package dist URLs from the default +registry (https://registry.npmjs.org) to the configured registry. If set to +"never", then use the registry value. If set to "always", then replace the +registry host with the configured host every time. + +You may also specify a bare hostname (e.g., "registry.npmjs.org"). + + + +#### \`save\` + +* Default: \`true\` unless when using \`npm update\` where it defaults to \`false\` +* Type: Boolean + +Save installed packages to a \`package.json\` file as dependencies. + +When used with the \`npm rm\` command, removes the dependency from +\`package.json\`. + +Will also prevent writing to \`package-lock.json\` if set to \`false\`. + + + +#### \`save-bundle\` + +* Default: false +* Type: Boolean + +If a package would be saved at install time by the use of \`--save\`, +\`--save-dev\`, or \`--save-optional\`, then also put it in the +\`bundleDependencies\` list. + +Ignored if \`--save-peer\` is set, since peerDependencies cannot be bundled. + + + +#### \`save-dev\` + +* Default: false +* Type: Boolean + +Save installed packages to a package.json file as \`devDependencies\`. + +This config cannot be used with: \`save-optional\`, \`save-peer\`, \`save-prod\` + +#### \`save-exact\` + +* Default: false +* Type: Boolean + +Dependencies saved to package.json will be configured with an exact version +rather than using npm's default semver range operator. + + + +#### \`save-optional\` + +* Default: false +* Type: Boolean + +Save installed packages to a package.json file as \`optionalDependencies\`. + +This config cannot be used with: \`save-dev\`, \`save-peer\`, \`save-prod\` + +#### \`save-peer\` + +* Default: false +* Type: Boolean + +Save installed packages to a package.json file as \`peerDependencies\` + +This config cannot be used with: \`save-dev\`, \`save-optional\`, \`save-prod\` + +#### \`save-prefix\` + +* Default: "^" +* Type: String + +Configure how versions of packages installed to a package.json file via +\`--save\` or \`--save-dev\` get prefixed. + +For example if a package has version \`1.2.3\`, by default its version is set +to \`^1.2.3\` which allows minor upgrades for that package, but after \`npm +config set save-prefix='~'\` it would be set to \`~1.2.3\` which only allows +patch upgrades. + + + +#### \`save-prod\` + +* Default: false +* Type: Boolean + +Save installed packages into \`dependencies\` specifically. This is useful if +a package already exists in \`devDependencies\` or \`optionalDependencies\`, but +you want to move it to be a non-optional production dependency. + +This is the default behavior if \`--save\` is true, and neither \`--save-dev\` +or \`--save-optional\` are true. + +This config cannot be used with: \`save-dev\`, \`save-optional\`, \`save-peer\` + +#### \`sbom-format\` + +* Default: null +* Type: "cyclonedx" or "spdx" + +SBOM format to use when generating SBOMs. + + + +#### \`sbom-type\` + +* Default: "library" +* Type: "library", "application", or "framework" + +The type of package described by the generated SBOM. For SPDX, this is the +value for the \`primaryPackagePurpose\` field. For CycloneDX, this is the +value for the \`type\` field. + + + +#### \`scope\` + +* Default: the scope of the current project, if any, or "" +* Type: String + +Associate an operation with a scope for a scoped registry. + +Useful when logging in to or out of a private registry: + +\`\`\` +# log in, linking the scope to the custom registry +npm login --scope=@mycorp --registry=https://registry.mycorp.com + +# log out, removing the link and the auth token +npm logout --scope=@mycorp +\`\`\` + +This will cause \`@mycorp\` to be mapped to the registry for future +installation of packages specified according to the pattern +\`@mycorp/package\`. + +This will also cause \`npm init\` to create a scoped package. + +\`\`\` +# accept all defaults, and create a package named "@foo/whatever", +# instead of just named "whatever" +npm init --scope=@foo --yes +\`\`\` + + + +#### \`scopes\` + +* Default: null +* Type: null or String (can be set multiple times) + +When creating a Granular Access Token with \`npm token create\`, this limits +the token access to specific scopes. Provide a scope name (with or without @ +prefix). + + + +#### \`script-shell\` + +* Default: '/bin/sh' on POSIX systems, 'cmd.exe' on Windows +* Type: null or String + +The shell to use for scripts run with the \`npm exec\`, \`npm run\` and \`npm +init \` commands. + + + +#### \`searchexclude\` + +* Default: "" +* Type: String + +Space-separated options that limit the results from search. + + + +#### \`searchlimit\` + +* Default: 20 +* Type: Number + +Number of items to limit search results to. Will not apply at all to legacy +searches. + + + +#### \`searchopts\` + +* Default: "" +* Type: String + +Space-separated options that are always passed to search. + + + +#### \`searchstaleness\` + +* Default: 900 +* Type: Number + +The age of the cache, in seconds, before another registry request is made if +using legacy search endpoint. + + + +#### \`shell\` + +* Default: SHELL environment variable, or "bash" on Posix, or "cmd.exe" on + Windows +* Type: String + +The shell to run for the \`npm explore\` command. + + + +#### \`sign-git-commit\` + +* Default: false +* Type: Boolean + +If set to true, then the \`npm version\` command will commit the new package +version using \`-S\` to add a signature. + +Note that git requires you to have set up GPG keys in your git configs for +this to work properly. + + + +#### \`sign-git-tag\` + +* Default: false +* Type: Boolean + +If set to true, then the \`npm version\` command will tag the version using +\`-s\` to add a signature. + +Note that git requires you to have set up GPG keys in your git configs for +this to work properly. + + + +#### \`strict-peer-deps\` + +* Default: false +* Type: Boolean + +If set to \`true\`, and \`--legacy-peer-deps\` is not set, then _any_ +conflicting \`peerDependencies\` will be treated as an install failure, even +if npm could reasonably guess the appropriate resolution based on non-peer +dependency relationships. + +By default, conflicting \`peerDependencies\` deep in the dependency graph will +be resolved using the nearest non-peer dependency specification, even if +doing so will result in some packages receiving a peer dependency outside +the range set in their package's \`peerDependencies\` object. + +When such an override is performed, a warning is printed, explaining the +conflict and the packages involved. If \`--strict-peer-deps\` is set, then +this warning is treated as a failure. + + + +#### \`strict-ssl\` + +* Default: true +* Type: Boolean + +Whether or not to do SSL key validation when making requests to the registry +via https. + +See also the \`ca\` config. + + + +#### \`tag\` + +* Default: "latest" +* Type: String + +If you ask npm to install a package and don't tell it a specific version, +then it will install the specified tag. + +It is the tag added to the package@version specified in the \`npm dist-tag +add\` command, if no explicit tag is given. + +When used by the \`npm diff\` command, this is the tag used to fetch the +tarball that will be compared with the local files by default. + +If used in the \`npm publish\` command, this is the tag that will be added to +the package submitted to the registry. + + + +#### \`tag-version-prefix\` + +* Default: "v" +* Type: String + +If set, alters the prefix used when tagging a new version when performing a +version increment using \`npm version\`. To remove the prefix altogether, set +it to the empty string: \`""\`. + +Because other tools may rely on the convention that npm version tags look +like \`v1.0.0\`, _only use this property if it is absolutely necessary_. In +particular, use care when overriding this setting for public packages. + + + +#### \`timing\` + +* Default: false +* Type: Boolean + +If true, writes timing information to a process specific json file in the +cache or \`logs-dir\`. The file name ends with \`-timing.json\`. + +You can quickly view it with this [json](https://npm.im/json) command line: +\`cat ~/.npm/_logs/*-timing.json | npm exec -- json -g\`. + +Timing information will also be reported in the terminal. To suppress this +while still writing the timing file, use \`--silent\`. + + + +#### \`token-description\` + +* Default: null +* Type: null or String + +Description text for the token when using \`npm token create\`. + + + +#### \`umask\` + +* Default: 0 +* Type: Octal numeric string in range 0000..0777 (0..511) + +The "umask" value to use when setting the file creation mode on files and +folders. + +Folders and executables are given a mode which is \`0o777\` masked against +this value. Other files are given a mode which is \`0o666\` masked against +this value. + +Note that the underlying system will _also_ apply its own umask value to +files and folders that are created, and npm does not circumvent this, but +rather adds the \`--umask\` config to it. + +Thus, the effective default umask value on most POSIX systems is 0o22, +meaning that folders and executables are created with a mode of 0o755 and +other files are created with a mode of 0o644. + + + +#### \`unicode\` + +* Default: false on windows, true on mac/unix systems with a unicode locale, + as defined by the \`LC_ALL\`, \`LC_CTYPE\`, or \`LANG\` environment variables. +* Type: Boolean + +When set to true, npm uses unicode characters in the tree output. When +false, it uses ascii characters instead of unicode glyphs. + + + +#### \`update-notifier\` + +* Default: true +* Type: Boolean + +Set to false to suppress the update notification when using an older version +of npm than the latest. + + + +#### \`usage\` + +* Default: false +* Type: Boolean + +Show short usage output about the command specified. + + + +#### \`user-agent\` + +* Default: "npm/{npm-version} node/{node-version} {platform} {arch} + workspaces/{workspaces} {ci}" +* Type: String + +Sets the User-Agent request header. The following fields are replaced with +their actual counterparts: + +* \`{npm-version}\` - The npm version in use +* \`{node-version}\` - The Node.js version in use +* \`{platform}\` - The value of \`process.platform\` +* \`{arch}\` - The value of \`process.arch\` +* \`{workspaces}\` - Set to \`true\` if the \`workspaces\` or \`workspace\` options + are set. +* \`{ci}\` - The value of the \`ci-name\` config, if set, prefixed with \`ci/\`, or + an empty string if \`ci-name\` is empty. + + + +#### \`userconfig\` + +* Default: "~/.npmrc" +* Type: Path + +The location of user-level configuration settings. + +This may be overridden by the \`npm_config_userconfig\` environment variable +or the \`--userconfig\` command line option, but may _not_ be overridden by +settings in the \`globalconfig\` file. + + + +#### \`version\` + +* Default: false +* Type: Boolean + +If true, output the npm version and exit successfully. + +Only relevant when specified explicitly on the command line. + + + +#### \`versions\` + +* Default: false +* Type: Boolean + +If true, output the npm version as well as node's \`process.versions\` map and +the version in the current working directory's \`package.json\` file if one +exists, and exit successfully. + +Only relevant when specified explicitly on the command line. + + + +#### \`viewer\` + +* Default: "man" on Posix, "browser" on Windows +* Type: String + +The program to use to view help content. + +Set to \`"browser"\` to view html help content in the default web browser. + + + +#### \`which\` + +* Default: null +* Type: null or Number + +If there are multiple funding sources, which 1-indexed source URL to open. + + + +#### \`workspace\` + +* Default: +* Type: String (can be set multiple times) + +Enable running a command in the context of the configured workspaces of the +current project while filtering by running only the workspaces defined by +this configuration option. + +Valid values for the \`workspace\` config are either: + +* Workspace names +* Path to a workspace directory +* Path to a parent workspace directory (will result in selecting all + workspaces within that folder) + +When set for the \`npm init\` command, this may be set to the folder of a +workspace which does not yet exist, to create the folder and set it up as a +brand new workspace within the project. + +This value is not exported to the environment for child processes. + +#### \`workspaces\` + +* Default: null +* Type: null or Boolean + +Set to true to run the command in the context of **all** configured +workspaces. + +Explicitly setting this to false will cause commands like \`install\` to +ignore workspaces altogether. When not set explicitly: + +- Commands that operate on the \`node_modules\` tree (install, update, etc.) +will link workspaces into the \`node_modules\` folder. - Commands that do +other things (test, exec, publish, etc.) will operate on the root project, +_unless_ one or more workspaces are specified in the \`workspace\` config. + +This value is not exported to the environment for child processes. + +#### \`workspaces-update\` + +* Default: true +* Type: Boolean + +If set to true, the npm cli will run an update after operations that may +possibly change the workspaces installed to the \`node_modules\` folder. + + + +#### \`yes\` + +* Default: null +* Type: null or Boolean + +Automatically answer "yes" to any prompts that npm might print on the +command line. + + + +#### \`also\` + +* Default: null +* Type: null, "dev", or "development" +* DEPRECATED: Please use --include=dev instead. + +When set to \`dev\` or \`development\`, this is an alias for \`--include=dev\`. + + + +#### \`cache-max\` + +* Default: Infinity +* Type: Number +* DEPRECATED: This option has been deprecated in favor of \`--prefer-online\` + +\`--cache-max=0\` is an alias for \`--prefer-online\` + + + +#### \`cache-min\` + +* Default: 0 +* Type: Number +* DEPRECATED: This option has been deprecated in favor of \`--prefer-offline\`. + +\`--cache-min=9999 (or bigger)\` is an alias for \`--prefer-offline\`. + + + +#### \`cert\` + +* Default: null +* Type: null or String +* DEPRECATED: \`key\` and \`cert\` are no longer used for most registry + operations. Use registry scoped \`keyfile\` and \`certfile\` instead. Example: + //other-registry.tld/:keyfile=/path/to/key.pem + //other-registry.tld/:certfile=/path/to/cert.crt + +A client certificate to pass when accessing the registry. Values should be +in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with +newlines replaced by the string "\\n". For example: + +\`\`\`ini +cert="-----BEGIN CERTIFICATE-----\\nXXXX\\nXXXX\\n-----END CERTIFICATE-----" +\`\`\` + +It is _not_ the path to a certificate file, though you can set a +registry-scoped "certfile" path like +"//other-registry.tld/:certfile=/path/to/cert.pem". + + + +#### \`dev\` + +* Default: false +* Type: Boolean +* DEPRECATED: Please use --include=dev instead. + +Alias for \`--include=dev\`. + + + +#### \`global-style\` + +* Default: false +* Type: Boolean +* DEPRECATED: This option has been deprecated in favor of + \`--install-strategy=shallow\` + +Only install direct dependencies in the top level \`node_modules\`, but hoist +on deeper dependencies. Sets \`--install-strategy=shallow\`. + + + +#### \`init.author.email\` + +* Default: "" +* Type: String +* DEPRECATED: Use \`--init-author-email\` instead. + +Alias for \`--init-author-email\` + + + +#### \`init.author.name\` + +* Default: "" +* Type: String +* DEPRECATED: Use \`--init-author-name\` instead. + +Alias for \`--init-author-name\` + + + +#### \`init.author.url\` + +* Default: "" +* Type: "" or URL +* DEPRECATED: Use \`--init-author-url\` instead. + +Alias for \`--init-author-url\` + + + +#### \`init.license\` + +* Default: "ISC" +* Type: String +* DEPRECATED: Use \`--init-license\` instead. + +Alias for \`--init-license\` + + + +#### \`init.module\` + +* Default: "~/.npm-init.js" +* Type: Path +* DEPRECATED: Use \`--init-module\` instead. + +Alias for \`--init-module\` + + + +#### \`init.version\` + +* Default: "1.0.0" +* Type: SemVer string +* DEPRECATED: Use \`--init-version\` instead. + +Alias for \`--init-version\` + + + +#### \`key\` + +* Default: null +* Type: null or String +* DEPRECATED: \`key\` and \`cert\` are no longer used for most registry + operations. Use registry scoped \`keyfile\` and \`certfile\` instead. Example: + //other-registry.tld/:keyfile=/path/to/key.pem + //other-registry.tld/:certfile=/path/to/cert.crt + +A client key to pass when accessing the registry. Values should be in PEM +format with newlines replaced by the string "\\n". For example: + +\`\`\`ini +key="-----BEGIN PRIVATE KEY-----\\nXXXX\\nXXXX\\n-----END PRIVATE KEY-----" +\`\`\` + +It is _not_ the path to a key file, though you can set a registry-scoped +"keyfile" path like "//other-registry.tld/:keyfile=/path/to/key.pem". + + + +#### \`legacy-bundling\` + +* Default: false +* Type: Boolean +* DEPRECATED: This option has been deprecated in favor of + \`--install-strategy=nested\` + +Instead of hoisting package installs in \`node_modules\`, install packages in +the same manner that they are depended on. This may cause very deep +directory structures and duplicate package installs as there is no +de-duplicating. Sets \`--install-strategy=nested\`. + + + +#### \`only\` + +* Default: null +* Type: null, "prod", or "production" +* DEPRECATED: Use \`--omit=dev\` to omit dev dependencies from the install. + +When set to \`prod\` or \`production\`, this is an alias for \`--omit=dev\`. + + + +#### \`optional\` + +* Default: null +* Type: null or Boolean +* DEPRECATED: Use \`--omit=optional\` to exclude optional dependencies, or + \`--include=optional\` to include them. + +Default value does install optional deps unless otherwise omitted. + +Alias for --include=optional or --omit=optional + + + +#### \`production\` + +* Default: null +* Type: null or Boolean +* DEPRECATED: Use \`--omit=dev\` instead. + +Alias for \`--omit=dev\` + + + +#### \`shrinkwrap\` + +* Default: true +* Type: Boolean +* DEPRECATED: Use the --package-lock setting instead. + +Alias for --package-lock + + +` + +exports[`test/lib/docs.js TAP config > all keys 1`] = ` +Array [ + "_auth", + "access", + "all", + "allow-same-version", + "allow-git", + "also", + "audit", + "audit-level", + "auth-type", + "before", + "bin-links", + "browser", + "bypass-2fa", + "ca", + "cache", + "cache-max", + "cache-min", + "cafile", + "call", + "cert", + "cidr", + "color", + "commit-hooks", + "cpu", + "depth", + "description", + "dev", + "diff", + "diff-ignore-all-space", + "diff-name-only", + "diff-no-prefix", + "diff-dst-prefix", + "diff-src-prefix", + "diff-text", + "diff-unified", + "dry-run", + "editor", + "engine-strict", + "expect-result-count", + "expect-results", + "expires", + "fetch-retries", + "fetch-retry-factor", + "fetch-retry-maxtimeout", + "fetch-retry-mintimeout", + "fetch-timeout", + "force", + "foreground-scripts", + "format-package-lock", + "fund", + "git", + "git-tag-version", + "global", + "globalconfig", + "global-style", + "heading", + "https-proxy", + "if-present", + "ignore-scripts", + "include", + "include-staged", + "include-workspace-root", + "init-author-email", + "init-author-name", + "init-author-url", + "init-license", + "init-module", + "init-type", + "init-version", + "init-private", + "init.author.email", + "init.author.name", + "init.author.url", + "init.license", + "init.module", + "init.version", + "install-links", + "install-strategy", + "json", + "key", + "legacy-bundling", + "legacy-peer-deps", + "libc", + "link", + "local-address", + "location", + "lockfile-version", + "loglevel", + "logs-dir", + "logs-max", + "long", + "name", + "maxsockets", + "message", + "node-gyp", + "node-options", + "noproxy", + "offline", + "omit", + "omit-lockfile-registry-resolved", + "only", + "orgs", + "optional", + "os", + "otp", + "package", + "package-lock", + "package-lock-only", + "pack-destination", + "packages", + "parseable", + "prefer-dedupe", + "prefer-offline", + "prefer-online", + "prefix", + "preid", + "production", + "progress", + "provenance", + "provenance-file", + "proxy", + "read-only", + "rebuild-bundle", + "registry", + "replace-registry-host", + "save", + "save-bundle", + "save-dev", + "save-exact", + "save-optional", + "save-peer", + "save-prefix", + "save-prod", + "sbom-format", + "sbom-type", + "scope", + "scopes", + "packages-all", + "packages-and-scopes-permission", + "orgs-permission", + "password", + "token-description", + "script-shell", + "searchexclude", + "searchlimit", + "searchopts", + "searchstaleness", + "shell", + "shrinkwrap", + "sign-git-commit", + "sign-git-tag", + "strict-peer-deps", + "strict-ssl", + "tag", + "tag-version-prefix", + "timing", + "umask", + "unicode", + "update-notifier", + "usage", + "user-agent", + "userconfig", + "version", + "versions", + "viewer", + "which", + "workspace", + "workspaces", + "workspaces-update", + "yes", +] +` + +exports[`test/lib/docs.js TAP config > keys that are flattened 1`] = ` +Array [ + "_auth", + "access", + "all", + "allow-same-version", + "allow-git", + "also", + "audit", + "audit-level", + "auth-type", + "before", + "bin-links", + "browser", + "bypass-2fa", + "ca", + "cache", + "cache-max", + "cache-min", + "cafile", + "call", + "cert", + "cidr", + "color", + "commit-hooks", + "cpu", + "depth", + "description", + "dev", + "diff", + "diff-ignore-all-space", + "diff-name-only", + "diff-no-prefix", + "diff-dst-prefix", + "diff-src-prefix", + "diff-text", + "diff-unified", + "dry-run", + "editor", + "engine-strict", + "expires", + "fetch-retries", + "fetch-retry-factor", + "fetch-retry-maxtimeout", + "fetch-retry-mintimeout", + "fetch-timeout", + "force", + "foreground-scripts", + "format-package-lock", + "fund", + "git", + "git-tag-version", + "global", + "globalconfig", + "global-style", + "heading", + "https-proxy", + "if-present", + "ignore-scripts", + "include", + "include-staged", + "include-workspace-root", + "init-private", + "install-links", + "install-strategy", + "json", + "key", + "legacy-bundling", + "legacy-peer-deps", + "libc", + "local-address", + "location", + "lockfile-version", + "loglevel", + "name", + "maxsockets", + "message", + "node-gyp", + "noproxy", + "offline", + "omit", + "omit-lockfile-registry-resolved", + "only", + "orgs", + "optional", + "os", + "otp", + "package", + "package-lock", + "package-lock-only", + "pack-destination", + "packages", + "parseable", + "prefer-dedupe", + "prefer-offline", + "prefer-online", + "preid", + "production", + "progress", + "provenance", + "provenance-file", + "proxy", + "read-only", + "rebuild-bundle", + "registry", + "replace-registry-host", + "save", + "save-bundle", + "save-dev", + "save-exact", + "save-optional", + "save-peer", + "save-prefix", + "save-prod", + "sbom-format", + "sbom-type", + "scope", + "scopes", + "packages-all", + "packages-and-scopes-permission", + "orgs-permission", + "password", + "token-description", + "script-shell", + "searchexclude", + "searchlimit", + "searchopts", + "searchstaleness", + "shell", + "shrinkwrap", + "sign-git-commit", + "sign-git-tag", + "strict-peer-deps", + "strict-ssl", + "tag", + "tag-version-prefix", + "umask", + "unicode", + "user-agent", + "workspace", + "workspaces", + "workspaces-update", +] +` + +exports[`test/lib/docs.js TAP config > keys that are not flattened 1`] = ` +Array [ + "expect-result-count", + "expect-results", + "init-author-email", + "init-author-name", + "init-author-url", + "init-license", + "init-module", + "init-type", + "init-version", + "init.author.email", + "init.author.name", + "init.author.url", + "init.license", + "init.module", + "init.version", + "link", + "logs-dir", + "logs-max", + "long", + "node-options", + "prefix", + "timing", + "update-notifier", + "usage", + "userconfig", + "version", + "versions", + "viewer", + "which", + "yes", +] +` + +exports[`test/lib/docs.js TAP flat options > full flat options object 1`] = ` +Object { + "_auth": null, + "access": null, + "all": false, + "allowGit": "all", + "allowSameVersion": false, + "audit": true, + "auditLevel": null, + "authType": "web", + "before": null, + "binLinks": true, + "browser": null, + "bypass-2fa": false, + "ca": null, + "cache": "{CWD}/cache/_cacache", + "call": "", + "cert": null, + "cidr": null, + "color": false, + "commitHooks": true, + "cpu": null, + "defaultTag": "latest", + "depth": null, + "diff": Array [], + "diffDstPrefix": "b/", + "diffIgnoreAllSpace": false, + "diffNameOnly": false, + "diffNoPrefix": false, + "diffSrcPrefix": "a/", + "diffText": false, + "diffUnified": 3, + "dryRun": false, + "editor": "{EDITOR}", + "engineStrict": false, + "expires": null, + "force": false, + "foregroundScripts": false, + "formatPackageLock": true, + "fund": true, + "git": "git", + "gitTagVersion": true, + "global": false, + "globalconfig": "{CWD}/global/etc/npmrc", + "heading": "npm", + "httpsProxy": null, + "ifPresent": false, + "ignoreScripts": false, + "includeStaged": false, + "includeWorkspaceRoot": false, + "initPrivate": false, + "installLinks": false, + "installStrategy": "hoisted", + "json": false, + "key": null, + "legacyPeerDeps": false, + "libc": null, + "localAddress": null, + "location": "user", + "lockfileVersion": null, + "logColor": false, + "maxSockets": 15, + "message": "%s", + "name": null, + "nodeBin": "{NODE}", + "nodeGyp": "{CWD}/node_modules/node-gyp/bin/node-gyp.js", + "nodeVersion": "2.2.2", + "noProxy": "", + "npmBin": "{CWD}/other/bin/npm-cli.js", + "npmCommand": "version", + "npmVersion": "3.3.3", + "npxCache": "{CWD}/cache/_npx", + "offline": false, + "omit": Array [], + "omitLockfileRegistryResolved": false, + "orgs": null, + "orgsPermission": null, + "os": null, + "otp": null, + "package": Array [], + "packageLock": true, + "packageLockOnly": false, + "packages": Array [], + "packagesAll": false, + "packagesAndScopesPermission": null, + "packDestination": ".", + "parseable": false, + "password": null, + "preferDedupe": false, + "preferOffline": false, + "preferOnline": false, + "preid": "", + "progress": false, + "projectScope": "", + "provenance": false, + "provenanceFile": null, + "proxy": null, + "readOnly": false, + "rebuildBundle": true, + "registry": "https://registry.npmjs.org/", + "replaceRegistryHost": "npmjs", + "retry": Object { + "factor": 10, + "maxTimeout": 60000, + "minTimeout": 10000, + "retries": 0, + }, + "save": true, + "saveBundle": false, + "savePrefix": "^", + "sbomFormat": null, + "sbomType": "library", + "scope": "", + "scopes": null, + "scriptShell": undefined, + "search": Object { + "description": true, + "exclude": "", + "limit": 20, + "opts": Null Object {}, + "staleness": 900, + }, + "shell": "{SHELL}", + "signGitCommit": false, + "signGitTag": false, + "silent": false, + "strictPeerDeps": false, + "strictSSL": true, + "tagVersionPrefix": "v", + "timeout": 300000, + "tokenDescription": null, + "tufCache": "{CWD}/cache/_tuf", + "umask": 0, + "unicode": false, + "userAgent": "npm/1.1.1 node/2.2.2 {PLATFORM} {ARCH} workspaces/false ci/{ci}", + "workspacesEnabled": true, + "workspacesUpdate": true, +} +` + +exports[`test/lib/docs.js TAP shorthands > docs 1`] = ` +* \`-a\`: \`--all\` +* \`--enjoy-by\`: \`--before\` +* \`-c\`: \`--call\` +* \`--desc\`: \`--description\` +* \`-f\`: \`--force\` +* \`-g\`: \`--global\` +* \`--iwr\`: \`--include-workspace-root\` +* \`-L\`: \`--location\` +* \`-d\`: \`--loglevel info\` +* \`-s\`: \`--loglevel silent\` +* \`--silent\`: \`--loglevel silent\` +* \`--ddd\`: \`--loglevel silly\` +* \`--dd\`: \`--loglevel verbose\` +* \`--verbose\`: \`--loglevel verbose\` +* \`-q\`: \`--loglevel warn\` +* \`--quiet\`: \`--loglevel warn\` +* \`-l\`: \`--long\` +* \`-m\`: \`--message\` +* \`--local\`: \`--no-global\` +* \`-n\`: \`--no-yes\` +* \`--no\`: \`--no-yes\` +* \`-p\`: \`--parseable\` +* \`--porcelain\`: \`--parseable\` +* \`-C\`: \`--prefix\` +* \`--readonly\`: \`--read-only\` +* \`--reg\`: \`--registry\` +* \`-S\`: \`--save\` +* \`-B\`: \`--save-bundle\` +* \`-D\`: \`--save-dev\` +* \`-E\`: \`--save-exact\` +* \`-O\`: \`--save-optional\` +* \`-P\`: \`--save-prod\` +* \`-?\`: \`--usage\` +* \`-h\`: \`--usage\` +* \`-H\`: \`--usage\` +* \`--help\`: \`--usage\` +* \`-v\`: \`--version\` +* \`-w\`: \`--workspace\` +* \`--ws\`: \`--workspaces\` +* \`-y\`: \`--yes\` +` + +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 collaborators [ []] +npm access get status [] +npm access set status=public|private [] +npm access set mfa=none|publish|automation [] +npm access grant [] +npm access revoke [] + +Options: +[--json] [--otp ] [--registry ] + +Run "npm help access" for more info + +\`\`\`bash +npm access list packages [||] [] +npm access list collaborators [ []] +npm access get status [] +npm access set status=public|private [] +npm access set mfa=none|publish|automation [] +npm access grant [] +npm access revoke [] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`json\` +#### \`otp\` +#### \`registry\` +` + +exports[`test/lib/docs.js TAP usage adduser > must match snapshot 1`] = ` +Add a registry user account + +Usage: +npm adduser + +Options: +[--registry ] [--scope <@scope>] [--auth-type ] + +alias: add-user + +Run "npm help adduser" for more info + +\`\`\`bash +npm adduser + +alias: add-user +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`scope\` +#### \`auth-type\` +` + +exports[`test/lib/docs.js TAP usage audit > must match snapshot 1`] = ` +Run a security audit + +Usage: +npm audit [fix|signatures] + +Options: +[--audit-level ] [--dry-run] [-f|--force] +[--json] [--package-lock-only] [--no-package-lock] +[--omit [--omit ...]] +[--include [--include ...]] +[--foreground-scripts] [--ignore-scripts] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +Run "npm help audit" for more info + +\`\`\`bash +npm audit [fix|signatures] +\`\`\` + +#### \`audit-level\` +#### \`dry-run\` +#### \`force\` +#### \`json\` +#### \`package-lock-only\` +#### \`package-lock\` +#### \`omit\` +#### \`include\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage bugs > must match snapshot 1`] = ` +Report bugs for a package in a web browser + +Usage: +npm bugs [ [ ...]] + +Options: +[--no-browser|--browser ] [--registry ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +alias: issues + +Run "npm help bugs" for more info + +\`\`\`bash +npm bugs [ [ ...]] + +alias: issues +\`\`\` + +#### \`browser\` +#### \`registry\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage cache > must match snapshot 1`] = ` +Manipulates packages and npx cache + +Usage: +npm cache add +npm cache clean [] +npm cache ls [@] +npm cache verify +npm cache npx ls +npm cache npx rm [...] +npm cache npx info ... + +Options: +[--cache ] + +Run "npm help cache" for more info + +\`\`\`bash +npm cache add +npm cache clean [] +npm cache ls [@] +npm cache verify +npm cache npx ls +npm cache npx rm [...] +npm cache npx info ... +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`cache\` +` + +exports[`test/lib/docs.js TAP usage ci > must match snapshot 1`] = ` +Clean install a project + +Usage: +npm ci + +Options: +[--install-strategy ] [--legacy-bundling] +[--global-style] [--omit [--omit ...]] +[--include [--include ...]] +[--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] +[--allow-git ] [--no-audit] [--no-bin-links] [--no-fund] +[--dry-run] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +aliases: clean-install, ic, install-clean, isntall-clean + +Run "npm help ci" for more info + +\`\`\`bash +npm ci + +aliases: clean-install, ic, install-clean, isntall-clean +\`\`\` + +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`omit\` +#### \`include\` +#### \`strict-peer-deps\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`allow-git\` +#### \`audit\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage completion > must match snapshot 1`] = ` +Tab Completion for npm + +Usage: +npm completion + +Run "npm help completion" for more info + +\`\`\`bash +npm completion +\`\`\` + +Note: This command is unaware of workspaces. + +NO PARAMS +` + +exports[`test/lib/docs.js TAP usage config > must match snapshot 1`] = ` +Manage the npm configuration files + +Usage: +npm config set = [= ...] +npm config get [ [ ...]] +npm config delete [ ...] +npm config list [--json] +npm config edit +npm config fix + +Options: +[--json] [-g|--global] [--editor ] [-L|--location ] +[-l|--long] + +alias: c + +Run "npm help config" for more info + +\`\`\`bash +npm config set = [= ...] +npm config get [ [ ...]] +npm config delete [ ...] +npm config list [--json] +npm config edit +npm config fix + +alias: c +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`json\` +#### \`global\` +#### \`editor\` +#### \`location\` +#### \`long\` +` + +exports[`test/lib/docs.js TAP usage dedupe > must match snapshot 1`] = ` +Reduce duplication in the package tree + +Usage: +npm dedupe + +Options: +[--install-strategy ] [--legacy-bundling] +[--global-style] [--strict-peer-deps] [--no-package-lock] +[--omit [--omit ...]] +[--include [--include ...]] +[--ignore-scripts] [--allow-git ] [--no-audit] [--no-bin-links] +[--no-fund] [--dry-run] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +alias: ddp + +Run "npm help dedupe" for more info + +\`\`\`bash +npm dedupe + +alias: ddp +\`\`\` + +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`strict-peer-deps\` +#### \`package-lock\` +#### \`omit\` +#### \`include\` +#### \`ignore-scripts\` +#### \`allow-git\` +#### \`audit\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage deprecate > must match snapshot 1`] = ` +Deprecate a version of a package + +Usage: +npm deprecate + +Options: +[--registry ] [--otp ] [--dry-run] + +Run "npm help deprecate" for more info + +\`\`\`bash +npm deprecate +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`otp\` +#### \`dry-run\` +` + +exports[`test/lib/docs.js TAP usage diff > must match snapshot 1`] = ` +The registry diff command + +Usage: +npm diff [...] + +Options: +[--diff [--diff ...]] [--diff-name-only] +[--diff-unified ] [--diff-ignore-all-space] [--diff-no-prefix] +[--diff-src-prefix ] [--diff-dst-prefix ] [--diff-text] [-g|--global] +[--tag ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +Run "npm help diff" for more info + +\`\`\`bash +npm diff [...] +\`\`\` + +#### \`diff\` +#### \`diff-name-only\` +#### \`diff-unified\` +#### \`diff-ignore-all-space\` +#### \`diff-no-prefix\` +#### \`diff-src-prefix\` +#### \`diff-dst-prefix\` +#### \`diff-text\` +#### \`global\` +#### \`tag\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage dist-tag > must match snapshot 1`] = ` +Modify package distribution tags + +Usage: +npm dist-tag add [] +npm dist-tag rm +npm dist-tag ls [] + +Options: +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +alias: dist-tags + +Run "npm help dist-tag" for more info + +\`\`\`bash +npm dist-tag add [] +npm dist-tag rm +npm dist-tag ls [] + +alias: dist-tags +\`\`\` + +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage docs > must match snapshot 1`] = ` +Open documentation for a package in a web browser + +Usage: +npm docs [ [ ...]] + +Options: +[--no-browser|--browser ] [--registry ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +alias: home + +Run "npm help docs" for more info + +\`\`\`bash +npm docs [ [ ...]] + +alias: home +\`\`\` + +#### \`browser\` +#### \`registry\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage doctor > must match snapshot 1`] = ` +Check the health of your npm environment + +Usage: +npm doctor [connection] [registry] [versions] [environment] [permissions] [cache] + +Options: +[--registry ] + +Run "npm help doctor" for more info + +\`\`\`bash +npm doctor [connection] [registry] [versions] [environment] [permissions] [cache] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +` + +exports[`test/lib/docs.js TAP usage edit > must match snapshot 1`] = ` +Edit an installed package + +Usage: +npm edit [/...] + +Options: +[--editor ] + +Run "npm help edit" for more info + +\`\`\`bash +npm edit [/...] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`editor\` +` + +exports[`test/lib/docs.js TAP usage exec > must match snapshot 1`] = ` +Run a command from a local or remote npm package + +Usage: +npm exec -- [@] [args...] +npm exec --package=[@] -- [args...] +npm exec -c ' [args...]' +npm exec --package=foo -c ' [args...]' + +Options: +[--package [--package ...]] [-c|--call ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +alias: x + +Run "npm help exec" for more info + +\`\`\`bash +npm exec -- [@] [args...] +npm exec --package=[@] -- [args...] +npm exec -c ' [args...]' +npm exec --package=foo -c ' [args...]' + +alias: x +\`\`\` + +#### \`package\` +#### \`call\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage explain > must match snapshot 1`] = ` +Explain installed packages + +Usage: +npm explain + +Options: +[--json] [-w|--workspace [-w|--workspace ...]] + +alias: why + +Run "npm help explain" for more info + +\`\`\`bash +npm explain + +alias: why +\`\`\` + +#### \`json\` +#### \`workspace\` +` + +exports[`test/lib/docs.js TAP usage explore > must match snapshot 1`] = ` +Browse an installed package + +Usage: +npm explore [ -- ] + +Options: +[--shell ] + +Run "npm help explore" for more info + +\`\`\`bash +npm explore [ -- ] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`shell\` +` + +exports[`test/lib/docs.js TAP usage find-dupes > must match snapshot 1`] = ` +Find duplication in the package tree + +Usage: +npm find-dupes + +Options: +[--install-strategy ] [--legacy-bundling] +[--global-style] [--strict-peer-deps] [--no-package-lock] +[--omit [--omit ...]] +[--include [--include ...]] +[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +Run "npm help find-dupes" for more info + +\`\`\`bash +npm find-dupes +\`\`\` + +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`strict-peer-deps\` +#### \`package-lock\` +#### \`omit\` +#### \`include\` +#### \`ignore-scripts\` +#### \`audit\` +#### \`bin-links\` +#### \`fund\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage fund > must match snapshot 1`] = ` +Retrieve funding information + +Usage: +npm fund [] + +Options: +[--json] [--no-browser|--browser ] [--unicode] +[-w|--workspace [-w|--workspace ...]] +[--which ] + +Run "npm help fund" for more info + +\`\`\`bash +npm fund [] +\`\`\` + +#### \`json\` +#### \`browser\` +#### \`unicode\` +#### \`workspace\` +#### \`which\` +` + +exports[`test/lib/docs.js TAP usage get > must match snapshot 1`] = ` +Get a value from the npm configuration + +Usage: +npm get [ ...] (See \`npm config\`) + +Options: +[-l|--long] + +Run "npm help get" for more info + +\`\`\`bash +npm get [ ...] (See \`npm config\`) +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`long\` +` + +exports[`test/lib/docs.js TAP usage help > must match snapshot 1`] = ` +Get help on npm + +Usage: +npm help [] + +Options: +[--viewer ] + +alias: hlep + +Run "npm help help" for more info + +\`\`\`bash +npm help [] + +alias: hlep +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`viewer\` +` + +exports[`test/lib/docs.js TAP usage help-search > must match snapshot 1`] = ` +Search npm help documentation + +Usage: +npm help-search + +Options: +[-l|--long] + +Run "npm help help-search" for more info + +\`\`\`bash +npm help-search +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`long\` +` + +exports[`test/lib/docs.js TAP usage init > must match snapshot 1`] = ` +Create a package.json file + +Usage: +npm init (same as \`npx create-\`) +npm init <@scope> (same as \`npx <@scope>/create\`) + +Options: +[--init-author-name ] [--init-author-url ] [--init-license ] +[--init-module ] [--init-type ] [--init-version ] +[--init-private] [-y|--yes] [-f|--force] [--scope <@scope>] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--no-workspaces-update] [--include-workspace-root] + +aliases: create, innit + +Run "npm help init" for more info + +\`\`\`bash +npm init (same as \`npx create-\`) +npm init <@scope> (same as \`npx <@scope>/create\`) + +aliases: create, innit +\`\`\` + +#### \`init-author-name\` +#### \`init-author-url\` +#### \`init-license\` +#### \`init-module\` +#### \`init-type\` +#### \`init-version\` +#### \`init-private\` +#### \`yes\` +#### \`force\` +#### \`scope\` +#### \`workspace\` +#### \`workspaces\` +#### \`workspaces-update\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage install > must match snapshot 1`] = ` +Install a package + +Usage: +npm install [ ...] + +Options: +[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-E|--save-exact] [-g|--global] +[--install-strategy ] [--legacy-bundling] +[--global-style] [--omit [--omit ...]] +[--include [--include ...]] +[--strict-peer-deps] [--prefer-dedupe] [--no-package-lock] [--package-lock-only] +[--foreground-scripts] [--ignore-scripts] [--allow-git ] +[--no-audit] [--before ] [--no-bin-links] [--no-fund] [--dry-run] +[--cpu ] [--os ] [--libc ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall + +Run "npm help install" for more info + +\`\`\`bash +npm install [ ...] + +aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall +\`\`\` + +#### \`save\` +#### \`save-exact\` +#### \`global\` +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`omit\` +#### \`include\` +#### \`strict-peer-deps\` +#### \`prefer-dedupe\` +#### \`package-lock\` +#### \`package-lock-only\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`allow-git\` +#### \`audit\` +#### \`before\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`cpu\` +#### \`os\` +#### \`libc\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage install-ci-test > must match snapshot 1`] = ` +Install a project with a clean slate and run tests + +Usage: +npm install-ci-test + +Options: +[--install-strategy ] [--legacy-bundling] +[--global-style] [--omit [--omit ...]] +[--include [--include ...]] +[--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] +[--allow-git ] [--no-audit] [--no-bin-links] [--no-fund] +[--dry-run] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +aliases: cit, clean-install-test, sit + +Run "npm help install-ci-test" for more info + +\`\`\`bash +npm install-ci-test + +aliases: cit, clean-install-test, sit +\`\`\` + +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`omit\` +#### \`include\` +#### \`strict-peer-deps\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`allow-git\` +#### \`audit\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage install-test > must match snapshot 1`] = ` +Install package(s) and run tests + +Usage: +npm install-test [ ...] + +Options: +[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-E|--save-exact] [-g|--global] +[--install-strategy ] [--legacy-bundling] +[--global-style] [--omit [--omit ...]] +[--include [--include ...]] +[--strict-peer-deps] [--prefer-dedupe] [--no-package-lock] [--package-lock-only] +[--foreground-scripts] [--ignore-scripts] [--allow-git ] +[--no-audit] [--before ] [--no-bin-links] [--no-fund] [--dry-run] +[--cpu ] [--os ] [--libc ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +alias: it + +Run "npm help install-test" for more info + +\`\`\`bash +npm install-test [ ...] + +alias: it +\`\`\` + +#### \`save\` +#### \`save-exact\` +#### \`global\` +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`omit\` +#### \`include\` +#### \`strict-peer-deps\` +#### \`prefer-dedupe\` +#### \`package-lock\` +#### \`package-lock-only\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`allow-git\` +#### \`audit\` +#### \`before\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`cpu\` +#### \`os\` +#### \`libc\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage link > must match snapshot 1`] = ` +Symlink a package folder + +Usage: +npm link [] + +Options: +[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-E|--save-exact] [-g|--global] +[--install-strategy ] [--legacy-bundling] +[--global-style] [--strict-peer-deps] [--no-package-lock] +[--omit [--omit ...]] +[--include [--include ...]] +[--ignore-scripts] [--allow-git ] [--no-audit] [--no-bin-links] +[--no-fund] [--dry-run] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +alias: ln + +Run "npm help link" for more info + +\`\`\`bash +npm link [] + +alias: ln +\`\`\` + +#### \`save\` +#### \`save-exact\` +#### \`global\` +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`strict-peer-deps\` +#### \`package-lock\` +#### \`omit\` +#### \`include\` +#### \`ignore-scripts\` +#### \`allow-git\` +#### \`audit\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage ll > must match snapshot 1`] = ` +List installed packages + +Usage: +npm ll [[<@scope>/] ...] + +Options: +[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [--depth ] +[--omit [--omit ...]] +[--include [--include ...]] +[--link] [--package-lock-only] [--unicode] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +alias: la + +Run "npm help ll" for more info + +\`\`\`bash +npm ll [[<@scope>/] ...] + +alias: la +\`\`\` + +#### \`all\` +#### \`json\` +#### \`long\` +#### \`parseable\` +#### \`global\` +#### \`depth\` +#### \`omit\` +#### \`include\` +#### \`link\` +#### \`package-lock-only\` +#### \`unicode\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage login > must match snapshot 1`] = ` +Login to a registry user account + +Usage: +npm login + +Options: +[--registry ] [--scope <@scope>] [--auth-type ] + +Run "npm help login" for more info + +\`\`\`bash +npm login +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`scope\` +#### \`auth-type\` +` + +exports[`test/lib/docs.js TAP usage logout > must match snapshot 1`] = ` +Log out of the registry + +Usage: +npm logout + +Options: +[--registry ] [--scope <@scope>] + +Run "npm help logout" for more info + +\`\`\`bash +npm logout +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`scope\` +` + +exports[`test/lib/docs.js TAP usage ls > must match snapshot 1`] = ` +List installed packages + +Usage: +npm ls + +Options: +[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [--depth ] +[--omit [--omit ...]] +[--include [--include ...]] +[--link] [--package-lock-only] [--unicode] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +alias: list + +Run "npm help ls" for more info + +\`\`\`bash +npm ls + +alias: list +\`\`\` + +#### \`all\` +#### \`json\` +#### \`long\` +#### \`parseable\` +#### \`global\` +#### \`depth\` +#### \`omit\` +#### \`include\` +#### \`link\` +#### \`package-lock-only\` +#### \`unicode\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage npm > must match snapshot 1`] = ` +\`\`\`bash +npm +\`\`\` + +Note: This command is unaware of workspaces. + +NO PARAMS +` + +exports[`test/lib/docs.js TAP usage npx > must match snapshot 1`] = ` +\`\`\`bash +npx -- [@] [args...] +npx --package=[@] -- [args...] +npx -c ' [args...]' +npx --package=foo -c ' [args...]' +\`\`\` + +NO PARAMS +` + +exports[`test/lib/docs.js TAP usage org > must match snapshot 1`] = ` +Manage orgs + +Usage: +npm org set orgname username [developer | admin | owner] +npm org rm orgname username +npm org ls orgname [] + +Options: +[--registry ] [--otp ] [--json] [-p|--parseable] + +alias: ogr + +Run "npm help org" for more info + +\`\`\`bash +npm org set orgname username [developer | admin | owner] +npm org rm orgname username +npm org ls orgname [] + +alias: ogr +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`otp\` +#### \`json\` +#### \`parseable\` +` + +exports[`test/lib/docs.js TAP usage outdated > must match snapshot 1`] = ` +Check for outdated packages + +Usage: +npm outdated [ ...] + +Options: +[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] +[-w|--workspace [-w|--workspace ...]] +[--before ] + +Run "npm help outdated" for more info + +\`\`\`bash +npm outdated [ ...] +\`\`\` + +#### \`all\` +#### \`json\` +#### \`long\` +#### \`parseable\` +#### \`global\` +#### \`workspace\` +#### \`before\` +` + +exports[`test/lib/docs.js TAP usage owner > must match snapshot 1`] = ` +Manage package owners + +Usage: +npm owner add +npm owner rm +npm owner ls + +Options: +[--registry ] [--otp ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] + +alias: author + +Run "npm help owner" for more info + +\`\`\`bash +npm owner add +npm owner rm +npm owner ls + +alias: author +\`\`\` + +#### \`registry\` +#### \`otp\` +#### \`workspace\` +#### \`workspaces\` +` + +exports[`test/lib/docs.js TAP usage pack > must match snapshot 1`] = ` +Create a tarball from a package + +Usage: +npm pack + +Options: +[--dry-run] [--json] [--pack-destination ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--ignore-scripts] + +Run "npm help pack" for more info + +\`\`\`bash +npm pack +\`\`\` + +#### \`dry-run\` +#### \`json\` +#### \`pack-destination\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`ignore-scripts\` +` + +exports[`test/lib/docs.js TAP usage ping > must match snapshot 1`] = ` +Ping npm registry + +Usage: +npm ping + +Options: +[--registry ] + +Run "npm help ping" for more info + +\`\`\`bash +npm ping +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +` + +exports[`test/lib/docs.js TAP usage pkg > must match snapshot 1`] = ` +Manages your package.json + +Usage: +npm pkg set = [= ...] +npm pkg get [ [ ...]] +npm pkg delete [ ...] +npm pkg set [[].= ...] +npm pkg set [[].= ...] +npm pkg fix + +Options: +[-f|--force] [--json] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] + +Run "npm help pkg" for more info + +\`\`\`bash +npm pkg set = [= ...] +npm pkg get [ [ ...]] +npm pkg delete [ ...] +npm pkg set [[].= ...] +npm pkg set [[].= ...] +npm pkg fix +\`\`\` + +#### \`force\` +#### \`json\` +#### \`workspace\` +#### \`workspaces\` +` + +exports[`test/lib/docs.js TAP usage prefix > must match snapshot 1`] = ` +Display prefix + +Usage: +npm prefix + +Options: +[-g|--global] + +Run "npm help prefix" for more info + +\`\`\`bash +npm prefix +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`global\` +` + +exports[`test/lib/docs.js TAP usage profile > must match snapshot 1`] = ` +Change settings on your registry profile + +Usage: +npm profile enable-2fa [auth-only|auth-and-writes] +npm profile disable-2fa +npm profile get [] +npm profile set + +Options: +[--registry ] [--json] [-p|--parseable] [--otp ] + +Run "npm help profile" for more info + +\`\`\`bash +npm profile enable-2fa [auth-only|auth-and-writes] +npm profile disable-2fa +npm profile get [] +npm profile set +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`json\` +#### \`parseable\` +#### \`otp\` +` + +exports[`test/lib/docs.js TAP usage prune > must match snapshot 1`] = ` +Remove extraneous packages + +Usage: +npm prune [[<@scope>/]...] + +Options: +[--omit [--omit ...]] +[--include [--include ...]] +[--dry-run] [--json] [--foreground-scripts] [--ignore-scripts] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +Run "npm help prune" for more info + +\`\`\`bash +npm prune [[<@scope>/]...] +\`\`\` + +#### \`omit\` +#### \`include\` +#### \`dry-run\` +#### \`json\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage publish > must match snapshot 1`] = ` +Publish a package + +Usage: +npm publish + +Options: +[--tag ] [--access ] [--dry-run] [--otp ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--provenance|--provenance-file ] + +Run "npm help publish" for more info + +\`\`\`bash +npm publish +\`\`\` + +#### \`tag\` +#### \`access\` +#### \`dry-run\` +#### \`otp\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`provenance\` +#### \`provenance-file\` +` + +exports[`test/lib/docs.js TAP usage query > must match snapshot 1`] = ` +Retrieve a filtered list of packages + +Usage: +npm query + +Options: +[-g|--global] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--package-lock-only] +[--expect-results|--expect-result-count ] + +Run "npm help query" for more info + +\`\`\`bash +npm query +\`\`\` + +#### \`global\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`package-lock-only\` +#### \`expect-results\` +#### \`expect-result-count\` +` + +exports[`test/lib/docs.js TAP usage rebuild > must match snapshot 1`] = ` +Rebuild a package + +Usage: +npm rebuild [] ...] + +Options: +[-g|--global] [--no-bin-links] [--foreground-scripts] [--ignore-scripts] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +alias: rb + +Run "npm help rebuild" for more info + +\`\`\`bash +npm rebuild [] ...] + +alias: rb +\`\`\` + +#### \`global\` +#### \`bin-links\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage repo > must match snapshot 1`] = ` +Open package repository page in the browser + +Usage: +npm repo [ [ ...]] + +Options: +[--no-browser|--browser ] [--registry ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +Run "npm help repo" for more info + +\`\`\`bash +npm repo [ [ ...]] +\`\`\` + +#### \`browser\` +#### \`registry\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage restart > must match snapshot 1`] = ` +Restart a package + +Usage: +npm restart [-- ] + +Options: +[--ignore-scripts] [--script-shell ] + +Run "npm help restart" for more info + +\`\`\`bash +npm restart [-- ] +\`\`\` + +#### \`ignore-scripts\` +#### \`script-shell\` +` + +exports[`test/lib/docs.js TAP usage root > must match snapshot 1`] = ` +Display npm root + +Usage: +npm root + +Options: +[-g|--global] + +Run "npm help root" for more info + +\`\`\`bash +npm root +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`global\` +` + +exports[`test/lib/docs.js TAP usage run > must match snapshot 1`] = ` +Run arbitrary package scripts + +Usage: +npm run [-- ] + +Options: +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--if-present] [--ignore-scripts] +[--foreground-scripts] [--script-shell ] + +aliases: run-script, rum, urn + +Run "npm help run" for more info + +\`\`\`bash +npm run [-- ] + +aliases: run-script, rum, urn +\`\`\` + +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`if-present\` +#### \`ignore-scripts\` +#### \`foreground-scripts\` +#### \`script-shell\` +` + +exports[`test/lib/docs.js TAP usage sbom > must match snapshot 1`] = ` +Generate a Software Bill of Materials (SBOM) + +Usage: +npm sbom + +Options: +[--omit [--omit ...]] +[--package-lock-only] [--sbom-format ] +[--sbom-type ] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] + +Run "npm help sbom" for more info + +\`\`\`bash +npm sbom +\`\`\` + +#### \`omit\` +#### \`package-lock-only\` +#### \`sbom-format\` +#### \`sbom-type\` +#### \`workspace\` +#### \`workspaces\` +` + +exports[`test/lib/docs.js TAP usage search > must match snapshot 1`] = ` +Search for packages + +Usage: +npm search [ ...] + +Options: +[--json] [--color|--no-color|--color always] [-p|--parseable] [--no-description] +[--searchlimit ] [--searchopts ] +[--searchexclude ] [--registry ] [--prefer-online] +[--prefer-offline] [--offline] + +aliases: find, s, se + +Run "npm help search" for more info + +\`\`\`bash +npm search [ ...] + +aliases: find, s, se +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`json\` +#### \`color\` +#### \`parseable\` +#### \`description\` +#### \`searchlimit\` +#### \`searchopts\` +#### \`searchexclude\` +#### \`registry\` +#### \`prefer-online\` +#### \`prefer-offline\` +#### \`offline\` +` + +exports[`test/lib/docs.js TAP usage set > must match snapshot 1`] = ` +Set a value in the npm configuration + +Usage: +npm set = [= ...] (See \`npm config\`) + +Options: +[-g|--global] [-L|--location ] + +Run "npm help set" for more info + +\`\`\`bash +npm set = [= ...] (See \`npm config\`) +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`global\` +#### \`location\` +` + +exports[`test/lib/docs.js TAP usage shrinkwrap > must match snapshot 1`] = ` +Lock down dependency versions for publication + +Usage: +npm shrinkwrap + +Run "npm help shrinkwrap" for more info + +\`\`\`bash +npm shrinkwrap +\`\`\` + +Note: This command is unaware of workspaces. + +NO PARAMS +` + +exports[`test/lib/docs.js TAP usage star > must match snapshot 1`] = ` +Mark your favorite packages + +Usage: +npm star [...] + +Options: +[--registry ] [--unicode] [--otp ] + +Run "npm help star" for more info + +\`\`\`bash +npm star [...] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`unicode\` +#### \`otp\` +` + +exports[`test/lib/docs.js TAP usage stars > must match snapshot 1`] = ` +View packages marked as favorites + +Usage: +npm stars [] + +Options: +[--registry ] + +Run "npm help stars" for more info + +\`\`\`bash +npm stars [] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +` + +exports[`test/lib/docs.js TAP usage start > must match snapshot 1`] = ` +Start a package + +Usage: +npm start [-- ] + +Options: +[--ignore-scripts] [--script-shell ] + +Run "npm help start" for more info + +\`\`\`bash +npm start [-- ] +\`\`\` + +#### \`ignore-scripts\` +#### \`script-shell\` +` + +exports[`test/lib/docs.js TAP usage stop > must match snapshot 1`] = ` +Stop a package + +Usage: +npm stop [-- ] + +Options: +[--ignore-scripts] [--script-shell ] + +Run "npm help stop" for more info + +\`\`\`bash +npm stop [-- ] +\`\`\` + +#### \`ignore-scripts\` +#### \`script-shell\` +` + +exports[`test/lib/docs.js TAP usage team > must match snapshot 1`] = ` +Manage organization teams and team memberships + +Usage: +npm team create [--otp ] +npm team destroy [--otp ] +npm team add [--otp ] +npm team rm [--otp ] +npm team ls | + +Options: +[--registry ] [--otp ] [-p|--parseable] [--json] + +Run "npm help team" for more info + +\`\`\`bash +npm team create [--otp ] +npm team destroy [--otp ] +npm team add [--otp ] +npm team rm [--otp ] +npm team ls | +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`otp\` +#### \`parseable\` +#### \`json\` +` + +exports[`test/lib/docs.js TAP usage test > must match snapshot 1`] = ` +Test a package + +Usage: +npm test [-- ] + +Options: +[--ignore-scripts] [--script-shell ] + +aliases: tst, t + +Run "npm help test" for more info + +\`\`\`bash +npm test [-- ] + +aliases: tst, t +\`\`\` + +#### \`ignore-scripts\` +#### \`script-shell\` +` + +exports[`test/lib/docs.js TAP usage token > must match snapshot 1`] = ` +Manage your authentication tokens + +Usage: +npm token list +npm token revoke +npm token create + +Options: +[--name ] [--token-description ] [--expires ] +[--packages [--packages ...]] [--packages-all] +[--scopes [--scopes ...]] [--orgs [--orgs ...]] +[--packages-and-scopes-permission ] +[--orgs-permission ] +[--cidr [--cidr ...]] [--bypass-2fa] [--password ] +[--registry ] [--otp ] [--read-only] + +Run "npm help token" for more info + +\`\`\`bash +npm token list +npm token revoke +npm token create +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`name\` +#### \`token-description\` +#### \`expires\` +#### \`packages\` +#### \`packages-all\` +#### \`scopes\` +#### \`orgs\` +#### \`packages-and-scopes-permission\` +#### \`orgs-permission\` +#### \`cidr\` +#### \`bypass-2fa\` +#### \`password\` +#### \`registry\` +#### \`otp\` +#### \`read-only\` +` + +exports[`test/lib/docs.js TAP usage undeprecate > must match snapshot 1`] = ` +Undeprecate a version of a package + +Usage: +npm undeprecate + +Options: +[--registry ] [--otp ] [--dry-run] + +Run "npm help undeprecate" for more info + +\`\`\`bash +npm undeprecate +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`otp\` +#### \`dry-run\` +` + +exports[`test/lib/docs.js TAP usage uninstall > must match snapshot 1`] = ` +Remove a package + +Usage: +npm uninstall [<@scope>/]... + +Options: +[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-g|--global] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +aliases: unlink, remove, rm, r, un + +Run "npm help uninstall" for more info + +\`\`\`bash +npm uninstall [<@scope>/]... + +aliases: unlink, remove, rm, r, un +\`\`\` + +#### \`save\` +#### \`global\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage unpublish > must match snapshot 1`] = ` +Remove a package from the registry + +Usage: +npm unpublish [] + +Options: +[--dry-run] [-f|--force] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] + +Run "npm help unpublish" for more info + +\`\`\`bash +npm unpublish [] +\`\`\` + +#### \`dry-run\` +#### \`force\` +#### \`workspace\` +#### \`workspaces\` +` + +exports[`test/lib/docs.js TAP usage unstar > must match snapshot 1`] = ` +Remove an item from your favorite packages + +Usage: +npm unstar [...] + +Options: +[--registry ] [--unicode] [--otp ] + +Run "npm help unstar" for more info + +\`\`\`bash +npm unstar [...] +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`unicode\` +#### \`otp\` +` + +exports[`test/lib/docs.js TAP usage update > must match snapshot 1`] = ` +Update packages + +Usage: +npm update [...] + +Options: +[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-g|--global] [--install-strategy ] +[--legacy-bundling] [--global-style] +[--omit [--omit ...]] +[--include [--include ...]] +[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] +[--ignore-scripts] [--no-audit] [--before ] [--no-bin-links] [--no-fund] +[--dry-run] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] [--install-links] + +aliases: up, upgrade, udpate + +Run "npm help update" for more info + +\`\`\`bash +npm update [...] + +aliases: up, upgrade, udpate +\`\`\` + +#### \`save\` +#### \`global\` +#### \`install-strategy\` +#### \`legacy-bundling\` +#### \`global-style\` +#### \`omit\` +#### \`include\` +#### \`strict-peer-deps\` +#### \`package-lock\` +#### \`foreground-scripts\` +#### \`ignore-scripts\` +#### \`audit\` +#### \`before\` +#### \`bin-links\` +#### \`fund\` +#### \`dry-run\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +#### \`install-links\` +` + +exports[`test/lib/docs.js TAP usage version > must match snapshot 1`] = ` +Bump a package version + +Usage: +npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git] + +Options: +[--allow-same-version] [--no-commit-hooks] [--no-git-tag-version] [--json] +[--preid prerelease-id] [--sign-git-tag] +[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] +[-w|--workspace [-w|--workspace ...]] +[--workspaces] [--no-workspaces-update] [--include-workspace-root] +[--ignore-scripts] + +alias: verison + +Run "npm help version" for more info + +\`\`\`bash +npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git] + +alias: verison +\`\`\` + +#### \`allow-same-version\` +#### \`commit-hooks\` +#### \`git-tag-version\` +#### \`json\` +#### \`preid\` +#### \`sign-git-tag\` +#### \`save\` +#### \`workspace\` +#### \`workspaces\` +#### \`workspaces-update\` +#### \`include-workspace-root\` +#### \`ignore-scripts\` +` + +exports[`test/lib/docs.js TAP usage view > must match snapshot 1`] = ` +View registry info + +Usage: +npm view [] [[.subfield]...] + +Options: +[--json] [-w|--workspace [-w|--workspace ...]] +[--workspaces] [--include-workspace-root] + +aliases: info, show, v + +Run "npm help view" for more info + +\`\`\`bash +npm view [] [[.subfield]...] + +aliases: info, show, v +\`\`\` + +#### \`json\` +#### \`workspace\` +#### \`workspaces\` +#### \`include-workspace-root\` +` + +exports[`test/lib/docs.js TAP usage whoami > must match snapshot 1`] = ` +Display npm username + +Usage: +npm whoami + +Options: +[--registry ] + +Run "npm help whoami" for more info + +\`\`\`bash +npm whoami +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +` diff --git a/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/tap-snapshots/test/lib/load-all-commands.js.test.cjs deleted file mode 100644 index eac037f4b2708..0000000000000 --- a/tap-snapshots/test/lib/load-all-commands.js.test.cjs +++ /dev/null @@ -1,1024 +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/load-all-commands.js TAP load each command access > must match snapshot 1`] = ` -Set access level on published packages - -Usage: -npm access public [] -npm access restricted [] -npm access grant [] -npm access revoke [] -npm access 2fa-required [] -npm access 2fa-not-required [] -npm access ls-packages [||] -npm access ls-collaborators [ []] -npm access edit [] - -Options: -[--registry ] [--otp ] - -Run "npm help access" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command adduser > must match snapshot 1`] = ` -Add a registry user account - -Usage: -npm adduser - -Options: -[--registry ] [--scope <@scope>] -[--auth-type ] - -aliases: login, add-user - -Run "npm help adduser" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command audit > must match snapshot 1`] = ` -Run a security audit - -Usage: -npm audit [fix|signatures] - -Options: -[--audit-level ] [--dry-run] [-f|--force] -[--json] [--package-lock-only] -[--omit [--omit ...]] -[--foreground-scripts] [--ignore-scripts] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -Run "npm help audit" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command bin > must match snapshot 1`] = ` -Display npm bin folder - -Usage: -npm bin - -Options: -[-g|--global] - -Run "npm help bin" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command birthday > must match snapshot 1`] = ` -Birthday, deprecated - -Usage: -npm birthday - -Run "npm help birthday" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command bugs > must match snapshot 1`] = ` -Report bugs for a package in a web browser - -Usage: -npm bugs [ [ ...]] - -Options: -[--no-browser|--browser ] [--registry ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -alias: issues - -Run "npm help bugs" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command cache > must match snapshot 1`] = ` -Manipulates packages cache - -Usage: -npm cache add -npm cache clean [] -npm cache ls [@] -npm cache verify - -Options: -[--cache ] - -Run "npm help cache" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command ci > must match snapshot 1`] = ` -Clean install a project - -Usage: -npm ci - -Options: -[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -[--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -aliases: clean-install, ic, install-clean, isntall-clean - -Run "npm help ci" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command completion > must match snapshot 1`] = ` -Tab Completion for npm - -Usage: -npm completion - -Run "npm help completion" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command config > must match snapshot 1`] = ` -Manage the npm configuration files - -Usage: -npm config set = [= ...] -npm config get [ [ ...]] -npm config delete [ ...] -npm config list [--json] -npm config edit - -Options: -[--json] [-g|--global] [--editor ] [-L|--location ] -[-l|--long] - -alias: c - -Run "npm help config" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command dedupe > must match snapshot 1`] = ` -Reduce duplication in the package tree - -Usage: -npm dedupe - -Options: -[--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock] -[--omit [--omit ...]] [--ignore-scripts] -[--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: ddp - -Run "npm help dedupe" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command deprecate > must match snapshot 1`] = ` -Deprecate a version of a package - -Usage: -npm deprecate - -Options: -[--registry ] [--otp ] - -Run "npm help deprecate" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command diff > must match snapshot 1`] = ` -The registry diff command - -Usage: -npm diff [...] - -Options: -[--diff [--diff ...]] [--diff-name-only] -[--diff-unified ] [--diff-ignore-all-space] [--diff-no-prefix] -[--diff-src-prefix ] [--diff-dst-prefix ] [--diff-text] [-g|--global] -[--tag ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -Run "npm help diff" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command dist-tag > must match snapshot 1`] = ` -Modify package distribution tags - -Usage: -npm dist-tag add [] -npm dist-tag rm -npm dist-tag ls [] - -Options: -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -alias: dist-tags - -Run "npm help dist-tag" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command docs > must match snapshot 1`] = ` -Open documentation for a package in a web browser - -Usage: -npm docs [ [ ...]] - -Options: -[--no-browser|--browser ] [--registry ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -alias: home - -Run "npm help docs" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command doctor > must match snapshot 1`] = ` -Check your npm environment - -Usage: -npm doctor - -Options: -[--registry ] - -Run "npm help doctor" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command edit > must match snapshot 1`] = ` -Edit an installed package - -Usage: -npm edit [/...] - -Options: -[--editor ] - -Run "npm help edit" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command exec > must match snapshot 1`] = ` -Run a command from a local or remote npm package - -Usage: -npm exec -- [@] [args...] -npm exec --package=[@] -- [args...] -npm exec -c ' [args...]' -npm exec --package=foo -c ' [args...]' - -Options: -[--package [--package ...]] [-c|--call ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -alias: x - -Run "npm help exec" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command explain > must match snapshot 1`] = ` -Explain installed packages - -Usage: -npm explain - -Options: -[--json] [-w|--workspace [-w|--workspace ...]] - -alias: why - -Run "npm help explain" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command explore > must match snapshot 1`] = ` -Browse an installed package - -Usage: -npm explore [ -- ] - -Options: -[--shell ] - -Run "npm help explore" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command find-dupes > must match snapshot 1`] = ` -Find duplication in the package tree - -Usage: -npm find-dupes - -Options: -[--global-style] [--legacy-bundling] [--strict-peer-deps] [--no-package-lock] -[--omit [--omit ...]] [--ignore-scripts] -[--no-audit] [--no-bin-links] [--no-fund] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -Run "npm help find-dupes" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command fund > must match snapshot 1`] = ` -Retrieve funding information - -Usage: -npm fund [] - -Options: -[--json] [--no-browser|--browser ] [--unicode] -[-w|--workspace [-w|--workspace ...]] -[--which ] - -Run "npm help fund" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command get > must match snapshot 1`] = ` -Get a value from the npm configuration - -Usage: -npm get [ ...] (See \`npm config\`) - -Run "npm help get" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command help > must match snapshot 1`] = ` -Get help on npm - -Usage: -npm help [] - -Options: -[--viewer ] - -alias: hlep - -Run "npm help help" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command help-search > must match snapshot 1`] = ` -Search npm help documentation - -Usage: -npm help-search - -Options: -[-l|--long] - -Run "npm help help-search" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command hook > must match snapshot 1`] = ` -Manage registry hooks - -Usage: -npm hook add [--type=] -npm hook ls [pkg] -npm hook rm -npm hook update - -Options: -[--registry ] [--otp ] - -Run "npm help hook" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command init > must match snapshot 1`] = ` -Create a package.json file - -Usage: -npm init (same as \`npx ) -npm init <@scope> (same as \`npx <@scope>/create\`) - -Options: -[-y|--yes] [-f|--force] [--scope <@scope>] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--no-workspaces-update] [--include-workspace-root] - -aliases: create, innit - -Run "npm help init" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command install > must match snapshot 1`] = ` -Install a package - -Usage: -npm install [ ...] - -Options: -[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -[--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall - -Run "npm help install" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command install-ci-test > must match snapshot 1`] = ` -Install a project with a clean slate and run tests - -Usage: -npm install-ci-test - -Options: -[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -[--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: cit - -Run "npm help install-ci-test" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command install-test > must match snapshot 1`] = ` -Install package(s) and run tests - -Usage: -npm install-test [ ...] - -Options: -[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -[--omit [--omit ...]] -[--strict-peer-deps] [--no-package-lock] [--foreground-scripts] -[--ignore-scripts] [--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: it - -Run "npm help install-test" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command link > must match snapshot 1`] = ` -Symlink a package folder - -Usage: -npm link [] - -Options: -[-S|--save|--no-save|--save-prod|--save-dev|--save-optional|--save-peer|--save-bundle] -[-E|--save-exact] [-g|--global] [--global-style] [--legacy-bundling] -[--strict-peer-deps] [--no-package-lock] -[--omit [--omit ...]] [--ignore-scripts] -[--no-audit] [--no-bin-links] [--no-fund] [--dry-run] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: ln - -Run "npm help link" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command ll > must match snapshot 1`] = ` -List installed packages - -Usage: -npm ll [[<@scope>/] ...] - -Options: -[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [--depth ] -[--omit [--omit ...]] [--link] -[--package-lock-only] [--unicode] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: la - -Run "npm help ll" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command login > must match snapshot 1`] = ` -Add a registry user account - -Usage: -npm adduser - -Options: -[--registry ] [--scope <@scope>] -[--auth-type ] - -aliases: login, add-user - -Run "npm help adduser" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command logout > must match snapshot 1`] = ` -Log out of the registry - -Usage: -npm logout - -Options: -[--registry ] [--scope <@scope>] - -Run "npm help logout" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command ls > must match snapshot 1`] = ` -List installed packages - -Usage: -npm ls - -Options: -[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] [--depth ] -[--omit [--omit ...]] [--link] -[--package-lock-only] [--unicode] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: list - -Run "npm help ls" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command org > must match snapshot 1`] = ` -Manage orgs - -Usage: -npm org set orgname username [developer | admin | owner] -npm org rm orgname username -npm org ls orgname [] - -Options: -[--registry ] [--otp ] [--json] [-p|--parseable] - -alias: ogr - -Run "npm help org" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command outdated > must match snapshot 1`] = ` -Check for outdated packages - -Usage: -npm outdated [ ...] - -Options: -[-a|--all] [--json] [-l|--long] [-p|--parseable] [-g|--global] -[-w|--workspace [-w|--workspace ...]] - -Run "npm help outdated" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command owner > must match snapshot 1`] = ` -Manage package owners - -Usage: -npm owner add -npm owner rm -npm owner ls - -Options: -[--registry ] [--otp ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] - -alias: author - -Run "npm help owner" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command pack > must match snapshot 1`] = ` -Create a tarball from a package - -Usage: -npm pack - -Options: -[--dry-run] [--json] [--pack-destination ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -Run "npm help pack" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command ping > must match snapshot 1`] = ` -Ping npm registry - -Usage: -npm ping - -Options: -[--registry ] - -Run "npm help ping" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command pkg > must match snapshot 1`] = ` -Manages your package.json - -Usage: -npm pkg set = [= ...] -npm pkg get [ [ ...]] -npm pkg delete [ ...] -npm pkg set [[].= ...] -npm pkg set [[].= ...] - -Options: -[-f|--force] [--json] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] - -Run "npm help pkg" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command prefix > must match snapshot 1`] = ` -Display prefix - -Usage: -npm prefix [-g] - -Options: -[-g|--global] - -Run "npm help prefix" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command profile > must match snapshot 1`] = ` -Change settings on your registry profile - -Usage: -npm profile enable-2fa [auth-only|auth-and-writes] -npm profile disable-2fa -npm profile get [] -npm profile set - -Options: -[--registry ] [--json] [-p|--parseable] [--otp ] - -Run "npm help profile" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command prune > must match snapshot 1`] = ` -Remove extraneous packages - -Usage: -npm prune [[<@scope>/]...] - -Options: -[--omit [--omit ...]] [--dry-run] -[--json] [--foreground-scripts] [--ignore-scripts] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -Run "npm help prune" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command publish > must match snapshot 1`] = ` -Publish a package - -Usage: -npm publish - -Options: -[--tag ] [--access ] [--dry-run] [--otp ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -Run "npm help publish" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command query > must match snapshot 1`] = ` -Retrieve a filtered list of packages - -Usage: -npm query - -Options: -[-g|--global] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -Run "npm help query" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command rebuild > must match snapshot 1`] = ` -Rebuild a package - -Usage: -npm rebuild [] ...] - -Options: -[-g|--global] [--no-bin-links] [--foreground-scripts] [--ignore-scripts] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--install-links] - -alias: rb - -Run "npm help rebuild" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command repo > must match snapshot 1`] = ` -Open package repository page in the browser - -Usage: -npm repo [ [ ...]] - -Options: -[--no-browser|--browser ] [--registry ] -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] - -Run "npm help repo" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command restart > must match snapshot 1`] = ` -Restart a package - -Usage: -npm restart [-- ] - -Options: -[--ignore-scripts] [--script-shell ] - -Run "npm help restart" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command root > must match snapshot 1`] = ` -Display npm root - -Usage: -npm root - -Options: -[-g|--global] - -Run "npm help root" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command run-script > must match snapshot 1`] = ` -Run arbitrary package scripts - -Usage: -npm run-script [-- ] - -Options: -[-w|--workspace [-w|--workspace ...]] -[-ws|--workspaces] [--include-workspace-root] [--if-present] [--ignore-scripts] -[--foreground-scripts] [--script-shell ] - -aliases: run, rum, urn - -Run "npm help run-script" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command search > must match snapshot 1`] = ` -Search for packages - -Usage: -npm search [search terms ...] - -Options: -[-l|--long] [--json] [--color|--no-color|--color always] [-p|--parseable] -[--no-description] [--searchopts ] [--searchexclude ] -[--registry ] [--prefer-online] [--prefer-offline] [--offline] - -aliases: find, s, se - -Run "npm help search" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command set > must match snapshot 1`] = ` -Set a value in the npm configuration - -Usage: -npm set = [= ...] (See \`npm config\`) - -Run "npm help set" for more info -` - -exports[`test/lib/load-all-commands.js TAP load each command set-script > must match snapshot 1`] = ` -Set tasks in the scripts section of package.json, deprecated - -Usage: -npm set-script [